diff options
author | Brant Knudson <bknudson@us.ibm.com> | 2013-07-25 17:43:36 -0500 |
---|---|---|
committer | Brant Knudson <bknudson@us.ibm.com> | 2013-08-14 18:09:01 -0500 |
commit | 760856e9669b0af20909c56d4a5a082bd4d7e450 (patch) | |
tree | b32c7c0547d8ee19e5e4c954aa2d2d729d9d6057 /keystone/common/wsgi.py | |
parent | 14e090154c10001550127628c2728013f15d4256 (diff) | |
download | keystone-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.py | 37 |
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 |