Merge branch 'master' into dev

This commit is contained in:
Ross Lawley 2012-03-24 19:07:17 +00:00
commit 46e088d379
7 changed files with 22 additions and 31 deletions

View File

@ -98,4 +98,4 @@ that much better:
* Chris Williams * Chris Williams
* Robert Kajic * Robert Kajic
* Jacob Peddicord * Jacob Peddicord
* Adam Parrish * Nils Hasenbanck

View File

@ -2,8 +2,9 @@
Changelog Changelog
========= =========
Changes in 0.6.X Changes in 0.6.3
================ ================
- Updated sessions for Django 1.4
- Bug fix for updates where listfields contain embedded documents - Bug fix for updates where listfields contain embedded documents
- Bug fix for collection naming and mixins - Bug fix for collection naming and mixins

View File

@ -2,19 +2,21 @@
Using MongoEngine with Django Using MongoEngine with Django
============================= =============================
.. note :: Updated to support Django 1.4
Connecting Connecting
========== ==========
In your **settings.py** file, ignore the standard database settings (unless you In your **settings.py** file, ignore the standard database settings (unless you
also plan to use the ORM in your project), and instead call also plan to use the ORM in your project), and instead call
:func:`~mongoengine.connect` somewhere in the settings module. :func:`~mongoengine.connect` somewhere in the settings module.
Authentication Authentication
============== ==============
MongoEngine includes a Django authentication backend, which uses MongoDB. The MongoEngine includes a Django authentication backend, which uses MongoDB. The
:class:`~mongoengine.django.auth.User` model is a MongoEngine :class:`~mongoengine.django.auth.User` model is a MongoEngine
:class:`~mongoengine.Document`, but implements most of the methods and :class:`~mongoengine.Document`, but implements most of the methods and
attributes that the standard Django :class:`User` model does - so the two are attributes that the standard Django :class:`User` model does - so the two are
moderately compatible. Using this backend will allow you to store users in moderately compatible. Using this backend will allow you to store users in
MongoDB but still use many of the Django authentication infrastucture (such as MongoDB but still use many of the Django authentication infrastucture (such as
the :func:`login_required` decorator and the :func:`authenticate` function). To the :func:`login_required` decorator and the :func:`authenticate` function). To
enable the MongoEngine auth backend, add the following to you **settings.py** enable the MongoEngine auth backend, add the following to you **settings.py**
@ -24,7 +26,7 @@ file::
'mongoengine.django.auth.MongoEngineBackend', 'mongoengine.django.auth.MongoEngineBackend',
) )
The :mod:`~mongoengine.django.auth` module also contains a The :mod:`~mongoengine.django.auth` module also contains a
:func:`~mongoengine.django.auth.get_user` helper function, that takes a user's :func:`~mongoengine.django.auth.get_user` helper function, that takes a user's
:attr:`id` and returns a :class:`~mongoengine.django.auth.User` object. :attr:`id` and returns a :class:`~mongoengine.django.auth.User` object.
@ -49,9 +51,9 @@ Storage
======= =======
With MongoEngine's support for GridFS via the :class:`~mongoengine.FileField`, With MongoEngine's support for GridFS via the :class:`~mongoengine.FileField`,
it is useful to have a Django file storage backend that wraps this. The new it is useful to have a Django file storage backend that wraps this. The new
storage module is called :class:`~mongoengine.django.storage.GridFSStorage`. storage module is called :class:`~mongoengine.django.storage.GridFSStorage`.
Using it is very similar to using the default FileSystemStorage.:: Using it is very similar to using the default FileSystemStorage.::
from mongoengine.django.storage import GridFSStorage from mongoengine.django.storage import GridFSStorage
fs = GridFSStorage() fs = GridFSStorage()

View File

@ -12,7 +12,7 @@ from signals import *
__all__ = (document.__all__ + fields.__all__ + connection.__all__ + __all__ = (document.__all__ + fields.__all__ + connection.__all__ +
queryset.__all__ + signals.__all__) queryset.__all__ + signals.__all__)
VERSION = (0, 6, 2) VERSION = (0, 6, 3)
def get_version(): def get_version():

View File

@ -1,23 +1,14 @@
from mongoengine import * from mongoengine import *
from django.utils.hashcompat import md5_constructor, sha_constructor
from django.utils.encoding import smart_str from django.utils.encoding import smart_str
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
from django.contrib.auth.hashers import check_password, make_password
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
import datetime import datetime
REDIRECT_FIELD_NAME = 'next' 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): class User(Document):
"""A User document that aims to mirror most of the API specified by Django """A User document that aims to mirror most of the API specified by Django
at http://docs.djangoproject.com/en/dev/topics/auth/#users at http://docs.djangoproject.com/en/dev/topics/auth/#users
@ -34,7 +25,7 @@ class User(Document):
email = EmailField(verbose_name=_('e-mail address')) email = EmailField(verbose_name=_('e-mail address'))
password = StringField(max_length=128, password = StringField(max_length=128,
verbose_name=_('password'), verbose_name=_('password'),
help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>.")) help_text=_("Use '[algo]$[iterations]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."))
is_staff = BooleanField(default=False, is_staff = BooleanField(default=False,
verbose_name=_('staff status'), verbose_name=_('staff status'),
help_text=_("Designates whether the user can log into this admin site.")) help_text=_("Designates whether the user can log into this admin site."))
@ -75,11 +66,7 @@ class User(Document):
assigning to :attr:`~mongoengine.django.auth.User.password` as the assigning to :attr:`~mongoengine.django.auth.User.password` as the
password is hashed before storage. password is hashed before storage.
""" """
from random import random self.password = make_password(raw_password)
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)
self.save() self.save()
return self return self
@ -89,8 +76,7 @@ class User(Document):
:attr:`~mongoengine.django.auth.User.password` as the password is :attr:`~mongoengine.django.auth.User.password` as the password is
hashed before storage. hashed before storage.
""" """
algo, salt, hash = self.password.split('$') return check_password(raw_password, self.password)
return hash == get_hexdigest(algo, salt, raw_password)
@classmethod @classmethod
def create_user(cls, username, password, email=None): def create_user(cls, username, password, email=None):

View File

@ -41,7 +41,7 @@ class SessionStore(SessionBase):
def create(self): def create(self):
while True: while True:
self.session_key = self._get_new_session_key() self._session_key = self._get_new_session_key()
try: try:
self.save(must_create=True) self.save(must_create=True)
except CreateError: except CreateError:
@ -51,7 +51,9 @@ class SessionStore(SessionBase):
return return
def save(self, must_create=False): def save(self, must_create=False):
s = MongoSession(session_key=self.session_key) if self._session_key is None:
self.create()
s = MongoSession(session_key=self._session_key)
s.session_data = self.encode(self._get_session(no_load=must_create)) s.session_data = self.encode(self._get_session(no_load=must_create))
s.expire_date = self.get_expiry_date() s.expire_date = self.get_expiry_date()
try: try:

View File

@ -5,7 +5,7 @@
%define srcname mongoengine %define srcname mongoengine
Name: python-%{srcname} Name: python-%{srcname}
Version: 0.6.2 Version: 0.6.3
Release: 1%{?dist} Release: 1%{?dist}
Summary: A Python Document-Object Mapper for working with MongoDB Summary: A Python Document-Object Mapper for working with MongoDB