| 30 | |
| 31 | @dataclass |
| 32 | class RevocationHandler: |
| 33 | provider: OAuthAuthorizationServerProvider[Any, Any, Any] |
| 34 | client_authenticator: ClientAuthenticator |
| 35 | |
| 36 | async def handle(self, request: Request) -> Response: |
| 37 | """Handler for the OAuth 2.0 Token Revocation endpoint.""" |
| 38 | try: |
| 39 | client = await self.client_authenticator.authenticate_request(request) |
| 40 | except AuthenticationError as e: # pragma: no cover |
| 41 | return PydanticJSONResponse( |
| 42 | status_code=401, |
| 43 | content=RevocationErrorResponse( |
| 44 | error="unauthorized_client", |
| 45 | error_description=e.message, |
| 46 | ), |
| 47 | ) |
| 48 | |
| 49 | try: |
| 50 | form_data = await request.form() |
| 51 | revocation_request = RevocationRequest.model_validate(dict(form_data)) |
| 52 | except ValidationError as e: |
| 53 | return PydanticJSONResponse( |
| 54 | status_code=400, |
| 55 | content=RevocationErrorResponse( |
| 56 | error="invalid_request", |
| 57 | error_description=stringify_pydantic_error(e), |
| 58 | ), |
| 59 | ) |
| 60 | |
| 61 | loaders = [ |
| 62 | self.provider.load_access_token, |
| 63 | partial(self.provider.load_refresh_token, client), |
| 64 | ] |
| 65 | if revocation_request.token_type_hint == "refresh_token": # pragma: no cover |
| 66 | loaders = reversed(loaders) |
| 67 | |
| 68 | token: None | AccessToken | RefreshToken = None |
| 69 | for loader in loaders: |
| 70 | token = await loader(revocation_request.token) |
| 71 | if token is not None: |
| 72 | break |
| 73 | |
| 74 | # if token is not found, just return HTTP 200 per the RFC |
| 75 | if token and token.client_id == client.client_id: |
| 76 | # Revoke token; provider is not meant to be able to do validation |
| 77 | # at this point that would result in an error |
| 78 | await self.provider.revoke_token(token) |
| 79 | |
| 80 | # Return successful empty response |
| 81 | return Response( |
| 82 | status_code=200, |
| 83 | headers={ |
| 84 | "Cache-Control": "no-store", |
| 85 | "Pragma": "no-cache", |
| 86 | }, |
| 87 | ) |
no outgoing calls
no test coverage detected