diff options
| author | Hiral Bhavsar <hbh@odoo.com> | 2020-01-02 07:22:46 +0000 |
|---|---|---|
| committer | Alexandre Kühn <aku@odoo.com> | 2020-03-20 10:09:10 +0000 |
| commit | 73834a659c72639b1c3e2a18bfd431b35089ef1e (patch) | |
| tree | 812e0840fdeb1b01665ce4458d369e0f2137a1cc | |
| parent | 3e9293e0e8bfa6561288b03980e7fe34206a3087 (diff) | |
[IMP] calendar, web: private events shouldn't be editable/deletable
Before this commit, when user attempts to edit or delete a private
event without being an attendee, it raises an access right error.
This commit disables edit and delete buttons in this case, in
addition to hide event details.
task-2151150
Closes https://github.com/odoo/odoo/pull/42569
closes odoo/odoo#42569
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
| -rw-r--r-- | addons/calendar/models/calendar.py | 6 | ||||
| -rw-r--r-- | addons/calendar/static/src/js/calendar_view.js | 49 | ||||
| -rw-r--r-- | addons/calendar/static/src/xml/base_calendar.xml | 2 | ||||
| -rw-r--r-- | addons/calendar/views/calendar_views.xml | 1 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/calendar/calendar_popover.js | 25 | ||||
| -rw-r--r-- | addons/web/static/src/xml/web_calendar.xml | 6 |
6 files changed, 78 insertions, 11 deletions
diff --git a/addons/calendar/models/calendar.py b/addons/calendar/models/calendar.py index 59a8a11bcda..1007c1457b4 100644 --- a/addons/calendar/models/calendar.py +++ b/addons/calendar/models/calendar.py @@ -781,9 +781,9 @@ class Meeting(models.Model): event_tz = fields.Selection('_event_tz_get', string='Timezone', default=lambda self: self.env.context.get('tz') or self.user_id.tz) duration = fields.Float('Duration', states={'done': [('readonly', True)]}) description = fields.Text('Description', states={'done': [('readonly', True)]}) - privacy = fields.Selection([('public', 'Everyone'), ('private', 'Only me'), ('confidential', 'Only internal users')], 'Privacy', default='public', states={'done': [('readonly', True)]}) + privacy = fields.Selection([('public', 'Everyone'), ('private', 'Only me'), ('confidential', 'Only internal users')], 'Privacy', default='public', states={'done': [('readonly', True)]}, required=True) location = fields.Char('Location', states={'done': [('readonly', True)]}, tracking=True, help="Location of Event") - show_as = fields.Selection([('free', 'Free'), ('busy', 'Busy')], 'Show Time as', states={'done': [('readonly', True)]}, default='busy') + show_as = fields.Selection([('free', 'Free'), ('busy', 'Busy')], 'Show Time as', states={'done': [('readonly', True)]}, default='busy', required=True) # linked document res_id = fields.Integer('Document ID') @@ -1692,7 +1692,7 @@ class Meeting(models.Model): if r['privacy'] == 'private': for f in r: recurrent_fields = self._get_recurrent_fields() - public_fields = list(set(recurrent_fields + ['id', 'active', 'allday', 'start', 'stop', 'display_start', 'display_stop', 'duration', 'user_id', 'state', 'interval', 'count', 'recurrent_id_date', 'rrule'])) + public_fields = list(set(recurrent_fields + ['id', 'active', 'allday', 'start', 'stop', 'display_start', 'display_stop', 'duration', 'user_id', 'state', 'interval', 'count', 'recurrent_id_date', 'rrule', 'privacy'])) if f not in public_fields: if isinstance(r[f], list): r[f] = [] diff --git a/addons/calendar/static/src/js/calendar_view.js b/addons/calendar/static/src/js/calendar_view.js index 7ed963183d1..1717deb7899 100644 --- a/addons/calendar/static/src/js/calendar_view.js +++ b/addons/calendar/static/src/js/calendar_view.js @@ -4,6 +4,7 @@ odoo.define('calendar.CalendarView', function (require) { var CalendarPopover = require('web.CalendarPopover'); var CalendarRenderer = require('web.CalendarRenderer'); var CalendarView = require('web.CalendarView'); +const session = require('web.session'); var viewRegistry = require('web.view_registry'); var AttendeeCalendarPopover = CalendarPopover.extend({ @@ -17,10 +18,8 @@ var AttendeeCalendarPopover = CalendarPopover.extend({ init: function () { var self = this; this._super.apply(this, arguments); - var session = this.getSession(); // Show status dropdown if user is in attendees list - this.showStatusDropdown = _.contains(this.event.record.partner_ids, session.partner_id); - if (this.showStatusDropdown) { + if (this.isCurrentPartnerAttendee()) { this.statusColors = {accepted: 'text-success', declined: 'text-danger', tentative: 'text-muted', needsAction: 'text-dark'}; this.statusInfo = {}; _.each(this.fields.attendee_status.selection, function (selection) { @@ -31,6 +30,50 @@ var AttendeeCalendarPopover = CalendarPopover.extend({ }, //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * @return {boolean} + */ + isCurrentPartnerAttendee() { + return this.event.record.partner_ids.includes(session.partner_id); + }, + /** + * @override + * @return {boolean} + */ + isEventDeletable() { + return this._super() && (this._isEventPrivate() ? this.isCurrentPartnerAttendee() : true); + }, + /** + * @override + * @return {boolean} + */ + isEventDetailsVisible() { + return this._isEventPrivate() ? this.isCurrentPartnerAttendee() : this._super(); + }, + /** + * @override + * @return {boolean} + */ + isEventEditable() { + return this._isEventPrivate() ? this.isCurrentPartnerAttendee() : this._super(); + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + * @return {boolean} + */ + _isEventPrivate() { + return this.event.record.privacy === 'private'; + }, + + //-------------------------------------------------------------------------- // Handlers //-------------------------------------------------------------------------- diff --git a/addons/calendar/static/src/xml/base_calendar.xml b/addons/calendar/static/src/xml/base_calendar.xml index c367c192e67..22af9cbee03 100644 --- a/addons/calendar/static/src/xml/base_calendar.xml +++ b/addons/calendar/static/src/xml/base_calendar.xml @@ -30,7 +30,7 @@ <t t-name="Calendar.attendee.status.popover" t-extend="CalendarView.event.popover"> <t t-jquery=".o_cw_popover_delete" t-operation="after"> - <div t-if="widget.showStatusDropdown" class="btn-group o-calendar-attendee-status ml-2"> + <div t-if="widget.isCurrentPartnerAttendee()" class="btn-group o-calendar-attendee-status ml-2"> <a href="#" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <i t-attf-class="fa fa-circle o-calendar-attendee-status-icon #{widget.selectedStatusInfo.color}"/> <span class="o-calendar-attendee-status-text" t-esc="widget.selectedStatusInfo.text"></span> </a> diff --git a/addons/calendar/views/calendar_views.xml b/addons/calendar/views/calendar_views.xml index 0566e4973fb..99111bc42be 100644 --- a/addons/calendar/views/calendar_views.xml +++ b/addons/calendar/views/calendar_views.xml @@ -267,6 +267,7 @@ <field name="partner_ids" widget="many2many_tags_avatar" write_model="calendar.contacts" write_field="partner_id" avatar_field="image_128"/> <field name="is_highlighted" invisible="1"/> <field name="description"/> + <field name="privacy"/> </calendar> </field> </record> diff --git a/addons/web/static/src/js/views/calendar/calendar_popover.js b/addons/web/static/src/js/views/calendar/calendar_popover.js index 1094f345c7d..8a5e5a7ecae 100644 --- a/addons/web/static/src/js/views/calendar/calendar_popover.js +++ b/addons/web/static/src/js/views/calendar/calendar_popover.js @@ -27,7 +27,7 @@ var CalendarPopover = Widget.extend(StandaloneFieldManagerMixin, { this.fields = eventInfo.fields; this.event = eventInfo.event; this.modelName = eventInfo.modelName; - this.canDelete = eventInfo.canDelete; + this._canDelete = eventInfo.canDelete; }, /** * @override @@ -47,6 +47,29 @@ var CalendarPopover = Widget.extend(StandaloneFieldManagerMixin, { }, //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * @return {boolean} + */ + isEventDeletable() { + return this._canDelete;; + }, + /** + * @return {boolean} + */ + isEventDetailsVisible() { + return true; + }, + /** + * @return {boolean} + */ + isEventEditable() { + return true; + }, + + //-------------------------------------------------------------------------- // Private //-------------------------------------------------------------------------- diff --git a/addons/web/static/src/xml/web_calendar.xml b/addons/web/static/src/xml/web_calendar.xml index 1ab1d935896..be0d645e45f 100644 --- a/addons/web/static/src/xml/web_calendar.xml +++ b/addons/web/static/src/xml/web_calendar.xml @@ -42,10 +42,10 @@ <b t-esc="widget.eventTime.time"/> <small t-if="widget.eventTime.duration"><b t-esc="_.str.sprintf('(%s)', widget.eventTime.duration)"/></small> </li> </ul> - <ul class="list-group list-group-flush o_cw_popover_fields_secondary"/> + <ul t-if="widget.isEventDetailsVisible()" class="list-group list-group-flush o_cw_popover_fields_secondary"/> <div class="card-footer border-top"> - <a href="#" class="btn btn-primary o_cw_popover_edit">Edit</a> - <a t-if="widget.canDelete" href="#" class="btn btn-secondary o_cw_popover_delete ml-2">Delete</a> + <a t-if="widget.isEventEditable()" href="#" class="btn btn-primary o_cw_popover_edit">Edit</a> + <a t-if="widget.isEventDeletable()" href="#" class="btn btn-secondary o_cw_popover_delete ml-2">Delete</a> </div> </div> </t> |
