Browse Source

Fix(partnership): URL for users with multiple sentry orgs (#54666)

This PR fixes a bug for users hitting
sentry.io/auth/channel/fly/{org-X-fly-id} while they're logged in
another org.
Before:
1. User logs in org-Y
2. User hits
sentry.io/auth/channel/fly/{org-X-fly-id}/?next/issues/?project={org-X-project}
3. User gets page not found because we redirect them to org Y and
org-X-project doesn't exist

After:
3. User gets log in page for Org X
4. After login will redirect to Org-X-project issues page
Athena Moghaddam 1 year ago
parent
commit
3957a8769d

+ 20 - 7
src/sentry/web/frontend/auth_channel_login.py

@@ -39,12 +39,25 @@ class AuthChannelLoginView(AuthOrganizationLoginView):
         if organization_context is None:
             return self.redirect(reverse("sentry-login"))
 
+        next_uri = self.get_next_uri(request)
+        # If user has an active session within the same organization skip login
         if request.user.is_authenticated:
-            next_uri = self.get_next_uri(request)
-            if is_valid_redirect(next_uri, allowed_hosts=(request.get_host())):
-                return self.redirect(next_uri)
-            return self.redirect(Organization.get_url(slug=organization_context.organization.slug))
-
-        return self.redirect(
-            reverse("sentry-auth-organization", args=[organization_context.organization.slug])
+            if self.active_organization is not None:
+                if self.active_organization.organization.id == organization_id:
+                    if is_valid_redirect(next_uri, allowed_hosts=(request.get_host())):
+                        return self.redirect(next_uri)
+                    return self.redirect(
+                        Organization.get_url(slug=organization_context.organization.slug)
+                    )
+
+        # If user doesn't have active session within the same organization redirect to login for the
+        # organization in the url
+        org_auth_url = reverse(
+            "sentry-auth-organization", args=[organization_context.organization.slug]
+        )
+        redirect_url = (
+            org_auth_url + "?next=" + next_uri
+            if is_valid_redirect(next_uri, allowed_hosts=(request.get_host()))
+            else org_auth_url
         )
+        return self.redirect(redirect_url)

+ 21 - 6
tests/sentry/web/frontend/test_auth_channel_login.py

@@ -8,14 +8,16 @@ from sentry.testutils.silo import region_silo_test
 
 @region_silo_test
 class AuthOrganizationChannelLoginTest(TestCase):
-    def setup(self):
-        self.organization = self.create_organization(name="test org", owner=self.user)
-        self.partner_org_id = "foobar"
-        config_data = FlyOAuth2Provider.build_config(resource={"id": self.partner_org_id})
+    def create_auth_provider(self, partner_org_id, sentry_org_id):
+        config_data = FlyOAuth2Provider.build_config(resource={"id": partner_org_id})
         AuthProvider.objects.create(
-            organization_id=self.organization.id, provider="fly", config=config_data
+            organization_id=sentry_org_id, provider="fly", config=config_data
         )
-        self.path = reverse("sentry-auth-channel", args=["fly", self.partner_org_id])
+
+    def setup(self):
+        self.organization = self.create_organization(name="test org", owner=self.user)
+        self.create_auth_provider("fly-test-org", self.organization.id)
+        self.path = reverse("sentry-auth-channel", args=["fly", "fly-test-org"])
 
     def test_redirect_for_logged_in_user(self):
         self.setup()
@@ -26,6 +28,19 @@ class AuthOrganizationChannelLoginTest(TestCase):
             (f"/organizations/{self.organization.slug}/issues/", 302),
         ]
 
+    def test_redirect_for_logged_in_user_with_different_active_org(self):
+        self.setup()
+        self.login_as(self.user)  # log in to "test org"
+        another_org = self.create_organization(name="another org", owner=self.user)
+        self.create_auth_provider("another-fly-org", another_org.id)
+        path = reverse("sentry-auth-channel", args=["fly", "another-fly-org"])
+        response = self.client.get(path + "?next=/projects/", follow=True)
+        assert response.status_code == 200
+        # redirects to login to the org in the url
+        assert response.redirect_chain == [
+            (f"/auth/login/{another_org.slug}/?next=/projects/", 302),
+        ]
+
     def test_redirect_for_logged_out_user(self):
         self.setup()
         response = self.client.get(self.path, follow=True)