mirror of
https://github.com/fastapi-users/fastapi-users.git
synced 2025-11-02 04:05:19 +08:00
* Add CRU superuser routes * Add delete method on DB adapters * Add superuser delete route * Add superuser routes documentation * Pass black formatter
This commit is contained in:
@ -29,6 +29,10 @@ class BaseUserDatabase:
|
||||
"""Update a user."""
|
||||
raise NotImplementedError()
|
||||
|
||||
async def delete(self, user: BaseUserDB) -> None:
|
||||
"""Delete a user."""
|
||||
raise NotImplementedError()
|
||||
|
||||
async def authenticate(
|
||||
self, credentials: OAuth2PasswordRequestForm
|
||||
) -> Optional[BaseUserDB]:
|
||||
|
||||
@ -38,3 +38,6 @@ class MongoDBUserDatabase(BaseUserDatabase):
|
||||
async def update(self, user: BaseUserDB) -> BaseUserDB:
|
||||
await self.collection.replace_one({"id": user.id}, user.dict())
|
||||
return user
|
||||
|
||||
async def delete(self, user: BaseUserDB) -> None:
|
||||
await self.collection.delete_one({"id": user.id})
|
||||
|
||||
@ -57,3 +57,7 @@ class SQLAlchemyUserDatabase(BaseUserDatabase):
|
||||
)
|
||||
await self.database.execute(query)
|
||||
return user
|
||||
|
||||
async def delete(self, user: BaseUserDB) -> None:
|
||||
query = self.users.delete().where(self.users.c.id == user.id)
|
||||
await self.database.execute(query)
|
||||
|
||||
@ -23,6 +23,9 @@ class BaseUser(BaseModel):
|
||||
skip_defaults=True, exclude={"id", "is_superuser", "is_active"}
|
||||
)
|
||||
|
||||
def create_update_dict_superuser(self):
|
||||
return self.dict(skip_defaults=True, exclude={"id"})
|
||||
|
||||
|
||||
class BaseUserCreate(BaseUser):
|
||||
email: EmailStr
|
||||
|
||||
@ -54,6 +54,24 @@ def get_user_router(
|
||||
reset_password_token_audience = "fastapi-users:reset"
|
||||
|
||||
get_current_active_user = auth.get_current_active_user(user_db)
|
||||
get_current_superuser = auth.get_current_superuser(user_db)
|
||||
|
||||
async def _get_or_404(id: str) -> models.UserDB: # type: ignore
|
||||
user = await user_db.get(id)
|
||||
if user is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
||||
return user
|
||||
|
||||
async def _update_user(
|
||||
user: models.UserDB, update_dict: typing.Dict[str, typing.Any] # type: ignore
|
||||
):
|
||||
for field in update_dict:
|
||||
if field == "password":
|
||||
hashed_password = get_password_hash(update_dict[field])
|
||||
user.hashed_password = hashed_password
|
||||
else:
|
||||
setattr(user, field, update_dict[field])
|
||||
return await user_db.update(user)
|
||||
|
||||
@router.post(
|
||||
"/register", response_model=models.User, status_code=status.HTTP_201_CREATED
|
||||
@ -136,13 +154,38 @@ def get_user_router(
|
||||
user: models.UserDB = Depends(get_current_active_user), # type: ignore
|
||||
):
|
||||
updated_user_data = updated_user.create_update_dict()
|
||||
for field in updated_user_data:
|
||||
if field == "password":
|
||||
hashed_password = get_password_hash(updated_user_data[field])
|
||||
user.hashed_password = hashed_password
|
||||
else:
|
||||
setattr(user, field, updated_user_data[field])
|
||||
return await _update_user(user, updated_user_data)
|
||||
|
||||
return await user_db.update(user)
|
||||
@router.get("/", response_model=typing.List[models.User]) # type: ignore
|
||||
async def list_users(
|
||||
superuser: models.UserDB = Depends(get_current_superuser), # type: ignore
|
||||
):
|
||||
return await user_db.list()
|
||||
|
||||
@router.get("/{id}", response_model=models.User)
|
||||
async def get_user(
|
||||
id: str,
|
||||
superuser: models.UserDB = Depends(get_current_superuser), # type: ignore
|
||||
):
|
||||
return await _get_or_404(id)
|
||||
|
||||
@router.patch("/{id}", response_model=models.User)
|
||||
async def update_user(
|
||||
id: str,
|
||||
updated_user: models.UserUpdate, # type: ignore
|
||||
superuser: models.UserDB = Depends(get_current_superuser), # type: ignore
|
||||
):
|
||||
user = await _get_or_404(id)
|
||||
updated_user_data = updated_user.create_update_dict_superuser()
|
||||
return await _update_user(user, updated_user_data)
|
||||
|
||||
@router.delete("/{id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_user(
|
||||
id: str,
|
||||
superuser: models.UserDB = Depends(get_current_superuser), # type: ignore
|
||||
):
|
||||
user = await _get_or_404(id)
|
||||
await user_db.delete(user)
|
||||
return None
|
||||
|
||||
return router
|
||||
|
||||
Reference in New Issue
Block a user