Coverage for nova/api/auth.py: 100%

54 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-04-17 15:08 +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. 

16 

17""" 

18 

19from oslo_log import log as logging 

20from oslo_log import versionutils 

21from oslo_serialization import jsonutils 

22import webob.dec 

23import webob.exc 

24 

25from nova.api import wsgi 

26import nova.conf 

27from nova import context 

28from nova.i18n import _ 

29 

30 

31CONF = nova.conf.CONF 

32LOG = logging.getLogger(__name__) 

33 

34 

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 

42 

43 

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 ) 

52 

53 

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()) 

66 

67 

68class InjectContext(wsgi.Middleware): 

69 """Add a 'nova.context' to WSGI environ.""" 

70 

71 def __init__(self, context, *args, **kwargs): 

72 self.context = context 

73 super(InjectContext, self).__init__(*args, **kwargs) 

74 

75 @webob.dec.wsgify(RequestClass=wsgi.Request) 

76 def __call__(self, req): 

77 req.environ['nova.context'] = self.context 

78 return self.application 

79 

80 

81class NovaKeystoneContext(wsgi.Middleware): 

82 """Make a request context from keystone headers.""" 

83 

84 @staticmethod 

85 def _create_context(env, **kwargs): 

86 """Create a context from a request environ. 

87 

88 This exists to make test stubbing easier. 

89 """ 

90 return context.RequestContext.from_environ(env, **kwargs) 

91 

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 

96 

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.')) 

105 

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') 

109 

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) 

115 

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() 

119 

120 req.environ['nova.context'] = ctx 

121 return self.application