Test project users against system assignment API

This commit ensures that project users are not able to operate on
system role assignments in anyway since they lack the proper
authorization to do so.

Change-Id: I8b5add170ba0d9eec42f2d088f4b89aa801136df
Related-Bug: 1805368
Related-Bug: 1750669
Related-Bug: 1806762
(cherry picked from commit fac844c4ae)
This commit is contained in:
Lance Bragstad 2019-03-20 21:58:51 +00:00 committed by Colleen Murphy
parent 4ccb4c258f
commit de083009eb
2 changed files with 197 additions and 0 deletions

View File

@ -12,14 +12,17 @@
import uuid
from oslo_serialization import jsonutils
from six.moves import http_client
from keystone.common.policies import base
from keystone.common import provider_api
import keystone.conf
from keystone.tests.common import auth as common_auth
from keystone.tests import unit
from keystone.tests.unit import base_classes
from keystone.tests.unit import ksfixtures
from keystone.tests.unit.ksfixtures import temporaryfile
CONF = keystone.conf.CONF
PROVIDERS = provider_api.ProviderAPIs
@ -325,3 +328,157 @@ class DomainUserTests(base_classes.TestCaseWithBootstrap,
r = c.post('/v3/auth/tokens', json=auth)
self.token_id = r.headers['X-Subject-Token']
self.headers = {'X-Auth-Token': self.token_id}
class ProjectReaderTests(base_classes.TestCaseWithBootstrap,
common_auth.AuthTestMixin,
_DomainAndProjectUserSystemAssignmentTests):
def setUp(self):
super(ProjectReaderTests, self).setUp()
self.loadapp()
self.useFixture(ksfixtures.Policy(self.config_fixture))
self.config_fixture.config(group='oslo_policy', enforce_scope=True)
domain = PROVIDERS.resource_api.create_domain(
uuid.uuid4().hex, unit.new_domain_ref()
)
self.domain_id = domain['id']
project_reader = unit.new_user_ref(domain_id=self.domain_id)
project_reader_id = PROVIDERS.identity_api.create_user(
project_reader
)['id']
project = unit.new_project_ref(domain_id=self.domain_id)
project_id = PROVIDERS.resource_api.create_project(
project['id'], project
)['id']
PROVIDERS.assignment_api.create_grant(
self.bootstrapper.reader_role_id, user_id=project_reader_id,
project_id=project_id
)
auth = self.build_authentication_request(
user_id=project_reader_id,
password=project_reader['password'],
project_id=project_id
)
# Grab a token using the persona we're testing and prepare headers
# for requests we'll be making in the tests.
with self.test_client() as c:
r = c.post('/v3/auth/tokens', json=auth)
self.token_id = r.headers['X-Subject-Token']
self.headers = {'X-Auth-Token': self.token_id}
class ProjectMemberTests(base_classes.TestCaseWithBootstrap,
common_auth.AuthTestMixin,
_DomainAndProjectUserSystemAssignmentTests):
def setUp(self):
super(ProjectMemberTests, self).setUp()
self.loadapp()
self.useFixture(ksfixtures.Policy(self.config_fixture))
self.config_fixture.config(group='oslo_policy', enforce_scope=True)
domain = PROVIDERS.resource_api.create_domain(
uuid.uuid4().hex, unit.new_domain_ref()
)
self.domain_id = domain['id']
project_member = unit.new_user_ref(domain_id=self.domain_id)
project_member_id = PROVIDERS.identity_api.create_user(
project_member
)['id']
project = unit.new_project_ref(domain_id=self.domain_id)
project_id = PROVIDERS.resource_api.create_project(
project['id'], project
)['id']
PROVIDERS.assignment_api.create_grant(
self.bootstrapper.member_role_id, user_id=project_member_id,
project_id=project_id
)
auth = self.build_authentication_request(
user_id=project_member_id,
password=project_member['password'],
project_id=project_id
)
# Grab a token using the persona we're testing and prepare headers
# for requests we'll be making in the tests.
with self.test_client() as c:
r = c.post('/v3/auth/tokens', json=auth)
self.token_id = r.headers['X-Subject-Token']
self.headers = {'X-Auth-Token': self.token_id}
class ProjectAdminTests(base_classes.TestCaseWithBootstrap,
common_auth.AuthTestMixin,
_DomainAndProjectUserSystemAssignmentTests):
def setUp(self):
super(ProjectAdminTests, self).setUp()
self.loadapp()
self.policy_file = self.useFixture(temporaryfile.SecureTempFile())
self.policy_file_name = self.policy_file.file_name
self.useFixture(
ksfixtures.Policy(
self.config_fixture, policy_file=self.policy_file_name
)
)
self._override_policy()
self.config_fixture.config(group='oslo_policy', enforce_scope=True)
domain = PROVIDERS.resource_api.create_domain(
uuid.uuid4().hex, unit.new_domain_ref()
)
self.domain_id = domain['id']
project_admin = unit.new_user_ref(domain_id=self.domain_id)
project_admin_id = PROVIDERS.identity_api.create_user(
project_admin
)['id']
project = unit.new_project_ref(domain_id=self.domain_id)
project_id = PROVIDERS.resource_api.create_project(
project['id'], project
)['id']
PROVIDERS.assignment_api.create_grant(
self.bootstrapper.admin_role_id, user_id=project_admin_id,
project_id=project_id
)
auth = self.build_authentication_request(
user_id=project_admin_id,
password=project_admin['password'],
project_id=project_id
)
# Grab a token using the persona we're testing and prepare headers
# for requests we'll be making in the tests.
with self.test_client() as c:
r = c.post('/v3/auth/tokens', json=auth)
self.token_id = r.headers['X-Subject-Token']
self.headers = {'X-Auth-Token': self.token_id}
def _override_policy(self):
# TODO(lbragstad): Remove this once the deprecated policies in
# keystone.common.policies.grants have been removed. This is only
# here to make sure we test the new policies instead of the deprecated
# ones. Oslo.policy will OR deprecated policies with new policies to
# maintain compatibility and give operators a chance to update
# permissions or update policies without breaking users. This will
# cause these specific tests to fail since we're trying to correct this
# broken behavior with better scope checking.
with open(self.policy_file_name, 'w') as f:
overridden_policies = {
'identity:check_system_grant_for_user': base.SYSTEM_READER,
'identity:list_system_grants_for_user': base.SYSTEM_READER,
'identity:create_system_grant_for_user': base.SYSTEM_ADMIN,
'identity:revoke_system_grant_for_user': base.SYSTEM_ADMIN
}
f.write(jsonutils.dumps(overridden_policies))

View File

@ -0,0 +1,40 @@
---
features:
- |
[`bug 1805368 <https://bugs.launchpad.net/keystone/+bug/1805368>`_]
[`bug 1750669 <https://bugs.launchpad.net/keystone/+bug/1750669>`_]
The system assignment API now supports the ``admin``, ``member``,
and ``reader`` default roles across system-scope, domain-scope,
and project-scope.
upgrade:
- |
[`bug 1805368 <https://bugs.launchpad.net/keystone/+bug/1805368>`_]
[`bug 1750669 <https://bugs.launchpad.net/keystone/+bug/1750669>`_]
The system assignment API uses new default policies that make it more
accessible to end users and administrators in a secure way. Please
consider these new defaults if your deployment overrides system
assignment policies.
deprecations:
- |
[`bug 1805368 <https://bugs.launchpad.net/keystone/+bug/1805368>`_]
[`bug 1750669 <https://bugs.launchpad.net/keystone/+bug/1750669>`_]
The system assignment policies have been deprecated. The
``identity:list_system_grants_for_user`` and
``identity:check_system_grant_for_user`` policies now use
``role:reader and system_scope:all`` instead of
``rule:admin_required``. The
``identity:create_system_grant_for_user`` and
``identity:revoke_system_grant_for_user`` policies now use
``role:admin and system_scope:all`` instead of
``rule:admin_required``. These new defaults automatically include
support for a read-only role and allow for more granular access to
the system assignment API, making it easier for administrators to
delegate authorization, safely. Please consider these new defaults
if your deployment overrides the system assignment APIs.
security:
- |
[`bug 1805368 <https://bugs.launchpad.net/keystone/+bug/1805368>`_]
[`bug 1750669 <https://bugs.launchpad.net/keystone/+bug/1750669>`_]
The system assignment API now uses system-scope, domain-scope,
project-scope, and default roles to provide better accessibility
to users in a secure way.