# -*- 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()