Skip to content

Commit f63f2a7

Browse files
authored
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
1 parent 791177b commit f63f2a7

File tree

5 files changed

+88
-40
lines changed

5 files changed

+88
-40
lines changed

src/sentry/api/endpoints/accept_project_transfer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from sentry.api.base import Endpoint, SessionAuthentication
1212
from sentry.api.decorators import sudo_required
1313
from sentry.api.serializers import serialize
14-
from sentry.api.serializers.models.organization import DetailedOrganizationSerializer
14+
from sentry.api.serializers.models.organization import DetailedOrganizationSerializerWithProjectsAndTeams
1515
from sentry.utils.signing import unsign
1616
from sentry.models import (
1717
AuditLogEntryEvent, OrganizationMember, Organization, OrganizationStatus, Team, Project
@@ -70,7 +70,7 @@ def get(self, request):
7070
'organizations': serialize(
7171
list(organizations),
7272
request.user,
73-
DetailedOrganizationSerializer(),
73+
DetailedOrganizationSerializerWithProjectsAndTeams(),
7474
access=request.access
7575
),
7676
'project': {

src/sentry/api/endpoints/organization_details.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,12 +318,15 @@ def get(self, request, organization):
318318
319319
:pparam string organization_slug: the slug of the organization the
320320
team should be created for.
321+
:param string detailed: Specify '0' to retrieve details without projects and teams.
321322
:auth: required
322323
"""
324+
is_detailed = request.GET.get('detailed', '1') != '0'
325+
serializer = org_serializers.DetailedOrganizationSerializerWithProjectsAndTeams if is_detailed else org_serializers.DetailedOrganizationSerializer
323326
context = serialize(
324327
organization,
325328
request.user,
326-
org_serializers.DetailedOrganizationSerializer(),
329+
serializer(),
327330
access=request.access,
328331
)
329332
return self.respond(context)
@@ -391,7 +394,7 @@ def put(self, request, organization):
391394
serialize(
392395
organization,
393396
request.user,
394-
org_serializers.DetailedOrganizationSerializer(),
397+
org_serializers.DetailedOrganizationSerializerWithProjectsAndTeams(),
395398
access=request.access,
396399
)
397400
)
@@ -462,7 +465,7 @@ def delete(self, request, organization):
462465
context = serialize(
463466
organization,
464467
request.user,
465-
org_serializers.DetailedOrganizationSerializer(),
468+
org_serializers.DetailedOrganizationSerializerWithProjectsAndTeams(),
466469
access=request.access,
467470
)
468471
return self.respond(context, status=202)

src/sentry/api/serializers/models/organization.py

Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -120,39 +120,8 @@ class DetailedOrganizationSerializer(OrganizationSerializer):
120120
def get_attrs(self, item_list, user, **kwargs):
121121
return super(DetailedOrganizationSerializer, self).get_attrs(item_list, user)
122122

123-
def _project_list(self, organization, access):
124-
member_projects = list(access.projects)
125-
member_project_ids = [p.id for p in member_projects]
126-
other_projects = list(Project.objects.filter(
127-
organization=organization,
128-
status=ProjectStatus.VISIBLE,
129-
).exclude(id__in=member_project_ids))
130-
project_list = sorted(other_projects + member_projects, key=lambda x: x.slug)
131-
132-
for project in project_list:
133-
project._organization_cache = organization
134-
return project_list
135-
136-
def _team_list(self, organization, access):
137-
member_teams = list(access.teams)
138-
member_team_ids = [p.id for p in member_teams]
139-
other_teams = list(Team.objects.filter(
140-
organization=organization,
141-
status=TeamStatus.VISIBLE,
142-
).exclude(id__in=member_team_ids))
143-
team_list = sorted(other_teams + member_teams, key=lambda x: x.slug)
144-
145-
for team in team_list:
146-
team._organization_cache = organization
147-
return team_list
148-
149123
def serialize(self, obj, attrs, user, access):
150124
from sentry import experiments
151-
from sentry.api.serializers.models.project import ProjectSummarySerializer
152-
from sentry.api.serializers.models.team import TeamSerializer
153-
154-
team_list = self._team_list(obj, access)
155-
project_list = self._project_list(obj, access)
156125

157126
onboarding_tasks = list(
158127
OrganizationOnboardingTask.objects.filter(
@@ -205,11 +174,61 @@ def serialize(self, obj, attrs, user, access):
205174
'scrapeJavaScript': bool(obj.get_option('sentry:scrape_javascript', SCRAPE_JAVASCRIPT_DEFAULT)),
206175
'trustedRelays': obj.get_option('sentry:trusted-relays', TRUSTED_RELAYS_DEFAULT) or [],
207176
})
208-
context['teams'] = serialize(team_list, user, TeamSerializer())
209-
context['projects'] = serialize(project_list, user, ProjectSummarySerializer())
210177
context['access'] = access.scopes
211178
context['pendingAccessRequests'] = OrganizationAccessRequest.objects.filter(
212179
team__organization=obj,
213180
).count()
214181
context['onboardingTasks'] = serialize(onboarding_tasks, user, OnboardingTasksSerializer())
215182
return context
183+
184+
185+
class DetailedOrganizationSerializerWithProjectsAndTeams(DetailedOrganizationSerializer):
186+
def get_attrs(self, item_list, user, **kwargs):
187+
return super(DetailedOrganizationSerializerWithProjectsAndTeams,
188+
self).get_attrs(item_list, user)
189+
190+
def _project_list(self, organization, access):
191+
member_projects = list(access.projects)
192+
member_project_ids = [p.id for p in member_projects]
193+
other_projects = list(Project.objects.filter(
194+
organization=organization,
195+
status=ProjectStatus.VISIBLE,
196+
).exclude(id__in=member_project_ids))
197+
project_list = sorted(other_projects + member_projects, key=lambda x: x.slug)
198+
199+
for project in project_list:
200+
project._organization_cache = organization
201+
return project_list
202+
203+
def _team_list(self, organization, access):
204+
member_teams = list(access.teams)
205+
member_team_ids = [p.id for p in member_teams]
206+
other_teams = list(Team.objects.filter(
207+
organization=organization,
208+
status=TeamStatus.VISIBLE,
209+
).exclude(id__in=member_team_ids))
210+
team_list = sorted(other_teams + member_teams, key=lambda x: x.slug)
211+
212+
for team in team_list:
213+
team._organization_cache = organization
214+
return team_list
215+
216+
def serialize(self, obj, attrs, user, access):
217+
from sentry.api.serializers.models.project import ProjectSummarySerializer
218+
from sentry.api.serializers.models.team import TeamSerializer
219+
220+
context = super(
221+
DetailedOrganizationSerializerWithProjectsAndTeams,
222+
self).serialize(
223+
obj,
224+
attrs,
225+
user,
226+
access)
227+
228+
team_list = self._team_list(obj, access)
229+
project_list = self._project_list(obj, access)
230+
231+
context['teams'] = serialize(team_list, user, TeamSerializer())
232+
context['projects'] = serialize(project_list, user, ProjectSummarySerializer())
233+
234+
return context

src/sentry/templatetags/sentry_api.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66
from sentry.auth.access import from_user, NoAccess
77
from sentry.api.serializers.base import serialize as serialize_func
8-
from sentry.api.serializers.models.organization import (DetailedOrganizationSerializer)
8+
from sentry.api.serializers.models.organization import (
9+
DetailedOrganizationSerializerWithProjectsAndTeams)
910
from sentry.utils import json
1011

1112
register = template.Library()
@@ -38,7 +39,7 @@ def serialize_detailed_org(context, obj):
3839
context = serialize_func(
3940
obj,
4041
user,
41-
DetailedOrganizationSerializer(),
42+
DetailedOrganizationSerializerWithProjectsAndTeams(),
4243
access=access
4344
)
4445

tests/sentry/api/endpoints/test_organization_details.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,31 @@ def test_with_projects(self):
9696
assert len(team_slugs) == 2
9797
assert 'deleted' not in team_slugs
9898

99+
def test_details_no_projects_or_teams(self):
100+
user = self.create_user('[email protected]')
101+
org = self.create_organization(owner=user)
102+
team = self.create_team(
103+
name='appy',
104+
organization=org,
105+
members=[user])
106+
# Create non-member team to test response shape
107+
self.create_team(name='no-member', organization=org)
108+
109+
for i in range(2):
110+
self.create_project(organization=org, teams=[team])
111+
112+
url = reverse(
113+
'sentry-api-0-organization-details', kwargs={
114+
'organization_slug': org.slug,
115+
}
116+
)
117+
self.login_as(user=user)
118+
119+
response = self.client.get(u'{}?detailed=0'.format(url), format='json')
120+
121+
assert 'projects' not in response.data
122+
assert 'teams' not in response.data
123+
99124
def test_as_superuser(self):
100125
self.user = self.create_user('[email protected]', is_superuser=True)
101126
org = self.create_organization(owner=self.user)

0 commit comments

Comments
 (0)