diff --git a/pagure/api/__init__.py b/pagure/api/__init__.py index 2453d97..7705d52 100644 --- a/pagure/api/__init__.py +++ b/pagure/api/__init__.py @@ -525,6 +525,7 @@ def api(): api_update_project_watchers_doc = load_doc( project.api_update_project_watchers ) + api_get_project_options_doc = load_doc(project.api_get_project_options) issues = [] if pagure_config.get("ENABLE_TICKETS", True): @@ -609,6 +610,7 @@ def api(): api_commit_flags_doc, api_commit_add_flag_doc, api_update_project_watchers_doc, + api_get_project_options_doc, ], issues=issues, requests=[ diff --git a/pagure/api/project.py b/pagure/api/project.py index 1a8de5d..9ea05af 100644 --- a/pagure/api/project.py +++ b/pagure/api/project.py @@ -1898,3 +1898,66 @@ def api_modify_acls(repo, namespace=None, username=None): jsonout = flask.jsonify(output) return jsonout + + +@API.route("//options", methods=["GET"]) +@API.route("///options", methods=["GET"]) +@API.route("/fork///options", methods=["GET"]) +@API.route("/fork////options", methods=["GET"]) +@api_login_required(acls=["modify_project"]) +@api_method +def api_get_project_options(repo, username=None, namespace=None): + """ + Get project options + ---------------------- + Allow project admins to retrieve the current options of a project. + + :: + + GET /api/0//options + GET /api/0///options + + :: + + GET /api/0/fork///options + GET /api/0/fork////options + + Sample response + ^^^^^^^^^^^^^^^ + + :: + + { + "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": null, + "always_merge": false, + "disable_non_fast-forward_merges": false, + "fedmsg_notifications": true, + "issue_tracker": true, + "issue_tracker_read_only": false, + "issues_default_to_private": false, + "notify_on_commit_flag": false, + "notify_on_pull-request_flag": false, + "open_metadata_access_to_all": false, + "project_documentation": false, + "pull_request_access_only": false, + "pull_requests": true, + "stomp_notifications": true + }, + "status": "ok" + } + + """ + project = get_authorized_api_project( + flask.g.session, repo, namespace=namespace + ) + if not project: + raise pagure.exceptions.APIError(404, error_code=APIERROR.ENOPROJECT) + + if flask.g.token.project and project != flask.g.token.project: + raise pagure.exceptions.APIError(401, error_code=APIERROR.EINVALIDTOK) + + return flask.jsonify({"settings": project.settings, "status": "ok"}) diff --git a/tests/test_pagure_flask_api_project.py b/tests/test_pagure_flask_api_project.py index 16b5862..ecf758a 100644 --- a/tests/test_pagure_flask_api_project.py +++ b/tests/test_pagure_flask_api_project.py @@ -3789,5 +3789,88 @@ class PagureFlaskApiProjectModifyAclTests(tests.Modeltests): {u'admin': [], u'commit': [], u'ticket': []} ) + +class PagureFlaskApiProjectOptionsTests(tests.Modeltests): + """ Tests for the flask API of pagure for modifying options ofs a project + """ + + maxDiff = None + + def setUp(self): + """ Set up the environnment, ran before every tests. """ + super(PagureFlaskApiProjectOptionsTests, self).setUp() + tests.create_projects(self.session) + tests.create_tokens(self.session, project_id=None) + tests.create_tokens_acl( + self.session, 'aaabbbcccddd', 'modify_project') + + project = pagure.lib.query._get_project(self.session, 'test') + self.assertEquals( + project.access_users, + {u'admin': [], u'commit': [], u'ticket': []} + ) + + def test_api_get_project_options_wrong_project(self): + """ Test accessing api_get_project_options w/o auth header. """ + + headers = {'Authorization': 'token aaabbbcccddd'} + output = self.app.get('/api/0/unknown/options', headers=headers) + self.assertEqual(output.status_code, 404) + data = json.loads(output.get_data(as_text=True)) + self.assertEqual( + data, + {u'error': u'Project not found', u'error_code': u'ENOPROJECT'} + ) + + def test_api_get_project_options_wo_header(self): + """ Test accessing api_get_project_options w/o auth header. """ + + output = self.app.get('/api/0/test/options') + self.assertEqual(output.status_code, 401) + data = json.loads(output.get_data(as_text=True)) + self.assertEqual( + data, + { + u'error': u'Invalid or expired token. Please visit ' + 'http://localhost.localdomain/settings#api-keys to get ' + 'or renew your API token.', + u'error_code': u'EINVALIDTOK' + } + ) + + def test_api_get_project_options_w_header(self): + """ Test accessing api_get_project_options w/ auth header. """ + + headers = {'Authorization': 'token aaabbbcccddd'} + output = self.app.get('/api/0/test/options', headers=headers) + self.assertEqual(output.status_code, 200) + data = json.loads(output.get_data(as_text=True)) + self.assertEqual( + data, + { + "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, + "disable_non_fast-forward_merges": False, + "fedmsg_notifications": True, + "issue_tracker": True, + "issue_tracker_read_only": False, + "issues_default_to_private": False, + "notify_on_commit_flag": False, + "notify_on_pull-request_flag": False, + "open_metadata_access_to_all": False, + "project_documentation": False, + "pull_request_access_only": False, + "pull_requests": True, + "stomp_notifications": True + }, + "status": "ok" + } + ) + + if __name__ == '__main__': unittest.main(verbosity=2)