def __init__(self, name): logger = logging.getLogger(__name__ + '.__init__') self.name = name self.IGH = GitHub(GitHubToken(get_api_key('GH'))) self.IGL = GitLab(GitLabPrivateToken(get_api_key('GL'))) logger.info('loading org %s' % name) self.REPOS = dict() self.gh_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGH.write_repositories) } self.REPOS.update(self.gh_repos) self.gl_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGL.write_repositories) } self.REPOS.update(self.gl_repos) logger.info('loaded org %s with %d repositories' % (name, len(self.REPOS)))
def setUp(self): self.gl = GitLab(GitLabOAuthToken( os.environ.get('GITLAB_TEST_TOKEN', ''))) self.repo_name = 'test/test' self.default_data = { 'project': { 'path_with_namespace': self.repo_name, }, 'object_attributes': { 'id': 12, 'iid': 23, 'action': 'open', 'noteable_type': 'Issue', 'target': { 'path_with_namespace': 'gitmate-test-user/test' } }, 'commit': { 'id': 'bcbb5ec396a2c0f828686f14fac9b80b780504f2', }, 'merge_request': { 'iid': 123, }, 'issue': { 'iid': 123, 'action': 'open', }, 'repository': { 'git_ssh_url': '[email protected]:gitmate-test-user/test.git' } }
def test_repo_permissions_inheritance(self): repos = [ { 'namespace':{'id': 1, 'parent_id': None}, 'permissions': {'group_access': {'access_level': 40}, 'project_access': None} }, { 'namespace': {'id': 2, 'parent_id': 1}, 'permissions': {'group_access': None, 'project_access': None} }, { 'namespace': {'id': 3, 'parent_id': 2}, 'permissions': {'group_access': None, 'project_access': None} }, { 'namespace': {'id': 4, 'parent_id': None}, 'permissions': {'group_access': None, 'project_access': {'access_level': 40}} } ] self.assertEqual(set(map(lambda x: x['namespace']['id'], GitLab._get_repos_with_permissions( repos, AccessLevel.ADMIN))), {1, 2, 3, 4})
class GitOrg(): def __init__(self, name): logger = logging.getLogger(__name__ + '.__init__') self.name = name self.IGH = GitHub(GitHubToken(get_api_key('GH'))) self.IGL = GitLab(GitLabPrivateToken(get_api_key('GL'))) logger.info('loading org %s' % name) self.REPOS = dict() self.gh_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGH.write_repositories) } self.REPOS.update(self.gh_repos) self.gl_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGL.write_repositories) } self.REPOS.update(self.gl_repos) logger.info('loaded org %s with %d repositories' % (name, len(self.REPOS))) def get_repo(self, repo_name): logger = logging.getLogger(__name__ + '.get_repo') if repo_name not in self.REPOS: full_name = '%s/%s' % (self.name, repo_name) logger.info('loading non-writable repo %s' % full_name) try: repo = self.IGH.get_repo(full_name) # Use `clone_url` to ensure the repository is usable repo.clone_url self.REPOS[repo_name] = repo logger.info('loaded non-writable GitHub repo %s' % full_name) return repo except Exception as e: logger.error('Unable to load GitHub repo %s: %s' % (full_name, e)) try: repo = self.IGL.get_repo(full_name) # Use `clone_url` to ensure the repository is usable repo.clone_url logger.info('loaded non-writable GitLab repo %s' % full_name) self.REPOS[repo_name] = repo except Exception as e: logger.error('Unable to load GitLab repo %s: %s' % (full_name, e)) return self.REPOS[repo_name]
def __init__(self, bot, name=None): super().__init__(bot, name) teams = dict() try: gh = github3.login(token=os.environ.get('GH_TOKEN')) assert gh is not None except AssertionError: self.log.error( 'Cannot create github object, please check GH_TOKEN') else: self.GH3_ORG = gh.organization(self.GH_ORG_NAME) for team in self.GH3_ORG.teams(): teams[team.name] = team self._teams = teams self.IGH = GitHub(GitHubToken(os.environ.get('GH_TOKEN'))) self.IGL = GitLab(GitLabPrivateToken(os.environ.get('GL_TOKEN'))) self.REPOS = dict() try: self.gh_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.GH_ORG_NAME), self.IGH.write_repositories) } except RuntimeError: self.log.exception( 'Something went wrong in fetching github repos.') else: self.REPOS.update(self.gh_repos) try: self.gl_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.GL_ORG_NAME), self.IGL.write_repositories) } except RuntimeError: # pragma: no cover, for logging self.log.exception( 'Something went wrong in fetching gitlab repos.') else: self.REPOS.update(self.gl_repos) self.invited_users = set() self.hello_world_users = set()
def __init__(self, name): self.name = name self.IGH = GitHub(GitHubToken(get_api_key('GH'))) self.IGL = GitLab(GitLabPrivateToken(get_api_key('GL'))) print('loading org %s' % name) self.REPOS = dict() self.gh_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGH.write_repositories) } self.REPOS.update(self.gh_repos) self.gl_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGL.write_repositories) } self.REPOS.update(self.gl_repos) print('loaded org %s' % name)
def get_ihoster(url): global _IGH, _IGL if url.resource == 'github.com': if not _IGH: # Allow unauthenticated requests try: token = get_api_key('GH') except Exception: token = None _IGH = GitHub(GitHubToken(token)) return _IGH elif url.resource == 'gitlab.com': if not _IGL: # https://gitlab.com/gitmate/open-source/IGitt/issues/114 _IGL = GitLab(GitLabPrivateToken(get_api_key('GL'))) return _IGL
class GitLabHosterTest(IGittTestCase): def setUp(self): self.gl = GitLab(GitLabOAuthToken(os.environ.get('GITLAB_TEST_TOKEN', ''))) def test_repo_permissions_inheritance(self): repos = [ { 'namespace':{'id': 1, 'parent_id': None}, 'permissions': {'group_access': {'access_level': 40}, 'project_access': None} }, { 'namespace': {'id': 2, 'parent_id': 1}, 'permissions': {'group_access': None, 'project_access': None} }, { 'namespace': {'id': 3, 'parent_id': 2}, 'permissions': {'group_access': None, 'project_access': None} }, { 'namespace': {'id': 4, 'parent_id': None}, 'permissions': {'group_access': None, 'project_access': {'access_level': 40}} } ] self.assertEqual(set(map(lambda x: x['namespace']['id'], GitLab._get_repos_with_permissions( repos, AccessLevel.ADMIN))), {1, 2, 3, 4}) def test_master_repositories(self): self.assertEqual(sorted(map(lambda x: x.full_name, self.gl.master_repositories)), ['gitmate-test-user/test']) def test_owned_repositories(self): self.assertEqual(sorted(map(lambda x: x.full_name, self.gl.owned_repositories)), ['gitmate-test-user/test']) def test_write_repositories(self): self.assertEqual(sorted(map(lambda x: x.full_name, self.gl.write_repositories)), ['gitmate-test-user/test']) def test_get_repo(self): self.assertEqual(self.gl.get_repo('gitmate-test-user/test').full_name, 'gitmate-test-user/test')
class GitOrg(): def __init__(self, name): self.name = name self.IGH = GitHub(GitHubToken(get_api_key('GH'))) self.IGL = GitLab(GitLabPrivateToken(get_api_key('GL'))) print('loading org %s' % name) self.REPOS = dict() self.gh_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGH.write_repositories) } self.REPOS.update(self.gh_repos) self.gl_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGL.write_repositories) } self.REPOS.update(self.gl_repos) print('loaded org %s' % name) def get_repo(self, repo_name): if repo_name not in self.REPOS: full_name = '%s/%s' % (self.name, repo_name) print('loading non-writable repo %s' % full_name) try: repo = self.IGH.get_repo(full_name) repo.identifier self.REPOS[repo_name] = repo except Exception: print('Unable to load GitHub repo %s' % full_name) try: repo = self.IGL.get_repo(full_name) repo.identifier self.REPOS[repo_name] = repo except Exception: print('Unable to load GitLab repo %s' % full_name) return self.REPOS[repo_name]
def gitlab_webhook_receiver(request): """ Receives webhooks from GitLab and carries out the appropriate action. """ webhook = json.loads(request.body.decode('utf-8')) event = request.META['HTTP_X_GITLAB_EVENT'] def _get_repo_name(data: dict): # Push, Tag, Issue, Note, Wiki Page and Pipeline Hooks if 'project' in data.keys(): return data['project']['path_with_namespace'] # Merge Request Hook if 'object_attributes' in data.keys(): return data['object_attributes']['target']['path_with_namespace'] # Build Hook if 'repository' in data.keys(): ssh_url = data['repository']['git_ssh_url'] return ssh_url[ssh_url.find(':') + 1: ssh_url.rfind('.git')] repository = _get_repo_name(webhook) repo_obj = get_object_or_404(Repository, active=True, full_name=repository, provider=Providers.GITLAB.value) try: for action, objs in GitLab(repo_obj.token).handle_webhook( event, webhook): ResponderRegistrar.respond(action, *objs, repo=repo_obj) except NotImplementedError: # pragma: no cover # IGitt can't handle it yet, upstream issue, no plugin needs it yet return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_200_OK)
class GitLabWebhookTest(IGittTestCase): def setUp(self): self.gl = GitLab(GitLabOAuthToken( os.environ.get('GITLAB_TEST_TOKEN', ''))) self.repo_name = 'test/test' self.default_data = { 'project': { 'path_with_namespace': self.repo_name, }, 'object_attributes': { 'id': 12, 'iid': 23, 'action': 'open', 'noteable_type': 'Issue', 'target': { 'path_with_namespace': 'gitmate-test-user/test' } }, 'commit': { 'id': 'bcbb5ec396a2c0f828686f14fac9b80b780504f2', }, 'merge_request': { 'iid': 123, }, 'issue': { 'iid': 123, 'action': 'open', }, 'repository': { 'git_ssh_url': '[email protected]:gitmate-test-user/test.git' } } def test_unknown_event(self): with self.assertRaises(NotImplementedError): list(self.gl.handle_webhook('unknown_event', self.default_data)) def test_issue_hook(self): for event, obj in self.gl.handle_webhook('Issue Hook', self.default_data): self.assertEqual(event, IssueActions.OPENED) self.assertIsInstance(obj[0], GitLabIssue) def test_pr_hook(self): for event, obj in self.gl.handle_webhook('Merge Request Hook', self.default_data): self.assertEqual(event, MergeRequestActions.OPENED) self.assertIsInstance(obj[0], GitLabMergeRequest) def test_pr_synchronized(self): data = self.default_data data['object_attributes']['oldrev'] = 'deadbeef' for event, obj in self.gl.handle_webhook('Merge Request Hook', self.default_data): self.assertEqual(event, MergeRequestActions.SYNCHRONIZED) self.assertIsInstance(obj[0], GitLabMergeRequest) def test_issue_comment(self): for event, obj in self.gl.handle_webhook('Note Hook', self.default_data): self.assertEqual(event, IssueActions.COMMENTED) self.assertIsInstance(obj[0], GitLabIssue) self.assertIsInstance(obj[1], GitLabComment) def test_unsupported_comment(self): data = self.default_data data['object_attributes']['noteable_type'] = 'Snippet' with self.assertRaises(NotImplementedError): list(self.gl.handle_webhook('Note Hook', data)) def test_pr_comment(self): data = self.default_data del data['project'] data['object_attributes']['noteable_type'] = 'MergeRequest' for event, obj in self.gl.handle_webhook('Note Hook', data): self.assertEqual(event, MergeRequestActions.COMMENTED) self.assertIsInstance(obj[0], GitLabMergeRequest) self.assertIsInstance(obj[1], GitLabComment) def test_status(self): del self.default_data['project'] del self.default_data['object_attributes'] for event, obj in self.gl.handle_webhook('Pipeline Hook', self.default_data): self.assertEqual(event, PipelineActions.UPDATED) self.assertIsInstance(obj[0], GitLabCommit) def test_issue_label(self): obj_attrs = self.default_data['object_attributes'] obj_attrs.update({'action': 'update'}) self.default_data.update({ 'object_attributes': obj_attrs, 'changes': { 'labels': { 'previous': [{'title': 'old'}, {'title': 'old2'}], 'current': [{'title': 'new'}], }, }, }) unlabeled_labels = set() labeled_labels = set() for event, obj in self.gl.handle_webhook('Issue Hook', self.default_data): self.assertIsInstance(obj[0], GitLabIssue) if event == IssueActions.LABELED: labeled_labels.add(obj[1]) elif event == IssueActions.UNLABELED: unlabeled_labels.add(obj[1]) self.assertEqual(unlabeled_labels, {'old', 'old2'}) self.assertEqual(labeled_labels, {'new'}) def test_merge_request_label(self): obj_attrs = self.default_data['object_attributes'] obj_attrs.update({'action': 'update'}) self.default_data.update({ 'object_attributes': obj_attrs, 'changes': { 'labels': { 'previous': [{'title': 'old'}, {'title': 'old2'}], 'current': [{'title': 'new'}], }, }, }) unlabeled_labels = set() labeled_labels = set() for event, obj in self.gl.handle_webhook('Merge Request Hook', self.default_data): self.assertIsInstance(obj[0], GitLabMergeRequest) if event == MergeRequestActions.LABELED: labeled_labels.add(obj[1]) elif event == MergeRequestActions.UNLABELED: unlabeled_labels.add(obj[1]) self.assertEqual(unlabeled_labels, {'old', 'old2'}) self.assertEqual(labeled_labels, {'new'})
def setUp(self): self.gl = GitLab(GitLabOAuthToken(os.environ.get('GITLAB_TEST_TOKEN', '')))