ekko/ekko/api/middleware/auth_token.py
Paul Bourke a5f99317ac Add bare bones ekko-api
Foundation for ekko-api, ported over from the Ironic project.

The goal here was to copy enough to give a solid foundation that
conforms to the "OpenStack way", without a lot of extra frills that we
either may not need right away, or makes it harder see what's going on
starting out.

After installation the service can be started via 'ekko-api', which
listens on port 6800 by default. This was chosen from the list of
unassigned ports at
http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt

There are still plenty of TODO's, primarily keystone integration and
config file generation. Foundations for these are here but completely
untested as of this commit.

Change-Id: If136a3bb66949ef710d741eaf3691f36f7b60692
2016-02-08 01:07:34 +00:00

65 lines
2.3 KiB
Python

#
# 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 keystonemiddleware import auth_token
from oslo_log import log
from ekko.common import exception
LOG = log.getLogger(__name__)
# TODO(pbourke): add i18n support
_ = lambda x: x
class AuthTokenMiddleware(auth_token.AuthProtocol):
"""A wrapper on Keystone auth_token middleware.
Does not perform verification of authentication tokens
for public routes in the API.
"""
def __init__(self, app, conf, public_api_routes=[]):
self._ekko_app = app
# 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 public_api_routes]
except re.error as e:
msg = _('Cannot compile public API routes: %s') % e
LOG.error(msg)
raise exception.ConfigInvalid(error_msg=msg)
super(AuthTokenMiddleware, self).__init__(app, conf)
def __call__(self, env, start_response):
# TODO(pbourke): ironic uses a utils.safe_rstrip function here.
path = env.get('PATH_INFO').rstrip('/')
# 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._ekko_app(env, start_response)
return super(AuthTokenMiddleware, self).__call__(env, start_response)