web/views/sessions.py
changeset 10369 0c678b63d017
parent 10358 d551d0a162d5
child 10557 9826dc78eec1
--- a/web/views/sessions.py	Wed Jun 11 18:24:40 2014 +0200
+++ b/web/views/sessions.py	Thu Feb 13 16:32:41 2014 +0100
@@ -15,18 +15,83 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""web session component: by dfault the session is actually the db connection
-object :/
-"""
-
+"""web session: by default the session is actually the db connection """
 __docformat__ = "restructuredtext en"
 
 from time import time
 
-from cubicweb import (RepositoryError, Unauthorized, AuthenticationError,
-                      BadConnectionId)
-from cubicweb.web import InvalidSession, Redirect
-from cubicweb.web.application import AbstractSessionManager
+from cubicweb import RepositoryError, Unauthorized, BadConnectionId
+from cubicweb.web import InvalidSession, component
+
+
+class AbstractSessionManager(component.Component):
+    """manage session data associated to a session identifier"""
+    __abstract__ = True
+    __regid__ = 'sessionmanager'
+
+    def __init__(self, repo):
+        vreg = repo.vreg
+        self.session_time = vreg.config['http-session-time'] or None
+        self.authmanager = vreg['components'].select('authmanager', repo=repo)
+        interval = (self.session_time or 0) / 2.
+        if vreg.config.anonymous_user()[0] is not None:
+            self.cleanup_anon_session_time = vreg.config['cleanup-anonymous-session-time'] or 5 * 60
+            assert self.cleanup_anon_session_time > 0
+            if self.session_time is not None:
+                self.cleanup_anon_session_time = min(self.session_time,
+                                                     self.cleanup_anon_session_time)
+            interval = self.cleanup_anon_session_time / 2.
+        # we don't want to check session more than once every 5 minutes
+        self.clean_sessions_interval = max(5 * 60, interval)
+
+    def clean_sessions(self):
+        """cleanup sessions which has not been unused since a given amount of
+        time. Return the number of sessions which have been closed.
+        """
+        self.debug('cleaning http sessions')
+        session_time = self.session_time
+        closed, total = 0, 0
+        for session in self.current_sessions():
+            total += 1
+            try:
+                last_usage_time = session.cnx.check()
+            except AttributeError:
+                last_usage_time = session.mtime
+            except BadConnectionId:
+                self.close_session(session)
+                closed += 1
+            else:
+                no_use_time = (time() - last_usage_time)
+                if session.anonymous_session:
+                    if no_use_time >= self.cleanup_anon_session_time:
+                        self.close_session(session)
+                        closed += 1
+                elif session_time is not None and no_use_time >= session_time:
+                    self.close_session(session)
+                    closed += 1
+        return closed, total - closed
+
+    def current_sessions(self):
+        """return currently open sessions"""
+        raise NotImplementedError()
+
+    def get_session(self, req, sessionid):
+        """return existing session for the given session identifier"""
+        raise NotImplementedError()
+
+    def open_session(self, req):
+        """open and return a new session for the given request.
+
+        raise :exc:`cubicweb.AuthenticationError` if authentication failed
+        (no authentication info found or wrong user/password)
+        """
+        raise NotImplementedError()
+
+    def close_session(self, session):
+        """close session on logout or on invalid session detected (expired out,
+        corrupted...)
+        """
+        raise NotImplementedError()
 
 
 class InMemoryRepositorySessionManager(AbstractSessionManager):