summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Morel <xmo@odoo.com>2019-06-05 09:06:09 +0000
committerOlivier Dony <odo@odoo.com>2020-08-14 23:06:24 +0000
commit096972de0be5af2bbdf5003904bd31b79f8f4ce1 (patch)
tree12a4c1e6db34be5c41ad10554d345f564aee9f08
parent909b64a50bc9d23fec1b36e5a6f11ab3106d893c (diff)
[ADD] core, web: support for partial sessions & MFA
-rw-r--r--addons/web/controllers/main.py13
-rw-r--r--odoo/addons/base/models/res_users.py3
-rw-r--r--odoo/http.py20
3 files changed, 30 insertions, 6 deletions
diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py
index b2f9b268dea..e3996348043 100644
--- a/addons/web/controllers/main.py
+++ b/addons/web/controllers/main.py
@@ -869,7 +869,18 @@ class Home(http.Controller):
return response
def _login_redirect(self, uid, redirect=None):
- return redirect if redirect else '/web'
+ if request.session.uid: # fully logged
+ return redirect or '/web'
+
+ # partial session (MFA)
+ url = request.env(user=uid)['res.users'].browse(uid)._mfa_url()
+ if not redirect:
+ return url
+
+ parsed = werkzeug.urls.url_parse(url)
+ qs = parsed.decode_query()
+ qs['redirect'] = redirect
+ return parsed.replace(query=werkzeug.urls.url_encode(qs)).to_url()
@http.route('/web/login', type='http', auth="none")
def web_login(self, redirect=None, **kw):
diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py
index 336be363e36..11d0f0980ae 100644
--- a/odoo/addons/base/models/res_users.py
+++ b/odoo/addons/base/models/res_users.py
@@ -998,6 +998,9 @@ class Users(models.Model):
return 'base/static/img/user-slash.png'
return super()._get_placeholder_filename(field=field)
+ def _mfa_url(self):
+ """ If an MFA method is enabled, returns the URL for its second step. """
+ return
#
# Implied groups
#
diff --git a/odoo/http.py b/odoo/http.py
index 40da5a5b131..d025e7fac31 100644
--- a/odoo/http.py
+++ b/odoo/http.py
@@ -48,7 +48,6 @@ except ImportError:
psutil = None
import odoo
-from odoo import fields
from .service.server import memory_info
from .service import security, model as service_model
from .sql_db import flush_env
@@ -992,18 +991,29 @@ class OpenERPSession(sessions.Session):
REMOTE_ADDR=wsgienv['REMOTE_ADDR'],
)
uid = odoo.registry(db)['res.users'].authenticate(db, login, password, env)
+ self.pre_uid = uid
+
+ user = request.env(user=uid)['res.users'].browse(uid)
+ if not user._mfa_url():
+ self.finalize()
self.rotate = True
self.db = db
- self.uid = uid
self.login = login
- self.session_token = security.compute_session_token(self, request.env)
- request.uid = uid
request.disable_db = False
- self.get_context()
return uid
+ def finalize(self):
+ """ Finalizes a partial session, should be called on MFA validation to
+ convert a partial / pre-session into a full-fledged "logged-in" one
+ """
+ self.rotate = True
+ request.uid = self.uid = self.pop('pre_uid')
+ user = request.env(user=self.uid)['res.users'].browse(self.uid)
+ self.session_token = user._compute_session_token(self.sid)
+ self.get_context()
+
def check_security(self):
"""
Check the current authentication parameters to know if those are still