diff --git a/app/controllers/maintenance/user/deletions_controller.rb b/app/controllers/maintenance/user/deletions_controller.rb
deleted file mode 100644
index f029066b6..000000000
--- a/app/controllers/maintenance/user/deletions_controller.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-module Maintenance
- module User
- class DeletionsController < ApplicationController
- respond_to :html, :json, :xml
-
- def show
- end
-
- def destroy
- deletion = UserDeletion.new(user: CurrentUser.user, deleter: CurrentUser.user, password: params.dig(:user, :password), request: request)
- deletion.delete!
-
- if deletion.errors.none?
- session.delete(:user_id)
- flash[:notice] = "Your account has been deactivated"
- respond_with(deletion, location: posts_path)
- else
- flash[:notice] = deletion.errors.full_messages.join("; ")
- redirect_to maintenance_user_deletion_path
- end
- end
- end
- end
-end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 9dc0639f9..6ab1a14c4 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -114,6 +114,32 @@ class UsersController < ApplicationController
end
end
+ def deactivate
+ if params[:id].present?
+ @user = authorize User.find(params[:id])
+ else
+ @user = authorize CurrentUser.user
+ end
+
+ respond_with(@user)
+ end
+
+ def destroy
+ @user = authorize User.find(params[:id])
+
+ user_deletion = UserDeletion.new(user: @user, deleter: CurrentUser.user, password: params.dig(:user, :password), request: request)
+ user_deletion.delete!
+
+ if user_deletion.errors.none?
+ session.delete(:user_id)
+ flash[:notice] = "Your account has been deactivated"
+ respond_with(user_deletion, location: posts_path)
+ else
+ flash[:notice] = user_deletion.errors.full_messages.join("; ")
+ redirect_to deactivate_user_path(@user)
+ end
+ end
+
def custom_style
@custom_css = CurrentUser.user.custom_css
expires_in 10.years
diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb
index 9ad9f1fb1..e8145fbf1 100644
--- a/app/policies/user_policy.rb
+++ b/app/policies/user_policy.rb
@@ -13,6 +13,14 @@ class UserPolicy < ApplicationPolicy
record.id == user.id || user.is_admin?
end
+ def deactivate?
+ (record.id == user.id && !user.is_anonymous?) || user.is_owner?
+ end
+
+ def destroy?
+ deactivate?
+ end
+
def promote?
user.is_moderator?
end
diff --git a/app/views/maintenance/user/deletions/show.html.erb b/app/views/maintenance/user/deletions/show.html.erb
deleted file mode 100644
index 7334839bb..000000000
--- a/app/views/maintenance/user/deletions/show.html.erb
+++ /dev/null
@@ -1,40 +0,0 @@
-<% page_title "Deactivate Account" %>
-
-
-
-
Deactivate Account
-
-
- You can deactivate your <%= Danbooru.config.app_name %> account using
- the form below. Deactivating your account will do the following things:
-
-
-
- - Change your name to a generic name
- - Delete your favorites
- - Delete your saved searches
- - Delete your password and email address
- - Delete your account settings
-
-
-
- The following things will not be deleted:
-
-
-
- - Posts you've uploaded
- - Comments, forum posts, and private messages
- - Tag edits, wiki edits, translation notes, or any other contributions to the site
-
-
-
- Enter your password below to deactivate your account. This cannot be
- undone. Your account cannot be recovered after it is deactivated.
-
-
- <%= edit_form_for(:user, url: maintenance_user_deletion_path, method: :delete) do |f| %>
- <%= f.input :password %>
- <%= f.submit "Deactivate account", "data-confirm": "Are you sure you want to deactivate your account? This cannot be undone" %>
- <% end %>
-
-
diff --git a/app/views/static/privacy_policy.html.erb b/app/views/static/privacy_policy.html.erb
index 6f1e7da32..c62736662 100644
--- a/app/views/static/privacy_policy.html.erb
+++ b/app/views/static/privacy_policy.html.erb
@@ -353,8 +353,8 @@
Summary: You may deactivate your account, but we may
retain your IP address and your public contributions to the Site.
- If you would like to delete your account, you may request your
- account to be deactivated <%= link_to "here", maintenance_user_deletion_path %>.
+ If you wish to to close your <%= @app_name %> account, you may deactivate your account
+ <%= link_to "here", deactivate_users_path %>.
When your account is deactivated, we will delete your non-public personal
information from our active systems, including your email address,
diff --git a/app/views/users/deactivate.html.erb b/app/views/users/deactivate.html.erb
new file mode 100644
index 000000000..3528325ef
--- /dev/null
+++ b/app/views/users/deactivate.html.erb
@@ -0,0 +1,47 @@
+<% page_title "Deactivate Account" %>
+<%= render "secondary_links" %>
+
+
+
+ <% if @user == CurrentUser.user %>
+
Deactivate Account
+ <% else %>
+
Deactivate Account: <%= link_to_user @user %>
+ <% end %>
+
+
+
+ You can deactivate your <%= Danbooru.config.app_name %> account by entering your password below. Deactivating
+ your account will do the following things:
+
+
+
+ - Change your username to a generic username (user_<%= @user.id %>).
+ - Delete your password, email address, and account settings.
+ - Delete your favorites.
+ - Delete your saved searches.
+
+
+
+ The following things will not be deleted:
+
+
+
+ - Posts you've uploaded.
+ - Your comments, forum posts, and private messages.
+ - Your tag edits, wiki edits, translation notes, and any other contributions you've made to the site.
+ - Your login history, including your IP address and geographic location. This is kept for moderation purposes.
+
+
+
+ Enter your password below to deactivate your account. This cannot be
+ undone. Your account cannot be recovered after it is deactivated.
+
+
+
+ <%= edit_form_for(:user, url: user_path(@user), method: :delete) do |f| %>
+ <%= f.input :password %>
+ <%= f.submit "Deactivate account", "data-confirm": "Are you sure you want to deactivate your account? This cannot be undone" %>
+ <% end %>
+
+
diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb
index 33eb21260..875c4b7ab 100644
--- a/app/views/users/edit.html.erb
+++ b/app/views/users/edit.html.erb
@@ -53,7 +53,7 @@
diff --git a/config/routes.rb b/config/routes.rb
index 8ffb5d8e3..f85bc97be 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -50,7 +50,6 @@ Rails.application.routes.draw do
namespace :user do
resource :count_fixes, only: [:new, :create]
resource :email_notification, only: [:show, :create, :destroy]
- resource :deletion, :only => [:show, :destroy]
end
end
@@ -274,6 +273,8 @@ Rails.application.routes.draw do
get :change_name, on: :member, to: "user_name_change_requests#new"
get :custom_style, on: :collection
+ get :deactivate, on: :member # /users/:id/deactivate
+ get :deactivate, on: :collection # /users/deactivate
end
get "/upgrade", to: "user_upgrades#new", as: "new_user_upgrade"
get "/user_upgrades/new", to: redirect("/upgrade")
@@ -354,6 +355,7 @@ Rails.application.routes.draw do
get "/static/contact", to: redirect("/contact")
get "/user_upgrade/new", to: redirect("/upgrade")
get "/delayed_jobs", to: redirect("/jobs")
+ get "/maintenance/user/deletion", to: redirect("/users/deactivate")
get "/mock/recommender/recommend/:user_id" => "mock_services#recommender_recommend", as: "mock_recommender_recommend"
get "/mock/recommender/similiar/:post_id" => "mock_services#recommender_similar", as: "mock_recommender_similar"
diff --git a/test/functional/maintenance/user/deletions_controller_test.rb b/test/functional/maintenance/user/deletions_controller_test.rb
deleted file mode 100644
index 07fab37c3..000000000
--- a/test/functional/maintenance/user/deletions_controller_test.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-require "test_helper"
-
-module Maintenance
- module User
- class DeletionsControllerTest < ActionDispatch::IntegrationTest
- context "in all cases" do
- setup do
- @user = create(:user)
- end
-
- context "#show" do
- should "render" do
- get_auth maintenance_user_deletion_path, @user
- assert_response :success
- end
- end
-
- context "#destroy" do
- should "delete the user when given the correct password" do
- delete_auth maintenance_user_deletion_path, @user, params: { user: { password: "password" }}
-
- assert_redirected_to posts_path
- assert_equal(true, @user.reload.is_deleted?)
- assert_equal("Your account has been deactivated", flash[:notice])
- assert_nil(session[:user_id])
- assert_equal(true, @user.user_events.user_deletion.exists?)
- end
-
- should "not delete the user when given an incorrect password" do
- delete_auth maintenance_user_deletion_path, @user, params: { user: { password: "hunter2" }}
-
- assert_redirected_to maintenance_user_deletion_path
- assert_equal(false, @user.reload.is_deleted?)
- assert_equal("Password is incorrect", flash[:notice])
- assert_equal(@user.id, session[:user_id])
- assert_equal(false, @user.user_events.user_deletion.exists?)
- end
- end
- end
- end
- end
-end
diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb
index 05238427f..df3a3df97 100644
--- a/test/functional/users_controller_test.rb
+++ b/test/functional/users_controller_test.rb
@@ -102,6 +102,82 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
end
end
+ context "#deactivate action" do
+ should "render /users/:id/deactivate for the current user" do
+ get_auth deactivate_user_path(@user), @user
+ assert_response :success
+ end
+
+ should "render /users/:id/deactivate for the Owner user" do
+ get_auth deactivate_user_path(@user), create(:owner)
+ assert_response :success
+ end
+
+ should "not render /users/:id/deactivate for a different user" do
+ get_auth deactivate_user_path(@user), create(:user)
+ assert_response 403
+ end
+
+ should "render /users/deactivate for a logged-in user" do
+ get_auth deactivate_users_path, @user
+ assert_response :success
+ end
+
+ should "not render /users/deactivate for a logged-out user" do
+ get deactivate_users_path
+ assert_response 403
+ end
+
+ should "redirect /maintenance/user/deletion to /users/deactivate" do
+ get "/maintenance/user/deletion"
+ assert_redirected_to deactivate_users_path
+ end
+ end
+
+ context "#destroy action" do
+ should "delete the user when given the correct password" do
+ delete_auth user_path(@user), @user, params: { user: { password: "password" }}
+
+ assert_redirected_to posts_path
+ assert_equal(true, @user.reload.is_deleted?)
+ assert_equal("Your account has been deactivated", flash[:notice])
+ assert_nil(session[:user_id])
+ assert_equal(true, @user.user_events.user_deletion.exists?)
+ end
+
+ should "not delete the user when given an incorrect password" do
+ delete_auth user_path(@user), @user, params: { user: { password: "hunter2" }}
+
+ assert_redirected_to deactivate_user_path(@user)
+ assert_equal(false, @user.reload.is_deleted?)
+ assert_equal("Password is incorrect", flash[:notice])
+ assert_equal(@user.id, session[:user_id])
+ assert_equal(false, @user.user_events.user_deletion.exists?)
+ end
+
+ should "allow the Owner to delete other users" do
+ delete_auth user_path(@user), create(:owner)
+
+ assert_redirected_to posts_path
+ assert_equal(true, @user.reload.is_deleted?)
+ assert_equal("Your account has been deactivated", flash[:notice])
+ assert_nil(session[:user_id])
+ assert_equal(true, @user.user_events.user_deletion.exists?)
+ end
+
+ should "not allow users to delete other users" do
+ delete_auth user_path(@user), create(:user), params: { user: { password: "password" }}
+
+ assert_response 403
+ end
+
+ should "not allow logged-out users to delete other users" do
+ delete user_path(@user), params: { user: { password: "password" }}
+
+ assert_response 403
+ end
+ end
+
context "custom_style action" do
should "work" do
@user.update!(custom_style: "span { color: red; }")