|
1 | 1 | import re
|
2 | 2 | from inspect import Parameter, Signature
|
3 |
| -from typing import Callable, List, Optional, Sequence, Tuple, cast |
| 3 | +from typing import Callable, List, Optional, Sequence, Tuple, cast, ClassVar |
4 | 4 |
|
5 | 5 | from fastapi import Depends, HTTPException, status
|
6 | 6 | from makefun import with_signature
|
@@ -48,14 +48,29 @@ class Authenticator:
|
48 | 48 |
|
49 | 49 | backends: Sequence[AuthenticationBackend]
|
50 | 50 |
|
| 51 | + default_no_user: ClassVar[str] = "Unauthorized: No authenticated user" |
| 52 | + default_detail_inactive_user: ClassVar[str] = "Unauthorized: User is inactive" |
| 53 | + default_detail_unverified_user: ClassVar[str] = "Forbidden: User is unverified" |
| 54 | + |
51 | 55 | def __init__(
|
52 | 56 | self,
|
53 | 57 | backends: Sequence[AuthenticationBackend],
|
54 | 58 | get_user_manager: UserManagerDependency[models.UP, models.ID],
|
| 59 | + http_error_no_user: Optional[str] = None, |
| 60 | + http_error_detail_inactive_user: Optional[str] = None, |
| 61 | + http_error_detail_unverified_user: Optional[str] = None, |
55 | 62 | ):
|
56 | 63 | self.backends = backends
|
57 | 64 | self.get_user_manager = get_user_manager
|
58 | 65 |
|
| 66 | + self.http_error_no_user = http_error_no_user or self.default_no_user |
| 67 | + self.http_error_detail_inactive_user = ( |
| 68 | + http_error_detail_inactive_user or self.default_detail_inactive_user |
| 69 | + ) |
| 70 | + self.http_error_detail_unverified_user = ( |
| 71 | + http_error_detail_unverified_user or self.default_detail_unverified_user |
| 72 | + ) |
| 73 | + |
59 | 74 | def current_user_token(
|
60 | 75 | self,
|
61 | 76 | optional: bool = False,
|
@@ -171,18 +186,30 @@ async def _authenticate(
|
171 | 186 | if user:
|
172 | 187 | break
|
173 | 188 |
|
174 |
| - status_code = status.HTTP_401_UNAUTHORIZED |
175 | 189 | if user:
|
176 |
| - status_code = status.HTTP_403_FORBIDDEN |
177 | 190 | if active and not user.is_active:
|
178 |
| - status_code = status.HTTP_401_UNAUTHORIZED |
| 191 | + if not optional: |
| 192 | + raise HTTPException( |
| 193 | + status_code=status.HTTP_401_UNAUTHORIZED, |
| 194 | + detail=self.http_error_detail_inactive_user, |
| 195 | + ) |
179 | 196 | user = None
|
| 197 | + |
180 | 198 | elif (
|
181 | 199 | verified and not user.is_verified or superuser and not user.is_superuser
|
182 | 200 | ):
|
| 201 | + if not optional: |
| 202 | + raise HTTPException( |
| 203 | + status_code=status.HTTP_403_FORBIDDEN, |
| 204 | + detail=self.http_error_detail_unverified_user, |
| 205 | + ) |
183 | 206 | user = None
|
184 |
| - if not user and not optional: |
185 |
| - raise HTTPException(status_code=status_code) |
| 207 | + |
| 208 | + elif not optional: |
| 209 | + raise HTTPException( |
| 210 | + status_code=status.HTTP_401_UNAUTHORIZED, detail=self.http_error_no_user |
| 211 | + ) |
| 212 | + |
186 | 213 | return user, token
|
187 | 214 |
|
188 | 215 | def _get_dependency_signature(
|
|
0 commit comments