diff --git a/fas/fas/client.py b/fas/fas/client.py index 3b13981..36e18d1 100644 --- a/fas/fas/client.py +++ b/fas/fas/client.py @@ -177,9 +177,13 @@ class BaseClient(object): if auth: req.add_header('Cookie', self.session.output(attrs=[], - header='').strip()) + header='').strip()) + elif self._sessionCookie: + # If the cookie exists, send it so that visit tracking works. + req.add_header('Cookie', self._sessionCookie.output(attrs=[], + header='').strip()) try: - response = urllib2.urlopen(req).read() + response = urllib2.urlopen(req) except urllib2.HTTPError, e: if e.msg == 'Forbidden': if (inspect.currentframe().f_back.f_code != @@ -195,8 +199,14 @@ class BaseClient(object): log.error(e) raise ServerError, str(e) + # In case the server returned a new session cookie to us try: - data = simplejson.loads(response) + self._sessionCookie.load(response.headers['set-cookie']) + except KeyError: + pass + + try: + data = simplejson.load(response) except Exception, e: regex = re.compile('(.*)') match = regex.search(response) diff --git a/fas/fas/jsonfasvisit.py b/fas/fas/jsonfasvisit.py new file mode 100644 index 0000000..0bdd38a --- /dev/null +++ b/fas/fas/jsonfasvisit.py @@ -0,0 +1,82 @@ +''' +This plugin provides integration with the Fedora Account System using JSON +calls to the account system server. +''' + +import Cookie + +from datetime import datetime + +from sqlalchemy import * +from sqlalchemy.orm import class_mapper + +from turbogears import config +from turbogears.visit.api import BaseVisitManager, Visit +from turbogears.database import get_engine, metadata, session, mapper +from turbogears.util import load_class + +# Once this works, propogate the changes back to python-fedora and import as +# from fedora.tg.client import BaseClient +from client import BaseClient + +import gettext +t = gettext.translation('python-fedora', '/usr/share/locale', fallback=True) +_ = t.ugettext + +import logging +log = logging.getLogger("turbogears.identity.savisit") + +class JsonFasVisitManager(BaseClient): + ''' + This proxies visit requests to the Account System Server running remotely. + + We don't need to worry about threading and other concerns because our proxy + doesn't cause any asynchronous calls. + ''' + fasURL = config.get('fas.url', 'https://admin.fedoraproject.org/admin/fas') + cookieName = config.get('visit.cookie.name', 'tg-visit') + + def __init__(self, timeout, debug=None): + super(JsonFasVisitManager,self).__init__(self.fasURL, debug=debug) + + def create_model(self): + ''' + Create the Visit table if it doesn't already exist + ''' + # Not needed as the visit tables reside remotely in the FAS2 database. + pass + + def new_visit_with_key(self, visit_key): + # Hit any URL in fas2 with the visit_key set. That will call the + # new_visit method in fas2 + self._sessionCookie = Cookie.SimpleCookie() + self._sessionCookie[self.cookieName] = visit_key + data = self.send_request('', auth=True) + return Visit(self._sessionCookie[self.cookieName].value, True) + + def visit_for_key(self, visit_key): + ''' + Return the visit for this key or None if the visit doesn't exist or has + expired. + ''' + # Hit any URL in fas2 with the visit_key set. That will call the + # new_visit method in fas2 + self._sessionCookie = Cookie.SimpleCookie() + self._sessionCookie[self.cookieName] = visit_key + data = self.send_request('', auth=True) + # Knowing what happens in turbogears/visit/api.py when this is called, + # we can shortcircuit this step and avoid a round trip to the FAS + # server. + # if visit_key != self._sessionCookie[self.cookieName].value: + # # visit has expired + # return None + # # Hitting FAS has already updated the visit. + # return Visit(visit_key, False) + if visit_key != self._sessionCookie[self.cookieName].value: + return Visit(self._sessionCookie[self.cookieName].value, True) + else: + return Visit(visit_key, False) + + def update_queued_visits(self, queue): + # Let the visit_manager on the FAS server manage this + pass