Repository: mdn/kuma

Issue:
Server error when trying to delete my account on stage
It looks like there is a foreign key constraint blocking deletion of users in some cases. Here's the related sentry error:
> "Cannot delete some instances of model 'User' because they are referenced through a protected foreign key: 'AttachmentRevision.creator'", <QuerySet [<AttachmentRevision: test (file: "Screenshot_6.png", ID: #17085)>]>

https://sentry.prod.mozaws.net/operations/mdn-stage/issues/7271436


Discussion:
What's so bizarre is that there is already a test for this: https://github.com/mdn/kuma/blob/3df115a9ba8d3130094a9007f4e9d668a6f274fe/kuma/users/tests/test_views.py#L1533

I wonder, what happened is that you didn't have any Wiki document revisions, so it didn't even ask if you wanted to donate or scrub your account. But for some reason, you had an AttachmentRevision to your name. 
Also I think I just created the account yesterday and not doing anything in the wiki with it. So I don't even know where that Attachment would've come from 🤔 
> Also I think I just created the account yesterday and not doing anything in the wiki with it. So I don't even know where that Attachment would've come from 🤔

Now that's very curious!
Here's the attachment revision that supposedly belongs to your account: https://developer.allizom.org/admin/attachments/attachmentrevision/17085/change/
And here's its attachment itself: https://developer.allizom.org/admin/attachments/attachment/16885/change/
Doesn't say in the Django Admin who the creator is. 
Okay maybe I got things mixed up and I had an account before, that is certainly my screenshot 😕
Either way, it's a bug. And I think I can write a unit test to reproduce it. 

By the way, it's weird that you can't look at who the creator was of an attachment revision in the Django admin. 

I tried going into the Kubernetes Stage cluster but https://github.com/mdn/infra/issues/374
Crap. It's not trivial. If a user has attachments, they need to be treated just like document revisions. I.e. "Do you want to donate them to 'Anonymous' or just scrub your account?"

That means that the UI needs to change too. Annoyingly, that UI needs to change in two places :(

CC @schalkneethling @atopal 
For the record, https://github.com/mdn/kuma/pull/6482 takes care of the backend piece. If you have *document* OR *attachment* revisions, it now requires that you make a decision about what to do with your attributions. 

The two UIs that use this backend still needs to get this upgrade. I.e. We determine whether to ask the user what to do based on them having DOCUMENT revisions only. It needs to be both. 
By the way, I can totally reproduce it. I created a brand new account and went to the Wiki and clicked to Edit a document. But I never edited the document at all. Instead, I just scrolled down to the bottom and added an attachment and that's it. Then I went into my Edit profile and clicked "Delete account" and it's not asking me what I want to do with my attachment revision(s). 
<img width="794" alt="Screen Shot 2020-02-13 at 11 12 43 AM" src="https://user-images.githubusercontent.com/26739/74454539-0e27de00-4e52-11ea-8d87-eb771f2f178b.png">


Resolving patch:
diff --git a/kuma/users/views.py b/kuma/users/views.py
--- a/kuma/users/views.py
+++ b/kuma/users/views.py
@@ -38,6 +38,7 @@
 from raven.contrib.django.models import client as raven_client
 from waffle import flag_is_active
 
+from kuma.attachments.models import AttachmentRevision
 from kuma.core.decorators import (
     ensure_wiki_domain,
     login_required,
@@ -432,6 +433,7 @@ def user_edit(request, username):
         return HttpResponseForbidden()
 
     revisions = Revision.objects.filter(creator=edit_user)
+    attachment_revisions = AttachmentRevision.objects.filter(creator=edit_user)
 
     if request.method != "POST":
         initial = {
@@ -469,6 +471,7 @@ def user_edit(request, username):
         "username": user_form["username"].value(),
         "form": UserDeleteForm(),
         "revisions": revisions,
+        "attachment_revisions": attachment_revisions,
         "subscription_info": retrieve_stripe_subscription_info(edit_user,),
         "has_stripe_error": has_stripe_error,
     }
@@ -538,6 +541,7 @@ def delete_user():
         user.delete()
 
     revisions = Revision.objects.filter(creator=request.user)
+    attachment_revisions = AttachmentRevision.objects.filter(creator=request.user)
     context = {}
     if request.method == "POST":
         # If the user has no revisions there's not choices on the form.
@@ -564,6 +568,7 @@ def delete_user():
     context["form"] = form
     context["username"] = username
     context["revisions"] = revisions
+    context["attachment_revisions"] = attachment_revisions
 
     return render(request, "users/user_delete.html", context)
 


Test patch: