Remove validated decorator
Since validation was moved inline this isn't necessary any more. Change-Id: I261fa3f7c1bbe9ec8c5e0b94fb4aa5986ed56175
This commit is contained in:
parent
8ff6b0ea51
commit
172e8c545d
|
@ -11,12 +11,7 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
"""Request body validating middleware for OpenStack Identity resources."""
|
"""Request body validating middleware for OpenStack Identity resources."""
|
||||||
|
|
||||||
import functools
|
|
||||||
import inspect
|
|
||||||
|
|
||||||
from keystone.common.validation import validators
|
from keystone.common.validation import validators
|
||||||
from keystone import exception
|
|
||||||
from keystone.i18n import _
|
|
||||||
|
|
||||||
|
|
||||||
def lazy_validate(request_body_schema, resource_to_validate):
|
def lazy_validate(request_body_schema, resource_to_validate):
|
||||||
|
@ -35,59 +30,6 @@ def lazy_validate(request_body_schema, resource_to_validate):
|
||||||
schema_validator.validate(resource_to_validate)
|
schema_validator.validate(resource_to_validate)
|
||||||
|
|
||||||
|
|
||||||
def validated(request_body_schema, resource_to_validate):
|
|
||||||
"""Register a schema to validate a resource reference.
|
|
||||||
|
|
||||||
Registered schema will be used for validating a request body just before
|
|
||||||
API method execution.
|
|
||||||
|
|
||||||
:param request_body_schema: a schema to validate the resource reference
|
|
||||||
:param resource_to_validate: the reference to validate
|
|
||||||
:raises keystone.exception.ValidationError: if `resource_to_validate` is
|
|
||||||
None. (see wrapper method below).
|
|
||||||
:raises TypeError: at decoration time when the expected resource to
|
|
||||||
validate isn't found in the decorated method's
|
|
||||||
signature
|
|
||||||
|
|
||||||
"""
|
|
||||||
schema_validator = validators.SchemaValidator(request_body_schema)
|
|
||||||
|
|
||||||
def add_validator(func):
|
|
||||||
argspec = inspect.getargspec(func)
|
|
||||||
try:
|
|
||||||
arg_index = argspec.args.index(resource_to_validate)
|
|
||||||
except ValueError:
|
|
||||||
raise TypeError(_('validated expected to find %(param_name)r in '
|
|
||||||
'function signature for %(func_name)r.') %
|
|
||||||
{'param_name': resource_to_validate,
|
|
||||||
'func_name': func.__name__})
|
|
||||||
|
|
||||||
@functools.wraps(func)
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
if (resource_to_validate in kwargs and
|
|
||||||
kwargs[resource_to_validate] is not None):
|
|
||||||
schema_validator.validate(kwargs[resource_to_validate])
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
resource = args[arg_index]
|
|
||||||
# If the resource to be validated is not None but
|
|
||||||
# empty, it is possible to be validated by jsonschema.
|
|
||||||
if resource is not None:
|
|
||||||
schema_validator.validate(resource)
|
|
||||||
else:
|
|
||||||
raise exception.ValidationError(
|
|
||||||
attribute=resource_to_validate,
|
|
||||||
target='request body')
|
|
||||||
# We cannot find the resource neither from kwargs nor args.
|
|
||||||
except IndexError:
|
|
||||||
raise exception.ValidationError(
|
|
||||||
attribute=resource_to_validate,
|
|
||||||
target='request body')
|
|
||||||
return func(*args, **kwargs)
|
|
||||||
return wrapper
|
|
||||||
return add_validator
|
|
||||||
|
|
||||||
|
|
||||||
def nullable(property_schema):
|
def nullable(property_schema):
|
||||||
"""Clone a property schema into one that is nullable.
|
"""Clone a property schema into one that is nullable.
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
import six
|
import six
|
||||||
import testtools
|
|
||||||
|
|
||||||
from keystone.assignment import schema as assignment_schema
|
from keystone.assignment import schema as assignment_schema
|
||||||
from keystone.catalog import schema as catalog_schema
|
from keystone.catalog import schema as catalog_schema
|
||||||
|
@ -120,94 +119,6 @@ def expected_validation_failure(msg):
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
class ValidatedDecoratorTests(unit.BaseTestCase):
|
|
||||||
|
|
||||||
entity_schema = {
|
|
||||||
'type': 'object',
|
|
||||||
'properties': {
|
|
||||||
'name': parameter_types.name,
|
|
||||||
},
|
|
||||||
'required': ['name'],
|
|
||||||
}
|
|
||||||
|
|
||||||
valid_entity = {
|
|
||||||
'name': uuid.uuid4().hex,
|
|
||||||
}
|
|
||||||
|
|
||||||
invalid_entity = {
|
|
||||||
'name': 1.0, # NOTE(dstanek): this is the incorrect type for name
|
|
||||||
}
|
|
||||||
|
|
||||||
@validation.validated(entity_create, 'entity')
|
|
||||||
def create_entity(self, entity):
|
|
||||||
"""Used to test cases where validated param is the only param."""
|
|
||||||
|
|
||||||
@validation.validated(entity_create_optional_body, 'entity')
|
|
||||||
def create_entity_optional_body(self, entity):
|
|
||||||
"""Used to test cases where there is an optional body."""
|
|
||||||
|
|
||||||
@validation.validated(entity_update, 'entity')
|
|
||||||
def update_entity(self, entity_id, entity):
|
|
||||||
"""Used to test cases where validated param is not the only param."""
|
|
||||||
|
|
||||||
def test_calling_create_with_valid_entity_kwarg_succeeds(self):
|
|
||||||
self.create_entity(entity=self.valid_entity)
|
|
||||||
|
|
||||||
def test_calling_create_with_empty_entity_kwarg_succeeds(self):
|
|
||||||
"""Test the case when client passing in an empty kwarg reference."""
|
|
||||||
self.create_entity_optional_body(entity={})
|
|
||||||
|
|
||||||
@expected_validation_failure('Expecting to find entity in request body')
|
|
||||||
def test_calling_create_with_kwarg_as_None_fails(self):
|
|
||||||
self.create_entity(entity=None)
|
|
||||||
|
|
||||||
def test_calling_create_with_valid_entity_arg_succeeds(self):
|
|
||||||
self.create_entity(self.valid_entity)
|
|
||||||
|
|
||||||
def test_calling_create_with_empty_entity_arg_succeeds(self):
|
|
||||||
"""Test the case when client passing in an empty entity reference."""
|
|
||||||
self.create_entity_optional_body({})
|
|
||||||
|
|
||||||
@expected_validation_failure("Invalid input for field 'name'")
|
|
||||||
def test_calling_create_with_invalid_entity_fails(self):
|
|
||||||
self.create_entity(self.invalid_entity)
|
|
||||||
|
|
||||||
@expected_validation_failure('Expecting to find entity in request body')
|
|
||||||
def test_calling_create_with_entity_arg_as_None_fails(self):
|
|
||||||
self.create_entity(None)
|
|
||||||
|
|
||||||
@expected_validation_failure('Expecting to find entity in request body')
|
|
||||||
def test_calling_create_without_an_entity_fails(self):
|
|
||||||
self.create_entity()
|
|
||||||
|
|
||||||
def test_using_the_wrong_name_with_the_decorator_fails(self):
|
|
||||||
with testtools.ExpectedException(TypeError):
|
|
||||||
@validation.validated(self.entity_schema, 'entity_')
|
|
||||||
def function(entity):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# NOTE(dstanek): below are the test cases for making sure the validation
|
|
||||||
# works when the validated param is not the only param. Since all of the
|
|
||||||
# actual validation cases are tested above these test are for a sanity
|
|
||||||
# check.
|
|
||||||
|
|
||||||
def test_calling_update_with_valid_entity_succeeds(self):
|
|
||||||
self.update_entity(uuid.uuid4().hex, self.valid_entity)
|
|
||||||
|
|
||||||
@expected_validation_failure("Invalid input for field 'name'")
|
|
||||||
def test_calling_update_with_invalid_entity_fails(self):
|
|
||||||
self.update_entity(uuid.uuid4().hex, self.invalid_entity)
|
|
||||||
|
|
||||||
def test_calling_update_with_empty_entity_kwarg_succeeds(self):
|
|
||||||
"""Test the case when client passing in an empty entity reference."""
|
|
||||||
global entity_update
|
|
||||||
original_entity_update = entity_update.copy()
|
|
||||||
# pop 'minProperties' from schema so that empty body is allowed.
|
|
||||||
entity_update.pop('minProperties')
|
|
||||||
self.update_entity(uuid.uuid4().hex, entity={})
|
|
||||||
entity_update = original_entity_update
|
|
||||||
|
|
||||||
|
|
||||||
class EntityValidationTestCase(unit.BaseTestCase):
|
class EntityValidationTestCase(unit.BaseTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
Loading…
Reference in New Issue