✨ Added delete-user route
This commit is contained in:
@@ -15,7 +15,7 @@ from classquiz.auth import (
|
|||||||
get_current_user,
|
get_current_user,
|
||||||
)
|
)
|
||||||
from classquiz.cache import clear_cache_for_account
|
from classquiz.cache import clear_cache_for_account
|
||||||
from classquiz.config import redis, settings
|
from classquiz.config import redis, settings, meilisearch
|
||||||
import uuid
|
import uuid
|
||||||
import bleach
|
import bleach
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
@@ -64,9 +64,9 @@ async def create_user(user: route_user, background_task: BackgroundTasks) -> Use
|
|||||||
|
|
||||||
@router.post("/token/cookie", response_model=Token)
|
@router.post("/token/cookie", response_model=Token)
|
||||||
async def login_for_cookie_access_token(
|
async def login_for_cookie_access_token(
|
||||||
request: Request,
|
request: Request,
|
||||||
response: Response,
|
response: Response,
|
||||||
form_data: OAuth2PasswordRequestForm = Depends(),
|
form_data: OAuth2PasswordRequestForm = Depends(),
|
||||||
):
|
):
|
||||||
user = await authenticate_user(form_data.username, form_data.password)
|
user = await authenticate_user(form_data.username, form_data.password)
|
||||||
if not user:
|
if not user:
|
||||||
@@ -168,9 +168,9 @@ async def verify_user(verify_key: str):
|
|||||||
|
|
||||||
@router.put("/password/update")
|
@router.put("/password/update")
|
||||||
async def change_password(
|
async def change_password(
|
||||||
password_data: UpdatePassword,
|
password_data: UpdatePassword,
|
||||||
response: Response,
|
response: Response,
|
||||||
user: User = Depends(get_current_user),
|
user: User = Depends(get_current_user),
|
||||||
):
|
):
|
||||||
if not verify_password(password_data.old_password, user.password):
|
if not verify_password(password_data.old_password, user.password):
|
||||||
raise HTTPException(status_code=400, detail="Incorrect password")
|
raise HTTPException(status_code=400, detail="Incorrect password")
|
||||||
@@ -268,6 +268,14 @@ class DeleteUserInput(BaseModel):
|
|||||||
async def delete_user_account(input_data: DeleteUserInput, user: User = Depends(get_current_user)):
|
async def delete_user_account(input_data: DeleteUserInput, user: User = Depends(get_current_user)):
|
||||||
if not verify_password(input_data.password, user.password):
|
if not verify_password(input_data.password, user.password):
|
||||||
raise HTTPException(status_code=400, detail="Incorrect password")
|
raise HTTPException(status_code=400, detail="Incorrect password")
|
||||||
|
user = await User.objects.filter(id=user.id).get_or_none()
|
||||||
await UserSession.objects.filter(user=user).delete()
|
await UserSession.objects.filter(user=user).delete()
|
||||||
await Quiz.objects.filter(user=user).delete()
|
quizzes = await Quiz.objects.filter(user_id=user).all()
|
||||||
|
quizzes_to_delete = []
|
||||||
|
for quiz in quizzes:
|
||||||
|
if quiz.is_public:
|
||||||
|
quizzes_to_delete.append(quiz.id)
|
||||||
|
if len(quizzes_to_delete) > 0:
|
||||||
|
meilisearch.index(settings.meilisearch_index).delete_documents(quizzes_to_delete)
|
||||||
|
await User.objects.filter(id=user.id).delete()
|
||||||
await user.delete()
|
await user.delete()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import pytest
|
|||||||
from classquiz.kahoot_importer.get import get
|
from classquiz.kahoot_importer.get import get
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.order("last")
|
@pytest.mark.order(-2)
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_get():
|
async def test_get():
|
||||||
await get("1f95eb0b-fcf4-4db2-879b-5418ef75116b")
|
await get("1f95eb0b-fcf4-4db2-879b-5418ef75116b")
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from classquiz.kahoot_importer.search import search
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.order("last")
|
@pytest.mark.order(-2)
|
||||||
async def test_search():
|
async def test_search():
|
||||||
res = await search(query="Python", limit=100)
|
res = await search(query="Python", limit=100)
|
||||||
assert len(res.entities) == 100
|
assert len(res.entities) == 100
|
||||||
|
|||||||
@@ -359,3 +359,16 @@ class TestQuiz:
|
|||||||
ValueStorage.imported_quizzes.append(resp.json()["id"])
|
ValueStorage.imported_quizzes.append(resp.json()["id"])
|
||||||
resp = test_client.post("/api/v1/quiz/import/1f95eb0bdassdadasdas", cookies={"access_token": token})
|
resp = test_client.post("/api/v1/quiz/import/1f95eb0bdassdadasdas", cookies={"access_token": token})
|
||||||
assert resp.text == '"quiz not found"'
|
assert resp.text == '"quiz not found"'
|
||||||
|
|
||||||
|
|
||||||
|
class TestDeleteUser:
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_delete_user(self, test_client):
|
||||||
|
resp = test_client.post(
|
||||||
|
"/api/v1/users/token/cookie", data={"username": test_user_email, "password": test_user_password}
|
||||||
|
)
|
||||||
|
token = resp.cookies["access_token"]
|
||||||
|
resp = test_client.delete(
|
||||||
|
"/api/v1/users/me", cookies={"access_token": token}, json={"password": test_user_password}
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
|||||||
@@ -45,13 +45,13 @@
|
|||||||
<td> On my server, by Netcup, in Germany.</td>
|
<td> On my server, by Netcup, in Germany.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td> The data you enter (quizzes, email, username)</td>
|
<td> The data the user enters (quizzes, email, username)</td>
|
||||||
<td> Self-explaining</td>
|
<td> Self-explaining</td>
|
||||||
<td> Maximum of 30 days after you've deleted your account</td>
|
<td> Maximum of 30 days after you've deleted your account</td>
|
||||||
<td> On my server, by Netcup, in Germany.</td>
|
<td> On my server, by Netcup, in Germany.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Your hashed password</td>
|
<td>The hashed password of the user</td>
|
||||||
<td>Self-explaining</td>
|
<td>Self-explaining</td>
|
||||||
<td>Maximum of 30 days after you've deleted your account</td>
|
<td>Maximum of 30 days after you've deleted your account</td>
|
||||||
<td>On my server, by Netcup, in Germany.</td>
|
<td>On my server, by Netcup, in Germany.</td>
|
||||||
|
|||||||
Reference in New Issue
Block a user