Mercurial > public > sg101
view wiki/middleware.py @ 626:a6bc1e2efa63
Created wiki app to provide integration with MoinMoin.
This commit has a working middleware & test.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Wed, 07 Nov 2012 20:17:33 -0600 |
parents | |
children | a4300639c6e7 |
line wrap: on
line source
"""Middleware for wiki integration. """ import datetime import hashlib import logging import random import string import time from django.conf import settings import redis from core.services import get_redis_connection SESSION_KEY = 'wiki_redis_key' logger = logging.getLogger(__name__) def cookie_value(user, now): """Creates the value for the external wiki cookie.""" # The key part of the cookie is just a string that would make things # difficult for a spoofer; something that can't be easily made up: h = hashlib.sha256() h.update(user.username + user.email) h.update(now.isoformat()) h.update(''.join(random.sample(string.printable, 64))) h.update(settings.SECRET_KEY) key = h.hexdigest() parts = (user.username, user.email, key) return '#'.join(parts) def create_wiki_session(request, response): """Sets up the session for the external wiki application. Creates the external cookie for the Wiki. Updates the Redis set so the Wiki can verify the cookie. """ now = datetime.datetime.utcnow() value = cookie_value(request.user, now) response.set_cookie(settings.WIKI_COOKIE_NAME, value=value, max_age=settings.WIKI_COOKIE_AGE, domain=settings.WIKI_COOKIE_DOMAIN) # Update a sorted set in Redis with a hash of our cookie and a score # of the current time as a timestamp. This allows us to delete old # entries by score periodically. To verify the cookie, the external wiki # application computes a hash of the cookie value and checks to see if # it is in our Redis set. h = hashlib.sha256() h.update(value) name = h.hexdigest() score = time.mktime(now.utctimetuple()) conn = get_redis_connection() try: conn.zadd(settings.WIKI_REDIS_SET, score, name) except redis.RedisError: logger.error("Error adding wiki cookie key") # Store the set member name in the session so we can delete it when the # user logs out: request.session[SESSION_KEY] = name def destroy_wiki_session(request, response): """Destroys the session for the external wiki application. Delete the external cookie. Deletes the key from the Redis set as this entry is no longer valid. """ response.delete_cookie(settings.WIKI_COOKIE_NAME, domain=settings.WIKI_COOKIE_DOMAIN) try: key = request.session[SESSION_KEY] except KeyError: # Hmmm, perhaps user logged in before this application was installed. return conn = get_redis_connection() try: conn.zrem(settings.WIKI_REDIS_SET, key) except redis.RedisError: logger.error("Error deleting wiki cookie key") del request.session[SESSION_KEY] class WikiMiddleware(object): """ Check for flags set in the session to determine when to set or delete an external cookie for the wiki application. When creating a cookie, also set an entry in Redis that the wiki application can validate to prevent spoofing. """ def process_response(self, request, response): if request.session.get('wiki_set_cookie', False): del request.session['wiki_set_cookie'] create_wiki_session(request, response) elif request.session.get('wiki_delete_cookie', False): del request.session['wiki_delete_cookie'] destroy_wiki_session(request, response) return response