ctran / appengine-starter

A starter application template for the Google App Engine platform

This URL has Read+Write access

appengine-starter / auth.py
100644 82 lines (64 sloc) 3.085 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# -*- coding: utf-8 -*-
from gettext import gettext as _
 
from google.appengine.ext import db
from google.appengine.api import users
 
def role_required(role = 'user'):
  """A decorator to require that a user be logged in to access a handler.
 
To use it, decorate your get() method like this:
 
@role_required('user')
def get(self):
user = users.GetCurrentUser(self)
self.response.out.write('Hello, ' + user.nickname())
 
We will redirect to a login page if the user is not logged in. We always
redirect to the request URI for GET requests. Otherwise returns a 403.
"""
  def wrapper(handler_method):
    def check_login(self, *args, **kwargs):
        user = users.get_current_user()
        if not user:
            if self.request.method != 'GET':
                self.error(403)
            else:
                self.redirect(users.create_login_url(self.request.uri))
        elif role == "user" or (role == "admin" and
                                users.is_current_user_admin()):
            handler_method(self, *args, **kwargs)
        else:
            if self.request.method == 'GET':
                self.redirect("/403.html") # Some unauthorized feedback
            else:
                self.error(403) # User didn't meet role.
    return check_login
    
  return wrapper
  
UNUSABLE_PASSWORD = '!' # This will never be a valid hash
 
class UserTraits(db.Model):
  last_login = db.DateTimeProperty(verbose_name=_('last login'))
  date_joined = db.DateTimeProperty(auto_now_add=True, verbose_name=_('date joined'))
 
  is_active = db.BooleanProperty(default=False, verbose_name=_('active'))
  is_banned = db.BooleanProperty(default=False, verbose_name=_('banned status'))
 
  is_staff = db.BooleanProperty(default=False, verbose_name=_('staff status'))
  is_superuser = db.BooleanProperty(default=False, verbose_name=_('superuser status'))
  password = db.StringProperty(default=UNUSABLE_PASSWORD, verbose_name=_('password'))
 
  def get_full_name(self):
      # Provide a default method that expects first_name and last_name to
      # be defined. Subclasses can still override the default behavior.
      return u' '.join((self.first_name, self.last_name))
 
class EmailUserTraits(UserTraits):
  def email_user(self, subject, message, from_email=None):
      """Sends an e-mail to this user."""
      from django.core.mail import send_mail
      send_mail(subject, message, from_email, [self.email])
  
  def __unicode__(self):
      return self.email
 
class EmailUser(EmailUserTraits):
  email = db.EmailProperty(required=True, verbose_name=_('e-mail address'))
 
  def __unicode__(self):
      return unicode(self.email)
 
class User(EmailUserTraits):
  """Default User class that mimics Django's User class."""
  username = db.StringProperty(required=True, verbose_name=_('username'))
  email = db.EmailProperty(verbose_name=_('e-mail address'))
  first_name = db.StringProperty(verbose_name=_('first name'))
  last_name = db.StringProperty(verbose_name=_('last name'))
  
  def __unicode__(self):
      return self.get_full_name()