Browse Source

feat(superuser): unclosable superuser modal (#67015)

Cathy Teng 11 months ago
parent
commit
8ea6c050dd

+ 9 - 3
static/app/actionCreators/sudoModal.tsx

@@ -1,6 +1,8 @@
+import type {ModalOptions} from 'sentry/actionCreators/modal';
 import ModalStore from 'sentry/stores/modalStore';
 
-type OpenSudoModalOptions = {
+type OpenSudoModalOptions = ModalOptions & {
+  closeButton?: boolean;
   isSuperuser?: boolean;
   needsReload?: boolean;
   onClose?: () => void;
@@ -8,9 +10,13 @@ type OpenSudoModalOptions = {
   sudo?: boolean;
 };
 
-export async function openSudo({onClose, ...args}: OpenSudoModalOptions = {}) {
+export async function openSudo({
+  onClose,
+  closeEvents,
+  ...args
+}: OpenSudoModalOptions = {}) {
   const mod = await import('sentry/components/modals/sudoModal');
   const {default: Modal} = mod;
 
-  ModalStore.openModal(deps => <Modal {...deps} {...args} />, {onClose});
+  ModalStore.openModal(deps => <Modal {...deps} {...args} />, {onClose, closeEvents});
 }

+ 11 - 2
static/app/components/modals/sudoModal.tsx

@@ -24,7 +24,12 @@ import TextBlock from 'sentry/views/settings/components/text/textBlock';
 
 type OnTapProps = NonNullable<React.ComponentProps<typeof U2fContainer>['onTap']>;
 
+type DefaultProps = {
+  closeButton?: boolean;
+};
+
 type Props = WithRouterProps &
+  DefaultProps &
   Pick<ModalRenderProps, 'Body' | 'Header'> & {
     api: Client;
     closeModal: () => void;
@@ -50,6 +55,10 @@ type State = {
 };
 
 class SudoModal extends Component<Props, State> {
+  static defaultProps: DefaultProps = {
+    closeButton: true,
+  };
+
   state: State = {
     authenticators: [],
     busy: false,
@@ -313,11 +322,11 @@ class SudoModal extends Component<Props, State> {
   }
 
   render() {
-    const {Header, Body} = this.props;
+    const {Header, Body, closeButton} = this.props;
 
     return (
       <Fragment>
-        <Header closeButton>{t('Confirm Password to Continue')}</Header>
+        <Header closeButton={closeButton}>{t('Confirm Password to Continue')}</Header>
         <Body>{this.renderBodyContent()}</Body>
       </Fragment>
     );

+ 12 - 2
static/app/views/organizationContext.tsx

@@ -147,14 +147,24 @@ export function OrganizationContextProvider({children}: Props) {
       // If the user has an active staff session, the response will not return a
       // 403 but access scopes will be an empty list.
       if (user?.isSuperuser && user?.isStaff && organization?.access?.length === 0) {
-        openSudo({isSuperuser: true, needsReload: true});
+        openSudo({
+          isSuperuser: true,
+          needsReload: true,
+          closeEvents: 'none',
+          closeButton: false,
+        });
       }
 
       return;
     }
 
     if (user?.isSuperuser && error.status === 403) {
-      openSudo({isSuperuser: true, needsReload: true});
+      openSudo({
+        isSuperuser: true,
+        needsReload: true,
+        closeEvents: 'none',
+        closeButton: false,
+      });
     }
 
     // This `catch` can swallow up errors in development (and tests)