Пример #1
0
    def commits(self, pid=None, tid=None, cid=None, gid=None,
                start=0, limit=10,
                dfrom=None, dto=None, inc_merge_commit=None,
                inc_repos=None, metadata=None, exc_groups=None,
                inc_groups=None):

        c = Commits(index.Connector())
        projects_index = Projects()
        idents = Contributors()

        query_kwargs = utils.resolv_filters(
            projects_index, idents, pid, tid, cid, gid,
            dfrom, dto, inc_repos, inc_merge_commit,
            metadata, exc_groups, inc_groups)
        query_kwargs.update(
            {'start': start, 'limit': limit})

        resp = c.get_commits(**query_kwargs)

        for cmt in resp[2]:
            # Get extra metadata keys
            extra = set(cmt.keys()) - set(PROPERTIES.keys())
            cmt['metadata'] = list(extra)
            cmt['repos'] = [r for r in cmt['repos']
                            if not r.startswith('meta_ref: ')]
            # Compute link to access commit diff based on the
            # URL template provided in projects.yaml
            cmt['gitwebs'] = [
                projects_index.get_gitweb_link(r) %
                {'sha': cmt['sha']} for r in cmt['repos']]
            cmt['projects'] = utils.get_projects_from_references(
                projects_index, cmt['repos'])
            # Also remove the URI part
            cmt['repos'] = [":".join(p.split(':')[-2:]) for
                            p in cmt['repos']]
            # Request the ident index to fetch author/committer name/email
            for elm in ('author', 'committer'):
                ident = list(idents.get_idents_by_emails(
                    cmt['%s_email' % elm]).values())[0]
                cmt['%s_email' % elm] = ident['default-email']
                if ident['name']:
                    cmt['%s_name' % elm] = ident['name']
            # Convert the TTL to something human readable
            cmt['ttl'] = str((datetime.fromtimestamp(cmt['ttl']) -
                              datetime.fromtimestamp(0)))
            cmt['author_gravatar'] = \
                hashlib.md5(cmt['author_email'].encode(
                    errors='ignore')).hexdigest()
            cmt['committer_gravatar'] = \
                hashlib.md5(cmt['committer_email'].encode(
                    errors='ignore')).hexdigest()
            if len(cmt['commit_msg']) > 80:
                cmt['commit_msg'] = cmt['commit_msg'][0:76] + '...'
            # Add cid and ccid
            cmt['cid'] = utils.encrypt(xorkey, cmt['author_email'])
            cmt['ccid'] = utils.encrypt(xorkey, cmt['committer_email'])
            # Remove email details
            del cmt['author_email']
            del cmt['committer_email']
        return resp
Пример #2
0
    def test_users_crud_admin(self):
        headers = {
            'REMOTE_USER': '******',
            'ADMIN_TOKEN': '12345'}
        # User should not exist
        response = self.app.get(
            '/api/v1/users/admin', headers=headers, status="*")
        self.assertEqual(response.status_int, 404)

        # Push user details
        data = {
            'uid': 'admin',
            'name': 'saboten',
            'default-email': 'saboten@domain1',
            'emails': [
                {'email': 'saboten@domain1',
                 'groups': [
                     {'group': 'ugroup2',
                      'begin-date': '1410456005',
                      'end-date': '1410476005'}
                 ]}
            ]}
        response = self.app.put_json(
            '/api/v1/users/admin', data, headers=headers, status="*")
        self.assertEqual(response.status_int, 201)

        # Get admin user details
        response = self.app.get(
            '/api/v1/users/admin', headers=headers, status="*")
        self.assertEqual(response.status_int, 200)
        rdata = copy.deepcopy(data)
        rdata['cid'] = utils.encrypt(xorkey, 'saboten@domain1')
        self.assertDictEqual(response.json, rdata)

        # Update admin user details
        data['name'] = 'sabosan'
        response = self.app.post_json(
            '/api/v1/users/admin', data, headers=headers, status="*")
        self.assertEqual(response.status_int, 200)

        # Get admin user details
        response = self.app.get(
            '/api/v1/users/admin', headers=headers, status="*")
        self.assertEqual(response.status_int, 200)
        rdata = copy.deepcopy(data)
        rdata['cid'] = utils.encrypt(xorkey, 'saboten@domain1')
        self.assertDictEqual(response.json, rdata)

        # Get admin user details w/o admin_token
        headers = {'REMOTE_USER': '******'}
        response = self.app.get(
            '/api/v1/users/admin', headers=headers, status="*")
        self.assertEqual(response.status_int, 200)
        rdata = copy.deepcopy(data)
        rdata['cid'] = utils.encrypt(xorkey, 'saboten@domain1')
        self.assertDictEqual(response.json, rdata)
