add account deletion

This commit is contained in:
r888888888
2013-05-16 15:15:00 -07:00
parent 7db85d8301
commit 0a9e2a39b0
6 changed files with 196 additions and 2 deletions

View File

@@ -1,10 +1,18 @@
module Maintenance
module User
class DeletionsController < ApplicationController
rescue_from UserDeletion::ValidationError, :with => :rescue_exception
def show
end
def destroy
deletion = UserDeletion.new(CurrentUser.user, params[:password])
deletion.delete!
session.delete(:user_id)
cookies.delete(:cookie_password_hash)
cookies.delete(:user_name)
redirect_to(posts_path, :notice => "You are now logged out")
end
end
end

View File

@@ -0,0 +1,71 @@
class UserDeletion
class ValidationError < Exception ; end
attr_reader :user, :password
def initialize(user, password)
@user = user
@password = password
end
def delete!
validate
clear_user_settings
remove_favorites
rename
reset_password
end
private
def clear_user_settings
user.email = nil
user.last_logged_in_at = nil
user.last_forum_read_at = nil
user.recent_tags = nil
user.favorite_tags = nil
user.blacklisted_tags = nil
user.hide_deleted_posts = false
user.time_zone = "Eastern Time (US & Canada)"
user.save!
end
def reset_password
random = SecureRandom.hex(16)
user.password = random
user.password_confirmation = random
user.old_password = password
user.save!
end
def remove_favorites
Post.tag_match("fav:#{user.name}").find_each do |post|
Favorite.remove(post, user)
end
end
def rename
name = "user_#{user.id}"
n = 0
while User.where(:name => name).exists? && (n < 10)
name += "~"
end
if n == 10
raise ValidationError.new("New name could not be found")
end
user.name = name
user.save!
end
def validate
if !User.authenticate(user.name, password)
raise ValidationError.new("Password is incorrect")
end
if user.level >= User::Levels::ADMIN
raise ValidationError.new("Admins cannot delete their account")
end
end
end

View File

@@ -6,7 +6,18 @@
<li>Rename your account to a generic string</li>
<li>Scramble your password</li>
<li>Remove all your favorites</li>
<li>Blank out your settings (including email)</li>
</ul>
<p>You must enter your password to delete your account.</p>
<%= form_tag(maintenance_user_deletion_path, :method => :delete, :class => "simple_form") do %>
<div class="input">
<label>Password</label>
<%= password_field_tag :password %>
</div>
<div class="input">
<%= submit_tag %>
</div>
<% end %>

View File

@@ -25,8 +25,6 @@
<%= f.input :per_page, :label => "Posts per page", :as => :select, :collection => (1..100), :include_blank => false %>
<% end %>
<%= f.input :style_usernames, :as => :select, :label => "Colored usernames", :hint => "Color each user's name depending on their rank", :include_blank => false, :collection => [["Yes", "true"], ["No", "false"]] %>
<%= f.input :blacklisted_tags, :hint => "Put any tag combinations you never want to see here. Each combination should go on a separate line.", :input_html => {:size => "40x5"} %>
<div class="input text optional field_with_hint">
<label class="text optional" for="user_favorite_tags">Frequent tags</label>
@@ -37,6 +35,7 @@
<fieldset>
<legend>Advanced Settings</legend>
<%= f.input :style_usernames, :as => :select, :label => "Colored usernames", :hint => "Color each user's name depending on their rank", :include_blank => false, :collection => [["Yes", "true"], ["No", "false"]] %>
<%= f.input :always_resize_images, :as => :select, :include_blank => false, :label => "Fit images to window", :hint => "Use JavaScript to resize images to fit window" %>
<%= f.input :enable_post_navigation, :as => :select, :include_blank => false, :label => "Enable keyboard shortcuts" %>
<%= f.input :new_post_navigation_layout, :as => :select, :label => "Pool links", :include_blank => false, :collection => [["Bottom", "true"], ["Top", "false"]], :hint => "When browsing pools, where do you want the navigation links to be placed?" %>
@@ -50,6 +49,11 @@
<%= f.input :old_password, :as => :password, :input_html => {:autocomplete => "off"} %>
</fieldset>
<fieldset>
<legend>Delete Account</legend>
<p><%= link_to "Click here to delete your account", maintenance_user_deletion_path %></p>
</fieldset>
<%= f.button :submit, "Submit" %>
<% end %>
</div>

View File

@@ -0,0 +1,29 @@
require "test_helper"
module Maintenance
module User
class DeletionsControllerTest < ActionController::TestCase
context "in all cases" do
setup do
@user = FactoryGirl.create(:user)
CurrentUser.user = @user
CurrentUser.ip_addr = "127.0.0.1"
end
context "#show" do
should "render" do
get :show, {}, {:user_id => @user.id}
assert_response :success
end
end
context "#destroy" do
should "render" do
post :destroy, {:password => "password"}, {:user_id => @user.id}
assert_redirected_to(posts_path)
end
end
end
end
end
end

View File

@@ -0,0 +1,71 @@
require 'test_helper'
class UserDeletionTest < ActiveSupport::TestCase
context "an invalid user deletion" do
context "for an invalid password" do
setup do
@user = FactoryGirl.create(:user)
CurrentUser.user = @user
CurrentUser.ip_addr = "127.0.0.1"
@deletion = UserDeletion.new(@user, "wrongpassword")
end
should "fail" do
assert_raise(UserDeletion::ValidationError) do
@deletion.delete!
end
end
end
context "for an admin" do
setup do
@user = FactoryGirl.create(:admin_user)
CurrentUser.user = @user
CurrentUser.ip_addr = "127.0.0.1"
@deletion = UserDeletion.new(@user, "password")
end
should "fail" do
assert_raise(UserDeletion::ValidationError) do
@deletion.delete!
end
end
end
end
context "a valid user deletion" do
setup do
@user = FactoryGirl.create(:user)
CurrentUser.user = @user
CurrentUser.ip_addr = "127.0.0.1"
@post = FactoryGirl.create(:post)
Favorite.add(@post, @user)
@user.update_attributes(:email => "ted@danbooru.com")
@deletion = UserDeletion.new(@user, "password")
@deletion.delete!
@user.reload
end
should "blank out the email" do
assert_nil(@user.email)
end
should "rename the user" do
assert_equal("user_#{@user.id}", @user.name)
end
should "reset the password" do
assert_nil(User.authenticate(@user.name, "password"))
end
should "remove any favorites" do
@post.reload
assert_equal(0, Favorite.count)
assert_equal("", @post.fav_string)
assert_equal(0, @post.fav_count)
end
end
end