summaryrefslogtreecommitdiffstats
path: root/keystone/common/wsgi.py
diff options
context:
space:
mode:
authorBrant Knudson <bknudson@us.ibm.com>2013-07-25 17:43:36 -0500
committerBrant Knudson <bknudson@us.ibm.com>2013-08-14 18:09:01 -0500
commit760856e9669b0af20909c56d4a5a082bd4d7e450 (patch)
treeb32c7c0547d8ee19e5e4c954aa2d2d729d9d6057 /keystone/common/wsgi.py
parent14e090154c10001550127628c2728013f15d4256 (diff)
downloadkeystone-760856e9669b0af20909c56d4a5a082bd4d7e450.tar.gz
keystone-760856e9669b0af20909c56d4a5a082bd4d7e450.tar.xz
keystone-760856e9669b0af20909c56d4a5a082bd4d7e450.zip
Add support for API message localization
Add support for doing language resolution for a request, based on the Accept-Language HTTP header. Using the lazy gettext functionality from oslo gettextutils, it is possible to use the resolved language to translate an exception message to the user requested language and return that translation from the API. Co-authored-by: Luis A. Garcia <luis@linux.vnet.ibm.com> Co-authored-by: Mathew Odden <mrodden@us.ibm.com> Implements bp user-locale-api Change-Id: Id8e92a42039d2f0b01d5c2dada733d068b2bdfeb
Diffstat (limited to 'keystone/common/wsgi.py')
-rw-r--r--keystone/common/wsgi.py37
1 files changed, 26 insertions, 11 deletions
diff --git a/keystone/common/wsgi.py b/keystone/common/wsgi.py
index f47cde13..ae199d74 100644
--- a/keystone/common/wsgi.py
+++ b/keystone/common/wsgi.py
@@ -30,6 +30,7 @@ from keystone.common import config
from keystone.common import logging
from keystone.common import utils
from keystone import exception
+from keystone.openstack.common import gettextutils
from keystone.openstack.common import importutils
from keystone.openstack.common import jsonutils
@@ -134,7 +135,14 @@ class WritableLogger(object):
class Request(webob.Request):
- pass
+ def best_match_language(self):
+ """Determines the best available locale from the Accept-Language
+ HTTP header passed in the request.
+ """
+
+ return self.accept_language.best_match(
+ gettextutils.get_available_languages('keystone'),
+ default_match='en_US')
class BaseApplication(object):
@@ -242,16 +250,18 @@ class Application(BaseApplication):
LOG.warning(
_('Authorization failed. %(exception)s from %(remote_addr)s') %
{'exception': e, 'remote_addr': req.environ['REMOTE_ADDR']})
- return render_exception(e)
+ return render_exception(e, user_locale=req.best_match_language())
except exception.Error as e:
LOG.warning(e)
- return render_exception(e)
+ return render_exception(e, user_locale=req.best_match_language())
except TypeError as e:
LOG.exception(e)
- return render_exception(exception.ValidationError(e))
+ return render_exception(exception.ValidationError(e),
+ user_locale=req.best_match_language())
except Exception as e:
LOG.exception(e)
- return render_exception(exception.UnexpectedError(exception=e))
+ return render_exception(exception.UnexpectedError(exception=e),
+ user_locale=req.best_match_language())
if result is None:
return render_response(status=(204, 'No Content'))
@@ -375,13 +385,16 @@ class Middleware(Application):
return self.process_response(request, response)
except exception.Error as e:
LOG.warning(e)
- return render_exception(e)
+ return render_exception(e,
+ user_locale=request.best_match_language())
except TypeError as e:
LOG.exception(e)
- return render_exception(exception.ValidationError(e))
+ return render_exception(exception.ValidationError(e),
+ user_locale=request.best_match_language())
except Exception as e:
LOG.exception(e)
- return render_exception(exception.UnexpectedError(exception=e))
+ return render_exception(exception.UnexpectedError(exception=e),
+ user_locale=request.best_match_language())
class Debug(Middleware):
@@ -483,7 +496,8 @@ class Router(object):
match = req.environ['wsgiorg.routing_args'][1]
if not match:
return render_exception(
- exception.NotFound(_('The resource could not be found.')))
+ exception.NotFound(_('The resource could not be found.')),
+ user_locale=req.best_match_language())
app = match['controller']
return app
@@ -577,12 +591,13 @@ def render_response(body=None, status=None, headers=None):
headerlist=headers)
-def render_exception(error):
+def render_exception(error, user_locale=None):
"""Forms a WSGI response based on the current error."""
body = {'error': {
'code': error.code,
'title': error.title,
- 'message': unicode(error)
+ 'message': unicode(gettextutils.get_localized_message(error.args[0],
+ user_locale)),
}}
if isinstance(error, exception.AuthPluginException):
body['error']['identity'] = error.authentication