Skip to content
Snippets Groups Projects
Unverified Commit 08d7a8fb authored by Duncan Macleod's avatar Duncan Macleod
Browse files

application: refactor auth handling

try all auth systems to find a 200 (authorised) response, rather than only trying the first one that doesn't fail - also, do this before attempting to connect to the database.
parent 472a1dab
Branches main
No related tags found
No related merge requests found
Pipeline #502551 failed
...@@ -26,6 +26,43 @@ import LDBDWAuth ...@@ -26,6 +26,43 @@ import LDBDWAuth
import logging import logging
import time import time
def _authorize(environ, *auth_funcs):
"""Authorize a response.
This function loops through the ``auth_funcs``, and returns as soon
as an authorised response comes back.
"""
# if request is not a GET, it's a write operation
iswrite = environ["REQUEST_METHOD"].upper() != "GET"
res = None
for auth_func in (
ldbdsauth.check_authorization_scitoken,
ldbdwauth.check_authorization_gridmap,
):
# authenticate
try:
res = auth_func(
environ,
environ['REQUEST_METHOD'],
environ['REQUEST_URI'],
iswrite,
)
except: # something went wrong, try the next method
continue
# if authorised, return that status
if res[0] == 200:
return res
if res is None:
# all of the authorisation functions failed!
return RuntimeError("no authorisation available")
# return unauthorised response (likely 401)
return res
def application(environ, start_response): def application(environ, start_response):
# Instantiate logger. # Instantiate logger.
constant = Constants.ConstantsHandle() constant = Constants.ConstantsHandle()
...@@ -38,37 +75,32 @@ def application(environ, start_response): ...@@ -38,37 +75,32 @@ def application(environ, start_response):
reqhan = Request.RequestHandle() reqhan = Request.RequestHandle()
ldbdsauth = LDBDWAuth.SciTokensAuthorization() ldbdsauth = LDBDWAuth.SciTokensAuthorization()
ldbdwauth = LDBDWAuth.GridmapAuthorization() ldbdwauth = LDBDWAuth.GridmapAuthorization()
# Set HTTP code and log. # Set HTTP code and log.
res = admin.log_and_set_http_code(400, 0, environ['REQUEST_METHOD'], None, environ['REQUEST_URI']) res = admin.log_and_set_http_code(400, 0, environ['REQUEST_METHOD'], None, environ['REQUEST_URI'])
# Connect to DB.
if dao.connect_to_db(environ['REQUEST_METHOD'], environ['REQUEST_URI']): # Attempt authorisation
try:
res = _authorize(environ)
except RuntimeError:
# no auth, keep 400 (Bad Request) from above
pass
# If the request is authorized and we can connect to the DB:
if res[0] == 200 and dao.connect_to_db(environ['REQUEST_METHOD'], environ['REQUEST_URI']):
# Respond to a GET request. # Respond to a GET request.
if environ['REQUEST_METHOD'] == 'GET': if environ['REQUEST_METHOD'] == 'GET':
# Authenticate. # Get content for output.
try: res = reqhan.serve_get_uri(environ['REQUEST_METHOD'], environ['REQUEST_URI'], environ['PATH_INFO'], environ['QUERY_STRING'])
res = ldbdsauth.check_authorization_scitoken(environ, environ['REQUEST_METHOD'], environ['REQUEST_URI'], False)
except:
res = ldbdwauth.check_authorization_gridmap(environ, environ['REQUEST_METHOD'], environ['REQUEST_URI'], False)
# If authentication successful.
if res[0] == 200:
# Get content for output.
res = reqhan.serve_get_uri(environ['REQUEST_METHOD'], environ['REQUEST_URI'], environ['PATH_INFO'], environ['QUERY_STRING'])
# Respond to a PUT request. # Respond to a PUT request.
elif environ['REQUEST_METHOD'] == 'PUT' or environ['REQUEST_METHOD'] == 'PATCH': elif environ['REQUEST_METHOD'] == 'PUT' or environ['REQUEST_METHOD'] == 'PATCH':
# Authorise. # Get the size of the requested JSON.
try: try:
res = ldbdsauth.check_authorization_scitoken(environ, environ['REQUEST_METHOD'], environ['REQUEST_URI'], True) request_body_size = int(environ.get('CONTENT_LENGTH', 0))
except: except:
res = ldbdwauth.check_authorization_gridmap(environ, environ['REQUEST_METHOD'], environ['REQUEST_URI'], True) request_body_size = 0
# If authorisation successful. # Process PUT or PATCH request.
if res[0] == 200: res = reqhan.serve_put_or_patch_uri(environ['REQUEST_METHOD'], environ['REQUEST_URI'], environ['PATH_INFO'], environ['QUERY_STRING'], environ['wsgi.input'].read(request_body_size))
# Get the size of the requested JSON.
try:
request_body_size = int(environ.get('CONTENT_LENGTH', 0))
except:
request_body_size = 0
# Process PUT or PATCH request.
res = reqhan.serve_put_or_patch_uri(environ['REQUEST_METHOD'], environ['REQUEST_URI'], environ['PATH_INFO'], environ['QUERY_STRING'], environ['wsgi.input'].read(request_body_size))
# Check first character to check content is Python dictionary converted to JSON. # Check first character to check content is Python dictionary converted to JSON.
if not res[1][:1] == '{': if not res[1][:1] == '{':
# Handle error. # Handle error.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment