Remove list endpoint and related methods

This commit is contained in:
François Voron
2020-04-25 11:46:20 +02:00
parent f37e4b90df
commit a9ee467518
13 changed files with 5 additions and 134 deletions

View File

@ -201,26 +201,6 @@ Update the current authenticated active user.
## Superuser ## Superuser
### `GET /`
Return the list of registered users.
!!! success "`200 OK`"
```json
[{
"id": "57cbb51a-ab71-4009-8802-3f54b4f2e23",
"email": "king.arthur@camelot.bt",
"is_active": true,
"is_superuser": false
}]
```
!!! fail "`401 Unauthorized`"
Missing token or inactive user.
!!! fail "`403 Forbidden`"
Not a superuser.
### `GET /{user_id}` ### `GET /{user_id}`
Return the user with id `user_id`. Return the user with id `user_id`.

View File

@ -1,4 +1,4 @@
from typing import Generic, List, Optional, Type from typing import Generic, Optional, Type
from fastapi.security import OAuth2PasswordRequestForm from fastapi.security import OAuth2PasswordRequestForm
@ -18,10 +18,6 @@ class BaseUserDatabase(Generic[UD]):
def __init__(self, user_db_model: Type[UD]): def __init__(self, user_db_model: Type[UD]):
self.user_db_model = user_db_model self.user_db_model = user_db_model
async def list(self) -> List[UD]:
"""List all users."""
raise NotImplementedError()
async def get(self, id: str) -> Optional[UD]: async def get(self, id: str) -> Optional[UD]:
"""Get a single user by id.""" """Get a single user by id."""
raise NotImplementedError() raise NotImplementedError()

View File

@ -1,4 +1,4 @@
from typing import List, Optional, Type from typing import Optional, Type
from motor.motor_asyncio import AsyncIOMotorCollection from motor.motor_asyncio import AsyncIOMotorCollection
@ -22,9 +22,6 @@ class MongoDBUserDatabase(BaseUserDatabase[UD]):
self.collection.create_index("id", unique=True) self.collection.create_index("id", unique=True)
self.collection.create_index("email", unique=True) self.collection.create_index("email", unique=True)
async def list(self) -> List[UD]:
return [self.user_db_model(**user) async for user in self.collection.find()]
async def get(self, id: str) -> Optional[UD]: async def get(self, id: str) -> Optional[UD]:
user = await self.collection.find_one({"id": id}) user = await self.collection.find_one({"id": id})
return self.user_db_model(**user) if user else None return self.user_db_model(**user) if user else None

View File

@ -1,4 +1,4 @@
from typing import List, Mapping, Optional, Type from typing import Mapping, Optional, Type
from databases import Database from databases import Database
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, Table, select from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, Table, select
@ -75,11 +75,6 @@ class SQLAlchemyUserDatabase(BaseUserDatabase[UD]):
self.users = users self.users = users
self.oauth_accounts = oauth_accounts self.oauth_accounts = oauth_accounts
async def list(self) -> List[UD]:
query = self.users.select()
users = await self.database.fetch_all(query)
return [await self._make_user(user) for user in users]
async def get(self, id: str) -> Optional[UD]: async def get(self, id: str) -> Optional[UD]:
query = self.users.select().where(self.users.c.id == id) query = self.users.select().where(self.users.c.id == id)
user = await self.database.fetch_one(query) user = await self.database.fetch_one(query)

View File

@ -1,4 +1,4 @@
from typing import List, Optional, Type from typing import Optional, Type
from tortoise import fields, models from tortoise import fields, models
from tortoise.exceptions import DoesNotExist from tortoise.exceptions import DoesNotExist
@ -61,16 +61,6 @@ class TortoiseUserDatabase(BaseUserDatabase[UD]):
self.model = model self.model = model
self.oauth_account_model = oauth_account_model self.oauth_account_model = oauth_account_model
async def list(self) -> List[UD]:
query = self.model.all()
if self.oauth_account_model is not None:
query = query.prefetch_related("oauth_accounts")
users = await query
return [self.user_db_model(**await user.to_dict()) for user in users]
async def get(self, id: str) -> Optional[UD]: async def get(self, id: str) -> Optional[UD]:
try: try:
query = self.model.get(id=id) query = self.model.get(id=id)

