11"""Authorization for API Keys within the SDS."""
22
3+ import logging
4+
35import boto3
46
7+ from sds_data_manager .lambda_code .authorization .manage_api_keys import VALID_SCOPES
8+
9+ # Configure logging
10+ logger = logging .getLogger ()
11+ logger .setLevel (logging .INFO )
12+
513# Initialize DynamoDB resource
614# Specifically outside of the handler to be cached in the lambda execution environment
715dynamodb = boto3 .resource ("dynamodb" )
816table = dynamodb .Table ("imap-sdc-api-keys" )
917
1018
11- def _is_authorized (api_key , scope , path , http_method ):
19+ def _is_authorized (scope , path , http_method ):
1220 """Check if the API key is authorized for the requested operation.
1321
1422 Parameters
1523 ----------
16- api_key : str
17- The API key from the request
1824 scope : str
1925 The scope/permission level of the API key
2026 path : str
@@ -27,22 +33,27 @@ def _is_authorized(api_key, scope, path, http_method):
2733 bool
2834 True if authorized, False otherwise
2935 """
30- # Restrict write operations for read-only scope
36+ logger .info (
37+ f"Checking authorization - scope: { scope } , path: { path } , method: { http_method } "
38+ )
39+
40+ # Restrict write operations for read scope
3141 if scope == "read" and http_method in ("PUT" , "POST" , "DELETE" , "PATCH" ):
42+ logger .warning (
43+ f"DENIED: read scope user attempted { http_method } operation on { path } "
44+ )
3245 return False
3346
34- # Restrict write operations (upload) for read-only scope
47+ # Restrict write operations (upload) for read scope
3548 if scope == "read" and path .startswith ("/api-key/upload" ):
49+ logger .warning (f"DENIED: read scope user attempted upload on { path } " )
3650 return False
3751
3852 # Check scope-based authorization for specific endpoints
39- if path .startswith ("/ialirt-db-query" ) and scope not in (
40- "ialirt_db" ,
41- "full" ,
42- "ialirt_external_partner" ,
43- "ialirt_scientist" ,
44- "read" ,
45- ):
53+ if path .startswith ("/ialirt-db-query" ) and scope not in VALID_SCOPES :
54+ logger .warning (
55+ f"DENIED: scope '{ scope } ' not authorized for /ialirt-db-query endpoint"
56+ )
4657 return False
4758
4859 # Public download except for logs and packets.
@@ -55,8 +66,12 @@ def _is_authorized(api_key, scope, path, http_method):
5566 "ialirt_scientist" ,
5667 "read" ,
5768 ):
69+ logger .warning (
70+ f"DENIED: scope '{ scope } ' not authorized for I-ALiRT download endpoint"
71+ )
5872 return False
5973
74+ logger .info (f"AUTHORIZED: API key with scope '{ scope } ' granted access to { path } " )
6075 return True
6176
6277
@@ -65,23 +80,32 @@ def lambda_handler(event, context):
6580 api_key = event .get ("headers" , {}).get ("x-api-key" , None )
6681
6782 if not api_key :
83+ logger .warning ("DENIED: No API key provided in request headers" )
6884 return {"isAuthorized" : False }
6985
86+ logger .info ("API key received. Checking authorization..." )
87+
7088 # Retrieve metadata from DynamoDB
7189 try :
7290 metadata = table .get_item (Key = {"api_key" : api_key }).get ("Item" )
73- except Exception :
74- # Log? print (f"Error retrieving API key metadata: {e}")
91+ except Exception as e :
92+ logger . error (f"Error retrieving API key metadata from DynamoDB : { e } " )
7593 return {"isAuthorized" : False }
94+
7695 if not metadata :
96+ logger .warning ("DENIED: API key not found in database" )
7797 return {"isAuthorized" : False }
7898
7999 scope = metadata .get ("scope" , "" )
80100 path = event .get ("rawPath" ) or event .get ("path" , "" )
81101 http_method = event .get ("requestContext" , {}).get ("http" , {}).get ("method" , "GET" )
82102
83- is_authorized = _is_authorized (api_key , scope , path , http_method )
103+ logger .info (f"API key found with scope: { scope } " )
104+ logger .info (f"Request details - Path: { path } , Method: { http_method } " )
105+
106+ is_authorized = _is_authorized (scope , path , http_method )
84107
108+ logger .info (f"Authorization successful for scope '{ scope } '" )
85109 return {
86110 "isAuthorized" : is_authorized ,
87111 "context" : {
0 commit comments