diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 9ef461b20..0956c28cc 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -47,6 +47,13 @@ class UsersController < ApplicationController end + def destroy + current_user.destroy + sign_out current_user + flash[:notice] = t('user.destroy') + redirect_to root_path + end + def public user = User.find_by_username(params[:username]) diff --git a/app/models/person.rb b/app/models/person.rb index 62126c9a4..a1dca0089 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -146,6 +146,5 @@ class Person private def remove_all_traces Post.all(:person_id => id).each{|p| p.delete} - Album.all(:person_id => id).each{|p| p.delete} end end diff --git a/app/models/user.rb b/app/models/user.rb index d1ead85cf..270cb7a70 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -39,6 +39,8 @@ class User before_validation :downcase_username, :on => :create + before_destroy :unfriend_everyone, :remove_person + def self.find_for_authentication(conditions={}) if conditions[:username] =~ /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i # email regex conditions[:email] = conditions.delete(:username) @@ -293,5 +295,20 @@ class User def encryption_key OpenSSL::PKey::RSA.new( serialized_private_key ) end + + protected + def remove_person + self.person.destroy + end + + def unfriend_everyone + friends.each{ |friend| + if friend.owner? + friend.owner.unfriended_by (self.person ) + else + self.unfriend( friend ) + end + } + end end diff --git a/app/views/users/_account.haml b/app/views/users/_account.haml index 8bd19d72d..ef416df29 100644 --- a/app/views/users/_account.haml +++ b/app/views/users/_account.haml @@ -27,3 +27,7 @@ = link_to "download my xml", users_export_path, :class => "button" = link_to "download my photos", users_export_photos_path, :class => "button" +%h3 Close Account += link_to "Close Account", current_user, + :confirm => "Are you sure?", :method => :delete, + :class => "button`" diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml index 5a5cc7a43..554f8bcb8 100644 --- a/config/locales/diaspora/en.yml +++ b/config/locales/diaspora/en.yml @@ -114,6 +114,7 @@ en: you_dont_have_any_photos: "You don't have any photos! Go to the" page_to_upload_some: "page to upload some." or: "or" + destroy: "Account successfully closed." comments: comment: ago: "ago" diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 100b9ff39..dfb0f685c 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -6,6 +6,11 @@ require 'spec_helper' describe User do let(:user) { Factory(:user) } + let(:aspect) { user.aspect(:name => 'heroes') } + let(:user2) { Factory(:user) } + let(:aspect2) { user2.aspect(:name => 'stuff') } + let(:user3) { Factory(:user) } + let(:aspect3) { user3.aspect(:name => 'stuff') } describe "validations" do it "downcases the username" do @@ -38,9 +43,6 @@ describe User do end context 'aspects' do - let(:aspect) { user.aspect(:name => 'heroes') } - let(:user2) { Factory(:user) } - let(:aspect2) { user2.aspect(:name => 'stuff') } it 'should delete an empty aspect' do user.drop_aspect(aspect) @@ -48,11 +50,63 @@ describe User do end it 'should not delete an aspect with friends' do - friend_users(user, Aspect.find_by_id(aspect.id), user2, Aspect.find_by_id(aspect2.id)) + friend_users(user, aspect, user2, aspect2) aspect.reload proc{user.drop_aspect(aspect)}.should raise_error /Aspect not empty/ user.aspects.include?(aspect).should == true end end + context 'account removal' do + before do + friend_users(user, aspect, user2, aspect2) + friend_users(user, aspect, user3, aspect3) + end + + it 'should unfriend everyone' do + user.should_receive(:unfriend_everyone) + user.destroy + end + + it 'should remove person' do + user.should_receive(:remove_person) + user.destroy + end + + describe '#remove_person' do + it 'should remove the person object' do + person = user.person + user.destroy + person.reload + person.should be nil + end + + it 'should remove the posts' do + message = user.post(:status_message, :message => "hi", :to => aspect.id) + user.reload + user.destroy + proc{ message.reload }.should raise_error /does not exist/ + end + end + + describe '#unfriend_everyone' do + + before do + user3.delete + end + + it 'should send retractions to remote poeple' do + user.should_receive(:unfriend).once + user.destroy + end + + it 'should unfriend local people' do + user2.friends.count.should be 1 + user.destroy + user2.reload + user2.friends.count.should be 0 + end + end + end + end