Пример #3
0
    def test_users_crud_admin(self):
        headers = {
            'REMOTE_USER': '******',
            'ADMIN_TOKEN': '12345'}
        # User should not exist
        response = self.app.get(
            '/api/v1/users/admin', headers=headers, status="*")
        self.assertEqual(response.status_int, 404)

        # Push user details
        data = {
            'uid': 'admin',
            'name': 'saboten',
            'default-email': 'saboten@domain1',
            'emails': [
                {'email': 'saboten@domain1',
                 'groups': [
                     {'group': 'ugroup2',
                      'begin-date': '1410456005',
                      'end-date': '1410476005'}
                 ]}
            ]}
        response = self.app.put_json(
            '/api/v1/users/admin', data, headers=headers, status="*")
        self.assertEqual(response.status_int, 201)

        # Get admin user details
        response = self.app.get(
            '/api/v1/users/admin', headers=headers, status="*")
        self.assertEqual(response.status_int, 200)
        rdata = copy.deepcopy(data)
        rdata['cid'] = utils.encrypt(xorkey, 'saboten@domain1')
        self.assertDictEqual(response.json, rdata)

        # Update admin user details
        data['name'] = 'sabosan'
        response = self.app.post_json(
            '/api/v1/users/admin', data, headers=headers, status="*")
        self.assertEqual(response.status_int, 200)

        # Get admin user details
        response = self.app.get(
            '/api/v1/users/admin', headers=headers, status="*")
        self.assertEqual(response.status_int, 200)
        rdata = copy.deepcopy(data)
        rdata['cid'] = utils.encrypt(xorkey, 'saboten@domain1')
        self.assertDictEqual(response.json, rdata)

        # Get admin user details w/o admin_token
        headers = {'REMOTE_USER': '******'}
        response = self.app.get(
            '/api/v1/users/admin', headers=headers, status="*")
        self.assertEqual(response.status_int, 200)
        rdata = copy.deepcopy(data)
        rdata['cid'] = utils.encrypt(xorkey, 'saboten@domain1')
        self.assertDictEqual(response.json, rdata)
Пример #4
0
    def top_authors_sanitize(
            self, idents, authors, commits, top,
            resolv_name=True, clean_email=True):
        sanitized = utils.authors_sanitize(idents, authors)
        top_authors_s = []
        for email, v in sanitized.items():
            top_authors_s.append(
                {'cid': utils.encrypt(xorkey, v[2]),
                 'email': email,
                 'gravatar': hashlib.md5(
                     email.encode(errors='ignore')).hexdigest(),
                 'amount': int(v[0]),
                 'name': v[1]})
        top_authors_s_sorted = sorted(top_authors_s,
                                      key=lambda k: k['amount'],
                                      reverse=True)
        if top is None:
            top = 10
        else:
            top = int(top)
        # If top set to a negative value all results will be returned
        if top >= 0:
            top_authors_s_sorted = top_authors_s_sorted[:int(top)]

        if resolv_name:
            self.resolv_name(commits, top_authors_s_sorted)

        return top_authors_s_sorted
Пример #5
0
 def search_authors(self, query=""):
     ret_limit = 100
     c = Commits(index.Connector())
     ret = c.es.search(index=c.index,
                       q=query,
                       df="author_name",
                       size=10000,
                       default_operator="AND",
                       _source_includes=["author_name", "author_email"])
     ret = ret['hits']['hits']
     if not len(ret):
         return {}
     idents = Contributors()
     authors = dict([(d['_source']['author_email'],
                      d['_source']['author_name']) for d in ret])
     result = {}
     _idents = idents.get_idents_by_emails(list(authors.keys())[:ret_limit])
     for iid, ident in _idents.items():
         email = ident['default-email']
         name = ident['name'] or authors[email]
         result[utils.encrypt(xorkey, iid)] = {
             'name': name,
             'gravatar':
             hashlib.md5(email.encode(errors='ignore')).hexdigest()
         }
     result = OrderedDict(
         sorted(list(result.items()), key=lambda t: t[1]['name']))
     return result
Пример #6
0
 def search_authors(self, query=""):
     ret_limit = 100
     c = Commits(index.Connector())
     ret = c.es.search(
         index=c.index, doc_type=c.dbname,
         q=query, df="author_name", size=10000,
         default_operator="AND",
         _source_include=["author_name", "author_email"])
     ret = ret['hits']['hits']
     if not len(ret):
         return {}
     idents = Contributors()
     authors = dict([(d['_source']['author_email'],
                      d['_source']['author_name']) for d in ret])
     result = {}
     _idents = idents.get_idents_by_emails(list(authors.keys())[:ret_limit])
     for iid, ident in _idents.items():
         email = ident['default-email']
         name = ident['name'] or authors[email]
         result[utils.encrypt(xorkey, iid)] = {
             'name': name,
             'gravatar': hashlib.md5(
                 email.encode(errors='ignore')).hexdigest()}
     result = OrderedDict(
         sorted(list(result.items()), key=lambda t: t[1]['name']))
     return result
Пример #7
0
    def top_authors_sanitize(
            self, idents, authors, commits, top,
            resolv_name=True, clean_email=True):
        sanitized = utils.authors_sanitize(idents, authors)
        top_authors_s = []
        for email, v in sanitized.items():
            top_authors_s.append(
                {'cid': utils.encrypt(xorkey, v[2]),
                 'email': email,
                 'gravatar': hashlib.md5(email.encode('utf-8')).hexdigest(),
                 'amount': int(v[0]),
                 'name': v[1]})
        top_authors_s_sorted = sorted(top_authors_s,
                                      key=lambda k: k['amount'],
                                      reverse=True)
        if top is None:
            top = 10
        else:
            top = int(top)
        # If top set to a negative value all results will be returned
        if top >= 0:
            top_authors_s_sorted = top_authors_s_sorted[:int(top)]

        if resolv_name:
            self.resolv_name(commits, top_authors_s_sorted)

        return top_authors_s_sorted
