Add RBAC tests

This change leverages the nine default personas available in tempest[1]
to demonstrate a potential framework for testing default policies. An
abstract base class is created that helps set up credentials and
outlines every policy that needs to be tested, then nine subclasses are
created to test every persona. Each test represents one policy rule, and
some tests make multiple requests in order to test the policy from
different approaches, for example, to check what happens if a different
domain is specified, or what happens if the resource does not exist.

The idea here is to be very verbose and explicit about what is being
tested: every policy gets one test in the base class, and each persona
is tested in a subclass. The layout should be easy to understand and
someone reading the code should not be left guessing whether a case is
missing or if there is magic happening in the background that is causing
a false positive or false negative.

This is intended to replace the unittest protection tests currently
in place.

[1] https://review.opendev.org/686306 (this will require additional
devstack and keystone configuration to work properly in CI)

Depends-on: https://review.opendev.org/686306
Depends-on: https://review.opendev.org/699051
Depends-on: https://review.opendev.org/699519
Depends-on: https://review.opendev.org/700826
Depends-on: https://review.opendev.org/743853
Depends-on: https://review.opendev.org/744087
Depends-on: https://review.opendev.org/744268
Depends-on: https://review.opendev.org/731087

Change-Id: Icb5317b9297230490bd783fe9b07c8db244c06f8
This commit is contained in:
Colleen Murphy 2019-12-23 13:56:27 -08:00 committed by Lance Bragstad
parent 2473e5bdba
commit a6d4ceaf57
37 changed files with 16024 additions and 4 deletions

View File

@ -1,3 +1,39 @@
- job:
name: keystone-protection-functional
parent: keystone-dsvm-py3-functional
vars:
tempest_test_regex: 'keystone_tempest_plugin.tests.rbac'
devstack_localrc:
KEYSTONE_ENFORCE_SCOPE: True
devstack_plugins:
keystone: https://opendev.org/openstack/keystone
devstack_services:
g-api: false
g-reg: false
n-api: false
n-api-meta: false
n-cond: false
n-cpu: false
n-novnc: false
n-sch: false
placement-api: false
q-agt: false
q-dhcp: false
q-l3: false
q-meta: false
q-metering: false
s-account: false
s-container: false
s-object: false
s-proxy: false
c-api: false
c-bak: false
c-sch: false
c-vol: false
cinder: false
devstack_local_conf:
post-config: {}
- project:
templates:
- check-requirements
@ -11,10 +47,12 @@
- keystone-dsvm-py3-functional-ussuri
- keystone-dsvm-py3-functional-train
- keystone-dsvm-py3-functional-stein
- keystone-protection-functional
gate:
jobs:
- keystone-dsvm-py3-functional
- keystone-dsvm-py3-functional-federation-ubuntu-focal-k2k
- keystone-protection-functional
- job:
name: keystone-dsvm-py3-functional-ussuri

View File

