summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiral Bhavsar <hbh@odoo.com>2020-01-02 07:22:46 +0000
committerAlexandre Kühn <aku@odoo.com>2020-03-20 10:09:10 +0000
commit73834a659c72639b1c3e2a18bfd431b35089ef1e (patch)
tree812e0840fdeb1b01665ce4458d369e0f2137a1cc
parent3e9293e0e8bfa6561288b03980e7fe34206a3087 (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.py6
-rw-r--r--addons/calendar/static/src/js/calendar_view.js49
-rw-r--r--addons/calendar/static/src/xml/base_calendar.xml2
-rw-r--r--addons/calendar/views/calendar_views.xml1
-rw-r--r--addons/web/static/src/js/views/calendar/calendar_popover.js25
-rw-r--r--addons/web/static/src/xml/web_calendar.xml6
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>