django.contrib.sessions.backends.base: 160 total statements, 0.0% covered

Generated: Wed 2013-03-13 10:33 CET

Source file: /media/Envs/Envs/filer-gallery/lib/python2.7/site-packages/django/contrib/sessions/backends/base.py

Stats: 0 executed, 149 missed, 11 excluded, 120 ignored

  1. import base64
  2. import time
  3. from datetime import datetime, timedelta
  4. try:
  5. import cPickle as pickle
  6. except ImportError:
  7. import pickle
  8. from django.conf import settings
  9. from django.core.exceptions import SuspiciousOperation
  10. from django.utils.crypto import constant_time_compare
  11. from django.utils.crypto import get_random_string
  12. from django.utils.crypto import salted_hmac
  13. from django.utils import timezone
  14. class CreateError(Exception):
  15. """
  16. Used internally as a consistent exception type to catch from save (see the
  17. docstring for SessionBase.save() for details).
  18. """
  19. pass
  20. class SessionBase(object):
  21. """
  22. Base class for all Session classes.
  23. """
  24. TEST_COOKIE_NAME = 'testcookie'
  25. TEST_COOKIE_VALUE = 'worked'
  26. def __init__(self, session_key=None):
  27. self._session_key = session_key
  28. self.accessed = False
  29. self.modified = False
  30. def __contains__(self, key):
  31. return key in self._session
  32. def __getitem__(self, key):
  33. return self._session[key]
  34. def __setitem__(self, key, value):
  35. self._session[key] = value
  36. self.modified = True
  37. def __delitem__(self, key):
  38. del self._session[key]
  39. self.modified = True
  40. def get(self, key, default=None):
  41. return self._session.get(key, default)
  42. def pop(self, key, *args):
  43. self.modified = self.modified or key in self._session
  44. return self._session.pop(key, *args)
  45. def setdefault(self, key, value):
  46. if key in self._session:
  47. return self._session[key]
  48. else:
  49. self.modified = True
  50. self._session[key] = value
  51. return value
  52. def set_test_cookie(self):
  53. self[self.TEST_COOKIE_NAME] = self.TEST_COOKIE_VALUE
  54. def test_cookie_worked(self):
  55. return self.get(self.TEST_COOKIE_NAME) == self.TEST_COOKIE_VALUE
  56. def delete_test_cookie(self):
  57. del self[self.TEST_COOKIE_NAME]
  58. def _hash(self, value):
  59. key_salt = "django.contrib.sessions" + self.__class__.__name__
  60. return salted_hmac(key_salt, value).hexdigest()
  61. def encode(self, session_dict):
  62. "Returns the given session dictionary pickled and encoded as a string."
  63. pickled = pickle.dumps(session_dict, pickle.HIGHEST_PROTOCOL)
  64. hash = self._hash(pickled)
  65. return base64.encodestring(hash + ":" + pickled)
  66. def decode(self, session_data):
  67. encoded_data = base64.decodestring(session_data)
  68. try:
  69. # could produce ValueError if there is no ':'
  70. hash, pickled = encoded_data.split(':', 1)
  71. expected_hash = self._hash(pickled)
  72. if not constant_time_compare(hash, expected_hash):
  73. raise SuspiciousOperation("Session data corrupted")
  74. else:
  75. return pickle.loads(pickled)
  76. except Exception:
  77. # ValueError, SuspiciousOperation, unpickling exceptions. If any of
  78. # these happen, just return an empty dictionary (an empty session).
  79. return {}
  80. def update(self, dict_):
  81. self._session.update(dict_)
  82. self.modified = True
  83. def has_key(self, key):
  84. return key in self._session
  85. def keys(self):
  86. return self._session.keys()
  87. def values(self):
  88. return self._session.values()
  89. def items(self):
  90. return self._session.items()
  91. def iterkeys(self):
  92. return self._session.iterkeys()
  93. def itervalues(self):
  94. return self._session.itervalues()
  95. def iteritems(self):
  96. return self._session.iteritems()
  97. def clear(self):
  98. # To avoid unnecessary persistent storage accesses, we set up the
  99. # internals directly (loading data wastes time, since we are going to
  100. # set it to an empty dict anyway).
  101. self._session_cache = {}
  102. self.accessed = True
  103. self.modified = True
  104. def _get_new_session_key(self):
  105. "Returns session key that isn't being used."
  106. # Todo: move to 0-9a-z charset in 1.5
  107. hex_chars = '1234567890abcdef'
  108. # session_key should not be case sensitive because some backends
  109. # can store it on case insensitive file systems.
  110. while True:
  111. session_key = get_random_string(32, hex_chars)
  112. if not self.exists(session_key):
  113. break
  114. return session_key
  115. def _get_or_create_session_key(self):
  116. if self._session_key is None:
  117. self._session_key = self._get_new_session_key()
  118. return self._session_key
  119. def _get_session_key(self):
  120. return self._session_key
  121. session_key = property(_get_session_key)
  122. def _get_session(self, no_load=False):
  123. """
  124. Lazily loads session from storage (unless "no_load" is True, when only
  125. an empty dict is stored) and stores it in the current instance.
  126. """
  127. self.accessed = True
  128. try:
  129. return self._session_cache
  130. except AttributeError:
  131. if self.session_key is None or no_load:
  132. self._session_cache = {}
  133. else:
  134. self._session_cache = self.load()
  135. return self._session_cache
  136. _session = property(_get_session)
  137. def get_expiry_age(self):
  138. """Get the number of seconds until the session expires."""
  139. expiry = self.get('_session_expiry')
  140. if not expiry: # Checks both None and 0 cases
  141. return settings.SESSION_COOKIE_AGE
  142. if not isinstance(expiry, datetime):
  143. return expiry
  144. delta = expiry - timezone.now()
  145. return delta.days * 86400 + delta.seconds
  146. def get_expiry_date(self):
  147. """Get session the expiry date (as a datetime object)."""
  148. expiry = self.get('_session_expiry')
  149. if isinstance(expiry, datetime):
  150. return expiry
  151. if not expiry: # Checks both None and 0 cases
  152. expiry = settings.SESSION_COOKIE_AGE
  153. return timezone.now() + timedelta(seconds=expiry)
  154. def set_expiry(self, value):
  155. """
  156. Sets a custom expiration for the session. ``value`` can be an integer,
  157. a Python ``datetime`` or ``timedelta`` object or ``None``.
  158. If ``value`` is an integer, the session will expire after that many
  159. seconds of inactivity. If set to ``0`` then the session will expire on
  160. browser close.
  161. If ``value`` is a ``datetime`` or ``timedelta`` object, the session
  162. will expire at that specific future time.
  163. If ``value`` is ``None``, the session uses the global session expiry
  164. policy.
  165. """
  166. if value is None:
  167. # Remove any custom expiration for this session.
  168. try:
  169. del self['_session_expiry']
  170. except KeyError:
  171. pass
  172. return
  173. if isinstance(value, timedelta):
  174. value = timezone.now() + value
  175. self['_session_expiry'] = value
  176. def get_expire_at_browser_close(self):
  177. """
  178. Returns ``True`` if the session is set to expire when the browser
  179. closes, and ``False`` if there's an expiry date. Use
  180. ``get_expiry_date()`` or ``get_expiry_age()`` to find the actual expiry
  181. date/age, if there is one.
  182. """
  183. if self.get('_session_expiry') is None:
  184. return settings.SESSION_EXPIRE_AT_BROWSER_CLOSE
  185. return self.get('_session_expiry') == 0
  186. def flush(self):
  187. """
  188. Removes the current session data from the database and regenerates the
  189. key.
  190. """
  191. self.clear()
  192. self.delete()
  193. self.create()
  194. def cycle_key(self):
  195. """
  196. Creates a new session key, whilst retaining the current session data.
  197. """
  198. data = self._session_cache
  199. key = self.session_key
  200. self.create()
  201. self._session_cache = data
  202. self.delete(key)
  203. # Methods that child classes must implement.
  204. def exists(self, session_key):
  205. """
  206. Returns True if the given session_key already exists.
  207. """
  208. raise NotImplementedError
  209. def create(self):
  210. """
  211. Creates a new session instance. Guaranteed to create a new object with
  212. a unique key and will have saved the result once (with empty data)
  213. before the method returns.
  214. """
  215. raise NotImplementedError
  216. def save(self, must_create=False):
  217. """
  218. Saves the session data. If 'must_create' is True, a new session object
  219. is created (otherwise a CreateError exception is raised). Otherwise,
  220. save() can update an existing object with the same key.
  221. """
  222. raise NotImplementedError
  223. def delete(self, session_key=None):
  224. """
  225. Deletes the session data under this key. If the key is None, the
  226. current session key value is used.
  227. """
  228. raise NotImplementedError
  229. def load(self):
  230. """
  231. Loads the session data and returns a dictionary.
  232. """
  233. raise NotImplementedError