Skip to content

Commit 6faf8a0

Browse files
Copilotalvarolopez
andcommitted
Fix code style issues in bearer authentication implementation
Co-authored-by: alvarolopez <[email protected]>
1 parent 0eb0251 commit 6faf8a0

File tree

3 files changed

+83
-63
lines changed

3 files changed

+83
-63
lines changed

deepaas/auth.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,24 @@ def is_auth_enabled() -> bool:
3232
return bool(CONF.auth_bearer_token)
3333

3434

35-
async def verify_bearer_token(token: str = fastapi.Depends(bearer_scheme)) -> str:
35+
async def verify_bearer_token(
36+
token: fastapi.security.HTTPAuthorizationCredentials = fastapi.Depends(bearer_scheme) # noqa: E501,B008
37+
) -> str:
3638
"""Verify the bearer token against the configured token.
37-
39+
3840
Args:
3941
token: The HTTPAuthorizationCredentials from the request
40-
42+
4143
Returns:
4244
The validated token string
43-
45+
4446
Raises:
4547
HTTPException: If authentication is enabled but token is invalid/missing
4648
"""
4749
# If auth is not enabled, allow all requests
4850
if not is_auth_enabled():
4951
return None
50-
52+
5153
# If auth is enabled but no token provided
5254
if token is None:
5355
LOG.warning("Authentication required but no bearer token provided")
@@ -56,7 +58,7 @@ async def verify_bearer_token(token: str = fastapi.Depends(bearer_scheme)) -> st
5658
detail="Bearer token required",
5759
headers={"WWW-Authenticate": "Bearer"},
5860
)
59-
61+
6062
# Validate the token
6163
if token.credentials != CONF.auth_bearer_token:
6264
LOG.warning("Invalid bearer token provided")
@@ -65,18 +67,18 @@ async def verify_bearer_token(token: str = fastapi.Depends(bearer_scheme)) -> st
6567
detail="Invalid bearer token",
6668
headers={"WWW-Authenticate": "Bearer"},
6769
)
68-
70+
6971
LOG.debug("Bearer token validated successfully")
7072
return token.credentials
7173

7274

7375
def get_auth_dependency():
7476
"""Get the authentication dependency.
75-
77+
7678
Returns a dependency that can be used with FastAPI routes to enforce
7779
authentication when enabled.
78-
80+
7981
Returns:
8082
The authentication dependency function
8183
"""
82-
return fastapi.Depends(verify_bearer_token)
84+
return fastapi.Depends(verify_bearer_token)

deepaas/tests/test_auth.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ async def test_verify_token_disabled_auth(self):
5353
async def test_verify_token_no_token_provided(self):
5454
"""Test token verification when auth is enabled but no token provided."""
5555
CONF.set_override("auth_bearer_token", "test-token")
56-
56+
5757
with pytest.raises(fastapi.HTTPException) as exc_info:
5858
await auth.verify_bearer_token(None)
59-
59+
6060
assert exc_info.value.status_code == 401
6161
assert "Bearer token required" in exc_info.value.detail
6262
assert exc_info.value.headers["WWW-Authenticate"] == "Bearer"
@@ -65,16 +65,16 @@ async def test_verify_token_no_token_provided(self):
6565
async def test_verify_token_invalid_token(self):
6666
"""Test token verification with invalid token."""
6767
CONF.set_override("auth_bearer_token", "correct-token")
68-
68+
6969
# Mock HTTPAuthorizationCredentials
7070
mock_token = fastapi.security.HTTPAuthorizationCredentials(
71-
scheme="Bearer",
71+
scheme="Bearer",
7272
credentials="wrong-token"
7373
)
74-
74+
7575
with pytest.raises(fastapi.HTTPException) as exc_info:
7676
await auth.verify_bearer_token(mock_token)
77-
77+
7878
assert exc_info.value.status_code == 401
7979
assert "Invalid bearer token" in exc_info.value.detail
8080
assert exc_info.value.headers["WWW-Authenticate"] == "Bearer"
@@ -83,13 +83,13 @@ async def test_verify_token_invalid_token(self):
8383
async def test_verify_token_valid_token(self):
8484
"""Test token verification with valid token."""
8585
CONF.set_override("auth_bearer_token", "correct-token")
86-
86+
8787
# Mock HTTPAuthorizationCredentials
8888
mock_token = fastapi.security.HTTPAuthorizationCredentials(
89-
scheme="Bearer",
89+
scheme="Bearer",
9090
credentials="correct-token"
9191
)
92-
92+
9393
result = await auth.verify_bearer_token(mock_token)
9494
assert result == "correct-token"
9595

