aboutsummaryrefslogtreecommitdiffstats
path: root/keystone-moon/keystone/trust
diff options
context:
space:
mode:
Diffstat (limited to 'keystone-moon/keystone/trust')
-rw-r--r--keystone-moon/keystone/trust/__init__.py1
-rw-r--r--keystone-moon/keystone/trust/backends/sql.py78
-rw-r--r--keystone-moon/keystone/trust/controllers.py42
-rw-r--r--keystone-moon/keystone/trust/core.py29
4 files changed, 70 insertions, 80 deletions
diff --git a/keystone-moon/keystone/trust/__init__.py b/keystone-moon/keystone/trust/__init__.py
index e5ee61fb..bd7297ea 100644
--- a/keystone-moon/keystone/trust/__init__.py
+++ b/keystone-moon/keystone/trust/__init__.py
@@ -14,4 +14,3 @@
from keystone.trust import controllers # noqa
from keystone.trust.core import * # noqa
-from keystone.trust import routers # noqa
diff --git a/keystone-moon/keystone/trust/backends/sql.py b/keystone-moon/keystone/trust/backends/sql.py
index a017056b..cb8446b3 100644
--- a/keystone-moon/keystone/trust/backends/sql.py
+++ b/keystone-moon/keystone/trust/backends/sql.py
@@ -14,7 +14,6 @@
import time
-from oslo_log import log
from oslo_utils import timeutils
from six.moves import range
@@ -23,7 +22,6 @@ from keystone import exception
from keystone import trust
-LOG = log.getLogger(__name__)
# The maximum number of iterations that will be attempted for optimistic
# locking on consuming a limited-use trust.
MAXIMUM_CONSUME_ATTEMPTS = 10
@@ -45,6 +43,10 @@ class TrustModel(sql.ModelBase, sql.DictBase):
expires_at = sql.Column(sql.DateTime)
remaining_uses = sql.Column(sql.Integer, nullable=True)
extra = sql.Column(sql.JsonBlob())
+ __table_args__ = (sql.UniqueConstraint(
+ 'trustor_user_id', 'trustee_user_id', 'project_id',
+ 'impersonation', 'expires_at',
+ name='duplicate_trust_constraint'),)
class TrustRole(sql.ModelBase):
@@ -57,7 +59,7 @@ class TrustRole(sql.ModelBase):
class Trust(trust.TrustDriverV8):
@sql.handle_conflicts(conflict_type='trust')
def create_trust(self, trust_id, trust, roles):
- with sql.transaction() as session:
+ with sql.session_for_write() as session:
ref = TrustModel.from_dict(trust)
ref['id'] = trust_id
if ref.get('expires_at') and ref['expires_at'].tzinfo is not None:
@@ -70,9 +72,9 @@ class Trust(trust.TrustDriverV8):
trust_role.role_id = role['id']
added_roles.append({'id': role['id']})
session.add(trust_role)
- trust_dict = ref.to_dict()
- trust_dict['roles'] = added_roles
- return trust_dict
+ trust_dict = ref.to_dict()
+ trust_dict['roles'] = added_roles
+ return trust_dict
def _add_roles(self, trust_id, session, trust_dict):
roles = []
@@ -84,7 +86,7 @@ class Trust(trust.TrustDriverV8):
def consume_use(self, trust_id):
for attempt in range(MAXIMUM_CONSUME_ATTEMPTS):
- with sql.transaction() as session:
+ with sql.session_for_write() as session:
try:
query_result = (session.query(TrustModel.remaining_uses).
filter_by(id=trust_id).
@@ -130,51 +132,51 @@ class Trust(trust.TrustDriverV8):
raise exception.TrustConsumeMaximumAttempt(trust_id=trust_id)
def get_trust(self, trust_id, deleted=False):
- session = sql.get_session()
- query = session.query(TrustModel).filter_by(id=trust_id)
- if not deleted:
- query = query.filter_by(deleted_at=None)
- ref = query.first()
- if ref is None:
- raise exception.TrustNotFound(trust_id=trust_id)
- if ref.expires_at is not None and not deleted:
- now = timeutils.utcnow()
- if now > ref.expires_at:
+ with sql.session_for_read() as session:
+ query = session.query(TrustModel).filter_by(id=trust_id)
+ if not deleted:
+ query = query.filter_by(deleted_at=None)
+ ref = query.first()
+ if ref is None:
raise exception.TrustNotFound(trust_id=trust_id)
- # Do not return trusts that can't be used anymore
- if ref.remaining_uses is not None and not deleted:
- if ref.remaining_uses <= 0:
- raise exception.TrustNotFound(trust_id=trust_id)
- trust_dict = ref.to_dict()
+ if ref.expires_at is not None and not deleted:
+ now = timeutils.utcnow()
+ if now > ref.expires_at:
+ raise exception.TrustNotFound(trust_id=trust_id)
+ # Do not return trusts that can't be used anymore
+ if ref.remaining_uses is not None and not deleted:
+ if ref.remaining_uses <= 0:
+ raise exception.TrustNotFound(trust_id=trust_id)
+ trust_dict = ref.to_dict()
- self._add_roles(trust_id, session, trust_dict)
- return trust_dict
+ self._add_roles(trust_id, session, trust_dict)
+ return trust_dict
@sql.handle_conflicts(conflict_type='trust')
def list_trusts(self):
- session = sql.get_session()
- trusts = session.query(TrustModel).filter_by(deleted_at=None)
- return [trust_ref.to_dict() for trust_ref in trusts]
+ with sql.session_for_read() as session:
+ trusts = session.query(TrustModel).filter_by(deleted_at=None)
+ return [trust_ref.to_dict() for trust_ref in trusts]
@sql.handle_conflicts(conflict_type='trust')
def list_trusts_for_trustee(self, trustee_user_id):
- session = sql.get_session()
- trusts = (session.query(TrustModel).
- filter_by(deleted_at=None).
- filter_by(trustee_user_id=trustee_user_id))
- return [trust_ref.to_dict() for trust_ref in trusts]
+ with sql.session_for_read() as session:
+ trusts = (session.query(TrustModel).
+ filter_by(deleted_at=None).
+ filter_by(trustee_user_id=trustee_user_id))
+ return [trust_ref.to_dict() for trust_ref in trusts]
@sql.handle_conflicts(conflict_type='trust')
def list_trusts_for_trustor(self, trustor_user_id):
- session = sql.get_session()
- trusts = (session.query(TrustModel).
- filter_by(deleted_at=None).
- filter_by(trustor_user_id=trustor_user_id))
- return [trust_ref.to_dict() for trust_ref in trusts]
+ with sql.session_for_read() as session:
+ trusts = (session.query(TrustModel).
+ filter_by(deleted_at=None).
+ filter_by(trustor_user_id=trustor_user_id))
+ return [trust_ref.to_dict() for trust_ref in trusts]
@sql.handle_conflicts(conflict_type='trust')
def delete_trust(self, trust_id):
- with sql.transaction() as session:
+ with sql.session_for_write() as session:
trust_ref = session.query(TrustModel).get(trust_id)
if not trust_ref:
raise exception.TrustNotFound(trust_id=trust_id)
diff --git a/keystone-moon/keystone/trust/controllers.py b/keystone-moon/keystone/trust/controllers.py
index 39cf0110..00581304 100644
--- a/keystone-moon/keystone/trust/controllers.py
+++ b/keystone-moon/keystone/trust/controllers.py
@@ -14,9 +14,6 @@
import uuid
-from oslo_config import cfg
-from oslo_log import log
-from oslo_log import versionutils
from oslo_utils import timeutils
import six
@@ -31,11 +28,6 @@ from keystone import notifications
from keystone.trust import schema
-CONF = cfg.CONF
-
-LOG = log.getLogger(__name__)
-
-
def _trustor_trustee_only(trust, user_id):
if (user_id != trust.get('trustee_user_id') and
user_id != trust.get('trustor_user_id')):
@@ -47,8 +39,8 @@ def _admin_trustor_only(context, trust, user_id):
raise exception.Forbidden()
-@dependency.requires('assignment_api', 'identity_api', 'role_api',
- 'token_provider_api', 'trust_api')
+@dependency.requires('assignment_api', 'identity_api', 'resource_api',
+ 'role_api', 'token_provider_api', 'trust_api')
class TrustV3(controller.V3Controller):
collection_name = "trusts"
member_name = "trust"
@@ -56,7 +48,6 @@ class TrustV3(controller.V3Controller):
@classmethod
def base_url(cls, context, path=None):
"""Construct a path and pass it to V3Controller.base_url method."""
-
# NOTE(stevemar): Overriding path to /OS-TRUST/trusts so that
# V3Controller.base_url handles setting the self link correctly.
path = '/OS-TRUST/' + cls.collection_name
@@ -113,7 +104,7 @@ class TrustV3(controller.V3Controller):
trust_roles.append({'id':
all_role_names[rolename]['id']})
else:
- raise exception.RoleNotFound("role %s is not defined" %
+ raise exception.RoleNotFound(_("role %s is not defined") %
rolename)
else:
raise exception.ValidationError(attribute='id or name',
@@ -128,7 +119,6 @@ class TrustV3(controller.V3Controller):
The user creating the trust must be the trustor.
"""
-
auth_context = context.get('environment',
{}).get('KEYSTONE_AUTH_CONTEXT', {})
@@ -178,17 +168,27 @@ class TrustV3(controller.V3Controller):
raise exception.Forbidden(
_('At least one role should be specified.'))
- def _get_user_role(self, trust):
+ def _get_trustor_roles(self, trust):
+ original_trust = trust.copy()
+ while original_trust.get('redelegated_trust_id'):
+ original_trust = self.trust_api.get_trust(
+ original_trust['redelegated_trust_id'])
+
if not self._attribute_is_empty(trust, 'project_id'):
- return self.assignment_api.get_roles_for_user_and_project(
- trust['trustor_user_id'], trust['project_id'])
+ self.resource_api.get_project(original_trust['project_id'])
+ # Get a list of roles including any domain specific roles
+ assignment_list = self.assignment_api.list_role_assignments(
+ user_id=original_trust['trustor_user_id'],
+ project_id=original_trust['project_id'],
+ effective=True, strip_domain_roles=False)
+ return list(set([x['role_id'] for x in assignment_list]))
else:
return []
def _require_trustor_has_role_in_project(self, trust):
- user_roles = self._get_user_role(trust)
+ trustor_roles = self._get_trustor_roles(trust)
for trust_role in trust['roles']:
- matching_roles = [x for x in user_roles
+ matching_roles = [x for x in trustor_roles
if x == trust_role['id']]
if not matching_roles:
raise exception.RoleNotFound(role_id=trust_role['id'])
@@ -262,12 +262,6 @@ class TrustV3(controller.V3Controller):
return {'roles': trust['roles'],
'links': trust['roles_links']}
- @versionutils.deprecated(
- versionutils.deprecated.KILO,
- remove_in=+2)
- def check_role_for_trust(self, context, trust_id, role_id):
- return self._check_role_for_trust(self, context, trust_id, role_id)
-
@controller.protected()
def get_role_for_trust(self, context, trust_id, role_id):
"""Get a role that has been assigned to a trust."""
diff --git a/keystone-moon/keystone/trust/core.py b/keystone-moon/keystone/trust/core.py
index 7838cb03..43069deb 100644
--- a/keystone-moon/keystone/trust/core.py
+++ b/keystone-moon/keystone/trust/core.py
@@ -17,7 +17,6 @@
import abc
from oslo_config import cfg
-from oslo_log import log
import six
from six.moves import zip
@@ -30,8 +29,6 @@ from keystone import notifications
CONF = cfg.CONF
-LOG = log.getLogger(__name__)
-
@dependency.requires('identity_api')
@dependency.provider('trust_api')
@@ -93,14 +90,9 @@ class Manager(manager.Manager):
def get_trust_pedigree(self, trust_id):
trust = self.driver.get_trust(trust_id)
trust_chain = [trust]
- if trust and trust.get('redelegated_trust_id'):
- trusts = self.driver.list_trusts_for_trustor(
- trust['trustor_user_id'])
- while trust_chain[-1].get('redelegated_trust_id'):
- for t in trusts:
- if t['id'] == trust_chain[-1]['redelegated_trust_id']:
- trust_chain.append(t)
- break
+ while trust and trust.get('redelegated_trust_id'):
+ trust = self.driver.get_trust(trust['redelegated_trust_id'])
+ trust_chain.append(trust)
return trust_chain
@@ -179,7 +171,7 @@ class Manager(manager.Manager):
def delete_trust(self, trust_id, initiator=None):
"""Remove a trust.
- :raises: keystone.exception.TrustNotFound
+ :raises keystone.exception.TrustNotFound: If the trust doesn't exist.
Recursively remove given and redelegated trusts
"""
@@ -192,7 +184,7 @@ class Manager(manager.Manager):
# recursive call to make sure all notifications are sent
try:
self.delete_trust(t['id'])
- except exception.TrustNotFound:
+ except exception.TrustNotFound: # nosec
# if trust was deleted by concurrent process
# consistency must not suffer
pass
@@ -244,11 +236,14 @@ class TrustDriverV8(object):
@abc.abstractmethod
def consume_use(self, trust_id):
- """Consume one use when a trust was created with a limitation on its
- uses, provided there are still uses available.
+ """Consume one use of a trust.
+
+ One use of a trust is consumed when the trust was created with a
+ limitation on its uses, provided there are still uses available.
- :raises: keystone.exception.TrustUseLimitReached,
- keystone.exception.TrustNotFound
+ :raises keystone.exception.TrustUseLimitReached: If no remaining uses
+ for trust.
+ :raises keystone.exception.TrustNotFound: If the trust doesn't exist.
"""
raise exception.NotImplemented() # pragma: no cover