Skip to content

Grab the correct name of RemoteOrganization to use in the query #7430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Sep 8, 2020
9 changes: 5 additions & 4 deletions readthedocs/oauth/services/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,18 +193,19 @@ def sync(self):
- updates fields for existing RemoteRepository/Organization
- deletes old RemoteRepository/Organization that are not present for this user
"""
repos = self.sync_repositories()
organizations, organization_repos = self.sync_organizations()
remote_repositories = self.sync_repositories()
remote_organizations, remote_repositories_organizations = self.sync_organizations()

# Delete RemoteRepository where the user doesn't have access anymore
# (skip RemoteRepository tied to a Project on this user)
repository_full_names = self.get_repository_full_names(repos + organization_repos)
all_remote_repositories = remote_repositories + remote_repositories_organizations
repository_full_names = [r.full_name for r in all_remote_repositories if r is not None]
self.user.oauth_repositories.exclude(
Q(full_name__in=repository_full_names) | Q(project__isnull=False)
).delete()

# Delete RemoteOrganization where the user doesn't have access anymore
organization_names = self.get_organization_names(organizations)
organization_names = [o.name for o in remote_organizations if o is not None]
self.user.oauth_organizations.exclude(name__in=organization_names).delete()

def create_repository(self, fields, privacy=None, organization=None):
Expand Down
30 changes: 14 additions & 16 deletions readthedocs/oauth/services/bitbucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@ class BitbucketService(Service):

def sync_repositories(self):
"""Sync repositories from Bitbucket API."""
repos = []
remote_repositories = []

# Get user repos
try:
repos = self.paginate(
'https://bitbucket.org/api/2.0/repositories/?role=member',
)
for repo in repos:
self.create_repository(repo)
remote_repository = self.create_repository(repo)
remote_repositories.append(remote_repository)

except (TypeError, ValueError):
log.warning('Error syncing Bitbucket repositories')
Expand Down Expand Up @@ -69,26 +70,29 @@ def sync_repositories(self):
except (TypeError, ValueError):
pass

return repos
return remote_repositories

def sync_organizations(self):
"""Sync Bitbucket teams (our RemoteOrganization) and team repositories."""
teams = []
repositories = []
remote_organizations = []
remote_repositories = []

try:
teams = self.paginate(
'https://api.bitbucket.org/2.0/teams/?role=member',
)
for team in teams:
org = self.create_organization(team)
remote_organization = self.create_organization(team)
repos = self.paginate(team['links']['repositories']['href'])

# Add organization's repositories to the result
repositories.extend(repos)
remote_organizations.append(remote_organization)

for repo in repos:
self.create_repository(repo, organization=org)
remote_repository = self.create_repository(
repo,
organization=remote_organization,
)
remote_repositories.append(remote_repository)

except ValueError:
log.warning('Error syncing Bitbucket organizations')
Expand All @@ -97,7 +101,7 @@ def sync_organizations(self):
'try reconnecting your account',
)

return teams, repositories
return remote_organizations, remote_repositories

def create_repository(self, fields, privacy=None, organization=None):
"""
Expand Down Expand Up @@ -190,12 +194,6 @@ def create_organization(self, fields):
organization.save()
return organization

def get_repository_full_names(self, repositories):
return {repository.get('full_name') for repository in repositories}

def get_organization_names(self, organizations):
return {organization.get('display_name') for organization in organizations}

def get_next_url_to_paginate(self, response):
return response.json().get('next')

Expand Down
32 changes: 15 additions & 17 deletions readthedocs/oauth/services/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,41 +36,45 @@ class GitHubService(Service):

def sync_repositories(self):
"""Sync repositories from GitHub API."""
repos = []
remote_repositories = []

try:
repos = self.paginate('https://api.github.com/user/repos?per_page=100')
for repo in repos:
self.create_repository(repo)
remote_repository = self.create_repository(repo)
remote_repositories.append(remote_repository)
except (TypeError, ValueError):
log.warning('Error syncing GitHub repositories')
raise SyncServiceError(
'Could not sync your GitHub repositories, '
'try reconnecting your account'
)
return repos
return remote_repositories

