Skip to content

Commit 0e9da5f

Browse files
authored
Разделение логики удаления юзера по скоупам (#237)
1 parent 989e7c3 commit 0e9da5f

File tree

2 files changed

+39
-33
lines changed

2 files changed

+39
-33
lines changed

auth_backend/routes/user.py

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
from datetime import datetime
33
from typing import Any, Literal
44

5-
from fastapi import APIRouter, Depends, HTTPException, Query
5+
from fastapi import APIRouter, Depends, Query
66
from fastapi_sqlalchemy import db
77
from sqlalchemy import not_
88
from sqlalchemy.orm import Session
9-
from starlette.status import HTTP_403_FORBIDDEN
109

1110
from auth_backend.auth_method import AuthPluginMeta
1211
from auth_backend.auth_plugins.email import Email
@@ -144,36 +143,44 @@ async def patch_user(
144143
@user.delete("/{user_id}", response_model=None)
145144
async def delete_user(
146145
user_id: int,
147-
current_user: UserSession = Depends(UnionAuth(scopes=[], allow_none=False, auto_error=True)),
146+
current_user: UserSession = Depends(UnionAuth(scopes=["auth.user.delete"], allow_none=False, auto_error=True)),
148147
) -> None:
149148
"""
150-
Scopes: `["auth.user.delete"]` or `["auth.user.selfdelete"]` for self delete
149+
Scopes: `["auth.user.delete"]`
151150
"""
152-
session_scopes = set([scope.name.lower() for scope in current_user.scopes])
153-
if "auth.user.delete" in session_scopes or (
154-
"auth.user.selfdelete" in session_scopes and user_id == current_user.user_id
155-
):
156-
logger.debug(f'User id={current_user.id} triggered delete_user')
157-
old_user = {"user_id": current_user.id}
158-
user: User = User.get(user_id, session=db.session)
159-
160-
for method in user._auth_methods:
161-
if method.is_deleted:
162-
continue
163-
# Сохраняем старое состояние пользователя
164-
if method.auth_method not in old_user:
165-
old_user[method.auth_method] = {}
166-
old_user[method.auth_method][method.param] = method.value
167-
# Удаляем AuthMethod
168-
AuthMethod.delete(method.id, session=db.session)
169-
logger.info(f'{method=} for {user.id=} deleted')
170-
User.delete(user_id, session=db.session)
171-
# Удаляем сессии
172-
db.session.query(UserSession).filter(UserSession.user_id == user_id).filter(not_(UserSession.expired)).update(
173-
{"expires": datetime.utcnow()}
174-
)
175-
db.session.commit()
176-
await AuthPluginMeta.user_updated(None, old_user)
177-
logger.info(f'{user=} deleted')
178-
else:
179-
raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail="Not authorized")
151+
await delete_user_common(user_triggered_id=current_user.user_id, user_delete_id=user_id)
152+
153+
154+
@user.delete("", response_model=None)
155+
async def delete_self_user(
156+
current_user: UserSession = Depends(UnionAuth(scopes=["auth.user.selfdelete"], allow_none=False, auto_error=True))
157+
) -> None:
158+
"""
159+
Scopes: `["auth.user.selfdelete"]`
160+
"""
161+
await delete_user_common(user_triggered_id=current_user.user_id, user_delete_id=current_user.user_id)
162+
163+
164+
async def delete_user_common(user_triggered_id: int, user_delete_id: int):
165+
logger.debug(f'User id={user_triggered_id} triggered delete_user')
166+
old_user = {"user_id": user_triggered_id}
167+
user: User = User.get(user_delete_id, session=db.session)
168+
169+
for method in user._auth_methods:
170+
if method.is_deleted:
171+
continue
172+
# Сохраняем старое состояние пользователя
173+
if method.auth_method not in old_user:
174+
old_user[method.auth_method] = {}
175+
old_user[method.auth_method][method.param] = method.value
176+
# Удаляем AuthMethod
177+
AuthMethod.delete(method.id, session=db.session)
178+
logger.info(f'{method=} for {user.id=} deleted')
179+
User.delete(user_delete_id, session=db.session)
180+
# Удаляем сессии
181+
db.session.query(UserSession).filter(UserSession.user_id == user_delete_id).filter(
182+
not_(UserSession.expired)
183+
).update({"expires": datetime.utcnow()})
184+
db.session.commit()
185+
await AuthPluginMeta.user_updated(None, old_user)
186+
logger.info(f'{user=} deleted')

auth_backend/settings.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
from annotated_types import Gt
99
from pydantic import PostgresDsn
10-
from pydantic.types import PathType
1110
from pydantic_settings import BaseSettings, SettingsConfigDict
1211

1312

0 commit comments

Comments
 (0)