From 64cd8724dddfa4dad30ea2dcfb0d7124d9a99895 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Mon, 22 Apr 2024 12:14:25 +0200 Subject: [PATCH] fix(setup-wizard): Always create a new user API token (#69388) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the wizard endpoint, we’d reuse existing user auth tokens of the authenticated user if: 1. the user was part of multiple orgs (==> we can't create an org-based token) 2. AND we found one that satisfied the necessary permissions for sourcemap upload. With https://github.com/getsentry/sentry/pull/68148 being merged, we cannot do this anymore. Plain user auth token values are only gonna be available directly after the token was created. For the fix, this PR makes a change to the wizard endpoint to always create a new user API token. This now works just like when we create an org token for single-org users. Closes: https://github.com/getsentry/sentry/pull/69381 --------- Co-authored-by: Daniel Griesser --- src/sentry/web/frontend/setup_wizard.py | 15 ++++++--------- tests/sentry/web/frontend/test_setup_wizard.py | 14 ++++---------- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/sentry/web/frontend/setup_wizard.py b/src/sentry/web/frontend/setup_wizard.py index 4d8cc581ef29e..df78d05ac6d4a 100644 --- a/src/sentry/web/frontend/setup_wizard.py +++ b/src/sentry/web/frontend/setup_wizard.py @@ -154,15 +154,12 @@ def get_token(mappings: list[OrganizationMapping], user: RpcUser): return token # Otherwise, generate a user token - tokens = ApiToken.objects.filter(user_id=user.id) - token = next((token for token in tokens if "project:releases" in token.get_scopes()), None) - if token is None: - token = ApiToken.objects.create( - user_id=user.id, - scope_list=["project:releases"], - token_type=AuthTokenType.USER, - expires_at=None, - ) + token = ApiToken.objects.create( + user_id=user.id, + scope_list=["project:releases"], + token_type=AuthTokenType.USER, + expires_at=None, + ) return serialize(token) diff --git a/tests/sentry/web/frontend/test_setup_wizard.py b/tests/sentry/web/frontend/test_setup_wizard.py index 1b6cf0cf46867..2fab385c55ae0 100644 --- a/tests/sentry/web/frontend/test_setup_wizard.py +++ b/tests/sentry/web/frontend/test_setup_wizard.py @@ -2,9 +2,7 @@ from django.urls import reverse from sentry.api.endpoints.setup_wizard import SETUP_WIZARD_CACHE_KEY -from sentry.api.serializers import serialize from sentry.cache import default_cache -from sentry.models.apitoken import ApiToken from sentry.models.projectkey import ProjectKey from sentry.silo.base import SiloMode from sentry.testutils.cases import PermissionTestCase @@ -90,13 +88,6 @@ def test_project_multiple_keys(self): assert len(cached.get("projects")[0].get("keys")) == 2 def test_return_user_auth_token_if_multiple_orgs(self): - user_api_token = ApiToken.objects.create_or_update( - user=self.user, - scope_list=["project:releases"], - refresh_token=None, - expires_at=None, - )[0] - self.org = self.create_organization(name="org1", owner=self.user) self.org2 = self.create_organization(name="org2", owner=self.user) self.team = self.create_team(organization=self.org, name="Mariachi Band") @@ -116,7 +107,10 @@ def test_return_user_auth_token_if_multiple_orgs(self): self.assertTemplateUsed(resp, "sentry/setup-wizard.html") cached = default_cache.get(key) - assert cached.get("apiKeys") == serialize(user_api_token) + assert cached.get("apiKeys") is not None + + token = cached.get("apiKeys")["token"] + assert token.startswith("sntryu_") def test_return_org_auth_token_if_one_org(self): self.org = self.create_organization(owner=self.user)