Пример #8
0
    def index(self, prefix=None, nameonly='false', withstats='false'):
        ci = Commits(index.Connector())
        contributors_index = Contributors()
        groups = contributors_index.get_groups()
        if nameonly == 'true':
            ret = dict([(k, None) for k in groups.keys()])
            if prefix:
                ret = dict([(k, None) for k in ret.keys() if
                            k.lower().startswith(prefix)])
            return ret
        ret_groups = {}
        for group, data in groups.items():
            if prefix and not group.lower().startswith(prefix.lower()):
                continue
            rg = {'members': {},
                  'description': data['description'],
                  'domains': data.get('domains', [])}
            emails = data['emails'].keys()
            members = contributors_index.get_idents_by_emails(emails)
            for id, member in members.items():
                member['gravatar'] = hashlib.md5(
                    member['default-email']).hexdigest()
                # TODO(fbo): bounces should be a list of bounce
                # Let's deactivate that for now
                # member['bounces'] = bounces
                del member['emails']
                if not member['name']:
                    # Try to find it among commits
                    suggested = ci.get_commits_author_name_by_emails(
                        [member['default-email']])
                    name = suggested.get(member['default-email'],
                                         'Unknown name')
                    member['name'] = name
                del member['default-email']
                rg['members'][utils.encrypt(xorkey, id)] = member

            if withstats == 'true':
                # TODO(fbo): This endpoint needs to handle some filters like
                # dates bounces to return more accurate stats

                # Fetch the number of projects and repos contributed to
                p_filter = {}
                query_kwargs = {
                    'mails': data['emails'],
                    'merge_commit': False,
                    'repos': p_filter,
                }
                projects = Projects()
                tops_ctl = tops.TopProjectsController()
                top_projects = tops_ctl.gbycommits(
                    ci, projects, query_kwargs, False)
                top_repos = tops_ctl.gbycommits(
                    ci, projects, query_kwargs, True)
                rg['projects_amount'] = len(top_projects)
                rg['repos_amount'] = len(top_repos)

            ret_groups[group] = rg

        return ret_groups
Пример #9
0
 def test_search_authors(self):
     root.search.indexname = 'repoxplorertest'
     response = self.app.get('/api/v1/search/search_authors?query=jean')
     cid = utils.encrypt(xorkey, '*****@*****.**')
     expected = {
         cid: {'name': 'Jean Paul',
               'gravatar': 'c184ebe163aa66b25668757000116849'}}
     self.assertDictEqual(response.json, expected)
Пример #10
0
 def test_search_authors(self):
     root.search.indexname = 'repoxplorertest'
     response = self.app.get('/api/v1/search/search_authors?query=jean')
     cid = utils.encrypt(xorkey, '*****@*****.**')
     expected = {
         cid: {'name': 'Jean Paul',
               'gravatar': 'c184ebe163aa66b25668757000116849'}}
     self.assertDictEqual(response.json, expected)
Пример #11
0
 def get(self, uid):
     self._authorize(uid)
     _users = users.Users(index.Connector(index_suffix='users'))
     u = _users.get(uid)
     if not u:
         abort(404)
     u['cid'] = utils.encrypt(xorkey, u['default-email'])
     return u
Пример #12
0
 def get(self, uid):
     self._authorize(uid)
     _users = users.Users(
         index.Connector(index_suffix='users'))
     u = _users.get(uid)
     if not u:
         abort(404)
     u['cid'] = utils.encrypt(xorkey, u['default-email'])
     return u
Пример #13
0
    def index(self, prefix=None, nameonly='false', withstats='false',
              pid=None, dfrom=None, dto=None, inc_merge_commit=None):
        ci = Commits(index.Connector())
        contributors_index = Contributors()
        groups = contributors_index.get_groups()
        if withstats == 'true':
            projects_index = Projects()
        if nameonly == 'true':
            ret = dict([(k, None) for k in groups.keys()])
            if prefix:
                ret = dict([(k, None) for k in ret.keys() if
                            k.lower().startswith(prefix)])
            return ret
        ret_groups = {}
        for group, data in groups.items():
            if prefix and not group.lower().startswith(prefix.lower()):
                continue
            rg = {'members': {},
                  'description': data.get('description', ''),
                  'domains': data.get('domains', [])}
            emails = list(data['emails'].keys())
            members = contributors_index.get_idents_by_emails(emails)
            for id, member in members.items():
                member['gravatar'] = hashlib.md5(
                    member['default-email'].encode(
                        errors='ignore')).hexdigest()
                # TODO(fbo): bounces should be a list of bounce
                # Let's deactivate that for now
                # member['bounces'] = bounces
                del member['emails']
                if not member['name']:
                    # Try to find it among commits
                    suggested = ci.get_commits_author_name_by_emails(
                        [member['default-email']])
                    name = suggested.get(member['default-email'],
                                         'Unnamed')
                    member['name'] = name
                del member['default-email']
                rg['members'][utils.encrypt(xorkey, id)] = member

            if withstats == 'true':
                # Fetch the number of projects and repos contributed to
                query_kwargs = utils.resolv_filters(
                    projects_index, contributors_index, pid, None, None, group,
                    dfrom, dto, None, inc_merge_commit, None, None, None)

                repos = [r for r in ci.get_repos(**query_kwargs)[1]
                         if not r.startswith('meta_ref: ')]
                projects = utils.get_projects_from_references(
                    projects_index, repos)
                rg['repos_amount'] = len(repos)
                rg['projects_amount'] = len(projects)

            ret_groups[group] = rg

        return ret_groups
