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:
parent
2473e5bdba
commit
a6d4ceaf57
38
.zuul.yaml
38
.zuul.yaml
@ -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
|
||||
|
@ -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',
|
||||
|
@ -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)]
|
||||
|
0
keystone_tempest_plugin/tests/rbac/__init__.py
Normal file
0
keystone_tempest_plugin/tests/rbac/__init__.py
Normal file
0
keystone_tempest_plugin/tests/rbac/v3/__init__.py
Normal file
0
keystone_tempest_plugin/tests/rbac/v3/__init__.py
Normal file
41
keystone_tempest_plugin/tests/rbac/v3/base.py
Normal file
41
keystone_tempest_plugin/tests/rbac/v3/base.py
Normal 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
|
487
keystone_tempest_plugin/tests/rbac/v3/test_access_rule.py
Normal file
487
keystone_tempest_plugin/tests/rbac/v3/test_access_rule.py
Normal 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']
|
@ -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']
|
196
keystone_tempest_plugin/tests/rbac/v3/test_consumer.py
Normal file
196
keystone_tempest_plugin/tests/rbac/v3/test_consumer.py
Normal 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']
|
490
keystone_tempest_plugin/tests/rbac/v3/test_credential.py
Normal file
490
keystone_tempest_plugin/tests/rbac/v3/test_credential.py
Normal 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']
|
223
keystone_tempest_plugin/tests/rbac/v3/test_domain.py
Normal file
223
keystone_tempest_plugin/tests/rbac/v3/test_domain.py
Normal 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']
|
381
keystone_tempest_plugin/tests/rbac/v3/test_domain_config.py
Normal file
381
keystone_tempest_plugin/tests/rbac/v3/test_domain_config.py
Normal 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']
|
544
keystone_tempest_plugin/tests/rbac/v3/test_ec2_credential.py
Normal file
544
keystone_tempest_plugin/tests/rbac/v3/test_ec2_credential.py
Normal 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']
|
245
keystone_tempest_plugin/tests/rbac/v3/test_endpoint.py
Normal file
245
keystone_tempest_plugin/tests/rbac/v3/test_endpoint.py
Normal 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']
|
521
keystone_tempest_plugin/tests/rbac/v3/test_endpoint_group.py
Normal file
521
keystone_tempest_plugin/tests/rbac/v3/test_endpoint_group.py
Normal 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']
|
3799
keystone_tempest_plugin/tests/rbac/v3/test_grant.py
Normal file
3799
keystone_tempest_plugin/tests/rbac/v3/test_grant.py
Normal file
File diff suppressed because it is too large
Load Diff
1152
keystone_tempest_plugin/tests/rbac/v3/test_group.py
Normal file
1152
keystone_tempest_plugin/tests/rbac/v3/test_group.py
Normal file
File diff suppressed because it is too large
Load Diff
283
keystone_tempest_plugin/tests/rbac/v3/test_identity_provider.py
Normal file
283
keystone_tempest_plugin/tests/rbac/v3/test_identity_provider.py
Normal 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']
|
257
keystone_tempest_plugin/tests/rbac/v3/test_implied_role.py
Normal file
257
keystone_tempest_plugin/tests/rbac/v3/test_implied_role.py
Normal 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']
|
391
keystone_tempest_plugin/tests/rbac/v3/test_limit.py
Normal file
391
keystone_tempest_plugin/tests/rbac/v3/test_limit.py
Normal 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']
|
255
keystone_tempest_plugin/tests/rbac/v3/test_mapping.py
Normal file
255
keystone_tempest_plugin/tests/rbac/v3/test_mapping.py
Normal 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']
|
232
keystone_tempest_plugin/tests/rbac/v3/test_policy.py
Normal file
232
keystone_tempest_plugin/tests/rbac/v3/test_policy.py
Normal 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']
|
469
keystone_tempest_plugin/tests/rbac/v3/test_policy_association.py
Normal file
469
keystone_tempest_plugin/tests/rbac/v3/test_policy_association.py
Normal 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']
|
467
keystone_tempest_plugin/tests/rbac/v3/test_project.py
Normal file
467
keystone_tempest_plugin/tests/rbac/v3/test_project.py
Normal 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']
|
251
keystone_tempest_plugin/tests/rbac/v3/test_project_endpoint.py
Normal file
251
keystone_tempest_plugin/tests/rbac/v3/test_project_endpoint.py
Normal 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']
|
599
keystone_tempest_plugin/tests/rbac/v3/test_project_tag.py
Normal file
599
keystone_tempest_plugin/tests/rbac/v3/test_project_tag.py
Normal 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']
|
302
keystone_tempest_plugin/tests/rbac/v3/test_protocol.py
Normal file
302
keystone_tempest_plugin/tests/rbac/v3/test_protocol.py
Normal 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']
|
209
keystone_tempest_plugin/tests/rbac/v3/test_region.py
Normal file
209
keystone_tempest_plugin/tests/rbac/v3/test_region.py
Normal 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']
|
222
keystone_tempest_plugin/tests/rbac/v3/test_registered_limit.py
Normal file
222
keystone_tempest_plugin/tests/rbac/v3/test_registered_limit.py
Normal 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']
|
390
keystone_tempest_plugin/tests/rbac/v3/test_role.py
Normal file
390
keystone_tempest_plugin/tests/rbac/v3/test_role.py
Normal 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']
|
1130
keystone_tempest_plugin/tests/rbac/v3/test_role_assignment.py
Normal file
1130
keystone_tempest_plugin/tests/rbac/v3/test_role_assignment.py
Normal file
File diff suppressed because it is too large
Load Diff
233
keystone_tempest_plugin/tests/rbac/v3/test_service.py
Normal file
233
keystone_tempest_plugin/tests/rbac/v3/test_service.py
Normal 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']
|
250
keystone_tempest_plugin/tests/rbac/v3/test_service_provider.py
Normal file
250
keystone_tempest_plugin/tests/rbac/v3/test_service_provider.py
Normal 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']
|
309
keystone_tempest_plugin/tests/rbac/v3/test_token.py
Normal file
309
keystone_tempest_plugin/tests/rbac/v3/test_token.py
Normal 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']
|
559
keystone_tempest_plugin/tests/rbac/v3/test_trust.py
Normal file
559
keystone_tempest_plugin/tests/rbac/v3/test_trust.py
Normal 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
|
540
keystone_tempest_plugin/tests/rbac/v3/test_user.py
Normal file
540
keystone_tempest_plugin/tests/rbac/v3/test_user.py
Normal 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']
|
Loading…
Reference in New Issue
Block a user