allow users to delete their own accounts

not much can actually be deleted, but it can be put into a deleted
state
This commit is contained in:
joshua stein 2014-01-13 10:12:17 -06:00
parent 1ef58d6496
commit e12d91cd43
13 changed files with 124 additions and 30 deletions

View file

@ -507,12 +507,12 @@ li .byline a {
color: #888;
text-decoration: none;
}
.new_user,
span.new_user, a.new_user,
li .byline a.new_user {
color: green;
}
.banned_user,
li .byline a.banned_user {
span.inactive_user, a.inactive_user,
li .byline a.inactive_user {
color: gray;
text-decoration: line-through;
}

View file

@ -10,7 +10,7 @@ class ApplicationController < ActionController::Base
def authenticate_user
if session[:u] &&
(user = User.where(:session_token => session[:u].to_s).first) &&
!user.is_banned?
user.is_active?
@user = user
Rails.logger.info " Logged in as user #{@user.id} (#{@user.username})"
end

View file

@ -21,7 +21,7 @@ class LoginController < ApplicationController
user = User.where(:username => params[:email]).first
end
if user && !user.is_banned? &&
if user && user.is_active? &&
user.try(:authenticate, params[:password].to_s)
session[:u] = user.session_token
return redirect_to "/"
@ -70,7 +70,7 @@ class LoginController < ApplicationController
# this will get reset upon save
@reset_user.session_token = nil
if @reset_user.save && !@reset_user.is_banned?
if @reset_user.save && @reset_user.is_active?
session[:u] = @reset_user.session_token
return redirect_to "/"
end

View file

@ -7,6 +7,18 @@ class SettingsController < ApplicationController
@edit_user = @user.dup
end
def delete_account
if @user.try(:authenticate, params[:user][:password].to_s)
@user.delete!
reset_session
flash[:success] = "Your account has been deleted."
return redirect_to "/"
end
flash[:error] = "Your password could not be verified."
return redirect_to settings_url
end
def update
@edit_user = @user.clone

View file

@ -2,10 +2,11 @@ class StoriesController < ApplicationController
before_filter :require_logged_in_user_or_400,
:only => [ :upvote, :downvote, :unvote, :preview ]
before_filter :require_logged_in_user, :only => [ :delete, :create, :edit,
before_filter :require_logged_in_user, :only => [ :destroy, :create, :edit,
:fetch_url_title, :new ]
before_filter :find_user_story, :only => [ :destroy, :edit, :undelete, :update ]
before_filter :find_user_story, :only => [ :destroy, :edit, :undelete,
:update ]
def create
@title = "Submit Story"

View file

@ -18,6 +18,7 @@ class User < ActiveRecord::Base
:class_name => "User"
belongs_to :banned_by_user,
:class_name => "User"
has_many :invitations
has_secure_password
@ -38,7 +39,7 @@ class User < ActiveRecord::Base
attr_accessible :username, :email, :password, :password_confirmation,
:about, :email_replies, :pushover_replies, :pushover_user_key,
:pushover_device, :email_messages, :pushover_messages, :email_mentions,
:pushover_mentions, :mailing_list_enabled
:pushover_mentions, :mailing_list_enabled, :delete_me
before_save :check_session_token
before_validation :on => :create do
@ -80,10 +81,7 @@ class User < ActiveRecord::Base
self.banned_by_user_id = banner.id
self.banned_reason = reason
self.session_token = nil
self.check_session_token
self.save!
self.delete!
BanNotification.notify(self, banner, reason)
@ -124,6 +122,29 @@ class User < ActiveRecord::Base
Keystore.value_for("user:#{self.id}:comments_posted").to_i
end
def delete!
User.transaction do
self.comments.each{|c| c.delete_for_user(self) }
self.sent_messages.each do |m|
m.deleted_by_author = true
m.save
end
self.received_messages.each do |m|
m.deleted_by_recipient = true
m.save
end
self.invitations.destroy_all
self.session_token = nil
self.check_session_token
self.deleted_at = Time.now
self.save!
end
end
def initiate_password_reset_for_ip(ip)
self.password_reset_token = Utils.random_str(40)
self.save!
@ -131,6 +152,10 @@ class User < ActiveRecord::Base
PasswordReset.password_reset_link(self, ip).deliver
end
def is_active?
!(deleted_at? || is_banned?)
end
def is_banned?
banned_at?
end

View file

@ -29,8 +29,8 @@ class="comment <%= comment.current_vote ? (comment.current_vote[:vote] == 1 ?
just now
<% else %>
<a href="/u/<%= comment.user.username %>"
<% if comment.user.is_banned? %>
class="banned_user"
<% if !comment.user.is_active? %>
class="inactive_user"
<% elsif comment.user.is_new? %>
class="new_user"
<% end %>

View file

@ -165,6 +165,32 @@
<br>
<br>
<%= form_for @edit_user, :url => delete_account_url, :method => :post do |f| %>
<div class="legend">
Delete Account
</div>
<p>
To permanently delete your account, verify your current password below.
Your account will be put into a deleted state, your comments will be marked
as deleted and no longer readable by any other users, and your private
messages will be deleted. Your submitted stories will not be deleted.
Your username will remain reserved and will not be available to use on any
other account.
</p>
<div class="boxline">
<%= f.label :password, "Verify Password:", :class => "required" %>
<%= f.password_field :password, :size => 40, :autocomplete => "off" %>
</div>
<br>
<%= f.submit "Yes, Delete My Account" %>
<% end %>
<br>
<br>
<a name="invite"></a>
<div class="legend">
Invite a New User

View file

@ -1,19 +1,31 @@
<div class="box wide">
<div class="legend">
<%= @showing_user.username %>
<% if !@showing_user.is_active? %>
<span class="inactive_user">
<% elsif @showing_user.is_new? %>
<span class="new_user">
<% else %>
<span>
<% end %>
<%= @showing_user.username %>
</span>
<% if @user %>
(<a href="/messages?to=<%= @showing_user.username %>">Send a Message</a>)
<% end %>
</div>
<div id="gravatar">
<img src="<%= @showing_user.avatar_url %>">
</div>
<% if @showing_user.is_active? %>
<div id="gravatar">
<img src="<%= @showing_user.avatar_url %>">
</div>
<% end %>
<label class="required">Status:</label>
<span class="d"
<%= @showing_user.is_banned? ? raw("style=\"color: red;\"") : "" %>>
<% if @showing_user.is_banned? %>
Banned
<% elsif !@showing_user.is_active? %>
Inactive
<% else %>
Active
@ -47,6 +59,14 @@
<br>
<% end %>
<% if @showing_user.deleted_at? %>
<label class="required">Left:</label>
<span class="d">
<%= raw(time_ago_in_words_label(@showing_user.deleted_at)) %> ago
</span>
<br>
<% end %>
<label class="required">Karma:</label>
<span class="d">
<%= @showing_user.karma %>, averaging <%=
@ -75,13 +95,15 @@
</span>
<br>
<label class="required">About:</label>
<% if @showing_user.is_active? %>
<label class="required">About:</label>
<div id="user_about" class="shorten_first_p">
<% if @showing_user.about.present? %>
<%= raw @showing_user.linkified_about %>
<% else %>
<span class="na">A mystery...</span>
<% end %>
</div>
<div id="user_about" class="shorten_first_p">
<% if @showing_user.about.present? %>
<%= raw @showing_user.linkified_about %>
<% else %>
<span class="na">A mystery...</span>
<% end %>
</div>
<% end %>
</div>

View file

@ -10,8 +10,8 @@
<% if (user = subtree.pop) %>
<li>
<a href="/u/<%= user.username %>"
<% if user.is_banned? %>
class="banned_user"
<% if !user.is_active? %>
class="inactive_user"
<% elsif user.is_new? %>
class="new_user"
<% end %>

View file

@ -72,6 +72,8 @@ Lobsters::Application.routes.draw do
get "/settings" => "settings#index"
post "/settings" => "settings#update"
post "/settings/delete_account" => "settings#delete_account",
:as => "delete_account"
get "/filters" => "filters#index"
post "/filters" => "filters#update"

View file

@ -0,0 +1,5 @@
class AddAccountDeletion < ActiveRecord::Migration
def change
add_column :users, :deleted_at, :datetime
end
end

View file

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20140112192936) do
ActiveRecord::Schema.define(version: 20140113153413) do
create_table "comments", force: true do |t|
t.datetime "created_at", null: false
@ -161,6 +161,7 @@ ActiveRecord::Schema.define(version: 20140112192936) do
t.datetime "banned_at"
t.integer "banned_by_user_id"
t.string "banned_reason", limit: 200
t.datetime "deleted_at"
end
add_index "users", ["mailing_list_enabled"], name: "mailing_list_enabled", using: :btree