[FIX] web_editor, website: fix website editor as restricted editor

When assigned the role of restricted editor, there are many ways to
break the web_editor when trying to do actions that should be
unavailable. There is a traceback for the following scenarios under
some circumstances (mainly because of pages without editable areas or
features without the proper access rights):

- Drag and dropping snippet when Restricted Editor.
- Clicking on product when Restricted Editor in /shop.
- Clicking on product image on specific product page.
- Clicking on user name (e.g. Marc Demo).
- Clicking on menu items or logo.
- Clicking on a blog's image in /blog.
- Clicking on a blog's image on specific blog page.
- Clicking on calendar's image in /calendar.

There is now no longer a traceback which makes the editor crash or
freeze. This mimics the behavior in other cases where the editor does
not show a traceback, but there is no message indicating that the action
is unauthorized.

When accessing a menu that cannot be edited, the "Edit the menu" button
is not shown to the restricted editor.

task-2747895
opw-3164176

closes odoo/odoo#118116

X-original-commit: 15c85e4f9f967ee04af3cdeb766d280a2c00731e
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
Co-authored-by: Benjamin Vray <bvr@odoo.com>
Co-authored-by: qsm-odoo <qsm@odoo.com>
This commit is contained in:
Kamen Zhekov
2023-04-11 16:53:47 +02:00
committed by qsm-odoo
co-authored by Benjamin Vray qsm-odoo
parent fbb909b24b
commit 03dd2513b5
3 changed files with 34 additions and 9 deletions
@@ -157,7 +157,15 @@ var SnippetEditor = Widget.extend({
init: function (parent, target, templateOptions, $editable, options) {
this._super.apply(this, arguments);
this.options = options;
this.$editable = $editable;
// This is possible to have a snippet editor not inside an editable area
// (data-no-check="true") and it is possible to not have editable areas
// at all (restricted editor), in that case we just suppose this is the
// body so related code can still be executed without crash (as we still
// need to instantiate instances of editors even if nothing is really
// editable (data-no-check="true" / navigation options / ...)).
// TODO this should probably be reviewed in master: do we need a
// reference to the editable area? There should be workarounds.
this.$editable = $editable && $editable.length ? $editable : $(document.body);
this.ownerDocument = this.$editable[0].ownerDocument;
this.$body = $(this.ownerDocument.body);
this.$target = $(target);
@@ -3166,6 +3174,7 @@ var SnippetsMenu = Widget.extend({
const smoothScrollOptions = this._getScrollOptions({
jQueryDraggableOptions: {
handle: '.oe_snippet_thumbnail:not(.o_we_already_dragging)',
cancel: '.oe_snippet.o_disabled',
helper: function () {
const dragSnip = this.cloneNode(true);
dragSnip.querySelectorAll('.o_delete_btn, .o_rename_btn').forEach(
@@ -343,7 +343,9 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
* @private
*/
_addEditorMessages() {
const $wrap = this.$editable.find('.oe_structure.oe_empty, [data-oe-type="html"]');
const $wrap = this.$editable
.find('.oe_structure.oe_empty, [data-oe-type="html"]')
.filter(':o_editable');
this.$editorMessageElement = $wrap.not('[data-editor-message]')
.attr('data-editor-message-default', true)
.attr('data-editor-message', this.env._t('DRAG BUILDING BLOCKS HERE'));
@@ -29,14 +29,28 @@ const NavbarLinkPopoverWidget = weWidgets.LinkPopoverWidget.extend({
*
* @override
*/
start() {
async start() {
const _super = this._super.bind(this);
this.isWebsiteDesigner = await this._rpc({
'model': 'res.users',
'method': 'has_group',
'args': ['website.group_website_designer'],
});
const $removeLink = this.$('.o_we_remove_link');
// remove link has no sense on navbar menu links, instead show edit menu
const $anchor = $('<a/>', {
href: '#', class: 'ms-2 js_edit_menu', title: _t('Edit Menu'),
'data-bs-placement': 'top', 'data-bs-toggle': 'tooltip',
}).append($('<i/>', {class: 'fa fa-sitemap'}));
this.$('.o_we_remove_link').replaceWith($anchor);
return this._super(...arguments);
if (this.isWebsiteDesigner) {
const $anchor = $('<a/>', {
href: '#', class: 'ms-2 js_edit_menu', title: _t('Edit Menu'),
'data-bs-placement': 'top', 'data-bs-toggle': 'tooltip',
}).append($('<i/>', {class: 'fa fa-sitemap'}));
$removeLink.replaceWith($anchor);
} else {
this.$('.o_we_edit_link').remove();
$removeLink.remove();
}
return _super(...arguments);
},
//--------------------------------------------------------------------------