summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlin-hua-cheng <os.lcheng@gmail.com>2015-02-25 16:33:22 -0800
committerlin-hua-cheng <os.lcheng@gmail.com>2015-04-07 13:24:27 -0700
commit7ec44e898b08dc57e231d78465d9d242f2058d77 (patch)
tree0f4cd73e1b023e9dfd6155616f863a5405c84d90
parent09611a3d3ce1191d5c3084200e1c27db34b7c3e4 (diff)
downloaddjango_openstack_auth-7ec44e898b08dc57e231d78465d9d242f2058d77.tar.gz
Updated parsing of catalog to handle bad format
Don't assume that the service catalog is well-formed, added code to safely parsing the catalog. Parsing of region from service catalog has been fixed as well. 'region' has been deprecated in the Keystone V3 catalog in favor of 'region_id'. Fix how region is extracted by checking 'region_id' then fallback to 'region'. Change-Id: I7b649a8b90e20caa2d04fdd3f79b5b1ac775237c Closes-Bug: #1424825
-rw-r--r--openstack_auth/backend.py18
-rw-r--r--openstack_auth/user.py15
-rw-r--r--openstack_auth/utils.py34
3 files changed, 45 insertions, 22 deletions
diff --git a/openstack_auth/backend.py b/openstack_auth/backend.py
index 362855c..46c32d4 100644
--- a/openstack_auth/backend.py
+++ b/openstack_auth/backend.py
@@ -215,11 +215,19 @@ class KeystoneBackend(object):
# when supported by Keystone.
role_perms = set(["openstack.roles.%s" % role['name'].lower()
for role in user.roles])
- service_perms = set(["openstack.services.%s" % service['type'].lower()
- for service in user.service_catalog
- if user.services_region in
- [endpoint.get('region', None) for endpoint
- in service.get('endpoints', [])]])
+
+ services = []
+ for service in user.service_catalog:
+ try:
+ service_type = service['type']
+ except KeyError:
+ continue
+ service_regions = [utils.get_endpoint_region(endpoint) for endpoint
+ in service.get('endpoints', [])]
+ if user.services_region in service_regions:
+ services.append(service_type.lower())
+ service_perms = set(["openstack.services.%s" % service
+ for service in services])
return role_perms | service_perms
def has_perm(self, user, perm, obj=None):
diff --git a/openstack_auth/user.py b/openstack_auth/user.py
index 43336e5..811fe84 100644
--- a/openstack_auth/user.py
+++ b/openstack_auth/user.py
@@ -113,10 +113,7 @@ class Token(object):
else:
self.roles = auth_ref.get('roles', [])
- if utils.get_keystone_version() < 3:
- self.serviceCatalog = auth_ref.get('serviceCatalog', [])
- else:
- self.serviceCatalog = auth_ref.get('catalog', [])
+ self.serviceCatalog = auth_ref.service_catalog.get_data()
class User(models.AnonymousUser):
@@ -331,11 +328,13 @@ class User(models.AnonymousUser):
regions = []
if self.service_catalog:
for service in self.service_catalog:
- if service['type'] == 'identity':
+ service_type = service.get('type')
+ if service_type is None or service_type == 'identity':
continue
- for endpoint in service['endpoints']:
- if endpoint['region'] not in regions:
- regions.append(endpoint['region'])
+ for endpoint in service.get('endpoints', []):
+ region = utils.get_endpoint_region(endpoint)
+ if region not in regions:
+ regions.append(region)
return regions
def save(*args, **kwargs):
diff --git a/openstack_auth/utils.py b/openstack_auth/utils.py
index 198c8a0..d861010 100644
--- a/openstack_auth/utils.py
+++ b/openstack_auth/utils.py
@@ -260,20 +260,24 @@ def default_services_region(service_catalog, request=None):
Extracted from the service catalog.
"""
if service_catalog:
- available_regions = [endpoint['region'] for service
+ available_regions = [get_endpoint_region(endpoint) for service
in service_catalog for endpoint
- in service['endpoints']
- if service['type'] != 'identity']
+ in service.get('endpoints', [])
+ if (service.get('type') is not None
+ and service.get('type') != 'identity')]
if not available_regions:
# this is very likely an incomplete keystone setup
LOG.warning('No regions could be found excluding identity.')
- available_regions = [endpoint['region'] for service
+ available_regions = [get_endpoint_region(endpoint) for service
in service_catalog for endpoint
- in service['endpoints']]
- if not available_regions:
- # this is a critical problem and it's not clear how this occurs
- LOG.error('No regions can be found in the service catalog.')
- return None
+ in service.get('endpoints', [])]
+
+ if not available_regions:
+ # if there are no region setup for any service endpoint,
+ # this is a critical problem and it's not clear how this occurs
+ LOG.error('No regions can be found in the service catalog.')
+ return None
+
selected_region = None
if request:
selected_region = request.COOKIES.get('services_region',
@@ -297,6 +301,18 @@ def set_response_cookie(response, cookie_name, cookie_value):
response.set_cookie(cookie_name, cookie_value, expires=expire_date)
+def get_endpoint_region(endpoint):
+ """Common function for getting the region from endpoint.
+
+ In Keystone V3, region has been deprecated in favor of
+ region_id.
+
+ This method provides a way to get region that works for both
+ Keystone V2 and V3.
+ """
+ return endpoint.get('region_id') or endpoint.get('region')
+
+
if django.VERSION < (1, 7):
try:
from importlib import import_module