diff --git a/mongoengine/django/__init__.py b/mongoengine/django/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/mongoengine/django/auth.py b/mongoengine/django/auth.py new file mode 100644 index 00000000..c9180596 --- /dev/null +++ b/mongoengine/django/auth.py @@ -0,0 +1,78 @@ +from mongoengine import * + +from django.utils.hashcompat import md5_constructor, sha_constructor +from django.utils.encoding import smart_str +from django.contrib.auth.models import AnonymousUser + +import datetime + +REDIRECT_FIELD_NAME = 'next' + +def get_hexdigest(algorithm, salt, raw_password): + raw_password, salt = smart_str(raw_password), smart_str(salt) + if algorithm == 'md5': + return md5_constructor(salt + raw_password).hexdigest() + elif algorithm == 'sha1': + return sha_constructor(salt + raw_password).hexdigest() + raise ValueError('Got unknown password algorithm type in password') + + +class User(Document): + """A User document that aims to mirror most of the API specified by Django + at http://docs.djangoproject.com/en/dev/topics/auth/#users + """ + username = StringField(max_length=30, required=True) + first_name = StringField(max_length=30) + last_name = StringField(max_length=30) + email = StringField() + password = StringField(max_length=128) + is_staff = BooleanField(default=False) + is_active = BooleanField(default=True) + is_superuser = BooleanField(default=False) + last_login = DateTimeField(default=datetime.datetime.now) + + def get_full_name(self): + full_name = u'%s %s' % (self.first_name or '', self.last_name or '') + return full_name.strip() + + def is_anonymous(self): + return False + + def is_authenticated(self): + return True + + def set_password(self, raw_password): + from random import random + algo = 'sha1' + salt = get_hexdigest(algo, str(random()), str(random()))[:5] + hash = get_hexdigest(algo, salt, raw_password) + self.password = '%s$%s$%s' % (algo, salt, hash) + + def check_password(self, raw_password): + algo, salt, hash = self.password.split('$') + return hash == get_hexdigest(algo, salt, raw_password) + + +class MongoEngineBackend(object): + """Authenticate using MongoEngine and mongoengine.django.auth.User. + """ + + def authenticate(self, username=None, password=None): + user = User.objects(username=username).first() + if user: + if password and user.check_password(password): + return user + return None + + def get_user(self, user_id): + return User.objects.with_id(user_id) + + +def get_user(userid): + """Returns a User object from an id (User.id). Django's equivalent takes + request, but taking an id instead leaves it up to the developer to store + the id in any way they want (session, signed cookie, etc.) + """ + if not userid: + return AnonymousUser() + return MongoEngineBackend().get_user(userid) or AnonymousUser()