Пример #14
0
 def test_get_infos_contributor(self):
     expected = {
         'name': 'Nakata Daisuke',
         'mails_amount': 1,
         'gravatar': '505dcbea438008f24001e2928cdc0678',
     }
     cid = utils.encrypt(xorkey, '*****@*****.**')
     response = self.app.get('/api/v1/infos/contributor', {'cid': cid})
     self.assertEqual(response.status_int, 200)
     self.assertDictEqual(response.json, expected)
Пример #15
0
    def test_get_tops_authors_bycommits(self):
        with patch.object(root.projects.Projects, 'get_projects') as m:
            expected_top1 = {
                'gravatar': 'c184ebe163aa66b25668757000116849',
                'amount': 3,
                'name': 'Jean Paul',
                'cid': utils.encrypt(xorkey, '*****@*****.**'),
            }
            expected_top2 = {
                'gravatar': '505dcbea438008f24001e2928cdc0678',
                'amount': 1,
                'name': 'Nakata Daisuke',
                'cid': utils.encrypt(xorkey, '*****@*****.**'),
            }
            m.return_value = self.projects
            root.tops.indexname = 'repoxplorertest'
            response = self.app.get(
                '/api/v1/tops/authors/bycommits?pid=test&inc_merge_commit=on')
            assert response.status_int == 200
            self.assertDictEqual(response.json[0], expected_top1)
            self.assertDictEqual(response.json[1], expected_top2)
            self.assertEqual(len(response.json), 2)
            # Same request but with a limit set to 1
            response = self.app.get('/api/v1/tops/authors/bycommits?pid=test'
                                    '&inc_merge_commit=on&limit=1')
            assert response.status_int == 200
            self.assertDictEqual(response.json[0], expected_top1)
            self.assertEqual(len(response.json), 1)

            # Validate the CSV endpoint mode
            # First convert all expected dict values to str
            expected_top1 = dict((k, str(v)) for k, v in expected_top1.items())
            expected_top2 = dict((k, str(v)) for k, v in expected_top2.items())
            response = self.app.get(
                '/api/v1/tops/authors/bycommits?'
                'pid=test&inc_merge_commit=on',
                headers={'Accept': 'text/csv'})
            assert response.status_int == 200
            csvret = build_dict_from_csv(response.body)
            self.assertDictEqual(csvret[0], expected_top1)
            self.assertDictEqual(csvret[1], expected_top2)
            self.assertEqual(len(csvret), 2)
Пример #16
0
 def test_get_infos_contributor(self):
     expected = {
         'name': 'Nakata Daisuke',
         'mails_amount': 1,
         'gravatar': '505dcbea438008f24001e2928cdc0678',
     }
     cid = utils.encrypt(xorkey, '*****@*****.**')
     response = self.app.get(
         '/api/v1/infos/contributor', {'cid': cid})
     self.assertEqual(response.status_int, 200)
     self.assertDictEqual(response.json, expected)
Пример #17
0
    def test_get_tops_projects_bylchanged(self):
        cid = utils.encrypt(xorkey, '*****@*****.**')
        response = self.app.get(
            '/api/v1/tops/projects/bylchanged?cid=%s' % cid)
        expected_top1 = {
            'amount': 19,
            'name': 'test'
        }
        assert response.status_int == 200
        self.assertDictEqual(response.json[0], expected_top1)
        self.assertEqual(len(response.json), 1)
        # Ask repo details
        response = self.app.get(
            '/api/v1/tops/projects/bylchanged?cid='
            '%s&inc_repos_detail=true' % cid)
        expected_top1_d = {
            'amount': 19,
            'name': 'monkey:master',
            'projects': ['test']
        }
        assert response.status_int == 200
        self.assertDictEqual(response.json[0], expected_top1_d)
        self.assertEqual(len(response.json), 1)
        # Check the limit attribute
        response = self.app.get(
            '/api/v1/tops/projects/bylchanged?cid=%s&limit=0' % cid)
        assert response.status_int == 200
        self.assertEqual(len(response.json), 0)

        # Validate the CSV endpoint mode
        # First convert all expected dict values to str
        expected_top1 = dict((k, str(v)) for k, v in expected_top1.items())
        for k, v in expected_top1_d.items():
            if isinstance(v, list):
                # A list, that will be semi column separated, can be return
                # when inc_repos_detail is passed to this endpoint
                expected_top1_d[k] = ";".join(v)
            else:
                expected_top1_d[k] = str(v)
        response = self.app.get(
            '/api/v1/tops/projects/bylchanged?'
            'cid=%s' % cid,
            headers={'Accept': 'text/csv'})
        assert response.status_int == 200
        csvret = build_dict_from_csv(response.body)
        self.assertDictEqual(csvret[0], expected_top1)
        response = self.app.get(
            '/api/v1/tops/projects/bylchanged?'
            'cid=%s&inc_repos_detail=true' % cid,
            headers={'Accept': 'text/csv'})
        assert response.status_int == 200
        csvret = build_dict_from_csv(response.body)
        self.assertDictEqual(csvret[0], expected_top1_d)
