| LEFT | RIGHT |
| 1 # Copyright 2008 Google Inc. | 1 # Copyright 2008 Google Inc. |
| 2 # | 2 # |
| 3 # Licensed under the Apache License, Version 2.0 (the "License"); | 3 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 # 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. |
| 5 # You may obtain a copy of the License at | 5 # You may obtain a copy of the License at |
| 6 # | 6 # |
| 7 # http://www.apache.org/licenses/LICENSE-2.0 | 7 # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 # | 8 # |
| 9 # Unless required by applicable law or agreed to in writing, software | 9 # Unless required by applicable law or agreed to in writing, software |
| 10 # distributed under the License is distributed on an "AS IS" BASIS, | 10 # distributed under the License is distributed on an "AS IS" BASIS, |
| 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 # See the License for the specific language governing permissions and | 12 # See the License for the specific language governing permissions and |
| 13 # limitations under the License. | 13 # limitations under the License. |
| 14 | 14 |
| 15 """ | 15 """ |
| 16 Authentication module that mimics the behavior of Django's authentication | 16 Authentication module that mimics the behavior of Django's authentication |
| 17 implementation. | 17 implementation. |
| 18 | 18 |
| 19 Limitations: | 19 Limitations: |
| 20 - all user permissions methods are not available | 20 - all user permissions methods are not available |
| 21 """ | 21 """ |
| 22 | 22 |
| 23 from datetime import datetime | 23 from datetime import datetime |
| 24 import urllib | 24 import urllib |
| 25 | 25 |
| 26 from django.db.models.manager import EmptyManager | 26 from django.db.models.manager import EmptyManager |
| 27 from django.http import HttpResponseRedirect | 27 from django.http import HttpResponseRedirect |
| 28 from django.template import Node | 28 from django.template import Node |
| 29 from django.utils.encoding import smart_str | 29 from django.utils.encoding import smart_str |
| 30 | 30 |
| 31 from google.appengine.api import datastore_types | 31 from google.appengine.api import datastore_types |
| 32 from google.appengine.api import users | 32 from google.appengine.api import users |
| 33 from google.appengine.ext.db import UserProperty | 33 from google.appengine.ext.db import UserProperty |
| 34 from google.appengine.ext.webapp import template | 34 from google.appengine.ext.webapp import template |
| 35 | 35 |
| 36 from appengine_django import models | 36 from appengine_django import models |
| 37 | 37 |
| 38 register = template.create_template_register() | 38 register = template.create_template_register() |
| 39 template.register_template_library("appengine_django.auth") | 39 template.register_template_library("appengine_django.auth") |
| 40 | 40 |
| 41 | 41 |
| 42 def login_required(function): | 42 def login_required(function): |
| 43 """Implementation of Django's login_required decorator. | 43 """Implementation of Django's login_required decorator. |
| 44 | 44 |
| 45 The login redirect URL is always set to request.path | 45 The login redirect URL is always set to request.path |
| 46 """ | 46 """ |
| 47 def login_required_wrapper(request, *args, **kw): | 47 def login_required_wrapper(request, *args, **kw): |
| 48 if request.user.is_authenticated(): | 48 if request.user.is_authenticated(): |
| 49 return function(request, *args, **kw) | 49 return function(request, *args, **kw) |
| 50 return HttpResponseRedirect(users.create_login_url(request.path)) | 50 return HttpResponseRedirect(users.create_login_url(request.path)) |
| 51 return login_required_wrapper | 51 return login_required_wrapper |
| 52 | 52 |
| 53 | 53 |
| 54 class AuthLoginUrlsNode(Node): | 54 class AuthLoginUrlsNode(Node): |
| 55 """Template node that creates an appengine login or logout URL. | 55 """Template node that creates an appengine login or logout URL. |
| 56 | 56 |
| 57 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 |
| 58 the template, otherwise the logout URL. | 58 the template, otherwise the logout URL. |
| 59 """ | 59 """ |
| 60 def __init__(self, create_login_url, redirect): | 60 def __init__(self, create_login_url, redirect): |
| 61 self.redirect = redirect | 61 self.redirect = redirect |
| 62 self.create_login_url = create_login_url | 62 self.create_login_url = create_login_url |
| 63 | 63 |
| 64 def render(self, context): | 64 def render(self, context): |
| 65 if self.create_login_url: | 65 if self.create_login_url: |
| 66 return users.create_login_url(self.redirect) | 66 return users.create_login_url(self.redirect) |
| 67 else: | 67 else: |
| 68 return users.create_logout_url(self.redirect) | 68 return users.create_logout_url(self.redirect) |
| 69 | 69 |
| 70 | 70 |
| 71 def auth_login_urls(parser, token): | 71 def auth_login_urls(parser, token): |
| 72 """Template tag registered as 'auth_login_url' and 'auth_logout_url' | 72 """Template tag registered as 'auth_login_url' and 'auth_logout_url' |
| 73 when the module is imported. | 73 when the module is imported. |
| 74 | 74 |
| 75 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 |
| 76 defaults to '/'. | 76 defaults to '/'. |
| 77 """ | 77 """ |
| 78 bits = list(token.split_contents()) | 78 bits = list(token.split_contents()) |
| 79 if len(bits) == 2: | 79 if len(bits) == 2: |
| 80 redirect = bits[1] | 80 redirect = bits[1] |
| 81 else: | 81 else: |
| 82 redirect = "/" | 82 redirect = "/" |
| 83 login = bits[0] == "auth_login_url" | 83 login = bits[0] == "auth_login_url" |
| 84 return AuthLoginUrlsNode(login, redirect) | 84 return AuthLoginUrlsNode(login, redirect) |
| 85 register.tag("auth_login_url", auth_login_urls) | 85 register.tag("auth_login_url", auth_login_urls) |
| 86 register.tag("auth_logout_url", auth_login_urls) | 86 register.tag("auth_logout_url", auth_login_urls) |
| LEFT | RIGHT |