change close account to clear profile, still need to dispatch account deletion xml
This commit is contained in:
parent
7667029e71
commit
0bd101dca9
16 changed files with 204 additions and 55 deletions
|
|
@ -82,7 +82,7 @@ class UsersController < ApplicationController
|
|||
def destroy
|
||||
if params[:user] && params[:user][:current_password] && current_user.valid_password?(params[:user][:current_password])
|
||||
Resque.enqueue(Jobs::DeleteAccount, current_user.id)
|
||||
current_user.lock_access!
|
||||
current_user.close_account!
|
||||
sign_out current_user
|
||||
flash[:notice] = I18n.t 'users.destroy.success'
|
||||
redirect_to multi_path
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ class AccountDeleter
|
|||
|
||||
attr_accessor :person, :user
|
||||
|
||||
def initialize(diaspora_id)
|
||||
self.person = Person.where(:diaspora_handle => diaspora_id).first
|
||||
def initialize(diaspora_handle)
|
||||
self.person = Person.where(:diaspora_handle => diaspora_handle).first
|
||||
self.user = self.person.owner
|
||||
end
|
||||
|
||||
|
|
@ -90,11 +90,12 @@ class AccountDeleter
|
|||
end
|
||||
|
||||
def tombstone_person_and_profile
|
||||
self.person.close_account!
|
||||
self.person.lock_access!
|
||||
self.person.clear_profile!
|
||||
end
|
||||
|
||||
def tombstone_user
|
||||
self.user.close_account!
|
||||
self.user.clear_account!
|
||||
end
|
||||
|
||||
def delete_contacts_of_me
|
||||
|
|
|
|||
|
|
@ -3,5 +3,44 @@
|
|||
# the COPYRIGHT file.
|
||||
|
||||
class AccountDeletion < ActiveRecord::Base
|
||||
include ROXML
|
||||
include Diaspora::Webhooks
|
||||
|
||||
|
||||
belongs_to :person
|
||||
after_create :queue_delete_account
|
||||
|
||||
attr_accessible :person
|
||||
|
||||
xml_attr :diaspora_handle
|
||||
|
||||
|
||||
def person=(person)
|
||||
self[:diaspora_handle] = person.diaspora_handle
|
||||
self[:person_id] = person.id
|
||||
end
|
||||
|
||||
def diaspora_handle=(diaspora_handle)
|
||||
self[:diaspora_handle] = diaspora_handle
|
||||
self[:person_id] ||= Person.find_by_diaspora_handle(diaspora_handle).id
|
||||
end
|
||||
|
||||
|
||||
|
||||
def queue_delete_account
|
||||
Resque.enqueue(Jobs::DeleteAccount, self.id)
|
||||
end
|
||||
|
||||
def perform!
|
||||
AccountDeleter.new(self.diaspora_handle).perform!
|
||||
self.dispatch if person.local?
|
||||
end
|
||||
|
||||
def subscribers(user)
|
||||
person.owner.contact_people | Person.who_have_reshared_a_users_posts(person.owner)
|
||||
end
|
||||
|
||||
def dispatch
|
||||
Postzord::Dispatcher.build(person.owner, self).post
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
module Jobs
|
||||
class DeleteAccount < Base
|
||||
@queue = :delete_account
|
||||
def self.perform(user_id)
|
||||
user = User.find(user_id)
|
||||
AccountDeleter.new(user.person.diaspora_handle).perform!
|
||||
def self.perform(account_deletion_id)
|
||||
account_deletion = AccountDeletion.find(account_deletion_id)
|
||||
account_deletion.perform!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -61,6 +61,10 @@ class Person < ActiveRecord::Base
|
|||
|
||||
scope :profile_tagged_with, lambda{|tag_name| joins(:profile => :tags).where(:profile => {:tags => {:name => tag_name}}).where('profiles.searchable IS TRUE') }
|
||||
|
||||
scope :who_have_reshared_a_users_posts, lambda{|user|
|
||||
joins(:posts).where(:posts => {:root_guid => StatusMessage.guids_for_author(user.person), :type => 'Reshare'} )
|
||||
}
|
||||
|
||||
def self.community_spotlight
|
||||
AppConfig[:community_spotlight].present? ? Person.where(:diaspora_handle => AppConfig[:community_spotlight]) : []
|
||||
end
|
||||
|
|
@ -285,10 +289,13 @@ class Person < ActiveRecord::Base
|
|||
self.update_attributes(:url => newuri)
|
||||
end
|
||||
|
||||
def close_account!
|
||||
self.profile.tombstone!
|
||||
def lock_access!
|
||||
self.closed_account = true
|
||||
self.save
|
||||
end
|
||||
|
||||
def clear_profile!
|
||||
self.profile.tombstone!
|
||||
self
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ class StatusMessage < Post
|
|||
joins(:likes).where(:likes => {:author_id => person.id})
|
||||
}
|
||||
|
||||
def self.guids_for_author(person)
|
||||
Post.connection.select_values(Post.where(:author_id => person.id).select('posts.guid').to_sql)
|
||||
end
|
||||
|
||||
def self.user_tag_stream(user, tag_ids)
|
||||
owned_or_visible_by_user(user).
|
||||
tag_stream(tag_ids)
|
||||
|
|
|
|||
|
|
@ -490,6 +490,12 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def close_account!
|
||||
AccountDeletion.create(:person => self.person)
|
||||
self.person.lock_access!
|
||||
self.lock_access!
|
||||
end
|
||||
|
||||
def clear_account!
|
||||
clearable_fields.each do |field|
|
||||
self[field] = nil
|
||||
end
|
||||
|
|
@ -502,6 +508,6 @@ class User < ActiveRecord::Base
|
|||
|
||||
private
|
||||
def clearable_fields
|
||||
self.attributes.keys - ["id", "username", "encrypted_password", "created_at", "updated_at"]
|
||||
self.attributes.keys - ["id", "username", "encrypted_password", "created_at", "updated_at", "locked_at"]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
class CreateAccountDeletions < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :account_deletions do |t|
|
||||
t.string :diaspora_id
|
||||
t.string :diaspora_handle
|
||||
t.integer :person_id
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@
|
|||
|
||||
ActiveRecord::Schema.define(:version => 20111109023618) do
|
||||
|
||||
create_table "account_deletion", :force => true do |t|
|
||||
t.string "diaspora_id"
|
||||
create_table "account_deletions", :force => true do |t|
|
||||
t.string "diaspora_handle"
|
||||
t.integer "person_id"
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ describe UsersController do
|
|||
@aspect = @user.aspects.first
|
||||
@aspect1 = @user.aspects.create(:name => "super!!")
|
||||
sign_in :user, @user
|
||||
@controller.stub(:current_user).and_return(@user)
|
||||
end
|
||||
|
||||
describe '#export' do
|
||||
|
|
@ -192,15 +193,16 @@ describe UsersController do
|
|||
delete :destroy, :user => { :current_password => "stuff" }
|
||||
end
|
||||
|
||||
it 'closes the account' do
|
||||
alice.should_receive(:close_account!)
|
||||
delete :destroy, :user => { :current_password => "bluepin7" }
|
||||
end
|
||||
|
||||
it 'enqueues a delete job' do
|
||||
Resque.should_receive(:enqueue).with(Jobs::DeleteAccount, alice.id)
|
||||
delete :destroy, :user => { :current_password => "bluepin7" }
|
||||
end
|
||||
|
||||
it 'locks the user out' do
|
||||
delete :destroy, :user => { :current_password => "bluepin7" }
|
||||
alice.reload.access_locked?.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe '#confirm_email' do
|
||||
|
|
|
|||
|
|
@ -123,8 +123,13 @@ describe AccountDeleter do
|
|||
end
|
||||
|
||||
describe '#tombstone_person_and_profile' do
|
||||
it 'calls close_account! on person' do
|
||||
@account_deletion.person.should_receive(:close_account!)
|
||||
it 'calls clear_profile! on person' do
|
||||
@account_deletion.person.should_receive(:clear_profile!)
|
||||
@account_deletion.tombstone_person_and_profile
|
||||
end
|
||||
|
||||
it 'calls lock_access! on person' do
|
||||
@account_deletion.person.should_receive(:lock_access!)
|
||||
@account_deletion.tombstone_person_and_profile
|
||||
end
|
||||
end
|
||||
|
|
@ -160,7 +165,7 @@ describe AccountDeleter do
|
|||
|
||||
describe "#tombstone_user" do
|
||||
it 'calls strip_model on user' do
|
||||
bob.should_receive(:close_account!)
|
||||
bob.should_receive(:clear_account!)
|
||||
@account_deletion.tombstone_user
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,10 +5,74 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe AccountDeletion do
|
||||
|
||||
it 'gets initialized with diaspora_id' do
|
||||
AccountDeletion.new(:diaspora_id => alice.person.diaspora_handle).should be_true
|
||||
it 'assigns the diaspora_handle from the person object' do
|
||||
a = AccountDeletion.new(:person => alice.person)
|
||||
a.diaspora_handle.should == alice.person.diaspora_handle
|
||||
end
|
||||
|
||||
|
||||
it 'fires a resque job after creation'do
|
||||
Resque.should_receive(:enqueue).with(Jobs::DeleteAccount, anything)
|
||||
|
||||
AccountDeletion.create(:person => alice.person)
|
||||
end
|
||||
|
||||
describe "#perform!" do
|
||||
before do
|
||||
@ad = AccountDeletion.new(:person => alice.person)
|
||||
end
|
||||
|
||||
it 'creates a deleter' do
|
||||
AccountDeleter.should_receive(:new).with(alice.person.diaspora_handle).and_return(stub(:perform! => true))
|
||||
@ad.perform!
|
||||
end
|
||||
|
||||
it 'dispatches the account deletion if the user exists' do
|
||||
@ad.should_receive(:dispatch)
|
||||
@ad.perform!
|
||||
end
|
||||
|
||||
it 'does not dispatch an account deletion for non-local people' do
|
||||
deletion = AccountDeletion.new(:person => remote_raphael)
|
||||
deletion.should_not_receive(:dispatch)
|
||||
deletion.perform!
|
||||
end
|
||||
end
|
||||
|
||||
describe '#dispatch' do
|
||||
it "sends the account deletion xml" do
|
||||
@ad = AccountDeletion.new(:person => alice.person)
|
||||
@ad.send(:dispatch)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
describe "#subscribers" do
|
||||
it 'includes all contacts' do
|
||||
@ad = AccountDeletion.new(:person => alice.person)
|
||||
@ad.person.owner.should_receive(:contact_people).and_return([remote_raphael])
|
||||
@ad.subscribers(alice).should include(remote_raphael)
|
||||
end
|
||||
|
||||
it 'includes resharers' do
|
||||
@ad = AccountDeletion.new(:person => alice.person)
|
||||
p = Factory(:person)
|
||||
Person.should_receive(:who_have_reshared_a_users_posts).with(alice).and_return([p])
|
||||
@ad.subscribers(alice).should include(p)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'serialization' do
|
||||
before do
|
||||
account_deletion = AccountDeletion.new(:person => alice.person)
|
||||
@xml = account_deletion.to_xml.to_s
|
||||
end
|
||||
|
||||
it 'should have a diaspora_handle' do
|
||||
@xml.include?(alice.person.diaspora_handle).should == true
|
||||
end
|
||||
|
||||
it 'marshals the xml' do
|
||||
AccountDeletion.from_xml(@xml).should be_valid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,25 +6,12 @@ require 'spec_helper'
|
|||
|
||||
describe Jobs::DeleteAccount do
|
||||
describe '#perform' do
|
||||
it 'calls remove_all_traces' do
|
||||
stub_find_for(bob)
|
||||
bob.should_receive(:remove_all_traces)
|
||||
Jobs::DeleteAccount.perform(bob.id)
|
||||
end
|
||||
|
||||
it 'calls destroy' do
|
||||
stub_find_for(bob)
|
||||
bob.should_receive(:destroy)
|
||||
Jobs::DeleteAccount.perform(bob.id)
|
||||
end
|
||||
def stub_find_for model
|
||||
model.class.stub!(:find) do |id, conditions|
|
||||
if id == model.id
|
||||
model
|
||||
else
|
||||
model.class.find_by_id(id)
|
||||
end
|
||||
end
|
||||
it 'performs the account deletion' do
|
||||
account_deletion = stub
|
||||
AccountDeletion.stub(:find).and_return(account_deletion)
|
||||
account_deletion.should_receive(:perform!)
|
||||
|
||||
Jobs::DeleteAccount.perform(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -91,6 +91,14 @@ describe Person do
|
|||
Person.all_from_aspects(aspect_ids, bob).map(&:id).should == []
|
||||
end
|
||||
end
|
||||
|
||||
describe ".who_have_reshared a user's posts" do
|
||||
it 'pulls back users who reshared the status message of a user' do
|
||||
sm = Factory.create(:status_message, :author => alice.person, :public => true)
|
||||
reshare = Factory.create(:reshare, :root => sm)
|
||||
Person.who_have_reshared_a_users_posts(alice).should == [reshare.author]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "delegating" do
|
||||
|
|
@ -537,18 +545,21 @@ describe Person do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#close_account!" do
|
||||
describe '#lock_access!' do
|
||||
it 'sets the closed_account flag' do
|
||||
@person.lock_access!
|
||||
@person.reload.closed_account.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe "#clear_profile!!" do
|
||||
before do
|
||||
@person = Factory(:person)
|
||||
end
|
||||
it 'sets the closed_account flag' do
|
||||
@person.close_account!
|
||||
@person.reload.closed_account.should be_true
|
||||
end
|
||||
|
||||
it 'calls Profile#tombstone!' do
|
||||
@person.profile.should_receive(:tombstone!)
|
||||
@person.close_account!
|
||||
@person.clear_profile!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -66,6 +66,15 @@ describe StatusMessage do
|
|||
end
|
||||
end
|
||||
|
||||
describe ".guids_for_author" do
|
||||
it 'returns an array of the status_message guids' do
|
||||
sm1 = Factory(:status_message, :author => alice.person)
|
||||
sm2 = Factory(:status_message, :author => bob.person)
|
||||
guids = StatusMessage.guids_for_author(alice.person)
|
||||
guids.should == [sm1.guid]
|
||||
end
|
||||
end
|
||||
|
||||
describe '.before_create' do
|
||||
it 'calls build_tags' do
|
||||
status = Factory.build(:status_message)
|
||||
|
|
|
|||
|
|
@ -1010,20 +1010,35 @@ describe User do
|
|||
end
|
||||
|
||||
describe "#close_account!" do
|
||||
before do
|
||||
@user = Factory.create(:user)
|
||||
it 'locks the user out' do
|
||||
@user.close_account!
|
||||
@user.reload.access_locked?.should be_true
|
||||
end
|
||||
|
||||
it 'creates an account deletion' do
|
||||
expect{
|
||||
@user.close_account!
|
||||
}.to change(AccountDeletion, :count).by(1)
|
||||
end
|
||||
|
||||
it 'calls person#lock_access!' do
|
||||
@user.person.should_receive(:lock_access!)
|
||||
@user.close_account!
|
||||
end
|
||||
end
|
||||
|
||||
describe "#clear_account!" do
|
||||
it 'resets the password to a random string' do
|
||||
random_pass = "12345678909876543210"
|
||||
ActiveSupport::SecureRandom.should_receive(:hex).and_return(random_pass)
|
||||
@user.close_account!
|
||||
@user.clear_account!
|
||||
@user.valid_password?(random_pass)
|
||||
end
|
||||
|
||||
it 'clears all the clearable fields' do
|
||||
@user.reload
|
||||
attributes = @user.send(:clearable_fields)
|
||||
@user.close_account!
|
||||
@user.clear_account!
|
||||
|
||||
@user.reload
|
||||
attributes.each do |attr|
|
||||
|
|
@ -1059,7 +1074,6 @@ describe User do
|
|||
authentication_token
|
||||
unconfirmed_email
|
||||
confirm_email_token
|
||||
locked_at
|
||||
show_community_spotlight_in_stream
|
||||
}.sort
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue