From e17aef8896e7611d6c3bdb627a4b8f76f612e4a1 Mon Sep 17 00:00:00 2001 From: Florian Damhaut Date: Fri, 17 Feb 2023 08:24:32 +0000 Subject: [PATCH] [IMP] calendar: Make calendar edit more restricted This task change the people who can edit a calendar event. This calendar event currently allow every user to modify every event in the calendar. This cause issue where one user can modify the time-off event for other employees. This PR change the right to modify an event from the calendar view in the calendar app. With these changes, only the people attending an event will be able to modify it from the calendar view. task-id : 3185743 closes odoo/odoo#112964 Signed-off-by: Arnaud Joset --- addons/calendar/models/calendar_event.py | 7 +++ .../attendee_calendar_common_popover.js | 13 ++++- .../attendee_calendar_common_popover.xml | 5 ++ .../attendee_calendar_common_renderer.js | 11 ++++ addons/calendar/tests/test_calendar.py | 5 +- .../tests/test_event_notifications.py | 4 +- addons/calendar/views/calendar_views.xml | 55 ++++++++++--------- .../calendar_common_popover.js | 3 + .../calendar_common_popover.xml | 2 +- 9 files changed, 72 insertions(+), 33 deletions(-) diff --git a/addons/calendar/models/calendar_event.py b/addons/calendar/models/calendar_event.py index 711ccf5d5c1..97fa9577219 100644 --- a/addons/calendar/models/calendar_event.py +++ b/addons/calendar/models/calendar_event.py @@ -221,6 +221,7 @@ class Meeting(models.Model): declined_count = fields.Integer(compute='_compute_attendees_count') tentative_count = fields.Integer(compute='_compute_attendees_count') awaiting_count = fields.Integer(compute="_compute_attendees_count") + user_can_edit = fields.Boolean(compute='_compute_user_can_edit') @api.depends('attendee_ids', 'attendee_ids.state', 'partner_ids') def _compute_attendees_count(self): @@ -241,6 +242,12 @@ class Meeting(models.Model): 'awaiting_count': attendees_count - accepted_count - declined_count - tentative_count }) + @api.depends('partner_ids') + @api.depends_context('uid') + def _compute_user_can_edit(self): + for event in self: + event.user_can_edit = self.env.user in event.partner_ids.user_ids + event.user_id + @api.depends('attendee_ids') def _compute_invalid_email_partner_ids(self): for event in self: diff --git a/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.js b/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.js index a862bc81877..b9c7817a4d9 100644 --- a/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.js +++ b/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.js @@ -32,7 +32,7 @@ export class AttendeeCalendarCommonPopover extends CalendarCommonPopover { } get isCurrentUserAttendee() { - return this.props.record.rawRecord.partner_ids.includes(this.user.partnerId); + return this.props.record.rawRecord.partner_ids.includes(this.user.partnerId) || this.props.record.rawRecord.partner_id[0] === this.user.partnerId; } get isCurrentUserOrganizer() { @@ -69,9 +69,20 @@ export class AttendeeCalendarCommonPopover extends CalendarCommonPopover { * @override */ get isEventEditable() { + return this.isCurrentUserAttendee; + } + + get isEventViewable() { return this.isEventPrivate ? this.isCurrentUserAttendee : super.isEventEditable; } + /** + * @override + */ + get hasFooter() { + return this.isEventViewable || super.hasFooter; + } + async changeAttendeeStatus(selectedStatus) { const record = this.props.record; if (record.attendeeStatus === selectedStatus) { diff --git a/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.xml b/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.xml index 4432f24b770..ed951cab900 100644 --- a/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.xml +++ b/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.xml @@ -7,6 +7,11 @@ + + + View + + Delete
diff --git a/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_renderer.js b/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_renderer.js index a4726cb4e45..5fe511fb28d 100644 --- a/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_renderer.js +++ b/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_renderer.js @@ -1,18 +1,29 @@ /** @odoo-module **/ +import { useService } from "@web/core/utils/hooks"; import { CalendarCommonRenderer } from "@web/views/calendar/calendar_common/calendar_common_renderer"; import { AttendeeCalendarCommonPopover } from "@calendar/views/attendee_calendar/common/attendee_calendar_common_popover"; export class AttendeeCalendarCommonRenderer extends CalendarCommonRenderer { + + setup() { + super.setup(); + this.user = useService("user"); + } /** * @override * * Give a new key to our fc records to be able to iterate through in templates */ convertRecordToEvent(record) { + let editable = false; + if (record && record.rawRecord) { + editable = record.rawRecord.partner_ids.includes(this.user.partnerId) + } return { ...super.convertRecordToEvent(record), id: record._recordId || record.id, + editable: editable, }; } diff --git a/addons/calendar/tests/test_calendar.py b/addons/calendar/tests/test_calendar.py index 0c7d4228f20..b317acbd445 100644 --- a/addons/calendar/tests/test_calendar.py +++ b/addons/calendar/tests/test_calendar.py @@ -214,8 +214,9 @@ class TestCalendar(SavepointCaseWithUserDemo): self.assertEqual(d.minute, 30) def test_recurring_ny(self): - self.env.user.tz = 'US/Eastern' - f = Form(self.CalendarEvent.with_context(tz='US/Eastern')) + self.user_demo.tz = 'US/Eastern' + event = self.CalendarEvent.create({'user_id': self.user_demo.id, 'name': 'test', 'partner_ids': [Command.link(self.user_demo.partner_id.id)]}) + f = Form(event.with_context(tz='US/Eastern').with_user(self.user_demo)) f.name = 'test' f.start = '2022-07-07 01:00:00' # This is in UTC. In NY, it corresponds to the 6th of july at 9pm. f.recurrency = True diff --git a/addons/calendar/tests/test_event_notifications.py b/addons/calendar/tests/test_event_notifications.py index de2d982b396..8241aef3c9c 100644 --- a/addons/calendar/tests/test_event_notifications.py +++ b/addons/calendar/tests/test_event_notifications.py @@ -161,13 +161,13 @@ class TestEventNotifications(TransactionCase, MailCase, CronMixinCase): def test_email_alarm(self): now = fields.Datetime.now() with self.capture_triggers('calendar.ir_cron_scheduler_alarm') as capt: - alarm = self.env['calendar.alarm'].create({ + alarm = self.env['calendar.alarm'].with_user(self.user).create({ 'name': 'Alarm', 'alarm_type': 'email', 'interval': 'minutes', 'duration': 20, }) - self.event.write({ + self.event.with_user(self.user).write({ 'name': 'test event', 'start': now + relativedelta(minutes=15), 'stop': now + relativedelta(minutes=18), diff --git a/addons/calendar/views/calendar_views.xml b/addons/calendar/views/calendar_views.xml index 3600a25e4ad..ecfe36748c6 100644 --- a/addons/calendar/views/calendar_views.xml +++ b/addons/calendar/views/calendar_views.xml @@ -114,28 +114,29 @@ +

- +

- - - - - + + + + + @@ -166,10 +167,10 @@ @@ -193,6 +194,7 @@ context="{'force_email':True}" domain="[('type','!=','private')]" class="oe_inline" + attrs="{'readonly': [('user_can_edit', '=', False)]}" />
@@ -206,23 +208,23 @@
- +
@@ -231,13 +233,13 @@ + 'invisible': [('month_by', '!=', 'date')], 'readonly': [('user_can_edit', '=', False)]}"/> + 'invisible': [('month_by', '!=', 'day')], 'readonly': [('user_can_edit', '=', False)]}"/> + 'invisible': [('month_by', '!=', 'day')], 'readonly': [('user_can_edit', '=', False)]}"/>
@@ -248,7 +250,7 @@
- +
-