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

Delta Between Two Patch Sets: 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/
Left Patch Set: Created 4 months ago
Right Patch Set: DjangoUserModel, better helpers integration for authentication Created 3 months, 4 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:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
1 # Copyright 2008 Google Inc.
2 #
1 # Licensed under the Apache License, Version 2.0 (the "License"); 3 # 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
2 # you may not use this file except in compliance with the License. 4 # you may not use this file except in compliance with the License.
3 # You may obtain a copy of the License at 5 # You may obtain a copy of the License at
4 # 6 #
5 # http://www.apache.org/licenses/LICENSE-2.0 7 # http://www.apache.org/licenses/LICENSE-2.0
6 # 8 #
7 # Unless required by applicable law or agreed to in writing, software 9 # Unless required by applicable law or agreed to in writing, software
8 # distributed under the License is distributed on an "AS IS" BASIS, 10 # distributed under the License is distributed on an "AS IS" BASIS,
9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 # See the License for the specific language governing permissions and 12 # See the License for the specific language governing permissions and
11 # limitations under the License. 13 # limitations under the License.
12 14
13 """ 15 """
14 Authentication module that mimics the behavior of Django's authentication 16 Authentication module that mimics the behavior of Django's authentication
15 implementation. 17 implementation.
16 18
17 To use this authentication module in an Appengine/Django project:
18 - add 'appengine_django.auth.middleware.AuthenticationMiddleware'
19 to MIDDLEWARE_CLASSES
20 - add 'appengine_django.auth.context_processors.auth'
21 to TEMPLATE_CONTEXT_PROCESSORS
22
23 Limitations: 19 Limitations:
24 - all user manipulation methods are not available
25 - all user permissions methods are not available 20 - all user permissions methods are not available
26 - user.get_profile method not implemented
27 - db.UserProperty returns user.User instead of DjangoUser
28 """ 21 """
29 22
30 from datetime import datetime 23 from datetime import datetime
31 import urllib 24 import urllib
32 25
33 from django.db.models.manager import EmptyManager 26 from django.db.models.manager import EmptyManager
34 from django.http import HttpResponseRedirect 27 from django.http import HttpResponseRedirect
35 from django.template import Node 28 from django.template import Node
36 from django.utils.encoding import smart_str 29 from django.utils.encoding import smart_str
37 30
38 from google.appengine.api import datastore_types 31 from google.appengine.api import datastore_types
39 from google.appengine.api import mail
40 from google.appengine.api import users 32 from google.appengine.api import users
33 from google.appengine.ext.db import UserProperty
41 from google.appengine.ext.webapp import template 34 from google.appengine.ext.webapp import template
42 35
43 from appengine_django import models 36 from appengine_django import models
44 37
45 register = template.create_template_register() 38 register = template.create_template_register()
46 template.register_template_library("appengine_django.auth") 39 template.register_template_library("appengine_django.auth")
47
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
48 class CallableString(str):
49 """String subclass that returns the string if it's called as a function.
50 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
51 def __call__(self):
52 return str(self)
53
54
55 class DjangoUser(users.User):
56 """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
57
58 This class is added to datastore_types when importing this module
59 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
60 """
61 id = None
62 is_active = True
63 first_name = None
64 last_name = None
65 password = None
66 _groups = EmptyManager()
67 _user_permissions = EmptyManager()
68
69 def __init__(self, *args, **kw):
70 super(DjangoUser, self).__init__(*args, **kw)
71 self.email = CallableString(self._User__email)
72
73 def __unicode__(self):
74 return self.username
75
76 def __str__(self):
77 return unicode(self).encode('utf-8')
78
79 def _get_username(self):
80 return self.nickname()
81 username = property(fget=_get_username)
82
83 def _is_superuser(self):
84 return users.is_current_user_admin()
85 is_superuser = property(fget=_is_superuser)
86 is_staff = property(fget=_is_superuser)
87
88 def _default_now(self):
89 return datetime.now()
90 last_login = property(fget=_default_now)
91 date_joined = property(fget=_default_now)
92
93 def save(self):
94 raise NotImplementedError
95
96 def delete(self):
97 raise NotImplementedError
98
99 def set_password(self, raw_password):
100 raise NotImplementedError
101
102 def check_password(self, raw_password):
103 raise NotImplementedError
104
105 def set_unusable_password(self):
106 raise NotImplementedError
107
108 def has_usable_password(self):
109 raise NotImplementedError
110
111 def _get_groups(self):
112 return self._groups
113 groups = property(_get_groups)
114
115 def _get_user_permissions(self):
116 return self._user_permissions
117 user_permissions = property(_get_user_permissions)
118
119 def get_group_permissions(self):
120 return self._user_permissions
121
122 def get_all_permissions(self):
123 return self._user_permissions
124
125 def has_perm(self, perm):
126 return False
127
128 def has_perms(self, perm_list):
129 return False
130
131 def has_module_perms(self, module):
132 return False
133
134 def get_and_delete_messages(self):
135 return []
136
137 def is_anonymous(self):
138 """Always return False"""
139 return False
140
141 def is_authenticated(self):
142 """Always return True"""
143 return True
144
145 def get_absolute_url(self):
146 return "/users/%s/" % urllib.quote(smart_str(self.username))
147
148 def get_full_name(self):
149 return ""
150
151 def email_user(self, subject, message, from_email=None):
152 """Sends an email to this user"""
153 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
154 to=self.email,
155 subject=subject,
156 message=message)
157
158 def get_profile(self):
159 raise NotImplementedError
160 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
161 40
162 41
163 def login_required(function): 42 def login_required(function):
164 """Implementation of Django's login_required decorator. 43 """Implementation of Django's login_required decorator.
165 44
166 The login redirect URL is always set to request.path 45 The login redirect URL is always set to request.path
167 """ 46 """
168 def login_required_wrapper(request, *args, **kw): 47 def login_required_wrapper(request, *args, **kw):
169 if request.user.is_authenticated(): 48 if request.user.is_authenticated():
170 return function(request, *args, **kw) 49 return function(request, *args, **kw)
171 return HttpResponseRedirect(users.create_login_url(request.path)) 50 return HttpResponseRedirect(users.create_login_url(request.path))
172 return login_required_wrapper 51 return login_required_wrapper
173 52
174 53
175 class AuthLoginUrlsNode(Node): 54 class AuthLoginUrlsNode(Node):
176 """Template node that creates an appengine login or logout URL. 55 """Template node that creates an appengine login or logout URL.
177 56
178 If create_login_url is True the appengine's login URL is rendered into 57 If create_login_url is True the appengine's login URL is rendered into
179 the template, otherwise the logout URL. 58 the template, otherwise the logout URL.
180 """ 59 """
181 def __init__(self, create_login_url, redirect): 60 def __init__(self, create_login_url, redirect):
182 self.redirect = redirect 61 self.redirect = redirect
183 self.create_login_url = create_login_url 62 self.create_login_url = create_login_url
184 63
185 def render(self, context): 64 def render(self, context):
186 if self.create_login_url: 65 if self.create_login_url:
187 return users.create_login_url(self.redirect) 66 return users.create_login_url(self.redirect)
188 else: 67 else:
189 return users.create_logout_url(self.redirect) 68 return users.create_logout_url(self.redirect)
190 69
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
70
191 def auth_login_urls(parser, token): 71 def auth_login_urls(parser, token):
192 """Template tag registered as 'auth_login_url' and 'auth_logout_url' 72 """Template tag registered as 'auth_login_url' and 'auth_logout_url'
193 when the module is imported. 73 when the module is imported.
194 74
195 Both tags take an optional argument that specifies the redirect URL and 75 Both tags take an optional argument that specifies the redirect URL and
196 defaults to '/'. 76 defaults to '/'.
197 """ 77 """
198 bits = list(token.split_contents()) 78 bits = list(token.split_contents())
199 if len(bits) == 2: 79 if len(bits) == 2:
200 redirect = bits[1] 80 redirect = bits[1]
201 else: 81 else:
202 redirect = "/" 82 redirect = "/"
203 login = bits[0] == "auth_login_url" 83 login = bits[0] == "auth_login_url"
204 return AuthLoginUrlsNode(login, redirect) 84 return AuthLoginUrlsNode(login, redirect)
205 register.tag("auth_login_url", auth_login_urls) 85 register.tag("auth_login_url", auth_login_urls)
206 register.tag("auth_logout_url", auth_login_urls) 86 register.tag("auth_logout_url", auth_login_urls)
LEFTRIGHT

Powered by Google App Engine
This is Rietveld r305