| LEFT | RIGHT |
|---|---|
| 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. |
| (...skipping 11 matching lines...) Show 10 above Show 10 below | |
| 23 Limitations: | 25 Limitations: |
| 24 - all user manipulation methods are not available | 26 - all user manipulation methods are not available |
| 25 - all user permissions methods are not available | 27 - all user permissions methods are not available |
| 26 - user.get_profile method not implemented | 28 - user.get_profile method not implemented |
| 27 - db.UserProperty returns user.User instead of DjangoUser | 29 - db.UserProperty returns user.User instead of DjangoUser |
| 28 """ | 30 """ |
| 29 | 31 |
| 30 from datetime import datetime | 32 from datetime import datetime |
| 31 import urllib | 33 import urllib |
| 32 | 34 |
| 35 from django.core import mail | |
| 33 from django.db.models.manager import EmptyManager | 36 from django.db.models.manager import EmptyManager |
| 34 from django.http import HttpResponseRedirect | 37 from django.http import HttpResponseRedirect |
| 35 from django.template import Node | 38 from django.template import Node |
| 36 from django.utils.encoding import smart_str | 39 from django.utils.encoding import smart_str |
| 37 | 40 |
| 38 from google.appengine.api import datastore_types | 41 from google.appengine.api import datastore_types |
| 39 from google.appengine.api import mail | |
| 40 from google.appengine.api import users | 42 from google.appengine.api import users |
| 41 from google.appengine.ext.webapp import template | 43 from google.appengine.ext.webapp import template |
| 42 | 44 |
| 43 from appengine_django import models | 45 from appengine_django import models |
| 44 | 46 |
| 45 register = template.create_template_register() | 47 register = template.create_template_register() |
| 46 template.register_template_library("appengine_django.auth") | 48 template.register_template_library("appengine_django.auth") |
| 47 | 49 |
|
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
| |
| 50 | |
| 48 class CallableString(str): | 51 class CallableString(str): |
| 49 """String subclass that returns the string if it's called as a function. | 52 """String subclass that returns the string if it's called as a function. |
| 50 This class is required for the user's email attribute.""" | 53 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
| |
| 54 """ | |
| 51 def __call__(self): | 55 def __call__(self): |
| 52 return str(self) | 56 return str(self) |
| 53 | 57 |
| 54 | 58 |
| 55 class DjangoUser(users.User): | 59 class DjangoUser(users.User): |
| 56 """Appengine User subclass that mimics the behavior of an Django user. | 60 """App Engine 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 | 61 |
| 58 This class is added to datastore_types when importing this module | 62 This class is added to datastore_types when importing this module |
| 59 to make it usable for db.UserProperty(). | 63 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 """ | 64 """ |
| 61 id = None | 65 id = None |
| 62 is_active = True | 66 is_active = True |
| 63 first_name = None | 67 first_name = None |
| 64 last_name = None | 68 last_name = None |
| 65 password = None | 69 password = None |
| 66 _groups = EmptyManager() | 70 _groups = EmptyManager() |
| 67 _user_permissions = EmptyManager() | 71 _user_permissions = EmptyManager() |
| 68 | 72 |
| 69 def __init__(self, *args, **kw): | 73 def __init__(self, *args, **kw): |
| (...skipping 71 matching lines...) Show 10 above Show 10 below | |
| 141 def is_authenticated(self): | 145 def is_authenticated(self): |
| 142 """Always return True""" | 146 """Always return True""" |
| 143 return True | 147 return True |
| 144 | 148 |
| 145 def get_absolute_url(self): | 149 def get_absolute_url(self): |
| 146 return "/users/%s/" % urllib.quote(smart_str(self.username)) | 150 return "/users/%s/" % urllib.quote(smart_str(self.username)) |
| 147 | 151 |
| 148 def get_full_name(self): | 152 def get_full_name(self): |
| 149 return "" | 153 return "" |
| 150 | 154 |
| 151 def email_user(self, subject, message, from_email=None): | 155 def email_user(self, subject, message, from_email): |
| 152 """Sends an email to this user""" | 156 """Sends an email to this user. |
| 153 mail.send_mail(sender=from_email, | 157 |
|
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, | 158 According to the App Engine email API the from_email must be the |
| 155 subject=subject, | 159 email address of a registered administrator for the application. |
| 156 message=message) | 160 """ |
| 161 mail.send_mail(subject, | |
| 162 message, | |
| 163 from_email, | |
| 164 [self.email]) | |
| 157 | 165 |
| 158 def get_profile(self): | 166 def get_profile(self): |
| 159 raise NotImplementedError | 167 raise NotImplementedError |
| 160 datastore_types._PROPERTY_TYPES.append(DjangoUser) | 168 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 | 169 |
| 162 | 170 |
| 163 def login_required(function): | 171 def login_required(function): |
| 164 """Implementation of Django's login_required decorator. | 172 """Implementation of Django's login_required decorator. |
| 165 | 173 |
| 166 The login redirect URL is always set to request.path | 174 The login redirect URL is always set to request.path |
| 167 """ | 175 """ |
| 168 def login_required_wrapper(request, *args, **kw): | 176 def login_required_wrapper(request, *args, **kw): |
| 169 if request.user.is_authenticated(): | 177 if request.user.is_authenticated(): |
| 170 return function(request, *args, **kw) | 178 return function(request, *args, **kw) |
| 171 return HttpResponseRedirect(users.create_login_url(request.path)) | 179 return HttpResponseRedirect(users.create_login_url(request.path)) |
| 172 return login_required_wrapper | 180 return login_required_wrapper |
| 173 | 181 |
| 174 | 182 |
| 175 class AuthLoginUrlsNode(Node): | 183 class AuthLoginUrlsNode(Node): |
| 176 """Template node that creates an appengine login or logout URL. | 184 """Template node that creates an appengine login or logout URL. |
| 177 | 185 |
| 178 If create_login_url is True the appengine's login URL is rendered into | 186 If create_login_url is True the appengine's login URL is rendered into |
| 179 the template, otherwise the logout URL. | 187 the template, otherwise the logout URL. |
| 180 """ | 188 """ |
| 181 def __init__(self, create_login_url, redirect): | 189 def __init__(self, create_login_url, redirect): |
| 182 self.redirect = redirect | 190 self.redirect = redirect |
| 183 self.create_login_url = create_login_url | 191 self.create_login_url = create_login_url |
| 184 | 192 |
| 185 def render(self, context): | 193 def render(self, context): |
| 186 if self.create_login_url: | 194 if self.create_login_url: |
| 187 return users.create_login_url(self.redirect) | 195 return users.create_login_url(self.redirect) |
| 188 else: | 196 else: |
| 189 return users.create_logout_url(self.redirect) | 197 return users.create_logout_url(self.redirect) |
| 198 | |
| 190 | 199 |
|
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
| |
| 191 def auth_login_urls(parser, token): | 200 def auth_login_urls(parser, token): |
| 192 """Template tag registered as 'auth_login_url' and 'auth_logout_url' | 201 """Template tag registered as 'auth_login_url' and 'auth_logout_url' |
| 193 when the module is imported. | 202 when the module is imported. |
| 194 | 203 |
| 195 Both tags take an optional argument that specifies the redirect URL and | 204 Both tags take an optional argument that specifies the redirect URL and |
| 196 defaults to '/'. | 205 defaults to '/'. |
| 197 """ | 206 """ |
| 198 bits = list(token.split_contents()) | 207 bits = list(token.split_contents()) |
| 199 if len(bits) == 2: | 208 if len(bits) == 2: |
| 200 redirect = bits[1] | 209 redirect = bits[1] |
| 201 else: | 210 else: |
| 202 redirect = "/" | 211 redirect = "/" |
| 203 login = bits[0] == "auth_login_url" | 212 login = bits[0] == "auth_login_url" |
| 204 return AuthLoginUrlsNode(login, redirect) | 213 return AuthLoginUrlsNode(login, redirect) |
| 205 register.tag("auth_login_url", auth_login_urls) | 214 register.tag("auth_login_url", auth_login_urls) |
| 206 register.tag("auth_logout_url", auth_login_urls) | 215 register.tag("auth_logout_url", auth_login_urls) |
| LEFT | RIGHT |