Coverage for nova/api/auth.py: 100%
54 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-24 11:16 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-24 11:16 +0000
1# Copyright (c) 2011 OpenStack Foundation
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14"""
15Common Auth Middleware.
17"""
19from oslo_log import log as logging
20from oslo_log import versionutils
21from oslo_serialization import jsonutils
22import webob.dec
23import webob.exc
25from nova.api import wsgi
26import nova.conf
27from nova import context
28from nova.i18n import _
31CONF = nova.conf.CONF
32LOG = logging.getLogger(__name__)
35def _load_pipeline(loader, pipeline):
36 filters = [loader.get_filter(n) for n in pipeline[:-1]]
37 app = loader.get_app(pipeline[-1])
38 filters.reverse()
39 for filter in filters:
40 app = filter(app)
41 return app
44def pipeline_factory(loader, global_conf, **local_conf):
45 """A paste pipeline replica that keys off of auth_strategy."""
46 versionutils.report_deprecated_feature(
47 LOG,
48 "The legacy V2 API code tree has been removed in Newton. "
49 "Please remove legacy v2 API entry from api-paste.ini, and use "
50 "V2.1 API or V2.1 API compat mode instead"
51 )
54def pipeline_factory_v21(loader, global_conf, **local_conf):
55 """A paste pipeline replica that keys off of auth_strategy."""
56 auth_strategy = CONF.api.auth_strategy
57 if auth_strategy == 'noauth2':
58 versionutils.report_deprecated_feature(
59 LOG,
60 "'[api]auth_strategy=noauth2' is deprecated as of the 21.0.0 "
61 "Ussuri release and will be removed in a future release. Please "
62 "remove any 'noauth2' entries from api-paste.ini; only the "
63 "'keystone' pipeline is supported."
64 )
65 return _load_pipeline(loader, local_conf[auth_strategy].split())
68class InjectContext(wsgi.Middleware):
69 """Add a 'nova.context' to WSGI environ."""
71 def __init__(self, context, *args, **kwargs):
72 self.context = context
73 super(InjectContext, self).__init__(*args, **kwargs)
75 @webob.dec.wsgify(RequestClass=wsgi.Request)
76 def __call__(self, req):
77 req.environ['nova.context'] = self.context
78 return self.application
81class NovaKeystoneContext(wsgi.Middleware):
82 """Make a request context from keystone headers."""
84 @staticmethod
85 def _create_context(env, **kwargs):
86 """Create a context from a request environ.
88 This exists to make test stubbing easier.
89 """
90 return context.RequestContext.from_environ(env, **kwargs)
92 @webob.dec.wsgify(RequestClass=wsgi.Request)
93 def __call__(self, req):
94 # Build a context, including the auth_token...
95 remote_address = req.remote_addr
97 service_catalog = None
98 if req.headers.get('X_SERVICE_CATALOG') is not None:
99 try:
100 catalog_header = req.headers.get('X_SERVICE_CATALOG')
101 service_catalog = jsonutils.loads(catalog_header)
102 except ValueError:
103 raise webob.exc.HTTPInternalServerError(
104 _('Invalid service catalog json.'))
106 # NOTE(jamielennox): This is a full auth plugin set by auth_token
107 # middleware in newer versions.
108 user_auth_plugin = req.environ.get('keystone.token_auth')
110 ctx = self._create_context(
111 req.environ,
112 user_auth_plugin=user_auth_plugin,
113 remote_address=remote_address,
114 service_catalog=service_catalog)
116 if ctx.user_id is None:
117 LOG.debug("Neither X_USER_ID nor X_USER found in request")
118 return webob.exc.HTTPUnauthorized()
120 req.environ['nova.context'] = ctx
121 return self.application