def sync_organizations(self):
"""Sync organizations from GitHub API."""
orgs = []
repositories = []
remote_organizations = []
remote_repositories = []

try:
orgs = self.paginate('https://api.github.com/user/orgs')
for org in orgs:
org_resp = self.get_session().get(org['url'])
org_obj = self.create_organization(org_resp.json())
org_details = self.get_session().get(org['url']).json()
remote_organization = self.create_organization(org_details)
# Add repos
# TODO ?per_page=100
org_repos = self.paginate(
'{org_url}/repos'.format(org_url=org['url']),
)

# Add all the repositories for this organization to the result
repositories.extend(org_repos)
remote_organizations.append(remote_organization)

for repo in org_repos:
self.create_repository(repo, organization=org_obj)
remote_repository = self.create_repository(
repo,
organization=remote_organization,
)
remote_repositories.append(remote_repository)

except (TypeError, ValueError):
log.warning('Error syncing GitHub organizations')
Expand All @@ -79,7 +83,7 @@ def sync_organizations(self):
'try reconnecting your account'
)

return orgs, repositories
return remote_organizations, remote_repositories

def create_repository(self, fields, privacy=None, organization=None):
"""
Expand Down Expand Up @@ -170,12 +174,6 @@ def create_organization(self, fields):
organization.save()
return organization

def get_repository_full_names(self, repositories):
return {repository.get('full_name') for repository in repositories}

def get_organization_names(self, organizations):
return {organization.get('name') for organization in organizations}

def get_next_url_to_paginate(self, response):
return response.links.get('next', {}).get('url')

Expand Down
30 changes: 14 additions & 16 deletions readthedocs/oauth/services/gitlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def get_paginated_results(self, response):
return response.json()

def sync_repositories(self):
repos = []
remote_repositories = []
try:
repos = self.paginate(
'{url}/api/v4/projects'.format(url=self.adapter.provider_base_url),
Expand All @@ -79,19 +79,20 @@ def sync_repositories(self):
)

for repo in repos:
self.create_repository(repo)
remote_repository = self.create_repository(repo)
remote_repositories.append(remote_repository)
except (TypeError, ValueError):
log.warning('Error syncing GitLab repositories')
raise SyncServiceError(
'Could not sync your GitLab repositories, '
'try reconnecting your account'
)

return repos
return remote_repositories

def sync_organizations(self):
orgs = []
repositories = []
remote_organizations = []
remote_repositories = []

try:
orgs = self.paginate(
Expand All @@ -102,7 +103,7 @@ def sync_organizations(self):
sort='asc',
)
for org in orgs:
org_obj = self.create_organization(org)
remote_organization = self.create_organization(org)
org_repos = self.paginate(
'{url}/api/v4/groups/{id}/projects'.format(
url=self.adapter.provider_base_url,
Expand All @@ -114,19 +115,22 @@ def sync_organizations(self):
sort='asc',
)

# Add organization's repositories to the result
repositories.extend(org_repos)
remote_organizations.append(remote_organization)

for repo in org_repos:
self.create_repository(repo, organization=org_obj)
remote_repository = self.create_repository(
repo,
organization=remote_organization,
)
remote_repositories.append(remote_repository)
except (TypeError, ValueError):
log.warning('Error syncing GitLab organizations')
raise SyncServiceError(
'Could not sync your GitLab organization, '
'try reconnecting your account'
)

return orgs, repositories
return remote_organizations, remote_repositories

def is_owned_by(self, owner_id):
return self.account.extra_data['id'] == owner_id
Expand Down Expand Up @@ -232,12 +236,6 @@ def create_organization(self, fields):
organization.save()
return organization

def get_repository_full_names(self, repositories):
return {repository.get('name_with_namespace') for repository in repositories}

def get_organization_names(self, organizations):
return {organization.get('name') for organization in organizations}

def get_webhook_data(self, repo_id, project, integration):
"""
Get webhook JSON data to post to the API.
Expand Down
Loading