View File

@ -1,4 +1,4 @@
from typing import Any, Dict, List, Type, cast from typing import Any, Dict, Type, cast
import jwt import jwt
from fastapi import Body, Depends, HTTPException from fastapi import Body, Depends, HTTPException
@ -185,14 +185,6 @@ def get_user_router(
return updated_user return updated_user
@router.get(
"/",
response_model=List[user_model], # type: ignore
dependencies=[Depends(get_current_superuser)],
)
async def list_users():
return await user_db.list()
@router.get( @router.get(
"/{id}", "/{id}",
response_model=user_model, response_model=user_model,

View File

@ -155,9 +155,6 @@ def oauth_account3() -> BaseOAuthAccount:
@pytest.fixture @pytest.fixture
def mock_user_db(user, inactive_user, superuser) -> BaseUserDatabase: def mock_user_db(user, inactive_user, superuser) -> BaseUserDatabase:
class MockUserDatabase(BaseUserDatabase[UserDB]): class MockUserDatabase(BaseUserDatabase[UserDB]):
async def list(self) -> List[UserDB]:
return [user, inactive_user, superuser]
async def get(self, id: str) -> Optional[UserDB]: async def get(self, id: str) -> Optional[UserDB]:
if id == user.id: if id == user.id:
return user return user
@ -193,9 +190,6 @@ def mock_user_db_oauth(
user_oauth, inactive_user_oauth, superuser_oauth user_oauth, inactive_user_oauth, superuser_oauth
) -> BaseUserDatabase: ) -> BaseUserDatabase:
class MockUserDatabase(BaseUserDatabase[UserDBOAuth]): class MockUserDatabase(BaseUserDatabase[UserDBOAuth]):
async def list(self) -> List[UserDBOAuth]:
return [user_oauth, inactive_user_oauth, superuser_oauth]
async def get(self, id: str) -> Optional[UserDBOAuth]: async def get(self, id: str) -> Optional[UserDBOAuth]:
if id == user_oauth.id: if id == user_oauth.id:
return user_oauth return user_oauth

View File

@ -18,9 +18,6 @@ def create_oauth2_password_request_form():
async def test_not_implemented_methods(user): async def test_not_implemented_methods(user):
base_user_db = BaseUserDatabase(UserDB) base_user_db = BaseUserDatabase(UserDB)
with pytest.raises(NotImplementedError):
await base_user_db.list()
with pytest.raises(NotImplementedError): with pytest.raises(NotImplementedError):
await base_user_db.get("aaa") await base_user_db.get("aaa")

View File

@ -77,12 +77,6 @@ async def test_queries(mongodb_user_db: MongoDBUserDatabase[UserDB]):
assert email_user is not None assert email_user is not None
assert email_user.id == user_db.id assert email_user.id == user_db.id
# List
users = await mongodb_user_db.list()
assert len(users) == 1
first_user = users[0]
assert first_user.id == user_db.id
# Exception when inserting existing email # Exception when inserting existing email
with pytest.raises(pymongo.errors.DuplicateKeyError): with pytest.raises(pymongo.errors.DuplicateKeyError):
await mongodb_user_db.create(user) await mongodb_user_db.create(user)
@ -151,13 +145,6 @@ async def test_queries_oauth(
assert email_user.id == user_db.id assert email_user.id == user_db.id
assert len(email_user.oauth_accounts) == 2 assert len(email_user.oauth_accounts) == 2
# List
users = await mongodb_user_db_oauth.list()
assert len(users) == 1
first_user = users[0]
assert first_user.id == user_db.id
assert len(first_user.oauth_accounts) == 2
# Get by OAuth account # Get by OAuth account
oauth_user = await mongodb_user_db_oauth.get_by_oauth_account( oauth_user = await mongodb_user_db_oauth.get_by_oauth_account(
oauth_account1.oauth_name, oauth_account1.account_id oauth_account1.oauth_name, oauth_account1.account_id

View File

@ -97,12 +97,6 @@ async def test_queries(sqlalchemy_user_db: SQLAlchemyUserDatabase[UserDB]):
assert email_user is not None assert email_user is not None
assert email_user.id == user_db.id assert email_user.id == user_db.id
# List
users = await sqlalchemy_user_db.list()
assert len(users) == 1
first_user = users[0]
assert first_user.id == user_db.id
# Exception when inserting existing email # Exception when inserting existing email
with pytest.raises(sqlite3.IntegrityError): with pytest.raises(sqlite3.IntegrityError):
await sqlalchemy_user_db.create(user) await sqlalchemy_user_db.create(user)
@ -193,13 +187,6 @@ async def test_queries_oauth(
assert email_user.id == user_db.id assert email_user.id == user_db.id
assert len(email_user.oauth_accounts) == 2 assert len(email_user.oauth_accounts) == 2
# List
users = await sqlalchemy_user_db_oauth.list()
assert len(users) == 1
first_user = users[0]
assert first_user.id == user_db.id
assert len(first_user.oauth_accounts) == 2
# Get by OAuth account # Get by OAuth account
oauth_user = await sqlalchemy_user_db_oauth.get_by_oauth_account( oauth_user = await sqlalchemy_user_db_oauth.get_by_oauth_account(
oauth_account1.oauth_name, oauth_account1.account_id oauth_account1.oauth_name, oauth_account1.account_id

View File

@ -82,12 +82,6 @@ async def test_queries(tortoise_user_db: TortoiseUserDatabase[UserDB]):
assert email_user is not None assert email_user is not None
assert email_user.id == user_db.id assert email_user.id == user_db.id
# List
users = await tortoise_user_db.list()
assert len(users) == 1
first_user = users[0]
assert first_user.id == user_db.id
# Exception when inserting existing email # Exception when inserting existing email
with pytest.raises(IntegrityError): with pytest.raises(IntegrityError):
await tortoise_user_db.create(user) await tortoise_user_db.create(user)
@ -161,13 +155,6 @@ async def test_queries_oauth(
assert email_user.id == user_db.id assert email_user.id == user_db.id
assert len(email_user.oauth_accounts) == 2 assert len(email_user.oauth_accounts) == 2
# List
users = await tortoise_user_db_oauth.list()
assert len(users) == 1
first_user = users[0]
assert first_user.id == user_db.id
assert len(first_user.oauth_accounts) == 2
# Get by OAuth account # Get by OAuth account
oauth_user = await tortoise_user_db_oauth.get_by_oauth_account( oauth_user = await tortoise_user_db_oauth.get_by_oauth_account(
oauth_account1.oauth_name, oauth_account1.account_id oauth_account1.oauth_name, oauth_account1.account_id

View File

@ -93,9 +93,6 @@ class TestRouter:
response = await test_app_client.post("/users/reset-password") response = await test_app_client.post("/users/reset-password")
assert response.status_code != status.HTTP_404_NOT_FOUND assert response.status_code != status.HTTP_404_NOT_FOUND
response = await test_app_client.get("/users")
assert response.status_code != status.HTTP_404_NOT_FOUND
response = await test_app_client.get("/users/aaa") response = await test_app_client.get("/users/aaa")
assert response.status_code != status.HTTP_404_NOT_FOUND assert response.status_code != status.HTTP_404_NOT_FOUND

View File

@ -500,34 +500,6 @@ class TestUpdateMe:
assert isinstance(request, Request) assert isinstance(request, Request)
@pytest.mark.router
@pytest.mark.asyncio
class TestListUsers:
async def test_missing_token(self, test_app_client: httpx.AsyncClient):
response = await test_app_client.get("/")
assert response.status_code == status.HTTP_401_UNAUTHORIZED
async def test_regular_user(self, test_app_client: httpx.AsyncClient, user: UserDB):
response = await test_app_client.get(
"/", headers={"Authorization": f"Bearer {user.id}"}
)
assert response.status_code == status.HTTP_403_FORBIDDEN
async def test_superuser(
self, test_app_client: httpx.AsyncClient, superuser: UserDB
):
response = await test_app_client.get(
"/", headers={"Authorization": f"Bearer {superuser.id}"}
)
assert response.status_code == status.HTTP_200_OK
response_json = response.json()
assert len(response_json) == 3
for user in response_json:
assert "id" in user
assert "hashed_password" not in user
@pytest.mark.router @pytest.mark.router
@pytest.mark.asyncio @pytest.mark.asyncio
class TestGetUser: class TestGetUser: