PageRenderTime 71ms CodeModel.GetById 52ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

/circuits/web/sessions.py

https://bitbucket.org/prologic/circuits/
Python | 85 lines | 69 code | 8 blank | 8 comment | 1 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
 5
 6"""Session Components
 7
 8This module implements Session Components that can be used to store
 9and access persistent information.
10"""
11
12
13from uuid import uuid4 as uuid
14from hashlib import sha1 as sha
15from collections import defaultdict
16
17
18from circuits import handler, Component
19
20
21def who(request, encoding="utf-8"):
22    """Create a SHA1 Hash of the User's IP Address and User-Agent"""
23
24    ip = request.remote.ip
25    agent = request.headers.get("User-Agent", "")
26
27    return sha("{0:s}{1:s}".format(ip, agent).encode(encoding)).hexdigest()
28
29
30def create_session(request):
31    """Create a unique session id from the request
32
33    Returns a unique session using ``uuid4()`` and a ``sha1()`` hash
34    of the users IP Address and User Agent in the form of ``sid/who``.
35    """
36
37    return "{0:s}/{1:s}".format(uuid().hex, who(request))
38
39
40def verify_session(request, sid):
41    """Verify a User's Session
42
43    This verifies the User's Session by verifying the SHA1 Hash
44    of the User's IP Address and User-Agent match the provided
45    Session ID.
46    """
47
48    if "/" not in sid:
49        return create_session(request)
50
51    user = sid.split("/", 1)[1]
52
53    if user != who(request):
54        return create_session(request)
55
56    return sid
57
58
59class Sessions(Component):
60
61    channel = "web"
62
63    def __init__(self, name="circuits.session", channel=channel):
64        super(Sessions, self).__init__(channel=channel)
65
66        self._name = name
67        self._data = defaultdict(dict)
68
69    def load(self, sid):
70        return self._data[sid]
71
72    def save(self, sid, data):
73        """Save User Session Data for sid"""
74
75    @handler("request", priority=10)
76    def request(self, request, response):
77        if self._name in request.cookie:
78            sid = request.cookie[self._name].value
79            sid = verify_session(request, sid)
80        else:
81            sid = create_session(request)
82
83        request.sid = sid
84        request.session = self.load(sid)
85        response.cookie[self._name] = sid