@@ -101,6 +101,10 @@ def test_get_auth_dependency(self):
101101
assert callable(dependency.dependency)
102102

103103

104+
# Fix the function definition issue by creating a separate auth dependency
105+
auth_dependency = auth.get_auth_dependency()
106+
107+
104108
class TestBearerAuthIntegration:
105109
"""Integration tests for bearer authentication with FastAPI."""
106110

@@ -118,7 +122,7 @@ async def public_endpoint():
118122
return {"message": "public"}
119123

120124
@app.get("/protected")
121-
async def protected_endpoint(_: str = auth.get_auth_dependency()):
125+
async def protected_endpoint(_=auth_dependency):
122126
return {"message": "protected"}
123127

124128
return app
@@ -127,7 +131,7 @@ def test_public_endpoint_no_auth(self):
127131
"""Test that public endpoints work without authentication."""
128132
app = self.create_test_app()
129133
client = fastapi.testclient.TestClient(app)
130-
134+
131135
response = client.get("/public")
132136
assert response.status_code == 200
133137
assert response.json() == {"message": "public"}
@@ -137,7 +141,7 @@ def test_protected_endpoint_no_auth_disabled(self):
137141
CONF.set_override("auth_bearer_token", "")
138142
app = self.create_test_app()
139143
client = fastapi.testclient.TestClient(app)
140-
144+
141145
response = client.get("/protected")
142146
assert response.status_code == 200
143147
assert response.json() == {"message": "protected"}
@@ -147,7 +151,7 @@ def test_protected_endpoint_auth_enabled_no_token(self):
147151
CONF.set_override("auth_bearer_token", "secret-token")
148152
app = self.create_test_app()
149153
client = fastapi.testclient.TestClient(app)
150-
154+
151155
response = client.get("/protected")
152156
assert response.status_code == 401
153157
assert "Bearer token required" in response.json()["detail"]
@@ -157,7 +161,7 @@ def test_protected_endpoint_auth_enabled_invalid_token(self):
157161
CONF.set_override("auth_bearer_token", "secret-token")
158162
app = self.create_test_app()
159163
client = fastapi.testclient.TestClient(app)
160-
164+
161165
response = client.get(
162166
"/protected",
163167
headers={"Authorization": "Bearer wrong-token"}
@@ -170,7 +174,7 @@ def test_protected_endpoint_auth_enabled_valid_token(self):
170174
CONF.set_override("auth_bearer_token", "secret-token")
171175
app = self.create_test_app()
172176
client = fastapi.testclient.TestClient(app)
173-
177+
174178
response = client.get(
175179
"/protected",
176180
headers={"Authorization": "Bearer secret-token"}
@@ -183,11 +187,11 @@ def test_protected_endpoint_malformed_header(self):
183187
CONF.set_override("auth_bearer_token", "secret-token")
184188
app = self.create_test_app()
185189
client = fastapi.testclient.TestClient(app)
186-
190+
187191
# Test with malformed header (no "Bearer" prefix)
188192
response = client.get(
189193
"/protected",
190194
headers={"Authorization": "secret-token"}
191195
)
192196
assert response.status_code == 401
193-
assert "Bearer token required" in response.json()["detail"]
197+
assert "Bearer token required" in response.json()["detail"]

deepaas/tests/test_e2e_auth.py

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@
2929

3030
class TestE2EBearerAuth:
3131
"""End-to-end tests for bearer authentication."""
32-
32+
3333
def setup_method(self):
3434
"""Set up test environment."""
3535
CONF.clear()
3636
config.parse_args([])
37-
37+
3838
# Reset the global APP
3939
api.APP = None
4040

@@ -48,7 +48,9 @@ def create_mock_model(self):
4848
"author": "Test Author",
4949
}
5050
mock_model.get_predict_args.return_value = {}
51-
mock_model.predict = unittest.mock.AsyncMock(return_value={"result": "success"})
51+
mock_model.predict = unittest.mock.AsyncMock(
52+
return_value={"result": "success"}
53+
)
5254
mock_model.has_schema = False
5355
mock_model.response_schema = None # Important: set response_schema to None
5456
mock_model.warm = unittest.mock.MagicMock()
@@ -57,52 +59,56 @@ def create_mock_model(self):
5759
def test_api_access_without_auth(self):
5860
"""Test API access when authentication is disabled."""
5961
CONF.set_override("auth_bearer_token", "")
60-
61-
with unittest.mock.patch('deepaas.model.load_v2_model') as mock_load:
62+
63+
with unittest.mock.patch('deepaas.model.load_v2_model'):
6264
with unittest.mock.patch.object(model, 'V2_MODEL_NAME', 'test-model'):
63-
with unittest.mock.patch.object(model, 'V2_MODEL', self.create_mock_model()):
65+
with unittest.mock.patch.object(
66+
model, 'V2_MODEL', self.create_mock_model()
67+
):
6468
app = api.get_fastapi_app()
6569
client = fastapi.testclient.TestClient(app)
66-
70+
6771
# Test root endpoint
6872
response = client.get("/")
6973
assert response.status_code == 200
70-
74+
7175
# Test v2 version endpoint
7276
response = client.get("/v2/")
7377
assert response.status_code == 200
74-
78+
7579
# Test models endpoint
7680
response = client.get("/v2/models/")
7781
assert response.status_code == 200
78-
82+
7983
# Test individual model endpoint
8084
response = client.get("/v2/models/test-model")
8185
assert response.status_code == 200
8286

8387
def test_api_access_with_auth_no_token(self):
8488
"""Test API access when authentication is enabled but no token provided."""
8589
CONF.set_override("auth_bearer_token", "my-secret-token")
86-
87-
with unittest.mock.patch('deepaas.model.load_v2_model') as mock_load:
90+
91+
with unittest.mock.patch('deepaas.model.load_v2_model'):
8892
with unittest.mock.patch.object(model, 'V2_MODEL_NAME', 'test-model'):
89-
with unittest.mock.patch.object(model, 'V2_MODEL', self.create_mock_model()):
93+
with unittest.mock.patch.object(
94+
model, 'V2_MODEL', self.create_mock_model()
95+
):
9096
app = api.get_fastapi_app()
9197
client = fastapi.testclient.TestClient(app)
92-
98+
9399
# Test root endpoint (should still work - not protected)
94100
response = client.get("/")
95101
assert response.status_code == 200
96-
102+
97103
# Test v2 version endpoint (should still work - not protected)
98104
response = client.get("/v2/")
99105
assert response.status_code == 200
100-
106+
101107
# Test models endpoint (should require auth)
102108
response = client.get("/v2/models/")
103109
assert response.status_code == 401
104110
assert "Bearer token required" in response.json()["detail"]
105-
111+
106112
# Test individual model endpoint (should require auth)
107113
response = client.get("/v2/models/test-model")
108114
assert response.status_code == 401
@@ -111,20 +117,22 @@ def test_api_access_with_auth_no_token(self):
111117
def test_api_access_with_auth_invalid_token(self):
112118
"""Test API access with invalid bearer token."""
113119
CONF.set_override("auth_bearer_token", "my-secret-token")
114-
115-
with unittest.mock.patch('deepaas.model.load_v2_model') as mock_load:
120+
121+
with unittest.mock.patch('deepaas.model.load_v2_model'):
116122
with unittest.mock.patch.object(model, 'V2_MODEL_NAME', 'test-model'):
117-
with unittest.mock.patch.object(model, 'V2_MODEL', self.create_mock_model()):
123+
with unittest.mock.patch.object(
124+
model, 'V2_MODEL', self.create_mock_model()
125+
):
118126
app = api.get_fastapi_app()
119127
client = fastapi.testclient.TestClient(app)
120-
128+
121129
headers = {"Authorization": "Bearer wrong-token"}
122-
130+
123131
# Test models endpoint with wrong token
124132
response = client.get("/v2/models/", headers=headers)
125133
assert response.status_code == 401
126134
assert "Invalid bearer token" in response.json()["detail"]
127-
135+
128136
# Test individual model endpoint with wrong token
129137
response = client.get("/v2/models/test-model", headers=headers)
130138
assert response.status_code == 401
@@ -133,23 +141,25 @@ def test_api_access_with_auth_invalid_token(self):
133141
def test_api_access_with_auth_valid_token(self):
134142
"""Test API access with valid bearer token."""
135143
CONF.set_override("auth_bearer_token", "my-secret-token")
136-
137-
with unittest.mock.patch('deepaas.model.load_v2_model') as mock_load:
144+
145+
with unittest.mock.patch('deepaas.model.load_v2_model'):
138146
with unittest.mock.patch.object(model, 'V2_MODEL_NAME', 'test-model'):
139-
with unittest.mock.patch.object(model, 'V2_MODEL', self.create_mock_model()):
147+
with unittest.mock.patch.object(
148+
model, 'V2_MODEL', self.create_mock_model()
149+
):
140150
app = api.get_fastapi_app()
141151
client = fastapi.testclient.TestClient(app)
142-
152+
143153
headers = {"Authorization": "Bearer my-secret-token"}
144-
154+
145155
# Test models endpoint with correct token
146156
response = client.get("/v2/models/", headers=headers)
147157
assert response.status_code == 200
148158
data = response.json()
149159
assert "models" in data
150160
assert len(data["models"]) == 1
151161
assert data["models"][0]["name"] == "Test Model"
152-
162+
153163
# Test individual model endpoint with correct token
154164
response = client.get("/v2/models/test-model", headers=headers)
155165
assert response.status_code == 200
@@ -160,21 +170,25 @@ def test_api_access_with_auth_valid_token(self):
160170
def test_predict_endpoint_with_auth(self):
161171
"""Test predict endpoint with authentication."""
162172
CONF.set_override("auth_bearer_token", "my-secret-token")
163-
164-
with unittest.mock.patch('deepaas.model.load_v2_model') as mock_load:
173+
174+
with unittest.mock.patch('deepaas.model.load_v2_model'):
165175
with unittest.mock.patch.object(model, 'V2_MODEL_NAME', 'test-model'):
166-
with unittest.mock.patch.object(model, 'V2_MODEL', self.create_mock_model()):
176+
with unittest.mock.patch.object(
177+
model, 'V2_MODEL', self.create_mock_model()
178+
):
167179
app = api.get_fastapi_app()
168180
client = fastapi.testclient.TestClient(app)
169-
181+
170182
# Test predict endpoint without auth
171183
response = client.post("/v2/models/test-model/predict")
172184
assert response.status_code == 401
173185
assert "Bearer token required" in response.json()["detail"]
174-
186+
175187
# Test predict endpoint with correct auth
176188
headers = {"Authorization": "Bearer my-secret-token"}
177-
response = client.post("/v2/models/test-model/predict", headers=headers)
189+
response = client.post(
190+
"/v2/models/test-model/predict", headers=headers
191+
)
178192
assert response.status_code == 200
179193
data = response.json()
180-
assert "predictions" in data or "result" in data
194+
assert "predictions" in data or "result" in data

0 commit comments

Comments
 (0)