Implement identity deletion

This commit is contained in:
Andrew Godwin 2023-05-03 13:39:02 -06:00
parent 2e605ca9a9
commit 592466579f
7 changed files with 92 additions and 1 deletions

View file

@ -80,6 +80,11 @@ urlpatterns = [
settings.TokenEdit.as_view(),
name="settings_token_edit",
),
path(
"@<handle>/settings/delete/",
settings.DeleteIdentity.as_view(),
name="settings_delete",
),
path(
"admin/",
admin.AdminRoot.as_view(),

View file

@ -14,10 +14,14 @@
<i class="fa-solid fa-cloud-arrow-up"></i>
<span>Import/Export</span>
</a>
<a href="{% url "settings_tokens" handle=identity.handle %}" {% if section == "tokens" %}class="selected"{% endif %} title="Interface">
<a href="{% url "settings_tokens" handle=identity.handle %}" {% if section == "tokens" %}class="selected"{% endif %} title="Authorized Apps">
<i class="fa-solid fa-window-restore"></i>
<span>Authorized Apps</span>
</a>
<a href="{% url "settings_delete" handle=identity.handle %}" {% if section == "delete" %}class="selected"{% endif %} title="Delete Identity">
<i class="fa-solid fa-user-slash"></i>
<span>Delete Identity</span>
</a>
<hr>
<h3>Tools</h3>
<a href="{% url "settings_follows" handle=identity.handle %}" {% if section == "follows" %}class="selected"{% endif %} title="Follows">

View file

@ -0,0 +1,31 @@
{% extends "settings/base.html" %}
{% block subtitle %}Token{% endblock %}
{% block settings_content %}
<h1>Deleting {{ identity.handle }}</h1>
<form action="." method="POST">
{% csrf_token %}
<fieldset>
<legend>Confirmation</legend>
<p>
Deleting this account is <i>permanent and irreversible</i>. Once you
start the deletion process, all your posts, interactions and profile
data will be gone, and other servers will be contacted to remove
your data as well.
</p>
<p>
Some other servers in the Fediverse may maintain a copy of your
profile and posts; we do not control them, and cannot speed up
or affect your data's removal. Most data will disappear from
the network after a couple of weeks.
</p>
{% include "forms/_field.html" with field=form.confirmation %}
</fieldset>
<div class="buttons">
<a href="{% url "settings" handle=identity.handle %}" class="button secondary left">Cancel</a>
<button class="danger">Delete {{ identity.handle }}</button>
</div>
</form>
{% endblock %}

View file

@ -614,6 +614,23 @@ class Identity(StatorModel):
except cls.DoesNotExist:
pass
### Deletion ###
def mark_deleted(self):
"""
Marks the identity and all of its related content as deleted.
"""
# Move all posts to deleted
from activities.models.post import Post, PostStates
Post.transition_perform_queryset(self.posts, PostStates.deleted)
# Move ourselves to deleted
self.transition_perform(IdentityStates.deleted)
# Remove all users from ourselves and mark deletion date
self.users.set([])
self.deleted = timezone.now()
self.save()
### Actor/Webfinger fetching ###
@classmethod

View file

@ -3,6 +3,7 @@ from django.shortcuts import redirect
from django.utils.decorators import method_decorator
from django.views.generic import View
from users.views.settings.delete import DeleteIdentity # noqa
from users.views.settings.follows import FollowsPage # noqa
from users.views.settings.import_export import ( # noqa
CsvFollowers,

View file

@ -0,0 +1,32 @@
from django import forms
from django.contrib import messages
from django.shortcuts import redirect
from django.views.generic import FormView
from users.views.base import IdentityViewMixin
class DeleteIdentity(IdentityViewMixin, FormView):
template_name = "settings/delete.html"
extra_context = {"section": "delete"}
class form_class(forms.Form):
confirmation = forms.CharField(
help_text="Write the word DELETE in this box if you wish to delete this account",
required=True,
)
def clean_confirmation(self):
value = self.cleaned_data.get("confirmation")
if value.lower() != "delete":
raise forms.ValidationError("You must write DELETE here")
return value
def form_valid(self, form):
self.identity.mark_deleted()
messages.success(
self.request,
f"The identity {self.identity.handle} is now being deleted.",
)
return redirect("/")

View file

@ -33,6 +33,7 @@ class TokenCreate(IdentityViewMixin, FormView):
"""
template_name = "settings/token_create.html"
extra_context = {"section": "tokens"}
class form_class(forms.Form):
name = forms.CharField(help_text="Identifies this app in your app list")