engine: allow stack_user_project users to retrieve stack

The current DB scoping (and service.py check) enforces retrieval of
stacks only when they match the request context project/tenant, but
with stack_user_project_id we must make an exception, since these
users will require access to the stack for a subset of operations,
which ones will be enforced via policy.json (not the engine)

Change-Id: I82bee14ae96e30653702b4bdb104a2b74cc20cd4
blueprint: instance-users
This commit is contained in:
Steven Hardy 2014-02-05 15:29:16 +00:00
parent 1fc688c0b2
commit fef832fb2a
3 changed files with 18 additions and 5 deletions

View File

@ -269,8 +269,11 @@ def stack_get(context, stack_id, show_deleted=False, tenant_safe=True):
if result is None or result.deleted_at is not None and not deleted_ok:
return None
# One exception to normal project scoping is users created by the
# stacks in the stack_user_project_id (in the heat stack user domain)
if (tenant_safe and result is not None and context is not None and
result.tenant != context.tenant_id):
context.tenant_id not in (result.tenant,
result.stack_user_project_id)):
return None
return result

View File

@ -263,16 +263,17 @@ class EngineService(service.Service):
def _get_stack(self, cnxt, stack_identity, show_deleted=False):
identity = identifier.HeatIdentifier(**stack_identity)
if identity.tenant != cnxt.tenant_id:
raise exception.InvalidTenant(target=identity.tenant,
actual=cnxt.tenant_id)
s = db_api.stack_get(cnxt, identity.stack_id,
show_deleted=show_deleted)
if s is None:
raise exception.StackNotFound(stack_name=identity.stack_name)
if cnxt.tenant_id not in (identity.tenant, s.stack_user_project_id):
# The DB API should not allow this, but sanity-check anyway..
raise exception.InvalidTenant(target=identity.tenant,
actual=cnxt.tenant_id)
if identity.path or s.name != identity.stack_name:
raise exception.StackNotFound(stack_name=identity.stack_name)

View File

@ -1001,6 +1001,15 @@ class DBAPIStackTest(HeatTestCase):
stack = db_api.stack_get(self.ctx, UUID1, show_deleted=False)
self.assertIsNone(stack)
def test_stack_get_tenant_is_stack_user_project_id(self):
stack = create_stack(self.ctx, self.template, self.user_creds,
stack_user_project_id='astackuserproject')
self.ctx.tenant_id = 'astackuserproject'
ret_stack = db_api.stack_get(self.ctx, stack.id, show_deleted=False)
self.assertIsNotNone(ret_stack)
self.assertEqual(stack.id, ret_stack.id)
self.assertEqual('db_test_stack_name', ret_stack.name)
def test_stack_get_can_return_a_stack_from_different_tenant(self):
stack = create_stack(self.ctx, self.template, self.user_creds)
self.ctx.tenant_id = 'abc'