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):
|
class BaseResource(object):
|
||||||
"""Base resource class for implementing API resources."""
|
"""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):
|
def on_options(self, req, resp):
|
||||||
self_attrs = dir(self)
|
self_attrs = dir(self)
|
||||||
|
|
||||||
|
@ -18,9 +18,14 @@ from deckhand.control.base import BaseResource
|
|||||||
|
|
||||||
|
|
||||||
class HealthResource(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
|
Deckhand's health status. The response must be returned within 30 seconds
|
||||||
for Deckhand to be deemed "healthy".
|
for Deckhand to be deemed "healthy".
|
||||||
|
Unauthenticated GET.
|
||||||
"""
|
"""
|
||||||
|
no_authentication_methods = ['GET']
|
||||||
|
|
||||||
def on_get(self, req, resp):
|
def on_get(self, req, resp):
|
||||||
resp.status = falcon.HTTP_204
|
resp.status = falcon.HTTP_204
|
||||||
|
@ -29,25 +29,37 @@ LOG = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class ContextMiddleware(object):
|
class ContextMiddleware(object):
|
||||||
|
|
||||||
def process_request(self, req, resp):
|
def process_resource(self, req, resp, resource, params):
|
||||||
"""Convert authentication information into a request context.
|
"""Handle the authentication needs of the routed request.
|
||||||
|
|
||||||
Generate a ``deckhand.context.RequestContext`` object from the
|
:param req: ``falcon`` request object that will be examined for method
|
||||||
available authentication headers and store in the ``context`` attribute
|
:param resource: ``falcon`` resource class that will be examined for
|
||||||
of the ``req`` object.
|
authentication needs by looking at the no_authentication_methods
|
||||||
|
list of http methods. By default, this will assume that all
|
||||||
:param req: ``falcon`` request object that will be given the context
|
requests need authentication unless noted in this array.
|
||||||
object.
|
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
|
:raises: falcon.HTTPUnauthorized: when value of the
|
||||||
'X-Identity-Status' header is not 'Confirmed' and anonymous access
|
'X-Identity-Status' header is not 'Confirmed' and anonymous access
|
||||||
is disallowed.
|
is disallowed.
|
||||||
"""
|
"""
|
||||||
if req.headers.get('X-IDENTITY-STATUS') == 'Confirmed':
|
authentication_required = True
|
||||||
req.context = deckhand.context.RequestContext.from_environ(req.env)
|
try:
|
||||||
elif CONF.allow_anonymous_access:
|
if req.method in resource.no_authentication_methods:
|
||||||
req.context = deckhand.context.get_context()
|
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:
|
else:
|
||||||
raise falcon.HTTPUnauthorized()
|
req.context = deckhand.context.RequestContext.from_environ(req.env)
|
||||||
|
|
||||||
|
|
||||||
class HookableMiddlewareMixin(object):
|
class HookableMiddlewareMixin(object):
|
||||||
|
@ -18,6 +18,12 @@ from deckhand.control import base as api_base
|
|||||||
|
|
||||||
|
|
||||||
class VersionsResource(api_base.BaseResource):
|
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):
|
def on_get(self, req, resp):
|
||||||
resp.body = {
|
resp.body = {
|
||||||
|
Loading…
Reference in New Issue
Block a user