This is an automated email from the ASF dual-hosted git repository.
yjc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 6755083 fix(dashboard): incorrect perm for users with multiple roles
(#14148)
6755083 is described below
commit 6755083e3adddcb72c7124db5fa2f3100ab13d72
Author: Jesse Yang <[email protected]>
AuthorDate: Wed Apr 14 16:04:09 2021 -0700
fix(dashboard): incorrect perm for users with multiple roles (#14148)
---
superset-frontend/package-lock.json | 40 ++++++++++-----
superset-frontend/src/dashboard/actions/hydrate.js | 18 +++----
.../src/dashboard/util/findPermission.test.ts | 59 ++++++++++++++++++++++
.../util/{getPermissions.ts => findPermission.ts} | 25 +++------
4 files changed, 102 insertions(+), 40 deletions(-)
diff --git a/superset-frontend/package-lock.json
b/superset-frontend/package-lock.json
index 035e48f..d1b1d0d 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -122,7 +122,7 @@
"regenerator-runtime": "^0.13.5",
"rison": "^0.1.1",
"shortid": "^2.2.6",
- "urijs": "^1.19.4",
+ "urijs": "^1.19.6",
"use-immer": "^0.4.2",
"use-query-params": "^1.1.9"
},
@@ -54461,9 +54461,9 @@
}
},
"node_modules/urijs": {
- "version": "1.19.4",
- "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.4.tgz",
- "integrity":
"sha512-2YF/wdFu02Gsly/wyx+S/f5w/oCF0ihVSgK/Sn8fcY/ZYMYtqxgi03Vi3V7HqyQP8mj8xHMuNFTBIPufmPRdoA=="
+ "version": "1.19.6",
+ "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.6.tgz",
+ "integrity":
"sha512-eSXsXZ2jLvGWeLYlQA3Gh36BcjF+0amo92+wHPyN1mdR8Nxf75fuEuYTd9c0a+m/vhCjRK0ESlE9YNLW+E1VEw=="
},
"node_modules/urix": {
"version": "0.1.0",
@@ -78681,6 +78681,12 @@
"requires": {
"glob": "^7.1.3"
}
+ },
+ "y18n": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+ "integrity":
"sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+ "dev": true
}
}
},
@@ -78844,7 +78850,7 @@
},
"chalk": {
"version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
@@ -82030,7 +82036,7 @@
"dependencies": {
"domelementtype": {
"version": "1.1.3",
- "resolved":
"https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
+ "resolved":
"http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
"integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs="
}
}
@@ -92097,7 +92103,7 @@
},
"json5": {
"version": "0.5.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+ "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE="
},
"jsonfile": {
@@ -94586,7 +94592,7 @@
},
"pify": {
"version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
},
@@ -100253,7 +100259,7 @@
},
"regexpu-core": {
"version": "1.0.0",
- "resolved":
"https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
+ "resolved":
"http://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
"integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
"dev": true,
"requires": {
@@ -100264,13 +100270,13 @@
},
"regjsgen": {
"version": "0.2.0",
- "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
+ "resolved": "http://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
"integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
"dev": true
},
"regjsparser": {
"version": "0.1.5",
- "resolved":
"https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
+ "resolved":
"http://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
"integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
"dev": true,
"requires": {
@@ -106039,6 +106045,12 @@
"strip-ansi": "^5.0.0"
}
},
+ "y18n": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+ "integrity":
"sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+ "dev": true
+ },
"yargs": {
"version": "13.2.4",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz",
@@ -107142,9 +107154,9 @@
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
},
"y18n": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
- "integrity":
"sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+ "integrity":
"sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
"dev": true
},
"yallist": {
diff --git a/superset-frontend/src/dashboard/actions/hydrate.js
b/superset-frontend/src/dashboard/actions/hydrate.js
index 8065bf6..7b87d5c 100644
--- a/superset-frontend/src/dashboard/actions/hydrate.js
+++ b/superset-frontend/src/dashboard/actions/hydrate.js
@@ -28,7 +28,7 @@ import { getInitialState as getInitialNativeFilterState }
from 'src/dashboard/re
import { getParam } from 'src/modules/utils';
import { applyDefaultFormData } from 'src/explore/store';
import { buildActiveFilters } from 'src/dashboard/util/activeDashboardFilters';
-import getPermissions from 'src/dashboard/util/getPermissions';
+import findPermission from 'src/dashboard/util/findPermission';
import {
DASHBOARD_FILTER_SCOPE_GLOBAL,
dashboardFilter,
@@ -311,21 +311,21 @@ export const hydrateDashboard = (dashboardData,
chartData, datasourcesData) => (
dashboardInfo: {
...dashboardData,
userId: String(user.userId), // legacy, please use state.user instead
- dash_edit_perm: getPermissions('can_write', 'Dashboard', roles),
- dash_save_perm: getPermissions('can_save_dash', 'Superset', roles),
- dash_share_perm: getPermissions(
+ dash_edit_perm: findPermission('can_write', 'Dashboard', roles),
+ dash_save_perm: findPermission('can_save_dash', 'Superset', roles),
+ dash_share_perm: findPermission(
'can_share_dashboard',
'Superset',
roles,
),
- superset_can_explore: getPermissions('can_explore', 'Superset', roles),
- superset_can_share: getPermissions(
+ superset_can_explore: findPermission('can_explore', 'Superset', roles),
+ superset_can_share: findPermission(
'can_share_chart',
'Superset',
roles,
),
- superset_can_csv: getPermissions('can_csv', 'Superset', roles),
- slice_can_edit: getPermissions('can_slice', 'Superset', roles),
+ superset_can_csv: findPermission('can_csv', 'Superset', roles),
+ slice_can_edit: findPermission('can_slice', 'Superset', roles),
common: {
// legacy, please use state.common instead
flash_messages: common.flash_messages,
@@ -347,7 +347,7 @@ export const hydrateDashboard = (dashboardData, chartData,
datasourcesData) => (
css: dashboardData.css || '',
colorNamespace: metadata?.color_namespace || null,
colorScheme: metadata?.color_scheme || null,
- editMode: getPermissions('can_write', 'Dashboard', roles) && editMode,
+ editMode: findPermission('can_write', 'Dashboard', roles) && editMode,
isPublished: dashboardData.published,
hasUnsavedChanges: false,
maxUndoHistoryExceeded: false,
diff --git a/superset-frontend/src/dashboard/util/findPermission.test.ts
b/superset-frontend/src/dashboard/util/findPermission.test.ts
new file mode 100644
index 0000000..0dda552
--- /dev/null
+++ b/superset-frontend/src/dashboard/util/findPermission.test.ts
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import findPermission from './findPermission';
+
+test('findPermission for single role', () => {
+ expect(findPermission('abc', 'def', { role: [['abc', 'def']] })).toEqual(
+ true,
+ );
+
+ expect(findPermission('abc', 'def', { role: [['abc', 'de']] })).toEqual(
+ false,
+ );
+
+ expect(findPermission('abc', 'def', { role: [] })).toEqual(false);
+});
+
+test('findPermission for multiple roles', () => {
+ expect(
+ findPermission('abc', 'def', {
+ role1: [
+ ['ccc', 'aaa'],
+ ['abc', 'def'],
+ ],
+ role2: [['abc', 'def']],
+ }),
+ ).toEqual(true);
+
+ expect(
+ findPermission('abc', 'def', {
+ role1: [['abc', 'def']],
+ role2: [['abc', 'dd']],
+ }),
+ ).toEqual(true);
+
+ expect(
+ findPermission('abc', 'def', {
+ role1: [['ccc', 'aaa']],
+ role2: [['aaa', 'ddd']],
+ }),
+ ).toEqual(false);
+
+ expect(findPermission('abc', 'def', { role1: [], role2: []
})).toEqual(false);
+});
diff --git a/superset-frontend/src/dashboard/util/getPermissions.ts
b/superset-frontend/src/dashboard/util/findPermission.ts
similarity index 63%
rename from superset-frontend/src/dashboard/util/getPermissions.ts
rename to superset-frontend/src/dashboard/util/findPermission.ts
index 0208fd6..613d189 100644
--- a/superset-frontend/src/dashboard/util/getPermissions.ts
+++ b/superset-frontend/src/dashboard/util/findPermission.ts
@@ -18,22 +18,13 @@
*/
import memoizeOne from 'memoize-one';
-const findPermissions = (perm: string, view: string, roles: object) => {
- const roleList = Object.entries(roles);
- if (roleList.length === 0) return false;
- let bool;
+type UserRoles = Record<string, [string, string][]>;
- roleList.forEach(([role, permissions]) => {
- bool = Boolean(
- permissions.find(
- (permission: Array<string>) =>
- permission[0] === perm && permission[1] === view,
- ),
- );
- });
- return bool;
-};
+const findPermission = memoizeOne(
+ (perm: string, view: string, roles: UserRoles) =>
+ Object.values(roles).some(permissions =>
+ permissions.some(([perm_, view_]) => perm_ === perm && view_ === view),
+ ),
+);
-const getPermissions = memoizeOne(findPermissions);
-
-export default getPermissions;
+export default findPermission;