diff --git a/keystone/assignment/controllers.py b/keystone/assignment/controllers.py index 37e68c26fa..824991e325 100644 --- a/keystone/assignment/controllers.py +++ b/keystone/assignment/controllers.py @@ -320,13 +320,13 @@ class RoleV3(controller.V3Controller): return self.create_role(context, role=role) @controller.protected() - @validation.validated(schema.role_create, 'role') def create_role(self, request, role): + validation.lazy_validate(schema.role_create, role) return self._create_role(request.context_dict, role) @controller.protected() - @validation.validated(schema.role_create, 'role') def create_domain_role(self, request, role): + validation.lazy_validate(schema.role_create, role) return self._create_role(request.context_dict, role) def list_roles_wrapper(self, request): @@ -368,13 +368,13 @@ class RoleV3(controller.V3Controller): return self.update_role(context, role_id=role_id, role=role) @controller.protected() - @validation.validated(schema.role_update, 'role') def update_role(self, request, role_id, role): + validation.lazy_validate(schema.role_update, role) return self._update_role(request.context_dict, role_id, role) @controller.protected() - @validation.validated(schema.role_update, 'role') def update_domain_role(self, request, role_id, role): + validation.lazy_validate(schema.role_update, role) return self._update_role(request.context_dict, role_id, role) def delete_role_wrapper(self, context, role_id): diff --git a/keystone/catalog/controllers.py b/keystone/catalog/controllers.py index 0adb3ac1d9..119b32ace5 100644 --- a/keystone/catalog/controllers.py +++ b/keystone/catalog/controllers.py @@ -221,8 +221,8 @@ class RegionV3(controller.V3Controller): return self.create_region(context, region) @controller.protected() - @validation.validated(schema.region_create, 'region') def create_region(self, request, region): + validation.lazy_validate(schema.region_create, region) ref = self._normalize_dict(region) if not ref.get('id'): @@ -249,8 +249,8 @@ class RegionV3(controller.V3Controller): return RegionV3.wrap_member(request.context_dict, ref) @controller.protected() - @validation.validated(schema.region_update, 'region') def update_region(self, request, region_id, region): + validation.lazy_validate(schema.region_update, region) self._require_matching_id(region_id, region) initiator = notifications._get_request_audit_info(request.context_dict) ref = self.catalog_api.update_region(region_id, region, initiator) @@ -272,8 +272,8 @@ class ServiceV3(controller.V3Controller): self.get_member_from_driver = self.catalog_api.get_service @controller.protected() - @validation.validated(schema.service_create, 'service') def create_service(self, request, service): + validation.lazy_validate(schema.service_create, service) ref = self._assign_unique_id(self._normalize_dict(service)) initiator = notifications._get_request_audit_info(request.context_dict) ref = self.catalog_api.create_service(ref['id'], ref, initiator) @@ -293,8 +293,8 @@ class ServiceV3(controller.V3Controller): return ServiceV3.wrap_member(request.context_dict, ref) @controller.protected() - @validation.validated(schema.service_update, 'service') def update_service(self, request, service_id, service): + validation.lazy_validate(schema.service_update, service) self._require_matching_id(service_id, service) initiator = notifications._get_request_audit_info(request.context_dict) ref = self.catalog_api.update_service(service_id, service, initiator) @@ -352,8 +352,8 @@ class EndpointV3(controller.V3Controller): return endpoint @controller.protected() - @validation.validated(schema.endpoint_create, 'endpoint') def create_endpoint(self, request, endpoint): + validation.lazy_validate(schema.endpoint_create, endpoint) utils.check_endpoint_url(endpoint['url']) ref = self._assign_unique_id(self._normalize_dict(endpoint)) ref = self._validate_endpoint_region(ref, request.context_dict) @@ -375,8 +375,8 @@ class EndpointV3(controller.V3Controller): return EndpointV3.wrap_member(request.context_dict, ref) @controller.protected() - @validation.validated(schema.endpoint_update, 'endpoint') def update_endpoint(self, request, endpoint_id, endpoint): + validation.lazy_validate(schema.endpoint_update, endpoint) self._require_matching_id(endpoint_id, endpoint) endpoint = self._validate_endpoint_region(endpoint.copy(), @@ -490,9 +490,9 @@ class EndpointGroupV3Controller(controller.V3Controller): path=path) @controller.protected() - @validation.validated(schema.endpoint_group_create, 'endpoint_group') def create_endpoint_group(self, request, endpoint_group): """Create an Endpoint Group with the associated filters.""" + validation.lazy_validate(schema.endpoint_group_create, endpoint_group) ref = self._assign_unique_id(self._normalize_dict(endpoint_group)) self._require_attribute(ref, 'filters') self._require_valid_filter(ref) @@ -518,10 +518,10 @@ class EndpointGroupV3Controller(controller.V3Controller): request.context_dict, ref) @controller.protected() - @validation.validated(schema.endpoint_group_update, 'endpoint_group') def update_endpoint_group(self, request, endpoint_group_id, endpoint_group): """Update fixed values and/or extend the filters.""" + validation.lazy_validate(schema.endpoint_group_update, endpoint_group) if 'filters' in endpoint_group: self._require_valid_filter(endpoint_group) ref = self.catalog_api.update_endpoint_group(endpoint_group_id, diff --git a/keystone/common/validation/__init__.py b/keystone/common/validation/__init__.py index 9d812f4007..cfc86bc127 100644 --- a/keystone/common/validation/__init__.py +++ b/keystone/common/validation/__init__.py @@ -19,6 +19,22 @@ from keystone import exception from keystone.i18n import _ +def lazy_validate(request_body_schema, resource_to_validate): + """A non-decorator way to validate a request, to be used inline. + + :param request_body_schema: a schema to validate the resource reference + :param resource_to_validate: dictionary 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) + schema_validator.validate(resource_to_validate) + + def validated(request_body_schema, resource_to_validate): """Register a schema to validate a resource reference. diff --git a/keystone/credential/controllers.py b/keystone/credential/controllers.py index 1d95be934c..056bb8f108 100644 --- a/keystone/credential/controllers.py +++ b/keystone/credential/controllers.py @@ -62,8 +62,8 @@ class CredentialV3(controller.V3Controller): return super(CredentialV3, self)._assign_unique_id(ref) @controller.protected() - @validation.validated(schema.credential_create, 'credential') def create_credential(self, request, credential): + validation.lazy_validate(schema.credential_create, credential) trust_id = self._get_trust_id_for_request(request.context_dict) ref = self._assign_unique_id(self._normalize_dict(credential), trust_id) @@ -97,8 +97,8 @@ class CredentialV3(controller.V3Controller): return CredentialV3.wrap_member(request.context_dict, ret_ref) @controller.protected() - @validation.validated(schema.credential_update, 'credential') def update_credential(self, request, credential_id, credential): + validation.lazy_validate(schema.credential_update, credential) self._require_matching_id(credential_id, credential) ref = self.credential_api.update_credential(credential_id, credential) diff --git a/keystone/federation/controllers.py b/keystone/federation/controllers.py index 51c96c1dc4..07861f3831 100644 --- a/keystone/federation/controllers.py +++ b/keystone/federation/controllers.py @@ -90,8 +90,9 @@ class IdentityProvider(_ControllerBase): return {cls.member_name: ref} @controller.protected() - @validation.validated(schema.identity_provider_create, 'identity_provider') def create_identity_provider(self, request, idp_id, identity_provider): + validation.lazy_validate(schema.identity_provider_create, + identity_provider) identity_provider = self._normalize_dict(identity_provider) identity_provider.setdefault('enabled', False) idp_ref = self.federation_api.create_idp(idp_id, identity_provider) @@ -118,8 +119,9 @@ class IdentityProvider(_ControllerBase): self.federation_api.delete_idp(idp_id) @controller.protected() - @validation.validated(schema.identity_provider_update, 'identity_provider') def update_identity_provider(self, request, idp_id, identity_provider): + validation.lazy_validate(schema.identity_provider_update, + identity_provider) identity_provider = self._normalize_dict(identity_provider) idp_ref = self.federation_api.update_idp(idp_id, identity_provider) return IdentityProvider.wrap_member(request.context_dict, idp_ref) @@ -181,8 +183,8 @@ class FederationProtocol(_ControllerBase): return {cls.member_name: ref} @controller.protected() - @validation.validated(schema.protocol_create, 'protocol') def create_protocol(self, request, idp_id, protocol_id, protocol): + validation.lazy_validate(schema.protocol_create, protocol) ref = self._normalize_dict(protocol) ref = self.federation_api.create_protocol(idp_id, protocol_id, ref) response = FederationProtocol.wrap_member(request.context_dict, ref) @@ -191,8 +193,8 @@ class FederationProtocol(_ControllerBase): http_client.responses[http_client.CREATED])) @controller.protected() - @validation.validated(schema.protocol_update, 'protocol') def update_protocol(self, request, idp_id, protocol_id, protocol): + validation.lazy_validate(schema.protocol_update, protocol) ref = self._normalize_dict(protocol) ref = self.federation_api.update_protocol(idp_id, protocol_id, protocol) @@ -390,13 +392,13 @@ class Auth(auth_controllers.Auth): ('X-sp-url', service_provider['sp_url'].encode('utf-8')), ('X-auth-url', service_provider['auth_url'].encode('utf-8'))] - @validation.validated(schema.saml_create, 'auth') def create_saml_assertion(self, request, auth): """Exchange a scoped token for a SAML assertion. :param auth: Dictionary that contains a token and service provider ID :returns: SAML Assertion based on properties from the token """ + validation.lazy_validate(schema.saml_create, auth) t = self._create_base_saml_assertion(request.context_dict, auth) (response, service_provider) = t @@ -406,13 +408,13 @@ class Auth(auth_controllers.Auth): status=(http_client.OK, http_client.responses[http_client.OK]), headers=headers) - @validation.validated(schema.saml_create, 'auth') def create_ecp_assertion(self, context, auth): """Exchange a scoped token for an ECP assertion. :param auth: Dictionary that contains a token and service provider ID :returns: ECP Assertion based on properties from the token """ + validation.lazy_validate(schema.saml_create, auth) t = self._create_base_saml_assertion(context, auth) (saml_assertion, service_provider) = t relay_state_prefix = service_provider['relay_state_prefix'] @@ -492,8 +494,9 @@ class ServiceProvider(_ControllerBase): 'links', 'relay_state_prefix', 'sp_url']) @controller.protected() - @validation.validated(schema.service_provider_create, 'service_provider') def create_service_provider(self, request, sp_id, service_provider): + validation.lazy_validate(schema.service_provider_create, + service_provider) service_provider = self._normalize_dict(service_provider) service_provider.setdefault('enabled', False) service_provider.setdefault('relay_state_prefix', @@ -522,8 +525,9 @@ class ServiceProvider(_ControllerBase): self.federation_api.delete_sp(sp_id) @controller.protected() - @validation.validated(schema.service_provider_update, 'service_provider') def update_service_provider(self, request, sp_id, service_provider): + validation.lazy_validate(schema.service_provider_update, + service_provider) service_provider = self._normalize_dict(service_provider) sp_ref = self.federation_api.update_sp(sp_id, service_provider) return ServiceProvider.wrap_member(request.context_dict, sp_ref) diff --git a/keystone/identity/controllers.py b/keystone/identity/controllers.py index fa31882efe..adb293fa3c 100644 --- a/keystone/identity/controllers.py +++ b/keystone/identity/controllers.py @@ -216,8 +216,8 @@ class UserV3(controller.V3Controller): self.check_protection(context, prep_info, ref) @controller.protected() - @validation.validated(schema.user_create, 'user') def create_user(self, request, user): + validation.lazy_validate(schema.user_create, user) # The manager layer will generate the unique ID for users ref = self._normalize_dict(user) ref = self._normalize_domain_id(request.context_dict, ref) @@ -253,8 +253,8 @@ class UserV3(controller.V3Controller): return UserV3.wrap_member(context, ref) @controller.protected() - @validation.validated(schema.user_update, 'user') def update_user(self, request, user_id, user): + validation.lazy_validate(schema.user_update, user) return self._update_user(request.context_dict, user_id, user) @controller.protected(callback=_check_user_and_group_protection) @@ -309,8 +309,8 @@ class GroupV3(controller.V3Controller): self.check_protection(context, prep_info, ref) @controller.protected() - @validation.validated(schema.group_create, 'group') def create_group(self, request, group): + validation.lazy_validate(schema.group_create, group) # The manager layer will generate the unique ID for groups ref = self._normalize_dict(group) ref = self._normalize_domain_id(request.context_dict, ref) @@ -337,8 +337,8 @@ class GroupV3(controller.V3Controller): return GroupV3.wrap_member(request.context_dict, ref) @controller.protected() - @validation.validated(schema.group_update, 'group') def update_group(self, request, group_id, group): + validation.lazy_validate(schema.group_update, group) self._require_matching_id(group_id, group) self._require_matching_domain_id( group_id, group, self.identity_api.get_group) diff --git a/keystone/oauth1/controllers.py b/keystone/oauth1/controllers.py index a626bc40d5..29b6b84096 100644 --- a/keystone/oauth1/controllers.py +++ b/keystone/oauth1/controllers.py @@ -60,16 +60,16 @@ class ConsumerCrudV3(controller.V3Controller): return controller.V3Controller.base_url(context, path=path) @controller.protected() - @validation.validated(schema.consumer_create, 'consumer') def create_consumer(self, request, consumer): + validation.lazy_validate(schema.consumer_create, consumer) ref = self._assign_unique_id(self._normalize_dict(consumer)) initiator = notifications._get_request_audit_info(request.context_dict) consumer_ref = self.oauth_api.create_consumer(ref, initiator) return ConsumerCrudV3.wrap_member(request.context_dict, consumer_ref) @controller.protected() - @validation.validated(schema.consumer_update, 'consumer') def update_consumer(self, request, consumer_id, consumer): + validation.lazy_validate(schema.consumer_update, consumer) self._require_matching_id(consumer_id, consumer) ref = self._normalize_dict(consumer) initiator = notifications._get_request_audit_info(request.context_dict) diff --git a/keystone/policy/controllers.py b/keystone/policy/controllers.py index d5fa3edc51..3feef16b94 100644 --- a/keystone/policy/controllers.py +++ b/keystone/policy/controllers.py @@ -25,8 +25,8 @@ class PolicyV3(controller.V3Controller): member_name = 'policy' @controller.protected() - @validation.validated(schema.policy_create, 'policy') def create_policy(self, request, policy): + validation.lazy_validate(schema.policy_create, policy) ref = self._assign_unique_id(self._normalize_dict(policy)) initiator = notifications._get_request_audit_info(request.context_dict) ref = self.policy_api.create_policy(ref['id'], ref, initiator) @@ -45,8 +45,8 @@ class PolicyV3(controller.V3Controller): return PolicyV3.wrap_member(request.context_dict, ref) @controller.protected() - @validation.validated(schema.policy_update, 'policy') def update_policy(self, request, policy_id, policy): + validation.lazy_validate(schema.policy_update, policy) initiator = notifications._get_request_audit_info(request.context_dict) ref = self.policy_api.update_policy(policy_id, policy, initiator) return PolicyV3.wrap_member(request.context_dict, ref) diff --git a/keystone/resource/controllers.py b/keystone/resource/controllers.py index e6b464f009..4fef4e45ae 100644 --- a/keystone/resource/controllers.py +++ b/keystone/resource/controllers.py @@ -141,8 +141,8 @@ class DomainV3(controller.V3Controller): self.get_member_from_driver = self.resource_api.get_domain @controller.protected() - @validation.validated(schema.domain_create, 'domain') def create_domain(self, request, domain): + validation.lazy_validate(schema.domain_create, domain) ref = self._assign_unique_id(self._normalize_dict(domain)) initiator = notifications._get_request_audit_info(request.context_dict) ref = self.resource_api.create_domain(ref['id'], ref, initiator) @@ -161,8 +161,8 @@ class DomainV3(controller.V3Controller): return DomainV3.wrap_member(request.context_dict, ref) @controller.protected() - @validation.validated(schema.domain_update, 'domain') def update_domain(self, request, domain_id, domain): + validation.lazy_validate(schema.domain_update, domain) self._require_matching_id(domain_id, domain) initiator = notifications._get_request_audit_info(request.context_dict) ref = self.resource_api.update_domain(domain_id, domain, initiator) @@ -240,8 +240,8 @@ class ProjectV3(controller.V3Controller): self.get_member_from_driver = self.resource_api.get_project @controller.protected() - @validation.validated(schema.project_create, 'project') def create_project(self, request, project): + validation.lazy_validate(schema.project_create, project) ref = self._assign_unique_id(self._normalize_dict(project)) if not ref.get('is_domain'): @@ -324,8 +324,8 @@ class ProjectV3(controller.V3Controller): return ProjectV3.wrap_member(request.context_dict, ref) @controller.protected() - @validation.validated(schema.project_update, 'project') def update_project(self, request, project_id, project): + validation.lazy_validate(schema.project_update, project) self._require_matching_id(project_id, project) self._require_matching_domain_id( project_id, project, self.resource_api.get_project) diff --git a/keystone/trust/controllers.py b/keystone/trust/controllers.py index e0d0f7667c..dcc0e0713d 100644 --- a/keystone/trust/controllers.py +++ b/keystone/trust/controllers.py @@ -112,13 +112,13 @@ class TrustV3(controller.V3Controller): return trust_roles @controller.protected() - @validation.validated(schema.trust_create, 'trust') def create_trust(self, request, trust): """Create a new trust. The user creating the trust must be the trustor. """ + validation.lazy_validate(schema.trust_create, trust) # Check if delegated via trust if request.auth_context.get('is_delegated_auth'): # Redelegation case