Use referer too as source of transaction IDs
authorSimo Sorce <simo@redhat.com>
Mon, 12 Jan 2015 20:02:18 +0000 (15:02 -0500)
committerPatrick Uiterwijk <puiterwijk@redhat.com>
Fri, 16 Jan 2015 09:33:22 +0000 (10:33 +0100)
This allows us to use apache module that use things like ErrorDocument
directives to do internal redirects and still retain the original
transaction intact.

Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Patrick Uiterwijk <puiterwijk@redhat.com>
ipsilon/util/page.py
ipsilon/util/trans.py

index db1c145..0929961 100644 (file)
@@ -22,9 +22,11 @@ from ipsilon.util.trans import Transaction
 from urllib import unquote
 try:
     from urlparse import urlparse
+    from urlparse import parse_qs
 except ImportError:
     # pylint: disable=no-name-in-module, import-error
     from urllib.parse import urlparse
+    from urllib.parse import parse_qs
 
 
 def admin_protect(fn):
@@ -123,7 +125,18 @@ class Page(Log):
 
     def get_valid_transaction(self, provider, **kwargs):
         try:
-            return Transaction(provider, **kwargs)
+            t = Transaction(provider)
+            # Try with kwargs first
+            tid = t.find_tid(kwargs)
+            if not tid:
+                # If no TID yet See if we have it in a referer
+                if 'referer' in cherrypy.request.headers:
+                    r = urlparse(unquote(cherrypy.request.headers['referer']))
+                    if r.query:
+                        tid = t.find_tid(parse_qs(r.query))
+                if not tid:
+                    t.create_tid()
+            return t
         except ValueError:
             msg = 'Transaction expired, or cookies not available'
             raise cherrypy.HTTPError(401, msg)
index 8d4be14..5ac3e42 100644 (file)
@@ -17,18 +17,36 @@ class Transaction(Log):
         self.transaction_id = None
         self._ts = TranStore()
         self.cookie = None
+
+        # Backwards compat,
+        # if arguments are passed find or get new transaction
+        if kwargs:
+            self.find_tid(kwargs)
+            if not self.transaction_id:
+                self.create_tid()
+
+    def find_tid(self, kwargs):
         tid = kwargs.get(TRANSID)
         if tid:
+            # If more than one only pick the first
+            if isinstance(tid, list):
+                tid = tid[0]
             self.transaction_id = tid
             data = self.retrieve()
             if data and 'provider' in data:
                 self.provider = data['provider']
             self._get_cookie(data)
-        else:
-            data = {'provider': self.provider,
-                    'origintime': str(datetime.now())}
-            self.transaction_id = self._ts.new_unique_data(TRANSTABLE, data)
-            self._set_cookie()
+            self.debug('Transaction: %s %s' % (self.provider,
+                                               self.transaction_id))
+            return tid
+
+        return None
+
+    def create_tid(self):
+        data = {'provider': self.provider,
+                'origintime': str(datetime.now())}
+        self.transaction_id = self._ts.new_unique_data(TRANSTABLE, data)
+        self._set_cookie()
         self.debug('Transaction: %s %s' % (self.provider,
                                            self.transaction_id))