From 203c03e2626c891fafb1b6e606e4f76f249e3acb Mon Sep 17 00:00:00 2001 From: George Daramouskas Date: Thu, 31 Jan 2019 14:48:16 +0100 Subject: [PATCH 1/3] [FIX] Use _compute_session_token to invalidate user sessions on auth_session_timeout --- auth_session_timeout/models/res_users.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/auth_session_timeout/models/res_users.py b/auth_session_timeout/models/res_users.py index 04c5bc4c6..c22e17920 100644 --- a/auth_session_timeout/models/res_users.py +++ b/auth_session_timeout/models/res_users.py @@ -102,9 +102,8 @@ class ResUsers(models.Model): 'Exception updating session file access/modified times.', ) - @classmethod - def check(cls, *args, **kwargs): - res = super(ResUsers, cls).check(*args, **kwargs) + def _compute_session_token(self, sid): + res = super(ResUsers, self)._compute_session_token(sid) if http.request: http.request.env.user._auth_timeout_check() return res From 87eb1d11ecab6804c04b3ae6410440bbadbdbc80 Mon Sep 17 00:00:00 2001 From: George Daramouskas Date: Thu, 21 Mar 2019 16:14:12 +0100 Subject: [PATCH 2/3] fixup! [FIX] Use _compute_session_token to invalidate user sessions on auth_session_timeout --- auth_session_timeout/tests/test_res_users.py | 64 +++++++++++++------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/auth_session_timeout/tests/test_res_users.py b/auth_session_timeout/tests/test_res_users.py index ad601202e..253623369 100644 --- a/auth_session_timeout/tests/test_res_users.py +++ b/auth_session_timeout/tests/test_res_users.py @@ -17,15 +17,23 @@ class EndTestException(Exception): class TestResUsers(TransactionCase): + post_install = True + at_install = False + def setUp(self): super(TestResUsers, self).setUp() - self.ResUsers = self.env['res.users'] + self.TestUser = self.env['res.users'].create({ + 'login': 'test_user', + 'name': 'test_user', + }) @contextmanager def _mock_assets(self, assets=None): - """ It provides mocked imports from res_users.py - :param assets: (list) Name of imports to mock. Mocks `http` if None - :return: (dict) Dictionary of mocks, keyed by module name + """ Multi patch names in `odoo.addons.auth_session_timeout.models. + res_users` for mocking them. + + :param assets: The symbols in res_users that will be patched with + MagicMock objects. """ if assets is None: assets = ['http'] @@ -43,20 +51,25 @@ class TestResUsers(TransactionCase): self.path = '/this/is/a/test/path' get_filename = http_mock.root.session_store.get_session_filename get_filename.return_value = self.path - return self.ResUsers._auth_timeout_check() + return self.TestUser._auth_timeout_check() def test_session_validity_no_request(self): - """ It should return immediately if no request """ + """ Tests what happens when the user being tested has not made any + requests. + """ with self._mock_assets() as assets: assets['http'].request = False res = self._auth_timeout_check(assets['http']) self.assertFalse(res) def test_session_validity_gets_session_file(self): - """ It should call get the session file for the session id """ + """ All the sessions a user generates are saved as a file in the + filesystem by Werkzeug. + + This function makes sure that our `_auth_timeout_check` makes an + attempt in fetching that file by the correct session id. + """ with self._mock_assets() as assets: - get_params = assets['http'].request.env[''].get_session_parameters - get_params.return_value = 0, [] store = assets['http'].root.session_store store.get_session_filename.side_effect = EndTestException with self.assertRaises(EndTestException): @@ -66,10 +79,10 @@ class TestResUsers(TransactionCase): ) def test_session_validity_logout(self): - """ It should log out of session if past deadline """ + """ Forcefully expire an already existing session and see if the user + is actually logged out. + """ with self._mock_assets(['http', 'getmtime', 'utime']) as assets: - get_params = assets['http'].request.env[''].get_session_parameters - get_params.return_value = -9999, [] assets['getmtime'].return_value = 0 self._auth_timeout_check(assets['http']) assets['http'].request.session.logout.assert_called_once_with( @@ -77,10 +90,14 @@ class TestResUsers(TransactionCase): ) def test_session_validity_updates_utime(self): - """ It should update utime of session file if not expired """ + """ When a user makes a request, `_auth_timeout_check` is keeping the + user's time of request by setting the access time of the session file + using utime. + + This function asserts that the access time of the session file is set + correctly. + """ with self._mock_assets(['http', 'getmtime', 'utime']) as assets: - get_params = assets['http'].request.env[''].get_session_parameters - get_params.return_value = 9999, [] self._auth_timeout_check(assets['http']) assets['utime'].assert_called_once_with( assets['http'].root.session_store.get_session_filename(), @@ -89,20 +106,25 @@ class TestResUsers(TransactionCase): @mute_logger('odoo.addons.auth_session_timeout.models.res_users') def test_session_validity_os_error_guard(self): - """ It should properly guard from OSError & return """ + """ Make sure that when we get an OSError while trying to set up an + access time the session is terminated immediately. + """ with self._mock_assets(['http', 'utime', 'getmtime']) as assets: - get_params = assets['http'].request.env[''].get_session_parameters - get_params.return_value = 0, [] assets['getmtime'].side_effect = OSError res = self._auth_timeout_check(assets['http']) self.assertFalse(res) def test_on_timeout_session_loggedout(self): + """ Make sure that when the timeout has come, the user is actually + logged out. + """ with self._mock_assets(['http', 'getmtime']) as assets: assets['getmtime'].return_value = 0 - assets['http'].request.session.uid = self.env.uid + attrs = {'__nonzero__': lambda self: True} + assets['http'].request.configure_mock(**attrs) + assets['http'].request.session.uid = self.TestUser.id assets['http'].request.session.dbname = self.env.cr.dbname - assets['http'].request.session.sid = 123 + assets['http'].request.session.sid = '123' assets['http'].request.session.logout = mock.Mock() - self.ResUsers._auth_timeout_check() + self.TestUser._compute_session_token('123') self.assertTrue(assets['http'].request.session.logout.called) From 85141533a604af15cdb8d9cb37cdbd3aff31b862 Mon Sep 17 00:00:00 2001 From: George Daramouskas Date: Thu, 21 Mar 2019 16:45:45 +0100 Subject: [PATCH 3/3] fixup! fixup! [FIX] Use _compute_session_token to invalidate user sessions on auth_session_timeout --- auth_session_timeout/tests/test_res_users.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/auth_session_timeout/tests/test_res_users.py b/auth_session_timeout/tests/test_res_users.py index 253623369..a96d030c3 100644 --- a/auth_session_timeout/tests/test_res_users.py +++ b/auth_session_timeout/tests/test_res_users.py @@ -32,7 +32,7 @@ class TestResUsers(TransactionCase): """ Multi patch names in `odoo.addons.auth_session_timeout.models. res_users` for mocking them. - :param assets: The symbols in res_users that will be patched with + :param assets: The symbols in res_users that will be patched with MagicMock objects. """ if assets is None: @@ -64,7 +64,7 @@ class TestResUsers(TransactionCase): def test_session_validity_gets_session_file(self): """ All the sessions a user generates are saved as a file in the - filesystem by Werkzeug. + filesystem by Werkzeug. This function makes sure that our `_auth_timeout_check` makes an attempt in fetching that file by the correct session id. @@ -120,8 +120,7 @@ class TestResUsers(TransactionCase): """ with self._mock_assets(['http', 'getmtime']) as assets: assets['getmtime'].return_value = 0 - attrs = {'__nonzero__': lambda self: True} - assets['http'].request.configure_mock(**attrs) + assets['http'].request.env.user = self.TestUser assets['http'].request.session.uid = self.TestUser.id assets['http'].request.session.dbname = self.env.cr.dbname assets['http'].request.session.sid = '123'