summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Lefèvre <lul@odoo.com>2020-03-04 14:54:52 +0000
committerLucas Lefèvre <lul@odoo.com>2020-03-04 16:15:56 +0000
commit7032dde60a60c6fba730c236b89189a8f56f2bd0 (patch)
tree7e79af74858bb5410cfad0aaf504f319d8badc76
parent01497474d7dea1f1f8f24230995d94edcf210602 (diff)
[IMP] web: Add quick security access to debug menu
PURPOSE Debugging access issues can quickly be a pain. The goal is to allow to easily debug an access rights issue from the debug tools. SPECIFICATION In the debug tools, add the following two new items: - View Access Rights - View Record Rules closes odoo/odoo#46906 Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
-rw-r--r--addons/web/static/src/js/tools/debug_manager.js13
-rw-r--r--addons/web/static/src/js/tools/debug_manager_backend.js85
-rw-r--r--addons/web/static/src/xml/debug.xml3
3 files changed, 77 insertions, 24 deletions
diff --git a/addons/web/static/src/js/tools/debug_manager.js b/addons/web/static/src/js/tools/debug_manager.js
index 8bbdd2bbe1b..b0560805594 100644
--- a/addons/web/static/src/js/tools/debug_manager.js
+++ b/addons/web/static/src/js/tools/debug_manager.js
@@ -107,6 +107,19 @@ var DebugManager = Widget.extend({
qs.debug = '';
window.location.search = '?' + $.param(qs);
},
+ /**
+ * @private
+ * @param {string} model
+ * @param {string} operation
+ * @returns {Promise<boolean>}
+ */
+ _checkAccessRight(model, operation) {
+ return this._rpc({
+ model: model,
+ method: 'check_access_rights',
+ kwargs: {operation, raise_exception: false},
+ })
+ },
});
return DebugManager;
diff --git a/addons/web/static/src/js/tools/debug_manager_backend.js b/addons/web/static/src/js/tools/debug_manager_backend.js
index f9be341d3ec..2c445ff745e 100644
--- a/addons/web/static/src/js/tools/debug_manager_backend.js
+++ b/addons/web/static/src/js/tools/debug_manager_backend.js
@@ -110,6 +110,28 @@ DebugManager.include({
* (window action)
*/
DebugManager.include({
+ async start() {
+ const [_, canSeeRecordRules, canSeeModelAccess] = await Promise.all([
+ this._super(...arguments),
+ this._checkAccessRight('ir.rule', 'read'),
+ this._checkAccessRight('ir.model.access', 'read'),
+ ])
+ this.canSeeRecordRules = canSeeRecordRules;
+ this.canSeeModelAccess = canSeeModelAccess;
+ },
+ /**
+ * Return the ir.model id from the model name
+ * @param {string} modelName
+ */
+ async getModelId(modelName) {
+ const [modelId] = await this._rpc({
+ model: 'ir.model',
+ method: 'search',
+ args: [[['model', '=', modelName]]],
+ kwargs: { limit: 1},
+ });
+ return modelId
+ },
/**
* Updates current action (action descriptor) on tag = action,
*/
@@ -136,24 +158,17 @@ DebugManager.include({
flags: {action_buttons: true, headless: true}
});
},
- get_view_fields: function () {
- var model = this._action.res_model,
- self = this;
- this._rpc({
- model: 'ir.model',
- method: 'search',
- args: [[['model', '=', model]]]
- }).then(function (ids) {
- self.do_action({
- res_model: 'ir.model.fields',
- name: _t('View Fields'),
- views: [[false, 'list'], [false, 'form']],
- domain: [['model_id', '=', model]],
- type: 'ir.actions.act_window',
- context: {
- 'default_model_id': ids[0]
- }
- });
+ async get_view_fields () {
+ const modelId = await this.getModelId(this._action.res_model);
+ this.do_action({
+ res_model: 'ir.model.fields',
+ name: _t('View Fields'),
+ views: [[false, 'list'], [false, 'form']],
+ domain: [['model_id', '=', modelId]],
+ type: 'ir.actions.act_window',
+ context: {
+ 'default_model_id': modelId
+ }
});
},
manage_filters: function () {
@@ -175,7 +190,33 @@ DebugManager.include({
args: [this._action.res_model],
})
.then(this.do_action);
- }
+ },
+ async actionRecordRules() {
+ const modelId = await this.getModelId(this._action.res_model);
+ this.do_action({
+ res_model: 'ir.rule',
+ name: _t('Model Record Rules'),
+ views: [[false, 'list'], [false, 'form']],
+ domain: [['model_id', '=', modelId]],
+ type: 'ir.actions.act_window',
+ context: {
+ 'default_model_id': modelId,
+ },
+ });
+ },
+ async actionModelAccess() {
+ const modelId = await this.getModelId(this._action.res_model);
+ this.do_action({
+ res_model: 'ir.model.access',
+ name: _t('Model Access'),
+ views: [[false, 'list'], [false, 'form']],
+ domain: [['model_id', '=', modelId]],
+ type: 'ir.actions.act_window',
+ context: {
+ 'default_model_id': modelId,
+ },
+ });
+ },
});
/**
@@ -188,11 +229,7 @@ DebugManager.include({
this._can_edit_views = false;
return Promise.all([
this._super(),
- this._rpc({
- model: 'ir.ui.view',
- method: 'check_access_rights',
- kwargs: {operation: 'write', raise_exception: false},
- })
+ this._checkAccessRight('ir.ui.view', 'write')
.then(function (ar) {
this._can_edit_views = ar;
}.bind(this))
diff --git a/addons/web/static/src/xml/debug.xml b/addons/web/static/src/xml/debug.xml
index ff4613f26b6..4a53168c84b 100644
--- a/addons/web/static/src/xml/debug.xml
+++ b/addons/web/static/src/xml/debug.xml
@@ -38,6 +38,9 @@
<a role="menuitem" href="#" data-action="get_view_fields" class="dropdown-item">View Fields</a>
<a role="menuitem" href="#" data-action="manage_filters" class="dropdown-item">Manage Filters</a>
<a role="menuitem" href="#" data-action="translate" class="dropdown-item">Technical Translation</a>
+ <div t-if="manager.canSeeModelAccess || manager.canSeeRecordRules" class="dropdown-divider" role="separator"/>
+ <a t-if="manager.canSeeModelAccess" role="menuitem" href="#" data-action="actionModelAccess" class="dropdown-item">View Access Rights</a>
+ <a t-if="manager.canSeeRecordRules" role="menuitem" href="#" data-action="actionRecordRules" class="dropdown-item">View Record Rules</a>
</t>
</t>
</t>