Use referer too as source of transaction IDs
[cascardo/ipsilon.git] / ipsilon / util / trans.py
1 # Copyright (C) 2014  Ipsilon project Contributors, for licensee see COPYING
2
3 from ipsilon.util.data import TranStore
4 from ipsilon.util.log import Log
5 from datetime import datetime
6 from ipsilon.util.cookies import SecureCookie
7
8
9 TRANSTABLE = 'transactions'
10 TRANSID = "ipsilon_transaction_id"
11
12
13 class Transaction(Log):
14
15     def __init__(self, provider, **kwargs):
16         self.provider = provider
17         self.transaction_id = None
18         self._ts = TranStore()
19         self.cookie = None
20
21         # Backwards compat,
22         # if arguments are passed find or get new transaction
23         if kwargs:
24             self.find_tid(kwargs)
25             if not self.transaction_id:
26                 self.create_tid()
27
28     def find_tid(self, kwargs):
29         tid = kwargs.get(TRANSID)
30         if tid:
31             # If more than one only pick the first
32             if isinstance(tid, list):
33                 tid = tid[0]
34             self.transaction_id = tid
35             data = self.retrieve()
36             if data and 'provider' in data:
37                 self.provider = data['provider']
38             self._get_cookie(data)
39             self.debug('Transaction: %s %s' % (self.provider,
40                                                self.transaction_id))
41             return tid
42
43         return None
44
45     def create_tid(self):
46         data = {'provider': self.provider,
47                 'origintime': str(datetime.now())}
48         self.transaction_id = self._ts.new_unique_data(TRANSTABLE, data)
49         self._set_cookie()
50         self.debug('Transaction: %s %s' % (self.provider,
51                                            self.transaction_id))
52
53     def _set_cookie(self):
54         self.cookie = SecureCookie(name=None, value=self.provider)
55         self.cookie.send()
56         cookiedata = {'cookie': self.cookie.name}
57         data = {self.transaction_id: cookiedata}
58         self._ts.save_unique_data(TRANSTABLE, data)
59
60     def _get_cookie(self, data=None):
61         if data is None:
62             data = self.retrieve()
63         if data is None or 'cookie' not in data:
64             raise ValueError('Cookie name not available')
65         self.cookie = SecureCookie(data['cookie'])
66         self.cookie.receive()
67         if self.cookie.value is None:
68             raise ValueError('Missing or invalid cookie')
69
70     def _del_cookie(self):
71         if self.cookie:
72             self.cookie.delete()
73
74     def wipe(self):
75         if not self.transaction_id:
76             return
77         self._ts.del_unique_data(TRANSTABLE, self.transaction_id)
78         self._del_cookie()
79         self.transaction_id = None
80
81     def store(self, data):
82         savedata = {self.transaction_id: data}
83         self._ts.save_unique_data(TRANSTABLE, savedata)
84
85     def retrieve(self):
86         data = self._ts.get_unique_data(TRANSTABLE,
87                                         uuidval=self.transaction_id)
88         return data.get(self.transaction_id) or dict()
89
90     def get_GET_arg(self):
91         return "%s=%s" % (TRANSID, self.transaction_id)
92
93     def get_POST_tuple(self):
94         return (TRANSID, self.transaction_id)