diff options
| author | Lucas Lefèvre <lul@odoo.com> | 2020-03-04 14:54:52 +0000 |
|---|---|---|
| committer | Lucas Lefèvre <lul@odoo.com> | 2020-03-04 16:15:56 +0000 |
| commit | 7032dde60a60c6fba730c236b89189a8f56f2bd0 (patch) | |
| tree | 7e79af74858bb5410cfad0aaf504f319d8badc76 | |
| parent | 01497474d7dea1f1f8f24230995d94edcf210602 (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.js | 13 | ||||
| -rw-r--r-- | addons/web/static/src/js/tools/debug_manager_backend.js | 85 | ||||
| -rw-r--r-- | addons/web/static/src/xml/debug.xml | 3 |
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> |
