Skip to content

Commit 50e8d3b

Browse files
committed
Validate that user_id is not empty in noop authentication modules
1 parent 226a43f commit 50e8d3b

6 files changed

Lines changed: 53 additions & 9 deletions

File tree

src/authentication/noop.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Manage authentication flow for FastAPI endpoints with no-op auth."""
22

3-
from fastapi import Request
3+
from fastapi import HTTPException, Request
44

55
from constants import (
66
DEFAULT_USER_NAME,
@@ -50,5 +50,7 @@ async def __call__(self, request: Request) -> tuple[str, str, bool, str]:
5050
)
5151
# try to extract user ID from request
5252
user_id = request.query_params.get("user_id", DEFAULT_USER_UID)
53+
if not user_id:
54+
raise HTTPException(status_code=400, detail="user_id cannot be empty")
5355
logger.debug("Retrieved user ID: %s", user_id)
5456
return user_id, DEFAULT_USER_NAME, self.skip_userid_check, NO_USER_TOKEN

src/authentication/noop_with_token.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
- Returns a tuple: (user_id, DEFAULT_USER_NAME, user_token).
1010
"""
1111

12-
from fastapi import Request
12+
from fastapi import HTTPException, Request
1313

1414
from constants import (
1515
DEFAULT_USER_NAME,
@@ -63,5 +63,7 @@ async def __call__(self, request: Request) -> tuple[str, str, bool, str]:
6363
user_token = extract_user_token(request.headers)
6464
# try to extract user ID from request
6565
user_id = request.query_params.get("user_id", DEFAULT_USER_UID)
66+
if not user_id:
67+
raise HTTPException(status_code=400, detail="user_id cannot be empty")
6668
logger.debug("Retrieved user ID: %s", user_id)
6769
return user_id, DEFAULT_USER_NAME, self.skip_userid_check, user_token

tests/e2e/features/authorized_noop.feature

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ Feature: Authorized endpoint API tests for the noop authentication module
3535
{"user_id": "00000000-0000-0000-0000-000","username": "lightspeed-user","skip_userid_check": true}
3636
"""
3737

38-
Scenario: Check if the authorized endpoint works when providing empty user_id
38+
Scenario: Check if the authorized endpoint rejects empty user_id
3939
Given The system is in default state
4040
And I set the Authorization header to Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva
4141
When I access endpoint "authorized" using HTTP POST method with user_id ""
42-
Then The status code of the response is 200
42+
Then The status code of the response is 400
4343
And The body of the response is the following
4444
"""
45-
{"user_id": "","username": "lightspeed-user","skip_userid_check": true}
45+
{"detail": "user_id cannot be empty"}
4646
"""
4747

4848
Scenario: Check if the authorized endpoint works when providing proper user_id

tests/e2e/features/authorized_noop_token.feature

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ Feature: Authorized endpoint API tests for the noop-with-token authentication mo
3232
{"user_id": "00000000-0000-0000-0000-000","username": "lightspeed-user","skip_userid_check": true}
3333
"""
3434

35-
Scenario: Check if the authorized endpoint works when providing empty user_id
35+
Scenario: Check if the authorized endpoint rejects empty user_id
3636
Given The system is in default state
3737
And I set the Authorization header to Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva
3838
When I access endpoint "authorized" using HTTP POST method with user_id ""
39-
Then The status code of the response is 200
39+
Then The status code of the response is 400
4040
And The body of the response is the following
4141
"""
42-
{"user_id": "","username": "lightspeed-user","skip_userid_check": true}
42+
{"detail": "user_id cannot be empty"}
4343
"""
4444

4545
Scenario: Check if the authorized endpoint works when providing proper user_id

tests/unit/authentication/test_noop.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""Unit tests for functions defined in authentication/noop.py"""
22

3-
from fastapi import Request
3+
from fastapi import Request, HTTPException
4+
import pytest
5+
46
from authentication.noop import NoopAuthDependency
57
from constants import DEFAULT_USER_NAME, DEFAULT_USER_UID, NO_USER_TOKEN
68

@@ -37,3 +39,18 @@ async def test_noop_auth_dependency_custom_user_id() -> None:
3739
assert username == DEFAULT_USER_NAME
3840
assert skip_userid_check is True
3941
assert user_token == NO_USER_TOKEN
42+
43+
44+
async def test_noop_auth_dependency_empty_user_id() -> None:
45+
"""Test that NoopAuthDependency rejects empty user_id with HTTP 400."""
46+
dependency = NoopAuthDependency()
47+
48+
# Create a mock request with empty user_id
49+
request = Request(scope={"type": "http", "query_string": b"user_id="})
50+
51+
# Assert that an HTTPException is raised for empty user_id
52+
with pytest.raises(HTTPException) as exc_info:
53+
await dependency(request)
54+
55+
assert exc_info.value.status_code == 400
56+
assert exc_info.value.detail == "user_id cannot be empty"

tests/unit/authentication/test_noop_with_token.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,26 @@ async def test_noop_with_token_auth_dependency_no_bearer() -> None:
117117
detail = cast(dict[str, str], exc_info.value.detail)
118118
assert detail["response"] == ("Missing or invalid credentials provided by client")
119119
assert detail["cause"] == "No token found in Authorization header"
120+
121+
122+
async def test_noop_with_token_auth_dependency_empty_user_id() -> None:
123+
"""Test that NoopWithTokenAuthDependency rejects empty user_id with HTTP 400."""
124+
dependency = NoopWithTokenAuthDependency()
125+
126+
# Create a mock request with empty user_id but valid token
127+
request = Request(
128+
scope={
129+
"type": "http",
130+
"query_string": b"user_id=",
131+
"headers": [
132+
(b"authorization", b"Bearer spongebob-token"),
133+
],
134+
},
135+
)
136+
137+
# Assert that an HTTPException is raised for empty user_id
138+
with pytest.raises(HTTPException) as exc_info:
139+
await dependency(request)
140+
141+
assert exc_info.value.status_code == 400
142+
assert exc_info.value.detail == "user_id cannot be empty"

0 commit comments

Comments
 (0)