Browse Source

fix(scim): add excludeAttributes to team details routes (#27938)

* fix(scim): add excludeAttributes to team details routes as well as team_index
Josh Ferge 3 years ago
parent
commit
b8c6cab9a0

+ 6 - 6
src/sentry/scim/endpoints/teams.py

@@ -39,6 +39,10 @@ delete_logger = logging.getLogger("sentry.deletions.api")
 CONFLICTING_SLUG_ERROR = "A team with this slug already exists."
 CONFLICTING_SLUG_ERROR = "A team with this slug already exists."
 
 
 
 
+def _team_expand(query):
+    return None if "members" in query.get("excludedAttributes", []) else ["members"]
+
+
 class OrganizationSCIMTeamIndex(SCIMEndpoint, OrganizationTeamsEndpoint):
 class OrganizationSCIMTeamIndex(SCIMEndpoint, OrganizationTeamsEndpoint):
     permission_classes = (OrganizationSCIMTeamPermission,)
     permission_classes = (OrganizationSCIMTeamPermission,)
 
 
@@ -54,10 +58,6 @@ class OrganizationSCIMTeamIndex(SCIMEndpoint, OrganizationTeamsEndpoint):
         except ValueError:
         except ValueError:
             raise ParseError(detail=SCIM_400_INVALID_FILTER)
             raise ParseError(detail=SCIM_400_INVALID_FILTER)
 
 
-        if "members" in request.GET.get("excludedAttributes", []):
-            expand = None
-        else:
-            expand = ["members"]
         queryset = Team.objects.filter(
         queryset = Team.objects.filter(
             organization=organization, status=TeamStatus.VISIBLE
             organization=organization, status=TeamStatus.VISIBLE
         ).order_by("slug")
         ).order_by("slug")
@@ -69,7 +69,7 @@ class OrganizationSCIMTeamIndex(SCIMEndpoint, OrganizationTeamsEndpoint):
             return list(queryset[offset : offset + limit])
             return list(queryset[offset : offset + limit])
 
 
         def on_results(results):
         def on_results(results):
-            results = serialize(results, None, TeamSCIMSerializer(expand=expand))
+            results = serialize(results, None, TeamSCIMSerializer(expand=_team_expand(request.GET)))
             return self.list_api_format(request, queryset.count(), results)
             return self.list_api_format(request, queryset.count(), results)
 
 
         return self.paginate(
         return self.paginate(
@@ -110,7 +110,7 @@ class OrganizationSCIMTeamDetails(SCIMEndpoint, TeamDetailsEndpoint):
         return team
         return team
 
 
     def get(self, request, organization, team):
     def get(self, request, organization, team):
-        context = serialize(team, serializer=TeamSCIMSerializer(expand=["members"]))
+        context = serialize(team, serializer=TeamSCIMSerializer(expand=_team_expand(request.GET)))
         return Response(context)
         return Response(context)
 
 
     def _add_members_operation(self, request, operation, team):
     def _add_members_operation(self, request, operation, team):

+ 18 - 7
tests/sentry/api/endpoints/test_scim_team_details.py

@@ -4,9 +4,8 @@ from sentry.models import OrganizationMemberTeam, Team, TeamStatus
 from sentry.testutils import SCIMTestCase
 from sentry.testutils import SCIMTestCase
 
 
 
 
-class SCIMGroupDetailsTests(SCIMTestCase):
-    def test_group_details_404(self):
-        # test team route 404s
+class SCIMTeamDetailsTests(SCIMTestCase):
+    def test_team_details_404(self):
         url = reverse(
         url = reverse(
             "sentry-api-0-organization-scim-team-details",
             "sentry-api-0-organization-scim-team-details",
             args=[self.organization.slug, 2],
             args=[self.organization.slug, 2],
@@ -21,7 +20,6 @@ class SCIMGroupDetailsTests(SCIMTestCase):
 
 
     def test_scim_team_details_basic(self):
     def test_scim_team_details_basic(self):
         team = self.create_team(organization=self.organization, name="test-scimv2")
         team = self.create_team(organization=self.organization, name="test-scimv2")
-        # test team details GET
         url = reverse(
         url = reverse(
             "sentry-api-0-organization-scim-team-details",
             "sentry-api-0-organization-scim-team-details",
             args=[self.organization.slug, team.id],
             args=[self.organization.slug, team.id],
@@ -36,9 +34,24 @@ class SCIMGroupDetailsTests(SCIMTestCase):
             "meta": {"resourceType": "Group"},
             "meta": {"resourceType": "Group"},
         }
         }
 
 
+    def test_scim_team_details_excluded_attributes(self):
+        team = self.create_team(organization=self.organization, name="test-scimv2")
+        url = reverse(
+            "sentry-api-0-organization-scim-team-details",
+            args=[self.organization.slug, team.id],
+        )
+        response = self.client.get(f"{url}?excludedAttributes=members")
+        assert response.status_code == 200, response.content
+        assert response.data == {
+            "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
+            "id": str(team.id),
+            "displayName": "test-scimv2",
+            "members": None,
+            "meta": {"resourceType": "Group"},
+        }
+
     def test_scim_team_details_patch_replace_rename_team(self):
     def test_scim_team_details_patch_replace_rename_team(self):
         team = self.create_team(organization=self.organization)
         team = self.create_team(organization=self.organization)
-        # rename a team with the replace op
         url = reverse(
         url = reverse(
             "sentry-api-0-organization-scim-team-details", args=[self.organization.slug, team.id]
             "sentry-api-0-organization-scim-team-details", args=[self.organization.slug, team.id]
         )
         )
@@ -104,8 +117,6 @@ class SCIMGroupDetailsTests(SCIMTestCase):
             team_id=str(team.id), organizationmember_id=member1.id
             team_id=str(team.id), organizationmember_id=member1.id
         ).exists()
         ).exists()
 
 
-        # remove a member from a team
-
     def test_scim_team_details_patch_remove(self):
     def test_scim_team_details_patch_remove(self):
         team = self.create_team(organization=self.organization)
         team = self.create_team(organization=self.organization)
         member1 = self.create_member(
         member1 = self.create_member(