Skip to content

Commit adee789

Browse files
committed
remove auto_error and make user optioanl in authorize method
1 parent b9ced59 commit adee789

File tree

2 files changed

+15
-16
lines changed

2 files changed

+15
-16
lines changed

oauth2_lib/fastapi.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from httpx import AsyncClient, NetworkError
2424
from pydantic import BaseModel
2525
from starlette.requests import ClientDisconnect, HTTPConnection
26+
from starlette.status import HTTP_403_FORBIDDEN
2627
from starlette.websockets import WebSocket
2728
from structlog import get_logger
2829

@@ -137,22 +138,18 @@ class IdTokenExtractor(ABC):
137138
"""
138139

139140
@abstractmethod
140-
async def extract(self, request: Request, auto_error: bool = True) -> Optional[str]:
141+
async def extract(self, request: Request) -> Optional[str]:
141142
pass
142143

143144

144145
class HttpBearerExtractor(IdTokenExtractor):
145146
"""Extracts bearer tokens using FastAPI's HTTPBearer.
146147
147148
Specifically designed for HTTP Authorization header token extraction.
148-
149-
By default, if an HTTP Bearer token is not provided in the `Authorization` header,
150-
the `extract` method will cancel the request and send an error unless `auto_error`
151-
is set to `False`, allowing optional or multiple authentication methods.
152149
"""
153150

154-
async def extract(self, request: Request, auto_error: bool = True) -> Optional[str]:
155-
http_bearer = HTTPBearer(auto_error=auto_error)
151+
async def extract(self, request: Request) -> Optional[str]:
152+
http_bearer = HTTPBearer(auto_error=False)
156153
credential = await http_bearer(request)
157154

158155
return credential.credentials if credential else None
@@ -218,7 +215,11 @@ async def authenticate(self, request: HTTPConnection, token: Optional[str] = Non
218215
return None
219216

220217
if token is None:
221-
token_or_extracted_id_token = await self.id_token_extractor.extract(request, auto_error=True) or ""
218+
extracted_id_token = await self.id_token_extractor.extract(request)
219+
if not extracted_id_token:
220+
raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail="Not authenticated")
221+
222+
token_or_extracted_id_token = extracted_id_token
222223
else:
223224
token_or_extracted_id_token = token
224225

@@ -262,7 +263,7 @@ class Authorization(ABC):
262263
"""
263264

264265
@abstractmethod
265-
async def authorize(self, request: HTTPConnection, user: OIDCUserModel) -> Optional[bool]:
266+
async def authorize(self, request: HTTPConnection, user: Optional[OIDCUserModel] = None) -> Optional[bool]:
266267
pass
267268

268269

@@ -273,7 +274,7 @@ class GraphqlAuthorization(ABC):
273274
"""
274275

275276
@abstractmethod
276-
async def authorize(self, request: RequestPath, user: OIDCUserModel) -> Optional[bool]:
277+
async def authorize(self, request: RequestPath, user: Optional[OIDCUserModel] = None) -> Optional[bool]:
277278
pass
278279

279280

@@ -323,7 +324,7 @@ class OPAAuthorization(Authorization, OPAMixin):
323324
Uses OAUTH2 settings and request information to authorize actions.
324325
"""
325326

326-
async def authorize(self, request: HTTPConnection, user_info: OIDCUserModel) -> Optional[bool]:
327+
async def authorize(self, request: HTTPConnection, user_info: Optional[OIDCUserModel] = None) -> Optional[bool]:
327328
if not (oauth2lib_settings.OAUTH2_ACTIVE and oauth2lib_settings.OAUTH2_AUTHORIZATION_ACTIVE):
328329
return None
329330

@@ -379,7 +380,7 @@ def __init__(self, opa_url: str, auto_error: bool = False, opa_kwargs: Union[Map
379380
# By default don't raise HTTP 403 because partial results are preferred
380381
super().__init__(opa_url, auto_error, opa_kwargs)
381382

382-
async def authorize(self, request: RequestPath, user_info: OIDCUserModel) -> Optional[bool]:
383+
async def authorize(self, request: RequestPath, user_info: Optional[OIDCUserModel] = None) -> Optional[bool]:
383384
if not (oauth2lib_settings.OAUTH2_ACTIVE and oauth2lib_settings.OAUTH2_AUTHORIZATION_ACTIVE):
384385
return None
385386

tests/test_fastapi.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,11 @@ async def test_extract_token_success():
149149

150150

151151
@pytest.mark.asyncio
152-
async def test_extract_token_failure():
152+
async def test_extract_token_returns_none():
153153
request = mock.MagicMock()
154154
request.headers = {}
155155
extractor = HttpBearerExtractor()
156-
with pytest.raises(HTTPException) as exc_info:
157-
await extractor.extract(request)
158-
assert exc_info.value.status_code == 403, "Expected HTTP 403 error for missing token"
156+
assert await extractor.extract(request) is None
159157

160158

161159
@pytest.mark.asyncio

0 commit comments

Comments
 (0)