From 53b7929689d4ac55124aedc0fded10e94dfb53a1 Mon Sep 17 00:00:00 2001 From: Fabien Boucher Date: Feb 11 2019 10:11:57 +0000 Subject: Use wtforms to validate a new token in the projects api --- diff --git a/pagure/api/project.py b/pagure/api/project.py index c33295f..622a7f5 100644 --- a/pagure/api/project.py +++ b/pagure/api/project.py @@ -2168,12 +2168,11 @@ def api_project_create_api_token(repo, namespace=None, username=None): +------------------+---------+---------------+---------------------------+ | Key | Type | Optionality | Description | +==================+=========+===============+===========================+ - | ``desc`` | String | Mandatory | A string to specify the | + | ``description`` | String | optional | A string to specify the | | | | | description of the token | | | | | | +------------------+---------+---------------+---------------------------+ - | ``acl`` | String | Mandatory | The ACL as a comma | - | | | | string | + | ``acls`` | List | Mandatory | The ACLs | | | | | | +------------------+---------+---------------+---------------------------+ @@ -2208,26 +2207,21 @@ def api_project_create_api_token(repo, namespace=None, username=None): raise pagure.exceptions.APIError( 401, error_code=APIERROR.ENOTHIGHENOUGH) - form = flask.request.form - valid_form = True - description = form.get('description') - acl = form.get('acl') - if not isinstance(description, str) or not isinstance(acl, str): - valid_form = False - acl_list = acl.split(',') - for ac in acl_list: - if ac not in pagure_config.get("ACLS", []): - valid_form = False - break - if not valid_form: + authorized_acls = pagure_config.get("ACLS", {}).keys() + form = pagure.forms.NewTokenForm( + csrf_enabled=False, sacls=authorized_acls) + if form.validate_on_submit(): + acls = form.acls.data + description = form.description.data + else: raise pagure.exceptions.APIError( - 400, error_code=APIERROR.EINVALIDREQ) + 400, error_code=APIERROR.EINVALIDREQ, errors=form.errors) pagure.lib.query.add_token_to_user( - flask.g.session, project, acl.split(','), flask.g.fas_user.user, + flask.g.session, project, acls, flask.g.fas_user.user, description) token_id = pagure.lib.query.search_token( - flask.g.session, None, user=flask.g.fas_user.user, + flask.g.session, acls=None, user=flask.g.fas_user.user, description=description)[0].id output = { 'token': { diff --git a/pagure/forms.py b/pagure/forms.py index d2ba507..a063c9c 100644 --- a/pagure/forms.py +++ b/pagure/forms.py @@ -407,7 +407,7 @@ class MilestoneForm(PagureForm): class NewTokenForm(PagureForm): - """ Form to add/change the status of an issue. """ + """ Form to add a new token. """ description = wtforms.StringField( "description", [wtforms.validators.Optional()] @@ -426,6 +426,9 @@ class NewTokenForm(PagureForm): self.acls.choices = [ (acl.name, acl.name) for acl in kwargs["acls"] ] + if "sacls" in kwargs: + self.acls.choices = [ + (acl, acl) for acl in kwargs['sacls']] class UpdateIssueForm(PagureForm): diff --git a/tests/test_pagure_flask_api_project.py b/tests/test_pagure_flask_api_project.py index 560e82c..97ab8ff 100644 --- a/tests/test_pagure_flask_api_project.py +++ b/tests/test_pagure_flask_api_project.py @@ -4111,7 +4111,7 @@ class PagureFlaskApiProjectCreateAPITokenTests(tests.Modeltests): self.session, 'aaabbbcccddd', 'modify_project') def test_api_createapitoken_as_owner(self): - """ Test accessing api_project_createapitoken as owner. """ + """ Test accessing api_project_create_token as owner. """ headers = {'Authorization': 'token aaabbbcccddd'} project = pagure.lib.query._get_project(self.session, 'test') @@ -4120,7 +4120,7 @@ class PagureFlaskApiProjectCreateAPITokenTests(tests.Modeltests): # Call the api with pingou user token and verify content data = { 'description': tdescription, - 'acl': 'pull_request_merge,pull_request_comment' + 'acls': ['pull_request_merge', 'pull_request_comment'] } output = self.app.post('/api/0/test/token/create', headers=headers, data=data) @@ -4140,14 +4140,14 @@ class PagureFlaskApiProjectCreateAPITokenTests(tests.Modeltests): # Call the api with pingou user token and error code data = { 'description': tdescription, - 'acl': 'foo,bar' + 'acl': ['foo', 'bar'] } output = self.app.post('/api/0/test/token/create', headers=headers, data=data) self.assertEqual(output.status_code, 400) def test_api_createapitoken_as_admin(self): - """ Test accessing api_project_createapitoken as admin. """ + """ Test accessing api_project_create_token as admin. """ project = pagure.lib.query._get_project(self.session, 'test') @@ -4176,7 +4176,7 @@ class PagureFlaskApiProjectCreateAPITokenTests(tests.Modeltests): # Call the api with pingou user token and verify content data = { 'description': tdescription, - 'acl': 'pull_request_merge,pull_request_comment' + 'acls': ['pull_request_merge', 'pull_request_comment'] } output = self.app.post('/api/0/test/token/create', headers=headers, data=data) @@ -4194,7 +4194,7 @@ class PagureFlaskApiProjectCreateAPITokenTests(tests.Modeltests): ) def test_api_createapitoken_as_unauthorized(self): - """ Test accessing api_project_createapitoken as project admin + """ Test accessing api_project_create_token as project admin but with unauthorized token ACL. """ @@ -4225,14 +4225,14 @@ class PagureFlaskApiProjectCreateAPITokenTests(tests.Modeltests): # Call the api with pingou user token and verify content data = { 'description': tdescription, - 'acl': 'pull_request_merge,pull_request_comment' + 'acls': ['pull_request_merge', 'pull_request_comment'] } output = self.app.post('/api/0/test/token/create', headers=headers, data=data) self.assertEqual(output.status_code, 401) def test_api_createapitoken_as_unauthorized_2(self): - """ Test accessing api_project_createapitoken as project user + """ Test accessing api_project_create_token as project user with unauthorized token ACL. """ @@ -4263,7 +4263,7 @@ class PagureFlaskApiProjectCreateAPITokenTests(tests.Modeltests): # Call the api with pingou user token and verify content data = { 'description': tdescription, - 'acl': 'pull_request_merge,pull_request_comment' + 'acls': ['pull_request_merge', 'pull_request_comment'] } output = self.app.post('/api/0/test/token/create', headers=headers, data=data)