|
1 | 1 | import logging |
2 | 2 | from typing import Any, Literal |
3 | 3 |
|
4 | | -from fastapi import APIRouter, Depends, Query |
| 4 | +from fastapi import APIRouter, Depends, HTTPException, Query |
5 | 5 | from fastapi_sqlalchemy import db |
6 | 6 | from sqlalchemy.orm import Session |
| 7 | +from starlette.status import HTTP_403_FORBIDDEN |
7 | 8 |
|
8 | 9 | from auth_backend.auth_method import AuthPluginMeta |
9 | 10 | from auth_backend.auth_plugins.email import Email |
@@ -141,26 +142,32 @@ async def patch_user( |
141 | 142 | @user.delete("/{user_id}", response_model=None) |
142 | 143 | async def delete_user( |
143 | 144 | user_id: int, |
144 | | - current_user: UserSession = Depends(UnionAuth(scopes=["auth.user.delete"], allow_none=False, auto_error=True)), |
| 145 | + current_user: UserSession = Depends(UnionAuth(scopes=[], allow_none=False, auto_error=True)), |
145 | 146 | ) -> None: |
146 | 147 | """ |
147 | | - Scopes: `["auth.user.delete"]` |
| 148 | + Scopes: `["auth.user.delete"]` or `["auth.user.selfdelete"]` for self delete |
148 | 149 | """ |
149 | | - logger.debug(f'User id={current_user.id} triggered delete_user') |
150 | | - old_user = {"user_id": current_user.id} |
151 | | - user: User = User.get(user_id, session=db.session) |
| 150 | + session_scopes = set([scope.name.lower() for scope in current_user.scopes]) |
| 151 | + if "auth.user.delete" in session_scopes or ( |
| 152 | + "auth.user.selfdelete" in session_scopes and user_id == current_user.user_id |
| 153 | + ): |
| 154 | + logger.debug(f'User id={current_user.id} triggered delete_user') |
| 155 | + old_user = {"user_id": current_user.id} |
| 156 | + user: User = User.get(user_id, session=db.session) |
152 | 157 |
|
153 | | - for method in user._auth_methods: |
154 | | - if method.is_deleted: |
155 | | - continue |
156 | | - # Сохраняем старое состояние пользователя |
157 | | - if method.auth_method not in old_user: |
158 | | - old_user[method.auth_method] = {} |
159 | | - old_user[method.auth_method][method.param] = method.value |
160 | | - # Удаляем AuthMethod |
161 | | - AuthMethod.delete(method.id, session=db.session) |
162 | | - logger.info(f'{method=} for {user.id=} deleted') |
163 | | - User.delete(user_id, session=db.session) |
164 | | - db.session.commit() |
165 | | - await AuthPluginMeta.user_updated(None, old_user) |
166 | | - logger.info(f'{user=} deleted') |
| 158 | + for method in user._auth_methods: |
| 159 | + if method.is_deleted: |
| 160 | + continue |
| 161 | + # Сохраняем старое состояние пользователя |
| 162 | + if method.auth_method not in old_user: |
| 163 | + old_user[method.auth_method] = {} |
| 164 | + old_user[method.auth_method][method.param] = method.value |
| 165 | + # Удаляем AuthMethod |
| 166 | + AuthMethod.delete(method.id, session=db.session) |
| 167 | + logger.info(f'{method=} for {user.id=} deleted') |
| 168 | + User.delete(user_id, session=db.session) |
| 169 | + db.session.commit() |
| 170 | + await AuthPluginMeta.user_updated(None, old_user) |
| 171 | + logger.info(f'{user=} deleted') |
| 172 | + else: |
| 173 | + raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail="Not authorized") |
0 commit comments