/circuits/web/sessions.py

https://bitbucket.org/prologic/circuits/ · Python · 85 lines · 66 code · 9 blank · 10 comment · 3 complexity · 33e520afba4eacee44d45e804231b50b MD5 · raw file

  1. # Module: sessions
  2. # Date: 22nd February 2009
  3. # Author: James Mills, prologic at shortcircuit dot net dot au
  4. """Session Components
  5. This module implements Session Components that can be used to store
  6. and access persistent information.
  7. """
  8. from uuid import uuid4 as uuid
  9. from hashlib import sha1 as sha
  10. from collections import defaultdict
  11. from circuits import handler, Component
  12. def who(request, encoding="utf-8"):
  13. """Create a SHA1 Hash of the User's IP Address and User-Agent"""
  14. ip = request.remote.ip
  15. agent = request.headers.get("User-Agent", "")
  16. return sha("{0:s}{1:s}".format(ip, agent).encode(encoding)).hexdigest()
  17. def create_session(request):
  18. """Create a unique session id from the request
  19. Returns a unique session using ``uuid4()`` and a ``sha1()`` hash
  20. of the users IP Address and User Agent in the form of ``sid/who``.
  21. """
  22. return "{0:s}/{1:s}".format(uuid().hex, who(request))
  23. def verify_session(request, sid):
  24. """Verify a User's Session
  25. This verifies the User's Session by verifying the SHA1 Hash
  26. of the User's IP Address and User-Agent match the provided
  27. Session ID.
  28. """
  29. if "/" not in sid:
  30. return create_session(request)
  31. user = sid.split("/", 1)[1]
  32. if user != who(request):
  33. return create_session(request)
  34. return sid
  35. class Sessions(Component):
  36. channel = "web"
  37. def __init__(self, name="circuits.session", channel=channel):
  38. super(Sessions, self).__init__(channel=channel)
  39. self._name = name
  40. self._data = defaultdict(dict)
  41. def load(self, sid):
  42. return self._data[sid]
  43. def save(self, sid, data):
  44. """Save User Session Data for sid"""
  45. @handler("request", priority=10)
  46. def request(self, request, response):
  47. if self._name in request.cookie:
  48. sid = request.cookie[self._name].value
  49. sid = verify_session(request, sid)
  50. else:
  51. sid = create_session(request)
  52. request.sid = sid
  53. request.session = self.load(sid)
  54. response.cookie[self._name] = sid