From ed02c3285318ce92c452cd407b1ce59e4ad54ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Baranx=20=28bar=29?= Date: Wed, 26 Jan 2022 10:23:19 +0000 Subject: [PATCH] [FIX] google_calendar: allow user to reset his own tokens only Each user should be able to reset his own google calendar token. An admin user (from `base.group_system`) should be able to reset any tokens. Task-2673934 closes odoo/odoo#83397 Signed-off-by: Arnaud Joset --- addons/google_calendar/__manifest__.py | 1 + .../models/google_credentials.py | 8 +-- .../security/google_calendar_security.xml | 24 +++++++ .../security/ir.model.access.csv | 2 +- addons/google_calendar/tests/__init__.py | 1 + .../tests/test_token_access.py | 66 +++++++++++++++++++ 6 files changed, 97 insertions(+), 5 deletions(-) create mode 100644 addons/google_calendar/security/google_calendar_security.xml create mode 100644 addons/google_calendar/tests/test_token_access.py diff --git a/addons/google_calendar/__manifest__.py b/addons/google_calendar/__manifest__.py index e46a736c054..ff737785bbc 100644 --- a/addons/google_calendar/__manifest__.py +++ b/addons/google_calendar/__manifest__.py @@ -8,6 +8,7 @@ 'depends': ['google_account', 'calendar'], 'data': [ 'data/google_calendar_data.xml', + 'security/google_calendar_security.xml', 'security/ir.model.access.csv', 'wizard/reset_account_views.xml', 'views/res_config_settings_views.xml', diff --git a/addons/google_calendar/models/google_credentials.py b/addons/google_calendar/models/google_credentials.py index 3e16d21ccb7..4ec06bb18ca 100644 --- a/addons/google_calendar/models/google_credentials.py +++ b/addons/google_calendar/models/google_credentials.py @@ -20,10 +20,10 @@ class GoogleCredentials(models.Model): _description = 'Google Calendar Account Data' user_ids = fields.One2many('res.users', 'google_cal_account_id', required=True) - calendar_rtoken = fields.Char('Refresh Token', copy=False, groups="base.group_system") - calendar_token = fields.Char('User token', copy=False, groups="base.group_system") - calendar_token_validity = fields.Datetime('Token Validity', copy=False, groups="base.group_system") - calendar_sync_token = fields.Char('Next Sync Token', copy=False, groups="base.group_system") + calendar_rtoken = fields.Char('Refresh Token', copy=False) + calendar_token = fields.Char('User token', copy=False) + calendar_token_validity = fields.Datetime('Token Validity', copy=False) + calendar_sync_token = fields.Char('Next Sync Token', copy=False) calendar_cal_id = fields.Char('Calendar ID', copy=False, help='Last Calendar ID who has been synchronized. If it is changed, we remove all links between GoogleID and Odoo Google Internal ID') synchronization_stopped = fields.Boolean('Google Synchronization stopped', copy=False) diff --git a/addons/google_calendar/security/google_calendar_security.xml b/addons/google_calendar/security/google_calendar_security.xml new file mode 100644 index 00000000000..5dc9f08304e --- /dev/null +++ b/addons/google_calendar/security/google_calendar_security.xml @@ -0,0 +1,24 @@ + + + + Google Calendar NOT own token access rule + + [('user_ids', 'not in', user.id)] + + + + + + + + Google Calendar own token access rule + + [('user_ids', 'in', user.id)] + + + + + + + + diff --git a/addons/google_calendar/security/ir.model.access.csv b/addons/google_calendar/security/ir.model.access.csv index f2f622519e3..072fb3c6c7f 100644 --- a/addons/google_calendar/security/ir.model.access.csv +++ b/addons/google_calendar/security/ir.model.access.csv @@ -1,4 +1,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink google_calendar_account_reset,google_calendar_account_reset_access_right,model_google_calendar_account_reset,base.group_system,1,1,1,0 -google_calendar.access_google_calendar_credentials,access_google_calendar_credentials,google_calendar.model_google_calendar_credentials,base.group_user,1,0,0,0 +google_calendar.access_google_calendar_credentials,access_google_calendar_credentials,google_calendar.model_google_calendar_credentials,base.group_user,1,1,0,0 google_calendar_manager,access_google_calendar_credentials_manager,google_calendar.model_google_calendar_credentials,base.group_system,1,1,0,0 diff --git a/addons/google_calendar/tests/__init__.py b/addons/google_calendar/tests/__init__.py index 7eafa0298f7..465c59b9b24 100644 --- a/addons/google_calendar/tests/__init__.py +++ b/addons/google_calendar/tests/__init__.py @@ -4,3 +4,4 @@ from . import test_sync_common from . import test_sync_google2odoo from . import test_sync_odoo2google +from . import test_token_access diff --git a/addons/google_calendar/tests/test_token_access.py b/addons/google_calendar/tests/test_token_access.py new file mode 100644 index 00000000000..21749f495d0 --- /dev/null +++ b/addons/google_calendar/tests/test_token_access.py @@ -0,0 +1,66 @@ +from odoo import fields, Command +from odoo.exceptions import AccessError +from odoo.tests.common import TransactionCase + +class TestTokenAccess(TransactionCase): + + @classmethod + def setUpClass(cls): + super().setUpClass() + + cls.users = [] + for u in ('user1', 'user2'): + credentials = cls.env['google.calendar.credentials'].create({ + 'calendar_rtoken': f'{u}_rtoken', + 'calendar_token': f'{u}_token', + 'calendar_token_validity': fields.Datetime.today(), + 'calendar_sync_token': f'{u}_sync_token', + }) + user = cls.env['res.users'].create({ + 'name': f'{u}', + 'login': f'{u}', + 'email': f'{u}@odoo.com', + 'google_cal_account_id': credentials.id, + }) + cls.users += [user] + + cls.system_user = cls.env['res.users'].create({ + 'name': 'system_user', + 'login': 'system_user', + 'email': 'system_user@odoo.com', + 'groups_id': [Command.link(cls.env.ref('base.group_system').id)], + }) + + def test_normal_user_should_be_able_to_reset_his_own_token(self): + user = self.users[0] + old_validity = user.google_cal_account_id.calendar_token_validity + + user.with_user(user).google_cal_account_id._set_auth_tokens('my_new_token', 'my_new_rtoken', 3600) + + self.assertEqual(user.google_cal_account_id.calendar_rtoken, 'my_new_rtoken') + self.assertEqual(user.google_cal_account_id.calendar_token, 'my_new_token') + self.assertNotEqual( + user.google_cal_account_id.calendar_token_validity, + old_validity + ) + + def test_normal_user_should_not_be_able_to_reset_other_user_tokens(self): + user1, user2 = self.users + + with self.assertRaises(AccessError): + user2.with_user(user1).google_cal_account_id._set_auth_tokens(False, False, 0) + + def test_system_user_should_be_able_to_reset_any_tokens(self): + user = self.users[0] + old_validity = user.google_cal_account_id.calendar_token_validity + + user.with_user(self.system_user).google_cal_account_id._set_auth_tokens( + 'my_new_token', 'my_new_rtoken', 3600 + ) + + self.assertEqual(user.google_cal_account_id.calendar_rtoken, 'my_new_rtoken') + self.assertEqual(user.google_cal_account_id.calendar_token, 'my_new_token') + self.assertNotEqual( + user.google_cal_account_id.calendar_token_validity, + old_validity + )