summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorMitali Patel <mpa@odoo.com>2020-02-12 14:09:12 +0000
committerXavier Morel <xmo@odoo.com>2020-04-01 13:07:50 +0000
commitc248594ee5255b232e42438783b9061d235153cb (patch)
treea436fcd46d9b2d55356cc1d2778f1c2b5971881a /addons
parent271112980941825a76af6488a19e12031c771b99 (diff)
[IMP] base: allow restricting / removing exports right
Add a new group allowing administrators to remove the ability for users to bulk-export data from the database. It's pretty minor as technically the user can still access the underlying object through the basic methods but it's still a bit of a roadblock. Users can export by default. Task 2170900 closes odoo/odoo#45400 Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Diffstat (limited to 'addons')
-rw-r--r--addons/test_xlsx_export/tests/test_export.py2
-rw-r--r--addons/web/static/src/js/views/list/list_controller.js14
-rw-r--r--addons/web/static/tests/views/list_tests.js46
3 files changed, 48 insertions, 14 deletions
diff --git a/addons/test_xlsx_export/tests/test_export.py b/addons/test_xlsx_export/tests/test_export.py
index 7a2e50a80e3..9ba0960be5a 100644
--- a/addons/test_xlsx_export/tests/test_export.py
+++ b/addons/test_xlsx_export/tests/test_export.py
@@ -22,7 +22,7 @@ class XlsxCreatorCase(common.HttpCase):
super().setUp()
self.model = self.env[self.model_name]
- mail_new_test_user(self.env, login='fof', password='123456789')
+ u = mail_new_test_user(self.env, login='fof', password='123456789', groups='base.group_user,base.group_allow_export')
self.authenticate('fof', '123456789')
self.worksheet = {} # mock worksheet
diff --git a/addons/web/static/src/js/views/list/list_controller.js b/addons/web/static/src/js/views/list/list_controller.js
index 4a3972d50eb..988291fdb1e 100644
--- a/addons/web/static/src/js/views/list/list_controller.js
+++ b/addons/web/static/src/js/views/list/list_controller.js
@@ -58,6 +58,9 @@ var ListController = BasicController.extend({
this.fieldChangedPrevented = false;
this.isPageSelected = false; // true iff all records of the page are selected
this.isDomainSelected = false; // true iff the user selected all records matching the domain
+ session.user_has_group('base.group_allow_export').then(has_group => {
+ this.isExportEnable = has_group;
+ });
Object.defineProperty(this, 'mode', {
get: () => this.renderer.isEditable() ? 'edit' : 'readonly',
set: () => {},
@@ -372,10 +375,13 @@ var ListController = BasicController.extend({
return null;
}
const props = this._super(...arguments);
- const otherActionItems = [{
- description: _t("Export"),
- callback: () => this._onExportData(),
- }];
+ const otherActionItems = [];
+ if (this.isExportEnable) {
+ otherActionItems.push({
+ description: _t("Export"),
+ callback: () => this._onExportData()
+ });
+ }
if (this.archiveEnabled) {
otherActionItems.push({
description: _t("Archive"),
diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js
index 94a7a3bb156..b2340f37065 100644
--- a/addons/web/static/tests/views/list_tests.js
+++ b/addons/web/static/tests/views/list_tests.js
@@ -177,7 +177,7 @@ QUnit.module('Views', {
});
QUnit.test('list with delete="0"', async function (assert) {
- assert.expect(4);
+ assert.expect(3);
const list = await createView({
View: ListView,
@@ -192,13 +192,7 @@ QUnit.module('Views', {
assert.ok(list.$('tbody td.o_list_record_selector').length, 'should have at least one record');
await testUtils.dom.click(list.$('tbody td.o_list_record_selector:first input'));
- assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
- await cpHelpers.toggleActionMenu(list);
- assert.deepEqual(
- cpHelpers.getMenuItemTexts(list),
- ['Export'],
- 'action menu should not have Delete button'
- );
+ assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus .o_dropdown_menu');
list.destroy();
});
@@ -222,6 +216,40 @@ QUnit.module('Views', {
list.destroy();
});
+ QUnit.test('list with export button', async function (assert) {
+ assert.expect(4);
+
+ const list = await createView({
+ View: ListView,
+ model: 'foo',
+ data: this.data,
+ viewOptions: {hasActionMenus: true},
+ arch: '<tree><field name="foo"/></tree>',
+ session: {
+ async user_has_group(group) {
+ if (group === 'base.group_allow_export') {
+ return true;
+ }
+ return this._super(...arguments);
+ },
+ },
+ });
+
+ assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus');
+ assert.ok(list.$('tbody td.o_list_record_selector').length, 'should have at least one record');
+
+ await testUtils.dom.click(list.$('tbody td.o_list_record_selector:first input'));
+ assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
+ await cpHelpers.toggleActionMenu(list);
+ assert.deepEqual(
+ cpHelpers.getMenuItemTexts(list),
+ ['Export', 'Delete'],
+ 'action menu should have Export button'
+ );
+
+ list.destroy();
+ });
+
QUnit.test('simple editable rendering', async function (assert) {
assert.expect(15);
@@ -4538,7 +4566,7 @@ QUnit.module('Views', {
await testUtils.dom.click(list.$('.o_list_record_selector:first input'));
await cpHelpers.toggleActionMenu(list);
- assert.deepEqual(cpHelpers.getMenuItemTexts(list), ['Export', 'Delete', 'Action event']);
+ assert.deepEqual(cpHelpers.getMenuItemTexts(list), ['Delete', 'Action event']);
list.destroy();
});