Пример #18
0
    def test_get_tops_projects_bylchanged(self):
        cid = utils.encrypt(xorkey, '*****@*****.**')
        response = self.app.get(
            '/api/v1/tops/projects/bylchanged?cid=%s' % cid)
        expected_top1 = {
            'amount': 19,
            'name': 'test'
        }
        assert response.status_int == 200
        self.assertDictEqual(response.json[0], expected_top1)
        self.assertEqual(len(response.json), 1)
        # Ask repo details
        response = self.app.get(
            '/api/v1/tops/projects/bylchanged?cid='
            '%s&inc_repos_detail=true' % cid)
        expected_top1_d = {
            'amount': 19,
            'name': 'monkey:master',
            'projects': ['test']
        }
        assert response.status_int == 200
        self.assertDictEqual(response.json[0], expected_top1_d)
        self.assertEqual(len(response.json), 1)
        # Check the limit attribute
        response = self.app.get(
            '/api/v1/tops/projects/bylchanged?cid=%s&limit=0' % cid)
        assert response.status_int == 200
        self.assertEqual(len(response.json), 0)

        # Validate the CSV endpoint mode
        # First convert all expected dict values to str
        expected_top1 = dict((k, str(v)) for k, v in expected_top1.items())
        for k, v in expected_top1_d.items():
            if isinstance(v, list):
                # A list, that will be semi column separated, can be return
                # when inc_repos_detail is passed to this endpoint
                expected_top1_d[k] = ";".join(v)
            else:
                expected_top1_d[k] = str(v)
        response = self.app.get(
            '/api/v1/tops/projects/bylchanged?'
            'cid=%s' % cid,
            headers={'Accept': 'text/csv'})
        assert response.status_int == 200
        csvret = build_dict_from_csv(response.body)
        self.assertDictEqual(csvret[0], expected_top1)
        response = self.app.get(
            '/api/v1/tops/projects/bylchanged?'
            'cid=%s&inc_repos_detail=true' % cid,
            headers={'Accept': 'text/csv'})
        assert response.status_int == 200
        csvret = build_dict_from_csv(response.body)
        self.assertDictEqual(csvret[0], expected_top1_d)
Пример #19
0
    def test_get_tops_authors_bycommits(self):
        expected_top1 = {
            'gravatar': 'c184ebe163aa66b25668757000116849',
            'amount': 3,
            'name': 'Jean Paul',
            'cid': utils.encrypt(xorkey, '*****@*****.**'),
        }
        expected_top2 = {
            'gravatar': '505dcbea438008f24001e2928cdc0678',
            'amount': 1,
            'name': 'Nakata Daisuke',
            'cid': utils.encrypt(xorkey, '*****@*****.**'),
        }
        response = self.app.get(
            '/api/v1/tops/authors/bycommits?pid=test&inc_merge_commit=on')
        assert response.status_int == 200
        self.assertDictEqual(response.json[0], expected_top1)
        self.assertDictEqual(response.json[1], expected_top2)
        self.assertEqual(len(response.json), 2)
        # Same request but with a limit set to 1
        response = self.app.get(
            '/api/v1/tops/authors/bycommits?pid=test'
            '&inc_merge_commit=on&limit=1')
        assert response.status_int == 200
        self.assertDictEqual(response.json[0], expected_top1)
        self.assertEqual(len(response.json), 1)

        # Validate the CSV endpoint mode
        # First convert all expected dict values to str
        expected_top1 = dict((k, str(v)) for k, v in expected_top1.items())
        expected_top2 = dict((k, str(v)) for k, v in expected_top2.items())
        response = self.app.get(
            '/api/v1/tops/authors/bycommits?'
            'pid=test&inc_merge_commit=on',
            headers={'Accept': 'text/csv'})
        assert response.status_int == 200
        csvret = build_dict_from_csv(response.body)
        self.assertDictEqual(csvret[0], expected_top1)
        self.assertDictEqual(csvret[1], expected_top2)
        self.assertEqual(len(csvret), 2)
Пример #20
0
    def test_get_tops_authors_bylchanged(self):
        expected_top1 = {
            'amount': 19,
            'gravatar': 'c184ebe163aa66b25668757000116849',
            'cid': utils.encrypt(xorkey, '*****@*****.**'),
            'name': 'Jean Paul'
        }
        expected_top2 = {
            'amount': 10,
            'gravatar': '505dcbea438008f24001e2928cdc0678',
            'cid': utils.encrypt(xorkey, '*****@*****.**'),
            'name': 'Nakata Daisuke'
        }
        response = self.app.get('/api/v1/tops/authors/bylchanged?pid=test')
        assert response.status_int == 200
        self.assertDictEqual(response.json[0], expected_top1)
        self.assertDictEqual(response.json[1], expected_top2)
        self.assertEqual(len(response.json), 2)
        # Same request but with a limit set to 1
        response = self.app.get(
            '/api/v1/tops/authors/bylchanged?pid=test&limit=1')
        assert response.status_int == 200
        self.assertDictEqual(response.json[0], expected_top1)
        self.assertEqual(len(response.json), 1)

        # Validate the CSV endpoint mode
        # First convert all expected dict values to str
        expected_top1 = dict((k, str(v)) for k, v in expected_top1.items())
        expected_top2 = dict((k, str(v)) for k, v in expected_top2.items())
        response = self.app.get(
            '/api/v1/tops/authors/bylchanged?pid=test',
            headers={'Accept': 'text/csv'})
        assert response.status_int == 200
        csvret = build_dict_from_csv(response.body)
        self.assertDictEqual(csvret[0], expected_top1)
        self.assertDictEqual(csvret[1], expected_top2)
        self.assertEqual(len(csvret), 2)
