"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "keystone/api/credentials.py" between
keystone-16.0.0.tar.gz and keystone-16.0.1.tar.gz

About: OpenStack Keystone (Core Service: Identity) provides an authentication and authorization service for other OpenStack services. Provides a catalog of endpoints for all OpenStack services.
The "Train" series (latest release).

credentials.py  (keystone-16.0.0):credentials.py  (keystone-16.0.1)
skipping to change at line 16 skipping to change at line 16
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
# This file handles all flask-restful resources for /v3/credentials # This file handles all flask-restful resources for /v3/credentials
import hashlib import hashlib
import six
import flask import flask
from oslo_serialization import jsonutils from oslo_serialization import jsonutils
from six.moves import http_client from six.moves import http_client
from keystone.common import provider_api from keystone.common import provider_api
from keystone.common import rbac_enforcer from keystone.common import rbac_enforcer
from keystone.common import validation from keystone.common import validation
import keystone.conf import keystone.conf
from keystone.credential import schema from keystone.credential import schema
skipping to change at line 61 skipping to change at line 62
@staticmethod @staticmethod
def _blob_to_json(ref): def _blob_to_json(ref):
# credentials stored via ec2tokens before the fix for #1259584 # credentials stored via ec2tokens before the fix for #1259584
# need json_serailzing, as that's the documented API format # need json_serailzing, as that's the documented API format
blob = ref.get('blob') blob = ref.get('blob')
if isinstance(blob, dict): if isinstance(blob, dict):
ref = ref.copy() ref = ref.copy()
ref['blob'] = jsonutils.dumps(blob) ref['blob'] = jsonutils.dumps(blob)
return ref return ref
def _assign_unique_id(self, ref, trust_id=None): def _validate_blob_json(self, ref):
try:
blob = jsonutils.loads(ref.get('blob'))
except (ValueError, TabError):
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='credential')
return blob
def _assign_unique_id(
self, ref, trust_id=None, app_cred_id=None, access_token_id=None):
# Generates an assigns a unique identifier to a credential reference. # Generates an assigns a unique identifier to a credential reference.
if ref.get('type', '').lower() == 'ec2': if ref.get('type', '').lower() == 'ec2':
try: blob = self._validate_blob_json(ref)
blob = jsonutils.loads(ref.get('blob'))
except (ValueError, TabError):
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='credential')
ref = ref.copy() ref = ref.copy()
ref['id'] = hashlib.sha256( ref['id'] = hashlib.sha256(
blob['access'].encode('utf8')).hexdigest() blob['access'].encode('utf8')).hexdigest()
# update the blob with the trust_id, so credentials created with # update the blob with the trust_id or app_cred_id, so credentials
# a trust scoped token will result in trust scoped tokens when # created with a trust- or app cred-scoped token will result in
# authentication via ec2tokens happens # trust- or app cred-scoped tokens when authentication via
# ec2tokens happens
if trust_id is not None: if trust_id is not None:
blob['trust_id'] = trust_id blob['trust_id'] = trust_id
ref['blob'] = jsonutils.dumps(blob) ref['blob'] = jsonutils.dumps(blob)
if app_cred_id is not None:
blob['app_cred_id'] = app_cred_id
ref['blob'] = jsonutils.dumps(blob)
if access_token_id is not None:
blob['access_token_id'] = access_token_id
ref['blob'] = jsonutils.dumps(blob)
return ref return ref
else: else:
return super(CredentialResource, self)._assign_unique_id(ref) return super(CredentialResource, self)._assign_unique_id(ref)
def _list_credentials(self): def _list_credentials(self):
filters = ['user_id', 'type'] filters = ['user_id', 'type']
if not self.oslo_context.system_scope: if not self.oslo_context.system_scope:
target = {'credential': {'user_id': self.oslo_context.user_id}} target = {'credential': {'user_id': self.oslo_context.user_id}}
else: else:
target = None target = None
ENFORCER.enforce_call(action='identity:list_credentials', ENFORCER.enforce_call(action='identity:list_credentials',
filters=filters, target_attr=target) filters=filters, target_attr=target)
hints = self.build_driver_hints(filters) hints = self.build_driver_hints(filters)
refs = PROVIDERS.credential_api.list_credentials(hints) refs = PROVIDERS.credential_api.list_credentials(hints)
# If the request was filtered, make sure to return only the # If the request was filtered, make sure to return only the
# credentials specific to that user. This makes it so that users with # credentials specific to that user. This makes it so that users with
# roles on projects can't see credentials that aren't theirs. # roles on projects can't see credentials that aren't theirs.
if (not self.oslo_context.system_scope and filtered_refs = []
CONF.oslo_policy.enforce_scope): for ref in refs:
filtered_refs = [] # Check each credential again to make sure the user has access to
for ref in refs: # it, either by owning it, being a project admin with
if ref['user_id'] == target['credential']['user_id']: # enforce_scope=false, being a system user, or having some other
filtered_refs.append(ref) # custom policy that allows access.
refs = filtered_refs try:
cred = PROVIDERS.credential_api.get_credential(ref['id'])
ENFORCER.enforce_call(
action='identity:get_credential',
target_attr={'credential': cred}
)
filtered_refs.append(ref)
except exception.Forbidden:
pass
refs = filtered_refs
refs = [self._blob_to_json(r) for r in refs] refs = [self._blob_to_json(r) for r in refs]
return self.wrap_collection(refs, hints=hints) return self.wrap_collection(refs, hints=hints)
def _get_credential(self, credential_id): def _get_credential(self, credential_id):
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:get_credential', action='identity:get_credential',
build_target=_build_target_enforcement build_target=_build_target_enforcement
) )
credential = PROVIDERS.credential_api.get_credential(credential_id) credential = PROVIDERS.credential_api.get_credential(credential_id)
return self.wrap_member(self._blob_to_json(credential)) return self.wrap_member(self._blob_to_json(credential))
skipping to change at line 138 skipping to change at line 159
def post(self): def post(self):
# Create a new credential # Create a new credential
credential = self.request_body_json.get('credential', {}) credential = self.request_body_json.get('credential', {})
target = {} target = {}
target['credential'] = credential target['credential'] = credential
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:create_credential', target_attr=target action='identity:create_credential', target_attr=target
) )
validation.lazy_validate(schema.credential_create, credential) validation.lazy_validate(schema.credential_create, credential)
trust_id = getattr(self.oslo_context, 'trust_id', None) trust_id = getattr(self.oslo_context, 'trust_id', None)
app_cred_id = getattr(
self.auth_context['token'], 'application_credential_id', None)
access_token_id = getattr(
self.auth_context['token'], 'access_token_id', None)
ref = self._assign_unique_id( ref = self._assign_unique_id(
self._normalize_dict(credential), trust_id=trust_id) self._normalize_dict(credential),
ref = PROVIDERS.credential_api.create_credential(ref['id'], ref, trust_id=trust_id, app_cred_id=app_cred_id,
initiator=self.audit_in access_token_id=access_token_id)
itiator) ref = PROVIDERS.credential_api.create_credential(
ref['id'], ref, initiator=self.audit_initiator)
return self.wrap_member(ref), http_client.CREATED return self.wrap_member(ref), http_client.CREATED
def _validate_blob_update_keys(self, credential, ref):
if credential.get('type', '').lower() == 'ec2':
new_blob = self._validate_blob_json(ref)
old_blob = credential.get('blob')
if isinstance(old_blob, six.string_types):
old_blob = jsonutils.loads(old_blob)
# if there was a scope set, prevent changing it or unsetting it
for key in ['trust_id', 'app_cred_id', 'access_token_id']:
if old_blob.get(key) != new_blob.get(key):
message = _('%s can not be updated for credential') % key
raise exception.ValidationError(message=message)
def patch(self, credential_id): def patch(self, credential_id):
# Update Credential # Update Credential
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:update_credential', action='identity:update_credential',
build_target=_build_target_enforcement build_target=_build_target_enforcement
) )
PROVIDERS.credential_api.get_credential(credential_id) current = PROVIDERS.credential_api.get_credential(credential_id)
credential = self.request_body_json.get('credential', {}) credential = self.request_body_json.get('credential', {})
validation.lazy_validate(schema.credential_update, credential) validation.lazy_validate(schema.credential_update, credential)
self._validate_blob_update_keys(current.copy(), credential.copy())
self._require_matching_id(credential) self._require_matching_id(credential)
# Check that the user hasn't illegally modified the owner or scope
target = {'credential': dict(current, **credential)}
ENFORCER.enforce_call(
action='identity:update_credential', target_attr=target
)
ref = PROVIDERS.credential_api.update_credential( ref = PROVIDERS.credential_api.update_credential(
credential_id, credential) credential_id, credential)
return self.wrap_member(ref) return self.wrap_member(ref)
def delete(self, credential_id): def delete(self, credential_id):
# Delete credentials # Delete credentials
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:delete_credential', action='identity:delete_credential',
build_target=_build_target_enforcement build_target=_build_target_enforcement
) )
 End of changes. 12 change blocks. 
28 lines changed or deleted 72 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)