From: Thierry Parmentelat Date: Tue, 31 Mar 2015 13:57:52 +0000 (+0200) Subject: SessionCache is a cleaner and more robust mechanism for caching material attached... X-Git-Tag: myslice-1.3~45^2~3 X-Git-Url: http://git.onelab.eu/?p=myslice.git;a=commitdiff_plain;h=6c38e861f92b75716f40ed9d8f15af824d1ec19c SessionCache is a cleaner and more robust mechanism for caching material attached to a session across requests --- diff --git a/localauth/manifoldbackend.py b/localauth/manifoldbackend.py index 4889d34f..c2899e9d 100644 --- a/localauth/manifoldbackend.py +++ b/localauth/manifoldbackend.py @@ -7,6 +7,8 @@ from manifold.core.query import Query from myslice.settings import config, logger, DEBUG +from unfold.sessioncache import SessionCache + # Name my backend 'ManifoldBackend' class ManifoldBackend: @@ -34,7 +36,8 @@ class ManifoldBackend: logger.debug("SESSION : {}".format(session)) # Change to session authentication - api.auth = {'AuthMethod': 'session', 'session': session['session']} + session_auth = {'AuthMethod': 'session', 'session': session['session']} + api.auth = session_auth self.api = api # Get account details @@ -49,7 +52,8 @@ class ManifoldBackend: #logger.info("{} {} <{}> logged in"\ # .format(person['config']['first_name'], person['config']['last_name'], person['config']['email'])) - request.session['manifold'] = {'auth': api.auth, 'person': person, 'expires': session['expires']} + SessionCache().store_auth(request, session_auth) + except ManifoldException as e: logger.error("ManifoldException in Auth Backend: {}".format(e.manifold_result)) except Exception as e: diff --git a/manifoldapi/manifoldapi.py b/manifoldapi/manifoldapi.py index f487cb8d..2edecdd7 100644 --- a/manifoldapi/manifoldapi.py +++ b/manifoldapi/manifoldapi.py @@ -7,9 +7,10 @@ from django.contrib import messages from django.shortcuts import redirect from manifold.core.result_value import ResultValue - from manifoldresult import ManifoldResult, ManifoldCode, ManifoldException, truncate_result +from unfold.sessioncache import SessionCache + from myslice.settings import config, logger class ManifoldAPI: @@ -45,12 +46,12 @@ class ManifoldAPI: start = time.time() # the message to display - auth_message = "".format(auth) if 'AuthMethod' not in self.auth \ + auth_message = "".format(self.auth) if 'AuthMethod' not in self.auth \ else "[session]" if self.auth['AuthMethod'] == 'session' \ else "user:{}".format(self.auth['Username']) if self.auth['AuthMethod'] == 'password' \ else "anonymous" if self.auth['AuthMethod'] == 'anonymous' \ else "[???]" + "{}".format(self.auth) - end_message = "MANIFOLD {}( {}( {} ) ) with auth={} to {}"\ + end_message = "MANIFOLD <- {}( {}( {} ) ) with auth={} to {}"\ .format(methodName, args[0]['action'] or '', args[0]['object'] or '', @@ -84,15 +85,14 @@ def _execute_query(request, query, manifold_api_session_auth): manifold_api = ManifoldAPI(auth = manifold_api_session_auth) - logger.debug("MANIFOLD QUERY : {}".format(" ".join(str(query).split()))) - #logger.debug("MANIFOLD DICT : {}".format(query.to_dict())) + logger.debug("MANIFOLD -> QUERY : {}".format(" ".join(str(query).split()))) result = manifold_api.forward(query.to_dict()) if result['code'] == 2: # this is gross; at the very least we need to logout() # but most importantly there is a need to refine that test, since # code==2 does not necessarily mean an expired session # XXX only if we know it is the issue - del request.session['manifold'] + SessionCache().end_session(request) # Flush django session request.session.flush() #raise Exception, 'Error running query: {}'.format(result) @@ -106,14 +106,14 @@ def _execute_query(request, query, manifold_api_session_auth): return result['value'] def execute_query(request, query): - if not 'manifold' in request.session or not 'auth' in request.session['manifold']: + + manifold_api_session_auth = SessionCache().get_auth(request) + if not manifold_api_session_auth: request.session.flush() #raise Exception, "User not authenticated" host = request.get_host() return redirect('/') - manifold_api_session_auth = request.session['manifold']['auth'] - return _execute_query(request, query, manifold_api_session_auth) def execute_admin_query(request, query): diff --git a/manifoldapi/manifoldproxy.py b/manifoldapi/manifoldproxy.py index a42e98d5..5a095bfc 100644 --- a/manifoldapi/manifoldproxy.py +++ b/manifoldapi/manifoldproxy.py @@ -12,6 +12,8 @@ from manifoldapi import ManifoldAPI from manifoldresult import ManifoldException from manifold.util.log import Log +from unfold.sessioncache import SessionCache + from myslice.settings import config, logger # register activity @@ -59,9 +61,8 @@ def proxy (request,format): admin_user, admin_password = config.manifold_admin_user_password() manifold_api_session_auth = {'AuthMethod': 'password', 'Username': admin_user, 'AuthString': admin_password} else: - if 'manifold' in request.session: - manifold_api_session_auth = request.session['manifold']['auth'] - else: + manifold_api_session_auth = SessionCache().get_auth(request) + if not manifold_api_session_auth: return HttpResponse (json.dumps({'code':0,'value':[]}), mimetype="application/json") if debug_empty and manifold_query.action.lower()=='get': diff --git a/unfold/page.py b/unfold/page.py index dbe5a7cb..f8f4eb3b 100644 --- a/unfold/page.py +++ b/unfold/page.py @@ -9,7 +9,8 @@ from django.template.loader import render_to_string from manifoldapi.metadata import MetaData from unfold.prelude import Prelude - +from unfold.sessioncache import SessionCache + from myslice.configengine import ConfigEngine from myslice.settings import logger @@ -98,24 +99,16 @@ class Page: # needs to be called explicitly and only when metadata is actually required # in particular user needs to be logged def get_metadata (self): - # look in session's cache - we don't want to retrieve this for every request - session=self.request.session - - if 'manifold' not in session: - session['manifold'] = {} - manifold = session['manifold'] - - # if cached, use it - if 'metadata' in manifold and isinstance(manifold['metadata'],MetaData): + cached_metadata = SessionCache().get_metadata(self.request) + if cached_metadata and isinstance(cached_metadata, MetaData): logger.debug("Page.get_metadata: return cached value") - return manifold['metadata'] + return cached_metadata metadata_auth = {'AuthMethod':'anonymous'} - metadata=MetaData (metadata_auth) + metadata = MetaData (metadata_auth) metadata.fetch(self.request) - # store it for next time - manifold['metadata']=metadata + SessionCache().store_metadata(self.request, metadata) logger.debug("Page.get_metadata: return new value") return metadata diff --git a/unfold/sessioncache.py b/unfold/sessioncache.py new file mode 100644 index 00000000..aff43c49 --- /dev/null +++ b/unfold/sessioncache.py @@ -0,0 +1,129 @@ +import uuid + +from manifold.util.singleton import Singleton + +from myslice.settings import logger + +# the key attached to the session object, where we store +# the uuid attached to that session in this cache +cache_key = 'cached_uuid' + +class _SessionExtension(object): + """ + This object holds all the data we need to attach to a django session object + """ + + def __init__(self): + self.metadata = None + self.auth = None + + def __repr__(self): + result = " {}".format(k,v)) + if cache_key not in session: + return + cached_uuid = session[cache_key] + if cached_uuid not in self: + return + extension = self[cached_uuid] + logger.debug("SessionCache: found extension {}".format(extension)) + logger.debug("SessionCache: ----------") + + @staticmethod + def _debug_session(session): + result = "" + result += "{} x {}".format(session, session.keys()) + if cache_key in session: + result += " <{} = {}>".format(cache_key, session[cache_key]) + return result