Implement validation on Credential V3
Use jsonschema to validate create and update operations on V3 Credentials. bp: api-validation Change-Id: Ib61902ce6bf037b2185c405de7b407ad49ed423b
This commit is contained in:
parent
28f60cfa69
commit
67289e689a
|
@ -16,6 +16,8 @@ import hashlib
|
|||
|
||||
from keystone.common import controller
|
||||
from keystone.common import dependency
|
||||
from keystone.common import validation
|
||||
from keystone.credential import schema
|
||||
from keystone import exception
|
||||
from keystone.i18n import _
|
||||
from keystone.openstack.common import jsonutils
|
||||
|
@ -58,6 +60,7 @@ class CredentialV3(controller.V3Controller):
|
|||
return super(CredentialV3, self)._assign_unique_id(ref)
|
||||
|
||||
@controller.protected()
|
||||
@validation.validated(schema.credential_create, 'credential')
|
||||
def create_credential(self, context, credential):
|
||||
trust_id = self._get_trust_id_for_request(context)
|
||||
ref = self._assign_unique_id(self._normalize_dict(credential),
|
||||
|
@ -92,6 +95,7 @@ class CredentialV3(controller.V3Controller):
|
|||
return CredentialV3.wrap_member(context, ret_ref)
|
||||
|
||||
@controller.protected()
|
||||
@validation.validated(schema.credential_update, 'credential')
|
||||
def update_credential(self, context, credential_id, credential):
|
||||
self._require_matching_id(credential_id, credential)
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
_credential_properties = {
|
||||
'blob': {
|
||||
'type': 'string'
|
||||
},
|
||||
'project_id': {
|
||||
'type': 'string'
|
||||
},
|
||||
'type': {
|
||||
'type': 'string'
|
||||
},
|
||||
'user_id': {
|
||||
'type': 'string'
|
||||
}
|
||||
}
|
||||
|
||||
credential_create = {
|
||||
'type': 'object',
|
||||
'properties': _credential_properties,
|
||||
'required': ['blob', 'type', 'user_id'],
|
||||
'additionalProperties': True
|
||||
}
|
||||
|
||||
credential_update = {
|
||||
'type': 'object',
|
||||
'properties': _credential_properties,
|
||||
'minProperties': 1,
|
||||
'additionalProperties': True
|
||||
}
|
|
@ -316,11 +316,16 @@ class RestfulTestCase(tests.SQLDriverOverrides, rest.RestfulTestCase,
|
|||
ref['domain_id'] = domain_id
|
||||
return ref
|
||||
|
||||
def new_credential_ref(self, user_id, project_id=None):
|
||||
ref = self.new_ref()
|
||||
def new_credential_ref(self, user_id, project_id=None, cred_type=None):
|
||||
ref = dict()
|
||||
ref['id'] = uuid.uuid4().hex
|
||||
ref['user_id'] = user_id
|
||||
ref['blob'] = uuid.uuid4().hex
|
||||
ref['type'] = uuid.uuid4().hex
|
||||
if cred_type == 'ec2':
|
||||
ref['type'] = 'ec2'
|
||||
ref['blob'] = {'blah': 'test'}
|
||||
else:
|
||||
ref['type'] = 'cert'
|
||||
ref['blob'] = uuid.uuid4().hex
|
||||
if project_id:
|
||||
ref['project_id'] = project_id
|
||||
return ref
|
||||
|
@ -967,6 +972,7 @@ class RestfulTestCase(tests.SQLDriverOverrides, rest.RestfulTestCase,
|
|||
resp,
|
||||
'credentials',
|
||||
self.assertValidCredential,
|
||||
keys_to_check=['blob', 'user_id', 'type'],
|
||||
*args,
|
||||
**kwargs)
|
||||
|
||||
|
@ -975,6 +981,7 @@ class RestfulTestCase(tests.SQLDriverOverrides, rest.RestfulTestCase,
|
|||
resp,
|
||||
'credential',
|
||||
self.assertValidCredential,
|
||||
keys_to_check=['blob', 'user_id', 'type'],
|
||||
*args,
|
||||
**kwargs)
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ from keystone.assignment import schema as assignment_schema
|
|||
from keystone.common import validation
|
||||
from keystone.common.validation import parameter_types
|
||||
from keystone.common.validation import validators
|
||||
from keystone.credential import schema as credential_schema
|
||||
from keystone import exception
|
||||
from keystone.policy import schema as policy_schema
|
||||
|
||||
|
@ -610,3 +611,91 @@ class PolicyValidationTestCase(testtools.TestCase):
|
|||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.update_policy_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
|
||||
class CredentialValidationTestCase(testtools.TestCase):
|
||||
"""Test for V3 Credential API validation."""
|
||||
|
||||
def setUp(self):
|
||||
super(CredentialValidationTestCase, self).setUp()
|
||||
|
||||
create = credential_schema.credential_create
|
||||
update = credential_schema.credential_update
|
||||
self.create_credential_validator = validators.SchemaValidator(create)
|
||||
self.update_credential_validator = validators.SchemaValidator(update)
|
||||
|
||||
def test_validate_credential_succeeds(self):
|
||||
"""Test that we validate a credential request."""
|
||||
request_to_validate = {'blob': 'some string',
|
||||
'project_id': uuid.uuid4().hex,
|
||||
'type': 'ec2',
|
||||
'user_id': uuid.uuid4().hex}
|
||||
self.create_credential_validator.validate(request_to_validate)
|
||||
|
||||
def test_validate_credential_without_blob_fails(self):
|
||||
"""Exception raised without `blob` in create request."""
|
||||
request_to_validate = {'type': 'ec2',
|
||||
'user_id': uuid.uuid4().hex}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.create_credential_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_credential_without_user_id_fails(self):
|
||||
"""Exception raised without `user_id` in create request."""
|
||||
request_to_validate = {'blob': 'some credential blob',
|
||||
'type': 'ec2'}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.create_credential_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_credential_without_type_fails(self):
|
||||
"""Exception raised without `type` in create request."""
|
||||
request_to_validate = {'blob': 'some credential blob',
|
||||
'user_id': uuid.uuid4().hex}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.create_credential_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_credential_with_types_succeeds(self):
|
||||
"""Test that credential type works for ec2 and cert."""
|
||||
cred_types = ['ec2', 'cert', uuid.uuid4().hex]
|
||||
|
||||
for c_type in cred_types:
|
||||
request_to_validate = {'blob': 'some blob',
|
||||
'type': c_type,
|
||||
'user_id': uuid.uuid4().hex}
|
||||
# Make sure an exception isn't raised
|
||||
self.create_credential_validator.validate(request_to_validate)
|
||||
|
||||
def test_validate_credential_with_extra_parameters_succeeds(self):
|
||||
"""Validate create request with extra parameters."""
|
||||
request_to_validate = {'blob': 'some string',
|
||||
'extra': False,
|
||||
'project_id': uuid.uuid4().hex,
|
||||
'type': 'ec2',
|
||||
'user_id': uuid.uuid4().hex}
|
||||
self.create_credential_validator.validate(request_to_validate)
|
||||
|
||||
def test_validate_credential_update_succeeds(self):
|
||||
"""Test that a credential request is properly validated."""
|
||||
request_to_validate = {'blob': 'some string',
|
||||
'project_id': uuid.uuid4().hex,
|
||||
'type': 'ec2',
|
||||
'user_id': uuid.uuid4().hex}
|
||||
self.update_credential_validator.validate(request_to_validate)
|
||||
|
||||
def test_validate_credential_update_without_parameters_fails(self):
|
||||
"""Exception is raised on update without parameters."""
|
||||
request_to_validate = {}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.update_credential_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_credential_update_with_extra_parameters_succeeds(self):
|
||||
"""Validate credential update with extra parameters."""
|
||||
request_to_validate = {'blob': 'some string',
|
||||
'extra': False,
|
||||
'project_id': uuid.uuid4().hex,
|
||||
'type': 'ec2',
|
||||
'user_id': uuid.uuid4().hex}
|
||||
self.update_credential_validator.validate(request_to_validate)
|
||||
|
|
Loading…
Reference in New Issue