Browse Source

feat(api): Add option to fetch Organization details without Pr… (#13925)

This adds an option to fetch Organization details without projects and teams. This is the direction we want to move towards, but we do not want to break the existing details endpoint
Billy Vong 5 years ago
parent
commit
f63f2a704d

+ 2 - 2
src/sentry/api/endpoints/accept_project_transfer.py

@@ -11,7 +11,7 @@ from sentry import roles
 from sentry.api.base import Endpoint, SessionAuthentication
 from sentry.api.decorators import sudo_required
 from sentry.api.serializers import serialize
-from sentry.api.serializers.models.organization import DetailedOrganizationSerializer
+from sentry.api.serializers.models.organization import DetailedOrganizationSerializerWithProjectsAndTeams
 from sentry.utils.signing import unsign
 from sentry.models import (
     AuditLogEntryEvent, OrganizationMember, Organization, OrganizationStatus, Team, Project
@@ -70,7 +70,7 @@ class AcceptProjectTransferEndpoint(Endpoint):
             'organizations': serialize(
                 list(organizations),
                 request.user,
-                DetailedOrganizationSerializer(),
+                DetailedOrganizationSerializerWithProjectsAndTeams(),
                 access=request.access
             ),
             'project': {

+ 6 - 3
src/sentry/api/endpoints/organization_details.py

@@ -318,12 +318,15 @@ class OrganizationDetailsEndpoint(OrganizationEndpoint):
 
         :pparam string organization_slug: the slug of the organization the
                                           team should be created for.
+        :param string detailed: Specify '0' to retrieve details without projects and teams.
         :auth: required
         """
+        is_detailed = request.GET.get('detailed', '1') != '0'
+        serializer = org_serializers.DetailedOrganizationSerializerWithProjectsAndTeams if is_detailed else org_serializers.DetailedOrganizationSerializer
         context = serialize(
             organization,
             request.user,
-            org_serializers.DetailedOrganizationSerializer(),
+            serializer(),
             access=request.access,
         )
         return self.respond(context)
@@ -391,7 +394,7 @@ class OrganizationDetailsEndpoint(OrganizationEndpoint):
                 serialize(
                     organization,
                     request.user,
-                    org_serializers.DetailedOrganizationSerializer(),
+                    org_serializers.DetailedOrganizationSerializerWithProjectsAndTeams(),
                     access=request.access,
                 )
             )
@@ -462,7 +465,7 @@ class OrganizationDetailsEndpoint(OrganizationEndpoint):
         context = serialize(
             organization,
             request.user,
-            org_serializers.DetailedOrganizationSerializer(),
+            org_serializers.DetailedOrganizationSerializerWithProjectsAndTeams(),
             access=request.access,
         )
         return self.respond(context, status=202)

+ 52 - 33
src/sentry/api/serializers/models/organization.py

@@ -120,39 +120,8 @@ class DetailedOrganizationSerializer(OrganizationSerializer):
     def get_attrs(self, item_list, user, **kwargs):
         return super(DetailedOrganizationSerializer, self).get_attrs(item_list, user)
 
-    def _project_list(self, organization, access):
-        member_projects = list(access.projects)
-        member_project_ids = [p.id for p in member_projects]
-        other_projects = list(Project.objects.filter(
-            organization=organization,
-            status=ProjectStatus.VISIBLE,
-        ).exclude(id__in=member_project_ids))
-        project_list = sorted(other_projects + member_projects, key=lambda x: x.slug)
-
-        for project in project_list:
-            project._organization_cache = organization
-        return project_list
-
-    def _team_list(self, organization, access):
-        member_teams = list(access.teams)
-        member_team_ids = [p.id for p in member_teams]
-        other_teams = list(Team.objects.filter(
-            organization=organization,
-            status=TeamStatus.VISIBLE,
-        ).exclude(id__in=member_team_ids))
-        team_list = sorted(other_teams + member_teams, key=lambda x: x.slug)
-
-        for team in team_list:
-            team._organization_cache = organization
-        return team_list
-
     def serialize(self, obj, attrs, user, access):
         from sentry import experiments
-        from sentry.api.serializers.models.project import ProjectSummarySerializer
-        from sentry.api.serializers.models.team import TeamSerializer
-
-        team_list = self._team_list(obj, access)
-        project_list = self._project_list(obj, access)
 
         onboarding_tasks = list(
             OrganizationOnboardingTask.objects.filter(
@@ -205,11 +174,61 @@ class DetailedOrganizationSerializer(OrganizationSerializer):
             'scrapeJavaScript': bool(obj.get_option('sentry:scrape_javascript', SCRAPE_JAVASCRIPT_DEFAULT)),
             'trustedRelays': obj.get_option('sentry:trusted-relays', TRUSTED_RELAYS_DEFAULT) or [],
         })
-        context['teams'] = serialize(team_list, user, TeamSerializer())
-        context['projects'] = serialize(project_list, user, ProjectSummarySerializer())
         context['access'] = access.scopes
         context['pendingAccessRequests'] = OrganizationAccessRequest.objects.filter(
             team__organization=obj,
         ).count()
         context['onboardingTasks'] = serialize(onboarding_tasks, user, OnboardingTasksSerializer())
         return context
+
+
+class DetailedOrganizationSerializerWithProjectsAndTeams(DetailedOrganizationSerializer):
+    def get_attrs(self, item_list, user, **kwargs):
+        return super(DetailedOrganizationSerializerWithProjectsAndTeams,
+                     self).get_attrs(item_list, user)
+
+    def _project_list(self, organization, access):
+        member_projects = list(access.projects)
+        member_project_ids = [p.id for p in member_projects]
+        other_projects = list(Project.objects.filter(
+            organization=organization,
+            status=ProjectStatus.VISIBLE,
+        ).exclude(id__in=member_project_ids))
+        project_list = sorted(other_projects + member_projects, key=lambda x: x.slug)
+
+        for project in project_list:
+            project._organization_cache = organization
+        return project_list
+
+    def _team_list(self, organization, access):
+        member_teams = list(access.teams)
+        member_team_ids = [p.id for p in member_teams]
+        other_teams = list(Team.objects.filter(
+            organization=organization,
+            status=TeamStatus.VISIBLE,
+        ).exclude(id__in=member_team_ids))
+        team_list = sorted(other_teams + member_teams, key=lambda x: x.slug)
+
+        for team in team_list:
+            team._organization_cache = organization
+        return team_list
+
+    def serialize(self, obj, attrs, user, access):
+        from sentry.api.serializers.models.project import ProjectSummarySerializer
+        from sentry.api.serializers.models.team import TeamSerializer
+
+        context = super(
+            DetailedOrganizationSerializerWithProjectsAndTeams,
+            self).serialize(
+            obj,
+            attrs,
+            user,
+            access)
+
+        team_list = self._team_list(obj, access)
+        project_list = self._project_list(obj, access)
+
+        context['teams'] = serialize(team_list, user, TeamSerializer())
+        context['projects'] = serialize(project_list, user, ProjectSummarySerializer())
+
+        return context

+ 3 - 2
src/sentry/templatetags/sentry_api.py

@@ -5,7 +5,8 @@ from django.http import HttpRequest
 
 from sentry.auth.access import from_user, NoAccess
 from sentry.api.serializers.base import serialize as serialize_func
-from sentry.api.serializers.models.organization import (DetailedOrganizationSerializer)
+from sentry.api.serializers.models.organization import (
+    DetailedOrganizationSerializerWithProjectsAndTeams)
 from sentry.utils import json
 
 register = template.Library()
@@ -38,7 +39,7 @@ def serialize_detailed_org(context, obj):
     context = serialize_func(
         obj,
         user,
-        DetailedOrganizationSerializer(),
+        DetailedOrganizationSerializerWithProjectsAndTeams(),
         access=access
     )
 

+ 25 - 0
tests/sentry/api/endpoints/test_organization_details.py

@@ -96,6 +96,31 @@ class OrganizationDetailsTest(APITestCase):
         assert len(team_slugs) == 2
         assert 'deleted' not in team_slugs
 
+    def test_details_no_projects_or_teams(self):
+        user = self.create_user('owner@example.org')
+        org = self.create_organization(owner=user)
+        team = self.create_team(
+            name='appy',
+            organization=org,
+            members=[user])
+        # Create non-member team to test response shape
+        self.create_team(name='no-member', organization=org)
+
+        for i in range(2):
+            self.create_project(organization=org, teams=[team])
+
+        url = reverse(
+            'sentry-api-0-organization-details', kwargs={
+                'organization_slug': org.slug,
+            }
+        )
+        self.login_as(user=user)
+
+        response = self.client.get(u'{}?detailed=0'.format(url), format='json')
+
+        assert 'projects' not in response.data
+        assert 'teams' not in response.data
+
     def test_as_superuser(self):
         self.user = self.create_user('super@example.org', is_superuser=True)
         org = self.create_organization(owner=self.user)