Skip to content

Commit ac69118

Browse files
authored
Dashboard: optimize for .com (#12389)
- Use an internal cache for checking if an org has sso enabled. While we cache the results in redis, this still requires checking redis, and then hitting the DB, a local cache avoids that. - Instead of doing two queries for getting the teams (admin and read only), just do it in one.
1 parent 25b66f1 commit ac69118

File tree

1 file changed

+26
-12
lines changed

1 file changed

+26
-12
lines changed

readthedocs/core/permissions.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,29 +45,43 @@ def projects(cls, user, admin=False, member=False):
4545
# when we aren't using organizations.
4646
return user.projects.all()
4747

48-
if admin:
49-
# Project Team Admin
50-
admin_teams = user.teams.filter(access=ADMIN_ACCESS)
51-
for team in admin_teams:
52-
if not cls.has_sso_enabled(team.organization, SSOIntegration.PROVIDER_ALLAUTH):
48+
# Internal cache to avoid hitting the database/cache multiple times.
49+
_organizations_with_allauth_sso = {}
50+
51+
def _has_sso_with_allauth_enabled(org):
52+
if org.pk not in _organizations_with_allauth_sso:
53+
_organizations_with_allauth_sso[org.pk] = cls.has_sso_enabled(
54+
org,
55+
SSOIntegration.PROVIDER_ALLAUTH,
56+
)
57+
return _organizations_with_allauth_sso[org.pk]
58+
59+
# Projects from teams
60+
if admin or member:
61+
filter = Q()
62+
if admin:
63+
filter |= Q(access=ADMIN_ACCESS)
64+
if member:
65+
filter |= Q(access=READ_ONLY_ACCESS)
66+
67+
teams = user.teams.filter(filter).select_related(
68+
"organization", "organization__ssointegration"
69+
)
70+
for team in teams:
71+
if not _has_sso_with_allauth_enabled(team.organization):
5372
projects |= team.projects.all()
5473

74+
if admin:
5575
# Org Admin
5676
for org in user.owner_organizations.all():
57-
if not cls.has_sso_enabled(org, SSOIntegration.PROVIDER_ALLAUTH):
77+
if not _has_sso_with_allauth_enabled(org):
5878
# Do not grant admin access on projects for owners if the
5979
# organization has SSO enabled with Authorization on the provider.
6080
projects |= org.projects.all()
6181

6282
projects |= cls._get_projects_for_sso_user(user, admin=True)
6383

6484
if member:
65-
# Project Team Member
66-
member_teams = user.teams.filter(access=READ_ONLY_ACCESS)
67-
for team in member_teams:
68-
if not cls.has_sso_enabled(team.organization, SSOIntegration.PROVIDER_ALLAUTH):
69-
projects |= team.projects.all()
70-
7185
projects |= cls._get_projects_for_sso_user(user, admin=False)
7286

7387
return projects

0 commit comments

Comments
 (0)