Skip to content
This repository has been archived by the owner on Oct 30, 2018. It is now read-only.

Commit

Permalink
Merge branch 'cache-auth-user'
Browse files Browse the repository at this point in the history
  • Loading branch information
peterbe committed Jul 18, 2014
2 parents fb58c50 + 1a04205 commit a71978a
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 1 deletion.
25 changes: 25 additions & 0 deletions airmozilla/auth/backend.py
@@ -0,0 +1,25 @@
from django_browserid.auth import BrowserIDBackend
from django.core.cache import cache


class AirmozillaBrowserIDBackend(BrowserIDBackend):
"""The only difference between this backend and the default
BrowserIDBackend backend is that this one uses the cache framework
to remember the user.
The cache is invalidated by a post_save signal in this app's models.py.
"""

def get_user(self, user_id):
if not user_id:
return None
cache_key = 'user:%s' % (user_id,)
user = cache.get(cache_key)
if user:
return user
try:
user = self.User.objects.get(pk=user_id)
cache.set(cache_key, user, 60 * 60)
return user
except self.User.DoesNotExist:
return None
12 changes: 11 additions & 1 deletion airmozilla/auth/models.py
@@ -1 +1,11 @@
# delete me
from django.core.cache import cache
from django.dispatch import receiver
from django.contrib.auth.models import User
from django.db import models


@receiver(models.signals.post_save, sender=User)
def invalidate_user_cache(sender, instance, **kwargs):
if instance.id:
cache_key = 'user:%s' % (instance.id,)
cache.delete(cache_key)
43 changes: 43 additions & 0 deletions airmozilla/auth/tests/test_backend.py
@@ -0,0 +1,43 @@
from django.test import TestCase
from django.contrib.auth.models import User

from nose.tools import eq_

from airmozilla.auth.backend import AirmozillaBrowserIDBackend


class TestBackend(TestCase):

# def setUp(self):
# super(TestViews, self).setUp()

def shortDescription(self):
# Stop nose using the test docstring and instead the test method name.
pass

def test_getuser_none(self):
backend = AirmozillaBrowserIDBackend()
eq_(backend.get_user(0), None)
eq_(backend.get_user(None), None)

def test_getuser_known(self):
backend = AirmozillaBrowserIDBackend()
user = User.objects.create(username='richard')
eq_(backend.get_user(user.id), user)
# a second time and it should be coming from the cache
eq_(backend.get_user(user.id), user)
# change the user and it should be reflected
user.username = 'zandr'
user.save()
eq_(backend.get_user(user.id).username, 'zandr')
# a second time
eq_(backend.get_user(user.id).username, 'zandr')

def test_getuser_deleted(self):
backend = AirmozillaBrowserIDBackend()
user = User.objects.create(username='richard')
eq_(backend.get_user(user.id), user)
# twice
eq_(backend.get_user(user.id), user)
user.delete()
eq_(backend.get_user(user.id), None)
4 changes: 4 additions & 0 deletions airmozilla/settings/base.py
Expand Up @@ -51,6 +51,10 @@
# BrowserID configuration
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
# this is the first one that matters
'%s.auth.backend.AirmozillaBrowserIDBackend' % PROJECT_MODULE,
# but we're keeping this in case people still have sessions
# whose backend cookie points to this class path
'django_browserid.auth.BrowserIDBackend',
]

Expand Down

0 comments on commit a71978a

Please sign in to comment.