From 5931c8beec7b202ade00a9a3d68ee1ed7267ceaa Mon Sep 17 00:00:00 2001 From: Lily Kuang Date: Thu, 14 Apr 2022 16:59:31 -0700 Subject: [PATCH 01/11] feat: get user roles endpoint --- superset/views/users/api.py | 31 ++++++++++++++++++++++ tests/integration_tests/users/api_tests.py | 8 ++++++ 2 files changed, 39 insertions(+) diff --git a/superset/views/users/api.py b/superset/views/users/api.py index 584e8145ec391..72c1e1056db6e 100644 --- a/superset/views/users/api.py +++ b/superset/views/users/api.py @@ -19,6 +19,7 @@ from flask_jwt_extended.exceptions import NoAuthorizationError from .schemas import UserResponseSchema +from superset.views.utils import get_permissions user_response_schema = UserResponseSchema() @@ -59,3 +60,33 @@ def get_me(self) -> Response: return self.response_401() return self.response(200, result=user_response_schema.dump(g.user)) + + @expose("/roles/", methods=["GET"]) + @safe + def get_my_roles(self) -> Response: + """Get the user object corresponding to the agent making the request + --- + get: + description: >- + Returns the user object corresponding to the agent making the request, + or returns a 401 error if the user is unauthenticated. + responses: + 200: + description: The current user + content: + application/json: + schema: + type: object + properties: + result: + $ref: '#/components/schemas/UserResponseSchema' + 401: + $ref: '#/components/responses/401' + """ + try: + if g.user is None or g.user.is_anonymous: + return self.response_401() + except NoAuthorizationError: + return self.response_401() + roles, _ = get_permissions(g.user) + return self.response(200, result={"roles": roles}) diff --git a/tests/integration_tests/users/api_tests.py b/tests/integration_tests/users/api_tests.py index ee965f6f2bf01..98c7ee811e7c9 100644 --- a/tests/integration_tests/users/api_tests.py +++ b/tests/integration_tests/users/api_tests.py @@ -37,6 +37,14 @@ def test_get_me_logged_in(self): self.assertEqual(True, response["result"]["is_active"]) self.assertEqual(False, response["result"]["is_anonymous"]) + def test_get_me_with_roles(self): + self.login(username="admin") + + rv = self.client.get(meUri+"/roles/") + self.assertEqual(200, rv.status_code) + response = json.loads(rv.data.decode("utf-8")) + self.assertEqual("Admin", response["result"]["roles"][0].keys()) + def test_get_me_unauthorized(self): self.logout() rv = self.client.get(meUri) From d0be33f11ab5eca4609c1ed0825502dc56e583cb Mon Sep 17 00:00:00 2001 From: Lily Kuang Date: Fri, 15 Apr 2022 11:53:52 -0700 Subject: [PATCH 02/11] add tests --- superset/views/users/api.py | 7 ++++--- tests/integration_tests/users/api_tests.py | 11 +++++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/superset/views/users/api.py b/superset/views/users/api.py index 72c1e1056db6e..1069e74b3d4f5 100644 --- a/superset/views/users/api.py +++ b/superset/views/users/api.py @@ -18,9 +18,10 @@ from flask_appbuilder.api import BaseApi, expose, safe from flask_jwt_extended.exceptions import NoAuthorizationError -from .schemas import UserResponseSchema from superset.views.utils import get_permissions +from .schemas import UserResponseSchema + user_response_schema = UserResponseSchema() @@ -64,11 +65,11 @@ def get_me(self) -> Response: @expose("/roles/", methods=["GET"]) @safe def get_my_roles(self) -> Response: - """Get the user object corresponding to the agent making the request + """Get the user roles corresponding to the agent making the request --- get: description: >- - Returns the user object corresponding to the agent making the request, + Returns the user roles corresponding to the agent making the request, or returns a 401 error if the user is unauthenticated. responses: 200: diff --git a/tests/integration_tests/users/api_tests.py b/tests/integration_tests/users/api_tests.py index 98c7ee811e7c9..f4c897b6a0ca1 100644 --- a/tests/integration_tests/users/api_tests.py +++ b/tests/integration_tests/users/api_tests.py @@ -40,10 +40,17 @@ def test_get_me_logged_in(self): def test_get_me_with_roles(self): self.login(username="admin") - rv = self.client.get(meUri+"/roles/") + rv = self.client.get(meUri + "roles/") self.assertEqual(200, rv.status_code) response = json.loads(rv.data.decode("utf-8")) - self.assertEqual("Admin", response["result"]["roles"][0].keys()) + roles = list(response["result"]["roles"].keys()) + self.assertEqual("Admin", roles.pop()) + + @patch("superset.security.manager.g") + def test_get_my_roles_anonymous(self, mock_g): + mock_g.user = security_manager.get_anonymous_user + rv = self.client.get(meUri + "roles/") + self.assertEqual(401, rv.status_code) def test_get_me_unauthorized(self): self.logout() From abe72f31ab8e1a10908dd2eb3cd0298bd97f5867 Mon Sep 17 00:00:00 2001 From: Lily Kuang Date: Fri, 15 Apr 2022 14:23:27 -0700 Subject: [PATCH 03/11] fix test --- tests/integration_tests/security_tests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration_tests/security_tests.py b/tests/integration_tests/security_tests.py index 82b4d8717d14d..3add863de839c 100644 --- a/tests/integration_tests/security_tests.py +++ b/tests/integration_tests/security_tests.py @@ -889,6 +889,7 @@ def test_views_are_secured(self): ["AuthDBView", "login"], ["AuthDBView", "logout"], ["CurrentUserRestApi", "get_me"], + ["CurrentUserRestApi", "get_my_roles"], # TODO (embedded) remove Dashboard:embedded after uuids have been shipped ["Dashboard", "embedded"], ["EmbeddedView", "embedded"], From 2d624c1fe59dff248a33d05ce8e556c5fa7fb7fc Mon Sep 17 00:00:00 2001 From: Lily Kuang Date: Tue, 19 Apr 2022 11:22:01 -0700 Subject: [PATCH 04/11] get user with permission and roles with full user --- superset/views/users/api.py | 6 +++--- superset/views/utils.py | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/superset/views/users/api.py b/superset/views/users/api.py index 1069e74b3d4f5..29d376935a77e 100644 --- a/superset/views/users/api.py +++ b/superset/views/users/api.py @@ -18,7 +18,7 @@ from flask_appbuilder.api import BaseApi, expose, safe from flask_jwt_extended.exceptions import NoAuthorizationError -from superset.views.utils import get_permissions +from superset.views.utils import bootstrap_user_data from .schemas import UserResponseSchema @@ -89,5 +89,5 @@ def get_my_roles(self) -> Response: return self.response_401() except NoAuthorizationError: return self.response_401() - roles, _ = get_permissions(g.user) - return self.response(200, result={"roles": roles}) + user = bootstrap_user_data(g.user, include_perms=True) + return self.response(200, result=user) diff --git a/superset/views/utils.py b/superset/views/utils.py index 202f87d996976..e0f97cba1839b 100644 --- a/superset/views/utils.py +++ b/superset/views/utils.py @@ -72,6 +72,14 @@ def bootstrap_user_data(user: User, include_perms: bool = False) -> Dict[str, An if user.is_anonymous: payload = {} user.roles = (security_manager.find_role("Public"),) + elif security_manager.is_guest_user(user): + payload = { + "username": user.username, + "firstName": user.first_name, + "lastName": user.last_name, + "isActive": user.is_active, + "isAnonymous": user.is_anonymous, + } else: payload = { "username": user.username, From 38873954c73ac472c544d27b673d9b2b1ed64d22 Mon Sep 17 00:00:00 2001 From: David Aaron Suddjian Date: Tue, 19 Apr 2022 11:52:49 -0700 Subject: [PATCH 05/11] frontend --- .../src/dashboard/util/findPermission.ts | 7 ++-- superset-frontend/src/embedded/index.tsx | 37 +++++++++++++++++-- superset-frontend/src/preamble.ts | 4 +- superset-frontend/src/types/bootstrapTypes.ts | 16 +++++++- 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/superset-frontend/src/dashboard/util/findPermission.ts b/superset-frontend/src/dashboard/util/findPermission.ts index d3a8b61eca94a..a83d62c8d6765 100644 --- a/superset-frontend/src/dashboard/util/findPermission.ts +++ b/superset-frontend/src/dashboard/util/findPermission.ts @@ -17,11 +17,12 @@ * under the License. */ import memoizeOne from 'memoize-one'; -import { UserWithPermissionsAndRoles } from 'src/types/bootstrapTypes'; +import { + UserRoles, + UserWithPermissionsAndRoles, +} from 'src/types/bootstrapTypes'; import Dashboard from 'src/types/Dashboard'; -type UserRoles = Record; - const findPermission = memoizeOne( (perm: string, view: string, roles?: UserRoles | null) => !!roles && diff --git a/superset-frontend/src/embedded/index.tsx b/superset-frontend/src/embedded/index.tsx index afea2fd8bb94b..633447a69f210 100644 --- a/superset-frontend/src/embedded/index.tsx +++ b/superset-frontend/src/embedded/index.tsx @@ -19,7 +19,7 @@ import React, { lazy, Suspense } from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter as Router, Route } from 'react-router-dom'; -import { t } from '@superset-ui/core'; +import { makeApi, t } from '@superset-ui/core'; import { Switchboard } from '@superset-ui/switchboard'; import { bootstrapData } from 'src/preamble'; import setupClient from 'src/setup/setupClient'; @@ -29,6 +29,7 @@ import ErrorBoundary from 'src/components/ErrorBoundary'; import Loading from 'src/components/Loading'; import { addDangerToast } from 'src/components/MessageToasts/actions'; import ToastContainer from 'src/components/MessageToasts/ToastContainer'; +import { UserWithPermissionsAndRoles } from 'src/types/bootstrapTypes'; const debugMode = process.env.WEBPACK_MODE === 'development'; @@ -69,8 +70,13 @@ const appMountPoint = document.getElementById('app')!; const MESSAGE_TYPE = '__embedded_comms__'; if (!window.parent || window.parent === window) { - appMountPoint.innerHTML = - 'This page is intended to be embedded in an iframe, but it looks like that is not the case.'; + showFailureMessage( + 'This page is intended to be embedded in an iframe, but it looks like that is not the case.', + ); +} + +function showFailureMessage(message: string) { + appMountPoint.innerHTML = message; } // if the page is embedded in an origin that hasn't @@ -109,6 +115,29 @@ function guestUnauthorizedHandler() { ); } +function start() { + const getMeWithRole = makeApi({ + method: 'GET', + endpoint: '/api/v1/me/roles', + }); + return getMeWithRole().then( + meWithPerm => { + // fill in some missing bootstrap data + // (because at pageload, we don't have any auth yet) + // this allows the frontend's permissions checks to work. + bootstrapData.user = meWithPerm; + ReactDOM.render(, appMountPoint); + }, + err => { + // something is most likely wrong with the guest token + console.error(err); + showFailureMessage( + 'Something went wrong with embedded authentication. Check the dev console for details.', + ); + }, + ); +} + /** * Configures SupersetClient with the correct settings for the embedded dashboard page. */ @@ -153,7 +182,7 @@ window.addEventListener('message', function embeddedPageInitializer(event) { switchboard.defineMethod('guestToken', ({ guestToken }) => { setupGuestClient(guestToken); if (!started) { - ReactDOM.render(, appMountPoint); + start(); started = true; } }); diff --git a/superset-frontend/src/preamble.ts b/superset-frontend/src/preamble.ts index 8d89104bf2098..5c05e1ec3a3bb 100644 --- a/superset-frontend/src/preamble.ts +++ b/superset-frontend/src/preamble.ts @@ -26,7 +26,7 @@ import setupClient from './setup/setupClient'; import setupColors from './setup/setupColors'; import setupFormatters from './setup/setupFormatters'; import setupDashboardComponents from './setup/setupDasboardComponents'; -import { User } from './types/bootstrapTypes'; +import { User, UserWithPermissionsAndRoles } from './types/bootstrapTypes'; if (process.env.WEBPACK_MODE === 'development') { setHotLoaderConfig({ logLevel: 'debug', trackTailUpdates: false }); @@ -34,7 +34,7 @@ if (process.env.WEBPACK_MODE === 'development') { // eslint-disable-next-line import/no-mutable-exports export let bootstrapData: { - user?: User | undefined; + user?: UserWithPermissionsAndRoles | undefined; common?: any; config?: any; embedded?: { diff --git a/superset-frontend/src/types/bootstrapTypes.ts b/superset-frontend/src/types/bootstrapTypes.ts index 33314e7e46906..b49404477cc7f 100644 --- a/superset-frontend/src/types/bootstrapTypes.ts +++ b/superset-frontend/src/types/bootstrapTypes.ts @@ -29,14 +29,26 @@ export type User = { username: string; }; -export interface UserWithPermissionsAndRoles extends User { +export type GuestUser = { + firstName: string; + lastName: string; + username: string; + isAnonymous: false; + isActive: false; +}; + +export type UserRoles = Record; +export interface PermissionsAndRoles { permissions: { database_access?: string[]; datasource_access?: string[]; }; - roles: Record; + roles: UserRoles; } +export type UserWithPermissionsAndRoles = (User | GuestUser) & + PermissionsAndRoles; + export type Dashboard = { dttm: number; id: number; From f1ffe34764149fc4f89f56b430102ab0eebf0e11 Mon Sep 17 00:00:00 2001 From: David Aaron Suddjian Date: Tue, 19 Apr 2022 15:16:37 -0700 Subject: [PATCH 06/11] type juggling --- .../src/dashboard/util/findPermission.test.ts | 2 +- .../ExploreReport.tsx | 2 +- superset-frontend/src/types/bootstrapTypes.ts | 17 ++++------------- .../src/views/CRUD/welcome/Welcome.tsx | 6 +++--- 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/superset-frontend/src/dashboard/util/findPermission.test.ts b/superset-frontend/src/dashboard/util/findPermission.test.ts index 1c80770f50014..0752bad404443 100644 --- a/superset-frontend/src/dashboard/util/findPermission.test.ts +++ b/superset-frontend/src/dashboard/util/findPermission.test.ts @@ -58,7 +58,7 @@ const outsiderUser: UserWithPermissionsAndRoles = { const owner: Owner = { first_name: 'Test', - id: ownerUser.userId, + id: ownerUser.userId!, last_name: 'User', username: ownerUser.username, }; diff --git a/superset-frontend/src/explore/components/ExploreAdditionalActionsMenu/ExploreReport.tsx b/superset-frontend/src/explore/components/ExploreAdditionalActionsMenu/ExploreReport.tsx index 967903d7b04cf..4ec5ceb0ad08a 100644 --- a/superset-frontend/src/explore/components/ExploreAdditionalActionsMenu/ExploreReport.tsx +++ b/superset-frontend/src/explore/components/ExploreAdditionalActionsMenu/ExploreReport.tsx @@ -53,7 +53,7 @@ export const ExploreReport = ({ }); const { userId, email } = useSelector< ExplorePageState, - { userId: number; email: string } + { userId?: number; email?: string } >(state => pick(state.explore.user, ['userId', 'email'])); const handleReportDelete = useCallback(() => { diff --git a/superset-frontend/src/types/bootstrapTypes.ts b/superset-frontend/src/types/bootstrapTypes.ts index 920188b38998f..6b8b99fe43308 100644 --- a/superset-frontend/src/types/bootstrapTypes.ts +++ b/superset-frontend/src/types/bootstrapTypes.ts @@ -20,24 +20,16 @@ import { isPlainObject } from 'lodash'; * under the License. */ export type User = { - createdOn: string; - email: string; + createdOn?: string; + email?: string; firstName: string; isActive: boolean; isAnonymous: boolean; lastName: string; - userId: number; + userId?: number; // optional because guest user doesn't have a user id username: string; }; -export type GuestUser = { - firstName: string; - lastName: string; - username: string; - isAnonymous: false; - isActive: false; -}; - export type UserRoles = Record; export interface PermissionsAndRoles { permissions: { @@ -47,8 +39,7 @@ export interface PermissionsAndRoles { roles: UserRoles; } -export type UserWithPermissionsAndRoles = (User | GuestUser) & - PermissionsAndRoles; +export type UserWithPermissionsAndRoles = User & PermissionsAndRoles; export type UndefinedUser = {}; diff --git a/superset-frontend/src/views/CRUD/welcome/Welcome.tsx b/superset-frontend/src/views/CRUD/welcome/Welcome.tsx index 2d564bc66fe9f..3660b8acc8e09 100644 --- a/superset-frontend/src/views/CRUD/welcome/Welcome.tsx +++ b/superset-frontend/src/views/CRUD/welcome/Welcome.tsx @@ -151,7 +151,7 @@ export const LoadingCards = ({ cover }: LoadingProps) => ( function Welcome({ user, addDangerToast }: WelcomeProps) { const userid = user.userId; - const id = userid.toString(); + const id = userid!.toString(); // confident that user is not a guest user const recent = `/superset/recent_activity/${user.userId}/?limit=6`; const [activeChild, setActiveChild] = useState('Loading'); const userKey = dangerouslyGetItemDoNotUse(id, null); @@ -180,7 +180,7 @@ function Welcome({ user, addDangerToast }: WelcomeProps) { useEffect(() => { const activeTab = getItem(LocalStorageKeys.homepage_activity_filter, null); setActiveState(collapseState.length > 0 ? collapseState : DEFAULT_TAB_ARR); - getRecentAcitivtyObjs(user.userId, recent, addDangerToast) + getRecentAcitivtyObjs(user.userId!, recent, addDangerToast) .then(res => { const data: ActivityData | null = {}; data.Examples = res.examples; @@ -295,7 +295,7 @@ function Welcome({ user, addDangerToast }: WelcomeProps) { activityData.Created) && activeChild !== 'Loading' ? ( Date: Tue, 19 Apr 2022 15:17:24 -0700 Subject: [PATCH 07/11] the hash slinging slasher --- superset-frontend/src/embedded/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/superset-frontend/src/embedded/index.tsx b/superset-frontend/src/embedded/index.tsx index 633447a69f210..122545a93dda1 100644 --- a/superset-frontend/src/embedded/index.tsx +++ b/superset-frontend/src/embedded/index.tsx @@ -118,7 +118,7 @@ function guestUnauthorizedHandler() { function start() { const getMeWithRole = makeApi({ method: 'GET', - endpoint: '/api/v1/me/roles', + endpoint: '/api/v1/me/roles/', }); return getMeWithRole().then( meWithPerm => { From 40c63bc48947f2811be9bf4cf3345afc5ae3f263 Mon Sep 17 00:00:00 2001 From: David Aaron Suddjian Date: Tue, 19 Apr 2022 16:15:05 -0700 Subject: [PATCH 08/11] user reducer and action --- superset-frontend/src/embedded/index.tsx | 10 +++++--- superset-frontend/src/preamble.ts | 4 ++-- superset-frontend/src/types/bootstrapTypes.ts | 2 ++ superset-frontend/src/views/store.ts | 24 ++++++++++++++++++- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/superset-frontend/src/embedded/index.tsx b/superset-frontend/src/embedded/index.tsx index 122545a93dda1..50e5c14b7e416 100644 --- a/superset-frontend/src/embedded/index.tsx +++ b/superset-frontend/src/embedded/index.tsx @@ -24,7 +24,7 @@ import { Switchboard } from '@superset-ui/switchboard'; import { bootstrapData } from 'src/preamble'; import setupClient from 'src/setup/setupClient'; import { RootContextProviders } from 'src/views/RootContextProviders'; -import { store } from 'src/views/store'; +import { store, USER_LOADED } from 'src/views/store'; import ErrorBoundary from 'src/components/ErrorBoundary'; import Loading from 'src/components/Loading'; import { addDangerToast } from 'src/components/MessageToasts/actions'; @@ -121,11 +121,15 @@ function start() { endpoint: '/api/v1/me/roles/', }); return getMeWithRole().then( - meWithPerm => { + meWithRole => { // fill in some missing bootstrap data // (because at pageload, we don't have any auth yet) // this allows the frontend's permissions checks to work. - bootstrapData.user = meWithPerm; + bootstrapData.user = meWithRole; + store.dispatch({ + type: USER_LOADED, + user: meWithRole, + }); ReactDOM.render(, appMountPoint); }, err => { diff --git a/superset-frontend/src/preamble.ts b/superset-frontend/src/preamble.ts index 5c05e1ec3a3bb..ab6d696f5b727 100644 --- a/superset-frontend/src/preamble.ts +++ b/superset-frontend/src/preamble.ts @@ -26,7 +26,7 @@ import setupClient from './setup/setupClient'; import setupColors from './setup/setupColors'; import setupFormatters from './setup/setupFormatters'; import setupDashboardComponents from './setup/setupDasboardComponents'; -import { User, UserWithPermissionsAndRoles } from './types/bootstrapTypes'; +import { BootstrapUser, User } from './types/bootstrapTypes'; if (process.env.WEBPACK_MODE === 'development') { setHotLoaderConfig({ logLevel: 'debug', trackTailUpdates: false }); @@ -34,7 +34,7 @@ if (process.env.WEBPACK_MODE === 'development') { // eslint-disable-next-line import/no-mutable-exports export let bootstrapData: { - user?: UserWithPermissionsAndRoles | undefined; + user?: BootstrapUser; common?: any; config?: any; embedded?: { diff --git a/superset-frontend/src/types/bootstrapTypes.ts b/superset-frontend/src/types/bootstrapTypes.ts index 6b8b99fe43308..a6c1a32440b10 100644 --- a/superset-frontend/src/types/bootstrapTypes.ts +++ b/superset-frontend/src/types/bootstrapTypes.ts @@ -43,6 +43,8 @@ export type UserWithPermissionsAndRoles = User & PermissionsAndRoles; export type UndefinedUser = {}; +export type BootstrapUser = UserWithPermissionsAndRoles | undefined; + export type Dashboard = { dttm: number; id: number; diff --git a/superset-frontend/src/views/store.ts b/superset-frontend/src/views/store.ts index 04dacba80eda8..edfb35957acff 100644 --- a/superset-frontend/src/views/store.ts +++ b/superset-frontend/src/views/store.ts @@ -32,6 +32,11 @@ import sliceEntities from 'src/dashboard/reducers/sliceEntities'; import dashboardLayout from 'src/dashboard/reducers/undoableDashboardLayout'; import logger from 'src/middleware/loggerMiddleware'; import shortid from 'shortid'; +import { + BootstrapUser, + User, + UserWithPermissionsAndRoles, +} from 'src/types/bootstrapTypes'; // Some reducers don't do anything, and redux is just used to reference the initial "state". // This may change later, as the client application takes on more responsibilities. @@ -57,11 +62,28 @@ const dashboardReducers = { reports, }; +export const USER_LOADED = 'USER_LOADED'; + +export type UserLoadedAction = { + type: typeof USER_LOADED; + user: UserWithPermissionsAndRoles; +}; + +const userReducer = ( + user: BootstrapUser = bootstrap.user, + action: UserLoadedAction, +): BootstrapUser => { + if (action.type === USER_LOADED) { + return action.user; + } + return user; +}; + // exported for tests export const rootReducer = combineReducers({ messageToasts: messageToastReducer, common: noopReducer(bootstrap.common || {}), - user: noopReducer(bootstrap.user || {}), + user: userReducer, impressionId: noopReducer(shortid.generate()), ...dashboardReducers, }); From 6a54282c0711e6934233f07c320fd8c50a4a7e2f Mon Sep 17 00:00:00 2001 From: David Aaron Suddjian Date: Tue, 19 Apr 2022 16:21:02 -0700 Subject: [PATCH 09/11] make it happy --- superset-frontend/src/views/store.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/superset-frontend/src/views/store.ts b/superset-frontend/src/views/store.ts index edfb35957acff..a8e7b4cf3538f 100644 --- a/superset-frontend/src/views/store.ts +++ b/superset-frontend/src/views/store.ts @@ -70,7 +70,7 @@ export type UserLoadedAction = { }; const userReducer = ( - user: BootstrapUser = bootstrap.user, + user: BootstrapUser = bootstrap.user || {}, action: UserLoadedAction, ): BootstrapUser => { if (action.type === USER_LOADED) { From 5b17a5be7322633aaa2bc118ce0d055de7d07b85 Mon Sep 17 00:00:00 2001 From: David Aaron Suddjian Date: Tue, 19 Apr 2022 16:23:31 -0700 Subject: [PATCH 10/11] result --- superset-frontend/src/embedded/index.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/superset-frontend/src/embedded/index.tsx b/superset-frontend/src/embedded/index.tsx index 50e5c14b7e416..52e0aee8d29b5 100644 --- a/superset-frontend/src/embedded/index.tsx +++ b/superset-frontend/src/embedded/index.tsx @@ -116,19 +116,19 @@ function guestUnauthorizedHandler() { } function start() { - const getMeWithRole = makeApi({ + const getMeWithRole = makeApi({ method: 'GET', endpoint: '/api/v1/me/roles/', }); return getMeWithRole().then( - meWithRole => { + ({ result }) => { // fill in some missing bootstrap data // (because at pageload, we don't have any auth yet) // this allows the frontend's permissions checks to work. - bootstrapData.user = meWithRole; + bootstrapData.user = result; store.dispatch({ type: USER_LOADED, - user: meWithRole, + user: result, }); ReactDOM.render(, appMountPoint); }, From e28a102437fbcd4b232fc24621850cecbbe85009 Mon Sep 17 00:00:00 2001 From: Lily Kuang Date: Fri, 29 Apr 2022 14:16:11 -0700 Subject: [PATCH 11/11] lint --- superset-frontend/src/views/store.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/superset-frontend/src/views/store.ts b/superset-frontend/src/views/store.ts index a8e7b4cf3538f..d363ed2cd99fa 100644 --- a/superset-frontend/src/views/store.ts +++ b/superset-frontend/src/views/store.ts @@ -34,7 +34,6 @@ import logger from 'src/middleware/loggerMiddleware'; import shortid from 'shortid'; import { BootstrapUser, - User, UserWithPermissionsAndRoles, } from 'src/types/bootstrapTypes';