Skip to content

Commit b3be377

Browse files
authored
Merge pull request #1668 from codidact/art/self-serve-deletion
Self-serve account deletion
2 parents 7faaf4d + 42a7b9c commit b3be377

13 files changed

Lines changed: 280 additions & 7 deletions

File tree

app/controllers/application_controller.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,4 +406,12 @@ def storable_location?
406406
def store_user_location!
407407
store_location_for(:user, request.fullpath)
408408
end
409+
410+
def require_sudo
411+
unless user_signed_in? && session[:sudo].present? &&
412+
DateTime.iso8601(session[:sudo]) >= AppConfig.server_settings['user_sudo_duration'].minutes.ago
413+
session[:sudo_return] = request.fullpath
414+
redirect_to user_sudo_path
415+
end
416+
end
409417
end

app/controllers/sudo_controller.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class SudoController < ApplicationController
2+
before_action :authenticate_user!
3+
4+
def sudo; end
5+
6+
def enter_sudo
7+
if current_user.valid_password? params[:password]
8+
session[:sudo] = DateTime.now.iso8601
9+
redirect_to session[:sudo_return]
10+
else
11+
flash[:danger] = 'The password you entered was incorrect.'
12+
render :sudo
13+
end
14+
end
15+
end

app/controllers/users/registrations_controller.rb

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
class Users::RegistrationsController < Devise::RegistrationsController
2+
layout 'without_sidebar', only: :edit
3+
4+
before_action :check_sso, only: :update
5+
before_action :authenticate_user!, only: [:delete, :do_delete]
6+
before_action :require_sudo, only: [:delete, :do_delete]
7+
28
def create
39
super do |user|
410
unless user.errors.any?
@@ -19,11 +25,29 @@ def create
1925
end
2026
end
2127

22-
protected
28+
def delete
29+
@user = current_user
30+
end
2331

24-
layout 'without_sidebar', only: :edit
32+
def do_delete
33+
@user = current_user
34+
if @user.admin?
35+
@user.errors.add(:base, I18n.t('users.errors.no_admin_self_delete'))
36+
render :delete
37+
elsif @user.moderator?
38+
@user.errors.add(:base, I18n.t('users.errors.no_mod_self_delete'))
39+
render :delete
40+
elsif params[:username] != @user.username
41+
@user.errors.add(:base, I18n.t('users.errors.self_delete_wrong_username'))
42+
render :delete
43+
else
44+
@user.do_soft_delete(@user)
45+
flash[:info] = 'Sorry to see you go!'
46+
redirect_to root_path
47+
end
48+
end
2549

26-
before_action :check_sso, only: :update
50+
protected
2751

2852
def after_update_path_for(resource)
2953
edit_user_registration_path(resource)

app/helpers/sudo_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
module SudoHelper
2+
end

app/views/devise/registrations/edit.html.erb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,16 @@
5858

5959
<%= f.submit "Update", class: 'button is-filled is-very-large', disabled: sso %>
6060
<% end %><br/>
61+
62+
<% if current_user.at_least_moderator? %>
63+
<%= link_to 'javascript:void(0)', class: 'button is-outlined is-danger', disabled: true do %>
64+
Delete my account &raquo;
65+
<% end %>
66+
<p class="has-color-red has-font-size-caption">
67+
Moderators and admins cannot be self-deleted. Contact support if you wish to delete your account.
68+
</p>
69+
<% else %>
70+
<%= link_to delete_account_path, class: 'button is-outlined is-danger' do %>
71+
Delete my account &raquo;
72+
<% end %>
73+
<% end %>

app/views/sudo/sudo.html.erb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<h1>Re-enter your password</h1>
2+
3+
<div class="notice is-info has-font-size-caption has-color-teal-900 flex-row-always jc-sb ai-c">
4+
<i class="fas fa-info-circle"></i>
5+
<p>
6+
You are entering <strong>sudo mode</strong>, where you are required to verify your password to take certain
7+
security-sensitive actions. This mode will last for <%= AppConfig.server_settings['user_sudo_duration'] %>
8+
minutes, during which time you will not be asked for your password again.
9+
</p>
10+
</div>
11+
12+
<%= form_tag enter_sudo_path, method: :post do %>
13+
<%= label_tag :password, 'Re-enter your password', class: 'form-element' %>
14+
<%= password_field_tag :password, nil, class: 'form-element' %>
15+
<%= submit_tag 'Verify', class: 'button is-primary is-filled' %>
16+
<% end %>

app/views/users/_deleted.html.erb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
<p class="has-font-size-caption">
1212
<%= deletion_type.capitalize %> deleted
1313
<span title="<%= deleted_object.deleted_at %>"><%= time_ago_in_words(deleted_object.deleted_at) %> ago</span>
14-
by <%= link_to deleted_object.deleted_by.username, user_path(deleted_object.deleted_by) %>.
14+
<% if deleted_object.deleted_by == user %>
15+
(self-deleted).
16+
<% else %>
17+
by <%= link_to deleted_object.deleted_by.username, user_path(deleted_object.deleted_by) %>.
18+
<% end %>
1519
</p>
1620
</div>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<h1 class="has-color-red">Delete my account</h1>
2+
<p>
3+
If you no longer want to use our network of communities, you can delete your account. This means:
4+
</p>
5+
<ul>
6+
<li>Your profiles will be deleted on <strong>every community</strong> in the network.
7+
<li>Your user account will be deleted and anonymized.</li>
8+
<li>
9+
The content of your posts and comments will remain, under the licenses you set for them. Your username will no
10+
longer be shown alongside them.
11+
</li>
12+
</ul>
13+
14+
<div class="notice is-danger has-color-red-900 flex-row-always jc-sb ai-c">
15+
<i class="fas fa-exclamation-triangle"></i>
16+
<p>
17+
This will take effect immediately and <strong>cannot be undone</strong>. If you're sure, type your username below to
18+
confirm.
19+
</p>
20+
</div>
21+
22+
<% if @user.errors.any? %>
23+
<div class="notice is-danger has-color-red-900">
24+
<p>Couldn't delete your account:</p>
25+
<ul>
26+
<% @user.errors.full_messages.each do |msg| %>
27+
<li><%= msg %></li>
28+
<% end %>
29+
</ul>
30+
</div>
31+
<% end %>
32+
33+
<%= form_tag do_delete_account_path, method: :post do %>
34+
<%= label_tag :username, 'Type your username', class: 'form-element' %>
35+
<%= text_field_tag :username, params[:username], class: 'form-element' %>
36+
37+
<%= submit_tag 'Delete my account', class: 'button is-danger is-filled' %>
38+
<% end %>

config/config/server_settings.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
registration_rate_limit: 300
2+
user_sudo_duration: 30
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
en:
2+
users:
3+
errors:
4+
no_admin_self_delete: >
5+
Admin accounts cannot be self-deleted. Contact support.
6+
no_mod_self_delete: >
7+
Moderator accounts cannot be self-deleted. Contact support.
8+
self_delete_wrong_username: >
9+
The username you entered was incorrect.

0 commit comments

Comments
 (0)