@ -15,7 +15,7 @@
from oslo_config import cfg
identity_feature_option = [
identity_feature_options = [
cfg.BoolOpt('federation',
default=False,
help='Does the environment support the Federated Identity '
@ -25,6 +25,10 @@ identity_feature_option = [
help='Whether to test federated scenarios against an external '
'identity provider. If disabled, only '
'Keystone-to-Keystone tests will be enabled.'),
cfg.BoolOpt('enforce_scope',
default=False,
help='Does the keystone service enforce scope and use '
'scope-aware policies?'),
]
fed_scenario_group = cfg.OptGroup(name='fed_scenario',

View File

@ -32,12 +32,12 @@ class KeystoneTempestPlugin(plugins.TempestPlugin):
def register_opts(self, conf):
config.register_opt_group(conf, config.identity_feature_group,
project_config.identity_feature_option)
project_config.identity_feature_options)
config.register_opt_group(conf, project_config.fed_scenario_group,
project_config.FedScenarioGroup)
def get_opt_lists(self):
return [(config.identity_feature_group.name,
project_config.identity_feature_option),
project_config.identity_feature_options),
(project_config.fed_scenario_group.name,
project_config.FedScenarioGroup)]

View File

@ -0,0 +1,41 @@
# Copyright 2020 SUSE LLC
#
# 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.
from tempest import config
CONF = config.CONF
class IdentityV3RbacBaseTests(object):
identity_version = 'v3'
@classmethod
def skip_checks(cls):
super(IdentityV3RbacBaseTests, cls).skip_checks()
if not CONF.identity_feature_enabled.enforce_scope:
raise cls.skipException("enforce_scope is not enabled for "
"keystone, skipping RBAC tests")
def do_request(self, method, expected_status=200, client=None, **payload):
if not client:
client = self.client
if isinstance(expected_status, type(Exception)):
self.assertRaises(expected_status,
getattr(client, method),
**payload)
else:
response = getattr(client, method)(**payload)
self.assertEqual(response.response.status, expected_status)
return response

View File

@ -0,0 +1,487 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest import clients
from tempest.lib import auth
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacAccessRuleTest(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
identity_version = 'v3'
@classmethod
def setup_clients(cls):
super(IdentityV3RbacAccessRuleTest, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.access_rules_client
cls.admin_client = cls.os_system_admin
def user(self):
user = {}
name = data_utils.rand_name('user')
user['name'] = name
user['password'] = data_utils.rand_password()
return user
def app_cred(self):
app_cred = {}
app_cred['name'] = data_utils.rand_name('app_cred')
app_cred['access_rules'] = [
{
'path': '/servers',
'method': 'GET',
'service': 'compute',
}
]
return app_cred
@classmethod
def setup_user_client(cls, domain_id=None):
"""Set up project user with its own client.
This is to enable the project user to create its own app cred.
Returns a client object and the user's ID.
"""
user_dict = {
'name': data_utils.rand_name('user'),
'password': data_utils.rand_password(),
}
if domain_id:
user_dict['domain_id'] = domain_id
user_id = cls.admin_client.users_v3_client.create_user(
**user_dict)['user']['id']
def try_delete_user():
# delete user if not deleted by domain deletion
try:
cls.admin_client.users_v3_client.delete_user(user_id)
except exceptions.NotFound:
pass
cls.addClassResourceCleanup(try_delete_user)
project_id = cls.admin_client.projects_client.create_project(
data_utils.rand_name())['project']['id']
cls.addClassResourceCleanup(
cls.admin_client.projects_client.delete_project, project_id)
member_role_id = cls.admin_client.roles_v3_client.list_roles(
name='member')['roles'][0]['id']
cls.admin_client.roles_v3_client.create_user_role_on_project(
project_id, user_id, member_role_id)
creds = auth.KeystoneV3Credentials(
user_id=user_id,
password=user_dict['password'],
project_id=project_id)
auth_provider = clients.get_auth_provider(creds)
creds = auth_provider.fill_credentials()
client = clients.Manager(credentials=creds)
return client, user_id
@abc.abstractmethod
def test_identity_get_access_rule(self):
"""Test identity:get_access_rule policy
This test must check:
* whether the persona can retrieve an access rule they own
* whether the persona can retrieve an access rule they do not own
* whether the persona can retrieve an access rule that does not exist
* whether the persona can retrieve an access rule for a user in their
own domain (if applicable)
* whether the persona can retrieve an access rule for a user in
another domain (if applicable)
"""
pass
@abc.abstractmethod
def test_identity_list_access_rules(self):
"""Test identity:list_access_rules policy
This test must check:
* whether the persona can list their own access rules
* whether the persona can list the access rules for another user
* whether the persona can list the access rules for a user in their
own domain
* whether the persona can list the access rules for a user in another
domain
"""
pass
@abc.abstractmethod
def test_identity_delete_access_rule(self):
"""Test identity:delete_access_rule policy.
This test must check
* whether the persona can delete an access rule they own
* whether the persona can delete an access rule for an arbitrary user
* whether the persona can delete an access rule that does not exist
* whether the persona can delete an access rule for a user in another
domain (if applicable)
* whether the persona can delete an access rule for a user in their
own domain (if applicable)
* whether the persona can delete an access rule that does not exist
"""
pass
class SystemAdminTests(IdentityV3RbacAccessRuleTest, base.BaseIdentityTest):
credentials = ['system_admin']
@classmethod
def setup_clients(cls):
super(SystemAdminTests, cls).setup_clients()
cls.test_user_client, cls.test_user_id = cls.setup_user_client()
def setUp(self):
# create app cred for other user
super(SystemAdminTests, self).setUp()
app_cred_client = self.test_user_client.application_credentials_client
app_cred = app_cred_client.create_application_credential(
user_id=self.test_user_id, **self.app_cred()
)['application_credential']
self.app_cred_id = app_cred['id']
self.access_rule_id = app_cred['access_rules'][0]['id']
def try_delete_app_cred(id):
app_cred_client = self.admin_client.application_credentials_client
try:
app_cred_client.delete_application_credential(
user_id=self.test_user_id,
application_credential_id=id)
except exceptions.NotFound:
pass
def try_delete_access_rule(id):
try:
self.admin_client.access_rules_client.delete_access_rule(
user_id=self.test_user_id,
access_rule_id=id)
except exceptions.NotFound:
pass
self.addCleanup(try_delete_access_rule, self.access_rule_id)
self.addCleanup(try_delete_app_cred, self.app_cred_id)
def test_identity_get_access_rule(self):
# system admin cannot create app creds and therefore cannot create
# access rules, so skip retrieval of own access rule
# retrieve other user's access rules
self.do_request(
'show_access_rule',
user_id=self.test_user_id, access_rule_id=self.access_rule_id)
# retrieving a non-existent access rule should return a 404
self.do_request(
'show_access_rule', expected_status=exceptions.NotFound,
user_id=self.test_user_id,
access_rule_id=data_utils.rand_uuid_hex())
def test_identity_list_access_rules(self):
# system admin cannot create app creds and therefore cannot create
# access rules, so skip listing of own access rule
# list other user's access rules
self.do_request('list_access_rules', user_id=self.test_user_id)
def test_identity_delete_access_rule(self):
# system admin cannot create app creds and therefore cannot create
# access rules, so skip deletion of own access rule
# delete other user's access rules
app_cred_client = self.admin_client.application_credentials_client
app_cred_client.delete_application_credential(
user_id=self.test_user_id,
application_credential_id=self.app_cred_id)
self.do_request(
'delete_access_rule', expected_status=204,
user_id=self.test_user_id, access_rule_id=self.access_rule_id)
# deleting a non-existent access rule should return a 404
self.do_request(
'delete_access_rule', expected_status=exceptions.NotFound,
user_id=self.test_user_id,
access_rule_id=data_utils.rand_uuid_hex())
class SystemMemberTests(SystemAdminTests):
credentials = ['system_member', 'system_admin']
def test_identity_delete_access_rule(self):
app_cred_client = self.admin_client.application_credentials_client
app_cred_client.delete_application_credential(
user_id=self.test_user_id,
application_credential_id=self.app_cred_id)
self.do_request(
'delete_access_rule', expected_status=exceptions.Forbidden,
user_id=self.test_user_id, access_rule_id=self.access_rule_id)
# retrieving a non-existent access rule should return a 404
self.do_request(
'show_access_rule', expected_status=exceptions.NotFound,
user_id=self.test_user_id,
access_rule_id=data_utils.rand_uuid_hex())
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(IdentityV3RbacAccessRuleTest, base.BaseIdentityTest):
# Domain admins cannot create their own app creds (app creds can only be
# scoped to projects) and domain admins have no special privileges over the
# app creds own by users in their domains.
credentials = ['domain_admin', 'system_admin']
@classmethod
def setup_clients(cls):
super(DomainAdminTests, cls).setup_clients()
own_domain_id = cls.persona.credentials.domain_id
cls.test_client_1, cls.test_user_1 = cls.setup_user_client(
domain_id=own_domain_id)
def setUp(self):
super(DomainAdminTests, self).setUp()
self.other_domain_id = self.admin_client.domains_client.create_domain(
name=data_utils.rand_name())['domain']['id']
self.addCleanup(self.admin_client.domains_client.delete_domain,
self.other_domain_id)
self.addCleanup(self.admin_client.domains_client.update_domain,
domain_id=self.other_domain_id, enabled=False)
self.test_client_2, self.test_user_2 = self.setup_user_client(
domain_id=self.other_domain_id)
client = self.test_client_1.application_credentials_client
app_cred_1 = client.create_application_credential(
user_id=self.test_user_1, **self.app_cred()
)['application_credential']
self.access_rule_1 = app_cred_1['access_rules'][0]['id']
self.addCleanup(
self.test_client_1.access_rules_client.delete_access_rule,
self.test_user_1,
self.access_rule_1)
self.addCleanup(
client.delete_application_credential,
self.test_user_1,
app_cred_1['id'])
client = self.test_client_2.application_credentials_client
app_cred_2 = client.create_application_credential(
user_id=self.test_user_2, **self.app_cred()
)['application_credential']
self.access_rule_2 = app_cred_2['access_rules'][0]['id']
self.addCleanup(
self.test_client_2.access_rules_client.delete_access_rule,
self.test_user_2,
self.access_rule_2)
self.addCleanup(
client.delete_application_credential,
self.test_user_2,
app_cred_2['id'])
def test_identity_get_access_rule(self):
# accessing access rules should be forbidden no matter whether the
# owner is in the domain or outside of it
# retrieve access rule from user in own domain
self.do_request(
'show_access_rule', expected_status=exceptions.Forbidden,
user_id=self.test_user_1, access_rule_id=self.access_rule_1)
# retrieve access rule from user in other domain
self.do_request(
'show_access_rule', expected_status=exceptions.Forbidden,
user_id=self.test_user_2, access_rule_id=self.access_rule_2)
# retrieving a non-existent access rule should return a 403
self.do_request(
'show_access_rule', expected_status=exceptions.Forbidden,
user_id=self.test_user_1,
access_rule_id=data_utils.rand_uuid_hex())
self.do_request(
'show_access_rule', expected_status=exceptions.Forbidden,
user_id=self.test_user_2,
access_rule_id=data_utils.rand_uuid_hex())
def test_identity_list_access_rules(self):
# listing access rules should be forbidden no matter whether the
# owner is in the domain or outside of it
self.do_request(
'list_access_rules', expected_status=exceptions.Forbidden,
user_id=self.test_user_1)
self.do_request(
'list_access_rules', expected_status=exceptions.Forbidden,
user_id=self.test_user_2)
def test_identity_delete_access_rule(self):
# deleting access rules should be forbidden no matter whether the
# owner is in the domain or outside of it
# delete access rule from user in own domain
self.do_request(
'delete_access_rule', expected_status=exceptions.Forbidden,
user_id=self.test_user_1, access_rule_id=self.access_rule_1)
# delete access rule from user in other domain
self.do_request(
'delete_access_rule', expected_status=exceptions.Forbidden,
user_id=self.test_user_2, access_rule_id=self.access_rule_2)
# deleting a non-existent access rule should return a 403
self.do_request(
'delete_access_rule', expected_status=exceptions.Forbidden,
user_id=self.test_user_1,
access_rule_id=data_utils.rand_uuid_hex())
self.do_request(
'delete_access_rule', expected_status=exceptions.Forbidden,
user_id=self.test_user_2,
access_rule_id=data_utils.rand_uuid_hex())
class DomainMemberTests(DomainAdminTests):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainAdminTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(IdentityV3RbacAccessRuleTest, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
@classmethod
def setup_clients(cls):
super(ProjectAdminTests, cls).setup_clients()
cls.test_user_client, cls.test_user_id = cls.setup_user_client()
def setUp(self):
super(ProjectAdminTests, self).setUp()
app_cred_client = self.persona.application_credentials_client
user_id = self.persona.credentials.user_id
self.app_cred_1 = app_cred_client.create_application_credential(
user_id, **self.app_cred())['application_credential']
self.access_rule_1 = self.app_cred_1['access_rules'][0]['id']
def try_delete_own_app_cred(id):
app_cred_client = self.persona.application_credentials_client
try:
app_cred_client.delete_application_credential(
self.persona.credentials.user_id, id)
except exceptions.NotFound:
pass
def try_delete_own_access_rule(id):
try:
self.persona.access_rules_client.delete_access_rule(
self.persona.credentials.user_id, id)
except exceptions.NotFound:
pass
self.addCleanup(try_delete_own_access_rule, self.access_rule_1)
self.addCleanup(try_delete_own_app_cred, self.app_cred_1['id'])
app_cred_client = self.test_user_client.application_credentials_client
self.app_cred_2 = app_cred_client.create_application_credential(
self.test_user_id, **self.app_cred())['application_credential']
self.access_rule_2 = self.app_cred_2['access_rules'][0]['id']
self.addCleanup(
self.test_user_client.access_rules_client.delete_access_rule,
self.test_user_id, self.access_rule_2)
self.addCleanup(
app_cred_client.delete_application_credential,
self.test_user_id, self.app_cred_2['id'])
def test_identity_get_access_rule(self):
# should be able to access own credential
self.do_request(
'show_access_rule',
user_id=self.persona.credentials.user_id,
access_rule_id=self.access_rule_1)
# retrieving non-existent access rule for self should return 404
self.do_request(
'show_access_rule', expected_status=exceptions.NotFound,
user_id=self.persona.credentials.user_id,
access_rule_id=data_utils.rand_uuid_hex())
# should not be able to access another user's credential
self.do_request(
'show_access_rule', expected_status=exceptions.Forbidden,
user_id=self.test_user_id, access_rule_id=self.access_rule_2)
# retrieving non-existent access rule for other user should return 403
self.do_request(
'show_access_rule', expected_status=exceptions.Forbidden,
user_id=self.test_user_id,
access_rule_id=data_utils.rand_uuid_hex())
def test_identity_list_access_rules(self):
# should be able to list own credentials
self.do_request(
'list_access_rules', user_id=self.persona.credentials.user_id)
# should not be able to list another user's credentials
self.do_request(
'list_access_rules', expected_status=exceptions.Forbidden,
user_id=self.test_user_id)
def test_identity_delete_access_rule(self):
# should be able to delete own credential
app_cred_client = self.persona.application_credentials_client
app_cred_client.delete_application_credential(
user_id=self.persona.credentials.user_id,
application_credential_id=self.app_cred_1['id'])
self.do_request(
'delete_access_rule', expected_status=204,
user_id=self.persona.credentials.user_id,
access_rule_id=self.access_rule_1)
# deleting non-existent access rule for self should return 404
self.do_request(
'delete_access_rule', expected_status=exceptions.NotFound,
user_id=self.persona.credentials.user_id,
access_rule_id=data_utils.rand_uuid_hex())
# should not be able to delete another user's credential
self.do_request(
'delete_access_rule', expected_status=exceptions.Forbidden,
user_id=self.test_user_id, access_rule_id=self.access_rule_2)
# deleting non-existent access rule for other user should return 403
self.do_request(
'delete_access_rule', expected_status=exceptions.Forbidden,
user_id=self.test_user_id,
access_rule_id=data_utils.rand_uuid_hex())
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,551 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest import clients
from tempest.lib import auth
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacApplicationCredentialTest(
rbac_base.IdentityV3RbacBaseTests, metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacApplicationCredentialTest, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.application_credentials_client
cls.admin_client = cls.os_system_admin
@classmethod
def setup_user_client(cls, domain_id=None):
"""Set up project user with its own client.
This is to enable the project user to create its own app cred.
Returns a client object and the user's ID.
"""
user_dict = {
'name': data_utils.rand_name('user'),
'password': data_utils.rand_password(),
}
if domain_id:
user_dict['domain_id'] = domain_id
user_id = cls.admin_client.users_v3_client.create_user(
**user_dict)['user']['id']
def try_cleanup_user():
# if domain is cleaned up first, user will already be deleted
try:
cls.admin_client.users_v3_client.delete_user(user_id)
except exceptions.NotFound:
pass
cls.addClassResourceCleanup(try_cleanup_user)
project_id = cls.admin_client.projects_client.create_project(
data_utils.rand_name())['project']['id']
cls.addClassResourceCleanup(
cls.admin_client.projects_client.delete_project, project_id)
member_role_id = cls.admin_client.roles_v3_client.list_roles(
name='member')['roles'][0]['id']
cls.admin_client.roles_v3_client.create_user_role_on_project(
project_id, user_id, member_role_id)
creds = auth.KeystoneV3Credentials(
user_id=user_id,
password=user_dict['password'],
project_id=project_id)
auth_provider = clients.get_auth_provider(creds)
creds = auth_provider.fill_credentials()
client = clients.Manager(credentials=creds)
return client, user_id
def app_cred(self):
app_cred = {}
app_cred['name'] = data_utils.rand_name('app_cred')
return app_cred
@abc.abstractmethod
def test_identity_create_application_credential(self):
"""Test identity:create_application_credential policy.
This test must check:
* whether the persona can create an application credential for
themself
* whether the persona can create an application credential for
another user
"""
pass
@abc.abstractmethod
def test_identity_get_application_credential(self):
"""Test identity:get_application_credential policy.
This test must check:
* whether the persona can get their own application credential
* whether the persona can get an application credential for another
user
* whether the persona can get an application credential for a user in
another domain (if applicable)
* whether the persona can get an application credential for a user in
their own domain (if applicable)
* whether the persona can get an application credential that does not
exist
"""
pass
@abc.abstractmethod
def test_identity_list_application_credentials(self):
"""Test identity:list_application_credentials policy.
This test must check:
* whether the persona can list all application credentials for
themself
* whether the persona can list all application credentials for
another user
* whether the persona can list application credentials for a user in
their own domain
* whether the persona can list application credentials for a user in
another domain
"""
pass
@abc.abstractmethod
def test_identity_delete_application_credential(self):
"""Test identity:delete_application_credential policy.
This test must check
* whether the persona can delete their own application credential
* whether the persona can delete an application credential for
another user
* whether the persona can delete an application credential for a user
in another domain (if applicable)
* whether the persona can delete an application credential for a user
in their own domain (if applicable)
* whether the persona can delete an application credential that does
not exist
"""
pass
class SystemAdminTests(
IdentityV3RbacApplicationCredentialTest, base.BaseIdentityTest):
credentials = ['system_admin']
@classmethod
def setup_clients(cls):
super(SystemAdminTests, cls).setup_clients()
cls.test_user_client, cls.test_user_id = cls.setup_user_client()
def test_identity_create_application_credential(self):
# Creating an application credential requires a project ID in the
# token, therefore system-scoped users cannot create app creds.
raise self.skipException(
"Skipping identity:create_application_credential test for "
"system user")
def test_identity_get_application_credential(self):
# Creating an application credential requires a project ID in the
# token, therefore system-scoped users cannot create app creds, so skip
# check for showing user's own app creds
# retrieve other user's app cred
user_app_cred_client = \
self.test_user_client.application_credentials_client
app_cred = user_app_cred_client.create_application_credential(
user_id=self.test_user_id, **self.app_cred()
)['application_credential']
self.addCleanup(
user_app_cred_client.delete_application_credential,
self.test_user_id,
app_cred['id'])
self.do_request(
'show_application_credential',
user_id=self.test_user_id,
application_credential_id=app_cred['id'])
# retrieve app cred that does not exist
self.do_request(
'show_application_credential',
expected_status=exceptions.NotFound,
user_id=self.test_user_id,
application_credential_id=data_utils.rand_uuid_hex())
def test_identity_list_application_credentials(self):
# Creating an application credential requires a project ID in the
# token, therefore system-scoped users cannot create app creds, so skip
# check for listing user's own app creds
# list other user's app creds
user_app_cred_client = \
self.test_user_client.application_credentials_client
app_cred = user_app_cred_client.create_application_credential(
user_id=self.test_user_id, **self.app_cred()
)['application_credential']
self.addCleanup(
user_app_cred_client.delete_application_credential,
self.test_user_id,
app_cred['id'])
resp = self.do_request(
'list_application_credentials',
user_id=self.test_user_id)
self.assertEqual(
resp['application_credentials'][0]['id'],
app_cred['id'])
def test_identity_delete_application_credential(self):
# Creating an application credential requires a project ID in the
# token, therefore system-scoped users cannot create app creds, so skip
# check for deleting user's own app creds
# delete other user's app cred
user_app_cred_client = \
self.test_user_client.application_credentials_client
app_cred = user_app_cred_client.create_application_credential(
user_id=self.test_user_id, **self.app_cred()
)['application_credential']
self.do_request(
'delete_application_credential',
expected_status=204,
user_id=self.test_user_id,
application_credential_id=app_cred['id'])
# delete app cred that does not exist
self.do_request(
'delete_application_credential',
expected_status=exceptions.NotFound,
user_id=self.test_user_id,
application_credential_id=data_utils.rand_uuid_hex())
class SystemMemberTests(SystemAdminTests):
credentials = ['system_member', 'system_admin']
def test_identity_delete_application_credential(self):
# Creating an application credential requires a project ID in the
# token, therefore system-scoped users cannot create app creds, so skip
# check for deleting user's own app creds
# delete other user's app cred
user_app_cred_client = \
self.test_user_client.application_credentials_client
app_cred = user_app_cred_client.create_application_credential(
user_id=self.test_user_id, **self.app_cred()
)['application_credential']
self.addCleanup(
user_app_cred_client.delete_application_credential,
self.test_user_id,
app_cred['id'])
self.do_request(
'delete_application_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_id,
application_credential_id=app_cred['id'])
# delete app cred that does not exist
self.do_request(
'delete_application_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_id,
application_credential_id=data_utils.rand_uuid_hex())
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(
IdentityV3RbacApplicationCredentialTest, base.BaseIdentityTest):
# Domain admins cannot create their own app creds (app creds can only be
# scoped to projects) and domain admins have no special privileges over the
# app creds own by users in their domains.
credentials = ['domain_admin', 'system_admin']
@classmethod
def setup_clients(cls):
super(DomainAdminTests, cls).setup_clients()
own_domain_id = cls.persona.credentials.domain_id
cls.test_client_1, cls.test_user_1 = cls.setup_user_client(
domain_id=own_domain_id)
def setUp(self):
super(DomainAdminTests, self).setUp()
self.other_domain_id = self.admin_client.domains_client.create_domain(
name=data_utils.rand_name())['domain']['id']
self.addCleanup(self.admin_client.domains_client.delete_domain,
self.other_domain_id)
self.addCleanup(self.admin_client.domains_client.update_domain,
domain_id=self.other_domain_id, enabled=False)
self.test_client_2, self.test_user_2 = self.setup_user_client(
domain_id=self.other_domain_id)
client = self.test_client_1.application_credentials_client
self.app_cred_1 = client.create_application_credential(
user_id=self.test_user_1, **self.app_cred()
)['application_credential']
self.addCleanup(
client.delete_application_credential,
self.test_user_1,
self.app_cred_1['id'])
client = self.test_client_2.application_credentials_client
self.app_cred_2 = client.create_application_credential(
user_id=self.test_user_2, **self.app_cred()
)['application_credential']
self.addCleanup(
client.delete_application_credential,
self.test_user_2,
self.app_cred_2['id'])
def test_identity_create_application_credential(self):
# Creating an application credential requires a project ID in the
# token, therefore system-scoped users cannot create app creds.
raise self.skipException(
"Skipping identity:create_application_credential test for "
"domain user")
def test_identity_get_application_credential(self):
# Creating an application credential requires a project ID in the
# token, therefore domain-scoped users cannot create app creds, so skip
# check for showing user's own app creds
# accessing application credentials should be forbidden no matter
# whether the owner is in the domain or outside of it
# retrieve app cred from user in own domain
self.do_request(
'show_application_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_1,
application_credential_id=self.app_cred_1['id'])
# retrieve app cred from user in other domain
self.do_request(
'show_application_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_2,
application_credential_id=self.app_cred_2['id'])
# retrieve app cred that does not exist
self.do_request(
'show_application_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_1,
application_credential_id=data_utils.rand_uuid_hex())
def test_identity_list_application_credentials(self):
# Creating an application credential requires a project ID in the
# token, therefore domain-scoped users cannot create app creds, so skip
# check for listing user's own app creds
# listing application credentials should be forbidden no matter
# whether the owner is in the domain or outside of it
# list app creds from user in own domain
self.do_request(
'list_application_credentials',
expected_status=exceptions.Forbidden,
user_id=self.test_user_1)
# list app creds from user in other domain
self.do_request(
'list_application_credentials',
expected_status=exceptions.Forbidden,
user_id=self.test_user_2)
def test_identity_delete_application_credential(self):
# Creating an application credential requires a project ID in the
# token, therefore domain-scoped users cannot create app creds, so skip
# check for deleting user's own app creds
# deleting application credentials should be forbidden no matter
# whether the owner is in the domain or outside of it
# delete app cred from user in own domain
self.do_request(
'delete_application_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_1,
application_credential_id=self.app_cred_1['id'])
# delete app cred from user in other domain
self.do_request(
'delete_application_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_2,
application_credential_id=self.app_cred_2['id'])
# delete app cred that does not exist
self.do_request(
'delete_application_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_1,
application_credential_id=data_utils.rand_uuid_hex())
class DomainMemberTests(DomainAdminTests):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainAdminTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(IdentityV3RbacApplicationCredentialTest,
base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
@classmethod
def setup_clients(cls):
super(ProjectAdminTests, cls).setup_clients()
cls.test_user_client, cls.test_user_id = cls.setup_user_client()
def test_identity_create_application_credential(self):
# user can create their own app cred
user_id = self.persona.credentials.user_id
resp = self.do_request(
'create_application_credential',
expected_status=201,
user_id=user_id,
**self.app_cred())['application_credential']
self.addCleanup(
self.client.delete_application_credential,
user_id, resp['id'])
# user cannot create app cred for another user
user_id = self.test_user_id
self.do_request(
'create_application_credential',
expected_status=exceptions.Forbidden,
user_id=user_id,
**self.app_cred())
def test_identity_get_application_credential(self):
# user can retrieve their own app cred
user_id = self.persona.credentials.user_id
app_cred = self.client.create_application_credential(
user_id=user_id, **self.app_cred())['application_credential']
self.addCleanup(
self.client.delete_application_credential,
user_id=user_id, application_credential_id=app_cred['id'])
self.do_request(
'show_application_credential',
user_id=user_id, application_credential_id=app_cred['id'])
# retrieving non-existent app cred for self should return 404
self.do_request(
'show_application_credential',
expected_status=exceptions.NotFound,
user_id=user_id,
application_credential_id=data_utils.rand_uuid_hex())
# user cannot retrieve another user's app cred
user_id = self.test_user_id
client = self.test_user_client.application_credentials_client
app_cred = client.create_application_credential(
user_id=user_id, **self.app_cred())['application_credential']
self.addCleanup(
client.delete_application_credential,
user_id=user_id, application_credential_id=app_cred['id'])
self.do_request(
'show_application_credential',
expected_status=exceptions.Forbidden,
user_id=user_id, application_credential_id=app_cred['id'])
# retrieving non-existent app cred for another user should return 403
self.do_request(
'show_application_credential',
expected_status=exceptions.Forbidden,
user_id=user_id,
application_credential_id=data_utils.rand_uuid_hex())
def test_identity_list_application_credentials(self):
# user can list their own app creds
user_id = self.persona.credentials.user_id
app_cred = self.client.create_application_credential(
user_id=user_id, **self.app_cred())['application_credential']
self.addCleanup(
self.client.delete_application_credential,
user_id=user_id, application_credential_id=app_cred['id'])
self.do_request(
'list_application_credentials', user_id=user_id)
# user cannot list another user's app creds
user_id = self.test_user_id
client = self.test_user_client.application_credentials_client
app_cred = client.create_application_credential(
user_id=user_id, **self.app_cred())['application_credential']
self.addCleanup(
client.delete_application_credential,
user_id=user_id, application_credential_id=app_cred['id'])
self.do_request(
'list_application_credentials',
expected_status=exceptions.Forbidden, user_id=user_id)
def test_identity_delete_application_credential(self):
# user can delete their own app cred
user_id = self.persona.credentials.user_id
app_cred = self.client.create_application_credential(
user_id=user_id, **self.app_cred())['application_credential']
self.do_request(
'delete_application_credential',
expected_status=204,
user_id=user_id, application_credential_id=app_cred['id'])
# deleting non-existent app cred for self should return 404
self.do_request(
'delete_application_credential',
expected_status=exceptions.NotFound,
user_id=user_id,
application_credential_id=data_utils.rand_uuid_hex())
# user cannot delete another user's app cred
user_id = self.test_user_id
client = self.test_user_client.application_credentials_client
app_cred = client.create_application_credential(
user_id=user_id, **self.app_cred())['application_credential']
self.addCleanup(
client.delete_application_credential,
user_id=user_id, application_credential_id=app_cred['id'])
self.do_request(
'delete_application_credential',
expected_status=exceptions.Forbidden,
user_id=user_id, application_credential_id=app_cred['id'])
# deleting non-existent app cred for another user should return 403
self.do_request(
'delete_application_credential',
expected_status=exceptions.Forbidden,
user_id=user_id,
application_credential_id=data_utils.rand_uuid_hex())
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,196 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacOauth1ConsumerTest(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacOauth1ConsumerTest, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.oauth_consumers_client
cls.admin_client = cls.os_system_admin.oauth_consumers_client
def consumer(self):
return {"description": data_utils.arbitrary_string()}
@abc.abstractmethod
def test_identity_create_consumer(self):
"""Test identity:create_consumer policy.
This test must check:
* whether the persona can create a consumer
"""
pass
@abc.abstractmethod
def test_identity_get_consumer(self):
"""Test identity:get_consumer policy.
This test must check:
* whether the persona can get a consumer
"""
pass
@abc.abstractmethod
def test_identity_list_consumers(self):
"""Test identity:list_consumers policy.
This test must check:
* whether the persona can list all consumers
"""
pass
@abc.abstractmethod
def test_identity_update_consumer(self):
"""Test identity:update_consumer policy.
This test must check:
* whether the persona can update a
"""
pass
@abc.abstractmethod
def test_identity_delete_consumer(self):
"""Test identity:delete_consumer policy.
This test must check
* whether the persona can delete a consumer
"""
pass
class SystemAdminTests(
IdentityV3RbacOauth1ConsumerTest, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_consumer(self):
resp = self.do_request('create_consumer',
expected_status=201,
**self.consumer())
self.addCleanup(self.client.delete_consumer,
resp['consumer']['id'])
def test_identity_get_consumer(self):
consumer = self.admin_client.create_consumer(
**self.consumer())['consumer']
self.addCleanup(self.admin_client.delete_consumer, consumer['id'])
resp = self.do_request('show_consumer', consumer_id=consumer['id'])
self.assertEqual(resp['consumer']['id'], consumer['id'])
def test_identity_list_consumers(self):
consumer = self.admin_client.create_consumer(
**self.consumer())['consumer']
self.addCleanup(self.admin_client.delete_consumer, consumer['id'])
resp = self.do_request('list_consumers')
self.assertIn(consumer['id'], set(c['id'] for c in resp['consumers']))
def test_identity_update_consumer(self):
consumer = self.client.create_consumer(**self.consumer())['consumer']
self.addCleanup(self.client.delete_consumer, consumer['id'])
self.do_request('update_consumer',
consumer_id=consumer['id'],
description=data_utils.arbitrary_string())
def test_identity_delete_consumer(self):
consumer = self.client.create_consumer(**self.consumer())['consumer']
self.do_request('delete_consumer',
expected_status=204,
consumer_id=consumer['id'])
class SystemMemberTests(SystemAdminTests):
credentials = ['system_member', 'system_admin']
def test_identity_create_consumer(self):
self.do_request('create_consumer',
expected_status=exceptions.Forbidden,
**self.consumer())
def test_identity_update_consumer(self):
consumer = self.admin_client.create_consumer(
**self.consumer())['consumer']
self.addCleanup(self.admin_client.delete_consumer, consumer['id'])
self.do_request('update_consumer',
expected_status=exceptions.Forbidden,
consumer_id=consumer['id'],
description=data_utils.arbitrary_string())
def test_identity_delete_consumer(self):
consumer = self.admin_client.create_consumer(
**self.consumer())['consumer']
self.do_request('delete_consumer',
expected_status=exceptions.Forbidden,
consumer_id=consumer['id'])
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemMemberTests):
credentials = ['domain_admin', 'system_admin']
def test_identity_get_consumer(self):
consumer = self.admin_client.create_consumer(
**self.consumer())['consumer']
self.addCleanup(self.admin_client.delete_consumer, consumer['id'])
self.do_request('show_consumer',
expected_status=exceptions.Forbidden,
consumer_id=consumer['id'])
def test_identity_list_consumers(self):
consumer = self.admin_client.create_consumer(
**self.consumer())['consumer']
self.addCleanup(self.admin_client.delete_consumer, consumer['id'])
self.do_request('list_consumers',
expected_status=exceptions.Forbidden)
class DomainMemberTests(DomainAdminTests):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,490 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest import clients
from tempest.lib import auth
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacCredentialTest(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacCredentialTest, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.credentials_client
cls.admin_client = cls.os_system_admin
cls.admin_credentials_client = cls.admin_client.credentials_client
# personas in own or other domains
own_domain_id = cls.persona.credentials.domain_id
cls.test_client_1, cls.test_user_1 = cls.setup_user_client(
domain_id=own_domain_id)
cls.other_domain_id = cls.admin_client.domains_client.create_domain(
name=data_utils.rand_name())['domain']['id']
cls.addClassResourceCleanup(
cls.admin_client.domains_client.delete_domain, cls.other_domain_id)
cls.addClassResourceCleanup(
cls.admin_client.domains_client.update_domain,
domain_id=cls.other_domain_id, enabled=False)
cls.test_client_2, cls.test_user_2 = cls.setup_user_client(
domain_id=cls.other_domain_id)
@classmethod
def setup_user_client(cls, domain_id=None):
"""Set up project user with its own client.
This is to enable the project user to create its own credential.
Returns a client object and the user's ID.
"""
user_dict = {
'name': data_utils.rand_name('user'),
'password': data_utils.rand_password(),
}
if domain_id:
user_dict['domain_id'] = domain_id
user_id = cls.admin_client.users_v3_client.create_user(
**user_dict)['user']['id']
def try_cleanup_user():
# if domain is cleaned up first, user will already be deleted
try:
cls.admin_client.users_v3_client.delete_user(user_id)
except exceptions.NotFound:
pass
cls.addClassResourceCleanup(try_cleanup_user)
project_id = cls.admin_client.projects_client.create_project(
data_utils.rand_name())['project']['id']
cls.addClassResourceCleanup(
cls.admin_client.projects_client.delete_project, project_id)
member_role_id = cls.admin_client.roles_v3_client.list_roles(
name='member')['roles'][0]['id']
cls.admin_client.roles_v3_client.create_user_role_on_project(
project_id, user_id, member_role_id)
creds = auth.KeystoneV3Credentials(
user_id=user_id,
password=user_dict['password'],
project_id=project_id)
auth_provider = clients.get_auth_provider(creds)
creds = auth_provider.fill_credentials()
client = clients.Manager(credentials=creds)
return client, user_id
def credential(self, user_id):
cred = {
'blob': data_utils.rand_uuid_hex(),
'type': data_utils.rand_uuid_hex(),
'user_id': user_id,
}
return cred
@abc.abstractmethod
def test_identity_create_credential(self):
"""Test identity:create_credential policy.
This test must check:
* whether the persona can create a credential for themself
* whether the persona can create acredential for another user in
their own domain
* whether the persona can create acredential for another user in
another domain
"""
pass
@abc.abstractmethod
def test_identity_get_credential(self):
"""Test identity:get_credential policy.
This test must check:
* whether the persona can get their own credential
* whether the persona can get a credential for a user in another
domain
* whether the persona can get a credential for a user in their own
domain
* whether the persona can get a credential that does not exist
"""
pass
@abc.abstractmethod
def test_identity_list_credentials(self):
"""Test identity:list_credentials policy.
This test must check:
* whether the persona can list all credentials for themself
* whether the persona can list credentials for a user in their own
domain
* whether the persona can list credentials for a user in another
domain
"""
pass
@abc.abstractmethod
def test_identity_update_credential(self):
"""Test identity:update_credential policy.
This test must check:
* whether the persona can update their own credential
* whether the persona can update a credential for a user in another
domain
* whether the persona can update a credential for a user in their own
domain
* whether the persona can update a credential that does not exist
"""
pass
@abc.abstractmethod
def test_identity_delete_credential(self):
"""Test identity:delete_credential policy.
This test must check
* whether the persona can delete their own credential
* whether the persona can delete a credential for a user in another
domain
* whether the persona can delete a credential for a user in their own
domain
* whether the persona can delete a credential that does not exist
"""
pass
class SystemAdminTests(IdentityV3RbacCredentialTest, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_credential(self):
# user can create their own credential
user_id = self.persona.credentials.user_id
resp = self.do_request(
'create_credential',
expected_status=201,
**self.credential(user_id=user_id))['credential']
self.addCleanup(self.client.delete_credential, resp['id'])
# user can create credential for other user in own domain
resp = self.do_request(
'create_credential',
expected_status=201,
**self.credential(user_id=self.test_user_1))['credential']
self.addCleanup(self.client.delete_credential, resp['id'])
# user can create credential for other user in other domain
resp = self.do_request(
'create_credential',
expected_status=201,
**self.credential(user_id=self.test_user_2))['credential']
self.addCleanup(self.client.delete_credential, resp['id'])
def test_identity_get_credential(self):
# user can get their own credential, credential for user in own domain,
# or credential for user in other domain
user_id = self.persona.credentials.user_id
for u in [user_id, self.test_user_1, self.test_user_2]:
cred = self.admin_credentials_client.create_credential(
**self.credential(user_id=u))['credential']
self.addCleanup(
self.admin_credentials_client.delete_credential, cred['id'])
self.do_request('show_credential', credential_id=cred['id'])
# non-existent credential is Not Found
self.do_request(
'show_credential',
expected_status=exceptions.NotFound,
credential_id=data_utils.rand_uuid_hex())
def test_identity_list_credentials(self):
# user can list their own credentials, credentials for user in own
# domain, or credentials for user in other domain
user_id = self.persona.credentials.user_id
for u in [user_id, self.test_user_1, self.test_user_2]:
cred = self.admin_credentials_client.create_credential(
**self.credential(user_id=u))['credential']
self.addCleanup(
self.admin_credentials_client.delete_credential, cred['id'])
resp = self.do_request('list_credentials')['credentials']
self.assertIn(cred['id'], [c['id'] for c in resp])
def test_identity_update_credential(self):
# user can update their own credential, credential for user in own
# domain, or credential for user in other domain
user_id = self.persona.credentials.user_id
for u in [user_id, self.test_user_1, self.test_user_2]:
cred = self.credential(user_id=u)
resp = self.client.create_credential(**cred)['credential']
self.addCleanup(self.client.delete_credential, resp['id'])
cred['blob'] = data_utils.rand_uuid_hex()
self.do_request(
'update_credential', credential_id=resp['id'], **cred)
# non-existent credential is Not Found
self.do_request(
'update_credential',
expected_status=exceptions.NotFound,
credential_id=data_utils.rand_uuid_hex(),
**self.credential(user_id=self.test_user_2))
def test_identity_delete_credential(self):
# user can delete their own credential, credential for user in own
# domain, or credential for user in other domain
user_id = self.persona.credentials.user_id
for u in [user_id, self.test_user_1, self.test_user_2]:
cred = self.credential(user_id=u)
resp = self.client.create_credential(**cred)['credential']
self.do_request(
'delete_credential',
expected_status=204,
credential_id=resp['id'])
# non-existent credential is Not Found
self.do_request(
'delete_credential',
expected_status=exceptions.NotFound,
credential_id=data_utils.rand_uuid_hex())
class SystemMemberTests(SystemAdminTests):
credentials = ['system_member', 'system_admin']
def test_identity_create_credential(self):
# user can create their own credential
user_id = self.persona.credentials.user_id
resp = self.do_request(
'create_credential',
expected_status=201,
**self.credential(user_id=user_id))['credential']
self.addCleanup(self.client.delete_credential, resp['id'])
# user cannot create credential for other user
for u in [self.test_user_1, self.test_user_2]:
self.do_request(
'create_credential',
expected_status=exceptions.Forbidden,
**self.credential(user_id=u))
def test_identity_update_credential(self):
# user can update their own credential
user_id = self.persona.credentials.user_id
cred = self.credential(user_id=user_id)
resp = self.admin_credentials_client.create_credential(
**cred)['credential']
self.addCleanup(
self.admin_credentials_client.delete_credential, resp['id'])
cred['blob'] = data_utils.rand_uuid_hex()
self.do_request(
'update_credential',
credential_id=resp['id'], **cred)
# user cannot update credential for other user
for u in [self.test_user_1, self.test_user_2]:
cred = self.credential(user_id=u)
resp = self.admin_credentials_client.create_credential(
**cred)['credential']
self.addCleanup(
self.admin_credentials_client.delete_credential, resp['id'])
cred['blob'] = data_utils.rand_uuid_hex()
self.do_request(
'update_credential',
expected_status=exceptions.Forbidden,
credential_id=resp['id'], **cred)
# non-existent credential is Forbidden
self.do_request(
'update_credential',
expected_status=exceptions.Forbidden,
credential_id=data_utils.rand_uuid_hex(),
**self.credential(user_id=self.test_user_2))
def test_identity_delete_credential(self):
# user can delete their own credential
user_id = self.persona.credentials.user_id
cred = self.credential(user_id=user_id)
resp = self.admin_credentials_client.create_credential(
**cred)['credential']
self.do_request(
'delete_credential',
expected_status=204,
credential_id=resp['id'])
# user cannot delete credential for other user
for u in [self.test_user_1, self.test_user_2]:
cred = self.credential(user_id=u)
resp = self.admin_credentials_client.create_credential(
**cred)['credential']
self.addCleanup(
self.admin_credentials_client.delete_credential, resp['id'])
self.do_request(
'delete_credential',
expected_status=exceptions.Forbidden,
credential_id=resp['id'])
# non-existent credential is Forbidden
self.do_request(
'delete_credential',
expected_status=exceptions.Forbidden,
credential_id=data_utils.rand_uuid_hex())
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(IdentityV3RbacCredentialTest, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def test_identity_create_credential(self):
# domain admins cannot create credentials
user_id = self.persona.credentials.user_id
for u in [user_id, self.test_user_1, self.test_user_2]:
self.do_request(
'create_credential',
expected_status=exceptions.Forbidden,
**self.credential(user_id=u))
def test_identity_get_credential(self):
# domain admins cannot get credentials
user_id = self.persona.credentials.user_id
for u in [user_id, self.test_user_1, self.test_user_2]:
cred = self.admin_credentials_client.create_credential(
**self.credential(user_id=u))['credential']
self.addCleanup(
self.admin_credentials_client.delete_credential, cred['id'])
self.do_request(
'show_credential',
expected_status=exceptions.Forbidden,
credential_id=cred['id'])
# non-existent credential is Forbidden
self.do_request(
'show_credential',
expected_status=exceptions.Forbidden,
credential_id=data_utils.rand_uuid_hex())
def test_identity_list_credentials(self):
# domain admins cannot list credentials
user_id = self.persona.credentials.user_id
for u in [user_id, self.test_user_1, self.test_user_2]:
cred = self.admin_credentials_client.create_credential(
**self.credential(user_id=u))['credential']
self.addCleanup(
self.admin_credentials_client.delete_credential, cred['id'])
self.do_request(
'list_credentials',
expected_status=exceptions.Forbidden)
def test_identity_update_credential(self):
# domain admins cannot update credentials
user_id = self.persona.credentials.user_id
for u in [user_id, self.test_user_1, self.test_user_2]:
cred = self.credential(user_id=u)
resp = self.admin_credentials_client.create_credential(
**cred)['credential']
self.addCleanup(
self.admin_credentials_client.delete_credential, resp['id'])
cred['blob'] = data_utils.rand_uuid_hex()
self.do_request(
'update_credential',
expected_status=exceptions.Forbidden,
credential_id=resp['id'], **cred)
# non-existent credential is Forbidden
self.do_request(
'update_credential',
expected_status=exceptions.Forbidden,
credential_id=data_utils.rand_uuid_hex(),
**self.credential(user_id=user_id))
def test_identity_delete_credential(self):
# domain admins cannot delete credentials
user_id = self.persona.credentials.user_id
for u in [user_id, self.test_user_1, self.test_user_2]:
cred = self.credential(user_id=u)
resp = self.admin_credentials_client.create_credential(
**cred)['credential']
self.addCleanup(
self.admin_credentials_client.delete_credential, resp['id'])
self.do_request(
'delete_credential',
expected_status=exceptions.Forbidden,
credential_id=resp['id'])
# non-existent credential is Forbidden
self.do_request(
'delete_credential',
expected_status=exceptions.Forbidden,
credential_id=data_utils.rand_uuid_hex())
class DomainMemberTests(DomainAdminTests):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainAdminTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(SystemReaderTests):
credentials = ['project_admin', 'system_admin']
def test_identity_get_credential(self):
# user can get their own credential
user_id = self.persona.credentials.user_id
cred = self.admin_credentials_client.create_credential(
**self.credential(user_id=user_id))['credential']
self.addCleanup(
self.admin_credentials_client.delete_credential, cred['id'])
self.do_request('show_credential', credential_id=cred['id'])
# user cannot get credential for another user
for u in [self.test_user_1, self.test_user_2]:
cred = self.admin_credentials_client.create_credential(
**self.credential(user_id=u))['credential']
self.addCleanup(
self.admin_credentials_client.delete_credential, cred['id'])
self.do_request(
'show_credential',
expected_status=exceptions.Forbidden,
credential_id=cred['id'])
# non-existent credential is Forbidden
self.do_request(
'show_credential',
expected_status=exceptions.Forbidden,
credential_id=data_utils.rand_uuid_hex())
def test_identity_list_credentials(self):
# user can list their own credentials
user_id = self.persona.credentials.user_id
cred = self.admin_credentials_client.create_credential(
**self.credential(user_id=user_id))['credential']
self.addCleanup(
self.admin_credentials_client.delete_credential, cred['id'])
resp = self.do_request('list_credentials')['credentials']
self.assertIn(cred['id'], [c['id'] for c in resp])
# user cannot list credentials for other users
for u in [self.test_user_1, self.test_user_2]:
cred = self.admin_credentials_client.create_credential(
**self.credential(user_id=u))['credential']
self.addCleanup(
self.admin_credentials_client.delete_credential, cred['id'])
resp = self.do_request('list_credentials')['credentials']
self.assertNotIn(cred['id'], [c['id'] for c in resp])
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,223 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacDomainTests(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacDomainTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.domains_client
admin_client = cls.os_system_admin
cls.admin_domains_client = admin_client.domains_client
@abc.abstractmethod
def test_identity_create_domain(self):
"""Test identity:create_domain policy.
This test must check:
* whether the persona can create a domain
"""
pass
@abc.abstractmethod
def test_identity_get_domain(self):
"""Test identity:get_domain policy.
This test must check:
* whether the persona can get a domain
* whether the persona can get a domain that does not exist
"""
pass
@abc.abstractmethod
def test_identity_list_domains(self):
"""Test identity:list_domains policy.
This test must check:
* whether the persona can list all domains
"""
pass
@abc.abstractmethod
def test_identity_update_domain(self):
"""Test identity:update_domain policy.
This test must check:
* whether the persona can update a domain
* whether the persona can update a domain that does not exist
"""
pass
@abc.abstractmethod
def test_identity_delete_domain(self):
"""Test identity:delete_domain policy.
This test must check
* whether the persona can delete a domain
* whether the persona can delete a domain that does not exist
"""
pass
class SystemAdminTests(IdentityV3RbacDomainTests, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_domain(self):
domain_id = self.do_request(
'create_domain', expected_status=201, name=data_utils.rand_name()
)['domain']['id']
self.addCleanup(self.admin_domains_client.delete_domain, domain_id)
self.addCleanup(self.admin_domains_client.update_domain,
domain_id=domain_id, enabled=False)
def test_identity_get_domain(self):
domain_id = self.admin_domains_client.create_domain(
name=data_utils.rand_name())['domain']['id']
self.addCleanup(self.admin_domains_client.delete_domain, domain_id)
self.addCleanup(self.admin_domains_client.update_domain,
domain_id=domain_id, enabled=False)
self.do_request('show_domain', domain_id=domain_id)
# user gets a 404 for nonexistent domain
self.do_request('show_domain', expected_status=exceptions.NotFound,
domain_id=data_utils.rand_uuid_hex())
def test_identity_list_domains(self):
domain_id = self.admin_domains_client.create_domain(
name=data_utils.rand_name())['domain']['id']
self.addCleanup(self.admin_domains_client.delete_domain, domain_id)
self.addCleanup(self.admin_domains_client.update_domain,
domain_id=domain_id, enabled=False)
resp = self.do_request('list_domains')
self.assertIn(domain_id, [d['id'] for d in resp['domains']])
def test_identity_update_domain(self):
domain_id = self.admin_domains_client.create_domain(
name=data_utils.rand_name())['domain']['id']
self.addCleanup(self.admin_domains_client.delete_domain, domain_id)
self.addCleanup(self.admin_domains_client.update_domain,
domain_id=domain_id, enabled=False)
self.do_request('update_domain',
domain_id=domain_id,
description=data_utils.arbitrary_string())
# user gets a 404 for nonexistent domain
self.do_request('update_domain', expected_status=exceptions.NotFound,
domain_id=data_utils.rand_uuid_hex())
def test_identity_delete_domain(self):
domain_id = self.admin_domains_client.create_domain(
name=data_utils.rand_name())['domain']['id']
self.do_request('update_domain',
domain_id=domain_id,
enabled=False)
self.do_request('delete_domain', expected_status=204,
domain_id=domain_id)
class SystemMemberTests(SystemAdminTests, base.BaseIdentityTest):
credentials = ['system_member', 'system_admin']
def test_identity_create_domain(self):
self.do_request('create_domain', expected_status=exceptions.Forbidden,
name=data_utils.rand_name())
def test_identity_update_domain(self):
domain_id = self.admin_domains_client.create_domain(
name=data_utils.rand_name())['domain']['id']
self.addCleanup(self.admin_domains_client.delete_domain, domain_id)
self.addCleanup(self.admin_domains_client.update_domain,
domain_id=domain_id, enabled=False)
self.do_request('update_domain', expected_status=exceptions.Forbidden,
domain_id=domain_id,
description=data_utils.arbitrary_string())
# user gets a 404 for nonexistent domain
self.do_request('update_domain', expected_status=exceptions.NotFound,
domain_id=data_utils.rand_uuid_hex())
def test_identity_delete_domain(self):
domain_id = self.admin_domains_client.create_domain(
name=data_utils.rand_name())['domain']['id']
self.addCleanup(self.admin_domains_client.delete_domain, domain_id)
self.addCleanup(self.admin_domains_client.update_domain,
domain_id=domain_id, enabled=False)
self.do_request('delete_domain', expected_status=exceptions.Forbidden,
domain_id=domain_id)
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def test_identity_get_domain(self):
domain_id = self.admin_domains_client.create_domain(
name=data_utils.rand_name())['domain']['id']
self.addCleanup(self.admin_domains_client.delete_domain, domain_id)
self.addCleanup(self.admin_domains_client.update_domain,
domain_id=domain_id, enabled=False)
self.do_request('show_domain', expected_status=exceptions.Forbidden,
domain_id=domain_id)
# user gets a 403 for nonexistent domain
self.do_request('show_domain', expected_status=exceptions.Forbidden,
domain_id=data_utils.rand_uuid_hex())
def test_identity_list_domains(self):
domain_id = self.admin_domains_client.create_domain(
name=data_utils.rand_name())['domain']['id']
self.addCleanup(self.admin_domains_client.delete_domain, domain_id)
self.addCleanup(self.admin_domains_client.update_domain,
domain_id=domain_id, enabled=False)
self.do_request('list_domains',
expected_status=exceptions.Forbidden)
class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,381 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacDomainConfigTest(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacDomainConfigTest, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.domain_config_client
cls.admin_client = cls.os_system_admin
cls.admin_domain_config_client = cls.admin_client.domain_config_client
@classmethod
def resource_setup(cls):
super(IdentityV3RbacDomainConfigTest, cls).resource_setup()
cls.domain_id = cls.admin_client.domains_client.create_domain(
name=data_utils.rand_name('domain'))['domain']['id']
cls.addClassResourceCleanup(
cls.admin_client.domains_client.delete_domain,
cls.domain_id)
cls.addClassResourceCleanup(
cls.admin_client.domains_client.update_domain,
cls.domain_id,
enabled=False)
def domain_config(self, **kwargs):
ref = {
"identity": {
"driver": "ldap"
},
"ldap": {
"url": "ldap://myldap.com:389/",
"user_tree_dn": "ou=Users,dc=my_new_root,dc=org"
}
}
ref.update(kwargs)
return ref
@abc.abstractmethod
def test_identity_create_domain_config(self):
"""Test identity:create_domain_config policy.
This test must check:
* whether the persona can create a domain config for a valid domain
"""
pass
@abc.abstractmethod
def test_identity_get_domain_config(self):
"""Test identity:get_domain_config policy.
This test must check:
* whether the persona can get a domain config
* whether the persona can get an option group for a domain config
* whether the persona can get an option from a group in a domain
config
* whether the persona can get a config for an invalid domain
* whether the persona can get a config that does not exist
"""
pass
@abc.abstractmethod
def test_identity_get_domain_config_default(self):
"""Test identity:get_domain_config_default policy.
* whether the persona can get the default config
* whether the persona can get the default config for an option group
* whether the persona can get the default value for an option
"""
pass
@abc.abstractmethod
def test_identity_get_security_compliance_domain_config(self):
"""Test identity:get_security_compliance_domain_config policy.
This test must check:
* whether the persona can get the security compliance configuration
for the default domain
* whether the persona can get an option from the security compliance
configuration for the default domain
"""
pass
@abc.abstractmethod
def test_identity_update_domain_config(self):
"""Test identity:update_domain_config policy.
This test must check:
* whether the persona can update the config for a domain
* whether the persona can update an option group config for a domain
* whether the persona can update an option in a domain config
"""
pass
@abc.abstractmethod
def test_identity_delete_domain_config(self):
"""Test identity:delete_domain_config policy.
This test must check
* whether the persona can delete a domain config
* whether the persona can delete an option group within a domain
config
* whether the persona can delete an option within a domain config
"""
pass
class SystemAdminTests(IdentityV3RbacDomainConfigTest, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_domain_config(self):
self.do_request(
'create_domain_config',
expected_status=201,
domain_id=self.domain_id,
**self.domain_config())
self.addCleanup(
self.admin_domain_config_client.delete_domain_config,
self.domain_id)
def test_identity_get_domain_config(self):
# should be able to get domain config, group and individual options
self.admin_domain_config_client.create_domain_config(
self.domain_id, **self.domain_config())
self.addCleanup(
self.admin_domain_config_client.delete_domain_config,
self.domain_id)
self.do_request(
'show_domain_config',
domain_id=self.domain_id)
self.do_request(
'show_domain_group_config',
domain_id=self.domain_id,
group='ldap')
self.do_request(
'show_domain_group_option_config',
domain_id=self.domain_id,
group='ldap',
option='url')
# should get Not Found for invalid domain
self.do_request(
'show_domain_config',
expected_status=exceptions.NotFound,
domain_id=data_utils.rand_uuid_hex())
# should get Not Found for nonexistent config for valid domain
domain = self.admin_client.domains_client.create_domain(
name=data_utils.rand_name('domain'))['domain']['id']
self.addCleanup(self.admin_client.domains_client.delete_domain, domain)
self.addCleanup(
self.admin_client.domains_client.update_domain,
domain, enabled=False)
self.do_request(
'show_domain_config',
expected_status=exceptions.NotFound,
domain_id=domain)
def test_identity_get_domain_config_default(self):
self.do_request('show_default_config_settings')
self.do_request('show_default_group_config', group='ldap')
self.do_request(
'show_default_group_option', group='ldap', option='url')
def test_identity_get_security_compliance_domain_config(self):
self.do_request(
'show_domain_group_config',
domain_id='default',
group='security_compliance')
self.do_request(
'show_domain_group_option_config',
domain_id='default',
group='security_compliance',
option='password_regex_description')
def test_identity_update_domain_config(self):
self.admin_domain_config_client.create_domain_config(
self.domain_id, **self.domain_config())
self.addCleanup(
self.admin_domain_config_client.delete_domain_config,
self.domain_id)
self.do_request(
'update_domain_group_config',
domain_id=self.domain_id,
group='ldap',
ldap={'url': 'ldaps://myldap.com:636/',
'user_tree_dn': 'ou=People,dc=my_new_root,dc=org'})
self.do_request(
'update_domain_group_option_config',
domain_id=self.domain_id,
group='ldap',
option='user_tree_dn',
user_tree_dn='ou=Aliens,dc=my_new_root,dc=org')
# test changing the entire config last
self.do_request(
'update_domain_config',
domain_id=self.domain_id,
identity={"driver": "sql"})
def test_identity_delete_domain_config(self):
self.admin_domain_config_client.create_domain_config(
self.domain_id, **self.domain_config())
self.do_request(
'delete_domain_group_option_config',
expected_status=204,
domain_id=self.domain_id,
group='ldap',
option='user_tree_dn')
self.do_request(
'delete_domain_group_config',
expected_status=204,
domain_id=self.domain_id,
group='ldap')
self.do_request(
'delete_domain_config',
expected_status=204,
domain_id=self.domain_id)
class SystemMemberTests(SystemAdminTests):
credentials = ['system_member', 'system_admin']
def test_identity_create_domain_config(self):
self.do_request(
'create_domain_config',
expected_status=exceptions.Forbidden,
domain_id=self.domain_id,
**self.domain_config())
def test_identity_update_domain_config(self):
self.admin_domain_config_client.create_domain_config(
self.domain_id, **self.domain_config())
self.addCleanup(
self.admin_domain_config_client.delete_domain_config,
self.domain_id)
self.do_request(
'update_domain_group_config',
expected_status=exceptions.Forbidden,
domain_id=self.domain_id,
group='ldap',
ldap={'url': 'ldaps://myldap.com:636/',
'user_tree_dn': 'ou=People,dc=my_new_root,dc=org'})
self.do_request(
'update_domain_group_option_config',
expected_status=exceptions.Forbidden,
domain_id=self.domain_id,
group='ldap',
option='user_tree_dn',
user_tree_dn='ou=Aliens,dc=my_new_root,dc=org')
# test changing the entire config last
self.do_request(
'update_domain_config',
expected_status=exceptions.Forbidden,
domain_id=self.domain_id,
identity={"driver": "sql"})
def test_identity_delete_domain_config(self):
self.admin_domain_config_client.create_domain_config(
self.domain_id, **self.domain_config())
self.do_request(
'delete_domain_group_option_config',
expected_status=exceptions.Forbidden,
domain_id=self.domain_id,
group='ldap',
option='user_tree_dn')
self.do_request(
'delete_domain_group_config',
expected_status=exceptions.Forbidden,
domain_id=self.domain_id,
group='ldap')
self.do_request(
'delete_domain_config',
expected_status=exceptions.Forbidden,
domain_id=self.domain_id)
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests):
credentials = ['domain_admin', 'system_admin']
def test_identity_get_domain_config(self):
# should not be able to get domain config, group and individual options
self.admin_domain_config_client.create_domain_config(
self.domain_id, **self.domain_config())
self.addCleanup(
self.admin_domain_config_client.delete_domain_config,
self.domain_id)
self.do_request(
'show_domain_config',
expected_status=exceptions.Forbidden,
domain_id=self.domain_id)
self.do_request(
'show_domain_group_config',
expected_status=exceptions.Forbidden,
domain_id=self.domain_id,
group='ldap')
self.do_request(
'show_domain_group_option_config',
expected_status=exceptions.Forbidden,
domain_id=self.domain_id,
group='ldap',
option='url')
# should get Forbidden for invalid domain
self.do_request(
'show_domain_config',
expected_status=exceptions.Forbidden,
domain_id=data_utils.rand_uuid_hex())
# should get Forbidden for nonexistent config for valid domain
domain = self.admin_client.domains_client.create_domain(
name=data_utils.rand_name('domain'))['domain']['id']
self.addCleanup(self.admin_client.domains_client.delete_domain, domain)
self.addCleanup(
self.admin_client.domains_client.update_domain,
domain, enabled=False)
self.do_request(
'show_domain_config',
expected_status=exceptions.Forbidden,
domain_id=domain)
def test_identity_get_domain_config_default(self):
self.do_request(
'show_default_config_settings',
expected_status=exceptions.Forbidden)
self.do_request(
'show_default_group_config',
expected_status=exceptions.Forbidden, group='ldap')
self.do_request(
'show_default_group_option',
expected_status=exceptions.Forbidden, group='ldap', option='url')
class DomainMemberTests(DomainAdminTests):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainAdminTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,544 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest import clients
from tempest.lib import auth
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacEc2CredentialTest(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacEc2CredentialTest, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.users_v3_client
cls.admin_client = cls.os_system_admin
cls.admin_credentials_client = cls.admin_client.users_v3_client
# personas in own or other domains
own_domain_id = cls.persona.credentials.domain_id
cls.test_client_1, cls.test_user_1, cls.test_project_1 = (
cls.setup_user_client(domain_id=own_domain_id))
cls.other_domain_id = cls.admin_client.domains_client.create_domain(
name=data_utils.rand_name())['domain']['id']
cls.addClassResourceCleanup(
cls.admin_client.domains_client.delete_domain, cls.other_domain_id)
cls.addClassResourceCleanup(
cls.admin_client.domains_client.update_domain,
domain_id=cls.other_domain_id, enabled=False)
cls.test_client_2, cls.test_user_2, cls.test_project_2 = (
cls.setup_user_client(domain_id=cls.other_domain_id))
@classmethod
def setup_user_client(cls, domain_id=None):
"""Set up project user with its own client.
This is to enable the project user to create its own credential.
Returns a client object and the user's ID.
"""
user_dict = {
'name': data_utils.rand_name('user'),
'password': data_utils.rand_password(),
}
if domain_id:
user_dict['domain_id'] = domain_id
user_id = cls.admin_client.users_v3_client.create_user(
**user_dict)['user']['id']
def try_cleanup_user():
# if domain is cleaned up first, user will already be deleted
try:
cls.admin_client.users_v3_client.delete_user(user_id)
except exceptions.NotFound:
pass
cls.addClassResourceCleanup(try_cleanup_user)
project_id = cls.admin_client.projects_client.create_project(
data_utils.rand_name())['project']['id']
cls.addClassResourceCleanup(
cls.admin_client.projects_client.delete_project, project_id)
member_role_id = cls.admin_client.roles_v3_client.list_roles(
name='member')['roles'][0]['id']
cls.admin_client.roles_v3_client.create_user_role_on_project(
project_id, user_id, member_role_id)
creds = auth.KeystoneV3Credentials(
user_id=user_id,
password=user_dict['password'],
project_id=project_id)
auth_provider = clients.get_auth_provider(creds)
creds = auth_provider.fill_credentials()
client = clients.Manager(credentials=creds)
return client, user_id, project_id
def ec2_credential(self, project_id=None):
return {
'tenant_id': project_id or self.project_id
}
@abc.abstractmethod
def test_identity_ec2_create_credential(self):
"""Test identity:ec2_create_credential policy.
This test must check:
* whether the persona can create a credential for themself
* whether the persona can create acredential for another user in
their own domain
* whether the persona can create acredential for another user in
another domain
"""
pass
@abc.abstractmethod
def test_identity_ec2_get_credential(self):
"""Test identity:ec2_get_credential policy.
This test must check:
* whether the persona can get their own credential
* whether the persona can get a credential for a user in another
domain
* whether the persona can get a credential for a user in their own
domain
* whether the persona can get a credential that does not exist
"""
pass
@abc.abstractmethod
def test_identity_ec2_list_credentials(self):
"""Test identity:list_credentials policy.
This test must check:
* whether the persona can list all credentials for themself
* whether the persona can list credentials for a user in their own
domain
* whether the persona can list credentials for a user in another
domain
"""
pass
@abc.abstractmethod
def test_identity_ec2_delete_credential(self):
"""Test identity:ec2_delete_credential policy.
This test must check
* whether the persona can delete their own credential
* whether the persona can delete a credential for a user in another
domain
* whether the persona can delete a credential for a user in their own
domain
* whether the persona can delete a credential that does not exist
"""
pass
class SystemAdminTests(IdentityV3RbacEc2CredentialTest, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_ec2_create_credential(self):
# user can create their own credential
user_id = self.persona.credentials.user_id
resp = self.do_request(
'create_user_ec2_credential',
expected_status=201,
user_id=user_id,
**self.ec2_credential(project_id=self.test_project_1)
)['credential']
self.addCleanup(self.client.delete_user_ec2_credential,
user_id=user_id, access=resp['access'])
# user can create credential for other user
resp = self.do_request(
'create_user_ec2_credential',
expected_status=201,
user_id=self.test_user_2,
**self.ec2_credential(project_id=self.test_project_2)
)['credential']
self.addCleanup(self.client.delete_user_ec2_credential,
user_id=user_id, access=resp['access'])
def test_identity_ec2_get_credential(self):
# user can get their own credential
user_id = self.persona.credentials.user_id
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=user_id,
**self.ec2_credential(project_id=self.test_project_1)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=user_id, access=cred['access'])
self.do_request('show_user_ec2_credential',
user_id=user_id, access=cred['access'])
# user can get credential for other user
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=self.test_user_2,
**self.ec2_credential(project_id=self.test_project_2)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=self.test_user_2, access=cred['access'])
self.do_request('show_user_ec2_credential',
user_id=self.test_user_2, access=cred['access'])
# non-existent credential is Not Found
self.do_request(
'show_user_ec2_credential',
expected_status=exceptions.NotFound,
user_id=self.test_user_2,
access=data_utils.rand_uuid_hex())
def test_identity_ec2_list_credentials(self):
# user can list their own credentials
user_id = self.persona.credentials.user_id
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=user_id,
**self.ec2_credential(project_id=self.test_project_1)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=user_id, access=cred['access'])
resp = self.do_request('list_user_ec2_credentials',
user_id=user_id)['credentials']
self.assertIn(cred['access'], [c['access'] for c in resp])
# user can list credentials for other user
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=self.test_user_2,
**self.ec2_credential(project_id=self.test_project_2)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=self.test_user_2, access=cred['access'])
resp = self.do_request('list_user_ec2_credentials',
user_id=self.test_user_2)['credentials']
self.assertIn(cred['access'], [c['access'] for c in resp])
def test_identity_ec2_delete_credential(self):
# user can delete their own credential
user_id = self.persona.credentials.user_id
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=user_id,
**self.ec2_credential(project_id=self.test_project_1)
)['credential']
self.do_request(
'delete_user_ec2_credential',
expected_status=204,
user_id=user_id, access=cred['access'])
# user can delete another user's credential
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=self.test_user_2,
**self.ec2_credential(project_id=self.test_project_2)
)['credential']
self.do_request(
'delete_user_ec2_credential',
expected_status=204,
user_id=self.test_user_2, access=cred['access'])
# non-existent credential is Not Found
self.do_request(
'delete_user_ec2_credential',
expected_status=exceptions.NotFound,
user_id=self.test_user_2,
access=data_utils.rand_uuid_hex())
class SystemMemberTests(SystemAdminTests):
credentials = ['system_member', 'system_admin']
def test_identity_ec2_create_credential(self):
# user can create their own credential
user_id = self.persona.credentials.user_id
resp = self.do_request(
'create_user_ec2_credential',
expected_status=201,
user_id=user_id,
**self.ec2_credential(project_id=self.test_project_1)
)['credential']
self.addCleanup(self.client.delete_user_ec2_credential,
user_id=user_id, access=resp['access'])
# user cannot create credential for other user
self.do_request(
'create_user_ec2_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_2,
**self.ec2_credential(project_id=self.test_project_2))
def test_identity_ec2_delete_credential(self):
# user can delete their own credential
user_id = self.persona.credentials.user_id
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=user_id,
**self.ec2_credential(project_id=self.test_project_1)
)['credential']
self.do_request(
'delete_user_ec2_credential',
expected_status=204,
user_id=user_id, access=cred['access'])
# user cannot delete another user's credential
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=self.test_user_2,
**self.ec2_credential(project_id=self.test_project_2)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=self.test_user_2, access=cred['access'])
self.do_request(
'delete_user_ec2_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_2, access=cred['access'])
# non-existent credential is Not Found
self.do_request(
'delete_user_ec2_credential',
expected_status=exceptions.NotFound,
user_id=self.test_user_2,
access=data_utils.rand_uuid_hex())
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(IdentityV3RbacEc2CredentialTest, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def test_identity_ec2_create_credential(self):
# user cannot create their own credential
user_id = self.persona.credentials.user_id
self.do_request(
'create_user_ec2_credential',
expected_status=exceptions.Forbidden,
user_id=user_id,
**self.ec2_credential(project_id=self.test_project_1))
# user cannot create credential for user in own domain
self.do_request(
'create_user_ec2_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_1,
**self.ec2_credential(project_id=self.test_project_1))
# user cannot create credential for other user
self.do_request(
'create_user_ec2_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_2,
**self.ec2_credential(project_id=self.test_project_2))
def test_identity_ec2_get_credential(self):
# user cannot get their own credential
user_id = self.persona.credentials.user_id
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=user_id,
**self.ec2_credential(project_id=self.test_project_1)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=user_id, access=cred['access'])
self.do_request('show_user_ec2_credential',
expected_status=exceptions.Forbidden,
user_id=user_id, access=cred['access'])
# user cannot get credential for user in own domain
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=self.test_user_1,
**self.ec2_credential(project_id=self.test_project_1)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=self.test_user_1, access=cred['access'])
self.do_request('show_user_ec2_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_2, access=cred['access'])
# user cannot get credential for other user
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=self.test_user_2,
**self.ec2_credential(project_id=self.test_project_2)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=self.test_user_2, access=cred['access'])
self.do_request('show_user_ec2_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_2, access=cred['access'])
# non-existent credential is Not Found
self.do_request(
'show_user_ec2_credential',
expected_status=exceptions.NotFound,
user_id=self.test_user_2,
access=data_utils.rand_uuid_hex())
def test_identity_ec2_list_credentials(self):
# user cannot list their own credentials
user_id = self.persona.credentials.user_id
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=user_id,
**self.ec2_credential(project_id=self.test_project_1)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=user_id, access=cred['access'])
self.do_request('list_user_ec2_credentials',
expected_status=exceptions.Forbidden,
user_id=user_id)
# user cannot list credentials for user in own domain
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=self.test_user_1,
**self.ec2_credential(project_id=self.test_project_1)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=self.test_user_1, access=cred['access'])
self.do_request('list_user_ec2_credentials',
expected_status=exceptions.Forbidden,
user_id=self.test_user_1)
# user cannot list credentials for other user
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=self.test_user_2,
**self.ec2_credential(project_id=self.test_project_2)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=self.test_user_2, access=cred['access'])
self.do_request('list_user_ec2_credentials',
expected_status=exceptions.Forbidden,
user_id=self.test_user_2)
def test_identity_ec2_delete_credential(self):
# user cannot delete their own credential
user_id = self.persona.credentials.user_id
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=user_id,
**self.ec2_credential(project_id=self.test_project_1)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=user_id, access=cred['access'])
self.do_request(
'delete_user_ec2_credential',
expected_status=exceptions.Forbidden,
user_id=user_id, access=cred['access'])
# user cannot delete credential for user in own domain
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=self.test_user_1,
**self.ec2_credential(project_id=self.test_project_1)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=self.test_user_1, access=cred['access'])
self.do_request(
'delete_user_ec2_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_1, access=cred['access'])
# user cannot delete another user's credential
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=self.test_user_2,
**self.ec2_credential(project_id=self.test_project_2)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=self.test_user_2, access=cred['access'])
self.do_request(
'delete_user_ec2_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_2, access=cred['access'])
# non-existent credential is Not Found
self.do_request(
'delete_user_ec2_credential',
expected_status=exceptions.NotFound,
user_id=self.test_user_2,
access=data_utils.rand_uuid_hex())
class DomainMemberTests(DomainAdminTests):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainAdminTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(SystemReaderTests):
credentials = ['project_admin', 'system_admin']
def test_identity_ec2_get_credential(self):
# user can get their own credential
user_id = self.persona.credentials.user_id
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=user_id,
**self.ec2_credential(project_id=self.test_project_1)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=user_id, access=cred['access'])
self.do_request('show_user_ec2_credential',
user_id=user_id, access=cred['access'])
# user cannot get credential for other user
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=self.test_user_2,
**self.ec2_credential(project_id=self.test_project_2)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=self.test_user_2, access=cred['access'])
self.do_request('show_user_ec2_credential',
expected_status=exceptions.Forbidden,
user_id=self.test_user_2, access=cred['access'])
# non-existent credential is Not Found
self.do_request(
'show_user_ec2_credential',
expected_status=exceptions.NotFound,
user_id=self.test_user_2,
access=data_utils.rand_uuid_hex())
def test_identity_ec2_list_credentials(self):
# user can list their own credentials
user_id = self.persona.credentials.user_id
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=user_id,
**self.ec2_credential(project_id=self.test_project_1)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=user_id, access=cred['access'])
resp = self.do_request('list_user_ec2_credentials',
user_id=user_id)['credentials']
self.assertIn(cred['access'], [c['access'] for c in resp])
# user cannot list credentials for other user
cred = self.admin_credentials_client.create_user_ec2_credential(
user_id=self.test_user_2,
**self.ec2_credential(project_id=self.test_project_2)
)['credential']
self.addCleanup(
self.admin_credentials_client.delete_user_ec2_credential,
user_id=self.test_user_2, access=cred['access'])
self.do_request('list_user_ec2_credentials',
expected_status=exceptions.Forbidden,
user_id=self.test_user_2)
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,245 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacEndpointTests(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacEndpointTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.endpoints_v3_client
admin_client = cls.os_system_admin
cls.services_client = admin_client.identity_services_v3_client
cls.admin_endpoints_client = admin_client.endpoints_v3_client
@classmethod
def setUpClass(cls):
super(IdentityV3RbacEndpointTests, cls).setUpClass()
cls.service_id = cls.services_client.create_service(
type=data_utils.rand_name(),
name=data_utils.rand_name())['service']['id']
cls.addClassResourceCleanup(
cls.services_client.delete_service,
cls.service_id)
def endpoint(self):
return {
'interface': 'public',
'service_id': self.service_id,
'url': 'http://localhost/service'
}
@abc.abstractmethod
def test_identity_create_endpoint(self):
"""Test identity:create_endpoint policy.
This test must check:
* whether the persona can create an endpoint
"""
pass
@abc.abstractmethod
def test_identity_get_endpoint(self):
"""Test identity:get_endpoint policy.
This test must check:
* whether the persona can get an endpoint
* whether the persona can get an endpoint that does not exist
"""
pass
@abc.abstractmethod
def test_identity_list_endpoints(self):
"""Test identity:list_endpoints policy.
This test must check:
* whether the persona can list all endpoints
"""
pass
@abc.abstractmethod
def test_identity_update_endpoint(self):
"""Test identity:update_endpoint policy.
This test must check:
* whether the persona can update an endpoint
* whether the persona can update an endpoint that does not exist
"""
pass
@abc.abstractmethod
def test_identity_delete_endpoint(self):
"""Test identity:delete_endpoint policy.
This test must check
* whether the persona can delete an endpoint
* whether the persona can delete an endpoint that does not exist
"""
pass
class SystemAdminTests(IdentityV3RbacEndpointTests, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_endpoint(self):
endpoint_id = self.do_request(
'create_endpoint', expected_status=201,
**self.endpoint())['endpoint']['id']
self.addCleanup(
self.admin_endpoints_client.delete_endpoint,
endpoint_id=endpoint_id)
def test_identity_get_endpoint(self):
endpoint_id = self.admin_endpoints_client.create_endpoint(
**self.endpoint())['endpoint']['id']
self.addCleanup(
self.admin_endpoints_client.delete_endpoint,
endpoint_id=endpoint_id)
self.do_request('show_endpoint', endpoint_id=endpoint_id)
# user gets a 404 for nonexistent endpoint
self.do_request('show_endpoint', expected_status=exceptions.NotFound,
endpoint_id=data_utils.rand_uuid_hex())
def test_identity_list_endpoints(self):
endpoint_id = self.admin_endpoints_client.create_endpoint(
**self.endpoint())['endpoint']['id']
self.addCleanup(
self.admin_endpoints_client.delete_endpoint,
endpoint_id=endpoint_id)
resp = self.do_request('list_endpoints')
self.assertIn(endpoint_id, [e['id'] for e in resp['endpoints']])
def test_identity_update_endpoint(self):
endpoint_id = self.admin_endpoints_client.create_endpoint(
**self.endpoint())['endpoint']['id']
self.addCleanup(
self.admin_endpoints_client.delete_endpoint,
endpoint_id=endpoint_id)
self.do_request('update_endpoint',
endpoint_id=endpoint_id,
interface='internal')
# user gets a 404 for nonexistent endpoint
self.do_request('update_endpoint', expected_status=exceptions.NotFound,
endpoint_id=data_utils.rand_uuid_hex(),
interface='internal')
def test_identity_delete_endpoint(self):
endpoint_id = self.admin_endpoints_client.create_endpoint(
**self.endpoint())['endpoint']['id']
self.do_request('delete_endpoint', expected_status=204,
endpoint_id=endpoint_id)
# user gets a 404 for nonexistent endpoint
self.do_request('delete_endpoint', expected_status=exceptions.NotFound,
endpoint_id=data_utils.rand_uuid_hex())
class SystemMemberTests(SystemAdminTests, base.BaseIdentityTest):
credentials = ['system_member', 'system_admin']
def test_identity_create_endpoint(self):
self.do_request(
'create_endpoint', expected_status=exceptions.Forbidden,
**self.endpoint())
def test_identity_update_endpoint(self):
endpoint_id = self.admin_endpoints_client.create_endpoint(
**self.endpoint())['endpoint']['id']
self.addCleanup(
self.admin_endpoints_client.delete_endpoint,
endpoint_id=endpoint_id)
self.do_request('update_endpoint',
expected_status=exceptions.Forbidden,
endpoint_id=endpoint_id,
interface='internal')
# user gets a 404 for nonexistent endpoint
self.do_request('update_endpoint', expected_status=exceptions.NotFound,
endpoint_id=data_utils.rand_uuid_hex(),
interface='internal')
def test_identity_delete_endpoint(self):
endpoint_id = self.admin_endpoints_client.create_endpoint(
**self.endpoint())['endpoint']['id']
self.do_request('delete_endpoint',
expected_status=exceptions.Forbidden,
endpoint_id=endpoint_id)
# user gets a 404 for nonexistent endpoint
self.do_request('delete_endpoint', expected_status=exceptions.NotFound,
endpoint_id=data_utils.rand_uuid_hex())
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def test_identity_get_endpoint(self):
endpoint_id = self.admin_endpoints_client.create_endpoint(
**self.endpoint())['endpoint']['id']
self.addCleanup(
self.admin_endpoints_client.delete_endpoint,
endpoint_id=endpoint_id)
self.do_request('show_endpoint', expected_status=exceptions.Forbidden,
endpoint_id=endpoint_id)
# user gets a 404 for nonexistent endpoint
self.do_request('show_endpoint', expected_status=exceptions.NotFound,
endpoint_id=data_utils.rand_uuid_hex())
def test_identity_list_endpoints(self):
endpoint_id = self.admin_endpoints_client.create_endpoint(
**self.endpoint())['endpoint']['id']
self.addCleanup(
self.admin_endpoints_client.delete_endpoint,
endpoint_id=endpoint_id)
self.do_request('list_endpoints', expected_status=exceptions.Forbidden)
class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,521 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacEndpointGroupTests(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacEndpointGroupTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.eg_client = cls.persona.endpoint_groups_client
cls.ef_client = cls.persona.endpoint_filter_client
cls.admin_client = cls.os_system_admin
cls.admin_eg_client = cls.admin_client.endpoint_groups_client
cls.admin_ef_client = cls.admin_client.endpoint_filter_client
def endpoint_group(self):
return {
'name': data_utils.rand_name('endpoint_group'),
'filters': {'interface': 'public'},
}
@abc.abstractmethod
def test_identity_create_endpoint_group(self):
"""Test identity:create_endpoint_group policy.
This test must check:
* whether the persona can create an endpoint group
"""
pass
@abc.abstractmethod
def test_identity_get_endpoint_group(self):
"""Test identity:get_endpoint_group policy.
This test must check:
* whether the persona can get an endpoint group
* whether the persona can get an endpoint group that does not exist
"""
pass
@abc.abstractmethod
def test_identity_list_endpoint_groups(self):
"""Test identity:list_endpoint_groups policy.
This test must check:
* whether the persona can list all endpoint groups
"""
pass
@abc.abstractmethod
def test_identity_update_endpoint_group(self):
"""Test identity:update_endpoint_group policy.
This test must check:
* whether the persona can update an endpoint group
* whether the persona can update an endpoint group that does not
exist
"""
pass
@abc.abstractmethod
def test_identity_delete_endpoint_group(self):
"""Test identity:delete_endpoint_group policy.
This test must check
* whether the persona can delete an endpoint group
* whether the persona can delete an endpoint group that does not
exist
"""
pass
@abc.abstractmethod
def test_identity_list_projects_associated_with_endpoint_group(self):
"""Test identity:list_projects_associated_with_endpoint_group policy.
This test must check
* whether the persona can list projects associated with an endpoint
group
"""
pass
@abc.abstractmethod
def test_identity_list_endpoints_associated_with_endpoint_group(self):
"""Test identity:list_endpoints_associated_with_endpoint_group
This test must check
* whether the persona can list endpoints associated with an endpoint
group
"""
pass
@abc.abstractmethod
def test_identity_get_endpoint_group_in_project(self):
"""Test identity:get_endpoint_group_in_project
This test must check
* whether the persona can check if an endpoint group is associated
with a project
"""
pass
@abc.abstractmethod
def test_identity_list_endpoint_groups_for_project(self):
"""Test identity:list_endpoint_groups_for_project
This test must check
* whether the persona can list endpoint groups associated with a
project
"""
pass
@abc.abstractmethod
def test_identity_add_endpoint_group_to_project(self):
"""Test identity:add_endpoint_group_to_project
This test must check
* whether the persona can allow a project to access an endpoint group
"""
pass
@abc.abstractmethod
def test_identity_remove_endpoint_group_from_project(self):
"""Test identity:remove_endpoint_group_from_project
This test must check
* whether the persona can remove an endpoint group from a project
"""
pass
class SystemAdminTests(
IdentityV3RbacEndpointGroupTests, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_endpoint_group(self):
eg = self.do_request('create_endpoint_group', expected_status=201,
client=self.eg_client,
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
def test_identity_get_endpoint_group(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
# user can get an endpoint group
self.do_request('show_endpoint_group', client=self.eg_client,
endpoint_group_id=eg)
# nonexistent endpoint group gives a 404
self.do_request('show_endpoint_group',
expected_status=exceptions.NotFound,
client=self.eg_client,
endpoint_group_id=data_utils.rand_uuid_hex())
def test_identity_list_endpoint_groups(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
resp = self.do_request('list_endpoint_groups',
client=self.eg_client)['endpoint_groups']
self.assertIn(eg, [e['id'] for e in resp])
def test_identity_update_endpoint_group(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
# user can update an endpoint group
self.do_request('update_endpoint_group', client=self.eg_client,
endpoint_group_id=eg,
description=data_utils.arbitrary_string())
# nonexistent endpoint group gives a 404
self.do_request('update_endpoint_group', client=self.eg_client,
expected_status=exceptions.NotFound,
endpoint_group_id=data_utils.rand_uuid_hex(),
description=data_utils.arbitrary_string())
def test_identity_delete_endpoint_group(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
# user can delete an endpoint group
self.do_request('delete_endpoint_group',
expected_status=204,
client=self.eg_client,
endpoint_group_id=eg)
# nonexistent endpoint group gives a 404
self.do_request('delete_endpoint_group',
expected_status=exceptions.NotFound,
client=self.eg_client,
endpoint_group_id=data_utils.rand_uuid_hex())
def test_identity_list_projects_associated_with_endpoint_group(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
project = self.admin_client.projects_client.create_project(
name=data_utils.rand_name('project'))['project']['id']
self.addCleanup(self.admin_client.projects_client.delete_project,
project)
self.admin_ef_client.add_endpoint_group_to_project(
endpoint_group_id=eg, project_id=project)
self.addCleanup(
self.admin_ef_client.delete_endpoint_group_from_project,
endpoint_group_id=eg, project_id=project)
resp = self.do_request('list_projects_for_endpoint_group',
client=self.ef_client,
endpoint_group_id=eg)['projects']
self.assertIn(project, [p['id'] for p in resp])
def test_identity_list_endpoints_associated_with_endpoint_group(self):
service = self.admin_client.identity_services_v3_client.create_service(
type=data_utils.rand_name('service'))['service']['id']
self.addCleanup(
self.admin_client.identity_services_v3_client.delete_service,
service)
endpoint = self.admin_client.endpoints_v3_client.create_endpoint(
interface='public',
url='http://localhost/foo',
service_id=service)['endpoint']['id']
self.addCleanup(self.admin_client.endpoints_v3_client.delete_endpoint,
endpoint)
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
resp = self.do_request('list_endpoints_for_endpoint_group',
client=self.ef_client,
endpoint_group_id=eg)['endpoints']
self.assertIn(endpoint, [e['id'] for e in resp])
def test_identity_get_endpoint_group_in_project(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
project = self.admin_client.projects_client.create_project(
name=data_utils.rand_name('project'))['project']['id']
self.addCleanup(self.admin_client.projects_client.delete_project,
project)
self.admin_ef_client.add_endpoint_group_to_project(
endpoint_group_id=eg, project_id=project)
self.addCleanup(
self.admin_ef_client.delete_endpoint_group_from_project,
endpoint_group_id=eg, project_id=project)
self.do_request('show_endpoint_group_for_project',
client=self.ef_client,
endpoint_group_id=eg,
project_id=project)
def test_identity_list_endpoint_groups_for_project(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
project = self.admin_client.projects_client.create_project(
name=data_utils.rand_name('project'))['project']['id']
self.addCleanup(self.admin_client.projects_client.delete_project,
project)
self.admin_ef_client.add_endpoint_group_to_project(
endpoint_group_id=eg, project_id=project)
self.addCleanup(
self.admin_ef_client.delete_endpoint_group_from_project,
endpoint_group_id=eg, project_id=project)
resp = self.do_request('list_endpoint_groups_for_project',
client=self.ef_client,
project_id=project)
self.assertIn(eg, [e['id'] for e in resp['endpoint_groups']])
def test_identity_add_endpoint_group_to_project(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
project = self.admin_client.projects_client.create_project(
name=data_utils.rand_name('project'))['project']['id']
self.addCleanup(self.admin_client.projects_client.delete_project,
project)
self.do_request('add_endpoint_group_to_project',
client=self.ef_client,
expected_status=204,
endpoint_group_id=eg,
project_id=project)
self.addCleanup(
self.admin_ef_client.delete_endpoint_group_from_project,
endpoint_group_id=eg, project_id=project)
def test_identity_remove_endpoint_group_from_project(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
project = self.admin_client.projects_client.create_project(
name=data_utils.rand_name('project'))['project']['id']
self.addCleanup(self.admin_client.projects_client.delete_project,
project)
self.admin_ef_client.add_endpoint_group_to_project(
endpoint_group_id=eg, project_id=project)
self.do_request('delete_endpoint_group_from_project',
client=self.ef_client,
expected_status=204,
endpoint_group_id=eg, project_id=project)
class SystemMemberTests(SystemAdminTests, base.BaseIdentityTest):
credentials = ['system_member', 'system_admin']
def test_identity_create_endpoint_group(self):
self.do_request('create_endpoint_group',
expected_status=exceptions.Forbidden,
client=self.eg_client,
**self.endpoint_group())
def test_identity_update_endpoint_group(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
# user can update an endpoint group
self.do_request('update_endpoint_group', client=self.eg_client,
expected_status=exceptions.Forbidden,
endpoint_group_id=eg,
description=data_utils.arbitrary_string())
# nonexistent endpoint group gives a 403
self.do_request('update_endpoint_group', client=self.eg_client,
expected_status=exceptions.Forbidden,
endpoint_group_id=data_utils.rand_uuid_hex(),
description=data_utils.arbitrary_string())
def test_identity_delete_endpoint_group(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
# user cannot delete an endpoint group
self.do_request('delete_endpoint_group',
expected_status=exceptions.Forbidden,
client=self.eg_client,
endpoint_group_id=eg)
# nonexistent endpoint group gives a 403
self.do_request('delete_endpoint_group',
expected_status=exceptions.Forbidden,
client=self.eg_client,
endpoint_group_id=data_utils.rand_uuid_hex())
def test_identity_add_endpoint_group_to_project(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
project = self.admin_client.projects_client.create_project(
name=data_utils.rand_name('project'))['project']['id']
self.addCleanup(self.admin_client.projects_client.delete_project,
project)
self.do_request('add_endpoint_group_to_project',
client=self.ef_client,
expected_status=exceptions.Forbidden,
endpoint_group_id=eg,
project_id=project)
def test_identity_remove_endpoint_group_from_project(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
project = self.admin_client.projects_client.create_project(
name=data_utils.rand_name('project'))['project']['id']
self.addCleanup(self.admin_client.projects_client.delete_project,
project)
self.admin_ef_client.add_endpoint_group_to_project(
endpoint_group_id=eg, project_id=project)
self.addCleanup(
self.admin_ef_client.delete_endpoint_group_from_project,
endpoint_group_id=eg, project_id=project)
self.do_request('delete_endpoint_group_from_project',
client=self.ef_client,
expected_status=exceptions.Forbidden,
endpoint_group_id=eg, project_id=project)
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def test_identity_get_endpoint_group(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
# user cannot get an endpoint group
self.do_request('show_endpoint_group', client=self.eg_client,
expected_status=exceptions.Forbidden,
endpoint_group_id=eg)
# nonexistent endpoint group gives a 403
self.do_request('show_endpoint_group',
expected_status=exceptions.Forbidden,
client=self.eg_client,
endpoint_group_id=data_utils.rand_uuid_hex())
def test_identity_list_endpoint_groups(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
self.do_request('list_endpoint_groups',
expected_status=exceptions.Forbidden,
client=self.eg_client)
def test_identity_list_projects_associated_with_endpoint_group(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
project = self.admin_client.projects_client.create_project(
name=data_utils.rand_name('project'))['project']['id']
self.addCleanup(self.admin_client.projects_client.delete_project,
project)
self.admin_ef_client.add_endpoint_group_to_project(
endpoint_group_id=eg, project_id=project)
self.addCleanup(
self.admin_ef_client.delete_endpoint_group_from_project,
endpoint_group_id=eg, project_id=project)
self.do_request('list_projects_for_endpoint_group',
client=self.ef_client,
expected_status=exceptions.Forbidden,
endpoint_group_id=eg)
def test_identity_list_endpoints_associated_with_endpoint_group(self):
service = self.admin_client.identity_services_v3_client.create_service(
type=data_utils.rand_name('service'))['service']['id']
self.addCleanup(
self.admin_client.identity_services_v3_client.delete_service,
service)
endpoint = self.admin_client.endpoints_v3_client.create_endpoint(
interface='public',
url='http://localhost/foo',
service_id=service)['endpoint']['id']
self.addCleanup(self.admin_client.endpoints_v3_client.delete_endpoint,
endpoint)
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
self.do_request('list_endpoints_for_endpoint_group',
client=self.ef_client,
expected_status=exceptions.Forbidden,
endpoint_group_id=eg)
def test_identity_get_endpoint_group_in_project(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
project = self.admin_client.projects_client.create_project(
name=data_utils.rand_name('project'))['project']['id']
self.addCleanup(self.admin_client.projects_client.delete_project,
project)
self.admin_ef_client.add_endpoint_group_to_project(
endpoint_group_id=eg, project_id=project)
self.addCleanup(
self.admin_ef_client.delete_endpoint_group_from_project,
endpoint_group_id=eg, project_id=project)
self.do_request('show_endpoint_group_for_project',
client=self.ef_client,
expected_status=exceptions.Forbidden,
endpoint_group_id=eg,
project_id=project)
def test_identity_list_endpoint_groups_for_project(self):
eg = self.admin_eg_client.create_endpoint_group(
**self.endpoint_group())['endpoint_group']['id']
self.addCleanup(self.admin_eg_client.delete_endpoint_group, eg)
project = self.admin_client.projects_client.create_project(
name=data_utils.rand_name('project'))['project']['id']
self.addCleanup(self.admin_client.projects_client.delete_project,
project)
self.admin_ef_client.add_endpoint_group_to_project(
endpoint_group_id=eg, project_id=project)
self.addCleanup(
self.admin_ef_client.delete_endpoint_group_from_project,
endpoint_group_id=eg, project_id=project)
self.do_request('list_endpoint_groups_for_project',
client=self.ef_client,
expected_status=exceptions.Forbidden,
project_id=project)
class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,283 @@
# Copyright 2020 SUSE LLC #
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin import clients
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacIdentityProviderTests(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacIdentityProviderTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.keystone_manager = clients.Manager(cls.persona.credentials)
persona_mgr = clients.Manager(cls.persona.credentials)
cls.client = persona_mgr.identity_providers_client
cls.admin_client = cls.os_system_admin
admin_mgr = clients.Manager(cls.admin_client.credentials)
cls.admin_idp_client = admin_mgr.identity_providers_client
@abc.abstractmethod
def test_identity_create_identity_provider(self):
"""Test identity:create_identity_provider policy.
This test must check:
* whether the persona can create an identity provider
"""
pass
@abc.abstractmethod
def test_identity_get_identity_provider(self):
"""Test identity:get_identity_provider policy.
This test must check:
* whether the persona can get an identity provider
* whether the persona can get an identity provider that does not
exist
"""
pass
@abc.abstractmethod
def test_identity_list_identity_providers(self):
"""Test identity:list_identity_providers policy.
This test must check:
* whether the persona can list all identity providers
"""
pass
@abc.abstractmethod
def test_identity_update_identity_provider(self):
"""Test identity:update_identity_provider policy.
This test must check:
* whether the persona can update an identity provider
* whether the persona can update an identity provider that does not
exist
"""
pass
@abc.abstractmethod
def test_identity_delete_identity_provider(self):
"""Test identity:delete_identity_provider policy.
This test must check
* whether the persona can delete an identity provider
* whether the persona can delete an identity provider that does not
exist
"""
pass
class SystemAdminTests(IdentityV3RbacIdentityProviderTests,
base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_identity_provider(self):
idp = self.do_request(
'create_identity_provider', expected_status=201,
idp_id=data_utils.rand_name()
)['identity_provider']
self.addCleanup(
self.admin_client.domains_client.delete_domain, idp['domain_id'])
self.addCleanup(
self.admin_client.domains_client.update_domain,
idp['domain_id'], enabled=False)
self.addCleanup(
self.admin_idp_client.delete_identity_provider, idp['id'])
def test_identity_get_identity_provider(self):
idp = self.admin_idp_client.create_identity_provider(
idp_id=data_utils.rand_name())['identity_provider']
self.addCleanup(
self.admin_client.domains_client.delete_domain, idp['domain_id'])
self.addCleanup(
self.admin_client.domains_client.update_domain,
idp['domain_id'], enabled=False)
self.addCleanup(
self.admin_idp_client.delete_identity_provider, idp['id'])
self.do_request('show_identity_provider', idp_id=idp['id'])
# user gets a 404 for nonexistent idp
self.do_request('show_identity_provider',
expected_status=exceptions.NotFound,
idp_id=data_utils.rand_uuid_hex())
def test_identity_list_identity_providers(self):
idp = self.admin_idp_client.create_identity_provider(
idp_id=data_utils.rand_name())['identity_provider']
self.addCleanup(
self.admin_client.domains_client.delete_domain, idp['domain_id'])
self.addCleanup(
self.admin_client.domains_client.update_domain,
idp['domain_id'], enabled=False)
self.addCleanup(
self.admin_idp_client.delete_identity_provider, idp['id'])
resp = self.do_request('list_identity_providers')
self.assertIn(idp['id'], [i['id'] for i in resp['identity_providers']])
def test_identity_update_identity_provider(self):
idp = self.admin_idp_client.create_identity_provider(
idp_id=data_utils.rand_name())['identity_provider']
self.addCleanup(
self.admin_client.domains_client.delete_domain, idp['domain_id'])
self.addCleanup(
self.admin_client.domains_client.update_domain,
idp['domain_id'], enabled=False)
self.addCleanup(
self.admin_idp_client.delete_identity_provider, idp['id'])
self.do_request('update_identity_provider',
idp_id=idp['id'],
description=data_utils.arbitrary_string())
# user gets a 404 for nonexistent idp
self.do_request('update_identity_provider',
expected_status=exceptions.NotFound,
idp_id=data_utils.rand_uuid_hex(),
description=data_utils.arbitrary_string())
def test_identity_delete_identity_provider(self):
idp = self.admin_idp_client.create_identity_provider(
idp_id=data_utils.rand_name())['identity_provider']
self.addCleanup(
self.admin_client.domains_client.delete_domain, idp['domain_id'])
self.addCleanup(
self.admin_client.domains_client.update_domain,
idp['domain_id'], enabled=False)
self.do_request('delete_identity_provider', expected_status=204,
idp_id=idp['id'])
# user gets a 404 for nonexistent idp
self.do_request('delete_identity_provider',
expected_status=exceptions.NotFound,
idp_id=data_utils.rand_uuid_hex())
class SystemMemberTests(SystemAdminTests, base.BaseIdentityTest):
credentials = ['system_member', 'system_admin']
def test_identity_create_identity_provider(self):
self.do_request('create_identity_provider',
expected_status=exceptions.Forbidden,
idp_id=data_utils.rand_name())
def test_identity_update_identity_provider(self):
idp = self.admin_idp_client.create_identity_provider(
idp_id=data_utils.rand_name())['identity_provider']
self.addCleanup(
self.admin_client.domains_client.delete_domain, idp['domain_id'])
self.addCleanup(
self.admin_client.domains_client.update_domain,
idp['domain_id'], enabled=False)
self.addCleanup(
self.admin_idp_client.delete_identity_provider, idp['id'])
self.do_request('update_identity_provider',
expected_status=exceptions.Forbidden,
idp_id=idp['id'],
description=data_utils.arbitrary_string())
# user gets a 403 for nonexistent idp
self.do_request('update_identity_provider',
expected_status=exceptions.Forbidden,
idp_id=data_utils.rand_uuid_hex(),
description=data_utils.arbitrary_string())
def test_identity_delete_identity_provider(self):
idp = self.admin_idp_client.create_identity_provider(
idp_id=data_utils.rand_name())['identity_provider']
self.addCleanup(
self.admin_client.domains_client.delete_domain, idp['domain_id'])
self.addCleanup(
self.admin_client.domains_client.update_domain,
idp['domain_id'], enabled=False)
self.addCleanup(
self.admin_idp_client.delete_identity_provider, idp['id'])
self.do_request('delete_identity_provider',
expected_status=exceptions.Forbidden,
idp_id=idp['id'])
# user gets a 403 for nonexistent idp
self.do_request('delete_identity_provider',
expected_status=exceptions.Forbidden,
idp_id=data_utils.rand_uuid_hex())
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def test_identity_get_identity_provider(self):
idp = self.admin_idp_client.create_identity_provider(
idp_id=data_utils.rand_name())['identity_provider']
self.addCleanup(
self.admin_client.domains_client.delete_domain, idp['domain_id'])
self.addCleanup(
self.admin_client.domains_client.update_domain,
idp['domain_id'], enabled=False)
self.addCleanup(
self.admin_idp_client.delete_identity_provider, idp['id'])
self.do_request('show_identity_provider',
expected_status=exceptions.Forbidden,
idp_id=idp['id'])
# user gets a 403 for nonexistent idp
self.do_request('show_identity_provider',
expected_status=exceptions.Forbidden,
idp_id=data_utils.rand_uuid_hex())
def test_identity_list_identity_providers(self):
idp = self.admin_idp_client.create_identity_provider(
idp_id=data_utils.rand_name())['identity_provider']
self.addCleanup(
self.admin_client.domains_client.delete_domain, idp['domain_id'])
self.addCleanup(
self.admin_client.domains_client.update_domain,
idp['domain_id'], enabled=False)
self.addCleanup(
self.admin_idp_client.delete_identity_provider, idp['id'])
self.do_request('list_identity_providers',
expected_status=exceptions.Forbidden)
class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,257 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacImpliedRoleTest(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacImpliedRoleTest, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.roles_v3_client
cls.admin_client = cls.os_system_admin
cls.admin_roles_client = cls.admin_client.roles_v3_client
@classmethod
def resource_setup(cls):
super(IdentityV3RbacImpliedRoleTest, cls).resource_setup()
cls.prior_role = cls.admin_roles_client.create_role(
name=data_utils.rand_name('prior_role'))['role']['id']
cls.addClassResourceCleanup(
cls.admin_roles_client.delete_role, cls.prior_role)
cls.implied_role = cls.admin_roles_client.create_role(
name=data_utils.rand_name('implied_role'))['role']['id']
cls.addClassResourceCleanup(
cls.admin_roles_client.delete_role, cls.implied_role)
@abc.abstractmethod
def test_identity_create_implied_role(self):
"""Test identity:create_implied_role policy.
This test must check:
* whether the persona can create an implied role
"""
pass
@abc.abstractmethod
def test_identity_get_implied_role(self):
"""Test identity:get_implied_role policy.
This test must check:
* whether the persona can get an implied role
"""
pass
@abc.abstractmethod
def test_identity_list_implied_roles(self):
"""Test identity:list_implied_roles policy.
This test must check:
* whether the persona can list implied roles
"""
pass
@abc.abstractmethod
def test_identity_list_role_inference_rules(self):
"""Test identity:list_role_inference_rules policy.
This test must check:
* whether the persona can list role inference rules
"""
pass
@abc.abstractmethod
def test_identity_delete_implied_role(self):
"""Test identity:delete_implied_role policy.
This test must check
* whether the persona can delete an implied role
"""
pass
@abc.abstractmethod
def test_identity_check_implied_role(self):
"""Test identity:check_implied_role policy.
This test must check:
* whether the persona can check an association between two roles
"""
pass
class SystemAdminTests(IdentityV3RbacImpliedRoleTest, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_implied_role(self):
self.do_request('create_role_inference_rule',
expected_status=201,
prior_role=self.prior_role,
implies_role=self.implied_role)
self.addCleanup(self.admin_roles_client.delete_role_inference_rule,
prior_role=self.prior_role,
implies_role=self.implied_role)
def test_identity_get_implied_role(self):
self.admin_roles_client.create_role_inference_rule(
prior_role=self.prior_role, implies_role=self.implied_role)
self.addCleanup(self.admin_roles_client.delete_role_inference_rule,
prior_role=self.prior_role,
implies_role=self.implied_role)
self.do_request('show_role_inference_rule',
prior_role=self.prior_role,
implies_role=self.implied_role)
def test_identity_list_implied_roles(self):
self.admin_roles_client.create_role_inference_rule(
prior_role=self.prior_role, implies_role=self.implied_role)
self.addCleanup(self.admin_roles_client.delete_role_inference_rule,
prior_role=self.prior_role,
implies_role=self.implied_role)
self.do_request('list_role_inferences_rules',
prior_role=self.prior_role)
def test_identity_list_role_inference_rules(self):
self.admin_roles_client.create_role_inference_rule(
prior_role=self.prior_role, implies_role=self.implied_role)
self.addCleanup(self.admin_roles_client.delete_role_inference_rule,
prior_role=self.prior_role,
implies_role=self.implied_role)
self.do_request('list_all_role_inference_rules')
def test_identity_delete_implied_role(self):
self.admin_roles_client.create_role_inference_rule(
prior_role=self.prior_role, implies_role=self.implied_role)
self.do_request('delete_role_inference_rule',
expected_status=204,
prior_role=self.prior_role,
implies_role=self.implied_role)
def test_identity_check_implied_role(self):
self.admin_roles_client.create_role_inference_rule(
prior_role=self.prior_role, implies_role=self.implied_role)
self.addCleanup(self.admin_roles_client.delete_role_inference_rule,
prior_role=self.prior_role,
implies_role=self.implied_role)
self.do_request('check_role_inference_rule',
expected_status=204,
prior_role=self.prior_role,
implies_role=self.implied_role)
class SystemMemberTests(SystemAdminTests):
credentials = ['system_member', 'system_admin']
def test_identity_create_implied_role(self):
self.do_request('create_role_inference_rule',
expected_status=exceptions.Forbidden,
prior_role=self.prior_role,
implies_role=self.implied_role)
def test_identity_delete_implied_role(self):
self.admin_roles_client.create_role_inference_rule(
prior_role=self.prior_role, implies_role=self.implied_role)
self.addCleanup(self.admin_roles_client.delete_role_inference_rule,
prior_role=self.prior_role,
implies_role=self.implied_role)
self.do_request('delete_role_inference_rule',
expected_status=exceptions.Forbidden,
prior_role=self.prior_role,
implies_role=self.implied_role)
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests):
credentials = ['domain_admin', 'system_admin']
def test_identity_get_implied_role(self):
self.admin_roles_client.create_role_inference_rule(
prior_role=self.prior_role, implies_role=self.implied_role)
self.addCleanup(self.admin_roles_client.delete_role_inference_rule,
prior_role=self.prior_role,
implies_role=self.implied_role)
self.do_request('show_role_inference_rule',
expected_status=exceptions.Forbidden,
prior_role=self.prior_role,
implies_role=self.implied_role)
def test_identity_list_implied_roles(self):
self.admin_roles_client.create_role_inference_rule(
prior_role=self.prior_role, implies_role=self.implied_role)
self.addCleanup(self.admin_roles_client.delete_role_inference_rule,
prior_role=self.prior_role,
implies_role=self.implied_role)
self.do_request('list_role_inferences_rules',
expected_status=exceptions.Forbidden,
prior_role=self.prior_role)
def test_identity_list_role_inference_rules(self):
self.admin_roles_client.create_role_inference_rule(
prior_role=self.prior_role, implies_role=self.implied_role)
self.addCleanup(self.admin_roles_client.delete_role_inference_rule,
prior_role=self.prior_role,
implies_role=self.implied_role)
self.do_request('list_all_role_inference_rules',
expected_status=exceptions.Forbidden)
def test_identity_check_implied_role(self):
self.admin_roles_client.create_role_inference_rule(
prior_role=self.prior_role, implies_role=self.implied_role)
self.addCleanup(self.admin_roles_client.delete_role_inference_rule,
prior_role=self.prior_role,
implies_role=self.implied_role)
self.do_request('check_role_inference_rule',
expected_status=exceptions.Forbidden,
prior_role=self.prior_role,
implies_role=self.implied_role)
class DomainMemberTests(DomainAdminTests):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,391 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin import clients
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacLimitTests(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacLimitTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
persona_mgr = clients.Manager(cls.persona.credentials)
cls.client = persona_mgr.limits_client
cls.admin_client = cls.os_system_admin
admin_mgr = clients.Manager(cls.admin_client.credentials)
cls.admin_reglim_client = admin_mgr.registered_limits_client
cls.admin_limits_client = admin_mgr.limits_client
@classmethod
def resource_setup(cls):
cls.region_id = cls.admin_client.regions_client.create_region(
region_id=data_utils.rand_name())['region']['id']
cls.addClassResourceCleanup(
cls.admin_client.regions_client.delete_region,
cls.region_id)
svc_client = cls.admin_client.identity_services_v3_client
cls.service_id = svc_client.create_service(
type=data_utils.rand_name())['service']['id']
cls.addClassResourceCleanup(svc_client.delete_service, cls.service_id)
cls.own_domain = cls.persona.credentials.domain_id
cls.other_domain = cls.admin_client.domains_client.create_domain(
name=data_utils.rand_name())['domain']['id']
cls.addClassResourceCleanup(
cls.admin_client.domains_client.delete_domain, cls.other_domain)
cls.addClassResourceCleanup(
cls.admin_client.domains_client.update_domain,
domain_id=cls.other_domain,
enabled=False)
cls.own_project = cls.persona.credentials.project_id
# if project-scoped, use existing project
# else create project in domain
if not cls.own_project:
cls.own_project = cls.admin_client.projects_client.create_project(
name=data_utils.rand_name(),
domain_id=cls.own_domain)['project']['id']
cls.addClassResourceCleanup(
cls.admin_client.projects_client.delete_project,
cls.own_project)
cls.other_project = cls.admin_client.projects_client.create_project(
name=data_utils.rand_name(),
domain_id=cls.other_domain)['project']['id']
cls.addClassResourceCleanup(
cls.admin_client.projects_client.delete_project, cls.other_project)
cls.reg_limit = cls.admin_reglim_client.create_registered_limits(
payload=[{
"service_id": cls.service_id,
"region_id": cls.region_id,
"resource_name": data_utils.rand_name(),
"default_limit": 5
}])['registered_limits'][0]
cls.addClassResourceCleanup(
cls.admin_reglim_client.delete_registered_limit,
registered_limit_id=cls.reg_limit['id'])
def limits(self, project_id=None):
return [
{
"service_id": self.service_id,
"region_id": self.region_id,
"project_id": project_id or self.other_project,
"resource_name": self.reg_limit['resource_name'],
"resource_limit": 10
}
]
@abc.abstractmethod
def test_identity_get_limit_model(self):
"""Test identity:get_limit_model policy.
This test must check:
* whether the persona can get the limit model
"""
pass
@abc.abstractmethod
def test_identity_create_limits(self):
"""Test identity:create_limits policy.
This test must check:
* whether the persona can create a project limit for a project in any
domain
* whether the persona can create a project limit for a project in own
domain
* whether the persona can create a project limit for own project
"""
pass
@abc.abstractmethod
def test_identity_list_limits(self):
"""Test identity:list_limits policy.
This test must check:
* whether the persona can list limits for any project
* whether the persona can list limits for projects in own domain
* whether the persona can list limits for own project
"""
pass
@abc.abstractmethod
def test_identity_get_limit(self):
"""Test identity:get_limit policy.
This test must check:
* whether the persona can get a project limit for a project in any
domain
* whether the persona can get a project limit for a project in own
domain
* whether the persona can get a project limit for own project
"""
pass
@abc.abstractmethod
def test_identity_update_limit(self):
"""Test identity:update_limit policy.
This test must check:
* whether the persona can update a project limit for a project in any
domain
* whether the persona can update a project limit for a project in own
domain
* whether the persona can update a project limit for own project
"""
pass
@abc.abstractmethod
def test_identity_delete_limit(self):
"""Test identity:delete_limit policy.
This test must check:
* whether the persona can delete a project limit for a project limit
in any domain
* whether the persona can delete a project limit for a project limit
in own domain
* whether the persona can delete a project limit for a project limit
own project
"""
pass
class SystemAdminTests(IdentityV3RbacLimitTests, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_get_limit_model(self):
self.do_request('limits_model')
def test_identity_create_limits(self):
resp = self.do_request('create_limits',
expected_status=201,
payload=self.limits())
self.addCleanup(
self.admin_limits_client.delete_limit,
limit_id=resp['limits'][0]['id'])
def test_identity_list_limits(self):
reg_limit_id = self.admin_limits_client.create_limits(
payload=self.limits())['limits'][0]['id']
self.addCleanup(
self.admin_limits_client.delete_limit,
limit_id=reg_limit_id)
resp = self.do_request('list_limits')
self.assertIn(
reg_limit_id, [rl['id'] for rl in resp['limits']])
def test_identity_get_limit(self):
reg_limit_id = self.admin_limits_client.create_limits(
payload=self.limits())['limits'][0]['id']
self.addCleanup(
self.admin_limits_client.delete_limit,
limit_id=reg_limit_id)
self.do_request('show_limit',
limit_id=reg_limit_id)
def test_identity_update_limit(self):
reg_limit_id = self.admin_limits_client.create_limits(
payload=self.limits())['limits'][0]['id']
self.addCleanup(
self.admin_limits_client.delete_limit,
limit_id=reg_limit_id)
updated = {'description': data_utils.arbitrary_string()}
self.do_request('update_limit',
limit_id=reg_limit_id,
limit=updated)
def test_identity_delete_limit(self):
reg_limit_id = self.admin_limits_client.create_limits(
payload=self.limits())['limits'][0]['id']
self.do_request('delete_limit',
expected_status=204,
limit_id=reg_limit_id)
class SystemMemberTests(SystemAdminTests):
credentials = ['system_member', 'system_admin']
def test_identity_create_limits(self):
self.do_request('create_limits',
expected_status=exceptions.Forbidden,
payload=self.limits())
def test_identity_update_limit(self):
reg_limit_id = self.admin_limits_client.create_limits(
payload=self.limits())['limits'][0]['id']
self.addCleanup(
self.admin_limits_client.delete_limit,
limit_id=reg_limit_id)
updated = {'description': data_utils.arbitrary_string()}
self.do_request('update_limit',
expected_status=exceptions.Forbidden,
limit_id=reg_limit_id,
limit=updated)
def test_identity_delete_limit(self):
reg_limit_id = self.admin_limits_client.create_limits(
payload=self.limits())['limits'][0]['id']
self.addCleanup(
self.admin_limits_client.delete_limit,
limit_id=reg_limit_id)
self.do_request('delete_limit',
expected_status=exceptions.Forbidden,
limit_id=reg_limit_id)
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(IdentityV3RbacLimitTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def test_identity_get_limit_model(self):
self.do_request('limits_model')
def test_identity_create_limits(self):
# cannot create limit in arbitrary project
self.do_request('create_limits',
expected_status=exceptions.Forbidden,
payload=self.limits())
# cannot create limit in project in own domain
self.do_request('create_limits',
expected_status=exceptions.Forbidden,
payload=self.limits(project_id=self.own_project))
def test_identity_list_limits(self):
# random project
reg_limit_1 = self.admin_limits_client.create_limits(
payload=self.limits())['limits'][0]['id']
self.addCleanup(
self.admin_limits_client.delete_limit,
limit_id=reg_limit_1)
# project in own domain
reg_limit_2 = self.admin_limits_client.create_limits(
payload=self.limits(project_id=self.own_project)
)['limits'][0]['id']
self.addCleanup(
self.admin_limits_client.delete_limit,
limit_id=reg_limit_2)
resp = self.do_request('list_limits')
# should not see limit for other project
self.assertNotIn(
reg_limit_1, [rl['id'] for rl in resp['limits']])
# should see limit for project in own domain
self.assertIn(
reg_limit_2, [rl['id'] for rl in resp['limits']])
def test_identity_get_limit(self):
# random project
reg_limit_1 = self.admin_limits_client.create_limits(
payload=self.limits())['limits'][0]['id']
self.addCleanup(
self.admin_limits_client.delete_limit,
limit_id=reg_limit_1)
# project in own domain
reg_limit_2 = self.admin_limits_client.create_limits(
payload=self.limits(project_id=self.own_project)
)['limits'][0]['id']
self.addCleanup(
self.admin_limits_client.delete_limit,
limit_id=reg_limit_2)
# cannot get limit for other project
self.do_request('show_limit',
expected_status=exceptions.Forbidden,
limit_id=reg_limit_1)
# can get limit for project in own domain
self.do_request('show_limit',
limit_id=reg_limit_2)
def test_identity_update_limit(self):
# cannot update limit for arbitrary project
reg_limit_id = self.admin_limits_client.create_limits(
payload=self.limits())['limits'][0]['id']
self.addCleanup(
self.admin_limits_client.delete_limit,
limit_id=reg_limit_id)
updated = {'description': data_utils.arbitrary_string()}
self.do_request('update_limit',
expected_status=exceptions.Forbidden,
limit_id=reg_limit_id,
limit=updated)
# cannot update limit for project in own domain
reg_limit_id = self.admin_limits_client.create_limits(
payload=self.limits(project_id=self.own_project)
)['limits'][0]['id']
self.addCleanup(
self.admin_limits_client.delete_limit,
limit_id=reg_limit_id)
updated = {'description': data_utils.arbitrary_string()}
self.do_request('update_limit',
expected_status=exceptions.Forbidden,
limit_id=reg_limit_id,
limit=updated)
def test_identity_delete_limit(self):
# cannot delete limit for arbitrary project
reg_limit_id = self.admin_limits_client.create_limits(
payload=self.limits())['limits'][0]['id']
self.addCleanup(
self.admin_limits_client.delete_limit,
limit_id=reg_limit_id)
self.do_request('delete_limit',
expected_status=exceptions.Forbidden,
limit_id=reg_limit_id)
# cannot delete limit for project in own domain
reg_limit_id = self.admin_limits_client.create_limits(
payload=self.limits(project_id=self.own_project)
)['limits'][0]['id']
self.addCleanup(
self.admin_limits_client.delete_limit,
limit_id=reg_limit_id)
self.do_request('delete_limit',
expected_status=exceptions.Forbidden,
limit_id=reg_limit_id)
class DomainMemberTests(DomainAdminTests):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectMemberTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,255 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin import clients
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacMappingTests(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacMappingTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.keystone_manager = clients.Manager(cls.persona.credentials)
persona_mgr = clients.Manager(cls.persona.credentials)
cls.client = persona_mgr.mapping_rules_client
admin_client = cls.os_system_admin
admin_mgr = clients.Manager(admin_client.credentials)
cls.admin_mapping_client = admin_mgr.mapping_rules_client
@abc.abstractmethod
def test_identity_create_mapping(self):
"""Test identity:create_mapping policy.
This test must check:
* whether the persona can create a mapping
"""
pass
@abc.abstractmethod
def test_identity_get_mapping(self):
"""Test identity:get_mapping policy.
This test must check:
* whether the persona can get a mapping
* whether the persona can get a mapping that does not exist
"""
pass
@abc.abstractmethod
def test_identity_list_mappings(self):
"""Test identity:list_mappings policy.
This test must check:
* whether the persona can list all mappings
"""
pass
@abc.abstractmethod
def test_identity_update_mapping(self):
"""Test identity:update_mapping policy.
This test must check:
* whether the persona can update a mapping
* whether the persona can update a mapping that does not
exist
"""
pass
@abc.abstractmethod
def test_identity_delete_mapping(self):
"""Test identity:delete_mapping policy.
This test must check
* whether the persona can delete a mapping
* whether the persona can delete a mapping that does not
exist
"""
pass
_RULES = {
"rules":
[{
"local": [],
"remote": [{"type": data_utils.rand_name()}]
}]
}
class SystemAdminTests(IdentityV3RbacMappingTests, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_mapping(self):
mapping_id = self.do_request(
'create_mapping_rule', expected_status=201,
mapping_id=data_utils.rand_name(),
rules=_RULES
)['mapping']['id']
self.addCleanup(self.admin_mapping_client.delete_mapping_rule,
mapping_id)
def test_identity_get_mapping(self):
mapping_id = self.admin_mapping_client.create_mapping_rule(
mapping_id=data_utils.rand_name(),
rules=_RULES)['mapping']['id']
self.addCleanup(self.admin_mapping_client.delete_mapping_rule,
mapping_id)
self.do_request('show_mapping_rule', mapping_id=mapping_id)
# user gets a 404 for nonexistent mapping
self.do_request('show_mapping_rule',
expected_status=exceptions.NotFound,
mapping_id=data_utils.rand_uuid_hex())
def test_identity_list_mappings(self):
mapping_id = self.admin_mapping_client.create_mapping_rule(
mapping_id=data_utils.rand_name(),
rules=_RULES)['mapping']['id']
self.addCleanup(self.admin_mapping_client.delete_mapping_rule,
mapping_id)
resp = self.do_request('list_mapping_rules')
self.assertIn(mapping_id, [i['id'] for i in resp['mappings']])
def test_identity_update_mapping(self):
mapping_id = self.admin_mapping_client.create_mapping_rule(
mapping_id=data_utils.rand_name(),
rules=_RULES)['mapping']['id']
self.addCleanup(self.admin_mapping_client.delete_mapping_rule,
mapping_id)
self.do_request('update_mapping_rule',
mapping_id=mapping_id,
rules=_RULES)
# user gets a 404 for nonexistent mapping
self.do_request('update_mapping_rule',
expected_status=exceptions.NotFound,
mapping_id=data_utils.rand_uuid_hex(),
rules=_RULES)
def test_identity_delete_mapping(self):
mapping_id = self.admin_mapping_client.create_mapping_rule(
mapping_id=data_utils.rand_name(),
rules=_RULES)['mapping']['id']
self.do_request('delete_mapping_rule', expected_status=204,
mapping_id=mapping_id)
# user gets a 404 for nonexistent mapping
self.do_request('delete_mapping_rule',
expected_status=exceptions.NotFound,
mapping_id=mapping_id)
class SystemMemberTests(SystemAdminTests, base.BaseIdentityTest):
credentials = ['system_member', 'system_admin']
def test_identity_create_mapping(self):
self.do_request('create_mapping_rule',
expected_status=exceptions.Forbidden,
mapping_id=data_utils.rand_name(),
rules=_RULES)
def test_identity_update_mapping(self):
mapping_id = self.admin_mapping_client.create_mapping_rule(
mapping_id=data_utils.rand_name(),
rules=_RULES)['mapping']['id']
self.addCleanup(self.admin_mapping_client.delete_mapping_rule,
mapping_id)
self.do_request('update_mapping_rule',
expected_status=exceptions.Forbidden,
mapping_id=mapping_id,
rules=_RULES)
# user gets a 403 for nonexistent mapping
self.do_request('update_mapping_rule',
expected_status=exceptions.Forbidden,
mapping_id=data_utils.rand_uuid_hex(),
rules=_RULES)
def test_identity_delete_mapping(self):
mapping_id = self.admin_mapping_client.create_mapping_rule(
mapping_id=data_utils.rand_name(),
rules=_RULES)['mapping']['id']
self.addCleanup(self.admin_mapping_client.delete_mapping_rule,
mapping_id)
self.do_request('delete_mapping_rule',
expected_status=exceptions.Forbidden,
mapping_id=mapping_id)
# user gets a 403 for nonexistent mapping
self.do_request('delete_mapping_rule',
expected_status=exceptions.Forbidden,
mapping_id=mapping_id)
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def test_identity_get_mapping(self):
mapping_id = self.admin_mapping_client.create_mapping_rule(
mapping_id=data_utils.rand_name(),
rules=_RULES)['mapping']['id']
self.addCleanup(self.admin_mapping_client.delete_mapping_rule,
mapping_id)
self.do_request('show_mapping_rule',
expected_status=exceptions.Forbidden,
mapping_id=mapping_id)
# user gets a 403 for nonexistent mapping
self.do_request('show_mapping_rule',
expected_status=exceptions.Forbidden,
mapping_id=data_utils.rand_uuid_hex())
def test_identity_list_mappings(self):
mapping_id = self.admin_mapping_client.create_mapping_rule(
mapping_id=data_utils.rand_name(),
rules=_RULES)['mapping']['id']
self.addCleanup(self.admin_mapping_client.delete_mapping_rule,
mapping_id)
self.do_request('list_mapping_rules',
expected_status=exceptions.Forbidden)
class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,232 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacPolicyTests(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacPolicyTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.policies_client
admin_client = cls.os_system_admin
cls.admin_policies_client = admin_client.policies_client
def policy(self):
return {
'blob': data_utils.rand_uuid_hex(),
'type': data_utils.rand_uuid_hex()
}
@abc.abstractmethod
def test_identity_create_policy(self):
"""Test identity:create_policy policy.
This test must check:
* whether the persona can create a policy
"""
pass
@abc.abstractmethod
def test_identity_get_policy(self):
"""Test identity:get_policy policy.
This test must check:
* whether the persona can get a policy
* whether the persona can get a policy that does not exist
"""
pass
@abc.abstractmethod
def test_identity_list_policies(self):
"""Test identity:list_policies policy.
This test must check:
* whether the persona can list all policies
"""
pass
@abc.abstractmethod
def test_identity_update_policy(self):
"""Test identity:update_policy policy.
This test must check:
* whether the persona can update a policy
* whether the persona can update a policy that does not exist
"""
pass
@abc.abstractmethod
def test_identity_delete_policy(self):
"""Test identity:delete_policy policy.
This test must check
* whether the persona can delete a policy
* whether the persona can delete a policy that does not exist
"""
pass
class SystemAdminTests(IdentityV3RbacPolicyTests, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_policy(self):
policy_id = self.do_request(
'create_policy', expected_status=201,
**self.policy())['policy']['id']
self.addCleanup(
self.admin_policies_client.delete_policy,
policy_id=policy_id)
def test_identity_get_policy(self):
policy_id = self.admin_policies_client.create_policy(
**self.policy())['policy']['id']
self.addCleanup(
self.admin_policies_client.delete_policy,
policy_id=policy_id)
self.do_request('show_policy', policy_id=policy_id)
# user gets a 404 for nonexistent policy
self.do_request('show_policy', expected_status=exceptions.NotFound,
policy_id=data_utils.rand_uuid_hex())
def test_identity_list_policies(self):
policy_id = self.admin_policies_client.create_policy(
**self.policy())['policy']['id']
self.addCleanup(
self.admin_policies_client.delete_policy,
policy_id=policy_id)
resp = self.do_request('list_policies')
self.assertIn(policy_id, [e['id'] for e in resp['policies']])
def test_identity_update_policy(self):
policy_id = self.admin_policies_client.create_policy(
**self.policy())['policy']['id']
self.addCleanup(
self.admin_policies_client.delete_policy,
policy_id=policy_id)
self.do_request('update_policy',
policy_id=policy_id,
blob=data_utils.rand_uuid_hex())
# user gets a 404 for nonexistent policy
self.do_request('update_policy', expected_status=exceptions.NotFound,
policy_id=data_utils.rand_uuid_hex(),
blob=data_utils.rand_uuid_hex())
def test_identity_delete_policy(self):
policy_id = self.admin_policies_client.create_policy(
**self.policy())['policy']['id']
self.do_request('delete_policy', expected_status=204,
policy_id=policy_id)
# user gets a 404 for nonexistent policy
self.do_request('delete_policy', expected_status=exceptions.NotFound,
policy_id=data_utils.rand_uuid_hex())
class SystemMemberTests(SystemAdminTests, base.BaseIdentityTest):
credentials = ['system_member', 'system_admin']
def test_identity_create_policy(self):
self.do_request(
'create_policy', expected_status=exceptions.Forbidden,
**self.policy())
def test_identity_update_policy(self):
policy_id = self.admin_policies_client.create_policy(
**self.policy())['policy']['id']
self.addCleanup(
self.admin_policies_client.delete_policy,
policy_id=policy_id)
self.do_request('update_policy', expected_status=exceptions.Forbidden,
policy_id=policy_id,
blob=data_utils.rand_uuid_hex())
# user gets a 403 for nonexistent policy
self.do_request('update_policy', expected_status=exceptions.Forbidden,
policy_id=data_utils.rand_uuid_hex(),
blob=data_utils.rand_uuid_hex())
def test_identity_delete_policy(self):
policy_id = self.admin_policies_client.create_policy(
**self.policy())['policy']['id']
self.do_request('delete_policy',
expected_status=exceptions.Forbidden,
policy_id=policy_id)
# user gets a 403 for nonexistent policy
self.do_request('delete_policy', expected_status=exceptions.Forbidden,
policy_id=data_utils.rand_uuid_hex())
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def test_identity_get_policy(self):
policy_id = self.admin_policies_client.create_policy(
**self.policy())['policy']['id']
self.addCleanup(
self.admin_policies_client.delete_policy,
policy_id=policy_id)
self.do_request('show_policy', expected_status=exceptions.Forbidden,
policy_id=policy_id)
# user gets a 403 for nonexistent policy
self.do_request('show_policy', expected_status=exceptions.Forbidden,
policy_id=data_utils.rand_uuid_hex())
def test_identity_list_policies(self):
policy_id = self.admin_policies_client.create_policy(
**self.policy())['policy']['id']
self.addCleanup(
self.admin_policies_client.delete_policy,
policy_id=policy_id)
self.do_request('list_policies', expected_status=exceptions.Forbidden)
class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,469 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacPolicyAssociationTests(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacPolicyAssociationTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.policies_client
cls.admin_client = cls.os_system_admin
cls.admin_policies_client = cls.admin_client.policies_client
@classmethod
def resource_setup(cls):
super(IdentityV3RbacPolicyAssociationTests, cls).resource_setup()
cls.policy_id = cls.admin_policies_client.create_policy(
blob=data_utils.rand_uuid_hex(),
type=data_utils.rand_uuid_hex())['policy']['id']
cls.addClassResourceCleanup(
cls.admin_policies_client.delete_policy,
policy_id=cls.policy_id)
cls.region_id = cls.admin_client.regions_client.create_region(
region_id=data_utils.rand_name())['region']['id']
cls.addClassResourceCleanup(
cls.admin_client.regions_client.delete_region,
cls.region_id)
svc_client = cls.admin_client.identity_services_v3_client
cls.service_id = svc_client.create_service(
type=data_utils.rand_name())['service']['id']
cls.addClassResourceCleanup(svc_client.delete_service, cls.service_id)
cls.endpoint_id = cls.admin_client.endpoints_v3_client.create_endpoint(
interface='public',
url='http://localhost/foo',
service_id=cls.service_id)['endpoint']['id']
cls.addClassResourceCleanup(
cls.admin_client.endpoints_v3_client.delete_endpoint,
endpoint_id=cls.endpoint_id)
@abc.abstractmethod
def test_identity_create_policy_association_for_endpoint(self):
"""Test identity:create_policy_association_for_endpoint policy.
This test must check:
* whether the persona can associate a policy with an endpoint
"""
pass
@abc.abstractmethod
def test_identity_create_policy_association_for_service(self):
"""Test identity:create_policy_association_for_service policy.
This test must check:
* whether the persona can associate a policy with a service
"""
pass
@abc.abstractmethod
def test_identity_create_policy_association_for_region_and_service(self):
"""Test identity:create_policy_association_for_region_and_service.
This test must check:
* whether the persona can associate a policy with a region and
service
"""
pass
@abc.abstractmethod
def test_identity_check_policy_association_for_endpoint(self):
"""Test identity:check_policy_association_for_endpoint policy.
This test must check:
* whether the persona can check a policy association for an endpoint
"""
pass
@abc.abstractmethod
def test_identity_check_policy_association_for_service(self):
"""Test identity:check_policy_association_for_service policy.
This test must check:
* whether the persona can check a policy association for a service
"""
pass
@abc.abstractmethod
def test_identity_check_policy_association_for_region_and_service(self):
"""Test identity:check_policy_association_for_region_and_service.
This test must check:
* whether the persona can check a policy association for a region and
service
"""
pass
@abc.abstractmethod
def test_identity_get_policy_for_endpoint(self):
"""Test identity:get_policy_for_endpoint policy.
This test must check:
* whether the persona can get a policy for an endpoint
"""
pass
@abc.abstractmethod
def test_identity_list_endpoints_for_policy(self):
"""Test identity:list_endpoints_for_policy policy.
This test must check:
* whether the persona can list endpoints for a policy
"""
pass
@abc.abstractmethod
def test_identity_delete_policy_association_for_endpoint(self):
"""Test identity:delete_policy_association_for_endpoint policy.
This test must check
* whether the persona can delete a policy association for an endpoint
"""
pass
@abc.abstractmethod
def test_identity_delete_policy_association_for_service(self):
"""Test identity:delete_policy_association_for_service policy.
This test must check
* whether the persona can delete a policy association for a service
"""
pass
@abc.abstractmethod
def test_identity_delete_policy_association_for_region_and_service(self):
"""Test identity:delete_policy_association_for_region_and_service policy.
This test must check
* whether the persona can delete a policy association for a region
and service
"""
pass
class SystemAdminTests(
IdentityV3RbacPolicyAssociationTests, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_policy_association_for_endpoint(self):
self.do_request(
'update_policy_association_for_endpoint',
expected_status=204,
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.addCleanup(
self.admin_policies_client.delete_policy_association_for_endpoint,
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
def test_identity_create_policy_association_for_service(self):
self.do_request(
'update_policy_association_for_service',
expected_status=204,
policy_id=self.policy_id, service_id=self.service_id)
self.addCleanup(
self.admin_policies_client.delete_policy_association_for_service,
policy_id=self.policy_id, service_id=self.service_id)
def test_identity_create_policy_association_for_region_and_service(self):
self.do_request(
'update_policy_association_for_region_and_service',
expected_status=204,
policy_id=self.policy_id, service_id=self.service_id,
region_id=self.region_id)
delete_fn = getattr(
self.admin_policies_client,
'delete_policy_association_for_region_and_service'
)
self.addCleanup(delete_fn,
policy_id=self.policy_id,
service_id=self.service_id,
region_id=self.region_id)
def test_identity_check_policy_association_for_endpoint(self):
self.admin_policies_client.update_policy_association_for_endpoint(
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.addCleanup(
self.admin_policies_client.delete_policy_association_for_endpoint,
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.do_request(
'show_policy_association_for_endpoint',
expected_status=204,
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
def test_identity_check_policy_association_for_service(self):
self.admin_policies_client.update_policy_association_for_service(
policy_id=self.policy_id, service_id=self.service_id)
self.addCleanup(
self.admin_policies_client.delete_policy_association_for_service,
policy_id=self.policy_id, service_id=self.service_id)
self.do_request(
'show_policy_association_for_service',
expected_status=204,
policy_id=self.policy_id, service_id=self.service_id)
def test_identity_check_policy_association_for_region_and_service(self):
update_fn = getattr(
self.admin_policies_client,
'update_policy_association_for_region_and_service'
)
update_fn(policy_id=self.policy_id,
service_id=self.service_id,
region_id=self.region_id)
delete_fn = getattr(
self.admin_policies_client,
'delete_policy_association_for_region_and_service'
)
self.addCleanup(delete_fn,
policy_id=self.policy_id,
service_id=self.service_id,
region_id=self.region_id)
self.do_request(
'show_policy_association_for_region_and_service',
expected_status=204,
policy_id=self.policy_id,
service_id=self.service_id,
region_id=self.region_id)
def test_identity_get_policy_for_endpoint(self):
self.admin_policies_client.update_policy_association_for_endpoint(
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.addCleanup(
self.admin_policies_client.delete_policy_association_for_endpoint,
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.do_request(
'show_policy_for_endpoint',
expected_status=200,
endpoint_id=self.endpoint_id)
def test_identity_list_endpoints_for_policy(self):
self.admin_policies_client.update_policy_association_for_endpoint(
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.addCleanup(
self.admin_policies_client.delete_policy_association_for_endpoint,
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.do_request(
'list_endpoints_for_policy',
expected_status=200,
policy_id=self.policy_id)
def test_identity_delete_policy_association_for_endpoint(self):
self.admin_policies_client.update_policy_association_for_endpoint(
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.do_request(
'delete_policy_association_for_endpoint',
expected_status=204,
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
def test_identity_delete_policy_association_for_service(self):
self.admin_policies_client.update_policy_association_for_service(
policy_id=self.policy_id, service_id=self.service_id)
self.do_request(
'delete_policy_association_for_service',
expected_status=204,
policy_id=self.policy_id, service_id=self.service_id)
def test_identity_delete_policy_association_for_region_and_service(self):
update_fn = getattr(
self.admin_policies_client,
'update_policy_association_for_region_and_service'
)
update_fn(policy_id=self.policy_id,
service_id=self.service_id,
region_id=self.region_id)
self.do_request(
'delete_policy_association_for_region_and_service',
expected_status=204,
policy_id=self.policy_id,
service_id=self.service_id,
region_id=self.region_id)
class SystemMemberTests(SystemAdminTests, base.BaseIdentityTest):
credentials = ['system_member', 'system_admin']
def test_identity_create_policy_association_for_endpoint(self):
self.do_request(
'update_policy_association_for_endpoint',
expected_status=exceptions.Forbidden,
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
def test_identity_create_policy_association_for_service(self):
self.do_request(
'update_policy_association_for_service',
expected_status=exceptions.Forbidden,
policy_id=self.policy_id, service_id=self.service_id)
def test_identity_create_policy_association_for_region_and_service(self):
self.do_request(
'update_policy_association_for_region_and_service',
expected_status=exceptions.Forbidden,
policy_id=self.policy_id, service_id=self.service_id,
region_id=self.region_id)
def test_identity_delete_policy_association_for_endpoint(self):
self.admin_policies_client.update_policy_association_for_endpoint(
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.addCleanup(
self.admin_policies_client.delete_policy_association_for_endpoint,
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.do_request(
'delete_policy_association_for_endpoint',
expected_status=exceptions.Forbidden,
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
def test_identity_delete_policy_association_for_service(self):
self.admin_policies_client.update_policy_association_for_service(
policy_id=self.policy_id, service_id=self.service_id)
self.addCleanup(
self.admin_policies_client.delete_policy_association_for_service,
policy_id=self.policy_id, service_id=self.service_id)
self.do_request(
'delete_policy_association_for_service',
expected_status=exceptions.Forbidden,
policy_id=self.policy_id, service_id=self.service_id)
def test_identity_delete_policy_association_for_region_and_service(self):
update_fn = getattr(
self.admin_policies_client,
'update_policy_association_for_region_and_service'
)
update_fn(policy_id=self.policy_id,
service_id=self.service_id,
region_id=self.region_id)
delete_fn = getattr(
self.admin_policies_client,
'delete_policy_association_for_region_and_service'
)
self.addCleanup(delete_fn,
policy_id=self.policy_id,
service_id=self.service_id,
region_id=self.region_id)
self.do_request(
'delete_policy_association_for_region_and_service',
expected_status=exceptions.Forbidden,
policy_id=self.policy_id,
service_id=self.service_id,
region_id=self.region_id)
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def test_identity_check_policy_association_for_endpoint(self):
self.admin_policies_client.update_policy_association_for_endpoint(
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.addCleanup(
self.admin_policies_client.delete_policy_association_for_endpoint,
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.do_request(
'show_policy_association_for_endpoint',
expected_status=exceptions.Forbidden,
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
def test_identity_check_policy_association_for_service(self):
self.admin_policies_client.update_policy_association_for_service(
policy_id=self.policy_id, service_id=self.service_id)
self.addCleanup(
self.admin_policies_client.delete_policy_association_for_service,
policy_id=self.policy_id, service_id=self.service_id)
self.do_request(
'show_policy_association_for_service',
expected_status=exceptions.Forbidden,
policy_id=self.policy_id, service_id=self.service_id)
def test_identity_check_policy_association_for_region_and_service(self):
update_fn = getattr(
self.admin_policies_client,
'update_policy_association_for_region_and_service'
)
update_fn(policy_id=self.policy_id,
service_id=self.service_id,
region_id=self.region_id)
delete_fn = getattr(
self.admin_policies_client,
'delete_policy_association_for_region_and_service'
)
self.addCleanup(delete_fn,
policy_id=self.policy_id,
service_id=self.service_id,
region_id=self.region_id)
self.do_request(
'show_policy_association_for_region_and_service',
expected_status=exceptions.Forbidden,
policy_id=self.policy_id,
service_id=self.service_id,
region_id=self.region_id)
def test_identity_get_policy_for_endpoint(self):
self.admin_policies_client.update_policy_association_for_endpoint(
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.addCleanup(
self.admin_policies_client.delete_policy_association_for_endpoint,
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.do_request(
'show_policy_for_endpoint',
expected_status=exceptions.Forbidden,
endpoint_id=self.endpoint_id)
def test_identity_list_endpoints_for_policy(self):
self.admin_policies_client.update_policy_association_for_endpoint(
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.addCleanup(
self.admin_policies_client.delete_policy_association_for_endpoint,
policy_id=self.policy_id, endpoint_id=self.endpoint_id)
self.do_request(
'list_endpoints_for_policy',
expected_status=exceptions.Forbidden,
policy_id=self.policy_id)
class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,467 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacProjectsTests(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacProjectsTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.projects_client
cls.users_client = cls.persona.users_v3_client
cls.admin_client = cls.os_system_admin
cls.admin_projects_client = cls.admin_client.projects_client
@abc.abstractmethod
def test_identity_create_project(self):
"""Test identity:create_project policy.
This test must check:
* whether the persona can create a project
* whether the persona can create a project in their own domain
* whether the persona can create a project in another domain
"""
pass
@abc.abstractmethod
def test_identity_get_project(self):
"""Test identity:get_project policy.
This test must check:
* whether the persona can get a project
* whether the persona can get a project in their own domain
* whether the persona can get a project in another domain
* whether the persona can get a project that does not exist
* whether the persona can get their own project
"""
pass
@abc.abstractmethod
def test_identity_list_projects(self):
"""Test identity:list_projects policy.
This test must check:
* whether the persona can list all projects
* whether the persona can list all projects in their own domain
* whether the persona can list all projects in another domain
"""
pass
@abc.abstractmethod
def test_identity_list_user_projects(self):
"""Test identity:list_user_projects policy.
This test must check:
* whether the persona can list projects of a user
* whether the persona can list projects of a user in their own domain
* whether the persona can list projects of a user in another domain
* whether the persona can list projects for themself
"""
pass
@abc.abstractmethod
def test_identity_update_project(self):
"""Test identity:update_project policy.
This test must check:
* whether the persona can update a project
* whether the persona can update a project in their own domain
* whether the persona can update a project in another domain
* whether the persona can update a project that does not exist
"""
pass
@abc.abstractmethod
def test_identity_delete_project(self):
"""Test identity:delete_project policy.
This test must check
* whether the persona can delete a project
* whether the persona can delete a project in their own domain
* whether the persona can delete a project in another domain
* whether the persona can delete a project that does not exist
"""
pass
class SystemAdminTests(IdentityV3RbacProjectsTests, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_project(self):
project_id = self.do_request(
'create_project', expected_status=201, name=data_utils.rand_name()
)['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
def test_identity_get_project(self):
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name())['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
self.do_request('show_project', project_id=project_id)
# user gets a 404 for nonexistent project
self.do_request('show_project', expected_status=exceptions.NotFound,
project_id=data_utils.rand_uuid_hex())
def test_identity_list_projects(self):
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name())['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
resp = self.do_request('list_projects')
self.assertIn(project_id, [p['id'] for p in resp['projects']])
def test_identity_list_user_projects(self):
user_id = self.admin_client.users_v3_client.create_user(
name=data_utils.rand_name())['user']['id']
self.addCleanup(self.admin_client.users_v3_client.delete_user, user_id)
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name())['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
role_id = self.admin_client.roles_v3_client.create_role(
name=data_utils.rand_name())['role']['id']
self.addCleanup(self.admin_client.roles_v3_client.delete_role,
role_id)
self.admin_client.roles_v3_client.create_user_role_on_project(
project_id, user_id, role_id)
# user can list projects for arbitrary user
resp = self.do_request('list_user_projects', client=self.users_client,
user_id=user_id)
self.assertIn(project_id, [p['id'] for p in resp['projects']])
# user can list projects for self
resp = self.do_request('list_user_projects', client=self.users_client,
user_id=self.persona.credentials.user_id)
self.assertEqual(0, len([p['id'] for p in resp['projects']]))
def test_identity_update_project(self):
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name())['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
self.do_request('update_project',
project_id=project_id,
description=data_utils.arbitrary_string())
# user gets a 404 for nonexistent domain
self.do_request('update_project', expected_status=exceptions.NotFound,
project_id=data_utils.rand_uuid_hex(),
description=data_utils.arbitrary_string())
def test_identity_delete_project(self):
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name())['project']['id']
self.do_request('delete_project', expected_status=204,
project_id=project_id)
class SystemMemberTests(SystemAdminTests, base.BaseIdentityTest):
credentials = ['system_member', 'system_admin']
def test_identity_create_project(self):
self.do_request('create_project', expected_status=exceptions.Forbidden,
name=data_utils.rand_name())
def test_identity_update_project(self):
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name())['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
self.do_request('update_project', expected_status=exceptions.Forbidden,
project_id=project_id,
description=data_utils.arbitrary_string())
# user gets a 403 for nonexistent domain
self.do_request('update_project', expected_status=exceptions.Forbidden,
project_id=data_utils.rand_uuid_hex())
def test_identity_delete_project(self):
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name())['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
self.do_request('delete_project', expected_status=exceptions.Forbidden,
project_id=project_id)
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(IdentityV3RbacProjectsTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def setUp(self):
super(DomainAdminTests, self).setUp()
self.own_domain = self.persona.credentials.domain_id
self.other_domain = self.admin_client.domains_client.create_domain(
name=data_utils.rand_name())['domain']['id']
self.addCleanup(self.admin_client.domains_client.delete_domain,
self.other_domain)
self.addCleanup(self.admin_client.domains_client.update_domain,
domain_id=self.other_domain, enabled=False)
def test_identity_create_project(self):
# user can create project in own domain
project_id = self.do_request(
'create_project', expected_status=201, name=data_utils.rand_name(),
domain_id=self.own_domain
)['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
# user cannot create project in other domain
self.do_request(
'create_project', expected_status=exceptions.Forbidden,
name=data_utils.rand_name(), domain_id=self.other_domain
)
def test_identity_get_project(self):
# user can get project in own domain
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name(),
domain_id=self.own_domain)['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
self.do_request('show_project', project_id=project_id)
# user cannot get project in other domain
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name(),
domain_id=self.other_domain)['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
self.do_request('show_project', expected_status=exceptions.Forbidden,
project_id=project_id)
# user gets a 403 for nonexistent project
self.do_request('show_project', expected_status=exceptions.Forbidden,
project_id=data_utils.rand_uuid_hex())
def test_identity_list_projects(self):
# user can list projects but cannot see project in other domain
own_project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name(),
domain_id=self.own_domain)['project']['id']
self.addCleanup(self.admin_projects_client.delete_project,
own_project_id)
other_project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name(),
domain_id=self.other_domain)['project']['id']
self.addCleanup(self.admin_projects_client.delete_project,
other_project_id)
resp = self.do_request('list_projects')
self.assertIn(own_project_id, [d['id'] for d in resp['projects']])
self.assertNotIn(other_project_id, [d['id'] for d in resp['projects']])
def test_identity_list_user_projects(self):
# user can list projects for user in own domain
user_id = self.admin_client.users_v3_client.create_user(
name=data_utils.rand_name(),
domain_id=self.own_domain)['user']['id']
self.addCleanup(self.admin_client.users_v3_client.delete_user, user_id)
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name())['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
role_id = self.admin_client.roles_v3_client.create_role(
name=data_utils.rand_name())['role']['id']
self.addCleanup(self.admin_client.roles_v3_client.delete_role,
role_id)
self.admin_client.roles_v3_client.create_user_role_on_project(
project_id, user_id, role_id)
resp = self.do_request('list_user_projects', client=self.users_client,
user_id=user_id)
self.assertIn(project_id, [p['id'] for p in resp['projects']])
# user cannot list projects for user in other domain
user_id = self.admin_client.users_v3_client.create_user(
name=data_utils.rand_name(),
domain_id=self.other_domain)['user']['id']
self.addCleanup(self.admin_client.users_v3_client.delete_user, user_id)
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name())['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
role_id = self.admin_client.roles_v3_client.create_role(
name=data_utils.rand_name())['role']['id']
self.addCleanup(self.admin_client.roles_v3_client.delete_role,
role_id)
self.admin_client.roles_v3_client.create_user_role_on_project(
project_id, user_id, role_id)
self.do_request('list_user_projects', client=self.users_client,
expected_status=exceptions.Forbidden,
user_id=user_id)
# user can list projects for self
resp = self.do_request('list_user_projects', client=self.users_client,
user_id=self.persona.credentials.user_id)
self.assertEqual(0, len([p['id'] for p in resp['projects']]))
def test_identity_update_project(self):
# user can update project in own domain
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name(),
domain_id=self.own_domain)['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
self.do_request('update_project',
project_id=project_id,
description=data_utils.arbitrary_string())
# user cannot update project in other domain
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name(),
domain_id=self.other_domain)['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
self.do_request('update_project',
expected_status=exceptions.Forbidden,
project_id=project_id,
description=data_utils.arbitrary_string())
# user gets a 403 for nonexistent domain
self.do_request('update_project', expected_status=exceptions.Forbidden,
project_id=data_utils.rand_uuid_hex(),
description=data_utils.arbitrary_string())
def test_identity_delete_project(self):
# user can delete project in own domain
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name(),
domain_id=self.own_domain)['project']['id']
self.do_request('delete_project', expected_status=204,
project_id=project_id)
# user cannot delete project in other domain
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name(),
domain_id=self.other_domain)['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
self.do_request('delete_project', expected_status=exceptions.Forbidden,
project_id=project_id)
class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
credentials = ['domain_member', 'system_admin']
def test_identity_create_project(self):
# user cannot create project in own domain
self.do_request(
'create_project', expected_status=exceptions.Forbidden,
name=data_utils.rand_name(),
domain_id=self.own_domain
)
# user cannot create project in other domain
self.do_request(
'create_project', expected_status=exceptions.Forbidden,
name=data_utils.rand_name(), domain_id=self.other_domain
)
def test_identity_update_project(self):
# user cannot update project in own domain
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name(),
domain_id=self.own_domain)['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
self.do_request('update_project',
expected_status=exceptions.Forbidden,
project_id=project_id,
description=data_utils.arbitrary_string())
# user cannot update project in other domain
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name(),
domain_id=self.other_domain)['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
self.do_request('update_project',
expected_status=exceptions.Forbidden,
project_id=project_id,
description=data_utils.arbitrary_string())
# user gets a 403 for nonexistent domain
self.do_request('update_project', expected_status=exceptions.Forbidden,
project_id=data_utils.rand_uuid_hex(),
description=data_utils.arbitrary_string())
def test_identity_delete_project(self):
# user cannot delete project in own domain
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name(),
domain_id=self.own_domain)['project']['id']
self.do_request('delete_project', expected_status=exceptions.Forbidden,
project_id=project_id)
# user cannot delete project in other domain
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name(),
domain_id=self.other_domain)['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
self.do_request('delete_project', expected_status=exceptions.Forbidden,
project_id=project_id)
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
def test_identity_get_project(self):
# user cannot get arbitrary project
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name(),
domain_id=self.own_domain)['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
self.do_request('show_project', expected_status=exceptions.Forbidden,
project_id=project_id)
# user gets a 403 for nonexistent project
self.do_request('show_project', expected_status=exceptions.Forbidden,
project_id=data_utils.rand_uuid_hex())
# user can get own project
self.do_request('show_project',
project_id=self.persona.credentials.project_id)
def test_identity_list_projects(self):
# user cannot list projects
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name())['project']['id']
self.addCleanup(self.admin_projects_client.delete_project,
project_id)
self.do_request('list_projects', expected_status=exceptions.Forbidden)
def test_identity_list_user_projects(self):
# user can list projects for other user
user_id = self.admin_client.users_v3_client.create_user(
name=data_utils.rand_name())['user']['id']
self.addCleanup(self.admin_client.users_v3_client.delete_user, user_id)
project_id = self.admin_projects_client.create_project(
name=data_utils.rand_name())['project']['id']
self.addCleanup(self.admin_projects_client.delete_project, project_id)
role_id = self.admin_client.roles_v3_client.create_role(
name=data_utils.rand_name())['role']['id']
self.addCleanup(self.admin_client.roles_v3_client.delete_role,
role_id)
self.admin_client.roles_v3_client.create_user_role_on_project(
project_id, user_id, role_id)
self.do_request('list_user_projects', client=self.users_client,
expected_status=exceptions.Forbidden,
user_id=user_id)
# user can list projects for self
resp = self.do_request('list_user_projects', client=self.users_client,
user_id=self.persona.credentials.user_id)
self.assertIn(self.persona.credentials.project_id,
[p['id'] for p in resp['projects']])
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,251 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacProjectEndpointsTests(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacProjectEndpointsTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.endpoint_filter_client
cls.admin_client = cls.os_system_admin
cls.admin_ef_client = cls.admin_client.endpoint_filter_client
@classmethod
def resource_setup(cls):
super(IdentityV3RbacProjectEndpointsTests, cls).resource_setup()
cls.project_id = cls.admin_client.projects_client.create_project(
name=data_utils.rand_name())['project']['id']
cls.addClassResourceCleanup(
cls.admin_client.projects_client.delete_project,
project_id=cls.project_id)
service = cls.admin_client.identity_services_v3_client.create_service(
type=data_utils.rand_name())['service']
cls.addClassResourceCleanup(
cls.admin_client.identity_services_v3_client.delete_service,
service['id'])
cls.endpoint_id = cls.admin_client.endpoints_v3_client.create_endpoint(
interface='public',
url='http://localhost/foo',
service_id=service['id'])['endpoint']['id']
cls.addClassResourceCleanup(
cls.admin_client.endpoints_v3_client.delete_endpoint,
endpoint_id=cls.endpoint_id)
@abc.abstractmethod
def test_identity_add_endpoint_to_project(self):
"""Test identity:add_endpoint_to_project policy.
This test must check:
* whether the persona can allow a project to access an endpoint
"""
pass
@abc.abstractmethod
def test_identity_check_endpoint_in_project(self):
"""Test identity:check_endpoint_in_project policy.
This test must check:
* whether the persona can check if a project has access to an
endpoint
"""
pass
@abc.abstractmethod
def test_identity_list_projects_for_endpoint(self):
"""Test identity:list_projects_for_endpoint policy.
This test must check:
* whether the persona can list all projects that have access to an
endpoint
"""
pass
@abc.abstractmethod
def test_identity_list_endpoints_for_project(self):
"""Test identity:list_endpoints_for_project policy.
This test must check:
* whether the persona can list all endpoints to which a project has
access
"""
pass
@abc.abstractmethod
def test_identity_remove_endpoint_from_project(self):
"""Test identity:remove_endpoint_from_project policy.
This test must check
* whether the persona can remove a project's access to an endpoint
"""
pass
class SystemAdminTests(IdentityV3RbacProjectEndpointsTests):
credentials = ['system_admin']
def test_identity_add_endpoint_to_project(self):
self.do_request('add_endpoint_to_project',
expected_status=204,
project_id=self.project_id,
endpoint_id=self.endpoint_id)
self.addCleanup(self.admin_ef_client.delete_endpoint_from_project,
project_id=self.project_id,
endpoint_id=self.endpoint_id)
def test_identity_check_endpoint_in_project(self):
self.admin_ef_client.add_endpoint_to_project(
project_id=self.project_id,
endpoint_id=self.endpoint_id)
self.addCleanup(self.admin_ef_client.delete_endpoint_from_project,
project_id=self.project_id,
endpoint_id=self.endpoint_id)
self.do_request('check_endpoint_in_project',
expected_status=204,
project_id=self.project_id,
endpoint_id=self.endpoint_id)
def test_identity_list_projects_for_endpoint(self):
self.admin_ef_client.add_endpoint_to_project(
project_id=self.project_id,
endpoint_id=self.endpoint_id)
self.addCleanup(self.admin_ef_client.delete_endpoint_from_project,
project_id=self.project_id,
endpoint_id=self.endpoint_id)
resp = self.do_request('list_projects_for_endpoint',
endpoint_id=self.endpoint_id)
self.assertIn(self.project_id, [p['id'] for p in resp['projects']])
def test_identity_list_endpoints_for_project(self):
self.admin_ef_client.add_endpoint_to_project(
project_id=self.project_id,
endpoint_id=self.endpoint_id)
self.addCleanup(self.admin_ef_client.delete_endpoint_from_project,
project_id=self.project_id,
endpoint_id=self.endpoint_id)
resp = self.do_request('list_endpoints_in_project',
project_id=self.project_id)
self.assertIn(self.endpoint_id, [e['id'] for e in resp['endpoints']])
def test_identity_remove_endpoint_from_project(self):
self.admin_ef_client.add_endpoint_to_project(
project_id=self.project_id,
endpoint_id=self.endpoint_id)
self.do_request('delete_endpoint_from_project',
expected_status=204,
project_id=self.project_id,
endpoint_id=self.endpoint_id)
class SystemMemberTests(SystemAdminTests):
credentials = ['system_member', 'system_admin']
def test_identity_add_endpoint_to_project(self):
self.do_request('add_endpoint_to_project',
expected_status=exceptions.Forbidden,
project_id=self.project_id,
endpoint_id=self.endpoint_id)
def test_identity_remove_endpoint_from_project(self):
self.admin_ef_client.add_endpoint_to_project(
project_id=self.project_id,
endpoint_id=self.endpoint_id)
self.addCleanup(self.admin_ef_client.delete_endpoint_from_project,
project_id=self.project_id,
endpoint_id=self.endpoint_id)
self.do_request('delete_endpoint_from_project',
expected_status=exceptions.Forbidden,
project_id=self.project_id,
endpoint_id=self.endpoint_id)
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def test_identity_check_endpoint_in_project(self):
self.admin_ef_client.add_endpoint_to_project(
project_id=self.project_id,
endpoint_id=self.endpoint_id)
self.addCleanup(self.admin_ef_client.delete_endpoint_from_project,
project_id=self.project_id,
endpoint_id=self.endpoint_id)
self.do_request('check_endpoint_in_project',
expected_status=exceptions.Forbidden,
project_id=self.project_id,
endpoint_id=self.endpoint_id)
def test_identity_list_projects_for_endpoint(self):
self.admin_ef_client.add_endpoint_to_project(
project_id=self.project_id,
endpoint_id=self.endpoint_id)
self.addCleanup(self.admin_ef_client.delete_endpoint_from_project,
project_id=self.project_id,
endpoint_id=self.endpoint_id)
self.do_request('list_projects_for_endpoint',
expected_status=exceptions.Forbidden,
endpoint_id=self.endpoint_id)
def test_identity_list_endpoints_for_project(self):
self.admin_ef_client.add_endpoint_to_project(
project_id=self.project_id,
endpoint_id=self.endpoint_id)
self.addCleanup(self.admin_ef_client.delete_endpoint_from_project,
project_id=self.project_id,
endpoint_id=self.endpoint_id)
self.do_request('list_endpoints_in_project',
expected_status=exceptions.Forbidden,
project_id=self.project_id)
class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,599 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacProjectTagTests(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacProjectTagTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.project_tags_client
cls.admin_client = cls.os_system_admin
cls.admin_project_tags_client = cls.admin_client.project_tags_client
@abc.abstractmethod
def test_identity_create_project_tag(self):
"""Test identity:create_project_tag policy.
This test must check:
* whether the persona can create a tag for an arbitrary project
* whether the persona can create a tag for a project in their own
domain
* whether the persona can create a tag for a project in another
domain
* whether the persona can create a tag for their own project
"""
pass
@abc.abstractmethod
def test_identity_get_project_tag(self):
"""Test identity:get_project_tag policy.
This test must check:
* whether the persona can get a tag for an arbitrary project
* whether the persona can get a tag for a project in their own domain
* whether the persona can get a tag for a project in another domain
* whether the persona can get tag for their own project
"""
pass
@abc.abstractmethod
def test_identity_list_project_tags(self):
"""Test identity:list_project_tags policy.
This test must check:
* whether the persona can list tags for an arbitrary project
* whether the persona can list tags for a project in their own domain
* whether the persona can list tags for a project in another domain
* whether the persona can list tags for their own project
"""
pass
@abc.abstractmethod
def test_identity_update_project_tags(self):
"""Test identity:update_project_tags policy.
This test must check:
* whether the persona can update all tags for an project
* whether the persona can update all tags for a project in their own
domain
* whether the persona can update all tags for a project in another
domain
* whether the persona can update all tags for their own project
"""
pass
@abc.abstractmethod
def test_identity_delete_project_tag(self):
"""Test identity:delete_project_tag policy.
This test must check
* whether the persona can delete a single tag for an arbitrary
project
* whether the persona can delete a single tag for a project in their
own domain
* whether the persona can delete a single tag for a project in
another domain
* whether the persona can delete a single tag for their own project
"""
pass
@abc.abstractmethod
def test_identity_delete_project_tags(self):
"""Test identity:delete_project_tag policy.
This test must check
* whether the persona can delete all tags for an arbitrary project
* whether the persona can delete all tags for a project in their own
domain
* whether the persona can delete all tags for a project in another
domain
* whether the persona can delete all tags for their own project
"""
pass
class SystemAdminTests(IdentityV3RbacProjectTagTests, base.BaseIdentityTest):
credentials = ['system_admin']
def setUp(self):
super(SystemAdminTests, self).setUp()
self.project_id = self.admin_client.projects_client.create_project(
name=data_utils.rand_name())['project']['id']
self.addCleanup(
self.admin_client.projects_client.delete_project, self.project_id)
def test_identity_create_project_tag(self):
self.do_request(
'update_project_tag', expected_status=201,
project_id=self.project_id,
tag=data_utils.rand_uuid_hex()
)
def test_identity_get_project_tag(self):
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.project_id, tag=tag)
self.do_request('check_project_tag_existence',
expected_status=204,
project_id=self.project_id, tag=tag)
def test_identity_list_project_tags(self):
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.project_id, tag=tag)
resp = self.do_request('list_project_tags', project_id=self.project_id)
self.assertIn(tag, resp['tags'])
def test_identity_update_project_tags(self):
self.do_request('update_all_project_tags',
project_id=self.project_id,
tags=[data_utils.rand_uuid_hex()])
def test_identity_delete_project_tag(self):
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.project_id, tag=tag)
self.do_request('delete_project_tag', expected_status=204,
project_id=self.project_id,
tag=tag)
def test_identity_delete_project_tags(self):
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.project_id, tag=tag)
self.do_request('delete_all_project_tags', expected_status=204,
project_id=self.project_id)
class SystemMemberTests(SystemAdminTests, base.BaseIdentityTest):
credentials = ['system_member', 'system_admin']
def test_identity_create_project_tag(self):
self.do_request(
'update_project_tag', expected_status=exceptions.Forbidden,
project_id=self.project_id,
tag=data_utils.rand_uuid_hex()
)
def test_identity_update_project_tags(self):
self.do_request('update_all_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.project_id,
tags=[data_utils.rand_uuid_hex()])
def test_identity_delete_project_tag(self):
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.project_id, tag=tag)
self.do_request('delete_project_tag',
expected_status=exceptions.Forbidden,
project_id=self.project_id,
tag=tag)
def test_identity_delete_project_tags(self):
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.project_id, tag=tag)
self.do_request('delete_all_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.project_id)
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(IdentityV3RbacProjectTagTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def setUp(self):
super(DomainAdminTests, self).setUp()
self.own_domain = self.persona.credentials.domain_id
self.other_domain = self.admin_client.domains_client.create_domain(
name=data_utils.rand_name())['domain']['id']
self.addCleanup(self.admin_client.domains_client.delete_domain,
self.other_domain)
self.addCleanup(self.admin_client.domains_client.update_domain,
domain_id=self.other_domain, enabled=False)
project_client = self.admin_client.projects_client
self.own_project_id = project_client.create_project(
name=data_utils.rand_name(),
domain_id=self.own_domain)['project']['id']
self.addCleanup(
project_client.delete_project,
self.own_project_id)
self.other_project_id = project_client.create_project(
name=data_utils.rand_name(),
domain_id=self.other_domain)['project']['id']
self.addCleanup(project_client.delete_project, self.other_project_id)
def test_identity_create_project_tag(self):
# user can add tags to project in own domain
tag = data_utils.rand_uuid_hex()
self.do_request(
'update_project_tag', expected_status=201,
project_id=self.own_project_id,
tag=tag
)
# user cannot add tags to project in other domain
tag = data_utils.rand_uuid_hex()
self.do_request(
'update_project_tag', expected_status=exceptions.Forbidden,
project_id=self.other_project_id,
tag=tag
)
def test_identity_get_project_tag(self):
# user can get tag for project in own domain
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.own_project_id, tag=tag)
self.do_request('check_project_tag_existence',
expected_status=204,
project_id=self.own_project_id, tag=tag)
# user cannot get tag for project in other domain
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.other_project_id, tag=tag)
self.do_request('check_project_tag_existence',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id, tag=tag)
def test_identity_list_project_tags(self):
# user can list tags for project in own domain
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.own_project_id, tag=tag)
resp = self.do_request('list_project_tags',
project_id=self.own_project_id)
self.assertIn(tag, resp['tags'])
# user cannot list tags for project in other domain
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.other_project_id, tag=tag)
self.do_request('list_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id)
def test_identity_update_project_tags(self):
# user can update tags for project in own domain
tag = data_utils.rand_uuid_hex()
self.do_request('update_all_project_tags',
project_id=self.own_project_id,
tags=[tag])
# user cannot update tags for project in other domain
tag = data_utils.rand_uuid_hex()
self.do_request('update_all_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id,
tags=[tag])
def test_identity_delete_project_tag(self):
# user can delete tag for project in own domain
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.own_project_id, tag=tag)
self.do_request('delete_project_tag', expected_status=204,
project_id=self.own_project_id,
tag=tag)
# user cannot delete tag for project in other domain
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.other_project_id, tag=tag)
self.do_request('delete_project_tag',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id,
tag=tag)
def test_identity_delete_project_tags(self):
# user can delete tags for project in own domain
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.own_project_id, tag=tag)
self.do_request('delete_all_project_tags', expected_status=204,
project_id=self.own_project_id)
# user cannot delete tags for project in other domain
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.other_project_id, tag=tag)
self.do_request('delete_all_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id)
class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
credentials = ['domain_member', 'system_admin']
def test_identity_create_project_tag(self):
# user cannot add tags to project in own domain
tag = data_utils.rand_uuid_hex()
self.do_request(
'update_project_tag', expected_status=exceptions.Forbidden,
project_id=self.own_project_id,
tag=tag
)
# user cannot add tags to project in other domain
tag = data_utils.rand_uuid_hex()
self.do_request(
'update_project_tag', expected_status=exceptions.Forbidden,
project_id=self.other_project_id,
tag=tag
)
def test_identity_update_project_tags(self):
# user cannot update tags for project in own domain
tag = data_utils.rand_uuid_hex()
self.do_request('update_all_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.own_project_id,
tags=[tag])
# user cannot update tags for project in other domain
tag = data_utils.rand_uuid_hex()
self.do_request('update_all_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id,
tags=[tag])
def test_identity_delete_project_tag(self):
# user cannot delete tag for project in own domain
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.own_project_id, tag=tag)
self.do_request('delete_project_tag',
expected_status=exceptions.Forbidden,
project_id=self.own_project_id,
tag=tag)
# user cannot delete tag for project in other domain
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.other_project_id, tag=tag)
self.do_request('delete_project_tag',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id,
tag=tag)
def test_identity_delete_project_tags(self):
# user cannot delete tags for project in own domain
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.own_project_id, tag=tag)
self.do_request('delete_all_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.own_project_id)
# user cannot delete tags for project in other domain
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.other_project_id, tag=tag)
self.do_request('delete_all_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id)
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(IdentityV3RbacProjectTagTests, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
def setUp(self):
super(ProjectAdminTests, self).setUp()
self.own_project_id = self.persona.credentials.project_id
project_client = self.admin_client.projects_client
self.other_project_id = project_client.create_project(
name=data_utils.rand_name())['project']['id']
self.addCleanup(project_client.delete_project, self.other_project_id)
def test_identity_create_project_tag(self):
# user can add tags to own project
tag = data_utils.rand_uuid_hex()
self.do_request(
'update_project_tag', expected_status=201,
project_id=self.own_project_id,
tag=tag
)
self.addCleanup(self.admin_project_tags_client.delete_project_tag,
project_id=self.own_project_id,
tag=tag)
# user cannot add tags to arbitrary project
tag = data_utils.rand_uuid_hex()
self.do_request(
'update_project_tag', expected_status=exceptions.Forbidden,
project_id=self.other_project_id,
tag=tag
)
def test_identity_get_project_tag(self):
# user can get tag for own project
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.own_project_id, tag=tag)
self.addCleanup(self.admin_project_tags_client.delete_project_tag,
project_id=self.own_project_id,
tag=tag)
self.do_request('check_project_tag_existence',
expected_status=204,
project_id=self.own_project_id, tag=tag)
# user cannot get tag for arbitrary project
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.other_project_id, tag=tag)
self.do_request('check_project_tag_existence',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id, tag=tag)
def test_identity_list_project_tags(self):
# user can list tags for own project
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.own_project_id, tag=tag)
self.addCleanup(self.admin_project_tags_client.delete_project_tag,
project_id=self.own_project_id,
tag=tag)
resp = self.do_request('list_project_tags',
project_id=self.own_project_id)
self.assertIn(tag, resp['tags'])
# user cannot list tags for arbitrary project
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.other_project_id, tag=tag)
self.do_request('list_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id)
def test_identity_update_project_tags(self):
# user can update tags for own project
tag = data_utils.rand_uuid_hex()
self.do_request('update_all_project_tags',
project_id=self.own_project_id,
tags=[tag])
self.addCleanup(self.admin_project_tags_client.delete_project_tag,
project_id=self.own_project_id,
tag=tag)
# user cannot update tags for arbitrary project
tag = data_utils.rand_uuid_hex()
self.do_request('update_all_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id,
tags=[tag])
def test_identity_delete_project_tag(self):
# user can delete tag for own project
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.own_project_id, tag=tag)
self.do_request('delete_project_tag', expected_status=204,
project_id=self.own_project_id,
tag=tag)
# user cannot delete tag for arbitrary project
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.other_project_id, tag=tag)
self.do_request('delete_project_tag',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id,
tag=tag)
def test_identity_delete_project_tags(self):
# user can delete tags for own project
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.own_project_id, tag=tag)
self.do_request('delete_all_project_tags', expected_status=204,
project_id=self.own_project_id)
# user cannot delete tags for arbitrary project
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.other_project_id, tag=tag)
self.do_request('delete_all_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id)
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
def test_identity_create_project_tag(self):
# user cannot add tags to own project
tag = data_utils.rand_uuid_hex()
self.do_request(
'update_project_tag', expected_status=exceptions.Forbidden,
project_id=self.own_project_id,
tag=tag
)
# user cannot add tags to arbitrary project
tag = data_utils.rand_uuid_hex()
self.do_request(
'update_project_tag', expected_status=exceptions.Forbidden,
project_id=self.other_project_id,
tag=tag
)
def test_identity_update_project_tags(self):
# user cannot update tags for own project
tag = data_utils.rand_uuid_hex()
self.do_request('update_all_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.own_project_id,
tags=[tag])
# user cannot update tags for arbitrary project
tag = data_utils.rand_uuid_hex()
self.do_request('update_all_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id,
tags=[tag])
def test_identity_delete_project_tag(self):
# user cannot delete tag for own project
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.own_project_id, tag=tag)
self.addCleanup(self.admin_project_tags_client.delete_project_tag,
project_id=self.own_project_id,
tag=tag)
self.do_request('delete_project_tag',
expected_status=exceptions.Forbidden,
project_id=self.own_project_id,
tag=tag)
# user cannot delete tag for arbitrary project
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.other_project_id, tag=tag)
self.do_request('delete_project_tag',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id,
tag=tag)
def test_identity_delete_project_tags(self):
# user cannot delete tags for own project
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.own_project_id, tag=tag)
self.addCleanup(self.admin_project_tags_client.delete_project_tag,
project_id=self.own_project_id,
tag=tag)
self.do_request('delete_all_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.own_project_id)
# user cannot delete tags for arbitrary project
tag = data_utils.rand_uuid_hex()
self.admin_project_tags_client.update_project_tag(
project_id=self.other_project_id, tag=tag)
self.do_request('delete_all_project_tags',
expected_status=exceptions.Forbidden,
project_id=self.other_project_id)
class ProjectReaderTests(ProjectMemberTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,302 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin import clients
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacProtocolTests(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacProtocolTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.keystone_manager = clients.Manager(cls.persona.credentials)
persona_mgr = clients.Manager(cls.persona.credentials)
cls.client = persona_mgr.identity_providers_client
admin_client = cls.os_system_admin
admin_mgr = clients.Manager(admin_client.credentials)
cls.admin_idp_client = admin_mgr.identity_providers_client
cls.admin_mapping_client = admin_mgr.mapping_rules_client
@classmethod
def setUpClass(cls):
super(IdentityV3RbacProtocolTests, cls).setUpClass()
cls.idp_id = cls.admin_idp_client.create_identity_provider(
idp_id=data_utils.rand_name())['identity_provider']['id']
cls.addClassResourceCleanup(
cls.admin_idp_client.delete_identity_provider, cls.idp_id)
rules = {
"rules":
[{
"local": [],
"remote": [{"type": data_utils.rand_name()}]
}]
}
cls.mapping_id = cls.admin_mapping_client.create_mapping_rule(
mapping_id=data_utils.rand_name(), rules=rules)['mapping']['id']
cls.addClassResourceCleanup(
cls.admin_mapping_client.delete_mapping_rule,
mapping_id=cls.mapping_id)
@abc.abstractmethod
def test_identity_create_protocol(self):
"""Test identity:create_protocol policy.
This test must check:
* whether the persona can create a protocol
"""
pass
@abc.abstractmethod
def test_identity_get_protocol(self):
"""Test identity:get_protocol policy.
This test must check:
* whether the persona can get a protocol
* whether the persona can get a protocol that does not
exist
"""
pass
@abc.abstractmethod
def test_identity_list_protocols(self):
"""Test identity:list_protocols policy.
This test must check:
* whether the persona can list all identity providers
"""
pass
@abc.abstractmethod
def test_identity_update_protocol(self):
"""Test identity:update_protocol policy.
This test must check:
* whether the persona can update a protocol
* whether the persona can update a protocol that does not
exist
"""
pass
@abc.abstractmethod
def test_identity_delete_protocol(self):
"""Test identity:delete_protocol policy.
This test must check
* whether the persona can delete a protocol
* whether the persona can delete a protocol that does not
exist
"""
pass
class SystemAdminTests(IdentityV3RbacProtocolTests, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_protocol(self):
protocol_id = self.do_request(
'add_protocol_and_mapping', expected_status=201,
idp_id=self.idp_id,
protocol_id=data_utils.rand_name(),
mapping_id=self.mapping_id
)['protocol']['id']
self.addCleanup(self.admin_idp_client.delete_protocol_and_mapping,
idp_id=self.idp_id,
protocol_id=protocol_id)
def test_identity_get_protocol(self):
protocol_id = self.admin_idp_client.add_protocol_and_mapping(
idp_id=self.idp_id,
protocol_id=data_utils.rand_name(),
mapping_id=self.mapping_id)['protocol']['id']
self.addCleanup(self.admin_idp_client.delete_protocol_and_mapping,
idp_id=self.idp_id,
protocol_id=protocol_id)
self.do_request('get_protocol_and_mapping',
idp_id=self.idp_id,
protocol_id=protocol_id)
# user gets a 404 for nonexistent idp
self.do_request('get_protocol_and_mapping',
expected_status=exceptions.NotFound,
idp_id=self.idp_id,
protocol_id=data_utils.rand_uuid_hex())
def test_identity_list_protocols(self):
protocol_id = self.admin_idp_client.add_protocol_and_mapping(
idp_id=self.idp_id,
protocol_id=data_utils.rand_name(),
mapping_id=self.mapping_id)['protocol']['id']
self.addCleanup(self.admin_idp_client.delete_protocol_and_mapping,
idp_id=self.idp_id,
protocol_id=protocol_id)
resp = self.do_request('list_protocols_and_mappings',
idp_id=self.idp_id)
self.assertIn(protocol_id, [p['id'] for p in resp['protocols']])
def test_identity_update_protocol(self):
protocol_id = self.admin_idp_client.add_protocol_and_mapping(
idp_id=self.idp_id,
protocol_id=data_utils.rand_name(),
mapping_id=self.mapping_id)['protocol']['id']
self.addCleanup(self.admin_idp_client.delete_protocol_and_mapping,
idp_id=self.idp_id,
protocol_id=protocol_id)
self.do_request('update_protocol_mapping',
idp_id=self.idp_id,
protocol_id=protocol_id,
mapping_id=self.mapping_id)
# user gets a 404 for nonexistent protocol
self.do_request('update_protocol_mapping',
expected_status=exceptions.NotFound,
idp_id=self.idp_id,
protocol_id=data_utils.rand_uuid_hex(),
mapping_id=self.mapping_id)
def test_identity_delete_protocol(self):
protocol_id = self.admin_idp_client.add_protocol_and_mapping(
idp_id=self.idp_id,
protocol_id=data_utils.rand_name(),
mapping_id=self.mapping_id)['protocol']['id']
self.do_request('delete_protocol_and_mapping', expected_status=204,
idp_id=self.idp_id,
protocol_id=protocol_id)
# user gets a 404 for nonexistent idp
self.do_request('delete_protocol_and_mapping',
expected_status=exceptions.NotFound,
idp_id=self.idp_id,
protocol_id=data_utils.rand_uuid_hex())
class SystemMemberTests(SystemAdminTests, base.BaseIdentityTest):
credentials = ['system_member', 'system_admin']
def test_identity_create_protocol(self):
self.do_request('add_protocol_and_mapping',
expected_status=exceptions.Forbidden,
idp_id=self.idp_id,
protocol_id=data_utils.rand_name(),
mapping_id=self.mapping_id)
def test_identity_update_protocol(self):
protocol_id = self.admin_idp_client.add_protocol_and_mapping(
idp_id=self.idp_id,
protocol_id=data_utils.rand_name(),
mapping_id=self.mapping_id)['protocol']['id']
self.addCleanup(self.admin_idp_client.delete_protocol_and_mapping,
idp_id=self.idp_id,
protocol_id=protocol_id)
self.do_request('update_protocol_mapping',
expected_status=exceptions.Forbidden,
idp_id=self.idp_id,
protocol_id=protocol_id,
mapping_id=self.mapping_id)
# user gets a 403 for nonexistent protocol
self.do_request('update_protocol_mapping',
expected_status=exceptions.Forbidden,
idp_id=self.idp_id,
protocol_id=data_utils.rand_uuid_hex(),
mapping_id=self.mapping_id)
def test_identity_delete_protocol(self):
protocol_id = self.admin_idp_client.add_protocol_and_mapping(
idp_id=self.idp_id,
protocol_id=data_utils.rand_name(),
mapping_id=self.mapping_id)['protocol']['id']
self.addCleanup(self.admin_idp_client.delete_protocol_and_mapping,
idp_id=self.idp_id,
protocol_id=protocol_id)
self.do_request('delete_protocol_and_mapping',
expected_status=exceptions.Forbidden,
idp_id=self.idp_id,
protocol_id=protocol_id)
# user gets a 403 for nonexistent protocol
self.do_request('delete_protocol_and_mapping',
expected_status=exceptions.Forbidden,
idp_id=self.idp_id,
protocol_id=data_utils.rand_uuid_hex())
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def test_identity_get_protocol(self):
protocol_id = self.admin_idp_client.add_protocol_and_mapping(
idp_id=self.idp_id,
protocol_id=data_utils.rand_name(),
mapping_id=self.mapping_id)['protocol']['id']
self.addCleanup(self.admin_idp_client.delete_protocol_and_mapping,
idp_id=self.idp_id,
protocol_id=protocol_id)
self.do_request('get_protocol_and_mapping',
expected_status=exceptions.Forbidden,
idp_id=self.idp_id,
protocol_id=protocol_id)
# user gets a 403 for nonexistent idp
self.do_request('get_protocol_and_mapping',
expected_status=exceptions.Forbidden,
idp_id=self.idp_id,
protocol_id=data_utils.rand_uuid_hex())
def test_identity_list_protocols(self):
protocol_id = self.admin_idp_client.add_protocol_and_mapping(
idp_id=self.idp_id,
protocol_id=data_utils.rand_name(),
mapping_id=self.mapping_id)['protocol']['id']
self.addCleanup(self.admin_idp_client.delete_protocol_and_mapping,
idp_id=self.idp_id,
protocol_id=protocol_id)
self.do_request('list_protocols_and_mappings',
expected_status=exceptions.Forbidden,
idp_id=self.idp_id)
class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,209 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacRegionTests(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacRegionTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.regions_client
admin_client = cls.os_system_admin
cls.admin_regions_client = admin_client.regions_client
def region(self):
return {'region_id': data_utils.rand_uuid_hex()}
@abc.abstractmethod
def test_identity_create_region(self):
"""Test identity:create_region policy.
This test must check:
* whether the persona can create a region
"""
pass
@abc.abstractmethod
def test_identity_get_region(self):
"""Test identity:get_region policy.
This test must check:
* whether the persona can get a region
* whether the persona can get a region that does not exist
"""
pass
@abc.abstractmethod
def test_identity_list_regions(self):
"""Test identity:list_regions policy.
This test must check:
* whether the persona can list all regions
"""
pass
@abc.abstractmethod
def test_identity_update_region(self):
"""Test identity:update_region policy.
This test must check:
* whether the persona can update a region
* whether the persona can update a region that does not exist
"""
pass
@abc.abstractmethod
def test_identity_delete_region(self):
"""Test identity:delete_region policy.
This test must check
* whether the persona can delete a region
* whether the persona can delete a region that does not exist
"""
pass
class SystemAdminTests(IdentityV3RbacRegionTests, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_region(self):
region_id = self.do_request(
'create_region', expected_status=201,
**self.region())['region']['id']
self.addCleanup(
self.admin_regions_client.delete_region,
region_id=region_id)
def test_identity_get_region(self):
region_id = self.admin_regions_client.create_region(
**self.region())['region']['id']
self.addCleanup(
self.admin_regions_client.delete_region,
region_id=region_id)
self.do_request('show_region', region_id=region_id)
# user gets a 404 for nonexistent region
self.do_request('show_region', expected_status=exceptions.NotFound,
region_id=data_utils.rand_uuid_hex())
def test_identity_list_regions(self):
region_id = self.admin_regions_client.create_region(
**self.region())['region']['id']
self.addCleanup(
self.admin_regions_client.delete_region,
region_id=region_id)
resp = self.do_request('list_regions')
self.assertIn(region_id, [e['id'] for e in resp['regions']])
def test_identity_update_region(self):
region_id = self.admin_regions_client.create_region(
**self.region())['region']['id']
self.addCleanup(
self.admin_regions_client.delete_region,
region_id=region_id)
self.do_request('update_region',
region_id=region_id,
description=data_utils.rand_uuid_hex())
# user gets a 404 for nonexistent region
self.do_request('update_region', expected_status=exceptions.NotFound,
region_id=data_utils.rand_uuid_hex(),
description=data_utils.rand_uuid_hex())
def test_identity_delete_region(self):
region_id = self.admin_regions_client.create_region(
**self.region())['region']['id']
self.do_request('delete_region', expected_status=204,
region_id=region_id)
# user gets a 404 for nonexistent region
self.do_request('delete_region', expected_status=exceptions.NotFound,
region_id=data_utils.rand_uuid_hex())
class SystemMemberTests(SystemAdminTests, base.BaseIdentityTest):
credentials = ['system_member', 'system_admin']
def test_identity_create_region(self):
self.do_request(
'create_region', expected_status=exceptions.Forbidden,
**self.region())
def test_identity_update_region(self):
region_id = self.admin_regions_client.create_region(
**self.region())['region']['id']
self.addCleanup(
self.admin_regions_client.delete_region,
region_id=region_id)
self.do_request('update_region', expected_status=exceptions.Forbidden,
region_id=region_id,
description=data_utils.rand_uuid_hex())
# user gets a 403 for nonexistent region
self.do_request('update_region', expected_status=exceptions.Forbidden,
region_id=data_utils.rand_uuid_hex(),
description=data_utils.rand_uuid_hex())
def test_identity_delete_region(self):
region_id = self.admin_regions_client.create_region(
**self.region())['region']['id']
self.do_request('delete_region',
expected_status=exceptions.Forbidden,
region_id=region_id)
# user gets a 403 for nonexistent region
self.do_request('delete_region', expected_status=exceptions.Forbidden,
region_id=data_utils.rand_uuid_hex())
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,222 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin import clients
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacRegisteredLimitTests(
rbac_base.IdentityV3RbacBaseTests, metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacRegisteredLimitTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
persona_mgr = clients.Manager(cls.persona.credentials)
cls.client = persona_mgr.registered_limits_client
cls.admin_client = cls.os_system_admin
admin_mgr = clients.Manager(cls.admin_client.credentials)
cls.admin_reglim_client = admin_mgr.registered_limits_client
@classmethod
def resource_setup(cls):
cls.region_id = cls.admin_client.regions_client.create_region(
region_id=data_utils.rand_name())['region']['id']
cls.addClassResourceCleanup(
cls.admin_client.regions_client.delete_region,
cls.region_id)
svc_client = cls.admin_client.identity_services_v3_client
cls.service_id = svc_client.create_service(
type=data_utils.rand_name())['service']['id']
cls.addClassResourceCleanup(svc_client.delete_service, cls.service_id)
def registered_limits(self):
return [
{
"service_id": self.service_id,
"region_id": self.region_id,
"resource_name": data_utils.rand_name(),
"default_limit": 5,
"description": data_utils.arbitrary_string()
}
]
@abc.abstractmethod
def test_identity_create_registered_limits(self):
"""Test identity:create_registered_limits policy.
This test must check:
* whether the persona can create a registered limit
"""
pass
@abc.abstractmethod
def test_identity_list_registered_limits(self):
"""Test identity:list_registered_limits policy.
This test must check:
* whether the persona can list registered limits
"""
pass
@abc.abstractmethod
def test_identity_get_registered_limit(self):
"""Test identity:get_registered_limit policy.
This test must check:
* whether the persona can get a registered limit
"""
pass
@abc.abstractmethod
def test_identity_update_registered_limit(self):
"""Test identity:update_registered_limit policy.
This test must check:
* whether the persona can update a registered limit
"""
pass
@abc.abstractmethod
def test_identity_delete_registered_limit(self):
"""Test identity:delete_registered_limit policy.
This test must check:
* whether the persona can delete a registered limit
"""
pass
class SystemAdminTests(IdentityV3RbacRegisteredLimitTests,
base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_registered_limits(self):
resp = self.do_request('create_registered_limits',
expected_status=201,
payload=self.registered_limits())
self.addCleanup(
self.admin_reglim_client.delete_registered_limit,
registered_limit_id=resp['registered_limits'][0]['id'])
def test_identity_list_registered_limits(self):
reg_limit_id = self.admin_reglim_client.create_registered_limits(
payload=self.registered_limits())['registered_limits'][0]['id']
self.addCleanup(
self.admin_reglim_client.delete_registered_limit,
registered_limit_id=reg_limit_id)
resp = self.do_request('list_registered_limits')
self.assertIn(
reg_limit_id, [rl['id'] for rl in resp['registered_limits']])
def test_identity_get_registered_limit(self):
reg_limit_id = self.admin_reglim_client.create_registered_limits(
payload=self.registered_limits())['registered_limits'][0]['id']
self.addCleanup(
self.admin_reglim_client.delete_registered_limit,
registered_limit_id=reg_limit_id)
self.do_request('show_registered_limit',
registered_limit_id=reg_limit_id)
def test_identity_update_registered_limit(self):
reg_limit_id = self.admin_reglim_client.create_registered_limits(
payload=self.registered_limits())['registered_limits'][0]['id']
self.addCleanup(
self.admin_reglim_client.delete_registered_limit,
registered_limit_id=reg_limit_id)
updated = {'description': data_utils.arbitrary_string()}
self.do_request('update_registered_limit',
registered_limit_id=reg_limit_id,
registered_limit=updated)
def test_identity_delete_registered_limit(self):
reg_limit_id = self.admin_reglim_client.create_registered_limits(
payload=self.registered_limits())['registered_limits'][0]['id']
self.do_request('delete_registered_limit',
expected_status=204,
registered_limit_id=reg_limit_id)
class SystemMemberTests(SystemAdminTests):
credentials = ['system_member', 'system_admin']
def test_identity_create_registered_limits(self):
self.do_request('create_registered_limits',
expected_status=exceptions.Forbidden,
payload=self.registered_limits())
def test_identity_update_registered_limit(self):
reg_limit_id = self.admin_reglim_client.create_registered_limits(
payload=self.registered_limits())['registered_limits'][0]['id']
self.addCleanup(
self.admin_reglim_client.delete_registered_limit,
registered_limit_id=reg_limit_id)
updated = {'description': data_utils.arbitrary_string()}
self.do_request('update_registered_limit',
expected_status=exceptions.Forbidden,
registered_limit_id=reg_limit_id,
registered_limit=updated)
def test_identity_delete_registered_limit(self):
reg_limit_id = self.admin_reglim_client.create_registered_limits(
payload=self.registered_limits())['registered_limits'][0]['id']
self.addCleanup(
self.admin_reglim_client.delete_registered_limit,
registered_limit_id=reg_limit_id)
self.do_request('delete_registered_limit',
expected_status=exceptions.Forbidden,
registered_limit_id=reg_limit_id)
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests):
credentials = ['domain_admin', 'system_admin']
class DomainMemberTests(DomainAdminTests):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectMemberTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,390 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacRoleTest(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacRoleTest, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.roles_v3_client
cls.admin_client = cls.os_system_admin
cls.admin_roles_client = cls.admin_client.roles_v3_client
@classmethod
def resource_setup(cls):
super(IdentityV3RbacRoleTest, cls).resource_setup()
cls.own_domain = cls.persona.credentials.domain_id
cls.domain_id = cls.admin_client.domains_client.create_domain(
name=data_utils.rand_name('domain'))['domain']['id']
cls.addClassResourceCleanup(
cls.admin_client.domains_client.delete_domain,
cls.domain_id)
cls.addClassResourceCleanup(
cls.admin_client.domains_client.update_domain,
cls.domain_id,
enabled=False)
def role(self, domain_id=None):
role = {}
name = data_utils.rand_name('role')
role['name'] = name
if domain_id:
role['domain_id'] = domain_id
return role
@abc.abstractmethod
def test_identity_create_role(self):
"""Test identity:create_role policy.
This test must check:
* whether the persona can create a role
"""
pass
@abc.abstractmethod
def test_identity_get_role(self):
"""Test identity:get_role policy.
This test must check:
* whether the persona can get a role
* whether the persona can get a role that does not exist
"""
pass
@abc.abstractmethod
def test_identity_list_roles(self):
"""Test identity:list_roles policy.
This test must check:
* whether the persona can list roles
"""
pass
@abc.abstractmethod
def test_identity_update_role(self):
"""Test identity:update_role policy.
This test must check:
* whether the persona can update a role
* whether the persona can update a role that does not exist
"""
pass
@abc.abstractmethod
def test_identity_delete_role(self):
"""Test identity:delete_role policy.
This test must check
* whether the persona can delete a role
* whether the persona can delete a role that does not exist
"""
pass
@abc.abstractmethod
def test_identity_create_domain_role(self):
"""Test identity:create_domain_role policy.
This test must check:
* whether the persona can create a domain role in their own domain
* whether the persona can create a domain role in another domain
"""
pass
@abc.abstractmethod
def test_identity_get_domain_role(self):
"""Test identity:get_domain_role policy.
This test must check:
* whether the persona can get a domain role in their own domain
* whether the persona can get a domain role in another domain
* whether the persona can get a domain role that does not exist
"""
pass
@abc.abstractmethod
def test_identity_list_domain_roles(self):
"""Test identity:list_domain_roles policy.
This test must check:
* whether the persona can list domain roles for their own domain
* whether the persona can list domain roles for another domain
"""
pass
@abc.abstractmethod
def test_identity_update_domain_role(self):
"""Test identity:update_domain_role policy.
This test must check:
* whether the persona can update a domain role for their own domain
* whether the persona can update a domain role for another domain
* whether the persona can update a domain role that does not exist
"""
pass
@abc.abstractmethod
def test_identity_delete_domain_role(self):
"""Test identity:delete_domain_role policy.
This test must check
* whether the persona can delete a domain role for their own domain
* whether the persona can delete a domain role for another domain
* whether the persona can delete a domain role that does not exist
"""
pass
class SystemAdminTests(IdentityV3RbacRoleTest, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_role(self):
# user can create role
resp = self.do_request('create_role',
expected_status=201,
**self.role())
self.addCleanup(self.admin_roles_client.delete_role,
resp['role']['id'])
def test_identity_get_role(self):
# user can get role
role = self.admin_roles_client.create_role(**self.role())['role']
self.addCleanup(self.admin_roles_client.delete_role, role['id'])
self.do_request('show_role', role_id=role['id'])
# user gets a 404 for nonexistent role
self.do_request('show_role', expected_status=exceptions.NotFound,
role_id=data_utils.rand_uuid_hex())
def test_identity_list_roles(self):
# user can list roles
role = self.admin_roles_client.create_role(**self.role())['role']
self.addCleanup(self.admin_roles_client.delete_role, role['id'])
self.do_request('list_roles')
def test_identity_update_role(self):
# user can update role
role = self.admin_roles_client.create_role(**self.role())['role']
self.addCleanup(self.admin_roles_client.delete_role, role['id'])
self.do_request('update_role',
role_id=role['id'],
description=data_utils.arbitrary_string())
# user gets a 404 for nonexistent role
self.do_request('update_role', expected_status=exceptions.NotFound,
role_id=data_utils.rand_uuid_hex(),
description=data_utils.arbitrary_string())
def test_identity_delete_role(self):
# user can delete role
role = self.admin_roles_client.create_role(**self.role())['role']
self.do_request('delete_role', expected_status=204, role_id=role['id'])
# user gets a 404 for nonexistent role
self.do_request('delete_role', expected_status=exceptions.NotFound,
role_id=data_utils.rand_uuid_hex())
def test_identity_create_domain_role(self):
# user can create domain role
resp = self.do_request('create_role',
expected_status=201,
**self.role(domain_id=self.domain_id))
self.addCleanup(self.admin_roles_client.delete_role,
resp['role']['id'])
def test_identity_get_domain_role(self):
# user can get domain role
role = self.admin_roles_client.create_role(
**self.role(domain_id=self.domain_id))['role']
self.addCleanup(self.admin_roles_client.delete_role, role['id'])
self.do_request('show_role', role_id=role['id'])
# user gets a 404 for nonexistent domain role
self.do_request('show_role', expected_status=exceptions.NotFound,
role_id=data_utils.rand_uuid_hex())
def test_identity_list_domain_roles(self):
# user can list domain roles
role = self.admin_roles_client.create_role(
**self.role(domain_id=self.domain_id))['role']
self.addCleanup(self.admin_roles_client.delete_role, role['id'])
self.do_request('list_roles', domain_id=self.domain_id)
def test_identity_update_domain_role(self):
# user can update domain role
role = self.admin_roles_client.create_role(
**self.role(domain_id=self.domain_id))['role']
self.addCleanup(self.admin_roles_client.delete_role, role['id'])
self.do_request('update_role',
role_id=role['id'],
description=data_utils.arbitrary_string())
# user gets a 404 for nonexistent domain role
self.do_request('update_role', expected_status=exceptions.NotFound,
role_id=data_utils.rand_uuid_hex(),
description=data_utils.arbitrary_string())
def test_identity_delete_domain_role(self):
# user can delete role in other domain
role = self.admin_roles_client.create_role(
**self.role(domain_id=self.domain_id))['role']
self.do_request('delete_role', expected_status=204, role_id=role['id'])
# user gets a 404 for nonexistent role
self.do_request('delete_role', expected_status=exceptions.NotFound,
role_id=data_utils.rand_uuid_hex())
class SystemMemberTests(SystemAdminTests):
credentials = ['system_member', 'system_admin']
def test_identity_create_role(self):
# user cannot create role
self.do_request('create_role',
expected_status=exceptions.Forbidden,
**self.role())
def test_identity_update_role(self):
# user cannot update role
role = self.admin_roles_client.create_role(
**self.role())['role']
self.addCleanup(self.admin_roles_client.delete_role, role['id'])
self.do_request('update_role', expected_status=exceptions.Forbidden,
role_id=role['id'],
description=data_utils.arbitrary_string())
# user gets a 404 for nonexistent role
self.do_request('update_role', expected_status=exceptions.NotFound,
role_id=data_utils.rand_uuid_hex(),
description=data_utils.arbitrary_string())
def test_identity_delete_role(self):
# user can delete role
role = self.admin_roles_client.create_role(
**self.role())['role']
self.do_request('delete_role', expected_status=exceptions.Forbidden,
role_id=role['id'])
# user gets a 404 for nonexistent domain role
self.do_request('delete_role', expected_status=exceptions.NotFound,
role_id=data_utils.rand_uuid_hex())
def test_identity_create_domain_role(self):
# user cannot create domain role
self.do_request('create_role',
expected_status=exceptions.Forbidden,
**self.role(domain_id=self.domain_id))
def test_identity_update_domain_role(self):
# user cannot update domain role
role = self.admin_roles_client.create_role(
**self.role(domain_id=self.domain_id))['role']
self.addCleanup(self.admin_roles_client.delete_role, role['id'])
self.do_request('update_role', expected_status=exceptions.Forbidden,
role_id=role['id'],
description=data_utils.arbitrary_string())
# user gets a 404 for nonexistent domain role
self.do_request('update_role', expected_status=exceptions.NotFound,
role_id=data_utils.rand_uuid_hex(),
description=data_utils.arbitrary_string())
def test_identity_delete_domain_role(self):
# user can delete domain role
role = self.admin_roles_client.create_role(
**self.role(domain_id=self.domain_id))['role']
self.do_request('delete_role', expected_status=exceptions.Forbidden,
role_id=role['id'])
# user gets a 404 for nonexistent domain role
self.do_request('delete_role', expected_status=exceptions.NotFound,
role_id=data_utils.rand_uuid_hex())
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests):
credentials = ['domain_admin', 'system_admin']
def test_identity_get_role(self):
# user cannot get role
role = self.admin_roles_client.create_role(
**self.role())['role']
self.addCleanup(self.admin_roles_client.delete_role, role['id'])
self.do_request('show_role', expected_status=exceptions.Forbidden,
role_id=role['id'])
# user gets a 404 for nonexistent role
self.do_request('show_role', expected_status=exceptions.NotFound,
role_id=data_utils.rand_uuid_hex())
def test_identity_list_roles(self):
# user cannot list roles
role = self.admin_roles_client.create_role(**self.role())['role']
self.addCleanup(self.admin_roles_client.delete_role, role['id'])
self.do_request('list_roles', expected_status=exceptions.Forbidden)
def test_identity_get_domain_role(self):
# user cannot get domain role in own domain
role = self.admin_roles_client.create_role(**self.role())['role']
self.addCleanup(self.admin_roles_client.delete_role, role['id'])
self.do_request('show_role', expected_status=exceptions.Forbidden,
role_id=role['id'])
# user gets a 404 for nonexistent domain role
self.do_request('show_role', expected_status=exceptions.NotFound,
role_id=data_utils.rand_uuid_hex())
def test_identity_list_domain_roles(self):
# user cannot list domain roles in own domain
role = self.admin_roles_client.create_role(
**self.role(domain_id=self.own_domain))['role']
self.addCleanup(self.admin_roles_client.delete_role, role['id'])
self.do_request('list_roles', expected_status=exceptions.Forbidden,
domain_id=self.persona.credentials.domain_id)
# user cannot get domain role in other domain
role = self.admin_roles_client.create_role(
**self.role(domain_id=self.domain_id))['role']
self.addCleanup(self.admin_roles_client.delete_role, role['id'])
self.do_request('list_roles', expected_status=exceptions.Forbidden,
domain_id=self.domain_id)
class DomainMemberTests(DomainAdminTests):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,233 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacServiceTests(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacServiceTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.identity_services_v3_client
admin_client = cls.os_system_admin
cls.admin_services_client = admin_client.identity_services_v3_client
def service(self):
return {
'name': data_utils.rand_name('service_name'),
'type': data_utils.rand_name('service_type'),
}
@abc.abstractmethod
def test_identity_create_service(self):
"""Test identity:create_service policy.
This test must check:
* whether the persona can create a service
"""
pass
@abc.abstractmethod
def test_identity_get_service(self):
"""Test identity:get_service policy.
This test must check:
* whether the persona can get a service
* whether the persona can get a service that does not exist
"""
pass
@abc.abstractmethod
def test_identity_list_services(self):
"""Test identity:list_services policy.
This test must check:
* whether the persona can list all services
"""
pass
@abc.abstractmethod
def test_identity_update_service(self):
"""Test identity:update_service policy.
This test must check:
* whether the persona can update a service
* whether the persona can update a service that does not exist
"""
pass
@abc.abstractmethod
def test_identity_delete_service(self):
"""Test identity:delete_service policy.
This test must check
* whether the persona can delete a service
* whether the persona can delete a service that does not exist
"""
pass
class SystemAdminTests(IdentityV3RbacServiceTests, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_service(self):
service_id = self.do_request(
'create_service', expected_status=201,
**self.service())['service']['id']
self.addCleanup(
self.admin_services_client.delete_service,
service_id=service_id)
def test_identity_get_service(self):
service_id = self.admin_services_client.create_service(
**self.service())['service']['id']
self.addCleanup(
self.admin_services_client.delete_service,
service_id=service_id)
self.do_request('show_service', service_id=service_id)
# user gets a 404 for nonexistent service
self.do_request('show_service', expected_status=exceptions.NotFound,
service_id=data_utils.rand_uuid_hex())
def test_identity_list_services(self):
service_id = self.admin_services_client.create_service(
**self.service())['service']['id']
self.addCleanup(
self.admin_services_client.delete_service,
service_id=service_id)
resp = self.do_request('list_services')
self.assertIn(service_id, [e['id'] for e in resp['services']])
def test_identity_update_service(self):
service_id = self.admin_services_client.create_service(
**self.service())['service']['id']
self.addCleanup(
self.admin_services_client.delete_service,
service_id=service_id)
self.do_request('update_service',
service_id=service_id,
type=data_utils.rand_name('service_type'))
# user gets a 404 for nonexistent service
self.do_request('update_service', expected_status=exceptions.NotFound,
service_id=data_utils.rand_uuid_hex(),
type=data_utils.rand_name('service_type'))
def test_identity_delete_service(self):
service_id = self.admin_services_client.create_service(
**self.service())['service']['id']
self.do_request('delete_service', expected_status=204,
service_id=service_id)
# user gets a 404 for nonexistent service
self.do_request('delete_service', expected_status=exceptions.NotFound,
service_id=data_utils.rand_uuid_hex())
class SystemMemberTests(SystemAdminTests, base.BaseIdentityTest):
credentials = ['system_member', 'system_admin']
def test_identity_create_service(self):
self.do_request(
'create_service', expected_status=exceptions.Forbidden,
**self.service())
def test_identity_update_service(self):
service_id = self.admin_services_client.create_service(
**self.service())['service']['id']
self.addCleanup(
self.admin_services_client.delete_service,
service_id=service_id)
self.do_request('update_service',
expected_status=exceptions.Forbidden,
service_id=service_id,
type=data_utils.rand_name('service_type'))
# user gets a 403 for nonexistent service
self.do_request('update_service', expected_status=exceptions.Forbidden,
service_id=data_utils.rand_uuid_hex(),
type=data_utils.rand_name('service_type'))
def test_identity_delete_service(self):
service_id = self.admin_services_client.create_service(
**self.service())['service']['id']
self.do_request('delete_service',
expected_status=exceptions.Forbidden,
service_id=service_id)
# user gets a 403 for nonexistent service
self.do_request('delete_service', expected_status=exceptions.Forbidden,
service_id=data_utils.rand_uuid_hex())
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def test_identity_get_service(self):
service_id = self.admin_services_client.create_service(
**self.service())['service']['id']
self.addCleanup(
self.admin_services_client.delete_service,
service_id=service_id)
self.do_request('show_service', expected_status=exceptions.Forbidden,
service_id=service_id)
# user gets a 403 for nonexistent service
self.do_request('show_service', expected_status=exceptions.Forbidden,
service_id=data_utils.rand_uuid_hex())
def test_identity_list_services(self):
service_id = self.admin_services_client.create_service(
**self.service())['service']['id']
self.addCleanup(
self.admin_services_client.delete_service,
service_id=service_id)
self.do_request('list_services', expected_status=exceptions.Forbidden)
class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,250 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin import clients
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacServiceProviderTests(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacServiceProviderTests, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
persona_mgr = clients.Manager(cls.persona.credentials)
cls.client = persona_mgr.service_providers_client
admin_client = cls.os_system_admin
admin_mgr = clients.Manager(admin_client.credentials)
cls.admin_sp_client = admin_mgr.service_providers_client
@abc.abstractmethod
def test_identity_create_service_provider(self):
"""Test identity:create_service_provider policy.
This test must check:
* whether the persona can create a service provider
"""
pass
@abc.abstractmethod
def test_identity_get_service_provider(self):
"""Test identity:get_service_provider policy.
This test must check:
* whether the persona can get a service provider
* whether the persona can get a service provider that does not
exist
"""
pass
@abc.abstractmethod
def test_identity_list_service_providers(self):
"""Test identity:list_service_providers policy.
This test must check:
* whether the persona can list all identity providers
"""
pass
@abc.abstractmethod
def test_identity_update_service_provider(self):
"""Test identity:update_service_provider policy.
This test must check:
* whether the persona can update a service provider
* whether the persona can update a service provider that does not
exist
"""
pass
@abc.abstractmethod
def test_identity_delete_service_provider(self):
"""Test identity:delete_service_provider policy.
This test must check
* whether the persona can delete a service provider
* whether the persona can delete a service provider that does not
exist
"""
pass
class SystemAdminTests(IdentityV3RbacServiceProviderTests,
base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_service_provider(self):
sp_id = self.do_request(
'create_service_provider', expected_status=201,
sp_id=data_utils.rand_name(),
auth_url=data_utils.rand_url(),
sp_url=data_utils.rand_url()
)['service_provider']['id']
self.addCleanup(self.admin_sp_client.delete_service_provider, sp_id)
def test_identity_get_service_provider(self):
sp_id = self.admin_sp_client.create_service_provider(
sp_id=data_utils.rand_name(),
auth_url=data_utils.rand_url(),
sp_url=data_utils.rand_url())['service_provider']['id']
self.addCleanup(self.admin_sp_client.delete_service_provider, sp_id)
self.do_request('show_service_provider', sp_id=sp_id)
# user gets a 404 for nonexistent sp
self.do_request('show_service_provider',
expected_status=exceptions.NotFound,
sp_id=data_utils.rand_uuid_hex())
def test_identity_list_service_providers(self):
sp_id = self.admin_sp_client.create_service_provider(
sp_id=data_utils.rand_name(),
auth_url=data_utils.rand_url(),
sp_url=data_utils.rand_url())['service_provider']['id']
self.addCleanup(self.admin_sp_client.delete_service_provider, sp_id)
resp = self.do_request('list_service_providers')
self.assertIn(sp_id, [i['id'] for i in resp['service_providers']])
def test_identity_update_service_provider(self):
sp_id = self.admin_sp_client.create_service_provider(
sp_id=data_utils.rand_name(),
auth_url=data_utils.rand_url(),
sp_url=data_utils.rand_url())['service_provider']['id']
self.addCleanup(self.admin_sp_client.delete_service_provider, sp_id)
self.do_request('update_service_provider',
sp_id=sp_id,
description=data_utils.arbitrary_string())
# user gets a 404 for nonexistent sp
self.do_request('update_service_provider',
expected_status=exceptions.NotFound,
sp_id=data_utils.rand_uuid_hex(),
description=data_utils.arbitrary_string())
def test_identity_delete_service_provider(self):
sp_id = self.admin_sp_client.create_service_provider(
sp_id=data_utils.rand_name(),
auth_url=data_utils.rand_url(),
sp_url=data_utils.rand_url())['service_provider']['id']
self.do_request('delete_service_provider', expected_status=204,
sp_id=sp_id)
# user gets a 404 for nonexistent sp
self.do_request('delete_service_provider',
expected_status=exceptions.NotFound,
sp_id=sp_id)
class SystemMemberTests(SystemAdminTests, base.BaseIdentityTest):
credentials = ['system_member', 'system_admin']
def test_identity_create_service_provider(self):
self.do_request('create_service_provider',
expected_status=exceptions.Forbidden,
sp_id=data_utils.rand_name(),
auth_url=data_utils.rand_url(),
sp_url=data_utils.rand_url())
def test_identity_update_service_provider(self):
sp_id = self.admin_sp_client.create_service_provider(
sp_id=data_utils.rand_name(),
auth_url=data_utils.rand_url(),
sp_url=data_utils.rand_url())['service_provider']['id']
self.addCleanup(self.admin_sp_client.delete_service_provider, sp_id)
self.do_request('update_service_provider',
expected_status=exceptions.Forbidden,
sp_id=sp_id,
description=data_utils.arbitrary_string())
# user gets a 403 for nonexistent sp
self.do_request('update_service_provider',
expected_status=exceptions.Forbidden,
sp_id=data_utils.rand_uuid_hex(),
description=data_utils.arbitrary_string())
def test_identity_delete_service_provider(self):
sp_id = self.admin_sp_client.create_service_provider(
sp_id=data_utils.rand_name(),
auth_url=data_utils.rand_url(),
sp_url=data_utils.rand_url())['service_provider']['id']
self.addCleanup(self.admin_sp_client.delete_service_provider, sp_id)
self.do_request('delete_service_provider',
expected_status=exceptions.Forbidden,
sp_id=sp_id)
# user gets a 403 for nonexistent sp
self.do_request('delete_service_provider',
expected_status=exceptions.Forbidden,
sp_id=sp_id)
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def test_identity_get_service_provider(self):
sp_id = self.admin_sp_client.create_service_provider(
sp_id=data_utils.rand_name(),
auth_url=data_utils.rand_url(),
sp_url=data_utils.rand_url())['service_provider']['id']
self.addCleanup(self.admin_sp_client.delete_service_provider, sp_id)
self.do_request('show_service_provider',
expected_status=exceptions.Forbidden,
sp_id=sp_id)
# user gets a 403 for nonexistent sp
self.do_request('show_service_provider',
expected_status=exceptions.Forbidden,
sp_id=data_utils.rand_uuid_hex())
def test_identity_list_service_providers(self):
sp_id = self.admin_sp_client.create_service_provider(
sp_id=data_utils.rand_name(),
auth_url=data_utils.rand_url(),
sp_url=data_utils.rand_url())['service_provider']['id']
self.addCleanup(self.admin_sp_client.delete_service_provider, sp_id)
self.do_request('list_service_providers',
expected_status=exceptions.Forbidden)
class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainReaderTests, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,309 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest import clients
from tempest.lib import auth
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacTokenTest(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacTokenTest, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.identity_v3_client
@classmethod
def resource_setup(cls):
admin_client = cls.os_system_admin
cls.user = {
'name': data_utils.rand_name('user'),
'password': data_utils.rand_password(),
}
cls.user_id = admin_client.users_v3_client.create_user(
**cls.user)['user']['id']
cls.addClassResourceCleanup(
admin_client.users_v3_client.delete_user, user_id=cls.user_id)
cls.project_id = admin_client.projects_client.create_project(
name=data_utils.rand_name()
)['project']['id']
cls.addClassResourceCleanup(
admin_client.projects_client.delete_project,
project_id=cls.project_id)
cls.domain_id = admin_client.domains_client.create_domain(
name=data_utils.rand_name()
)['domain']['id']
cls.addClassResourceCleanup(
admin_client.domains_client.delete_domain,
domain_id=cls.domain_id)
cls.addClassResourceCleanup(
admin_client.domains_client.update_domain,
domain_id=cls.domain_id, enabled=False)
role_id = admin_client.roles_v3_client.create_role(
name=data_utils.rand_name())['role']['id']
cls.addClassResourceCleanup(
admin_client.roles_v3_client.delete_role,
role_id=role_id)
admin_client.roles_v3_client.create_user_role_on_project(
project_id=cls.project_id,
user_id=cls.user_id,
role_id=role_id
)
admin_client.roles_v3_client.create_user_role_on_domain(
domain_id=cls.domain_id,
user_id=cls.user_id,
role_id=role_id
)
admin_client.roles_v3_client.create_user_role_on_system(
user_id=cls.user_id,
role_id=role_id
)
def setUp(self):
super(IdentityV3RbacTokenTest, self).setUp()
own_creds = auth.KeystoneV3Credentials(**self.own_keystone_creds)
own_creds = clients.get_auth_provider(own_creds).fill_credentials()
self.own_token = clients.Manager(
credentials=own_creds).identity_v3_client.token
project_creds = auth.KeystoneV3Credentials(
user_id=self.user_id,
password=self.user['password'],
project_id=self.project_id)
project_creds = clients.get_auth_provider(
project_creds).fill_credentials()
self.project_token = clients.Manager(
credentials=project_creds).identity_v3_client.token
domain_creds = auth.KeystoneV3Credentials(
user_id=self.user_id,
password=self.user['password'],
domain_id=self.domain_id)
domain_creds = clients.get_auth_provider(
domain_creds).fill_credentials()
self.domain_token = clients.Manager(
credentials=domain_creds).identity_v3_client.token
system_creds = auth.KeystoneV3Credentials(
user_id=self.user_id,
password=self.user['password'],
system='all')
system_creds = clients.get_auth_provider(
system_creds).fill_credentials()
self.system_token = clients.Manager(
credentials=system_creds).identity_v3_client.token
@abc.abstractmethod
def test_identity_check_token(self):
"""Test identity:check_token policy.
This test must check:
* whether the persona can check their own token in their current
scope
* whether the persona can check a system-scoped token for a different
user
* whether the persona can check a domain-scoped token for a different
user
* whether the persona can check a project-scoped token for a
different user
"""
pass
@abc.abstractmethod
def test_identity_validate_token(self):
"""Test identity:validate_token policy.
This test must validate:
* whether the persona can validate their own token in their current
scope
* whether the persona can validate a system-scoped token for a
different user
* whether the persona can validate a domain-scoped token for a
different user
* whether the persona can validate a project-scoped token for a
different user
"""
pass
@abc.abstractmethod
def test_identity_revoke_token(self):
"""Test identity:revoke_token policy.
This test must revoke:
* whether the persona can revoke their own token in their current
scope
* whether the persona can revoke a system-scoped token for a
different user
* whether the persona can revoke a domain-scoped token for a
different user
* whether the persona can revoke a project-scoped token for a
different user
"""
pass
class SystemAdminTests(IdentityV3RbacTokenTest, base.BaseIdentityTest):
credentials = ['system_admin']
def setUp(self):
self.own_keystone_creds = {
'user_id': self.persona.credentials.user_id,
'password': self.persona.credentials.password,
'system': 'all'
}
super(SystemAdminTests, self).setUp()
def test_identity_check_token(self):
# user can check own token
self.do_request('check_token_existence', resp_token=self.own_token)
# user can check other system user's token
self.do_request('check_token_existence', resp_token=self.system_token)
# user can check domain user's token
self.do_request('check_token_existence', resp_token=self.domain_token)
# user can check project user's token
self.do_request('check_token_existence', resp_token=self.project_token)
def test_identity_validate_token(self):
# user can validate own token
self.do_request('show_token', resp_token=self.own_token)
# user can validate other system user's token
self.do_request('show_token', resp_token=self.system_token)
# user can validate domain user's token
self.do_request('show_token', resp_token=self.domain_token)
# user can validate project user's token
self.do_request('show_token', resp_token=self.project_token)
def test_identity_revoke_token(self):
# user can revoke own token
self.do_request('delete_token', expected_status=204,
resp_token=self.own_token)
# user can revoke other system user's token
self.do_request('delete_token', expected_status=204,
resp_token=self.system_token)
# user can revoke domain user's token
self.do_request('delete_token', expected_status=204,
resp_token=self.domain_token)
# user can revoke project user's token
self.do_request('delete_token', expected_status=204,
resp_token=self.project_token)
class SystemMemberTests(SystemAdminTests):
credentials = ['system_member', 'system_admin']
def test_identity_revoke_token(self):
# user can revoke own token
self.do_request('delete_token', expected_status=204,
resp_token=self.own_token)
# user cannot revoke other system user's token
self.do_request('delete_token', expected_status=exceptions.Forbidden,
resp_token=self.system_token)
# user cannot revoke domain user's token
self.do_request('delete_token', expected_status=exceptions.Forbidden,
resp_token=self.domain_token)
# user cannot revoke project user's token
self.do_request('delete_token', expected_status=exceptions.Forbidden,
resp_token=self.project_token)
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def setUp(self):
self.own_keystone_creds = {
'user_id': self.persona.credentials.user_id,
'password': self.persona.credentials.password,
'domain_id': self.persona.credentials.domain_id
}
# call base setUp directly to ensure we don't use system creds
super(SystemAdminTests, self).setUp()
def test_identity_check_token(self):
# user can check own token
self.do_request('check_token_existence', resp_token=self.own_token)
# user cannot check other system user's token
self.do_request('check_token_existence',
expected_status=exceptions.Forbidden,
resp_token=self.system_token)
# user cannot check domain user's token
self.do_request('check_token_existence',
expected_status=exceptions.Forbidden,
resp_token=self.domain_token)
# user cannot check project user's token
self.do_request('check_token_existence',
expected_status=exceptions.Forbidden,
resp_token=self.project_token)
def test_identity_validate_token(self):
# user can validate own token
self.do_request('show_token', resp_token=self.own_token)
# user cannot validate other system user's token
self.do_request('show_token',
expected_status=exceptions.Forbidden,
resp_token=self.system_token)
# user cannot validate domain user's token
self.do_request('show_token',
expected_status=exceptions.Forbidden,
resp_token=self.domain_token)
# user cannot validate project user's token
self.do_request('show_token',
expected_status=exceptions.Forbidden,
resp_token=self.project_token)
class DomainMemberTests(DomainAdminTests):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainAdminTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(DomainAdminTests, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
def setUp(self):
self.own_keystone_creds = {
'user_id': self.persona.credentials.user_id,
'password': self.persona.credentials.password,
'project_id': self.persona.credentials.project_id
}
# call base setUp directly to ensure we don't use system creds
super(SystemAdminTests, self).setUp()
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -0,0 +1,559 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest import clients
from tempest.lib import auth
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacTrustTest(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacTrustTest, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.trusts_client
cls.admin_client = cls.os_system_admin
cls.admin_trusts_client = cls.admin_client.trusts_client
@classmethod
def resource_setup(cls):
trustor_user = {
'name': data_utils.rand_name('user'),
'password': data_utils.rand_password(),
}
cls.trustor = cls.admin_client.users_v3_client.create_user(
**trustor_user)['user']['id']
cls.addClassResourceCleanup(
cls.admin_client.users_v3_client.delete_user,
user_id=cls.trustor)
cls.trustee = cls.admin_client.users_v3_client.create_user(
name=data_utils.rand_name())['user']['id']
cls.addClassResourceCleanup(
cls.admin_client.users_v3_client.delete_user,
user_id=cls.trustee)
cls.project = cls.admin_client.projects_client.create_project(
name=data_utils.rand_name()
)['project']['id']
cls.addClassResourceCleanup(
cls.admin_client.projects_client.delete_project,
project_id=cls.project)
cls.roles = [
{'id': cls.admin_client.roles_v3_client.create_role(
name=data_utils.rand_name())['role']['id']}
]
cls.addClassResourceCleanup(
cls.admin_client.roles_v3_client.delete_role,
role_id=cls.roles[0]['id'])
cls.admin_client.roles_v3_client.create_user_role_on_project(
project_id=cls.project,
user_id=cls.trustor,
role_id=cls.roles[0]['id']
)
creds = auth.KeystoneV3Credentials(
user_id=cls.trustor,
password=trustor_user['password'],
project_id=cls.project)
auth_provider = clients.get_auth_provider(creds)
creds = auth_provider.fill_credentials()
user_client = clients.Manager(credentials=creds)
cls.user_trust_client = user_client.trusts_client
cls.admin_role_id = cls.admin_client.roles_v3_client.list_roles(
name='admin')['roles'][0]['id']
cls.member_role_id = cls.admin_client.roles_v3_client.list_roles(
name='member')['roles'][0]['id']
cls.reader_role_id = cls.admin_client.roles_v3_client.list_roles(
name='reader')['roles'][0]['id']
def trust(self, trustor=None, trustee=None, project_id=None, roles=None):
trust = {}
trust['trustor_user_id'] = trustor or self.trustor
trust['trustee_user_id'] = trustee or self.trustee
trust['project_id'] = project_id or self.project
trust['roles'] = roles or self.roles
trust['impersonation'] = False
return trust
@abc.abstractmethod
def test_identity_create_trust(self):
"""Test identity:create_trust policy.
This test must check:
* whether the persona can create a trust for themself
* whether the persona can create a trust for another user
"""
pass
@abc.abstractmethod
def test_identity_get_trust(self):
"""Test identity:get_trust policy.
This test must check:
* whether the persona can get a trust for which they are the trustor
* whether the persona can get a trust for which they are the trustee
* whether the persona can get a trust with which they are
unaffiliated
"""
pass
@abc.abstractmethod
def test_identity_list_trusts(self):
"""Test identity:list_trusts policy.
This test must check:
* whether the persona can list all trusts
"""
pass
@abc.abstractmethod
def test_identity_list_trusts_for_trustor(self):
"""Test identity:list_trusts_for_trustor policy.
This test must check:
* whether the persona can list trusts by trustor for which they are
the trustor
* whether the persona can list trusts by trustor for which another
user is trustor
"""
pass
@abc.abstractmethod
def test_identity_list_trusts_for_trustee(self):
"""Test identity:list_trusts_for_trustee policy.
This test must check:
* whether the persona can list trusts by trustee for which they are
the trustee
* whether the persona can list trusts by trustee for which another
user is trustee
"""
pass
@abc.abstractmethod
def test_identity_list_roles_for_trust(self):
"""Test identity:list_roles_for_trust policy.
This test must check:
* whether the persona can list the roles of a trust for which they
are the trustee
* whether the persona can list the roles of a trust for which they
are the trustor
* whether the persona can list the roles of a trust with which they
are unaffiliated
"""
pass
@abc.abstractmethod
def test_identity_get_role_for_trust(self):
"""Test identity:get_role_for_trust policy.
This test must check:
* whether the persona can get a role of a trust for which they are
the trustee
* whether the persona can get a role of a trust for which they are
the trustor
* whether the persona can get a role of a trust with which they are
unaffiliated
"""
pass
@abc.abstractmethod
def test_identity_delete_trust(self):
"""Test identity:delete_trust policy.
This test must check
* whether the persona can delete a trust for which they are the
trustor
* whether the persona can delete a trust for which they are the
trustee
* whether the persona can delete a trust which which they are
unaffiliated
"""
pass
class SystemAdminTests(IdentityV3RbacTrustTest, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_trust(self):
# user cannot create trust for themself
self.do_request('create_trust',
expected_status=exceptions.Forbidden,
**self.trust(trustor=self.persona.credentials.user_id))
# user cannot create trust for another user
self.do_request('create_trust',
expected_status=exceptions.Forbidden,
**self.trust())
def test_identity_get_trust(self):
# user cannot have their own trust
# user can get trust for other user
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.admin_trusts_client.delete_trust,
trust_id=trust_id)
self.do_request('show_trust', trust_id=trust_id)
def test_identity_list_trusts(self):
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.admin_trusts_client.delete_trust,
trust_id=trust_id)
resp = self.do_request('list_trusts')
self.assertIn(trust_id, [t['id'] for t in resp['trusts']])
def test_identity_list_trusts_for_trustor(self):
# user cannot have their own trust
# user can list trusts for other user
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.admin_trusts_client.delete_trust,
trust_id=trust_id)
self.do_request('list_trusts', trustor_user_id=self.trustor)
def test_identity_list_trusts_for_trustee(self):
# user cannot have their own trust
# user can list trusts for other user
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.admin_trusts_client.delete_trust,
trust_id=trust_id)
self.do_request('list_trusts', trustee_user_id=self.trustee)
def test_identity_list_roles_for_trust(self):
# user cannot have their own trust
# user can list roles of trust for other user
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.admin_trusts_client.delete_trust,
trust_id=trust_id)
resp = self.do_request('list_trust_roles', trust_id=trust_id)
self.assertIn(self.roles[0]['id'], [r['id'] for r in resp['roles']])
def test_identity_get_role_for_trust(self):
# user cannot have their own trust
# user can get role of trust for other user
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.admin_trusts_client.delete_trust,
trust_id=trust_id)
self.do_request('show_trust_role',
trust_id=trust_id, role_id=self.roles[0]['id'])
def test_identity_delete_trust(self):
# user cannot have their own trust
# user can delete a user's trust
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.do_request('delete_trust', expected_status=204, trust_id=trust_id)
class SystemMemberTests(SystemAdminTests):
credentials = ['system_member', 'system_admin']
def test_identity_delete_trust(self):
# system user cannot have their own trust
# user cannot delete another user's trust
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.admin_trusts_client.delete_trust,
trust_id=trust_id)
self.do_request('delete_trust', expected_status=exceptions.Forbidden,
trust_id=trust_id)
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(SystemReaderTests, base.BaseIdentityTest):
# Domain admins cannot create their own trusts (trusts can only be
# scoped to projects) and domain admins have no special privileges over the
# trusts own by users in their domains.
credentials = ['domain_admin', 'system_admin']
def test_identity_get_trust(self):
# user cannot have their own trust
# user can get trust for other user
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.admin_trusts_client.delete_trust,
trust_id=trust_id)
self.do_request('show_trust', expected_status=exceptions.Forbidden,
trust_id=trust_id)
def test_identity_list_trusts(self):
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.admin_trusts_client.delete_trust,
trust_id=trust_id)
self.do_request('list_trusts',
expected_status=exceptions.Forbidden)
def test_identity_list_trusts_for_trustor(self):
# user cannot have their own trust
# user can list trusts for other user
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.admin_trusts_client.delete_trust,
trust_id=trust_id)
self.do_request('list_trusts', expected_status=exceptions.Forbidden,
trustor_user_id=self.trustor)
def test_identity_list_trusts_for_trustee(self):
# user cannot have their own trust
# user can list trusts for other user
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.admin_trusts_client.delete_trust,
trust_id=trust_id)
self.do_request('list_trusts', expected_status=exceptions.Forbidden,
trustee_user_id=self.trustee)
def test_identity_list_roles_for_trust(self):
# user cannot have their own trust
# user can list roles of trust for other user
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.admin_trusts_client.delete_trust,
trust_id=trust_id)
self.do_request('list_trust_roles',
expected_status=exceptions.Forbidden,
trust_id=trust_id)
def test_identity_get_role_for_trust(self):
# user cannot have their own trust
# user can get role of trust for other user
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.admin_trusts_client.delete_trust,
trust_id=trust_id)
self.do_request('show_trust_role',
expected_status=exceptions.Forbidden,
trust_id=trust_id, role_id=self.roles[0]['id'])
class DomainMemberTests(DomainAdminTests):
credentials = ['domain_member', 'system_admin']
class DomainReaderTests(DomainAdminTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(IdentityV3RbacTrustTest, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
def setUp(self):
super(ProjectAdminTests, self).setUp()
self.role_id = self.admin_role_id
def test_identity_create_trust(self):
# user can create a trust for their own project
trustor_user_id = self.persona.credentials.user_id
project_id = self.persona.credentials.project_id
resp = self.do_request(
'create_trust',
expected_status=201,
**self.trust(
trustor=trustor_user_id,
project_id=project_id,
roles=[{'id': self.role_id}])
)['trust']
self.addCleanup(self.client.delete_trust, resp['id'])
# user cannot create trust with another user as trustor
self.do_request(
'create_trust',
expected_status=exceptions.Forbidden,
**self.trust())
def test_identity_get_trust(self):
# user can get a trust for which they are trustor
trustor_user_id = self.persona.credentials.user_id
project_id = self.persona.credentials.project_id
trust_id = self.client.create_trust(
**self.trust(trustor=trustor_user_id,
project_id=project_id,
roles=[{'id': self.role_id}]))['trust']['id']
self.addCleanup(self.client.delete_trust, trust_id=trust_id)
self.do_request('show_trust', trust_id=trust_id)
# user can get a trust for which they are trustee
trustee_user_id = self.persona.credentials.user_id
trust_id = self.user_trust_client.create_trust(
**self.trust(trustee=trustee_user_id))['trust']['id']
self.addCleanup(self.user_trust_client.delete_trust, trust_id=trust_id)
self.do_request('show_trust', trust_id=trust_id)
# user cannot get a trust with which they are unaffiliated
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.user_trust_client.delete_trust, trust_id=trust_id)
self.do_request('show_trust', expected_status=exceptions.Forbidden,
trust_id=trust_id)
def test_identity_list_trusts(self):
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.admin_trusts_client.delete_trust,
trust_id=trust_id)
self.do_request('list_trusts',
expected_status=exceptions.Forbidden)
def test_identity_list_trusts_for_trustor(self):
# user can list their own trusts
trustor_user_id = self.persona.credentials.user_id
project_id = self.persona.credentials.project_id
trust_id = self.client.create_trust(
**self.trust(trustor=trustor_user_id,
project_id=project_id,
roles=[{'id': self.role_id}]))['trust']['id']
self.addCleanup(self.client.delete_trust, trust_id=trust_id)
self.do_request('list_trusts', trustor_user_id=trustor_user_id)
# user cannot list another user's trusts
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.user_trust_client.delete_trust, trust_id=trust_id)
self.do_request('list_trusts', expected_status=exceptions.Forbidden,
trustor_user_id=self.trustor)
def test_identity_list_trusts_for_trustee(self):
# user can list their own trusts
trustee_user_id = self.persona.credentials.user_id
trust_id = self.user_trust_client.create_trust(
**self.trust(trustee=trustee_user_id))['trust']['id']
self.addCleanup(self.user_trust_client.delete_trust, trust_id=trust_id)
self.do_request('list_trusts', trustee_user_id=trustee_user_id)
# user cannot list another user's trusts
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.user_trust_client.delete_trust, trust_id=trust_id)
self.do_request('list_trusts', expected_status=exceptions.Forbidden,
trustee_user_id=self.trustee)
def test_identity_list_roles_for_trust(self):
# user can list roles for trust for which they are trustor
trustor_user_id = self.persona.credentials.user_id
project_id = self.persona.credentials.project_id
trust_id = self.client.create_trust(
**self.trust(trustor=trustor_user_id,
project_id=project_id,
roles=[{'id': self.role_id}]))['trust']['id']
self.addCleanup(self.client.delete_trust, trust_id=trust_id)
self.do_request('list_trust_roles', trust_id=trust_id)
# user can list roles for trust for which they are trustee
trustee_user_id = self.persona.credentials.user_id
trust_id = self.user_trust_client.create_trust(
**self.trust(trustee=trustee_user_id))['trust']['id']
self.addCleanup(self.user_trust_client.delete_trust, trust_id=trust_id)
self.do_request('list_trust_roles', trust_id=trust_id)
# user cannot list roles for trust with which they are unaffiliated
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.user_trust_client.delete_trust, trust_id=trust_id)
self.do_request('list_trust_roles',
expected_status=exceptions.Forbidden,
trust_id=trust_id)
def test_identity_get_role_for_trust(self):
# user can get roles for trust for which they are trustor
trustor_user_id = self.persona.credentials.user_id
project_id = self.persona.credentials.project_id
trust_id = self.client.create_trust(
**self.trust(trustor=trustor_user_id,
project_id=project_id,
roles=[{'id': self.role_id}]))['trust']['id']
self.addCleanup(self.client.delete_trust, trust_id=trust_id)
self.do_request('show_trust_role',
trust_id=trust_id, role_id=self.role_id)
# user can list roles for trust for which they are trustee
trustee_user_id = self.persona.credentials.user_id
trust_id = self.user_trust_client.create_trust(
**self.trust(trustee=trustee_user_id))['trust']['id']
self.addCleanup(self.user_trust_client.delete_trust, trust_id=trust_id)
self.do_request('show_trust_role',
trust_id=trust_id, role_id=self.roles[0]['id'])
# user cannot list roles for trust with which they are unaffiliated
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.user_trust_client.delete_trust, trust_id=trust_id)
self.do_request('show_trust_role',
expected_status=exceptions.Forbidden,
trust_id=trust_id, role_id=self.role_id)
def test_identity_delete_trust(self):
# user can delete trust for which they are the trustor
trustor_user_id = self.persona.credentials.user_id
project_id = self.persona.credentials.project_id
trust_id = self.client.create_trust(
**self.trust(trustor=trustor_user_id,
project_id=project_id,
roles=[{'id': self.role_id}]))['trust']['id']
self.do_request('delete_trust', expected_status=204, trust_id=trust_id)
# user cannot delete trust for which they are the trustee
trustee_user_id = self.persona.credentials.user_id
trust_id = self.user_trust_client.create_trust(
**self.trust(trustee=trustee_user_id))['trust']['id']
self.addCleanup(self.user_trust_client.delete_trust, trust_id=trust_id)
self.do_request('delete_trust', expected_status=exceptions.Forbidden,
trust_id=trust_id)
# user cannot delete trust with which they are unaffiliated
trust_id = self.user_trust_client.create_trust(
**self.trust())['trust']['id']
self.addCleanup(self.user_trust_client.delete_trust, trust_id=trust_id)
self.do_request('delete_trust', expected_status=exceptions.Forbidden,
trust_id=trust_id)
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
def setUp(self):
super(ProjectMemberTests, self).setUp()
self.role_id = self.member_role_id
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']
def setUp(self):
super(ProjectReaderTests, self).setUp()
self.role_id = self.reader_role_id

View File

@ -0,0 +1,540 @@
# Copyright 2020 SUSE LLC
#
# 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 abc
from tempest.api.identity import base
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions
from keystone_tempest_plugin.tests.rbac.v3 import base as rbac_base
class IdentityV3RbacUserTest(rbac_base.IdentityV3RbacBaseTests,
metaclass=abc.ABCMeta):
@classmethod
def setup_clients(cls):
super(IdentityV3RbacUserTest, cls).setup_clients()
cls.persona = getattr(cls, 'os_%s' % cls.credentials[0])
cls.client = cls.persona.users_v3_client
admin_client = cls.os_system_admin
cls.admin_users_client = admin_client.users_v3_client
cls.admin_domains_client = admin_client.domains_client
def user(self):
user = {}
name = data_utils.rand_name('user')
user['name'] = name
user['description'] = name + 'description'
user['email'] = name + '@testmail.tm'
user['password'] = data_utils.rand_password()
user['enabled'] = False
return user
@abc.abstractmethod
def test_identity_create_user(self):
"""Test identity:create_user policy.
This test must check:
* whether the persona can create an arbitrary user
* whether the persona can create a user in another domain
(if applicable)
* whether the persona can create a user in their own domain
(if applicable)
"""
pass
@abc.abstractmethod
def test_identity_get_user(self):
"""Test identity:get_user policy.
This test must check:
* whether the persona can get an arbitary user
* whether the persona can get their own user
* whether the persona can get a user in another domain
(if applicable)
* whether the persona can get a user in their own domain
(if applicable)
* whether the persona can get a user that does not exist
"""
pass
@abc.abstractmethod
def test_identity_list_users(self):
"""Test identity:list_users policy.
This test must check:
* whether the persona can list all users
* whether the result list is appropriately filtered to domain
(if applicable)
"""
pass
@abc.abstractmethod
def test_identity_update_user(self):
"""Test identity:update_users policy.
This test must check:
* whether the persona can update an arbitrary user
* whether the persona can update a user in another domain
(if applicable)
* whether the persona can update a user in their own domain
(if applicable)
* whether the persona can update a user that does not exist
"""
pass
@abc.abstractmethod
def test_identity_delete_user(self):
"""Test identity:delete_user policy.
This test must check
* whether the persona can delete an arbitrary user
* whether the persona can delete a user in another domain
(if applicable)
* whether the persona can delete a user in their own domain
(if applicable)
* whether the persona can delete a user that does not exist
"""
pass
class SystemAdminTests(IdentityV3RbacUserTest, base.BaseIdentityTest):
credentials = ['system_admin']
def test_identity_create_user(self):
resp = self.do_request('create_user',
expected_status=201,
**self.user())
self.addCleanup(self.admin_users_client.delete_user,
resp['user']['id'])
def test_identity_get_user(self):
user = self.admin_users_client.create_user(**self.user())['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
# user can get arbitrary user
resp = self.do_request('show_user', user_id=user['id'])
self.assertEqual(resp['user']['id'], user['id'])
# user can get own user
user_id = self.persona.credentials.user_id
resp = self.do_request('show_user', user_id=user_id)
self.assertEqual(resp['user']['id'], user_id)
# user gets a 404 for nonexistent user
self.do_request('show_user', expected_status=exceptions.NotFound,
user_id='fakeuser')
def test_identity_list_users(self):
domain = self.admin_domains_client.create_domain(
name=data_utils.rand_name())['domain']
user_create = self.user()
# create user in default domain
user1 = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user1['id'])
# create user in arbitrary domain
user_create['domain_id'] = domain['id']
user2 = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user2['id'])
resp = self.do_request('list_users')
user_ids = set(u['id'] for u in resp['users'])
# both users should be in the list
self.assertIn(user1['id'], user_ids)
self.assertIn(user2['id'], user_ids)
def test_identity_update_user(self):
user = self.admin_users_client.create_user(**self.user())['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
user_update = {
'user_id': user['id'],
'description': data_utils.arbitrary_string()
}
self.do_request('update_user', **user_update)
# user gets a 404 for nonexistent user
user_update = {
'user_id': 'fakeuser',
'description': data_utils.arbitrary_string()
}
self.do_request('update_user', expected_status=exceptions.NotFound,
**user_update)
def test_identity_delete_user(self):
user = self.admin_users_client.create_user(**self.user())['user']
self.do_request('delete_user', expected_status=204, user_id=user['id'])
# user gets a 404 for nonexistent user
self.do_request('delete_user', expected_status=exceptions.NotFound,
user_id='fakeuser')
class SystemMemberTests(IdentityV3RbacUserTest, base.BaseIdentityTest):
credentials = ['system_member', 'system_admin']
def test_identity_create_user(self):
self.do_request('create_user', expected_status=exceptions.Forbidden,
**self.user())
def test_identity_get_user(self):
user = self.admin_users_client.create_user(**self.user())['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
# user can get arbitrary user
resp = self.do_request('show_user', user_id=user['id'])
self.assertEqual(resp['user']['id'], user['id'])
# user can get own user
user_id = self.persona.credentials.user_id
resp = self.do_request('show_user', user_id=user_id)
self.assertEqual(resp['user']['id'], user_id)
# user gets a 404 for nonexistent user
self.do_request('show_user', expected_status=exceptions.NotFound,
user_id='fakeuser')
def test_identity_list_users(self):
domain = self.admin_domains_client.create_domain(
name=data_utils.rand_name())['domain']
user_create = self.user()
# create user in default domain
user1 = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user1['id'])
# create user in arbitrary domain
user_create['domain_id'] = domain['id']
user2 = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user2['id'])
resp = self.do_request('list_users')
user_ids = set(u['id'] for u in resp['users'])
# both users should be in the list
self.assertIn(user1['id'], user_ids)
self.assertIn(user2['id'], user_ids)
def test_identity_update_user(self):
user = self.admin_users_client.create_user(**self.user())['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
user_update = {
'user_id': user['id'],
'description': data_utils.arbitrary_string()
}
self.do_request('update_user', expected_status=exceptions.Forbidden,
**user_update)
# user gets a 403 for nonexistent user
user_update = {
'user_id': 'fakeuser',
'description': data_utils.arbitrary_string()
}
self.do_request('update_user', expected_status=exceptions.Forbidden,
**user_update)
def test_identity_delete_user(self):
user = self.admin_users_client.create_user(**self.user())['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
self.do_request('delete_user', expected_status=exceptions.Forbidden,
user_id=user['id'])
# user gets a 403 for nonexistent user
self.do_request('delete_user', expected_status=exceptions.Forbidden,
user_id='fakeuser')
class SystemReaderTests(SystemMemberTests):
credentials = ['system_reader', 'system_admin']
class DomainAdminTests(IdentityV3RbacUserTest, base.BaseIdentityTest):
credentials = ['domain_admin', 'system_admin']
def setUp(self):
super(DomainAdminTests, self).setUp()
self.other_domain = self.admin_domains_client.create_domain(
name=data_utils.rand_name())['domain']
self.addCleanup(self.admin_domains_client.delete_domain,
self.other_domain['id'])
self.addCleanup(self.admin_domains_client.update_domain,
domain_id=self.other_domain['id'], enabled=False)
def test_identity_create_user(self):
user_create = self.user()
# create user in other domain
user_create['domain_id'] = self.other_domain['id']
self.do_request('create_user', expected_status=exceptions.Forbidden,
**user_create)
# create user in own domain
user_create['domain_id'] = self.persona.credentials.domain_id
resp = self.do_request('create_user',
expected_status=201,
**user_create)
self.addCleanup(self.admin_users_client.delete_user,
resp['user']['id'])
def test_identity_get_user(self):
user_create = self.user()
user_create['domain_id'] = self.other_domain['id']
user = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
# user cannot get user in other domain
self.do_request('show_user', expected_status=exceptions.Forbidden,
user_id=user['id'])
user_create['domain_id'] = self.persona.credentials.domain_id
user = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
# user can get user in own domain
resp = self.do_request('show_user', user_id=user['id'])
self.assertEqual(resp['user']['id'], user['id'])
# user can get own user
user_id = self.persona.credentials.user_id
resp = self.do_request('show_user', user_id=user_id)
self.assertEqual(resp['user']['id'], user_id)
# user gets a 403 for nonexistent user
self.do_request('show_user', expected_status=exceptions.Forbidden,
user_id='fakeuser')
def test_identity_list_users(self):
user_create = self.user()
# create user in other domain
user_create['domain_id'] = self.other_domain['id']
user1 = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user1['id'])
# create user in own domain
user_create['domain_id'] = self.persona.credentials.domain_id
user2 = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user2['id'])
resp = self.do_request('list_users')
user_ids = set(u['id'] for u in resp['users'])
self.assertNotIn(user1['id'], user_ids)
self.assertIn(user2['id'], user_ids)
def test_identity_update_user(self):
user_create = self.user()
# create user in other domain
user_create['domain_id'] = self.other_domain['id']
user = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
user_update = {
'user_id': user['id'],
'description': data_utils.arbitrary_string()
}
self.do_request('update_user', expected_status=exceptions.Forbidden,
**user_update)
# create user in own domain
user_create['domain_id'] = self.persona.credentials.domain_id
user = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
user_update = {
'user_id': user['id'],
'description': data_utils.arbitrary_string()
}
self.do_request('update_user', **user_update)
# user gets a 403 for nonexistent user
user_update = {
'user_id': 'fakeuser',
'description': data_utils.arbitrary_string()
}
self.do_request('update_user', expected_status=exceptions.Forbidden,
**user_update)
def test_identity_delete_user(self):
user_create = self.user()
# create user in other domain
user_create['domain_id'] = self.other_domain['id']
user = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
self.do_request('delete_user', expected_status=exceptions.Forbidden,
user_id=user['id'])
# create user in own domain
user_create['domain_id'] = self.persona.credentials.domain_id
user = self.admin_users_client.create_user(**user_create)['user']
self.do_request('delete_user', expected_status=204, user_id=user['id'])
# user gets a 403 for nonexistent user
self.do_request('delete_user', expected_status=exceptions.Forbidden,
user_id='fakeuser')
class DomainMemberTests(IdentityV3RbacUserTest, base.BaseIdentityTest):
credentials = ['domain_member', 'system_admin']
def setUp(self):
super(DomainMemberTests, self).setUp()
self.other_domain = self.admin_domains_client.create_domain(
name=data_utils.rand_name())['domain']
self.addCleanup(self.admin_domains_client.delete_domain,
self.other_domain['id'])
self.addCleanup(self.admin_domains_client.update_domain,
domain_id=self.other_domain['id'], enabled=False)
def test_identity_create_user(self):
user_create = self.user()
# create user without domain specified
self.do_request('create_user', expected_status=exceptions.Forbidden,
**user_create)
# create user in other domain
user_create['domain_id'] = self.other_domain['id']
self.do_request('create_user', expected_status=exceptions.Forbidden,
**user_create)
# create user in own domain
user_create['domain_id'] = self.persona.credentials.domain_id
self.do_request('create_user', expected_status=exceptions.Forbidden,
**user_create)
def test_identity_get_user(self):
user_create = self.user()
user_create['domain_id'] = self.other_domain['id']
user = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
# user cannot get user in other domain
self.do_request('show_user', expected_status=exceptions.Forbidden,
user_id=user['id'])
user_create['domain_id'] = self.persona.credentials.domain_id
user = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
# user can get user in own domain
resp = self.do_request('show_user', user_id=user['id'])
self.assertEqual(resp['user']['id'], user['id'])
# user can get own user
user_id = self.persona.credentials.user_id
resp = self.do_request('show_user', user_id=user_id)
self.assertEqual(resp['user']['id'], user_id)
# user gets a 403 for nonexistent user
self.do_request('show_user', expected_status=exceptions.Forbidden,
user_id='fakeuser')
def test_identity_list_users(self):
user_create = self.user()
# create user in other domain
user_create['domain_id'] = self.other_domain['id']
user1 = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user1['id'])
# create user in own domain
user_create['domain_id'] = self.persona.credentials.domain_id
user2 = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user2['id'])
resp = self.do_request('list_users')
user_ids = set(u['id'] for u in resp['users'])
self.assertNotIn(user1['id'], user_ids)
self.assertIn(user2['id'], user_ids)
def test_identity_update_user(self):
user_create = self.user()
# create user in other domain
user_create['domain_id'] = self.other_domain['id']
user = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
user_update = {
'user_id': user['id'],
'description': data_utils.arbitrary_string()
}
self.do_request('update_user', expected_status=exceptions.Forbidden,
**user_update)
# create user in own domain
user_create['domain_id'] = self.persona.credentials.domain_id
user = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
user_update = {
'user_id': user['id'],
'description': data_utils.arbitrary_string()
}
self.do_request('update_user', expected_status=exceptions.Forbidden,
**user_update)
# user gets a 403 for nonexistent user
user_update = {
'user_id': 'fakeuser',
'description': data_utils.arbitrary_string()
}
self.do_request('update_user', expected_status=exceptions.Forbidden,
**user_update)
def test_identity_delete_user(self):
user_create = self.user()
# create user in other domain
user_create['domain_id'] = self.other_domain['id']
user = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
self.do_request('delete_user', expected_status=exceptions.Forbidden,
user_id=user['id'])
# create user in own domain
user_create['domain_id'] = self.persona.credentials.domain_id
user = self.admin_users_client.create_user(**user_create)['user']
self.do_request('delete_user', expected_status=exceptions.Forbidden,
user_id=user['id'])
# user gets a 403 for nonexistent user
self.do_request('delete_user', expected_status=exceptions.Forbidden,
user_id='fakeuser')
class DomainReaderTests(DomainMemberTests):
credentials = ['domain_reader', 'system_admin']
class ProjectAdminTests(IdentityV3RbacUserTest, base.BaseIdentityTest):
credentials = ['project_admin', 'system_admin']
def test_identity_create_user(self):
self.do_request('create_user', expected_status=exceptions.Forbidden,
**self.user())
def test_identity_get_user(self):
user = self.admin_users_client.create_user(**self.user())['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
# user cannot get arbitrary user
self.do_request('show_user', expected_status=exceptions.Forbidden,
user_id=user['id'])
# user can get own user
user_id = self.persona.credentials.user_id
resp = self.do_request('show_user', user_id=user_id)
self.assertEqual(resp['user']['id'], user_id)
# user gets a 403 for nonexistent user
self.do_request('show_user', expected_status=exceptions.Forbidden,
user_id='fakeuser')
def test_identity_list_users(self):
user = self.admin_users_client.create_user(**self.user())['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
self.do_request('list_users', expected_status=exceptions.Forbidden)
def test_identity_update_user(self):
user_create = self.user()
user = self.admin_users_client.create_user(**user_create)['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
user_update = {
'user_id': user['id'],
'description': data_utils.arbitrary_string()
}
self.do_request('update_user', expected_status=exceptions.Forbidden,
**user_update)
# user gets a 403 for nonexistent user
user_update = {
'user_id': 'fakeuser',
'description': data_utils.arbitrary_string()
}
self.do_request('update_user', expected_status=exceptions.Forbidden,
**user_update)
def test_identity_delete_user(self):
user = self.admin_users_client.create_user(**self.user())['user']
self.addCleanup(self.admin_users_client.delete_user, user['id'])
self.do_request('delete_user', expected_status=exceptions.Forbidden,
user_id=user['id'])
# user gets a 403 for nonexistent user
self.do_request('delete_user', expected_status=exceptions.Forbidden,
user_id='fakeuser')
class ProjectMemberTests(ProjectAdminTests):
credentials = ['project_member', 'system_admin']
class ProjectReaderTests(ProjectAdminTests):
credentials = ['project_reader', 'system_admin']

View File

@ -42,6 +42,6 @@ commands = oslo_debug_helper {posargs}
# E123, E125 skipped as they are invalid PEP-8.
show-source = True
ignore = E123,E125
ignore = E123,E125,W503
builtins = _
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build