summaryrefslogtreecommitdiff
path: root/keystoneclient/middleware
diff options
context:
space:
mode:
authorJamie Lennox <jamielennox@redhat.com>2014-04-22 12:17:42 +1000
committerJamie Lennox <jamielennox@redhat.com>2014-05-05 08:06:16 +1000
commitc1c5669d0c95ca43788abcb3eda07fd3bccec73f (patch)
tree88af3cb5fd8cd2ad50ad01238f7c11d98c3f4eea /keystoneclient/middleware
parent570a9dc22dad6c246372f273bd6db23342752c3a (diff)
downloadpython-keystoneclient-c1c5669d0c95ca43788abcb3eda07fd3bccec73f.tar.gz
Make auth_token return a V2 Catalog
As there is no way to distinguish a v2 or v3 catalog from the headers provided to an application we will for the meantime always return a v2 catalog. This should not cause any issues as the full token data is not provided to the service so there is no-one that will get caught out by a v2/v3 mix, and anyone that is already supporting the v3 catalog format will have to support the v2 catalog format as well so it will continue to work. Change-Id: Ic9b38e0ba4682b47ae295bd3f89bac59ef7437cf Closes-Bug: #1302970
Diffstat (limited to 'keystoneclient/middleware')
-rw-r--r--keystoneclient/middleware/auth_token.py40
1 files changed, 40 insertions, 0 deletions
diff --git a/keystoneclient/middleware/auth_token.py b/keystoneclient/middleware/auth_token.py
index 637b3b2..25544dd 100644
--- a/keystoneclient/middleware/auth_token.py
+++ b/keystoneclient/middleware/auth_token.py
@@ -108,6 +108,8 @@ HTTP_X_ROLES
HTTP_X_SERVICE_CATALOG
json encoded keystone service catalog (optional).
+ For compatibility reasons this catalog will always be in the V2 catalog
+ format even if it is a v3 token.
HTTP_X_TENANT_ID
*Deprecated* in favor of HTTP_X_PROJECT_ID
@@ -371,6 +373,42 @@ def confirm_token_not_expired(data):
return timeutils.isotime(at=expires, subsecond=True)
+def _v3_to_v2_catalog(catalog):
+ """Convert a catalog to v2 format.
+
+ X_SERVICE_CATALOG must be specified in v2 format. If you get a token
+ that is in v3 convert it.
+ """
+ v2_services = []
+ for v3_service in catalog:
+ # first copy over the entries we allow for the service
+ v2_service = {'type': v3_service['type']}
+ try:
+ v2_service['name'] = v3_service['name']
+ except KeyError:
+ pass
+
+ # now convert the endpoints. Because in v3 we specify region per
+ # URL not per group we have to collect all the entries of the same
+ # region together before adding it to the new service.
+ regions = {}
+ for v3_endpoint in v3_service.get('endpoints', []):
+ region_name = v3_endpoint.get('region')
+ try:
+ region = regions[region_name]
+ except KeyError:
+ region = {'region': region_name} if region_name else {}
+ regions[region_name] = region
+
+ interface_name = v3_endpoint['interface'].lower() + 'URL'
+ region[interface_name] = v3_endpoint['url']
+
+ v2_service['endpoints'] = list(regions.values())
+ v2_services.append(v2_service)
+
+ return v2_services
+
+
def safe_quote(s):
"""URL-encode strings that are not already URL-encoded."""
return urllib.parse.quote(s) if s == urllib.parse.unquote(s) else s
@@ -939,6 +977,8 @@ class AuthProtocol(object):
if self.include_service_catalog and auth_ref.has_service_catalog():
catalog = auth_ref.service_catalog.get_data()
+ if _token_is_v3(token_info):
+ catalog = _v3_to_v2_catalog(catalog)
rval['X-Service-Catalog'] = jsonutils.dumps(catalog)
return rval