gabriel / musehub public

musehub_account.py file-level

at sha256:c · View file ↗ · Intel ↗

History
1 files
1 commits
0 hotspots
0 🧊 dead
0 💥 blast risk
sha256:1 fix: getting-started page's muse --version sample output showed musehub… · gabriel · Oct 23, 2026
1 """Account deletion — shared by self-service (GDPR Article 17, DELETE /api/me)
2 and admin-initiated deletion (DELETE /api/admin/users/{handle}, musehub#224).
3
4 Both paths must apply the identical effect: hard-delete all registered auth
5 keys (so the handle can never re-authenticate) and soft-delete the identity
6 (``deleted_at`` set) so commit/push history attribution is preserved.
7 """
8
9 import logging
10 from datetime import datetime, timezone
11
12 from sqlalchemy import delete
13 from sqlalchemy.ext.asyncio import AsyncSession
14
15 from musehub.db.musehub_auth_models import MusehubAuthKey
16 from musehub.db.musehub_identity_models import MusehubIdentity
17
18 logger = logging.getLogger(__name__)
19
20
21 async def delete_identity_account(session: AsyncSession, identity: MusehubIdentity) -> None:
22 """Hard-delete all auth keys and soft-delete *identity*.
23
24 Does not commit — callers own the transaction boundary so they can add
25 their own audit logging / additional effects within the same commit.
26 """
27 await session.execute(
28 delete(MusehubAuthKey).where(MusehubAuthKey.identity_id == identity.identity_id)
29 )
30 identity.deleted_at = datetime.now(timezone.utc)