From a5264d7f3584b749c30bcccba4d39fb66df36de9 Mon Sep 17 00:00:00 2001 From: gage hugo Date: Thu, 28 Jul 2016 14:55:39 -0500 Subject: [PATCH] Add schema validation to create user v2 Added validation for create user in v2 Partially implements: bp schema-validation-extent Change-Id: I555243cb00423367a415dcbf3674af0940c2a669 --- keystone/identity/controllers.py | 10 +---- keystone/identity/schema.py | 18 ++++++++ keystone/tests/unit/test_v2_validation.py | 51 +++++++++++++++++++++++ 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/keystone/identity/controllers.py b/keystone/identity/controllers.py index e62afbec46..4f161ee179 100644 --- a/keystone/identity/controllers.py +++ b/keystone/identity/controllers.py @@ -21,7 +21,7 @@ from keystone.common import dependency from keystone.common import validation import keystone.conf from keystone import exception -from keystone.i18n import _, _LW +from keystone.i18n import _LW from keystone.identity import schema from keystone import notifications @@ -61,18 +61,12 @@ class User(controller.V2Controller): # CRUD extension @controller.v2_deprecated def create_user(self, request, user): + validation.lazy_validate(schema.user_create_v2, user) user = self._normalize_OSKSADM_password_on_request(user) user = self.normalize_username_in_request(user) user = self._normalize_dict(user) self.assert_admin(request) - if 'name' not in user or not user['name']: - msg = _('Name field is required and cannot be empty') - raise exception.ValidationError(message=msg) - if 'enabled' in user and not isinstance(user['enabled'], bool): - msg = _('Enabled field must be a boolean') - raise exception.ValidationError(message=msg) - default_project_id = user.pop('tenantId', None) if default_project_id is not None: # Check to see if the project is valid before moving on. diff --git a/keystone/identity/schema.py b/keystone/identity/schema.py index 4e0db3676b..dc82aeacce 100644 --- a/keystone/identity/schema.py +++ b/keystone/identity/schema.py @@ -35,6 +35,24 @@ _user_properties_v2 = { } } +user_create_v2 = { + 'type': 'object', + 'properties': _user_properties_v2, + 'anyOf': [ + { + 'required': ['username'] + }, + { + 'required': ['name'] + } + ], + 'additionalProperties': True +} + +# NOTE(ghugo): minProperties value should really be 1, however it +# is currently set to 0 to avoid breaking backwards compatability, +# and tempest tests. + user_update_v2 = { 'type': 'object', 'properties': _user_properties_v2, diff --git a/keystone/tests/unit/test_v2_validation.py b/keystone/tests/unit/test_v2_validation.py index 98627a4759..40bb542905 100644 --- a/keystone/tests/unit/test_v2_validation.py +++ b/keystone/tests/unit/test_v2_validation.py @@ -311,9 +311,60 @@ class UserValidationTestCase(unit.BaseTestCase): def setUp(self): super(UserValidationTestCase, self).setUp() + schema_user_create = identity_schema.user_create_v2 schema_user_update = identity_schema.user_update_v2 + self.create_validator = validators.SchemaValidator(schema_user_create) self.update_validator = validators.SchemaValidator(schema_user_update) + def test_validate_user_create_succeeds_with_name(self): + request = { + 'name': uuid.uuid4().hex + } + self.create_validator.validate(request) + + def test_validate_user_create_succeeds_with_username(self): + request = { + 'username': uuid.uuid4().hex + } + self.create_validator.validate(request) + + def test_validate_user_create_fails_with_invalid_params(self): + request = { + 'bogus': uuid.uuid4().hex + } + self.assertRaises(exception.SchemaValidationError, + self.create_validator.validate, + request) + + def test_validate_user_create_fails_with_invalid_name(self): + for invalid_name in _INVALID_NAMES: + request = { + 'name': invalid_name + } + self.assertRaises(exception.SchemaValidationError, + self.create_validator.validate, + request) + + def test_validate_user_create_with_enabled(self): + """Validate `enabled` as boolean-like values.""" + for valid_enabled in _VALID_ENABLED_FORMATS: + request = { + 'name': uuid.uuid4().hex, + 'enabled': valid_enabled + } + self.create_validator.validate(request) + + def test_validate_user_create_with_invalid_enabled_fails(self): + """Exception is raised when `enabled` isn't a boolean-like value.""" + for invalid_enabled in _INVALID_ENABLED_FORMATS: + request = { + 'name': uuid.uuid4().hex, + 'enabled': invalid_enabled + } + self.assertRaises(exception.SchemaValidationError, + self.create_validator.validate, + request) + def test_validate_user_update_succeeds_with_name(self): request = { 'name': uuid.uuid4().hex,