Пример #21
0
 def test_get_tops_authors_diff(self):
     # with patch.object(root.projects.Projects, 'get_projects') as m:
     expected_diff = {
         'gravatar': '505dcbea438008f24001e2928cdc0678',
         'amount': 1,
         'name': 'Nakata Daisuke',
         'cid': utils.encrypt(xorkey, '*****@*****.**'),
     }
     response = self.app.get(
         '/api/v1/tops/authors/diff?pid=test&dfromref=2014-01-01'
         '&dtoref=2014-09-03&dfrom=2014-09-04&dto=2017-01-01'
         '&inc_merge_commit=on&limit=1')
     assert response.status_int == 200
     self.assertDictEqual(response.json[0], expected_diff)
     self.assertEqual(len(response.json), 1)
Пример #22
0
 def test_get_tops_authors_diff(self):
     # with patch.object(root.projects.Projects, 'get_projects') as m:
     expected_diff = {
         'gravatar': '505dcbea438008f24001e2928cdc0678',
         'amount': 1,
         'name': 'Nakata Daisuke',
         'cid': utils.encrypt(xorkey, '*****@*****.**'),
     }
     response = self.app.get(
         '/api/v1/tops/authors/diff?pid=test&dfromref=2014-01-01'
         '&dtoref=2014-09-03&dfrom=2014-09-04&dto=2017-01-01'
         '&inc_merge_commit=on&limit=1')
     assert response.status_int == 200
     self.assertDictEqual(response.json[0], expected_diff)
     self.assertEqual(len(response.json), 1)
Пример #23
0
 def test_get_infos_contributor(self):
     expected = {
         'repos_amount': 1,
         'name': 'Nakata Daisuke',
         'mails_amount': 1,
         'gravatar': '505dcbea438008f24001e2928cdc0678',
         'projects_amount': 1
     }
     cid = utils.encrypt(xorkey, '*****@*****.**')
     with patch.object(root.projects.Projects, 'get_projects') as m:
         root.infos.indexname = 'repoxplorertest'
         m.return_value = self.projects
         response = self.app.get('/api/v1/infos/contributor?cid=%s' % cid)
         self.assertEqual(response.status_int, 200)
         self.assertDictEqual(response.json, expected)
Пример #24
0
    def test_get_infos(self):
        expected = {
            'first': 1393860653,
            'last': 1410456005,
            'commits_amount': 3,
            'authors_amount': 2,
            'line_modifieds_amount': 29,
            'duration': 16595352,
            'ttl_average': 0,
            'projects_amount': 1,
            'repos_amount': 1,
        }
        response = self.app.get('/api/v1/infos/infos?pid=test')
        self.assertEqual(response.status_int, 200)
        self.assertDictEqual(response.json, expected)

        # Check endpoint CSV mode
        response = self.app.get('/api/v1/infos/infos?pid=test',
                                headers={'Accept': 'text/csv'})
        self.assertEqual(response.status_int, 200)
        csvret = build_dict_from_csv(response.body)
        # Convert all dict values to str
        expected = dict((k, str(v)) for k, v in expected.items())
        self.assertDictEqual(csvret[0], expected)
        self.assertEqual(len(csvret), 1)

        # Make an attempt by setting meta ref to True
        new_projects_file = """
        project-templates:
          default:
            uri: https://github.com/nakata/%(name)s.git
            branches:
            - master

        projects:
          test:
            meta-ref: true
            repos:
              monkey:
                template: default
        """
        self.db = set_projects_definition(self.conp, new_projects_file)

        expected = {
            'first': 1393860653,
            'last': 1410456005,
            'commits_amount': 2,
            'authors_amount': 2,
            'line_modifieds_amount': 18,
            'duration': 16595352,
            'ttl_average': 0,
            'projects_amount': 1,
            'repos_amount': 1,
        }
        response = self.app.get('/api/v1/infos/infos?pid=test')
        self.assertEqual(response.status_int, 200)
        self.assertDictEqual(response.json, expected)

        # Test with a cid
        expected = {
            'projects_amount': 1,
            'first': 1410456005,
            'line_modifieds_amount': 10,
            'duration': 0,
            'commits_amount': 1,
            'ttl_average': 0,
            'last': 1410456005,
            'authors_amount': 1,
            'repos_amount': 1
        }
        cid = utils.encrypt(xorkey, '*****@*****.**')
        response = self.app.get('/api/v1/infos/infos', {'cid': cid})
        self.assertEqual(response.status_int, 200)
        self.assertDictEqual(response.json, expected)
