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