From 60845c8d73e466ec76d95dd3106594b16bd9f166 Mon Sep 17 00:00:00 2001 From: pedrambiria Date: Mon, 16 Jan 2023 12:10:31 +0000 Subject: [PATCH] [FIX] microsoft_calendar: prevent spamming after syncing the 2nd user Before this commit: If the Odoo database is shared amongst multiple users, and another user wants to sync their Outlook calendar with Odoo Calendar, Outlook will again pull the existing Odoo Calendar events during the sync and treat them as new events, causing Outlook to send email invitations to all event attendees. Steps to reproduce the issue: 1. Create two users in Odoo 2. Create two outlook accounts 3. Change the email of Odoo's users to the same as the outlook accounts 4. Create some shared events with the second user on the first outlook calendar and vice versa 5. Sync the first user's calendar with Outlook 6. When the events are fetched to the Odoo, sync the second user => emails send to the attendees The solution is to exclude synced events from the first synchronization. opw-2929673 closes odoo/odoo#112931 X-original-commit: 86862f2527341247b75df155de16b09d44a7eee6 Signed-off-by: Pedram Bi Ria (pebr) --- addons/microsoft_calendar/models/calendar.py | 3 ++- .../models/calendar_recurrence_rule.py | 3 ++- .../models/microsoft_sync.py | 24 ++++++++++++------- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/addons/microsoft_calendar/models/calendar.py b/addons/microsoft_calendar/models/calendar.py index 6fca702932e..09fae1be09d 100644 --- a/addons/microsoft_calendar/models/calendar.py +++ b/addons/microsoft_calendar/models/calendar.py @@ -131,13 +131,14 @@ class Meeting(models.Model): day_range = int(ICP.get_param('microsoft_calendar.sync.range_days', default=365)) lower_bound = fields.Datetime.subtract(fields.Datetime.now(), days=day_range) upper_bound = fields.Datetime.add(fields.Datetime.now(), days=day_range) - return [ + domain = [ ('partner_ids.user_ids', 'in', self.env.user.id), ('stop', '>', lower_bound), ('start', '<', upper_bound), # Do not sync events that follow the recurrence, they are already synced at recurrence creation '!', '&', '&', ('recurrency', '=', True), ('recurrence_id', '!=', False), ('follow_recurrence', '=', True) ] + return self._extend_microsoft_domain(domain) @api.model diff --git a/addons/microsoft_calendar/models/calendar_recurrence_rule.py b/addons/microsoft_calendar/models/calendar_recurrence_rule.py index 57195abed1a..fc1aa66f77c 100644 --- a/addons/microsoft_calendar/models/calendar_recurrence_rule.py +++ b/addons/microsoft_calendar/models/calendar_recurrence_rule.py @@ -138,7 +138,8 @@ class RecurrenceRule(models.Model): # older versions of the module. When synced, these recurrence may come back from Microsoft after database cleaning # and trigger errors as the records are not properly populated. # We also prevent sync of other user recurrent events. - return [('calendar_event_ids.user_id', '=', self.env.user.id), ('rrule', '!=', False)] + domain = [('calendar_event_ids.user_id', '=', self.env.user.id), ('rrule', '!=', False)] + return self._extend_microsoft_domain(domain) def _cancel_microsoft(self): self.calendar_event_ids._cancel_microsoft() diff --git a/addons/microsoft_calendar/models/microsoft_sync.py b/addons/microsoft_calendar/models/microsoft_sync.py index 68eed99017d..49b169154fa 100644 --- a/addons/microsoft_calendar/models/microsoft_sync.py +++ b/addons/microsoft_calendar/models/microsoft_sync.py @@ -461,14 +461,7 @@ class MicrosoftSync(models.AbstractModel): :param full_sync: If True, all events attended by the user are returned :return: events """ - domain = self._get_microsoft_sync_domain() - if not full_sync: - is_active_clause = (self._active_name, '=', True) if self._active_name else expression.TRUE_LEAF - domain = expression.AND([domain, [ - '|', - '&', ('ms_universal_event_id', '=', False), is_active_clause, - ('need_sync_m', '=', True), - ]]) + domain = self.with_context(full_sync_m=full_sync)._get_microsoft_sync_domain() return self.with_context(active_test=False).search(domain) @api.model @@ -513,3 +506,18 @@ class MicrosoftSync(models.AbstractModel): a given user. """ raise NotImplementedError() + + def _extend_microsoft_domain(self, domain): + """ Extends the sync domain based on the full_sync_m context parameter. + In case of full sync it shouldn't include already synced events. + """ + if self._context.get('full_sync_m', True): + domain = expression.AND([domain, [('ms_universal_event_id', '=', False)]]) + else: + is_active_clause = (self._active_name, '=', True) if self._active_name else expression.TRUE_LEAF + domain = expression.AND([domain, [ + '|', + '&', ('ms_universal_event_id', '=', False), is_active_clause, + ('need_sync_m', '=', True), + ]]) + return domain