Mercurial > public > sg101
view wiki/middleware.py @ 943:cf9918328c64
Haystack tweaks for Django 1.7.7.
I had to upgrade to Haystack 2.3.1 to get it to work with Django
1.7.7. I also had to update the Xapian backend. But I ran into
problems.
On my laptop anyway (Ubuntu 14.0.4), xapian gets mad when search terms
are greater than 245 chars (or something) when indexing. So I created
a custom field that would simply omit terms greater than 64 chars and
used this field everywhere I previously used a CharField.
Secondly, the custom search form was broken now. Something changed in
the Xapian backend and exact searches stopped working. Fortunately the
auto_query (which I was using originally and broke during an upgrade)
started working again. So I cut the search form back over to doing an
auto_query. I kept the form the same (3 fields) because I didn't want
to change the form and I think it's better that way.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Wed, 13 May 2015 20:25:07 -0500 |
parents | 47521d9e94bd |
children | ba3230aba90c |
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 from wiki.constants import SESSION_SET_MEMBER 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.encode('utf-8')) h.update(user.email.encode('utf-8')) 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_SET_MEMBER] = name def destroy_wiki_session(set_member, response): """Destroys the session for the external wiki application. Delete the external cookie. Deletes the member from the Redis set as this entry is no longer valid. """ response.delete_cookie(settings.WIKI_COOKIE_NAME, domain=settings.WIKI_COOKIE_DOMAIN) if set_member: conn = get_redis_connection() try: conn.zrem(settings.WIKI_REDIS_SET, set_member) except redis.RedisError: logger.error("Error deleting wiki cookie set member") class WikiMiddleware(object): """ Check for flags on the request object 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 hasattr(request, 'wiki_set_cookie'): create_wiki_session(request, response) elif hasattr(request, 'wiki_delete_cookie'): destroy_wiki_session(request.wiki_delete_cookie, response) return response