|
1 | 1 | # -*- coding: utf-8 -*- |
2 | 2 | # (c) 2015 ACSONE SA/NV, Dhinesh D |
| 3 | + |
3 | 4 | # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
4 | 5 |
|
| 6 | +import logging |
| 7 | + |
| 8 | +from odoo import models |
| 9 | + |
| 10 | +from odoo.http import root |
| 11 | +from odoo.http import request |
| 12 | + |
5 | 13 | from os import utime |
6 | 14 | from os.path import getmtime |
7 | 15 | from time import time |
8 | 16 |
|
9 | | -from odoo import models, http |
| 17 | +_logger = logging.getLogger(__name__) |
10 | 18 |
|
11 | 19 |
|
12 | 20 | class ResUsers(models.Model): |
13 | 21 | _inherit = 'res.users' |
14 | 22 |
|
15 | | - @classmethod |
16 | | - def _check_session_validity(cls, db, uid, passwd): |
17 | | - if not http.request: |
| 23 | + def _auth_timeout_ignoredurls_get(self): |
| 24 | + """Pluggable method for calculating ignored urls |
| 25 | + Defaults to stored config param |
| 26 | + """ |
| 27 | + param_model = self.pool['ir.config_parameter'] |
| 28 | + return param_model._auth_timeout_get_parameter_ignoredurls() |
| 29 | + |
| 30 | + def _auth_timeout_deadline_calculate(self): |
| 31 | + """Pluggable method for calculating timeout deadline |
| 32 | + Defaults to current time minus delay using delay stored as config param |
| 33 | + """ |
| 34 | + param_model = self.pool['ir.config_parameter'] |
| 35 | + delay = param_model._auth_timeout_get_parameter_delay() |
| 36 | + if delay is False or delay <= 0: |
| 37 | + return False |
| 38 | + return time() - delay |
| 39 | + |
| 40 | + def _auth_timeout_session_terminate(self, session): |
| 41 | + """Pluggable method for terminating a timed-out session |
| 42 | +
|
| 43 | + This is a late stage where a session timeout can be aborted. |
| 44 | + Useful if you want to do some heavy checking, as it won't be |
| 45 | + called unless the session inactivity deadline has been reached. |
| 46 | +
|
| 47 | + Return: |
| 48 | + True: session terminated |
| 49 | + False: session timeout cancelled |
| 50 | + """ |
| 51 | + if session.db and session.uid: |
| 52 | + session.logout(keep_db=True) |
| 53 | + return True |
| 54 | + |
| 55 | + def _auth_timeout_check(self): |
| 56 | + if not request: |
18 | 57 | return |
19 | | - session = http.request.session |
20 | | - session_store = http.root.session_store |
21 | | - ConfigParam = http.request.env['ir.config_parameter'] |
22 | | - delay, urls = ConfigParam.get_session_parameters() |
23 | | - deadline = time() - delay |
24 | | - path = session_store.get_session_filename(session.sid) |
25 | | - try: |
26 | | - if getmtime(path) < deadline: |
27 | | - if session.db and session.uid: |
28 | | - session.logout(keep_db=True) |
29 | | - elif http.request.httprequest.path not in urls: |
30 | | - # the session is not expired, update the last modification |
31 | | - # and access time. |
| 58 | + |
| 59 | + session = request.session |
| 60 | + |
| 61 | + # Calculate deadline |
| 62 | + deadline = self._auth_timeout_deadline_calculate() |
| 63 | + |
| 64 | + # Check if past deadline |
| 65 | + expired = False |
| 66 | + if deadline is not False: |
| 67 | + path = root.session_store.get_session_filename(session.sid) |
| 68 | + try: |
| 69 | + expired = getmtime(path) < deadline |
| 70 | + except OSError as e: |
| 71 | + _logger.warning( |
| 72 | + 'Exception reading session file modified time: %s' |
| 73 | + % e |
| 74 | + ) |
| 75 | + pass |
| 76 | + |
| 77 | + # Try to terminate the session |
| 78 | + terminated = False |
| 79 | + if expired: |
| 80 | + terminated = self._auth_timeout_session_terminate(session) |
| 81 | + |
| 82 | + # If session terminated, all done |
| 83 | + if terminated: |
| 84 | + return |
| 85 | + |
| 86 | + # Else, conditionally update session modified and access times |
| 87 | + ignoredurls = self._auth_timeout_ignoredurls_get() |
| 88 | + |
| 89 | + if request.httprequest.path not in ignoredurls: |
| 90 | + if 'path' not in locals(): |
| 91 | + path = root.session_store.get_session_filename(session.sid) |
| 92 | + try: |
32 | 93 | utime(path, None) |
33 | | - except OSError: |
34 | | - pass |
| 94 | + except OSError as e: |
| 95 | + _logger.warning( |
| 96 | + 'Exception updating session file access/modified times: %s' |
| 97 | + % e |
| 98 | + ) |
| 99 | + pass |
| 100 | + |
35 | 101 | return |
36 | 102 |
|
37 | | - @classmethod |
38 | | - def check(cls, db, uid, passwd): |
39 | | - res = super(ResUsers, cls).check(db, uid, passwd) |
40 | | - cls._check_session_validity(db, uid, passwd) |
| 103 | + def _check_session_validity(self, db, uid, passwd): |
| 104 | + """Adaptor method for backward compatibility""" |
| 105 | + return self._auth_timeout_check() |
| 106 | + |
| 107 | + def check(self, db, uid, passwd): |
| 108 | + res = super(ResUsers, self).check(db, uid, passwd) |
| 109 | + self._check_session_validity(db, uid, passwd) |
41 | 110 | return res |
0 commit comments