[Zope3-checkins] SVN: Zope3/branches/stub-session/src/zope/app/session/browserid.py Die

Stuart Bishop zen at shangri-la.dropbear.id.au
Mon Jul 5 17:58:10 EDT 2004


Log message for revision 26102:
Die



-=-
Deleted: Zope3/branches/stub-session/src/zope/app/session/browserid.py
===================================================================
--- Zope3/branches/stub-session/src/zope/app/session/browserid.py	2004-07-05 21:25:38 UTC (rev 26101)
+++ Zope3/branches/stub-session/src/zope/app/session/browserid.py	2004-07-05 21:58:09 UTC (rev 26102)
@@ -1,259 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""
-Session implementation using cookies
-
-$Id$
-"""
-import sha, time, string, random, hmac, warnings, thread
-from UserDict import IterableUserDict
-from heapq import heapify, heappop
-
-from persistent import Persistent
-from zope.server.http.http_date import build_http_date
-from zope.interface import implements
-from zope.component import ComponentLookupError
-from zope.app.zapi import getUtility
-from BTrees.OOBTree import OOBTree
-from zope.app.utility.interfaces import ILocalUtility
-from zope.app.annotation.interfaces import IAttributeAnnotatable
-
-from interfaces import \
-        IBrowserIdManager, IBrowserId, ICookieBrowserIdManager, \
-        ISessionDataContainer, ISession, ISessionProductData, ISessionData
-
-import ZODB
-import ZODB.MappingStorage
-
-cookieSafeTrans = string.maketrans("+/", "-.")
-
-def digestEncode(s):
-    """Encode SHA digest for cookie."""
-    return s.encode("base64")[:-2].translate(cookieSafeTrans)
-
-
-class BrowserId(str):
-    """See zope.app.interfaces.utilities.session.IBrowserId"""
-    implements(IBrowserId)
-
-    def __new__(cls, request):
-        return str.__new__(
-                cls, getUtility(IBrowserIdManager).getBrowserId(request)
-                )
-
-
-class CookieBrowserIdManager(Persistent):
-    """Session service implemented using cookies."""
-
-    implements(IBrowserIdManager, ICookieBrowserIdManager,
-               ILocalUtility, IAttributeAnnotatable,
-               )
-
-    __parent__ = __name__ = None
-
-    def __init__(self):
-        self.namespace = "zope3_cs_%x" % (int(time.time()) - 1000000000)
-        self.secret = "%.20f" % random.random()
-        self.cookieLifetime = None
-
-    def generateUniqueId(self):
-        """Generate a new, random, unique id."""
-        data = "%.20f%.20f%.20f" % (random.random(), time.time(), time.clock())
-        digest = sha.sha(data).digest()
-        s = digestEncode(digest)
-        # we store a HMAC of the random value together with it, which makes
-        # our session ids unforgeable.
-        mac = hmac.new(s, self.secret, digestmod=sha).digest()
-        return s + digestEncode(mac)
-
-    def getRequestId(self, request):
-        """Return the browser id encoded in request as a string, 
-        or None if it's non-existent."""
-        # If there is an id set on the response, use that but don't trust it.
-        # We need to check the response in case there has already been a new
-        # session created during the course of this request.
-        response_cookie = request.response.getCookie(self.namespace)
-        if response_cookie:
-            sid = response_cookie['value']
-        else:
-            sid = request.cookies.get(self.namespace)
-        if sid is None or len(sid) != 54:
-            return None
-        s, mac = sid[:27], sid[27:]
-        if (digestEncode(hmac.new(s, self.secret, digestmod=sha).digest())
-            != mac):
-            return None
-        else:
-            return sid
-
-    def setRequestId(self, request, id):
-        """Set cookie with id on request."""
-        # XXX Currently, the path is the ApplicationURL. This is reasonable,
-        #     and will be adequate for most purposes.
-        #     A better path to use would be that of the folder that contains
-        #     the service-manager this service is registered within. However,
-        #     that would be expensive to look up on each request, and would
-        #     have to be altered to take virtual hosting into account.
-        #     Seeing as this service instance has a unique namespace for its
-        #     cookie, using ApplicationURL shouldn't be a problem.
-
-        if self.cookieLifetime is not None:
-            if self.cookieLifetime:
-                expires = build_http_date(time.time() + self.cookieLifetime)
-            else:
-                expires = 'Tue, 19 Jan 2038 00:00:00 GMT'
-            request.response.setCookie(
-                    self.namespace, id, expires=expires,
-                    path=request.getApplicationURL(path_only=True)
-                    )
-        else:
-            request.response.setCookie(
-                    self.namespace, id,
-                    path=request.getApplicationURL(path_only=True)
-                    )
-
-    def getBrowserId(self, request):
-        """See zope.app.session.interfaces.IBrowserIdManager"""
-        sid = self.getRequestId(request)
-        if sid is None:
-            sid = self.generateUniqueId()
-        self.setRequestId(request, sid)
-        return sid
-
-
-class PersistentSessionDataContainer(Persistent, IterableUserDict):
-    ''' A SessionDataContainer that stores data in the ZODB '''
-    __parent__ = __name__ = None
-
-    implements(ISessionDataContainer, ILocalUtility, IAttributeAnnotatable)
-
-    def __init__(self):
-        self.data = OOBTree()
-        self.sweepInterval = 5*60
-
-    def __getitem__(self, product_id):
-        rv = IterableUserDict.__getitem__(self, product_id)
-        now = time.time()
-        # Only update lastAccessTime once every few minutes, rather than
-        # every hit, to avoid ZODB bloat and conflicts
-        if rv.lastAccessTime + self.sweepInterval < now:
-            rv.lastAccessTime = int(now)
-            # XXX: When scheduler exists, this method should just schedule
-            # a sweep later since we are currently busy handling a request
-            # and may end up doing simultaneous sweeps
-            self.sweep()
-        return rv
-
-    def __setitem__(self, product_id, session_data):
-        session_data.lastAccessTime = int(time.time())
-        return IterableUserDict.__setitem__(self, product_id, session_data)
-
-    def sweep(self):
-        ''' Clean out stale data '''
-        expire_time = time.time() - self.sweepInterval
-        heap = [(v.lastAccessTime, k) for k,v in self.data.items()]
-        heapify(heap)
-        while heap:
-            lastAccessTime, key = heappop(heap)
-            if lastAccessTime < expire_time:
-                del self.data[key]
-            else:
-                return
-
-
-class RAMSessionDataContainer(PersistentSessionDataContainer):
-    ''' A SessionDataContainer that stores data in RAM. Currently session
-        data is not shared between Zope clients, so server affinity will
-        need to be maintained to use this in a ZEO cluster.
-    '''
-    def __init__(self):
-        self.sweepInterval = 5*60
-        self.key = sha.new(str(time.time() + random.random())).hexdigest()
-
-    _ram_storage = ZODB.MappingStorage.MappingStorage()
-    _ram_db = ZODB.DB(_ram_storage)
-    _conns = {}
-
-    def _getData(self):
-
-        # Open a connection to _ram_storage per thread
-        tid = thread.get_ident()
-        if not self._conns.has_key(tid):
-            self._conns[tid] = self._ram_db.open()
-
-        root = self._conns[tid].root()
-        if not root.has_key(self.key):
-            root[self.key] = OOBTree()
-        return root[self.key]
-
-    data = property(_getData, None)
-
-    def sweep(self):
-        super(RAMSessionDataContainer, self).sweep()
-        self._ram_db.pack(time.time())
-
-
-class Session:
-    """See zope.app.session.interfaces.ISession"""
-    implements(ISession)
-    __slots__ = ('browser_id',)
-    def __init__(self, request):
-        self.browser_id = str(IBrowserId(request))
-
-    def __getitem__(self, product_id):
-        """See zope.app.session.interfaces.ISession"""
-
-        # First locate the ISessionDataContainer by looking up
-        # the named Utility, and falling back to the unnamed one.
-        try:
-            sdc = getUtility(ISessionDataContainer, product_id)
-        except ComponentLookupError:
-            # XXX: Do we want this?
-            warnings.warn(
-                    'Unable to find ISessionDataContainer named %s. '
-                    'Using default' % repr(product_id),
-                    RuntimeWarning
-                    )
-            sdc = getUtility(ISessionDataContainer)
-
-        # The ISessionDataContainer contains two levels:
-        # ISessionDataContainer[product_id] == ISessionProductData
-        # ISessionDataContainer[product_id][browser_id] == ISessionData
-        try:
-            spd = sdc[product_id]
-        except KeyError:
-            sdc[product_id] = SessionProductData()
-            spd = sdc[product_id]
-
-        try:
-            return spd[self.browser_id]
-        except KeyError:
-            spd[self.browser_id] = SessionData()
-            return spd[self.browser_id]
-
-
-class SessionProductData(Persistent, IterableUserDict):
-    """See zope.app.session.interfaces.ISessionProductData"""
-    implements(ISessionProductData)
-    lastAccessTime = 0
-    def __init__(self):
-        self.data = OOBTree()
-
-
-class SessionData(Persistent, IterableUserDict):
-    """See zope.app.session.interfaces.ISessionData"""
-    implements(ISessionData)
-    def __init__(self):
-        self.data = OOBTree()
-



More information about the Zope3-Checkins mailing list