Просмотр исходного кода

fix(frontend): handle user in no organization better (#66911)

- if there is no organization slug, don't try to fetch org details
- add a new method `setNoOrganization` on the organization context
manager, which will set loading = false, and allow pages to load

In local testing i've observed i'm able to access all of the user
organization settings except for organization tokens without the org
context being populated.

This means in theory a user should be able to close their account if no
org context is loaded. Still probably need to handle redirects better
when a user attempts to log in.

I have no idea what the ramifications are hybrid cloud wise, or if there
are other settings besides a user not being in an org that can result in
there being no org slug. need to test this further

Related: #inc-679
Josh Ferge 1 год назад
Родитель
Сommit
04023db53e

+ 4 - 0
src/sentry/templates/sentry/partial/preload-data.html

@@ -50,6 +50,10 @@
     var preloadPromises = {orgSlug: slug};
     window.__sentry_preload = preloadPromises;
 
+    if (!slug) {
+      return;
+    }
+
     preloadPromises.organization = promiseRequest(makeUrl('/?detailed=0'));
     preloadPromises.projects = promiseRequest(
       makeUrl('/projects/?all_projects=1&collapse=latestDeploys&collapse=unusedFeatures')

+ 3 - 0
static/app/bootstrap/index.tsx

@@ -94,6 +94,9 @@ function preloadOrganizationData(config: Config) {
   const preloadPromises: Record<string, any> = {orgSlug: slug};
   window.__sentry_preload = preloadPromises;
   try {
+    if (!slug) {
+      return;
+    }
     preloadPromises.organization = promiseRequest(makeUrl('/?detailed=0'));
     preloadPromises.projects = promiseRequest(
       makeUrl('/projects/?all_projects=1&collapse=latestDeploys&collapse=unusedFeatures')

+ 1 - 0
static/app/constants/index.tsx

@@ -354,6 +354,7 @@ export const FILTER_MASK = '[Filtered]';
 export const ORGANIZATION_FETCH_ERROR_TYPES = {
   ORG_NOT_FOUND: 'ORG_NOT_FOUND',
   ORG_NO_ACCESS: 'ORG_NO_ACCESS',
+  NO_ORGS: 'NO_ORGS',
 };
 
 export const CONFIG_DOCS_URL = 'https://develop.sentry.dev/config/';

+ 9 - 0
static/app/stores/organizationStore.tsx

@@ -24,6 +24,7 @@ interface OrganizationStoreDefinition extends CommonStoreDefinition<State> {
   onUpdate(org: Organization, options?: {replace: true}): void;
   onUpdate(org: Partial<Organization>, options?: {replace?: false}): void;
   reset(): void;
+  setNoOrganization(): void;
 }
 
 const storeConfig: OrganizationStoreDefinition = {
@@ -78,6 +79,14 @@ const storeConfig: OrganizationStoreDefinition = {
     this.trigger(this.get());
   },
 
+  setNoOrganization() {
+    this.organization = null;
+    this.errorType = ORGANIZATION_FETCH_ERROR_TYPES.NO_ORGS;
+    this.loading = false;
+    this.dirty = false;
+    this.trigger(this.get());
+  },
+
   get() {
     return {
       organization: this.organization,

+ 9 - 2
static/app/views/organizationContainer.tsx

@@ -29,13 +29,20 @@ function OrganizationContainer({children}: Props) {
 
   // XXX(epurkhiser): There is a special case scenarion when we're unable to
   // load an organization due to access issues. Right now this is VERY SPECIFIC
-  // to being able to enable 2FA
+  // to being able to enable 2FA, or a user not being a member of any org.
   //
   // In this scenario we render the children **explicitly without an
   // organization in context**.
   //
   // TODO(epurkhiser): This scenario desprately should be improved
-  if (error && errorType === ORGANIZATION_FETCH_ERROR_TYPES.ORG_NO_ACCESS) {
+  if (
+    error &&
+    errorType &&
+    [
+      ORGANIZATION_FETCH_ERROR_TYPES.ORG_NO_ACCESS,
+      ORGANIZATION_FETCH_ERROR_TYPES.NO_ORGS,
+    ].includes(errorType)
+  ) {
     return children;
   }
 

+ 1 - 1
static/app/views/organizationContext.tsx

@@ -105,8 +105,8 @@ export function OrganizationContextProvider({children}: Props) {
     if (organization && organization.slug === orgSlug) {
       return;
     }
-
     if (!orgSlug) {
+      OrganizationStore.setNoOrganization();
       return;
     }