From bcda21d4c95b3310ba1cfb4f786316938046d14b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Fri, 6 Jan 2023 14:52:00 +0100 Subject: [PATCH] saml: create a new session if expired during passive SSO (#72898) --- tests/test_saml_auth.py | 31 +++++++++++++++++++++++++++++++ wcs/root.py | 8 +++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/tests/test_saml_auth.py b/tests/test_saml_auth.py index 983c7771a..35c70e156 100644 --- a/tests/test_saml_auth.py +++ b/tests/test_saml_auth.py @@ -674,3 +674,34 @@ def test_no_opened_session_cookie(pub): assert resp.status_int == 200 cookie_name = '%s-passive-auth-tried' % pub.config.session_cookie_name assert cookie_name not in app.cookies + + +def test_expired_opened_session_cookie_menu_json(pub): + app = get_app(pub) + app.get('/') # init pub, set app_dir, etc. + + pub.site_options.set('options', 'idp_session_cookie_name', 'IDP_OPENED_SESSION') + with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd: + pub.site_options.write(fd) + + app.set_cookie('IDP_OPENED_SESSION', '1') + + # simulate a saml login + user = pub.user_class() + user.store() + request = mock.Mock() + request.get_environ.return_value = '1.1.1.1' + with mock.patch('quixote.session.get_request', return_value=request), mock.patch( + 'wcs.qommon.saml2', return_value=mock.Mock(cookies={'IDP_OPENED_SESSION': '2'}) + ): + session = get_session_manager().session_class(id=None) + session.set_user(user.id) + session.opened_session_value = '2' + session.id = 'abcd' + session.store() + app.set_cookie(pub.config.session_cookie_name, session.id) + app.set_cookie(pub.config.session_cookie_name + '-passive-auth-tried', '3') + + # access to a restricted page with no session on the idp or passive sso already tried + app.set_cookie('IDP_OPENED_SESSION', '3') + app.get('/backoffice/menu.json', status=302) diff --git a/wcs/root.py b/wcs/root.py index 796ab57a4..6c46d7cf5 100644 --- a/wcs/root.py +++ b/wcs/root.py @@ -347,7 +347,13 @@ class RootDirectory(Directory): if idp_session_cookie_name not in cookies or cookies.get(idp_session_cookie_name) == cookies.get( passive_tried_cookie_name ): - # no session on the idp or passive sso already tried, stop here. + # no session on the idp or passive sso already tried, init a new session if necessary + # (because it was explicitly expired just above), then let the flow continue and the + # expected page be served. + if get_session() is None: + # init a new session + get_publisher().session_manager.start_request() + get_publisher().session_manager.maintain_session(get_session()) return response.set_cookie( passive_tried_cookie_name, -- 2.39.2