web/views/sessions.py
author Aurelien Campeas <aurelien.campeas@logilab.fr>
Thu, 13 Feb 2014 17:00:40 +0100
changeset 10565 f5063eae939e
parent 10564 6b109900583b
child 10578 c70606673384
permissions -rw-r--r--
[web/sessions] the session managers are definitely not components Component (or AppObjects) take a _cw at __init__ time. The session managers want a repository. Related to #1381328.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10358
d551d0a162d5 [web/sessions] reduce repoapi usage where possible
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10354
diff changeset
     1
# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
10369
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    18
"""web session: by default the session is actually the db connection """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
9573
99166335a8e0 Move setting session.mtime from dbapi to web session manager
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
    21
from time import time
10565
f5063eae939e [web/sessions] the session managers are definitely not components
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10564
diff changeset
    22
from logging import getLogger
9573
99166335a8e0 Move setting session.mtime from dbapi to web session manager
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
    23
10565
f5063eae939e [web/sessions] the session managers are definitely not components
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10564
diff changeset
    24
from logilab.common.registry import RegistrableObject
f5063eae939e [web/sessions] the session managers are definitely not components
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10564
diff changeset
    25
f5063eae939e [web/sessions] the session managers are definitely not components
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10564
diff changeset
    26
from cubicweb import RepositoryError, Unauthorized, BadConnectionId, set_log_methods
f5063eae939e [web/sessions] the session managers are definitely not components
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10564
diff changeset
    27
from cubicweb.predicates import yes
f5063eae939e [web/sessions] the session managers are definitely not components
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10564
diff changeset
    28
from cubicweb.web import InvalidSession
10369
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    29
10564
6b109900583b [web] the AuthenticationManager is no more an appobject
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10557
diff changeset
    30
from cubicweb.web.views import authentication
10369
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    31
10565
f5063eae939e [web/sessions] the session managers are definitely not components
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10564
diff changeset
    32
f5063eae939e [web/sessions] the session managers are definitely not components
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10564
diff changeset
    33
class AbstractSessionManager(RegistrableObject):
10369
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    34
    """manage session data associated to a session identifier"""
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    35
    __abstract__ = True
10565
f5063eae939e [web/sessions] the session managers are definitely not components
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10564
diff changeset
    36
    __select__ = yes()
f5063eae939e [web/sessions] the session managers are definitely not components
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10564
diff changeset
    37
    __registry__ = 'sessions'
10369
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    38
    __regid__ = 'sessionmanager'
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    39
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    40
    def __init__(self, repo):
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    41
        vreg = repo.vreg
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    42
        self.session_time = vreg.config['http-session-time'] or None
10564
6b109900583b [web] the AuthenticationManager is no more an appobject
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10557
diff changeset
    43
        self.authmanager = authentication.RepositoryAuthenticationManager(repo)
10369
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    44
        interval = (self.session_time or 0) / 2.
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    45
        if vreg.config.anonymous_user()[0] is not None:
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    46
            self.cleanup_anon_session_time = vreg.config['cleanup-anonymous-session-time'] or 5 * 60
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    47
            assert self.cleanup_anon_session_time > 0
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    48
            if self.session_time is not None:
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    49
                self.cleanup_anon_session_time = min(self.session_time,
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    50
                                                     self.cleanup_anon_session_time)
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    51
            interval = self.cleanup_anon_session_time / 2.
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    52
        # we don't want to check session more than once every 5 minutes
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    53
        self.clean_sessions_interval = max(5 * 60, interval)
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    54
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    55
    def clean_sessions(self):
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    56
        """cleanup sessions which has not been unused since a given amount of
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    57
        time. Return the number of sessions which have been closed.
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    58
        """
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    59
        self.debug('cleaning http sessions')
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    60
        session_time = self.session_time
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    61
        closed, total = 0, 0
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    62
        for session in self.current_sessions():
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    63
            total += 1
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    64
            try:
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    65
                last_usage_time = session.cnx.check()
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    66
            except AttributeError:
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    67
                last_usage_time = session.mtime
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    68
            except BadConnectionId:
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    69
                self.close_session(session)
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    70
                closed += 1
