Allow anonymous access for health and versions
Updates the context middleware to check for authentication upon routing the request instead of pre-routing. Adds a list to the base resource that means all requests must be authenticated by default, but allows for child resources to specify the HTTP methods that should not be authenticated. Change-Id: I369087430b403355ce551384b8d798465738b684
This commit is contained in:
parent
59b7d7f7b1
commit
8cc63164d2
@ -20,6 +20,15 @@ from deckhand import context
|
||||
class BaseResource(object):
|
||||
"""Base resource class for implementing API resources."""
|
||||
|
||||
# Shadowing no_authentication_methods and supplying the HTTP method as a
|
||||
# value (e.g. 'GET') allows that method to run without authentication. By
|
||||
# default all require authentication.
|
||||
# Warning: This method of skipping authentication is applied to a HTTP
|
||||
# method, which ultimately maps to a resource's on_ methods.
|
||||
# If a method such as on_get were to service both a list and a single
|
||||
# response, both would share the skipped authentication.
|
||||
no_authentication_methods = []
|
||||
|
||||
def on_options(self, req, resp):
|
||||
self_attrs = dir(self)
|
||||
|
||||
|
@ -18,9 +18,14 @@ from deckhand.control.base import BaseResource
|
||||
|
||||
|
||||
class HealthResource(BaseResource):
|
||||
"""A resource that allows other UCP components to access and validate
|
||||
"""Basic health check for Deckhand
|
||||
|
||||
A resource that allows other UCP components to access and validate
|
||||
Deckhand's health status. The response must be returned within 30 seconds
|
||||
for Deckhand to be deemed "healthy".
|
||||
Unauthenticated GET.
|
||||
"""
|
||||
no_authentication_methods = ['GET']
|
||||
|
||||
def on_get(self, req, resp):
|
||||
resp.status = falcon.HTTP_204
|
||||
|
@ -29,25 +29,37 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
class ContextMiddleware(object):
|
||||
|
||||
def process_request(self, req, resp):
|
||||
"""Convert authentication information into a request context.
|
||||
def process_resource(self, req, resp, resource, params):
|
||||
"""Handle the authentication needs of the routed request.
|
||||
|
||||
Generate a ``deckhand.context.RequestContext`` object from the
|
||||
available authentication headers and store in the ``context`` attribute
|
||||
of the ``req`` object.
|
||||
|
||||
:param req: ``falcon`` request object that will be given the context
|
||||
object.
|
||||
:param req: ``falcon`` request object that will be examined for method
|
||||
:param resource: ``falcon`` resource class that will be examined for
|
||||
authentication needs by looking at the no_authentication_methods
|
||||
list of http methods. By default, this will assume that all
|
||||
requests need authentication unless noted in this array.
|
||||
Note that this does not bypass any authorization checks, which will
|
||||
fail if the user is not authenticated.
|
||||
:raises: falcon.HTTPUnauthorized: when value of the
|
||||
'X-Identity-Status' header is not 'Confirmed' and anonymous access
|
||||
is disallowed.
|
||||
"""
|
||||
if req.headers.get('X-IDENTITY-STATUS') == 'Confirmed':
|
||||
req.context = deckhand.context.RequestContext.from_environ(req.env)
|
||||
elif CONF.allow_anonymous_access:
|
||||
req.context = deckhand.context.get_context()
|
||||
authentication_required = True
|
||||
try:
|
||||
if req.method in resource.no_authentication_methods:
|
||||
authentication_required = False
|
||||
except AttributeError:
|
||||
# assume that authentication is required.
|
||||
pass
|
||||
if authentication_required:
|
||||
if req.headers.get('X-IDENTITY-STATUS') == 'Confirmed':
|
||||
req.context = deckhand.context.RequestContext.from_environ(
|
||||
req.env)
|
||||
elif CONF.allow_anonymous_access:
|
||||
req.context = deckhand.context.get_context()
|
||||
else:
|
||||
raise falcon.HTTPUnauthorized()
|
||||
else:
|
||||
raise falcon.HTTPUnauthorized()
|
||||
req.context = deckhand.context.RequestContext.from_environ(req.env)
|
||||
|
||||
|
||||
class HookableMiddlewareMixin(object):
|
||||
|
@ -18,6 +18,12 @@ from deckhand.control import base as api_base
|
||||
|
||||
|
||||
class VersionsResource(api_base.BaseResource):
|
||||
"""Versions resource
|
||||
|
||||
Returns the list of supported versions of the Deckhand API.
|
||||
Unauthenticated GET.
|
||||
"""
|
||||
no_authentication_methods = ['GET']
|
||||
|
||||
def on_get(self, req, resp):
|
||||
resp.body = {
|
||||
|
Loading…
Reference in New Issue
Block a user