Skip to content

Instantly share code, notes, and snippets.

@silkentrance
Created May 15, 2015 13:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save silkentrance/c5543afc2883b107243f to your computer and use it in GitHub Desktop.
Save silkentrance/c5543afc2883b107243f to your computer and use it in GitHub Desktop.
Django 1.8.1 Auth Integration for Mongoengine <0.9.0
# adapted from django.contrib.auth
#
# simply import the here provided login() to make mongoengine work with Django 1.8.1
from django.conf import settings
from django.middleware.csrf import rotate_token
from django.utils.translation import LANGUAGE_SESSION_KEY
from django.contrib.auth.signals import user_logged_in, user_logged_out, user_login_failed
from django.contrib.auth import SESSION_KEY, BACKEND_SESSION_KEY, HASH_SESSION_KEY, REDIRECT_FIELD_NAME, get_user_model, load_backend
from bson import ObjectId
from django.utils.functional import SimpleLazyObject
def _get_user_session_key(request):
"""
Drop in replacement for django.contrib.auth._get_user_session_key as it also
access _meta.pk which is not present in mongoengine.django.auth.
"""
return ObjectId(request.session.get(SESSION_KEY))
def login(request, user):
"""
Drop in replacement for django.contrib.auth.login as it will no longer work
with mongoengine.djang.auth since version 1.8 of django.
"""
session_auth_hash = ''
if user is None:
user = request.user
if hasattr(user, 'get_session_auth_hash'):
session_auth_hash = user.get_session_auth_hash()
if SESSION_KEY in request.session:
if _get_user_session_key(request) != user.pk or (
session_auth_hash and
request.session.get(HASH_SESSION_KEY) != session_auth_hash):
# To avoid reusing another user's session, create a new, empty
# session if the existing session corresponds to a different
# authenticated user.
request.session.flush()
else:
request.session.cycle_key()
request.session[SESSION_KEY] = str(getattr(user, user._meta['id_field']))
request.session[BACKEND_SESSION_KEY] = user.backend
request.session[HASH_SESSION_KEY] = session_auth_hash
if hasattr(request, 'user'):
request.user = user
rotate_token(request)
user_logged_in.send(sender=user.__class__, request=request, user=user)
def _get_user(request):
"""
Returns the user model instance associated with the given request session.
If no user is retrieved an instance of `AnonymousUser` is returned.
"""
from django.contrib.auth.models import AnonymousUser
user = None
try:
user_id = _get_user_session_key(request)
backend_path = request.session[BACKEND_SESSION_KEY]
except KeyError:
pass
else:
if backend_path in settings.AUTHENTICATION_BACKENDS:
backend = load_backend(backend_path)
user = backend.get_user(user_id)
# Verify the session
if ('django.contrib.auth.middleware.SessionAuthenticationMiddleware'
in settings.MIDDLEWARE_CLASSES and hasattr(user, 'get_session_auth_hash')):
session_hash = request.session.get(HASH_SESSION_KEY)
session_hash_verified = session_hash and constant_time_compare(
session_hash,
user.get_session_auth_hash()
)
if not session_hash_verified:
request.session.flush()
user = None
return user or AnonymousUser()
def get_user(request):
if not hasattr(request, '_cached_user'):
request._cached_user = _get_user(request)
return request._cached_user
class AuthenticationMiddleware(object):
def process_request(self, request):
assert hasattr(request, 'session'), (
"The Django authentication middleware requires session middleware "
"to be installed. Edit your MIDDLEWARE_CLASSES setting to insert "
"'django.contrib.sessions.middleware.SessionMiddleware' before "
"'django.contrib.auth.middleware.AuthenticationMiddleware'."
)
request.user = SimpleLazyObject(lambda: get_user(request))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment