Merge "Add schema validation to update user v2"
This commit is contained in:
commit
4605f90283
|
@ -95,13 +95,10 @@ class User(controller.V2Controller):
|
||||||
@controller.v2_deprecated
|
@controller.v2_deprecated
|
||||||
def update_user(self, request, user_id, user):
|
def update_user(self, request, user_id, user):
|
||||||
# NOTE(termie): this is really more of a patch than a put
|
# NOTE(termie): this is really more of a patch than a put
|
||||||
|
validation.lazy_validate(schema.user_update_v2, user)
|
||||||
user = self.normalize_username_in_request(user)
|
user = self.normalize_username_in_request(user)
|
||||||
self.assert_admin(request)
|
self.assert_admin(request)
|
||||||
|
|
||||||
if 'enabled' in user and not isinstance(user['enabled'], bool):
|
|
||||||
msg = _('Enabled field should be a boolean')
|
|
||||||
raise exception.ValidationError(message=msg)
|
|
||||||
|
|
||||||
default_project_id = user.pop('tenantId', None)
|
default_project_id = user.pop('tenantId', None)
|
||||||
if default_project_id is not None:
|
if default_project_id is not None:
|
||||||
user['default_project_id'] = default_project_id
|
user['default_project_id'] = default_project_id
|
||||||
|
|
|
@ -22,6 +22,28 @@ _identity_name = {
|
||||||
'pattern': '[\S]+'
|
'pattern': '[\S]+'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Schema for Identity v2 API
|
||||||
|
|
||||||
|
_user_properties_v2 = {
|
||||||
|
'description': validation.nullable(parameter_types.description),
|
||||||
|
'enabled': parameter_types.boolean,
|
||||||
|
'tenantId': validation.nullable(parameter_types.id_string),
|
||||||
|
'name': _identity_name,
|
||||||
|
'username': _identity_name,
|
||||||
|
'password': {
|
||||||
|
'type': ['string', 'null']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user_update_v2 = {
|
||||||
|
'type': 'object',
|
||||||
|
'properties': _user_properties_v2,
|
||||||
|
'minProperties': 0,
|
||||||
|
'additionalProperties': True
|
||||||
|
}
|
||||||
|
|
||||||
|
# Schema for Identity v3 API
|
||||||
|
|
||||||
_user_properties = {
|
_user_properties = {
|
||||||
'default_project_id': validation.nullable(parameter_types.id_string),
|
'default_project_id': validation.nullable(parameter_types.id_string),
|
||||||
'description': validation.nullable(parameter_types.description),
|
'description': validation.nullable(parameter_types.description),
|
||||||
|
|
|
@ -447,31 +447,6 @@ class IdentityTests(object):
|
||||||
user['id'],
|
user['id'],
|
||||||
user)
|
user)
|
||||||
|
|
||||||
def test_update_user_blank_name_fails(self):
|
|
||||||
user = unit.new_user_ref(domain_id=CONF.identity.default_domain_id)
|
|
||||||
user = self.identity_api.create_user(user)
|
|
||||||
user['name'] = ''
|
|
||||||
self.assertRaises(exception.ValidationError,
|
|
||||||
self.identity_api.update_user,
|
|
||||||
user['id'],
|
|
||||||
user)
|
|
||||||
|
|
||||||
def test_update_user_invalid_name_fails(self):
|
|
||||||
user = unit.new_user_ref(domain_id=CONF.identity.default_domain_id)
|
|
||||||
user = self.identity_api.create_user(user)
|
|
||||||
|
|
||||||
user['name'] = None
|
|
||||||
self.assertRaises(exception.ValidationError,
|
|
||||||
self.identity_api.update_user,
|
|
||||||
user['id'],
|
|
||||||
user)
|
|
||||||
|
|
||||||
user['name'] = 123
|
|
||||||
self.assertRaises(exception.ValidationError,
|
|
||||||
self.identity_api.update_user,
|
|
||||||
user['id'],
|
|
||||||
user)
|
|
||||||
|
|
||||||
def test_list_users(self):
|
def test_list_users(self):
|
||||||
users = self.identity_api.list_users(
|
users = self.identity_api.list_users(
|
||||||
domain_scope=self._set_domain_scope(
|
domain_scope=self._set_domain_scope(
|
||||||
|
@ -568,19 +543,6 @@ class IdentityTests(object):
|
||||||
user_ref = self.identity_api.get_user(user_ref['id'])
|
user_ref = self.identity_api.get_user(user_ref['id'])
|
||||||
self.assertEqual(changed_name, user_ref['name'])
|
self.assertEqual(changed_name, user_ref['name'])
|
||||||
|
|
||||||
def test_update_user_enable_fails(self):
|
|
||||||
user = unit.new_user_ref(domain_id=CONF.identity.default_domain_id)
|
|
||||||
user = self.identity_api.create_user(user)
|
|
||||||
user_ref = self.identity_api.get_user(user['id'])
|
|
||||||
self.assertTrue(user_ref['enabled'])
|
|
||||||
|
|
||||||
# Strings are not valid boolean values
|
|
||||||
user['enabled'] = 'false'
|
|
||||||
self.assertRaises(exception.ValidationError,
|
|
||||||
self.identity_api.update_user,
|
|
||||||
user['id'],
|
|
||||||
user)
|
|
||||||
|
|
||||||
def test_add_user_to_group(self):
|
def test_add_user_to_group(self):
|
||||||
domain = self._get_domain_fixture()
|
domain = self._get_domain_fixture()
|
||||||
new_group = unit.new_group_ref(domain_id=domain['id'])
|
new_group = unit.new_group_ref(domain_id=domain['id'])
|
||||||
|
|
|
@ -17,6 +17,7 @@ from keystone.assignment import schema as assignment_schema
|
||||||
from keystone.catalog import schema as catalog_schema
|
from keystone.catalog import schema as catalog_schema
|
||||||
from keystone.common.validation import validators
|
from keystone.common.validation import validators
|
||||||
from keystone import exception
|
from keystone import exception
|
||||||
|
from keystone.identity import schema as identity_schema
|
||||||
from keystone.resource import schema as resource_schema
|
from keystone.resource import schema as resource_schema
|
||||||
from keystone.tests import unit
|
from keystone.tests import unit
|
||||||
|
|
||||||
|
@ -302,3 +303,60 @@ class ServiceValidationTestCase(unit.BaseTestCase):
|
||||||
self.assertRaises(exception.SchemaValidationError,
|
self.assertRaises(exception.SchemaValidationError,
|
||||||
self.create_validator.validate,
|
self.create_validator.validate,
|
||||||
request)
|
request)
|
||||||
|
|
||||||
|
|
||||||
|
class UserValidationTestCase(unit.BaseTestCase):
|
||||||
|
"""Test for V2 User API Validation."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(UserValidationTestCase, self).setUp()
|
||||||
|
|
||||||
|
schema_user_update = identity_schema.user_update_v2
|
||||||
|
self.update_validator = validators.SchemaValidator(schema_user_update)
|
||||||
|
|
||||||
|
def test_validate_user_update_succeeds_with_name(self):
|
||||||
|
request = {
|
||||||
|
'name': uuid.uuid4().hex,
|
||||||
|
'enabled': True
|
||||||
|
}
|
||||||
|
self.update_validator.validate(request)
|
||||||
|
|
||||||
|
def test_validate_user_update_succeeds_with_username(self):
|
||||||
|
request = {
|
||||||
|
'username': uuid.uuid4().hex,
|
||||||
|
'enabled': True
|
||||||
|
}
|
||||||
|
self.update_validator.validate(request)
|
||||||
|
|
||||||
|
def test_validate_user_update_succeeds_with_no_params(self):
|
||||||
|
request = {}
|
||||||
|
self.update_validator.validate(request)
|
||||||
|
|
||||||
|
def test_validate_user_update_fails_with_invalid_name(self):
|
||||||
|
for invalid_name in _INVALID_NAMES:
|
||||||
|
request = {
|
||||||
|
'name': invalid_name
|
||||||
|
}
|
||||||
|
self.assertRaises(exception.SchemaValidationError,
|
||||||
|
self.update_validator.validate,
|
||||||
|
request)
|
||||||
|
|
||||||
|
def test_validate_user_update_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.update_validator.validate(request)
|
||||||
|
|
||||||
|
def test_validate_user_update_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.update_validator.validate,
|
||||||
|
request)
|
||||||
|
|
Loading…
Reference in New Issue