ironic/ironic/api/middleware/auth_public_routes.py
Steve Baker a017447ec3 Encapsulate auth_token middleware
The existing public routes middleware wrapper subclasses the
keystoneauth middleware. This change refactors it to an encapsulation
of any middleware. In the future this allows for different auth
strategies by passing different auth middleware.

Change-Id: I51ae072e596e987334b79a0b6dfc4905bcf2bcef
Story: 2007656
Task: 39769
2020-05-15 09:49:54 +12:00

57 lines
2.1 KiB
Python

# -*- encoding: utf-8 -*-
#
# 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 re
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import utils
class AuthPublicRoutes(object):
"""A wrapper on authentication middleware.
Does not perform verification of authentication tokens
for public routes in the API.
"""
def __init__(self, app, auth, public_api_routes=None):
api_routes = [] if public_api_routes is None else public_api_routes
self._ironic_app = app
self._middleware = auth
# TODO(mrda): Remove .xml and ensure that doesn't result in a
# 401 Authentication Required instead of 404 Not Found
route_pattern_tpl = '%s(\\.json|\\.xml)?$'
try:
self.public_api_routes = [re.compile(route_pattern_tpl % route_tpl)
for route_tpl in api_routes]
except re.error as e:
raise exception.ConfigInvalid(
error_msg=_('Cannot compile public API routes: %s') % e)
def __call__(self, env, start_response):
path = utils.safe_rstrip(env.get('PATH_INFO'), '/')
# The information whether the API call is being performed against the
# public API is required for some other components. Saving it to the
# WSGI environment is reasonable thereby.
env['is_public_api'] = any(map(lambda pattern: re.match(pattern, path),
self.public_api_routes))
if env['is_public_api']:
return self._ironic_app(env, start_response)
return self._middleware(env, start_response)