Return 403 instead of 401 when a user is known (#705)

* return 403 instead of 401 if user is known

* return 403 for unverified users

* updated docs
This commit is contained in:
Daan Beverdam
2021-09-04 18:11:48 +02:00
committed by GitHub
parent 7527902e9d
commit e59fb2c9b9
5 changed files with 28 additions and 33 deletions

View File

@ -11,7 +11,7 @@ Return a dependency callable to retrieve currently authenticated user, passing t
* `optional`: If `True`, `None` is returned if there is no authenticated user or if it doesn't pass the other requirements. Otherwise, throw `401 Unauthorized`. Defaults to `False`.
* `active`: If `True`, throw `401 Unauthorized` if the authenticated user is inactive. Defaults to `False`.
* `verified`: If `True`, throw `401 Unauthorized` if the authenticated user is not verified. Defaults to `False`.
* `verified`: If `True`, throw `403 Forbidden` if the authenticated user is not verified. Defaults to `False`.
* `superuser`: If `True`, throw `403 Forbidden` if the authenticated user is not a superuser. Defaults to `False`.
### Examples
@ -88,7 +88,7 @@ def protected_route(user: User = Depends(fastapi_users.get_current_active_user))
### `get_current_verified_user`
Get the current active and verified user. Will throw a `401 Unauthorized` if missing or wrong credentials or if the user is not active and verified.
Get the current active and verified user. Will throw a `401 Unauthorized` if missing or wrong credentials or if the user is not active. Will throw a `403 Forbidden` if the user is unverified.
```py
@app.get("/protected-route")

View File

@ -183,12 +183,13 @@ class Authenticator:
status_code = status.HTTP_401_UNAUTHORIZED
if user:
status_code = status.HTTP_403_FORBIDDEN
if active and not user.is_active:
status_code = status.HTTP_401_UNAUTHORIZED
user = None
elif verified and not user.is_verified:
user = None
elif superuser and not user.is_superuser:
status_code = status.HTTP_403_FORBIDDEN
user = None
if not user and not optional:

View File

@ -191,7 +191,7 @@ class TestGetCurrentVerifiedUser:
"/current-verified-user",
headers={"Authorization": f"Bearer {user.id}"},
)
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
async def test_valid_token_verified_user(
self, test_app_client: httpx.AsyncClient, verified_user: UserDB
@ -253,7 +253,7 @@ class TestGetCurrentVerifiedSuperuser:
"/current-verified-superuser",
headers={"Authorization": f"Bearer {user.id}"},
)
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
async def test_valid_token_verified_user(
self, test_app_client: httpx.AsyncClient, verified_user: UserDB
@ -271,7 +271,7 @@ class TestGetCurrentVerifiedSuperuser:
"/current-verified-superuser",
headers={"Authorization": f"Bearer {superuser.id}"},
)
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
async def test_valid_token_verified_superuser(
self, test_app_client: httpx.AsyncClient, verified_superuser: UserDB

View File

@ -183,7 +183,7 @@ class TestLogout:
path, headers={"Authorization": f"Bearer {user.id}"}
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
else:
assert response.status_code == status.HTTP_200_OK

View File

@ -97,7 +97,7 @@ class TestMe:
"/me", headers={"Authorization": f"Bearer {user.id}"}
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
else:
assert response.status_code == status.HTTP_200_OK
data = cast(Dict[str, Any], response.json())
@ -159,7 +159,7 @@ class TestUpdateMe:
headers={"Authorization": f"Bearer {user.id}"},
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
assert after_update.called is False
else:
assert response.status_code == status.HTTP_400_BAD_REQUEST
@ -181,7 +181,7 @@ class TestUpdateMe:
headers={"Authorization": f"Bearer {user.id}"},
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
assert after_update.called is False
else:
assert response.status_code == status.HTTP_400_BAD_REQUEST
@ -204,7 +204,7 @@ class TestUpdateMe:
"/me", json={}, headers={"Authorization": f"Bearer {user.id}"}
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
assert after_update.called is False
else:
assert response.status_code == status.HTTP_200_OK
@ -232,7 +232,7 @@ class TestUpdateMe:
"/me", json=json, headers={"Authorization": f"Bearer {user.id}"}
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
assert after_update.called is False
else:
assert response.status_code == status.HTTP_200_OK
@ -260,7 +260,7 @@ class TestUpdateMe:
"/me", json=json, headers={"Authorization": f"Bearer {user.id}"}
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
assert after_update.called is False
else:
assert response.status_code == status.HTTP_200_OK
@ -288,7 +288,7 @@ class TestUpdateMe:
"/me", json=json, headers={"Authorization": f"Bearer {user.id}"}
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
assert after_update.called is False
else:
assert response.status_code == status.HTTP_200_OK
@ -316,7 +316,7 @@ class TestUpdateMe:
"/me", json=json, headers={"Authorization": f"Bearer {user.id}"}
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
assert after_update.called is False
else:
assert response.status_code == status.HTTP_200_OK
@ -349,7 +349,7 @@ class TestUpdateMe:
"/me", json=json, headers={"Authorization": f"Bearer {user.id}"}
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
assert after_update.called is False
else:
assert response.status_code == status.HTTP_200_OK
@ -535,8 +535,6 @@ class TestGetUser:
headers={"Authorization": f"Bearer {user.id}"},
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
else:
assert response.status_code == status.HTTP_403_FORBIDDEN
async def test_verified_user(
@ -562,7 +560,7 @@ class TestGetUser:
headers={"Authorization": f"Bearer {superuser.id}"},
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
else:
assert response.status_code == status.HTTP_404_NOT_FOUND
@ -589,7 +587,7 @@ class TestGetUser:
f"/{user.id}", headers={"Authorization": f"Bearer {superuser.id}"}
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
else:
assert response.status_code == status.HTTP_200_OK
@ -633,8 +631,6 @@ class TestUpdateUser:
headers={"Authorization": f"Bearer {user.id}"},
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
else:
assert response.status_code == status.HTTP_403_FORBIDDEN
async def test_verified_user(
@ -661,7 +657,7 @@ class TestUpdateUser:
headers={"Authorization": f"Bearer {superuser.id}"},
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
else:
assert response.status_code == status.HTTP_404_NOT_FOUND
@ -689,7 +685,7 @@ class TestUpdateUser:
f"/{user.id}", json={}, headers={"Authorization": f"Bearer {superuser.id}"}
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
else:
assert response.status_code == status.HTTP_200_OK
@ -727,7 +723,7 @@ class TestUpdateUser:
headers={"Authorization": f"Bearer {superuser.id}"},
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
else:
assert response.status_code == status.HTTP_200_OK
@ -808,7 +804,7 @@ class TestUpdateUser:
headers={"Authorization": f"Bearer {superuser.id}"},
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
else:
assert response.status_code == status.HTTP_200_OK
@ -847,7 +843,7 @@ class TestUpdateUser:
headers={"Authorization": f"Bearer {superuser.id}"},
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
else:
assert response.status_code == status.HTTP_200_OK
@ -886,7 +882,7 @@ class TestUpdateUser:
headers={"Authorization": f"Bearer {superuser.id}"},
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
else:
assert response.status_code == status.HTTP_200_OK
@ -930,7 +926,7 @@ class TestUpdateUser:
headers={"Authorization": f"Bearer {superuser.id}"},
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
else:
assert response.status_code == status.HTTP_200_OK
assert mock_user_db.update.called is True
@ -982,8 +978,6 @@ class TestDeleteUser:
headers={"Authorization": f"Bearer {user.id}"},
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
else:
assert response.status_code == status.HTTP_403_FORBIDDEN
async def test_verified_user(
@ -1009,7 +1003,7 @@ class TestDeleteUser:
headers={"Authorization": f"Bearer {superuser.id}"},
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
else:
assert response.status_code == status.HTTP_404_NOT_FOUND
@ -1040,7 +1034,7 @@ class TestDeleteUser:
f"/{user.id}", headers={"Authorization": f"Bearer {superuser.id}"}
)
if requires_verification:
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.status_code == status.HTTP_403_FORBIDDEN
else:
assert response.status_code == status.HTTP_204_NO_CONTENT
assert response.content == b""