Skip to content

Commit e45a76a

Browse files
leedongweiiamrajjoshi
authored andcommitted
fix(superuser): Being superuser:read even if you're org owner results in fewer permissions (#87689)
If you're in superuser mode with only `superuser.read` permissions, and you're browsing a Sentry organization where you're the owner, you'll find that you have fewer permissions than expected. ### Before ![Screenshot 2025-03-23 at 4 50 25 PM](https://github.com/user-attachments/assets/a4046a4e-aaa9-43ee-98d4-b16acb55abc5) ### After ![Screenshot 2025-03-23 at 4 49 41 PM](https://github.com/user-attachments/assets/c859b0db-623f-405c-91d8-85969ea5ff1c) --------- Co-authored-by: Raj Joshi <[email protected]>
1 parent 06c75af commit e45a76a

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

src/sentry/auth/access.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,10 @@ def from_request_org_and_scopes(
901901
rpc_user_org_context: RpcUserOrganizationContext | None = None,
902902
scopes: Iterable[str] | None = None,
903903
) -> Access:
904+
"""
905+
Note that `scopes` is usually None because request.auth is not set at `get_authorization_header`
906+
when the request is made from the frontend using cookies
907+
"""
904908
is_superuser = is_active_superuser(request)
905909
is_staff = is_active_staff(request)
906910

@@ -929,6 +933,8 @@ def from_request_org_and_scopes(
929933
superuser_scopes = get_superuser_scopes(auth_state, request.user, rpc_user_org_context)
930934
if scopes:
931935
superuser_scopes = superuser_scopes.union(set(scopes))
936+
if member and member.scopes:
937+
superuser_scopes = superuser_scopes.union(set(member.scopes))
932938

933939
return ApiBackedOrganizationGlobalAccess(
934940
rpc_user_organization_context=rpc_user_org_context,
@@ -1033,6 +1039,8 @@ def from_request(
10331039
superuser_scopes = get_superuser_scopes(auth_state, request.user, organization)
10341040
if scopes:
10351041
superuser_scopes = superuser_scopes.union(set(scopes))
1042+
if member and (member_scopes := member.get_scopes()):
1043+
superuser_scopes = superuser_scopes.union(set(member_scopes))
10361044

10371045
return OrganizationGlobalAccess(
10381046
organization=organization,

tests/sentry/auth/test_access.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -587,15 +587,17 @@ def test_superuser_readonly_scopes(self):
587587
# superuser in organization
588588
member = self.create_member(user=self.superuser, organization=self.org, role="member")
589589

590+
# If superuser is a member of the organization, it should have both
591+
# the member scopes and the superuser scopes
590592
result = self.from_request(request, self.org)
591-
assert result.scopes == SUPERUSER_READONLY_SCOPES
593+
assert result.scopes == set(member.get_scopes()).union(SUPERUSER_READONLY_SCOPES)
592594

593595
# readonly scopes does not override owner scopes if passed in
594596
with assume_test_silo_mode(SiloMode.REGION):
595597
member.update(role="owner")
596598

597599
result = self.from_request(request, self.org, scopes=member.get_scopes())
598-
assert result.scopes == set(member.get_scopes()).union({"org:superuser"})
600+
assert result.scopes == set(member.get_scopes()).union(SUPERUSER_READONLY_SCOPES)
599601

600602
@override_options({"superuser.read-write.ga-rollout": True})
601603
@override_settings(SENTRY_SELF_HOSTED=False)

0 commit comments

Comments
 (0)