69 lines
2.5 KiB
Python
69 lines
2.5 KiB
Python
"""Local account views -- the ones allauth doesn't ship.
|
|
|
|
Today: just `close_account` ("permanently delete this user"). Logout is
|
|
allauth's; we override its template, not its view.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from django.contrib import messages
|
|
from django.contrib.auth import logout
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.db import transaction
|
|
from django.http import HttpResponseForbidden
|
|
from django.shortcuts import redirect, render
|
|
from django.views.decorators.http import require_http_methods
|
|
|
|
from apps.submissions.models import Submission
|
|
|
|
|
|
@login_required
|
|
@require_http_methods(["GET", "POST"])
|
|
def close_account(request):
|
|
"""Permanently delete the signed-in user and all of their submissions.
|
|
|
|
GET -> render a "are you sure?" confirmation page, showing how many of
|
|
their submissions will go with the user.
|
|
POST -> delete the rows, log the user out, redirect to the dashboard.
|
|
|
|
Refuses staff users (`is_staff=True`): they'd be locking themselves
|
|
(and possibly the only operator) out of /admin/ with no recourse, so
|
|
that path requires another operator to remove the row via
|
|
/admin/auth/user/ instead.
|
|
|
|
Why delete the submissions too: `Submission.submitted_by` uses
|
|
`on_delete=SET_NULL`, but the `CheckConstraint` on the model requires
|
|
that EITHER `submitted_by` OR `guest_email` is non-null. OAuth-created
|
|
submissions have `guest_email=NULL`, so SET_NULL would violate the
|
|
constraint at delete time. Simpler + matches user expectation of
|
|
"delete my account": wipe the rows wholesale. The `post_delete` signal
|
|
in `apps/submissions/signals.py` unlinks the uploaded STLs at the
|
|
same time.
|
|
"""
|
|
if request.user.is_staff:
|
|
return HttpResponseForbidden(
|
|
"Staff users cannot close their own account from here. "
|
|
"Ask another operator to remove the row via /admin/auth/user/."
|
|
)
|
|
|
|
if request.method == "POST":
|
|
user = request.user
|
|
username = user.get_username()
|
|
with transaction.atomic():
|
|
Submission.objects.filter(submitted_by=user).delete()
|
|
logout(request)
|
|
user.delete()
|
|
messages.info(
|
|
request,
|
|
f"Account {username} and all of your prints have been "
|
|
f"permanently deleted.",
|
|
)
|
|
return redirect("dashboard:index")
|
|
|
|
submission_count = Submission.objects.filter(submitted_by=request.user).count()
|
|
return render(
|
|
request,
|
|
"account/close.html",
|
|
{"submission_count": submission_count},
|
|
)
|