diff --git a/pagure/forms.py b/pagure/forms.py index f57eac2..d2ba507 100644 --- a/pagure/forms.py +++ b/pagure/forms.py @@ -29,10 +29,10 @@ import six import wtforms import pagure.lib.query +import pagure.validators from pagure.config import config as pagure_config from pagure.utils import urlpattern, is_admin - STRICT_REGEX = "^[a-zA-Z0-9-_]+$" TAGS_REGEX = "^[a-zA-Z0-9-_, .:]+$" FALSE_VALUES = ("false", "", False, "False", 0, "0") @@ -141,7 +141,11 @@ class ProjectFormSimplified(PagureForm): ], ) avatar_email = wtforms.StringField( - "Avatar email", [wtforms.validators.optional()] + "Avatar email", + [ + pagure.validators.EmailValidator("avatar_email must be an email"), + wtforms.validators.optional(), + ], ) tags = wtforms.StringField( "Project tags", diff --git a/pagure/validators.py b/pagure/validators.py new file mode 100644 index 0000000..20ee1c5 --- /dev/null +++ b/pagure/validators.py @@ -0,0 +1,21 @@ +import re + +import six +from wtforms import validators + + +class EmailValidator(object): + """Validates wtform email field""" + + def __init__(self, message="The field data was not an email"): + self._message = message + + def __call__(self, form, email): + if not isinstance(email.data, six.text_type): + raise validators.ValidationError( + "Email fields should be of text type. Found {0}".format( + type(email.data) + ) + ) + elif not re.match(r"[^@]+@[^@]+\.[^@]+", email.data): + raise validators.ValidationError(self._message) diff --git a/tests/test_pagure_flask_api_project.py b/tests/test_pagure_flask_api_project.py index 7dbbb12..d0a906c 100644 --- a/tests/test_pagure_flask_api_project.py +++ b/tests/test_pagure_flask_api_project.py @@ -2102,6 +2102,78 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ) data = { + 'name': 'api1', + 'description': 'Mighty mighty description', + 'avatar_email': 123 + } + + # invalid avatar_email - number + output = self.app.post( + '/api/0/new/', data=data, headers=headers) + self.assertEqual(output.status_code, 400) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual(data, + {"error": "Invalid or incomplete input submitted", + "error_code": "EINVALIDREQ", + "errors": + {"avatar_email": ['avatar_email must be an email']} + } + ) + + data = { + 'name': 'api1', + 'description': 'Mighty mighty description', + 'avatar_email': [1,2,3] + } + + # invalid avatar_email - list + output = self.app.post( + '/api/0/new/', data=data, headers=headers) + self.assertEqual(output.status_code, 400) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual(data, + {"error": "Invalid or incomplete input submitted", + "error_code": "EINVALIDREQ", + "errors": + {"avatar_email": ['avatar_email must be an email']} + } + ) + + data = { + 'name': 'api1', + 'description': 'Mighty mighty description', + 'avatar_email': True + } + + # invalid avatar_email - boolean + output = self.app.post( + '/api/0/new/', data=data, headers=headers) + self.assertEqual(output.status_code, 400) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual(data, + {"error": "Invalid or incomplete input submitted", + "error_code": "EINVALIDREQ", + "errors": + {"avatar_email": ['avatar_email must be an email']} + } + ) + + data = { + 'name': 'api1', + 'description': 'Mighty mighty description', + 'avatar_email': 'mighty@email.com' + } + + # valid avatar_email + output = self.app.post( + '/api/0/new/', data=data, headers=headers) + self.assertEqual(output.status_code, 200) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + {'message': 'Project "api1" created'}) + + data = { 'name': 'test_42', 'description': 'Just another small test project', }