1 import base64 |
1 import base64 |
2 import md5 |
|
3 import cPickle as pickle |
2 import cPickle as pickle |
4 |
3 |
5 from django.db import models |
4 from django.db import models |
6 from django.utils.translation import ugettext_lazy as _ |
5 from django.utils.translation import ugettext_lazy as _ |
7 from django.conf import settings |
6 from django.conf import settings |
|
7 from django.utils.hashcompat import md5_constructor |
|
8 |
8 |
9 |
9 class SessionManager(models.Manager): |
10 class SessionManager(models.Manager): |
10 def encode(self, session_dict): |
11 def encode(self, session_dict): |
11 "Returns the given session dictionary pickled and encoded as a string." |
12 """ |
|
13 Returns the given session dictionary pickled and encoded as a string. |
|
14 """ |
12 pickled = pickle.dumps(session_dict) |
15 pickled = pickle.dumps(session_dict) |
13 pickled_md5 = md5.new(pickled + settings.SECRET_KEY).hexdigest() |
16 pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest() |
14 return base64.encodestring(pickled + pickled_md5) |
17 return base64.encodestring(pickled + pickled_md5) |
15 |
18 |
16 def save(self, session_key, session_dict, expire_date): |
19 def save(self, session_key, session_dict, expire_date): |
17 s = self.model(session_key, self.encode(session_dict), expire_date) |
20 s = self.model(session_key, self.encode(session_dict), expire_date) |
18 if session_dict: |
21 if session_dict: |
19 s.save() |
22 s.save() |
20 else: |
23 else: |
21 s.delete() # Clear sessions with no data. |
24 s.delete() # Clear sessions with no data. |
22 return s |
25 return s |
|
26 |
23 |
27 |
24 class Session(models.Model): |
28 class Session(models.Model): |
25 """ |
29 """ |
26 Django provides full support for anonymous sessions. The session |
30 Django provides full support for anonymous sessions. The session |
27 framework lets you store and retrieve arbitrary data on a |
31 framework lets you store and retrieve arbitrary data on a |
36 |
40 |
37 For complete documentation on using Sessions in your code, consult |
41 For complete documentation on using Sessions in your code, consult |
38 the sessions documentation that is shipped with Django (also available |
42 the sessions documentation that is shipped with Django (also available |
39 on the Django website). |
43 on the Django website). |
40 """ |
44 """ |
41 session_key = models.CharField(_('session key'), max_length=40, primary_key=True) |
45 session_key = models.CharField(_('session key'), max_length=40, |
|
46 primary_key=True) |
42 session_data = models.TextField(_('session data')) |
47 session_data = models.TextField(_('session data')) |
43 expire_date = models.DateTimeField(_('expire date')) |
48 expire_date = models.DateTimeField(_('expire date')) |
44 objects = SessionManager() |
49 objects = SessionManager() |
45 |
50 |
46 class Meta: |
51 class Meta: |
49 verbose_name_plural = _('sessions') |
54 verbose_name_plural = _('sessions') |
50 |
55 |
51 def get_decoded(self): |
56 def get_decoded(self): |
52 encoded_data = base64.decodestring(self.session_data) |
57 encoded_data = base64.decodestring(self.session_data) |
53 pickled, tamper_check = encoded_data[:-32], encoded_data[-32:] |
58 pickled, tamper_check = encoded_data[:-32], encoded_data[-32:] |
54 if md5.new(pickled + settings.SECRET_KEY).hexdigest() != tamper_check: |
59 if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check: |
55 from django.core.exceptions import SuspiciousOperation |
60 from django.core.exceptions import SuspiciousOperation |
56 raise SuspiciousOperation, "User tampered with session cookie." |
61 raise SuspiciousOperation, "User tampered with session cookie." |
57 try: |
62 try: |
58 return pickle.loads(pickled) |
63 return pickle.loads(pickled) |
59 # Unpickling can cause a variety of exceptions. If something happens, |
64 # Unpickling can cause a variety of exceptions. If something happens, |