10557
9826dc78eec1 [web] fix AbstractSessionManager.clean_sessions (closes #5757240)
David Douard <david.douard@logilab.fr>
parents: 10369
diff changeset
    71
                continue
9826dc78eec1 [web] fix AbstractSessionManager.clean_sessions (closes #5757240)
David Douard <david.douard@logilab.fr>
parents: 10369
diff changeset
    72
9826dc78eec1 [web] fix AbstractSessionManager.clean_sessions (closes #5757240)
David Douard <david.douard@logilab.fr>
parents: 10369
diff changeset
    73
            no_use_time = (time() - last_usage_time)
9826dc78eec1 [web] fix AbstractSessionManager.clean_sessions (closes #5757240)
David Douard <david.douard@logilab.fr>
parents: 10369
diff changeset
    74
            if session.anonymous_session:
9826dc78eec1 [web] fix AbstractSessionManager.clean_sessions (closes #5757240)
David Douard <david.douard@logilab.fr>
parents: 10369
diff changeset
    75
                if no_use_time >= self.cleanup_anon_session_time:
10369
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    76
                    self.close_session(session)
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    77
                    closed += 1
10557
9826dc78eec1 [web] fix AbstractSessionManager.clean_sessions (closes #5757240)
David Douard <david.douard@logilab.fr>
parents: 10369
diff changeset
    78
            elif session_time is not None and no_use_time >= session_time:
9826dc78eec1 [web] fix AbstractSessionManager.clean_sessions (closes #5757240)
David Douard <david.douard@logilab.fr>
parents: 10369
diff changeset
    79
                self.close_session(session)
9826dc78eec1 [web] fix AbstractSessionManager.clean_sessions (closes #5757240)
David Douard <david.douard@logilab.fr>
parents: 10369
diff changeset
    80
                closed += 1
10369
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    81
        return closed, total - closed
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    82
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    83
    def current_sessions(self):
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    84
        """return currently open sessions"""
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    85
        raise NotImplementedError()
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    86
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    87
    def get_session(self, req, sessionid):
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    88
        """return existing session for the given session identifier"""
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    89
        raise NotImplementedError()
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    90
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    91
    def open_session(self, req):
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    92
        """open and return a new session for the given request.
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    93
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    94
        raise :exc:`cubicweb.AuthenticationError` if authentication failed
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    95
        (no authentication info found or wrong user/password)
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    96
        """
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    97
        raise NotImplementedError()
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    98
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
    99
    def close_session(self, session):
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
   100
        """close session on logout or on invalid session detected (expired out,
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
   101
        corrupted...)
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
   102
        """
0c678b63d017 [web] move abstract session manager to web/sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10358
diff changeset
   103
        raise NotImplementedError()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
10565
f5063eae939e [web/sessions] the session managers are definitely not components
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10564
diff changeset
   106
set_log_methods(AbstractSessionManager, getLogger('cubicweb.sessionmanager'))
f5063eae939e [web/sessions] the session managers are definitely not components
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10564
diff changeset
   107
f5063eae939e [web/sessions] the session managers are definitely not components
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10564
diff changeset
   108
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
class InMemoryRepositorySessionManager(AbstractSessionManager):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
    """manage session data associated to a session identifier"""
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   111
2887
1282dc6525c5 give vreg where we need it (eg no bound request)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2706
diff changeset
   112
    def __init__(self, *args, **kwargs):
10565
f5063eae939e [web/sessions] the session managers are definitely not components
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10564
diff changeset
   113
        super(InMemoryRepositorySessionManager, self).__init__(*args, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
        # XXX require a RepositoryAuthenticationManager which violates
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
        #     authenticate interface by returning a session instead of a user
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
        #assert isinstance(self.authmanager, RepositoryAuthenticationManager)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
        self._sessions = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
5080
cfc7c2b24f9e [cleanup] some notes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   119
    # dump_data / restore_data to avoid loosing open sessions on registry
cfc7c2b24f9e [cleanup] some notes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   120
    # reloading
2706
09baf5175196 [web session] proper reloading of the session manager on vreg update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   121
    def dump_data(self):
09baf5175196 [web session] proper reloading of the session manager on vreg update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   122
        return self._sessions
09baf5175196 [web session] proper reloading of the session manager on vreg update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   123
    def restore_data(self, data):
09baf5175196 [web session] proper reloading of the session manager on vreg update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   124
        self._sessions = data
09baf5175196 [web session] proper reloading of the session manager on vreg update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   125
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
    def current_sessions(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
        return self._sessions.values()
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   128
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
    def get_session(self, req, sessionid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
        """return existing session for the given session identifier"""
7428
5338d895b891 [web session] fix session handling so we get a chance to have for instance the 'forgotpwd' feature working on a site where anonymous are not allowed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6848
diff changeset
   131
        if sessionid not in self._sessions:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
            raise InvalidSession()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
        session = self._sessions[sessionid]
9071
46885bfa4150 Use new repoapi for the web stack
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9019
diff changeset
   134
        try:
46885bfa4150 Use new repoapi for the web stack
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9019
diff changeset
   135
            user = self.authmanager.validate_session(req, session)
46885bfa4150 Use new repoapi for the web stack
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9019
diff changeset
   136
        except InvalidSession:
46885bfa4150 Use new repoapi for the web stack
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9019
diff changeset
   137
            self.close_session(session)
46885bfa4150 Use new repoapi for the web stack
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9019
diff changeset
   138
            raise
46885bfa4150 Use new repoapi for the web stack
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9019
diff changeset
   139
        if session.closed:
46885bfa4150 Use new repoapi for the web stack
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9019
diff changeset
   140
            self.close_session(session)
46885bfa4150 Use new repoapi for the web stack
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9019
diff changeset
   141
            raise InvalidSession()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
        return session
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
9017
aa709bc6b6c1 [application/connect] simplify connection logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9015
diff changeset
   144
    def open_session(self, req):
5223
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
   145
        """open and return a new session for the given request. The session is
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
   146
        also bound to the request.
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   147
5223
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
   148
        raise :exc:`cubicweb.AuthenticationError` if authentication failed
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5080
diff changeset
   149
        (no authentication info found or wrong user/password)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
        """
9071
46885bfa4150 Use new repoapi for the web stack
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9019
diff changeset
   151
        session, login = self.authmanager.authenticate(req)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
        self._sessions[session.sessionid] = session
9573
99166335a8e0 Move setting session.mtime from dbapi to web session manager
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
   153
        session.mtime = time()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
        return session
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   155
9018
9deb024a96c0 [session-handler] use session directly to update last usage
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9017
diff changeset
   156
    def postlogin(self, req, session):
9deb024a96c0 [session-handler] use session directly to update last usage
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9017
diff changeset
   157
        """postlogin: the user have been related to a session
9deb024a96c0 [session-handler] use session directly to update last usage
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9017
diff changeset
   158
9deb024a96c0 [session-handler] use session directly to update last usage
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9017
diff changeset
   159
        Both req and session are passed to this function because actually
9deb024a96c0 [session-handler] use session directly to update last usage
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9017
diff changeset
   160
        linking the request to the session is not yet done and not the
9deb024a96c0 [session-handler] use session directly to update last usage
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9017
diff changeset
   161
        responsability of this object.
6791
fe58b234f9c2 [web session] refactor to finally closes #343036: allow _postlogin behaviour overloading
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279
diff changeset
   162
        """
fe58b234f9c2 [web session] refactor to finally closes #343036: allow _postlogin behaviour overloading
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279
diff changeset
   163
        # Update last connection date
fe58b234f9c2 [web session] refactor to finally closes #343036: allow _postlogin behaviour overloading
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279
diff changeset
   164
        # XXX: this should be in a post login hook in the repository, but there
fe58b234f9c2 [web session] refactor to finally closes #343036: allow _postlogin behaviour overloading
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279
diff changeset
   165
        #      we can't differentiate actual login of automatic session
fe58b234f9c2 [web session] refactor to finally closes #343036: allow _postlogin behaviour overloading
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279
diff changeset
   166
        #      reopening. Is it actually a problem?
fe58b234f9c2 [web session] refactor to finally closes #343036: allow _postlogin behaviour overloading
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279
diff changeset
   167
        if 'last_login_time' in req.vreg.schema:
9018
9deb024a96c0 [session-handler] use session directly to update last usage
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9017
diff changeset
   168
            self._update_last_login_time(session)
9543
39f981482e34 merge 3.18.x in 3.19 branch
Julien Cristau <julien.cristau@logilab.fr>
parents: 9071 9492
diff changeset
   169
        req.set_message(req._('welcome %s!') % session.user.login)
6791
fe58b234f9c2 [web session] refactor to finally closes #343036: allow _postlogin behaviour overloading
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279
diff changeset
   170
9018
9deb024a96c0 [session-handler] use session directly to update last usage
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9017
diff changeset
   171
    def _update_last_login_time(self, session):
6791
fe58b234f9c2 [web session] refactor to finally closes #343036: allow _postlogin behaviour overloading
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279
diff changeset
   172
        # XXX should properly detect missing permission / non writeable source
fe58b234f9c2 [web session] refactor to finally closes #343036: allow _postlogin behaviour overloading
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279
diff changeset
   173
        # and avoid "except (RepositoryError, Unauthorized)" below
fe58b234f9c2 [web session] refactor to finally closes #343036: allow _postlogin behaviour overloading
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279
diff changeset
   174
        try:
10358
d551d0a162d5 [web/sessions] reduce repoapi usage where possible
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10354
diff changeset
   175
            with session.new_cnx() as cnx:
9071
46885bfa4150 Use new repoapi for the web stack
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9019
diff changeset
   176
                cnx.execute('SET X last_login_time NOW WHERE X eid %(x)s',
46885bfa4150 Use new repoapi for the web stack
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9019
diff changeset
   177
                           {'x' : session.user.eid})
46885bfa4150 Use new repoapi for the web stack
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9019
diff changeset
   178
                cnx.commit()
6791
fe58b234f9c2 [web session] refactor to finally closes #343036: allow _postlogin behaviour overloading
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279
diff changeset
   179
        except (RepositoryError, Unauthorized):
9071
46885bfa4150 Use new repoapi for the web stack
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9019
diff changeset
   180
            pass
6791
fe58b234f9c2 [web session] refactor to finally closes #343036: allow _postlogin behaviour overloading
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279
diff changeset
   181
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
    def close_session(self, session):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
        """close session on logout or on invalid session detected (expired out,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
        corrupted...)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
        """
5799
93f4b4d2fecf use sessionid in log message
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5426
diff changeset
   186
        self.info('closing http session %s' % session.sessionid)
9071
46885bfa4150 Use new repoapi for the web stack
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9019
diff changeset
   187
        self._sessions.pop(session.sessionid, None)
46885bfa4150 Use new repoapi for the web stack
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9019
diff changeset
   188
        if not session.closed:
9624
a42fae4cd45a [web/sessions] use session.sessionid instead of deprecated session.id
Julien Cristau <julien.cristau@logilab.fr>
parents: 9573
diff changeset
   189
            session.repo.close(session.sessionid)