| 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 {} |
|---|