Skip to content

Commit 57df8cf

Browse files
committed
copilot feedback changes and added logs and better return message
1 parent a56efea commit 57df8cf

3 files changed

Lines changed: 68 additions & 37 deletions

File tree

sds_data_manager/lambda_code/SDSCode/api_lambdas/upload_api.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,27 @@ def lambda_handler(event, context):
110110
auth = request_ctx.get("authorizer", {})
111111
auth_ctx = auth.get("lambda", {})
112112
scope = auth_ctx.get("scope", "")
113+
api_key = auth_ctx.get("apiKey", "unknown")
113114

114-
# Deny upload access for read-only scope
115+
logger.info(f"Upload request received with scope: {scope}, api_key: {api_key}")
116+
117+
# Deny upload access for read scope
115118
if scope == "read":
119+
logger.warning("Upload denied: read scope user attempted upload")
120+
return {
121+
"statusCode": 403,
122+
"body": json.dumps(
123+
"Upload access denied. Your API key has read permissions."
124+
),
125+
}
126+
127+
# Check if scope is missing (might be caught by authorizer first)
128+
if not scope:
129+
logger.warning("Upload denied: no scope found in authorizer context")
116130
return {
117131
"statusCode": 403,
118132
"body": json.dumps(
119-
"Upload access denied. Your API key has read-only permissions."
133+
"Upload access denied. Your API key has read permissions."
120134
),
121135
}
122136

sds_data_manager/lambda_code/authorization/lambda_api_key_authorizer.py

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
"""Authorization for API Keys within the SDS."""
22

3+
import logging
4+
35
import 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
715
dynamodb = boto3.resource("dynamodb")
816
table = 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": {

sds_data_manager/lambda_code/authorization/manage_api_keys.py

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@
2424

2525
TABLE_NAME = "imap-sdc-api-keys"
2626

27+
# Validate scope
28+
VALID_SCOPES = {
29+
"full",
30+
"ialirt_db",
31+
"ialirt_external_partner",
32+
"ialirt_scientist",
33+
"read",
34+
}
35+
2736

2837
def get_table():
2938
"""Get the DynamoDB table resource."""
@@ -120,16 +129,8 @@ def add_key(owner, email, scope="full"):
120129
- 'read': Read-only access
121130
Default is 'full'
122131
"""
123-
# Validate scope
124-
valid_scopes = {
125-
"full",
126-
"read",
127-
"ialirt_db",
128-
"ialirt_external_partner",
129-
"ialirt_scientist",
130-
}
131-
if scope not in valid_scopes:
132-
valid_scopes_str = ", ".join(sorted(valid_scopes))
132+
if scope not in VALID_SCOPES:
133+
valid_scopes_str = ", ".join(sorted(VALID_SCOPES))
133134
print(f"Error: Invalid scope '{scope}'. Valid scopes are: {valid_scopes_str}")
134135
return
135136

@@ -172,16 +173,8 @@ def update_permission(owner: str, email: str, scope: str):
172173
- Other specialized scopes (ialirt_db, ialirt_external_partner,
173174
ialirt_scientist)
174175
"""
175-
# Validate scope
176-
valid_scopes = {
177-
"full",
178-
"read",
179-
"ialirt_db",
180-
"ialirt_external_partner",
181-
"ialirt_scientist",
182-
}
183-
if scope not in valid_scopes:
184-
valid_scopes_str = ", ".join(sorted(valid_scopes))
176+
if scope not in VALID_SCOPES:
177+
valid_scopes_str = ", ".join(sorted(VALID_SCOPES))
185178
print(f"Error: Invalid scope '{scope}'. Valid scopes are: {valid_scopes_str}")
186179
return
187180

0 commit comments

Comments
 (0)