|
1 import base64 |
|
2 import cPickle as pickle |
|
3 |
|
4 from django.db import models |
|
5 from django.utils.translation import ugettext_lazy as _ |
|
6 from django.conf import settings |
|
7 from django.utils.hashcompat import md5_constructor |
|
8 |
|
9 |
|
10 class SessionManager(models.Manager): |
|
11 def encode(self, session_dict): |
|
12 """ |
|
13 Returns the given session dictionary pickled and encoded as a string. |
|
14 """ |
|
15 pickled = pickle.dumps(session_dict) |
|
16 pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest() |
|
17 return base64.encodestring(pickled + pickled_md5) |
|
18 |
|
19 def save(self, session_key, session_dict, expire_date): |
|
20 s = self.model(session_key, self.encode(session_dict), expire_date) |
|
21 if session_dict: |
|
22 s.save() |
|
23 else: |
|
24 s.delete() # Clear sessions with no data. |
|
25 return s |
|
26 |
|
27 |
|
28 class Session(models.Model): |
|
29 """ |
|
30 Django provides full support for anonymous sessions. The session |
|
31 framework lets you store and retrieve arbitrary data on a |
|
32 per-site-visitor basis. It stores data on the server side and |
|
33 abstracts the sending and receiving of cookies. Cookies contain a |
|
34 session ID -- not the data itself. |
|
35 |
|
36 The Django sessions framework is entirely cookie-based. It does |
|
37 not fall back to putting session IDs in URLs. This is an intentional |
|
38 design decision. Not only does that behavior make URLs ugly, it makes |
|
39 your site vulnerable to session-ID theft via the "Referer" header. |
|
40 |
|
41 For complete documentation on using Sessions in your code, consult |
|
42 the sessions documentation that is shipped with Django (also available |
|
43 on the Django website). |
|
44 """ |
|
45 session_key = models.CharField(_('session key'), max_length=40, |
|
46 primary_key=True) |
|
47 session_data = models.TextField(_('session data')) |
|
48 expire_date = models.DateTimeField(_('expire date')) |
|
49 objects = SessionManager() |
|
50 |
|
51 class Meta: |
|
52 db_table = 'django_session' |
|
53 verbose_name = _('session') |
|
54 verbose_name_plural = _('sessions') |
|
55 |
|
56 def get_decoded(self): |
|
57 encoded_data = base64.decodestring(self.session_data) |
|
58 pickled, tamper_check = encoded_data[:-32], encoded_data[-32:] |
|
59 if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check: |
|
60 from django.core.exceptions import SuspiciousOperation |
|
61 raise SuspiciousOperation, "User tampered with session cookie." |
|
62 try: |
|
63 return pickle.loads(pickled) |
|
64 # Unpickling can cause a variety of exceptions. If something happens, |
|
65 # just return an empty dictionary (an empty session). |
|
66 except: |
|
67 return {} |