You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by su...@apache.org on 2022/04/19 18:53:23 UTC

[superset] 01/01: frontend

This is an automated email from the ASF dual-hosted git repository.

suddjian pushed a commit to branch user-with-roles-and-permission
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 38873954c73ac472c544d27b673d9b2b1ed64d22
Author: David Aaron Suddjian <aa...@gmail.com>
AuthorDate: Tue Apr 19 11:52:49 2022 -0700

    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 d3a8b61eca..a83d62c8d6 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<string, [string, string][]>;
-
 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 afea2fd8bb..633447a69f 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<void, UserWithPermissionsAndRoles>({
+    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(<EmbeddedApp />, 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(<EmbeddedApp />, appMountPoint);
+        start();
         started = true;
       }
     });
diff --git a/superset-frontend/src/preamble.ts b/superset-frontend/src/preamble.ts
index 8d89104bf2..5c05e1ec3a 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 33314e7e46..b49404477c 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<string, [string, string][]>;
+export interface PermissionsAndRoles {
   permissions: {
     database_access?: string[];
     datasource_access?: string[];
   };
-  roles: Record<string, [string, string][]>;
+  roles: UserRoles;
 }
 
+export type UserWithPermissionsAndRoles = (User | GuestUser) &
+  PermissionsAndRoles;
+
 export type Dashboard = {
   dttm: number;
   id: number;