Пример #25
0
    def test_users_crud_user(self):
        # First set a user as admin
        data = {
            'uid':
            'saboten',
            'name':
            'Cactus Saboten',
            'default-email':
            'saboten@domain1',
            'emails': [{
                'email':
                'saboten@domain1',
                'groups': [{
                    'group': 'ugroup2',
                    'begin-date': '1410456005',
                    'end-date': '1410476005'
                }]
            }]
        }

        headers = {'REMOTE_USER': '******', 'ADMIN_TOKEN': '12345'}
        self.app.put_json('/api/v1/users/saboten',
                          data,
                          headers=headers,
                          status="*")

        # Change user
        headers = {'REMOTE_USER': '******'}

        response = self.app.get('/api/v1/users/saboten',
                                headers=headers,
                                status="*")
        self.assertEqual(response.status_int, 200)
        rdata = copy.deepcopy(data)
        rdata['cid'] = utils.encrypt(xorkey, 'saboten@domain1')
        self.assertDictEqual(response.json, rdata)

        # User is not authorized to change protected fields
        ndata = copy.deepcopy(data)
        ndata['default-email'] = 'saboten@domain2'
        response = self.app.post_json('/api/v1/users/saboten',
                                      ndata,
                                      headers=headers,
                                      status="*")
        self.assertEqual(response.status_int, 403)

        # User is not authorized to change protected fields
        ndata = copy.deepcopy(data)
        ndata['emails'].append({'emails': '*****@*****.**'})
        response = self.app.post_json('/api/v1/users/saboten',
                                      ndata,
                                      headers=headers,
                                      status="*")
        self.assertEqual(response.status_int, 400)

        # Authorized to change its full name
        data['name'] = 'John Doe'
        response = self.app.post_json('/api/v1/users/saboten',
                                      data,
                                      headers=headers,
                                      status="*")
        self.assertEqual(response.status_int, 200)

        # Not authorized to change its full name if > 100 chars
        ndata = copy.deepcopy(data)
        ndata['name'] = 'a' * 101
        response = self.app.post_json('/api/v1/users/saboten',
                                      ndata,
                                      headers=headers,
                                      status="*")
        self.assertEqual(response.status_int, 400)

        # Authorized to change its emails memberships
        email = [e for e in data['emails']
                 if e['email'] == 'saboten@domain1'][0]
        email['groups'][0]['group'] = 'ugroup3'
        response = self.app.post_json('/api/v1/users/saboten',
                                      data,
                                      headers=headers,
                                      status="*")
        self.assertEqual(response.status_int, 200)

        # Change user
        headers = {'REMOTE_USER': '******'}

        # Another user not authorized to get
        response = self.app.get('/api/v1/users/saboten',
                                headers=headers,
                                status="*")
        self.assertEqual(response.status_int, 401)

        # Another user not authorized to change
        data['name'] = 'John Doe'
        response = self.app.post_json('/api/v1/users/saboten',
                                      data,
                                      headers=headers,
                                      status="*")
        self.assertEqual(response.status_int, 401)

        # Another user not authorized to delete
        response = self.app.delete('/api/v1/users/saboten',
                                   headers=headers,
                                   status="*")
        self.assertEqual(response.status_int, 401)

        # Change user
        headers = {'REMOTE_USER': '******'}

        # User authorized to delete itself
        response = self.app.delete('/api/v1/users/saboten',
                                   headers=headers,
                                   status="*")
        self.assertEqual(response.status_int, 200)
Пример #26
0
    def index(self,
              prefix=None,
              nameonly='false',
              withstats='false',
              pid=None,
              dfrom=None,
              dto=None,
              inc_merge_commit=None):
        ci = Commits(index.Connector())
        contributors_index = Contributors()
        groups = contributors_index.get_groups()
        if withstats == 'true':
            projects_index = Projects()
        if nameonly == 'true':
            ret = dict([(k, None) for k in groups.keys()])
            if prefix:
                ret = dict([(k, None) for k in ret.keys()
                            if k.lower().startswith(prefix)])
            return ret
        ret_groups = {}
        for group, data in groups.items():
            if prefix and not group.lower().startswith(prefix.lower()):
                continue
            rg = {
                'members': {},
                'description': data.get('description', ''),
                'domains': data.get('domains', [])
            }
            emails = list(data['emails'].keys())
            members = contributors_index.get_idents_by_emails(emails)
            for id, member in members.items():
                member['gravatar'] = hashlib.md5(
                    member['default-email'].encode(
                        errors='ignore')).hexdigest()
                # TODO(fbo): bounces should be a list of bounce
                # Let's deactivate that for now
                # member['bounces'] = bounces
                del member['emails']
                if not member['name']:
                    # Try to find it among commits
                    suggested = ci.get_commits_author_name_by_emails(
                        [member['default-email']])
                    name = suggested.get(member['default-email'], 'Unnamed')
                    member['name'] = name
                del member['default-email']
                rg['members'][utils.encrypt(xorkey, id)] = member

            if withstats == 'true':
                # Fetch the number of projects and repos contributed to
                query_kwargs = utils.resolv_filters(
                    projects_index, contributors_index, pid, None, None, group,
                    dfrom, dto, None, inc_merge_commit, None, None, None)

                repos = [
                    r for r in ci.get_repos(**query_kwargs)[1]
                    if not r.startswith('meta_ref: ')
                ]
                projects = utils.get_projects_from_references(
                    projects_index, repos)
                rg['repos_amount'] = len(repos)
                rg['projects_amount'] = len(projects)

            ret_groups[group] = rg

        return ret_groups
