Esempio n. 1
0
    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)))
Esempio n. 2
0
 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'
         }
     }
Esempio n. 3
0
 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})
Esempio n. 4
0
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]
Esempio n. 5
0
    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()
Esempio n. 6
0
    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)
Esempio n. 7
0
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
Esempio n. 8
0
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')
Esempio n. 9
0
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]
Esempio n. 10
0
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)
Esempio n. 11
0
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'})
Esempio n. 12
0
 def setUp(self):
     self.gl = GitLab(GitLabOAuthToken(os.environ.get('GITLAB_TEST_TOKEN', '')))