keystone/keystone/credential/controllers.py

109 lines
4.4 KiB
Python

# Copyright 2013 OpenStack Foundation
#
# 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.
import hashlib
from oslo.serialization import jsonutils
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 _
@dependency.requires('credential_api')
class CredentialV3(controller.V3Controller):
collection_name = 'credentials'
member_name = 'credential'
def __init__(self):
super(CredentialV3, self).__init__()
self.get_member_from_driver = self.credential_api.get_credential
def _assign_unique_id(self, ref, trust_id=None):
# Generates and assigns a unique identifier to
# a credential reference.
if ref.get('type', '').lower() == 'ec2':
try:
blob = jsonutils.loads(ref.get('blob'))
except (ValueError, TypeError):
raise exception.ValidationError(
message=_('Invalid blob in credential'))
if not blob or not isinstance(blob, dict):
raise exception.ValidationError(attribute='blob',
target='credential')
if blob.get('access') is None:
raise exception.ValidationError(attribute='access',
target='blob')
ret_ref = ref.copy()
ret_ref['id'] = hashlib.sha256(blob['access']).hexdigest()
# Update the blob with the trust_id, so credentials created
# with a trust scoped token will result in trust scoped
# tokens when authentication via ec2tokens happens
if trust_id is not None:
blob['trust_id'] = trust_id
ret_ref['blob'] = jsonutils.dumps(blob)
return ret_ref
else:
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),
trust_id)
ref = self.credential_api.create_credential(ref['id'], ref)
return CredentialV3.wrap_member(context, ref)
@staticmethod
def _blob_to_json(ref):
# credentials stored via ec2tokens before the fix for #1259584
# need json serializing, as that's the documented API format
blob = ref.get('blob')
if isinstance(blob, dict):
new_ref = ref.copy()
new_ref['blob'] = jsonutils.dumps(blob)
return new_ref
else:
return ref
@controller.filterprotected('user_id')
def list_credentials(self, context, filters):
hints = CredentialV3.build_driver_hints(context, filters)
refs = self.credential_api.list_credentials(hints)
ret_refs = [self._blob_to_json(r) for r in refs]
return CredentialV3.wrap_collection(context, ret_refs,
hints=hints)
@controller.protected()
def get_credential(self, context, credential_id):
ref = self.credential_api.get_credential(credential_id)
ret_ref = self._blob_to_json(ref)
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)
ref = self.credential_api.update_credential(credential_id, credential)
return CredentialV3.wrap_member(context, ref)
@controller.protected()
def delete_credential(self, context, credential_id):
return self.credential_api.delete_credential(credential_id)