diff options
author | Sascha Peilicke <saschpe@suse.de> | 2013-01-21 15:34:42 +0100 |
---|---|---|
committer | Monty Taylor <mordred@inaugust.com> | 2013-08-14 01:30:01 -0300 |
commit | 14e090154c10001550127628c2728013f15d4256 (patch) | |
tree | 99be365f496f7942638a95f28241839c6ca8771a /tests | |
parent | 361f6fe111b3eddf013c544776d63980689dfaf5 (diff) | |
download | keystone-14e090154c10001550127628c2728013f15d4256.tar.gz keystone-14e090154c10001550127628c2728013f15d4256.tar.xz keystone-14e090154c10001550127628c2728013f15d4256.zip |
Move 'tests' directory into 'keystone' package
Similar to a range of other components (e.g. glance,nova,...) and recent
reviews by Monty.
Running individual tests can be done like this:
./run_tests.sh keystone.tests.test_drivers
Change-Id: I2482a48322150e5eb09b703326a94d8283f1c75b
Diffstat (limited to 'tests')
75 files changed, 0 insertions, 20377 deletions
diff --git a/tests/_ldap_livetest.py b/tests/_ldap_livetest.py deleted file mode 100644 index ead54ea7..00000000 --- a/tests/_ldap_livetest.py +++ /dev/null @@ -1,160 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 ldap -import ldap.modlist -import subprocess - -from keystone.common import ldap as ldap_common -from keystone import config -from keystone import exception -from keystone.identity.backends import ldap as identity_ldap -from keystone import test - -import test_backend_ldap - - -CONF = config.CONF - - -def create_object(dn, attrs): - conn = ldap.initialize(CONF.ldap.url) - conn.simple_bind_s(CONF.ldap.user, CONF.ldap.password) - ldif = ldap.modlist.addModlist(attrs) - conn.add_s(dn, ldif) - conn.unbind_s() - - -class LiveLDAPIdentity(test_backend_ldap.LDAPIdentity): - - def clear_database(self): - devnull = open('/dev/null', 'w') - subprocess.call(['ldapdelete', - '-x', - '-D', CONF.ldap.user, - '-H', CONF.ldap.url, - '-w', CONF.ldap.password, - '-r', CONF.ldap.suffix], - stderr=devnull) - - if CONF.ldap.suffix.startswith('ou='): - tree_dn_attrs = {'objectclass': 'organizationalUnit', - 'ou': 'openstack'} - else: - tree_dn_attrs = {'objectclass': ['dcObject', 'organizationalUnit'], - 'dc': 'openstack', - 'ou': 'openstack'} - create_object(CONF.ldap.suffix, tree_dn_attrs) - create_object(CONF.ldap.user_tree_dn, - {'objectclass': 'organizationalUnit', - 'ou': 'Users'}) - create_object(CONF.ldap.role_tree_dn, - {'objectclass': 'organizationalUnit', - 'ou': 'Roles'}) - create_object(CONF.ldap.tenant_tree_dn, - {'objectclass': 'organizationalUnit', - 'ou': 'Projects'}) - create_object(CONF.ldap.group_tree_dn, - {'objectclass': 'organizationalUnit', - 'ou': 'UserGroups'}) - - def _set_config(self): - self.config([test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf'), - test.testsdir('backend_liveldap.conf')]) - - def test_build_tree(self): - """Regression test for building the tree names - """ - #logic is different from the fake backend. - user_api = identity_ldap.UserApi(CONF) - self.assertTrue(user_api) - self.assertEquals(user_api.tree_dn, CONF.ldap.user_tree_dn) - - def tearDown(self): - test.TestCase.tearDown(self) - - def test_user_enable_attribute_mask(self): - self.skipTest('Test is for Active Directory Only') - - def test_ldap_dereferencing(self): - alt_users_ldif = {'objectclass': ['top', 'organizationalUnit'], - 'ou': 'alt_users'} - alt_fake_user_ldif = {'objectclass': ['person', 'inetOrgPerson'], - 'cn': 'alt_fake1', - 'sn': 'alt_fake1'} - aliased_users_ldif = {'objectclass': ['alias', 'extensibleObject'], - 'aliasedobjectname': "ou=alt_users,%s" % - CONF.ldap.suffix} - create_object("ou=alt_users,%s" % CONF.ldap.suffix, alt_users_ldif) - create_object("%s=alt_fake1,ou=alt_users,%s" % - (CONF.ldap.user_id_attribute, CONF.ldap.suffix), - alt_fake_user_ldif) - create_object("ou=alt_users,%s" % CONF.ldap.user_tree_dn, - aliased_users_ldif) - - CONF.ldap.query_scope = 'sub' - CONF.ldap.alias_dereferencing = 'never' - self.identity_api = identity_ldap.Identity() - self.assertRaises(exception.UserNotFound, - self.identity_api.get_user, - 'alt_fake1') - - CONF.ldap.alias_dereferencing = 'searching' - self.identity_api = identity_ldap.Identity() - user_ref = self.identity_api.get_user('alt_fake1') - self.assertEqual(user_ref['id'], 'alt_fake1') - - CONF.ldap.alias_dereferencing = 'always' - self.identity_api = identity_ldap.Identity() - user_ref = self.identity_api.get_user('alt_fake1') - self.assertEqual(user_ref['id'], 'alt_fake1') - - def test_base_ldap_connection_deref_option(self): - deref = ldap_common.parse_deref('default') - ldap_wrapper = ldap_common.LdapWrapper(CONF.ldap.url, - CONF.ldap.page_size, - alias_dereferencing=deref) - self.assertEqual(ldap.get_option(ldap.OPT_DEREF), - ldap_wrapper.conn.get_option(ldap.OPT_DEREF)) - - deref = ldap_common.parse_deref('always') - ldap_wrapper = ldap_common.LdapWrapper(CONF.ldap.url, - CONF.ldap.page_size, - alias_dereferencing=deref) - self.assertEqual(ldap.DEREF_ALWAYS, - ldap_wrapper.conn.get_option(ldap.OPT_DEREF)) - - deref = ldap_common.parse_deref('finding') - ldap_wrapper = ldap_common.LdapWrapper(CONF.ldap.url, - CONF.ldap.page_size, - alias_dereferencing=deref) - self.assertEqual(ldap.DEREF_FINDING, - ldap_wrapper.conn.get_option(ldap.OPT_DEREF)) - - deref = ldap_common.parse_deref('never') - ldap_wrapper = ldap_common.LdapWrapper(CONF.ldap.url, - CONF.ldap.page_size, - alias_dereferencing=deref) - self.assertEqual(ldap.DEREF_NEVER, - ldap_wrapper.conn.get_option(ldap.OPT_DEREF)) - - deref = ldap_common.parse_deref('searching') - ldap_wrapper = ldap_common.LdapWrapper(CONF.ldap.url, - CONF.ldap.page_size, - alias_dereferencing=deref) - self.assertEqual(ldap.DEREF_SEARCHING, - ldap_wrapper.conn.get_option(ldap.OPT_DEREF)) diff --git a/tests/_ldap_tls_livetest.py b/tests/_ldap_tls_livetest.py deleted file mode 100644 index f52b6360..00000000 --- a/tests/_ldap_tls_livetest.py +++ /dev/null @@ -1,113 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 OpenStack LLC -# Copyright 2013 IBM Corp. -# -# 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 ldap -import ldap.modlist - -from keystone import config -from keystone import exception -from keystone import identity -from keystone import test - -import _ldap_livetest - - -CONF = config.CONF - - -def create_object(dn, attrs): - conn = ldap.initialize(CONF.ldap.url) - conn.simple_bind_s(CONF.ldap.user, CONF.ldap.password) - ldif = ldap.modlist.addModlist(attrs) - conn.add_s(dn, ldif) - conn.unbind_s() - - -class LiveTLSLDAPIdentity(_ldap_livetest.LiveLDAPIdentity): - - def _set_config(self): - self.config([test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf'), - test.testsdir('backend_tls_liveldap.conf')]) - - def test_tls_certfile_demand_option(self): - CONF.ldap.use_tls = True - CONF.ldap.tls_cacertdir = None - CONF.ldap.tls_req_cert = 'demand' - self.identity_api = identity.backends.ldap.Identity() - - user = {'id': 'fake1', - 'name': 'fake1', - 'password': 'fakepass1', - 'tenants': ['bar']} - self.identity_api.create_user('fake1', user) - user_ref = self.identity_api.get_user('fake1') - self.assertEqual(user_ref['id'], 'fake1') - - user['password'] = 'fakepass2' - self.identity_api.update_user('fake1', user) - - self.identity_api.delete_user('fake1') - self.assertRaises(exception.UserNotFound, self.identity_api.get_user, - 'fake1') - - def test_tls_certdir_demand_option(self): - CONF.ldap.use_tls = True - CONF.ldap.tls_cacertfile = None - CONF.ldap.tls_req_cert = 'demand' - self.identity_api = identity.backends.ldap.Identity() - - user = {'id': 'fake1', - 'name': 'fake1', - 'password': 'fakepass1', - 'tenants': ['bar']} - self.identity_api.create_user('fake1', user) - user_ref = self.identity_api.get_user('fake1') - self.assertEqual(user_ref['id'], 'fake1') - - user['password'] = 'fakepass2' - self.identity_api.update_user('fake1', user) - - self.identity_api.delete_user('fake1') - self.assertRaises(exception.UserNotFound, self.identity_api.get_user, - 'fake1') - - def test_tls_bad_certfile(self): - CONF.ldap.use_tls = True - CONF.ldap.tls_req_cert = 'demand' - CONF.ldap.tls_cacertfile = '/etc/keystone/ssl/certs/mythicalcert.pem' - CONF.ldap.tls_cacertdir = None - self.identity_api = identity.backends.ldap.Identity() - - user = {'id': 'fake1', - 'name': 'fake1', - 'password': 'fakepass1', - 'tenants': ['bar']} - self.assertRaises(IOError, self.identity_api.create_user, 'fake', user) - - def test_tls_bad_certdir(self): - CONF.ldap.use_tls = True - CONF.ldap.tls_cacertfile = None - CONF.ldap.tls_req_cert = 'demand' - CONF.ldap.tls_cacertdir = '/etc/keystone/ssl/mythicalcertdir' - self.identity_api = identity.backends.ldap.Identity() - - user = {'id': 'fake1', - 'name': 'fake1', - 'password': 'fakepass1', - 'tenants': ['bar']} - self.assertRaises(IOError, self.identity_api.create_user, 'fake', user) diff --git a/tests/_sql_livetest.py b/tests/_sql_livetest.py deleted file mode 100644 index a271ce7c..00000000 --- a/tests/_sql_livetest.py +++ /dev/null @@ -1,45 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Red Hat, Inc -# -# 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 test_sql_upgrade - -from keystone import config - -CONF = config.CONF - - -class PostgresqlMigrateTests(test_sql_upgrade.SqlUpgradeTests): - def config_files(self): - files = (test_sql_upgrade.SqlUpgradeTests. - _config_file_list[:]) - files.append("backend_postgresql.conf") - return files - - -class MysqlMigrateTests(test_sql_upgrade.SqlUpgradeTests): - def config_files(self): - files = (test_sql_upgrade.SqlUpgradeTests. - _config_file_list[:]) - files.append("backend_mysql.conf") - return files - - -class Db2MigrateTests(test_sql_upgrade.SqlUpgradeTests): - def config_files(self): - files = (test_sql_upgrade.SqlUpgradeTests. - _config_file_list[:]) - files.append("backend_db2.conf") - return files diff --git a/tests/_test_import_auth_token.py b/tests/_test_import_auth_token.py deleted file mode 100644 index 4e16f9a4..00000000 --- a/tests/_test_import_auth_token.py +++ /dev/null @@ -1,25 +0,0 @@ -"""This is an isolated test to prevent unexpected imports. - -This module must be run in isolation, e.g.: - - $ ./run_tests.sh _test_import_auth_token.py - -This module can be removed when keystone.middleware.auth_token is removed. - -""" - -import unittest - - -class TestAuthToken(unittest.TestCase): - def test_import(self): - # a consuming service like nova would import oslo.config first - from oslo.config import cfg - conf = cfg.CONF - - # define some config options - conf.register_opt(cfg.BoolOpt('debug', default=False)) - - # and then import auth_token as a filter - from keystone.middleware import auth_token - self.assertTrue(auth_token) diff --git a/tests/auth_plugin_external_disabled.conf b/tests/auth_plugin_external_disabled.conf deleted file mode 100644 index fed281d4..00000000 --- a/tests/auth_plugin_external_disabled.conf +++ /dev/null @@ -1,2 +0,0 @@ -[auth] -methods = password, token diff --git a/tests/auth_plugin_external_domain.conf b/tests/auth_plugin_external_domain.conf deleted file mode 100644 index b7be122f..00000000 --- a/tests/auth_plugin_external_domain.conf +++ /dev/null @@ -1,3 +0,0 @@ -[auth] -methods = external, password, token -external = keystone.auth.plugins.external.ExternalDomain diff --git a/tests/backend_db2.conf b/tests/backend_db2.conf deleted file mode 100644 index 44032255..00000000 --- a/tests/backend_db2.conf +++ /dev/null @@ -1,4 +0,0 @@ -#Used for running the Migrate tests against a live DB2 Server -#See _sql_livetest.py -[sql] -connection = ibm_db_sa://keystone:keystone@/staktest?charset=utf8 diff --git a/tests/backend_ldap.conf b/tests/backend_ldap.conf deleted file mode 100644 index 6b3f8a75..00000000 --- a/tests/backend_ldap.conf +++ /dev/null @@ -1,9 +0,0 @@ -[ldap] -url = fake://memory -user = cn=Admin -password = password -backend_entities = ['Tenant', 'User', 'UserRoleAssociation', 'Role', 'Group', 'Domain'] -suffix = cn=example,cn=com - -[identity] -driver = keystone.identity.backends.ldap.Identity diff --git a/tests/backend_ldap_sql.conf b/tests/backend_ldap_sql.conf deleted file mode 100644 index 8dcfa40d..00000000 --- a/tests/backend_ldap_sql.conf +++ /dev/null @@ -1,36 +0,0 @@ -[sql] -connection = sqlite:// -#For a file based sqlite use -#connection = sqlite:////tmp/keystone.db -#To Test MySQL: -#connection = mysql://keystone:keystone@localhost/keystone?charset=utf8 -#To Test PostgreSQL: -#connection = postgresql://keystone:keystone@localhost/keystone?client_encoding=utf8 -idle_timeout = 200 - -[ldap] -url = fake://memory -user = cn=Admin -password = password -suffix = cn=example,cn=com - -[identity] -driver = keystone.identity.backends.ldap.Identity - -[assignment] -driver = keystone.assignment.backends.sql.Assignment - -[token] -driver = keystone.token.backends.sql.Token - -[ec2] -driver = keystone.contrib.ec2.backends.sql.Ec2 - -[catalog] -driver = keystone.catalog.backends.sql.Catalog - -[policy] -driver = keystone.policy.backends.sql.Policy - -[trust] -driver = keystone.trust.backends.sql.Trust diff --git a/tests/backend_liveldap.conf b/tests/backend_liveldap.conf deleted file mode 100644 index 297d96d6..00000000 --- a/tests/backend_liveldap.conf +++ /dev/null @@ -1,17 +0,0 @@ -[ldap] -url = ldap://localhost -user = dc=Manager,dc=openstack,dc=org -password = test -suffix = dc=openstack,dc=org -group_tree_dn = ou=UserGroups,dc=openstack,dc=org -role_tree_dn = ou=Roles,dc=openstack,dc=org -tenant_tree_dn = ou=Projects,dc=openstack,dc=org -user_tree_dn = ou=Users,dc=openstack,dc=org -tenant_enabled_emulation = True -user_enabled_emulation = True -user_mail_attribute = mail -use_dumb_member = True - -[identity] -driver = keystone.identity.backends.ldap.Identity - diff --git a/tests/backend_mysql.conf b/tests/backend_mysql.conf deleted file mode 100644 index ee3b276e..00000000 --- a/tests/backend_mysql.conf +++ /dev/null @@ -1,4 +0,0 @@ -#Used for running the Migrate tests against a live Mysql Server -#See _sql_livetest.py -[sql] -connection = mysql://keystone:keystone@localhost/keystone_test?charset=utf8 diff --git a/tests/backend_pam.conf b/tests/backend_pam.conf deleted file mode 100644 index 41f868c7..00000000 --- a/tests/backend_pam.conf +++ /dev/null @@ -1,6 +0,0 @@ -[pam] -userid = fakeuser -password = fakepass - -[identity] -driver = keystone.identity.backends.pam.PamIdentity diff --git a/tests/backend_postgresql.conf b/tests/backend_postgresql.conf deleted file mode 100644 index 8468ad33..00000000 --- a/tests/backend_postgresql.conf +++ /dev/null @@ -1,4 +0,0 @@ -#Used for running the Migrate tests against a live Postgresql Server -#See _sql_livetest.py -[sql] -connection = postgresql://keystone:keystone@localhost/keystone_test?client_encoding=utf8 diff --git a/tests/backend_sql.conf b/tests/backend_sql.conf deleted file mode 100644 index 0baf610c..00000000 --- a/tests/backend_sql.conf +++ /dev/null @@ -1,27 +0,0 @@ -[sql] -connection = sqlite:// -#For a file based sqlite use -#connection = sqlite:////tmp/keystone.db -#To Test MySQL: -#connection = mysql://keystone:keystone@localhost/keystone?charset=utf8 -#To Test PostgreSQL: -#connection = postgresql://keystone:keystone@localhost/keystone?client_encoding=utf8 -idle_timeout = 200 - -[identity] -driver = keystone.identity.backends.sql.Identity - -[token] -driver = keystone.token.backends.sql.Token - -[ec2] -driver = keystone.contrib.ec2.backends.sql.Ec2 - -[catalog] -driver = keystone.catalog.backends.sql.Catalog - -[policy] -driver = keystone.policy.backends.sql.Policy - -[trust] -driver = keystone.trust.backends.sql.Trust diff --git a/tests/backend_sql_disk.conf b/tests/backend_sql_disk.conf deleted file mode 100644 index 0f8dfea7..00000000 --- a/tests/backend_sql_disk.conf +++ /dev/null @@ -1,2 +0,0 @@ -[sql] -connection = sqlite:///tmp/test.db diff --git a/tests/backend_tls_liveldap.conf b/tests/backend_tls_liveldap.conf deleted file mode 100644 index 409af674..00000000 --- a/tests/backend_tls_liveldap.conf +++ /dev/null @@ -1,21 +0,0 @@ -[ldap] -url = ldap:// -user = dc=Manager,dc=openstack,dc=org -password = test -suffix = dc=openstack,dc=org -group_tree_dn = ou=UserGroups,dc=openstack,dc=org -role_tree_dn = ou=Roles,dc=openstack,dc=org -tenant_tree_dn = ou=Projects,dc=openstack,dc=org -user_tree_dn = ou=Users,dc=openstack,dc=org -tenant_enabled_emulation = True -user_enabled_emulation = True -user_mail_attribute = mail -use_dumb_member = True -use_tls = True -tls_cacertfile = /etc/keystone/ssl/certs/cacert.pem -tls_cacertdir = /etc/keystone/ssl/certs/ -tls_req_cert = demand - -[identity] -driver = keystone.identity.backends.ldap.Identity - diff --git a/tests/default_catalog.templates b/tests/default_catalog.templates deleted file mode 100644 index f26c949a..00000000 --- a/tests/default_catalog.templates +++ /dev/null @@ -1,14 +0,0 @@ -# config for TemplatedCatalog, using camelCase because I don't want to do -# translations for keystone compat -catalog.RegionOne.identity.publicURL = http://localhost:$(public_port)s/v2.0 -catalog.RegionOne.identity.adminURL = http://localhost:$(admin_port)s/v2.0 -catalog.RegionOne.identity.internalURL = http://localhost:$(admin_port)s/v2.0 -catalog.RegionOne.identity.name = 'Identity Service' -catalog.RegionOne.identity.id = 1 - -# fake compute service for now to help novaclient tests work -catalog.RegionOne.compute.publicURL = http://localhost:$(compute_port)s/v1.1/$(tenant_id)s -catalog.RegionOne.compute.adminURL = http://localhost:$(compute_port)s/v1.1/$(tenant_id)s -catalog.RegionOne.compute.internalURL = http://localhost:$(compute_port)s/v1.1/$(tenant_id)s -catalog.RegionOne.compute.name = 'Compute Service' -catalog.RegionOne.compute.id = 2 diff --git a/tests/default_fixtures.py b/tests/default_fixtures.py deleted file mode 100644 index 2695da88..00000000 --- a/tests/default_fixtures.py +++ /dev/null @@ -1,124 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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. - -# NOTE(dolph): please try to avoid additional fixtures if possible; test suite -# performance may be negatively affected. - -from keystone import assignment -from keystone import config - - -CONF = config.CONF - - -DEFAULT_DOMAIN_ID = config.CONF.identity.default_domain_id - - -TENANTS = [ - { - 'id': 'bar', - 'name': 'BAR', - 'domain_id': DEFAULT_DOMAIN_ID, - 'description': 'description', - 'enabled': True, - }, { - 'id': 'baz', - 'name': 'BAZ', - 'domain_id': DEFAULT_DOMAIN_ID, - 'description': 'description', - 'enabled': True, - }, { - 'id': 'mtu', - 'name': 'MTU', - 'description': 'description', - 'enabled': True, - 'domain_id': DEFAULT_DOMAIN_ID - }, { - 'id': 'service', - 'name': 'service', - 'description': 'description', - 'enabled': True, - 'domain_id': DEFAULT_DOMAIN_ID - } -] - -# NOTE(ja): a role of keystone_admin is done in setUp -USERS = [ - { - 'id': 'foo', - 'name': 'FOO', - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': 'foo2', - 'tenants': ['bar'], - 'enabled': True, - 'email': 'foo@bar.com', - }, { - 'id': 'two', - 'name': 'TWO', - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': 'two2', - 'email': 'two@example.com', - 'enabled': True, - 'tenant_id': 'baz', - 'tenants': ['baz'], - 'email': 'two@three.com', - }, { - 'id': 'badguy', - 'name': 'BadGuy', - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': 'bad', - 'email': 'bad@guy.com', - 'enabled': False, - 'tenant_id': 'baz', - 'tenants': ['baz'], - 'email': 'badguy@goodguy.com', - }, { - 'id': 'sna', - 'name': 'SNA', - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': 'snafu', - 'enabled': True, - 'tenants': ['bar'], - 'email': 'sna@snl.coom', - } -] - -ROLES = [ - { - 'id': 'admin', - 'name': 'admin', - }, { - 'id': 'member', - 'name': 'Member', - }, { - 'id': CONF.member_role_id, - 'name': CONF.member_role_name, - }, { - 'id': 'other', - 'name': 'Other', - }, { - 'id': 'browser', - 'name': 'Browser', - }, { - 'id': 'writer', - 'name': 'Writer', - }, { - 'id': 'service', - 'name': 'Service', - } -] - -DOMAINS = [assignment.DEFAULT_DOMAIN] diff --git a/tests/legacy_d5.mysql b/tests/legacy_d5.mysql deleted file mode 100644 index 57b31feb..00000000 --- a/tests/legacy_d5.mysql +++ /dev/null @@ -1,281 +0,0 @@ --- MySQL dump 10.13 Distrib 5.1.54, for debian-linux-gnu (x86_64) --- --- Host: localhost Database: keystone --- ------------------------------------------------------ --- Server version 5.1.54-1ubuntu4 - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Table structure for table `credentials` --- - -DROP TABLE IF EXISTS `credentials`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `credentials` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` int(11) DEFAULT NULL, - `tenant_id` int(11) DEFAULT NULL, - `type` varchar(20) DEFAULT NULL, - `key` varchar(255) DEFAULT NULL, - `secret` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `tenant_id` (`tenant_id`), - KEY `user_id` (`user_id`) -) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `credentials` --- - -LOCK TABLES `credentials` WRITE; -/*!40000 ALTER TABLE `credentials` DISABLE KEYS */; -INSERT INTO `credentials` VALUES (1,1,1,'EC2','admin','secrete'),(2,2,2,'EC2','demo','secrete'); -/*!40000 ALTER TABLE `credentials` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `endpoint_templates` --- - -DROP TABLE IF EXISTS `endpoint_templates`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `endpoint_templates` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `region` varchar(255) DEFAULT NULL, - `service_id` int(11) DEFAULT NULL, - `public_url` varchar(2000) DEFAULT NULL, - `admin_url` varchar(2000) DEFAULT NULL, - `internal_url` varchar(2000) DEFAULT NULL, - `enabled` tinyint(1) DEFAULT NULL, - `is_global` tinyint(1) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `service_id` (`service_id`) -) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `endpoint_templates` --- - -LOCK TABLES `endpoint_templates` WRITE; -/*!40000 ALTER TABLE `endpoint_templates` DISABLE KEYS */; -INSERT INTO `endpoint_templates` VALUES (1,'RegionOne',1,'http://10.4.128.10:8774/v1.1/%tenant_id%','http://10.4.128.10:8774/v1.1/%tenant_id%','http://10.4.128.10:8774/v1.1/%tenant_id%',1,1),(2,'RegionOne',2,'http://10.4.128.10:9292/v1.1/%tenant_id%','http://10.4.128.10:9292/v1.1/%tenant_id%','http://10.4.128.10:9292/v1.1/%tenant_id%',1,1),(3,'RegionOne',3,'http://10.4.128.10:5000/v2.0','http://10.4.128.10:35357/v2.0','http://10.4.128.10:5000/v2.0',1,1); -/*!40000 ALTER TABLE `endpoint_templates` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `endpoints` --- - -DROP TABLE IF EXISTS `endpoints`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `endpoints` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `tenant_id` int(11) DEFAULT NULL, - `endpoint_template_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `endpoint_template_id` (`endpoint_template_id`,`tenant_id`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `endpoints` --- - -LOCK TABLES `endpoints` WRITE; -/*!40000 ALTER TABLE `endpoints` DISABLE KEYS */; -/*!40000 ALTER TABLE `endpoints` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `roles` --- - -DROP TABLE IF EXISTS `roles`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `roles` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) DEFAULT NULL, - `desc` varchar(255) DEFAULT NULL, - `service_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`,`service_id`), - KEY `service_id` (`service_id`) -) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `roles` --- - -LOCK TABLES `roles` WRITE; -/*!40000 ALTER TABLE `roles` DISABLE KEYS */; -INSERT INTO `roles` VALUES (1,'Admin',NULL,NULL),(2,'Member',NULL,NULL),(3,'KeystoneAdmin',NULL,NULL),(4,'KeystoneServiceAdmin',NULL,NULL); -/*!40000 ALTER TABLE `roles` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `services` --- - -DROP TABLE IF EXISTS `services`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `services` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) DEFAULT NULL, - `type` varchar(255) DEFAULT NULL, - `desc` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`) -) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `services` --- - -LOCK TABLES `services` WRITE; -/*!40000 ALTER TABLE `services` DISABLE KEYS */; -INSERT INTO `services` VALUES (1,'nova','compute','Nova Compute Service'),(2,'glance','image','Glance Image Service'),(3,'keystone','identity','Keystone Identity Service'); -/*!40000 ALTER TABLE `services` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `tenants` --- - -DROP TABLE IF EXISTS `tenants`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `tenants` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) DEFAULT NULL, - `desc` varchar(255) DEFAULT NULL, - `enabled` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`) -) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `tenants` --- - -LOCK TABLES `tenants` WRITE; -/*!40000 ALTER TABLE `tenants` DISABLE KEYS */; -INSERT INTO `tenants` VALUES (1,'admin',NULL,1),(2,'demo',NULL,1),(3,'invisible_to_admin',NULL,1); -/*!40000 ALTER TABLE `tenants` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `token` --- - -DROP TABLE IF EXISTS `token`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `token` ( - `id` varchar(255) NOT NULL, - `user_id` int(11) DEFAULT NULL, - `tenant_id` int(11) DEFAULT NULL, - `expires` datetime DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `id` (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `token` --- - -LOCK TABLES `token` WRITE; -/*!40000 ALTER TABLE `token` DISABLE KEYS */; -INSERT INTO `token` VALUES ('secrete',1,1,'2015-02-05 00:00:00'); -/*!40000 ALTER TABLE `token` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `user_roles` --- - -DROP TABLE IF EXISTS `user_roles`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `user_roles` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` int(11) DEFAULT NULL, - `role_id` int(11) DEFAULT NULL, - `tenant_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `user_id` (`user_id`,`role_id`,`tenant_id`), - KEY `tenant_id` (`tenant_id`), - KEY `role_id` (`role_id`) -) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `user_roles` --- - -LOCK TABLES `user_roles` WRITE; -/*!40000 ALTER TABLE `user_roles` DISABLE KEYS */; -INSERT INTO `user_roles` VALUES (1,1,1,1),(2,2,2,2),(3,2,2,3),(4,1,1,2),(5,1,1,NULL),(6,1,3,NULL),(7,1,4,NULL); -/*!40000 ALTER TABLE `user_roles` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `users` --- - -DROP TABLE IF EXISTS `users`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `users` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) DEFAULT NULL, - `password` varchar(255) DEFAULT NULL, - `email` varchar(255) DEFAULT NULL, - `enabled` int(11) DEFAULT NULL, - `tenant_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`), - KEY `tenant_id` (`tenant_id`) -) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `users` --- - -LOCK TABLES `users` WRITE; -/*!40000 ALTER TABLE `users` DISABLE KEYS */; -INSERT INTO `users` VALUES (1,'admin','secrete',NULL,1,NULL),(2,'demo','secrete',NULL,1,NULL); -/*!40000 ALTER TABLE `users` ENABLE KEYS */; -UNLOCK TABLES; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - --- Dump completed on 2012-02-14 0:16:40 diff --git a/tests/legacy_d5.sqlite b/tests/legacy_d5.sqlite deleted file mode 100644 index d96dbf40..00000000 --- a/tests/legacy_d5.sqlite +++ /dev/null @@ -1,277 +0,0 @@ -begin; --- MySQL dump 10.13 Distrib 5.1.54, for debian-linux-gnu (x86_64) --- --- Host: localhost Database: keystone --- ------------------------------------------------------ --- Server version 5.1.54-1ubuntu4 - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Table structure for table `credentials` --- - -DROP TABLE IF EXISTS `credentials`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `credentials` ( - `id` integer NOT NULL primary key autoincrement, - `user_id` integer NULL, - `tenant_id` integer NULL, - `type` varchar(20) NULL, - `key` varchar(255) NULL, - `secret` varchar(255) NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `credentials` --- - - -/*!40000 ALTER TABLE `credentials` DISABLE KEYS */; -INSERT INTO `credentials` VALUES (1,1,1,'EC2','admin','secrete'); -INSERT INTO `credentials` VALUES (2,2,2,'EC2','demo','secrete'); -/*!40000 ALTER TABLE `credentials` ENABLE KEYS */; - - --- --- Table structure for table `endpoint_templates` --- - -DROP TABLE IF EXISTS `endpoint_templates`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `endpoint_templates` ( - `id` integer NOT NULL primary key autoincrement, - `region` varchar(255) NULL, - `service_id` integer NULL, - `public_url` varchar(2000) NULL, - `admin_url` varchar(2000) NULL, - `internal_url` varchar(2000) NULL, - `enabled` integer NULL, - `is_global` integer NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `endpoint_templates` --- - - -/*!40000 ALTER TABLE `endpoint_templates` DISABLE KEYS */; -INSERT INTO `endpoint_templates` VALUES (1,'RegionOne',1,'http://10.4.128.10:8774/v1.1/%tenant_id%','http://10.4.128.10:8774/v1.1/%tenant_id%','http://10.4.128.10:8774/v1.1/%tenant_id%',1,1); -INSERT INTO `endpoint_templates` VALUES (2,'RegionOne',2,'http://10.4.128.10:9292/v1.1/%tenant_id%','http://10.4.128.10:9292/v1.1/%tenant_id%','http://10.4.128.10:9292/v1.1/%tenant_id%',1,1); -INSERT INTO `endpoint_templates` VALUES (3,'RegionOne',3,'http://10.4.128.10:5000/v2.0','http://10.4.128.10:35357/v2.0','http://10.4.128.10:5000/v2.0',1,1); -/*!40000 ALTER TABLE `endpoint_templates` ENABLE KEYS */; - - --- --- Table structure for table `endpoints` --- - -DROP TABLE IF EXISTS `endpoints`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `endpoints` ( - `id` integer NOT NULL primary key autoincrement, - `tenant_id` integer NULL, - `endpoint_template_id` integer NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `endpoints` --- - - -/*!40000 ALTER TABLE `endpoints` DISABLE KEYS */; -/*!40000 ALTER TABLE `endpoints` ENABLE KEYS */; - - --- --- Table structure for table `roles` --- - -DROP TABLE IF EXISTS `roles`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `roles` ( - `id` integer NOT NULL primary key autoincrement, - `name` varchar(255) NULL, - `desc` varchar(255) NULL, - `service_id` integer NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `roles` --- - - -/*!40000 ALTER TABLE `roles` DISABLE KEYS */; -INSERT INTO `roles` VALUES (1,'Admin',NULL,NULL); -INSERT INTO `roles` VALUES (2,'Member',NULL,NULL); -INSERT INTO `roles` VALUES (3,'KeystoneAdmin',NULL,NULL); -INSERT INTO `roles` VALUES (4,'KeystoneServiceAdmin',NULL,NULL); -/*!40000 ALTER TABLE `roles` ENABLE KEYS */; - - --- --- Table structure for table `services` --- - -DROP TABLE IF EXISTS `services`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `services` ( - `id` integer NOT NULL primary key autoincrement, - `name` varchar(255) NULL, - `type` varchar(255) NULL, - `desc` varchar(255) NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `services` --- - - -/*!40000 ALTER TABLE `services` DISABLE KEYS */; -INSERT INTO `services` VALUES (1,'nova','compute','Nova Compute Service'); -INSERT INTO `services` VALUES (2,'glance','image','Glance Image Service'); -INSERT INTO `services` VALUES (3,'keystone','identity','Keystone Identity Service'); -/*!40000 ALTER TABLE `services` ENABLE KEYS */; - - --- --- Table structure for table `tenants` --- - -DROP TABLE IF EXISTS `tenants`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `tenants` ( - `id` integer NOT NULL primary key autoincrement, - `name` varchar(255) NULL, - `desc` varchar(255) NULL, - `enabled` integer NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `tenants` --- - - -/*!40000 ALTER TABLE `tenants` DISABLE KEYS */; -INSERT INTO `tenants` VALUES (1,'admin',NULL,1); -INSERT INTO `tenants` VALUES (2,'demo',NULL,1); -INSERT INTO `tenants` VALUES (3,'invisible_to_admin',NULL,1); -/*!40000 ALTER TABLE `tenants` ENABLE KEYS */; - - --- --- Table structure for table `token` --- - -DROP TABLE IF EXISTS `token`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `token` ( - `id` varchar(255) NOT NULL, - `user_id` integer NULL, - `tenant_id` integer NULL, - `expires` datetime NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `token` --- - - -/*!40000 ALTER TABLE `token` DISABLE KEYS */; -INSERT INTO `token` VALUES ('secrete',1,1,'2015-02-05 00:00:00'); -/*!40000 ALTER TABLE `token` ENABLE KEYS */; - - --- --- Table structure for table `user_roles` --- - -DROP TABLE IF EXISTS `user_roles`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `user_roles` ( - `id` integer NOT NULL primary key autoincrement, - `user_id` integer NULL, - `role_id` integer NULL, - `tenant_id` integer NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `user_roles` --- - - -/*!40000 ALTER TABLE `user_roles` DISABLE KEYS */; -INSERT INTO `user_roles` VALUES (1,1,1,1); -INSERT INTO `user_roles` VALUES (2,2,2,2); -INSERT INTO `user_roles` VALUES (3,2,2,3); -INSERT INTO `user_roles` VALUES (4,1,1,2); -INSERT INTO `user_roles` VALUES (5,1,1,NULL); -INSERT INTO `user_roles` VALUES (6,1,3,NULL); -INSERT INTO `user_roles` VALUES (7,1,4,NULL); -/*!40000 ALTER TABLE `user_roles` ENABLE KEYS */; - - --- --- Table structure for table `users` --- - -DROP TABLE IF EXISTS `users`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `users` ( - `id` integer NOT NULL primary key autoincrement, - `name` varchar(255) NULL, - `password` varchar(255) NULL, - `email` varchar(255) NULL, - `enabled` integer NULL, - `tenant_id` integer NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `users` --- - - -/*!40000 ALTER TABLE `users` DISABLE KEYS */; -INSERT INTO `users` VALUES (1,'admin','secrete',NULL,1,NULL); -INSERT INTO `users` VALUES (2,'demo','secrete',NULL,1,NULL); -/*!40000 ALTER TABLE `users` ENABLE KEYS */; - -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - --- Dump completed on 2012-02-14 0:16:40 -commit; diff --git a/tests/legacy_diablo.mysql b/tests/legacy_diablo.mysql deleted file mode 100644 index 543f439f..00000000 --- a/tests/legacy_diablo.mysql +++ /dev/null @@ -1,281 +0,0 @@ --- MySQL dump 10.13 Distrib 5.1.58, for debian-linux-gnu (x86_64) --- --- Host: localhost Database: keystone --- ------------------------------------------------------ --- Server version 5.1.58-1ubuntu1 - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Table structure for table `credentials` --- - -DROP TABLE IF EXISTS `credentials`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `credentials` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` int(11) DEFAULT NULL, - `tenant_id` int(11) DEFAULT NULL, - `type` varchar(20) DEFAULT NULL, - `key` varchar(255) DEFAULT NULL, - `secret` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `tenant_id` (`tenant_id`), - KEY `user_id` (`user_id`) -) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `credentials` --- - -LOCK TABLES `credentials` WRITE; -/*!40000 ALTER TABLE `credentials` DISABLE KEYS */; -INSERT INTO `credentials` VALUES (1,1,1,'EC2','admin','secrete'),(2,2,2,'EC2','demo','secrete'); -/*!40000 ALTER TABLE `credentials` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `endpoint_templates` --- - -DROP TABLE IF EXISTS `endpoint_templates`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `endpoint_templates` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `region` varchar(255) DEFAULT NULL, - `service_id` int(11) DEFAULT NULL, - `public_url` varchar(2000) DEFAULT NULL, - `admin_url` varchar(2000) DEFAULT NULL, - `internal_url` varchar(2000) DEFAULT NULL, - `enabled` tinyint(1) DEFAULT NULL, - `is_global` tinyint(1) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `service_id` (`service_id`) -) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `endpoint_templates` --- - -LOCK TABLES `endpoint_templates` WRITE; -/*!40000 ALTER TABLE `endpoint_templates` DISABLE KEYS */; -INSERT INTO `endpoint_templates` VALUES (1,'RegionOne',1,'http://192.168.2.10:8774/v1.1/%tenant_id%','http://192.168.2.10:8774/v1.1/%tenant_id%','http://192.168.2.10:8774/v1.1/%tenant_id%',1,1),(2,'RegionOne',2,'http://192.168.2.10:9292/v1','http://192.168.2.10:9292/v1','http://192.168.2.10:9292/v1',1,1),(3,'RegionOne',3,'http://192.168.2.10:5000/v2.0','http://192.168.2.10:35357/v2.0','http://192.168.2.10:5000/v2.0',1,1),(4,'RegionOne',4,'http://192.168.2.10:8080/v1/AUTH_%tenant_id%','http://192.168.2.10:8080/','http://192.168.2.10:8080/v1/AUTH_%tenant_id%',1,1); -/*!40000 ALTER TABLE `endpoint_templates` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `endpoints` --- - -DROP TABLE IF EXISTS `endpoints`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `endpoints` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `tenant_id` int(11) DEFAULT NULL, - `endpoint_template_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `endpoint_template_id` (`endpoint_template_id`,`tenant_id`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `endpoints` --- - -LOCK TABLES `endpoints` WRITE; -/*!40000 ALTER TABLE `endpoints` DISABLE KEYS */; -/*!40000 ALTER TABLE `endpoints` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `roles` --- - -DROP TABLE IF EXISTS `roles`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `roles` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) DEFAULT NULL, - `desc` varchar(255) DEFAULT NULL, - `service_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`,`service_id`), - KEY `service_id` (`service_id`) -) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `roles` --- - -LOCK TABLES `roles` WRITE; -/*!40000 ALTER TABLE `roles` DISABLE KEYS */; -INSERT INTO `roles` VALUES (1,'Admin',NULL,NULL),(2,'Member',NULL,NULL),(3,'KeystoneAdmin',NULL,NULL),(4,'KeystoneServiceAdmin',NULL,NULL),(5,'sysadmin',NULL,NULL),(6,'netadmin',NULL,NULL); -/*!40000 ALTER TABLE `roles` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `services` --- - -DROP TABLE IF EXISTS `services`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `services` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) DEFAULT NULL, - `type` varchar(255) DEFAULT NULL, - `desc` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`) -) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `services` --- - -LOCK TABLES `services` WRITE; -/*!40000 ALTER TABLE `services` DISABLE KEYS */; -INSERT INTO `services` VALUES (1,'nova','compute','Nova Compute Service'),(2,'glance','image','Glance Image Service'),(3,'keystone','identity','Keystone Identity Service'),(4,'swift','object-store','Swift Service'); -/*!40000 ALTER TABLE `services` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `tenants` --- - -DROP TABLE IF EXISTS `tenants`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `tenants` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) DEFAULT NULL, - `desc` varchar(255) DEFAULT NULL, - `enabled` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`) -) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `tenants` --- - -LOCK TABLES `tenants` WRITE; -/*!40000 ALTER TABLE `tenants` DISABLE KEYS */; -INSERT INTO `tenants` VALUES (1,'admin',NULL,1),(2,'demo',NULL,1),(3,'invisible_to_admin',NULL,1); -/*!40000 ALTER TABLE `tenants` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `token` --- - -DROP TABLE IF EXISTS `token`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `token` ( - `id` varchar(255) NOT NULL, - `user_id` int(11) DEFAULT NULL, - `tenant_id` int(11) DEFAULT NULL, - `expires` datetime DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `id` (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `token` --- - -LOCK TABLES `token` WRITE; -/*!40000 ALTER TABLE `token` DISABLE KEYS */; -INSERT INTO `token` VALUES ('secrete',1,1,'2015-02-05 00:00:00'); -/*!40000 ALTER TABLE `token` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `user_roles` --- - -DROP TABLE IF EXISTS `user_roles`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `user_roles` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` int(11) DEFAULT NULL, - `role_id` int(11) DEFAULT NULL, - `tenant_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `user_id` (`user_id`,`role_id`,`tenant_id`), - KEY `tenant_id` (`tenant_id`), - KEY `role_id` (`role_id`) -) ENGINE=MyISAM AUTO_INCREMENT=10 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `user_roles` --- - -LOCK TABLES `user_roles` WRITE; -/*!40000 ALTER TABLE `user_roles` DISABLE KEYS */; -INSERT INTO `user_roles` VALUES (1,1,1,1),(2,2,2,2),(3,2,5,2),(4,2,6,2),(5,2,2,3),(6,1,1,2),(7,1,1,NULL),(8,1,3,NULL),(9,1,4,NULL); -/*!40000 ALTER TABLE `user_roles` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `users` --- - -DROP TABLE IF EXISTS `users`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `users` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) DEFAULT NULL, - `password` varchar(255) DEFAULT NULL, - `email` varchar(255) DEFAULT NULL, - `enabled` int(11) DEFAULT NULL, - `tenant_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`), - KEY `tenant_id` (`tenant_id`) -) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `users` --- - -LOCK TABLES `users` WRITE; -/*!40000 ALTER TABLE `users` DISABLE KEYS */; -INSERT INTO `users` VALUES (1,'admin','secrete',NULL,1,NULL),(2,'demo','secrete',NULL,1,NULL); -/*!40000 ALTER TABLE `users` ENABLE KEYS */; -UNLOCK TABLES; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - --- Dump completed on 2012-02-13 17:30:03 diff --git a/tests/legacy_diablo.sqlite b/tests/legacy_diablo.sqlite deleted file mode 100644 index edf15be4..00000000 --- a/tests/legacy_diablo.sqlite +++ /dev/null @@ -1,283 +0,0 @@ -begin; --- MySQL dump 10.13 Distrib 5.1.58, for debian-linux-gnu (x86_64) --- --- Host: localhost Database: keystone --- ------------------------------------------------------ --- Server version 5.1.58-1ubuntu1 - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Table structure for table `credentials` --- - -DROP TABLE IF EXISTS `credentials`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `credentials` ( - `id` integer NOT NULL primary key autoincrement, - `user_id` integer NULL, - `tenant_id` integer NULL, - `type` varchar(20) NULL, - `key` varchar(255) NULL, - `secret` varchar(255) NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `credentials` --- - - -/*!40000 ALTER TABLE `credentials` DISABLE KEYS */; -INSERT INTO `credentials` VALUES (1,1,1,'EC2','admin','secrete'); -INSERT INTO `credentials` VALUES (2,2,2,'EC2','demo','secrete'); -/*!40000 ALTER TABLE `credentials` ENABLE KEYS */; - - --- --- Table structure for table `endpoint_templates` --- - -DROP TABLE IF EXISTS `endpoint_templates`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `endpoint_templates` ( - `id` integer NOT NULL primary key autoincrement, - `region` varchar(255) NULL, - `service_id` integer NULL, - `public_url` varchar(2000) NULL, - `admin_url` varchar(2000) NULL, - `internal_url` varchar(2000) NULL, - `enabled` integer NULL, - `is_global` integer NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `endpoint_templates` --- - - -/*!40000 ALTER TABLE `endpoint_templates` DISABLE KEYS */; -INSERT INTO `endpoint_templates` VALUES (1,'RegionOne',1,'http://192.168.2.10:8774/v1.1/%tenant_id%','http://192.168.2.10:8774/v1.1/%tenant_id%','http://192.168.2.10:8774/v1.1/%tenant_id%',1,1); -INSERT INTO `endpoint_templates` VALUES (2,'RegionOne',2,'http://192.168.2.10:9292/v1','http://192.168.2.10:9292/v1','http://192.168.2.10:9292/v1',1,1); -INSERT INTO `endpoint_templates` VALUES (3,'RegionOne',3,'http://192.168.2.10:5000/v2.0','http://192.168.2.10:35357/v2.0','http://192.168.2.10:5000/v2.0',1,1); -INSERT INTO `endpoint_templates` VALUES (4,'RegionOne',4,'http://192.168.2.10:8080/v1/AUTH_%tenant_id%','http://192.168.2.10:8080/','http://192.168.2.10:8080/v1/AUTH_%tenant_id%',1,1); -/*!40000 ALTER TABLE `endpoint_templates` ENABLE KEYS */; - - --- --- Table structure for table `endpoints` --- - -DROP TABLE IF EXISTS `endpoints`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `endpoints` ( - `id` integer NOT NULL primary key autoincrement, - `tenant_id` integer NULL, - `endpoint_template_id` integer NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `endpoints` --- - - -/*!40000 ALTER TABLE `endpoints` DISABLE KEYS */; -/*!40000 ALTER TABLE `endpoints` ENABLE KEYS */; - - --- --- Table structure for table `roles` --- - -DROP TABLE IF EXISTS `roles`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `roles` ( - `id` integer NOT NULL primary key autoincrement, - `name` varchar(255) NULL, - `desc` varchar(255) NULL, - `service_id` integer NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `roles` --- - - -/*!40000 ALTER TABLE `roles` DISABLE KEYS */; -INSERT INTO `roles` VALUES (1,'Admin',NULL,NULL); -INSERT INTO `roles` VALUES (2,'Member',NULL,NULL); -INSERT INTO `roles` VALUES (3,'KeystoneAdmin',NULL,NULL); -INSERT INTO `roles` VALUES (4,'KeystoneServiceAdmin',NULL,NULL); -INSERT INTO `roles` VALUES (5,'sysadmin',NULL,NULL); -INSERT INTO `roles` VALUES (6,'netadmin',NULL,NULL); -/*!40000 ALTER TABLE `roles` ENABLE KEYS */; - - --- --- Table structure for table `services` --- - -DROP TABLE IF EXISTS `services`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `services` ( - `id` integer NOT NULL primary key autoincrement, - `name` varchar(255) NULL, - `type` varchar(255) NULL, - `desc` varchar(255) NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `services` --- - - -/*!40000 ALTER TABLE `services` DISABLE KEYS */; -INSERT INTO `services` VALUES (1,'nova','compute','Nova Compute Service'); -INSERT INTO `services` VALUES (2,'glance','image','Glance Image Service'); -INSERT INTO `services` VALUES (3,'keystone','identity','Keystone Identity Service'); -INSERT INTO `services` VALUES (4,'swift','object-store','Swift Service'); -/*!40000 ALTER TABLE `services` ENABLE KEYS */; - - --- --- Table structure for table `tenants` --- - -DROP TABLE IF EXISTS `tenants`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `tenants` ( - `id` integer NOT NULL primary key autoincrement, - `name` varchar(255) NULL, - `desc` varchar(255) NULL, - `enabled` integer NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `tenants` --- - - -/*!40000 ALTER TABLE `tenants` DISABLE KEYS */; -INSERT INTO `tenants` VALUES (1,'admin',NULL,1); -INSERT INTO `tenants` VALUES (2,'demo',NULL,1); -INSERT INTO `tenants` VALUES (3,'invisible_to_admin',NULL,1); -/*!40000 ALTER TABLE `tenants` ENABLE KEYS */; - - --- --- Table structure for table `token` --- - -DROP TABLE IF EXISTS `token`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `token` ( - `id` varchar(255) NOT NULL, - `user_id` integer NULL, - `tenant_id` integer NULL, - `expires` datetime NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `token` --- - - -/*!40000 ALTER TABLE `token` DISABLE KEYS */; -INSERT INTO `token` VALUES ('secrete',1,1,'2015-02-05 00:00:00'); -/*!40000 ALTER TABLE `token` ENABLE KEYS */; - - --- --- Table structure for table `user_roles` --- - -DROP TABLE IF EXISTS `user_roles`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `user_roles` ( - `id` integer NOT NULL primary key autoincrement, - `user_id` integer NULL, - `role_id` integer NULL, - `tenant_id` integer NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `user_roles` --- - - -/*!40000 ALTER TABLE `user_roles` DISABLE KEYS */; -INSERT INTO `user_roles` VALUES (1,1,1,1); -INSERT INTO `user_roles` VALUES (2,2,2,2); -INSERT INTO `user_roles` VALUES (3,2,5,2); -INSERT INTO `user_roles` VALUES (4,2,6,2); -INSERT INTO `user_roles` VALUES (5,2,2,3); -INSERT INTO `user_roles` VALUES (6,1,1,2); -INSERT INTO `user_roles` VALUES (7,1,1,NULL); -INSERT INTO `user_roles` VALUES (8,1,3,NULL); -INSERT INTO `user_roles` VALUES (9,1,4,NULL); -/*!40000 ALTER TABLE `user_roles` ENABLE KEYS */; - - --- --- Table structure for table `users` --- - -DROP TABLE IF EXISTS `users`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `users` ( - `id` integer NOT NULL primary key autoincrement, - `name` varchar(255) NULL, - `password` varchar(255) NULL, - `email` varchar(255) NULL, - `enabled` integer NULL, - `tenant_id` integer NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `users` --- - - -/*!40000 ALTER TABLE `users` DISABLE KEYS */; -INSERT INTO `users` VALUES (1,'admin','secrete',NULL,1,NULL); -INSERT INTO `users` VALUES (2,'demo','secrete',NULL,1,NULL); -/*!40000 ALTER TABLE `users` ENABLE KEYS */; - -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - --- Dump completed on 2012-02-13 17:30:03 -commit; diff --git a/tests/legacy_essex.mysql b/tests/legacy_essex.mysql deleted file mode 100644 index eade2cbf..00000000 --- a/tests/legacy_essex.mysql +++ /dev/null @@ -1,309 +0,0 @@ --- MySQL dump 10.13 Distrib 5.1.58, for debian-linux-gnu (x86_64) --- --- Host: localhost Database: keystone --- ------------------------------------------------------ --- Server version 5.1.58-1ubuntu1 - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Table structure for table `credentials` --- - -DROP TABLE IF EXISTS `credentials`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `credentials` ( - `user_id` int(11) DEFAULT NULL, - `tenant_id` int(11) DEFAULT NULL, - `secret` varchar(255) DEFAULT NULL, - `key` varchar(255) DEFAULT NULL, - `type` varchar(20) DEFAULT NULL, - `id` int(11) NOT NULL AUTO_INCREMENT, - PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `credentials` --- - -LOCK TABLES `credentials` WRITE; -/*!40000 ALTER TABLE `credentials` DISABLE KEYS */; -/*!40000 ALTER TABLE `credentials` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `endpoint_templates` --- - -DROP TABLE IF EXISTS `endpoint_templates`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `endpoint_templates` ( - `is_global` tinyint(1) DEFAULT NULL, - `region` varchar(255) DEFAULT NULL, - `public_url` varchar(2000) DEFAULT NULL, - `enabled` tinyint(1) DEFAULT NULL, - `internal_url` varchar(2000) DEFAULT NULL, - `id` int(11) NOT NULL AUTO_INCREMENT, - `service_id` int(11) DEFAULT NULL, - `admin_url` varchar(2000) DEFAULT NULL, - `version_id` varchar(20) DEFAULT NULL, - `version_list` varchar(2000) DEFAULT NULL, - `version_info` varchar(500) DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `endpoint_templates` --- - -LOCK TABLES `endpoint_templates` WRITE; -/*!40000 ALTER TABLE `endpoint_templates` DISABLE KEYS */; -INSERT INTO `endpoint_templates` VALUES (1,'RegionOne','http://4.2.2.1:8774/v1.1/%tenant_id%',1,'http://4.2.2.1:8774/v1.1/%tenant_id%',1,1,'http://4.2.2.1:8774/v1.1/%tenant_id%',NULL,NULL,NULL),(1,'RegionOne','http://4.2.2.1:8773/services/Cloud',1,'http://4.2.2.1:8773/services/Cloud',2,2,'http://4.2.2.1:8773/services/Admin',NULL,NULL,NULL),(1,'RegionOne','http://4.2.2.1:9292/v1',1,'http://4.2.2.1:9292/v1',3,3,'http://4.2.2.1:9292/v1',NULL,NULL,NULL),(1,'RegionOne','http://4.2.2.1:5000/v2.0',1,'http://4.2.2.1:5000/v2.0',4,4,'http://4.2.2.1:35357/v2.0',NULL,NULL,NULL),(1,'RegionOne','http://4.2.2.1:8080/v1/AUTH_%tenant_id%',1,'http://4.2.2.1:8080/v1/AUTH_%tenant_id%',5,5,'http://4.2.2.1:8080/',NULL,NULL,NULL); -/*!40000 ALTER TABLE `endpoint_templates` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `endpoints` --- - -DROP TABLE IF EXISTS `endpoints`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `endpoints` ( - `endpoint_template_id` int(11) DEFAULT NULL, - `tenant_id` int(11) DEFAULT NULL, - `id` int(11) NOT NULL AUTO_INCREMENT, - PRIMARY KEY (`id`), - UNIQUE KEY `endpoint_template_id` (`endpoint_template_id`,`tenant_id`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `endpoints` --- - -LOCK TABLES `endpoints` WRITE; -/*!40000 ALTER TABLE `endpoints` DISABLE KEYS */; -/*!40000 ALTER TABLE `endpoints` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `migrate_version` --- - -DROP TABLE IF EXISTS `migrate_version`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `migrate_version` ( - `repository_id` varchar(250) NOT NULL, - `repository_path` text, - `version` int(11) DEFAULT NULL, - PRIMARY KEY (`repository_id`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `migrate_version` --- - -LOCK TABLES `migrate_version` WRITE; -/*!40000 ALTER TABLE `migrate_version` DISABLE KEYS */; -INSERT INTO `migrate_version` VALUES ('Keystone','/opt/stack/keystone/keystone/backends/sqlalchemy/migrate_repo',11); -/*!40000 ALTER TABLE `migrate_version` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `roles` --- - -DROP TABLE IF EXISTS `roles`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `roles` ( - `service_id` int(11) DEFAULT NULL, - `desc` varchar(255) DEFAULT NULL, - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`,`service_id`) -) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `roles` --- - -LOCK TABLES `roles` WRITE; -/*!40000 ALTER TABLE `roles` DISABLE KEYS */; -INSERT INTO `roles` VALUES (NULL,NULL,1,'admin'),(NULL,NULL,2,'Member'),(NULL,NULL,3,'KeystoneAdmin'),(NULL,NULL,4,'KeystoneServiceAdmin'),(NULL,NULL,5,'sysadmin'),(NULL,NULL,6,'netadmin'); -/*!40000 ALTER TABLE `roles` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `services` --- - -DROP TABLE IF EXISTS `services`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `services` ( - `desc` varchar(255) DEFAULT NULL, - `type` varchar(255) DEFAULT NULL, - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) DEFAULT NULL, - `owner_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`), - UNIQUE KEY `name_2` (`name`) -) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `services` --- - -LOCK TABLES `services` WRITE; -/*!40000 ALTER TABLE `services` DISABLE KEYS */; -INSERT INTO `services` VALUES ('Nova Compute Service','compute',1,'nova',NULL),('EC2 Compatibility Layer','ec2',2,'ec2',NULL),('Glance Image Service','image',3,'glance',NULL),('Keystone Identity Service','identity',4,'keystone',NULL),('Swift Service','object-store',5,'swift',NULL); -/*!40000 ALTER TABLE `services` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `tenants` --- - -DROP TABLE IF EXISTS `tenants`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `tenants` ( - `desc` varchar(255) DEFAULT NULL, - `enabled` tinyint(1) DEFAULT NULL, - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) DEFAULT NULL, - `uid` varchar(255) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `tenants_uid_key` (`uid`), - UNIQUE KEY `name` (`name`), - UNIQUE KEY `name_2` (`name`) -) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `tenants` --- - -LOCK TABLES `tenants` WRITE; -/*!40000 ALTER TABLE `tenants` DISABLE KEYS */; -INSERT INTO `tenants` VALUES (NULL,1,1,'admin','182c1fbf7eef44eda162ff3fd30c0a76'),(NULL,1,2,'demo','b1a7ea3a884f4d0685a98cd6e682a5da'),(NULL,1,3,'invisible_to_admin','f4d1eed9bb5d4d35a5f37af934f87574'); -/*!40000 ALTER TABLE `tenants` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `tokens` --- - -DROP TABLE IF EXISTS `tokens`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `tokens` ( - `tenant_id` int(11) DEFAULT NULL, - `expires` datetime DEFAULT NULL, - `user_id` int(11) DEFAULT NULL, - `id` varchar(255) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `id` (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `tokens` --- - -LOCK TABLES `tokens` WRITE; -/*!40000 ALTER TABLE `tokens` DISABLE KEYS */; -INSERT INTO `tokens` VALUES (1,'2015-02-05 00:00:00',1,'123123123123123123123'); -/*!40000 ALTER TABLE `tokens` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `user_roles` --- - -DROP TABLE IF EXISTS `user_roles`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `user_roles` ( - `tenant_id` int(11) DEFAULT NULL, - `user_id` int(11) DEFAULT NULL, - `id` int(11) NOT NULL AUTO_INCREMENT, - `role_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `user_id` (`user_id`,`role_id`,`tenant_id`) -) ENGINE=MyISAM AUTO_INCREMENT=10 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `user_roles` --- - -LOCK TABLES `user_roles` WRITE; -/*!40000 ALTER TABLE `user_roles` DISABLE KEYS */; -INSERT INTO `user_roles` VALUES (1,1,1,1),(2,2,2,2),(2,2,3,5),(2,2,4,6),(3,2,5,2),(2,1,6,1),(NULL,1,7,1),(NULL,1,8,3),(NULL,1,9,4); -/*!40000 ALTER TABLE `user_roles` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `users` --- - -DROP TABLE IF EXISTS `users`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `users` ( - `name` varchar(255) DEFAULT NULL, - `tenant_id` int(11) DEFAULT NULL, - `enabled` tinyint(1) DEFAULT NULL, - `id` int(11) NOT NULL AUTO_INCREMENT, - `password` varchar(255) DEFAULT NULL, - `email` varchar(255) DEFAULT NULL, - `uid` varchar(255) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `users_uid_key` (`uid`), - UNIQUE KEY `name` (`name`), - UNIQUE KEY `name_2` (`name`) -) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `users` --- - -LOCK TABLES `users` WRITE; -/*!40000 ALTER TABLE `users` DISABLE KEYS */; -INSERT INTO `users` VALUES ('admin',NULL,1,1,'$6$rounds=40000$hFXlgBSMi599197d$tmGKBpoGHNRsLB3ruK9f1wPvvtfWWuMEUzdqUAynsmmYXBK6eekyNHTzzhwXTM3mWpnaMHCI4mHPOycqmPJJc0',NULL,'c93b19ea3fa94484824213db8ac0afce'),('demo',NULL,1,2,'$6$rounds=40000$RBsX2ja9fdj2uTNQ$/wJOn510AYKW9BPFAJneVQAjm6TM0Ty11LG.u4.k4RhmoUcXNSjGKmQT6KO0SsvypMM7A.doWgt73V5rNnv5h.',NULL,'04c6697e88ff4667820903fcce05d904'); -/*!40000 ALTER TABLE `users` ENABLE KEYS */; -UNLOCK TABLES; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - --- Dump completed on 2012-02-13 19:23:51 diff --git a/tests/legacy_essex.sqlite b/tests/legacy_essex.sqlite deleted file mode 100644 index 72326d76..00000000 --- a/tests/legacy_essex.sqlite +++ /dev/null @@ -1,313 +0,0 @@ -begin; --- MySQL dump 10.13 Distrib 5.1.58, for debian-linux-gnu (x86_64) --- --- Host: localhost Database: keystone --- ------------------------------------------------------ --- Server version 5.1.58-1ubuntu1 - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Table structure for table `credentials` --- - -DROP TABLE IF EXISTS `credentials`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `credentials` ( - `user_id` integer NULL, - `tenant_id` integer NULL, - `secret` varchar(255) NULL, - `key` varchar(255) NULL, - `type` varchar(20) NULL, - `id` integer NOT NULL primary key autoincrement -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `credentials` --- - - -/*!40000 ALTER TABLE `credentials` DISABLE KEYS */; -/*!40000 ALTER TABLE `credentials` ENABLE KEYS */; - - --- --- Table structure for table `endpoint_templates` --- - -DROP TABLE IF EXISTS `endpoint_templates`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `endpoint_templates` ( - `is_global` integer NULL, - `region` varchar(255) NULL, - `public_url` varchar(2000) NULL, - `enabled` integer NULL, - `internal_url` varchar(2000) NULL, - `id` integer NOT NULL primary key autoincrement, - `service_id` integer NULL, - `admin_url` varchar(2000) NULL, - `version_id` varchar(20) NULL, - `version_list` varchar(2000) NULL, - `version_info` varchar(500) NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `endpoint_templates` --- - - -/*!40000 ALTER TABLE `endpoint_templates` DISABLE KEYS */; -INSERT INTO `endpoint_templates` VALUES (1,'RegionOne','http://4.2.2.1:8774/v1.1/%tenant_id%',1,'http://4.2.2.1:8774/v1.1/%tenant_id%',1,1,'http://4.2.2.1:8774/v1.1/%tenant_id%',NULL,NULL,NULL); -INSERT INTO `endpoint_templates` VALUES (1,'RegionOne','http://4.2.2.1:8773/services/Cloud',1,'http://4.2.2.1:8773/services/Cloud',2,2,'http://4.2.2.1:8773/services/Admin',NULL,NULL,NULL); -INSERT INTO `endpoint_templates` VALUES (1,'RegionOne','http://4.2.2.1:9292/v1',1,'http://4.2.2.1:9292/v1',3,3,'http://4.2.2.1:9292/v1',NULL,NULL,NULL); -INSERT INTO `endpoint_templates` VALUES (1,'RegionOne','http://4.2.2.1:5000/v2.0',1,'http://4.2.2.1:5000/v2.0',4,4,'http://4.2.2.1:35357/v2.0',NULL,NULL,NULL); -INSERT INTO `endpoint_templates` VALUES (1,'RegionOne','http://4.2.2.1:8080/v1/AUTH_%tenant_id%',1,'http://4.2.2.1:8080/v1/AUTH_%tenant_id%',5,5,'http://4.2.2.1:8080/',NULL,NULL,NULL); -/*!40000 ALTER TABLE `endpoint_templates` ENABLE KEYS */; - - --- --- Table structure for table `endpoints` --- - -DROP TABLE IF EXISTS `endpoints`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `endpoints` ( - `endpoint_template_id` integer NULL, - `tenant_id` integer NULL, - `id` integer NOT NULL primary key autoincrement -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `endpoints` --- - - -/*!40000 ALTER TABLE `endpoints` DISABLE KEYS */; -/*!40000 ALTER TABLE `endpoints` ENABLE KEYS */; - - --- --- Table structure for table `migrate_version` --- - -DROP TABLE IF EXISTS `migrate_version`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `migrate_version` ( - `repository_id` varchar(250) NOT NULL, - `repository_path` text, - `version` integer NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `migrate_version` --- - - -/*!40000 ALTER TABLE `migrate_version` DISABLE KEYS */; -INSERT INTO `migrate_version` VALUES ('Keystone','/opt/stack/keystone/keystone/backends/sqlalchemy/migrate_repo',11); -/*!40000 ALTER TABLE `migrate_version` ENABLE KEYS */; - - --- --- Table structure for table `roles` --- - -DROP TABLE IF EXISTS `roles`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `roles` ( - `service_id` integer NULL, - `desc` varchar(255) NULL, - `id` integer NOT NULL primary key autoincrement, - `name` varchar(255) NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `roles` --- - - -/*!40000 ALTER TABLE `roles` DISABLE KEYS */; -INSERT INTO `roles` VALUES (NULL,NULL,1,'admin'); -INSERT INTO `roles` VALUES (NULL,NULL,2,'Member'); -INSERT INTO `roles` VALUES (NULL,NULL,3,'KeystoneAdmin'); -INSERT INTO `roles` VALUES (NULL,NULL,4,'KeystoneServiceAdmin'); -INSERT INTO `roles` VALUES (NULL,NULL,5,'sysadmin'); -INSERT INTO `roles` VALUES (NULL,NULL,6,'netadmin'); -/*!40000 ALTER TABLE `roles` ENABLE KEYS */; - - --- --- Table structure for table `services` --- - -DROP TABLE IF EXISTS `services`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `services` ( - `desc` varchar(255) NULL, - `type` varchar(255) NULL, - `id` integer NOT NULL primary key autoincrement, - `name` varchar(255) NULL, - `owner_id` integer NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `services` --- - - -/*!40000 ALTER TABLE `services` DISABLE KEYS */; -INSERT INTO `services` VALUES ('Nova Compute Service','compute',1,'nova',NULL); -INSERT INTO `services` VALUES ('EC2 Compatibility Layer','ec2',2,'ec2',NULL); -INSERT INTO `services` VALUES ('Glance Image Service','image',3,'glance',NULL); -INSERT INTO `services` VALUES ('Keystone Identity Service','identity',4,'keystone',NULL); -INSERT INTO `services` VALUES ('Swift Service','object-store',5,'swift',NULL); -/*!40000 ALTER TABLE `services` ENABLE KEYS */; - - --- --- Table structure for table `tenants` --- - -DROP TABLE IF EXISTS `tenants`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `tenants` ( - `desc` varchar(255) NULL, - `enabled` integer NULL, - `id` integer NOT NULL primary key autoincrement, - `name` varchar(255) NULL, - `uid` varchar(255) NOT NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `tenants` --- - - -/*!40000 ALTER TABLE `tenants` DISABLE KEYS */; -INSERT INTO `tenants` VALUES (NULL,1,1,'admin','182c1fbf7eef44eda162ff3fd30c0a76'); -INSERT INTO `tenants` VALUES (NULL,1,2,'demo','b1a7ea3a884f4d0685a98cd6e682a5da'); -INSERT INTO `tenants` VALUES (NULL,1,3,'invisible_to_admin','f4d1eed9bb5d4d35a5f37af934f87574'); -/*!40000 ALTER TABLE `tenants` ENABLE KEYS */; - - --- --- Table structure for table `tokens` --- - -DROP TABLE IF EXISTS `tokens`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `tokens` ( - `tenant_id` integer NULL, - `expires` datetime NULL, - `user_id` integer NULL, - `id` varchar(255) NOT NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `tokens` --- - - -/*!40000 ALTER TABLE `tokens` DISABLE KEYS */; -INSERT INTO `tokens` VALUES (1,'2015-02-05 00:00:00',1,'123123123123123123123'); -/*!40000 ALTER TABLE `tokens` ENABLE KEYS */; - - --- --- Table structure for table `user_roles` --- - -DROP TABLE IF EXISTS `user_roles`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `user_roles` ( - `tenant_id` integer NULL, - `user_id` integer NULL, - `id` integer NOT NULL primary key autoincrement, - `role_id` integer NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `user_roles` --- - - -/*!40000 ALTER TABLE `user_roles` DISABLE KEYS */; -INSERT INTO `user_roles` VALUES (1,1,1,1); -INSERT INTO `user_roles` VALUES (2,2,2,2); -INSERT INTO `user_roles` VALUES (2,2,3,5); -INSERT INTO `user_roles` VALUES (2,2,4,6); -INSERT INTO `user_roles` VALUES (3,2,5,2); -INSERT INTO `user_roles` VALUES (2,1,6,1); -INSERT INTO `user_roles` VALUES (NULL,1,7,1); -INSERT INTO `user_roles` VALUES (NULL,1,8,3); -INSERT INTO `user_roles` VALUES (NULL,1,9,4); -/*!40000 ALTER TABLE `user_roles` ENABLE KEYS */; - - --- --- Table structure for table `users` --- - -DROP TABLE IF EXISTS `users`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `users` ( - `name` varchar(255) NULL, - `tenant_id` integer NULL, - `enabled` integer NULL, - `id` integer NOT NULL primary key autoincrement, - `password` varchar(255) NULL, - `email` varchar(255) NULL, - `uid` varchar(255) NOT NULL -) ; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `users` --- - - -/*!40000 ALTER TABLE `users` DISABLE KEYS */; -INSERT INTO `users` VALUES ('admin',NULL,1,1,'$6$rounds=40000$hFXlgBSMi599197d$tmGKBpoGHNRsLB3ruK9f1wPvvtfWWuMEUzdqUAynsmmYXBK6eekyNHTzzhwXTM3mWpnaMHCI4mHPOycqmPJJc0',NULL,'c93b19ea3fa94484824213db8ac0afce'); -INSERT INTO `users` VALUES ('demo',NULL,1,2,'$6$rounds=40000$RBsX2ja9fdj2uTNQ$/wJOn510AYKW9BPFAJneVQAjm6TM0Ty11LG.u4.k4RhmoUcXNSjGKmQT6KO0SsvypMM7A.doWgt73V5rNnv5h.',NULL,'04c6697e88ff4667820903fcce05d904'); -/*!40000 ALTER TABLE `users` ENABLE KEYS */; - -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - --- Dump completed on 2012-02-13 19:23:51 -commit; diff --git a/tests/test_auth.py b/tests/test_auth.py deleted file mode 100644 index e8e6c7a9..00000000 --- a/tests/test_auth.py +++ /dev/null @@ -1,851 +0,0 @@ -# Copyright 2012 OpenStack 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 copy -import datetime -import uuid - -from keystone import test - -from keystone import auth -from keystone import config -from keystone import exception -from keystone.openstack.common import timeutils -from keystone import token -from keystone import trust - -import default_fixtures - - -CONF = config.CONF -TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ' - - -def _build_user_auth(token=None, user_id=None, username=None, - password=None, tenant_id=None, tenant_name=None, - trust_id=None): - """Build auth dictionary. - - It will create an auth dictionary based on all the arguments - that it receives. - """ - auth_json = {} - if token is not None: - auth_json['token'] = token - if username or password: - auth_json['passwordCredentials'] = {} - if username is not None: - auth_json['passwordCredentials']['username'] = username - if user_id is not None: - auth_json['passwordCredentials']['userId'] = user_id - if password is not None: - auth_json['passwordCredentials']['password'] = password - if tenant_name is not None: - auth_json['tenantName'] = tenant_name - if tenant_id is not None: - auth_json['tenantId'] = tenant_id - if trust_id is not None: - auth_json['trust_id'] = trust_id - return auth_json - - -class AuthTest(test.TestCase): - def setUp(self): - super(AuthTest, self).setUp() - - CONF.identity.driver = 'keystone.identity.backends.kvs.Identity' - self.load_backends() - self.load_fixtures(default_fixtures) - - # need to register the token provider first because auth controller - # depends on it - token.provider.Manager() - - self.controller = token.controllers.Auth() - - def assertEqualTokens(self, a, b): - """Assert that two tokens are equal. - - Compare two tokens except for their ids. This also truncates - the time in the comparison. - """ - def normalize(token): - token['access']['token']['id'] = 'dummy' - del token['access']['token']['expires'] - del token['access']['token']['issued_at'] - return token - - self.assertCloseEnoughForGovernmentWork( - timeutils.parse_isotime(a['access']['token']['expires']), - timeutils.parse_isotime(b['access']['token']['expires'])) - self.assertCloseEnoughForGovernmentWork( - timeutils.parse_isotime(a['access']['token']['issued_at']), - timeutils.parse_isotime(b['access']['token']['issued_at'])) - return self.assertDictEqual(normalize(a), normalize(b)) - - -class AuthBadRequests(AuthTest): - def setUp(self): - super(AuthBadRequests, self).setUp() - - def test_no_external_auth(self): - """Verify that _authenticate_external() raises exception if N/A.""" - self.assertRaises( - token.controllers.ExternalAuthNotApplicable, - self.controller._authenticate_external, - {}, {}) - - def test_no_token_in_auth(self): - """Verify that _authenticate_token() raises exception if no token.""" - self.assertRaises( - exception.ValidationError, - self.controller._authenticate_token, - None, {}) - - def test_no_credentials_in_auth(self): - """Verify that _authenticate_local() raises exception if no creds.""" - self.assertRaises( - exception.ValidationError, - self.controller._authenticate_local, - None, {}) - - def test_authenticate_blank_request_body(self): - """Verify sending empty json dict raises the right exception.""" - self.assertRaises(exception.ValidationError, - self.controller.authenticate, - {}, {}) - - def test_authenticate_blank_auth(self): - """Verify sending blank 'auth' raises the right exception.""" - body_dict = _build_user_auth() - self.assertRaises(exception.ValidationError, - self.controller.authenticate, - {}, body_dict) - - def test_authenticate_invalid_auth_content(self): - """Verify sending invalid 'auth' raises the right exception.""" - self.assertRaises(exception.ValidationError, - self.controller.authenticate, - {}, {'auth': 'abcd'}) - - def test_authenticate_user_id_too_large(self): - """Verify sending large 'userId' raises the right exception.""" - body_dict = _build_user_auth(user_id='0' * 65, username='FOO', - password='foo2') - self.assertRaises(exception.ValidationSizeError, - self.controller.authenticate, - {}, body_dict) - - def test_authenticate_username_too_large(self): - """Verify sending large 'username' raises the right exception.""" - body_dict = _build_user_auth(username='0' * 65, password='foo2') - self.assertRaises(exception.ValidationSizeError, - self.controller.authenticate, - {}, body_dict) - - def test_authenticate_tenant_id_too_large(self): - """Verify sending large 'tenantId' raises the right exception.""" - body_dict = _build_user_auth(username='FOO', password='foo2', - tenant_id='0' * 65) - self.assertRaises(exception.ValidationSizeError, - self.controller.authenticate, - {}, body_dict) - - def test_authenticate_tenant_name_too_large(self): - """Verify sending large 'tenantName' raises the right exception.""" - body_dict = _build_user_auth(username='FOO', password='foo2', - tenant_name='0' * 65) - self.assertRaises(exception.ValidationSizeError, - self.controller.authenticate, - {}, body_dict) - - def test_authenticate_token_too_large(self): - """Verify sending large 'token' raises the right exception.""" - body_dict = _build_user_auth(token={'id': '0' * 8193}) - self.assertRaises(exception.ValidationSizeError, - self.controller.authenticate, - {}, body_dict) - - def test_authenticate_password_too_large(self): - """Verify sending large 'password' raises the right exception.""" - length = CONF.identity.max_password_length + 1 - body_dict = _build_user_auth(username='FOO', password='0' * length) - self.assertRaises(exception.ValidationSizeError, - self.controller.authenticate, - {}, body_dict) - - -class AuthWithToken(AuthTest): - def setUp(self): - super(AuthWithToken, self).setUp() - - def test_unscoped_token(self): - """Verify getting an unscoped token with password creds.""" - body_dict = _build_user_auth(username='FOO', - password='foo2') - unscoped_token = self.controller.authenticate({}, body_dict) - tenant = unscoped_token["access"]["token"].get("tenant", None) - self.assertEqual(tenant, None) - - def test_auth_invalid_token(self): - """Verify exception is raised if invalid token.""" - body_dict = _build_user_auth(token={"id": uuid.uuid4().hex}) - self.assertRaises( - exception.Unauthorized, - self.controller.authenticate, - {}, body_dict) - - def test_auth_bad_formatted_token(self): - """Verify exception is raised if invalid token.""" - body_dict = _build_user_auth(token={}) - self.assertRaises( - exception.ValidationError, - self.controller.authenticate, - {}, body_dict) - - def test_auth_unscoped_token_no_project(self): - """Verify getting an unscoped token with an unscoped token.""" - body_dict = _build_user_auth( - username='FOO', - password='foo2') - unscoped_token = self.controller.authenticate({}, body_dict) - - body_dict = _build_user_auth( - token=unscoped_token["access"]["token"]) - unscoped_token_2 = self.controller.authenticate({}, body_dict) - - self.assertEqualTokens(unscoped_token, unscoped_token_2) - - def test_auth_unscoped_token_project(self): - """Verify getting a token in a tenant with an unscoped token.""" - # Add a role in so we can check we get this back - self.identity_api.add_role_to_user_and_project( - self.user_foo['id'], - self.tenant_bar['id'], - self.role_member['id']) - # Get an unscoped tenant - body_dict = _build_user_auth( - username='FOO', - password='foo2') - unscoped_token = self.controller.authenticate({}, body_dict) - # Get a token on BAR tenant using the unscoped tenant - body_dict = _build_user_auth( - token=unscoped_token["access"]["token"], - tenant_name="BAR") - scoped_token = self.controller.authenticate({}, body_dict) - - tenant = scoped_token["access"]["token"]["tenant"] - roles = scoped_token["access"]["metadata"]["roles"] - self.assertEquals(tenant["id"], self.tenant_bar['id']) - self.assertEquals(roles[0], self.role_member['id']) - - def test_auth_token_project_group_role(self): - """Verify getting a token in a tenant with group roles.""" - # Add a v2 style role in so we can check we get this back - self.identity_api.add_role_to_user_and_project( - self.user_foo['id'], - self.tenant_bar['id'], - self.role_member['id']) - # Now create a group role for this user as well - new_group = {'id': uuid.uuid4().hex, 'domain_id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex} - self.identity_api.create_group(new_group['id'], new_group) - self.identity_api.add_user_to_group(self.user_foo['id'], - new_group['id']) - self.identity_api.create_grant( - group_id=new_group['id'], - project_id=self.tenant_bar['id'], - role_id=self.role_admin['id']) - - # Get a scoped token for the tenant - body_dict = _build_user_auth( - username='FOO', - password='foo2', - tenant_name="BAR") - - scoped_token = self.controller.authenticate({}, body_dict) - - tenant = scoped_token["access"]["token"]["tenant"] - roles = scoped_token["access"]["metadata"]["roles"] - self.assertEquals(tenant["id"], self.tenant_bar['id']) - self.assertIn(self.role_member['id'], roles) - self.assertIn(self.role_admin['id'], roles) - - def test_auth_token_cross_domain_group_and_project(self): - """Verify getting a token in cross domain group/project roles.""" - # create domain, project and group and grant roles to user - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id']} - self.identity_api.create_project(project1['id'], project1) - role_foo_domain1 = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex} - self.identity_api.create_role(role_foo_domain1['id'], - role_foo_domain1) - role_group_domain1 = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex} - self.identity_api.create_role(role_group_domain1['id'], - role_group_domain1) - self.identity_api.add_user_to_project(project1['id'], - self.user_foo['id']) - new_group = {'id': uuid.uuid4().hex, 'domain_id': domain1['id'], - 'name': uuid.uuid4().hex} - self.identity_api.create_group(new_group['id'], new_group) - self.identity_api.add_user_to_group(self.user_foo['id'], - new_group['id']) - self.identity_api.create_grant( - user_id=self.user_foo['id'], - project_id=project1['id'], - role_id=self.role_member['id']) - self.identity_api.create_grant( - group_id=new_group['id'], - project_id=project1['id'], - role_id=self.role_admin['id']) - self.identity_api.create_grant( - user_id=self.user_foo['id'], - domain_id=domain1['id'], - role_id=role_foo_domain1['id']) - self.identity_api.create_grant( - group_id=new_group['id'], - domain_id=domain1['id'], - role_id=role_group_domain1['id']) - - # Get a scoped token for the tenant - body_dict = _build_user_auth( - username=self.user_foo['name'], - password=self.user_foo['password'], - tenant_name=project1['name']) - - scoped_token = self.controller.authenticate({}, body_dict) - tenant = scoped_token["access"]["token"]["tenant"] - roles = scoped_token["access"]["metadata"]["roles"] - self.assertEquals(tenant["id"], project1['id']) - self.assertIn(self.role_member['id'], roles) - self.assertIn(self.role_admin['id'], roles) - self.assertNotIn(role_foo_domain1['id'], roles) - self.assertNotIn(role_group_domain1['id'], roles) - - def test_belongs_to_no_tenant(self): - r = self.controller.authenticate( - {}, - auth={ - 'passwordCredentials': { - 'username': self.user_foo['name'], - 'password': self.user_foo['password'] - } - }) - unscoped_token_id = r['access']['token']['id'] - self.assertRaises( - exception.Unauthorized, - self.controller.validate_token, - dict(is_admin=True, query_string={'belongsTo': 'BAR'}), - token_id=unscoped_token_id) - - def test_belongs_to(self): - body_dict = _build_user_auth( - username='FOO', - password='foo2', - tenant_name="BAR") - - scoped_token = self.controller.authenticate({}, body_dict) - scoped_token_id = scoped_token['access']['token']['id'] - - self.assertRaises( - exception.Unauthorized, - self.controller.validate_token, - dict(is_admin=True, query_string={'belongsTo': 'me'}), - token_id=scoped_token_id) - - self.assertRaises( - exception.Unauthorized, - self.controller.validate_token, - dict(is_admin=True, query_string={'belongsTo': 'BAR'}), - token_id=scoped_token_id) - - def test_token_auth_with_binding(self): - CONF.token.bind = ['kerberos'] - body_dict = _build_user_auth() - context = {'REMOTE_USER': 'FOO', 'AUTH_TYPE': 'Negotiate'} - unscoped_token = self.controller.authenticate(context, body_dict) - - # the token should have bind information in it - bind = unscoped_token['access']['token']['bind'] - self.assertEqual(bind['kerberos'], 'FOO') - - body_dict = _build_user_auth( - token=unscoped_token['access']['token'], - tenant_name='BAR') - - # using unscoped token without remote user context fails - self.assertRaises( - exception.Unauthorized, - self.controller.authenticate, - {}, body_dict) - - # using token with remote user context succeeds - scoped_token = self.controller.authenticate(context, body_dict) - - # the bind information should be carried over from the original token - bind = scoped_token['access']['token']['bind'] - self.assertEqual(bind['kerberos'], 'FOO') - - -class AuthWithPasswordCredentials(AuthTest): - def setUp(self): - super(AuthWithPasswordCredentials, self).setUp() - - def test_auth_invalid_user(self): - """Verify exception is raised if invalid user.""" - body_dict = _build_user_auth( - username=uuid.uuid4().hex, - password=uuid.uuid4().hex) - self.assertRaises( - exception.Unauthorized, - self.controller.authenticate, - {}, body_dict) - - def test_auth_valid_user_invalid_password(self): - """Verify exception is raised if invalid password.""" - body_dict = _build_user_auth( - username="FOO", - password=uuid.uuid4().hex) - self.assertRaises( - exception.Unauthorized, - self.controller.authenticate, - {}, body_dict) - - def test_auth_empty_password(self): - """Verify exception is raised if empty password.""" - body_dict = _build_user_auth( - username="FOO", - password="") - self.assertRaises( - exception.Unauthorized, - self.controller.authenticate, - {}, body_dict) - - def test_auth_no_password(self): - """Verify exception is raised if empty password.""" - body_dict = _build_user_auth(username="FOO") - self.assertRaises( - exception.ValidationError, - self.controller.authenticate, - {}, body_dict) - - def test_authenticate_blank_password_credentials(self): - """Sending empty dict as passwordCredentials raises a 400 error.""" - body_dict = {'passwordCredentials': {}, 'tenantName': 'demo'} - self.assertRaises(exception.ValidationError, - self.controller.authenticate, - {}, body_dict) - - def test_authenticate_no_username(self): - """Verify skipping username raises the right exception.""" - body_dict = _build_user_auth(password="pass", - tenant_name="demo") - self.assertRaises(exception.ValidationError, - self.controller.authenticate, - {}, body_dict) - - def test_bind_without_remote_user(self): - CONF.token.bind = ['kerberos'] - body_dict = _build_user_auth(username='FOO', password='foo2', - tenant_name='BAR') - token = self.controller.authenticate({}, body_dict) - self.assertNotIn('bind', token['access']['token']) - - -class AuthWithRemoteUser(AuthTest): - def setUp(self): - super(AuthWithRemoteUser, self).setUp() - - def test_unscoped_remote_authn(self): - """Verify getting an unscoped token with external authn.""" - body_dict = _build_user_auth( - username='FOO', - password='foo2') - local_token = self.controller.authenticate( - {}, body_dict) - - body_dict = _build_user_auth() - remote_token = self.controller.authenticate( - {'REMOTE_USER': 'FOO'}, body_dict) - - self.assertEqualTokens(local_token, remote_token) - - def test_unscoped_remote_authn_jsonless(self): - """Verify that external auth with invalid request fails.""" - self.assertRaises( - exception.ValidationError, - self.controller.authenticate, - {'REMOTE_USER': 'FOO'}, - None) - - def test_scoped_remote_authn(self): - """Verify getting a token with external authn.""" - body_dict = _build_user_auth( - username='FOO', - password='foo2', - tenant_name='BAR') - local_token = self.controller.authenticate( - {}, body_dict) - - body_dict = _build_user_auth( - tenant_name='BAR') - remote_token = self.controller.authenticate( - {'REMOTE_USER': 'FOO'}, body_dict) - - self.assertEqualTokens(local_token, remote_token) - - def test_scoped_nometa_remote_authn(self): - """Verify getting a token with external authn and no metadata.""" - body_dict = _build_user_auth( - username='TWO', - password='two2', - tenant_name='BAZ') - local_token = self.controller.authenticate( - {}, body_dict) - - body_dict = _build_user_auth(tenant_name='BAZ') - remote_token = self.controller.authenticate( - {'REMOTE_USER': 'TWO'}, body_dict) - - self.assertEqualTokens(local_token, remote_token) - - def test_scoped_remote_authn_invalid_user(self): - """Verify that external auth with invalid user fails.""" - body_dict = _build_user_auth(tenant_name="BAR") - self.assertRaises( - exception.Unauthorized, - self.controller.authenticate, - {'REMOTE_USER': uuid.uuid4().hex}, - body_dict) - - def test_bind_with_kerberos(self): - CONF.token.bind = ['kerberos'] - kerb = {'REMOTE_USER': 'FOO', 'AUTH_TYPE': 'Negotiate'} - body_dict = _build_user_auth(tenant_name="BAR") - token = self.controller.authenticate(kerb, body_dict) - self.assertEqual(token['access']['token']['bind']['kerberos'], 'FOO') - - def test_bind_without_config_opt(self): - CONF.token.bind = ['x509'] - kerb = {'REMOTE_USER': 'FOO', 'AUTH_TYPE': 'Negotiate'} - body_dict = _build_user_auth(tenant_name='BAR') - token = self.controller.authenticate(kerb, body_dict) - self.assertNotIn('bind', token['access']['token']) - - -class AuthWithTrust(AuthTest): - def setUp(self): - super(AuthWithTrust, self).setUp() - self.opt_in_group('trust', enabled=True) - - trust.Manager() - self.trust_controller = trust.controllers.TrustV3() - self.auth_v3_controller = auth.controllers.Auth() - self.trustor = self.user_foo - self.trustee = self.user_two - self.assigned_roles = [self.role_member['id'], - self.role_browser['id']] - for assigned_role in self.assigned_roles: - self.identity_api.add_role_to_user_and_project( - self.trustor['id'], self.tenant_bar['id'], assigned_role) - - self.sample_data = {'trustor_user_id': self.trustor['id'], - 'trustee_user_id': self.trustee['id'], - 'project_id': self.tenant_bar['id'], - 'impersonation': 'True', - 'roles': [{'id': self.role_browser['id']}, - {'name': self.role_member['name']}]} - expires_at = timeutils.strtime(timeutils.utcnow() + - datetime.timedelta(minutes=10), - fmt=TIME_FORMAT) - self.create_trust(expires_at=expires_at) - - def create_trust(self, expires_at=None, impersonation='True'): - username = self.trustor['name'], - password = 'foo2' - body_dict = _build_user_auth(username=username, password=password) - self.unscoped_token = self.controller.authenticate({}, body_dict) - context = {'token_id': self.unscoped_token['access']['token']['id']} - trust_data = copy.deepcopy(self.sample_data) - trust_data['expires_at'] = expires_at - trust_data['impersonation'] = impersonation - - self.new_trust = self.trust_controller.create_trust( - context, trust=trust_data)['trust'] - - def build_v2_token_request(self, username, password): - body_dict = _build_user_auth(username=username, password=password) - self.unscoped_token = self.controller.authenticate({}, body_dict) - unscoped_token_id = self.unscoped_token['access']['token']['id'] - request_body = _build_user_auth(token={'id': unscoped_token_id}, - trust_id=self.new_trust['id'], - tenant_id=self.tenant_bar['id']) - return request_body - - def test_create_trust_bad_data_fails(self): - context = {'token_id': self.unscoped_token['access']['token']['id']} - bad_sample_data = {'trustor_user_id': self.trustor['id']} - - self.assertRaises(exception.ValidationError, - self.trust_controller.create_trust, - context, trust=bad_sample_data) - - def test_create_trust_no_roles(self): - self.new_trust = None - self.sample_data['roles'] = [] - self.create_trust() - self.assertEquals(self.new_trust['roles'], []) - - def test_create_trust(self): - self.assertEquals(self.new_trust['trustor_user_id'], - self.trustor['id']) - self.assertEquals(self.new_trust['trustee_user_id'], - self.trustee['id']) - role_ids = [self.role_browser['id'], self.role_member['id']] - self.assertTrue(timeutils.parse_strtime(self.new_trust['expires_at'], - fmt=TIME_FORMAT)) - self.assertIn('http://localhost:5000/v3/OS-TRUST/', - self.new_trust['links']['self']) - self.assertIn('http://localhost:5000/v3/OS-TRUST/', - self.new_trust['roles_links']['self']) - - for role in self.new_trust['roles']: - self.assertIn(role['id'], role_ids) - - def test_get_trust(self): - context = {'token_id': self.unscoped_token['access']['token']['id']} - trust = self.trust_controller.get_trust(context, - self.new_trust['id'])['trust'] - self.assertEquals(trust['trustor_user_id'], - self.trustor['id']) - self.assertEquals(trust['trustee_user_id'], - self.trustee['id']) - role_ids = [self.role_browser['id'], self.role_member['id']] - for role in self.new_trust['roles']: - self.assertIn(role['id'], role_ids) - - def test_create_trust_no_impersonation(self): - self.create_trust(expires_at=None, impersonation='False') - self.assertEquals(self.new_trust['trustor_user_id'], - self.trustor['id']) - self.assertEquals(self.new_trust['trustee_user_id'], - self.trustee['id']) - self.assertEquals(self.new_trust['impersonation'], - 'False') - auth_response = self.fetch_v2_token_from_trust() - token_user = auth_response['access']['user'] - self.assertEquals(token_user['id'], - self.new_trust['trustee_user_id']) - - # TODO(ayoung): Endpoints - - def test_token_from_trust_wrong_user_fails(self): - request_body = self.build_v2_token_request('FOO', 'foo2') - self.assertRaises( - exception.Forbidden, - self.controller.authenticate, {}, request_body) - - def fetch_v2_token_from_trust(self): - request_body = self.build_v2_token_request('TWO', 'two2') - auth_response = self.controller.authenticate({}, request_body) - return auth_response - - def fetch_v3_token_from_trust(self): - v3_password_data = { - 'identity': { - "methods": ["password"], - "password": { - "user": { - "id": self.trustee["id"], - "password": self.trustee["password"]}} - }, - 'scope': { - 'project': { - 'id': self.tenant_baz['id']}}} - auth_response = (self.auth_v3_controller.authenticate_for_token - ({'query_string': {}}, v3_password_data)) - token = auth_response.headers['X-Subject-Token'] - - v3_req_with_trust = { - "identity": { - "methods": ["token"], - "token": {"id": token}}, - "scope": { - "OS-TRUST:trust": {"id": self.new_trust['id']}}} - token_auth_response = (self.auth_v3_controller.authenticate_for_token - ({'query_string': {}}, v3_req_with_trust)) - return token_auth_response - - def test_create_v3_token_from_trust(self): - auth_response = self.fetch_v3_token_from_trust() - - trust_token_user = auth_response.json['token']['user'] - self.assertEquals(trust_token_user['id'], self.trustor['id']) - - trust_token_trust = auth_response.json['token']['OS-TRUST:trust'] - self.assertEquals(trust_token_trust['id'], self.new_trust['id']) - self.assertEquals(trust_token_trust['trustor_user']['id'], - self.trustor['id']) - self.assertEquals(trust_token_trust['trustee_user']['id'], - self.trustee['id']) - - trust_token_roles = auth_response.json['token']['roles'] - self.assertEquals(len(trust_token_roles), 2) - - def test_v3_trust_token_get_token_fails(self): - auth_response = self.fetch_v3_token_from_trust() - trust_token = auth_response.headers['X-Subject-Token'] - v3_token_data = {'identity': { - 'methods': ['token'], - 'token': {'id': trust_token} - }} - self.assertRaises( - exception.Forbidden, - self.auth_v3_controller.authenticate_for_token, - {'query_string': {}}, v3_token_data) - - def test_token_from_trust(self): - auth_response = self.fetch_v2_token_from_trust() - - self.assertIsNotNone(auth_response) - self.assertEquals(len(auth_response['access']['metadata']['roles']), - 2, - "user_foo has three roles, but the token should" - " only get the two roles specified in the trust.") - - def assert_token_count_for_trust(self, expected_value): - tokens = self.trust_controller.token_api.list_tokens( - self.trustee['id'], trust_id=self.new_trust['id']) - token_count = len(tokens) - self.assertEquals(token_count, expected_value) - - def test_delete_tokens_for_user_invalidates_tokens_from_trust(self): - self.assert_token_count_for_trust(0) - self.fetch_v2_token_from_trust() - self.assert_token_count_for_trust(1) - self.trust_controller._delete_tokens_for_user(self.trustee['id']) - self.assert_token_count_for_trust(0) - - def test_token_from_trust_cant_get_another_token(self): - auth_response = self.fetch_v2_token_from_trust() - trust_token_id = auth_response['access']['token']['id'] - request_body = _build_user_auth(token={'id': trust_token_id}, - tenant_id=self.tenant_bar['id']) - self.assertRaises( - exception.Forbidden, - self.controller.authenticate, {}, request_body) - - def test_delete_trust_revokes_token(self): - context = {'token_id': self.unscoped_token['access']['token']['id']} - self.fetch_v2_token_from_trust() - trust_id = self.new_trust['id'] - tokens = self.token_api.list_tokens(self.trustor['id'], - trust_id=trust_id) - self.assertEquals(len(tokens), 1) - self.trust_controller.delete_trust(context, trust_id=trust_id) - tokens = self.token_api.list_tokens(self.trustor['id'], - trust_id=trust_id) - self.assertEquals(len(tokens), 0) - - def test_token_from_trust_with_no_role_fails(self): - for assigned_role in self.assigned_roles: - self.identity_api.remove_role_from_user_and_project( - self.trustor['id'], self.tenant_bar['id'], assigned_role) - request_body = self.build_v2_token_request('TWO', 'two2') - self.assertRaises( - exception.Forbidden, - self.controller.authenticate, {}, request_body) - - def test_expired_trust_get_token_fails(self): - expiry = "1999-02-18T10:10:00Z" - self.create_trust(expiry) - request_body = self.build_v2_token_request('TWO', 'two2') - self.assertRaises( - exception.Forbidden, - self.controller.authenticate, {}, request_body) - - def test_token_from_trust_with_wrong_role_fails(self): - self.identity_api.add_role_to_user_and_project( - self.trustor['id'], - self.tenant_bar['id'], - self.role_other['id']) - for assigned_role in self.assigned_roles: - self.identity_api.remove_role_from_user_and_project( - self.trustor['id'], self.tenant_bar['id'], assigned_role) - - request_body = self.build_v2_token_request('TWO', 'two2') - - self.assertRaises( - exception.Forbidden, - self.controller.authenticate, {}, request_body) - - -class TokenExpirationTest(AuthTest): - def _maintain_token_expiration(self): - """Token expiration should be maintained after re-auth & validation.""" - timeutils.set_time_override() - - r = self.controller.authenticate( - {}, - auth={ - 'passwordCredentials': { - 'username': self.user_foo['name'], - 'password': self.user_foo['password'] - } - }) - unscoped_token_id = r['access']['token']['id'] - original_expiration = r['access']['token']['expires'] - - timeutils.advance_time_seconds(1) - - r = self.controller.validate_token( - dict(is_admin=True, query_string={}), - token_id=unscoped_token_id) - self.assertEqual(original_expiration, r['access']['token']['expires']) - - timeutils.advance_time_seconds(1) - - r = self.controller.authenticate( - {}, - auth={ - 'token': { - 'id': unscoped_token_id, - }, - 'tenantId': self.tenant_bar['id'], - }) - scoped_token_id = r['access']['token']['id'] - self.assertEqual(original_expiration, r['access']['token']['expires']) - - timeutils.advance_time_seconds(1) - - r = self.controller.validate_token( - dict(is_admin=True, query_string={}), - token_id=scoped_token_id) - self.assertEqual(original_expiration, r['access']['token']['expires']) - - def test_maintain_uuid_token_expiration(self): - self.opt_in_group('signing', token_format='UUID') - self._maintain_token_expiration() - - -class NonDefaultAuthTest(test.TestCase): - - def test_add_non_default_auth_method(self): - self.opt_in_group('auth', methods=['password', 'token', 'custom']) - config.setup_authentication() - self.assertTrue(hasattr(CONF.auth, 'custom')) diff --git a/tests/test_auth_plugin.conf b/tests/test_auth_plugin.conf deleted file mode 100644 index edec8f79..00000000 --- a/tests/test_auth_plugin.conf +++ /dev/null @@ -1,3 +0,0 @@ -[auth] -methods = external,password,token,simple-challenge-response -simple-challenge-response = challenge_response_method.SimpleChallengeResponse diff --git a/tests/test_auth_plugin.py b/tests/test_auth_plugin.py deleted file mode 100644 index d158ec46..00000000 --- a/tests/test_auth_plugin.py +++ /dev/null @@ -1,106 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 OpenStack 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 uuid - -from keystone import test - -from keystone import auth -from keystone import exception -from keystone import token - - -# for testing purposes only -METHOD_NAME = 'simple-challenge-response' -EXPECTED_RESPONSE = uuid.uuid4().hex -DEMO_USER_ID = uuid.uuid4().hex - - -class SimpleChallengeResponse(auth.AuthMethodHandler): - def authenticate(self, context, auth_payload, user_context): - if 'response' in auth_payload: - if auth_payload['response'] != EXPECTED_RESPONSE: - raise exception.Unauthorized('Wrong answer') - user_context['user_id'] = DEMO_USER_ID - else: - return {"challenge": "What's the name of your high school?"} - - -class TestAuthPlugin(test.TestCase): - def setUp(self): - super(TestAuthPlugin, self).setUp() - self.config([ - test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf'), - test.testsdir('backend_sql.conf'), - test.testsdir('backend_sql_disk.conf'), - test.testsdir('test_auth_plugin.conf')]) - self.load_backends() - auth.controllers.AUTH_METHODS[METHOD_NAME] = SimpleChallengeResponse() - - # need to register the token provider first because auth controller - # depends on it - token.provider.Manager() - - self.api = auth.controllers.Auth() - - def test_unsupported_auth_method(self): - method_name = uuid.uuid4().hex - auth_data = {'methods': [method_name]} - auth_data[method_name] = {'test': 'test'} - auth_data = {'identity': auth_data} - self.assertRaises(exception.AuthMethodNotSupported, - auth.controllers.AuthInfo, - None, - auth_data) - - def test_addition_auth_steps(self): - auth_data = {'methods': ['simple-challenge-response']} - auth_data['simple-challenge-response'] = { - 'test': 'test'} - auth_data = {'identity': auth_data} - auth_info = auth.controllers.AuthInfo(None, auth_data) - auth_context = {'extras': {}, 'method_names': []} - try: - self.api.authenticate({}, auth_info, auth_context) - except exception.AdditionalAuthRequired as e: - self.assertTrue('methods' in e.authentication) - self.assertTrue(METHOD_NAME in e.authentication['methods']) - self.assertTrue(METHOD_NAME in e.authentication) - self.assertTrue('challenge' in e.authentication[METHOD_NAME]) - - # test correct response - auth_data = {'methods': ['simple-challenge-response']} - auth_data['simple-challenge-response'] = { - 'response': EXPECTED_RESPONSE} - auth_data = {'identity': auth_data} - auth_info = auth.controllers.AuthInfo(None, auth_data) - auth_context = {'extras': {}, 'method_names': []} - self.api.authenticate({}, auth_info, auth_context) - self.assertEqual(auth_context['user_id'], DEMO_USER_ID) - - # test incorrect response - auth_data = {'methods': ['simple-challenge-response']} - auth_data['simple-challenge-response'] = { - 'response': uuid.uuid4().hex} - auth_data = {'identity': auth_data} - auth_info = auth.controllers.AuthInfo(None, auth_data) - auth_context = {'extras': {}, 'method_names': []} - self.assertRaises(exception.Unauthorized, - self.api.authenticate, - {}, - auth_info, - auth_context) diff --git a/tests/test_backend.py b/tests/test_backend.py deleted file mode 100644 index 75a94773..00000000 --- a/tests/test_backend.py +++ /dev/null @@ -1,2892 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 datetime -import uuid - -from keystone import test - -from keystone.catalog import core -from keystone import config -from keystone import exception -from keystone.openstack.common import timeutils - -import default_fixtures - - -CONF = config.CONF -DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id -TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ' -NULL_OBJECT = object() - - -class IdentityTests(object): - def _get_domain_fixture(self): - domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain['id'], domain) - return domain - - def test_project_add_and_remove_user_role(self): - user_refs = self.identity_api.get_project_users(self.tenant_bar['id']) - self.assertNotIn(self.user_two['id'], [x['id'] for x in user_refs]) - - self.identity_api.add_role_to_user_and_project( - tenant_id=self.tenant_bar['id'], - user_id=self.user_two['id'], - role_id=self.role_other['id']) - user_refs = self.identity_api.get_project_users(self.tenant_bar['id']) - self.assertIn(self.user_two['id'], [x['id'] for x in user_refs]) - - self.identity_api.remove_role_from_user_and_project( - tenant_id=self.tenant_bar['id'], - user_id=self.user_two['id'], - role_id=self.role_other['id']) - - user_refs = self.identity_api.get_project_users(self.tenant_bar['id']) - self.assertNotIn(self.user_two['id'], [x['id'] for x in user_refs]) - - def test_authenticate_bad_user(self): - self.assertRaises(AssertionError, - self.identity_api.authenticate, - user_id=uuid.uuid4().hex, - password=self.user_foo['password']) - - def test_authenticate_bad_password(self): - self.assertRaises(AssertionError, - self.identity_api.authenticate, - user_id=self.user_foo['id'], - password=uuid.uuid4().hex) - - def test_authenticate(self): - user_ref = self.identity_api.authenticate( - user_id=self.user_sna['id'], - password=self.user_sna['password']) - # NOTE(termie): the password field is left in user_foo to make - # it easier to authenticate in tests, but should - # not be returned by the api - self.user_sna.pop('password') - self.user_sna['enabled'] = True - self.assertDictEqual(user_ref, self.user_sna) - - def test_authenticate_and_get_roles_no_metadata(self): - user = { - 'id': 'no_meta', - 'name': 'NO_META', - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': 'no_meta2', - } - self.identity_api.create_user(user['id'], user) - self.identity_api.add_user_to_project(self.tenant_baz['id'], - user['id']) - user_ref = self.identity_api.authenticate( - user_id=user['id'], - password=user['password']) - # NOTE(termie): the password field is left in user_foo to make - # it easier to authenticate in tests, but should - # not be returned by the api - user.pop('password') - self.assertDictContainsSubset(user, user_ref) - role_list = self.identity_api.get_roles_for_user_and_project( - user['id'], self.tenant_baz['id']) - self.assertEqual(len(role_list), 1) - self.assertIn(CONF.member_role_id, role_list) - - def test_password_hashed(self): - user_ref = self.identity_api._get_user(self.user_foo['id']) - self.assertNotEqual(user_ref['password'], self.user_foo['password']) - - def test_create_unicode_user_name(self): - unicode_name = u'name \u540d\u5b57' - user = {'id': uuid.uuid4().hex, - 'name': unicode_name, - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': uuid.uuid4().hex} - ref = self.identity_api.create_user(user['id'], user) - self.assertEqual(unicode_name, ref['name']) - - def test_get_project(self): - tenant_ref = self.identity_api.get_project(self.tenant_bar['id']) - self.assertDictEqual(tenant_ref, self.tenant_bar) - - def test_get_project_404(self): - self.assertRaises(exception.ProjectNotFound, - self.identity_api.get_project, - uuid.uuid4().hex) - - def test_get_project_by_name(self): - tenant_ref = self.identity_api.get_project_by_name( - self.tenant_bar['name'], - DEFAULT_DOMAIN_ID) - self.assertDictEqual(tenant_ref, self.tenant_bar) - - def test_get_project_by_name_404(self): - self.assertRaises(exception.ProjectNotFound, - self.identity_api.get_project_by_name, - uuid.uuid4().hex, - DEFAULT_DOMAIN_ID) - - def test_get_project_users(self): - tenant_ref = self.identity_api.get_project_users(self.tenant_baz['id']) - user_ids = [] - for user in tenant_ref: - self.assertNotIn('password', user) - user_ids.append(user.get('id')) - self.assertEquals(len(user_ids), 2) - self.assertIn(self.user_two['id'], user_ids) - self.assertIn(self.user_badguy['id'], user_ids) - - def test_get_project_users_404(self): - self.assertRaises(exception.ProjectNotFound, - self.identity_api.get_project_users, - uuid.uuid4().hex) - - def test_get_user(self): - user_ref = self.identity_api.get_user(self.user_foo['id']) - # NOTE(termie): the password field is left in user_foo to make - # it easier to authenticate in tests, but should - # not be returned by the api - self.user_foo.pop('password') - self.assertDictEqual(user_ref, self.user_foo) - - def test_get_user_404(self): - self.assertRaises(exception.UserNotFound, - self.identity_api.get_user, - uuid.uuid4().hex) - - def test_get_user_by_name(self): - user_ref = self.identity_api.get_user_by_name( - self.user_foo['name'], DEFAULT_DOMAIN_ID) - - # NOTE(termie): the password field is left in user_foo to make - # it easier to authenticate in tests, but should - # not be returned by the api - self.user_foo.pop('password') - self.assertDictEqual(user_ref, self.user_foo) - - def test_get_user_by_name_404(self): - self.assertRaises(exception.UserNotFound, - self.identity_api.get_user_by_name, - uuid.uuid4().hex, - DEFAULT_DOMAIN_ID) - - def test_get_role(self): - role_ref = self.identity_api.get_role(self.role_admin['id']) - role_ref_dict = dict((x, role_ref[x]) for x in role_ref) - self.assertDictEqual(role_ref_dict, self.role_admin) - - def test_get_role_404(self): - self.assertRaises(exception.RoleNotFound, - self.identity_api.get_role, - uuid.uuid4().hex) - - def test_create_duplicate_role_name_fails(self): - role = {'id': 'fake1', - 'name': 'fake1name'} - self.identity_api.create_role('fake1', role) - role['id'] = 'fake2' - self.assertRaises(exception.Conflict, - self.identity_api.create_role, - 'fake2', - role) - - def test_rename_duplicate_role_name_fails(self): - role1 = { - 'id': 'fake1', - 'name': 'fake1name' - } - role2 = { - 'id': 'fake2', - 'name': 'fake2name' - } - self.identity_api.create_role('fake1', role1) - self.identity_api.create_role('fake2', role2) - role1['name'] = 'fake2name' - self.assertRaises(exception.Conflict, - self.identity_api.update_role, - 'fake1', - role1) - - def test_create_duplicate_user_id_fails(self): - user = {'id': 'fake1', - 'name': 'fake1', - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': 'fakepass', - 'tenants': ['bar']} - self.identity_api.create_user('fake1', user) - user['name'] = 'fake2' - self.assertRaises(exception.Conflict, - self.identity_api.create_user, - 'fake1', - user) - - def test_create_duplicate_user_name_fails(self): - user = {'id': 'fake1', - 'name': 'fake1', - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': 'fakepass', - 'tenants': ['bar']} - self.identity_api.create_user('fake1', user) - user['id'] = 'fake2' - self.assertRaises(exception.Conflict, - self.identity_api.create_user, - 'fake2', - user) - - def test_create_duplicate_user_name_in_different_domains(self): - new_domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(new_domain['id'], new_domain) - user1 = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': uuid.uuid4().hex} - user2 = {'id': uuid.uuid4().hex, - 'name': user1['name'], - 'domain_id': new_domain['id'], - 'password': uuid.uuid4().hex} - self.identity_api.create_user(user1['id'], user1) - self.identity_api.create_user(user2['id'], user2) - - def test_move_user_between_domains(self): - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - domain2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain2['id'], domain2) - user = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], - 'password': uuid.uuid4().hex} - self.identity_api.create_user(user['id'], user) - user['domain_id'] = domain2['id'] - self.identity_api.update_user(user['id'], user) - - def test_move_user_between_domains_with_clashing_names_fails(self): - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - domain2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain2['id'], domain2) - # First, create a user in domain1 - user1 = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], - 'password': uuid.uuid4().hex} - self.identity_api.create_user(user1['id'], user1) - # Now create a user in domain2 with a potentially clashing - # name - which should work since we have domain separation - user2 = {'id': uuid.uuid4().hex, - 'name': user1['name'], - 'domain_id': domain2['id'], - 'password': uuid.uuid4().hex} - self.identity_api.create_user(user2['id'], user2) - # Now try and move user1 into the 2nd domain - which should - # fail since the names clash - user1['domain_id'] = domain2['id'] - self.assertRaises(exception.Conflict, - self.identity_api.update_user, - user1['id'], - user1) - - def test_rename_duplicate_user_name_fails(self): - user1 = {'id': 'fake1', - 'name': 'fake1', - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': 'fakepass', - 'tenants': ['bar']} - user2 = {'id': 'fake2', - 'name': 'fake2', - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': 'fakepass', - 'tenants': ['bar']} - self.identity_api.create_user('fake1', user1) - self.identity_api.create_user('fake2', user2) - user2['name'] = 'fake1' - self.assertRaises(exception.Conflict, - self.identity_api.update_user, - 'fake2', - user2) - - def test_update_user_id_fails(self): - user = {'id': 'fake1', - 'name': 'fake1', - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': 'fakepass', - 'tenants': ['bar']} - self.identity_api.create_user('fake1', user) - user['id'] = 'fake2' - self.assertRaises(exception.ValidationError, - self.identity_api.update_user, - 'fake1', - user) - user_ref = self.identity_api.get_user('fake1') - self.assertEqual(user_ref['id'], 'fake1') - self.assertRaises(exception.UserNotFound, - self.identity_api.get_user, - 'fake2') - - def test_create_duplicate_project_id_fails(self): - tenant = {'id': 'fake1', 'name': 'fake1', - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_project('fake1', tenant) - tenant['name'] = 'fake2' - self.assertRaises(exception.Conflict, - self.identity_api.create_project, - 'fake1', - tenant) - - def test_create_duplicate_project_name_fails(self): - tenant = {'id': 'fake1', 'name': 'fake', - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_project('fake1', tenant) - tenant['id'] = 'fake2' - self.assertRaises(exception.Conflict, - self.identity_api.create_project, - 'fake1', - tenant) - - def test_create_duplicate_project_name_in_different_domains(self): - new_domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(new_domain['id'], new_domain) - tenant1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': DEFAULT_DOMAIN_ID} - tenant2 = {'id': uuid.uuid4().hex, 'name': tenant1['name'], - 'domain_id': new_domain['id']} - self.identity_api.create_project(tenant1['id'], tenant1) - self.identity_api.create_project(tenant2['id'], tenant2) - - def test_move_project_between_domains(self): - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - domain2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain2['id'], domain2) - project = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain1['id']} - self.identity_api.create_project(project['id'], project) - project['domain_id'] = domain2['id'] - self.identity_api.update_project(project['id'], project) - - def test_move_project_between_domains_with_clashing_names_fails(self): - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - domain2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain2['id'], domain2) - # First, create a project in domain1 - project1 = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain1['id']} - self.identity_api.create_project(project1['id'], project1) - # Now create a project in domain2 with a potentially clashing - # name - which should work since we have domain separation - project2 = {'id': uuid.uuid4().hex, - 'name': project1['name'], - 'domain_id': domain2['id']} - self.identity_api.create_project(project2['id'], project2) - # Now try and move project1 into the 2nd domain - which should - # fail since the names clash - project1['domain_id'] = domain2['id'] - self.assertRaises(exception.Conflict, - self.identity_api.update_project, - project1['id'], - project1) - - def test_rename_duplicate_project_name_fails(self): - tenant1 = {'id': 'fake1', 'name': 'fake1', - 'domain_id': DEFAULT_DOMAIN_ID} - tenant2 = {'id': 'fake2', 'name': 'fake2', - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_project('fake1', tenant1) - self.identity_api.create_project('fake2', tenant2) - tenant2['name'] = 'fake1' - self.assertRaises(exception.Error, - self.identity_api.update_project, - 'fake2', - tenant2) - - def test_update_project_id_does_nothing(self): - tenant = {'id': 'fake1', 'name': 'fake1', - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_project('fake1', tenant) - tenant['id'] = 'fake2' - self.identity_api.update_project('fake1', tenant) - tenant_ref = self.identity_api.get_project('fake1') - self.assertEqual(tenant_ref['id'], 'fake1') - self.assertRaises(exception.ProjectNotFound, - self.identity_api.get_project, - 'fake2') - - def test_list_role_assignments_unfiltered(self): - """Test for unfiltered listing role assignments. - - Test Plan: - - Create a domain, with a user, group & project - - Find how many role assignments already exist (from default - fixtures) - - Create a grant of each type (user/group on project/domain) - - Check the number of assignments has gone up by 4 and that - the entries we added are in the list returned - - """ - new_domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(new_domain['id'], new_domain) - new_user = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, 'enabled': True, - 'domain_id': new_domain['id']} - self.identity_api.create_user(new_user['id'], - new_user) - new_group = {'id': uuid.uuid4().hex, 'domain_id': new_domain['id'], - 'name': uuid.uuid4().hex} - self.identity_api.create_group(new_group['id'], new_group) - new_project = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': new_domain['id']} - self.identity_api.create_project(new_project['id'], new_project) - - # First check how many role grant already exist - existing_assignments = len(self.identity_api.list_role_assignments()) - - # Now create the grants (roles are defined in default_fixtures) - self.identity_api.create_grant(user_id=new_user['id'], - domain_id=new_domain['id'], - role_id='member') - self.identity_api.create_grant(user_id=new_user['id'], - project_id=new_project['id'], - role_id='other') - self.identity_api.create_grant(group_id=new_group['id'], - domain_id=new_domain['id'], - role_id='admin') - self.identity_api.create_grant(group_id=new_group['id'], - project_id=new_project['id'], - role_id='admin') - - # Read back the list of assignments - check it is gone up by 4 - assignment_list = self.identity_api.list_role_assignments() - self.assertEquals(len(assignment_list), existing_assignments + 4) - - # Now check that each of our four new entries are in the list - self.assertIn( - {'user_id': new_user['id'], 'domain_id': new_domain['id'], - 'role_id': 'member'}, - assignment_list) - self.assertIn( - {'user_id': new_user['id'], 'project_id': new_project['id'], - 'role_id': 'other'}, - assignment_list) - self.assertIn( - {'group_id': new_group['id'], 'domain_id': new_domain['id'], - 'role_id': 'admin'}, - assignment_list) - self.assertIn( - {'group_id': new_group['id'], 'project_id': new_project['id'], - 'role_id': 'admin'}, - assignment_list) - - def test_add_duplicate_role_grant(self): - roles_ref = self.identity_api.get_roles_for_user_and_project( - self.user_foo['id'], self.tenant_bar['id']) - self.assertNotIn(self.role_admin['id'], roles_ref) - self.identity_api.add_role_to_user_and_project( - self.user_foo['id'], self.tenant_bar['id'], self.role_admin['id']) - self.assertRaises(exception.Conflict, - self.identity_api.add_role_to_user_and_project, - self.user_foo['id'], - self.tenant_bar['id'], - self.role_admin['id']) - - def test_get_role_by_user_and_project(self): - roles_ref = self.identity_api.get_roles_for_user_and_project( - self.user_foo['id'], self.tenant_bar['id']) - self.assertNotIn(self.role_admin['id'], roles_ref) - self.identity_api.add_role_to_user_and_project( - self.user_foo['id'], self.tenant_bar['id'], self.role_admin['id']) - roles_ref = self.identity_api.get_roles_for_user_and_project( - self.user_foo['id'], self.tenant_bar['id']) - self.assertIn(self.role_admin['id'], roles_ref) - self.assertNotIn('member', roles_ref) - - self.identity_api.add_role_to_user_and_project( - self.user_foo['id'], self.tenant_bar['id'], 'member') - roles_ref = self.identity_api.get_roles_for_user_and_project( - self.user_foo['id'], self.tenant_bar['id']) - self.assertIn(self.role_admin['id'], roles_ref) - self.assertIn('member', roles_ref) - - def test_get_roles_for_user_and_domain(self): - """Test for getting roles for user on a domain. - - Test Plan: - - Create a domain, with 2 users - - Check no roles yet exit - - Give user1 two roles on the domain, user2 one role - - Get roles on user1 and the domain - maybe sure we only - get back the 2 roles on user1 - - Delete both roles from user1 - - Check we get no roles back for user1 on domain - - """ - new_domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(new_domain['id'], new_domain) - new_user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, 'enabled': True, - 'domain_id': new_domain['id']} - self.identity_api.create_user(new_user1['id'], new_user1) - new_user2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, 'enabled': True, - 'domain_id': new_domain['id']} - self.identity_api.create_user(new_user2['id'], new_user2) - roles_ref = self.identity_api.list_grants( - user_id=new_user1['id'], - domain_id=new_domain['id']) - self.assertEquals(len(roles_ref), 0) - # Now create the grants (roles are defined in default_fixtures) - self.identity_api.create_grant(user_id=new_user1['id'], - domain_id=new_domain['id'], - role_id='member') - self.identity_api.create_grant(user_id=new_user1['id'], - domain_id=new_domain['id'], - role_id='other') - self.identity_api.create_grant(user_id=new_user2['id'], - domain_id=new_domain['id'], - role_id='admin') - # Read back the roles for user1 on domain - roles_ids = self.identity_api.get_roles_for_user_and_domain( - new_user1['id'], new_domain['id']) - self.assertEqual(len(roles_ids), 2) - self.assertIn(self.role_member['id'], roles_ids) - self.assertIn(self.role_other['id'], roles_ids) - - # Now delete both grants for user1 - self.identity_api.delete_grant(user_id=new_user1['id'], - domain_id=new_domain['id'], - role_id='member') - self.identity_api.delete_grant(user_id=new_user1['id'], - domain_id=new_domain['id'], - role_id='other') - roles_ref = self.identity_api.list_grants( - user_id=new_user1['id'], - domain_id=new_domain['id']) - self.assertEquals(len(roles_ref), 0) - - def test_get_roles_for_user_and_domain_404(self): - """Test errors raised when getting roles for user on a domain. - - Test Plan: - - Check non-existing user gives UserNotFound - - Check non-existing domain gives DomainNotFound - - """ - new_domain = self._get_domain_fixture() - new_user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, 'enabled': True, - 'domain_id': new_domain['id']} - self.identity_api.create_user(new_user1['id'], new_user1) - - self.assertRaises(exception.UserNotFound, - self.identity_api.get_roles_for_user_and_domain, - uuid.uuid4().hex, - new_domain['id']) - - self.assertRaises(exception.DomainNotFound, - self.identity_api.get_roles_for_user_and_domain, - new_user1['id'], - uuid.uuid4().hex) - - def test_get_roles_for_user_and_project_404(self): - self.assertRaises(exception.UserNotFound, - self.identity_api.get_roles_for_user_and_project, - uuid.uuid4().hex, - self.tenant_bar['id']) - - self.assertRaises(exception.ProjectNotFound, - self.identity_api.get_roles_for_user_and_project, - self.user_foo['id'], - uuid.uuid4().hex) - - def test_add_role_to_user_and_project_404(self): - self.assertRaises(exception.UserNotFound, - self.identity_api.add_role_to_user_and_project, - uuid.uuid4().hex, - self.tenant_bar['id'], - self.role_admin['id']) - - self.assertRaises(exception.ProjectNotFound, - self.identity_api.add_role_to_user_and_project, - self.user_foo['id'], - uuid.uuid4().hex, - self.role_admin['id']) - - self.assertRaises(exception.RoleNotFound, - self.identity_api.add_role_to_user_and_project, - self.user_foo['id'], - self.tenant_bar['id'], - uuid.uuid4().hex) - - def test_remove_role_from_user_and_project(self): - self.identity_api.add_role_to_user_and_project( - self.user_foo['id'], self.tenant_bar['id'], 'member') - self.identity_api.remove_role_from_user_and_project( - self.user_foo['id'], self.tenant_bar['id'], 'member') - roles_ref = self.identity_api.get_roles_for_user_and_project( - self.user_foo['id'], self.tenant_bar['id']) - self.assertNotIn('member', roles_ref) - self.assertRaises(exception.NotFound, - self.identity_api.remove_role_from_user_and_project, - self.user_foo['id'], - self.tenant_bar['id'], - 'member') - - def test_get_role_grant_by_user_and_project(self): - roles_ref = self.identity_api.list_grants( - user_id=self.user_foo['id'], - project_id=self.tenant_bar['id']) - self.assertEquals(len(roles_ref), 1) - self.identity_api.create_grant(user_id=self.user_foo['id'], - project_id=self.tenant_bar['id'], - role_id=self.role_admin['id']) - roles_ref = self.identity_api.list_grants( - user_id=self.user_foo['id'], - project_id=self.tenant_bar['id']) - self.assertIn(self.role_admin['id'], - [role_ref['id'] for role_ref in roles_ref]) - - self.identity_api.create_grant(user_id=self.user_foo['id'], - project_id=self.tenant_bar['id'], - role_id='member') - roles_ref = self.identity_api.list_grants( - user_id=self.user_foo['id'], - project_id=self.tenant_bar['id']) - - roles_ref_ids = [] - for ref in roles_ref: - roles_ref_ids.append(ref['id']) - self.assertIn(self.role_admin['id'], roles_ref_ids) - self.assertIn('member', roles_ref_ids) - - def test_get_role_grants_for_user_and_project_404(self): - self.assertRaises(exception.UserNotFound, - self.identity_api.list_grants, - user_id=uuid.uuid4().hex, - project_id=self.tenant_bar['id']) - - self.assertRaises(exception.ProjectNotFound, - self.identity_api.list_grants, - user_id=self.user_foo['id'], - project_id=uuid.uuid4().hex) - - def test_add_role_grant_to_user_and_project_404(self): - self.assertRaises(exception.UserNotFound, - self.identity_api.create_grant, - user_id=uuid.uuid4().hex, - project_id=self.tenant_bar['id'], - role_id=self.role_admin['id']) - - self.assertRaises(exception.ProjectNotFound, - self.identity_api.create_grant, - user_id=self.user_foo['id'], - project_id=uuid.uuid4().hex, - role_id=self.role_admin['id']) - - self.assertRaises(exception.RoleNotFound, - self.identity_api.create_grant, - user_id=self.user_foo['id'], - project_id=self.tenant_bar['id'], - role_id=uuid.uuid4().hex) - - def test_remove_role_grant_from_user_and_project(self): - self.identity_api.create_grant(user_id=self.user_foo['id'], - project_id=self.tenant_baz['id'], - role_id='member') - roles_ref = self.identity_api.list_grants( - user_id=self.user_foo['id'], - project_id=self.tenant_baz['id']) - self.assertDictEqual(roles_ref[0], self.role_member) - - self.identity_api.delete_grant(user_id=self.user_foo['id'], - project_id=self.tenant_baz['id'], - role_id='member') - roles_ref = self.identity_api.list_grants( - user_id=self.user_foo['id'], - project_id=self.tenant_baz['id']) - self.assertEquals(len(roles_ref), 0) - self.assertRaises(exception.NotFound, - self.identity_api.delete_grant, - user_id=self.user_foo['id'], - project_id=self.tenant_baz['id'], - role_id='member') - - def test_get_and_remove_role_grant_by_group_and_project(self): - new_domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(new_domain['id'], new_domain) - new_group = {'id': uuid.uuid4().hex, 'domain_id': new_domain['id'], - 'name': uuid.uuid4().hex} - self.identity_api.create_group(new_group['id'], new_group) - new_user = {'id': uuid.uuid4().hex, 'name': 'new_user', - 'password': 'secret', 'enabled': True, - 'domain_id': new_domain['id']} - self.identity_api.create_user(new_user['id'], new_user) - self.identity_api.add_user_to_group(new_user['id'], - new_group['id']) - roles_ref = self.identity_api.list_grants( - group_id=new_group['id'], - project_id=self.tenant_bar['id']) - self.assertEquals(len(roles_ref), 0) - self.identity_api.create_grant(group_id=new_group['id'], - project_id=self.tenant_bar['id'], - role_id='member') - roles_ref = self.identity_api.list_grants( - group_id=new_group['id'], - project_id=self.tenant_bar['id']) - self.assertDictEqual(roles_ref[0], self.role_member) - - self.identity_api.delete_grant(group_id=new_group['id'], - project_id=self.tenant_bar['id'], - role_id='member') - roles_ref = self.identity_api.list_grants( - group_id=new_group['id'], - project_id=self.tenant_bar['id']) - self.assertEquals(len(roles_ref), 0) - self.assertRaises(exception.NotFound, - self.identity_api.delete_grant, - group_id=new_group['id'], - project_id=self.tenant_bar['id'], - role_id='member') - - def test_get_and_remove_role_grant_by_group_and_domain(self): - new_domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(new_domain['id'], new_domain) - new_group = {'id': uuid.uuid4().hex, 'domain_id': new_domain['id'], - 'name': uuid.uuid4().hex} - self.identity_api.create_group(new_group['id'], new_group) - new_user = {'id': uuid.uuid4().hex, 'name': 'new_user', - 'password': uuid.uuid4().hex, 'enabled': True, - 'domain_id': new_domain['id']} - self.identity_api.create_user(new_user['id'], new_user) - self.identity_api.add_user_to_group(new_user['id'], - new_group['id']) - - roles_ref = self.identity_api.list_grants( - group_id=new_group['id'], - domain_id=new_domain['id']) - self.assertEquals(len(roles_ref), 0) - - self.identity_api.create_grant(group_id=new_group['id'], - domain_id=new_domain['id'], - role_id='member') - - roles_ref = self.identity_api.list_grants( - group_id=new_group['id'], - domain_id=new_domain['id']) - self.assertDictEqual(roles_ref[0], self.role_member) - - self.identity_api.delete_grant(group_id=new_group['id'], - domain_id=new_domain['id'], - role_id='member') - roles_ref = self.identity_api.list_grants( - group_id=new_group['id'], - domain_id=new_domain['id']) - self.assertEquals(len(roles_ref), 0) - self.assertRaises(exception.NotFound, - self.identity_api.delete_grant, - group_id=new_group['id'], - domain_id=new_domain['id'], - role_id='member') - - def test_get_and_remove_correct_role_grant_from_a_mix(self): - new_domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(new_domain['id'], new_domain) - new_project = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': new_domain['id']} - self.identity_api.create_project(new_project['id'], new_project) - new_group = {'id': uuid.uuid4().hex, 'domain_id': new_domain['id'], - 'name': uuid.uuid4().hex} - self.identity_api.create_group(new_group['id'], new_group) - new_group2 = {'id': uuid.uuid4().hex, 'domain_id': new_domain['id'], - 'name': uuid.uuid4().hex} - self.identity_api.create_group(new_group2['id'], new_group2) - new_user = {'id': uuid.uuid4().hex, 'name': 'new_user', - 'password': uuid.uuid4().hex, 'enabled': True, - 'domain_id': new_domain['id']} - self.identity_api.create_user(new_user['id'], new_user) - new_user2 = {'id': uuid.uuid4().hex, 'name': 'new_user2', - 'password': uuid.uuid4().hex, 'enabled': True, - 'domain_id': new_domain['id']} - self.identity_api.create_user(new_user2['id'], new_user2) - self.identity_api.add_user_to_group(new_user['id'], - new_group['id']) - # First check we have no grants - roles_ref = self.identity_api.list_grants( - group_id=new_group['id'], - domain_id=new_domain['id']) - self.assertEquals(len(roles_ref), 0) - # Now add the grant we are going to test for, and some others as - # well just to make sure we get back the right one - self.identity_api.create_grant(group_id=new_group['id'], - domain_id=new_domain['id'], - role_id='member') - - self.identity_api.create_grant(group_id=new_group2['id'], - domain_id=new_domain['id'], - role_id=self.role_admin['id']) - self.identity_api.create_grant(user_id=new_user2['id'], - domain_id=new_domain['id'], - role_id=self.role_admin['id']) - self.identity_api.create_grant(group_id=new_group['id'], - project_id=new_project['id'], - role_id=self.role_admin['id']) - - roles_ref = self.identity_api.list_grants( - group_id=new_group['id'], - domain_id=new_domain['id']) - self.assertDictEqual(roles_ref[0], self.role_member) - - self.identity_api.delete_grant(group_id=new_group['id'], - domain_id=new_domain['id'], - role_id='member') - roles_ref = self.identity_api.list_grants( - group_id=new_group['id'], - domain_id=new_domain['id']) - self.assertEquals(len(roles_ref), 0) - self.assertRaises(exception.NotFound, - self.identity_api.delete_grant, - group_id=new_group['id'], - domain_id=new_domain['id'], - role_id='member') - - def test_get_and_remove_role_grant_by_user_and_domain(self): - new_domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(new_domain['id'], new_domain) - new_user = {'id': uuid.uuid4().hex, 'name': 'new_user', - 'password': 'secret', 'enabled': True, - 'domain_id': new_domain['id']} - self.identity_api.create_user(new_user['id'], new_user) - roles_ref = self.identity_api.list_grants( - user_id=new_user['id'], - domain_id=new_domain['id']) - self.assertEquals(len(roles_ref), 0) - self.identity_api.create_grant(user_id=new_user['id'], - domain_id=new_domain['id'], - role_id='member') - roles_ref = self.identity_api.list_grants( - user_id=new_user['id'], - domain_id=new_domain['id']) - self.assertDictEqual(roles_ref[0], self.role_member) - - self.identity_api.delete_grant(user_id=new_user['id'], - domain_id=new_domain['id'], - role_id='member') - roles_ref = self.identity_api.list_grants( - user_id=new_user['id'], - domain_id=new_domain['id']) - self.assertEquals(len(roles_ref), 0) - self.assertRaises(exception.NotFound, - self.identity_api.delete_grant, - user_id=new_user['id'], - domain_id=new_domain['id'], - role_id='member') - - def test_get_and_remove_role_grant_by_group_and_cross_domain(self): - group1_domain1_role = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex} - self.identity_api.create_role(group1_domain1_role['id'], - group1_domain1_role) - group1_domain2_role = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex} - self.identity_api.create_role(group1_domain2_role['id'], - group1_domain2_role) - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - domain2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain2['id'], domain2) - group1 = {'id': uuid.uuid4().hex, 'domain_id': domain1['id'], - 'name': uuid.uuid4().hex} - self.identity_api.create_group(group1['id'], group1) - roles_ref = self.identity_api.list_grants( - group_id=group1['id'], - domain_id=domain1['id']) - self.assertEquals(len(roles_ref), 0) - roles_ref = self.identity_api.list_grants( - group_id=group1['id'], - domain_id=domain2['id']) - self.assertEquals(len(roles_ref), 0) - self.identity_api.create_grant(group_id=group1['id'], - domain_id=domain1['id'], - role_id=group1_domain1_role['id']) - self.identity_api.create_grant(group_id=group1['id'], - domain_id=domain2['id'], - role_id=group1_domain2_role['id']) - roles_ref = self.identity_api.list_grants( - group_id=group1['id'], - domain_id=domain1['id']) - self.assertDictEqual(roles_ref[0], group1_domain1_role) - roles_ref = self.identity_api.list_grants( - group_id=group1['id'], - domain_id=domain2['id']) - self.assertDictEqual(roles_ref[0], group1_domain2_role) - - self.identity_api.delete_grant(group_id=group1['id'], - domain_id=domain2['id'], - role_id=group1_domain2_role['id']) - roles_ref = self.identity_api.list_grants( - group_id=group1['id'], - domain_id=domain2['id']) - self.assertEquals(len(roles_ref), 0) - self.assertRaises(exception.NotFound, - self.identity_api.delete_grant, - group_id=group1['id'], - domain_id=domain2['id'], - role_id=group1_domain2_role['id']) - - def test_get_and_remove_role_grant_by_user_and_cross_domain(self): - user1_domain1_role = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex} - self.identity_api.create_role(user1_domain1_role['id'], - user1_domain1_role) - user1_domain2_role = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex} - self.identity_api.create_role(user1_domain2_role['id'], - user1_domain2_role) - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - domain2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain2['id'], domain2) - user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'password': uuid.uuid4().hex, - 'enabled': True} - self.identity_api.create_user(user1['id'], user1) - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - domain_id=domain1['id']) - self.assertEquals(len(roles_ref), 0) - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - domain_id=domain2['id']) - self.assertEquals(len(roles_ref), 0) - self.identity_api.create_grant(user_id=user1['id'], - domain_id=domain1['id'], - role_id=user1_domain1_role['id']) - self.identity_api.create_grant(user_id=user1['id'], - domain_id=domain2['id'], - role_id=user1_domain2_role['id']) - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - domain_id=domain1['id']) - self.assertDictEqual(roles_ref[0], user1_domain1_role) - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - domain_id=domain2['id']) - self.assertDictEqual(roles_ref[0], user1_domain2_role) - - self.identity_api.delete_grant(user_id=user1['id'], - domain_id=domain2['id'], - role_id=user1_domain2_role['id']) - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - domain_id=domain2['id']) - self.assertEquals(len(roles_ref), 0) - self.assertRaises(exception.NotFound, - self.identity_api.delete_grant, - user_id=user1['id'], - domain_id=domain2['id'], - role_id=user1_domain2_role['id']) - - def test_role_grant_by_group_and_cross_domain_project(self): - role1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_role(role1['id'], role1) - role2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_role(role2['id'], role2) - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - domain2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain2['id'], domain2) - group1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'enabled': True} - self.identity_api.create_group(group1['id'], group1) - project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain2['id']} - self.identity_api.create_project(project1['id'], project1) - roles_ref = self.identity_api.list_grants( - group_id=group1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 0) - self.identity_api.create_grant(group_id=group1['id'], - project_id=project1['id'], - role_id=role1['id']) - self.identity_api.create_grant(group_id=group1['id'], - project_id=project1['id'], - role_id=role2['id']) - roles_ref = self.identity_api.list_grants( - group_id=group1['id'], - project_id=project1['id']) - - roles_ref_ids = [] - for i, ref in enumerate(roles_ref): - roles_ref_ids.append(ref['id']) - self.assertIn(role1['id'], roles_ref_ids) - self.assertIn(role2['id'], roles_ref_ids) - - self.identity_api.delete_grant(group_id=group1['id'], - project_id=project1['id'], - role_id=role1['id']) - roles_ref = self.identity_api.list_grants( - group_id=group1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 1) - self.assertDictEqual(roles_ref[0], role2) - - def test_role_grant_by_user_and_cross_domain_project(self): - role1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_role(role1['id'], role1) - role2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_role(role2['id'], role2) - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - domain2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain2['id'], domain2) - user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'password': uuid.uuid4().hex, - 'enabled': True} - self.identity_api.create_user(user1['id'], user1) - project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain2['id']} - self.identity_api.create_project(project1['id'], project1) - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 0) - self.identity_api.create_grant(user_id=user1['id'], - project_id=project1['id'], - role_id=role1['id']) - self.identity_api.create_grant(user_id=user1['id'], - project_id=project1['id'], - role_id=role2['id']) - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - project_id=project1['id']) - - roles_ref_ids = [] - for ref in roles_ref: - roles_ref_ids.append(ref['id']) - self.assertIn(role1['id'], roles_ref_ids) - self.assertIn(role2['id'], roles_ref_ids) - - self.identity_api.delete_grant(user_id=user1['id'], - project_id=project1['id'], - role_id=role1['id']) - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 1) - self.assertDictEqual(roles_ref[0], role2) - - def test_multi_role_grant_by_user_group_on_project_domain(self): - role_list = [] - for _ in range(10): - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_role(role['id'], role) - role_list.append(role) - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'password': uuid.uuid4().hex, - 'enabled': True} - self.identity_api.create_user(user1['id'], user1) - group1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'enabled': True} - self.identity_api.create_group(group1['id'], group1) - group2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'enabled': True} - self.identity_api.create_group(group2['id'], group2) - project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id']} - self.identity_api.create_project(project1['id'], project1) - - self.identity_api.add_user_to_group(user1['id'], - group1['id']) - self.identity_api.add_user_to_group(user1['id'], - group2['id']) - - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 0) - self.identity_api.create_grant(user_id=user1['id'], - domain_id=domain1['id'], - role_id=role_list[0]['id']) - self.identity_api.create_grant(user_id=user1['id'], - domain_id=domain1['id'], - role_id=role_list[1]['id']) - self.identity_api.create_grant(group_id=group1['id'], - domain_id=domain1['id'], - role_id=role_list[2]['id']) - self.identity_api.create_grant(group_id=group1['id'], - domain_id=domain1['id'], - role_id=role_list[3]['id']) - self.identity_api.create_grant(user_id=user1['id'], - project_id=project1['id'], - role_id=role_list[4]['id']) - self.identity_api.create_grant(user_id=user1['id'], - project_id=project1['id'], - role_id=role_list[5]['id']) - self.identity_api.create_grant(group_id=group1['id'], - project_id=project1['id'], - role_id=role_list[6]['id']) - self.identity_api.create_grant(group_id=group1['id'], - project_id=project1['id'], - role_id=role_list[7]['id']) - roles_ref = self.identity_api.list_grants(user_id=user1['id'], - domain_id=domain1['id']) - self.assertEquals(len(roles_ref), 2) - self.assertIn(role_list[0], roles_ref) - self.assertIn(role_list[1], roles_ref) - roles_ref = self.identity_api.list_grants(group_id=group1['id'], - domain_id=domain1['id']) - self.assertEquals(len(roles_ref), 2) - self.assertIn(role_list[2], roles_ref) - self.assertIn(role_list[3], roles_ref) - roles_ref = self.identity_api.list_grants(user_id=user1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 2) - self.assertIn(role_list[4], roles_ref) - self.assertIn(role_list[5], roles_ref) - roles_ref = self.identity_api.list_grants(group_id=group1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 2) - self.assertIn(role_list[6], roles_ref) - self.assertIn(role_list[7], roles_ref) - - # Now test the alternate way of getting back lists of grants, - # where user and group roles are combined. These should match - # the above results. - combined_role_list = self.identity_api.get_roles_for_user_and_project( - user1['id'], project1['id']) - self.assertEquals(len(combined_role_list), 4) - self.assertIn(role_list[4]['id'], combined_role_list) - self.assertIn(role_list[5]['id'], combined_role_list) - self.assertIn(role_list[6]['id'], combined_role_list) - self.assertIn(role_list[7]['id'], combined_role_list) - - combined_role_list = self.identity_api.get_roles_for_user_and_domain( - user1['id'], domain1['id']) - self.assertEquals(len(combined_role_list), 4) - self.assertIn(role_list[0]['id'], combined_role_list) - self.assertIn(role_list[1]['id'], combined_role_list) - self.assertIn(role_list[2]['id'], combined_role_list) - self.assertIn(role_list[3]['id'], combined_role_list) - - def test_multi_group_grants_on_project_domain(self): - """Test multiple group roles for user on project and domain. - - Test Plan: - - Create 6 roles - - Create a domain, with a project, user and two groups - - Make the user a member of both groups - - Check no roles yet exit - - Assign a role to each user and both groups on both the - project and domain - - Get a list of effective roles for the user on both the - project and domain, checking we get back the correct three - roles - - """ - role_list = [] - for _ in range(6): - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_role(role['id'], role) - role_list.append(role) - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'password': uuid.uuid4().hex, - 'enabled': True} - self.identity_api.create_user(user1['id'], user1) - group1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'enabled': True} - self.identity_api.create_group(group1['id'], group1) - group2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'enabled': True} - self.identity_api.create_group(group2['id'], group2) - project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id']} - self.identity_api.create_project(project1['id'], project1) - - self.identity_api.add_user_to_group(user1['id'], - group1['id']) - self.identity_api.add_user_to_group(user1['id'], - group2['id']) - - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 0) - self.identity_api.create_grant(user_id=user1['id'], - domain_id=domain1['id'], - role_id=role_list[0]['id']) - self.identity_api.create_grant(group_id=group1['id'], - domain_id=domain1['id'], - role_id=role_list[1]['id']) - self.identity_api.create_grant(group_id=group2['id'], - domain_id=domain1['id'], - role_id=role_list[2]['id']) - self.identity_api.create_grant(user_id=user1['id'], - project_id=project1['id'], - role_id=role_list[3]['id']) - self.identity_api.create_grant(group_id=group1['id'], - project_id=project1['id'], - role_id=role_list[4]['id']) - self.identity_api.create_grant(group_id=group2['id'], - project_id=project1['id'], - role_id=role_list[5]['id']) - - # Read by the roles, ensuring we get the correct 3 roles for - # both project and domain - combined_role_list = self.identity_api.get_roles_for_user_and_project( - user1['id'], project1['id']) - self.assertEquals(len(combined_role_list), 3) - self.assertIn(role_list[3]['id'], combined_role_list) - self.assertIn(role_list[4]['id'], combined_role_list) - self.assertIn(role_list[5]['id'], combined_role_list) - - combined_role_list = self.identity_api.get_roles_for_user_and_domain( - user1['id'], domain1['id']) - self.assertEquals(len(combined_role_list), 3) - self.assertIn(role_list[0]['id'], combined_role_list) - self.assertIn(role_list[1]['id'], combined_role_list) - self.assertIn(role_list[2]['id'], combined_role_list) - - def test_delete_role_with_user_and_group_grants(self): - role1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_role(role1['id'], role1) - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id']} - self.identity_api.create_project(project1['id'], project1) - user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'password': uuid.uuid4().hex, - 'enabled': True} - self.identity_api.create_user(user1['id'], user1) - group1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'enabled': True} - self.identity_api.create_group(group1['id'], group1) - self.identity_api.create_grant(user_id=user1['id'], - project_id=project1['id'], - role_id=role1['id']) - self.identity_api.create_grant(user_id=user1['id'], - domain_id=domain1['id'], - role_id=role1['id']) - self.identity_api.create_grant(group_id=group1['id'], - project_id=project1['id'], - role_id=role1['id']) - self.identity_api.create_grant(group_id=group1['id'], - domain_id=domain1['id'], - role_id=role1['id']) - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 1) - roles_ref = self.identity_api.list_grants( - group_id=group1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 1) - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - domain_id=domain1['id']) - self.assertEquals(len(roles_ref), 1) - roles_ref = self.identity_api.list_grants( - group_id=group1['id'], - domain_id=domain1['id']) - self.assertEquals(len(roles_ref), 1) - self.identity_api.delete_role(role1['id']) - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 0) - roles_ref = self.identity_api.list_grants( - group_id=group1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 0) - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - domain_id=domain1['id']) - self.assertEquals(len(roles_ref), 0) - roles_ref = self.identity_api.list_grants( - group_id=group1['id'], - domain_id=domain1['id']) - self.assertEquals(len(roles_ref), 0) - - def test_delete_user_with_group_project_domain_links(self): - role1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_role(role1['id'], role1) - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id']} - self.identity_api.create_project(project1['id'], project1) - user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'password': uuid.uuid4().hex, - 'enabled': True} - self.identity_api.create_user(user1['id'], user1) - group1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'enabled': True} - self.identity_api.create_group(group1['id'], group1) - self.identity_api.create_grant(user_id=user1['id'], - project_id=project1['id'], - role_id=role1['id']) - self.identity_api.create_grant(user_id=user1['id'], - domain_id=domain1['id'], - role_id=role1['id']) - self.identity_api.add_user_to_group(user_id=user1['id'], - group_id=group1['id']) - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 1) - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - domain_id=domain1['id']) - self.assertEquals(len(roles_ref), 1) - self.identity_api.check_user_in_group( - user_id=user1['id'], - group_id=group1['id']) - self.identity_api.delete_user(user1['id']) - self.assertRaises(exception.UserNotFound, - self.identity_api.list_grants, - user_id=user1['id'], - project_id=project1['id']) - self.assertRaises(exception.UserNotFound, - self.identity_api.list_grants, - user_id=user1['id'], - domain_id=domain1['id']) - self.assertRaises(exception.NotFound, - self.identity_api.check_user_in_group, - user1['id'], - group1['id']) - - def test_delete_group_with_user_project_domain_links(self): - role1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_role(role1['id'], role1) - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id']} - self.identity_api.create_project(project1['id'], project1) - user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'password': uuid.uuid4().hex, - 'enabled': True} - self.identity_api.create_user(user1['id'], user1) - group1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'enabled': True} - self.identity_api.create_group(group1['id'], group1) - self.identity_api.create_grant(group_id=group1['id'], - project_id=project1['id'], - role_id=role1['id']) - self.identity_api.create_grant(group_id=group1['id'], - domain_id=domain1['id'], - role_id=role1['id']) - self.identity_api.add_user_to_group(user_id=user1['id'], - group_id=group1['id']) - roles_ref = self.identity_api.list_grants( - group_id=group1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 1) - roles_ref = self.identity_api.list_grants( - group_id=group1['id'], - domain_id=domain1['id']) - self.assertEquals(len(roles_ref), 1) - self.identity_api.check_user_in_group( - user_id=user1['id'], - group_id=group1['id']) - self.identity_api.delete_group(group1['id']) - self.assertRaises(exception.GroupNotFound, - self.identity_api.list_grants, - group_id=group1['id'], - project_id=project1['id']) - self.assertRaises(exception.GroupNotFound, - self.identity_api.list_grants, - group_id=group1['id'], - domain_id=domain1['id']) - self.identity_api.get_user(user1['id']) - - def test_delete_domain_with_user_group_project_links(self): - #TODO(chungg):add test case once expected behaviour defined - pass - - def test_role_crud(self): - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_role(role['id'], role) - role_ref = self.identity_api.get_role(role['id']) - role_ref_dict = dict((x, role_ref[x]) for x in role_ref) - self.assertDictEqual(role_ref_dict, role) - - role['name'] = uuid.uuid4().hex - self.identity_api.update_role(role['id'], role) - role_ref = self.identity_api.get_role(role['id']) - role_ref_dict = dict((x, role_ref[x]) for x in role_ref) - self.assertDictEqual(role_ref_dict, role) - - self.identity_api.delete_role(role['id']) - self.assertRaises(exception.RoleNotFound, - self.identity_api.get_role, - role['id']) - - def test_update_role_404(self): - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.assertRaises(exception.RoleNotFound, - self.identity_api.update_role, - role['id'], - role) - - def test_add_user_to_project(self): - self.identity_api.add_user_to_project(self.tenant_baz['id'], - self.user_foo['id']) - tenants = self.identity_api.get_projects_for_user(self.user_foo['id']) - self.assertIn(self.tenant_baz['id'], tenants) - - def test_add_user_to_project_missing_default_role(self): - self.assignment_api.delete_role(CONF.member_role_id) - self.assertRaises(exception.RoleNotFound, - self.assignment_api.get_role, - CONF.member_role_id) - self.identity_api.add_user_to_project(self.tenant_baz['id'], - self.user_foo['id']) - tenants = self.identity_api.get_projects_for_user(self.user_foo['id']) - self.assertIn(self.tenant_baz['id'], tenants) - default_role = self.assignment_api.get_role(CONF.member_role_id) - self.assertIsNotNone(default_role) - - def test_add_user_to_project_404(self): - self.assertRaises(exception.ProjectNotFound, - self.identity_api.add_user_to_project, - uuid.uuid4().hex, - self.user_foo['id']) - - self.assertRaises(exception.UserNotFound, - self.identity_api.add_user_to_project, - self.tenant_bar['id'], - uuid.uuid4().hex) - - def test_remove_user_from_project(self): - self.identity_api.add_user_to_project(self.tenant_baz['id'], - self.user_foo['id']) - self.identity_api.remove_user_from_project(self.tenant_baz['id'], - self.user_foo['id']) - tenants = self.identity_api.get_projects_for_user(self.user_foo['id']) - self.assertNotIn(self.tenant_baz['id'], tenants) - - def test_remove_user_from_project_404(self): - self.assertRaises(exception.ProjectNotFound, - self.identity_api.remove_user_from_project, - uuid.uuid4().hex, - self.user_foo['id']) - - self.assertRaises(exception.UserNotFound, - self.identity_api.remove_user_from_project, - self.tenant_bar['id'], - uuid.uuid4().hex) - - self.assertRaises(exception.NotFound, - self.identity_api.remove_user_from_project, - self.tenant_baz['id'], - self.user_foo['id']) - - def test_get_projects_for_user_404(self): - self.assertRaises(exception.UserNotFound, - self.identity_api.get_projects_for_user, - uuid.uuid4().hex) - - def test_update_project_404(self): - self.assertRaises(exception.ProjectNotFound, - self.identity_api.update_project, - uuid.uuid4().hex, - dict()) - - def test_delete_project_404(self): - self.assertRaises(exception.ProjectNotFound, - self.identity_api.delete_project, - uuid.uuid4().hex) - - def test_update_user_404(self): - user_id = uuid.uuid4().hex - self.assertRaises(exception.UserNotFound, - self.identity_api.update_user, - user_id, - {'id': user_id}) - - def test_delete_user_with_project_association(self): - user = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': uuid.uuid4().hex} - self.identity_api.create_user(user['id'], user) - self.identity_api.add_user_to_project(self.tenant_bar['id'], - user['id']) - self.identity_api.delete_user(user['id']) - self.assertRaises(exception.UserNotFound, - self.identity_api.get_projects_for_user, - user['id']) - - def test_delete_user_with_project_roles(self): - user = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': uuid.uuid4().hex} - self.identity_api.create_user(user['id'], user) - self.identity_api.add_role_to_user_and_project( - user['id'], - self.tenant_bar['id'], - self.role_member['id']) - self.identity_api.delete_user(user['id']) - self.assertRaises(exception.UserNotFound, - self.identity_api.get_projects_for_user, - user['id']) - - def test_delete_user_404(self): - self.assertRaises(exception.UserNotFound, - self.identity_api.delete_user, - uuid.uuid4().hex) - - def test_delete_role_404(self): - self.assertRaises(exception.RoleNotFound, - self.identity_api.delete_role, - uuid.uuid4().hex) - - def test_create_project_long_name_fails(self): - tenant = {'id': 'fake1', 'name': 'a' * 65, - 'domain_id': DEFAULT_DOMAIN_ID} - self.assertRaises(exception.ValidationError, - self.identity_api.create_project, - tenant['id'], - tenant) - - def test_create_project_blank_name_fails(self): - tenant = {'id': 'fake1', 'name': '', - 'domain_id': DEFAULT_DOMAIN_ID} - self.assertRaises(exception.ValidationError, - self.identity_api.create_project, - tenant['id'], - tenant) - - def test_create_project_invalid_name_fails(self): - tenant = {'id': 'fake1', 'name': None, - 'domain_id': DEFAULT_DOMAIN_ID} - self.assertRaises(exception.ValidationError, - self.identity_api.create_project, - tenant['id'], - tenant) - tenant = {'id': 'fake1', 'name': 123, - 'domain_id': DEFAULT_DOMAIN_ID} - self.assertRaises(exception.ValidationError, - self.identity_api.create_project, - tenant['id'], - tenant) - - def test_update_project_blank_name_fails(self): - tenant = {'id': 'fake1', 'name': 'fake1', - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_project('fake1', tenant) - tenant['name'] = '' - self.assertRaises(exception.ValidationError, - self.identity_api.update_project, - tenant['id'], - tenant) - - def test_update_project_long_name_fails(self): - tenant = {'id': 'fake1', 'name': 'fake1', - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_project('fake1', tenant) - tenant['name'] = 'a' * 65 - self.assertRaises(exception.ValidationError, - self.identity_api.update_project, - tenant['id'], - tenant) - - def test_update_project_invalid_name_fails(self): - tenant = {'id': 'fake1', 'name': 'fake1', - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_project('fake1', tenant) - tenant['name'] = None - self.assertRaises(exception.ValidationError, - self.identity_api.update_project, - tenant['id'], - tenant) - - tenant['name'] = 123 - self.assertRaises(exception.ValidationError, - self.identity_api.update_project, - tenant['id'], - tenant) - - def test_create_user_long_name_fails(self): - user = {'id': 'fake1', 'name': 'a' * 65, - 'domain_id': DEFAULT_DOMAIN_ID} - self.assertRaises(exception.ValidationError, - self.identity_api.create_user, - 'fake1', - user) - - def test_create_user_blank_name_fails(self): - user = {'id': 'fake1', 'name': '', - 'domain_id': DEFAULT_DOMAIN_ID} - self.assertRaises(exception.ValidationError, - self.identity_api.create_user, - 'fake1', - user) - - def test_create_user_invalid_name_fails(self): - user = {'id': 'fake1', 'name': None, - 'domain_id': DEFAULT_DOMAIN_ID} - self.assertRaises(exception.ValidationError, - self.identity_api.create_user, - 'fake1', - user) - - user = {'id': 'fake1', 'name': 123, - 'domain_id': DEFAULT_DOMAIN_ID} - self.assertRaises(exception.ValidationError, - self.identity_api.create_user, - 'fake1', - user) - - def test_update_project_invalid_enabled_type_string(self): - project = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'enabled': True, - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_project(project['id'], project) - project_ref = self.identity_api.get_project(project['id']) - self.assertEqual(project_ref['enabled'], True) - - # Strings are not valid boolean values - project['enabled'] = "false" - self.assertRaises(exception.ValidationError, - self.identity_api.update_project, - project['id'], - project) - - def test_create_project_invalid_enabled_type_string(self): - project = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': DEFAULT_DOMAIN_ID, - # invalid string value - 'enabled': "true"} - self.assertRaises(exception.ValidationError, - self.identity_api.create_project, - project['id'], - project) - - def test_create_user_invalid_enabled_type_string(self): - user = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': uuid.uuid4().hex, - # invalid string value - 'enabled': "true"} - self.assertRaises(exception.ValidationError, - self.identity_api.create_user, - user['id'], - user) - - def test_update_user_long_name_fails(self): - user = {'id': 'fake1', 'name': 'fake1', - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_user('fake1', user) - user['name'] = 'a' * 65 - self.assertRaises(exception.ValidationError, - self.identity_api.update_user, - 'fake1', - user) - - def test_update_user_blank_name_fails(self): - user = {'id': 'fake1', 'name': 'fake1', - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_user('fake1', user) - user['name'] = '' - self.assertRaises(exception.ValidationError, - self.identity_api.update_user, - 'fake1', - user) - - def test_update_user_invalid_name_fails(self): - user = {'id': 'fake1', 'name': 'fake1', - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_user('fake1', user) - - user['name'] = None - self.assertRaises(exception.ValidationError, - self.identity_api.update_user, - 'fake1', - user) - - user['name'] = 123 - self.assertRaises(exception.ValidationError, - self.identity_api.update_user, - 'fake1', - user) - - def test_list_users(self): - users = self.identity_api.list_users() - for test_user in default_fixtures.USERS: - self.assertTrue(x for x in users if x['id'] == test_user['id']) - - def test_list_groups(self): - group1 = { - 'id': uuid.uuid4().hex, - 'domain_id': CONF.identity.default_domain_id, - 'name': uuid.uuid4().hex} - group2 = { - 'id': uuid.uuid4().hex, - 'domain_id': CONF.identity.default_domain_id, - 'name': uuid.uuid4().hex} - self.identity_api.create_group(group1['id'], group1) - self.identity_api.create_group(group2['id'], group2) - groups = self.identity_api.list_groups() - self.assertEquals(len(groups), 2) - group_ids = [] - for group in groups: - group_ids.append(group.get('id')) - self.assertIn(group1['id'], group_ids) - self.assertIn(group2['id'], group_ids) - - def test_list_domains(self): - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - domain2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - self.identity_api.create_domain(domain2['id'], domain2) - domains = self.identity_api.list_domains() - self.assertEquals(len(domains), 3) - domain_ids = [] - for domain in domains: - domain_ids.append(domain.get('id')) - self.assertIn(DEFAULT_DOMAIN_ID, domain_ids) - self.assertIn(domain1['id'], domain_ids) - self.assertIn(domain2['id'], domain_ids) - - def test_list_projects(self): - projects = self.identity_api.list_projects() - self.assertEquals(len(projects), 4) - project_ids = [] - for project in projects: - project_ids.append(project.get('id')) - self.assertIn(self.tenant_bar['id'], project_ids) - self.assertIn(self.tenant_baz['id'], project_ids) - - def test_list_projects_for_domain(self): - project_ids = ([x['id'] for x in - self.assignment_api.list_projects(DEFAULT_DOMAIN_ID)]) - self.assertEquals(len(project_ids), 4) - self.assertIn(self.tenant_bar['id'], project_ids) - self.assertIn(self.tenant_baz['id'], project_ids) - self.assertIn(self.tenant_mtu['id'], project_ids) - self.assertIn(self.tenant_service['id'], project_ids) - - def test_list_projects_for_alternate_domain(self): - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.assignment_api.create_domain(domain1['id'], domain1) - project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id']} - self.assignment_api.create_project(project1['id'], project1) - project2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id']} - self.assignment_api.create_project(project2['id'], project2) - project_ids = ([x['id'] for x in - self.assignment_api.list_projects(domain1['id'])]) - self.assertEquals(len(project_ids), 2) - self.assertIn(project1['id'], project_ids) - self.assertIn(project2['id'], project_ids) - - def test_list_roles(self): - roles = self.identity_api.list_roles() - for test_role in default_fixtures.ROLES: - self.assertTrue(x for x in roles if x['id'] == test_role['id']) - - def test_delete_project_with_role_assignments(self): - tenant = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_project(tenant['id'], tenant) - self.identity_api.add_role_to_user_and_project( - self.user_foo['id'], tenant['id'], 'member') - self.identity_api.delete_project(tenant['id']) - self.assertRaises(exception.NotFound, - self.identity_api.get_project, - tenant['id']) - - def test_delete_role_check_role_grant(self): - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - alt_role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_role(role['id'], role) - self.identity_api.create_role(alt_role['id'], alt_role) - self.identity_api.add_role_to_user_and_project( - self.user_foo['id'], self.tenant_bar['id'], role['id']) - self.identity_api.add_role_to_user_and_project( - self.user_foo['id'], self.tenant_bar['id'], alt_role['id']) - self.identity_api.delete_role(role['id']) - roles_ref = self.identity_api.get_roles_for_user_and_project( - self.user_foo['id'], self.tenant_bar['id']) - self.assertNotIn(role['id'], roles_ref) - self.assertIn(alt_role['id'], roles_ref) - - def test_create_project_doesnt_modify_passed_in_dict(self): - new_project = {'id': 'tenant_id', 'name': uuid.uuid4().hex, - 'domain_id': DEFAULT_DOMAIN_ID} - original_project = new_project.copy() - self.identity_api.create_project('tenant_id', new_project) - self.assertDictEqual(original_project, new_project) - - def test_create_user_doesnt_modify_passed_in_dict(self): - new_user = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, - 'domain_id': DEFAULT_DOMAIN_ID} - original_user = new_user.copy() - self.identity_api.create_user('user_id', new_user) - self.assertDictEqual(original_user, new_user) - - def test_update_user_enable(self): - user = {'id': 'fake1', 'name': 'fake1', 'enabled': True, - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_user('fake1', user) - user_ref = self.identity_api.get_user('fake1') - self.assertEqual(user_ref['enabled'], True) - - user['enabled'] = False - self.identity_api.update_user('fake1', user) - user_ref = self.identity_api.get_user('fake1') - self.assertEqual(user_ref['enabled'], user['enabled']) - - # If not present, enabled field should not be updated - del user['enabled'] - self.identity_api.update_user('fake1', user) - user_ref = self.identity_api.get_user('fake1') - self.assertEqual(user_ref['enabled'], False) - - user['enabled'] = True - self.identity_api.update_user('fake1', user) - user_ref = self.identity_api.get_user('fake1') - self.assertEqual(user_ref['enabled'], user['enabled']) - - del user['enabled'] - self.identity_api.update_user('fake1', user) - user_ref = self.identity_api.get_user('fake1') - self.assertEqual(user_ref['enabled'], True) - - # Integers are valid Python's booleans. Explicitly test it. - user['enabled'] = 0 - self.identity_api.update_user('fake1', user) - user_ref = self.identity_api.get_user('fake1') - self.assertEqual(user_ref['enabled'], False) - - # Any integers other than 0 are interpreted as True - user['enabled'] = -42 - self.identity_api.update_user('fake1', user) - user_ref = self.identity_api.get_user('fake1') - self.assertEqual(user_ref['enabled'], True) - - def test_update_user_enable_fails(self): - user = {'id': 'fake1', 'name': 'fake1', 'enabled': True, - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_user('fake1', user) - user_ref = self.identity_api.get_user('fake1') - self.assertEqual(user_ref['enabled'], True) - - # Strings are not valid boolean values - user['enabled'] = "false" - self.assertRaises(exception.ValidationError, - self.identity_api.update_user, - 'fake1', - user) - - def test_update_project_enable(self): - tenant = {'id': 'fake1', 'name': 'fake1', 'enabled': True, - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_project('fake1', tenant) - tenant_ref = self.identity_api.get_project('fake1') - self.assertEqual(tenant_ref['enabled'], True) - - tenant['enabled'] = False - self.identity_api.update_project('fake1', tenant) - tenant_ref = self.identity_api.get_project('fake1') - self.assertEqual(tenant_ref['enabled'], tenant['enabled']) - - # If not present, enabled field should not be updated - del tenant['enabled'] - self.identity_api.update_project('fake1', tenant) - tenant_ref = self.identity_api.get_project('fake1') - self.assertEqual(tenant_ref['enabled'], False) - - tenant['enabled'] = True - self.identity_api.update_project('fake1', tenant) - tenant_ref = self.identity_api.get_project('fake1') - self.assertEqual(tenant_ref['enabled'], tenant['enabled']) - - del tenant['enabled'] - self.identity_api.update_project('fake1', tenant) - tenant_ref = self.identity_api.get_project('fake1') - self.assertEqual(tenant_ref['enabled'], True) - - def test_add_user_to_group(self): - domain = self._get_domain_fixture() - new_group = {'id': uuid.uuid4().hex, 'domain_id': domain['id'], - 'name': uuid.uuid4().hex} - self.identity_api.create_group(new_group['id'], new_group) - new_user = {'id': uuid.uuid4().hex, 'name': 'new_user', - 'password': uuid.uuid4().hex, 'enabled': True, - 'domain_id': domain['id']} - self.identity_api.create_user(new_user['id'], new_user) - self.identity_api.add_user_to_group(new_user['id'], - new_group['id']) - groups = self.identity_api.list_groups_for_user(new_user['id']) - - found = False - for x in groups: - if (x['id'] == new_group['id']): - found = True - self.assertTrue(found) - - def test_add_user_to_group_404(self): - domain = self._get_domain_fixture() - new_user = {'id': uuid.uuid4().hex, 'name': 'new_user', - 'password': uuid.uuid4().hex, 'enabled': True, - 'domain_id': domain['id']} - self.identity_api.create_user(new_user['id'], new_user) - self.assertRaises(exception.GroupNotFound, - self.identity_api.add_user_to_group, - new_user['id'], - uuid.uuid4().hex) - - new_group = {'id': uuid.uuid4().hex, 'domain_id': domain['id'], - 'name': uuid.uuid4().hex} - self.identity_api.create_group(new_group['id'], new_group) - self.assertRaises(exception.UserNotFound, - self.identity_api.add_user_to_group, - uuid.uuid4().hex, - new_group['id']) - - def test_check_user_in_group(self): - domain = self._get_domain_fixture() - new_group = {'id': uuid.uuid4().hex, 'domain_id': domain['id'], - 'name': uuid.uuid4().hex} - self.identity_api.create_group(new_group['id'], new_group) - new_user = {'id': uuid.uuid4().hex, 'name': 'new_user', - 'password': uuid.uuid4().hex, 'enabled': True, - 'domain_id': domain['id']} - self.identity_api.create_user(new_user['id'], new_user) - self.identity_api.add_user_to_group(new_user['id'], - new_group['id']) - self.identity_api.check_user_in_group(new_user['id'], new_group['id']) - - def test_check_user_not_in_group(self): - new_group = { - 'id': uuid.uuid4().hex, - 'domain_id': CONF.identity.default_domain_id, - 'name': uuid.uuid4().hex} - self.identity_api.create_group(new_group['id'], new_group) - self.assertRaises(exception.UserNotFound, - self.identity_api.check_user_in_group, - uuid.uuid4().hex, - new_group['id']) - - def test_list_users_in_group(self): - domain = self._get_domain_fixture() - new_group = {'id': uuid.uuid4().hex, 'domain_id': domain['id'], - 'name': uuid.uuid4().hex} - self.identity_api.create_group(new_group['id'], new_group) - new_user = {'id': uuid.uuid4().hex, 'name': 'new_user', - 'password': uuid.uuid4().hex, 'enabled': True, - 'domain_id': domain['id']} - self.identity_api.create_user(new_user['id'], new_user) - self.identity_api.add_user_to_group(new_user['id'], - new_group['id']) - user_refs = self.identity_api.list_users_in_group(new_group['id']) - found = False - for x in user_refs: - if (x['id'] == new_user['id']): - found = True - self.assertTrue(found) - - def test_remove_user_from_group(self): - domain = self._get_domain_fixture() - new_group = {'id': uuid.uuid4().hex, 'domain_id': domain['id'], - 'name': uuid.uuid4().hex} - self.identity_api.create_group(new_group['id'], new_group) - new_user = {'id': uuid.uuid4().hex, 'name': 'new_user', - 'password': uuid.uuid4().hex, 'enabled': True, - 'domain_id': domain['id']} - self.identity_api.create_user(new_user['id'], new_user) - self.identity_api.add_user_to_group(new_user['id'], - new_group['id']) - groups = self.identity_api.list_groups_for_user(new_user['id']) - self.assertIn(new_group['id'], [x['id'] for x in groups]) - self.identity_api.remove_user_from_group(new_user['id'], - new_group['id']) - groups = self.identity_api.list_groups_for_user(new_user['id']) - self.assertNotIn(new_group['id'], [x['id'] for x in groups]) - - def test_remove_user_from_group_404(self): - domain = self._get_domain_fixture() - new_user = {'id': uuid.uuid4().hex, 'name': 'new_user', - 'password': uuid.uuid4().hex, 'enabled': True, - 'domain_id': domain['id']} - self.identity_api.create_user(new_user['id'], new_user) - new_group = {'id': uuid.uuid4().hex, 'domain_id': domain['id'], - 'name': uuid.uuid4().hex} - self.identity_api.create_group(new_group['id'], new_group) - self.assertRaises(exception.NotFound, - self.identity_api.remove_user_from_group, - new_user['id'], - uuid.uuid4().hex) - - self.assertRaises(exception.NotFound, - self.identity_api.remove_user_from_group, - uuid.uuid4().hex, - new_group['id']) - - self.assertRaises(exception.NotFound, - self.identity_api.remove_user_from_group, - uuid.uuid4().hex, - uuid.uuid4().hex) - - def test_group_crud(self): - domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain['id'], domain) - group = {'id': uuid.uuid4().hex, 'domain_id': domain['id'], - 'name': uuid.uuid4().hex} - self.identity_api.create_group(group['id'], group) - group_ref = self.identity_api.get_group(group['id']) - self.assertDictContainsSubset(group, group_ref) - - group['name'] = uuid.uuid4().hex - self.identity_api.update_group(group['id'], group) - group_ref = self.identity_api.get_group(group['id']) - self.assertDictContainsSubset(group, group_ref) - - self.identity_api.delete_group(group['id']) - self.assertRaises(exception.GroupNotFound, - self.identity_api.get_group, - group['id']) - - def test_create_duplicate_group_name_fails(self): - group1 = {'id': uuid.uuid4().hex, 'domain_id': DEFAULT_DOMAIN_ID, - 'name': uuid.uuid4().hex} - group2 = {'id': uuid.uuid4().hex, 'domain_id': DEFAULT_DOMAIN_ID, - 'name': group1['name']} - self.identity_api.create_group(group1['id'], group1) - self.assertRaises(exception.Conflict, - self.identity_api.create_group, - group2['id'], group2) - - def test_create_duplicate_group_name_in_different_domains(self): - new_domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(new_domain['id'], new_domain) - group1 = {'id': uuid.uuid4().hex, 'domain_id': DEFAULT_DOMAIN_ID, - 'name': uuid.uuid4().hex} - group2 = {'id': uuid.uuid4().hex, 'domain_id': new_domain['id'], - 'name': group1['name']} - self.identity_api.create_group(group1['id'], group1) - self.identity_api.create_group(group2['id'], group2) - - def test_move_group_between_domains(self): - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - domain2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain2['id'], domain2) - group = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain1['id']} - self.identity_api.create_group(group['id'], group) - group['domain_id'] = domain2['id'] - self.identity_api.update_group(group['id'], group) - - def test_move_group_between_domains_with_clashing_names_fails(self): - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - domain2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain2['id'], domain2) - # First, create a group in domain1 - group1 = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain1['id']} - self.identity_api.create_group(group1['id'], group1) - # Now create a group in domain2 with a potentially clashing - # name - which should work since we have domain separation - group2 = {'id': uuid.uuid4().hex, - 'name': group1['name'], - 'domain_id': domain2['id']} - self.identity_api.create_group(group2['id'], group2) - # Now try and move group1 into the 2nd domain - which should - # fail since the names clash - group1['domain_id'] = domain2['id'] - self.assertRaises(exception.Conflict, - self.identity_api.update_group, - group1['id'], - group1) - - def test_project_crud(self): - domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'enabled': True} - self.identity_api.create_domain(domain['id'], domain) - project = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain['id']} - self.identity_api.create_project(project['id'], project) - project_ref = self.identity_api.get_project(project['id']) - self.assertDictContainsSubset(project, project_ref) - - project['name'] = uuid.uuid4().hex - self.identity_api.update_project(project['id'], project) - project_ref = self.identity_api.get_project(project['id']) - self.assertDictContainsSubset(project, project_ref) - - self.identity_api.delete_project(project['id']) - self.assertRaises(exception.ProjectNotFound, - self.identity_api.get_project, - project['id']) - - def test_domain_crud(self): - domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'enabled': True} - self.identity_api.create_domain(domain['id'], domain) - domain_ref = self.identity_api.get_domain(domain['id']) - self.assertDictEqual(domain_ref, domain) - - domain['name'] = uuid.uuid4().hex - self.identity_api.update_domain(domain['id'], domain) - domain_ref = self.identity_api.get_domain(domain['id']) - self.assertDictEqual(domain_ref, domain) - - self.identity_api.delete_domain(domain['id']) - self.assertRaises(exception.DomainNotFound, - self.identity_api.get_domain, - domain['id']) - - def test_user_crud(self): - user = {'domain_id': CONF.identity.default_domain_id, - 'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, 'password': 'passw0rd'} - self.identity_api.create_user(user['id'], user) - user_ref = self.identity_api.get_user(user['id']) - del user['password'] - user_ref_dict = dict((x, user_ref[x]) for x in user_ref) - self.assertDictContainsSubset(user, user_ref_dict) - - user['password'] = uuid.uuid4().hex - self.identity_api.update_user(user['id'], user) - user_ref = self.identity_api.get_user(user['id']) - del user['password'] - user_ref_dict = dict((x, user_ref[x]) for x in user_ref) - self.assertDictContainsSubset(user, user_ref_dict) - - self.identity_api.delete_user(user['id']) - self.assertRaises(exception.UserNotFound, - self.identity_api.get_user, - user['id']) - - def test_list_user_projects(self): - domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain['id'], domain) - user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, 'domain_id': domain['id'], - 'enabled': True} - self.identity_api.create_user(user1['id'], user1) - user_projects = self.identity_api.list_user_projects(user1['id']) - self.assertEquals(len(user_projects), 0) - self.identity_api.create_grant(user_id=user1['id'], - project_id=self.tenant_bar['id'], - role_id=self.role_member['id']) - self.identity_api.create_grant(user_id=user1['id'], - project_id=self.tenant_baz['id'], - role_id=self.role_member['id']) - user_projects = self.identity_api.list_user_projects(user1['id']) - self.assertEquals(len(user_projects), 2) - - -class TokenTests(object): - def _create_token_id(self): - # Token must start with MII here otherwise it fails the asn1 test - # and is not hashed in a SQL backend. - token_id = "MII" - for i in range(1, 20): - token_id += uuid.uuid4().hex - return token_id - - def test_token_crud(self): - token_id = self._create_token_id() - data = {'id': token_id, 'a': 'b', - 'trust_id': None, - 'user': {'id': 'testuserid'}} - data_ref = self.token_api.create_token(token_id, data) - expires = data_ref.pop('expires') - data_ref.pop('user_id') - self.assertTrue(isinstance(expires, datetime.datetime)) - data_ref.pop('id') - data.pop('id') - self.assertDictEqual(data_ref, data) - - new_data_ref = self.token_api.get_token(token_id) - expires = new_data_ref.pop('expires') - self.assertTrue(isinstance(expires, datetime.datetime)) - new_data_ref.pop('user_id') - new_data_ref.pop('id') - - self.assertEquals(new_data_ref, data) - - self.token_api.delete_token(token_id) - self.assertRaises(exception.TokenNotFound, - self.token_api.get_token, token_id) - self.assertRaises(exception.TokenNotFound, - self.token_api.delete_token, token_id) - - def create_token_sample_data(self, tenant_id=None, trust_id=None, - user_id="testuserid"): - token_id = self._create_token_id() - data = {'id': token_id, 'a': 'b', - 'user': {'id': user_id}} - if tenant_id is not None: - data['tenant'] = {'id': tenant_id, 'name': tenant_id} - if tenant_id is NULL_OBJECT: - data['tenant'] = None - if trust_id is not None: - data['trust_id'] = trust_id - new_token = self.token_api.create_token(token_id, data) - return new_token['id'] - - def test_delete_tokens(self): - tokens = self.token_api.list_tokens('testuserid') - self.assertEquals(len(tokens), 0) - token_id1 = self.create_token_sample_data('testtenantid') - token_id2 = self.create_token_sample_data('testtenantid') - token_id3 = self.create_token_sample_data(tenant_id='testtenantid', - user_id="testuserid1") - tokens = self.token_api.list_tokens('testuserid') - self.assertEquals(len(tokens), 2) - self.assertIn(token_id2, tokens) - self.assertIn(token_id1, tokens) - self.token_api.delete_tokens(user_id='testuserid', - tenant_id='testtenantid') - tokens = self.token_api.list_tokens('testuserid') - self.assertEquals(len(tokens), 0) - self.assertRaises(exception.TokenNotFound, - self.token_api.get_token, token_id1) - self.assertRaises(exception.TokenNotFound, - self.token_api.get_token, token_id2) - - self.token_api.get_token(token_id3) - - def test_delete_tokens_trust(self): - tokens = self.token_api.list_tokens(user_id='testuserid') - self.assertEquals(len(tokens), 0) - token_id1 = self.create_token_sample_data(tenant_id='testtenantid', - trust_id='testtrustid') - token_id2 = self.create_token_sample_data(tenant_id='testtenantid', - user_id="testuserid1", - trust_id="testtrustid1") - tokens = self.token_api.list_tokens('testuserid') - self.assertEquals(len(tokens), 1) - self.assertIn(token_id1, tokens) - self.token_api.delete_tokens(user_id='testuserid', - tenant_id='testtenantid', - trust_id='testtrustid') - self.assertRaises(exception.TokenNotFound, - self.token_api.get_token, token_id1) - self.token_api.get_token(token_id2) - - def test_token_list(self): - tokens = self.token_api.list_tokens('testuserid') - self.assertEquals(len(tokens), 0) - token_id1 = self.create_token_sample_data() - tokens = self.token_api.list_tokens('testuserid') - self.assertEquals(len(tokens), 1) - self.assertIn(token_id1, tokens) - token_id2 = self.create_token_sample_data() - tokens = self.token_api.list_tokens('testuserid') - self.assertEquals(len(tokens), 2) - self.assertIn(token_id2, tokens) - self.assertIn(token_id1, tokens) - self.token_api.delete_token(token_id1) - tokens = self.token_api.list_tokens('testuserid') - self.assertIn(token_id2, tokens) - self.assertNotIn(token_id1, tokens) - self.token_api.delete_token(token_id2) - tokens = self.token_api.list_tokens('testuserid') - self.assertNotIn(token_id2, tokens) - self.assertNotIn(token_id1, tokens) - - # tenant-specific tokens - tenant1 = uuid.uuid4().hex - tenant2 = uuid.uuid4().hex - token_id3 = self.create_token_sample_data(tenant_id=tenant1) - token_id4 = self.create_token_sample_data(tenant_id=tenant2) - # test for existing but empty tenant (LP:1078497) - token_id5 = self.create_token_sample_data(tenant_id=NULL_OBJECT) - tokens = self.token_api.list_tokens('testuserid') - self.assertEquals(len(tokens), 3) - self.assertNotIn(token_id1, tokens) - self.assertNotIn(token_id2, tokens) - self.assertIn(token_id3, tokens) - self.assertIn(token_id4, tokens) - self.assertIn(token_id5, tokens) - tokens = self.token_api.list_tokens('testuserid', tenant2) - self.assertEquals(len(tokens), 1) - self.assertNotIn(token_id1, tokens) - self.assertNotIn(token_id2, tokens) - self.assertNotIn(token_id3, tokens) - self.assertIn(token_id4, tokens) - - def test_token_list_trust(self): - trust_id = uuid.uuid4().hex - token_id5 = self.create_token_sample_data(trust_id=trust_id) - tokens = self.token_api.list_tokens('testuserid', trust_id=trust_id) - self.assertEquals(len(tokens), 1) - self.assertIn(token_id5, tokens) - - def test_get_token_404(self): - self.assertRaises(exception.TokenNotFound, - self.token_api.get_token, - uuid.uuid4().hex) - self.assertRaises(exception.TokenNotFound, - self.token_api.get_token, - None) - - def test_delete_token_404(self): - self.assertRaises(exception.TokenNotFound, - self.token_api.delete_token, - uuid.uuid4().hex) - - def test_expired_token(self): - token_id = uuid.uuid4().hex - expire_time = timeutils.utcnow() - datetime.timedelta(minutes=1) - data = {'id_hash': token_id, 'id': token_id, 'a': 'b', - 'expires': expire_time, - 'trust_id': None, - 'user': {'id': 'testuserid'}} - data_ref = self.token_api.create_token(token_id, data) - data_ref.pop('user_id') - self.assertDictEqual(data_ref, data) - self.assertRaises(exception.TokenNotFound, - self.token_api.get_token, token_id) - - def test_null_expires_token(self): - token_id = uuid.uuid4().hex - data = {'id': token_id, 'id_hash': token_id, 'a': 'b', 'expires': None, - 'user': {'id': 'testuserid'}} - data_ref = self.token_api.create_token(token_id, data) - self.assertIsNotNone(data_ref['expires']) - new_data_ref = self.token_api.get_token(token_id) - - # MySQL doesn't store microseconds, so discard them before testing - data_ref['expires'] = data_ref['expires'].replace(microsecond=0) - new_data_ref['expires'] = new_data_ref['expires'].replace( - microsecond=0) - - self.assertEqual(data_ref, new_data_ref) - - def check_list_revoked_tokens(self, token_ids): - revoked_ids = [x['id'] for x in self.token_api.list_revoked_tokens()] - for token_id in token_ids: - self.assertIn(token_id, revoked_ids) - - def delete_token(self): - token_id = uuid.uuid4().hex - data = {'id_hash': token_id, 'id': token_id, 'a': 'b', - 'user': {'id': 'testuserid'}} - data_ref = self.token_api.create_token(token_id, data) - self.token_api.delete_token(token_id) - self.assertRaises( - exception.TokenNotFound, - self.token_api.get_token, - data_ref['id']) - self.assertRaises( - exception.TokenNotFound, - self.token_api.delete_token, - data_ref['id']) - return token_id - - def test_list_revoked_tokens_returns_empty_list(self): - revoked_ids = [x['id'] for x in self.token_api.list_revoked_tokens()] - self.assertEqual(revoked_ids, []) - - def test_list_revoked_tokens_for_single_token(self): - self.check_list_revoked_tokens([self.delete_token()]) - - def test_list_revoked_tokens_for_multiple_tokens(self): - self.check_list_revoked_tokens([self.delete_token() - for x in xrange(2)]) - - def test_flush_expired_token(self): - token_id = uuid.uuid4().hex - expire_time = timeutils.utcnow() - datetime.timedelta(minutes=1) - data = {'id_hash': token_id, 'id': token_id, 'a': 'b', - 'expires': expire_time, - 'trust_id': None, - 'user': {'id': 'testuserid'}} - data_ref = self.token_api.create_token(token_id, data) - data_ref.pop('user_id') - self.assertDictEqual(data_ref, data) - - token_id = uuid.uuid4().hex - expire_time = timeutils.utcnow() + datetime.timedelta(minutes=1) - data = {'id_hash': token_id, 'id': token_id, 'a': 'b', - 'expires': expire_time, - 'trust_id': None, - 'user': {'id': 'testuserid'}} - data_ref = self.token_api.create_token(token_id, data) - data_ref.pop('user_id') - self.assertDictEqual(data_ref, data) - - self.token_api.flush_expired_tokens() - tokens = self.token_api.list_tokens('testuserid') - self.assertEqual(len(tokens), 1) - self.assertIn(token_id, tokens) - - -class TrustTests(object): - def create_sample_trust(self, new_id): - self.trustor = self.user_foo - self.trustee = self.user_two - trust_data = (self.trust_api.create_trust - (new_id, - {'trustor_user_id': self.trustor['id'], - 'trustee_user_id': self.user_two['id'], - 'project_id': self.tenant_bar['id'], - 'expires_at': timeutils. - parse_isotime('2031-02-18T18:10:00Z'), - 'impersonation': True}, - roles=[{"id": "member"}, - {"id": "other"}, - {"id": "browser"}])) - return trust_data - - def test_delete_trust(self): - new_id = uuid.uuid4().hex - trust_data = self.create_sample_trust(new_id) - trust_id = trust_data['id'] - self.assertIsNotNone(trust_data) - trust_data = self.trust_api.get_trust(trust_id) - self.assertEquals(new_id, trust_data['id']) - self.trust_api.delete_trust(trust_id) - self.assertIsNone(self.trust_api.get_trust(trust_id)) - - def test_delete_trust_not_found(self): - trust_id = uuid.uuid4().hex - self.assertRaises(exception.TrustNotFound, - self.trust_api.delete_trust, - trust_id) - - def test_get_trust(self): - new_id = uuid.uuid4().hex - trust_data = self.create_sample_trust(new_id) - trust_id = trust_data['id'] - self.assertIsNotNone(trust_data) - trust_data = self.trust_api.get_trust(trust_id) - self.assertEquals(new_id, trust_data['id']) - - def test_create_trust(self): - new_id = uuid.uuid4().hex - trust_data = self.create_sample_trust(new_id) - - self.assertEquals(new_id, trust_data['id']) - self.assertEquals(self.trustee['id'], trust_data['trustee_user_id']) - self.assertEquals(self.trustor['id'], trust_data['trustor_user_id']) - self.assertTrue(timeutils.normalize_time(trust_data['expires_at']) > - timeutils.utcnow()) - - self.assertEquals([{'id': 'member'}, - {'id': 'other'}, - {'id': 'browser'}], trust_data['roles']) - - def test_list_trust_by_trustee(self): - for i in range(3): - self.create_sample_trust(uuid.uuid4().hex) - trusts = self.trust_api.list_trusts_for_trustee(self.trustee['id']) - self.assertEqual(len(trusts), 3) - self.assertEqual(trusts[0]["trustee_user_id"], self.trustee['id']) - trusts = self.trust_api.list_trusts_for_trustee(self.trustor['id']) - self.assertEqual(len(trusts), 0) - - def test_list_trust_by_trustor(self): - for i in range(3): - self.create_sample_trust(uuid.uuid4().hex) - trusts = self.trust_api.list_trusts_for_trustor(self.trustor['id']) - self.assertEqual(len(trusts), 3) - self.assertEqual(trusts[0]["trustor_user_id"], self.trustor['id']) - trusts = self.trust_api.list_trusts_for_trustor(self.trustee['id']) - self.assertEqual(len(trusts), 0) - - def test_list_trusts(self): - for i in range(3): - self.create_sample_trust(uuid.uuid4().hex) - trusts = self.trust_api.list_trusts() - self.assertEqual(len(trusts), 3) - - -class CommonHelperTests(test.TestCase): - def test_format_helper_raises_malformed_on_missing_key(self): - with self.assertRaises(exception.MalformedEndpoint): - core.format_url("http://%(foo)s/%(bar)s", {"foo": "1"}) - - def test_format_helper_raises_malformed_on_wrong_type(self): - with self.assertRaises(exception.MalformedEndpoint): - core.format_url("http://%foo%s", {"foo": "1"}) - - def test_format_helper_raises_malformed_on_incomplete_format(self): - with self.assertRaises(exception.MalformedEndpoint): - core.format_url("http://%(foo)", {"foo": "1"}) - - -class CatalogTests(object): - def test_service_crud(self): - # create - service_id = uuid.uuid4().hex - new_service = { - 'id': service_id, - 'type': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'description': uuid.uuid4().hex, - } - res = self.catalog_api.create_service( - service_id, - new_service.copy()) - self.assertDictEqual(res, new_service) - - # list - services = self.catalog_api.list_services() - self.assertIn(service_id, [x['id'] for x in services]) - - # delete - self.catalog_api.delete_service(service_id) - self.assertRaises(exception.ServiceNotFound, - self.catalog_api.delete_service, - service_id) - self.assertRaises(exception.ServiceNotFound, - self.catalog_api.get_service, - service_id) - - def test_delete_service_with_endpoint(self): - # create a service - service = { - 'id': uuid.uuid4().hex, - 'type': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'description': uuid.uuid4().hex, - } - self.catalog_api.create_service(service['id'], service) - - # create an endpoint attached to the service - endpoint = { - 'id': uuid.uuid4().hex, - 'region': uuid.uuid4().hex, - 'interface': uuid.uuid4().hex[:8], - 'url': uuid.uuid4().hex, - 'service_id': service['id'], - } - self.catalog_api.create_endpoint(endpoint['id'], endpoint) - - # deleting the service should also delete the endpoint - self.catalog_api.delete_service(service['id']) - self.assertRaises(exception.EndpointNotFound, - self.catalog_api.get_endpoint, - endpoint['id']) - self.assertRaises(exception.EndpointNotFound, - self.catalog_api.delete_endpoint, - endpoint['id']) - - def test_get_service_404(self): - self.assertRaises(exception.ServiceNotFound, - self.catalog_api.get_service, - uuid.uuid4().hex) - - def test_delete_service_404(self): - self.assertRaises(exception.ServiceNotFound, - self.catalog_api.delete_service, - uuid.uuid4().hex) - - def test_create_endpoint_404(self): - endpoint = { - 'id': uuid.uuid4().hex, - 'service_id': uuid.uuid4().hex, - } - self.assertRaises(exception.ServiceNotFound, - self.catalog_api.create_endpoint, - endpoint['id'], - endpoint) - - def test_get_endpoint_404(self): - self.assertRaises(exception.EndpointNotFound, - self.catalog_api.get_endpoint, - uuid.uuid4().hex) - - def test_delete_endpoint_404(self): - self.assertRaises(exception.EndpointNotFound, - self.catalog_api.delete_endpoint, - uuid.uuid4().hex) - - def test_create_endpoint(self): - service = { - 'id': uuid.uuid4().hex, - 'type': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'description': uuid.uuid4().hex, - } - self.catalog_api.create_service(service['id'], service.copy()) - - endpoint = { - 'id': uuid.uuid4().hex, - 'region': "0" * 255, - 'service_id': service['id'], - 'interface': 'public', - 'url': uuid.uuid4().hex, - } - self.catalog_api.create_endpoint(endpoint['id'], endpoint.copy()) - - -class PolicyTests(object): - def _new_policy_ref(self): - return { - 'id': uuid.uuid4().hex, - 'policy': uuid.uuid4().hex, - 'type': uuid.uuid4().hex, - 'endpoint_id': uuid.uuid4().hex, - } - - def assertEqualPolicies(self, a, b): - self.assertEqual(a['id'], b['id']) - self.assertEqual(a['endpoint_id'], b['endpoint_id']) - self.assertEqual(a['policy'], b['policy']) - self.assertEqual(a['type'], b['type']) - - def test_create(self): - ref = self._new_policy_ref() - res = self.policy_api.create_policy(ref['id'], ref) - self.assertEqualPolicies(ref, res) - - def test_get(self): - ref = self._new_policy_ref() - res = self.policy_api.create_policy(ref['id'], ref) - - res = self.policy_api.get_policy(ref['id']) - self.assertEqualPolicies(ref, res) - - def test_list(self): - ref = self._new_policy_ref() - self.policy_api.create_policy(ref['id'], ref) - - res = self.policy_api.list_policies() - res = [x for x in res if x['id'] == ref['id']][0] - self.assertEqualPolicies(ref, res) - - def test_update(self): - ref = self._new_policy_ref() - self.policy_api.create_policy(ref['id'], ref) - orig = ref - - ref = self._new_policy_ref() - - # (cannot change policy ID) - self.assertRaises(exception.ValidationError, - self.policy_api.update_policy, - orig['id'], - ref) - - ref['id'] = orig['id'] - res = self.policy_api.update_policy(orig['id'], ref) - self.assertEqualPolicies(ref, res) - - def test_delete(self): - ref = self._new_policy_ref() - self.policy_api.create_policy(ref['id'], ref) - - self.policy_api.delete_policy(ref['id']) - self.assertRaises(exception.PolicyNotFound, - self.policy_api.delete_policy, - ref['id']) - self.assertRaises(exception.PolicyNotFound, - self.policy_api.get_policy, - ref['id']) - res = self.policy_api.list_policies() - self.assertFalse(len([x for x in res if x['id'] == ref['id']])) - - def test_get_policy_404(self): - self.assertRaises(exception.PolicyNotFound, - self.policy_api.get_policy, - uuid.uuid4().hex) - - def test_update_policy_404(self): - ref = self._new_policy_ref() - self.assertRaises(exception.PolicyNotFound, - self.policy_api.update_policy, - ref['id'], - ref) - - def test_delete_policy_404(self): - self.assertRaises(exception.PolicyNotFound, - self.policy_api.delete_policy, - uuid.uuid4().hex) - - -class InheritanceTests(object): - - def test_inherited_role_grants_for_user(self): - """Test inherited user roles. - - Test Plan: - - Enable OS-INHERIT extension - - Create 3 roles - - Create a domain, with a project and a user - - Check no roles yet exit - - Assign a direct user role to the project and a (non-inherited) - user role to the domain - - Get a list of effective roles - should only get the one direct role - - Now add an inherited user role to the domain - - Get a list of effective roles - should have two roles, one - direct and one by virtue of the inherited user role - - Also get effective roles for the domain - the role marked as - inherited should not show up - - """ - self.opt_in_group('os_inherit', enabled=True) - role_list = [] - for _ in range(3): - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_role(role['id'], role) - role_list.append(role) - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'password': uuid.uuid4().hex, - 'enabled': True} - self.identity_api.create_user(user1['id'], user1) - project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id']} - self.identity_api.create_project(project1['id'], project1) - - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 0) - - # Create the first two roles - the domain one is not inherited - self.identity_api.create_grant(user_id=user1['id'], - project_id=project1['id'], - role_id=role_list[0]['id']) - self.identity_api.create_grant(user_id=user1['id'], - domain_id=domain1['id'], - role_id=role_list[1]['id']) - - # Now get the effective roles for the user and project, this - # should only include the direct role assignment on the project - combined_role_list = self.identity_api.get_roles_for_user_and_project( - user1['id'], project1['id']) - self.assertEquals(len(combined_role_list), 1) - self.assertIn(role_list[0]['id'], combined_role_list) - - # Now add an inherited role on the domain - self.identity_api.create_grant(user_id=user1['id'], - domain_id=domain1['id'], - role_id=role_list[2]['id'], - inherited_to_projects=True) - - # Now get the effective roles for the user and project again, this - # should now include the inherited role on the domain - combined_role_list = self.identity_api.get_roles_for_user_and_project( - user1['id'], project1['id']) - self.assertEquals(len(combined_role_list), 2) - self.assertIn(role_list[0]['id'], combined_role_list) - self.assertIn(role_list[2]['id'], combined_role_list) - - # Finally, check that the inherited role does not appear as a valid - # directly assigned role on the domain itself - combined_role_list = self.identity_api.get_roles_for_user_and_domain( - user1['id'], domain1['id']) - self.assertEquals(len(combined_role_list), 1) - self.assertIn(role_list[1]['id'], combined_role_list) - - def test_inherited_role_grants_for_group(self): - """Test inherited group roles. - - Test Plan: - - Enable OS-INHERIT extension - - Create 4 roles - - Create a domain, with a project, user and two groups - - Make the user a member of both groups - - Check no roles yet exit - - Assign a direct user role to the project and a (non-inherited) - group role on the domain - - Get a list of effective roles - should only get the one direct role - - Now add two inherited group roles to the domain - - Get a list of effective roles - should have three roles, one - direct and two by virtue of inherited group roles - - """ - self.opt_in_group('os_inherit', enabled=True) - role_list = [] - for _ in range(4): - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_role(role['id'], role) - role_list.append(role) - domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_domain(domain1['id'], domain1) - user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'password': uuid.uuid4().hex, - 'enabled': True} - self.identity_api.create_user(user1['id'], user1) - group1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'enabled': True} - self.identity_api.create_group(group1['id'], group1) - group2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], 'enabled': True} - self.identity_api.create_group(group2['id'], group2) - project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': domain1['id']} - self.identity_api.create_project(project1['id'], project1) - - self.identity_api.add_user_to_group(user1['id'], - group1['id']) - self.identity_api.add_user_to_group(user1['id'], - group2['id']) - - roles_ref = self.identity_api.list_grants( - user_id=user1['id'], - project_id=project1['id']) - self.assertEquals(len(roles_ref), 0) - - # Create two roles - the domain one is not inherited - self.identity_api.create_grant(user_id=user1['id'], - project_id=project1['id'], - role_id=role_list[0]['id']) - self.identity_api.create_grant(group_id=group1['id'], - domain_id=domain1['id'], - role_id=role_list[1]['id']) - - # Now get the effective roles for the user and project, this - # should only include the direct role assignment on the project - combined_role_list = self.identity_api.get_roles_for_user_and_project( - user1['id'], project1['id']) - self.assertEquals(len(combined_role_list), 1) - self.assertIn(role_list[0]['id'], combined_role_list) - - # Now add to more group roles, both inherited, to the domain - self.identity_api.create_grant(group_id=group2['id'], - domain_id=domain1['id'], - role_id=role_list[2]['id'], - inherited_to_projects=True) - self.identity_api.create_grant(group_id=group2['id'], - domain_id=domain1['id'], - role_id=role_list[3]['id'], - inherited_to_projects=True) - - # Now get the effective roles for the user and project again, this - # should now include the inherited roles on the domain - combined_role_list = self.identity_api.get_roles_for_user_and_project( - user1['id'], project1['id']) - self.assertEquals(len(combined_role_list), 3) - self.assertIn(role_list[0]['id'], combined_role_list) - self.assertIn(role_list[2]['id'], combined_role_list) - self.assertIn(role_list[3]['id'], combined_role_list) diff --git a/tests/test_backend_kvs.py b/tests/test_backend_kvs.py deleted file mode 100644 index d92a7510..00000000 --- a/tests/test_backend_kvs.py +++ /dev/null @@ -1,120 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 uuid - -from keystone import test - -from keystone import exception -from keystone import identity - -import default_fixtures -import test_backend - - -class KvsIdentity(test.TestCase, test_backend.IdentityTests): - def setUp(self): - super(KvsIdentity, self).setUp() - identity.CONF.identity.driver = ( - 'keystone.identity.backends.kvs.Identity') - self.load_backends() - self.load_fixtures(default_fixtures) - - def test_list_user_projects(self): - # NOTE(chungg): not implemented - self.skipTest('Blocked by bug 1119770') - - def test_create_duplicate_group_name_in_different_domains(self): - self.skipTest('Blocked by bug 1119770') - - def test_create_duplicate_user_name_in_different_domains(self): - self.skipTest('Blocked by bug 1119770') - - def test_create_duplicate_project_name_in_different_domains(self): - self.skipTest('Blocked by bug 1119770') - - def test_move_user_between_domains(self): - self.skipTest('Blocked by bug 1119770') - - def test_move_user_between_domains_with_clashing_names_fails(self): - self.skipTest('Blocked by bug 1119770') - - def test_move_group_between_domains(self): - self.skipTest('Blocked by bug 1119770') - - def test_move_group_between_domains_with_clashing_names_fails(self): - self.skipTest('Blocked by bug 1119770') - - def test_move_project_between_domains(self): - self.skipTest('Blocked by bug 1119770') - - def test_move_project_between_domains_with_clashing_names_fails(self): - self.skipTest('Blocked by bug 1119770') - - -class KvsToken(test.TestCase, test_backend.TokenTests): - def setUp(self): - super(KvsToken, self).setUp() - identity.CONF.identity.driver = ( - 'keystone.identity.backends.kvs.Identity') - self.load_backends() - - -class KvsTrust(test.TestCase, test_backend.TrustTests): - def setUp(self): - super(KvsTrust, self).setUp() - identity.CONF.identity.driver = ( - 'keystone.identity.backends.kvs.Identity') - identity.CONF.trust.driver = ( - 'keystone.trust.backends.kvs.Trust') - identity.CONF.catalog.driver = ( - 'keystone.catalog.backends.kvs.Catalog') - self.load_backends() - self.load_fixtures(default_fixtures) - - -class KvsCatalog(test.TestCase, test_backend.CatalogTests): - def setUp(self): - super(KvsCatalog, self).setUp() - identity.CONF.identity.driver = ( - 'keystone.identity.backends.kvs.Identity') - identity.CONF.trust.driver = ( - 'keystone.trust.backends.kvs.Trust') - identity.CONF.catalog.driver = ( - 'keystone.catalog.backends.kvs.Catalog') - self.load_backends() - self._load_fake_catalog() - - def _load_fake_catalog(self): - self.catalog_foobar = self.catalog_api.driver._create_catalog( - 'foo', 'bar', - {'RegionFoo': {'service_bar': {'foo': 'bar'}}}) - - def test_get_catalog_404(self): - # FIXME(dolph): this test should be moved up to test_backend - # FIXME(dolph): exceptions should be UserNotFound and ProjectNotFound - self.assertRaises(exception.NotFound, - self.catalog_api.get_catalog, - uuid.uuid4().hex, - 'bar') - - self.assertRaises(exception.NotFound, - self.catalog_api.get_catalog, - 'foo', - uuid.uuid4().hex) - - def test_get_catalog(self): - catalog_ref = self.catalog_api.get_catalog('foo', 'bar') - self.assertDictEqual(catalog_ref, self.catalog_foobar) diff --git a/tests/test_backend_ldap.py b/tests/test_backend_ldap.py deleted file mode 100644 index ec2b2737..00000000 --- a/tests/test_backend_ldap.py +++ /dev/null @@ -1,745 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack LLC -# Copyright 2013 IBM Corp. -# -# 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 uuid - -from keystone import assignment -from keystone.common.ldap import fakeldap -from keystone.common import sql -from keystone import config -from keystone import exception -from keystone import identity -from keystone import test - -import default_fixtures -import test_backend - - -CONF = config.CONF - - -class BaseLDAPIdentity(test_backend.IdentityTests): - def _get_domain_fixture(self): - """Domains in LDAP are read-only, so just return the static one.""" - return self.identity_api.get_domain(CONF.identity.default_domain_id) - - def clear_database(self): - db = fakeldap.FakeShelve().get_instance() - db.clear() - - def _set_config(self): - self.config([test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf'), - test.testsdir('backend_ldap.conf')]) - - def test_build_tree(self): - """Regression test for building the tree names - """ - user_api = identity.backends.ldap.UserApi(CONF) - self.assertTrue(user_api) - self.assertEquals(user_api.tree_dn, "ou=Users,%s" % CONF.ldap.suffix) - - def test_configurable_allowed_user_actions(self): - user = {'id': 'fake1', - 'name': 'fake1', - 'password': 'fakepass1', - 'tenants': ['bar']} - self.identity_api.create_user('fake1', user) - user_ref = self.identity_api.get_user('fake1') - self.assertEqual(user_ref['id'], 'fake1') - - user['password'] = 'fakepass2' - self.identity_api.update_user('fake1', user) - - self.identity_api.delete_user('fake1') - self.assertRaises(exception.UserNotFound, - self.identity_api.get_user, - 'fake1') - - def test_configurable_forbidden_user_actions(self): - CONF.ldap.user_allow_create = False - CONF.ldap.user_allow_update = False - CONF.ldap.user_allow_delete = False - self.load_backends() - - user = {'id': 'fake1', - 'name': 'fake1', - 'password': 'fakepass1', - 'tenants': ['bar']} - self.assertRaises(exception.ForbiddenAction, - self.identity_api.create_user, - 'fake1', - user) - - self.user_foo['password'] = 'fakepass2' - self.assertRaises(exception.ForbiddenAction, - self.identity_api.update_user, - self.user_foo['id'], - self.user_foo) - - self.assertRaises(exception.ForbiddenAction, - self.identity_api.delete_user, - self.user_foo['id']) - - def test_user_filter(self): - user_ref = self.identity_api.get_user(self.user_foo['id']) - self.user_foo.pop('password') - self.assertDictEqual(user_ref, self.user_foo) - - CONF.ldap.user_filter = '(CN=DOES_NOT_MATCH)' - self.load_backends() - self.assertRaises(exception.UserNotFound, - self.identity_api.get_user, - self.user_foo['id']) - - def test_get_role_grant_by_user_and_project(self): - self.skipTest('Blocked by bug 1101287') - - def test_get_role_grants_for_user_and_project_404(self): - self.skipTest('Blocked by bug 1101287') - - def test_add_role_grant_to_user_and_project_404(self): - self.skipTest('Blocked by bug 1101287') - - def test_remove_role_grant_from_user_and_project(self): - self.skipTest('Blocked by bug 1101287') - - def test_get_and_remove_role_grant_by_group_and_project(self): - self.skipTest('Blocked by bug 1101287') - - def test_get_and_remove_role_grant_by_group_and_domain(self): - self.skipTest('N/A: LDAP does not support multiple domains') - - def test_get_and_remove_role_grant_by_user_and_domain(self): - self.skipTest('N/A: LDAP does not support multiple domains') - - def test_get_and_remove_correct_role_grant_from_a_mix(self): - self.skipTest('Blocked by bug 1101287') - - def test_get_and_remove_role_grant_by_group_and_cross_domain(self): - self.skipTest('N/A: LDAP does not support multiple domains') - - def test_get_and_remove_role_grant_by_user_and_cross_domain(self): - self.skipTest('N/A: LDAP does not support multiple domains') - - def test_role_grant_by_group_and_cross_domain_project(self): - self.skipTest('N/A: LDAP does not support multiple domains') - - def test_role_grant_by_user_and_cross_domain_project(self): - self.skipTest('N/A: LDAP does not support multiple domains') - - def test_multi_role_grant_by_user_group_on_project_domain(self): - self.skipTest('N/A: LDAP does not support multiple domains') - - def test_delete_role_with_user_and_group_grants(self): - self.skipTest('Blocked by bug 1101287') - - def test_delete_user_with_group_project_domain_links(self): - self.skipTest('N/A: LDAP does not support multiple domains') - - def test_delete_group_with_user_project_domain_links(self): - self.skipTest('N/A: LDAP does not support multiple domains') - - def test_list_user_projects(self): - self.skipTest('Blocked by bug 1101287') - - def test_create_duplicate_user_name_in_different_domains(self): - self.skipTest('Blocked by bug 1101276') - - def test_create_duplicate_project_name_in_different_domains(self): - self.skipTest('Blocked by bug 1101276') - - def test_create_duplicate_group_name_in_different_domains(self): - self.skipTest( - 'N/A: LDAP does not support multiple domains') - - def test_move_user_between_domains(self): - self.skipTest('Blocked by bug 1101276') - - def test_move_user_between_domains_with_clashing_names_fails(self): - self.skipTest('Blocked by bug 1101276') - - def test_move_group_between_domains(self): - self.skipTest( - 'N/A: LDAP does not support multiple domains') - - def test_move_group_between_domains_with_clashing_names_fails(self): - self.skipTest('Blocked by bug 1101276') - - def test_move_project_between_domains(self): - self.skipTest('Blocked by bug 1101276') - - def test_move_project_between_domains_with_clashing_names_fails(self): - self.skipTest('Blocked by bug 1101276') - - def test_get_roles_for_user_and_domain(self): - self.skipTest('N/A: LDAP does not support multiple domains') - - def test_list_role_assignments_unfiltered(self): - self.skipTest('Blocked by bug 1195019') - - def test_multi_group_grants_on_project_domain(self): - self.skipTest('Blocked by bug 1101287') - - def test_list_group_members_missing_entry(self): - """List group members with deleted user. - - If a group has a deleted entry for a member, the non-deleted members - are returned. - - """ - - # Create a group - group_id = None - group = dict(name=uuid.uuid4().hex) - group_id = self.identity_api.create_group(group_id, group)['id'] - - # Create a couple of users and add them to the group. - user_id = None - user = dict(name=uuid.uuid4().hex, id=uuid.uuid4().hex) - user_1_id = self.identity_api.create_user(user_id, user)['id'] - - self.identity_api.add_user_to_group(user_1_id, group_id) - - user_id = None - user = dict(name=uuid.uuid4().hex, id=uuid.uuid4().hex) - user_2_id = self.identity_api.create_user(user_id, user)['id'] - - self.identity_api.add_user_to_group(user_2_id, group_id) - - # Delete user 2 - # NOTE(blk-u): need to go directly to user interface to keep from - # updating the group. - self.identity_api.driver.user.delete(user_2_id) - - # List group users and verify only user 1. - res = self.identity_api.list_users_in_group(group_id) - - self.assertEqual(len(res), 1, "Expected 1 entry (user_1)") - self.assertEqual(res[0]['id'], user_1_id, "Expected user 1 id") - - def test_list_domains(self): - domains = self.identity_api.list_domains() - self.assertEquals( - domains, - [assignment.DEFAULT_DOMAIN]) - - def test_authenticate_requires_simple_bind(self): - user = { - 'id': 'no_meta', - 'name': 'NO_META', - 'domain_id': test_backend.DEFAULT_DOMAIN_ID, - 'password': 'no_meta2', - 'enabled': True, - } - self.identity_api.create_user(user['id'], user) - self.identity_api.add_user_to_project(self.tenant_baz['id'], - user['id']) - self.identity_api.driver.user.LDAP_USER = None - self.identity_api.driver.user.LDAP_PASSWORD = None - - self.assertRaises(AssertionError, - self.identity_api.authenticate, - user_id=user['id'], - password=None) - - # (spzala)The group and domain crud tests below override the standard ones - # in test_backend.py so that we can exclude the update name test, since we - # do not yet support the update of either group or domain names with LDAP. - # In the tests below, the update is demonstrated by updating description. - # Refer to bug 1136403 for more detail. - def test_group_crud(self): - group = { - 'id': uuid.uuid4().hex, - 'domain_id': CONF.identity.default_domain_id, - 'name': uuid.uuid4().hex, - 'description': uuid.uuid4().hex} - self.identity_api.create_group(group['id'], group) - group_ref = self.identity_api.get_group(group['id']) - self.assertDictEqual(group_ref, group) - group['description'] = uuid.uuid4().hex - self.identity_api.update_group(group['id'], group) - group_ref = self.identity_api.get_group(group['id']) - self.assertDictEqual(group_ref, group) - - self.identity_api.delete_group(group['id']) - self.assertRaises(exception.GroupNotFound, - self.identity_api.get_group, - group['id']) - - -class LDAPIdentity(test.TestCase, BaseLDAPIdentity): - def setUp(self): - super(LDAPIdentity, self).setUp() - self._set_config() - self.clear_database() - - self.load_backends() - self.load_fixtures(default_fixtures) - - def test_configurable_allowed_project_actions(self): - tenant = {'id': 'fake1', 'name': 'fake1', 'enabled': True} - self.identity_api.create_project('fake1', tenant) - tenant_ref = self.identity_api.get_project('fake1') - self.assertEqual(tenant_ref['id'], 'fake1') - - tenant['enabled'] = False - self.identity_api.update_project('fake1', tenant) - - self.identity_api.delete_project('fake1') - self.assertRaises(exception.ProjectNotFound, - self.identity_api.get_project, - 'fake1') - - def test_configurable_forbidden_project_actions(self): - CONF.ldap.tenant_allow_create = False - CONF.ldap.tenant_allow_update = False - CONF.ldap.tenant_allow_delete = False - self.load_backends() - - tenant = {'id': 'fake1', 'name': 'fake1'} - self.assertRaises(exception.ForbiddenAction, - self.identity_api.create_project, - 'fake1', - tenant) - - self.tenant_bar['enabled'] = False - self.assertRaises(exception.ForbiddenAction, - self.identity_api.update_project, - self.tenant_bar['id'], - self.tenant_bar) - self.assertRaises(exception.ForbiddenAction, - self.identity_api.delete_project, - self.tenant_bar['id']) - - def test_configurable_allowed_role_actions(self): - role = {'id': 'fake1', 'name': 'fake1'} - self.identity_api.create_role('fake1', role) - role_ref = self.identity_api.get_role('fake1') - self.assertEqual(role_ref['id'], 'fake1') - - role['name'] = 'fake2' - self.identity_api.update_role('fake1', role) - - self.identity_api.delete_role('fake1') - self.assertRaises(exception.RoleNotFound, - self.identity_api.get_role, - 'fake1') - - def test_configurable_forbidden_role_actions(self): - CONF.ldap.role_allow_create = False - CONF.ldap.role_allow_update = False - CONF.ldap.role_allow_delete = False - self.load_backends() - - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.assertRaises(exception.ForbiddenAction, - self.identity_api.create_role, - role['id'], - role) - - self.role_member['name'] = uuid.uuid4().hex - self.assertRaises(exception.ForbiddenAction, - self.identity_api.update_role, - self.role_member['id'], - self.role_member) - - self.assertRaises(exception.ForbiddenAction, - self.identity_api.delete_role, - self.role_member['id']) - - def test_project_filter(self): - tenant_ref = self.identity_api.get_project(self.tenant_bar['id']) - self.assertDictEqual(tenant_ref, self.tenant_bar) - - CONF.ldap.tenant_filter = '(CN=DOES_NOT_MATCH)' - self.load_backends() - self.assertRaises(exception.ProjectNotFound, - self.identity_api.get_project, - self.tenant_bar['id']) - - def test_role_filter(self): - role_ref = self.identity_api.get_role(self.role_member['id']) - self.assertDictEqual(role_ref, self.role_member) - - CONF.ldap.role_filter = '(CN=DOES_NOT_MATCH)' - self.load_backends() - self.assertRaises(exception.RoleNotFound, - self.identity_api.get_role, - self.role_member['id']) - - def test_dumb_member(self): - CONF.ldap.use_dumb_member = True - CONF.ldap.dumb_member = 'cn=dumb,cn=example,cn=com' - self.clear_database() - self.load_backends() - self.load_fixtures(default_fixtures) - self.assertRaises(exception.UserNotFound, - self.identity_api.get_user, - 'dumb') - - def test_project_attribute_mapping(self): - CONF.ldap.tenant_name_attribute = 'ou' - CONF.ldap.tenant_desc_attribute = 'description' - CONF.ldap.tenant_enabled_attribute = 'enabled' - self.clear_database() - self.load_backends() - self.load_fixtures(default_fixtures) - tenant_ref = self.identity_api.get_project(self.tenant_baz['id']) - self.assertEqual(tenant_ref['id'], self.tenant_baz['id']) - self.assertEqual(tenant_ref['name'], self.tenant_baz['name']) - self.assertEqual( - tenant_ref['description'], - self.tenant_baz['description']) - self.assertEqual(tenant_ref['enabled'], self.tenant_baz['enabled']) - - CONF.ldap.tenant_name_attribute = 'description' - CONF.ldap.tenant_desc_attribute = 'ou' - self.load_backends() - tenant_ref = self.identity_api.get_project(self.tenant_baz['id']) - self.assertEqual(tenant_ref['id'], self.tenant_baz['id']) - self.assertEqual(tenant_ref['name'], self.tenant_baz['description']) - self.assertEqual(tenant_ref['description'], self.tenant_baz['name']) - self.assertEqual(tenant_ref['enabled'], self.tenant_baz['enabled']) - - def test_project_attribute_ignore(self): - CONF.ldap.tenant_attribute_ignore = ['name', - 'description', - 'enabled'] - self.clear_database() - self.load_backends() - self.load_fixtures(default_fixtures) - tenant_ref = self.identity_api.get_project(self.tenant_baz['id']) - self.assertEqual(tenant_ref['id'], self.tenant_baz['id']) - self.assertNotIn('name', tenant_ref) - self.assertNotIn('description', tenant_ref) - self.assertNotIn('enabled', tenant_ref) - - def test_role_attribute_mapping(self): - CONF.ldap.role_name_attribute = 'ou' - self.clear_database() - self.load_backends() - self.load_fixtures(default_fixtures) - role_ref = self.identity_api.get_role(self.role_member['id']) - self.assertEqual(role_ref['id'], self.role_member['id']) - self.assertEqual(role_ref['name'], self.role_member['name']) - - CONF.ldap.role_name_attribute = 'sn' - self.load_backends() - role_ref = self.identity_api.get_role(self.role_member['id']) - self.assertEqual(role_ref['id'], self.role_member['id']) - self.assertNotIn('name', role_ref) - - def test_role_attribute_ignore(self): - CONF.ldap.role_attribute_ignore = ['name'] - self.clear_database() - self.load_backends() - self.load_fixtures(default_fixtures) - role_ref = self.identity_api.get_role(self.role_member['id']) - self.assertEqual(role_ref['id'], self.role_member['id']) - self.assertNotIn('name', role_ref) - - def test_user_enable_attribute_mask(self): - CONF.ldap.user_enabled_attribute = 'enabled' - CONF.ldap.user_enabled_mask = 2 - CONF.ldap.user_enabled_default = 512 - self.clear_database() - user = {'id': 'fake1', 'name': 'fake1', 'enabled': True} - self.identity_api.create_user('fake1', user) - user_ref = self.identity_api.get_user('fake1') - self.assertEqual(user_ref['enabled'], True) - - user['enabled'] = False - self.identity_api.update_user('fake1', user) - user_ref = self.identity_api.get_user('fake1') - self.assertEqual(user_ref['enabled'], False) - - user['enabled'] = True - self.identity_api.update_user('fake1', user) - user_ref = self.identity_api.get_user('fake1') - self.assertEqual(user_ref['enabled'], True) - - def test_user_api_get_connection_no_user_password(self): - """Don't bind in case the user and password are blank.""" - self.config([test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf')]) - CONF.ldap.url = "fake://memory" - user_api = identity.backends.ldap.UserApi(CONF) - self.stubs.Set(fakeldap, 'FakeLdap', - self.mox.CreateMock(fakeldap.FakeLdap)) - # we have to track all calls on 'conn' to make sure that - # conn.simple_bind_s is not called - conn = self.mox.CreateMockAnything() - conn = fakeldap.FakeLdap(CONF.ldap.url).AndReturn(conn) - self.mox.ReplayAll() - - user_api.get_connection(user=None, password=None) - - def test_wrong_ldap_scope(self): - CONF.ldap.query_scope = uuid.uuid4().hex - self.assertRaisesRegexp( - ValueError, - 'Invalid LDAP scope: %s. *' % CONF.ldap.query_scope, - identity.backends.ldap.Identity) - - def test_wrong_alias_dereferencing(self): - CONF.ldap.alias_dereferencing = uuid.uuid4().hex - self.assertRaisesRegexp( - ValueError, - 'Invalid LDAP deref option: %s\.' % CONF.ldap.alias_dereferencing, - identity.backends.ldap.Identity) - - def test_user_extra_attribute_mapping(self): - CONF.ldap.user_additional_attribute_mapping = ['description:name'] - self.load_backends() - user = { - 'id': 'extra_attributes', - 'name': 'EXTRA_ATTRIBUTES', - 'password': 'extra', - } - self.identity_api.create_user(user['id'], user) - dn, attrs = self.identity_api.driver.user._ldap_get(user['id']) - self.assertTrue(user['name'] in attrs['description']) - - def test_parse_extra_attribute_mapping(self): - option_list = ['description:name', 'gecos:password', - 'fake:invalid', 'invalid1', 'invalid2:', - 'description:name:something'] - mapping = self.identity_api.driver.user._parse_extra_attrs(option_list) - expected_dict = {'description': 'name', 'gecos': 'password'} - self.assertDictEqual(expected_dict, mapping) - -# TODO(henry-nash): These need to be removed when the full LDAP implementation -# is submitted - see Bugs 1092187, 1101287, 1101276, 1101289 - - def test_domain_crud(self): - domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'enabled': True, 'description': uuid.uuid4().hex} - with self.assertRaises(exception.Forbidden): - self.identity_api.create_domain(domain['id'], domain) - with self.assertRaises(exception.Conflict): - self.identity_api.create_domain( - CONF.identity.default_domain_id, domain) - with self.assertRaises(exception.DomainNotFound): - self.identity_api.get_domain(domain['id']) - with self.assertRaises(exception.DomainNotFound): - domain['description'] = uuid.uuid4().hex - self.identity_api.update_domain(domain['id'], domain) - with self.assertRaises(exception.Forbidden): - self.identity_api.update_domain( - CONF.identity.default_domain_id, domain) - with self.assertRaises(exception.DomainNotFound): - self.identity_api.get_domain(domain['id']) - with self.assertRaises(exception.DomainNotFound): - self.identity_api.delete_domain(domain['id']) - with self.assertRaises(exception.Forbidden): - self.identity_api.delete_domain(CONF.identity.default_domain_id) - self.assertRaises(exception.DomainNotFound, - self.identity_api.get_domain, - domain['id']) - - def test_project_crud(self): - # NOTE(topol): LDAP implementation does not currently support the - # updating of a project name so this method override - # provides a different update test - project = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': CONF.identity.default_domain_id, - 'description': uuid.uuid4().hex - } - self.assignment_api.create_project(project['id'], project) - project_ref = self.assignment_api.get_project(project['id']) - - # NOTE(crazed): If running live test with emulation, there will be - # an enabled key in the project_ref. - if self.assignment_api.driver.project.enabled_emulation: - project['enabled'] = True - self.assertDictEqual(project_ref, project) - - project['description'] = uuid.uuid4().hex - self.identity_api.update_project(project['id'], project) - project_ref = self.identity_api.get_project(project['id']) - self.assertDictEqual(project_ref, project) - - self.identity_api.delete_project(project['id']) - self.assertRaises(exception.ProjectNotFound, - self.identity_api.get_project, - project['id']) - - def test_multi_role_grant_by_user_group_on_project_domain(self): - # This is a partial implementation of the standard test that - # is defined in test_backend.py. It omits both domain and - # group grants. since neither of these are yet supported by - # the ldap backend. - - role_list = [] - for _ in range(2): - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.identity_api.create_role(role['id'], role) - role_list.append(role) - - user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': CONF.identity.default_domain_id, - 'password': uuid.uuid4().hex, - 'enabled': True} - self.identity_api.create_user(user1['id'], user1) - project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, - 'domain_id': CONF.identity.default_domain_id} - self.identity_api.create_project(project1['id'], project1) - - self.identity_api.add_role_to_user_and_project( - user_id=user1['id'], - tenant_id=project1['id'], - role_id=role_list[0]['id']) - self.identity_api.add_role_to_user_and_project( - user_id=user1['id'], - tenant_id=project1['id'], - role_id=role_list[1]['id']) - - # Although list_grants are not yet supported, we can test the - # alternate way of getting back lists of grants, where user - # and group roles are combined. Only directly assigned user - # roles are available, since group grants are not yet supported - - combined_role_list = self.identity_api.get_roles_for_user_and_project( - user1['id'], project1['id']) - self.assertEquals(len(combined_role_list), 2) - self.assertIn(role_list[0]['id'], combined_role_list) - self.assertIn(role_list[1]['id'], combined_role_list) - - # Finally, although domain roles are not implemented, check we can - # issue the combined get roles call with benign results, since thus is - # used in token generation - - combined_role_list = self.identity_api.get_roles_for_user_and_domain( - user1['id'], CONF.identity.default_domain_id) - self.assertEquals(len(combined_role_list), 0) - - def test_list_projects_for_alternate_domain(self): - self.skipTest( - 'N/A: LDAP does not support multiple domains') - - -class LDAPIdentityEnabledEmulation(LDAPIdentity): - def setUp(self): - super(LDAPIdentityEnabledEmulation, self).setUp() - self.config([test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf'), - test.testsdir('backend_ldap.conf')]) - CONF.ldap.user_enabled_emulation = True - CONF.ldap.tenant_enabled_emulation = True - self.clear_database() - self.load_backends() - self.load_fixtures(default_fixtures) - for obj in [self.tenant_bar, self.tenant_baz, self.user_foo, - self.user_two, self.user_badguy]: - obj.setdefault('enabled', True) - - def test_project_crud(self): - # NOTE(topol): LDAPIdentityEnabledEmulation will create an - # enabled key in the project dictionary so this - # method override handles this side-effect - project = { - 'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': CONF.identity.default_domain_id, - 'description': uuid.uuid4().hex} - - self.identity_api.create_project(project['id'], project) - project_ref = self.identity_api.get_project(project['id']) - - # self.identity_api.create_project adds an enabled - # key with a value of True when LDAPIdentityEnabledEmulation - # is used so we now add this expected key to the project dictionary - project['enabled'] = True - self.assertDictEqual(project_ref, project) - - project['description'] = uuid.uuid4().hex - self.identity_api.update_project(project['id'], project) - project_ref = self.identity_api.get_project(project['id']) - self.assertDictEqual(project_ref, project) - - self.identity_api.delete_project(project['id']) - self.assertRaises(exception.ProjectNotFound, - self.identity_api.get_project, - project['id']) - - def test_user_crud(self): - user = { - 'id': uuid.uuid4().hex, - 'domain_id': CONF.identity.default_domain_id, - 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex} - self.identity_api.create_user(user['id'], user) - user['enabled'] = True - user_ref = self.identity_api.get_user(user['id']) - del user['password'] - user_ref_dict = dict((x, user_ref[x]) for x in user_ref) - self.assertDictEqual(user_ref_dict, user) - - user['password'] = uuid.uuid4().hex - self.identity_api.update_user(user['id'], user) - user_ref = self.identity_api.get_user(user['id']) - del user['password'] - user_ref_dict = dict((x, user_ref[x]) for x in user_ref) - self.assertDictEqual(user_ref_dict, user) - - self.identity_api.delete_user(user['id']) - self.assertRaises(exception.UserNotFound, - self.identity_api.get_user, - user['id']) - - def test_user_enable_attribute_mask(self): - self.skipTest( - "Enabled emulation conflicts with enabled mask") - - -class LdapIdentitySqlAssignment(sql.Base, test.TestCase, BaseLDAPIdentity): - - def _set_config(self): - self.config([test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf'), - test.testsdir('backend_ldap_sql.conf')]) - - def setUp(self): - self._set_config() - self.clear_database() - self.load_backends() - self.engine = self.get_engine() - sql.ModelBase.metadata.create_all(bind=self.engine) - self.load_fixtures(default_fixtures) - #defaulted by the data load - self.user_foo['enabled'] = True - - def tearDown(self): - sql.ModelBase.metadata.drop_all(bind=self.engine) - self.engine.dispose() - sql.set_global_engine(None) - - def test_domain_crud(self): - pass - - def test_list_domains(self): - domains = self.identity_api.list_domains() - self.assertEquals(domains, [assignment.DEFAULT_DOMAIN]) - - def test_project_filter(self): - self.skipTest( - 'N/A: Not part of SQL backend') - - def test_role_filter(self): - self.skipTest( - 'N/A: Not part of SQL backend') diff --git a/tests/test_backend_memcache.py b/tests/test_backend_memcache.py deleted file mode 100644 index 7516e0dd..00000000 --- a/tests/test_backend_memcache.py +++ /dev/null @@ -1,186 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 copy -import datetime -import uuid - -import memcache - -from keystone import test - -from keystone.common import utils -from keystone import exception -from keystone.openstack.common import jsonutils -from keystone.openstack.common import timeutils -from keystone import token -from keystone.token.backends import memcache as token_memcache - -import test_backend - - -class MemcacheClient(object): - """Replicates a tiny subset of memcached client interface.""" - - def __init__(self, *args, **kwargs): - """Ignores the passed in args.""" - self.cache = {} - self.reject_cas = False - - def add(self, key, value): - if self.get(key): - return False - return self.set(key, value) - - def append(self, key, value): - existing_value = self.get(key) - if existing_value: - self.set(key, existing_value + value) - return True - return False - - def check_key(self, key): - if not isinstance(key, str): - raise memcache.Client.MemcachedStringEncodingError() - - def gets(self, key): - #Call self.get() since we don't really do 'cas' here. - return self.get(key) - - def get(self, key): - """Retrieves the value for a key or None.""" - self.check_key(key) - obj = self.cache.get(key) - now = utils.unixtime(timeutils.utcnow()) - if obj and (obj[1] == 0 or obj[1] > now): - # NOTE(morganfainberg): This behaves more like memcache - # actually does and prevents modification of the passed in - # reference from affecting the cached back-end data. This makes - # tests a little easier to write. - # - # The back-end store should only change with an explicit - # set/delete/append/etc - data_copy = copy.deepcopy(obj[0]) - return data_copy - - def set(self, key, value, time=0): - """Sets the value for a key.""" - self.check_key(key) - # NOTE(morganfainberg): This behaves more like memcache - # actually does and prevents modification of the passed in - # reference from affecting the cached back-end data. This makes - # tests a little easier to write. - # - # The back-end store should only change with an explicit - # set/delete/append/etc - data_copy = copy.deepcopy(value) - self.cache[key] = (data_copy, time) - return True - - def cas(self, key, value, time=0, min_compress_len=0): - # Call self.set() since we don't really do 'cas' here. - if self.reject_cas: - return False - return self.set(key, value, time=time) - - def reset_cas(self): - #This is a stub for the memcache client reset_cas function. - pass - - def delete(self, key): - self.check_key(key) - try: - del self.cache[key] - except KeyError: - #NOTE(bcwaldon): python-memcached always returns the same value - pass - - -class MemcacheToken(test.TestCase, test_backend.TokenTests): - def setUp(self): - super(MemcacheToken, self).setUp() - fake_client = MemcacheClient() - self.token_man = token.Manager() - self.token_man.driver = token_memcache.Token(client=fake_client) - self.token_api = self.token_man - - def test_create_unicode_token_id(self): - token_id = unicode(self._create_token_id()) - data = {'id': token_id, 'a': 'b', - 'user': {'id': 'testuserid'}} - self.token_api.create_token(token_id, data) - self.token_api.get_token(token_id) - - def test_create_unicode_user_id(self): - token_id = self._create_token_id() - user_id = unicode(uuid.uuid4().hex) - data = {'id': token_id, 'a': 'b', - 'user': {'id': user_id}} - self.token_api.create_token(token_id, data) - self.token_api.get_token(token_id) - - def test_list_tokens_unicode_user_id(self): - user_id = unicode(uuid.uuid4().hex) - self.token_api.list_tokens(user_id) - - def test_flush_expired_token(self): - with self.assertRaises(exception.NotImplemented): - self.token_api.flush_expired_tokens() - - def test_cleanup_user_index_on_create(self): - valid_token_id = uuid.uuid4().hex - second_valid_token_id = uuid.uuid4().hex - expired_token_id = uuid.uuid4().hex - user_id = unicode(uuid.uuid4().hex) - - expire_delta = datetime.timedelta(seconds=86400) - - valid_data = {'id': valid_token_id, 'a': 'b', - 'user': {'id': user_id}} - second_valid_data = {'id': second_valid_token_id, 'a': 'b', - 'user': {'id': user_id}} - expired_data = {'id': expired_token_id, 'a': 'b', - 'user': {'id': user_id}} - self.token_api.create_token(valid_token_id, valid_data) - self.token_api.create_token(expired_token_id, expired_data) - # NOTE(morganfainberg): Directly access the data cache since we need to - # get expired tokens as well as valid tokens. token_api.list_tokens() - # will not return any expired tokens in the list. - user_key = self.token_api.driver._prefix_user_id(user_id) - user_record = self.token_api.driver.client.get(user_key) - user_token_list = jsonutils.loads('[%s]' % user_record) - self.assertEquals(len(user_token_list), 2) - expired_token_ptk = self.token_api.driver._prefix_token_id( - expired_token_id) - expired_token = self.token_api.driver.client.get(expired_token_ptk) - expired_token['expires'] = (timeutils.utcnow() - expire_delta) - self.token_api.driver.client.set(expired_token_ptk, expired_token) - - self.token_api.create_token(second_valid_token_id, second_valid_data) - user_record = self.token_api.driver.client.get(user_key) - user_token_list = jsonutils.loads('[%s]' % user_record) - self.assertEquals(len(user_token_list), 2) - - def test_cas_failure(self): - self.token_api.driver.client.reject_cas = True - token_id = uuid.uuid4().hex - user_id = unicode(uuid.uuid4().hex) - user_key = self.token_api.driver._prefix_user_id(user_id) - token_data = jsonutils.dumps(token_id) - self.assertRaises( - exception.UnexpectedError, - self.token_api.driver._update_user_list_with_cas, - user_key, token_data) diff --git a/tests/test_backend_pam.py b/tests/test_backend_pam.py deleted file mode 100644 index b66faa9c..00000000 --- a/tests/test_backend_pam.py +++ /dev/null @@ -1,68 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 uuid - -from keystone import test - -from keystone import config -from keystone.identity.backends import pam as identity_pam - - -CONF = config.CONF -DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id - - -class PamIdentity(test.TestCase): - def setUp(self): - super(PamIdentity, self).setUp() - self.config([test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf'), - test.testsdir('backend_pam.conf')]) - self.identity_api = identity_pam.PamIdentity() - id = uuid.uuid4().hex - self.tenant_in = {'id': id, 'name': id} - self.user_in = {'id': CONF.pam.userid, 'name': CONF.pam.userid} - - def test_get_project(self): - tenant_out = self.identity_api.get_project(self.tenant_in['id']) - self.assertDictEqual(self.tenant_in, tenant_out) - - def test_get_project_by_name(self): - tenant_in_name = self.tenant_in['name'] - tenant_out = self.identity_api.get_project_by_name( - tenant_in_name, DEFAULT_DOMAIN_ID) - self.assertDictEqual(self.tenant_in, tenant_out) - - def test_get_user(self): - user_out = self.identity_api.get_user(self.user_in['id']) - self.assertDictEqual(self.user_in, user_out) - - def test_get_user_by_name(self): - user_out = self.identity_api.get_user_by_name( - self.user_in['name'], DEFAULT_DOMAIN_ID) - self.assertDictEqual(self.user_in, user_out) - - def test_get_metadata_for_non_root(self): - metadata_out = self.identity_api._get_metadata(self.user_in['id'], - self.tenant_in['id']) - self.assertDictEqual({}, metadata_out) - - def test_get_metadata_for_root(self): - metadata = {'is_admin': True} - metadata_out = self.identity_api._get_metadata('root', - self.tenant_in['id']) - self.assertDictEqual(metadata, metadata_out) diff --git a/tests/test_backend_sql.py b/tests/test_backend_sql.py deleted file mode 100644 index 89276e86..00000000 --- a/tests/test_backend_sql.py +++ /dev/null @@ -1,416 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 uuid - -import sqlalchemy - -from keystone import test - -from keystone.common import sql -from keystone import config -from keystone import exception - -import default_fixtures -import test_backend - - -CONF = config.CONF -DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id - - -class SqlTests(test.TestCase, sql.Base): - - def setUp(self): - super(SqlTests, self).setUp() - self.config([test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf'), - test.testsdir('backend_sql.conf')]) - - self.load_backends() - - # create tables and keep an engine reference for cleanup. - # this must be done after the models are loaded by the managers. - self.engine = self.get_engine() - sql.ModelBase.metadata.create_all(bind=self.engine) - - # populate the engine with tables & fixtures - self.load_fixtures(default_fixtures) - #defaulted by the data load - self.user_foo['enabled'] = True - - def tearDown(self): - sql.ModelBase.metadata.drop_all(bind=self.engine) - self.engine.dispose() - sql.set_global_engine(None) - super(SqlTests, self).tearDown() - - -class SqlModels(SqlTests): - def setUp(self): - super(SqlModels, self).setUp() - - self.metadata = sql.ModelBase.metadata - self.metadata.bind = self.engine - - def select_table(self, name): - table = sqlalchemy.Table(name, - self.metadata, - autoload=True) - s = sqlalchemy.select([table]) - return s - - def assertExpectedSchema(self, table, cols): - table = self.select_table(table) - for col, type_, length in cols: - self.assertIsInstance(table.c[col].type, type_) - if length: - self.assertEquals(table.c[col].type.length, length) - - def test_user_model(self): - cols = (('id', sql.String, 64), - ('name', sql.String, 64), - ('password', sql.String, 128), - ('domain_id', sql.String, 64), - ('enabled', sql.Boolean, None), - ('extra', sql.JsonBlob, None)) - self.assertExpectedSchema('user', cols) - - def test_group_model(self): - cols = (('id', sql.String, 64), - ('name', sql.String, 64), - ('description', sql.Text, None), - ('domain_id', sql.String, 64), - ('extra', sql.JsonBlob, None)) - self.assertExpectedSchema('group', cols) - - def test_domain_model(self): - cols = (('id', sql.String, 64), - ('name', sql.String, 64), - ('enabled', sql.Boolean, None)) - self.assertExpectedSchema('domain', cols) - - def test_project_model(self): - cols = (('id', sql.String, 64), - ('name', sql.String, 64), - ('description', sql.Text, None), - ('domain_id', sql.String, 64), - ('enabled', sql.Boolean, None), - ('extra', sql.JsonBlob, None)) - self.assertExpectedSchema('project', cols) - - def test_role_model(self): - cols = (('id', sql.String, 64), - ('name', sql.String, 255)) - self.assertExpectedSchema('role', cols) - - def test_user_project_metadata_model(self): - cols = (('user_id', sql.String, 64), - ('project_id', sql.String, 64), - ('data', sql.JsonBlob, None)) - self.assertExpectedSchema('user_project_metadata', cols) - - def test_user_domain_metadata_model(self): - cols = (('user_id', sql.String, 64), - ('domain_id', sql.String, 64), - ('data', sql.JsonBlob, None)) - self.assertExpectedSchema('user_domain_metadata', cols) - - def test_group_project_metadata_model(self): - cols = (('group_id', sql.String, 64), - ('project_id', sql.String, 64), - ('data', sql.JsonBlob, None)) - self.assertExpectedSchema('group_project_metadata', cols) - - def test_group_domain_metadata_model(self): - cols = (('group_id', sql.String, 64), - ('domain_id', sql.String, 64), - ('data', sql.JsonBlob, None)) - self.assertExpectedSchema('group_domain_metadata', cols) - - def test_user_group_membership(self): - cols = (('group_id', sql.String, 64), - ('user_id', sql.String, 64)) - self.assertExpectedSchema('user_group_membership', cols) - - -class SqlIdentity(SqlTests, test_backend.IdentityTests): - def test_password_hashed(self): - session = self.identity_api.get_session() - user_ref = self.identity_api._get_user(session, self.user_foo['id']) - self.assertNotEqual(user_ref['password'], self.user_foo['password']) - - def test_delete_user_with_project_association(self): - user = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': uuid.uuid4().hex} - self.identity_api.create_user(user['id'], user) - self.identity_api.add_user_to_project(self.tenant_bar['id'], - user['id']) - self.identity_api.delete_user(user['id']) - self.assertRaises(exception.UserNotFound, - self.identity_api.get_projects_for_user, - user['id']) - - def test_create_null_user_name(self): - user = {'id': uuid.uuid4().hex, - 'name': None, - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': uuid.uuid4().hex} - self.assertRaises(exception.ValidationError, - self.identity_api.create_user, - user['id'], - user) - self.assertRaises(exception.UserNotFound, - self.identity_api.get_user, - user['id']) - self.assertRaises(exception.UserNotFound, - self.identity_api.get_user_by_name, - user['name'], - DEFAULT_DOMAIN_ID) - - def test_create_null_project_name(self): - tenant = {'id': uuid.uuid4().hex, - 'name': None, - 'domain_id': DEFAULT_DOMAIN_ID} - self.assertRaises(exception.ValidationError, - self.identity_api.create_project, - tenant['id'], - tenant) - self.assertRaises(exception.ProjectNotFound, - self.identity_api.get_project, - tenant['id']) - self.assertRaises(exception.ProjectNotFound, - self.identity_api.get_project_by_name, - tenant['name'], - DEFAULT_DOMAIN_ID) - - def test_create_null_role_name(self): - role = {'id': uuid.uuid4().hex, - 'name': None} - self.assertRaises(exception.Conflict, - self.identity_api.create_role, - role['id'], - role) - self.assertRaises(exception.RoleNotFound, - self.identity_api.get_role, - role['id']) - - def test_delete_project_with_user_association(self): - user = {'id': 'fake', - 'name': 'fakeuser', - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': 'passwd'} - self.identity_api.create_user('fake', user) - self.identity_api.add_user_to_project(self.tenant_bar['id'], - user['id']) - self.identity_api.delete_project(self.tenant_bar['id']) - tenants = self.identity_api.get_projects_for_user(user['id']) - self.assertEquals(tenants, []) - - def test_metadata_removed_on_delete_user(self): - # A test to check that the internal representation - # or roles is correctly updated when a user is deleted - user = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': 'passwd'} - self.identity_api.create_user(user['id'], user) - role = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex} - self.identity_api.create_role(role['id'], role) - self.identity_api.add_role_to_user_and_project( - user['id'], - self.tenant_bar['id'], - role['id']) - self.identity_api.delete_user(user['id']) - - # Now check whether the internal representation of roles - # has been deleted - self.assertRaises(exception.MetadataNotFound, - self.assignment_api._get_metadata, - user['id'], - self.tenant_bar['id']) - - def test_metadata_removed_on_delete_project(self): - # A test to check that the internal representation - # or roles is correctly updated when a project is deleted - user = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': 'passwd'} - self.identity_api.create_user(user['id'], user) - role = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex} - self.identity_api.create_role(role['id'], role) - self.identity_api.add_role_to_user_and_project( - user['id'], - self.tenant_bar['id'], - role['id']) - self.identity_api.delete_project(self.tenant_bar['id']) - - # Now check whether the internal representation of roles - # has been deleted - self.assertRaises(exception.MetadataNotFound, - self.assignment_api._get_metadata, - user['id'], - self.tenant_bar['id']) - - def test_update_project_returns_extra(self): - """This tests for backwards-compatibility with an essex/folsom bug. - - Non-indexed attributes were returned in an 'extra' attribute, instead - of on the entity itself; for consistency and backwards compatibility, - those attributes should be included twice. - - This behavior is specific to the SQL driver. - - """ - tenant_id = uuid.uuid4().hex - arbitrary_key = uuid.uuid4().hex - arbitrary_value = uuid.uuid4().hex - tenant = { - 'id': tenant_id, - 'name': uuid.uuid4().hex, - 'domain_id': DEFAULT_DOMAIN_ID, - arbitrary_key: arbitrary_value} - ref = self.identity_api.create_project(tenant_id, tenant) - self.assertEqual(arbitrary_value, ref[arbitrary_key]) - self.assertIsNone(ref.get('extra')) - - tenant['name'] = uuid.uuid4().hex - ref = self.identity_api.update_project(tenant_id, tenant) - self.assertEqual(arbitrary_value, ref[arbitrary_key]) - self.assertEqual(arbitrary_value, ref['extra'][arbitrary_key]) - - def test_update_user_returns_extra(self): - """This tests for backwards-compatibility with an essex/folsom bug. - - Non-indexed attributes were returned in an 'extra' attribute, instead - of on the entity itself; for consistency and backwards compatibility, - those attributes should be included twice. - - This behavior is specific to the SQL driver. - - """ - user_id = uuid.uuid4().hex - arbitrary_key = uuid.uuid4().hex - arbitrary_value = uuid.uuid4().hex - user = { - 'id': user_id, - 'name': uuid.uuid4().hex, - 'domain_id': DEFAULT_DOMAIN_ID, - 'password': uuid.uuid4().hex, - arbitrary_key: arbitrary_value} - ref = self.identity_api.create_user(user_id, user) - self.assertEqual(arbitrary_value, ref[arbitrary_key]) - self.assertIsNone(ref.get('password')) - self.assertIsNone(ref.get('extra')) - - user['name'] = uuid.uuid4().hex - user['password'] = uuid.uuid4().hex - ref = self.identity_api.update_user(user_id, user) - self.assertIsNone(ref.get('password')) - self.assertIsNone(ref['extra'].get('password')) - self.assertEqual(arbitrary_value, ref[arbitrary_key]) - self.assertEqual(arbitrary_value, ref['extra'][arbitrary_key]) - - -class SqlTrust(SqlTests, test_backend.TrustTests): - pass - - -class SqlToken(SqlTests, test_backend.TokenTests): - pass - - -class SqlCatalog(SqlTests, test_backend.CatalogTests): - def test_malformed_catalog_throws_error(self): - service = { - 'id': uuid.uuid4().hex, - 'type': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'description': uuid.uuid4().hex, - } - self.catalog_api.create_service(service['id'], service.copy()) - - malformed_url = "http://192.168.1.104:$(compute_port)s/v2/$(tenant)s" - endpoint = { - 'id': uuid.uuid4().hex, - 'region': uuid.uuid4().hex, - 'service_id': service['id'], - 'interface': 'public', - 'url': malformed_url, - } - self.catalog_api.create_endpoint(endpoint['id'], endpoint.copy()) - - with self.assertRaises(exception.MalformedEndpoint): - self.catalog_api.get_catalog('fake-user', 'fake-tenant') - - def test_get_catalog_with_empty_public_url(self): - service = { - 'id': uuid.uuid4().hex, - 'type': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'description': uuid.uuid4().hex, - } - self.catalog_api.create_service(service['id'], service.copy()) - - endpoint = { - 'id': uuid.uuid4().hex, - 'region': uuid.uuid4().hex, - 'interface': 'public', - 'url': '', - 'service_id': service['id'], - } - self.catalog_api.create_endpoint(endpoint['id'], endpoint.copy()) - - catalog = self.catalog_api.get_catalog('user', 'tenant') - catalog_endpoint = catalog[endpoint['region']][service['type']] - self.assertEqual(catalog_endpoint['name'], service['name']) - self.assertEqual(catalog_endpoint['id'], endpoint['id']) - self.assertEqual(catalog_endpoint['publicURL'], '') - self.assertIsNone(catalog_endpoint.get('adminURL')) - self.assertIsNone(catalog_endpoint.get('internalURL')) - - def test_create_endpoint_400(self): - service = { - 'id': uuid.uuid4().hex, - 'type': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'description': uuid.uuid4().hex, - } - self.catalog_api.create_service(service['id'], service.copy()) - - endpoint = { - 'id': uuid.uuid4().hex, - 'region': "0" * 256, - 'service_id': service['id'], - 'interface': 'public', - 'url': uuid.uuid4().hex, - } - - with self.assertRaises(exception.StringLengthExceeded): - self.catalog_api.create_endpoint(endpoint['id'], endpoint.copy()) - - -class SqlPolicy(SqlTests, test_backend.PolicyTests): - pass - - -class SqlInheritance(SqlTests, test_backend.InheritanceTests): - pass diff --git a/tests/test_backend_templated.py b/tests/test_backend_templated.py deleted file mode 100644 index bfa19192..00000000 --- a/tests/test_backend_templated.py +++ /dev/null @@ -1,67 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 os - -from keystone import test - -from keystone import exception - -import default_fixtures -import test_backend - -DEFAULT_CATALOG_TEMPLATES = os.path.abspath(os.path.join( - os.path.dirname(__file__), - 'default_catalog.templates')) - - -class TestTemplatedCatalog(test.TestCase, test_backend.CatalogTests): - - DEFAULT_FIXTURE = { - 'RegionOne': { - 'compute': { - 'adminURL': 'http://localhost:8774/v1.1/bar', - 'publicURL': 'http://localhost:8774/v1.1/bar', - 'internalURL': 'http://localhost:8774/v1.1/bar', - 'name': "'Compute Service'", - 'id': '2' - }, - 'identity': { - 'adminURL': 'http://localhost:35357/v2.0', - 'publicURL': 'http://localhost:5000/v2.0', - 'internalURL': 'http://localhost:35357/v2.0', - 'name': "'Identity Service'", - 'id': '1' - } - } - } - - def setUp(self): - super(TestTemplatedCatalog, self).setUp() - self.opt_in_group('catalog', template_file=DEFAULT_CATALOG_TEMPLATES) - self.load_backends() - self.load_fixtures(default_fixtures) - - def test_get_catalog(self): - catalog_ref = self.catalog_api.get_catalog('foo', 'bar') - self.assertDictEqual(catalog_ref, self.DEFAULT_FIXTURE) - - def test_malformed_catalog_throws_error(self): - (self.catalog_api.driver.templates - ['RegionOne']['compute']['adminURL']) = \ - 'http://localhost:$(compute_port)s/v1.1/$(tenant)s' - with self.assertRaises(exception.MalformedEndpoint): - self.catalog_api.get_catalog('fake-user', 'fake-tenant') diff --git a/tests/test_catalog.py b/tests/test_catalog.py deleted file mode 100644 index 3c00b1e8..00000000 --- a/tests/test_catalog.py +++ /dev/null @@ -1,77 +0,0 @@ -import uuid - -import test_content_types - - -BASE_URL = 'http://127.0.0.1:35357/v2' - - -class V2CatalogTestCase(test_content_types.RestfulTestCase): - def setUp(self): - super(V2CatalogTestCase, self).setUp() - self.service_id = uuid.uuid4().hex - self.service = self.new_service_ref() - self.service['id'] = self.service_id - self.catalog_api.create_service( - self.service_id, - self.service.copy()) - - def new_ref(self): - """Populates a ref with attributes common to all API entities.""" - return { - 'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'description': uuid.uuid4().hex, - 'enabled': True} - - def new_service_ref(self): - ref = self.new_ref() - ref['type'] = uuid.uuid4().hex - return ref - - def _get_token_id(self, r): - """Applicable only to JSON.""" - return r.result['access']['token']['id'] - - def assertValidErrorResponse(self, response): - self.assertEqual(response.status_code, 400) - - def _endpoint_create(self, expected_status=200, missing_param=None): - path = '/v2.0/endpoints' - body = { - "endpoint": { - "adminurl": "http://localhost:8080", - "service_id": self.service_id, - "region": "regionOne", - "internalurl": "http://localhost:8080", - "publicurl": "http://localhost:8080" - } - } - if missing_param: - body['endpoint'][missing_param] = None - r = self.admin_request(method='POST', token=self.get_scoped_token(), - path=path, expected_status=expected_status, - body=body) - return body, r - - def test_endpoint_create(self): - req_body, response = self._endpoint_create(expected_status=200) - self.assertTrue('endpoint' in response.result) - self.assertTrue('id' in response.result['endpoint']) - for field, value in req_body['endpoint'].iteritems(): - self.assertEqual(response.result['endpoint'][field], value) - - def test_endpoint_create_with_missing_adminurl(self): - req_body, response = self._endpoint_create(expected_status=200, - missing_param='adminurl') - self.assertEqual(response.status_code, 200) - - def test_endpoint_create_with_missing_internalurl(self): - req_body, response = self._endpoint_create(expected_status=200, - missing_param='internalurl') - self.assertEqual(response.status_code, 200) - - def test_endpoint_create_with_missing_publicurl(self): - req_body, response = self._endpoint_create(expected_status=400, - missing_param='publicurl') - self.assertValidErrorResponse(response) diff --git a/tests/test_cert_setup.py b/tests/test_cert_setup.py deleted file mode 100644 index e6c395e9..00000000 --- a/tests/test_cert_setup.py +++ /dev/null @@ -1,101 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 os -import shutil - -from keystone import test - -from keystone.common import openssl -from keystone import exception -from keystone import token - -import default_fixtures - - -ROOTDIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -SSLDIR = "%s/tests/ssl/" % ROOTDIR -CONF = test.CONF -DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id - - -def rootdir(*p): - return os.path.join(SSLDIR, *p) - - -CERTDIR = rootdir("certs") -KEYDIR = rootdir("private") - - -class CertSetupTestCase(test.TestCase): - - def setUp(self): - super(CertSetupTestCase, self).setUp() - CONF.signing.certfile = os.path.join(CERTDIR, 'signing_cert.pem') - CONF.signing.ca_certs = os.path.join(CERTDIR, "ca.pem") - CONF.signing.ca_key = os.path.join(CERTDIR, "cakey.pem") - CONF.signing.keyfile = os.path.join(KEYDIR, "signing_key.pem") - - CONF.ssl.ca_certs = CONF.signing.ca_certs - CONF.ssl.ca_key = CONF.signing.ca_key - - CONF.ssl.certfile = os.path.join(CERTDIR, 'keystone.pem') - CONF.ssl.keyfile = os.path.join(KEYDIR, 'keystonekey.pem') - - self.load_backends() - self.load_fixtures(default_fixtures) - self.controller = token.controllers.Auth() - - def test_can_handle_missing_certs(self): - self.opt_in_group('signing', certfile='invalid') - user = { - 'id': 'fake1', - 'name': 'fake1', - 'password': 'fake1', - 'domain_id': DEFAULT_DOMAIN_ID - } - body_dict = { - 'passwordCredentials': { - 'userId': user['id'], - 'password': user['password'], - }, - } - self.identity_api.create_user(user['id'], user) - self.assertRaises(exception.UnexpectedError, - self.controller.authenticate, - {}, body_dict) - - def test_create_pki_certs(self): - pki = openssl.ConfigurePKI(None, None) - pki.run() - self.assertTrue(os.path.exists(CONF.signing.certfile)) - self.assertTrue(os.path.exists(CONF.signing.ca_certs)) - self.assertTrue(os.path.exists(CONF.signing.keyfile)) - - def test_create_ssl_certs(self): - ssl = openssl.ConfigureSSL(None, None) - ssl.run() - self.assertTrue(os.path.exists(CONF.ssl.ca_certs)) - self.assertTrue(os.path.exists(CONF.ssl.certfile)) - self.assertTrue(os.path.exists(CONF.ssl.keyfile)) - - def tearDown(self): - try: - shutil.rmtree(rootdir(SSLDIR)) - except OSError: - pass - super(CertSetupTestCase, self).tearDown() diff --git a/tests/test_config.py b/tests/test_config.py deleted file mode 100644 index 3165a4f4..00000000 --- a/tests/test_config.py +++ /dev/null @@ -1,19 +0,0 @@ -from keystone import test - -from keystone import config -from keystone import exception - - -CONF = config.CONF - - -class ConfigTestCase(test.TestCase): - def test_paste_config(self): - self.assertEqual(config.find_paste_config(), - test.etcdir('keystone-paste.ini')) - self.opt_in_group('paste_deploy', config_file='XYZ') - self.assertRaises(exception.PasteConfigNotFound, - config.find_paste_config) - self.opt_in_group('paste_deploy', config_file='') - self.assertEqual(config.find_paste_config(), - test.etcdir('keystone.conf.sample')) diff --git a/tests/test_content_types.py b/tests/test_content_types.py deleted file mode 100644 index ebb5dcef..00000000 --- a/tests/test_content_types.py +++ /dev/null @@ -1,1104 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 io -import uuid - -from lxml import etree -import webtest - -from keystone import test - -from keystone.common import extension -from keystone.common import serializer -from keystone.openstack.common import jsonutils - -import default_fixtures - - -class RestfulTestCase(test.TestCase): - """Performs restful tests against the WSGI app over HTTP. - - This class launches public & admin WSGI servers for every test, which can - be accessed by calling ``public_request()`` or ``admin_request()``, - respectfully. - - ``restful_request()`` and ``request()`` methods are also exposed if you - need to bypass restful conventions or access HTTP details in your test - implementation. - - Three new asserts are provided: - - * ``assertResponseSuccessful``: called automatically for every request - unless an ``expected_status`` is provided - * ``assertResponseStatus``: called instead of ``assertResponseSuccessful``, - if an ``expected_status`` is provided - * ``assertValidResponseHeaders``: validates that the response headers - appear as expected - - Requests are automatically serialized according to the defined - ``content_type``. Responses are automatically deserialized as well, and - available in the ``response.body`` attribute. The original body content is - available in the ``response.raw`` attribute. - - """ - - # default content type to test - content_type = 'json' - - def setUp(self): - super(RestfulTestCase, self).setUp() - - self.load_backends() - self.load_fixtures(default_fixtures) - - self.public_app = webtest.TestApp( - self.loadapp('keystone', name='main')) - self.admin_app = webtest.TestApp( - self.loadapp('keystone', name='admin')) - - # TODO(termie): add an admin user to the fixtures and use that user - # override the fixtures, for now - self.metadata_foobar = self.identity_api.add_role_to_user_and_project( - self.user_foo['id'], - self.tenant_bar['id'], - self.role_admin['id']) - - def tearDown(self): - """Kill running servers and release references to avoid leaks.""" - self.public_app = None - self.admin_app = None - super(RestfulTestCase, self).tearDown() - - def request(self, app, path, body=None, headers=None, token=None, - expected_status=None, **kwargs): - if headers: - headers = dict([(str(k), str(v)) for k, v in headers.iteritems()]) - else: - headers = {} - - if token: - headers['X-Auth-Token'] = str(token) - - # setting body this way because of: - # https://github.com/Pylons/webtest/issues/71 - if body: - kwargs['body_file'] = io.BytesIO(body) - - # sets environ['REMOTE_ADDR'] - kwargs.setdefault('remote_addr', 'localhost') - - response = app.request(path, headers=headers, - status=expected_status, **kwargs) - - return response - - def assertResponseSuccessful(self, response): - """Asserts that a status code lies inside the 2xx range. - - :param response: :py:class:`httplib.HTTPResponse` to be - verified to have a status code between 200 and 299. - - example:: - - self.assertResponseSuccessful(response, 203) - """ - self.assertTrue( - response.status_code >= 200 and response.status_code <= 299, - 'Status code %d is outside of the expected range (2xx)\n\n%s' % - (response.status, response.body)) - - def assertResponseStatus(self, response, expected_status): - """Asserts a specific status code on the response. - - :param response: :py:class:`httplib.HTTPResponse` - :param assert_status: The specific ``status`` result expected - - example:: - - self.assertResponseStatus(response, 203) - """ - self.assertEqual( - response.status_code, - expected_status, - 'Status code %s is not %s, as expected)\n\n%s' % - (response.status_code, expected_status, response.body)) - - def assertValidResponseHeaders(self, response): - """Ensures that response headers appear as expected.""" - self.assertIn('X-Auth-Token', response.headers.get('Vary')) - - def _to_content_type(self, body, headers, content_type=None): - """Attempt to encode JSON and XML automatically.""" - content_type = content_type or self.content_type - - if content_type == 'json': - headers['Accept'] = 'application/json' - if body: - headers['Content-Type'] = 'application/json' - return jsonutils.dumps(body) - elif content_type == 'xml': - headers['Accept'] = 'application/xml' - if body: - headers['Content-Type'] = 'application/xml' - return serializer.to_xml(body) - - def _from_content_type(self, response, content_type=None): - """Attempt to decode JSON and XML automatically, if detected.""" - content_type = content_type or self.content_type - - if response.body is not None and response.body.strip(): - # if a body is provided, a Content-Type is also expected - header = response.headers.get('Content-Type', None) - self.assertIn(content_type, header) - - if content_type == 'json': - response.result = jsonutils.loads(response.body) - elif content_type == 'xml': - response.result = etree.fromstring(response.body) - - def restful_request(self, method='GET', headers=None, body=None, - content_type=None, **kwargs): - """Serializes/deserializes json/xml as request/response body. - - .. WARNING:: - - * Existing Accept header will be overwritten. - * Existing Content-Type header will be overwritten. - - """ - # Initialize headers dictionary - headers = {} if not headers else headers - - body = self._to_content_type(body, headers, content_type) - - # Perform the HTTP request/response - response = self.request(method=method, headers=headers, body=body, - **kwargs) - - self._from_content_type(response, content_type) - - # we can save some code & improve coverage by always doing this - if method != 'HEAD' and response.status_code >= 400: - self.assertValidErrorResponse(response) - - # Contains the decoded response.body - return response - - def _request(self, convert=True, **kwargs): - if convert: - response = self.restful_request(**kwargs) - else: - response = self.request(**kwargs) - - self.assertValidResponseHeaders(response) - return response - - def public_request(self, **kwargs): - return self._request(app=self.public_app, **kwargs) - - def admin_request(self, **kwargs): - return self._request(app=self.admin_app, **kwargs) - - def _get_token(self, body): - """Convenience method so that we can test authenticated requests.""" - r = self.public_request(method='POST', path='/v2.0/tokens', body=body) - return self._get_token_id(r) - - def get_unscoped_token(self): - """Convenience method so that we can test authenticated requests.""" - return self._get_token({ - 'auth': { - 'passwordCredentials': { - 'username': self.user_foo['name'], - 'password': self.user_foo['password'], - }, - }, - }) - - def get_scoped_token(self, tenant_id=None): - """Convenience method so that we can test authenticated requests.""" - if not tenant_id: - tenant_id = self.tenant_bar['id'] - return self._get_token({ - 'auth': { - 'passwordCredentials': { - 'username': self.user_foo['name'], - 'password': self.user_foo['password'], - }, - 'tenantId': tenant_id, - }, - }) - - def _get_token_id(self, r): - """Helper method to return a token ID from a response. - - This needs to be overridden by child classes for on their content type. - - """ - raise NotImplementedError() - - -class CoreApiTests(object): - def assertValidError(self, error): - """Applicable to XML and JSON.""" - self.assertIsNotNone(error.get('code')) - self.assertIsNotNone(error.get('title')) - self.assertIsNotNone(error.get('message')) - - def assertValidVersion(self, version): - """Applicable to XML and JSON. - - However, navigating links and media-types differs between content - types so they need to be validated separately. - - """ - self.assertIsNotNone(version) - self.assertIsNotNone(version.get('id')) - self.assertIsNotNone(version.get('status')) - self.assertIsNotNone(version.get('updated')) - - def assertValidExtension(self, extension): - """Applicable to XML and JSON. - - However, navigating extension links differs between content types. - They need to be validated separately with assertValidExtensionLink. - - """ - self.assertIsNotNone(extension) - self.assertIsNotNone(extension.get('name')) - self.assertIsNotNone(extension.get('namespace')) - self.assertIsNotNone(extension.get('alias')) - self.assertIsNotNone(extension.get('updated')) - - def assertValidExtensionLink(self, link): - """Applicable to XML and JSON.""" - self.assertIsNotNone(link.get('rel')) - self.assertIsNotNone(link.get('type')) - self.assertIsNotNone(link.get('href')) - - def assertValidTenant(self, tenant): - """Applicable to XML and JSON.""" - self.assertIsNotNone(tenant.get('id')) - self.assertIsNotNone(tenant.get('name')) - - def assertValidUser(self, user): - """Applicable to XML and JSON.""" - self.assertIsNotNone(user.get('id')) - self.assertIsNotNone(user.get('name')) - - def assertValidRole(self, tenant): - """Applicable to XML and JSON.""" - self.assertIsNotNone(tenant.get('id')) - self.assertIsNotNone(tenant.get('name')) - - def test_public_not_found(self): - r = self.public_request( - path='/%s' % uuid.uuid4().hex, - expected_status=404) - self.assertValidErrorResponse(r) - - def test_admin_not_found(self): - r = self.admin_request( - path='/%s' % uuid.uuid4().hex, - expected_status=404) - self.assertValidErrorResponse(r) - - def test_public_multiple_choice(self): - r = self.public_request(path='/', expected_status=300) - self.assertValidMultipleChoiceResponse(r) - - def test_admin_multiple_choice(self): - r = self.admin_request(path='/', expected_status=300) - self.assertValidMultipleChoiceResponse(r) - - def test_public_version(self): - r = self.public_request(path='/v2.0/') - self.assertValidVersionResponse(r) - - def test_admin_version(self): - r = self.admin_request(path='/v2.0/') - self.assertValidVersionResponse(r) - - def test_public_extensions(self): - r = self.public_request(path='/v2.0/extensions') - self.assertValidExtensionListResponse(r, - extension.PUBLIC_EXTENSIONS) - - def test_admin_extensions(self): - r = self.admin_request(path='/v2.0/extensions') - self.assertValidExtensionListResponse(r, - extension.ADMIN_EXTENSIONS) - - def test_admin_extensions_404(self): - self.admin_request(path='/v2.0/extensions/invalid-extension', - expected_status=404) - - def test_public_osksadm_extension_404(self): - self.public_request(path='/v2.0/extensions/OS-KSADM', - expected_status=404) - - def test_admin_osksadm_extension(self): - r = self.admin_request(path='/v2.0/extensions/OS-KSADM') - self.assertValidExtensionResponse(r, - extension.ADMIN_EXTENSIONS) - - def test_authenticate(self): - r = self.public_request( - method='POST', - path='/v2.0/tokens', - body={ - 'auth': { - 'passwordCredentials': { - 'username': self.user_foo['name'], - 'password': self.user_foo['password'], - }, - 'tenantId': self.tenant_bar['id'], - }, - }, - expected_status=200) - self.assertValidAuthenticationResponse(r, require_service_catalog=True) - - def test_authenticate_unscoped(self): - r = self.public_request( - method='POST', - path='/v2.0/tokens', - body={ - 'auth': { - 'passwordCredentials': { - 'username': self.user_foo['name'], - 'password': self.user_foo['password'], - }, - }, - }, - expected_status=200) - self.assertValidAuthenticationResponse(r) - - def test_get_tenants_for_token(self): - r = self.public_request(path='/v2.0/tenants', - token=self.get_scoped_token()) - self.assertValidTenantListResponse(r) - - def test_validate_token(self): - token = self.get_scoped_token() - r = self.admin_request( - path='/v2.0/tokens/%(token_id)s' % { - 'token_id': token, - }, - token=token) - self.assertValidAuthenticationResponse(r) - - def test_validate_token_service_role(self): - self.metadata_foobar = self.identity_api.add_role_to_user_and_project( - self.user_foo['id'], - self.tenant_service['id'], - self.role_service['id']) - - token = self.get_scoped_token(tenant_id='service') - r = self.admin_request( - path='/v2.0/tokens/%s' % token, - token=token) - self.assertValidAuthenticationResponse(r) - - def test_validate_token_belongs_to(self): - token = self.get_scoped_token() - path = ('/v2.0/tokens/%s?belongsTo=%s' % (token, - self.tenant_bar['id'])) - r = self.admin_request(path=path, token=token) - self.assertValidAuthenticationResponse(r, require_service_catalog=True) - - def test_validate_token_no_belongs_to_still_returns_catalog(self): - token = self.get_scoped_token() - path = ('/v2.0/tokens/%s' % token) - r = self.admin_request(path=path, token=token) - self.assertValidAuthenticationResponse(r, require_service_catalog=True) - - def test_validate_token_head(self): - """The same call as above, except using HEAD. - - There's no response to validate here, but this is included for the - sake of completely covering the core API. - - """ - token = self.get_scoped_token() - self.admin_request( - method='HEAD', - path='/v2.0/tokens/%(token_id)s' % { - 'token_id': token, - }, - token=token, - expected_status=204) - - def test_endpoints(self): - token = self.get_scoped_token() - r = self.admin_request( - path='/v2.0/tokens/%(token_id)s/endpoints' % { - 'token_id': token, - }, - token=token) - self.assertValidEndpointListResponse(r) - - def test_get_tenant(self): - token = self.get_scoped_token() - r = self.admin_request( - path='/v2.0/tenants/%(tenant_id)s' % { - 'tenant_id': self.tenant_bar['id'], - }, - token=token) - self.assertValidTenantResponse(r) - - def test_get_tenant_by_name(self): - token = self.get_scoped_token() - r = self.admin_request( - path='/v2.0/tenants?name=%(tenant_name)s' % { - 'tenant_name': self.tenant_bar['name'], - }, - token=token) - self.assertValidTenantResponse(r) - - def test_get_user_roles(self): - self.skipTest('Blocked by bug 933565') - - token = self.get_scoped_token() - r = self.admin_request( - path='/v2.0/users/%(user_id)s/roles' % { - 'user_id': self.user_foo['id'], - }, - token=token) - self.assertValidRoleListResponse(r) - - def test_get_user_roles_with_tenant(self): - token = self.get_scoped_token() - r = self.admin_request( - path='/v2.0/tenants/%(tenant_id)s/users/%(user_id)s/roles' % { - 'tenant_id': self.tenant_bar['id'], - 'user_id': self.user_foo['id'], - }, - token=token) - self.assertValidRoleListResponse(r) - - def test_get_user(self): - token = self.get_scoped_token() - r = self.admin_request( - path='/v2.0/users/%(user_id)s' % { - 'user_id': self.user_foo['id'], - }, - token=token) - self.assertValidUserResponse(r) - - def test_get_user_by_name(self): - token = self.get_scoped_token() - r = self.admin_request( - path='/v2.0/users?name=%(user_name)s' % { - 'user_name': self.user_foo['name'], - }, - token=token) - self.assertValidUserResponse(r) - - def test_create_update_user_invalid_enabled_type(self): - # Enforce usage of boolean for 'enabled' field in JSON and XML - token = self.get_scoped_token() - - # Test CREATE request - r = self.admin_request( - method='POST', - path='/v2.0/users', - body={ - 'user': { - 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, - # In XML, only "true|false" are converted to boolean. - 'enabled': "False", - }, - }, - token=token, - expected_status=400) - self.assertValidErrorResponse(r) - - r = self.admin_request( - method='POST', - path='/v2.0/users', - body={ - 'user': { - 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, - # In JSON, 0|1 are not booleans - 'enabled': 0, - }, - }, - token=token, - expected_status=400) - self.assertValidErrorResponse(r) - - # Test UPDATE request - path = '/v2.0/users/%(user_id)s' % { - 'user_id': self.user_foo['id'], - } - - r = self.admin_request( - method='PUT', - path=path, - body={ - 'user': { - # In XML, only "true|false" are converted to boolean. - 'enabled': "False", - }, - }, - token=token, - expected_status=400) - self.assertValidErrorResponse(r) - - r = self.admin_request( - method='PUT', - path=path, - body={ - 'user': { - # In JSON, 0|1 are not booleans - 'enabled': 1, - }, - }, - token=token, - expected_status=400) - self.assertValidErrorResponse(r) - - def test_error_response(self): - """This triggers assertValidErrorResponse by convention.""" - self.public_request(path='/v2.0/tenants', expected_status=401) - - def test_invalid_parameter_error_response(self): - token = self.get_scoped_token() - bad_body = { - 'OS-KSADM:service%s' % uuid.uuid4().hex: { - 'name': uuid.uuid4().hex, - 'type': uuid.uuid4().hex, - }, - } - res = self.admin_request(method='POST', - path='/v2.0/OS-KSADM/services', - body=bad_body, - token=token, - expected_status=400) - self.assertValidErrorResponse(res) - res = self.admin_request(method='POST', - path='/v2.0/users', - body=bad_body, - token=token, - expected_status=400) - self.assertValidErrorResponse(res) - - -class JsonTestCase(RestfulTestCase, CoreApiTests): - content_type = 'json' - - def _get_token_id(self, r): - """Applicable only to JSON.""" - return r.result['access']['token']['id'] - - def assertValidErrorResponse(self, r): - self.assertIsNotNone(r.result.get('error')) - self.assertValidError(r.result['error']) - self.assertEqual(r.result['error']['code'], r.status_code) - - def assertValidExtension(self, extension, expected): - super(JsonTestCase, self).assertValidExtension(extension) - descriptions = [ext['description'] for ext in expected.itervalues()] - description = extension.get('description') - self.assertIsNotNone(description) - self.assertIn(description, descriptions) - self.assertIsNotNone(extension.get('links')) - self.assertNotEmpty(extension.get('links')) - for link in extension.get('links'): - self.assertValidExtensionLink(link) - - def assertValidExtensionListResponse(self, r, expected): - self.assertIsNotNone(r.result.get('extensions')) - self.assertIsNotNone(r.result['extensions'].get('values')) - self.assertNotEmpty(r.result['extensions'].get('values')) - for extension in r.result['extensions']['values']: - self.assertValidExtension(extension, expected) - - def assertValidExtensionResponse(self, r, expected): - self.assertValidExtension(r.result.get('extension'), expected) - - def assertValidAuthenticationResponse(self, r, - require_service_catalog=False): - self.assertIsNotNone(r.result.get('access')) - self.assertIsNotNone(r.result['access'].get('token')) - self.assertIsNotNone(r.result['access'].get('user')) - - # validate token - self.assertIsNotNone(r.result['access']['token'].get('id')) - self.assertIsNotNone(r.result['access']['token'].get('expires')) - tenant = r.result['access']['token'].get('tenant') - if tenant is not None: - # validate tenant - self.assertIsNotNone(tenant.get('id')) - self.assertIsNotNone(tenant.get('name')) - - # validate user - self.assertIsNotNone(r.result['access']['user'].get('id')) - self.assertIsNotNone(r.result['access']['user'].get('name')) - - if require_service_catalog: - # roles are only provided with a service catalog - roles = r.result['access']['user'].get('roles') - self.assertNotEmpty(roles) - for role in roles: - self.assertIsNotNone(role.get('name')) - - serviceCatalog = r.result['access'].get('serviceCatalog') - # validate service catalog - if require_service_catalog: - self.assertIsNotNone(serviceCatalog) - if serviceCatalog is not None: - self.assertTrue(isinstance(serviceCatalog, list)) - if require_service_catalog: - self.assertNotEmpty(serviceCatalog) - for service in r.result['access']['serviceCatalog']: - # validate service - self.assertIsNotNone(service.get('name')) - self.assertIsNotNone(service.get('type')) - - # services contain at least one endpoint - self.assertIsNotNone(service.get('endpoints')) - self.assertNotEmpty(service['endpoints']) - for endpoint in service['endpoints']: - # validate service endpoint - self.assertIsNotNone(endpoint.get('publicURL')) - - def assertValidTenantListResponse(self, r): - self.assertIsNotNone(r.result.get('tenants')) - self.assertNotEmpty(r.result['tenants']) - for tenant in r.result['tenants']: - self.assertValidTenant(tenant) - self.assertIsNotNone(tenant.get('enabled')) - self.assertIn(tenant.get('enabled'), [True, False]) - - def assertValidUserResponse(self, r): - self.assertIsNotNone(r.result.get('user')) - self.assertValidUser(r.result['user']) - - def assertValidTenantResponse(self, r): - self.assertIsNotNone(r.result.get('tenant')) - self.assertValidTenant(r.result['tenant']) - - def assertValidRoleListResponse(self, r): - self.assertIsNotNone(r.result.get('roles')) - self.assertNotEmpty(r.result['roles']) - for role in r.result['roles']: - self.assertValidRole(role) - - def assertValidVersion(self, version): - super(JsonTestCase, self).assertValidVersion(version) - - self.assertIsNotNone(version.get('links')) - self.assertNotEmpty(version.get('links')) - for link in version.get('links'): - self.assertIsNotNone(link.get('rel')) - self.assertIsNotNone(link.get('href')) - - self.assertIsNotNone(version.get('media-types')) - self.assertNotEmpty(version.get('media-types')) - for media in version.get('media-types'): - self.assertIsNotNone(media.get('base')) - self.assertIsNotNone(media.get('type')) - - def assertValidMultipleChoiceResponse(self, r): - self.assertIsNotNone(r.result.get('versions')) - self.assertIsNotNone(r.result['versions'].get('values')) - self.assertNotEmpty(r.result['versions']['values']) - for version in r.result['versions']['values']: - self.assertValidVersion(version) - - def assertValidVersionResponse(self, r): - self.assertValidVersion(r.result.get('version')) - - def assertValidEndpointListResponse(self, r): - self.assertIsNotNone(r.result.get('endpoints')) - self.assertNotEmpty(r.result['endpoints']) - for endpoint in r.result['endpoints']: - self.assertIsNotNone(endpoint.get('id')) - self.assertIsNotNone(endpoint.get('name')) - self.assertIsNotNone(endpoint.get('type')) - self.assertIsNotNone(endpoint.get('publicURL')) - self.assertIsNotNone(endpoint.get('internalURL')) - self.assertIsNotNone(endpoint.get('adminURL')) - - def test_service_crud_requires_auth(self): - """Service CRUD should 401 without an X-Auth-Token (bug 1006822).""" - # values here don't matter because we should 401 before they're checked - service_path = '/v2.0/OS-KSADM/services/%s' % uuid.uuid4().hex - service_body = { - 'OS-KSADM:service': { - 'name': uuid.uuid4().hex, - 'type': uuid.uuid4().hex, - }, - } - - r = self.admin_request(method='GET', - path='/v2.0/OS-KSADM/services', - expected_status=401) - self.assertValidErrorResponse(r) - - r = self.admin_request(method='POST', - path='/v2.0/OS-KSADM/services', - body=service_body, - expected_status=401) - self.assertValidErrorResponse(r) - - r = self.admin_request(method='GET', - path=service_path, - expected_status=401) - self.assertValidErrorResponse(r) - - r = self.admin_request(method='DELETE', - path=service_path, - expected_status=401) - self.assertValidErrorResponse(r) - - def test_user_role_list_requires_auth(self): - """User role list should 401 without an X-Auth-Token (bug 1006815).""" - # values here don't matter because we should 401 before they're checked - path = '/v2.0/tenants/%(tenant_id)s/users/%(user_id)s/roles' % { - 'tenant_id': uuid.uuid4().hex, - 'user_id': uuid.uuid4().hex, - } - - r = self.admin_request(path=path, expected_status=401) - self.assertValidErrorResponse(r) - - def test_fetch_revocation_list_nonadmin_fails(self): - self.admin_request( - method='GET', - path='/v2.0/tokens/revoked', - expected_status=401) - - def test_fetch_revocation_list_admin_200(self): - token = self.get_scoped_token() - r = self.admin_request( - method='GET', - path='/v2.0/tokens/revoked', - token=token, - expected_status=200) - self.assertValidRevocationListResponse(r) - - def assertValidRevocationListResponse(self, response): - self.assertIsNotNone(response.result['signed']) - - def test_create_update_user_json_invalid_enabled_type(self): - # Enforce usage of boolean for 'enabled' field in JSON - token = self.get_scoped_token() - - # Test CREATE request - r = self.admin_request( - method='POST', - path='/v2.0/users', - body={ - 'user': { - 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, - # In JSON, "true|false" are not boolean - 'enabled': "true", - }, - }, - token=token, - expected_status=400) - self.assertValidErrorResponse(r) - - # Test UPDATE request - r = self.admin_request( - method='PUT', - path='/v2.0/users/%(user_id)s' % { - 'user_id': self.user_foo['id'], - }, - body={ - 'user': { - # In JSON, "true|false" are not boolean - 'enabled': "true", - }, - }, - token=token, - expected_status=400) - self.assertValidErrorResponse(r) - - -class XmlTestCase(RestfulTestCase, CoreApiTests): - xmlns = 'http://docs.openstack.org/identity/api/v2.0' - content_type = 'xml' - - def _get_token_id(self, r): - return r.result.find(self._tag('token')).get('id') - - def _tag(self, tag_name, xmlns=None): - """Helper method to build an namespaced element name.""" - return '{%(ns)s}%(tag)s' % {'ns': xmlns or self.xmlns, 'tag': tag_name} - - def assertValidErrorResponse(self, r): - xml = r.result - self.assertEqual(xml.tag, self._tag('error')) - - self.assertValidError(xml) - self.assertEqual(xml.get('code'), str(r.status_code)) - - def assertValidExtension(self, extension, expected): - super(XmlTestCase, self).assertValidExtension(extension) - - self.assertIsNotNone(extension.find(self._tag('description'))) - self.assertTrue(extension.find(self._tag('description')).text) - links = extension.find(self._tag('links')) - self.assertNotEmpty(links.findall(self._tag('link'))) - descriptions = [ext['description'] for ext in expected.itervalues()] - description = extension.find(self._tag('description')).text - self.assertIn(description, descriptions) - for link in links.findall(self._tag('link')): - self.assertValidExtensionLink(link) - - def assertValidExtensionListResponse(self, r, expected): - xml = r.result - self.assertEqual(xml.tag, self._tag('extensions')) - self.assertNotEmpty(xml.findall(self._tag('extension'))) - for ext in xml.findall(self._tag('extension')): - self.assertValidExtension(ext, expected) - - def assertValidExtensionResponse(self, r, expected): - xml = r.result - self.assertEqual(xml.tag, self._tag('extension')) - - self.assertValidExtension(xml, expected) - - def assertValidVersion(self, version): - super(XmlTestCase, self).assertValidVersion(version) - - links = version.find(self._tag('links')) - self.assertIsNotNone(links) - self.assertNotEmpty(links.findall(self._tag('link'))) - for link in links.findall(self._tag('link')): - self.assertIsNotNone(link.get('rel')) - self.assertIsNotNone(link.get('href')) - - media_types = version.find(self._tag('media-types')) - self.assertIsNotNone(media_types) - self.assertNotEmpty(media_types.findall(self._tag('media-type'))) - for media in media_types.findall(self._tag('media-type')): - self.assertIsNotNone(media.get('base')) - self.assertIsNotNone(media.get('type')) - - def assertValidMultipleChoiceResponse(self, r): - xml = r.result - self.assertEqual(xml.tag, self._tag('versions')) - - self.assertNotEmpty(xml.findall(self._tag('version'))) - for version in xml.findall(self._tag('version')): - self.assertValidVersion(version) - - def assertValidVersionResponse(self, r): - xml = r.result - self.assertEqual(xml.tag, self._tag('version')) - - self.assertValidVersion(xml) - - def assertValidEndpointListResponse(self, r): - xml = r.result - self.assertEqual(xml.tag, self._tag('endpoints')) - - self.assertNotEmpty(xml.findall(self._tag('endpoint'))) - for endpoint in xml.findall(self._tag('endpoint')): - self.assertIsNotNone(endpoint.get('id')) - self.assertIsNotNone(endpoint.get('name')) - self.assertIsNotNone(endpoint.get('type')) - self.assertIsNotNone(endpoint.get('publicURL')) - self.assertIsNotNone(endpoint.get('internalURL')) - self.assertIsNotNone(endpoint.get('adminURL')) - - def assertValidTenantResponse(self, r): - xml = r.result - self.assertEqual(xml.tag, self._tag('tenant')) - - self.assertValidTenant(xml) - - def assertValidUserResponse(self, r): - xml = r.result - self.assertEqual(xml.tag, self._tag('user')) - - self.assertValidUser(xml) - - def assertValidRoleListResponse(self, r): - xml = r.result - self.assertEqual(xml.tag, self._tag('roles')) - - self.assertNotEmpty(r.result.findall(self._tag('role'))) - for role in r.result.findall(self._tag('role')): - self.assertValidRole(role) - - def assertValidAuthenticationResponse(self, r, - require_service_catalog=False): - xml = r.result - self.assertEqual(xml.tag, self._tag('access')) - - # validate token - token = xml.find(self._tag('token')) - self.assertIsNotNone(token) - self.assertIsNotNone(token.get('id')) - self.assertIsNotNone(token.get('expires')) - tenant = token.find(self._tag('tenant')) - if tenant is not None: - # validate tenant - self.assertValidTenant(tenant) - self.assertIn(tenant.get('enabled'), ['true', 'false']) - - user = xml.find(self._tag('user')) - self.assertIsNotNone(user) - self.assertIsNotNone(user.get('id')) - self.assertIsNotNone(user.get('name')) - - if require_service_catalog: - # roles are only provided with a service catalog - roles = user.findall(self._tag('role')) - self.assertNotEmpty(roles) - for role in roles: - self.assertIsNotNone(role.get('name')) - - serviceCatalog = xml.find(self._tag('serviceCatalog')) - # validate the serviceCatalog - if require_service_catalog: - self.assertIsNotNone(serviceCatalog) - if serviceCatalog is not None: - services = serviceCatalog.findall(self._tag('service')) - if require_service_catalog: - self.assertNotEmpty(services) - for service in services: - # validate service - self.assertIsNotNone(service.get('name')) - self.assertIsNotNone(service.get('type')) - - # services contain at least one endpoint - endpoints = service.findall(self._tag('endpoint')) - self.assertNotEmpty(endpoints) - for endpoint in endpoints: - # validate service endpoint - self.assertIsNotNone(endpoint.get('publicURL')) - - def assertValidTenantListResponse(self, r): - xml = r.result - self.assertEqual(xml.tag, self._tag('tenants')) - - self.assertNotEmpty(r.result) - for tenant in r.result.findall(self._tag('tenant')): - self.assertValidTenant(tenant) - self.assertIn(tenant.get('enabled'), ['true', 'false']) - - def test_authenticate_with_invalid_xml_in_password(self): - # public_request would auto escape the ampersand - self.public_request( - method='POST', - path='/v2.0/tokens', - headers={ - 'Content-Type': 'application/xml' - }, - body=""" - <?xml version="1.0" encoding="UTF-8"?> - <auth xmlns="http://docs.openstack.org/identity/api/v2.0" - tenantId="bar"> - <passwordCredentials username="FOO" password="&"/> - </auth> - """, - expected_status=400, - convert=False) - - def test_add_tenant_xml(self): - """Create a tenant without providing description field.""" - token = self.get_scoped_token() - r = self.admin_request( - method='POST', - path='/v2.0/tenants', - headers={ - 'Content-Type': 'application/xml', - 'X-Auth-Token': token - }, - body=""" - <?xml version="1.0" encoding="UTF-8"?> - <tenant xmlns="http://docs.openstack.org/identity/api/v2.0" - enabled="true" name="ACME Corp"> - <description></description> - </tenant> - """, - convert=False) - self._from_content_type(r, 'json') - self.assertIsNotNone(r.result.get('tenant')) - self.assertValidTenant(r.result['tenant']) - self.assertEqual(r.result['tenant'].get('description'), "") - - def test_add_tenant_json(self): - """Create a tenant without providing description field.""" - token = self.get_scoped_token() - r = self.admin_request( - method='POST', - path='/v2.0/tenants', - headers={ - 'Content-Type': 'application/json', - 'X-Auth-Token': token - }, - body=""" - {"tenant":{ - "name":"test1", - "description":"", - "enabled":true} - } - """, - convert=False) - self._from_content_type(r, 'json') - self.assertIsNotNone(r.result.get('tenant')) - self.assertValidTenant(r.result['tenant']) - self.assertEqual(r.result['tenant'].get('description'), "") - - def test_create_project_invalid_enabled_type_string(self): - # Forbidden usage of string for 'enabled' field in JSON and XML - token = self.get_scoped_token() - - r = self.admin_request( - method='POST', - path='/v2.0/tenants', - body={ - 'tenant': { - 'name': uuid.uuid4().hex, - # In XML, only "true|false" are converted to boolean. - 'enabled': "False", - }, - }, - token=token, - expected_status=400) - self.assertValidErrorResponse(r) - - def test_update_project_invalid_enabled_type_string(self): - # Forbidden usage of string for 'enabled' field in JSON and XML - token = self.get_scoped_token() - - path = '/v2.0/tenants/%(tenant_id)s' % { - 'tenant_id': self.tenant_bar['id'], - } - - r = self.admin_request( - method='PUT', - path=path, - body={ - 'tenant': { - # In XML, only "true|false" are converted to boolean. - 'enabled': "False", - }, - }, - token=token, - expected_status=400) - self.assertValidErrorResponse(r) diff --git a/tests/test_contrib_s3_core.py b/tests/test_contrib_s3_core.py deleted file mode 100644 index e2c328b5..00000000 --- a/tests/test_contrib_s3_core.py +++ /dev/null @@ -1,61 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 uuid - -from keystone import test - -from keystone.contrib import ec2 -from keystone.contrib import s3 - -from keystone import exception - - -class S3ContribCore(test.TestCase): - def setUp(self): - super(S3ContribCore, self).setUp() - - self.load_backends() - - self.ec2_api = ec2.Manager() - self.controller = s3.S3Controller() - - def test_good_signature(self): - creds_ref = {'secret': - 'b121dd41cdcc42fe9f70e572e84295aa'} - credentials = {'token': - 'UFVUCjFCMk0yWThBc2dUcGdBbVk3UGhDZmc9PQphcHB' - 'saWNhdGlvbi9vY3RldC1zdHJlYW0KVHVlLCAxMSBEZWMgMjAxM' - 'iAyMTo0MTo0MSBHTVQKL2NvbnRfczMvdXBsb2FkZWRfZnJ' - 'vbV9zMy50eHQ=', - 'signature': 'IL4QLcLVaYgylF9iHj6Wb8BGZsw='} - - self.assertIsNone(self.controller.check_signature(creds_ref, - credentials)) - - def test_bad_signature(self): - creds_ref = {'secret': - 'b121dd41cdcc42fe9f70e572e84295aa'} - credentials = {'token': - 'UFVUCjFCMk0yWThBc2dUcGdBbVk3UGhDZmc9PQphcHB' - 'saWNhdGlvbi9vY3RldC1zdHJlYW0KVHVlLCAxMSBEZWMgMjAxM' - 'iAyMTo0MTo0MSBHTVQKL2NvbnRfczMvdXBsb2FkZWRfZnJ' - 'vbV9zMy50eHQ=', - 'signature': uuid.uuid4().hex} - - self.assertRaises(exception.Unauthorized, - self.controller.check_signature, - creds_ref, credentials) diff --git a/tests/test_contrib_stats_core.py b/tests/test_contrib_stats_core.py deleted file mode 100644 index 907c7d25..00000000 --- a/tests/test_contrib_stats_core.py +++ /dev/null @@ -1,45 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 keystone.contrib import stats - -from keystone import config -from keystone import test - - -CONF = config.CONF - - -class StatsContribCore(test.TestCase): - def setUp(self): - super(StatsContribCore, self).setUp() - self.stats_middleware = stats.StatsMiddleware(None) - - def test_admin_request(self): - host_admin = "127.0.0.1:%s" % CONF.admin_port - self.assertEqual("admin", - self.stats_middleware._resolve_api(host_admin)) - - def test_public_request(self): - host_public = "127.0.0.1:%s" % CONF.public_port - self.assertEqual("public", - self.stats_middleware._resolve_api(host_public)) - - def test_other_request(self): - host_public = "127.0.0.1:%s" % CONF.public_port - host_other = host_public + "1" - self.assertEqual(host_other, - self.stats_middleware._resolve_api(host_other)) diff --git a/tests/test_drivers.py b/tests/test_drivers.py deleted file mode 100644 index c83c1a89..00000000 --- a/tests/test_drivers.py +++ /dev/null @@ -1,57 +0,0 @@ -import inspect -import unittest2 as unittest - -from keystone import assignment -from keystone import catalog -from keystone import exception -from keystone import identity -from keystone import policy -from keystone import token - - -class TestDrivers(unittest.TestCase): - """Asserts that drivers are written as expected. - - Public methods on drivers should raise keystone.exception.NotImplemented, - which renders to the API as a HTTP 501 Not Implemented. - - """ - - def assertMethodNotImplemented(self, f): - """Asserts that a given method raises 501 Not Implemented. - - Provides each argument with a value of None, ignoring optional - arguments. - """ - args = inspect.getargspec(f).args - args.remove('self') - kwargs = dict(zip(args, [None] * len(args))) - with self.assertRaises(exception.NotImplemented): - f(**kwargs) - - def assertInterfaceNotImplemented(self, interface): - """Public methods on an interface class should not be implemented.""" - for name in dir(interface): - method = getattr(interface, name) - if name[0] != '_' and callable(method): - self.assertMethodNotImplemented(method) - - def test_assignment_driver_unimplemented(self): - interface = assignment.Driver() - self.assertInterfaceNotImplemented(interface) - - def test_catalog_driver_unimplemented(self): - interface = catalog.Driver() - self.assertInterfaceNotImplemented(interface) - - def test_identity_driver_unimplemented(self): - interface = identity.Driver() - self.assertInterfaceNotImplemented(interface) - - def test_policy_driver_unimplemented(self): - interface = policy.Driver() - self.assertInterfaceNotImplemented(interface) - - def test_token_driver_unimplemented(self): - interface = token.Driver() - self.assertInterfaceNotImplemented(interface) diff --git a/tests/test_exception.py b/tests/test_exception.py deleted file mode 100644 index d442d572..00000000 --- a/tests/test_exception.py +++ /dev/null @@ -1,163 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 uuid - -from keystone import test - -from keystone.common import wsgi -from keystone import config -from keystone import exception -from keystone.openstack.common import jsonutils - - -CONF = config.CONF - - -class ExceptionTestCase(test.TestCase): - def setUp(self): - pass - - def tearDown(self): - pass - - def assertValidJsonRendering(self, e): - resp = wsgi.render_exception(e) - self.assertEqual(resp.status_int, e.code) - self.assertEqual(resp.status, '%s %s' % (e.code, e.title)) - - j = jsonutils.loads(resp.body) - self.assertIsNotNone(j.get('error')) - self.assertIsNotNone(j['error'].get('code')) - self.assertIsNotNone(j['error'].get('title')) - self.assertIsNotNone(j['error'].get('message')) - self.assertNotIn('\n', j['error']['message']) - self.assertNotIn(' ', j['error']['message']) - self.assertTrue(type(j['error']['code']) is int) - - def test_all_json_renderings(self): - """Everything callable in the exception module should be renderable. - - ... except for the base error class (exception.Error), which is not - user-facing. - - This test provides a custom message to bypass docstring parsing, which - should be tested separately. - - """ - for cls in [x for x in exception.__dict__.values() if callable(x)]: - if cls is not exception.Error and isinstance(cls, exception.Error): - self.assertValidJsonRendering(cls(message='Overriden.')) - - def test_validation_error(self): - target = uuid.uuid4().hex - attribute = uuid.uuid4().hex - e = exception.ValidationError(target=target, attribute=attribute) - self.assertValidJsonRendering(e) - self.assertIn(target, unicode(e)) - self.assertIn(attribute, unicode(e)) - - def test_not_found(self): - target = uuid.uuid4().hex - e = exception.NotFound(target=target) - self.assertValidJsonRendering(e) - self.assertIn(target, unicode(e)) - - def test_403_title(self): - e = exception.Forbidden() - resp = wsgi.render_exception(e) - j = jsonutils.loads(resp.body) - self.assertEqual('Forbidden', e.title) - self.assertEqual('Forbidden', j['error'].get('title')) - - def test_unicode_message(self): - message = u'Comment \xe7a va' - e = exception.Error(message) - - try: - self.assertEqual(unicode(e), message) - except UnicodeEncodeError: - self.fail("unicode error message not supported") - - -class SecurityErrorTestCase(ExceptionTestCase): - """Tests whether security-related info is exposed to the API user.""" - def test_unauthorized_exposure(self): - self.opt(debug=False) - - risky_info = uuid.uuid4().hex - e = exception.Unauthorized(message=risky_info) - self.assertValidJsonRendering(e) - self.assertNotIn(risky_info, unicode(e)) - - def test_unauthorized_exposure_in_debug(self): - self.opt(debug=True) - - risky_info = uuid.uuid4().hex - e = exception.Unauthorized(message=risky_info) - self.assertValidJsonRendering(e) - self.assertIn(risky_info, unicode(e)) - - def test_forbidden_exposure(self): - self.opt(debug=False) - - risky_info = uuid.uuid4().hex - e = exception.Forbidden(message=risky_info) - self.assertValidJsonRendering(e) - self.assertNotIn(risky_info, unicode(e)) - - def test_forbidden_exposure_in_debug(self): - self.opt(debug=True) - - risky_info = uuid.uuid4().hex - e = exception.Forbidden(message=risky_info) - self.assertValidJsonRendering(e) - self.assertIn(risky_info, unicode(e)) - - def test_forbidden_action_exposure(self): - self.opt(debug=False) - - risky_info = uuid.uuid4().hex - action = uuid.uuid4().hex - e = exception.ForbiddenAction(message=risky_info, action=action) - self.assertValidJsonRendering(e) - self.assertNotIn(risky_info, unicode(e)) - self.assertIn(action, unicode(e)) - - e = exception.ForbiddenAction(action=risky_info) - self.assertValidJsonRendering(e) - self.assertIn(risky_info, unicode(e)) - - def test_forbidden_action_exposure_in_debug(self): - self.opt(debug=True) - - risky_info = uuid.uuid4().hex - - e = exception.ForbiddenAction(message=risky_info) - self.assertValidJsonRendering(e) - self.assertIn(risky_info, unicode(e)) - - e = exception.ForbiddenAction(action=risky_info) - self.assertValidJsonRendering(e) - self.assertIn(risky_info, unicode(e)) - - def test_unicode_argument_message(self): - self.opt(debug=False) - - risky_info = u'\u7ee7\u7eed\u884c\u7f29\u8fdb\u6216' - e = exception.Forbidden(message=risky_info) - self.assertValidJsonRendering(e) - self.assertNotIn(risky_info, unicode(e)) diff --git a/tests/test_import_legacy.py b/tests/test_import_legacy.py deleted file mode 100644 index 9e164099..00000000 --- a/tests/test_import_legacy.py +++ /dev/null @@ -1,120 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 os - -try: - import sqlite3 as dbapi -except ImportError: - from pysqlite2 import dbapi2 as dbapi - -from keystone import test - -from keystone.catalog.backends import templated as catalog_templated -from keystone.common.sql import legacy -from keystone import config -from keystone import identity -from keystone.identity.backends import sql as identity_sql - - -CONF = config.CONF - - -class ImportLegacy(test.TestCase): - def setUp(self): - super(ImportLegacy, self).setUp() - self.config([test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf'), - test.testsdir('backend_sql.conf'), - test.testsdir('backend_sql_disk.conf')]) - test.setup_test_database() - self.identity_man = identity.Manager() - self.identity_api = identity_sql.Identity() - - def tearDown(self): - test.teardown_test_database() - super(ImportLegacy, self).tearDown() - - def setup_old_database(self, sql_dump): - sql_path = test.testsdir(sql_dump) - db_path = test.tmpdir('%s.db' % sql_dump) - try: - os.unlink(db_path) - except OSError: - pass - script_str = open(sql_path).read().strip() - conn = dbapi.connect(db_path) - conn.executescript(script_str) - conn.commit() - return db_path - - def test_import_d5(self): - db_path = self.setup_old_database('legacy_d5.sqlite') - migration = legacy.LegacyMigration('sqlite:///%s' % db_path) - migration.migrate_all() - - admin_id = '1' - user_ref = self.identity_api.get_user(admin_id) - self.assertEquals(user_ref['name'], 'admin') - self.assertEquals(user_ref['enabled'], True) - - # check password hashing - user_ref = self.identity_man.authenticate( - user_id=admin_id, password='secrete') - - # check catalog - self._check_catalog(migration) - - def test_import_diablo(self): - db_path = self.setup_old_database('legacy_diablo.sqlite') - migration = legacy.LegacyMigration('sqlite:///%s' % db_path) - migration.migrate_all() - - admin_id = '1' - user_ref = self.identity_api.get_user(admin_id) - self.assertEquals(user_ref['name'], 'admin') - self.assertEquals(user_ref['enabled'], True) - - # check password hashing - user_ref = self.identity_man.authenticate( - user_id=admin_id, password='secrete') - - # check catalog - self._check_catalog(migration) - - def test_import_essex(self): - db_path = self.setup_old_database('legacy_essex.sqlite') - migration = legacy.LegacyMigration('sqlite:///%s' % db_path) - migration.migrate_all() - - admin_id = 'c93b19ea3fa94484824213db8ac0afce' - user_ref = self.identity_api.get_user(admin_id) - self.assertEquals(user_ref['name'], 'admin') - self.assertEquals(user_ref['enabled'], True) - - # check password hashing - user_ref = self.identity_man.authenticate( - user_id=admin_id, password='secrete') - - # check catalog - self._check_catalog(migration) - - def _check_catalog(self, migration): - catalog_lines = migration.dump_catalog() - catalog = catalog_templated.parse_templates(catalog_lines) - self.assert_('RegionOne' in catalog) - self.assert_('compute' in catalog['RegionOne']) - self.assert_('adminURL' in catalog['RegionOne']['compute']) diff --git a/tests/test_injection.py b/tests/test_injection.py deleted file mode 100644 index 36cd0126..00000000 --- a/tests/test_injection.py +++ /dev/null @@ -1,211 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 unittest2 as unittest -import uuid - -from keystone.common import dependency - - -class TestDependencyInjection(unittest.TestCase): - def tearDown(self): - dependency.reset() - super(TestDependencyInjection, self).tearDown() - - def test_dependency_injection(self): - class Interface(object): - def do_work(self): - assert False - - @dependency.provider('first_api') - class FirstImplementation(Interface): - def do_work(self): - return True - - @dependency.provider('second_api') - class SecondImplementation(Interface): - def do_work(self): - return True - - @dependency.requires('first_api', 'second_api') - class Consumer(object): - def do_work_with_dependencies(self): - assert self.first_api.do_work() - assert self.second_api.do_work() - - # initialize dependency providers - first_api = FirstImplementation() - second_api = SecondImplementation() - - # ... sometime later, initialize a dependency consumer - consumer = Consumer() - - # the expected dependencies should be available to the consumer - self.assertIs(consumer.first_api, first_api) - self.assertIs(consumer.second_api, second_api) - self.assertIsInstance(consumer.first_api, Interface) - self.assertIsInstance(consumer.second_api, Interface) - consumer.do_work_with_dependencies() - - def test_dependency_provider_configuration(self): - @dependency.provider('api') - class Configurable(object): - def __init__(self, value=None): - self.value = value - - def get_value(self): - return self.value - - @dependency.requires('api') - class Consumer(object): - def get_value(self): - return self.api.get_value() - - # initialize dependency providers - api = Configurable(value=True) - - # ... sometime later, initialize a dependency consumer - consumer = Consumer() - - # the expected dependencies should be available to the consumer - self.assertIs(consumer.api, api) - self.assertIsInstance(consumer.api, Configurable) - self.assertTrue(consumer.get_value()) - - def test_dependency_consumer_configuration(self): - @dependency.provider('api') - class Provider(object): - def get_value(self): - return True - - @dependency.requires('api') - class Configurable(object): - def __init__(self, value=None): - self.value = value - - def get_value(self): - if self.value: - return self.api.get_value() - - # initialize dependency providers - api = Provider() - - # ... sometime later, initialize a dependency consumer - consumer = Configurable(value=True) - - # the expected dependencies should be available to the consumer - self.assertIs(consumer.api, api) - self.assertIsInstance(consumer.api, Provider) - self.assertTrue(consumer.get_value()) - - def test_inherited_dependency(self): - class Interface(object): - def do_work(self): - assert False - - @dependency.provider('first_api') - class FirstImplementation(Interface): - def do_work(self): - return True - - @dependency.provider('second_api') - class SecondImplementation(Interface): - def do_work(self): - return True - - @dependency.requires('first_api') - class ParentConsumer(object): - def do_work_with_dependencies(self): - assert self.first_api.do_work() - - @dependency.requires('second_api') - class ChildConsumer(ParentConsumer): - def do_work_with_dependencies(self): - assert self.second_api.do_work() - super(ChildConsumer, self).do_work_with_dependencies() - - # initialize dependency providers - first_api = FirstImplementation() - second_api = SecondImplementation() - - # ... sometime later, initialize a dependency consumer - consumer = ChildConsumer() - - # dependencies should be naturally inherited - self.assertEqual( - ParentConsumer._dependencies, - set(['first_api'])) - self.assertEqual( - ChildConsumer._dependencies, - set(['first_api', 'second_api'])) - self.assertEqual( - consumer._dependencies, - set(['first_api', 'second_api'])) - - # the expected dependencies should be available to the consumer - self.assertIs(consumer.first_api, first_api) - self.assertIs(consumer.second_api, second_api) - self.assertIsInstance(consumer.first_api, Interface) - self.assertIsInstance(consumer.second_api, Interface) - consumer.do_work_with_dependencies() - - def test_unresolvable_dependency(self): - @dependency.requires(uuid.uuid4().hex) - class Consumer(object): - pass - - with self.assertRaises(dependency.UnresolvableDependencyException): - Consumer() - dependency.resolve_future_dependencies() - - def test_circular_dependency(self): - p1_name = uuid.uuid4().hex - p2_name = uuid.uuid4().hex - - @dependency.provider(p1_name) - @dependency.requires(p2_name) - class P1(object): - pass - - @dependency.provider(p2_name) - @dependency.requires(p1_name) - class P2(object): - pass - - p1 = P1() - p2 = P2() - - dependency.resolve_future_dependencies() - - self.assertIs(getattr(p1, p2_name), p2) - self.assertIs(getattr(p2, p1_name), p1) - - def test_reset(self): - # Can reset the registry of providers. - - p_id = uuid.uuid4().hex - - @dependency.provider(p_id) - class P(object): - pass - - p_inst = P() - - self.assertIs(dependency.REGISTRY[p_id], p_inst) - - dependency.reset() - - self.assertFalse(dependency.REGISTRY) diff --git a/tests/test_ipv6.py b/tests/test_ipv6.py deleted file mode 100644 index 9825a5fa..00000000 --- a/tests/test_ipv6.py +++ /dev/null @@ -1,51 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 keystone import test - -from keystone.common import environment -from keystone import config - - -CONF = config.CONF - - -class IPv6TestCase(test.TestCase): - @classmethod - def setUpClass(cls): - cls.skip_if_no_ipv6() - - def setUp(self): - super(IPv6TestCase, self).setUp() - self.load_backends() - - def test_ipv6_ok(self): - """Make sure both public and admin API work with ipv6.""" - self.public_server = self.serveapp('keystone', name='main', - host="::1", port=0) - self.admin_server = self.serveapp('keystone', name='admin', - host="::1", port=0) - # Verify Admin - conn = environment.httplib.HTTPConnection('::1', CONF.admin_port) - conn.request('GET', '/') - resp = conn.getresponse() - self.assertEqual(resp.status, 300) - # Verify Public - conn = environment.httplib.HTTPConnection('::1', CONF.public_port) - conn.request('GET', '/') - resp = conn.getresponse() - self.assertEqual(resp.status, 300) diff --git a/tests/test_keystoneclient.py b/tests/test_keystoneclient.py deleted file mode 100644 index 38062d4b..00000000 --- a/tests/test_keystoneclient.py +++ /dev/null @@ -1,1175 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 uuid -import webob - -from keystone import test - -from keystone import config -from keystone.openstack.common import jsonutils -from keystone.openstack.common import timeutils - -import default_fixtures - -CONF = config.CONF -DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id -OPENSTACK_REPO = 'https://review.openstack.org/p/openstack' -KEYSTONECLIENT_REPO = '%s/python-keystoneclient.git' % OPENSTACK_REPO - - -class CompatTestCase(test.TestCase): - def setUp(self): - super(CompatTestCase, self).setUp() - - # The backends should be loaded and initialized before the servers are - # started because the servers use the backends. - - self.load_backends() - self.load_fixtures(default_fixtures) - - # TODO(termie): add an admin user to the fixtures and use that user - # override the fixtures, for now - self.metadata_foobar = self.identity_api.add_role_to_user_and_project( - self.user_foo['id'], - self.tenant_bar['id'], - self.role_admin['id']) - - self.public_server = self.serveapp('keystone', name='main') - self.admin_server = self.serveapp('keystone', name='admin') - - revdir = test.checkout_vendor(*self.get_checkout()) - self.add_path(revdir) - self.clear_module('keystoneclient') - - def tearDown(self): - self.public_server.kill() - self.admin_server.kill() - self.public_server = None - self.admin_server = None - super(CompatTestCase, self).tearDown() - - def _public_url(self): - public_port = self.public_server.socket_info['socket'][1] - return "http://localhost:%s/v2.0" % public_port - - def _admin_url(self): - admin_port = self.admin_server.socket_info['socket'][1] - return "http://localhost:%s/v2.0" % admin_port - - def _client(self, admin=False, **kwargs): - from keystoneclient.v2_0 import client as ks_client - - url = self._admin_url() if admin else self._public_url() - kc = ks_client.Client(endpoint=url, - auth_url=self._public_url(), - **kwargs) - kc.authenticate() - # have to manually overwrite the management url after authentication - kc.management_url = url - return kc - - def get_client(self, user_ref=None, tenant_ref=None, admin=False): - if user_ref is None: - user_ref = self.user_foo - if tenant_ref is None: - for user in default_fixtures.USERS: - if user['id'] == user_ref['id']: - tenant_id = user['tenants'][0] - else: - tenant_id = tenant_ref['id'] - - return self._client(username=user_ref['name'], - password=user_ref['password'], - tenant_id=tenant_id, - admin=admin) - - -class KeystoneClientTests(object): - """Tests for all versions of keystoneclient.""" - - def test_authenticate_tenant_name_and_tenants(self): - client = self.get_client() - tenants = client.tenants.list() - self.assertEquals(tenants[0].id, self.tenant_bar['id']) - - def test_authenticate_tenant_id_and_tenants(self): - client = self._client(username=self.user_foo['name'], - password=self.user_foo['password'], - tenant_id='bar') - tenants = client.tenants.list() - self.assertEquals(tenants[0].id, self.tenant_bar['id']) - - def test_authenticate_invalid_tenant_id(self): - from keystoneclient import exceptions as client_exceptions - self.assertRaises(client_exceptions.Unauthorized, - self._client, - username=self.user_foo['name'], - password=self.user_foo['password'], - tenant_id='baz') - - def test_authenticate_token_no_tenant(self): - client = self.get_client() - token = client.auth_token - token_client = self._client(token=token) - tenants = token_client.tenants.list() - self.assertEquals(tenants[0].id, self.tenant_bar['id']) - - def test_authenticate_token_tenant_id(self): - client = self.get_client() - token = client.auth_token - token_client = self._client(token=token, tenant_id='bar') - tenants = token_client.tenants.list() - self.assertEquals(tenants[0].id, self.tenant_bar['id']) - - def test_authenticate_token_invalid_tenant_id(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client() - token = client.auth_token - self.assertRaises(client_exceptions.Unauthorized, - self._client, token=token, - tenant_id=uuid.uuid4().hex) - - def test_authenticate_token_invalid_tenant_name(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client() - token = client.auth_token - self.assertRaises(client_exceptions.Unauthorized, - self._client, token=token, - tenant_name=uuid.uuid4().hex) - - def test_authenticate_token_tenant_name(self): - client = self.get_client() - token = client.auth_token - token_client = self._client(token=token, tenant_name='BAR') - tenants = token_client.tenants.list() - self.assertEquals(tenants[0].id, self.tenant_bar['id']) - self.assertEquals(tenants[0].id, self.tenant_bar['id']) - - def test_authenticate_and_delete_token(self): - from keystoneclient import exceptions as client_exceptions - - client = self.get_client(admin=True) - token = client.auth_token - token_client = self._client(token=token) - tenants = token_client.tenants.list() - self.assertEquals(tenants[0].id, self.tenant_bar['id']) - - client.tokens.delete(token_client.auth_token) - - self.assertRaises(client_exceptions.Unauthorized, - token_client.tenants.list) - - def test_authenticate_no_password(self): - from keystoneclient import exceptions as client_exceptions - - user_ref = self.user_foo.copy() - user_ref['password'] = None - self.assertRaises(client_exceptions.AuthorizationFailure, - self.get_client, - user_ref) - - def test_authenticate_no_username(self): - from keystoneclient import exceptions as client_exceptions - - user_ref = self.user_foo.copy() - user_ref['name'] = None - self.assertRaises(client_exceptions.AuthorizationFailure, - self.get_client, - user_ref) - - def test_authenticate_disabled_tenant(self): - from keystoneclient import exceptions as client_exceptions - - admin_client = self.get_client(admin=True) - - tenant = { - 'name': uuid.uuid4().hex, - 'description': uuid.uuid4().hex, - 'enabled': False, - } - tenant_ref = admin_client.tenants.create( - tenant_name=tenant['name'], - description=tenant['description'], - enabled=tenant['enabled']) - tenant['id'] = tenant_ref.id - - user = { - 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, - 'email': uuid.uuid4().hex, - 'tenant_id': tenant['id'], - } - user_ref = admin_client.users.create( - name=user['name'], - password=user['password'], - email=user['email'], - tenant_id=user['tenant_id']) - user['id'] = user_ref.id - - # password authentication - self.assertRaises( - client_exceptions.Unauthorized, - self._client, - username=user['name'], - password=user['password'], - tenant_id=tenant['id']) - - # token authentication - client = self._client( - username=user['name'], - password=user['password']) - self.assertRaises( - client_exceptions.Unauthorized, - self._client, - token=client.auth_token, - tenant_id=tenant['id']) - - # FIXME(ja): this test should require the "keystone:admin" roled - # (probably the role set via --keystone_admin_role flag) - # FIXME(ja): add a test that admin endpoint is only sent to admin user - # FIXME(ja): add a test that admin endpoint returns unauthorized if not - # admin - def test_tenant_create_update_and_delete(self): - from keystoneclient import exceptions as client_exceptions - - tenant_name = 'original_tenant' - tenant_description = 'My original tenant!' - tenant_enabled = True - client = self.get_client(admin=True) - - # create, get, and list a tenant - tenant = client.tenants.create(tenant_name=tenant_name, - description=tenant_description, - enabled=tenant_enabled) - self.assertEquals(tenant.name, tenant_name) - self.assertEquals(tenant.description, tenant_description) - self.assertEquals(tenant.enabled, tenant_enabled) - - tenant = client.tenants.get(tenant_id=tenant.id) - self.assertEquals(tenant.name, tenant_name) - self.assertEquals(tenant.description, tenant_description) - self.assertEquals(tenant.enabled, tenant_enabled) - - tenant = [t for t in client.tenants.list() if t.id == tenant.id].pop() - self.assertEquals(tenant.name, tenant_name) - self.assertEquals(tenant.description, tenant_description) - self.assertEquals(tenant.enabled, tenant_enabled) - - # update, get, and list a tenant - tenant_name = 'updated_tenant' - tenant_description = 'Updated tenant!' - tenant_enabled = False - tenant = client.tenants.update(tenant_id=tenant.id, - tenant_name=tenant_name, - enabled=tenant_enabled, - description=tenant_description) - self.assertEquals(tenant.name, tenant_name) - self.assertEquals(tenant.description, tenant_description) - self.assertEquals(tenant.enabled, tenant_enabled) - - tenant = client.tenants.get(tenant_id=tenant.id) - self.assertEquals(tenant.name, tenant_name) - self.assertEquals(tenant.description, tenant_description) - self.assertEquals(tenant.enabled, tenant_enabled) - - tenant = [t for t in client.tenants.list() if t.id == tenant.id].pop() - self.assertEquals(tenant.name, tenant_name) - self.assertEquals(tenant.description, tenant_description) - self.assertEquals(tenant.enabled, tenant_enabled) - - # delete, get, and list a tenant - client.tenants.delete(tenant=tenant.id) - self.assertRaises(client_exceptions.NotFound, client.tenants.get, - tenant.id) - self.assertFalse([t for t in client.tenants.list() - if t.id == tenant.id]) - - def test_tenant_create_no_name(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.BadRequest, - client.tenants.create, - tenant_name="") - - def test_tenant_delete_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.tenants.delete, - tenant=uuid.uuid4().hex) - - def test_tenant_get_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.tenants.get, - tenant_id=uuid.uuid4().hex) - - def test_tenant_update_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.tenants.update, - tenant_id=uuid.uuid4().hex) - - def test_tenant_list(self): - client = self.get_client() - tenants = client.tenants.list() - self.assertEquals(len(tenants), 1) - - # Admin endpoint should return *all* tenants - client = self.get_client(admin=True) - tenants = client.tenants.list() - self.assertEquals(len(tenants), len(default_fixtures.TENANTS)) - - def test_invalid_password(self): - from keystoneclient import exceptions as client_exceptions - - good_client = self._client(username=self.user_foo['name'], - password=self.user_foo['password']) - good_client.tenants.list() - - self.assertRaises(client_exceptions.Unauthorized, - self._client, - username=self.user_foo['name'], - password=uuid.uuid4().hex) - - def test_invalid_user_and_password(self): - from keystoneclient import exceptions as client_exceptions - - self.assertRaises(client_exceptions.Unauthorized, - self._client, - username=uuid.uuid4().hex, - password=uuid.uuid4().hex) - - def test_change_password_invalidates_token(self): - from keystoneclient import exceptions as client_exceptions - - client = self.get_client(admin=True) - - username = uuid.uuid4().hex - passwd = uuid.uuid4().hex - user = client.users.create(name=username, password=passwd, - email=uuid.uuid4().hex) - - token_id = client.tokens.authenticate(username=username, - password=passwd).id - - # authenticate with a token should work before a password change - client.tokens.authenticate(token=token_id) - - client.users.update_password(user=user.id, password=uuid.uuid4().hex) - - # authenticate with a token should not work after a password change - self.assertRaises(client_exceptions.Unauthorized, - client.tokens.authenticate, - token=token_id) - - def test_disable_user_invalidates_token(self): - from keystoneclient import exceptions as client_exceptions - - admin_client = self.get_client(admin=True) - foo_client = self.get_client(self.user_foo) - - admin_client.users.update_enabled(user=self.user_foo['id'], - enabled=False) - - self.assertRaises(client_exceptions.Unauthorized, - foo_client.tokens.authenticate, - token=foo_client.auth_token) - - self.assertRaises(client_exceptions.Unauthorized, - self.get_client, - self.user_foo) - - def test_delete_user_invalidates_token(self): - from keystoneclient import exceptions as client_exceptions - - admin_client = self.get_client(admin=True) - client = self.get_client(admin=False) - - username = uuid.uuid4().hex - password = uuid.uuid4().hex - user_id = admin_client.users.create( - name=username, password=password, email=uuid.uuid4().hex).id - - token_id = client.tokens.authenticate( - username=username, password=password).id - - # token should be usable before the user is deleted - client.tokens.authenticate(token=token_id) - - admin_client.users.delete(user=user_id) - - # authenticate with a token should not work after the user is deleted - self.assertRaises(client_exceptions.Unauthorized, - client.tokens.authenticate, - token=token_id) - - def test_token_expiry_maintained(self): - timeutils.set_time_override() - foo_client = self.get_client(self.user_foo) - - orig_token = foo_client.service_catalog.catalog['token'] - timeutils.advance_time_seconds(1) - reauthenticated_token = foo_client.tokens.authenticate( - token=foo_client.auth_token) - - self.assertCloseEnoughForGovernmentWork( - timeutils.parse_isotime(orig_token['expires']), - timeutils.parse_isotime(reauthenticated_token.expires)) - - def test_user_create_update_delete(self): - from keystoneclient import exceptions as client_exceptions - - test_username = 'new_user' - client = self.get_client(admin=True) - user = client.users.create(name=test_username, - password='password', - email='user1@test.com') - self.assertEquals(user.name, test_username) - - user = client.users.get(user=user.id) - self.assertEquals(user.name, test_username) - - user = client.users.update(user=user, - name=test_username, - email='user2@test.com') - self.assertEquals(user.email, 'user2@test.com') - - # NOTE(termie): update_enabled doesn't return anything, probably a bug - client.users.update_enabled(user=user, enabled=False) - user = client.users.get(user.id) - self.assertFalse(user.enabled) - - self.assertRaises(client_exceptions.Unauthorized, - self._client, - username=test_username, - password='password') - client.users.update_enabled(user, True) - - user = client.users.update_password(user=user, password='password2') - - self._client(username=test_username, - password='password2') - - user = client.users.update_tenant(user=user, tenant='bar') - # TODO(ja): once keystonelight supports default tenant - # when you login without specifying tenant, the - # token should be scoped to tenant 'bar' - - client.users.delete(user.id) - self.assertRaises(client_exceptions.NotFound, client.users.get, - user.id) - - # Test creating a user with a tenant (auto-add to tenant) - user2 = client.users.create(name=test_username, - password='password', - email='user1@test.com', - tenant_id='bar') - self.assertEquals(user2.name, test_username) - - def test_update_default_tenant_to_existing_value(self): - client = self.get_client(admin=True) - - user = client.users.create( - name=uuid.uuid4().hex, - password=uuid.uuid4().hex, - email=uuid.uuid4().hex, - tenant_id=self.tenant_bar['id']) - - # attempting to update the tenant with the existing value should work - user = client.users.update_tenant( - user=user, tenant=self.tenant_bar['id']) - - def test_user_create_no_name(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.BadRequest, - client.users.create, - name="", - password=uuid.uuid4().hex, - email=uuid.uuid4().hex) - - def test_user_create_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.users.create, - name=uuid.uuid4().hex, - password=uuid.uuid4().hex, - email=uuid.uuid4().hex, - tenant_id=uuid.uuid4().hex) - - def test_user_get_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.users.get, - user=uuid.uuid4().hex) - - def test_user_list_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.users.list, - tenant_id=uuid.uuid4().hex) - - def test_user_update_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.users.update, - user=uuid.uuid4().hex) - - def test_user_update_tenant_404(self): - self.skipTest('N/A') - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.users.update, - user=self.user_foo['id'], - tenant_id=uuid.uuid4().hex) - - def test_user_update_password_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.users.update_password, - user=uuid.uuid4().hex, - password=uuid.uuid4().hex) - - def test_user_delete_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.users.delete, - user=uuid.uuid4().hex) - - def test_user_list(self): - client = self.get_client(admin=True) - users = client.users.list() - self.assertTrue(len(users) > 0) - user = users[0] - self.assertRaises(AttributeError, lambda: user.password) - - def test_user_get(self): - client = self.get_client(admin=True) - user = client.users.get(user=self.user_foo['id']) - self.assertRaises(AttributeError, lambda: user.password) - - def test_role_get(self): - client = self.get_client(admin=True) - role = client.roles.get(role=self.role_admin['id']) - self.assertEquals(role.id, self.role_admin['id']) - - def test_role_crud(self): - from keystoneclient import exceptions as client_exceptions - - test_role = 'new_role' - client = self.get_client(admin=True) - role = client.roles.create(name=test_role) - self.assertEquals(role.name, test_role) - - role = client.roles.get(role=role.id) - self.assertEquals(role.name, test_role) - - client.roles.delete(role=role.id) - - self.assertRaises(client_exceptions.NotFound, - client.roles.delete, - role=role.id) - self.assertRaises(client_exceptions.NotFound, - client.roles.get, - role=role.id) - - def test_role_create_no_name(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.BadRequest, - client.roles.create, - name="") - - def test_role_get_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.roles.get, - role=uuid.uuid4().hex) - - def test_role_delete_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.roles.delete, - role=uuid.uuid4().hex) - - def test_role_list_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.roles.roles_for_user, - user=uuid.uuid4().hex, - tenant=uuid.uuid4().hex) - self.assertRaises(client_exceptions.NotFound, - client.roles.roles_for_user, - user=self.user_foo['id'], - tenant=uuid.uuid4().hex) - self.assertRaises(client_exceptions.NotFound, - client.roles.roles_for_user, - user=uuid.uuid4().hex, - tenant=self.tenant_bar['id']) - - def test_role_list(self): - client = self.get_client(admin=True) - roles = client.roles.list() - # TODO(devcamcar): This assert should be more specific. - self.assertTrue(len(roles) > 0) - - def test_ec2_credential_crud(self): - client = self.get_client() - creds = client.ec2.list(user_id=self.user_foo['id']) - self.assertEquals(creds, []) - - cred = client.ec2.create(user_id=self.user_foo['id'], - tenant_id=self.tenant_bar['id']) - creds = client.ec2.list(user_id=self.user_foo['id']) - self.assertEquals(creds, [cred]) - - got = client.ec2.get(user_id=self.user_foo['id'], access=cred.access) - self.assertEquals(cred, got) - - client.ec2.delete(user_id=self.user_foo['id'], access=cred.access) - creds = client.ec2.list(user_id=self.user_foo['id']) - self.assertEquals(creds, []) - - def test_ec2_credentials_create_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client() - self.assertRaises(client_exceptions.NotFound, - client.ec2.create, - user_id=uuid.uuid4().hex, - tenant_id=self.tenant_bar['id']) - self.assertRaises(client_exceptions.NotFound, - client.ec2.create, - user_id=self.user_foo['id'], - tenant_id=uuid.uuid4().hex) - - def test_ec2_credentials_delete_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client() - self.assertRaises(client_exceptions.NotFound, - client.ec2.delete, - user_id=uuid.uuid4().hex, - access=uuid.uuid4().hex) - - def test_ec2_credentials_get_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client() - self.assertRaises(client_exceptions.NotFound, - client.ec2.get, - user_id=uuid.uuid4().hex, - access=uuid.uuid4().hex) - - def test_ec2_credentials_list_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client() - self.assertRaises(client_exceptions.NotFound, - client.ec2.list, - user_id=uuid.uuid4().hex) - - def test_ec2_credentials_list_user_forbidden(self): - from keystoneclient import exceptions as client_exceptions - - two = self.get_client(self.user_two) - self.assertRaises(client_exceptions.Forbidden, two.ec2.list, - user_id=self.user_foo['id']) - - def test_ec2_credentials_get_user_forbidden(self): - from keystoneclient import exceptions as client_exceptions - - foo = self.get_client() - cred = foo.ec2.create(user_id=self.user_foo['id'], - tenant_id=self.tenant_bar['id']) - - two = self.get_client(self.user_two) - self.assertRaises(client_exceptions.Forbidden, two.ec2.get, - user_id=self.user_foo['id'], access=cred.access) - - foo.ec2.delete(user_id=self.user_foo['id'], access=cred.access) - - def test_ec2_credentials_delete_user_forbidden(self): - from keystoneclient import exceptions as client_exceptions - - foo = self.get_client() - cred = foo.ec2.create(user_id=self.user_foo['id'], - tenant_id=self.tenant_bar['id']) - - two = self.get_client(self.user_two) - self.assertRaises(client_exceptions.Forbidden, two.ec2.delete, - user_id=self.user_foo['id'], access=cred.access) - - foo.ec2.delete(user_id=self.user_foo['id'], access=cred.access) - - def test_service_crud(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - - service_name = uuid.uuid4().hex - service_type = uuid.uuid4().hex - service_desc = uuid.uuid4().hex - - # create & read - service = client.services.create(name=service_name, - service_type=service_type, - description=service_desc) - self.assertEquals(service_name, service.name) - self.assertEquals(service_type, service.type) - self.assertEquals(service_desc, service.description) - - service = client.services.get(id=service.id) - self.assertEquals(service_name, service.name) - self.assertEquals(service_type, service.type) - self.assertEquals(service_desc, service.description) - - service = [x for x in client.services.list() if x.id == service.id][0] - self.assertEquals(service_name, service.name) - self.assertEquals(service_type, service.type) - self.assertEquals(service_desc, service.description) - - # update is not supported in API v2... - - # delete & read - client.services.delete(id=service.id) - self.assertRaises(client_exceptions.NotFound, - client.services.get, - id=service.id) - services = [x for x in client.services.list() if x.id == service.id] - self.assertEquals(len(services), 0) - - def test_service_delete_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.services.delete, - id=uuid.uuid4().hex) - - def test_service_get_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.services.get, - id=uuid.uuid4().hex) - - def test_endpoint_delete_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.endpoints.delete, - id=uuid.uuid4().hex) - - def test_admin_requires_adminness(self): - from keystoneclient import exceptions as client_exceptions - # FIXME(ja): this should be Unauthorized - exception = client_exceptions.ClientException - - two = self.get_client(self.user_two, admin=True) # non-admin user - - # USER CRUD - self.assertRaises(exception, - two.users.list) - self.assertRaises(exception, - two.users.get, - user=self.user_two['id']) - self.assertRaises(exception, - two.users.create, - name='oops', - password='password', - email='oops@test.com') - self.assertRaises(exception, - two.users.delete, - user=self.user_foo['id']) - - # TENANT CRUD - self.assertRaises(exception, - two.tenants.list) - self.assertRaises(exception, - two.tenants.get, - tenant_id=self.tenant_bar['id']) - self.assertRaises(exception, - two.tenants.create, - tenant_name='oops', - description="shouldn't work!", - enabled=True) - self.assertRaises(exception, - two.tenants.delete, - tenant=self.tenant_baz['id']) - - # ROLE CRUD - self.assertRaises(exception, - two.roles.get, - role=self.role_admin['id']) - self.assertRaises(exception, - two.roles.list) - self.assertRaises(exception, - two.roles.create, - name='oops') - self.assertRaises(exception, - two.roles.delete, - role=self.role_admin['id']) - - # TODO(ja): MEMBERSHIP CRUD - # TODO(ja): determine what else todo - - -class KcMasterTestCase(CompatTestCase, KeystoneClientTests): - def get_checkout(self): - return KEYSTONECLIENT_REPO, 'master' - - def test_ec2_auth(self): - client = self.get_client() - cred = client.ec2.create(user_id=self.user_foo['id'], - tenant_id=self.tenant_bar['id']) - - from keystoneclient.contrib.ec2 import utils as ec2_utils - signer = ec2_utils.Ec2Signer(cred.secret) - credentials = {'params': {'SignatureVersion': '2'}, - 'access': cred.access, - 'verb': 'GET', - 'host': 'localhost', - 'path': '/thisisgoingtowork'} - signature = signer.generate(credentials) - credentials['signature'] = signature - url = '%s/ec2tokens' % (client.auth_url) - (resp, token) = client.request(url=url, - method='POST', - body={'credentials': credentials}) - # make sure we have a v2 token - self.assertEqual(resp.status_code, 200) - self.assertIn('access', token) - - def test_tenant_add_and_remove_user(self): - client = self.get_client(admin=True) - client.roles.add_user_role(tenant=self.tenant_bar['id'], - user=self.user_two['id'], - role=self.role_other['id']) - user_refs = client.tenants.list_users(tenant=self.tenant_bar['id']) - self.assert_(self.user_two['id'] in [x.id for x in user_refs]) - client.roles.remove_user_role(tenant=self.tenant_bar['id'], - user=self.user_two['id'], - role=self.role_other['id']) - roles = client.roles.roles_for_user(user=self.user_foo['id'], - tenant=self.tenant_bar['id']) - self.assertNotIn(self.role_other['id'], roles) - user_refs = client.tenants.list_users(tenant=self.tenant_bar['id']) - self.assertNotIn(self.user_two['id'], [x.id for x in user_refs]) - - def test_user_role_add_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.roles.add_user_role, - tenant=uuid.uuid4().hex, - user=self.user_foo['id'], - role=self.role_member['id']) - self.assertRaises(client_exceptions.NotFound, - client.roles.add_user_role, - tenant=self.tenant_baz['id'], - user=uuid.uuid4().hex, - role=self.role_member['id']) - self.assertRaises(client_exceptions.NotFound, - client.roles.add_user_role, - tenant=self.tenant_baz['id'], - user=self.user_foo['id'], - role=uuid.uuid4().hex) - - def test_user_role_remove_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.roles.remove_user_role, - tenant=uuid.uuid4().hex, - user=self.user_foo['id'], - role=self.role_member['id']) - self.assertRaises(client_exceptions.NotFound, - client.roles.remove_user_role, - tenant=self.tenant_baz['id'], - user=uuid.uuid4().hex, - role=self.role_member['id']) - self.assertRaises(client_exceptions.NotFound, - client.roles.remove_user_role, - tenant=self.tenant_baz['id'], - user=self.user_foo['id'], - role=uuid.uuid4().hex) - self.assertRaises(client_exceptions.NotFound, - client.roles.remove_user_role, - tenant=self.tenant_baz['id'], - user=self.user_foo['id'], - role=self.role_member['id']) - - def test_tenant_list_marker(self): - client = self.get_client() - - # Add two arbitrary tenants to user for testing purposes - for i in range(2): - tenant_id = uuid.uuid4().hex - tenant = {'name': 'tenant-%s' % tenant_id, 'id': tenant_id, - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_project(tenant_id, tenant) - self.identity_api.add_user_to_project(tenant_id, - self.user_foo['id']) - - tenants = client.tenants.list() - self.assertEqual(len(tenants), 3) - - tenants_marker = client.tenants.list(marker=tenants[0].id) - self.assertEqual(len(tenants_marker), 2) - self.assertEqual(tenants[1].name, tenants_marker[0].name) - self.assertEqual(tenants[2].name, tenants_marker[1].name) - - def test_tenant_list_marker_not_found(self): - from keystoneclient import exceptions as client_exceptions - - client = self.get_client() - self.assertRaises(client_exceptions.BadRequest, - client.tenants.list, marker=uuid.uuid4().hex) - - def test_tenant_list_limit(self): - client = self.get_client() - - # Add two arbitrary tenants to user for testing purposes - for i in range(2): - tenant_id = uuid.uuid4().hex - tenant = {'name': 'tenant-%s' % tenant_id, 'id': tenant_id, - 'domain_id': DEFAULT_DOMAIN_ID} - self.identity_api.create_project(tenant_id, tenant) - self.identity_api.add_user_to_project(tenant_id, - self.user_foo['id']) - - tenants = client.tenants.list() - self.assertEqual(len(tenants), 3) - - tenants_limited = client.tenants.list(limit=2) - self.assertEqual(len(tenants_limited), 2) - self.assertEqual(tenants[0].name, tenants_limited[0].name) - self.assertEqual(tenants[1].name, tenants_limited[1].name) - - def test_tenant_list_limit_bad_value(self): - from keystoneclient import exceptions as client_exceptions - - client = self.get_client() - self.assertRaises(client_exceptions.BadRequest, - client.tenants.list, limit='a') - self.assertRaises(client_exceptions.BadRequest, - client.tenants.list, limit=-1) - - def test_roles_get_by_user(self): - client = self.get_client(admin=True) - roles = client.roles.roles_for_user(user=self.user_foo['id'], - tenant=self.tenant_bar['id']) - self.assertTrue(len(roles) > 0) - - def test_user_can_update_passwd(self): - client = self.get_client(self.user_two) - - token_id = client.auth_token - new_password = uuid.uuid4().hex - - # TODO(derekh): Update to use keystoneclient when available - class FakeResponse(object): - def start_fake_response(self, status, headers): - self.response_status = int(status.split(' ', 1)[0]) - self.response_headers = dict(headers) - responseobject = FakeResponse() - - req = webob.Request.blank( - '/v2.0/OS-KSCRUD/users/%s' % self.user_two['id'], - headers={'X-Auth-Token': token_id}) - req.method = 'PATCH' - req.body = ('{"user":{"password":"%s","original_password":"%s"}}' % - (new_password, self.user_two['password'])) - self.public_server.application(req.environ, - responseobject.start_fake_response) - - self.user_two['password'] = new_password - self.get_client(self.user_two) - - def test_user_cannot_update_other_users_passwd(self): - from keystoneclient import exceptions as client_exceptions - - client = self.get_client(self.user_two) - - token_id = client.auth_token - new_password = uuid.uuid4().hex - - # TODO(derekh): Update to use keystoneclient when available - class FakeResponse(object): - def start_fake_response(self, status, headers): - self.response_status = int(status.split(' ', 1)[0]) - self.response_headers = dict(headers) - responseobject = FakeResponse() - - req = webob.Request.blank( - '/v2.0/OS-KSCRUD/users/%s' % self.user_foo['id'], - headers={'X-Auth-Token': token_id}) - req.method = 'PATCH' - req.body = ('{"user":{"password":"%s","original_password":"%s"}}' % - (new_password, self.user_two['password'])) - self.public_server.application(req.environ, - responseobject.start_fake_response) - self.assertEquals(403, responseobject.response_status) - - self.user_two['password'] = new_password - self.assertRaises(client_exceptions.Unauthorized, - self.get_client, self.user_two) - - def test_tokens_after_user_update_passwd(self): - from keystoneclient import exceptions as client_exceptions - - client = self.get_client(self.user_two) - - token_id = client.auth_token - new_password = uuid.uuid4().hex - - # TODO(derekh): Update to use keystoneclient when available - class FakeResponse(object): - def start_fake_response(self, status, headers): - self.response_status = int(status.split(' ', 1)[0]) - self.response_headers = dict(headers) - responseobject = FakeResponse() - - req = webob.Request.blank( - '/v2.0/OS-KSCRUD/users/%s' % self.user_two['id'], - headers={'X-Auth-Token': token_id}) - req.method = 'PATCH' - req.body = ('{"user":{"password":"%s","original_password":"%s"}}' % - (new_password, self.user_two['password'])) - - rv = self.public_server.application( - req.environ, - responseobject.start_fake_response) - response_json = jsonutils.loads(rv.pop()) - new_token_id = response_json['access']['token']['id'] - - self.assertRaises(client_exceptions.Unauthorized, client.tenants.list) - client.auth_token = new_token_id - client.tenants.list() - - -class KcEssex3TestCase(CompatTestCase, KeystoneClientTests): - def get_checkout(self): - return KEYSTONECLIENT_REPO, 'essex-3' - - def test_tenant_add_and_remove_user(self): - client = self.get_client(admin=True) - client.roles.add_user_to_tenant(tenant_id=self.tenant_bar['id'], - user_id=self.user_two['id'], - role_id=self.role_member['id']) - role_refs = client.roles.get_user_role_refs( - user_id=self.user_two['id']) - self.assert_(self.tenant_baz['id'] in [x.tenantId for x in role_refs]) - - # get the "role_refs" so we get the proper id, this is how the clients - # do it - roleref_refs = client.roles.get_user_role_refs( - user_id=self.user_two['id']) - for roleref_ref in roleref_refs: - if (roleref_ref.roleId == self.role_member['id'] - and roleref_ref.tenantId == self.tenant_baz['id']): - # use python's scope fall through to leave roleref_ref set - break - - client.roles.remove_user_from_tenant(tenant_id=self.tenant_bar['id'], - user_id=self.user_two['id'], - role_id=roleref_ref.id) - - role_refs = client.roles.get_user_role_refs( - user_id=self.user_two['id']) - self.assert_(self.tenant_baz['id'] not in - [x.tenantId for x in role_refs]) - - def test_roles_get_by_user(self): - client = self.get_client(admin=True) - roles = client.roles.get_user_role_refs(user_id='foo') - self.assertTrue(len(roles) > 0) - - def test_role_list_404(self): - self.skipTest('N/A') - - def test_authenticate_and_delete_token(self): - self.skipTest('N/A') - - def test_user_create_update_delete(self): - from keystoneclient import exceptions as client_exceptions - - test_username = 'new_user' - client = self.get_client(admin=True) - user = client.users.create(name=test_username, - password='password', - email='user1@test.com') - self.assertEquals(user.name, test_username) - - user = client.users.get(user=user.id) - self.assertEquals(user.name, test_username) - - user = client.users.update_email(user=user, email='user2@test.com') - self.assertEquals(user.email, 'user2@test.com') - - # NOTE(termie): update_enabled doesn't return anything, probably a bug - client.users.update_enabled(user=user, enabled=False) - user = client.users.get(user.id) - self.assertFalse(user.enabled) - - self.assertRaises(client_exceptions.Unauthorized, - self._client, - username=test_username, - password='password') - client.users.update_enabled(user, True) - - user = client.users.update_password(user=user, password='password2') - - self._client(username=test_username, - password='password2') - - user = client.users.update_tenant(user=user, tenant='bar') - # TODO(ja): once keystonelight supports default tenant - # when you login without specifying tenant, the - # token should be scoped to tenant 'bar' - - client.users.delete(user.id) - self.assertRaises(client_exceptions.NotFound, client.users.get, - user.id) - - def test_user_update_404(self): - self.skipTest('N/A') - - def test_endpoint_create_404(self): - self.skipTest('N/A') - - def test_endpoint_delete_404(self): - self.skipTest('N/A') - - def test_policy_crud(self): - self.skipTest('N/A due to lack of endpoint CRUD') - - -class Kc11TestCase(CompatTestCase, KeystoneClientTests): - def get_checkout(self): - return KEYSTONECLIENT_REPO, '0.1.1' - - def test_policy_crud(self): - self.skipTest('N/A') diff --git a/tests/test_keystoneclient_sql.py b/tests/test_keystoneclient_sql.py deleted file mode 100644 index 166d808c..00000000 --- a/tests/test_keystoneclient_sql.py +++ /dev/null @@ -1,176 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 uuid - -from keystone import test - -from keystone.common import sql -from keystone import config - -import test_keystoneclient - - -CONF = config.CONF - - -class KcMasterSqlTestCase(test_keystoneclient.KcMasterTestCase, sql.Base): - def config(self, config_files): - super(KcMasterSqlTestCase, self).config([ - test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf'), - test.testsdir('backend_sql.conf')]) - - self.load_backends() - self.engine = self.get_engine() - sql.ModelBase.metadata.create_all(bind=self.engine) - - def tearDown(self): - sql.ModelBase.metadata.drop_all(bind=self.engine) - self.engine.dispose() - sql.set_global_engine(None) - super(KcMasterSqlTestCase, self).tearDown() - - def test_endpoint_crud(self): - from keystoneclient import exceptions as client_exceptions - - client = self.get_client(admin=True) - - service = client.services.create(name=uuid.uuid4().hex, - service_type=uuid.uuid4().hex, - description=uuid.uuid4().hex) - - endpoint_region = uuid.uuid4().hex - invalid_service_id = uuid.uuid4().hex - endpoint_publicurl = uuid.uuid4().hex - endpoint_internalurl = uuid.uuid4().hex - endpoint_adminurl = uuid.uuid4().hex - - # a non-existent service ID should trigger a 404 - self.assertRaises(client_exceptions.NotFound, - client.endpoints.create, - region=endpoint_region, - service_id=invalid_service_id, - publicurl=endpoint_publicurl, - adminurl=endpoint_adminurl, - internalurl=endpoint_internalurl) - - endpoint = client.endpoints.create(region=endpoint_region, - service_id=service.id, - publicurl=endpoint_publicurl, - adminurl=endpoint_adminurl, - internalurl=endpoint_internalurl) - - self.assertEquals(endpoint.region, endpoint_region) - self.assertEquals(endpoint.service_id, service.id) - self.assertEquals(endpoint.publicurl, endpoint_publicurl) - self.assertEquals(endpoint.internalurl, endpoint_internalurl) - self.assertEquals(endpoint.adminurl, endpoint_adminurl) - - client.endpoints.delete(id=endpoint.id) - self.assertRaises(client_exceptions.NotFound, client.endpoints.delete, - id=endpoint.id) - - def test_endpoint_create_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.endpoints.create, - region=uuid.uuid4().hex, - service_id=uuid.uuid4().hex, - publicurl=uuid.uuid4().hex, - adminurl=uuid.uuid4().hex, - internalurl=uuid.uuid4().hex) - - def test_endpoint_delete_404(self): - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - self.assertRaises(client_exceptions.NotFound, - client.endpoints.delete, - id=uuid.uuid4().hex) - - def test_policy_crud(self): - # FIXME(dolph): this test was written prior to the v3 implementation of - # the client and essentially refers to a non-existent - # policy manager in the v2 client. this test needs to be - # moved to a test suite running against the v3 api - self.skipTest('Written prior to v3 client; needs refactor') - - from keystoneclient import exceptions as client_exceptions - client = self.get_client(admin=True) - - policy_blob = uuid.uuid4().hex - policy_type = uuid.uuid4().hex - service = client.services.create( - name=uuid.uuid4().hex, - service_type=uuid.uuid4().hex, - description=uuid.uuid4().hex) - endpoint = client.endpoints.create( - service_id=service.id, - region=uuid.uuid4().hex, - adminurl=uuid.uuid4().hex, - internalurl=uuid.uuid4().hex, - publicurl=uuid.uuid4().hex) - - # create - policy = client.policies.create( - blob=policy_blob, - type=policy_type, - endpoint=endpoint.id) - self.assertEquals(policy_blob, policy.policy) - self.assertEquals(policy_type, policy.type) - self.assertEquals(endpoint.id, policy.endpoint_id) - - policy = client.policies.get(policy=policy.id) - self.assertEquals(policy_blob, policy.policy) - self.assertEquals(policy_type, policy.type) - self.assertEquals(endpoint.id, policy.endpoint_id) - - endpoints = [x for x in client.endpoints.list() if x.id == endpoint.id] - endpoint = endpoints[0] - self.assertEquals(policy_blob, policy.policy) - self.assertEquals(policy_type, policy.type) - self.assertEquals(endpoint.id, policy.endpoint_id) - - # update - policy_blob = uuid.uuid4().hex - policy_type = uuid.uuid4().hex - endpoint = client.endpoints.create( - service_id=service.id, - region=uuid.uuid4().hex, - adminurl=uuid.uuid4().hex, - internalurl=uuid.uuid4().hex, - publicurl=uuid.uuid4().hex) - - policy = client.policies.update( - policy=policy.id, - blob=policy_blob, - type=policy_type, - endpoint=endpoint.id) - - policy = client.policies.get(policy=policy.id) - self.assertEquals(policy_blob, policy.policy) - self.assertEquals(policy_type, policy.type) - self.assertEquals(endpoint.id, policy.endpoint_id) - - # delete - client.policies.delete(policy=policy.id) - self.assertRaises( - client_exceptions.NotFound, - client.policies.get, - policy=policy.id) - policies = [x for x in client.policies.list() if x.id == policy.id] - self.assertEquals(len(policies), 0) diff --git a/tests/test_middleware.py b/tests/test_middleware.py deleted file mode 100644 index 9f9d3fd2..00000000 --- a/tests/test_middleware.py +++ /dev/null @@ -1,163 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 webob - -from keystone import test - -from keystone import config -from keystone import middleware -from keystone.openstack.common import jsonutils - - -CONF = config.CONF - - -def make_request(**kwargs): - accept = kwargs.pop('accept', None) - method = kwargs.pop('method', 'GET') - body = kwargs.pop('body', None) - req = webob.Request.blank('/', **kwargs) - req.method = method - if body is not None: - req.body = body - if accept is not None: - req.accept = accept - return req - - -def make_response(**kwargs): - body = kwargs.pop('body', None) - return webob.Response(body) - - -class TokenAuthMiddlewareTest(test.TestCase): - def test_request(self): - req = make_request() - req.headers[middleware.AUTH_TOKEN_HEADER] = 'MAGIC' - middleware.TokenAuthMiddleware(None).process_request(req) - context = req.environ[middleware.CONTEXT_ENV] - self.assertEqual(context['token_id'], 'MAGIC') - - -class AdminTokenAuthMiddlewareTest(test.TestCase): - def test_request_admin(self): - req = make_request() - req.headers[middleware.AUTH_TOKEN_HEADER] = CONF.admin_token - middleware.AdminTokenAuthMiddleware(None).process_request(req) - context = req.environ[middleware.CONTEXT_ENV] - self.assertTrue(context['is_admin']) - - def test_request_non_admin(self): - req = make_request() - req.headers[middleware.AUTH_TOKEN_HEADER] = 'NOT-ADMIN' - middleware.AdminTokenAuthMiddleware(None).process_request(req) - context = req.environ[middleware.CONTEXT_ENV] - self.assertFalse(context['is_admin']) - - -class PostParamsMiddlewareTest(test.TestCase): - def test_request_with_params(self): - req = make_request(body="arg1=one", method='POST') - middleware.PostParamsMiddleware(None).process_request(req) - params = req.environ[middleware.PARAMS_ENV] - self.assertEqual(params, {"arg1": "one"}) - - -class JsonBodyMiddlewareTest(test.TestCase): - def test_request_with_params(self): - req = make_request(body='{"arg1": "one", "arg2": ["a"]}', - content_type='application/json', - method='POST') - middleware.JsonBodyMiddleware(None).process_request(req) - params = req.environ[middleware.PARAMS_ENV] - self.assertEqual(params, {"arg1": "one", "arg2": ["a"]}) - - def test_malformed_json(self): - req = make_request(body='{"arg1": "on', - content_type='application/json', - method='POST') - resp = middleware.JsonBodyMiddleware(None).process_request(req) - self.assertEqual(resp.status_int, 400) - - def test_no_content_type(self): - req = make_request(body='{"arg1": "one", "arg2": ["a"]}', - method='POST') - middleware.JsonBodyMiddleware(None).process_request(req) - params = req.environ[middleware.PARAMS_ENV] - self.assertEqual(params, {"arg1": "one", "arg2": ["a"]}) - - def test_unrecognized_content_type(self): - req = make_request(body='{"arg1": "one", "arg2": ["a"]}', - content_type='text/plain', - method='POST') - resp = middleware.JsonBodyMiddleware(None).process_request(req) - self.assertEqual(resp.status_int, 400) - - def test_unrecognized_content_type_without_body(self): - req = make_request(content_type='text/plain', - method='GET') - middleware.JsonBodyMiddleware(None).process_request(req) - params = req.environ.get(middleware.PARAMS_ENV, {}) - self.assertEqual(params, {}) - - -class XmlBodyMiddlewareTest(test.TestCase): - def test_client_wants_xml_back(self): - """Clients requesting XML should get what they ask for.""" - body = '{"container": {"attribute": "value"}}' - req = make_request(body=body, method='POST', accept='application/xml') - middleware.XmlBodyMiddleware(None).process_request(req) - resp = make_response(body=body) - middleware.XmlBodyMiddleware(None).process_response(req, resp) - self.assertEqual(resp.content_type, 'application/xml') - - def test_client_wants_json_back(self): - """Clients requesting JSON should definitely not get XML back.""" - body = '{"container": {"attribute": "value"}}' - req = make_request(body=body, method='POST', accept='application/json') - middleware.XmlBodyMiddleware(None).process_request(req) - resp = make_response(body=body) - middleware.XmlBodyMiddleware(None).process_response(req, resp) - self.assertNotIn('application/xml', resp.content_type) - - def test_client_fails_to_specify_accept(self): - """If client does not specify an Accept header, default to JSON.""" - body = '{"container": {"attribute": "value"}}' - req = make_request(body=body, method='POST') - middleware.XmlBodyMiddleware(None).process_request(req) - resp = make_response(body=body) - middleware.XmlBodyMiddleware(None).process_response(req, resp) - self.assertNotIn('application/xml', resp.content_type) - - def test_xml_replaced_by_json(self): - """XML requests should be replaced by JSON requests.""" - req = make_request( - body='<container><element attribute="value" /></container>', - content_type='application/xml', - method='POST') - middleware.XmlBodyMiddleware(None).process_request(req) - self.assertTrue(req.content_type, 'application/json') - self.assertTrue(jsonutils.loads(req.body)) - - def test_json_unnaffected(self): - """JSON-only requests should be unaffected by the XML middleware.""" - content_type = 'application/json' - body = '{"container": {"attribute": "value"}}' - req = make_request(body=body, content_type=content_type, method='POST') - middleware.XmlBodyMiddleware(None).process_request(req) - self.assertEqual(req.body, body) - self.assertEqual(req.content_type, content_type) diff --git a/tests/test_no_admin_token_auth.py b/tests/test_no_admin_token_auth.py deleted file mode 100644 index ffdaa7a8..00000000 --- a/tests/test_no_admin_token_auth.py +++ /dev/null @@ -1,47 +0,0 @@ - -import os -import webtest - -from keystone import test - - -def _generate_paste_config(): - # Generate a file, based on keystone-paste.ini, that doesn't include - # admin_token_auth in the pipeline - - with open(test.etcdir('keystone-paste.ini'), 'r') as f: - contents = f.read() - - new_contents = contents.replace(' admin_token_auth ', ' ') - - with open(test.tmpdir('no_admin_token_auth-paste.ini'), 'w') as f: - f.write(new_contents) - - -class TestNoAdminTokenAuth(test.TestCase): - def setUp(self): - super(TestNoAdminTokenAuth, self).setUp() - self.load_backends() - - _generate_paste_config() - - self.admin_app = webtest.TestApp( - self.loadapp(test.tmpdir('no_admin_token_auth'), name='admin'), - extra_environ=dict(REMOTE_ADDR='127.0.0.1')) - - def tearDown(self): - self.admin_app = None - os.remove(test.tmpdir('no_admin_token_auth-paste.ini')) - - def test_request_no_admin_token_auth(self): - # This test verifies that if the admin_token_auth middleware isn't - # in the paste pipeline that users can still make requests. - - # Note(blk-u): Picked /v2.0/tenants because it's an operation that - # requires is_admin in the context, any operation that requires - # is_admin would work for this test. - REQ_PATH = '/v2.0/tenants' - - # If the following does not raise, then the test is successful. - self.admin_app.get(REQ_PATH, headers={'X-Auth-Token': 'NotAdminToken'}, - status=401) diff --git a/tests/test_overrides.conf b/tests/test_overrides.conf deleted file mode 100644 index ef7524b7..00000000 --- a/tests/test_overrides.conf +++ /dev/null @@ -1,20 +0,0 @@ -[DEFAULT] -crypt_strength = 1000 - -[identity] -driver = keystone.identity.backends.kvs.Identity - -[catalog] -driver = keystone.catalog.backends.templated.TemplatedCatalog -template_file = default_catalog.templates - -[trust] -driver = keystone.trust.backends.kvs.Trust - -[token] -driver = keystone.token.backends.kvs.Token - -[signing] -certfile = ../examples/pki/certs/signing_cert.pem -keyfile = ../examples/pki/private/signing_key.pem -ca_certs = ../examples/pki/certs/cacert.pem diff --git a/tests/test_pki_token_provider.conf b/tests/test_pki_token_provider.conf deleted file mode 100644 index 255972c3..00000000 --- a/tests/test_pki_token_provider.conf +++ /dev/null @@ -1,2 +0,0 @@ -[token] -provider = keystone.token.providers.pki.Provider diff --git a/tests/test_policy.py b/tests/test_policy.py deleted file mode 100644 index 010a5abf..00000000 --- a/tests/test_policy.py +++ /dev/null @@ -1,191 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2011 Piston Cloud Computing, Inc. -# All Rights Reserved. - -# 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 StringIO -import tempfile -import urllib2 - -from keystone import test - -from keystone import config -from keystone import exception -from keystone.openstack.common import policy as common_policy -from keystone.policy.backends import rules - - -CONF = config.CONF - - -class PolicyFileTestCase(test.TestCase): - def setUp(self): - super(PolicyFileTestCase, self).setUp() - self.orig_policy_file = CONF.policy_file - rules.reset() - _unused, self.tmpfilename = tempfile.mkstemp() - self.opt(policy_file=self.tmpfilename) - self.target = {} - - def tearDown(self): - super(PolicyFileTestCase, self).tearDown() - rules.reset() - self.opt(policy_file=self.orig_policy_file) - - def test_modified_policy_reloads(self): - action = "example:test" - empty_credentials = {} - with open(self.tmpfilename, "w") as policyfile: - policyfile.write("""{"example:test": []}""") - rules.enforce(empty_credentials, action, self.target) - with open(self.tmpfilename, "w") as policyfile: - policyfile.write("""{"example:test": ["false:false"]}""") - # NOTE(vish): reset stored policy cache so we don't have to sleep(1) - rules._POLICY_CACHE = {} - self.assertRaises(exception.ForbiddenAction, rules.enforce, - empty_credentials, action, self.target) - - -class PolicyTestCase(test.TestCase): - def setUp(self): - super(PolicyTestCase, self).setUp() - rules.reset() - # NOTE(vish): preload rules to circumvent reloading from file - rules.init() - self.rules = { - "true": [], - "example:allowed": [], - "example:denied": [["false:false"]], - "example:get_http": [["http:http://www.example.com"]], - "example:my_file": [["role:compute_admin"], - ["project_id:%(project_id)s"]], - "example:early_and_fail": [["false:false", "rule:true"]], - "example:early_or_success": [["rule:true"], ["false:false"]], - "example:lowercase_admin": [["role:admin"], ["role:sysadmin"]], - "example:uppercase_admin": [["role:ADMIN"], ["role:sysadmin"]], - } - - # NOTE(vish): then overload underlying policy engine - self._set_rules() - self.credentials = {} - self.target = {} - - def _set_rules(self): - these_rules = common_policy.Rules( - dict((k, common_policy.parse_rule(v)) - for k, v in self.rules.items())) - common_policy.set_rules(these_rules) - - def tearDown(self): - rules.reset() - super(PolicyTestCase, self).tearDown() - - def test_enforce_nonexistent_action_throws(self): - action = "example:noexist" - self.assertRaises(exception.ForbiddenAction, rules.enforce, - self.credentials, action, self.target) - - def test_enforce_bad_action_throws(self): - action = "example:denied" - self.assertRaises(exception.ForbiddenAction, rules.enforce, - self.credentials, action, self.target) - - def test_enforce_good_action(self): - action = "example:allowed" - rules.enforce(self.credentials, action, self.target) - - def test_enforce_http_true(self): - - def fakeurlopen(url, post_data): - return StringIO.StringIO("True") - - self.stubs.Set(urllib2, 'urlopen', fakeurlopen) - action = "example:get_http" - target = {} - result = rules.enforce(self.credentials, action, target) - self.assertTrue(result) - - def test_enforce_http_false(self): - - def fakeurlopen(url, post_data): - return StringIO.StringIO("False") - self.stubs.Set(urllib2, 'urlopen', fakeurlopen) - action = "example:get_http" - target = {} - self.assertRaises(exception.ForbiddenAction, rules.enforce, - self.credentials, action, target) - - def test_templatized_enforcement(self): - target_mine = {'project_id': 'fake'} - target_not_mine = {'project_id': 'another'} - credentials = {'project_id': 'fake', 'roles': []} - action = "example:my_file" - rules.enforce(credentials, action, target_mine) - self.assertRaises(exception.ForbiddenAction, rules.enforce, - credentials, action, target_not_mine) - - def test_early_AND_enforcement(self): - action = "example:early_and_fail" - self.assertRaises(exception.ForbiddenAction, rules.enforce, - self.credentials, action, self.target) - - def test_early_OR_enforcement(self): - action = "example:early_or_success" - rules.enforce(self.credentials, action, self.target) - - def test_ignore_case_role_check(self): - lowercase_action = "example:lowercase_admin" - uppercase_action = "example:uppercase_admin" - # NOTE(dprince) we mix case in the Admin role here to ensure - # case is ignored - admin_credentials = {'roles': ['AdMiN']} - rules.enforce(admin_credentials, lowercase_action, self.target) - rules.enforce(admin_credentials, uppercase_action, self.target) - - -class DefaultPolicyTestCase(test.TestCase): - def setUp(self): - super(DefaultPolicyTestCase, self).setUp() - rules.reset() - rules.init() - - self.rules = { - "default": [], - "example:exist": [["false:false"]] - } - self._set_rules('default') - self.credentials = {} - - def _set_rules(self, default_rule): - these_rules = common_policy.Rules( - dict((k, common_policy.parse_rule(v)) - for k, v in self.rules.items()), default_rule) - common_policy.set_rules(these_rules) - - def tearDown(self): - super(DefaultPolicyTestCase, self).setUp() - rules.reset() - - def test_policy_called(self): - self.assertRaises(exception.ForbiddenAction, rules.enforce, - self.credentials, "example:exist", {}) - - def test_not_found_policy_calls_default(self): - rules.enforce(self.credentials, "example:noexist", {}) - - def test_default_not_found(self): - self._set_rules("default_noexist") - self.assertRaises(exception.ForbiddenAction, rules.enforce, - self.credentials, "example:noexist", {}) diff --git a/tests/test_s3_token_middleware.py b/tests/test_s3_token_middleware.py deleted file mode 100644 index ec31f2ac..00000000 --- a/tests/test_s3_token_middleware.py +++ /dev/null @@ -1,233 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 unittest2 as unittest -import webob - -from keystone.middleware import s3_token -from keystone.openstack.common import jsonutils - - -class FakeHTTPResponse(object): - def __init__(self, status, body): - self.status = status - self.body = body - self.reason = "" - - def read(self): - return self.body - - -class FakeApp(object): - """This represents a WSGI app protected by the auth_token middleware.""" - def __call__(self, env, start_response): - resp = webob.Response() - resp.environ = env - return resp(env, start_response) - - -class FakeHTTPConnection(object): - def __init__(self, *args): - return - - def getresponse(self): - return self.resp - - def close(self): - pass - - def request(self, method, path, **kwargs): - pass - - -class S3TokenMiddlewareTestBase(unittest.TestCase): - def setUp(self): - super(S3TokenMiddlewareTestBase, self).setUp() - - def start_fake_response(self, status, headers): - self.response_status = int(status.split(' ', 1)[0]) - self.response_headers = dict(headers) - - -def good_request(cls, method, path, **kwargs): - cls.status = 201 - ret = {'access': {'token': - {'id': 'TOKEN_ID', - 'tenant': {'id': 'TENANT_ID'}}}} - body = jsonutils.dumps(ret) - cls.resp = FakeHTTPResponse(cls.status, body) - - -class S3TokenMiddlewareTestGood(S3TokenMiddlewareTestBase): - def setup_middleware_fake(self): - self.middleware.http_client_class = FakeHTTPConnection - self.middleware.http_client_class.request = good_request - - def setUp(self): - self.middleware = s3_token.S3Token(FakeApp(), {}) - self.setup_middleware_fake() - super(S3TokenMiddlewareTestGood, self).setUp() - - # Ignore the request and pass to the next middleware in the - # pipeline if no path has been specified. - def test_no_path_request(self): - req = webob.Request.blank('/') - self.middleware(req.environ, self.start_fake_response) - self.assertEqual(self.response_status, 200) - - # Ignore the request and pass to the next middleware in the - # pipeline if no Authorization header has been specified - def test_without_authorization(self): - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - self.middleware(req.environ, self.start_fake_response) - self.assertEqual(self.response_status, 200) - - def test_without_auth_storage_token(self): - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - req.headers['Authorization'] = 'badboy' - self.middleware(req.environ, self.start_fake_response) - self.assertEqual(self.response_status, 200) - - def test_authorized(self): - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - req.headers['Authorization'] = 'access:signature' - req.headers['X-Storage-Token'] = 'token' - req.get_response(self.middleware) - self.assertTrue(req.path.startswith('/v1/AUTH_TENANT_ID')) - self.assertEqual(req.headers['X-Auth-Token'], 'TOKEN_ID') - - def test_authorized_http(self): - self.middleware = ( - s3_token.filter_factory({'auth_protocol': 'http'})(FakeApp())) - self.setup_middleware_fake() - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - req.headers['Authorization'] = 'access:signature' - req.headers['X-Storage-Token'] = 'token' - req.get_response(self.middleware) - self.assertTrue(req.path.startswith('/v1/AUTH_TENANT_ID')) - self.assertEqual(req.headers['X-Auth-Token'], 'TOKEN_ID') - - def test_authorization_nova_toconnect(self): - req = webob.Request.blank('/v1/AUTH_swiftint/c/o') - req.headers['Authorization'] = 'access:FORCED_TENANT_ID:signature' - req.headers['X-Storage-Token'] = 'token' - req.get_response(self.middleware) - path = req.environ['PATH_INFO'] - self.assertTrue(path.startswith('/v1/AUTH_FORCED_TENANT_ID')) - - -class S3TokenMiddlewareTestBad(S3TokenMiddlewareTestBase): - def setUp(self): - self.middleware = s3_token.S3Token(FakeApp(), {}) - self.middleware.http_client_class = FakeHTTPConnection - super(S3TokenMiddlewareTestBad, self).setUp() - - def test_unauthorized_token(self): - def request(self, method, path, **kwargs): - ret = {"error": - {"message": "EC2 access key not found.", - "code": 401, - "title": "Unauthorized"}} - body = jsonutils.dumps(ret) - self.status = 403 - self.resp = FakeHTTPResponse(self.status, body) - - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - req.headers['Authorization'] = 'access:signature' - req.headers['X-Storage-Token'] = 'token' - self.middleware.http_client_class.request = request - resp = req.get_response(self.middleware) - s3_denied_req = self.middleware.deny_request('AccessDenied') - self.assertEqual(resp.body, s3_denied_req.body) - self.assertEqual(resp.status_int, s3_denied_req.status_int) - - def test_bogus_authorization(self): - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - req.headers['Authorization'] = 'badboy' - req.headers['X-Storage-Token'] = 'token' - resp = req.get_response(self.middleware) - self.assertEqual(resp.status_int, 400) - s3_invalid_req = self.middleware.deny_request('InvalidURI') - self.assertEqual(resp.body, s3_invalid_req.body) - self.assertEqual(resp.status_int, s3_invalid_req.status_int) - - def test_fail_to_connect_to_keystone(self): - def request(self, method, path, **kwargs): - raise s3_token.ServiceError - self.middleware.http_client_class.request = request - - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - req.headers['Authorization'] = 'access:signature' - req.headers['X-Storage-Token'] = 'token' - self.middleware.http_client_class.status = 503 - resp = req.get_response(self.middleware) - s3_invalid_req = self.middleware.deny_request('InvalidURI') - self.assertEqual(resp.body, s3_invalid_req.body) - self.assertEqual(resp.status_int, s3_invalid_req.status_int) - - def test_bad_reply(self): - def request(self, method, path, **kwargs): - body = "<badreply>" - self.status = 201 - self.resp = FakeHTTPResponse(self.status, body) - - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - req.headers['Authorization'] = 'access:signature' - req.headers['X-Storage-Token'] = 'token' - self.middleware.http_client_class.request = request - resp = req.get_response(self.middleware) - s3_invalid_req = self.middleware.deny_request('InvalidURI') - self.assertEqual(resp.body, s3_invalid_req.body) - self.assertEqual(resp.status_int, s3_invalid_req.status_int) - - -class S3TokenMiddlewareTestUtil(unittest.TestCase): - def test_split_path_failed(self): - self.assertRaises(ValueError, s3_token.split_path, '') - self.assertRaises(ValueError, s3_token.split_path, '/') - self.assertRaises(ValueError, s3_token.split_path, '//') - self.assertRaises(ValueError, s3_token.split_path, '//a') - self.assertRaises(ValueError, s3_token.split_path, '/a/c') - self.assertRaises(ValueError, s3_token.split_path, '//c') - self.assertRaises(ValueError, s3_token.split_path, '/a/c/') - self.assertRaises(ValueError, s3_token.split_path, '/a//') - self.assertRaises(ValueError, s3_token.split_path, '/a', 2) - self.assertRaises(ValueError, s3_token.split_path, '/a', 2, 3) - self.assertRaises(ValueError, s3_token.split_path, '/a', 2, 3, True) - self.assertRaises(ValueError, s3_token.split_path, '/a/c/o/r', 3, 3) - self.assertRaises(ValueError, s3_token.split_path, '/a', 5, 4) - - def test_split_path_success(self): - self.assertEquals(s3_token.split_path('/a'), ['a']) - self.assertEquals(s3_token.split_path('/a/'), ['a']) - self.assertEquals(s3_token.split_path('/a/c', 2), ['a', 'c']) - self.assertEquals(s3_token.split_path('/a/c/o', 3), ['a', 'c', 'o']) - self.assertEquals(s3_token.split_path('/a/c/o/r', 3, 3, True), - ['a', 'c', 'o/r']) - self.assertEquals(s3_token.split_path('/a/c', 2, 3, True), - ['a', 'c', None]) - self.assertEquals(s3_token.split_path('/a/c/', 2), ['a', 'c']) - self.assertEquals(s3_token.split_path('/a/c/', 2, 3), ['a', 'c', '']) - - def test_split_path_invalid_path(self): - try: - s3_token.split_path('o\nn e', 2) - except ValueError, err: - self.assertEquals(str(err), 'Invalid path: o%0An%20e') - try: - s3_token.split_path('o\nn e', 2, 3, True) - except ValueError, err: - self.assertEquals(str(err), 'Invalid path: o%0An%20e') diff --git a/tests/test_serializer.py b/tests/test_serializer.py deleted file mode 100644 index 2024949b..00000000 --- a/tests/test_serializer.py +++ /dev/null @@ -1,297 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 copy - -from keystone.common import serializer -from keystone import test - - -class XmlSerializerTestCase(test.TestCase): - def assertSerializeDeserialize(self, d, xml, xmlns=None): - self.assertEqualXML( - serializer.to_xml(copy.deepcopy(d), xmlns), - xml) - self.assertEqual(serializer.from_xml(xml), d) - - # operations should be invertible - self.assertEqual( - serializer.from_xml(serializer.to_xml(copy.deepcopy(d), xmlns)), - d) - self.assertEqualXML( - serializer.to_xml(serializer.from_xml(xml), xmlns), - xml) - - def test_auth_request(self): - d = { - "auth": { - "passwordCredentials": { - "username": "test_user", - "password": "mypass" - }, - "tenantName": "customer-x" - } - } - - xml = """ - <?xml version="1.0" encoding="UTF-8"?> - <auth xmlns="http://docs.openstack.org/identity/api/v2.0" - tenantName="customer-x"> - <passwordCredentials - username="test_user" - password="mypass"/> - </auth> - """ - - self.assertSerializeDeserialize(d, xml) - - def test_role_crud(self): - d = { - "role": { - "id": "123", - "name": "Guest", - "description": "Guest Access" - } - } - - # TODO(dolph): examples show this description as an attribute? - xml = """ - <?xml version="1.0" encoding="UTF-8"?> - <role xmlns="http://docs.openstack.org/identity/api/v2.0" - id="123" - name="Guest"> - <description>Guest Access</description> - </role> - """ - - self.assertSerializeDeserialize(d, xml) - - def test_service_crud(self): - xmlns = "http://docs.openstack.org/identity/api/ext/OS-KSADM/v1.0" - - d = { - "OS-KSADM:service": { - "id": "123", - "name": "nova", - "type": "compute", - "description": "OpenStack Compute Service" - } - } - - # TODO(dolph): examples show this description as an attribute? - xml = """ - <?xml version="1.0" encoding="UTF-8"?> - <service - xmlns="%(xmlns)s" - type="compute" - id="123" - name="nova"> - <description>OpenStack Compute Service</description> - </service> - """ % {'xmlns': xmlns} - - self.assertSerializeDeserialize(d, xml, xmlns=xmlns) - - def test_tenant_crud(self): - d = { - "tenant": { - "id": "1234", - "name": "ACME corp", - "description": "A description...", - "enabled": True - } - } - - xml = """ - <?xml version="1.0" encoding="UTF-8"?> - <tenant - xmlns="http://docs.openstack.org/identity/api/v2.0" - enabled="true" - id="1234" - name="ACME corp"> - <description>A description...</description> - </tenant> - """ - - self.assertSerializeDeserialize(d, xml) - - def test_tenant_crud_no_description(self): - d = { - "tenant": { - "id": "1234", - "name": "ACME corp", - "description": "", - "enabled": True - } - } - - xml = """ - <?xml version="1.0" encoding="UTF-8"?> - <tenant - xmlns="http://docs.openstack.org/identity/api/v2.0" - enabled="true" - id="1234" - name="ACME corp"> - <description></description> - </tenant> - """ - - self.assertSerializeDeserialize(d, xml) - - def test_policy_list(self): - d = {"policies": [{"id": "ab12cd"}]} - - xml = """ - <?xml version="1.0" encoding="UTF-8"?> - <policies xmlns="http://docs.openstack.org/identity/api/v2.0"> - <policy id="ab12cd"/> - </policies> - """ - self.assertEqualXML(serializer.to_xml(d), xml) - - def test_values_list(self): - d = { - "objects": { - "values": [{ - "attribute": "value1", - }, { - "attribute": "value2", - }] - } - } - - xml = """ - <?xml version="1.0" encoding="UTF-8"?> - <objects xmlns="http://docs.openstack.org/identity/api/v2.0"> - <object attribute="value1"/> - <object attribute="value2"/> - </objects> - """ - - self.assertEqualXML(serializer.to_xml(d), xml) - - def test_collection_list(self): - d = { - "links": { - "next": "http://localhost:5000/v3/objects?page=3", - "previous": None, - "self": "http://localhost:5000/v3/objects" - }, - "objects": [{ - "attribute": "value1", - "links": { - "self": "http://localhost:5000/v3/objects/abc123def", - "anotherobj": "http://localhost:5000/v3/anotherobjs/123" - } - }, { - "attribute": "value2", - "links": { - "self": "http://localhost:5000/v3/objects/abc456" - } - }]} - xml = """ - <?xml version="1.0" encoding="UTF-8"?> - <objects xmlns="http://docs.openstack.org/identity/api/v2.0"> - <object attribute="value1"> - <links> - <link rel="self" - href="http://localhost:5000/v3/objects/abc123def"/> - <link rel="anotherobj" - href="http://localhost:5000/v3/anotherobjs/123"/> - </links> - </object> - <object attribute="value2"> - <links> - <link rel="self" - href="http://localhost:5000/v3/objects/abc456"/> - </links> - </object> - <links> - <link rel="self" - href="http://localhost:5000/v3/objects"/> - <link rel="next" - href="http://localhost:5000/v3/objects?page=3"/> - </links> - </objects> - """ - self.assertSerializeDeserialize(d, xml) - - def test_collection_member(self): - d = { - "object": { - "attribute": "value", - "links": { - "self": "http://localhost:5000/v3/objects/abc123def", - "anotherobj": "http://localhost:5000/v3/anotherobjs/123"}}} - - xml = """ - <?xml version="1.0" encoding="UTF-8"?> - <object xmlns="http://docs.openstack.org/identity/api/v2.0" - attribute="value"> - <links> - <link rel="self" - href="http://localhost:5000/v3/objects/abc123def"/> - <link rel="anotherobj" - href="http://localhost:5000/v3/anotherobjs/123"/> - </links> - </object> - """ - self.assertSerializeDeserialize(d, xml) - - def test_v2_links_special_case(self): - # There's special-case code (for backward compatibility) where if the - # data is the v2 version data, the link elements are also added to the - # main element. - - d = { - "object": { - "id": "v2.0", - "status": "stable", - "updated": "2013-03-06T00:00:00Z", - "links": [{"href": "http://localhost:5000/v2.0/", - "rel": "self"}, - {"href": "http://docs.openstack.org/api/openstack-" - "identity-service/2.0/content/", - "type": "text/html", "rel": "describedby"}, - {"href": "http://docs.openstack.org/api/openstack-" - "identity-service/2.0/" - "identity-dev-guide-2.0.pdf", - "type": "application/pdf", "rel": "describedby"}] - }} - - xml = """ - <?xml version="1.0" encoding="UTF-8"?> - <object xmlns="http://docs.openstack.org/identity/api/v2.0" - id="v2.0" status="stable" updated="2013-03-06T00:00:00Z"> - <links> - <link rel="self" href="http://localhost:5000/v2.0/"/> - <link rel="describedby" - href="http://docs.openstack.org/api/openstack-\ -identity-service/2.0/content/" type="text/html"/> - <link rel="describedby" - href="http://docs.openstack.org/api/openstack-\ -identity-service/2.0/identity-dev-guide-2.0.pdf" type="application/pdf"/> - </links> - <link rel="self" href="http://localhost:5000/v2.0/"/> - <link rel="describedby" - href="http://docs.openstack.org/api/openstack-\ -identity-service/2.0/content/" type="text/html"/> - <link rel="describedby" - href="http://docs.openstack.org/api/openstack-\ -identity-service/2.0/identity-dev-guide-2.0.pdf" type="application/pdf"/> - </object> - """ - self.assertEqualXML(serializer.to_xml(d), xml) diff --git a/tests/test_singular_plural.py b/tests/test_singular_plural.py deleted file mode 100644 index ea3ad27c..00000000 --- a/tests/test_singular_plural.py +++ /dev/null @@ -1,52 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 Red Hat, Inc. -# -# 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 ast - -from keystone.contrib.admin_crud import core as admin_crud_core -from keystone.contrib.ec2 import core as ec2_core -from keystone.contrib.s3 import core as s3_core -from keystone.contrib.stats import core as stats_core -from keystone.contrib.user_crud import core as user_crud_core -from keystone.identity import core as identity_core -from keystone import service - - -class TestSingularPlural(object): - def test_keyword_arg_condition_or_methods(self): - """Raise if we see a keyword arg called 'condition' or 'methods'.""" - modules = [admin_crud_core, ec2_core, s3_core, stats_core, - user_crud_core, identity_core, service] - for module in modules: - filename = module.__file__ - if filename.endswith(".pyc"): - # In Python 2, the .py and .pyc files are in the same dir. - filename = filename[:-1] - with open(filename) as fil: - source = fil.read() - module = ast.parse(source, filename) - last_stmt_or_expr = None - for node in ast.walk(module): - if isinstance(node, ast.stmt) or isinstance(node, ast.expr): - # keyword nodes don't have line numbers, so we need to - # get that information from the parent stmt or expr. - last_stmt_or_expr = node - elif isinstance(node, ast.keyword): - for bad_word in ["condition", "methods"]: - if node.arg == bad_word: - raise AssertionError( - "Suspicious name '%s' at %s line %s" % - (bad_word, filename, last_stmt_or_expr.lineno)) diff --git a/tests/test_sizelimit.py b/tests/test_sizelimit.py deleted file mode 100644 index abd2b639..00000000 --- a/tests/test_sizelimit.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (c) 2013 OpenStack, 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 webob - -from keystone import test - -from keystone import config -from keystone import exception -from keystone import middleware - -CONF = config.CONF -MAX_REQUEST_BODY_SIZE = CONF.max_request_body_size - - -class TestRequestBodySizeLimiter(test.TestCase): - - def setUp(self): - super(TestRequestBodySizeLimiter, self).setUp() - - @webob.dec.wsgify() - def fake_app(req): - return webob.Response(req.body) - - self.middleware = middleware.RequestBodySizeLimiter(fake_app) - self.request = webob.Request.blank('/', method='POST') - - def test_content_length_acceptable(self): - self.request.headers['Content-Length'] = MAX_REQUEST_BODY_SIZE - self.request.body = "0" * MAX_REQUEST_BODY_SIZE - response = self.request.get_response(self.middleware) - self.assertEqual(response.status_int, 200) - - def test_content_length_too_large(self): - self.request.headers['Content-Length'] = MAX_REQUEST_BODY_SIZE + 1 - self.request.body = "0" * (MAX_REQUEST_BODY_SIZE + 1) - self.assertRaises(exception.RequestTooLarge, - self.request.get_response, - self.middleware) - - def test_request_too_large_no_content_length(self): - self.request.body = "0" * (MAX_REQUEST_BODY_SIZE + 1) - self.request.headers['Content-Length'] = None - self.assertRaises(exception.RequestTooLarge, - self.request.get_response, - self.middleware) diff --git a/tests/test_sql_core.py b/tests/test_sql_core.py deleted file mode 100644 index e60005f5..00000000 --- a/tests/test_sql_core.py +++ /dev/null @@ -1,182 +0,0 @@ -# Copyright 2013 IBM Corp. -# -# 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 keystone.common import sql -from keystone import test - - -class CallbackMonitor: - def __init__(self, expect_called=True, raise_=False): - self.expect_called = expect_called - self.called = False - self._complete = False - self._raise = raise_ - - def call_this(self): - if self._complete: - return - - if not self.expect_called: - raise Exception("Did not expect callback.") - - if self.called: - raise Exception("Callback already called.") - - self.called = True - - if self._raise: - raise Exception("When called, raises.") - - def check(self): - if self.expect_called: - if not self.called: - raise Exception("Expected function to be called.") - self._complete = True - - -class TestGlobalEngine(test.TestCase): - - def tearDown(self): - sql.set_global_engine(None) - super(TestGlobalEngine, self).tearDown() - - def test_notify_on_set(self): - # If call sql.set_global_engine(), notify callbacks get called. - - cb_mon = CallbackMonitor() - - sql.register_global_engine_callback(cb_mon.call_this) - fake_engine = object() - sql.set_global_engine(fake_engine) - - cb_mon.check() - - def test_multi_notify(self): - # You can also set multiple notify callbacks and they each get called. - - cb_mon1 = CallbackMonitor() - cb_mon2 = CallbackMonitor() - - sql.register_global_engine_callback(cb_mon1.call_this) - sql.register_global_engine_callback(cb_mon2.call_this) - - fake_engine = object() - sql.set_global_engine(fake_engine) - - cb_mon1.check() - cb_mon2.check() - - def test_notify_once(self): - # After a callback is called, it's not called again if set global - # engine again. - - cb_mon = CallbackMonitor() - - sql.register_global_engine_callback(cb_mon.call_this) - fake_engine = object() - sql.set_global_engine(fake_engine) - - fake_engine = object() - # Note that cb_mon.call_this would raise if it's called again. - sql.set_global_engine(fake_engine) - - cb_mon.check() - - def test_set_same_engine(self): - # If you set the global engine to the same engine, callbacks don't get - # called. - - fake_engine = object() - - sql.set_global_engine(fake_engine) - - cb_mon = CallbackMonitor(expect_called=False) - sql.register_global_engine_callback(cb_mon.call_this) - - # Note that cb_mon.call_this would raise if it's called. - sql.set_global_engine(fake_engine) - - cb_mon.check() - - def test_notify_register_same(self): - # If you register the same callback twice, only gets called once. - cb_mon = CallbackMonitor() - - sql.register_global_engine_callback(cb_mon.call_this) - sql.register_global_engine_callback(cb_mon.call_this) - - fake_engine = object() - # Note that cb_mon.call_this would raise if it's called twice. - sql.set_global_engine(fake_engine) - - cb_mon.check() - - def test_callback_throws(self): - # If a callback function raises, - # a) the caller doesn't know about it, - # b) other callbacks are still called - - cb_mon1 = CallbackMonitor(raise_=True) - cb_mon2 = CallbackMonitor() - - sql.register_global_engine_callback(cb_mon1.call_this) - sql.register_global_engine_callback(cb_mon2.call_this) - - fake_engine = object() - sql.set_global_engine(fake_engine) - - cb_mon1.check() - cb_mon2.check() - - -class TestBase(test.TestCase): - - def tearDown(self): - sql.set_global_engine(None) - super(TestBase, self).tearDown() - - def test_get_engine_global(self): - # If call get_engine() twice, get the same global engine. - base = sql.Base() - engine1 = base.get_engine() - self.assertIsNotNone(engine1) - engine2 = base.get_engine() - self.assertIs(engine1, engine2) - - def test_get_engine_not_global(self): - # If call get_engine() twice, once with allow_global_engine=True - # and once with allow_global_engine=False, get different engines. - base = sql.Base() - engine1 = base.get_engine() - engine2 = base.get_engine(allow_global_engine=False) - self.assertIsNot(engine1, engine2) - - def test_get_session(self): - # autocommit and expire_on_commit flags to get_session() are passed on - # to the session created. - - base = sql.Base() - session = base.get_session(autocommit=False, expire_on_commit=True) - - self.assertFalse(session.autocommit) - self.assertTrue(session.expire_on_commit) - - def test_get_session_invalidated(self): - # If clear the global engine, a new engine is used for get_session(). - base = sql.Base() - session1 = base.get_session() - sql.set_global_engine(None) - session2 = base.get_session() - self.assertIsNot(session1.bind, session2.bind) diff --git a/tests/test_sql_migrate_extensions.py b/tests/test_sql_migrate_extensions.py deleted file mode 100644 index 4a529559..00000000 --- a/tests/test_sql_migrate_extensions.py +++ /dev/null @@ -1,47 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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. -""" -To run these tests against a live database: -1. Modify the file `tests/backend_sql.conf` to use the connection for your - live database -2. Set up a blank, live database. -3. run the tests using - ./run_tests.sh -N test_sql_upgrade - WARNING:: - Your database will be wiped. - Do not do this against a Database with valuable data as - all data will be lost. -""" - -from keystone.contrib import example - -import test_sql_upgrade - - -class SqlUpgradeExampleExtension(test_sql_upgrade.SqlMigrateBase): - def repo_package(self): - return example - - def test_upgrade(self): - self.assertTableDoesNotExist('example') - self.upgrade(1, repository=self.repo_path) - self.assertTableColumns('example', ['id', 'type', 'extra']) - - def test_downgrade(self): - self.upgrade(1, repository=self.repo_path) - self.assertTableColumns('example', ['id', 'type', 'extra']) - self.downgrade(0, repository=self.repo_path) - self.assertTableDoesNotExist('example') diff --git a/tests/test_sql_upgrade.py b/tests/test_sql_upgrade.py deleted file mode 100644 index 9540c4cd..00000000 --- a/tests/test_sql_upgrade.py +++ /dev/null @@ -1,1378 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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. -""" -To run these tests against a live database: -1. Modify the file `tests/backend_sql.conf` to use the connection for your - live database -2. Set up a blank, live database. -3. run the tests using - ./run_tests.sh -N test_sql_upgrade - WARNING:: - Your database will be wiped. - Do not do this against a Database with valuable data as - all data will be lost. -""" -import copy -import json -import uuid - -from migrate.versioning import api as versioning_api -import sqlalchemy - -from keystone import test - -from keystone.common import sql -from keystone.common.sql import migration -from keystone import config - -import default_fixtures - - -CONF = config.CONF -DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id - - -class SqlMigrateBase(test.TestCase): - def initialize_sql(self): - self.metadata = sqlalchemy.MetaData() - self.metadata.bind = self.engine - - _config_file_list = [test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf'), - test.testsdir('backend_sql.conf')] - - #override this to specify the complete list of configuration files - def config_files(self): - return self._config_file_list - - def repo_package(self): - return None - - def setUp(self): - super(SqlMigrateBase, self).setUp() - - self.config(self.config_files()) - self.base = sql.Base() - - # create and share a single sqlalchemy engine for testing - self.engine = self.base.get_engine(allow_global_engine=False) - self.Session = self.base.get_sessionmaker(engine=self.engine, - autocommit=False) - - self.initialize_sql() - self.repo_path = migration.find_migrate_repo(self.repo_package()) - self.schema = versioning_api.ControlledSchema.create( - self.engine, - self.repo_path, 0) - - # auto-detect the highest available schema version in the migrate_repo - self.max_version = self.schema.repository.version().version - - def tearDown(self): - sqlalchemy.orm.session.Session.close_all() - table = sqlalchemy.Table("migrate_version", self.metadata, - autoload=True) - self.downgrade(0) - table.drop(self.engine, checkfirst=True) - super(SqlMigrateBase, self).tearDown() - - def select_table(self, name): - table = sqlalchemy.Table(name, - self.metadata, - autoload=True) - s = sqlalchemy.select([table]) - return s - - def assertTableExists(self, table_name): - try: - self.select_table(table_name) - except sqlalchemy.exc.NoSuchTableError: - raise AssertionError('Table "%s" does not exist' % table_name) - - def assertTableDoesNotExist(self, table_name): - """Asserts that a given table exists cannot be selected by name.""" - # Switch to a different metadata otherwise you might still - # detect renamed or dropped tables - try: - temp_metadata = sqlalchemy.MetaData() - temp_metadata.bind = self.engine - sqlalchemy.Table(table_name, temp_metadata, autoload=True) - except sqlalchemy.exc.NoSuchTableError: - pass - else: - raise AssertionError('Table "%s" already exists' % table_name) - - def upgrade(self, *args, **kwargs): - self._migrate(*args, **kwargs) - - def downgrade(self, *args, **kwargs): - self._migrate(*args, downgrade=True, **kwargs) - - def _migrate(self, version, repository=None, downgrade=False, - current_schema=None): - repository = repository or self.repo_path - err = '' - version = versioning_api._migrate_version(self.schema, - version, - not downgrade, - err) - if not current_schema: - current_schema = self.schema - changeset = current_schema.changeset(version) - for ver, change in changeset: - self.schema.runchange(ver, change, changeset.step) - self.assertEqual(self.schema.version, version) - - def assertTableColumns(self, table_name, expected_cols): - """Asserts that the table contains the expected set of columns.""" - self.initialize_sql() - table = self.select_table(table_name) - actual_cols = [col.name for col in table.columns] - self.assertEqual(expected_cols, actual_cols, '%s table' % table_name) - - -class SqlUpgradeTests(SqlMigrateBase): - - def test_blank_db_to_start(self): - self.assertTableDoesNotExist('user') - - def test_start_version_0(self): - version = migration.db_version() - self.assertEqual(version, 0, "DB is at version 0") - - def test_two_steps_forward_one_step_back(self): - """You should be able to cleanly undo and re-apply all upgrades. - - Upgrades are run in the following order:: - - 0 -> 1 -> 0 -> 1 -> 2 -> 1 -> 2 -> 3 -> 2 -> 3 ... - ^---------^ ^---------^ ^---------^ - - """ - for x in range(1, self.max_version + 1): - self.upgrade(x) - self.downgrade(x - 1) - self.upgrade(x) - - def test_upgrade_add_initial_tables(self): - self.upgrade(1) - self.assertTableColumns("user", ["id", "name", "extra"]) - self.assertTableColumns("tenant", ["id", "name", "extra"]) - self.assertTableColumns("role", ["id", "name"]) - self.assertTableColumns("user_tenant_membership", - ["user_id", "tenant_id"]) - self.assertTableColumns("metadata", ["user_id", "tenant_id", "data"]) - self.populate_user_table() - - def test_upgrade_add_policy(self): - self.upgrade(5) - self.assertTableDoesNotExist('policy') - - self.upgrade(6) - self.assertTableExists('policy') - self.assertTableColumns('policy', ['id', 'type', 'blob', 'extra']) - - def test_upgrade_normalize_identity(self): - self.upgrade(8) - self.populate_user_table() - self.populate_tenant_table() - self.upgrade(10) - self.assertTableColumns("user", - ["id", "name", "extra", - "password", "enabled"]) - self.assertTableColumns("tenant", - ["id", "name", "extra", "description", - "enabled"]) - self.assertTableColumns("role", ["id", "name", "extra"]) - self.assertTableColumns("user_tenant_membership", - ["user_id", "tenant_id"]) - self.assertTableColumns("metadata", ["user_id", "tenant_id", "data"]) - session = self.Session() - user_table = sqlalchemy.Table("user", - self.metadata, - autoload=True) - a_user = session.query(user_table).filter("id='foo'").one() - self.assertTrue(a_user.enabled) - a_user = session.query(user_table).filter("id='badguy'").one() - self.assertFalse(a_user.enabled) - tenant_table = sqlalchemy.Table("tenant", - self.metadata, - autoload=True) - a_tenant = session.query(tenant_table).filter("id='baz'").one() - self.assertEqual(a_tenant.description, 'description') - session.commit() - session.close() - - def test_normalized_enabled_states(self): - self.upgrade(8) - - users = { - 'bool_enabled_user': { - 'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, - 'extra': json.dumps({'enabled': True})}, - 'bool_disabled_user': { - 'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, - 'extra': json.dumps({'enabled': False})}, - 'str_enabled_user': { - 'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, - 'extra': json.dumps({'enabled': 'True'})}, - 'str_disabled_user': { - 'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, - 'extra': json.dumps({'enabled': 'False'})}, - 'int_enabled_user': { - 'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, - 'extra': json.dumps({'enabled': 1})}, - 'int_disabled_user': { - 'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, - 'extra': json.dumps({'enabled': 0})}, - 'null_enabled_user': { - 'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, - 'extra': json.dumps({'enabled': None})}, - 'unset_enabled_user': { - 'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, - 'extra': json.dumps({})}} - - session = self.Session() - for user in users.values(): - self.insert_dict(session, 'user', user) - session.commit() - - self.upgrade(10) - - user_table = sqlalchemy.Table('user', self.metadata, autoload=True) - q = session.query(user_table, 'enabled') - - user = q.filter_by(id=users['bool_enabled_user']['id']).one() - self.assertTrue(user.enabled) - - user = q.filter_by(id=users['bool_disabled_user']['id']).one() - self.assertFalse(user.enabled) - - user = q.filter_by(id=users['str_enabled_user']['id']).one() - self.assertTrue(user.enabled) - - user = q.filter_by(id=users['str_disabled_user']['id']).one() - self.assertFalse(user.enabled) - - user = q.filter_by(id=users['int_enabled_user']['id']).one() - self.assertTrue(user.enabled) - - user = q.filter_by(id=users['int_disabled_user']['id']).one() - self.assertFalse(user.enabled) - - user = q.filter_by(id=users['null_enabled_user']['id']).one() - self.assertTrue(user.enabled) - - user = q.filter_by(id=users['unset_enabled_user']['id']).one() - self.assertTrue(user.enabled) - - def test_downgrade_10_to_8(self): - self.upgrade(10) - self.populate_user_table(with_pass_enab=True) - self.populate_tenant_table(with_desc_enab=True) - self.downgrade(8) - self.assertTableColumns('user', - ['id', 'name', 'extra']) - self.assertTableColumns('tenant', - ['id', 'name', 'extra']) - session = self.Session() - user_table = sqlalchemy.Table("user", - self.metadata, - autoload=True) - a_user = session.query(user_table).filter("id='badguy'").one() - self.assertEqual(a_user.name, default_fixtures.USERS[2]['name']) - tenant_table = sqlalchemy.Table("tenant", - self.metadata, - autoload=True) - a_tenant = session.query(tenant_table).filter("id='baz'").one() - self.assertEqual(a_tenant.name, default_fixtures.TENANTS[1]['name']) - session.commit() - session.close() - - def test_upgrade_endpoints(self): - self.upgrade(10) - service_extra = { - 'name': uuid.uuid4().hex, - } - service = { - 'id': uuid.uuid4().hex, - 'type': uuid.uuid4().hex, - 'extra': json.dumps(service_extra), - } - endpoint_extra = { - 'publicurl': uuid.uuid4().hex, - 'internalurl': uuid.uuid4().hex, - 'adminurl': uuid.uuid4().hex, - } - endpoint = { - 'id': uuid.uuid4().hex, - 'region': uuid.uuid4().hex, - 'service_id': service['id'], - 'extra': json.dumps(endpoint_extra), - } - - session = self.Session() - self.insert_dict(session, 'service', service) - self.insert_dict(session, 'endpoint', endpoint) - session.commit() - session.close() - - self.upgrade(13) - self.assertTableColumns( - 'service', - ['id', 'type', 'extra']) - self.assertTableColumns( - 'endpoint', - ['id', 'legacy_endpoint_id', 'interface', 'region', 'service_id', - 'url', 'extra']) - - endpoint_table = sqlalchemy.Table( - 'endpoint', self.metadata, autoload=True) - - session = self.Session() - self.assertEqual(session.query(endpoint_table).count(), 3) - for interface in ['public', 'internal', 'admin']: - q = session.query(endpoint_table) - q = q.filter_by(legacy_endpoint_id=endpoint['id']) - q = q.filter_by(interface=interface) - ref = q.one() - self.assertNotEqual(ref.id, endpoint['id']) - self.assertEqual(ref.legacy_endpoint_id, endpoint['id']) - self.assertEqual(ref.interface, interface) - self.assertEqual(ref.region, endpoint['region']) - self.assertEqual(ref.service_id, endpoint['service_id']) - self.assertEqual(ref.url, endpoint_extra['%surl' % interface]) - self.assertEqual(ref.extra, '{}') - session.commit() - session.close() - - def assertTenantTables(self): - self.assertTableExists('tenant') - self.assertTableExists('user_tenant_membership') - self.assertTableDoesNotExist('project') - self.assertTableDoesNotExist('user_project_membership') - - def assertProjectTables(self): - self.assertTableExists('project') - self.assertTableExists('user_project_membership') - self.assertTableDoesNotExist('tenant') - self.assertTableDoesNotExist('user_tenant_membership') - - def test_upgrade_tenant_to_project(self): - self.upgrade(14) - self.assertTenantTables() - self.upgrade(15) - self.assertProjectTables() - - def test_downgrade_project_to_tenant(self): - # TODO(henry-nash): Debug why we need to re-load the tenant - # or user_tenant_membership ahead of upgrading to project - # in order for the assertProjectTables to work on sqlite - # (MySQL is fine without it) - self.upgrade(14) - self.assertTenantTables() - self.upgrade(15) - self.assertProjectTables() - self.downgrade(14) - self.assertTenantTables() - - def test_upgrade_add_group_tables(self): - self.upgrade(13) - self.upgrade(14) - self.assertTableExists('group') - self.assertTableExists('group_project_metadata') - self.assertTableExists('group_domain_metadata') - self.assertTableExists('user_group_membership') - - def test_upgrade_14_to_16(self): - self.upgrade(14) - self.populate_user_table(with_pass_enab=True) - self.populate_tenant_table(with_desc_enab=True) - self.upgrade(16) - - self.assertTableColumns("user", - ["id", "name", "extra", - "password", "enabled", "domain_id"]) - session = self.Session() - user_table = sqlalchemy.Table("user", - self.metadata, - autoload=True) - a_user = session.query(user_table).filter("id='foo'").one() - self.assertTrue(a_user.enabled) - self.assertEqual(a_user.domain_id, DEFAULT_DOMAIN_ID) - a_user = session.query(user_table).filter("id='badguy'").one() - self.assertEqual(a_user.name, default_fixtures.USERS[2]['name']) - self.assertEqual(a_user.domain_id, DEFAULT_DOMAIN_ID) - project_table = sqlalchemy.Table("project", - self.metadata, - autoload=True) - a_project = session.query(project_table).filter("id='baz'").one() - self.assertEqual(a_project.description, - default_fixtures.TENANTS[1]['description']) - self.assertEqual(a_project.domain_id, DEFAULT_DOMAIN_ID) - - session.commit() - session.close() - - self.check_uniqueness_constraints() - - def test_downgrade_16_to_14(self): - self.upgrade(16) - self.populate_user_table(with_pass_enab_domain=True) - self.populate_tenant_table(with_desc_enab_domain=True) - self.downgrade(14) - self.assertTableColumns("user", - ["id", "name", "extra", - "password", "enabled"]) - session = self.Session() - user_table = sqlalchemy.Table("user", - self.metadata, - autoload=True) - a_user = session.query(user_table).filter("id='foo'").one() - self.assertTrue(a_user.enabled) - a_user = session.query(user_table).filter("id='badguy'").one() - self.assertEqual(a_user.name, default_fixtures.USERS[2]['name']) - tenant_table = sqlalchemy.Table("tenant", - self.metadata, - autoload=True) - a_tenant = session.query(tenant_table).filter("id='baz'").one() - self.assertEqual(a_tenant.description, - default_fixtures.TENANTS[1]['description']) - session.commit() - session.close() - - def test_downgrade_remove_group_tables(self): - self.upgrade(14) - self.downgrade(13) - self.assertTableDoesNotExist('group') - self.assertTableDoesNotExist('group_project_metadata') - self.assertTableDoesNotExist('group_domain_metadata') - self.assertTableDoesNotExist('user_group_membership') - - def test_downgrade_endpoints(self): - self.upgrade(13) - - service_extra = { - 'name': uuid.uuid4().hex, - } - service = { - 'id': uuid.uuid4().hex, - 'type': uuid.uuid4().hex, - 'extra': json.dumps(service_extra), - } - - common_endpoint_attrs = { - 'legacy_endpoint_id': uuid.uuid4().hex, - 'region': uuid.uuid4().hex, - 'service_id': service['id'], - 'extra': json.dumps({}), - } - endpoints = { - 'public': { - 'id': uuid.uuid4().hex, - 'interface': 'public', - 'url': uuid.uuid4().hex, - }, - 'internal': { - 'id': uuid.uuid4().hex, - 'interface': 'internal', - 'url': uuid.uuid4().hex, - }, - 'admin': { - 'id': uuid.uuid4().hex, - 'interface': 'admin', - 'url': uuid.uuid4().hex, - }, - } - - session = self.Session() - self.insert_dict(session, 'service', service) - for endpoint in endpoints.values(): - endpoint.update(common_endpoint_attrs) - self.insert_dict(session, 'endpoint', endpoint) - session.commit() - session.close() - - self.downgrade(9) - - self.assertTableColumns( - 'service', - ['id', 'type', 'extra']) - self.assertTableColumns( - 'endpoint', - ['id', 'region', 'service_id', 'extra']) - - endpoint_table = sqlalchemy.Table( - 'endpoint', self.metadata, autoload=True) - - session = self.Session() - self.assertEqual(session.query(endpoint_table).count(), 1) - q = session.query(endpoint_table) - q = q.filter_by(id=common_endpoint_attrs['legacy_endpoint_id']) - ref = q.one() - self.assertEqual(ref.id, common_endpoint_attrs['legacy_endpoint_id']) - self.assertEqual(ref.region, endpoint['region']) - self.assertEqual(ref.service_id, endpoint['service_id']) - extra = json.loads(ref.extra) - for interface in ['public', 'internal', 'admin']: - expected_url = endpoints[interface]['url'] - self.assertEqual(extra['%surl' % interface], expected_url) - session.commit() - session.close() - - def insert_dict(self, session, table_name, d): - """Naively inserts key-value pairs into a table, given a dictionary.""" - this_table = sqlalchemy.Table(table_name, self.metadata, autoload=True) - insert = this_table.insert() - insert.execute(d) - session.commit() - - def test_downgrade_to_0(self): - self.upgrade(self.max_version) - - if self.engine.name == 'mysql': - self._mysql_check_all_tables_innodb() - - self.downgrade(0) - for table_name in ["user", "token", "role", "user_tenant_membership", - "metadata"]: - self.assertTableDoesNotExist(table_name) - - def test_upgrade_add_domain_tables(self): - self.upgrade(6) - self.assertTableDoesNotExist('credential') - self.assertTableDoesNotExist('domain') - self.assertTableDoesNotExist('user_domain_metadata') - - self.upgrade(7) - self.assertTableExists('credential') - self.assertTableColumns('credential', ['id', 'user_id', 'project_id', - 'blob', 'type', 'extra']) - self.assertTableExists('domain') - self.assertTableColumns('domain', ['id', 'name', 'enabled', 'extra']) - self.assertTableExists('user_domain_metadata') - self.assertTableColumns('user_domain_metadata', - ['user_id', 'domain_id', 'data']) - - def test_metadata_table_migration(self): - # Scaffolding - session = self.Session() - - self.upgrade(16) - domain_table = sqlalchemy.Table('domain', self.metadata, autoload=True) - user_table = sqlalchemy.Table('user', self.metadata, autoload=True) - role_table = sqlalchemy.Table('role', self.metadata, autoload=True) - project_table = sqlalchemy.Table( - 'project', self.metadata, autoload=True) - metadata_table = sqlalchemy.Table( - 'metadata', self.metadata, autoload=True) - - # Create a Domain - domain = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'enabled': True} - session.execute(domain_table.insert().values(domain)) - - # Create a Project - project = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain['id'], - 'extra': "{}"} - session.execute(project_table.insert().values(project)) - - # Create another Project - project2 = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain['id'], - 'extra': "{}"} - session.execute(project_table.insert().values(project2)) - - # Create a User - user = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain['id'], - 'password': uuid.uuid4().hex, - 'enabled': True, - 'extra': json.dumps({})} - session.execute(user_table.insert().values(user)) - - # Create a Role - role = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex} - session.execute(role_table.insert().values(role)) - - # And another role - role2 = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex} - session.execute(role_table.insert().values(role2)) - - # Grant Role to User - role_grant = {'user_id': user['id'], - 'tenant_id': project['id'], - 'data': json.dumps({"roles": [role['id']]})} - session.execute(metadata_table.insert().values(role_grant)) - - role_grant = {'user_id': user['id'], - 'tenant_id': project2['id'], - 'data': json.dumps({"roles": [role2['id']]})} - session.execute(metadata_table.insert().values(role_grant)) - - # Create another user to test the case where member_role_id is already - # assigned. - user2 = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain['id'], - 'password': uuid.uuid4().hex, - 'enabled': True, - 'extra': json.dumps({})} - session.execute(user_table.insert().values(user2)) - - # Grant CONF.member_role_id to User2 - role_grant = {'user_id': user2['id'], - 'tenant_id': project['id'], - 'data': json.dumps({"roles": [CONF.member_role_id]})} - session.execute(metadata_table.insert().values(role_grant)) - - session.commit() - - self.upgrade(17) - - user_project_metadata_table = sqlalchemy.Table( - 'user_project_metadata', self.metadata, autoload=True) - - s = sqlalchemy.select([metadata_table.c.data]).where( - (metadata_table.c.user_id == user['id']) & - (metadata_table.c.tenant_id == project['id'])) - r = session.execute(s) - test_project1 = json.loads(r.fetchone()['data']) - self.assertEqual(len(test_project1['roles']), 1) - self.assertIn(role['id'], test_project1['roles']) - - # Test user in project2 has role2 - s = sqlalchemy.select([metadata_table.c.data]).where( - (metadata_table.c.user_id == user['id']) & - (metadata_table.c.tenant_id == project2['id'])) - r = session.execute(s) - test_project2 = json.loads(r.fetchone()['data']) - self.assertEqual(len(test_project2['roles']), 1) - self.assertIn(role2['id'], test_project2['roles']) - - # Test for user in project has role in user_project_metadata - # Migration 17 does not properly migrate this data, so this should - # be None. - s = sqlalchemy.select([user_project_metadata_table.c.data]).where( - (user_project_metadata_table.c.user_id == user['id']) & - (user_project_metadata_table.c.project_id == project['id'])) - r = session.execute(s) - self.assertIsNone(r.fetchone()) - - # Create a conflicting user-project in user_project_metadata with - # a different role - data = json.dumps({"roles": [role2['id']]}) - role_grant = {'user_id': user['id'], - 'project_id': project['id'], - 'data': data} - cmd = user_project_metadata_table.insert().values(role_grant) - self.engine.execute(cmd) - - # Create another conflicting user-project for User2 - data = json.dumps({"roles": [role2['id']]}) - role_grant = {'user_id': user2['id'], - 'project_id': project['id'], - 'data': data} - cmd = user_project_metadata_table.insert().values(role_grant) - self.engine.execute(cmd) - # End Scaffolding - - session.commit() - - # Migrate to 20 - self.upgrade(20) - - # The user-project pairs should have all roles from the previous - # metadata table in addition to any roles currently in - # user_project_metadata - s = sqlalchemy.select([user_project_metadata_table.c.data]).where( - (user_project_metadata_table.c.user_id == user['id']) & - (user_project_metadata_table.c.project_id == project['id'])) - r = session.execute(s) - role_ids = json.loads(r.fetchone()['data'])['roles'] - self.assertEqual(len(role_ids), 3) - self.assertIn(CONF.member_role_id, role_ids) - self.assertIn(role['id'], role_ids) - self.assertIn(role2['id'], role_ids) - - # pairs that only existed in old metadata table should be in - # user_project_metadata - s = sqlalchemy.select([user_project_metadata_table.c.data]).where( - (user_project_metadata_table.c.user_id == user['id']) & - (user_project_metadata_table.c.project_id == project2['id'])) - r = session.execute(s) - role_ids = json.loads(r.fetchone()['data'])['roles'] - self.assertEqual(len(role_ids), 2) - self.assertIn(CONF.member_role_id, role_ids) - self.assertIn(role2['id'], role_ids) - - self.assertTableDoesNotExist('metadata') - - def test_upgrade_default_roles(self): - def count_member_roles(): - session = self.Session() - query_string = ("select count(*) as c from role " - "where name='%s'" % config.CONF.member_role_name) - role_count = session.execute(query_string).fetchone()['c'] - session.close() - return role_count - - self.upgrade(16) - self.assertEquals(0, count_member_roles()) - self.upgrade(17) - self.assertEquals(1, count_member_roles()) - self.downgrade(16) - self.assertEquals(0, count_member_roles()) - - def check_uniqueness_constraints(self): - # Check uniqueness constraints for User & Project tables are - # correct following schema modification. The Group table's - # schema is never modified, so we don't bother to check that. - domain_table = sqlalchemy.Table('domain', - self.metadata, - autoload=True) - domain1 = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'enabled': True} - domain2 = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'enabled': True} - cmd = domain_table.insert().values(domain1) - self.engine.execute(cmd) - cmd = domain_table.insert().values(domain2) - self.engine.execute(cmd) - - # First, the User table. - this_table = sqlalchemy.Table('user', - self.metadata, - autoload=True) - user = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], - 'password': uuid.uuid4().hex, - 'enabled': True, - 'extra': json.dumps({})} - cmd = this_table.insert().values(user) - self.engine.execute(cmd) - # now insert a user with the same name into a different - # domain - which should work. - user['id'] = uuid.uuid4().hex - user['domain_id'] = domain2['id'] - cmd = this_table.insert().values(user) - self.engine.execute(cmd) - # TODO(henry-nash): For now, as part of clean-up we delete one of these - # users. Although not part of this test, unless we do so the - # downgrade(16->15) that is part of teardown with fail due to having - # two uses with clashing name as we try to revert to a single global - # name space. This limitation is raised as Bug #1125046 and the delete - # could be removed depending on how that bug is resolved. - cmd = this_table.delete(id=user['id']) - self.engine.execute(cmd) - - # Now, the Project table. - this_table = sqlalchemy.Table('project', - self.metadata, - autoload=True) - project = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain1['id'], - 'description': uuid.uuid4().hex, - 'enabled': True, - 'extra': json.dumps({})} - cmd = this_table.insert().values(project) - self.engine.execute(cmd) - # now insert a project with the same name into a different - # domain - which should work. - project['id'] = uuid.uuid4().hex - project['domain_id'] = domain2['id'] - cmd = this_table.insert().values(project) - self.engine.execute(cmd) - # TODO(henry-nash): For now, we delete one of the projects for the same - # reason as we delete one of the users (Bug #1125046). This delete - # could be removed depending on that bug resolution. - cmd = this_table.delete(id=project['id']) - self.engine.execute(cmd) - - def test_upgrade_trusts(self): - self.assertEqual(self.schema.version, 0, "DB is at version 0") - self.upgrade(20) - self.assertTableColumns("token", - ["id", "expires", "extra", "valid"]) - self.upgrade(21) - self.assertTableColumns("trust", - ["id", "trustor_user_id", - "trustee_user_id", - "project_id", "impersonation", - "deleted_at", - "expires_at", "extra"]) - self.assertTableColumns("trust_role", - ["trust_id", "role_id"]) - self.assertTableColumns("token", - ["id", "expires", "extra", "valid", - "trust_id", "user_id"]) - - def test_fixup_role(self): - session = self.Session() - self.assertEqual(self.schema.version, 0, "DB is at version 0") - self.upgrade(1) - self.insert_dict(session, "role", {"id": "test", "name": "test"}) - self.upgrade(18) - self.insert_dict(session, "role", {"id": "test2", - "name": "test2", - "extra": None}) - r = session.execute('select count(*) as c from role ' - 'where extra is null') - self.assertEqual(r.fetchone()['c'], 2) - session.commit() - self.upgrade(19) - r = session.execute('select count(*) as c from role ' - 'where extra is null') - self.assertEqual(r.fetchone()['c'], 0) - - def test_legacy_endpoint_id(self): - session = self.Session() - self.upgrade(21) - - service = { - 'id': uuid.uuid4().hex, - 'name': 'keystone', - 'type': 'identity'} - self.insert_dict(session, 'service', service) - - legacy_endpoint_id = uuid.uuid4().hex - endpoint = { - 'id': uuid.uuid4().hex, - 'service_id': service['id'], - 'interface': uuid.uuid4().hex[:8], - 'url': uuid.uuid4().hex, - 'extra': json.dumps({ - 'legacy_endpoint_id': legacy_endpoint_id})} - self.insert_dict(session, 'endpoint', endpoint) - - session.commit() - self.upgrade(22) - - endpoint_table = sqlalchemy.Table( - 'endpoint', self.metadata, autoload=True) - - self.assertEqual(session.query(endpoint_table).count(), 1) - ref = session.query(endpoint_table).one() - self.assertEqual(ref.id, endpoint['id'], ref) - self.assertEqual(ref.service_id, endpoint['service_id']) - self.assertEqual(ref.interface, endpoint['interface']) - self.assertEqual(ref.url, endpoint['url']) - self.assertEqual(ref.legacy_endpoint_id, legacy_endpoint_id) - self.assertEqual(ref.extra, '{}') - - def test_group_project_FK_fixup(self): - # To create test data we must start before we broke in the - # group_project_metadata table in 015. - self.upgrade(14) - session = self.Session() - - domain_table = sqlalchemy.Table('domain', self.metadata, autoload=True) - group_table = sqlalchemy.Table('group', self.metadata, autoload=True) - tenant_table = sqlalchemy.Table('tenant', self.metadata, autoload=True) - role_table = sqlalchemy.Table('role', self.metadata, autoload=True) - group_project_metadata_table = sqlalchemy.Table( - 'group_project_metadata', self.metadata, autoload=True) - - # Create a Domain - domain = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'enabled': True} - session.execute(domain_table.insert().values(domain)) - - # Create two Tenants - tenant = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'extra': "{}"} - session.execute(tenant_table.insert().values(tenant)) - - tenant1 = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'extra': "{}"} - session.execute(tenant_table.insert().values(tenant1)) - - # Create a Group - group = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain['id'], - 'extra': json.dumps({})} - session.execute(group_table.insert().values(group)) - - # Create roles - role_list = [] - for _ in range(2): - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - session.execute(role_table.insert().values(role)) - role_list.append(role) - - # Grant Role to User on Project - role_grant = {'group_id': group['id'], - 'project_id': tenant['id'], - 'data': json.dumps({'roles': [role_list[0]['id']]})} - session.execute( - group_project_metadata_table.insert().values(role_grant)) - - role_grant = {'group_id': group['id'], - 'project_id': tenant1['id'], - 'data': json.dumps({'roles': [role_list[1]['id']]})} - session.execute( - group_project_metadata_table.insert().values(role_grant)) - - session.commit() - - # Now upgrade and fix up the FKs - self.upgrade(28) - self.assertTableExists('group_project_metadata') - self.assertTableExists('project') - self.assertTableDoesNotExist('tenant') - - s = sqlalchemy.select([group_project_metadata_table.c.data]).where( - (group_project_metadata_table.c.group_id == group['id']) & - (group_project_metadata_table.c.project_id == tenant['id'])) - r = session.execute(s) - data = json.loads(r.fetchone()['data']) - self.assertEqual(len(data['roles']), 1) - self.assertIn(role_list[0]['id'], data['roles']) - - s = sqlalchemy.select([group_project_metadata_table.c.data]).where( - (group_project_metadata_table.c.group_id == group['id']) & - (group_project_metadata_table.c.project_id == tenant1['id'])) - r = session.execute(s) - data = json.loads(r.fetchone()['data']) - self.assertEqual(len(data['roles']), 1) - self.assertIn(role_list[1]['id'], data['roles']) - - self.downgrade(27) - self.assertTableExists('group_project_metadata') - self.assertTableExists('project') - self.assertTableDoesNotExist('tenant') - - def test_assignment_metadata_migration(self): - self.upgrade(28) - # Scaffolding - session = self.Session() - - domain_table = sqlalchemy.Table('domain', self.metadata, autoload=True) - user_table = sqlalchemy.Table('user', self.metadata, autoload=True) - group_table = sqlalchemy.Table('group', self.metadata, autoload=True) - role_table = sqlalchemy.Table('role', self.metadata, autoload=True) - project_table = sqlalchemy.Table( - 'project', self.metadata, autoload=True) - user_project_metadata_table = sqlalchemy.Table( - 'user_project_metadata', self.metadata, autoload=True) - user_domain_metadata_table = sqlalchemy.Table( - 'user_domain_metadata', self.metadata, autoload=True) - group_project_metadata_table = sqlalchemy.Table( - 'group_project_metadata', self.metadata, autoload=True) - group_domain_metadata_table = sqlalchemy.Table( - 'group_domain_metadata', self.metadata, autoload=True) - - # Create a Domain - domain = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'enabled': True} - session.execute(domain_table.insert().values(domain)) - - # Create anther Domain - domain2 = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'enabled': True} - session.execute(domain_table.insert().values(domain2)) - - # Create a Project - project = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain['id'], - 'extra': "{}"} - session.execute(project_table.insert().values(project)) - - # Create another Project - project2 = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain['id'], - 'extra': "{}"} - session.execute(project_table.insert().values(project2)) - - # Create a User - user = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain['id'], - 'password': uuid.uuid4().hex, - 'enabled': True, - 'extra': json.dumps({})} - session.execute(user_table.insert().values(user)) - - # Create a Group - group = {'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'domain_id': domain['id'], - 'extra': json.dumps({})} - session.execute(group_table.insert().values(group)) - - # Create roles - role_list = [] - for _ in range(7): - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - session.execute(role_table.insert().values(role)) - role_list.append(role) - - # Grant Role to User on Project - role_grant = {'user_id': user['id'], - 'project_id': project['id'], - 'data': json.dumps({'roles': [role_list[0]['id']]})} - session.execute( - user_project_metadata_table.insert().values(role_grant)) - - role_grant = {'user_id': user['id'], - 'project_id': project2['id'], - 'data': json.dumps({'roles': [role_list[1]['id']]})} - session.execute( - user_project_metadata_table.insert().values(role_grant)) - - # Grant Role to Group on different Project - role_grant = {'group_id': group['id'], - 'project_id': project2['id'], - 'data': json.dumps({'roles': [role_list[2]['id']]})} - session.execute( - group_project_metadata_table.insert().values(role_grant)) - - # Grant Role to User on Domain - role_grant = {'user_id': user['id'], - 'domain_id': domain['id'], - 'data': json.dumps({'roles': [role_list[3]['id']]})} - session.execute(user_domain_metadata_table.insert().values(role_grant)) - - # Grant Role to Group on Domain - role_grant = {'group_id': group['id'], - 'domain_id': domain['id'], - 'data': json.dumps( - {'roles': [role_list[4]['id']], - 'other': 'somedata'})} - session.execute( - group_domain_metadata_table.insert().values(role_grant)) - - session.commit() - - self.upgrade(29) - s = sqlalchemy.select([user_project_metadata_table.c.data]).where( - (user_project_metadata_table.c.user_id == user['id']) & - (user_project_metadata_table.c.project_id == project['id'])) - r = session.execute(s) - data = json.loads(r.fetchone()['data']) - self.assertEqual(len(data['roles']), 1) - self.assertIn({'id': role_list[0]['id']}, data['roles']) - - s = sqlalchemy.select([user_project_metadata_table.c.data]).where( - (user_project_metadata_table.c.user_id == user['id']) & - (user_project_metadata_table.c.project_id == project2['id'])) - r = session.execute(s) - data = json.loads(r.fetchone()['data']) - self.assertEqual(len(data['roles']), 1) - self.assertIn({'id': role_list[1]['id']}, data['roles']) - - s = sqlalchemy.select([group_project_metadata_table.c.data]).where( - (group_project_metadata_table.c.group_id == group['id']) & - (group_project_metadata_table.c.project_id == project2['id'])) - r = session.execute(s) - data = json.loads(r.fetchone()['data']) - self.assertEqual(len(data['roles']), 1) - self.assertIn({'id': role_list[2]['id']}, data['roles']) - - s = sqlalchemy.select([user_domain_metadata_table.c.data]).where( - (user_domain_metadata_table.c.user_id == user['id']) & - (user_domain_metadata_table.c.domain_id == domain['id'])) - r = session.execute(s) - data = json.loads(r.fetchone()['data']) - self.assertEqual(len(data['roles']), 1) - self.assertIn({'id': role_list[3]['id']}, data['roles']) - - s = sqlalchemy.select([group_domain_metadata_table.c.data]).where( - (group_domain_metadata_table.c.group_id == group['id']) & - (group_domain_metadata_table.c.domain_id == domain['id'])) - r = session.execute(s) - data = json.loads(r.fetchone()['data']) - self.assertEqual(len(data['roles']), 1) - self.assertIn({'id': role_list[4]['id']}, data['roles']) - self.assertIn('other', data) - - # Now add an entry that has one regular and one inherited role - role_grant = {'user_id': user['id'], - 'domain_id': domain2['id'], - 'data': json.dumps( - {'roles': [{'id': role_list[5]['id']}, - {'id': role_list[6]['id'], - 'inherited_to': 'projects'}]})} - session.execute(user_domain_metadata_table.insert().values(role_grant)) - - session.commit() - self.downgrade(28) - - s = sqlalchemy.select([user_project_metadata_table.c.data]).where( - (user_project_metadata_table.c.user_id == user['id']) & - (user_project_metadata_table.c.project_id == project['id'])) - r = session.execute(s) - data = json.loads(r.fetchone()['data']) - self.assertEqual(len(data['roles']), 1) - self.assertIn(role_list[0]['id'], data['roles']) - - s = sqlalchemy.select([user_project_metadata_table.c.data]).where( - (user_project_metadata_table.c.user_id == user['id']) & - (user_project_metadata_table.c.project_id == project2['id'])) - r = session.execute(s) - data = json.loads(r.fetchone()['data']) - self.assertEqual(len(data['roles']), 1) - self.assertIn(role_list[1]['id'], data['roles']) - - s = sqlalchemy.select([group_project_metadata_table.c.data]).where( - (group_project_metadata_table.c.group_id == group['id']) & - (group_project_metadata_table.c.project_id == project2['id'])) - r = session.execute(s) - data = json.loads(r.fetchone()['data']) - self.assertEqual(len(data['roles']), 1) - self.assertIn(role_list[2]['id'], data['roles']) - - s = sqlalchemy.select([user_domain_metadata_table.c.data]).where( - (user_domain_metadata_table.c.user_id == user['id']) & - (user_domain_metadata_table.c.domain_id == domain['id'])) - r = session.execute(s) - data = json.loads(r.fetchone()['data']) - self.assertEqual(len(data['roles']), 1) - self.assertIn(role_list[3]['id'], data['roles']) - - s = sqlalchemy.select([group_domain_metadata_table.c.data]).where( - (group_domain_metadata_table.c.group_id == group['id']) & - (group_domain_metadata_table.c.domain_id == domain['id'])) - r = session.execute(s) - data = json.loads(r.fetchone()['data']) - self.assertEqual(len(data['roles']), 1) - self.assertIn(role_list[4]['id'], data['roles']) - self.assertIn('other', data) - - # For user-domain2, where we had one regular and one inherited role, - # only the direct role should remain, the inherited role should - # have been deleted during the downgrade - s = sqlalchemy.select([user_domain_metadata_table.c.data]).where( - (user_domain_metadata_table.c.user_id == user['id']) & - (user_domain_metadata_table.c.domain_id == domain2['id'])) - r = session.execute(s) - data = json.loads(r.fetchone()['data']) - self.assertEqual(len(data['roles']), 1) - self.assertIn(role_list[5]['id'], data['roles']) - - def test_drop_credential_constraint(self): - ec2_credential = { - 'id': '100', - 'user_id': 'foo', - 'project_id': 'bar', - 'type': 'ec2', - 'blob': json.dumps({ - "access": "12345", - "secret": "12345" - }) - } - user = { - 'id': 'foo', - 'name': 'FOO', - 'password': 'foo2', - 'enabled': True, - 'email': 'foo@bar.com', - 'extra': json.dumps({'enabled': True}) - } - tenant = { - 'id': 'bar', - 'name': 'BAR', - 'description': 'description', - 'enabled': True, - 'extra': json.dumps({'enabled': True}) - } - session = self.Session() - self.upgrade(7) - self.insert_dict(session, 'user', user) - self.insert_dict(session, 'tenant', tenant) - self.insert_dict(session, 'credential', ec2_credential) - session.commit() - self.upgrade(30) - cred_table = sqlalchemy.Table('credential', - self.metadata, - autoload=True) - cred = session.query(cred_table).filter("id='100'").one() - self.assertEqual(cred.user_id, - ec2_credential['user_id']) - - def test_drop_credential_indexes(self): - self.upgrade(31) - table = sqlalchemy.Table('credential', self.metadata, autoload=True) - self.assertEqual(len(table.indexes), 0) - - def test_downgrade_30(self): - self.upgrade(31) - self.downgrade(30) - table = sqlalchemy.Table('credential', self.metadata, autoload=True) - index_data = [(idx.name, idx.columns.keys()) - for idx in table.indexes] - if self.engine.name == 'mysql': - self.assertIn(('user_id', ['user_id']), index_data) - self.assertIn(('credential_project_id_fkey', ['project_id']), - index_data) - else: - self.assertEqual(len(index_data), 0) - - def populate_user_table(self, with_pass_enab=False, - with_pass_enab_domain=False): - # Populate the appropriate fields in the user - # table, depending on the parameters: - # - # Default: id, name, extra - # pass_enab: Add password, enabled as well - # pass_enab_domain: Add password, enabled and domain as well - # - this_table = sqlalchemy.Table("user", - self.metadata, - autoload=True) - for user in default_fixtures.USERS: - extra = copy.deepcopy(user) - extra.pop('id') - extra.pop('name') - - if with_pass_enab: - password = extra.pop('password', None) - enabled = extra.pop('enabled', True) - ins = this_table.insert().values( - {'id': user['id'], - 'name': user['name'], - 'password': password, - 'enabled': bool(enabled), - 'extra': json.dumps(extra)}) - else: - if with_pass_enab_domain: - password = extra.pop('password', None) - enabled = extra.pop('enabled', True) - extra.pop('domain_id') - ins = this_table.insert().values( - {'id': user['id'], - 'name': user['name'], - 'domain_id': user['domain_id'], - 'password': password, - 'enabled': bool(enabled), - 'extra': json.dumps(extra)}) - else: - ins = this_table.insert().values( - {'id': user['id'], - 'name': user['name'], - 'extra': json.dumps(extra)}) - self.engine.execute(ins) - - def populate_tenant_table(self, with_desc_enab=False, - with_desc_enab_domain=False): - # Populate the appropriate fields in the tenant or - # project table, depending on the parameters - # - # Default: id, name, extra - # desc_enab: Add description, enabled as well - # desc_enab_domain: Add description, enabled and domain as well, - # plus use project instead of tenant - # - if with_desc_enab_domain: - # By this time tenants are now projects - this_table = sqlalchemy.Table("project", - self.metadata, - autoload=True) - else: - this_table = sqlalchemy.Table("tenant", - self.metadata, - autoload=True) - - for tenant in default_fixtures.TENANTS: - extra = copy.deepcopy(tenant) - extra.pop('id') - extra.pop('name') - - if with_desc_enab: - desc = extra.pop('description', None) - enabled = extra.pop('enabled', True) - ins = this_table.insert().values( - {'id': tenant['id'], - 'name': tenant['name'], - 'description': desc, - 'enabled': bool(enabled), - 'extra': json.dumps(extra)}) - else: - if with_desc_enab_domain: - desc = extra.pop('description', None) - enabled = extra.pop('enabled', True) - extra.pop('domain_id') - ins = this_table.insert().values( - {'id': tenant['id'], - 'name': tenant['name'], - 'domain_id': tenant['domain_id'], - 'description': desc, - 'enabled': bool(enabled), - 'extra': json.dumps(extra)}) - else: - ins = this_table.insert().values( - {'id': tenant['id'], - 'name': tenant['name'], - 'extra': json.dumps(extra)}) - self.engine.execute(ins) - - def _mysql_check_all_tables_innodb(self): - database = self.engine.url.database - - connection = self.engine.connect() - # sanity check - total = connection.execute("SELECT count(*) " - "from information_schema.TABLES " - "where TABLE_SCHEMA='%(database)s'" % - locals()) - self.assertTrue(total.scalar() > 0, "No tables found. Wrong schema?") - - noninnodb = connection.execute("SELECT table_name " - "from information_schema.TABLES " - "where TABLE_SCHEMA='%(database)s' " - "and ENGINE!='InnoDB' " - "and TABLE_NAME!='migrate_version'" % - locals()) - names = [x[0] for x in noninnodb] - self.assertEqual(names, [], - "Non-InnoDB tables exist") - - connection.close() diff --git a/tests/test_ssl.py b/tests/test_ssl.py deleted file mode 100644 index 8de5cc19..00000000 --- a/tests/test_ssl.py +++ /dev/null @@ -1,154 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 os -import ssl - -from keystone import test - -from keystone.common import environment -from keystone import config - -CONF = config.CONF - -CERTDIR = test.rootdir("examples/pki/certs") -KEYDIR = test.rootdir("examples/pki/private") -CERT = os.path.join(CERTDIR, 'ssl_cert.pem') -KEY = os.path.join(KEYDIR, 'ssl_key.pem') -CA = os.path.join(CERTDIR, 'cacert.pem') -CLIENT = os.path.join(CERTDIR, 'middleware.pem') - - -class SSLTestCase(test.TestCase): - def setUp(self): - super(SSLTestCase, self).setUp() - self.load_backends() - - def test_1way_ssl_ok(self): - """Make sure both public and admin API work with 1-way SSL.""" - self.public_server = self.serveapp('keystone', name='main', - cert=CERT, key=KEY, ca=CA) - self.admin_server = self.serveapp('keystone', name='admin', - cert=CERT, key=KEY, ca=CA) - # Verify Admin - conn = environment.httplib.HTTPSConnection('127.0.0.1', - CONF.admin_port) - conn.request('GET', '/') - resp = conn.getresponse() - self.assertEqual(resp.status, 300) - # Verify Public - conn = environment.httplib.HTTPSConnection('127.0.0.1', - CONF.public_port) - conn.request('GET', '/') - resp = conn.getresponse() - self.assertEqual(resp.status, 300) - - def test_2way_ssl_ok(self): - """Make sure both public and admin API work with 2-way SSL. - - Requires client certificate. - """ - self.public_server = self.serveapp( - 'keystone', name='main', cert=CERT, - key=KEY, ca=CA, cert_required=True) - self.admin_server = self.serveapp( - 'keystone', name='admin', cert=CERT, - key=KEY, ca=CA, cert_required=True) - # Verify Admin - conn = environment.httplib.HTTPSConnection( - '127.0.0.1', CONF.admin_port, CLIENT, CLIENT) - conn.request('GET', '/') - resp = conn.getresponse() - self.assertEqual(resp.status, 300) - # Verify Public - conn = environment.httplib.HTTPSConnection( - '127.0.0.1', CONF.public_port, CLIENT, CLIENT) - conn.request('GET', '/') - resp = conn.getresponse() - self.assertEqual(resp.status, 300) - - def test_1way_ssl_with_ipv6_ok(self): - """Make sure both public and admin API work with 1-way ipv6 & SSL.""" - self.skip_if_no_ipv6() - self.public_server = self.serveapp('keystone', name='main', - cert=CERT, key=KEY, ca=CA, - host="::1", port=0) - self.admin_server = self.serveapp('keystone', name='admin', - cert=CERT, key=KEY, ca=CA, - host="::1", port=0) - # Verify Admin - conn = environment.httplib.HTTPSConnection('::1', CONF.admin_port) - conn.request('GET', '/') - resp = conn.getresponse() - self.assertEqual(resp.status, 300) - # Verify Public - conn = environment.httplib.HTTPSConnection('::1', CONF.public_port) - conn.request('GET', '/') - resp = conn.getresponse() - self.assertEqual(resp.status, 300) - - def test_2way_ssl_with_ipv6_ok(self): - """Make sure both public and admin API work with 2-way ipv6 & SSL. - - Requires client certificate. - """ - self.skip_if_no_ipv6() - self.public_server = self.serveapp( - 'keystone', name='main', cert=CERT, - key=KEY, ca=CA, cert_required=True, - host="::1", port=0) - self.admin_server = self.serveapp( - 'keystone', name='admin', cert=CERT, - key=KEY, ca=CA, cert_required=True, - host="::1", port=0) - # Verify Admin - conn = environment.httplib.HTTPSConnection( - '::1', CONF.admin_port, CLIENT, CLIENT) - conn.request('GET', '/') - resp = conn.getresponse() - self.assertEqual(resp.status, 300) - # Verify Public - conn = environment.httplib.HTTPSConnection( - '::1', CONF.public_port, CLIENT, CLIENT) - conn.request('GET', '/') - resp = conn.getresponse() - self.assertEqual(resp.status, 300) - - def test_2way_ssl_fail(self): - """Expect to fail when client does not present proper certificate.""" - self.public_server = self.serveapp( - 'keystone', name='main', cert=CERT, - key=KEY, ca=CA, cert_required=True) - self.admin_server = self.serveapp( - 'keystone', name='admin', cert=CERT, - key=KEY, ca=CA, cert_required=True) - # Verify Admin - conn = environment.httplib.HTTPSConnection('127.0.0.1', - CONF.admin_port) - try: - conn.request('GET', '/') - self.fail('Admin API shoulda failed with SSL handshake!') - except ssl.SSLError: - pass - # Verify Public - conn = environment.httplib.HTTPSConnection('127.0.0.1', - CONF.public_port) - try: - conn.request('GET', '/') - self.fail('Public API shoulda failed with SSL handshake!') - except ssl.SSLError: - pass diff --git a/tests/test_token_bind.py b/tests/test_token_bind.py deleted file mode 100644 index 20488a91..00000000 --- a/tests/test_token_bind.py +++ /dev/null @@ -1,182 +0,0 @@ -# Copyright 2013 OpenStack 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 keystone.common import wsgi -from keystone import config -from keystone import exception -from keystone import test - -CONF = config.CONF - -KERBEROS_BIND = 'USER@REALM' - -# the only thing the function checks for is the presence of bind -TOKEN_BIND_KERB = {'bind': {'kerberos': KERBEROS_BIND}} -TOKEN_BIND_UNKNOWN = {'bind': {'FOO': 'BAR'}} -TOKEN_BIND_NONE = {} - -ANY = 'any' -ALL_TOKENS = [TOKEN_BIND_KERB, TOKEN_BIND_UNKNOWN, TOKEN_BIND_NONE] - - -class BindTest(test.TestCase): - """Test binding tokens to a Principal. - - Even though everything in this file references kerberos the same concepts - will apply to all future binding mechanisms. - """ - - def assert_kerberos_bind(self, tokens, bind_level, - use_kerberos=True, success=True): - if not isinstance(tokens, dict): - for token in tokens: - self.assert_kerberos_bind(token, bind_level, - use_kerberos=use_kerberos, - success=success) - elif use_kerberos == ANY: - for val in (True, False): - self.assert_kerberos_bind(tokens, bind_level, - use_kerberos=val, success=success) - else: - context = {} - CONF.token.enforce_token_bind = bind_level - - if use_kerberos: - context['REMOTE_USER'] = KERBEROS_BIND - context['AUTH_TYPE'] = 'Negotiate' - - if not success: - self.assertRaises(exception.Unauthorized, - wsgi.validate_token_bind, - context, tokens) - else: - wsgi.validate_token_bind(context, tokens) - - # DISABLED - - def test_bind_disabled_with_kerb_user(self): - self.assert_kerberos_bind(ALL_TOKENS, - bind_level='disabled', - use_kerberos=ANY, - success=True) - - # PERMISSIVE - - def test_bind_permissive_with_kerb_user(self): - self.assert_kerberos_bind(TOKEN_BIND_KERB, - bind_level='permissive', - use_kerberos=True, - success=True) - - def test_bind_permissive_with_regular_token(self): - self.assert_kerberos_bind(TOKEN_BIND_NONE, - bind_level='permissive', - use_kerberos=ANY, - success=True) - - def test_bind_permissive_without_kerb_user(self): - self.assert_kerberos_bind(TOKEN_BIND_KERB, - bind_level='permissive', - use_kerberos=False, - success=False) - - def test_bind_permissive_with_unknown_bind(self): - self.assert_kerberos_bind(TOKEN_BIND_UNKNOWN, - bind_level='permissive', - use_kerberos=ANY, - success=True) - - # STRICT - - def test_bind_strict_with_regular_token(self): - self.assert_kerberos_bind(TOKEN_BIND_NONE, - bind_level='strict', - use_kerberos=ANY, - success=True) - - def test_bind_strict_with_kerb_user(self): - self.assert_kerberos_bind(TOKEN_BIND_KERB, - bind_level='strict', - use_kerberos=True, - success=True) - - def test_bind_strict_without_kerb_user(self): - self.assert_kerberos_bind(TOKEN_BIND_KERB, - bind_level='strict', - use_kerberos=False, - success=False) - - def test_bind_strict_with_unknown_bind(self): - self.assert_kerberos_bind(TOKEN_BIND_UNKNOWN, - bind_level='strict', - use_kerberos=ANY, - success=False) - - # REQUIRED - - def test_bind_required_with_regular_token(self): - self.assert_kerberos_bind(TOKEN_BIND_NONE, - bind_level='required', - use_kerberos=ANY, - success=False) - - def test_bind_required_with_kerb_user(self): - self.assert_kerberos_bind(TOKEN_BIND_KERB, - bind_level='required', - use_kerberos=True, - success=True) - - def test_bind_required_without_kerb_user(self): - self.assert_kerberos_bind(TOKEN_BIND_KERB, - bind_level='required', - use_kerberos=False, - success=False) - - def test_bind_required_with_unknown_bind(self): - self.assert_kerberos_bind(TOKEN_BIND_UNKNOWN, - bind_level='required', - use_kerberos=ANY, - success=False) - - # NAMED - - def test_bind_named_with_regular_token(self): - self.assert_kerberos_bind(TOKEN_BIND_NONE, - bind_level='kerberos', - use_kerberos=ANY, - success=False) - - def test_bind_named_with_kerb_user(self): - self.assert_kerberos_bind(TOKEN_BIND_KERB, - bind_level='kerberos', - use_kerberos=True, - success=True) - - def test_bind_named_without_kerb_user(self): - self.assert_kerberos_bind(TOKEN_BIND_KERB, - bind_level='kerberos', - use_kerberos=False, - success=False) - - def test_bind_named_with_unknown_bind(self): - self.assert_kerberos_bind(TOKEN_BIND_UNKNOWN, - bind_level='kerberos', - use_kerberos=ANY, - success=False) - - def test_bind_named_with_unknown_scheme(self): - self.assert_kerberos_bind(ALL_TOKENS, - bind_level='unknown', - use_kerberos=ANY, - success=False) diff --git a/tests/test_token_provider.py b/tests/test_token_provider.py deleted file mode 100644 index a7e92717..00000000 --- a/tests/test_token_provider.py +++ /dev/null @@ -1,439 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 OpenStack 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 uuid - -from keystone import exception -from keystone import test -from keystone import token - - -SAMPLE_V2_TOKEN = { - "access": { - "trust": { - "id": "abc123", - "trustee_user_id": "123456" - }, - "serviceCatalog": [ - { - "endpoints": [ - { - "adminURL": "http://localhost:8774/v1.1/01257", - "id": "51934fe63a5b4ac0a32664f64eb462c3", - "internalURL": "http://localhost:8774/v1.1/01257", - "publicURL": "http://localhost:8774/v1.1/01257", - "region": "RegionOne" - } - ], - "endpoints_links": [], - "name": "nova", - "type": "compute" - }, - { - "endpoints": [ - { - "adminURL": "http://localhost:9292", - "id": "aaa17a539e364297a7845d67c7c7cc4b", - "internalURL": "http://localhost:9292", - "publicURL": "http://localhost:9292", - "region": "RegionOne" - } - ], - "endpoints_links": [], - "name": "glance", - "type": "image" - }, - { - "endpoints": [ - { - "adminURL": "http://localhost:8776/v1/01257", - "id": "077d82df25304abeac2294004441db5a", - "internalURL": "http://localhost:8776/v1/01257", - "publicURL": "http://localhost:8776/v1/01257", - "region": "RegionOne" - } - ], - "endpoints_links": [], - "name": "volume", - "type": "volume" - }, - { - "endpoints": [ - { - "adminURL": "http://localhost:8773/services/Admin", - "id": "b06997fd08414903ad458836efaa9067", - "internalURL": "http://localhost:8773/services/Cloud", - "publicURL": "http://localhost:8773/services/Cloud", - "region": "RegionOne" - } - ], - "endpoints_links": [], - "name": "ec2", - "type": "ec2" - }, - { - "endpoints": [ - { - "adminURL": "http://localhost:8888/v1", - "id": "7bd0c643e05a4a2ab40902b2fa0dd4e6", - "internalURL": "http://localhost:8888/v1/AUTH_01257", - "publicURL": "http://localhost:8888/v1/AUTH_01257", - "region": "RegionOne" - } - ], - "endpoints_links": [], - "name": "swift", - "type": "object-store" - }, - { - "endpoints": [ - { - "adminURL": "http://localhost:35357/v2.0", - "id": "02850c5d1d094887bdc46e81e1e15dc7", - "internalURL": "http://localhost:5000/v2.0", - "publicURL": "http://localhost:5000/v2.0", - "region": "RegionOne" - } - ], - "endpoints_links": [], - "name": "keystone", - "type": "identity" - } - ], - "token": { - "expires": "2013-05-22T00:02:43.941430Z", - "id": "ce4fc2d36eea4cc9a36e666ac2f1029a", - "issued_at": "2013-05-21T00:02:43.941473Z", - "tenant": { - "enabled": True, - "id": "01257", - "name": "service" - } - }, - "user": { - "id": "f19ddbe2c53c46f189fe66d0a7a9c9ce", - "name": "nova", - "roles": [ - { - "name": "_member_" - }, - { - "name": "admin" - } - ], - "roles_links": [], - "username": "nova" - } - } -} - -SAMPLE_V3_TOKEN = { - "token": { - "catalog": [ - { - "endpoints": [ - { - "id": "02850c5d1d094887bdc46e81e1e15dc7", - "interface": "admin", - "region": "RegionOne", - "url": "http://localhost:35357/v2.0" - }, - { - "id": "446e244b75034a9ab4b0811e82d0b7c8", - "interface": "internal", - "region": "RegionOne", - "url": "http://localhost:5000/v2.0" - }, - { - "id": "47fa3d9f499240abb5dfcf2668f168cd", - "interface": "public", - "region": "RegionOne", - "url": "http://localhost:5000/v2.0" - } - ], - "id": "26d7541715a44a4d9adad96f9872b633", - "type": "identity", - }, - { - "endpoints": [ - { - "id": "aaa17a539e364297a7845d67c7c7cc4b", - "interface": "admin", - "region": "RegionOne", - "url": "http://localhost:9292" - }, - { - "id": "4fa9620e42394cb1974736dce0856c71", - "interface": "internal", - "region": "RegionOne", - "url": "http://localhost:9292" - }, - { - "id": "9673687f9bc441d88dec37942bfd603b", - "interface": "public", - "region": "RegionOne", - "url": "http://localhost:9292" - } - ], - "id": "d27a41843f4e4b0e8cf6dac4082deb0d", - "type": "image", - }, - { - "endpoints": [ - { - "id": "7bd0c643e05a4a2ab40902b2fa0dd4e6", - "interface": "admin", - "region": "RegionOne", - "url": "http://localhost:8888/v1" - }, - { - "id": "43bef154594d4ccb8e49014d20624e1d", - "interface": "internal", - "region": "RegionOne", - "url": "http://localhost:8888/v1/AUTH_01257" - }, - { - "id": "e63b5f5d7aa3493690189d0ff843b9b3", - "interface": "public", - "region": "RegionOne", - "url": "http://localhost:8888/v1/AUTH_01257" - } - ], - "id": "a669e152f1104810a4b6701aade721bb", - "type": "object-store", - }, - { - "endpoints": [ - { - "id": "51934fe63a5b4ac0a32664f64eb462c3", - "interface": "admin", - "region": "RegionOne", - "url": "http://localhost:8774/v1.1/01257" - }, - { - "id": "869b535eea0d42e483ae9da0d868ebad", - "interface": "internal", - "region": "RegionOne", - "url": "http://localhost:8774/v1.1/01257" - }, - { - "id": "93583824c18f4263a2245ca432b132a6", - "interface": "public", - "region": "RegionOne", - "url": "http://localhost:8774/v1.1/01257" - } - ], - "id": "7f32cc2af6c9476e82d75f80e8b3bbb8", - "type": "compute", - }, - { - "endpoints": [ - { - "id": "b06997fd08414903ad458836efaa9067", - "interface": "admin", - "region": "RegionOne", - "url": "http://localhost:8773/services/Admin" - }, - { - "id": "411f7de7c9a8484c9b46c254fb2676e2", - "interface": "internal", - "region": "RegionOne", - "url": "http://localhost:8773/services/Cloud" - }, - { - "id": "f21c93f3da014785854b4126d0109c49", - "interface": "public", - "region": "RegionOne", - "url": "http://localhost:8773/services/Cloud" - } - ], - "id": "b08c9c7d4ef543eba5eeb766f72e5aa1", - "type": "ec2", - }, - { - "endpoints": [ - { - "id": "077d82df25304abeac2294004441db5a", - "interface": "admin", - "region": "RegionOne", - "url": "http://localhost:8776/v1/01257" - }, - { - "id": "875bf282362c40219665278b4fd11467", - "interface": "internal", - "region": "RegionOne", - "url": "http://localhost:8776/v1/01257" - }, - { - "id": "cd229aa6df0640dc858a8026eb7e640c", - "interface": "public", - "region": "RegionOne", - "url": "http://localhost:8776/v1/01257" - } - ], - "id": "5db21b82617f4a95816064736a7bec22", - "type": "volume", - } - ], - "expires_at": "2013-05-22T00:02:43.941430Z", - "issued_at": "2013-05-21T00:02:43.941473Z", - "methods": [ - "password" - ], - "project": { - "domain": { - "id": "default", - "name": "Default" - }, - "id": "01257", - "name": "service" - }, - "roles": [ - { - "id": "9fe2ff9ee4384b1894a90878d3e92bab", - "name": "_member_" - }, - { - "id": "53bff13443bd4450b97f978881d47b18", - "name": "admin" - } - ], - "user": { - "domain": { - "id": "default", - "name": "Default" - }, - "id": "f19ddbe2c53c46f189fe66d0a7a9c9ce", - "name": "nova" - }, - "OS-TRUST:trust": { - "id": "abc123", - "trustee_user_id": "123456", - "trustor_user_id": "333333", - "impersonation": False - } - } -} - - -class TestTokenProvider(test.TestCase): - def setUp(self): - super(TestTokenProvider, self).setUp() - self.load_backends() - - def test_get_token_version(self): - self.assertEqual( - token.provider.V2, - self.token_provider_api.get_token_version(SAMPLE_V2_TOKEN)) - self.assertEqual( - token.provider.V3, - self.token_provider_api.get_token_version(SAMPLE_V3_TOKEN)) - self.assertRaises(token.provider.UnsupportedTokenVersionException, - self.token_provider_api.get_token_version, - 'bogus') - - def test_issue_token(self): - self.assertRaises(token.provider.UnsupportedTokenVersionException, - self.token_provider_api.issue_token, - 'bogus_version') - - def test_validate_token(self): - self.assertRaises(token.provider.UnsupportedTokenVersionException, - self.token_provider_api.validate_token, - uuid.uuid4().hex, - None, - 'bogus_version') - - def test_token_format_provider_mismatch(self): - self.opt_in_group('signing', token_format='UUID') - self.opt_in_group('token', - provider=token.provider.PKI_PROVIDER) - try: - token.provider.Manager() - raise Exception( - 'expecting ValueError on token provider misconfiguration') - except exception.UnexpectedError: - pass - - self.opt_in_group('signing', token_format='PKI') - self.opt_in_group('token', - provider=token.provider.UUID_PROVIDER) - try: - token.provider.Manager() - raise Exception( - 'expecting ValueError on token provider misconfiguration') - except exception.UnexpectedError: - pass - - # should be OK as token_format and provider aligns - self.opt_in_group('signing', token_format='PKI') - self.opt_in_group('token', - provider=token.provider.PKI_PROVIDER) - token.provider.Manager() - - self.opt_in_group('signing', token_format='UUID') - self.opt_in_group('token', - provider=token.provider.UUID_PROVIDER) - token.provider.Manager() - - # custom provider should be OK too - self.opt_in_group('signing', token_format='CUSTOM') - self.opt_in_group('token', - provider=token.provider.PKI_PROVIDER) - token.provider.Manager() - - def test_default_token_format(self): - self.assertEqual(token.provider.Manager.get_token_provider(), - token.provider.PKI_PROVIDER) - - def test_uuid_token_format_and_no_provider(self): - self.opt_in_group('signing', token_format='UUID') - self.assertEqual(token.provider.Manager.get_token_provider(), - token.provider.UUID_PROVIDER) - - def test_unsupported_token_format(self): - self.opt_in_group('signing', token_format='CUSTOM') - self.assertRaises(exception.UnexpectedError, - token.provider.Manager.get_token_provider) - - def test_uuid_provider(self): - self.opt_in_group('token', provider=token.provider.UUID_PROVIDER) - self.assertEqual(token.provider.Manager.get_token_provider(), - token.provider.UUID_PROVIDER) - - def test_provider_override_token_format(self): - self.opt_in_group('token', - provider='keystone.token.providers.pki.Test') - self.assertEqual(token.provider.Manager.get_token_provider(), - 'keystone.token.providers.pki.Test') - - self.opt_in_group('signing', token_format='UUID') - self.opt_in_group('token', - provider=token.provider.UUID_PROVIDER) - self.assertEqual(token.provider.Manager.get_token_provider(), - token.provider.UUID_PROVIDER) - - self.opt_in_group('signing', token_format='PKI') - self.opt_in_group('token', - provider=token.provider.PKI_PROVIDER) - self.assertEqual(token.provider.Manager.get_token_provider(), - token.provider.PKI_PROVIDER) - - self.opt_in_group('signing', token_format='CUSTOM') - self.opt_in_group('token', - provider='my.package.MyProvider') - self.assertEqual(token.provider.Manager.get_token_provider(), - 'my.package.MyProvider') diff --git a/tests/test_url_middleware.py b/tests/test_url_middleware.py deleted file mode 100644 index 2a36e8c2..00000000 --- a/tests/test_url_middleware.py +++ /dev/null @@ -1,56 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 webob - -from keystone import test - -from keystone import middleware - - -class FakeApp(object): - """Fakes a WSGI app URL normalized.""" - def __call__(self, env, start_response): - resp = webob.Response() - resp.body = 'SUCCESS' - return resp(env, start_response) - - -class UrlMiddlewareTest(test.TestCase): - def setUp(self): - self.middleware = middleware.NormalizingFilter(FakeApp()) - self.response_status = None - self.response_headers = None - super(UrlMiddlewareTest, self).setUp() - - def start_fake_response(self, status, headers): - self.response_status = int(status.split(' ', 1)[0]) - self.response_headers = dict(headers) - - def test_trailing_slash_normalization(self): - """Tests /v2.0/tokens and /v2.0/tokens/ normalized URLs match.""" - req1 = webob.Request.blank('/v2.0/tokens') - req2 = webob.Request.blank('/v2.0/tokens/') - self.middleware(req1.environ, self.start_fake_response) - self.middleware(req2.environ, self.start_fake_response) - self.assertEqual(req1.path_url, req2.path_url) - self.assertEqual(req1.path_url, 'http://localhost/v2.0/tokens') - - def test_rewrite_empty_path(self): - """Tests empty path is rewritten to root.""" - req = webob.Request.blank('') - self.middleware(req.environ, self.start_fake_response) - self.assertEqual(req.path_url, 'http://localhost/') diff --git a/tests/test_utils.py b/tests/test_utils.py deleted file mode 100644 index 4a65bea1..00000000 --- a/tests/test_utils.py +++ /dev/null @@ -1,66 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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. - -# Copyright 2012 Justin Santa Barbara -# All Rights Reserved. -# -# 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 keystone import test - -from keystone.common import utils - - -class UtilsTestCase(test.TestCase): - def test_hash(self): - password = 'right' - wrong = 'wrongwrong' # Two wrongs don't make a right - hashed = utils.hash_password(password) - self.assertTrue(utils.check_password(password, hashed)) - self.assertFalse(utils.check_password(wrong, hashed)) - - def test_hash_long_password(self): - bigboy = '0' * 9999999 - hashed = utils.hash_password(bigboy) - self.assertTrue(utils.check_password(bigboy, hashed)) - - def test_hash_edge_cases(self): - hashed = utils.hash_password('secret') - self.assertFalse(utils.check_password('', hashed)) - self.assertFalse(utils.check_password(None, hashed)) - - def test_hash_unicode(self): - password = u'Comment \xe7a va' - wrong = 'Comment ?a va' - hashed = utils.hash_password(password) - self.assertTrue(utils.check_password(password, hashed)) - self.assertFalse(utils.check_password(wrong, hashed)) - - def test_auth_str_equal(self): - self.assertTrue(utils.auth_str_equal('abc123', 'abc123')) - self.assertFalse(utils.auth_str_equal('a', 'aaaaa')) - self.assertFalse(utils.auth_str_equal('aaaaa', 'a')) - self.assertFalse(utils.auth_str_equal('ABC123', 'abc123')) diff --git a/tests/test_uuid_token_provider.conf b/tests/test_uuid_token_provider.conf deleted file mode 100644 index d127ea3b..00000000 --- a/tests/test_uuid_token_provider.conf +++ /dev/null @@ -1,2 +0,0 @@ -[token] -provider = keystone.token.providers.uuid.Provider diff --git a/tests/test_v3.py b/tests/test_v3.py deleted file mode 100644 index 4f00de7d..00000000 --- a/tests/test_v3.py +++ /dev/null @@ -1,972 +0,0 @@ -import datetime -import uuid - -from lxml import etree -import webtest - -from keystone import test - -from keystone import auth -from keystone.common import serializer -from keystone import config -from keystone.openstack.common import timeutils -from keystone.policy.backends import rules - -import test_content_types - - -CONF = config.CONF -DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id - -TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ' - - -class RestfulTestCase(test_content_types.RestfulTestCase): - _config_file_list = [test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf'), - test.testsdir('backend_sql.conf'), - test.testsdir('backend_sql_disk.conf')] - - #override this to sepcify the complete list of configuration files - def config_files(self): - return self._config_file_list - - def setUp(self, load_sample_data=True): - """Setup for v3 Restful Test Cases. - - If a child class wants to create their own sample data - and provide their own auth data to obtain tokens, then - load_sample_data should be set to false. - - """ - self.config(self.config_files()) - - test.setup_test_database() - self.load_backends() - - self.public_app = webtest.TestApp( - self.loadapp('keystone', name='main')) - self.admin_app = webtest.TestApp( - self.loadapp('keystone', name='admin')) - - if load_sample_data: - self.domain_id = uuid.uuid4().hex - self.domain = self.new_domain_ref() - self.domain['id'] = self.domain_id - self.identity_api.create_domain(self.domain_id, self.domain) - - self.project_id = uuid.uuid4().hex - self.project = self.new_project_ref( - domain_id=self.domain_id) - self.project['id'] = self.project_id - self.identity_api.create_project(self.project_id, self.project) - - self.user_id = uuid.uuid4().hex - self.user = self.new_user_ref( - domain_id=self.domain_id, - project_id=self.project_id) - self.user['id'] = self.user_id - self.identity_api.create_user(self.user_id, self.user) - - self.default_domain_project_id = uuid.uuid4().hex - self.default_domain_project = self.new_project_ref( - domain_id=DEFAULT_DOMAIN_ID) - self.default_domain_project['id'] = self.default_domain_project_id - self.identity_api.create_project(self.default_domain_project_id, - self.default_domain_project) - - self.default_domain_user_id = uuid.uuid4().hex - self.default_domain_user = self.new_user_ref( - domain_id=DEFAULT_DOMAIN_ID, - project_id=self.default_domain_project_id) - self.default_domain_user['id'] = self.default_domain_user_id - self.identity_api.create_user(self.default_domain_user_id, - self.default_domain_user) - - # create & grant policy.json's default role for admin_required - self.role_id = uuid.uuid4().hex - self.role = self.new_role_ref() - self.role['id'] = self.role_id - self.role['name'] = 'admin' - self.identity_api.create_role(self.role_id, self.role) - self.identity_api.add_role_to_user_and_project( - self.user_id, self.project_id, self.role_id) - self.identity_api.add_role_to_user_and_project( - self.default_domain_user_id, self.default_domain_project_id, - self.role_id) - self.identity_api.add_role_to_user_and_project( - self.default_domain_user_id, self.project_id, - self.role_id) - - self.public_server = self.serveapp('keystone', name='main') - self.admin_server = self.serveapp('keystone', name='admin') - - def tearDown(self): - self.public_server.kill() - self.admin_server.kill() - self.public_server = None - self.admin_server = None - test.teardown_test_database() - # need to reset the plug-ins - auth.controllers.AUTH_METHODS = {} - #drop the policy rules - CONF.reset() - rules.reset() - - def new_ref(self): - """Populates a ref with attributes common to all API entities.""" - return { - 'id': uuid.uuid4().hex, - 'name': uuid.uuid4().hex, - 'description': uuid.uuid4().hex, - 'enabled': True} - - def new_service_ref(self): - ref = self.new_ref() - ref['type'] = uuid.uuid4().hex - return ref - - def new_endpoint_ref(self, service_id): - ref = self.new_ref() - ref['interface'] = uuid.uuid4().hex[:8] - ref['service_id'] = service_id - ref['url'] = uuid.uuid4().hex - ref['region'] = uuid.uuid4().hex - return ref - - def new_domain_ref(self): - ref = self.new_ref() - return ref - - def new_project_ref(self, domain_id): - ref = self.new_ref() - ref['domain_id'] = domain_id - return ref - - def new_user_ref(self, domain_id, project_id=None): - ref = self.new_ref() - ref['domain_id'] = domain_id - ref['email'] = uuid.uuid4().hex - ref['password'] = uuid.uuid4().hex - if project_id: - ref['project_id'] = project_id - return ref - - def new_group_ref(self, domain_id): - ref = self.new_ref() - ref['domain_id'] = domain_id - return ref - - def new_credential_ref(self, user_id, project_id=None): - ref = self.new_ref() - ref['user_id'] = user_id - ref['blob'] = uuid.uuid4().hex - ref['type'] = uuid.uuid4().hex - if project_id: - ref['project_id'] = project_id - return ref - - def new_role_ref(self): - ref = self.new_ref() - return ref - - def new_policy_ref(self): - ref = self.new_ref() - ref['blob'] = uuid.uuid4().hex - ref['type'] = uuid.uuid4().hex - return ref - - def new_trust_ref(self, trustor_user_id, trustee_user_id, project_id=None, - impersonation=None, expires=None, role_ids=None, - role_names=None): - ref = self.new_ref() - - ref['trustor_user_id'] = trustor_user_id - ref['trustee_user_id'] = trustee_user_id - ref['impersonation'] = impersonation or False - ref['project_id'] = project_id - - if isinstance(expires, basestring): - ref['expires_at'] = expires - elif isinstance(expires, dict): - ref['expires_at'] = timeutils.strtime( - timeutils.utcnow() + datetime.timedelta(**expires), - fmt=TIME_FORMAT) - elif expires is None: - pass - else: - raise NotImplementedError('Unexpected value for "expires"') - - role_ids = role_ids or [] - role_names = role_names or [] - if role_ids or role_names: - ref['roles'] = [] - for role_id in role_ids: - ref['roles'].append({'id': role_id}) - for role_name in role_names: - ref['roles'].append({'name': role_name}) - - return ref - - def admin_request(self, *args, **kwargs): - """Translates XML responses to dicts. - - This implies that we only have to write assertions for JSON. - - """ - r = super(RestfulTestCase, self).admin_request(*args, **kwargs) - if r.headers.get('Content-Type') == 'application/xml': - r.result = serializer.from_xml(etree.tostring(r.result)) - return r - - def get_scoped_token(self): - """Convenience method so that we can test authenticated requests.""" - r = self.admin_request( - method='POST', - path='/v3/auth/tokens', - body={ - 'auth': { - 'identity': { - 'methods': ['password'], - 'password': { - 'user': { - 'name': self.user['name'], - 'password': self.user['password'], - 'domain': { - 'id': self.user['domain_id'] - } - } - } - }, - 'scope': { - 'project': { - 'id': self.project['id'], - } - } - } - }) - return r.headers.get('X-Subject-Token') - - def get_requested_token(self, auth): - """Request the specific token we want.""" - - r = self.admin_request( - method='POST', - path='/v3/auth/tokens', - body=auth) - return r.headers.get('X-Subject-Token') - - def v3_request(self, path, **kwargs): - # Check if the caller has passed in auth details for - # use in requesting the token - auth = kwargs.pop('auth', None) - if auth: - token = self.get_requested_token(auth) - else: - token = kwargs.pop('token', None) - if not token: - token = self.get_scoped_token() - path = '/v3' + path - - return self.admin_request(path=path, token=token, **kwargs) - - def get(self, path, **kwargs): - r = self.v3_request(method='GET', path=path, **kwargs) - if 'expected_status' not in kwargs: - self.assertResponseStatus(r, 200) - return r - - def head(self, path, **kwargs): - r = self.v3_request(method='HEAD', path=path, **kwargs) - if 'expected_status' not in kwargs: - self.assertResponseStatus(r, 204) - return r - - def post(self, path, **kwargs): - r = self.v3_request(method='POST', path=path, **kwargs) - if 'expected_status' not in kwargs: - self.assertResponseStatus(r, 201) - return r - - def put(self, path, **kwargs): - r = self.v3_request(method='PUT', path=path, **kwargs) - if 'expected_status' not in kwargs: - self.assertResponseStatus(r, 204) - return r - - def patch(self, path, **kwargs): - r = self.v3_request(method='PATCH', path=path, **kwargs) - if 'expected_status' not in kwargs: - self.assertResponseStatus(r, 200) - return r - - def delete(self, path, **kwargs): - r = self.v3_request(method='DELETE', path=path, **kwargs) - if 'expected_status' not in kwargs: - self.assertResponseStatus(r, 204) - return r - - def assertValidErrorResponse(self, r): - if r.headers.get('Content-Type') == 'application/xml': - resp = serializer.from_xml(etree.tostring(r.result)) - else: - resp = r.result - self.assertIsNotNone(resp.get('error')) - self.assertIsNotNone(resp['error'].get('code')) - self.assertIsNotNone(resp['error'].get('title')) - self.assertIsNotNone(resp['error'].get('message')) - self.assertEqual(int(resp['error']['code']), r.status_code) - - def assertValidListLinks(self, links): - self.assertIsNotNone(links) - self.assertIsNotNone(links.get('self')) - self.assertIn(CONF.public_endpoint % CONF, links['self']) - - self.assertIn('next', links) - if links['next'] is not None: - self.assertIn( - CONF.public_endpoint % CONF, - links['next']) - - self.assertIn('previous', links) - if links['previous'] is not None: - self.assertIn( - CONF.public_endpoint % CONF, - links['previous']) - - def assertValidListResponse(self, resp, key, entity_validator, ref=None, - expected_length=None, keys_to_check=None): - """Make assertions common to all API list responses. - - If a reference is provided, it's ID will be searched for in the - response, and asserted to be equal. - - """ - entities = resp.result.get(key) - self.assertIsNotNone(entities) - - if expected_length is not None: - self.assertEqual(len(entities), expected_length) - elif ref is not None: - # we're at least expecting the ref - self.assertNotEmpty(entities) - - # collections should have relational links - self.assertValidListLinks(resp.result.get('links')) - - for entity in entities: - self.assertIsNotNone(entity) - self.assertValidEntity(entity, keys_to_check=keys_to_check) - entity_validator(entity) - if ref: - entity = [x for x in entities if x['id'] == ref['id']][0] - self.assertValidEntity(entity, ref=ref, - keys_to_check=keys_to_check) - entity_validator(entity, ref) - return entities - - def assertValidResponse(self, resp, key, entity_validator, *args, - **kwargs): - """Make assertions common to all API responses.""" - entity = resp.result.get(key) - self.assertIsNotNone(entity) - keys = kwargs.pop('keys_to_check', None) - self.assertValidEntity(entity, keys_to_check=keys, *args, **kwargs) - entity_validator(entity, *args, **kwargs) - return entity - - def assertValidEntity(self, entity, ref=None, keys_to_check=None): - """Make assertions common to all API entities. - - If a reference is provided, the entity will also be compared against - the reference. - """ - if keys_to_check: - keys = keys_to_check - else: - keys = ['name', 'description', 'enabled'] - - for k in ['id'] + keys: - msg = '%s unexpectedly None in %s' % (k, entity) - self.assertIsNotNone(entity.get(k), msg) - - self.assertIsNotNone(entity.get('links')) - self.assertIsNotNone(entity['links'].get('self')) - self.assertIn(CONF.public_endpoint % CONF, entity['links']['self']) - self.assertIn(entity['id'], entity['links']['self']) - - if ref: - for k in keys: - msg = '%s not equal: %s != %s' % (k, ref[k], entity[k]) - self.assertEquals(ref[k], entity[k]) - - return entity - - # auth validation - - def assertValidISO8601ExtendedFormatDatetime(self, dt): - try: - return timeutils.parse_strtime(dt, fmt=TIME_FORMAT) - except Exception: - msg = '%s is not a valid ISO 8601 extended format date time.' % dt - raise AssertionError(msg) - self.assertTrue(isinstance(dt, datetime.datetime)) - - def assertValidTokenResponse(self, r, user=None): - self.assertTrue(r.headers.get('X-Subject-Token')) - token = r.result['token'] - - self.assertIsNotNone(token.get('expires_at')) - expires_at = self.assertValidISO8601ExtendedFormatDatetime( - token['expires_at']) - self.assertIsNotNone(token.get('issued_at')) - issued_at = self.assertValidISO8601ExtendedFormatDatetime( - token['issued_at']) - self.assertTrue(issued_at < expires_at) - - self.assertIn('user', token) - self.assertIn('id', token['user']) - self.assertIn('name', token['user']) - self.assertIn('domain', token['user']) - self.assertIn('id', token['user']['domain']) - - if user is not None: - self.assertEqual(user['id'], token['user']['id']) - self.assertEqual(user['name'], token['user']['name']) - self.assertEqual(user['domain_id'], token['user']['domain']['id']) - - return token - - def assertValidUnscopedTokenResponse(self, r, *args, **kwargs): - token = self.assertValidTokenResponse(r, *args, **kwargs) - - self.assertNotIn('roles', token) - self.assertNotIn('catalog', token) - self.assertNotIn('project', token) - self.assertNotIn('domain', token) - - return token - - def assertValidScopedTokenResponse(self, r, *args, **kwargs): - require_catalog = kwargs.pop('require_catalog', True) - token = self.assertValidTokenResponse(r, *args, **kwargs) - - if require_catalog: - self.assertIn('catalog', token) - else: - self.assertNotIn('catalog', token) - - self.assertIn('roles', token) - self.assertTrue(token['roles']) - for role in token['roles']: - self.assertIn('id', role) - self.assertIn('name', role) - - return token - - def assertValidProjectScopedTokenResponse(self, r, *args, **kwargs): - token = self.assertValidScopedTokenResponse(r, *args, **kwargs) - - self.assertIn('project', token) - self.assertIn('id', token['project']) - self.assertIn('name', token['project']) - self.assertIn('domain', token['project']) - self.assertIn('id', token['project']['domain']) - self.assertIn('name', token['project']['domain']) - - self.assertEqual(self.role_id, token['roles'][0]['id']) - - return token - - def assertValidProjectTrustScopedTokenResponse(self, r, *args, **kwargs): - token = self.assertValidProjectScopedTokenResponse(r, *args, **kwargs) - - trust = token.get('OS-TRUST:trust') - self.assertIsNotNone(trust) - self.assertIsNotNone(trust.get('id')) - self.assertTrue(isinstance(trust.get('impersonation'), bool)) - self.assertIsNotNone(trust.get('trustor_user')) - self.assertIsNotNone(trust.get('trustee_user')) - self.assertIsNotNone(trust['trustor_user'].get('id')) - self.assertIsNotNone(trust['trustee_user'].get('id')) - - def assertValidDomainScopedTokenResponse(self, r, *args, **kwargs): - token = self.assertValidScopedTokenResponse(r, *args, **kwargs) - - self.assertIn('domain', token) - self.assertIn('id', token['domain']) - self.assertIn('name', token['domain']) - - return token - - def assertEqualTokens(self, a, b): - """Assert that two tokens are equal. - - Compare two tokens except for their ids. This also truncates - the time in the comparison. - """ - def normalize(token): - del token['token']['expires_at'] - del token['token']['issued_at'] - return token - - a_expires_at = self.assertValidISO8601ExtendedFormatDatetime( - a['token']['expires_at']) - b_expires_at = self.assertValidISO8601ExtendedFormatDatetime( - b['token']['expires_at']) - self.assertCloseEnoughForGovernmentWork(a_expires_at, b_expires_at) - - a_issued_at = self.assertValidISO8601ExtendedFormatDatetime( - a['token']['issued_at']) - b_issued_at = self.assertValidISO8601ExtendedFormatDatetime( - b['token']['issued_at']) - self.assertCloseEnoughForGovernmentWork(a_issued_at, b_issued_at) - - return self.assertDictEqual(normalize(a), normalize(b)) - - # service validation - - def assertValidServiceListResponse(self, resp, *args, **kwargs): - return self.assertValidListResponse( - resp, - 'services', - self.assertValidService, - *args, - **kwargs) - - def assertValidServiceResponse(self, resp, *args, **kwargs): - return self.assertValidResponse( - resp, - 'service', - self.assertValidService, - *args, - **kwargs) - - def assertValidService(self, entity, ref=None): - self.assertIsNotNone(entity.get('type')) - if ref: - self.assertEqual(ref['type'], entity['type']) - return entity - - # endpoint validation - - def assertValidEndpointListResponse(self, resp, *args, **kwargs): - return self.assertValidListResponse( - resp, - 'endpoints', - self.assertValidEndpoint, - *args, - **kwargs) - - def assertValidEndpointResponse(self, resp, *args, **kwargs): - return self.assertValidResponse( - resp, - 'endpoint', - self.assertValidEndpoint, - *args, - **kwargs) - - def assertValidEndpoint(self, entity, ref=None): - self.assertIsNotNone(entity.get('interface')) - self.assertIsNotNone(entity.get('service_id')) - - # this is intended to be an unexposed implementation detail - self.assertNotIn('legacy_endpoint_id', entity) - - if ref: - self.assertEqual(ref['interface'], entity['interface']) - self.assertEqual(ref['service_id'], entity['service_id']) - return entity - - # domain validation - - def assertValidDomainListResponse(self, resp, *args, **kwargs): - return self.assertValidListResponse( - resp, - 'domains', - self.assertValidDomain, - *args, - **kwargs) - - def assertValidDomainResponse(self, resp, *args, **kwargs): - return self.assertValidResponse( - resp, - 'domain', - self.assertValidDomain, - *args, - **kwargs) - - def assertValidDomain(self, entity, ref=None): - if ref: - pass - return entity - - # project validation - - def assertValidProjectListResponse(self, resp, *args, **kwargs): - return self.assertValidListResponse( - resp, - 'projects', - self.assertValidProject, - *args, - **kwargs) - - def assertValidProjectResponse(self, resp, *args, **kwargs): - return self.assertValidResponse( - resp, - 'project', - self.assertValidProject, - *args, - **kwargs) - - def assertValidProject(self, entity, ref=None): - self.assertIsNotNone(entity.get('domain_id')) - if ref: - self.assertEqual(ref['domain_id'], entity['domain_id']) - return entity - - # user validation - - def assertValidUserListResponse(self, resp, *args, **kwargs): - return self.assertValidListResponse( - resp, - 'users', - self.assertValidUser, - *args, - **kwargs) - - def assertValidUserResponse(self, resp, *args, **kwargs): - return self.assertValidResponse( - resp, - 'user', - self.assertValidUser, - *args, - **kwargs) - - def assertValidUser(self, entity, ref=None): - self.assertIsNotNone(entity.get('domain_id')) - self.assertIsNotNone(entity.get('email')) - self.assertIsNone(entity.get('password')) - if ref: - self.assertEqual(ref['domain_id'], entity['domain_id']) - self.assertEqual(ref['email'], entity['email']) - return entity - - # group validation - - def assertValidGroupListResponse(self, resp, *args, **kwargs): - return self.assertValidListResponse( - resp, - 'groups', - self.assertValidGroup, - *args, - **kwargs) - - def assertValidGroupResponse(self, resp, *args, **kwargs): - return self.assertValidResponse( - resp, - 'group', - self.assertValidGroup, - *args, - **kwargs) - - def assertValidGroup(self, entity, ref=None): - self.assertIsNotNone(entity.get('name')) - if ref: - self.assertEqual(ref['name'], entity['name']) - return entity - - # credential validation - - def assertValidCredentialListResponse(self, resp, *args, **kwargs): - return self.assertValidListResponse( - resp, - 'credentials', - self.assertValidCredential, - *args, - **kwargs) - - def assertValidCredentialResponse(self, resp, *args, **kwargs): - return self.assertValidResponse( - resp, - 'credential', - self.assertValidCredential, - *args, - **kwargs) - - def assertValidCredential(self, entity, ref=None): - self.assertIsNotNone(entity.get('user_id')) - self.assertIsNotNone(entity.get('blob')) - self.assertIsNotNone(entity.get('type')) - if ref: - self.assertEqual(ref['user_id'], entity['user_id']) - self.assertEqual(ref['blob'], entity['blob']) - self.assertEqual(ref['type'], entity['type']) - self.assertEqual(ref.get('project_id'), entity.get('project_id')) - return entity - - # role validation - - def assertValidRoleListResponse(self, resp, *args, **kwargs): - return self.assertValidListResponse( - resp, - 'roles', - self.assertValidRole, - keys_to_check=['name'], - *args, - **kwargs) - - def assertValidRoleResponse(self, resp, *args, **kwargs): - return self.assertValidResponse( - resp, - 'role', - self.assertValidRole, - keys_to_check=['name'], - *args, - **kwargs) - - def assertValidRole(self, entity, ref=None): - self.assertIsNotNone(entity.get('name')) - if ref: - self.assertEqual(ref['name'], entity['name']) - return entity - - def assertValidRoleAssignmentListResponse(self, resp, ref=None, - expected_length=None): - - entities = resp.result.get('role_assignments') - - if expected_length is not None: - self.assertEqual(len(entities), expected_length) - elif ref is not None: - # we're at least expecting the ref - self.assertNotEmpty(entities) - - # collections should have relational links - self.assertValidListLinks(resp.result.get('links')) - - for entity in entities: - self.assertIsNotNone(entity) - self.assertValidRoleAssignment(entity) - if ref: - self.assertValidRoleAssignment(entity, ref) - return entities - - def assertValidRoleAssignment(self, entity, ref=None, url=None): - self.assertIsNotNone(entity.get('role')) - self.assertIsNotNone(entity.get('scope')) - - # Only one of user or group should be present - self.assertIsNotNone(entity.get('user') or - entity.get('group')) - self.assertIsNone(entity.get('user') and - entity.get('group')) - - # Only one of domain or project should be present - self.assertIsNotNone(entity['scope'].get('project') or - entity['scope'].get('domain')) - self.assertIsNone(entity['scope'].get('project') and - entity['scope'].get('domain')) - - if entity['scope'].get('project'): - self.assertIsNotNone(entity['scope']['project'].get('id')) - else: - self.assertIsNotNone(entity['scope']['domain'].get('id')) - self.assertIsNotNone(entity.get('links')) - self.assertIsNotNone(entity['links'].get('assignment')) - - if ref: - if ref.get('user'): - self.assertEqual(ref['user']['id'], entity['user']['id']) - if ref.get('group'): - self.assertEqual(ref['group']['id'], entity['group']['id']) - if ref.get('role'): - self.assertEqual(ref['role']['id'], entity['role']['id']) - if ref['scope'].get('project'): - self.assertEqual(ref['scope']['project']['id'], - entity['scope']['project']['id']) - if ref['scope'].get('domain'): - self.assertEqual(ref['scope']['domain']['id'], - entity['scope']['domain']['id']) - if url: - self.assertIn(url, entity['links']['assignment']) - - def assertRoleAssignmentInListResponse( - self, resp, ref, link_url=None, expected=1): - - found_count = 0 - for entity in resp.result.get('role_assignments'): - try: - self.assertValidRoleAssignment( - entity, ref=ref, url=link_url) - except Exception: - # It doesn't match, so let's go onto the next one - pass - else: - found_count += 1 - self.assertEqual(found_count, expected) - - def assertRoleAssignmentNotInListResponse( - self, resp, ref, link_url=None): - - self.assertRoleAssignmentInListResponse( - resp, ref=ref, link_url=link_url, expected=0) - - # policy validation - - def assertValidPolicyListResponse(self, resp, *args, **kwargs): - return self.assertValidListResponse( - resp, - 'policies', - self.assertValidPolicy, - *args, - **kwargs) - - def assertValidPolicyResponse(self, resp, *args, **kwargs): - return self.assertValidResponse( - resp, - 'policy', - self.assertValidPolicy, - *args, - **kwargs) - - def assertValidPolicy(self, entity, ref=None): - self.assertIsNotNone(entity.get('blob')) - self.assertIsNotNone(entity.get('type')) - if ref: - self.assertEqual(ref['blob'], entity['blob']) - self.assertEqual(ref['type'], entity['type']) - return entity - - # trust validation - - def assertValidTrustListResponse(self, resp, *args, **kwargs): - return self.assertValidListResponse( - resp, - 'trusts', - self.assertValidTrust, - *args, - **kwargs) - - def assertValidTrustResponse(self, resp, *args, **kwargs): - return self.assertValidResponse( - resp, - 'trust', - self.assertValidTrust, - *args, - **kwargs) - - def assertValidTrust(self, entity, ref=None): - self.assertIsNotNone(entity.get('trustor_user_id')) - self.assertIsNotNone(entity.get('trustee_user_id')) - - self.assertIn('expires_at', entity) - if entity['expires_at'] is not None: - self.assertValidISO8601ExtendedFormatDatetime(entity['expires_at']) - - # always disallow project xor project_id (neither or both is allowed) - has_roles = bool(entity.get('roles')) - has_project = bool(entity.get('project_id')) - self.assertFalse(has_roles ^ has_project) - - for role in entity['roles']: - self.assertIsNotNone(role) - self.assertValidEntity(role) - self.assertValidRole(role) - - self.assertValidListLinks(entity.get('roles_links')) - - # these were used during dev and shouldn't land in final impl - self.assertNotIn('role_ids', entity) - self.assertNotIn('role_names', entity) - - if ref: - self.assertEqual(ref['trustor_user_id'], entity['trustor_user_id']) - self.assertEqual(ref['trustee_user_id'], entity['trustee_user_id']) - self.assertEqual(ref['project_id'], entity['project_id']) - if entity.get('expires_at') or ref.get('expires_at'): - entity_exp = self.assertValidISO8601ExtendedFormatDatetime( - entity['expires_at']) - ref_exp = self.assertValidISO8601ExtendedFormatDatetime( - ref['expires_at']) - self.assertCloseEnoughForGovernmentWork(entity_exp, ref_exp) - else: - self.assertEqual(ref.get('expires_at'), - entity.get('expires_at')) - - return entity - - def build_auth_scope(self, project_id=None, project_name=None, - project_domain_id=None, project_domain_name=None, - domain_id=None, domain_name=None, trust_id=None): - scope_data = {} - if project_id or project_name: - scope_data['project'] = {} - if project_id: - scope_data['project']['id'] = project_id - else: - scope_data['project']['name'] = project_name - if project_domain_id or project_domain_name: - project_domain_json = {} - if project_domain_id: - project_domain_json['id'] = project_domain_id - else: - project_domain_json['name'] = project_domain_name - scope_data['project']['domain'] = project_domain_json - if domain_id or domain_name: - scope_data['domain'] = {} - if domain_id: - scope_data['domain']['id'] = domain_id - else: - scope_data['domain']['name'] = domain_name - if trust_id: - scope_data['OS-TRUST:trust'] = {} - scope_data['OS-TRUST:trust']['id'] = trust_id - return scope_data - - def build_password_auth(self, user_id=None, username=None, - user_domain_id=None, user_domain_name=None, - password=None): - password_data = {'user': {}} - if user_id: - password_data['user']['id'] = user_id - else: - password_data['user']['name'] = username - if user_domain_id or user_domain_name: - password_data['user']['domain'] = {} - if user_domain_id: - password_data['user']['domain']['id'] = user_domain_id - else: - password_data['user']['domain']['name'] = user_domain_name - password_data['user']['password'] = password - return password_data - - def build_token_auth(self, token): - return {'id': token} - - def build_authentication_request(self, token=None, user_id=None, - username=None, user_domain_id=None, - user_domain_name=None, password=None, - **kwargs): - """Build auth dictionary. - - It will create an auth dictionary based on all the arguments - that it receives. - """ - auth_data = {} - auth_data['identity'] = {'methods': []} - if token: - auth_data['identity']['methods'].append('token') - auth_data['identity']['token'] = self.build_token_auth(token) - if user_id or username: - auth_data['identity']['methods'].append('password') - auth_data['identity']['password'] = self.build_password_auth( - user_id, username, user_domain_id, user_domain_name, password) - if kwargs: - auth_data['scope'] = self.build_auth_scope(**kwargs) - return {'auth': auth_data} - - -class VersionTestCase(RestfulTestCase): - def test_get_version(self): - pass diff --git a/tests/test_v3_auth.py b/tests/test_v3_auth.py deleted file mode 100644 index 11d66700..00000000 --- a/tests/test_v3_auth.py +++ /dev/null @@ -1,1860 +0,0 @@ -# Copyright 2012 OpenStack 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 json -import uuid - -from keystone import auth -from keystone.common import cms -from keystone import config -from keystone import exception -from keystone import test - -import test_v3 - - -CONF = config.CONF - - -class TestAuthInfo(test_v3.RestfulTestCase): - # TDOD(henry-nash) These tests are somewhat inefficient, since by - # using the test_v3.RestfulTestCase class to gain access to the auth - # building helper functions, they cause backend databases and fixtures - # to be loaded unnecessarily. Separating out the helper functions from - # this base class would improve efficiency (Bug #1134836) - def setUp(self, load_sample_data=False): - super(TestAuthInfo, self).setUp(load_sample_data=load_sample_data) - - def test_missing_auth_methods(self): - auth_data = {'identity': {}} - auth_data['identity']['token'] = {'id': uuid.uuid4().hex} - self.assertRaises(exception.ValidationError, - auth.controllers.AuthInfo, - None, - auth_data) - - def test_unsupported_auth_method(self): - auth_data = {'methods': ['abc']} - auth_data['abc'] = {'test': 'test'} - auth_data = {'identity': auth_data} - self.assertRaises(exception.AuthMethodNotSupported, - auth.controllers.AuthInfo, - None, - auth_data) - - def test_missing_auth_method_data(self): - auth_data = {'methods': ['password']} - auth_data = {'identity': auth_data} - self.assertRaises(exception.ValidationError, - auth.controllers.AuthInfo, - None, - auth_data) - - def test_project_name_no_domain(self): - auth_data = self.build_authentication_request( - username='test', - password='test', - project_name='abc')['auth'] - self.assertRaises(exception.ValidationError, - auth.controllers.AuthInfo, - None, - auth_data) - - def test_both_project_and_domain_in_scope(self): - auth_data = self.build_authentication_request( - user_id='test', - password='test', - project_name='test', - domain_name='test')['auth'] - self.assertRaises(exception.ValidationError, - auth.controllers.AuthInfo, - None, - auth_data) - - def test_get_method_data_invalid_method(self): - auth_data = self.build_authentication_request( - user_id='test', - password='test')['auth'] - context = None - auth_info = auth.controllers.AuthInfo(context, auth_data) - - method_name = uuid.uuid4().hex - self.assertRaises(exception.ValidationError, - auth_info.get_method_data, - method_name) - - -class TestPKITokenAPIs(test_v3.RestfulTestCase): - def config_files(self): - conf_files = super(TestPKITokenAPIs, self).config_files() - conf_files.append(test.testsdir('test_pki_token_provider.conf')) - return conf_files - - def setUp(self): - super(TestPKITokenAPIs, self).setUp() - auth_data = self.build_authentication_request( - username=self.user['name'], - user_domain_id=self.domain_id, - password=self.user['password']) - resp = self.post('/auth/tokens', body=auth_data) - self.token_data = resp.result - self.token = resp.headers.get('X-Subject-Token') - self.headers = {'X-Subject-Token': resp.headers.get('X-Subject-Token')} - - def test_default_fixture_scope_token(self): - self.assertIsNotNone(self.get_scoped_token()) - - def test_v3_token_id(self): - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password']) - resp = self.post('/auth/tokens', body=auth_data) - token_data = resp.result - token_id = resp.headers.get('X-Subject-Token') - self.assertIn('expires_at', token_data['token']) - - expected_token_id = cms.cms_sign_token(json.dumps(token_data), - CONF.signing.certfile, - CONF.signing.keyfile) - self.assertEqual(expected_token_id, token_id) - # should be able to validate hash PKI token as well - hash_token_id = cms.cms_hash_token(token_id) - headers = {'X-Subject-Token': hash_token_id} - resp = self.get('/auth/tokens', headers=headers) - expected_token_data = resp.result - self.assertDictEqual(expected_token_data, token_data) - - def test_v3_v2_intermix_non_default_domain_failed(self): - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password']) - resp = self.post('/auth/tokens', body=auth_data) - token = resp.headers.get('X-Subject-Token') - - # now validate the v3 token with v2 API - path = '/v2.0/tokens/%s' % (token) - resp = self.admin_request(path=path, - token='ADMIN', - method='GET', - expected_status=401) - - def test_v3_v2_intermix_domain_scoped_token_failed(self): - # grant the domain role to user - path = '/domains/%s/users/%s/roles/%s' % ( - self.domain['id'], self.user['id'], self.role['id']) - self.put(path=path) - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password'], - domain_id=self.domain['id']) - resp = self.post('/auth/tokens', body=auth_data) - token = resp.headers.get('X-Subject-Token') - - # now validate the v3 token with v2 API - path = '/v2.0/tokens/%s' % (token) - resp = self.admin_request(path=path, - token='ADMIN', - method='GET', - expected_status=401) - - def test_v3_v2_intermix_non_default_project_failed(self): - auth_data = self.build_authentication_request( - user_id=self.default_domain_user['id'], - password=self.default_domain_user['password'], - project_id=self.project['id']) - resp = self.post('/auth/tokens', body=auth_data) - token = resp.headers.get('X-Subject-Token') - - # now validate the v3 token with v2 API - path = '/v2.0/tokens/%s' % (token) - resp = self.admin_request(path=path, - token='ADMIN', - method='GET', - expected_status=401) - - def test_v3_v2_unscoped_token_intermix(self): - auth_data = self.build_authentication_request( - user_id=self.default_domain_user['id'], - password=self.default_domain_user['password']) - resp = self.post('/auth/tokens', body=auth_data) - token_data = resp.result - token = resp.headers.get('X-Subject-Token') - - # now validate the v3 token with v2 API - path = '/v2.0/tokens/%s' % (token) - resp = self.admin_request(path=path, - token='ADMIN', - method='GET') - v2_token = resp.result - self.assertEqual(v2_token['access']['user']['id'], - token_data['token']['user']['id']) - # v2 token time has not fraction of second precision so - # just need to make sure the non fraction part agrees - self.assertIn(v2_token['access']['token']['expires'][:-1], - token_data['token']['expires_at']) - - def test_v3_v2_token_intermix(self): - # FIXME(gyee): PKI tokens are not interchangeable because token - # data is baked into the token itself. - auth_data = self.build_authentication_request( - user_id=self.default_domain_user['id'], - password=self.default_domain_user['password'], - project_id=self.default_domain_project['id']) - resp = self.post('/auth/tokens', body=auth_data) - token_data = resp.result - token = resp.headers.get('X-Subject-Token') - - # now validate the v3 token with v2 API - path = '/v2.0/tokens/%s' % (token) - resp = self.admin_request(path=path, - token='ADMIN', - method='GET') - v2_token = resp.result - self.assertEqual(v2_token['access']['user']['id'], - token_data['token']['user']['id']) - # v2 token time has not fraction of second precision so - # just need to make sure the non fraction part agrees - self.assertIn(v2_token['access']['token']['expires'][:-1], - token_data['token']['expires_at']) - self.assertEqual(v2_token['access']['user']['roles'][0]['id'], - token_data['token']['roles'][0]['id']) - - def test_v3_v2_hashed_pki_token_intermix(self): - auth_data = self.build_authentication_request( - user_id=self.default_domain_user['id'], - password=self.default_domain_user['password'], - project_id=self.default_domain_project['id']) - resp = self.post('/auth/tokens', body=auth_data) - token_data = resp.result - token = resp.headers.get('X-Subject-Token') - - # should be able to validate a hash PKI token in v2 too - token = cms.cms_hash_token(token) - path = '/v2.0/tokens/%s' % (token) - resp = self.admin_request(path=path, - token='ADMIN', - method='GET') - v2_token = resp.result - self.assertEqual(v2_token['access']['user']['id'], - token_data['token']['user']['id']) - # v2 token time has not fraction of second precision so - # just need to make sure the non fraction part agrees - self.assertIn(v2_token['access']['token']['expires'][:-1], - token_data['token']['expires_at']) - self.assertEqual(v2_token['access']['user']['roles'][0]['id'], - token_data['token']['roles'][0]['id']) - - def test_v2_v3_unscoped_token_intermix(self): - body = { - 'auth': { - 'passwordCredentials': { - 'userId': self.user['id'], - 'password': self.user['password'] - } - }} - resp = self.admin_request(path='/v2.0/tokens', - method='POST', - body=body) - v2_token_data = resp.result - v2_token = v2_token_data['access']['token']['id'] - headers = {'X-Subject-Token': v2_token} - resp = self.get('/auth/tokens', headers=headers) - token_data = resp.result - self.assertEqual(v2_token_data['access']['user']['id'], - token_data['token']['user']['id']) - # v2 token time has not fraction of second precision so - # just need to make sure the non fraction part agrees - self.assertIn(v2_token_data['access']['token']['expires'][-1], - token_data['token']['expires_at']) - - def test_v2_v3_token_intermix(self): - body = { - 'auth': { - 'passwordCredentials': { - 'userId': self.user['id'], - 'password': self.user['password'] - }, - 'tenantId': self.project['id'] - }} - resp = self.admin_request(path='/v2.0/tokens', - method='POST', - body=body) - v2_token_data = resp.result - v2_token = v2_token_data['access']['token']['id'] - headers = {'X-Subject-Token': v2_token} - resp = self.get('/auth/tokens', headers=headers) - token_data = resp.result - self.assertEqual(v2_token_data['access']['user']['id'], - token_data['token']['user']['id']) - # v2 token time has not fraction of second precision so - # just need to make sure the non fraction part agrees - self.assertIn(v2_token_data['access']['token']['expires'][-1], - token_data['token']['expires_at']) - self.assertEqual(v2_token_data['access']['user']['roles'][0]['name'], - token_data['token']['roles'][0]['name']) - - def test_rescoping_token(self): - expires = self.token_data['token']['expires_at'] - auth_data = self.build_authentication_request( - token=self.token, - project_id=self.project_id) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidProjectScopedTokenResponse(r) - # make sure expires stayed the same - self.assertEqual(expires, r.result['token']['expires_at']) - - def test_check_token(self): - self.head('/auth/tokens', headers=self.headers, expected_status=204) - - def test_validate_token(self): - r = self.get('/auth/tokens', headers=self.headers) - self.assertValidUnscopedTokenResponse(r) - - def test_revoke_token(self): - headers = {'X-Subject-Token': self.get_scoped_token()} - self.delete('/auth/tokens', headers=headers, expected_status=204) - self.head('/auth/tokens', headers=headers, expected_status=401) - - # make sure we have a CRL - r = self.get('/auth/tokens/OS-PKI/revoked') - self.assertIn('signed', r.result) - - -class TestUUIDTokenAPIs(TestPKITokenAPIs): - def config_files(self): - conf_files = super(TestUUIDTokenAPIs, self).config_files() - conf_files.append(test.testsdir('test_uuid_token_provider.conf')) - return conf_files - - def test_v3_token_id(self): - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password']) - resp = self.post('/auth/tokens', body=auth_data) - token_data = resp.result - token_id = resp.headers.get('X-Subject-Token') - self.assertIn('expires_at', token_data['token']) - self.assertFalse(cms.is_ans1_token(token_id)) - - def test_v3_v2_hashed_pki_token_intermix(self): - # this test is only applicable for PKI tokens - # skipping it for UUID tokens - pass - - -class TestTokenRevoking(test_v3.RestfulTestCase): - """Test token revocation on the v3 Identity API.""" - - def setUp(self): - """Setup for Token Revoking Test Cases. - - As well as the usual housekeeping, create a set of domains, - users, groups, roles and projects for the subsequent tests: - - - Two domains: A & B - - DomainA has user1, domainB has user2 and user3 - - DomainA has group1 and group2, domainB has group3 - - User1 has a role on domainA - - Two projects: A & B, both in domainA - - All users have a role on projectA - - Two groups: 1 & 2 - - User1 and user2 are members of group1 - - User3 is a member of group2 - - """ - super(TestTokenRevoking, self).setUp() - - # Start by creating a couple of domains and projects - self.domainA = self.new_domain_ref() - self.identity_api.create_domain(self.domainA['id'], self.domainA) - self.domainB = self.new_domain_ref() - self.identity_api.create_domain(self.domainB['id'], self.domainB) - self.projectA = self.new_project_ref(domain_id=self.domainA['id']) - self.identity_api.create_project(self.projectA['id'], self.projectA) - self.projectB = self.new_project_ref(domain_id=self.domainA['id']) - self.identity_api.create_project(self.projectB['id'], self.projectB) - - # Now create some users, one in domainA and two of them in domainB - self.user1 = self.new_user_ref( - domain_id=self.domainA['id']) - self.user1['password'] = uuid.uuid4().hex - self.identity_api.create_user(self.user1['id'], self.user1) - - self.user2 = self.new_user_ref( - domain_id=self.domainB['id']) - self.user2['password'] = uuid.uuid4().hex - self.identity_api.create_user(self.user2['id'], self.user2) - - self.user3 = self.new_user_ref( - domain_id=self.domainB['id']) - self.user3['password'] = uuid.uuid4().hex - self.identity_api.create_user(self.user3['id'], self.user3) - - self.group1 = self.new_group_ref( - domain_id=self.domainA['id']) - self.identity_api.create_group(self.group1['id'], self.group1) - - self.group2 = self.new_group_ref( - domain_id=self.domainA['id']) - self.identity_api.create_group(self.group2['id'], self.group2) - - self.group3 = self.new_group_ref( - domain_id=self.domainB['id']) - self.identity_api.create_group(self.group3['id'], self.group3) - - self.identity_api.add_user_to_group(self.user1['id'], - self.group1['id']) - self.identity_api.add_user_to_group(self.user2['id'], - self.group1['id']) - self.identity_api.add_user_to_group(self.user3['id'], - self.group2['id']) - - self.role1 = self.new_role_ref() - self.identity_api.create_role(self.role1['id'], self.role1) - self.role2 = self.new_role_ref() - self.identity_api.create_role(self.role2['id'], self.role2) - - self.identity_api.create_grant(self.role1['id'], - user_id=self.user1['id'], - domain_id=self.domainA['id']) - self.identity_api.create_grant(self.role1['id'], - user_id=self.user1['id'], - project_id=self.projectA['id']) - self.identity_api.create_grant(self.role1['id'], - user_id=self.user2['id'], - project_id=self.projectA['id']) - self.identity_api.create_grant(self.role1['id'], - user_id=self.user3['id'], - project_id=self.projectA['id']) - self.identity_api.create_grant(self.role1['id'], - group_id=self.group1['id'], - project_id=self.projectA['id']) - - def test_unscoped_token_remains_valid_after_role_assignment(self): - r = self.post( - '/auth/tokens', - body=self.build_authentication_request( - user_id=self.user1['id'], - password=self.user1['password'])) - unscoped_token = r.headers.get('X-Subject-Token') - - r = self.post( - '/auth/tokens', - body=self.build_authentication_request( - token=unscoped_token, - project_id=self.projectA['id'])) - scoped_token = r.headers.get('X-Subject-Token') - - # confirm both tokens are valid - self.head('/auth/tokens', - headers={'X-Subject-Token': unscoped_token}, - expected_status=204) - self.head('/auth/tokens', - headers={'X-Subject-Token': scoped_token}, - expected_status=204) - - # create a new role - role = self.new_role_ref() - self.identity_api.create_role(role['id'], role) - - # assign a new role - self.put( - '/projects/%(project_id)s/users/%(user_id)s/roles/%(role_id)s' % { - 'project_id': self.projectA['id'], - 'user_id': self.user1['id'], - 'role_id': role['id']}) - - # both tokens should remain valid - self.head('/auth/tokens', - headers={'X-Subject-Token': unscoped_token}, - expected_status=204) - self.head('/auth/tokens', - headers={'X-Subject-Token': scoped_token}, - expected_status=204) - - def test_deleting_user_grant_revokes_token(self): - """Test deleting a user grant revokes token. - - Test Plan: - - Get a token for user1, scoped to ProjectA - - Delete the grant user1 has on ProjectA - - Check token is no longer valid - - """ - auth_data = self.build_authentication_request( - user_id=self.user1['id'], - password=self.user1['password'], - project_id=self.projectA['id']) - resp = self.post('/auth/tokens', body=auth_data) - token = resp.headers.get('X-Subject-Token') - # Confirm token is valid - self.head('/auth/tokens', - headers={'X-Subject-Token': token}, - expected_status=204) - # Delete the grant, which should invalidate the token - grant_url = ( - '/projects/%(project_id)s/users/%(user_id)s/' - 'roles/%(role_id)s' % { - 'project_id': self.projectA['id'], - 'user_id': self.user1['id'], - 'role_id': self.role1['id']}) - self.delete(grant_url) - self.head('/auth/tokens', - headers={'X-Subject-Token': token}, - expected_status=401) - - def test_domain_user_role_assignment_maintains_token(self): - """Test user-domain role assignment maintains existing token. - - Test Plan: - - Get a token for user1, scoped to ProjectA - - Create a grant for user1 on DomainB - - Check token is still valid - - """ - auth_data = self.build_authentication_request( - user_id=self.user1['id'], - password=self.user1['password'], - project_id=self.projectA['id']) - resp = self.post('/auth/tokens', body=auth_data) - token = resp.headers.get('X-Subject-Token') - # Confirm token is valid - self.head('/auth/tokens', - headers={'X-Subject-Token': token}, - expected_status=204) - # Assign a role, which should not affect the token - grant_url = ( - '/domains/%(domain_id)s/users/%(user_id)s/' - 'roles/%(role_id)s' % { - 'domain_id': self.domainB['id'], - 'user_id': self.user1['id'], - 'role_id': self.role1['id']}) - self.put(grant_url) - self.head('/auth/tokens', - headers={'X-Subject-Token': token}, - expected_status=204) - - def test_deleting_group_grant_revokes_tokens(self): - """Test deleting a group grant revokes tokens. - - Test Plan: - - Get a token for user1, scoped to ProjectA - - Get a token for user2, scoped to ProjectA - - Get a token for user3, scoped to ProjectA - - Delete the grant group1 has on ProjectA - - Check tokens for user1 & user2 are no longer valid, - since user1 and user2 are members of group1 - - Check token for user3 is still valid - - """ - auth_data = self.build_authentication_request( - user_id=self.user1['id'], - password=self.user1['password'], - project_id=self.projectA['id']) - resp = self.post('/auth/tokens', body=auth_data) - token1 = resp.headers.get('X-Subject-Token') - auth_data = self.build_authentication_request( - user_id=self.user2['id'], - password=self.user2['password'], - project_id=self.projectA['id']) - resp = self.post('/auth/tokens', body=auth_data) - token2 = resp.headers.get('X-Subject-Token') - auth_data = self.build_authentication_request( - user_id=self.user3['id'], - password=self.user3['password'], - project_id=self.projectA['id']) - resp = self.post('/auth/tokens', body=auth_data) - token3 = resp.headers.get('X-Subject-Token') - # Confirm tokens are valid - self.head('/auth/tokens', - headers={'X-Subject-Token': token1}, - expected_status=204) - self.head('/auth/tokens', - headers={'X-Subject-Token': token2}, - expected_status=204) - self.head('/auth/tokens', - headers={'X-Subject-Token': token3}, - expected_status=204) - # Delete the group grant, which should invalidate the - # tokens for user1 and user2 - grant_url = ( - '/projects/%(project_id)s/groups/%(group_id)s/' - 'roles/%(role_id)s' % { - 'project_id': self.projectA['id'], - 'group_id': self.group1['id'], - 'role_id': self.role1['id']}) - self.delete(grant_url) - self.head('/auth/tokens', - headers={'X-Subject-Token': token1}, - expected_status=401) - self.head('/auth/tokens', - headers={'X-Subject-Token': token2}, - expected_status=401) - # But user3's token should still be valid - self.head('/auth/tokens', - headers={'X-Subject-Token': token3}, - expected_status=204) - - def test_domain_group_role_assignment_maintains_token(self): - """Test domain-group role assignment maintains existing token. - - Test Plan: - - Get a token for user1, scoped to ProjectA - - Create a grant for group1 on DomainB - - Check token is still longer valid - - """ - auth_data = self.build_authentication_request( - user_id=self.user1['id'], - password=self.user1['password'], - project_id=self.projectA['id']) - resp = self.post('/auth/tokens', body=auth_data) - token = resp.headers.get('X-Subject-Token') - # Confirm token is valid - self.head('/auth/tokens', - headers={'X-Subject-Token': token}, - expected_status=204) - # Delete the grant, which should invalidate the token - grant_url = ( - '/domains/%(domain_id)s/groups/%(group_id)s/' - 'roles/%(role_id)s' % { - 'domain_id': self.domainB['id'], - 'group_id': self.group1['id'], - 'role_id': self.role1['id']}) - self.put(grant_url) - self.head('/auth/tokens', - headers={'X-Subject-Token': token}, - expected_status=204) - - def test_group_membership_changes_revokes_token(self): - """Test add/removal to/from group revokes token. - - Test Plan: - - Get a token for user1, scoped to ProjectA - - Get a token for user2, scoped to ProjectA - - Remove user1 from group1 - - Check token for user1 is no longer valid - - Check token for user2 is still valid, even though - user2 is also part of group1 - - Add user2 to group2 - - Check token for user2 is now no longer valid - - """ - auth_data = self.build_authentication_request( - user_id=self.user1['id'], - password=self.user1['password'], - project_id=self.projectA['id']) - resp = self.post('/auth/tokens', body=auth_data) - token1 = resp.headers.get('X-Subject-Token') - auth_data = self.build_authentication_request( - user_id=self.user2['id'], - password=self.user2['password'], - project_id=self.projectA['id']) - resp = self.post('/auth/tokens', body=auth_data) - token2 = resp.headers.get('X-Subject-Token') - # Confirm tokens are valid - self.head('/auth/tokens', - headers={'X-Subject-Token': token1}, - expected_status=204) - self.head('/auth/tokens', - headers={'X-Subject-Token': token2}, - expected_status=204) - # Remove user1 from group1, which should invalidate - # the token - self.delete('/groups/%(group_id)s/users/%(user_id)s' % { - 'group_id': self.group1['id'], - 'user_id': self.user1['id']}) - self.head('/auth/tokens', - headers={'X-Subject-Token': token1}, - expected_status=401) - # But user2's token should still be valid - self.head('/auth/tokens', - headers={'X-Subject-Token': token2}, - expected_status=204) - # Adding user2 to a group should invalidate token - self.put('/groups/%(group_id)s/users/%(user_id)s' % { - 'group_id': self.group2['id'], - 'user_id': self.user2['id']}) - self.head('/auth/tokens', - headers={'X-Subject-Token': token2}, - expected_status=401) - - def test_removing_role_assignment_does_not_affect_other_users(self): - """Revoking a role from one user should not affect other users.""" - r = self.post( - '/auth/tokens', - body=self.build_authentication_request( - user_id=self.user1['id'], - password=self.user1['password'], - project_id=self.projectA['id'])) - user1_token = r.headers.get('X-Subject-Token') - - r = self.post( - '/auth/tokens', - body=self.build_authentication_request( - user_id=self.user3['id'], - password=self.user3['password'], - project_id=self.projectA['id'])) - user3_token = r.headers.get('X-Subject-Token') - - # delete relationships between user1 and projectA from setUp - self.delete( - '/projects/%(project_id)s/users/%(user_id)s/roles/%(role_id)s' % { - 'project_id': self.projectA['id'], - 'user_id': self.user1['id'], - 'role_id': self.role1['id']}) - self.delete( - '/projects/%(project_id)s/groups/%(group_id)s/roles/%(role_id)s' % - {'project_id': self.projectA['id'], - 'group_id': self.group1['id'], - 'role_id': self.role1['id']}) - - # authorization for the first user should now fail - self.head('/auth/tokens', - headers={'X-Subject-Token': user1_token}, - expected_status=401) - self.post( - '/auth/tokens', - body=self.build_authentication_request( - user_id=self.user1['id'], - password=self.user1['password'], - project_id=self.projectA['id']), - expected_status=401) - - # authorization for the second user should still succeed - self.head('/auth/tokens', - headers={'X-Subject-Token': user3_token}, - expected_status=204) - self.post( - '/auth/tokens', - body=self.build_authentication_request( - user_id=self.user3['id'], - password=self.user3['password'], - project_id=self.projectA['id'])) - - -class TestAuthExternalDisabled(test_v3.RestfulTestCase): - def config_files(self): - list = self._config_file_list[:] - list.append('auth_plugin_external_disabled.conf') - return list - - def test_remote_user_disabled(self): - auth_data = self.build_authentication_request()['auth'] - api = auth.controllers.Auth() - context = {'REMOTE_USER': '%s@%s' % (self.user['name'], - self.domain['id'])} - auth_info = auth.controllers.AuthInfo(None, auth_data) - auth_context = {'extras': {}, 'method_names': []} - self.assertRaises(exception.Unauthorized, - api.authenticate, - context, - auth_info, - auth_context) - - -class TestAuthExternalDomain(test_v3.RestfulTestCase): - content_type = 'json' - - def config_files(self): - list = self._config_file_list[:] - list.append('auth_plugin_external_domain.conf') - return list - - def test_remote_user_with_realm(self): - auth_data = self.build_authentication_request()['auth'] - api = auth.controllers.Auth() - context = {'REMOTE_USER': '%s@%s' % - (self.user['name'], self.domain['name'])} - auth_info = auth.controllers.AuthInfo(None, auth_data) - auth_context = {'extras': {}, 'method_names': []} - api.authenticate(context, auth_info, auth_context) - self.assertEqual(auth_context['user_id'], self.user['id']) - - def test_project_id_scoped_with_remote_user(self): - CONF.token.bind = ['kerberos'] - auth_data = self.build_authentication_request( - project_id=self.project['id']) - remote_user = '%s@%s' % (self.user['name'], self.domain['name']) - self.admin_app.extra_environ.update({'REMOTE_USER': remote_user, - 'AUTH_TYPE': 'Negotiate'}) - r = self.post('/auth/tokens', body=auth_data) - token = self.assertValidProjectScopedTokenResponse(r) - self.assertEquals(token['bind']['kerberos'], self.user['name']) - - def test_unscoped_bind_with_remote_user(self): - CONF.token.bind = ['kerberos'] - auth_data = self.build_authentication_request() - remote_user = '%s@%s' % (self.user['name'], self.domain['name']) - self.admin_app.extra_environ.update({'REMOTE_USER': remote_user, - 'AUTH_TYPE': 'Negotiate'}) - r = self.post('/auth/tokens', body=auth_data) - token = self.assertValidUnscopedTokenResponse(r) - self.assertEquals(token['bind']['kerberos'], self.user['name']) - - -class TestAuthJSON(test_v3.RestfulTestCase): - content_type = 'json' - - def test_unscoped_token_with_user_id(self): - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidUnscopedTokenResponse(r) - - def test_unscoped_token_with_user_domain_id(self): - auth_data = self.build_authentication_request( - username=self.user['name'], - user_domain_id=self.domain['id'], - password=self.user['password']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidUnscopedTokenResponse(r) - - def test_unscoped_token_with_user_domain_name(self): - auth_data = self.build_authentication_request( - username=self.user['name'], - user_domain_name=self.domain['name'], - password=self.user['password']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidUnscopedTokenResponse(r) - - def test_project_id_scoped_token_with_user_id(self): - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password'], - project_id=self.project['id']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidProjectScopedTokenResponse(r) - - def test_default_project_id_scoped_token_with_user_id(self): - # create a second project to work with - ref = self.new_project_ref(domain_id=self.domain_id) - r = self.post('/projects', body={'project': ref}) - project = self.assertValidProjectResponse(r, ref) - - # grant the user a role on the project - self.put( - '/projects/%(project_id)s/users/%(user_id)s/roles/%(role_id)s' % { - 'user_id': self.user['id'], - 'project_id': project['id'], - 'role_id': self.role['id']}) - - # set the user's preferred project - body = {'user': {'default_project_id': project['id']}} - r = self.patch('/users/%(user_id)s' % { - 'user_id': self.user['id']}, - body=body) - self.assertValidUserResponse(r) - - # attempt to authenticate without requesting a project - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidProjectScopedTokenResponse(r) - self.assertEqual(r.result['token']['project']['id'], project['id']) - - def test_default_project_id_scoped_token_with_user_id_no_catalog(self): - # create a second project to work with - ref = self.new_project_ref(domain_id=self.domain_id) - r = self.post('/projects', body={'project': ref}) - project = self.assertValidProjectResponse(r, ref) - - # grant the user a role on the project - self.put( - '/projects/%(project_id)s/users/%(user_id)s/roles/%(role_id)s' % { - 'user_id': self.user['id'], - 'project_id': project['id'], - 'role_id': self.role['id']}) - - # set the user's preferred project - body = {'user': {'default_project_id': project['id']}} - r = self.patch('/users/%(user_id)s' % { - 'user_id': self.user['id']}, - body=body) - self.assertValidUserResponse(r) - - # attempt to authenticate without requesting a project - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password']) - r = self.post('/auth/tokens?nocatalog', body=auth_data) - self.assertValidProjectScopedTokenResponse(r, require_catalog=False) - self.assertEqual(r.result['token']['project']['id'], project['id']) - - def test_implicit_project_id_scoped_token_with_user_id_no_catalog(self): - # attempt to authenticate without requesting a project - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password'], - project_id=self.project['id']) - r = self.post('/auth/tokens?nocatalog', body=auth_data) - self.assertValidProjectScopedTokenResponse(r, require_catalog=False) - self.assertEqual(r.result['token']['project']['id'], - self.project['id']) - - def test_default_project_id_scoped_token_with_user_id_401(self): - # create a second project to work with - ref = self.new_project_ref(domain_id=self.domain['id']) - del ref['id'] - r = self.post('/projects', body={'project': ref}) - project = self.assertValidProjectResponse(r, ref) - - # set the user's preferred project without having authz on that project - body = {'user': {'default_project_id': project['id']}} - r = self.patch('/users/%(user_id)s' % { - 'user_id': self.user['id']}, - body=body) - self.assertValidUserResponse(r) - - # attempt to authenticate without requesting a project - # the default_project_id should be the assumed scope of the request, - # and fail because the user doesn't have explicit authz on that scope - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password']) - self.post('/auth/tokens', body=auth_data, expected_status=401) - - def test_project_id_scoped_token_with_user_id_401(self): - project_id = uuid.uuid4().hex - project = self.new_project_ref(domain_id=self.domain_id) - self.identity_api.create_project(project_id, project) - - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password'], - project_id=project['id']) - self.post('/auth/tokens', body=auth_data, expected_status=401) - - def test_user_and_group_roles_scoped_token(self): - """Test correct roles are returned in scoped token. - - Test Plan: - - Create a domain, with 1 project, 2 users (user1 and user2) - and 2 groups (group1 and group2) - - Make user1 a member of group1, user2 a member of group2 - - Create 8 roles, assigning them to each of the 8 combinations - of users/groups on domain/project - - Get a project scoped token for user1, checking that the right - two roles are returned (one directly assigned, one by virtue - of group membership) - - Repeat this for a domain scoped token - - Make user1 also a member of group2 - - Get another scoped token making sure the additional role - shows up - - User2 is just here as a spoiler, to make sure we don't get - any roles uniquely assigned to it returned in any of our - tokens - - """ - - domainA = self.new_domain_ref() - self.identity_api.create_domain(domainA['id'], domainA) - projectA = self.new_project_ref(domain_id=domainA['id']) - self.identity_api.create_project(projectA['id'], projectA) - - user1 = self.new_user_ref( - domain_id=domainA['id']) - user1['password'] = uuid.uuid4().hex - self.identity_api.create_user(user1['id'], user1) - - user2 = self.new_user_ref( - domain_id=domainA['id']) - user2['password'] = uuid.uuid4().hex - self.identity_api.create_user(user2['id'], user2) - - group1 = self.new_group_ref( - domain_id=domainA['id']) - self.identity_api.create_group(group1['id'], group1) - - group2 = self.new_group_ref( - domain_id=domainA['id']) - self.identity_api.create_group(group2['id'], group2) - - self.identity_api.add_user_to_group(user1['id'], - group1['id']) - self.identity_api.add_user_to_group(user2['id'], - group2['id']) - - # Now create all the roles and assign them - role_list = [] - for _ in range(8): - role = self.new_role_ref() - self.identity_api.create_role(role['id'], role) - role_list.append(role) - - self.identity_api.create_grant(role_list[0]['id'], - user_id=user1['id'], - domain_id=domainA['id']) - self.identity_api.create_grant(role_list[1]['id'], - user_id=user1['id'], - project_id=projectA['id']) - self.identity_api.create_grant(role_list[2]['id'], - user_id=user2['id'], - domain_id=domainA['id']) - self.identity_api.create_grant(role_list[3]['id'], - user_id=user2['id'], - project_id=projectA['id']) - self.identity_api.create_grant(role_list[4]['id'], - group_id=group1['id'], - domain_id=domainA['id']) - self.identity_api.create_grant(role_list[5]['id'], - group_id=group1['id'], - project_id=projectA['id']) - self.identity_api.create_grant(role_list[6]['id'], - group_id=group2['id'], - domain_id=domainA['id']) - self.identity_api.create_grant(role_list[7]['id'], - group_id=group2['id'], - project_id=projectA['id']) - - # First, get a project scoped token - which should - # contain the direct user role and the one by virtue - # of group membership - auth_data = self.build_authentication_request( - user_id=user1['id'], - password=user1['password'], - project_id=projectA['id']) - r = self.post('/auth/tokens', body=auth_data) - token = self.assertValidScopedTokenResponse(r) - roles_ids = [] - for i, ref in enumerate(token['roles']): - roles_ids.append(ref['id']) - self.assertEqual(len(token['roles']), 2) - self.assertIn(role_list[1]['id'], roles_ids) - self.assertIn(role_list[5]['id'], roles_ids) - - # Now the same thing for a domain scoped token - auth_data = self.build_authentication_request( - user_id=user1['id'], - password=user1['password'], - domain_id=domainA['id']) - r = self.post('/auth/tokens', body=auth_data) - token = self.assertValidScopedTokenResponse(r) - roles_ids = [] - for i, ref in enumerate(token['roles']): - roles_ids.append(ref['id']) - self.assertEqual(len(token['roles']), 2) - self.assertIn(role_list[0]['id'], roles_ids) - self.assertIn(role_list[4]['id'], roles_ids) - - # Finally, add user1 to the 2nd group, and get a new - # scoped token - the extra role should now be included - # by virtue of the 2nd group - self.identity_api.add_user_to_group(user1['id'], - group2['id']) - auth_data = self.build_authentication_request( - user_id=user1['id'], - password=user1['password'], - project_id=projectA['id']) - r = self.post('/auth/tokens', body=auth_data) - token = self.assertValidScopedTokenResponse(r) - roles_ids = [] - for i, ref in enumerate(token['roles']): - roles_ids.append(ref['id']) - self.assertEqual(len(token['roles']), 3) - self.assertIn(role_list[1]['id'], roles_ids) - self.assertIn(role_list[5]['id'], roles_ids) - self.assertIn(role_list[7]['id'], roles_ids) - - def test_project_id_scoped_token_with_user_domain_id(self): - auth_data = self.build_authentication_request( - username=self.user['name'], - user_domain_id=self.domain['id'], - password=self.user['password'], - project_id=self.project['id']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidProjectScopedTokenResponse(r) - - def test_project_id_scoped_token_with_user_domain_name(self): - auth_data = self.build_authentication_request( - username=self.user['name'], - user_domain_name=self.domain['name'], - password=self.user['password'], - project_id=self.project['id']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidProjectScopedTokenResponse(r) - - def test_domain_id_scoped_token_with_user_id(self): - path = '/domains/%s/users/%s/roles/%s' % ( - self.domain['id'], self.user['id'], self.role['id']) - self.put(path=path) - - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password'], - domain_id=self.domain['id']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidDomainScopedTokenResponse(r) - - def test_domain_id_scoped_token_with_user_domain_id(self): - path = '/domains/%s/users/%s/roles/%s' % ( - self.domain['id'], self.user['id'], self.role['id']) - self.put(path=path) - - auth_data = self.build_authentication_request( - username=self.user['name'], - user_domain_id=self.domain['id'], - password=self.user['password'], - domain_id=self.domain['id']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidDomainScopedTokenResponse(r) - - def test_domain_id_scoped_token_with_user_domain_name(self): - path = '/domains/%s/users/%s/roles/%s' % ( - self.domain['id'], self.user['id'], self.role['id']) - self.put(path=path) - - auth_data = self.build_authentication_request( - username=self.user['name'], - user_domain_name=self.domain['name'], - password=self.user['password'], - domain_id=self.domain['id']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidDomainScopedTokenResponse(r) - - def test_domain_name_scoped_token_with_user_id(self): - path = '/domains/%s/users/%s/roles/%s' % ( - self.domain['id'], self.user['id'], self.role['id']) - self.put(path=path) - - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password'], - domain_name=self.domain['name']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidDomainScopedTokenResponse(r) - - def test_domain_name_scoped_token_with_user_domain_id(self): - path = '/domains/%s/users/%s/roles/%s' % ( - self.domain['id'], self.user['id'], self.role['id']) - self.put(path=path) - - auth_data = self.build_authentication_request( - username=self.user['name'], - user_domain_id=self.domain['id'], - password=self.user['password'], - domain_name=self.domain['name']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidDomainScopedTokenResponse(r) - - def test_domain_name_scoped_token_with_user_domain_name(self): - path = '/domains/%s/users/%s/roles/%s' % ( - self.domain['id'], self.user['id'], self.role['id']) - self.put(path=path) - - auth_data = self.build_authentication_request( - username=self.user['name'], - user_domain_name=self.domain['name'], - password=self.user['password'], - domain_name=self.domain['name']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidDomainScopedTokenResponse(r) - - def test_domain_scope_token_with_group_role(self): - group_id = uuid.uuid4().hex - group = self.new_group_ref( - domain_id=self.domain_id) - group['id'] = group_id - self.identity_api.create_group(group_id, group) - - # add user to group - self.identity_api.add_user_to_group(self.user['id'], group['id']) - - # grant the domain role to group - path = '/domains/%s/groups/%s/roles/%s' % ( - self.domain['id'], group['id'], self.role['id']) - self.put(path=path) - - # now get a domain-scoped token - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password'], - domain_id=self.domain['id']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidDomainScopedTokenResponse(r) - - def test_domain_scope_token_with_name(self): - # grant the domain role to user - path = '/domains/%s/users/%s/roles/%s' % ( - self.domain['id'], self.user['id'], self.role['id']) - self.put(path=path) - # now get a domain-scoped token - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password'], - domain_name=self.domain['name']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidDomainScopedTokenResponse(r) - - def test_domain_scope_failed(self): - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password'], - domain_id=self.domain['id']) - self.post('/auth/tokens', body=auth_data, expected_status=401) - - def test_auth_with_id(self): - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidUnscopedTokenResponse(r) - - token = r.headers.get('X-Subject-Token') - - # test token auth - auth_data = self.build_authentication_request(token=token) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidUnscopedTokenResponse(r) - - def test_invalid_user_id(self): - auth_data = self.build_authentication_request( - user_id=uuid.uuid4().hex, - password=self.user['password']) - self.post('/auth/tokens', body=auth_data, expected_status=401) - - def test_invalid_user_name(self): - auth_data = self.build_authentication_request( - username=uuid.uuid4().hex, - user_domain_id=self.domain['id'], - password=self.user['password']) - self.post('/auth/tokens', body=auth_data, expected_status=401) - - def test_invalid_domain_id(self): - auth_data = self.build_authentication_request( - username=self.user['name'], - user_domain_id=uuid.uuid4().hex, - password=self.user['password']) - self.post('/auth/tokens', body=auth_data, expected_status=401) - - def test_invalid_domain_name(self): - auth_data = self.build_authentication_request( - username=self.user['name'], - user_domain_name=uuid.uuid4().hex, - password=self.user['password']) - self.post('/auth/tokens', body=auth_data, expected_status=401) - - def test_invalid_password(self): - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=uuid.uuid4().hex) - self.post('/auth/tokens', body=auth_data, expected_status=401) - - def test_remote_user_no_realm(self): - CONF.auth.methods = 'external' - api = auth.controllers.Auth() - auth_data = self.build_authentication_request()['auth'] - context = {'REMOTE_USER': self.default_domain_user['name']} - auth_info = auth.controllers.AuthInfo(None, auth_data) - auth_context = {'extras': {}, 'method_names': []} - api.authenticate(context, auth_info, auth_context) - self.assertEqual(auth_context['user_id'], - self.default_domain_user['id']) - - def test_remote_user_no_domain(self): - auth_data = self.build_authentication_request()['auth'] - api = auth.controllers.Auth() - context = {'REMOTE_USER': self.user['name']} - auth_info = auth.controllers.AuthInfo(None, auth_data) - auth_context = {'extras': {}, 'method_names': []} - self.assertRaises(exception.Unauthorized, - api.authenticate, - context, - auth_info, - auth_context) - - def test_remote_user_and_password(self): - #both REMOTE_USER and password methods must pass. - #note that they do not have to match - auth_data = self.build_authentication_request( - user_domain_id=self.domain['id'], - username=self.user['name'], - password=self.user['password'])['auth'] - api = auth.controllers.Auth() - context = {'REMOTE_USER': self.default_domain_user['name']} - auth_info = auth.controllers.AuthInfo(None, auth_data) - auth_context = {'extras': {}, 'method_names': []} - api.authenticate(context, auth_info, auth_context) - - def test_remote_user_and_explicit_external(self): - #both REMOTE_USER and password methods must pass. - #note that they do not have to match - auth_data = self.build_authentication_request( - user_domain_id=self.domain['id'], - username=self.user['name'], - password=self.user['password'])['auth'] - auth_data['identity']['methods'] = ["password", "external"] - auth_data['identity']['external'] = {} - api = auth.controllers.Auth() - context = {} - auth_info = auth.controllers.AuthInfo(None, auth_data) - auth_context = {'extras': {}, 'method_names': []} - self.assertRaises(exception.Unauthorized, - api.authenticate, - context, - auth_info, - auth_context) - - def test_remote_user_bad_password(self): - #both REMOTE_USER and password methods must pass. - auth_data = self.build_authentication_request( - user_domain_id=self.domain['id'], - username=self.user['name'], - password='badpassword')['auth'] - api = auth.controllers.Auth() - context = {'REMOTE_USER': self.default_domain_user['name']} - auth_info = auth.controllers.AuthInfo(None, auth_data) - auth_context = {'extras': {}, 'method_names': []} - self.assertRaises(exception.Unauthorized, - api.authenticate, - context, - auth_info, - auth_context) - - def test_bind_not_set_with_remote_user(self): - CONF.token.bind = [] - auth_data = self.build_authentication_request() - remote_user = self.default_domain_user['name'] - self.admin_app.extra_environ.update({'REMOTE_USER': remote_user, - 'AUTH_TYPE': 'Negotiate'}) - r = self.post('/auth/tokens', body=auth_data) - token = self.assertValidUnscopedTokenResponse(r) - self.assertNotIn('bind', token) - - #TODO(ayoung): move to TestPKITokenAPIs; it will be run for both formats - def test_verify_with_bound_token(self): - self.opt_in_group('token', bind='kerberos') - auth_data = self.build_authentication_request( - project_id=self.project['id']) - remote_user = self.default_domain_user['name'] - self.admin_app.extra_environ.update({'REMOTE_USER': remote_user, - 'AUTH_TYPE': 'Negotiate'}) - - resp = self.post('/auth/tokens', body=auth_data) - - token = resp.headers.get('X-Subject-Token') - headers = {'X-Subject-Token': token} - r = self.get('/auth/tokens', headers=headers, token=token) - token = self.assertValidProjectScopedTokenResponse(r) - self.assertEqual(token['bind']['kerberos'], - self.default_domain_user['name']) - - def test_auth_with_bind_token(self): - CONF.token.bind = ['kerberos'] - - auth_data = self.build_authentication_request() - remote_user = self.default_domain_user['name'] - self.admin_app.extra_environ.update({'REMOTE_USER': remote_user, - 'AUTH_TYPE': 'Negotiate'}) - r = self.post('/auth/tokens', body=auth_data) - - # the unscoped token should have bind information in it - token = self.assertValidUnscopedTokenResponse(r) - self.assertEqual(token['bind']['kerberos'], remote_user) - - token = r.headers.get('X-Subject-Token') - - # using unscoped token with remote user succeeds - auth_params = {'token': token, 'project_id': self.project_id} - auth_data = self.build_authentication_request(**auth_params) - r = self.post('/auth/tokens', body=auth_data) - token = self.assertValidProjectScopedTokenResponse(r) - - # the bind information should be carried over from the original token - self.assertEqual(token['bind']['kerberos'], remote_user) - - def test_v2_v3_bind_token_intermix(self): - self.opt_in_group('token', bind='kerberos') - - # we need our own user registered to the default domain because of - # the way external auth works. - remote_user = self.default_domain_user['name'] - self.admin_app.extra_environ.update({'REMOTE_USER': remote_user, - 'AUTH_TYPE': 'Negotiate'}) - body = {'auth': {}} - resp = self.admin_request(path='/v2.0/tokens', - method='POST', - body=body) - - v2_token_data = resp.result - - bind = v2_token_data['access']['token']['bind'] - self.assertEqual(bind['kerberos'], self.default_domain_user['name']) - - v2_token_id = v2_token_data['access']['token']['id'] - headers = {'X-Subject-Token': v2_token_id} - resp = self.get('/auth/tokens', headers=headers) - token_data = resp.result - - self.assertDictEqual(v2_token_data['access']['token']['bind'], - token_data['token']['bind']) - - -class TestAuthXML(TestAuthJSON): - content_type = 'xml' - - -class TestTrustOptional(test_v3.RestfulTestCase): - def setUp(self, *args, **kwargs): - self.opt_in_group('trust', enabled=False) - super(TestTrustOptional, self).setUp(*args, **kwargs) - - def test_trusts_404(self): - self.get('/OS-TRUST/trusts', body={'trust': {}}, expected_status=404) - self.post('/OS-TRUST/trusts', body={'trust': {}}, expected_status=404) - - def test_auth_with_scope_in_trust_403(self): - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password'], - trust_id=uuid.uuid4().hex) - self.post('/auth/tokens', body=auth_data, expected_status=403) - - -class TestTrustAuth(TestAuthInfo): - def setUp(self): - self.opt_in_group('trust', enabled=True) - super(TestTrustAuth, self).setUp(load_sample_data=True) - - # create a trustee to delegate stuff to - self.trustee_user_id = uuid.uuid4().hex - self.trustee_user = self.new_user_ref(domain_id=self.domain_id) - self.trustee_user['id'] = self.trustee_user_id - self.identity_api.create_user(self.trustee_user_id, self.trustee_user) - - def test_create_trust_400(self): - self.skipTest('Blocked by bug 1133435') - self.post('/OS-TRUST/trusts', body={'trust': {}}, expected_status=400) - - def test_create_unscoped_trust(self): - ref = self.new_trust_ref( - trustor_user_id=self.user_id, - trustee_user_id=self.trustee_user_id) - del ref['id'] - r = self.post('/OS-TRUST/trusts', body={'trust': ref}) - self.assertValidTrustResponse(r, ref) - - def test_trust_crud(self): - ref = self.new_trust_ref( - trustor_user_id=self.user_id, - trustee_user_id=self.trustee_user_id, - project_id=self.project_id, - role_ids=[self.role_id]) - del ref['id'] - r = self.post('/OS-TRUST/trusts', body={'trust': ref}) - trust = self.assertValidTrustResponse(r, ref) - - r = self.get( - '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']}, - expected_status=200) - self.assertValidTrustResponse(r, ref) - - # validate roles on the trust - r = self.get( - '/OS-TRUST/trusts/%(trust_id)s/roles' % { - 'trust_id': trust['id']}, - expected_status=200) - roles = self.assertValidRoleListResponse(r, self.role) - self.assertIn(self.role['id'], [x['id'] for x in roles]) - self.head( - '/OS-TRUST/trusts/%(trust_id)s/roles/%(role_id)s' % { - 'trust_id': trust['id'], - 'role_id': self.role['id']}, - expected_status=204) - r = self.get( - '/OS-TRUST/trusts/%(trust_id)s/roles/%(role_id)s' % { - 'trust_id': trust['id'], - 'role_id': self.role['id']}, - expected_status=200) - self.assertValidRoleResponse(r, self.role) - - r = self.get('/OS-TRUST/trusts', expected_status=200) - self.assertValidTrustListResponse(r, trust) - - # trusts are immutable - self.patch( - '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']}, - body={'trust': ref}, - expected_status=404) - - self.delete( - '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']}, - expected_status=204) - - self.get( - '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']}, - expected_status=404) - - def test_create_trust_trustee_404(self): - ref = self.new_trust_ref( - trustor_user_id=self.user_id, - trustee_user_id=uuid.uuid4().hex) - del ref['id'] - self.post('/OS-TRUST/trusts', body={'trust': ref}, expected_status=404) - - def test_create_trust_trustor_trustee_backwards(self): - ref = self.new_trust_ref( - trustor_user_id=self.trustee_user_id, - trustee_user_id=self.user_id) - del ref['id'] - self.post('/OS-TRUST/trusts', body={'trust': ref}, expected_status=403) - - def test_create_trust_project_404(self): - ref = self.new_trust_ref( - trustor_user_id=self.user_id, - trustee_user_id=self.trustee_user_id, - project_id=uuid.uuid4().hex, - role_ids=[self.role_id]) - del ref['id'] - self.post('/OS-TRUST/trusts', body={'trust': ref}, expected_status=404) - - def test_create_trust_role_id_404(self): - ref = self.new_trust_ref( - trustor_user_id=self.user_id, - trustee_user_id=self.trustee_user_id, - project_id=self.project_id, - role_ids=[uuid.uuid4().hex]) - del ref['id'] - self.post('/OS-TRUST/trusts', body={'trust': ref}, expected_status=404) - - def test_create_trust_role_name_404(self): - ref = self.new_trust_ref( - trustor_user_id=self.user_id, - trustee_user_id=self.trustee_user_id, - project_id=self.project_id, - role_names=[uuid.uuid4().hex]) - del ref['id'] - self.post('/OS-TRUST/trusts', body={'trust': ref}, expected_status=404) - - def test_create_expired_trust(self): - ref = self.new_trust_ref( - trustor_user_id=self.user_id, - trustee_user_id=self.trustee_user_id, - project_id=self.project_id, - expires=dict(seconds=-1), - role_ids=[self.role_id]) - del ref['id'] - r = self.post('/OS-TRUST/trusts', body={'trust': ref}) - trust = self.assertValidTrustResponse(r, ref) - - self.get('/OS-TRUST/trusts/%(trust_id)s' % { - 'trust_id': trust['id']}, - expected_status=404) - - auth_data = self.build_authentication_request( - user_id=self.trustee_user['id'], - password=self.trustee_user['password'], - trust_id=trust['id']) - self.post('/auth/tokens', body=auth_data, expected_status=401) - - def test_v3_v2_intermix_trustor_not_in_default_domain_failed(self): - ref = self.new_trust_ref( - trustor_user_id=self.user_id, - trustee_user_id=self.default_domain_user_id, - project_id=self.project_id, - impersonation=False, - expires=dict(minutes=1), - role_ids=[self.role_id]) - del ref['id'] - - r = self.post('/OS-TRUST/trusts', body={'trust': ref}) - trust = self.assertValidTrustResponse(r) - - auth_data = self.build_authentication_request( - user_id=self.default_domain_user['id'], - password=self.default_domain_user['password'], - trust_id=trust['id']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidProjectTrustScopedTokenResponse( - r, self.default_domain_user) - - token = r.headers.get('X-Subject-Token') - - # now validate the v3 token with v2 API - path = '/v2.0/tokens/%s' % (token) - self.admin_request( - path=path, token='ADMIN', method='GET', expected_status=401) - - def test_v3_v2_intermix_trustor_not_in_default_domaini_failed(self): - ref = self.new_trust_ref( - trustor_user_id=self.default_domain_user_id, - trustee_user_id=self.trustee_user_id, - project_id=self.default_domain_project_id, - impersonation=False, - expires=dict(minutes=1), - role_ids=[self.role_id]) - del ref['id'] - - auth_data = self.build_authentication_request( - user_id=self.default_domain_user['id'], - password=self.default_domain_user['password'], - project_id=self.default_domain_project_id) - r = self.post('/auth/tokens', body=auth_data) - token = r.headers.get('X-Subject-Token') - - r = self.post('/OS-TRUST/trusts', body={'trust': ref}, token=token) - trust = self.assertValidTrustResponse(r) - - auth_data = self.build_authentication_request( - user_id=self.trustee_user['id'], - password=self.trustee_user['password'], - trust_id=trust['id']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidProjectTrustScopedTokenResponse( - r, self.trustee_user) - token = r.headers.get('X-Subject-Token') - - # now validate the v3 token with v2 API - path = '/v2.0/tokens/%s' % (token) - self.admin_request( - path=path, token='ADMIN', method='GET', expected_status=401) - - def test_v3_v2_intermix_project_not_in_default_domaini_failed(self): - # create a trustee in default domain to delegate stuff to - trustee_user_id = uuid.uuid4().hex - trustee_user = self.new_user_ref(domain_id=test_v3.DEFAULT_DOMAIN_ID) - trustee_user['id'] = trustee_user_id - self.identity_api.create_user(trustee_user_id, trustee_user) - - ref = self.new_trust_ref( - trustor_user_id=self.default_domain_user_id, - trustee_user_id=trustee_user_id, - project_id=self.project_id, - impersonation=False, - expires=dict(minutes=1), - role_ids=[self.role_id]) - del ref['id'] - - auth_data = self.build_authentication_request( - user_id=self.default_domain_user['id'], - password=self.default_domain_user['password'], - project_id=self.default_domain_project_id) - r = self.post('/auth/tokens', body=auth_data) - token = r.headers.get('X-Subject-Token') - - r = self.post('/OS-TRUST/trusts', body={'trust': ref}, token=token) - trust = self.assertValidTrustResponse(r) - - auth_data = self.build_authentication_request( - user_id=trustee_user['id'], - password=trustee_user['password'], - trust_id=trust['id']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidProjectTrustScopedTokenResponse( - r, trustee_user) - token = r.headers.get('X-Subject-Token') - - # now validate the v3 token with v2 API - path = '/v2.0/tokens/%s' % (token) - self.admin_request( - path=path, token='ADMIN', method='GET', expected_status=401) - - def test_v3_v2_intermix(self): - # create a trustee in default domain to delegate stuff to - trustee_user_id = uuid.uuid4().hex - trustee_user = self.new_user_ref(domain_id=test_v3.DEFAULT_DOMAIN_ID) - trustee_user['id'] = trustee_user_id - self.identity_api.create_user(trustee_user_id, trustee_user) - - ref = self.new_trust_ref( - trustor_user_id=self.default_domain_user_id, - trustee_user_id=trustee_user_id, - project_id=self.default_domain_project_id, - impersonation=False, - expires=dict(minutes=1), - role_ids=[self.role_id]) - del ref['id'] - auth_data = self.build_authentication_request( - user_id=self.default_domain_user['id'], - password=self.default_domain_user['password'], - project_id=self.default_domain_project_id) - r = self.post('/auth/tokens', body=auth_data) - token = r.headers.get('X-Subject-Token') - - r = self.post('/OS-TRUST/trusts', body={'trust': ref}, token=token) - trust = self.assertValidTrustResponse(r) - - auth_data = self.build_authentication_request( - user_id=trustee_user['id'], - password=trustee_user['password'], - trust_id=trust['id']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidProjectTrustScopedTokenResponse( - r, trustee_user) - token = r.headers.get('X-Subject-Token') - - # now validate the v3 token with v2 API - path = '/v2.0/tokens/%s' % (token) - self.admin_request( - path=path, token='ADMIN', method='GET', expected_status=200) - - def test_exercise_trust_scoped_token_without_impersonation(self): - ref = self.new_trust_ref( - trustor_user_id=self.user_id, - trustee_user_id=self.trustee_user_id, - project_id=self.project_id, - impersonation=False, - expires=dict(minutes=1), - role_ids=[self.role_id]) - del ref['id'] - - r = self.post('/OS-TRUST/trusts', body={'trust': ref}) - trust = self.assertValidTrustResponse(r) - - auth_data = self.build_authentication_request( - user_id=self.trustee_user['id'], - password=self.trustee_user['password'], - trust_id=trust['id']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidProjectTrustScopedTokenResponse(r, self.trustee_user) - self.assertEqual(r.result['token']['user']['id'], - self.trustee_user['id']) - self.assertEqual(r.result['token']['user']['name'], - self.trustee_user['name']) - self.assertEqual(r.result['token']['user']['domain']['id'], - self.domain['id']) - self.assertEqual(r.result['token']['user']['domain']['name'], - self.domain['name']) - self.assertEqual(r.result['token']['project']['id'], - self.project['id']) - self.assertEqual(r.result['token']['project']['name'], - self.project['name']) - - def test_exercise_trust_scoped_token_with_impersonation(self): - ref = self.new_trust_ref( - trustor_user_id=self.user_id, - trustee_user_id=self.trustee_user_id, - project_id=self.project_id, - impersonation=True, - expires=dict(minutes=1), - role_ids=[self.role_id]) - del ref['id'] - - r = self.post('/OS-TRUST/trusts', body={'trust': ref}) - trust = self.assertValidTrustResponse(r) - - auth_data = self.build_authentication_request( - user_id=self.trustee_user['id'], - password=self.trustee_user['password'], - trust_id=trust['id']) - r = self.post('/auth/tokens', body=auth_data) - self.assertValidProjectTrustScopedTokenResponse(r, self.user) - self.assertEqual(r.result['token']['user']['id'], self.user['id']) - self.assertEqual(r.result['token']['user']['name'], self.user['name']) - self.assertEqual(r.result['token']['user']['domain']['id'], - self.domain['id']) - self.assertEqual(r.result['token']['user']['domain']['name'], - self.domain['name']) - self.assertEqual(r.result['token']['project']['id'], - self.project['id']) - self.assertEqual(r.result['token']['project']['name'], - self.project['name']) - - def test_delete_trust(self): - ref = self.new_trust_ref( - trustor_user_id=self.user_id, - trustee_user_id=self.trustee_user_id, - project_id=self.project_id, - impersonation=False, - expires=dict(minutes=1), - role_ids=[self.role_id]) - del ref['id'] - - r = self.post('/OS-TRUST/trusts', body={'trust': ref}) - - trust = self.assertValidTrustResponse(r, ref) - - self.delete('/OS-TRUST/trusts/%(trust_id)s' % { - 'trust_id': trust['id']}, - expected_status=204) - - self.get('/OS-TRUST/trusts/%(trust_id)s' % { - 'trust_id': trust['id']}, - expected_status=404) - - self.get('/OS-TRUST/trusts/%(trust_id)s' % { - 'trust_id': trust['id']}, - expected_status=404) - - auth_data = self.build_authentication_request( - user_id=self.trustee_user['id'], - password=self.trustee_user['password'], - trust_id=trust['id']) - self.post('/auth/tokens', body=auth_data, expected_status=401) - - def test_list_trusts(self): - ref = self.new_trust_ref( - trustor_user_id=self.user_id, - trustee_user_id=self.trustee_user_id, - project_id=self.project_id, - impersonation=False, - expires=dict(minutes=1), - role_ids=[self.role_id]) - del ref['id'] - - for i in range(0, 3): - r = self.post('/OS-TRUST/trusts', body={'trust': ref}) - self.assertValidTrustResponse(r, ref) - - r = self.get('/OS-TRUST/trusts?trustor_user_id=%s' % - self.user_id, expected_status=200) - trusts = r.result['trusts'] - self.assertEqual(len(trusts), 3) - - r = self.get('/OS-TRUST/trusts?trustee_user_id=%s' % - self.user_id, expected_status=200) - trusts = r.result['trusts'] - self.assertEqual(len(trusts), 0) - - def test_change_password_invalidates_trust_tokens(self): - ref = self.new_trust_ref( - trustor_user_id=self.user_id, - trustee_user_id=self.trustee_user_id, - project_id=self.project_id, - impersonation=True, - expires=dict(minutes=1), - role_ids=[self.role_id]) - del ref['id'] - - r = self.post('/OS-TRUST/trusts', body={'trust': ref}) - trust = self.assertValidTrustResponse(r) - - auth_data = self.build_authentication_request( - user_id=self.trustee_user['id'], - password=self.trustee_user['password'], - trust_id=trust['id']) - r = self.post('/auth/tokens', body=auth_data) - - self.assertValidProjectTrustScopedTokenResponse(r, self.user) - trust_token = r.headers.get('X-Subject-Token') - - self.get('/OS-TRUST/trusts?trustor_user_id=%s' % - self.user_id, expected_status=200, - token=trust_token) - - auth_data = self.build_authentication_request( - user_id=self.trustee_user['id'], - password=self.trustee_user['password']) - - self.assertValidUserResponse( - self.patch('/users/%s' % self.trustee_user['id'], - body={'user': {'password': uuid.uuid4().hex}}, - auth=auth_data, - expected_status=200)) - - self.get('/OS-TRUST/trusts?trustor_user_id=%s' % - self.user_id, expected_status=401, - token=trust_token) diff --git a/tests/test_v3_catalog.py b/tests/test_v3_catalog.py deleted file mode 100644 index 408670ec..00000000 --- a/tests/test_v3_catalog.py +++ /dev/null @@ -1,165 +0,0 @@ -import uuid - -import test_v3 - - -class CatalogTestCase(test_v3.RestfulTestCase): - """Test service & endpoint CRUD.""" - - def setUp(self): - super(CatalogTestCase, self).setUp() - - self.service_id = uuid.uuid4().hex - self.service = self.new_service_ref() - self.service['id'] = self.service_id - self.catalog_api.create_service( - self.service_id, - self.service.copy()) - - self.endpoint_id = uuid.uuid4().hex - self.endpoint = self.new_endpoint_ref(service_id=self.service_id) - self.endpoint['id'] = self.endpoint_id - self.catalog_api.create_endpoint( - self.endpoint_id, - self.endpoint.copy()) - - # service crud tests - - def test_create_service(self): - """Call ``POST /services``.""" - ref = self.new_service_ref() - r = self.post( - '/services', - body={'service': ref}) - return self.assertValidServiceResponse(r, ref) - - def test_list_services(self): - """Call ``GET /services``.""" - r = self.get('/services') - self.assertValidServiceListResponse(r, ref=self.service) - - def test_list_services_xml(self): - """Call ``GET /services (xml data)``.""" - r = self.get('/services', content_type='xml') - self.assertValidServiceListResponse(r, ref=self.service) - - def test_get_service(self): - """Call ``GET /services/{service_id}``.""" - r = self.get('/services/%(service_id)s' % { - 'service_id': self.service_id}) - self.assertValidServiceResponse(r, self.service) - - def test_update_service(self): - """Call ``PATCH /services/{service_id}``.""" - service = self.new_service_ref() - del service['id'] - r = self.patch('/services/%(service_id)s' % { - 'service_id': self.service_id}, - body={'service': service}) - self.assertValidServiceResponse(r, service) - - def test_delete_service(self): - """Call ``DELETE /services/{service_id}``.""" - self.delete('/services/%(service_id)s' % { - 'service_id': self.service_id}) - - # endpoint crud tests - - def test_list_endpoints(self): - """Call ``GET /endpoints``.""" - r = self.get('/endpoints') - self.assertValidEndpointListResponse(r, ref=self.endpoint) - - def test_list_endpoints_xml(self): - """Call ``GET /endpoints`` (xml data).""" - r = self.get('/endpoints', content_type='xml') - self.assertValidEndpointListResponse(r, ref=self.endpoint) - - def test_create_endpoint(self): - """Call ``POST /endpoints``.""" - ref = self.new_endpoint_ref(service_id=self.service_id) - r = self.post( - '/endpoints', - body={'endpoint': ref}) - self.assertValidEndpointResponse(r, ref) - - def assertValidErrorResponse(self, response): - self.assertTrue(response.status_code in [400]) - - def test_create_endpoint_400(self): - """Call ``POST /endpoints``.""" - ref = self.new_endpoint_ref(service_id=self.service_id) - ref["region"] = "0" * 256 - self.post('/endpoints', body={'endpoint': ref}, expected_status=400) - - def test_get_endpoint(self): - """Call ``GET /endpoints/{endpoint_id}``.""" - r = self.get( - '/endpoints/%(endpoint_id)s' % { - 'endpoint_id': self.endpoint_id}) - self.assertValidEndpointResponse(r, self.endpoint) - - def test_update_endpoint(self): - """Call ``PATCH /endpoints/{endpoint_id}``.""" - ref = self.new_endpoint_ref(service_id=self.service_id) - del ref['id'] - r = self.patch( - '/endpoints/%(endpoint_id)s' % { - 'endpoint_id': self.endpoint_id}, - body={'endpoint': ref}) - self.assertValidEndpointResponse(r, ref) - - def test_delete_endpoint(self): - """Call ``DELETE /endpoints/{endpoint_id}``.""" - self.delete( - '/endpoints/%(endpoint_id)s' % { - 'endpoint_id': self.endpoint_id}) - - def test_create_endpoint_on_v2(self): - # clear the v3 endpoint so we only have endpoints created on v2 - self.delete( - '/endpoints/%(endpoint_id)s' % { - 'endpoint_id': self.endpoint_id}) - - # create a v3 endpoint ref, and then tweak it back to a v2-style ref - ref = self.new_endpoint_ref(service_id=self.service['id']) - del ref['id'] - del ref['interface'] - ref['publicurl'] = ref.pop('url') - ref['internalurl'] = None - # don't set adminurl to ensure it's absence is handled like internalurl - - # create the endpoint on v2 (using a v3 token) - r = self.admin_request( - method='POST', - path='/v2.0/endpoints', - token=self.get_scoped_token(), - body={'endpoint': ref}) - endpoint_v2 = r.result['endpoint'] - - # test the endpoint on v3 - r = self.get('/endpoints') - endpoints = self.assertValidEndpointListResponse(r) - self.assertEqual(len(endpoints), 1) - endpoint_v3 = endpoints.pop() - - # these attributes are identical between both API's - self.assertEqual(endpoint_v3['region'], ref['region']) - self.assertEqual(endpoint_v3['service_id'], ref['service_id']) - self.assertEqual(endpoint_v3['description'], ref['description']) - - # a v2 endpoint is not quite the same concept as a v3 endpoint, so they - # receive different identifiers - self.assertNotEqual(endpoint_v2['id'], endpoint_v3['id']) - - # v2 has a publicurl; v3 has a url + interface type - self.assertEqual(endpoint_v3['url'], ref['publicurl']) - self.assertEqual(endpoint_v3['interface'], 'public') - - # tests for bug 1152632 -- these attributes were being returned by v3 - self.assertNotIn('publicurl', endpoint_v3) - self.assertNotIn('adminurl', endpoint_v3) - self.assertNotIn('internalurl', endpoint_v3) - - # test for bug 1152635 -- this attribute was being returned by v3 - self.assertNotIn('legacy_endpoint_id', endpoint_v3) diff --git a/tests/test_v3_credential.py b/tests/test_v3_credential.py deleted file mode 100644 index 6040cca3..00000000 --- a/tests/test_v3_credential.py +++ /dev/null @@ -1,78 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 OpenStack 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 uuid - -import test_v3 - - -class CredentialTestCase(test_v3.RestfulTestCase): - """Test credential CRUD.""" - def setUp(self): - - super(CredentialTestCase, self).setUp() - - self.credential_id = uuid.uuid4().hex - self.credential = self.new_credential_ref( - user_id=self.user['id'], - project_id=self.project_id) - self.credential['id'] = self.credential_id - self.credential_api.create_credential( - self.credential_id, - self.credential) - - def test_list_credentials(self): - """Call ``GET /credentials``.""" - r = self.get('/credentials') - self.assertValidCredentialListResponse(r, ref=self.credential) - - def test_list_credentials_xml(self): - """Call ``GET /credentials`` (xml data).""" - r = self.get('/credentials', content_type='xml') - self.assertValidCredentialListResponse(r, ref=self.credential) - - def test_create_credential(self): - """Call ``POST /credentials``.""" - ref = self.new_credential_ref(user_id=self.user['id']) - r = self.post( - '/credentials', - body={'credential': ref}) - self.assertValidCredentialResponse(r, ref) - - def test_get_credential(self): - """Call ``GET /credentials/{credential_id}``.""" - r = self.get( - '/credentials/%(credential_id)s' % { - 'credential_id': self.credential_id}) - self.assertValidCredentialResponse(r, self.credential) - - def test_update_credential(self): - """Call ``PATCH /credentials/{credential_id}``.""" - ref = self.new_credential_ref( - user_id=self.user['id'], - project_id=self.project_id) - del ref['id'] - r = self.patch( - '/credentials/%(credential_id)s' % { - 'credential_id': self.credential_id}, - body={'credential': ref}) - self.assertValidCredentialResponse(r, ref) - - def test_delete_credential(self): - """Call ``DELETE /credentials/{credential_id}``.""" - self.delete( - '/credentials/%(credential_id)s' % { - 'credential_id': self.credential_id}) diff --git a/tests/test_v3_identity.py b/tests/test_v3_identity.py deleted file mode 100644 index f1e19c42..00000000 --- a/tests/test_v3_identity.py +++ /dev/null @@ -1,1557 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 uuid - -from keystone import config -from keystone import exception - -import test_v3 - - -def _build_role_assignment_url_and_entity( - role_id, user_id=None, group_id=None, domain_id=None, - project_id=None, inherited_to_projects=False, - effective=False): - - if user_id and domain_id: - url = ('/domains/%(domain_id)s/users/%(user_id)s' - '/roles/%(role_id)s' % { - 'domain_id': domain_id, - 'user_id': user_id, - 'role_id': role_id}) - entity = {'role': {'id': role_id}, - 'user': {'id': user_id}, - 'scope': {'domain': {'id': domain_id}}} - if inherited_to_projects: - url = '/OS-INHERIT%s/inherited_to_projects' % url - if not effective: - entity['OS-INHERIT:inherited_to'] = 'projects' - elif user_id and project_id: - url = ('/projects/%(project_id)s/users/%(user_id)s' - '/roles/%(role_id)s' % { - 'project_id': project_id, - 'user_id': user_id, - 'role_id': role_id}) - entity = {'role': {'id': role_id}, - 'user': {'id': user_id}, - 'scope': {'project': {'id': project_id}}} - if group_id and domain_id: - url = ('/domains/%(domain_id)s/groups/%(group_id)s' - '/roles/%(role_id)s' % { - 'domain_id': domain_id, - 'group_id': group_id, - 'role_id': role_id}) - entity = {'role': {'id': role_id}, - 'group': {'id': group_id}, - 'scope': {'domain': {'id': domain_id}}} - if inherited_to_projects: - url = '/OS-INHERIT%s/inherited_to_projects' % url - if not effective: - entity['OS-INHERIT:inherited_to'] = 'projects' - elif group_id and project_id: - url = ('/projects/%(project_id)s/groups/%(group_id)s' - '/roles/%(role_id)s' % { - 'project_id': project_id, - 'group_id': group_id, - 'role_id': role_id}) - entity = {'role': {'id': role_id}, - 'group': {'id': group_id}, - 'scope': {'project': {'id': project_id}}} - return (url, entity) - - -class IdentityTestCase(test_v3.RestfulTestCase): - """Test domains, projects, users, groups, & role CRUD.""" - - def setUp(self): - super(IdentityTestCase, self).setUp() - - self.group_id = uuid.uuid4().hex - self.group = self.new_group_ref( - domain_id=self.domain_id) - self.group['id'] = self.group_id - self.identity_api.create_group(self.group_id, self.group) - - self.credential_id = uuid.uuid4().hex - self.credential = self.new_credential_ref( - user_id=self.user['id'], - project_id=self.project_id) - self.credential['id'] = self.credential_id - self.credential_api.create_credential( - self.credential_id, - self.credential) - - # domain crud tests - - def test_create_domain(self): - """Call ``POST /domains``.""" - ref = self.new_domain_ref() - r = self.post( - '/domains', - body={'domain': ref}) - return self.assertValidDomainResponse(r, ref) - - def test_create_domain_400(self): - """Call ``POST /domains``.""" - self.post('/domains', body={'domain': {}}, expected_status=400) - - def test_list_domains(self): - """Call ``GET /domains``.""" - r = self.get('/domains') - self.assertValidDomainListResponse(r, ref=self.domain) - - def test_list_domains_xml(self): - """Call ``GET /domains (xml data)``.""" - r = self.get('/domains', content_type='xml') - self.assertValidDomainListResponse(r, ref=self.domain) - - def test_get_domain(self): - """Call ``GET /domains/{domain_id}``.""" - r = self.get('/domains/%(domain_id)s' % { - 'domain_id': self.domain_id}) - self.assertValidDomainResponse(r, self.domain) - - def test_update_domain(self): - """Call ``PATCH /domains/{domain_id}``.""" - ref = self.new_domain_ref() - del ref['id'] - r = self.patch('/domains/%(domain_id)s' % { - 'domain_id': self.domain_id}, - body={'domain': ref}) - self.assertValidDomainResponse(r, ref) - - def test_disable_domain(self): - """Call ``PATCH /domains/{domain_id}`` (set enabled=False).""" - # Create a 2nd set of entities in a 2nd domain - self.domain2 = self.new_domain_ref() - self.identity_api.create_domain(self.domain2['id'], self.domain2) - - self.project2 = self.new_project_ref( - domain_id=self.domain2['id']) - self.identity_api.create_project(self.project2['id'], self.project2) - - self.user2 = self.new_user_ref( - domain_id=self.domain2['id'], - project_id=self.project2['id']) - self.identity_api.create_user(self.user2['id'], self.user2) - - self.identity_api.add_user_to_project(self.project2['id'], - self.user2['id']) - - # First check a user in that domain can authenticate, via - # Both v2 and v3 - body = { - 'auth': { - 'passwordCredentials': { - 'userId': self.user2['id'], - 'password': self.user2['password'] - }, - 'tenantId': self.project2['id'] - } - } - self.admin_request(path='/v2.0/tokens', method='POST', body=body) - - auth_data = self.build_authentication_request( - user_id=self.user2['id'], - password=self.user2['password'], - project_id=self.project2['id']) - self.post('/auth/tokens', body=auth_data) - - # Now disable the domain - self.domain2['enabled'] = False - r = self.patch('/domains/%(domain_id)s' % { - 'domain_id': self.domain2['id']}, - body={'domain': {'enabled': False}}) - self.assertValidDomainResponse(r, self.domain2) - - # Make sure the user can no longer authenticate, via - # either API - body = { - 'auth': { - 'passwordCredentials': { - 'userId': self.user2['id'], - 'password': self.user2['password'] - }, - 'tenantId': self.project2['id'] - } - } - self.admin_request( - path='/v2.0/tokens', method='POST', body=body, expected_status=401) - - # Try looking up in v3 by name and id - auth_data = self.build_authentication_request( - user_id=self.user2['id'], - password=self.user2['password'], - project_id=self.project2['id']) - self.post('/auth/tokens', body=auth_data, expected_status=401) - - auth_data = self.build_authentication_request( - username=self.user2['name'], - user_domain_id=self.domain2['id'], - password=self.user2['password'], - project_id=self.project2['id']) - self.post('/auth/tokens', body=auth_data, expected_status=401) - - def test_delete_enabled_domain_fails(self): - """Call ``DELETE /domains/{domain_id}`` (when domain enabled).""" - - # Try deleting an enabled domain, which should fail - self.delete('/domains/%(domain_id)s' % { - 'domain_id': self.domain['id']}, - expected_status=exception.ForbiddenAction.code) - - def test_delete_domain(self): - """Call ``DELETE /domains/{domain_id}``. - - The sample data set up already has a user, group, project - and credential that is part of self.domain. Since the user - we will authenticate with is in this domain, we create a - another set of entities in a second domain. Deleting this - second domain should delete all these new entities. In addition, - all the entities in the regular self.domain should be unaffected - by the delete. - - Test Plan: - - Create domain2 and a 2nd set of entities - - Disable domain2 - - Delete domain2 - - Check entities in domain2 have been deleted - - Check entities in self.domain are unaffected - - """ - - # Create a 2nd set of entities in a 2nd domain - self.domain2 = self.new_domain_ref() - self.identity_api.create_domain(self.domain2['id'], self.domain2) - - self.project2 = self.new_project_ref( - domain_id=self.domain2['id']) - self.identity_api.create_project(self.project2['id'], self.project2) - - self.user2 = self.new_user_ref( - domain_id=self.domain2['id'], - project_id=self.project2['id']) - self.identity_api.create_user(self.user2['id'], self.user2) - - self.group2 = self.new_group_ref( - domain_id=self.domain2['id']) - self.identity_api.create_group(self.group2['id'], self.group2) - - self.credential2 = self.new_credential_ref( - user_id=self.user2['id'], - project_id=self.project2['id']) - self.credential_api.create_credential( - self.credential2['id'], - self.credential2) - - # Now disable the new domain and delete it - self.domain2['enabled'] = False - r = self.patch('/domains/%(domain_id)s' % { - 'domain_id': self.domain2['id']}, - body={'domain': {'enabled': False}}) - self.assertValidDomainResponse(r, self.domain2) - self.delete('/domains/%(domain_id)s' % { - 'domain_id': self.domain2['id']}) - - # Check all the domain2 relevant entities are gone - self.assertRaises(exception.DomainNotFound, - self.identity_api.get_domain, - self.domain2['id']) - self.assertRaises(exception.ProjectNotFound, - self.identity_api.get_project, - self.project2['id']) - self.assertRaises(exception.GroupNotFound, - self.identity_api.get_group, - self.group2['id']) - self.assertRaises(exception.UserNotFound, - self.identity_api.get_user, - self.user2['id']) - self.assertRaises(exception.CredentialNotFound, - self.credential_api.get_credential, - self.credential2['id']) - - # ...and that all self.domain entities are still here - r = self.identity_api.get_domain(self.domain['id']) - self.assertDictEqual(r, self.domain) - r = self.identity_api.get_project(self.project['id']) - self.assertDictEqual(r, self.project) - r = self.identity_api.get_group(self.group['id']) - self.assertDictEqual(r, self.group) - r = self.identity_api.get_user(self.user['id']) - self.user.pop('password') - self.assertDictEqual(r, self.user) - r = self.credential_api.get_credential(self.credential['id']) - self.assertDictEqual(r, self.credential) - - # project crud tests - - def test_list_projects(self): - """Call ``GET /projects``.""" - r = self.get('/projects') - self.assertValidProjectListResponse(r, ref=self.project) - - def test_list_projects_xml(self): - """Call ``GET /projects`` (xml data).""" - r = self.get('/projects', content_type='xml') - self.assertValidProjectListResponse(r, ref=self.project) - - def test_create_project(self): - """Call ``POST /projects``.""" - ref = self.new_project_ref(domain_id=self.domain_id) - r = self.post( - '/projects', - body={'project': ref}) - self.assertValidProjectResponse(r, ref) - - def test_create_project_400(self): - """Call ``POST /projects``.""" - self.post('/projects', body={'project': {}}, expected_status=400) - - def test_get_project(self): - """Call ``GET /projects/{project_id}``.""" - r = self.get( - '/projects/%(project_id)s' % { - 'project_id': self.project_id}) - self.assertValidProjectResponse(r, self.project) - - def test_update_project(self): - """Call ``PATCH /projects/{project_id}``.""" - ref = self.new_project_ref(domain_id=self.domain_id) - del ref['id'] - r = self.patch( - '/projects/%(project_id)s' % { - 'project_id': self.project_id}, - body={'project': ref}) - self.assertValidProjectResponse(r, ref) - - def test_delete_project(self): - """Call ``DELETE /projects/{project_id} - - As well as making sure the delete succeeds, we ensure - that any credentials that reference this projects are - also deleted, while other credentials are unaffected. - - """ - # First check the credential for this project is present - r = self.credential_api.get_credential(self.credential['id']) - self.assertDictEqual(r, self.credential) - # Create a second credential with a different project - self.project2 = self.new_project_ref( - domain_id=self.domain['id']) - self.identity_api.create_project(self.project2['id'], self.project2) - self.credential2 = self.new_credential_ref( - user_id=self.user['id'], - project_id=self.project2['id']) - self.credential_api.create_credential( - self.credential2['id'], - self.credential2) - - # Now delete the project - self.delete( - '/projects/%(project_id)s' % { - 'project_id': self.project_id}) - - # Deleting the project should have deleted any credentials - # that reference this project - self.assertRaises(exception.CredentialNotFound, - self.credential_api.get_credential, - credential_id=self.credential['id']) - # But the credential for project2 is unaffected - r = self.credential_api.get_credential(self.credential2['id']) - self.assertDictEqual(r, self.credential2) - - # user crud tests - - def test_create_user(self): - """Call ``POST /users``.""" - ref = self.new_user_ref(domain_id=self.domain_id) - r = self.post( - '/users', - body={'user': ref}) - return self.assertValidUserResponse(r, ref) - - def test_create_user_400(self): - """Call ``POST /users``.""" - self.post('/users', body={'user': {}}, expected_status=400) - - def test_list_users(self): - """Call ``GET /users``.""" - r = self.get('/users') - self.assertValidUserListResponse(r, ref=self.user) - - def test_list_users_xml(self): - """Call ``GET /users`` (xml data).""" - r = self.get('/users', content_type='xml') - self.assertValidUserListResponse(r, ref=self.user) - - def test_get_user(self): - """Call ``GET /users/{user_id}``.""" - r = self.get('/users/%(user_id)s' % { - 'user_id': self.user['id']}) - self.assertValidUserResponse(r, self.user) - - def test_add_user_to_group(self): - """Call ``PUT /groups/{group_id}/users/{user_id}``.""" - self.put('/groups/%(group_id)s/users/%(user_id)s' % { - 'group_id': self.group_id, 'user_id': self.user['id']}) - - def test_list_groups_for_user(self): - """Call ``GET /users/{user_id}/groups``.""" - - self.user1 = self.new_user_ref( - domain_id=self.domain['id']) - self.user1['password'] = uuid.uuid4().hex - self.identity_api.create_user(self.user1['id'], self.user1) - self.user2 = self.new_user_ref( - domain_id=self.domain['id']) - self.user2['password'] = uuid.uuid4().hex - self.identity_api.create_user(self.user1['id'], self.user2) - self.put('/groups/%(group_id)s/users/%(user_id)s' % { - 'group_id': self.group_id, 'user_id': self.user1['id']}) - - #Scenarios below are written to test the default policy configuration - - #One should be allowed to list one's own groups - auth = self.build_authentication_request( - user_id=self.user1['id'], - password=self.user1['password']) - r = self.get('/users/%(user_id)s/groups' % { - 'user_id': self.user1['id']}, auth=auth) - self.assertValidGroupListResponse(r, ref=self.group) - - #Administrator is allowed to list others' groups - r = self.get('/users/%(user_id)s/groups' % { - 'user_id': self.user1['id']}) - self.assertValidGroupListResponse(r, ref=self.group) - - #Ordinary users should not be allowed to list other's groups - auth = self.build_authentication_request( - user_id=self.user2['id'], - password=self.user2['password']) - r = self.get('/users/%(user_id)s/groups' % { - 'user_id': self.user1['id']}, auth=auth, - expected_status=exception.ForbiddenAction.code) - - def test_check_user_in_group(self): - """Call ``HEAD /groups/{group_id}/users/{user_id}``.""" - self.put('/groups/%(group_id)s/users/%(user_id)s' % { - 'group_id': self.group_id, 'user_id': self.user['id']}) - self.head('/groups/%(group_id)s/users/%(user_id)s' % { - 'group_id': self.group_id, 'user_id': self.user['id']}) - - def test_list_users_in_group(self): - """Call ``GET /groups/{group_id}/users``.""" - r = self.put('/groups/%(group_id)s/users/%(user_id)s' % { - 'group_id': self.group_id, 'user_id': self.user['id']}) - r = self.get('/groups/%(group_id)s/users' % { - 'group_id': self.group_id}) - self.assertValidUserListResponse(r, ref=self.user) - self.assertIn('/groups/%(group_id)s/users' % { - 'group_id': self.group_id}, r.result['links']['self']) - - def test_remove_user_from_group(self): - """Call ``DELETE /groups/{group_id}/users/{user_id}``.""" - self.put('/groups/%(group_id)s/users/%(user_id)s' % { - 'group_id': self.group_id, 'user_id': self.user['id']}) - self.delete('/groups/%(group_id)s/users/%(user_id)s' % { - 'group_id': self.group_id, 'user_id': self.user['id']}) - - def test_update_user(self): - """Call ``PATCH /users/{user_id}``.""" - user = self.new_user_ref(domain_id=self.domain_id) - del user['id'] - r = self.patch('/users/%(user_id)s' % { - 'user_id': self.user['id']}, - body={'user': user}) - self.assertValidUserResponse(r, user) - - def test_delete_user(self): - """Call ``DELETE /users/{user_id}``. - - As well as making sure the delete succeeds, we ensure - that any credentials that reference this user are - also deleted, while other credentials are unaffected. - In addition, no tokens should remain valid for this user. - - """ - # First check the credential for this user is present - r = self.credential_api.get_credential(self.credential['id']) - self.assertDictEqual(r, self.credential) - # Create a second credential with a different user - self.user2 = self.new_user_ref( - domain_id=self.domain['id'], - project_id=self.project['id']) - self.identity_api.create_user(self.user2['id'], self.user2) - self.credential2 = self.new_credential_ref( - user_id=self.user2['id'], - project_id=self.project['id']) - self.credential_api.create_credential( - self.credential2['id'], - self.credential2) - # Create a token for this user which we can check later - # gets deleted - auth_data = self.build_authentication_request( - user_id=self.user['id'], - password=self.user['password'], - project_id=self.project['id']) - resp = self.post('/auth/tokens', body=auth_data) - token = resp.headers.get('X-Subject-Token') - # Confirm token is valid for now - self.head('/auth/tokens', - headers={'X-Subject-Token': token}, - expected_status=204) - - # Now delete the user - self.delete('/users/%(user_id)s' % { - 'user_id': self.user['id']}) - - # Deleting the user should have deleted any credentials - # that reference this project - self.assertRaises(exception.CredentialNotFound, - self.credential_api.get_credential, - self.credential['id']) - # And the no tokens we remain valid - tokens = self.token_api.list_tokens(self.user['id']) - self.assertEquals(len(tokens), 0) - # But the credential for user2 is unaffected - r = self.credential_api.get_credential(self.credential2['id']) - self.assertDictEqual(r, self.credential2) - - # group crud tests - - def test_create_group(self): - """Call ``POST /groups``.""" - ref = self.new_group_ref(domain_id=self.domain_id) - r = self.post( - '/groups', - body={'group': ref}) - return self.assertValidGroupResponse(r, ref) - - def test_create_group_400(self): - """Call ``POST /groups``.""" - self.post('/groups', body={'group': {}}, expected_status=400) - - def test_list_groups(self): - """Call ``GET /groups``.""" - r = self.get('/groups') - self.assertValidGroupListResponse(r, ref=self.group) - - def test_list_groups_xml(self): - """Call ``GET /groups`` (xml data).""" - r = self.get('/groups', content_type='xml') - self.assertValidGroupListResponse(r, ref=self.group) - - def test_get_group(self): - """Call ``GET /groups/{group_id}``.""" - r = self.get('/groups/%(group_id)s' % { - 'group_id': self.group_id}) - self.assertValidGroupResponse(r, self.group) - - def test_update_group(self): - """Call ``PATCH /groups/{group_id}``.""" - group = self.new_group_ref(domain_id=self.domain_id) - del group['id'] - r = self.patch('/groups/%(group_id)s' % { - 'group_id': self.group_id}, - body={'group': group}) - self.assertValidGroupResponse(r, group) - - def test_delete_group(self): - """Call ``DELETE /groups/{group_id}``.""" - self.delete('/groups/%(group_id)s' % { - 'group_id': self.group_id}) - - # role crud tests - - def test_create_role(self): - """Call ``POST /roles``.""" - ref = self.new_role_ref() - r = self.post( - '/roles', - body={'role': ref}) - return self.assertValidRoleResponse(r, ref) - - def test_create_role_400(self): - """Call ``POST /roles``.""" - self.post('/roles', body={'role': {}}, expected_status=400) - - def test_list_roles(self): - """Call ``GET /roles``.""" - r = self.get('/roles') - self.assertValidRoleListResponse(r, ref=self.role) - - def test_list_roles_xml(self): - """Call ``GET /roles`` (xml data).""" - r = self.get('/roles', content_type='xml') - self.assertValidRoleListResponse(r, ref=self.role) - - def test_get_role(self): - """Call ``GET /roles/{role_id}``.""" - r = self.get('/roles/%(role_id)s' % { - 'role_id': self.role_id}) - self.assertValidRoleResponse(r, self.role) - - def test_update_role(self): - """Call ``PATCH /roles/{role_id}``.""" - ref = self.new_role_ref() - del ref['id'] - r = self.patch('/roles/%(role_id)s' % { - 'role_id': self.role_id}, - body={'role': ref}) - self.assertValidRoleResponse(r, ref) - - def test_delete_role(self): - """Call ``DELETE /roles/{role_id}``.""" - self.delete('/roles/%(role_id)s' % { - 'role_id': self.role_id}) - - def test_crud_user_project_role_grants(self): - collection_url = ( - '/projects/%(project_id)s/users/%(user_id)s/roles' % { - 'project_id': self.project['id'], - 'user_id': self.user['id']}) - member_url = '%(collection_url)s/%(role_id)s' % { - 'collection_url': collection_url, - 'role_id': self.role_id} - - self.put(member_url) - self.head(member_url) - r = self.get(collection_url) - self.assertValidRoleListResponse(r, ref=self.role) - self.assertIn(collection_url, r.result['links']['self']) - - # FIXME(gyee): this test is no longer valid as user - # have no role in the project. Can't get a scoped token - #self.delete(member_url) - #r = self.get(collection_url) - #self.assertValidRoleListResponse(r, expected_length=0) - #self.assertIn(collection_url, r.result['links']['self']) - - def test_crud_user_domain_role_grants(self): - collection_url = ( - '/domains/%(domain_id)s/users/%(user_id)s/roles' % { - 'domain_id': self.domain_id, - 'user_id': self.user['id']}) - member_url = '%(collection_url)s/%(role_id)s' % { - 'collection_url': collection_url, - 'role_id': self.role_id} - - self.put(member_url) - self.head(member_url) - r = self.get(collection_url) - self.assertValidRoleListResponse(r, ref=self.role) - self.assertIn(collection_url, r.result['links']['self']) - - self.delete(member_url) - r = self.get(collection_url) - self.assertValidRoleListResponse(r, expected_length=0) - self.assertIn(collection_url, r.result['links']['self']) - - def test_crud_group_project_role_grants(self): - collection_url = ( - '/projects/%(project_id)s/groups/%(group_id)s/roles' % { - 'project_id': self.project_id, - 'group_id': self.group_id}) - member_url = '%(collection_url)s/%(role_id)s' % { - 'collection_url': collection_url, - 'role_id': self.role_id} - - self.put(member_url) - self.head(member_url) - r = self.get(collection_url) - self.assertValidRoleListResponse(r, ref=self.role) - self.assertIn(collection_url, r.result['links']['self']) - - self.delete(member_url) - r = self.get(collection_url) - self.assertValidRoleListResponse(r, expected_length=0) - self.assertIn(collection_url, r.result['links']['self']) - - def test_crud_group_domain_role_grants(self): - collection_url = ( - '/domains/%(domain_id)s/groups/%(group_id)s/roles' % { - 'domain_id': self.domain_id, - 'group_id': self.group_id}) - member_url = '%(collection_url)s/%(role_id)s' % { - 'collection_url': collection_url, - 'role_id': self.role_id} - - self.put(member_url) - self.head(member_url) - r = self.get(collection_url) - self.assertValidRoleListResponse(r, ref=self.role) - self.assertIn(collection_url, r.result['links']['self']) - - self.delete(member_url) - r = self.get(collection_url) - self.assertValidRoleListResponse(r, expected_length=0) - self.assertIn(collection_url, r.result['links']['self']) - - def test_get_role_assignments(self): - """Call ``GET /role_assignments``. - - The sample data set up already has a user, group and project - that is part of self.domain. We use these plus a new user - we create as our data set, making sure we ignore any - role assignments that are already in existence. - - Since we don't yet support a first class entity for role - assignments, we are only testing the LIST API. To create - and delete the role assignments we use the old grant APIs. - - Test Plan: - - Create extra user for tests - - Get a list of all existing role assignments - - Add a new assignment for each of the four combinations, i.e. - group+domain, user+domain, group+project, user+project, using - the same role each time - - Get a new list of all role assignments, checking these four new - ones have been added - - Then delete the four we added - - Get a new list of all role assignments, checking the four have - been removed - - """ - - # Since the default fixtures already assign some roles to the - # user it creates, we also need a new user that will not have any - # existing assignments - self.user1 = self.new_user_ref( - domain_id=self.domain['id']) - self.user1['password'] = uuid.uuid4().hex - self.identity_api.create_user(self.user1['id'], self.user1) - - collection_url = '/role_assignments' - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertIn(collection_url, r.result['links']['self']) - existing_assignments = len(r.result.get('role_assignments')) - - # Now add one of each of the four types of assignment, making sure - # that we get them all back. - gd_url, gd_entity = _build_role_assignment_url_and_entity( - domain_id=self.domain_id, group_id=self.group_id, - role_id=self.role_id) - self.put(gd_url) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), - existing_assignments + 1) - self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) - - ud_url, ud_entity = _build_role_assignment_url_and_entity( - domain_id=self.domain_id, user_id=self.user1['id'], - role_id=self.role_id) - self.put(ud_url) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), - existing_assignments + 2) - self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url) - - gp_url, gp_entity = _build_role_assignment_url_and_entity( - project_id=self.project_id, group_id=self.group_id, - role_id=self.role_id) - self.put(gp_url) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), - existing_assignments + 3) - self.assertRoleAssignmentInListResponse(r, gp_entity, link_url=gp_url) - - up_url, up_entity = _build_role_assignment_url_and_entity( - project_id=self.project_id, user_id=self.user1['id'], - role_id=self.role_id) - self.put(up_url) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), - existing_assignments + 4) - self.assertRoleAssignmentInListResponse(r, up_entity, link_url=up_url) - - # Now delete the four we added and make sure they are removed - # from the collection. - - self.delete(gd_url) - self.delete(ud_url) - self.delete(gp_url) - self.delete(up_url) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), - existing_assignments) - self.assertRoleAssignmentNotInListResponse(r, gd_entity) - self.assertRoleAssignmentNotInListResponse(r, ud_entity) - self.assertRoleAssignmentNotInListResponse(r, gp_entity) - self.assertRoleAssignmentNotInListResponse(r, up_entity) - - def test_get_effective_role_assignments(self): - """Call ``GET /role_assignments?effective``. - - Test Plan: - - Create two extra user for tests - - Add these users to a group - - Add a role assignment for the group on a domain - - Get a list of all role assignments, checking one has been added - - Then get a list of all effective role assignments - the group - assignment should have turned into assignments on the domain - for each of the group members. - - """ - self.user1 = self.new_user_ref( - domain_id=self.domain['id']) - self.user1['password'] = uuid.uuid4().hex - self.identity_api.create_user(self.user1['id'], self.user1) - self.user2 = self.new_user_ref( - domain_id=self.domain['id']) - self.user2['password'] = uuid.uuid4().hex - self.identity_api.create_user(self.user2['id'], self.user2) - self.identity_api.add_user_to_group(self.user1['id'], self.group['id']) - self.identity_api.add_user_to_group(self.user2['id'], self.group['id']) - - collection_url = '/role_assignments' - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertIn(collection_url, r.result['links']['self']) - existing_assignments = len(r.result.get('role_assignments')) - - gd_url, gd_entity = _build_role_assignment_url_and_entity( - domain_id=self.domain_id, group_id=self.group_id, - role_id=self.role_id) - self.put(gd_url) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), - existing_assignments + 1) - self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) - - # Now re-read the collection asking for effective roles - this - # should mean the group assignment is translated into the two - # member user assignments - collection_url = '/role_assignments?effective' - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), - existing_assignments + 2) - unused, ud_entity = _build_role_assignment_url_and_entity( - domain_id=self.domain_id, user_id=self.user1['id'], - role_id=self.role_id) - gd_url, unused = _build_role_assignment_url_and_entity( - domain_id=self.domain_id, group_id=self.group['id'], - role_id=self.role_id) - self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=gd_url) - ud_url, ud_entity = _build_role_assignment_url_and_entity( - domain_id=self.domain_id, user_id=self.user2['id'], - role_id=self.role_id) - self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=gd_url) - - def test_check_effective_values_for_role_assignments(self): - """Call ``GET /role_assignments?effective=value``. - - Check the various ways of specifying the 'effective' - query parameter. If the 'effective' query parameter - is included then this should always be treated as - as meaning 'True' unless it is specified as: - - {url}?effective=0 - - This is by design to match the agreed way of handling - policy checking on query/filter parameters. - - Test Plan: - - Create two extra user for tests - - Add these users to a group - - Add a role assignment for the group on a domain - - Get a list of all role assignments, checking one has been added - - Then issue various request with different ways of defining - the 'effective' query parameter. As we have tested the - correctness of the data coming back when we get effective roles - in other tests, here we just use the count of entities to - know if we are getting effective roles or not - - """ - self.user1 = self.new_user_ref( - domain_id=self.domain['id']) - self.user1['password'] = uuid.uuid4().hex - self.identity_api.create_user(self.user1['id'], self.user1) - self.user2 = self.new_user_ref( - domain_id=self.domain['id']) - self.user2['password'] = uuid.uuid4().hex - self.identity_api.create_user(self.user2['id'], self.user2) - self.identity_api.add_user_to_group(self.user1['id'], self.group['id']) - self.identity_api.add_user_to_group(self.user2['id'], self.group['id']) - - collection_url = '/role_assignments' - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - existing_assignments = len(r.result.get('role_assignments')) - - gd_url, gd_entity = _build_role_assignment_url_and_entity( - domain_id=self.domain_id, group_id=self.group_id, - role_id=self.role_id) - self.put(gd_url) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), - existing_assignments + 1) - self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) - - # Now re-read the collection asking for effective roles, - # using the most common way of defining "effective'. This - # should mean the group assignment is translated into the two - # member user assignments - collection_url = '/role_assignments?effective' - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), - existing_assignments + 2) - # Now set 'effective' to false explicitly - should get - # back the regular roles - collection_url = '/role_assignments?effective=0' - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), - existing_assignments + 1) - # Now try setting 'effective' to 'False' explicitly- this is - # NOT supported as a way of setting a query or filter - # parameter to false by design. Hence we should get back - # effective roles. - collection_url = '/role_assignments?effective=False' - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), - existing_assignments + 2) - # Now set 'effective' to True explicitly - collection_url = '/role_assignments?effective=True' - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), - existing_assignments + 2) - - def test_filtered_role_assignments(self): - """Call ``GET /role_assignments?filters``. - - Test Plan: - - Create extra users, group, role and project for tests - - Make the following assignments: - Give group1, role1 on project1 and domain - Give user1, role2 on project1 and domain - Make User1 a member of Group1 - - Test a series of single filter list calls, checking that - the correct results are obtained - - Test a multi-filtered list call - - Test listing all effective roles for a given user - - Test the equivalent of the list of roles in a project scoped - token (all effective roles for a user on a project) - - """ - - # Since the default fixtures already assign some roles to the - # user it creates, we also need a new user that will not have any - # existing assignments - self.user1 = self.new_user_ref( - domain_id=self.domain['id']) - self.user1['password'] = uuid.uuid4().hex - self.identity_api.create_user(self.user1['id'], self.user1) - self.user2 = self.new_user_ref( - domain_id=self.domain['id']) - self.user2['password'] = uuid.uuid4().hex - self.identity_api.create_user(self.user2['id'], self.user2) - self.group1 = self.new_group_ref( - domain_id=self.domain['id']) - self.identity_api.create_group(self.group1['id'], self.group1) - self.identity_api.add_user_to_group(self.user1['id'], - self.group1['id']) - self.identity_api.add_user_to_group(self.user2['id'], - self.group1['id']) - self.project1 = self.new_project_ref( - domain_id=self.domain['id']) - self.identity_api.create_project(self.project1['id'], self.project1) - self.role1 = self.new_role_ref() - self.identity_api.create_role(self.role1['id'], self.role1) - self.role2 = self.new_role_ref() - self.identity_api.create_role(self.role2['id'], self.role2) - - # Now add one of each of the four types of assignment - - gd_url, gd_entity = _build_role_assignment_url_and_entity( - domain_id=self.domain_id, group_id=self.group1['id'], - role_id=self.role1['id']) - self.put(gd_url) - - ud_url, ud_entity = _build_role_assignment_url_and_entity( - domain_id=self.domain_id, user_id=self.user1['id'], - role_id=self.role2['id']) - self.put(ud_url) - - gp_url, gp_entity = _build_role_assignment_url_and_entity( - project_id=self.project1['id'], group_id=self.group1['id'], - role_id=self.role1['id']) - self.put(gp_url) - - up_url, up_entity = _build_role_assignment_url_and_entity( - project_id=self.project1['id'], user_id=self.user1['id'], - role_id=self.role2['id']) - self.put(up_url) - - # Now list by various filters to make sure we get back the right ones - - collection_url = ('/role_assignments?scope.project.id=%s' % - self.project1['id']) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), 2) - self.assertRoleAssignmentInListResponse(r, up_entity, link_url=up_url) - self.assertRoleAssignmentInListResponse(r, gp_entity, link_url=gp_url) - - collection_url = ('/role_assignments?scope.domain.id=%s' % - self.domain['id']) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), 2) - self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url) - self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) - - collection_url = '/role_assignments?user.id=%s' % self.user1['id'] - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), 2) - self.assertRoleAssignmentInListResponse(r, up_entity, link_url=up_url) - self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url) - - collection_url = '/role_assignments?group.id=%s' % self.group1['id'] - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), 2) - self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) - self.assertRoleAssignmentInListResponse(r, gp_entity, link_url=gp_url) - - collection_url = '/role_assignments?role.id=%s' % self.role1['id'] - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), 2) - self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) - self.assertRoleAssignmentInListResponse(r, gp_entity, link_url=gp_url) - - # Let's try combining two filers together.... - - collection_url = ( - '/role_assignments?user.id=%(user_id)s' - '&scope.project.id=%(project_id)s' % { - 'user_id': self.user1['id'], - 'project_id': self.project1['id']}) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), 1) - self.assertRoleAssignmentInListResponse(r, up_entity, link_url=up_url) - - # Now for a harder one - filter for user with effective - # roles - this should return role assignment that were directly - # assigned as well as by virtue of group membership - - collection_url = ('/role_assignments?effective&user.id=%s' % - self.user1['id']) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), 4) - # Should have the two direct roles... - self.assertRoleAssignmentInListResponse(r, up_entity, link_url=up_url) - self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url) - # ...and the two via group membership... - unused, up1_entity = _build_role_assignment_url_and_entity( - project_id=self.project1['id'], user_id=self.user1['id'], - role_id=self.role1['id']) - unused, ud1_entity = _build_role_assignment_url_and_entity( - domain_id=self.domain_id, user_id=self.user1['id'], - role_id=self.role1['id']) - gp1_url, unused = _build_role_assignment_url_and_entity( - project_id=self.project1['id'], group_id=self.group1['id'], - role_id=self.role1['id']) - gd1_url, unused = _build_role_assignment_url_and_entity( - domain_id=self.domain_id, group_id=self.group1['id'], - role_id=self.role1['id']) - self.assertRoleAssignmentInListResponse(r, up1_entity, - link_url=gp1_url) - self.assertRoleAssignmentInListResponse(r, ud1_entity, - link_url=gd1_url) - - # ...and for the grand-daddy of them all, simulate the request - # that would generate the list of effective roles in a project - # scoped token. - - collection_url = ( - '/role_assignments?effective&user.id=%(user_id)s' - '&scope.project.id=%(project_id)s' % { - 'user_id': self.user1['id'], - 'project_id': self.project1['id']}) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), 2) - # Should have one direct role and one from group membership... - self.assertRoleAssignmentInListResponse(r, up_entity, link_url=up_url) - self.assertRoleAssignmentInListResponse(r, up1_entity, - link_url=gp1_url) - - -class IdentityIneritanceTestCase(test_v3.RestfulTestCase): - """Test inheritance crud and its effects.""" - - def setUp(self): - self.orig_extension_enablement = config.CONF.os_inherit.enabled - self.opt_in_group('os_inherit', enabled=True) - super(IdentityIneritanceTestCase, self).setUp() - - def tearDown(self): - super(IdentityIneritanceTestCase, self).tearDown() - self.opt_in_group('os_inherit', enabled=self.orig_extension_enablement) - - def test_crud_user_inherited_domain_role_grants(self): - role_list = [] - for _ in range(2): - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.assignment_api.create_role(role['id'], role) - role_list.append(role) - - # Create a non-inherited role as a spoiler - self.assignment_api.create_grant( - role_list[1]['id'], user_id=self.user['id'], - domain_id=self.domain_id) - - base_collection_url = ( - '/OS-INHERIT/domains/%(domain_id)s/users/%(user_id)s/roles' % { - 'domain_id': self.domain_id, - 'user_id': self.user['id']}) - member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { - 'collection_url': base_collection_url, - 'role_id': role_list[0]['id']} - collection_url = base_collection_url + '/inherited_to_projects' - - self.put(member_url) - - # Check we can read it back - self.head(member_url) - r = self.get(collection_url) - self.assertValidRoleListResponse(r, ref=role_list[0]) - self.assertIn(collection_url, r.result['links']['self']) - - # Now delete and check its gone - self.delete(member_url) - r = self.get(collection_url) - self.assertValidRoleListResponse(r, expected_length=0) - self.assertIn(collection_url, r.result['links']['self']) - - def test_crud_inherited_role_grants_failed_if_disabled(self): - # Disable the extension and check no API calls can be issued - self.opt_in_group('os_inherit', enabled=False) - super(IdentityIneritanceTestCase, self).setUp() - - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.assignment_api.create_role(role['id'], role) - - base_collection_url = ( - '/OS-INHERIT/domains/%(domain_id)s/users/%(user_id)s/roles' % { - 'domain_id': self.domain_id, - 'user_id': self.user['id']}) - member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { - 'collection_url': base_collection_url, - 'role_id': role['id']} - collection_url = base_collection_url + '/inherited_to_projects' - - self.put(member_url, expected_status=404) - self.head(member_url, expected_status=404) - self.get(collection_url, expected_status=404) - self.delete(member_url, expected_status=404) - - def test_list_role_assignments_for_inherited_domain_grants(self): - """Call ``GET /role_assignments with inherited domain grants``. - - Test Plan: - - Create 4 roles - - Create a domain with a user and two projects - - Assign two direct roles to project1 - - Assign a spoiler role to project2 - - Issue the URL to add inherited role to the domain - - Issue the URL to check it is indeed on the domain - - Issue the URL to check effective roles on project1 - this - should return 3 roles. - - """ - role_list = [] - for _ in range(4): - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.assignment_api.create_role(role['id'], role) - role_list.append(role) - - domain = self.new_domain_ref() - self.identity_api.create_domain(domain['id'], domain) - user1 = self.new_user_ref( - domain_id=domain['id']) - user1['password'] = uuid.uuid4().hex - self.identity_api.create_user(user1['id'], user1) - project1 = self.new_project_ref( - domain_id=domain['id']) - self.assignment_api.create_project(project1['id'], project1) - project2 = self.new_project_ref( - domain_id=domain['id']) - self.assignment_api.create_project(project2['id'], project2) - # Add some roles to the project - self.assignment_api.add_role_to_user_and_project( - user1['id'], project1['id'], role_list[0]['id']) - self.assignment_api.add_role_to_user_and_project( - user1['id'], project1['id'], role_list[1]['id']) - # ..and one on a different project as a spoiler - self.assignment_api.add_role_to_user_and_project( - user1['id'], project2['id'], role_list[2]['id']) - - # Now create our inherited role on the domain - base_collection_url = ( - '/OS-INHERIT/domains/%(domain_id)s/users/%(user_id)s/roles' % { - 'domain_id': domain['id'], - 'user_id': user1['id']}) - member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { - 'collection_url': base_collection_url, - 'role_id': role_list[3]['id']} - collection_url = base_collection_url + '/inherited_to_projects' - - self.put(member_url) - self.head(member_url) - r = self.get(collection_url) - self.assertValidRoleListResponse(r, ref=role_list[3]) - self.assertIn(collection_url, r.result['links']['self']) - - # Now use the list domain role assignments api to check if this - # is included - collection_url = ( - '/role_assignments?user.id=%(user_id)s' - '&scope.domain.id=%(domain_id)s' % { - 'user_id': user1['id'], - 'domain_id': domain['id']}) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), 1) - ud_url, ud_entity = _build_role_assignment_url_and_entity( - domain_id=domain['id'], user_id=user1['id'], - role_id=role_list[3]['id'], inherited_to_projects=True) - self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url) - - # Now ask for effective list role assignments - the role should - # turn into a project role, along with the two direct roles that are - # on the project - collection_url = ( - '/role_assignments?effective&user.id=%(user_id)s' - '&scope.project.id=%(project_id)s' % { - 'user_id': user1['id'], - 'project_id': project1['id']}) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), 3) - # An effective role for an inherited role will be a project - # entity, with a domain link to the inherited assignment - unused, up_entity = _build_role_assignment_url_and_entity( - project_id=project1['id'], user_id=user1['id'], - role_id=role_list[3]['id']) - ud_url, unused = _build_role_assignment_url_and_entity( - domain_id=domain['id'], user_id=user1['id'], - role_id=role_list[3]['id'], inherited_to_projects=True) - self.assertRoleAssignmentInListResponse(r, up_entity, link_url=ud_url) - - def test_list_role_assignments_for_disabled_inheritance_extension(self): - """Call ``GET /role_assignments with inherited domain grants``. - - Test Plan: - - Issue the URL to add inherited role to the domain - - Issue the URL to check effective roles on project include the - inherited role - - Disable the extension - - Re-check the effective roles, proving the inherited role no longer - shows up. - - """ - - role_list = [] - for _ in range(4): - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.assignment_api.create_role(role['id'], role) - role_list.append(role) - - domain = self.new_domain_ref() - self.identity_api.create_domain(domain['id'], domain) - user1 = self.new_user_ref( - domain_id=domain['id']) - user1['password'] = uuid.uuid4().hex - self.identity_api.create_user(user1['id'], user1) - project1 = self.new_project_ref( - domain_id=domain['id']) - self.assignment_api.create_project(project1['id'], project1) - project2 = self.new_project_ref( - domain_id=domain['id']) - self.assignment_api.create_project(project2['id'], project2) - # Add some roles to the project - self.assignment_api.add_role_to_user_and_project( - user1['id'], project1['id'], role_list[0]['id']) - self.assignment_api.add_role_to_user_and_project( - user1['id'], project1['id'], role_list[1]['id']) - # ..and one on a different project as a spoiler - self.assignment_api.add_role_to_user_and_project( - user1['id'], project2['id'], role_list[2]['id']) - - # Now create our inherited role on the domain - base_collection_url = ( - '/OS-INHERIT/domains/%(domain_id)s/users/%(user_id)s/roles' % { - 'domain_id': domain['id'], - 'user_id': user1['id']}) - member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { - 'collection_url': base_collection_url, - 'role_id': role_list[3]['id']} - collection_url = base_collection_url + '/inherited_to_projects' - - self.put(member_url) - self.head(member_url) - r = self.get(collection_url) - self.assertValidRoleListResponse(r, ref=role_list[3]) - self.assertIn(collection_url, r.result['links']['self']) - - # Get effective list role assignments - the role should - # turn into a project role, along with the two direct roles that are - # on the project - collection_url = ( - '/role_assignments?effective&user.id=%(user_id)s' - '&scope.project.id=%(project_id)s' % { - 'user_id': user1['id'], - 'project_id': project1['id']}) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), 3) - - unused, up_entity = _build_role_assignment_url_and_entity( - project_id=project1['id'], user_id=user1['id'], - role_id=role_list[3]['id']) - ud_url, unused = _build_role_assignment_url_and_entity( - domain_id=domain['id'], user_id=user1['id'], - role_id=role_list[3]['id'], inherited_to_projects=True) - self.assertRoleAssignmentInListResponse(r, up_entity, link_url=ud_url) - - # Disable the extension and re-check the list, the role inherited - # from the project should no longer show up - self.opt_in_group('os_inherit', enabled=False) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), 2) - - unused, up_entity = _build_role_assignment_url_and_entity( - project_id=project1['id'], user_id=user1['id'], - role_id=role_list[3]['id']) - ud_url, unused = _build_role_assignment_url_and_entity( - domain_id=domain['id'], user_id=user1['id'], - role_id=role_list[3]['id'], inherited_to_projects=True) - self.assertRoleAssignmentNotInListResponse(r, up_entity, - link_url=ud_url) - - def test_list_role_assignments_for_inherited_group_domain_grants(self): - """Call ``GET /role_assignments with inherited group domain grants``. - - Test Plan: - - Create 4 roles - - Create a domain with a user and two projects - - Assign two direct roles to project1 - - Assign a spoiler role to project2 - - Issue the URL to add inherited role to the domain - - Issue the URL to check it is indeed on the domain - - Issue the URL to check effective roles on project1 - this - should return 3 roles. - - """ - role_list = [] - for _ in range(4): - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.assignment_api.create_role(role['id'], role) - role_list.append(role) - - domain = self.new_domain_ref() - self.identity_api.create_domain(domain['id'], domain) - user1 = self.new_user_ref( - domain_id=domain['id']) - user1['password'] = uuid.uuid4().hex - self.identity_api.create_user(user1['id'], user1) - user2 = self.new_user_ref( - domain_id=domain['id']) - user2['password'] = uuid.uuid4().hex - self.identity_api.create_user(user2['id'], user2) - group1 = self.new_group_ref( - domain_id=domain['id']) - self.identity_api.create_group(group1['id'], group1) - self.identity_api.add_user_to_group(user1['id'], - group1['id']) - self.identity_api.add_user_to_group(user2['id'], - group1['id']) - project1 = self.new_project_ref( - domain_id=domain['id']) - self.assignment_api.create_project(project1['id'], project1) - project2 = self.new_project_ref( - domain_id=domain['id']) - self.assignment_api.create_project(project2['id'], project2) - # Add some roles to the project - self.assignment_api.add_role_to_user_and_project( - user1['id'], project1['id'], role_list[0]['id']) - self.assignment_api.add_role_to_user_and_project( - user1['id'], project1['id'], role_list[1]['id']) - # ..and one on a different project as a spoiler - self.assignment_api.add_role_to_user_and_project( - user1['id'], project2['id'], role_list[2]['id']) - - # Now create our inherited role on the domain - base_collection_url = ( - '/OS-INHERIT/domains/%(domain_id)s/groups/%(group_id)s/roles' % { - 'domain_id': domain['id'], - 'group_id': group1['id']}) - member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { - 'collection_url': base_collection_url, - 'role_id': role_list[3]['id']} - collection_url = base_collection_url + '/inherited_to_projects' - - self.put(member_url) - self.head(member_url) - r = self.get(collection_url) - self.assertValidRoleListResponse(r, ref=role_list[3]) - self.assertIn(collection_url, r.result['links']['self']) - - # Now use the list domain role assignments api to check if this - # is included - collection_url = ( - '/role_assignments?group.id=%(group_id)s' - '&scope.domain.id=%(domain_id)s' % { - 'group_id': group1['id'], - 'domain_id': domain['id']}) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), 1) - gd_url, gd_entity = _build_role_assignment_url_and_entity( - domain_id=domain['id'], group_id=group1['id'], - role_id=role_list[3]['id'], inherited_to_projects=True) - self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) - - # Now ask for effective list role assignments - the role should - # turn into a user project role, along with the two direct roles - # that are on the project - collection_url = ( - '/role_assignments?effective&user.id=%(user_id)s' - '&scope.project.id=%(project_id)s' % { - 'user_id': user1['id'], - 'project_id': project1['id']}) - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), 3) - # An effective role for an inherited role will be a project - # entity, with a domain link to the inherited assignment - unused, up_entity = _build_role_assignment_url_and_entity( - project_id=project1['id'], user_id=user1['id'], - role_id=role_list[3]['id']) - gd_url, unused = _build_role_assignment_url_and_entity( - domain_id=domain['id'], group_id=group1['id'], - role_id=role_list[3]['id'], inherited_to_projects=True) - self.assertRoleAssignmentInListResponse(r, up_entity, link_url=gd_url) - - def test_filtered_role_assignments_for_inherited_grants(self): - """Call ``GET /role_assignments?scope.OS-INHERIT:inherited_to``. - - Test Plan: - - Create 5 roles - - Create a domain with a user, group and two projects - - Assign three direct spoiler roles to projects - - Issue the URL to add an inherited user role to the domain - - Issue the URL to add an inherited group role to the domain - - Issue the URL to filter by inherited roles - this should - return just the 2 inherited roles. - - """ - role_list = [] - for _ in range(5): - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.assignment_api.create_role(role['id'], role) - role_list.append(role) - - domain = self.new_domain_ref() - self.identity_api.create_domain(domain['id'], domain) - user1 = self.new_user_ref( - domain_id=domain['id']) - user1['password'] = uuid.uuid4().hex - self.identity_api.create_user(user1['id'], user1) - group1 = self.new_group_ref( - domain_id=domain['id']) - self.identity_api.create_group(group1['id'], group1) - project1 = self.new_project_ref( - domain_id=domain['id']) - self.assignment_api.create_project(project1['id'], project1) - project2 = self.new_project_ref( - domain_id=domain['id']) - self.assignment_api.create_project(project2['id'], project2) - # Add some spoiler roles to the projects - self.assignment_api.add_role_to_user_and_project( - user1['id'], project1['id'], role_list[0]['id']) - self.assignment_api.add_role_to_user_and_project( - user1['id'], project2['id'], role_list[1]['id']) - # Create a non-inherited role as a spoiler - self.assignment_api.create_grant( - role_list[2]['id'], user_id=user1['id'], domain_id=domain['id']) - - # Now create two inherited roles on the domain, one for a user - # and one for a domain - base_collection_url = ( - '/OS-INHERIT/domains/%(domain_id)s/users/%(user_id)s/roles' % { - 'domain_id': domain['id'], - 'user_id': user1['id']}) - member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { - 'collection_url': base_collection_url, - 'role_id': role_list[3]['id']} - collection_url = base_collection_url + '/inherited_to_projects' - - self.put(member_url) - self.head(member_url) - r = self.get(collection_url) - self.assertValidRoleListResponse(r, ref=role_list[3]) - self.assertIn(collection_url, r.result['links']['self']) - - base_collection_url = ( - '/OS-INHERIT/domains/%(domain_id)s/groups/%(group_id)s/roles' % { - 'domain_id': domain['id'], - 'group_id': group1['id']}) - member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { - 'collection_url': base_collection_url, - 'role_id': role_list[4]['id']} - collection_url = base_collection_url + '/inherited_to_projects' - - self.put(member_url) - self.head(member_url) - r = self.get(collection_url) - self.assertValidRoleListResponse(r, ref=role_list[4]) - self.assertIn(collection_url, r.result['links']['self']) - - # Now use the list role assignments api to get a list of inherited - # roles on the domain - should get back the two roles - collection_url = ( - '/role_assignments?scope.OS-INHERIT:inherited_to=projects') - r = self.get(collection_url) - self.assertValidRoleAssignmentListResponse(r) - self.assertEqual(len(r.result.get('role_assignments')), 2) - ud_url, ud_entity = _build_role_assignment_url_and_entity( - domain_id=domain['id'], user_id=user1['id'], - role_id=role_list[3]['id'], inherited_to_projects=True) - gd_url, gd_entity = _build_role_assignment_url_and_entity( - domain_id=domain['id'], group_id=group1['id'], - role_id=role_list[4]['id'], inherited_to_projects=True) - self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url) - self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) diff --git a/tests/test_v3_policy.py b/tests/test_v3_policy.py deleted file mode 100644 index d988efd2..00000000 --- a/tests/test_v3_policy.py +++ /dev/null @@ -1,59 +0,0 @@ -import uuid - -import test_v3 - - -class PolicyTestCase(test_v3.RestfulTestCase): - """Test policy CRUD.""" - - def setUp(self): - super(PolicyTestCase, self).setUp() - self.policy_id = uuid.uuid4().hex - self.policy = self.new_policy_ref() - self.policy['id'] = self.policy_id - self.policy_api.create_policy( - self.policy_id, - self.policy.copy()) - - # policy crud tests - - def test_create_policy(self): - """Call ``POST /policies``.""" - ref = self.new_policy_ref() - r = self.post( - '/policies', - body={'policy': ref}) - return self.assertValidPolicyResponse(r, ref) - - def test_list_policies(self): - """Call ``GET /policies``.""" - r = self.get('/policies') - self.assertValidPolicyListResponse(r, ref=self.policy) - - def test_list_policies_xml(self): - """Call ``GET /policies (xml data)``.""" - r = self.get('/policies', content_type='xml') - self.assertValidPolicyListResponse(r, ref=self.policy) - - def test_get_policy(self): - """Call ``GET /policies/{policy_id}``.""" - r = self.get( - '/policies/%(policy_id)s' % { - 'policy_id': self.policy_id}) - self.assertValidPolicyResponse(r, self.policy) - - def test_update_policy(self): - """Call ``PATCH /policies/{policy_id}``.""" - policy = self.new_policy_ref() - policy['id'] = self.policy_id - r = self.patch( - '/policies/%(policy_id)s' % { - 'policy_id': self.policy_id}, - body={'policy': policy}) - self.assertValidPolicyResponse(r, policy) - - def test_delete_policy(self): - """Call ``DELETE /policies/{policy_id}``.""" - self.delete( - '/policies/%(policy_id)s' % { - 'policy_id': self.policy_id}) diff --git a/tests/test_v3_protection.py b/tests/test_v3_protection.py deleted file mode 100644 index 38e32813..00000000 --- a/tests/test_v3_protection.py +++ /dev/null @@ -1,308 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack LLC -# Copyright 2013 IBM Corp. -# -# 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 tempfile -import uuid - -from keystone import config -from keystone import exception -from keystone.openstack.common import jsonutils -from keystone.policy.backends import rules - -import test_v3 - - -CONF = config.CONF -DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id - - -class IdentityTestProtectedCase(test_v3.RestfulTestCase): - """Test policy enforcement on the v3 Identity API.""" - - def setUp(self): - """Setup for Identity Protection Test Cases. - - As well as the usual housekeeping, create a set of domains, - users, roles and projects for the subsequent tests: - - - Three domains: A,B & C. C is disabled. - - DomainA has user1, DomainB has user2 and user3 - - DomainA has group1 and group2, DomainB has group3 - - User1 has a role on DomainA - - Remember that there will also be a fourth domain in existence, - the default domain. - - """ - # Ensure that test_v3.RestfulTestCase doesn't load its own - # sample data, which would make checking the results of our - # tests harder - super(IdentityTestProtectedCase, self).setUp(load_sample_data=False) - # Start by creating a couple of domains - self.domainA = self.new_domain_ref() - self.identity_api.create_domain(self.domainA['id'], self.domainA) - self.domainB = self.new_domain_ref() - self.identity_api.create_domain(self.domainB['id'], self.domainB) - self.domainC = self.new_domain_ref() - self.domainC['enabled'] = False - self.identity_api.create_domain(self.domainC['id'], self.domainC) - - # Now create some users, one in domainA and two of them in domainB - self.user1 = self.new_user_ref(domain_id=self.domainA['id']) - self.user1['password'] = uuid.uuid4().hex - self.identity_api.create_user(self.user1['id'], self.user1) - - self.user2 = self.new_user_ref(domain_id=self.domainB['id']) - self.user2['password'] = uuid.uuid4().hex - self.identity_api.create_user(self.user2['id'], self.user2) - - self.user3 = self.new_user_ref(domain_id=self.domainB['id']) - self.user3['password'] = uuid.uuid4().hex - self.identity_api.create_user(self.user3['id'], self.user3) - - self.group1 = self.new_group_ref(domain_id=self.domainA['id']) - self.identity_api.create_group(self.group1['id'], self.group1) - - self.group2 = self.new_group_ref(domain_id=self.domainA['id']) - self.identity_api.create_group(self.group2['id'], self.group2) - - self.group3 = self.new_group_ref(domain_id=self.domainB['id']) - self.identity_api.create_group(self.group3['id'], self.group3) - - self.role = self.new_role_ref() - self.identity_api.create_role(self.role['id'], self.role) - self.identity_api.create_grant(self.role['id'], - user_id=self.user1['id'], - domain_id=self.domainA['id']) - - # Initialize the policy engine and allow us to write to a temp - # file in each test to create the policies - self.orig_policy_file = CONF.policy_file - rules.reset() - _unused, self.tmpfilename = tempfile.mkstemp() - self.opt(policy_file=self.tmpfilename) - - # A default auth request we can use - un-scoped user token - self.auth = self.build_authentication_request( - user_id=self.user1['id'], - password=self.user1['password']) - - def tearDown(self): - super(IdentityTestProtectedCase, self).tearDown() - rules.reset() - self.opt(policy_file=self.orig_policy_file) - - def _get_id_list_from_ref_list(self, ref_list): - result_list = [] - for x in ref_list: - result_list.append(x['id']) - return result_list - - def _set_policy(self, new_policy): - with open(self.tmpfilename, "w") as policyfile: - policyfile.write(jsonutils.dumps(new_policy)) - - def test_list_users_unprotected(self): - """GET /users (unprotected) - - Test Plan: - - Update policy so api is unprotected - - Use an un-scoped token to make sure we can get back all - the users independent of domain - - """ - self._set_policy({"identity:list_users": []}) - r = self.get('/users', auth=self.auth) - id_list = self._get_id_list_from_ref_list(r.result.get('users')) - self.assertIn(self.user1['id'], id_list) - self.assertIn(self.user2['id'], id_list) - self.assertIn(self.user3['id'], id_list) - - def test_list_users_filtered_by_domain(self): - """GET /users?domain_id=mydomain (filtered) - - Test Plan: - - Update policy so api is unprotected - - Use an un-scoped token to make sure we can filter the - users by domainB, getting back the 2 users in that domain - - """ - self._set_policy({"identity:list_users": []}) - url_by_name = '/users?domain_id=%s' % self.domainB['id'] - r = self.get(url_by_name, auth=self.auth) - # We should get back two users, those in DomainB - id_list = self._get_id_list_from_ref_list(r.result.get('users')) - self.assertIn(self.user2['id'], id_list) - self.assertIn(self.user3['id'], id_list) - - def test_get_user_protected_match_id(self): - """GET /users/{id} (match payload) - - Test Plan: - - Update policy to protect api by user_id - - List users with user_id of user1 as filter, to check that - this will correctly match user_id in the flattened - payload - - """ - # TODO(henry-nash, ayoung): It would be good to expand this - # test for further test flattening, e.g. protect on, say, an - # attribute of an object being created - new_policy = {"identity:get_user": [["user_id:%(user_id)s"]]} - self._set_policy(new_policy) - url_by_name = '/users/%s' % self.user1['id'] - r = self.get(url_by_name, auth=self.auth) - self.assertEquals(self.user1['id'], r.result['user']['id']) - - def test_list_users_protected_by_domain(self): - """GET /users?domain_id=mydomain (protected) - - Test Plan: - - Update policy to protect api by domain_id - - List groups using a token scoped to domainA with a filter - specifying domainA - we should only get back the one user - that is in domainA. - - Try and read the users from domainB - this should fail since - we don't have a token scoped for domainB - - """ - new_policy = {"identity:list_users": ["domain_id:%(domain_id)s"]} - self._set_policy(new_policy) - self.auth = self.build_authentication_request( - user_id=self.user1['id'], - password=self.user1['password'], - domain_id=self.domainA['id']) - url_by_name = '/users?domain_id=%s' % self.domainA['id'] - r = self.get(url_by_name, auth=self.auth) - # We should only get back one user, the one in DomainA - id_list = self._get_id_list_from_ref_list(r.result.get('users')) - self.assertEqual(len(id_list), 1) - self.assertIn(self.user1['id'], id_list) - - # Now try for domainB, which should fail - url_by_name = '/users?domain_id=%s' % self.domainB['id'] - r = self.get(url_by_name, auth=self.auth, - expected_status=exception.ForbiddenAction.code) - - def test_list_groups_protected_by_domain(self): - """GET /groups?domain_id=mydomain (protected) - - Test Plan: - - Update policy to protect api by domain_id - - List groups using a token scoped to domainA and make sure - we only get back the two groups that are in domainA - - Try and read the groups from domainB - this should fail since - we don't have a token scoped for domainB - - """ - new_policy = {"identity:list_groups": ["domain_id:%(domain_id)s"]} - self._set_policy(new_policy) - self.auth = self.build_authentication_request( - user_id=self.user1['id'], - password=self.user1['password'], - domain_id=self.domainA['id']) - url_by_name = '/groups?domain_id=%s' % self.domainA['id'] - r = self.get(url_by_name, auth=self.auth) - # We should only get back two groups, the ones in DomainA - id_list = self._get_id_list_from_ref_list(r.result.get('groups')) - self.assertEqual(len(id_list), 2) - self.assertIn(self.group1['id'], id_list) - self.assertIn(self.group2['id'], id_list) - - # Now try for domainB, which should fail - url_by_name = '/groups?domain_id=%s' % self.domainB['id'] - r = self.get(url_by_name, auth=self.auth, - expected_status=exception.ForbiddenAction.code) - - def test_list_groups_protected_by_domain_and_filtered(self): - """GET /groups?domain_id=mydomain&name=myname (protected) - - Test Plan: - - Update policy to protect api by domain_id - - List groups using a token scoped to domainA with a filter - specifying both domainA and the name of group. - - We should only get back the group in domainA that matches - the name - - """ - new_policy = {"identity:list_groups": ["domain_id:%(domain_id)s"]} - self._set_policy(new_policy) - self.auth = self.build_authentication_request( - user_id=self.user1['id'], - password=self.user1['password'], - domain_id=self.domainA['id']) - url_by_name = '/groups?domain_id=%s&name=%s' % ( - self.domainA['id'], self.group2['name']) - r = self.get(url_by_name, auth=self.auth) - # We should only get back one user, the one in DomainA that matches - # the name supplied - id_list = self._get_id_list_from_ref_list(r.result.get('groups')) - self.assertEqual(len(id_list), 1) - self.assertIn(self.group2['id'], id_list) - - def test_list_filtered_domains(self): - """GET /domains?enabled=0 - - Test Plan: - - Update policy for no protection on api - - Filter by the 'enabled' boolean to get disabled domains, which - should return just domainC - - Try the filter using different ways of specifying 'true' - to test that our handling of booleans in filter matching is - correct - - """ - new_policy = {"identity:list_domains": []} - self._set_policy(new_policy) - r = self.get('/domains?enabled=0', auth=self.auth) - id_list = self._get_id_list_from_ref_list(r.result.get('domains')) - self.assertEqual(len(id_list), 1) - self.assertIn(self.domainC['id'], id_list) - - # Now try a few ways of specifying 'true' when we should get back - # the other two domains, plus the default domain - r = self.get('/domains?enabled=1', auth=self.auth) - id_list = self._get_id_list_from_ref_list(r.result.get('domains')) - self.assertEqual(len(id_list), 3) - self.assertIn(self.domainA['id'], id_list) - self.assertIn(self.domainB['id'], id_list) - self.assertIn(DEFAULT_DOMAIN_ID, id_list) - - r = self.get('/domains?enabled', auth=self.auth) - id_list = self._get_id_list_from_ref_list(r.result.get('domains')) - self.assertEqual(len(id_list), 3) - self.assertIn(self.domainA['id'], id_list) - self.assertIn(self.domainB['id'], id_list) - self.assertIn(DEFAULT_DOMAIN_ID, id_list) - - def test_multiple_filters(self): - """GET /domains?enabled&name=myname - - Test Plan: - - Update policy for no protection on api - - Filter by the 'enabled' boolean and name - this should - return a single domain - - """ - new_policy = {"identity:list_domains": []} - self._set_policy(new_policy) - - my_url = '/domains?enableds&name=%s' % self.domainA['name'] - r = self.get(my_url, auth=self.auth) - id_list = self._get_id_list_from_ref_list(r.result.get('domains')) - self.assertEqual(len(id_list), 1) - self.assertIn(self.domainA['id'], id_list) diff --git a/tests/test_versions.py b/tests/test_versions.py deleted file mode 100644 index c5864c37..00000000 --- a/tests/test_versions.py +++ /dev/null @@ -1,422 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 keystone import test - -from keystone import config -from keystone import controllers -from keystone.openstack.common import jsonutils - - -CONF = config.CONF - -v2_MEDIA_TYPES = [ - { - "base": "application/json", - "type": "application/" - "vnd.openstack.identity-v2.0+json" - }, { - "base": "application/xml", - "type": "application/" - "vnd.openstack.identity-v2.0+xml" - } -] - -v2_HTML_DESCRIPTION = { - "rel": "describedby", - "type": "text/html", - "href": "http://docs.openstack.org/api/" - "openstack-identity-service/2.0/" - "content/" -} - -v2_PDF_DESCRIPTION = { - "rel": "describedby", - "type": "application/pdf", - "href": "http://docs.openstack.org/api/" - "openstack-identity-service/2.0/" - "identity-dev-guide-2.0.pdf" -} - -v2_EXPECTED_RESPONSE = { - "id": "v2.0", - "status": "stable", - "updated": "2013-03-06T00:00:00Z", - "links": [ - { - "rel": "self", - "href": "", # Will get filled in after initialization - }, - v2_HTML_DESCRIPTION, - v2_PDF_DESCRIPTION - ], - "media-types": v2_MEDIA_TYPES -} - -v2_VERSION_RESPONSE = { - "version": v2_EXPECTED_RESPONSE -} - -v3_MEDIA_TYPES = [ - { - "base": "application/json", - "type": "application/" - "vnd.openstack.identity-v3+json" - }, { - "base": "application/xml", - "type": "application/" - "vnd.openstack.identity-v3+xml" - } -] - -v3_EXPECTED_RESPONSE = { - "id": "v3.0", - "status": "stable", - "updated": "2013-03-06T00:00:00Z", - "links": [ - { - "rel": "self", - "href": "", # Will get filled in after initialization - } - ], - "media-types": v3_MEDIA_TYPES -} - -v3_VERSION_RESPONSE = { - "version": v3_EXPECTED_RESPONSE -} - -VERSIONS_RESPONSE = { - "versions": { - "values": [ - v3_EXPECTED_RESPONSE, - v2_EXPECTED_RESPONSE - ] - } -} - - -class VersionTestCase(test.TestCase): - def setUp(self): - super(VersionTestCase, self).setUp() - self.load_backends() - self.public_app = self.loadapp('keystone', 'main') - self.admin_app = self.loadapp('keystone', 'admin') - - self.public_server = self.serveapp('keystone', name='main') - self.admin_server = self.serveapp('keystone', name='admin') - - def _paste_in_port(self, response, port): - for link in response['links']: - if link['rel'] == 'self': - link['href'] = port - - def test_public_versions(self): - client = self.client(self.public_app) - resp = client.get('/') - self.assertEqual(resp.status_int, 300) - data = jsonutils.loads(resp.body) - expected = VERSIONS_RESPONSE - for version in expected['versions']['values']: - if version['id'] == 'v3.0': - self._paste_in_port( - version, 'http://localhost:%s/v3/' % CONF.public_port) - elif version['id'] == 'v2.0': - self._paste_in_port( - version, 'http://localhost:%s/v2.0/' % CONF.public_port) - self.assertEqual(data, expected) - - def test_admin_versions(self): - client = self.client(self.admin_app) - resp = client.get('/') - self.assertEqual(resp.status_int, 300) - data = jsonutils.loads(resp.body) - expected = VERSIONS_RESPONSE - for version in expected['versions']['values']: - if version['id'] == 'v3.0': - self._paste_in_port( - version, 'http://localhost:%s/v3/' % CONF.admin_port) - elif version['id'] == 'v2.0': - self._paste_in_port( - version, 'http://localhost:%s/v2.0/' % CONF.admin_port) - self.assertEqual(data, expected) - - def test_public_version_v2(self): - client = self.client(self.public_app) - resp = client.get('/v2.0/') - self.assertEqual(resp.status_int, 200) - data = jsonutils.loads(resp.body) - expected = v2_VERSION_RESPONSE - self._paste_in_port(expected['version'], - 'http://localhost:%s/v2.0/' % CONF.public_port) - self.assertEqual(data, expected) - - def test_admin_version_v2(self): - client = self.client(self.admin_app) - resp = client.get('/v2.0/') - self.assertEqual(resp.status_int, 200) - data = jsonutils.loads(resp.body) - expected = v2_VERSION_RESPONSE - self._paste_in_port(expected['version'], - 'http://localhost:%s/v2.0/' % CONF.admin_port) - self.assertEqual(data, expected) - - def test_public_version_v3(self): - client = self.client(self.public_app) - resp = client.get('/v3/') - self.assertEqual(resp.status_int, 200) - data = jsonutils.loads(resp.body) - expected = v3_VERSION_RESPONSE - self._paste_in_port(expected['version'], - 'http://localhost:%s/v3/' % CONF.public_port) - self.assertEqual(data, expected) - - def test_admin_version_v3(self): - client = self.client(self.public_app) - resp = client.get('/v3/') - self.assertEqual(resp.status_int, 200) - data = jsonutils.loads(resp.body) - expected = v3_VERSION_RESPONSE - self._paste_in_port(expected['version'], - 'http://localhost:%s/v3/' % CONF.admin_port) - self.assertEqual(data, expected) - - def test_v2_disabled(self): - self.stubs.Set(controllers, '_VERSIONS', ['v3']) - client = self.client(self.public_app) - # request to /v2.0 should fail - resp = client.get('/v2.0/') - self.assertEqual(resp.status_int, 404) - - # request to /v3 should pass - resp = client.get('/v3/') - self.assertEqual(resp.status_int, 200) - data = jsonutils.loads(resp.body) - expected = v3_VERSION_RESPONSE - self._paste_in_port(expected['version'], - 'http://localhost:%s/v3/' % CONF.public_port) - self.assertEqual(data, expected) - - # only v3 information should be displayed by requests to / - v3_only_response = { - "versions": { - "values": [ - v3_EXPECTED_RESPONSE - ] - } - } - self._paste_in_port(v3_only_response['versions']['values'][0], - 'http://localhost:%s/v3/' % CONF.public_port) - resp = client.get('/') - self.assertEqual(resp.status_int, 300) - data = jsonutils.loads(resp.body) - self.assertEqual(data, v3_only_response) - - def test_v3_disabled(self): - self.stubs.Set(controllers, '_VERSIONS', ['v2.0']) - client = self.client(self.public_app) - # request to /v3 should fail - resp = client.get('/v3/') - self.assertEqual(resp.status_int, 404) - - # request to /v2.0 should pass - resp = client.get('/v2.0/') - self.assertEqual(resp.status_int, 200) - data = jsonutils.loads(resp.body) - expected = v2_VERSION_RESPONSE - self._paste_in_port(expected['version'], - 'http://localhost:%s/v2.0/' % CONF.public_port) - self.assertEqual(data, expected) - - # only v2 information should be displayed by requests to / - v2_only_response = { - "versions": { - "values": [ - v2_EXPECTED_RESPONSE - ] - } - } - self._paste_in_port(v2_only_response['versions']['values'][0], - 'http://localhost:%s/v2.0/' % CONF.public_port) - resp = client.get('/') - self.assertEqual(resp.status_int, 300) - data = jsonutils.loads(resp.body) - self.assertEqual(data, v2_only_response) - - -class XmlVersionTestCase(test.TestCase): - - REQUEST_HEADERS = {'Accept': 'application/xml'} - - DOC_INTRO = '<?xml version="1.0" encoding="UTF-8"?>' - XML_NAMESPACE_ATTR = 'xmlns="http://docs.openstack.org/identity/api/v2.0"' - - v2_VERSION_DATA = """ -<version %(v2_namespace)s status="stable" updated="2013-03-06T00:00:00Z" - id="v2.0"> - <media-types> - <media-type base="application/json" type="application/\ -vnd.openstack.identity-v2.0+json"/> - <media-type base="application/xml" type="application/\ -vnd.openstack.identity-v2.0+xml"/> - </media-types> - <links> - <link href="http://localhost:%%(port)s/v2.0/" rel="self"/> - <link href="http://docs.openstack.org/api/openstack-identity-service/\ -2.0/content/" type="text/html" rel="describedby"/> - <link href="http://docs.openstack.org/api/openstack-identity-service/\ -2.0/identity-dev-guide-2.0.pdf" type="application/pdf" rel="describedby"/> - </links> - <link href="http://localhost:%%(port)s/v2.0/" rel="self"/> - <link href="http://docs.openstack.org/api/openstack-identity-service/\ -2.0/content/" type="text/html" rel="describedby"/> - <link href="http://docs.openstack.org/api/openstack-identity-service/\ -2.0/identity-dev-guide-2.0.pdf" type="application/pdf" rel="describedby"/> -</version> -""" - - v2_VERSION_RESPONSE = ((DOC_INTRO + v2_VERSION_DATA) % - dict(v2_namespace=XML_NAMESPACE_ATTR)) - - v3_VERSION_DATA = """ -<version %(v3_namespace)s status="stable" updated="2013-03-06T00:00:00Z" - id="v3.0"> - <media-types> - <media-type base="application/json" type="application/\ -vnd.openstack.identity-v3+json"/> - <media-type base="application/xml" type="application/\ -vnd.openstack.identity-v3+xml"/> - </media-types> - <links> - <link href="http://localhost:%%(port)s/v3/" rel="self"/> - </links> -</version> -""" - - v3_VERSION_RESPONSE = ((DOC_INTRO + v3_VERSION_DATA) % - dict(v3_namespace=XML_NAMESPACE_ATTR)) - - VERSIONS_RESPONSE = ((DOC_INTRO + """ -<versions %(namespace)s> -""" + - v3_VERSION_DATA + - v2_VERSION_DATA + """ -</versions> -""") % dict(namespace=XML_NAMESPACE_ATTR, v3_namespace='', v2_namespace='')) - - def setUp(self): - super(XmlVersionTestCase, self).setUp() - self.load_backends() - self.public_app = self.loadapp('keystone', 'main') - self.admin_app = self.loadapp('keystone', 'admin') - - self.public_server = self.serveapp('keystone', name='main') - self.admin_server = self.serveapp('keystone', name='admin') - - def test_public_versions(self): - client = self.client(self.public_app) - resp = client.get('/', headers=self.REQUEST_HEADERS) - self.assertEqual(resp.status_int, 300) - data = resp.body - expected = self.VERSIONS_RESPONSE % dict(port=CONF.public_port) - self.assertEqualXML(data, expected) - - def test_admin_versions(self): - client = self.client(self.admin_app) - resp = client.get('/', headers=self.REQUEST_HEADERS) - self.assertEqual(resp.status_int, 300) - data = resp.body - expected = self.VERSIONS_RESPONSE % dict(port=CONF.admin_port) - self.assertEqualXML(data, expected) - - def test_public_version_v2(self): - client = self.client(self.public_app) - resp = client.get('/v2.0/', headers=self.REQUEST_HEADERS) - self.assertEqual(resp.status_int, 200) - data = resp.body - expected = self.v2_VERSION_RESPONSE % dict(port=CONF.public_port) - self.assertEqualXML(data, expected) - - def test_admin_version_v2(self): - client = self.client(self.admin_app) - resp = client.get('/v2.0/', headers=self.REQUEST_HEADERS) - self.assertEqual(resp.status_int, 200) - data = resp.body - expected = self.v2_VERSION_RESPONSE % dict(port=CONF.admin_port) - self.assertEqualXML(data, expected) - - def test_public_version_v3(self): - client = self.client(self.public_app) - resp = client.get('/v3/', headers=self.REQUEST_HEADERS) - self.assertEqual(resp.status_int, 200) - data = resp.body - expected = self.v3_VERSION_RESPONSE % dict(port=CONF.public_port) - self.assertEqualXML(data, expected) - - def test_admin_version_v3(self): - client = self.client(self.public_app) - resp = client.get('/v3/', headers=self.REQUEST_HEADERS) - self.assertEqual(resp.status_int, 200) - data = resp.body - expected = self.v3_VERSION_RESPONSE % dict(port=CONF.admin_port) - self.assertEqualXML(data, expected) - - def test_v2_disabled(self): - self.stubs.Set(controllers, '_VERSIONS', ['v3']) - client = self.client(self.public_app) - - # request to /v3 should pass - resp = client.get('/v3/', headers=self.REQUEST_HEADERS) - self.assertEqual(resp.status_int, 200) - data = resp.body - expected = self.v3_VERSION_RESPONSE % dict(port=CONF.public_port) - self.assertEqualXML(data, expected) - - # only v3 information should be displayed by requests to / - v3_only_response = ((self.DOC_INTRO + '<versions %(namespace)s>' + - self.v3_VERSION_DATA + '</versions>') % - dict(namespace=self.XML_NAMESPACE_ATTR, - v3_namespace='') % - dict(port=CONF.public_port)) - - resp = client.get('/', headers=self.REQUEST_HEADERS) - self.assertEqual(resp.status_int, 300) - data = resp.body - self.assertEqualXML(data, v3_only_response) - - def test_v3_disabled(self): - self.stubs.Set(controllers, '_VERSIONS', ['v2.0']) - client = self.client(self.public_app) - - # request to /v2.0 should pass - resp = client.get('/v2.0/', headers=self.REQUEST_HEADERS) - self.assertEqual(resp.status_int, 200) - data = resp.body - expected = self.v2_VERSION_RESPONSE % dict(port=CONF.public_port) - self.assertEqualXML(data, expected) - - # only v2 information should be displayed by requests to / - v2_only_response = ((self.DOC_INTRO + '<versions %(namespace)s>' + - self.v2_VERSION_DATA + '</versions>') % - dict(namespace=self.XML_NAMESPACE_ATTR, - v2_namespace='') % - dict(port=CONF.public_port)) - - resp = client.get('/', headers=self.REQUEST_HEADERS) - self.assertEqual(resp.status_int, 300) - data = resp.body - self.assertEqualXML(data, v2_only_response) diff --git a/tests/test_wsgi.py b/tests/test_wsgi.py deleted file mode 100644 index 362df922..00000000 --- a/tests/test_wsgi.py +++ /dev/null @@ -1,214 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack 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 keystone import test - -from keystone.common import wsgi -from keystone import exception -from keystone.openstack.common import jsonutils - - -class FakeApp(wsgi.Application): - def index(self, context): - return {'a': 'b'} - - -class BaseWSGITest(test.TestCase): - def setUp(self): - self.app = FakeApp() - super(BaseWSGITest, self).setUp() - - def _make_request(self, url='/'): - req = wsgi.Request.blank(url) - args = {'action': 'index', 'controller': None} - req.environ['wsgiorg.routing_args'] = [None, args] - return req - - -class ApplicationTest(BaseWSGITest): - def test_response_content_type(self): - req = self._make_request() - resp = req.get_response(self.app) - self.assertEqual(resp.content_type, 'application/json') - - def test_query_string_available(self): - class FakeApp(wsgi.Application): - def index(self, context): - return context['query_string'] - req = self._make_request(url='/?1=2') - resp = req.get_response(FakeApp()) - self.assertEqual(jsonutils.loads(resp.body), {'1': '2'}) - - def test_headers_available(self): - class FakeApp(wsgi.Application): - def index(self, context): - return context['headers'] - - app = FakeApp() - req = self._make_request(url='/?1=2') - req.headers['X-Foo'] = "bar" - resp = req.get_response(app) - self.assertIn('X-Foo', eval(resp.body)) - - def test_render_response(self): - data = {'attribute': 'value'} - body = '{"attribute": "value"}' - - resp = wsgi.render_response(body=data) - self.assertEqual(resp.status, '200 OK') - self.assertEqual(resp.status_int, 200) - self.assertEqual(resp.body, body) - self.assertEqual(resp.headers.get('Vary'), 'X-Auth-Token') - self.assertEqual(resp.headers.get('Content-Length'), str(len(body))) - - def test_render_response_custom_status(self): - resp = wsgi.render_response(status=(501, 'Not Implemented')) - self.assertEqual(resp.status, '501 Not Implemented') - self.assertEqual(resp.status_int, 501) - - def test_render_response_custom_headers(self): - resp = wsgi.render_response(headers=[('Custom-Header', 'Some-Value')]) - self.assertEqual(resp.headers.get('Custom-Header'), 'Some-Value') - self.assertEqual(resp.headers.get('Vary'), 'X-Auth-Token') - - def test_render_response_no_body(self): - resp = wsgi.render_response() - self.assertEqual(resp.status, '204 No Content') - self.assertEqual(resp.status_int, 204) - self.assertEqual(resp.body, '') - self.assertEqual(resp.headers.get('Content-Length'), '0') - self.assertEqual(resp.headers.get('Content-Type'), None) - - def test_application_local_config(self): - class FakeApp(wsgi.Application): - def __init__(self, *args, **kwargs): - self.kwargs = kwargs - - app = FakeApp.factory({}, testkey="test") - self.assertIn("testkey", app.kwargs) - self.assertEquals("test", app.kwargs["testkey"]) - - def test_render_exception(self): - e = exception.Unauthorized(message=u'\u7f51\u7edc') - resp = wsgi.render_exception(e) - self.assertEqual(resp.status_int, 401) - - -class ExtensionRouterTest(BaseWSGITest): - def test_extensionrouter_local_config(self): - class FakeRouter(wsgi.ExtensionRouter): - def __init__(self, *args, **kwargs): - self.kwargs = kwargs - - factory = FakeRouter.factory({}, testkey="test") - app = factory(self.app) - self.assertIn("testkey", app.kwargs) - self.assertEquals("test", app.kwargs["testkey"]) - - -class MiddlewareTest(BaseWSGITest): - def test_middleware_request(self): - class FakeMiddleware(wsgi.Middleware): - def process_request(self, req): - req.environ['fake_request'] = True - return req - req = self._make_request() - resp = FakeMiddleware(None)(req) - self.assertIn('fake_request', resp.environ) - - def test_middleware_response(self): - class FakeMiddleware(wsgi.Middleware): - def process_response(self, request, response): - response.environ = {} - response.environ['fake_response'] = True - return response - req = self._make_request() - resp = FakeMiddleware(self.app)(req) - self.assertIn('fake_response', resp.environ) - - def test_middleware_bad_request(self): - class FakeMiddleware(wsgi.Middleware): - def process_response(self, request, response): - raise exception.Unauthorized() - - req = self._make_request() - req.environ['REMOTE_ADDR'] = '127.0.0.1' - resp = FakeMiddleware(self.app)(req) - self.assertEquals(resp.status_int, exception.Unauthorized.code) - - def test_middleware_type_error(self): - class FakeMiddleware(wsgi.Middleware): - def process_response(self, request, response): - raise TypeError() - - req = self._make_request() - req.environ['REMOTE_ADDR'] = '127.0.0.1' - resp = FakeMiddleware(self.app)(req) - # This is a validationerror type - self.assertEquals(resp.status_int, exception.ValidationError.code) - - def test_middleware_exception_error(self): - class FakeMiddleware(wsgi.Middleware): - def process_response(self, request, response): - raise exception.UnexpectedError("EXCEPTIONERROR") - - req = self._make_request() - resp = FakeMiddleware(self.app)(req) - self.assertEquals(resp.status_int, exception.UnexpectedError.code) - self.assertIn("EXCEPTIONERROR", resp.body) - - def test_middleware_local_config(self): - class FakeMiddleware(wsgi.Middleware): - def __init__(self, *args, **kwargs): - self.kwargs = kwargs - - factory = FakeMiddleware.factory({}, testkey="test") - app = factory(self.app) - self.assertIn("testkey", app.kwargs) - self.assertEquals("test", app.kwargs["testkey"]) - - -class WSGIFunctionTest(test.TestCase): - def test_mask_password(self): - message = ("test = 'password': 'aaaaaa', 'param1': 'value1', " - "\"new_password\": 'bbbbbb'") - self.assertEqual(wsgi.mask_password(message, True), - u"test = 'password': '***', 'param1': 'value1', " - "\"new_password\": '***'") - - message = "test = 'password' : 'aaaaaa'" - self.assertEqual(wsgi.mask_password(message, False, '111'), - "test = 'password' : '111'") - - message = u"test = u'password' : u'aaaaaa'" - self.assertEqual(wsgi.mask_password(message, True), - u"test = u'password' : u'***'") - - message = 'test = "password" : "aaaaaaaaa"' - self.assertEqual(wsgi.mask_password(message), - 'test = "password" : "***"') - - message = 'test = "original_password" : "aaaaaaaaa"' - self.assertEqual(wsgi.mask_password(message), - 'test = "original_password" : "***"') - - message = 'test = "original_password" : ""' - self.assertEqual(wsgi.mask_password(message), - 'test = "original_password" : "***"') - - message = 'test = "param1" : "value"' - self.assertEqual(wsgi.mask_password(message), - 'test = "param1" : "value"') diff --git a/tests/tmp/.gitkeep b/tests/tmp/.gitkeep deleted file mode 100644 index e69de29b..00000000 --- a/tests/tmp/.gitkeep +++ /dev/null |