Browse Source

ref: fix typing for serializers.models.role (#84334)

<!-- Describe your PR here. -->
anthony sottile 1 month ago
parent
commit
6f897bf9bb
2 changed files with 48 additions and 42 deletions
  1. 0 1
      pyproject.toml
  2. 48 41
      src/sentry/api/serializers/models/role.py

+ 0 - 1
pyproject.toml

@@ -147,7 +147,6 @@ module = [
     "sentry.api.permissions",
     "sentry.api.serializers.models.auth_provider",
     "sentry.api.serializers.models.event",
-    "sentry.api.serializers.models.role",
     "sentry.auth.helper",
     "sentry.auth.provider",
     "sentry.auth.system",

+ 48 - 41
src/sentry/api/serializers/models/role.py

@@ -1,17 +1,21 @@
-from collections.abc import Mapping
+from collections.abc import Collection, Mapping
 from typing import Any, TypedDict
 
+from django.contrib.auth.models import AnonymousUser
+
 from sentry import features
 from sentry.api.serializers import Serializer
+from sentry.models.organization import Organization
 from sentry.roles.manager import OrganizationRole, Role, TeamRole
 from sentry.users.models.user import User
+from sentry.users.services.user.model import RpcUser
 
 
 class BaseRoleSerializerResponse(TypedDict):
     id: str
     name: str
     desc: str
-    scopes: list[str]
+    scopes: frozenset[str]
 
     allowed: bool
     isAllowed: bool
@@ -29,58 +33,61 @@ class TeamRoleSerializerResponse(BaseRoleSerializerResponse):
     isMinimumRoleFor: str | None
 
 
-class RoleSerializer(Serializer):
+def _serialize_base_role(
+    obj: Role, organization: Organization, *, allowed_roles: Collection[Role] = ()
+) -> BaseRoleSerializerResponse:
+    has_team_roles = features.has("organizations:team-roles", organization)
+    is_retired_role = has_team_roles and obj.is_retired
+
+    return {
+        "id": str(obj.id),
+        "name": obj.name,
+        "desc": obj.desc,
+        "scopes": obj.scopes,
+        "allowed": obj in allowed_roles,  # backward compatibility
+        "isAllowed": obj in allowed_roles,
+        "isRetired": is_retired_role,
+        "isTeamRolesAllowed": obj.is_team_roles_allowed,
+    }
+
+
+class OrganizationRoleSerializer(Serializer):
     def __init__(self, **kwargs):
         """
-        Remove this when deleting "organization:team-roles" flag
+        Remove this when deleting "organizations:team-roles" flag
         """
         self.organization = kwargs["organization"]
 
     def serialize(
         self,
-        obj: Role,
+        obj: OrganizationRole,
         attrs: Mapping[str, Any],
-        user: User,
+        user: User | RpcUser | AnonymousUser,
         **kwargs: Any,
-    ) -> BaseRoleSerializerResponse:
-        has_team_roles = features.has("organizations:team-roles", self.organization)
-        is_retired_role = has_team_roles and obj.is_retired
-
-        allowed_roles = kwargs.get("allowed_roles") or ()
-
+    ) -> OrganizationRoleSerializerResponse:
+        base = _serialize_base_role(
+            obj, self.organization, allowed_roles=kwargs.get("allowed_roles", ())
+        )
         return {
-            "id": str(obj.id),
-            "name": obj.name,
-            "desc": obj.desc,
-            "scopes": obj.scopes,
-            "allowed": obj in allowed_roles,  # backward compatibility
-            "isAllowed": obj in allowed_roles,
-            "isRetired": is_retired_role,
-            "isTeamRolesAllowed": obj.is_team_roles_allowed,
+            **base,
+            "is_global": obj.is_global,  # backward compatibility
+            "isGlobal": obj.is_global,
+            "minimumTeamRole": obj.get_minimum_team_role().id,
         }
 
 
-class OrganizationRoleSerializer(RoleSerializer):
-    def serialize(
-        self, obj: OrganizationRole, attrs, user, **kwargs
-    ) -> OrganizationRoleSerializerResponse:
-        serialized = super().serialize(obj, attrs, user, **kwargs)
-        serialized.update(
-            {
-                "is_global": obj.is_global,  # backward compatibility
-                "isGlobal": obj.is_global,
-                "minimumTeamRole": obj.get_minimum_team_role().id,
-            }
-        )
-        return serialized
-
+class TeamRoleSerializer(Serializer):
+    def __init__(self, **kwargs):
+        """
+        Remove this when deleting "organizations:team-roles" flag
+        """
+        self.organization = kwargs["organization"]
 
-class TeamRoleSerializer(RoleSerializer):
     def serialize(self, obj: TeamRole, attrs, user, **kwargs) -> TeamRoleSerializerResponse:
-        serialized = super().serialize(obj, attrs, user, **kwargs)
-        serialized.update(
-            {
-                "isMinimumRoleFor": obj.is_minimum_role_for,
-            }
+        base = _serialize_base_role(
+            obj, self.organization, allowed_roles=kwargs.get("allowed_roles", ())
         )
-        return serialized
+        return {
+            **base,
+            "isMinimumRoleFor": obj.is_minimum_role_for,
+        }