diff --git a/pagure/api/group.py b/pagure/api/group.py index ea718a7..58edcf9 100644 --- a/pagure/api/group.py +++ b/pagure/api/group.py @@ -101,6 +101,32 @@ def api_view_group(group): GET /api/0/group/some_group_name + + :: + + GET /api/0/group/some_group_name?projects=1&acl=commit + + Input + ^^^^^ + + +------------------+---------+--------------+-----------------------------+ + | Key | Type | Optionality | Description | + +==================+=========+==============+=============================+ + | ``group name`` | str | Mandatory | The name of the group to | + | | | | retrieve information about. | + +------------------+---------+--------------+-----------------------------+ + | ``projects`` | bool | Optional | Specifies whether to include| + | | | | projects in the data | + | | | | returned. | + +------------------+---------+--------------+-----------------------------+ + | ``acl`` | str | Optional | Filter the project returned | + | | | | (if any) to those where the | + | | | | has the specified ACL level.| + | | | | Can be any of: ``admin``, | + | | | | ``commit`` or ``ticket``. | + +------------------+---------+--------------+-----------------------------+ + + Sample response ^^^^^^^^^^^^^^^ @@ -125,12 +151,58 @@ def api_view_group(group): ], "name": "some_group_name" } + + :: + + { + "creator": { + "default_email": "user1@example.com", + "emails": [ + "user1@example.com" + ], + "fullname": "User1", + "name": "user1" + }, + "date_created": "1492011511", + "description": "Some Group", + "display_name": "Some Group", + "group_type": "user", + "members": [ + "user1", + "user2" + ], + "name": "some_group_name", + "projects": [], + } + + """ # noqa + projects = flask.request.values.get( + 'projects', '').strip().lower() in ['1', 'true'] + acl = flask.request.values.get('acl', '').strip().lower() or None + if acl == 'ticket': + acl = ['admin', 'commit', 'ticket'] + elif acl == 'commit': + acl = ['commit', 'admin'] + elif acl: + acl = [acl] + group = pagure.lib.search_groups(SESSION, group_name=group) if not group: raise pagure.exceptions.APIError(404, error_code=APIERROR.ENOGROUP) - jsonout = flask.jsonify(group.to_json( - public=(not pagure.api_authenticated()))) + output = group.to_json(public=(not pagure.api_authenticated())) + if projects and not acl: + output['projects'] = [ + project.to_json(public=True) + for project in group.projects + ] + elif projects and acl: + output['projects'] = [ + pg.project.to_json(public=True) + for pg in group.projects_groups + if pg.access in acl + ] + jsonout = flask.jsonify(output) jsonout.status_code = 200 return jsonout diff --git a/tests/test_pagure_flask_api_group.py b/tests/test_pagure_flask_api_group.py index 3e267fa..1c6eef8 100644 --- a/tests/test_pagure_flask_api_group.py +++ b/tests/test_pagure_flask_api_group.py @@ -25,6 +25,8 @@ import tests class PagureFlaskApiGroupTests(tests.SimplePagureTest): """ Tests for the flask API of pagure for issue """ + maxDiff = None + def setUp(self): """ Set up the environnment, ran before every tests. """ super(PagureFlaskApiGroupTests, self).setUp() @@ -50,6 +52,17 @@ class PagureFlaskApiGroupTests(tests.SimplePagureTest): ) self.session.commit() + tests.create_projects(self.session) + + project = pagure.lib._get_project(self.session, 'test2') + msg = pagure.lib.add_group_to_project( + session=self.session, + project=project, + new_group='some_group', + user='pingou', + ) + self.session.commit() + self.assertEqual(msg, 'Group added') def test_api_groups(self): """ Test the api_groups function. """ @@ -113,21 +126,21 @@ class PagureFlaskApiGroupTests(tests.SimplePagureTest): self.assertEqual( data, { - "groups": [ - { - "description": None, - "name": "some_group" - }, - { - "description": None, - "name": "group1" - }, - { - "description": None, - "name": "rel-eng" - } - ], - "total_groups": 3 + "groups": [ + { + "description": None, + "name": "some_group" + }, + { + "description": None, + "name": "group1" + }, + { + "description": None, + "name": "rel-eng" + } + ], + "total_groups": 3 } ) @@ -136,8 +149,8 @@ class PagureFlaskApiGroupTests(tests.SimplePagureTest): Test the api_view_group method of the flask api with an authenticated user. The tested group has one member. """ - tests.create_projects(self.session) tests.create_tokens(self.session) + headers = {'Authorization': 'token aaabbbcccddd'} output = self.app.get('/api/0/group/some_group', headers=headers) self.assertEqual(output.status_code, 200) @@ -201,9 +214,10 @@ class PagureFlaskApiGroupTests(tests.SimplePagureTest): group = pagure.lib.search_groups(self.session, group_name='some_group') result = pagure.lib.add_user_to_group( self.session, user.username, group, user.username, True) + self.assertEqual( + result, 'User `mprahl` added to the group `some_group`.') self.session.commit() - tests.create_projects(self.session) tests.create_tokens(self.session) headers = {'Authorization': 'token aaabbbcccddd'} @@ -229,8 +243,6 @@ class PagureFlaskApiGroupTests(tests.SimplePagureTest): self.maxDiff = None data = json.loads(output.data) data['date_created'] = '1492020239' - from pprint import pprint - pprint(data) self.assertDictEqual(data, exp) def test_api_view_group_no_group_error(self): @@ -244,5 +256,387 @@ class PagureFlaskApiGroupTests(tests.SimplePagureTest): self.assertEqual(data['error'], 'Group not found') self.assertEqual(data['error_code'], 'ENOGROUP') + def test_api_view_group_w_projects_and_acl(self): + """ + Test the api_view_group method with project info and restricted + to the admin ACL + """ + tests.create_tokens(self.session) + + headers = {'Authorization': 'token aaabbbcccddd'} + output = self.app.get( + '/api/0/group/some_group?projects=1', headers=headers) + self.assertEqual(output.status_code, 200) + exp = { + "display_name": "Some Group", + "description": None, + "creator": { + "fullname": "PY C", + "default_email": "bar@pingou.com", + "emails": [ + "bar@pingou.com", + "foo@pingou.com" + ], + "name": "pingou" + }, + "members": ["pingou"], + "date_created": "1492020239", + "group_type": "user", + "name": "some_group", + "projects": [ + { + "access_groups": { + "admin": [ + "some_group" + ], + "commit": [], + "ticket": [] + }, + "access_users": { + "admin": [], + "commit": [], + "owner": [ + "pingou" + ], + "ticket": [] + }, + "close_status": [ + "Invalid", + "Insufficient data", + "Fixed", + "Duplicate" + ], + "custom_keys": [], + "date_created": "1492020239", + "date_modified": "1492020239", + "description": "test project #2", + "fullname": "test2", + "id": 2, + "milestones": {}, + "name": "test2", + "namespace": None, + "parent": None, + "priorities": {}, + "settings": { + "Enforce_signed-off_commits_in_pull-request": False, + "Minimum_score_to_merge_pull-request": -1, + "Only_assignee_can_merge_pull-request": False, + "Web-hooks": None, + "always_merge": False, + "fedmsg_notifications": True, + "issue_tracker": True, + "issues_default_to_private": False, + "project_documentation": False, + "pull_request_access_only": False, + "pull_requests": True + }, + "tags": [], + "url_path": "test2", + "user": { + "fullname": "PY C", + "name": "pingou" + } + } + ] + } + data = json.loads(output.data) + data['date_created'] = '1492020239' + projects = [] + for p in data['projects']: + p['date_created'] = '1492020239' + p['date_modified'] = '1492020239' + projects.append(p) + data['projects'] = projects + self.assertDictEqual(data, exp) + + output2 = self.app.get( + '/api/0/group/some_group?projects=1&acl=admin', headers=headers) + self.assertEqual(output.data.split('\n'), output2.data.split('\n')) + + def test_api_view_group_w_projects_and_acl_commit(self): + """ + Test the api_view_group method with project info and restricted + to the commit ACL + """ + + output = self.app.get( + '/api/0/group/some_group?projects=1&acl=commit') + self.assertEqual(output.status_code, 200) + exp = { + "display_name": "Some Group", + "description": None, + "creator": { + "fullname": "PY C", + "name": "pingou" + }, + "members": ["pingou"], + "date_created": "1492020239", + "group_type": "user", + "name": "some_group", + "projects": [ + { + "access_groups": { + "admin": [ + "some_group" + ], + "commit": [], + "ticket": [] + }, + "access_users": { + "admin": [], + "commit": [], + "owner": [ + "pingou" + ], + "ticket": [] + }, + "close_status": [ + "Invalid", + "Insufficient data", + "Fixed", + "Duplicate" + ], + "custom_keys": [], + "date_created": "1492020239", + "date_modified": "1492020239", + "description": "test project #2", + "fullname": "test2", + "id": 2, + "milestones": {}, + "name": "test2", + "namespace": None, + "parent": None, + "priorities": {}, + "settings": { + "Enforce_signed-off_commits_in_pull-request": False, + "Minimum_score_to_merge_pull-request": -1, + "Only_assignee_can_merge_pull-request": False, + "Web-hooks": None, + "always_merge": False, + "fedmsg_notifications": True, + "issue_tracker": True, + "issues_default_to_private": False, + "project_documentation": False, + "pull_request_access_only": False, + "pull_requests": True + }, + "tags": [], + "url_path": "test2", + "user": { + "fullname": "PY C", + "name": "pingou" + } + } + ] + } + data = json.loads(output.data) + data['date_created'] = '1492020239' + projects = [] + for p in data['projects']: + p['date_created'] = '1492020239' + p['date_modified'] = '1492020239' + projects.append(p) + data['projects'] = projects + self.assertDictEqual(data, exp) + + def test_api_view_group_w_projects_and_acl_ticket(self): + """ + Test the api_view_group method with project info and restricted + to the ticket ACL + """ + + output = self.app.get( + '/api/0/group/some_group?projects=1&acl=ticket') + self.assertEqual(output.status_code, 200) + exp = { + "display_name": "Some Group", + "description": None, + "creator": { + "fullname": "PY C", + "name": "pingou" + }, + "members": ["pingou"], + "date_created": "1492020239", + "group_type": "user", + "name": "some_group", + "projects": [ + { + "access_groups": { + "admin": [ + "some_group" + ], + "commit": [], + "ticket": [] + }, + "access_users": { + "admin": [], + "commit": [], + "owner": [ + "pingou" + ], + "ticket": [] + }, + "close_status": [ + "Invalid", + "Insufficient data", + "Fixed", + "Duplicate" + ], + "custom_keys": [], + "date_created": "1492020239", + "date_modified": "1492020239", + "description": "test project #2", + "fullname": "test2", + "id": 2, + "milestones": {}, + "name": "test2", + "namespace": None, + "parent": None, + "priorities": {}, + "settings": { + "Enforce_signed-off_commits_in_pull-request": False, + "Minimum_score_to_merge_pull-request": -1, + "Only_assignee_can_merge_pull-request": False, + "Web-hooks": None, + "always_merge": False, + "fedmsg_notifications": True, + "issue_tracker": True, + "issues_default_to_private": False, + "project_documentation": False, + "pull_request_access_only": False, + "pull_requests": True + }, + "tags": [], + "url_path": "test2", + "user": { + "fullname": "PY C", + "name": "pingou" + } + } + ] + } + data = json.loads(output.data) + data['date_created'] = '1492020239' + projects = [] + for p in data['projects']: + p['date_created'] = '1492020239' + p['date_modified'] = '1492020239' + projects.append(p) + data['projects'] = projects + self.assertDictEqual(data, exp) + + def test_api_view_group_w_projects_and_acl_admin_no_project(self): + """ + Test the api_view_group method with project info and restricted + to the admin ACL + """ + + # Make the group having only commit access + project = pagure.lib._get_project(self.session, 'test2') + msg = pagure.lib.add_group_to_project( + session=self.session, + project=project, + new_group='some_group', + user='pingou', + access='commit', + ) + self.session.commit() + self.assertEqual(msg, 'Group access updated') + + output = self.app.get( + '/api/0/group/some_group?projects=1&acl=admin') + self.assertEqual(output.status_code, 200) + exp = { + "display_name": "Some Group", + "description": None, + "creator": { + "fullname": "PY C", + "name": "pingou" + }, + "members": ["pingou"], + "date_created": "1492020239", + "group_type": "user", + "name": "some_group", + "projects": [] + } + data = json.loads(output.data) + data['date_created'] = '1492020239' + self.assertDictEqual(data, exp) + + def test_api_view_group_w_projects_and_acl_commit_no_project(self): + """ + Test the api_view_group method with project info and restricted + to the commit ACL + """ + + # Make the group having only ticket access + project = pagure.lib._get_project(self.session, 'test2') + msg = pagure.lib.add_group_to_project( + session=self.session, + project=project, + new_group='some_group', + user='pingou', + access='ticket', + ) + self.session.commit() + self.assertEqual(msg, 'Group access updated') + + output = self.app.get( + '/api/0/group/some_group?projects=1&acl=commit') + self.assertEqual(output.status_code, 200) + exp = { + "display_name": "Some Group", + "description": None, + "creator": { + "fullname": "PY C", + "name": "pingou" + }, + "members": ["pingou"], + "date_created": "1492020239", + "group_type": "user", + "name": "some_group", + "projects": [] + } + data = json.loads(output.data) + data['date_created'] = '1492020239' + self.assertDictEqual(data, exp) + + def test_api_view_group_w_projects_and_acl_ticket_no_project(self): + """ + Test the api_view_group method with project info and restricted + to the ticket ACL + """ + + # Create a group not linked to any project + item = pagure.lib.model.PagureGroup( + group_name='rel-eng', + group_type='user', + display_name='Release engineering group', + user_id=1, # pingou + ) + self.session.add(item) + self.session.commit() + + output = self.app.get( + '/api/0/group/rel-eng?projects=1&acl=ticket') + self.assertEqual(output.status_code, 200) + exp = { + "display_name": "Release engineering group", + "description": None, + "creator": { + "fullname": "PY C", + "name": "pingou" + }, + "members": [], + "date_created": "1492020239", + "group_type": "user", + "name": "rel-eng", + "projects": [] + } + data = json.loads(output.data) + data['date_created'] = '1492020239' + self.assertDictEqual(data, exp) + + if __name__ == "__main__": unittest.main(verbosity=2)