user deletions: fix error when given incorrect password.
Use validations instead of raising an exception when the password is incorrect so that the controller can display errors sensibly. Also fix users being logged out even when the deletion attempt failed due to an incorrect password.
This commit is contained in:
@@ -1,14 +1,23 @@
|
|||||||
module Maintenance
|
module Maintenance
|
||||||
module User
|
module User
|
||||||
class DeletionsController < ApplicationController
|
class DeletionsController < ApplicationController
|
||||||
|
respond_to :html, :json, :xml
|
||||||
|
|
||||||
def show
|
def show
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
deletion = UserDeletion.new(CurrentUser.user, params.dig(:user, :password))
|
deletion = UserDeletion.new(CurrentUser.user, params.dig(:user, :password))
|
||||||
deletion.delete!
|
deletion.delete!
|
||||||
session.delete(:user_id)
|
|
||||||
redirect_to(posts_path, :notice => "You are now logged out")
|
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
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
class UserDeletion
|
class UserDeletion
|
||||||
class ValidationError < StandardError; end
|
include ActiveModel::Validations
|
||||||
|
|
||||||
attr_reader :user, :password
|
attr_reader :user, :password
|
||||||
|
validate :validate_deletion
|
||||||
|
|
||||||
def initialize(user, password)
|
def initialize(user, password)
|
||||||
@user = user
|
@user = user
|
||||||
@@ -9,13 +10,14 @@ class UserDeletion
|
|||||||
end
|
end
|
||||||
|
|
||||||
def delete!
|
def delete!
|
||||||
validate
|
return false if invalid?
|
||||||
clear_user_settings
|
clear_user_settings
|
||||||
remove_favorites
|
remove_favorites
|
||||||
clear_saved_searches
|
clear_saved_searches
|
||||||
rename
|
rename
|
||||||
reset_password
|
reset_password
|
||||||
create_mod_action
|
create_mod_action
|
||||||
|
user
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -56,13 +58,13 @@ class UserDeletion
|
|||||||
request.save!(validate: false) # XXX don't validate so that the 1 name change per week rule doesn't interfere
|
request.save!(validate: false) # XXX don't validate so that the 1 name change per week rule doesn't interfere
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate
|
def validate_deletion
|
||||||
if !user.authenticate_password(password)
|
if !user.authenticate_password(password)
|
||||||
raise ValidationError.new("Password is incorrect")
|
errors[:base] << "Password is incorrect"
|
||||||
end
|
end
|
||||||
|
|
||||||
if user.level >= User::Levels::ADMIN
|
if user.level >= User::Levels::ADMIN
|
||||||
raise ValidationError.new("Admins cannot delete their account")
|
errors[:base] << "Admins cannot delete their account"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,9 +16,20 @@ module Maintenance
|
|||||||
end
|
end
|
||||||
|
|
||||||
context "#destroy" do
|
context "#destroy" do
|
||||||
should "render" do
|
should "delete the user when given the correct password" do
|
||||||
delete_auth maintenance_user_deletion_path, @user, params: {:password => "password"}
|
delete_auth maintenance_user_deletion_path, @user, params: { user: { password: "password" }}
|
||||||
assert_redirected_to(posts_path)
|
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])
|
||||||
|
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])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,10 +6,8 @@ class UserDeletionTest < ActiveSupport::TestCase
|
|||||||
should "fail" do
|
should "fail" do
|
||||||
@user = create(:user)
|
@user = create(:user)
|
||||||
@deletion = UserDeletion.new(@user, "wrongpassword")
|
@deletion = UserDeletion.new(@user, "wrongpassword")
|
||||||
|
@deletion.delete!
|
||||||
assert_raise(UserDeletion::ValidationError) do
|
assert_includes(@deletion.errors[:base], "Password is incorrect")
|
||||||
@deletion.delete!
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -17,10 +15,8 @@ class UserDeletionTest < ActiveSupport::TestCase
|
|||||||
should "fail" do
|
should "fail" do
|
||||||
@user = create(:admin_user)
|
@user = create(:admin_user)
|
||||||
@deletion = UserDeletion.new(@user, "password")
|
@deletion = UserDeletion.new(@user, "password")
|
||||||
|
@deletion.delete!
|
||||||
assert_raise(UserDeletion::ValidationError) do
|
assert_includes(@deletion.errors[:base], "Admins cannot delete their account")
|
||||||
@deletion.delete!
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user