Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(10)

Unified Diff: appengine_django/auth/__init__.py

Issue 908: [issue6] Google's Users API Integration (Closed) SVN Base: http://google-app-engine-django.googlecode.com/svn/trunk/
Patch Set: Created 3 months, 3 weeks ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side by-side-diff with in-line comments
Download patch
Index: appengine_django/auth/__init__.py
===================================================================
--- appengine_django/auth/__init__.py (Revision 0)
+++ appengine_django/auth/__init__.py (Revision 0)
@@ -0,0 +1,206 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
mattbrown.nz 2008/05/09 10:40:20 You should probably add an Author or Copyright lin
aalbrecht 2008/05/09 20:23:23 On 2008/05/09 10:40:20, mattbrown.nz wrote: > You
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Authentication module that mimics the behavior of Django's authentication
+implementation.
+
+To use this authentication module in an Appengine/Django project:
+ - add 'appengine_django.auth.middleware.AuthenticationMiddleware'
+ to MIDDLEWARE_CLASSES
+ - add 'appengine_django.auth.context_processors.auth'
+ to TEMPLATE_CONTEXT_PROCESSORS
+
+Limitations:
+ - all user manipulation methods are not available
+ - all user permissions methods are not available
+ - user.get_profile method not implemented
+ - db.UserProperty returns user.User instead of DjangoUser
+"""
+
+from datetime import datetime
+import urllib
+
+from django.db.models.manager import EmptyManager
+from django.http import HttpResponseRedirect
+from django.template import Node
+from django.utils.encoding import smart_str
+
+from google.appengine.api import datastore_types
+from google.appengine.api import mail
+from google.appengine.api import users
+from google.appengine.ext.webapp import template
+
+from appengine_django import models
+
+register = template.create_template_register()
+template.register_template_library("appengine_django.auth")
+
mattbrown.nz 2008/05/09 10:40:20 add extra blank line
aalbrecht 2008/05/09 20:23:23 On 2008/05/09 10:40:20, mattbrown.nz wrote: > add
+class CallableString(str):
+ """String subclass that returns the string if it's called as a function.
+ This class is required for the user's email attribute."""
mattbrown.nz 2008/05/09 10:40:20 closing """ on next line.
aalbrecht 2008/05/09 20:23:23 On 2008/05/09 10:40:20, mattbrown.nz wrote: > clos
+ def __call__(self):
+ return str(self)
+
+
+class DjangoUser(users.User):
+ """Appengine User subclass that mimics the behavior of an Django user.
mattbrown.nz 2008/05/09 10:40:20 App Engine (nitpick)
aalbrecht 2008/05/09 20:23:23 On 2008/05/09 10:40:20, mattbrown.nz wrote: > App
+
+ This class is added to datastore_types when importing this module
+ to make it usable for db.UserProperty().
mattbrown.nz 2008/05/09 10:40:20 I don't believe this is possible. See further comm
aalbrecht 2008/05/09 20:23:23 On 2008/05/09 10:40:20, mattbrown.nz wrote: > I do
+ """
+ id = None
+ is_active = True
+ first_name = None
+ last_name = None
+ password = None
+ _groups = EmptyManager()
+ _user_permissions = EmptyManager()
+
+ def __init__(self, *args, **kw):
+ super(DjangoUser, self).__init__(*args, **kw)
+ self.email = CallableString(self._User__email)
+
+ def __unicode__(self):
+ return self.username
+
+ def __str__(self):
+ return unicode(self).encode('utf-8')
+
+ def _get_username(self):
+ return self.nickname()
+ username = property(fget=_get_username)
+
+ def _is_superuser(self):
+ return users.is_current_user_admin()
+ is_superuser = property(fget=_is_superuser)
+ is_staff = property(fget=_is_superuser)
+
+ def _default_now(self):
+ return datetime.now()
+ last_login = property(fget=_default_now)
+ date_joined = property(fget=_default_now)
+
+ def save(self):
+ raise NotImplementedError
+
+ def delete(self):
+ raise NotImplementedError
+
+ def set_password(self, raw_password):
+ raise NotImplementedError
+
+ def check_password(self, raw_password):
+ raise NotImplementedError
+
+ def set_unusable_password(self):
+ raise NotImplementedError
+
+ def has_usable_password(self):
+ raise NotImplementedError
+
+ def _get_groups(self):
+ return self._groups
+ groups = property(_get_groups)
+
+ def _get_user_permissions(self):
+ return self._user_permissions
+ user_permissions = property(_get_user_permissions)
+
+ def get_group_permissions(self):
+ return self._user_permissions
+
+ def get_all_permissions(self):
+ return self._user_permissions
+
+ def has_perm(self, perm):
+ return False
+
+ def has_perms(self, perm_list):
+ return False
+
+ def has_module_perms(self, module):
+ return False
+
+ def get_and_delete_messages(self):
+ return []
+
+ def is_anonymous(self):
+ """Always return False"""
+ return False
+
+ def is_authenticated(self):
+ """Always return True"""
+ return True
+
+ def get_absolute_url(self):
+ return "/users/%s/" % urllib.quote(smart_str(self.username))
+
+ def get_full_name(self):
+ return ""
+
+ def email_user(self, subject, message, from_email=None):
+ """Sends an email to this user"""
+ mail.send_mail(sender=from_email,
mattbrown.nz 2008/05/09 10:40:20 The App Engine email API requires from_email to be
aalbrecht 2008/05/09 20:23:23 On 2008/05/09 10:40:20, mattbrown.nz wrote: > The
+ to=self.email,
+ subject=subject,
+ message=message)
+
+ def get_profile(self):
+ raise NotImplementedError
+datastore_types._PROPERTY_TYPES.append(DjangoUser)
mattbrown.nz 2008/05/09 10:40:20 model properties need to be descended from db.Prop
aalbrecht 2008/05/09 20:23:23 On 2008/05/09 10:40:20, mattbrown.nz wrote: > mode
mattbrown.nz 2008/05/11 03:01:20 On 2008/05/09 20:23:23, aalbrecht wrote: > 975, b
aalbrecht 2008/05/13 14:20:24 The DjangoUser class is now a model. I think this
+
+
+def login_required(function):
+ """Implementation of Django's login_required decorator.
+
+ The login redirect URL is always set to request.path
+ """
+ def login_required_wrapper(request, *args, **kw):
+ if request.user.is_authenticated():
+ return function(request, *args, **kw)
+ return HttpResponseRedirect(users.create_login_url(request.path))
+ return login_required_wrapper
+
+
+class AuthLoginUrlsNode(Node):
+ """Template node that creates an appengine login or logout URL.
+
+ If create_login_url is True the appengine's login URL is rendered into
+ the template, otherwise the logout URL.
+ """
+ def __init__(self, create_login_url, redirect):
+ self.redirect = redirect
+ self.create_login_url = create_login_url
+
+ def render(self, context):
+ if self.create_login_url:
+ return users.create_login_url(self.redirect)
+ else:
+ return users.create_logout_url(self.redirect)
+
mattbrown.nz 2008/05/09 10:40:20 add blank line
aalbrecht 2008/05/09 20:23:23 On 2008/05/09 10:40:20, mattbrown.nz wrote: > add
+def auth_login_urls(parser, token):
+ """Template tag registered as 'auth_login_url' and 'auth_logout_url'
+ when the module is imported.
+
+ Both tags take an optional argument that specifies the redirect URL and
+ defaults to '/'.
+ """
+ bits = list(token.split_contents())
+ if len(bits) == 2:
+ redirect = bits[1]
+ else:
+ redirect = "/"
+ login = bits[0] == "auth_login_url"
+ return AuthLoginUrlsNode(login, redirect)
+register.tag("auth_login_url", auth_login_urls)
+register.tag("auth_logout_url", auth_login_urls)

Powered by Google App Engine
This is Rietveld r292