diff options
author | Jenkins <jenkins@review.openstack.org> | 2014-01-14 00:30:57 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2014-01-14 00:30:57 +0000 |
commit | 01d26314d316d61443ee3a4c55f6d06bac477600 (patch) | |
tree | dc7758b654c9200ae0f0310cfb8c96d1b0d930d5 | |
parent | 9837137580688d0c8509c2a5337004d55f2b88e0 (diff) | |
parent | 97b0627d80116ddd562c0b9dab78ad22c3edcd4c (diff) | |
download | keystone-01d26314d316d61443ee3a4c55f6d06bac477600.tar.gz |
Merge "Documentation cleanup"
-rw-r--r-- | doc/source/developing.rst | 4 | ||||
-rw-r--r-- | keystone/common/base64utils.py | 55 | ||||
-rw-r--r-- | keystone/common/cache/core.py | 2 | ||||
-rw-r--r-- | keystone/common/cms.py | 49 | ||||
-rw-r--r-- | keystone/common/dependency.py | 4 | ||||
-rwxr-xr-x | keystone/common/pemutils.py | 4 | ||||
-rw-r--r-- | keystone/contrib/oauth1/core.py | 16 | ||||
-rw-r--r-- | keystone/contrib/oauth1/routers.py | 2 | ||||
-rw-r--r-- | keystone/identity/core.py | 1 | ||||
-rw-r--r-- | keystone/tests/core.py | 2 | ||||
-rw-r--r-- | keystone/tests/test_backend.py | 9 | ||||
-rw-r--r-- | keystone/tests/test_backend_ldap.py | 1 | ||||
-rw-r--r-- | keystone/tests/test_sql_migrate_extensions.py | 15 | ||||
-rw-r--r-- | keystone/tests/test_v3_auth.py | 7 | ||||
-rw-r--r-- | keystone/tests/test_v3_identity.py | 11 | ||||
-rw-r--r-- | keystone/tests/test_v3_protection.py | 10 | ||||
-rw-r--r-- | keystone/token/providers/common.py | 40 |
17 files changed, 138 insertions, 94 deletions
diff --git a/doc/source/developing.rst b/doc/source/developing.rst index ab7cc423d..342f2abc8 100644 --- a/doc/source/developing.rst +++ b/doc/source/developing.rst @@ -260,14 +260,14 @@ development environment, there's a couple of things you need to do. 1. Build the message files. Run the following command in your keystone directory:: - $ python setup.py compile_catalog + $ python setup.py compile_catalog This will generate .mo files like keystone/locale/[lang]/LC_MESSAGES/[lang].mo 2. When running Keystone, set the ``KEYSTONE_LOCALEDIR`` environment variable to the keystone/locale directory. For example:: - $ KEYSTONE_LOCALEDIR=/opt/stack/keystone/keystone/locale keystone-all + $ KEYSTONE_LOCALEDIR=/opt/stack/keystone/keystone/locale keystone-all Now you can get a translated error response:: diff --git a/keystone/common/base64utils.py b/keystone/common/base64utils.py index fe9a1c72d..d49371cab 100644 --- a/keystone/common/base64utils.py +++ b/keystone/common/base64utils.py @@ -133,33 +133,32 @@ def base64_to_base64url(text): This function only translates the altchars, non-alphabet characters are not filtered out. - WARNING - ------- - - base64url continues to use the '=' pad character which is NOT URL - safe. RFC-4648 suggests two alternate methods to deal with this. - - percent-encode - percent-encode the pad character (e.g. '=' becomes - '%3D'). This makes the base64url text fully safe. But - percent-enconding has the downside of requiring - percent-decoding prior to feeding the base64url text into a - base64url decoder since most base64url decoders do not - recognize %3D as a pad character and most decoders require - correct padding. - - no-padding - padding is not strictly necessary to decode base64 or - base64url text, the pad can be computed from the input text - length. However many decoders demand padding and will consider - non-padded text to be malformed. If one wants to omit the - trailing pad character(s) for use in URL's it can be added back - using the base64_assure_padding() function. - - This function makes no decisions about which padding methodolgy to - use. One can either call base64_strip_padding() to remove any pad - characters (restoring later with base64_assure_padding()) or call - base64url_percent_encode() to percent-encode the pad characters. + WARNING:: + + base64url continues to use the '=' pad character which is NOT URL + safe. RFC-4648 suggests two alternate methods to deal with this: + + percent-encode + percent-encode the pad character (e.g. '=' becomes + '%3D'). This makes the base64url text fully safe. But + percent-enconding has the downside of requiring + percent-decoding prior to feeding the base64url text into a + base64url decoder since most base64url decoders do not + recognize %3D as a pad character and most decoders require + correct padding. + + no-padding + padding is not strictly necessary to decode base64 or + base64url text, the pad can be computed from the input text + length. However many decoders demand padding and will consider + non-padded text to be malformed. If one wants to omit the + trailing pad character(s) for use in URL's it can be added back + using the base64_assure_padding() function. + + This function makes no decisions about which padding methodolgy to + use. One can either call base64_strip_padding() to remove any pad + characters (restoring later with base64_assure_padding()) or call + base64url_percent_encode() to percent-encode the pad characters. :param text: input base64 text :type text: string @@ -373,7 +372,7 @@ def base64_wrap(text, width=64): Input is assumed to consist only of members of a base64 alphabet (i.e no whitepace). Fold the text into lines whose line length is width chars long, terminate each line with line - ending (default is '\n'). Return the wrapped text as a single + ending (default is '\\n'). Return the wrapped text as a single string. Use the filter_formatting() function to assure the input text diff --git a/keystone/common/cache/core.py b/keystone/common/cache/core.py index c95e42009..a8f3ba0e6 100644 --- a/keystone/common/cache/core.py +++ b/keystone/common/cache/core.py @@ -160,7 +160,7 @@ def should_cache_fn(section): decorator if caching for that driver is enabled. To properly use this with the decorator, pass this function the configuration section and assign the result to a variable. Pass the new variable to the caching decorator - as the named argument ``should_cache_fn``. e.g.: + as the named argument ``should_cache_fn``. e.g.:: from keystone.common import cache diff --git a/keystone/common/cms.py b/keystone/common/cms.py index 086d106b9..e3c835cee 100644 --- a/keystone/common/cms.py +++ b/keystone/common/cms.py @@ -75,39 +75,40 @@ def is_ans1_token(token): thx to ayoung for sorting this out. - base64 decoded hex representation of MII is 3082 - In [3]: binascii.hexlify(base64.b64decode('MII=')) - Out[3]: '3082' + | base64 decoded hex representation of MII is 3082 + | In [3]: binascii.hexlify(base64.b64decode('MII=')) + | Out[3]: '3082' re: http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf - pg4: For tags from 0 to 30 the first octet is the identifier - pg10: Hex 30 means sequence, followed by the length of that sequence. - pg5: Second octet is the length octet - first bit indicates short or long form, next 7 bits encode the number - of subsequent octets that make up the content length octets as an - unsigned binary int - - 82 = 10000010 (first bit indicates long form) - 0000010 = 2 octets of content length - so read the next 2 octets to get the length of the content. + | pg4: For tags from 0 to 30 the first octet is the identifier + | pg10: Hex 30 means sequence, followed by the length of that sequence. + | pg5: Second octet is the length octet + | first bit indicates short or long form, next 7 bits encode the + number of subsequent octets that make up the content length octets + as an unsigned binary int + | + | 82 = 10000010 (first bit indicates long form) + | 0000010 = 2 octets of content length + | so read the next 2 octets to get the length of the content. In the case of a very large content length there could be a requirement to have more than 2 octets to designate the content length, therefore requiring us to check for MIM, MIQ, etc. - In [4]: base64.b64encode(binascii.a2b_hex('3083')) - Out[4]: 'MIM=' - In [5]: base64.b64encode(binascii.a2b_hex('3084')) - Out[5]: 'MIQ=' - Checking for MI would become invalid at 16 octets of content length - 10010000 = 90 - In [6]: base64.b64encode(binascii.a2b_hex('3090')) - Out[6]: 'MJA=' - Checking for just M is insufficient + + | In [4]: base64.b64encode(binascii.a2b_hex('3083')) + | Out[4]: 'MIM=' + | In [5]: base64.b64encode(binascii.a2b_hex('3084')) + | Out[5]: 'MIQ=' + | Checking for MI would become invalid at 16 octets of content length + | 10010000 = 90 + | In [6]: base64.b64encode(binascii.a2b_hex('3090')) + | Out[6]: 'MJA=' + | Checking for just M is insufficient But we will only check for MII: - Max length of the content using 2 octets is 7FFF or 32767 - It's not practical to support a token of this length or greater in http + Max length of the content using 2 octets is 7FFF or 32767. + It's not practical to support a token of this length or greater in http; therefore, we will check for MII only and ignore the case of larger tokens """ return token[:3] == PKI_ANS1_PREFIX diff --git a/keystone/common/dependency.py b/keystone/common/dependency.py index 7fa87cbec..5eaa4d886 100644 --- a/keystone/common/dependency.py +++ b/keystone/common/dependency.py @@ -46,7 +46,7 @@ def provider(name): When 'provider' is used to decorate a class, members of that class will register themselves as providers for the named dependency. As an example, - In the code fragment: + In the code fragment:: @dependency.provider('foo_api') class Foo: @@ -102,7 +102,7 @@ def requires(*dependencies): The required providers will be made available to instances of the decorated class via an attribute with the same name as the provider. For example, - in the code fragment: + in the code fragment:: @dependency.requires('foo_api', 'bar_api') class FooBarClient: diff --git a/keystone/common/pemutils.py b/keystone/common/pemutils.py index 599c6bbf4..fea7a7f4b 100755 --- a/keystone/common/pemutils.py +++ b/keystone/common/pemutils.py @@ -264,7 +264,7 @@ def pem_search(text, start=0): The start and end positions are suitable for use as slices into the text. To search for multiple PEM blocks pass pem_end as the start position for the next iteration. Terminate the iteration - when None is returned. Example: + when None is returned. Example:: start = 0 while True: @@ -335,7 +335,7 @@ def parse_pem(text, pem_type=None, max_items=None): including the decoded binary data for the PEM block. The list is ordered in the same order as found in the text. - Examples: + Examples:: # Get all certs certs = parse_pem(text, 'cert') diff --git a/keystone/contrib/oauth1/core.py b/keystone/contrib/oauth1/core.py index cecd6b4b3..857a4ad84 100644 --- a/keystone/contrib/oauth1/core.py +++ b/keystone/contrib/oauth1/core.py @@ -170,7 +170,7 @@ class Driver(object): def list_consumers(self): """List consumers. - returns: list of consumers + :returns: list of consumers """ raise exception.NotImplemented() @@ -219,7 +219,7 @@ class Driver(object): :param user_id: search for access tokens authorized by given user id :type user_id: string - returns: list of access tokens the user has authorized + :returns: list of access tokens the user has authorized """ raise exception.NotImplemented() @@ -232,7 +232,7 @@ class Driver(object): :type user_id: string :param access_token_id: access token to delete :type access_token_id: string - returns: None + :returns: None """ raise exception.NotImplemented() @@ -248,7 +248,7 @@ class Driver(object): :type requested_project_id: string :param request_token_duration: duration of request token :type request_token_duration: string - returns: request_token_ref + :returns: request_token_ref """ raise exception.NotImplemented() @@ -259,7 +259,7 @@ class Driver(object): :param request_token_id: the id of the request token :type request_token_id: string - returns: request_token_ref + :returns: request_token_ref """ raise exception.NotImplemented() @@ -270,7 +270,7 @@ class Driver(object): :param access_token_id: the id of the access token :type access_token_id: string - returns: access_token_ref + :returns: access_token_ref """ raise exception.NotImplemented() @@ -285,7 +285,7 @@ class Driver(object): :type user_id: string :param role_ids: list of role ids to authorize :type role_ids: list - returns: verifier + :returns: verifier """ raise exception.NotImplemented() @@ -298,7 +298,7 @@ class Driver(object): :type request_id: string :param access_token_duration: duration of an access token :type access_token_duration: string - returns: access_token_ref + :returns: access_token_ref """ raise exception.NotImplemented() diff --git a/keystone/contrib/oauth1/routers.py b/keystone/contrib/oauth1/routers.py index 3bfa9370a..435088e4b 100644 --- a/keystone/contrib/oauth1/routers.py +++ b/keystone/contrib/oauth1/routers.py @@ -27,7 +27,7 @@ class OAuth1Extension(wsgi.ExtensionRouter): on behalf of that user. This is done using an oauth-similar flow and api. - The API looks like: + The API looks like:: # Basic admin-only consumer crud POST /OS-OAUTH1/consumers diff --git a/keystone/identity/core.py b/keystone/identity/core.py index 21e5498d4..3e7278c1c 100644 --- a/keystone/identity/core.py +++ b/keystone/identity/core.py @@ -82,6 +82,7 @@ class DomainConfigs(dict): For each file, the domain_name will be turned into a domain_id and then this class will: + - Create a new config structure, adding in the specific additional options defined in this config file - Initialise a new instance of the required driver with this new config. diff --git a/keystone/tests/core.py b/keystone/tests/core.py index 11ef2a2e7..69180106c 100644 --- a/keystone/tests/core.py +++ b/keystone/tests/core.py @@ -188,7 +188,7 @@ def skip_if_cache_disabled(*sections): """This decorator is used to skip a test if caching is disabled either globally or for the specific section. - In the code fragment: + In the code fragment:: @skip_if_cache_is_disabled('assignment', 'token') def test_method(*args): diff --git a/keystone/tests/test_backend.py b/keystone/tests/test_backend.py index 11c808025..43b4894e7 100644 --- a/keystone/tests/test_backend.py +++ b/keystone/tests/test_backend.py @@ -460,6 +460,7 @@ class IdentityTests(object): """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) @@ -565,6 +566,7 @@ class IdentityTests(object): """Test for get role by user and project, user was added into a group. Test Plan: + - Create a user, a project & a group, add this user to group - Create roles and grant them to user and project - Check the role list get by the user and project was as expected @@ -628,6 +630,7 @@ class IdentityTests(object): """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 @@ -684,6 +687,7 @@ class IdentityTests(object): """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 @@ -1289,6 +1293,7 @@ class IdentityTests(object): """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 @@ -3627,6 +3632,7 @@ class InheritanceTests(object): """Test inherited user roles. Test Plan: + - Enable OS-INHERIT extension - Create 3 roles - Create a domain, with a project and a user @@ -3702,6 +3708,7 @@ class InheritanceTests(object): """Test inherited group roles. Test Plan: + - Enable OS-INHERIT extension - Create 4 roles - Create a domain, with a project, user and two groups @@ -3785,6 +3792,7 @@ class InheritanceTests(object): """Test inherited group roles. Test Plan: + - Enable OS-INHERIT extension - Create a domain, with two projects and a user - Assign an inherited user role on the domain, as well as a direct @@ -3824,6 +3832,7 @@ class InheritanceTests(object): """Test inherited group roles. Test Plan: + - Enable OS-INHERIT extension - Create two domains, each with two projects - Create a user and group diff --git a/keystone/tests/test_backend_ldap.py b/keystone/tests/test_backend_ldap.py index 43164d642..fc3a5ebe2 100644 --- a/keystone/tests/test_backend_ldap.py +++ b/keystone/tests/test_backend_ldap.py @@ -1170,6 +1170,7 @@ class MultiLDAPandSQLIdentity(sql.Base, tests.TestCase, BaseLDAPIdentity): """Test that separate configs have segregated the domain. Test Plan: + - Create a user in each of the domains - Make sure that you can only find a given user in its relevant domain diff --git a/keystone/tests/test_sql_migrate_extensions.py b/keystone/tests/test_sql_migrate_extensions.py index 57a0b6aa2..0d768709b 100644 --- a/keystone/tests/test_sql_migrate_extensions.py +++ b/keystone/tests/test_sql_migrate_extensions.py @@ -15,15 +15,22 @@ # 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. + + WARNING:: + + Your database will be wiped. + + Do not do this against a Database with valuable data as + all data will be lost. """ diff --git a/keystone/tests/test_v3_auth.py b/keystone/tests/test_v3_auth.py index e3f17bff8..b53467218 100644 --- a/keystone/tests/test_v3_auth.py +++ b/keystone/tests/test_v3_auth.py @@ -645,6 +645,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase): """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 @@ -676,6 +677,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase): """Test deleting a role revokes token. Test Plan: + - Add some additional test data, namely: - A third project (project C) - Three additional users - user4 owned by domainB and user5 and 6 @@ -805,6 +807,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase): """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 @@ -897,6 +900,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase): """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 @@ -958,6 +962,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase): """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 @@ -989,6 +994,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase): """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 @@ -1379,6 +1385,7 @@ class TestAuthJSON(test_v3.RestfulTestCase): """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 diff --git a/keystone/tests/test_v3_identity.py b/keystone/tests/test_v3_identity.py index 7bd89d6b8..10ad71da5 100644 --- a/keystone/tests/test_v3_identity.py +++ b/keystone/tests/test_v3_identity.py @@ -246,6 +246,7 @@ class IdentityTestCase(test_v3.RestfulTestCase): by the delete. Test Plan: + - Create domain2 and a 2nd set of entities - Disable domain2 - Delete domain2 @@ -359,7 +360,7 @@ class IdentityTestCase(test_v3.RestfulTestCase): self.assertValidProjectResponse(r, ref) def test_delete_project(self): - """Call ``DELETE /projects/{project_id} + """Call ``DELETE /projects/{project_id}`` As well as making sure the delete succeeds, we ensure that any credentials that reference this projects are @@ -749,6 +750,7 @@ class IdentityTestCase(test_v3.RestfulTestCase): 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. @@ -838,6 +840,7 @@ class IdentityTestCase(test_v3.RestfulTestCase): """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 @@ -908,6 +911,7 @@ class IdentityTestCase(test_v3.RestfulTestCase): 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 @@ -981,6 +985,7 @@ class IdentityTestCase(test_v3.RestfulTestCase): """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 @@ -1188,6 +1193,7 @@ class IdentityInheritanceTestCase(test_v3.RestfulTestCase): """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 @@ -1281,6 +1287,7 @@ class IdentityInheritanceTestCase(test_v3.RestfulTestCase): """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 @@ -1373,6 +1380,7 @@ class IdentityInheritanceTestCase(test_v3.RestfulTestCase): """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 @@ -1477,6 +1485,7 @@ class IdentityInheritanceTestCase(test_v3.RestfulTestCase): """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 diff --git a/keystone/tests/test_v3_protection.py b/keystone/tests/test_v3_protection.py index 434b934f2..f5e2308c0 100644 --- a/keystone/tests/test_v3_protection.py +++ b/keystone/tests/test_v3_protection.py @@ -130,6 +130,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase): """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 @@ -146,6 +147,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase): """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 @@ -163,6 +165,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase): """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 @@ -182,6 +185,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase): """GET /users/{id} (match target) Test Plan: + - Update policy to protect api by domain_id - Try and read a user who is in DomainB with a token scoped to Domain A - this should fail @@ -213,6 +217,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase): """DELETE /domains/{id}/users/{id}/roles/{id} (match target) Test Plan: + - Update policy to protect api by domain_id of entities in the grant - Try and delete the existing grant that has a user who is @@ -251,6 +256,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase): """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 @@ -281,6 +287,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase): """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 @@ -311,6 +318,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase): """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. @@ -337,6 +345,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase): """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 @@ -372,6 +381,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase): """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 diff --git a/keystone/token/providers/common.py b/keystone/token/providers/common.py index 889ee2cfb..233c613e9 100644 --- a/keystone/token/providers/common.py +++ b/keystone/token/providers/common.py @@ -85,27 +85,27 @@ class V2TokenDataHelper(object): @classmethod def format_catalog(cls, catalog_ref): """Munge catalogs from internal to output format - Internal catalogs look like: - - {$REGION: { - {$SERVICE: { - $key1: $value1, + Internal catalogs look like:: + + {$REGION: { + {$SERVICE: { + $key1: $value1, + ... + } + } + } + + The legacy api wants them to look like:: + + [{'name': $SERVICE[name], + 'type': $SERVICE, + 'endpoints': [{ + 'tenantId': $tenant_id, ... - } - } - } - - The legacy api wants them to look like - - [{'name': $SERVICE[name], - 'type': $SERVICE, - 'endpoints': [{ - 'tenantId': $tenant_id, - ... - 'region': $REGION, - }], - 'endpoints_links': [], - }] + 'region': $REGION, + }], + 'endpoints_links': [], + }] """ if not catalog_ref: |