--- /dev/null
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2011 OpenStack, LLC
+# Copyright 2010 OpenStack LLC.
+# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
Common Auth Middleware.
"""
+import os
import webob.dec
import webob.exc
+from cinder.api.openstack import wsgi
from cinder import context
from cinder import flags
from cinder.openstack.common import cfg
from cinder.openstack.common import log as logging
-from cinder import wsgi
+from cinder import wsgi as base_wsgi
use_forwarded_for_opt = cfg.BoolOpt('use_forwarded_for',
return app
-class InjectContext(wsgi.Middleware):
+class InjectContext(base_wsgi.Middleware):
"""Add a 'cinder.context' to WSGI environ."""
def __init__(self, context, *args, **kwargs):
self.context = context
super(InjectContext, self).__init__(*args, **kwargs)
- @webob.dec.wsgify(RequestClass=wsgi.Request)
+ @webob.dec.wsgify(RequestClass=base_wsgi.Request)
def __call__(self, req):
req.environ['cinder.context'] = self.context
return self.application
-class CinderKeystoneContext(wsgi.Middleware):
+class CinderKeystoneContext(base_wsgi.Middleware):
"""Make a request context from keystone headers"""
- @webob.dec.wsgify(RequestClass=wsgi.Request)
+ @webob.dec.wsgify(RequestClass=base_wsgi.Request)
def __call__(self, req):
user_id = req.headers.get('X_USER')
user_id = req.headers.get('X_USER_ID', user_id)
req.environ['cinder.context'] = ctx
return self.application
+
+
+class NoAuthMiddleware(base_wsgi.Middleware):
+ """Return a fake token if one isn't specified."""
+
+ @webob.dec.wsgify(RequestClass=wsgi.Request)
+ def __call__(self, req):
+ if 'X-Auth-Token' not in req.headers:
+ user_id = req.headers.get('X-Auth-User', 'admin')
+ project_id = req.headers.get('X-Auth-Project-Id', 'admin')
+ os_url = os.path.join(req.url, project_id)
+ res = webob.Response()
+ # NOTE(vish): This is expecting and returning Auth(1.1), whereas
+ # keystone uses 2.0 auth. We should probably allow
+ # 2.0 auth here as well.
+ res.headers['X-Auth-Token'] = '%s:%s' % (user_id, project_id)
+ res.headers['X-Server-Management-Url'] = os_url
+ res.content_type = 'text/plain'
+ res.status = '204'
+ return res
+
+ token = req.headers['X-Auth-Token']
+ user_id, _sep, project_id = token.partition(':')
+ project_id = project_id or user_id
+ remote_address = getattr(req, 'remote_address', '127.0.0.1')
+ if FLAGS.use_forwarded_for:
+ remote_address = req.headers.get('X-Forwarded-For', remote_address)
+ ctx = context.RequestContext(user_id,
+ project_id,
+ is_admin=True,
+ remote_address=remote_address)
+
+ req.environ['cinder.context'] = ctx
+ return self.application
--- /dev/null
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import webob.dec
+import webob.exc
+
+from cinder.api.openstack import wsgi
+from cinder.openstack.common import log as logging
+from cinder import utils
+from cinder import wsgi as base_wsgi
+
+
+LOG = logging.getLogger(__name__)
+
+
+class FaultWrapper(base_wsgi.Middleware):
+ """Calls down the middleware stack, making exceptions into faults."""
+
+ _status_to_type = {}
+
+ @staticmethod
+ def status_to_type(status):
+ if not FaultWrapper._status_to_type:
+ for clazz in utils.walk_class_hierarchy(webob.exc.HTTPError):
+ FaultWrapper._status_to_type[clazz.code] = clazz
+ return FaultWrapper._status_to_type.get(
+ status, webob.exc.HTTPInternalServerError)()
+
+ def _error(self, inner, req):
+ LOG.exception(_("Caught error: %s"), unicode(inner))
+
+ safe = getattr(inner, 'safe', False)
+ headers = getattr(inner, 'headers', None)
+ status = getattr(inner, 'code', 500)
+ if status is None:
+ status = 500
+
+ msg_dict = dict(url=req.url, status=status)
+ LOG.info(_("%(url)s returned with HTTP %(status)d") % msg_dict)
+ outer = self.status_to_type(status)
+ if headers:
+ outer.headers = headers
+ # NOTE(johannes): We leave the explanation empty here on
+ # purpose. It could possibly have sensitive information
+ # that should not be returned back to the user. See
+ # bugs 868360 and 874472
+ # NOTE(eglynn): However, it would be over-conservative and
+ # inconsistent with the EC2 API to hide every exception,
+ # including those that are safe to expose, see bug 1021373
+ if safe:
+ outer.explanation = '%s: %s' % (inner.__class__.__name__,
+ unicode(inner))
+ return wsgi.Fault(outer)
+
+ @webob.dec.wsgify(RequestClass=wsgi.Request)
+ def __call__(self, req):
+ try:
+ return req.get_response(self.application)
+ except Exception as ex:
+ return self._error(ex, req)
"""
import routes
-import webob.dec
-import webob.exc
from cinder.api.openstack import wsgi
from cinder.openstack.common import log as logging
LOG = logging.getLogger(__name__)
-class FaultWrapper(base_wsgi.Middleware):
- """Calls down the middleware stack, making exceptions into faults."""
-
- _status_to_type = {}
-
- @staticmethod
- def status_to_type(status):
- if not FaultWrapper._status_to_type:
- for clazz in utils.walk_class_hierarchy(webob.exc.HTTPError):
- FaultWrapper._status_to_type[clazz.code] = clazz
- return FaultWrapper._status_to_type.get(
- status, webob.exc.HTTPInternalServerError)()
-
- def _error(self, inner, req):
- LOG.exception(_("Caught error: %s"), unicode(inner))
-
- safe = getattr(inner, 'safe', False)
- headers = getattr(inner, 'headers', None)
- status = getattr(inner, 'code', 500)
- if status is None:
- status = 500
-
- msg_dict = dict(url=req.url, status=status)
- LOG.info(_("%(url)s returned with HTTP %(status)d") % msg_dict)
- outer = self.status_to_type(status)
- if headers:
- outer.headers = headers
- # NOTE(johannes): We leave the explanation empty here on
- # purpose. It could possibly have sensitive information
- # that should not be returned back to the user. See
- # bugs 868360 and 874472
- # NOTE(eglynn): However, it would be over-conservative and
- # inconsistent with the EC2 API to hide every exception,
- # including those that are safe to expose, see bug 1021373
- if safe:
- outer.explanation = '%s: %s' % (inner.__class__.__name__,
- unicode(inner))
- return wsgi.Fault(outer)
-
- @webob.dec.wsgify(RequestClass=wsgi.Request)
- def __call__(self, req):
- try:
- return req.get_response(self.application)
- except Exception as ex:
- return self._error(ex, req)
-
-
class APIMapper(routes.Mapper):
def routematch(self, url=None, environ=None):
if url is "":
+++ /dev/null
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 OpenStack LLC.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import os
-
-import webob.dec
-import webob.exc
-
-from cinder.api.openstack import wsgi
-from cinder import context
-from cinder import flags
-from cinder.openstack.common import log as logging
-from cinder import wsgi as base_wsgi
-
-LOG = logging.getLogger(__name__)
-FLAGS = flags.FLAGS
-flags.DECLARE('use_forwarded_for', 'cinder.api.auth')
-
-
-class NoAuthMiddleware(base_wsgi.Middleware):
- """Return a fake token if one isn't specified."""
-
- @webob.dec.wsgify(RequestClass=wsgi.Request)
- def __call__(self, req):
- if 'X-Auth-Token' not in req.headers:
- user_id = req.headers.get('X-Auth-User', 'admin')
- project_id = req.headers.get('X-Auth-Project-Id', 'admin')
- os_url = os.path.join(req.url, project_id)
- res = webob.Response()
- # NOTE(vish): This is expecting and returning Auth(1.1), whereas
- # keystone uses 2.0 auth. We should probably allow
- # 2.0 auth here as well.
- res.headers['X-Auth-Token'] = '%s:%s' % (user_id, project_id)
- res.headers['X-Server-Management-Url'] = os_url
- res.content_type = 'text/plain'
- res.status = '204'
- return res
-
- token = req.headers['X-Auth-Token']
- user_id, _sep, project_id = token.partition(':')
- project_id = project_id or user_id
- remote_address = getattr(req, 'remote_address', '127.0.0.1')
- if FLAGS.use_forwarded_for:
- remote_address = req.headers.get('X-Forwarded-For', remote_address)
- ctx = context.RequestContext(user_id,
- project_id,
- is_admin=True,
- remote_address=remote_address)
-
- req.environ['cinder.context'] = ctx
- return self.application
import webob
-import cinder.api.auth
+import cinder.api.middleware.auth
from cinder import test
return webob.Response()
self.context = None
- self.middleware = cinder.api.auth.CinderKeystoneContext(fake_app)
+ self.middleware = (cinder.api.middleware.auth
+ .CinderKeystoneContext(fake_app))
self.request = webob.Request.blank('/')
self.request.headers['X_TENANT_ID'] = 'testtenantid'
self.request.headers['X_AUTH_TOKEN'] = 'testauthtoken'
import webob
-import cinder.api.sizelimit
+import cinder.api.middleware.sizelimit
from cinder import flags
from cinder import test
def fake_app(req):
return webob.Response()
- self.middleware = cinder.api.sizelimit.RequestBodySizeLimiter(fake_app)
+ self.middleware = (cinder.api.middleware.sizelimit
+ .RequestBodySizeLimiter(fake_app))
self.request = webob.Request.blank('/', method='POST')
def test_content_length_acceptable(self):
import webob.dec
import webob.request
-from cinder.api import auth as api_auth
-from cinder.api import openstack as openstack_api
-from cinder.api.openstack import auth
+from cinder.api.middleware import auth
+from cinder.api.middleware import fault
from cinder.api.openstack import volume
from cinder.api.openstack.volume import limits
from cinder.api.openstack import wsgi as os_wsgi
ctxt = fake_auth_context
else:
ctxt = context.RequestContext('fake', 'fake', auth_token=True)
- api_v1 = openstack_api.FaultWrapper(api_auth.InjectContext(ctxt,
+ api_v1 = fault.FaultWrapper(auth.InjectContext(ctxt,
inner_app_v1))
elif use_no_auth:
- api_v1 = openstack_api.FaultWrapper(auth.NoAuthMiddleware(
+ api_v1 = fault.FaultWrapper(auth.NoAuthMiddleware(
limits.RateLimitingMiddleware(inner_app_v1)))
else:
- api_v1 = openstack_api.FaultWrapper(auth.AuthMiddleware(
+ api_v1 = fault.FaultWrapper(auth.AuthMiddleware(
limits.RateLimitingMiddleware(inner_app_v1)))
mapper = urlmap.URLMap()
mapper['/v1'] = api_v1
- mapper['/'] = openstack_api.FaultWrapper(versions.Versions())
+ mapper['/'] = fault.FaultWrapper(versions.Versions())
return mapper
import unittest
import webob.dec
-from cinder.api import openstack as openstack_api
+from cinder.api.middleware import fault
from cinder import exception
from cinder import test
import cinder.wsgi
class ExceptionTest(test.TestCase):
def _wsgi_app(self, inner_app):
- return openstack_api.FaultWrapper(inner_app)
+ return fault.FaultWrapper(inner_app)
def _do_test_exception_safety_reflected_in_faults(self, expose):
class ExceptionWithSafety(exception.CinderException):
/v1: openstack_volume_api_v1
[composite:openstack_volume_api_v1]
-use = call:cinder.api.auth:pipeline_factory
+use = call:cinder.api.middleware.auth:pipeline_factory
noauth = faultwrap sizelimit noauth osapi_volume_app_v1
keystone = faultwrap sizelimit authtoken keystonecontext osapi_volume_app_v1
keystone_nolimit = faultwrap sizelimit authtoken keystonecontext osapi_volume_app_v1
[filter:faultwrap]
-paste.filter_factory = cinder.api.openstack:FaultWrapper.factory
+paste.filter_factory = cinder.api.middleware.fault:FaultWrapper.factory
[filter:noauth]
-paste.filter_factory = cinder.api.openstack.auth:NoAuthMiddleware.factory
+paste.filter_factory = cinder.api.middleware.auth:NoAuthMiddleware.factory
[filter:sizelimit]
-paste.filter_factory = cinder.api.sizelimit:RequestBodySizeLimiter.factory
+paste.filter_factory = cinder.api.middleware.sizelimit:RequestBodySizeLimiter.factory
[app:osapi_volume_app_v1]
paste.app_factory = cinder.api.openstack.volume:APIRouter.factory
##########
[filter:keystonecontext]
-paste.filter_factory = cinder.api.auth:CinderKeystoneContext.factory
+paste.filter_factory = cinder.api.middleware.auth:CinderKeystoneContext.factory
[filter:authtoken]
paste.filter_factory = keystone.middleware.auth_token:filter_factory