summaryrefslogtreecommitdiffstats
path: root/keystone
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-02-27 01:30:09 +0000
committerGerrit Code Review <review@openstack.org>2013-02-27 01:30:09 +0000
commite865b978fbaf24f29c0797bf6589dc3f7df3f1d5 (patch)
tree8d3dad5fd57688d18aabb95ff7caa99a711a9b9e /keystone
parent5cfecddec07145d0b6594ecd982b713522536f00 (diff)
parent250e6716bd91f9cc3412c92e5341557e59837e1e (diff)
Merge "bug 1131840: fix auth and token data for XML translation"
Diffstat (limited to 'keystone')
-rw-r--r--keystone/auth/controllers.py26
-rw-r--r--keystone/auth/core.py28
-rw-r--r--keystone/auth/methods/token.py14
-rw-r--r--keystone/auth/token_factory.py14
-rw-r--r--keystone/common/controller.py2
-rw-r--r--keystone/common/serializer.py34
-rw-r--r--keystone/common/wsgi.py2
-rw-r--r--keystone/middleware/core.py3
8 files changed, 78 insertions, 45 deletions
diff --git a/keystone/auth/controllers.py b/keystone/auth/controllers.py
index d2eaa234..3760aa3a 100644
--- a/keystone/auth/controllers.py
+++ b/keystone/auth/controllers.py
@@ -187,15 +187,15 @@ class AuthInfo(object):
def _validate_auth_methods(self):
# make sure auth methods are provided
- if 'methods' not in self.auth['authentication']:
+ if 'methods' not in self.auth['identity']:
raise exception.ValidationError(attribute='methods',
- target='authentication')
+ target='identity')
# make sure all the method data/payload are provided
for method_name in self.get_method_names():
- if method_name not in self.auth['authentication']:
+ if method_name not in self.auth['identity']:
raise exception.ValidationError(attribute=method_name,
- target='authentication')
+ target='identity')
# make sure auth method is supported
for method_name in self.get_method_names():
@@ -213,12 +213,12 @@ class AuthInfo(object):
self._validate_and_normalize_scope_data()
def get_method_names(self):
- """ Returns the authentication method names.
+ """ Returns the identity method names.
:returns: list of auth method names
"""
- return self.auth['authentication']['methods']
+ return self.auth['identity']['methods']
def get_method_data(self, method):
""" Get the auth method payload.
@@ -226,10 +226,10 @@ class AuthInfo(object):
:returns: auth method payload
"""
- if method not in self.auth['authentication']['methods']:
+ if method not in self.auth['identity']['methods']:
raise exception.ValidationError(attribute=method_name,
- target='authentication')
- return self.auth['authentication'][method]
+ target='identity')
+ return self.auth['identity'][method]
def get_scope(self):
""" Get scope information.
@@ -257,13 +257,9 @@ class Auth(controller.V3Controller):
super(Auth, self).__init__(*args, **kw)
self.token_controllers_ref = token.controllers.Auth()
- def authenticate_for_token(self, context, authentication, scope=None):
+ def authenticate_for_token(self, context, auth=None):
""" Authenticate user and issue a token. """
try:
- auth = None
- auth = {'authentication': authentication}
- if scope:
- auth['scope'] = scope
auth_info = AuthInfo(context, auth=auth)
auth_context = {'extras': {}, 'method_names': []}
self.authenticate(context, auth_info, auth_context)
@@ -306,7 +302,7 @@ class Auth(controller.V3Controller):
# requiring domain_id to do user lookup now. Try to get
# the user_id from auth_info for now, assuming external auth
# has check to make sure user is the same as the one specify
- # in "authentication".
+ # in "identity".
if 'password' in auth_info.get_method_names():
user_info = auth_info.get_method_data('password')
user_ref = auth_info.lookup_user(user_info['user'])
diff --git a/keystone/auth/core.py b/keystone/auth/core.py
index 40f7d040..da70c43c 100644
--- a/keystone/auth/core.py
+++ b/keystone/auth/core.py
@@ -49,21 +49,23 @@ class AuthMethodHandler(object):
"extras": {}}
Plugins are invoked in the order in which they are specified in the
- "methods" attribute of the "authentication" request body.
+ "methods" attribute of the "identity" object.
For example, with the following authentication request,
- {"authentication": {
- "methods": ["custom-plugin", "password", "token"],
- "token": {
- "id": "sdfafasdfsfasfasdfds"
- },
- "custom-plugin": {
- "custom-data": "sdfdfsfsfsdfsf"
- },
- "password": {
- "user": {
- "id": "s23sfad1",
- "password": "secrete"
+ {"auth": {
+ "identity": {
+ "methods": ["custom-plugin", "password", "token"],
+ "token": {
+ "id": "sdfafasdfsfasfasdfds"
+ },
+ "custom-plugin": {
+ "custom-data": "sdfdfsfsfsdfsf"
+ },
+ "password": {
+ "user": {
+ "id": "s23sfad1",
+ "password": "secrete"
+ }
}
}
}}
diff --git a/keystone/auth/methods/token.py b/keystone/auth/methods/token.py
index 72006130..05c5385d 100644
--- a/keystone/auth/methods/token.py
+++ b/keystone/auth/methods/token.py
@@ -38,12 +38,14 @@ class Token(auth.AuthMethodHandler):
target=METHOD_NAME)
token_id = auth_payload['id']
token_ref = self.token_api.get_token(context, token_id)
- user_context.setdefault('user_id',
- token_ref['token_data']['user']['id'])
- user_context.setdefault('expires',
- token_ref['expires'])
- user_context['extras'].update(token_ref['token_data']['extras'])
- user_context['method_names'] += token_ref['token_data']['methods']
+ user_context.setdefault(
+ 'user_id', token_ref['token_data']['token']['user']['id'])
+ user_context.setdefault(
+ 'expires', token_ref['token_data']['token']['expires'])
+ user_context['extras'].update(
+ token_ref['token_data']['token']['extras'])
+ user_context['method_names'].extend(
+ token_ref['token_data']['token']['methods'])
except AssertionError as e:
LOG.error(e)
raise exception.Unauthorized(e)
diff --git a/keystone/auth/token_factory.py b/keystone/auth/token_factory.py
index 03d4ed74..4b1bf637 100644
--- a/keystone/auth/token_factory.py
+++ b/keystone/auth/token_factory.py
@@ -144,7 +144,7 @@ class TokenDataHelper(object):
self._populate_service_catalog(token_data, user_id, domain_id,
project_id)
self._populate_token(token_data, expires)
- return token_data
+ return {'token': token_data}
def recreate_token_data(context, token_data=None, expires=None,
@@ -161,6 +161,8 @@ def recreate_token_data(context, token_data=None, expires=None,
methods = ['password', 'token']
extras = {}
if token_data:
+ # peel the outer layer so its easier to operate
+ token_data = token_data['token']
domain_id = (token_data['domain']['id'] if 'domain' in token_data
else None)
project_id = (token_data['project']['id'] if 'project' in token_data
@@ -207,20 +209,20 @@ def create_token(context, auth_context, auth_info):
CONF.signing.token_format)
token_api = token_module.Manager()
try:
- expiry = token_data['expires']
+ expiry = token_data['token']['expires']
if isinstance(expiry, basestring):
expiry = timeutils.parse_isotime(expiry)
role_ids = []
- if 'project' in token_data:
+ if 'project' in token_data['token']:
# project-scoped token, fill in the v2 token data
# all we care are the role IDs
- role_ids = [role['id'] for role in token_data['roles']]
+ role_ids = [role['id'] for role in token_data['token']['roles']]
metadata_ref = {'roles': role_ids}
data = dict(key=token_id,
id=token_id,
expires=expiry,
- user=token_data['user'],
- tenant=token_data.get('project'),
+ user=token_data['token']['user'],
+ tenant=token_data['token'].get('project'),
metadata=metadata_ref,
token_data=token_data)
token_api.create_token(context, token_id, data)
diff --git a/keystone/common/controller.py b/keystone/common/controller.py
index 4d8c5ddc..c9300002 100644
--- a/keystone/common/controller.py
+++ b/keystone/common/controller.py
@@ -30,7 +30,7 @@ def _build_policy_check_credentials(self, action, context, kwargs):
creds = {}
if 'token_data' in token_ref:
#V3 Tokens
- token_data = token_ref['token_data']
+ token_data = token_ref['token_data']['token']
try:
creds['user_id'] = token_data['user']['id']
except AttributeError:
diff --git a/keystone/common/serializer.py b/keystone/common/serializer.py
index 2a33ee70..91a16be4 100644
--- a/keystone/common/serializer.py
+++ b/keystone/common/serializer.py
@@ -120,10 +120,28 @@ class XmlDeserializer(object):
# current spec does not have attributes on an element with text
values = values or text or {}
+ decoded_tag = XmlDeserializer._tag_name(element.tag, namespace)
+ list_item_tag = None
+ if decoded_tag[-1] == 's' and len(values) == 0:
+ # FIXME(gyee): special-case lists for now unti we
+ # figure out how to properly handle them.
+ # If any key ends with an 's', we are assuming it is a list.
+ # List element have no attributes.
+ values = list(values)
+ if decoded_tag == 'policies':
+ list_item_tag = 'policy'
+ else:
+ list_item_tag = decoded_tag[:-1]
for child in [self.walk_element(x) for x in element
if not isinstance(x, ENTITY_TYPE)]:
- values = dict(values.items() + child.items())
+ if list_item_tag:
+ # FIXME(gyee): special-case lists for now unti we
+ # figure out how to properly handle them.
+ # If any key ends with an 's', we are assuming it is a list.
+ values.append(child[list_item_tag])
+ else:
+ values = dict(values.items() + child.items())
return {XmlDeserializer._tag_name(element.tag, namespace): values}
@@ -173,7 +191,7 @@ class XmlSerializer(object):
container = etree.Element(k)
element.append(container)
name = k[:-1]
- elif k == 'serviceCatalog':
+ elif k == 'serviceCatalog' or k == 'catalog':
# xsd compliance: <serviceCatalog> contains <service>s
container = etree.Element(k)
element.append(container)
@@ -184,7 +202,13 @@ class XmlSerializer(object):
# unnecessary in XML
name = element.tag[:-1]
elif k[-1] == 's':
- name = k[:-1]
+ container = etree.Element(k)
+ element.append(container)
+ if k == 'policies':
+ # need to special-case policies since policie is not a word
+ name = 'policy'
+ else:
+ name = k[:-1]
else:
name = k
@@ -226,6 +250,8 @@ class XmlSerializer(object):
self._populate_sequence(element, value)
elif isinstance(value, dict):
self._populate_tree(element, value)
+ elif isinstance(value, basestring):
+ element.text = unicode(value)
def _populate_sequence(self, element, l):
"""Populates an etree with a sequence of elements, given a list."""
@@ -233,6 +259,8 @@ class XmlSerializer(object):
name = element.tag
if element.tag[-1] == 's':
name = element.tag[:-1]
+ if name == 'policie':
+ name = 'policy'
for item in l:
child = etree.Element(name)
diff --git a/keystone/common/wsgi.py b/keystone/common/wsgi.py
index a515eefe..108cc0ca 100644
--- a/keystone/common/wsgi.py
+++ b/keystone/common/wsgi.py
@@ -553,5 +553,5 @@ def render_exception(error):
'message': str(error)
}}
if isinstance(error, exception.AuthPluginException):
- body['authentication'] = error.authentication
+ body['error']['identity'] = error.authentication
return render_response(status=(error.code, error.title), body=body)
diff --git a/keystone/middleware/core.py b/keystone/middleware/core.py
index d904e3c0..29a6832b 100644
--- a/keystone/middleware/core.py
+++ b/keystone/middleware/core.py
@@ -16,6 +16,7 @@
import webob.dec
+from keystone.common import logging
from keystone.common import serializer
from keystone.common import utils
from keystone.common import wsgi
@@ -25,6 +26,7 @@ from keystone.openstack.common import jsonutils
CONF = config.CONF
+LOG = logging.getLogger(__name__)
# Header used to transmit the auth token
@@ -158,6 +160,7 @@ class XmlBodyMiddleware(wsgi.Middleware):
body_obj = jsonutils.loads(response.body)
response.body = serializer.to_xml(body_obj)
except Exception:
+ LOG.exception('Serializer failed')
raise exception.Error(message=response.body)
return response