[FIX] http: make session lifetime consistent and configurable

Before 16.0 and https://github.com/odoo/odoo/pull/78857 the session
cookie duration was set to 3 months, but the server-side garbage
collection of inactive session was reaping them after 7 days of
inactivity. The cookie lifetime was essentially superseded by the
server-side GC.

After https://github.com/odoo/odoo/pull/78857 these limits were made
consistent with each other, but the lifetime value was kept at 3 months,
which is a bit too long as a default.

This commit changes the default SESSION_LIFETIME back to 7 days for both
limits.

In addition, since the server-side GC is now implemented by a
database-specific cron job, this commit introduces an optional system
parameter `sessions.max_inactivity_seconds` that can be set to override
the default server-side GC threshold, to make it shorter.

Note 1: the ICP does not modify the cookie lifetime which will remain set
to the default 7 days. This means normal browser sessions won't stay
alive for longer than 7 days of inactivity. So `sessions.max_inactivity_seconds`
can't be effectively set to a longer expiration time.
This seems like a reasonably safe default.

Note 2: the session GC happens during the execution of the autovacuum
cron job ("Base: Auto-vacuum internal data") which is scheduled once per
day by default. When setting a small `sessions.max_inactivity_seconds`
value, it may be necessary to increase the frequency of that cron job
accordingly.

closes odoo/odoo#122964

X-original-commit: 05ff9a2db32c2fb1afa107ac005423218f452290
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
This commit is contained in:
Olivier Dony
2023-05-31 15:54:05 +02:00
parent 2bd074e26c
commit cea9150fb7
2 changed files with 9 additions and 6 deletions
+3 -1
View File
@@ -256,7 +256,9 @@ class IrHttp(models.AbstractModel):
@api.autovacuum
def _gc_sessions(self):
http.root.session_store.vacuum()
ICP = self.env["ir.config_parameter"]
max_lifetime = int(ICP.get_param('sessions.max_inactivity_seconds', http.SESSION_LIFETIME))
http.root.session_store.vacuum(max_lifetime=max_lifetime)
@api.model
def get_translations_for_webclient(self, modules, lang):
+6 -5
View File
@@ -280,9 +280,10 @@ if parse_version(werkzeug.__version__) >= parse_version('2.0.2'):
# let's add the websocket key only when appropriate.
ROUTING_KEYS.add('websocket')
# The duration of a user session before it is considered expired,
# three months.
SESSION_LIFETIME = 60 * 60 * 24 * 90
# The default duration of a user session cookie. Inactive sessions are reaped
# server-side as well with a threshold that can be set via an optional
# config parameter `sessions.max_inactivity_seconds` (default: SESSION_LIFETIME)
SESSION_LIFETIME = 60 * 60 * 24 * 7
# The cache duration for static content from the filesystem, one week.
STATIC_CACHE = 60 * 60 * 24 * 7
@@ -889,8 +890,8 @@ class FilesystemSessionStore(sessions.FilesystemSessionStore):
session.should_rotate = False
self.save(session)
def vacuum(self):
threshold = time.time() - SESSION_LIFETIME
def vacuum(self, max_lifetime=SESSION_LIFETIME):
threshold = time.time() - max_lifetime
for fname in glob.iglob(os.path.join(root.session_store.path, '*', '*')):
path = os.path.join(root.session_store.path, fname)
with contextlib.suppress(OSError):