Пример #27
0
    def test_users_crud_user(self):
        # First set a user as admin
        data = {
            'uid': 'saboten',
            'name': 'Cactus Saboten',
            'default-email': 'saboten@domain1',
            'emails': [
                {'email': 'saboten@domain1',
                 'groups': [
                    {'group': 'ugroup2',
                     'begin-date': '1410456005',
                     'end-date': '1410476005'}
                     ]
                 }
            ]
        }

        headers = {
            'REMOTE_USER': '******',
            'ADMIN_TOKEN': '12345'}
        self.app.put_json(
            '/api/v1/users/saboten', data, headers=headers, status="*")

        # Change user
        headers = {'REMOTE_USER': '******'}

        response = self.app.get(
            '/api/v1/users/saboten', headers=headers, status="*")
        self.assertEqual(response.status_int, 200)
        rdata = copy.deepcopy(data)
        rdata['cid'] = utils.encrypt(xorkey, 'saboten@domain1')
        self.assertDictEqual(response.json, rdata)

        # User is not authorized to change protected fields
        ndata = copy.deepcopy(data)
        ndata['default-email'] = 'saboten@domain2'
        response = self.app.post_json(
            '/api/v1/users/saboten', ndata, headers=headers, status="*")
        self.assertEqual(response.status_int, 403)

        # User is not authorized to change protected fields
        ndata = copy.deepcopy(data)
        ndata['emails'].append({'emails': '*****@*****.**'})
        response = self.app.post_json(
            '/api/v1/users/saboten', ndata, headers=headers, status="*")
        self.assertEqual(response.status_int, 400)

        # Authorized to change its full name
        data['name'] = 'John Doe'
        response = self.app.post_json(
            '/api/v1/users/saboten', data, headers=headers, status="*")
        self.assertEqual(response.status_int, 200)

        # Not authorized to change its full name if > 100 chars
        ndata = copy.deepcopy(data)
        ndata['name'] = 'a'*101
        response = self.app.post_json(
            '/api/v1/users/saboten', ndata, headers=headers, status="*")
        self.assertEqual(response.status_int, 400)

        # Authorized to change its emails memberships
        email = [e for e in data['emails'] if
                 e['email'] == 'saboten@domain1'][0]
        email['groups'][0]['group'] = 'ugroup3'
        response = self.app.post_json(
            '/api/v1/users/saboten', data, headers=headers, status="*")
        self.assertEqual(response.status_int, 200)

        # Change user
        headers = {'REMOTE_USER': '******'}

        # Another user not authorized to get
        response = self.app.get(
            '/api/v1/users/saboten', headers=headers, status="*")
        self.assertEqual(response.status_int, 401)

        # Another user not authorized to change
        data['name'] = 'John Doe'
        response = self.app.post_json(
            '/api/v1/users/saboten', data, headers=headers, status="*")
        self.assertEqual(response.status_int, 401)

        # Another user not authorized to delete
        response = self.app.delete(
            '/api/v1/users/saboten', headers=headers, status="*")
        self.assertEqual(response.status_int, 401)

        # Change user
        headers = {'REMOTE_USER': '******'}

        # User authorized to delete itself
        response = self.app.delete(
            '/api/v1/users/saboten', headers=headers, status="*")
        self.assertEqual(response.status_int, 200)
Пример #28
0
    def test_get_infos(self):
        expected = {
            'first': 1393860653,
            'last': 1410456005,
            'commits_amount': 3,
            'authors_amount': 2,
            'line_modifieds_amount': 29,
            'duration': 16595352,
            'ttl_average': 0,
            'projects_amount': 1,
            'repos_amount': 1,
        }
        response = self.app.get('/api/v1/infos/infos?pid=test')
        self.assertEqual(response.status_int, 200)
        self.assertDictEqual(response.json, expected)

        # Check endpoint CSV mode
        response = self.app.get(
            '/api/v1/infos/infos?pid=test',
            headers={'Accept': 'text/csv'})
        self.assertEqual(response.status_int, 200)
        csvret = build_dict_from_csv(response.body)
        # Convert all dict values to str
        expected = dict((k, str(v)) for k, v in expected.items())
        self.assertDictEqual(csvret[0], expected)
        self.assertEqual(len(csvret), 1)

        # Make an attempt by setting meta ref to True
        new_projects_file = """
        project-templates:
          default:
            uri: https://github.com/nakata/%(name)s.git
            branches:
            - master

        projects:
          test:
            meta-ref: true
            repos:
              monkey:
                template: default
        """
        self.db = set_projects_definition(self.conp, new_projects_file)

        expected = {
            'first': 1393860653,
            'last': 1410456005,
            'commits_amount': 2,
            'authors_amount': 2,
            'line_modifieds_amount': 18,
            'duration': 16595352,
            'ttl_average': 0,
            'projects_amount': 1,
            'repos_amount': 1,
        }
        response = self.app.get('/api/v1/infos/infos?pid=test')
        self.assertEqual(response.status_int, 200)
        self.assertDictEqual(response.json, expected)

        # Test with a cid
        expected = {
            'projects_amount': 1,
            'first': 1410456005,
            'line_modifieds_amount': 10,
            'duration': 0,
            'commits_amount': 1,
            'ttl_average': 0,
            'last': 1410456005,
            'authors_amount': 1,
            'repos_amount': 1
        }
        cid = utils.encrypt(xorkey, '*****@*****.**')
        response = self.app.get('/api/v1/infos/infos', {'cid': cid})
        self.assertEqual(response.status_int, 200)
        self.assertDictEqual(response.json, expected)