a017447ec3
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
57 lines
2.1 KiB
Python
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)
|