Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions services/token-service/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def get_github_handle_from_workspace_sa(service_account_email: str) -> str | Non
Returns
-------
str | None
GitHub handle if found, None otherwise.
GitHub handle (normalized to lowercase) if found, None otherwise.
"""
# For now, require github_handle to be passed in request body
# In production, you could map this via metadata or workspace labels
Expand All @@ -129,16 +129,22 @@ def get_github_handle_from_workspace_sa(service_account_email: str) -> str | Non
logger.warning("github_handle not provided in request")
return None

# Normalize GitHub handle to lowercase for case-insensitive matching
# GitHub handles are case-insensitive but case-preserving
github_handle_normalized = github_handle.lower()

# Verify this participant exists in Firestore
try:
doc_ref = db.collection("participants").document(github_handle)
doc_ref = db.collection("participants").document(github_handle_normalized)
doc = doc_ref.get()

if not doc.exists:
logger.warning(f"Participant {github_handle} not found in Firestore")
logger.warning(
f"Participant {github_handle_normalized} not found in Firestore"
)
return None

return github_handle
return github_handle_normalized

except Exception as e:
logger.error(f"Failed to verify participant: {e}")
Expand Down
35 changes: 31 additions & 4 deletions src/aieng_platform_onboard/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,26 @@ def get_console() -> Console:
return console


def normalize_github_handle(github_handle: str) -> str:
"""
Normalize GitHub handle to lowercase for case-insensitive matching.

GitHub handles are case-insensitive but case-preserving. This function
ensures consistent lookups in Firestore by normalizing to lowercase.

Parameters
----------
github_handle : str
GitHub handle in any case.

Returns
-------
str
Normalized (lowercase) GitHub handle.
"""
return github_handle.lower()


def get_github_user() -> str | None:
"""
Get GitHub username from environment variable.
Expand Down Expand Up @@ -145,7 +165,8 @@ def fetch_token_from_service( # noqa: PLR0911
"Authorization": f"Bearer {id_token}",
"Content-Type": "application/json",
}
payload = {"github_handle": github_handle}
# Normalize GitHub handle for case-insensitive matching
payload = {"github_handle": normalize_github_handle(github_handle)}

response = requests.post(url, json=payload, headers=headers, timeout=30)

Expand Down Expand Up @@ -292,7 +313,9 @@ def get_participant_data(
Participant data or None if not found.
"""
try:
doc_ref = db.collection("participants").document(github_handle)
# Normalize GitHub handle for case-insensitive matching
github_handle_normalized = normalize_github_handle(github_handle)
doc_ref = db.collection("participants").document(github_handle_normalized)
doc = doc_ref.get()

if not doc.exists:
Expand Down Expand Up @@ -548,7 +571,9 @@ def check_onboarded_status(
Tuple of (success, is_onboarded).
"""
try:
doc_ref = db.collection("participants").document(github_handle)
# Normalize GitHub handle for case-insensitive matching
github_handle_normalized = normalize_github_handle(github_handle)
doc_ref = db.collection("participants").document(github_handle_normalized)
doc = doc_ref.get()

if not doc.exists:
Expand Down Expand Up @@ -633,7 +658,9 @@ def update_onboarded_status(
Tuple of (success, error_message).
"""
try:
doc_ref = db.collection("participants").document(github_handle)
# Normalize GitHub handle for case-insensitive matching
github_handle_normalized = normalize_github_handle(github_handle)
doc_ref = db.collection("participants").document(github_handle_normalized)
doc_ref.update(
{
"onboarded": True,
Expand Down