Add proper email notifications

This commit is contained in:
2026-05-14 23:19:50 +03:00
parent fe62575790
commit 9e16b78793
34 changed files with 1313 additions and 83 deletions

14
apps/accounts/urls.py Normal file
View File

@@ -0,0 +1,14 @@
"""Local additions under `/accounts/`. Mounted in `hamprint/urls.py` BEFORE
`include("allauth.urls")` so any path defined here wins; everything we
don't claim falls through to allauth.
"""
from django.urls import path
from . import views
app_name = "accounts"
urlpatterns = [
path("close/", views.close_account, name="close"),
]

View File

@@ -1,3 +1,68 @@
from django.shortcuts import render
"""Local account views -- the ones allauth doesn't ship.
# Create your views here.
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},
)