Skip to content

Commit 1b54393

Browse files
authored
Merge pull request #7479 from readthedocs/humitos/gitlab-remoterepository-admin
2 parents 37df69f + 76559c9 commit 1b54393

File tree

2 files changed

+30
-15
lines changed

2 files changed

+30
-15
lines changed

readthedocs/oauth/services/gitlab.py

+25-6
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ class GitLabService(Service):
4141
re.escape(urlparse(adapter.provider_base_url).netloc),
4242
)
4343

44+
PERMISSION_NO_ACCESS = 0
45+
PERMISSION_MAINTAINER = 40
46+
PERMISSION_OWNER = 50
47+
4448
def _get_repo_id(self, project):
4549
# The ID or URL-encoded path of the project
4650
# https://docs.gitlab.com/ce/api/README.html#namespaced-path-encoding
@@ -132,13 +136,20 @@ def sync_organizations(self):
132136

133137
return remote_organizations, remote_repositories
134138

135-
def is_owned_by(self, owner_id):
136-
return self.account.extra_data['id'] == owner_id
137-
138139
def create_repository(self, fields, privacy=None, organization=None):
139140
"""
140141
Update or create a repository from GitLab API response.
141142
143+
``admin`` field is computed using the ``permissions`` fields from the
144+
repository response. The permission from GitLab is given by an integer:
145+
* 0: No access
146+
* (... others ...)
147+
* 40: Maintainer
148+
* 50: Owner
149+
150+
https://docs.gitlab.com/ee/api/access_requests.html
151+
https://gitlab.com/help/user/permissions
152+
142153
:param fields: dictionary of response data from API
143154
:param privacy: privacy level to support
144155
:param organization: remote organization to associate with
@@ -179,9 +190,17 @@ def create_repository(self, fields, privacy=None, organization=None):
179190
else:
180191
repo.clone_url = fields['http_url_to_repo']
181192

182-
repo.admin = not repo_is_public
183-
if not repo.admin and 'owner' in fields:
184-
repo.admin = self.is_owned_by(fields['owner']['id'])
193+
project_access_level = group_access_level = self.PERMISSION_NO_ACCESS
194+
project_access = fields.get('permissions', {}).get('project_access', {})
195+
if project_access:
196+
project_access_level = project_access.get('access_level', self.PERMISSION_NO_ACCESS)
197+
group_access = fields.get('permissions', {}).get('group_access', {})
198+
if group_access:
199+
group_access_level = group_access.get('access_level', self.PERMISSION_NO_ACCESS)
200+
repo.admin = any([
201+
project_access_level in (self.PERMISSION_MAINTAINER, self.PERMISSION_OWNER),
202+
group_access_level in (self.PERMISSION_MAINTAINER, self.PERMISSION_OWNER),
203+
])
185204

186205
repo.vcs = 'git'
187206
repo.account = self.account

readthedocs/rtd_tests/tests/test_oauth.py

+5-9
Original file line numberDiff line numberDiff line change
@@ -951,12 +951,10 @@ def get_private_repo_data(self):
951951
return data
952952

953953
def test_make_project_pass(self):
954-
with mock.patch('readthedocs.oauth.services.gitlab.GitLabService.is_owned_by') as m: # yapf: disable
955-
m.return_value = True
956-
repo = self.service.create_repository(
957-
self.repo_response_data, organization=self.org,
958-
privacy=self.privacy,
959-
)
954+
repo = self.service.create_repository(
955+
self.repo_response_data, organization=self.org,
956+
privacy=self.privacy,
957+
)
960958
self.assertIsInstance(repo, RemoteRepository)
961959
self.assertEqual(repo.name, 'testrepo')
962960
self.assertEqual(repo.full_name, 'testorga / testrepo')
@@ -1009,9 +1007,7 @@ def test_make_private_project(self):
10091007
"""
10101008
data = self.repo_response_data.copy()
10111009
data['visibility'] = 'public'
1012-
with mock.patch('readthedocs.oauth.services.gitlab.GitLabService.is_owned_by') as m: # yapf: disable
1013-
m.return_value = True
1014-
repo = self.service.create_repository(data, organization=self.org)
1010+
repo = self.service.create_repository(data, organization=self.org)
10151011
self.assertIsNotNone(repo)
10161012

10171013
@mock.patch('readthedocs.oauth.services.gitlab.log')

0 commit comments

Comments
 (0)