More work on retracting posts with reshares, one failing spec on User#retract
This commit is contained in:
parent
7382dfb7be
commit
a1bf22fe7e
6 changed files with 52 additions and 97 deletions
|
|
@ -2,81 +2,28 @@
|
||||||
# licensed under the Affero General Public License version 3 or later. See
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
# the COPYRIGHT file.
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
class RelayableRetraction
|
class RelayableRetraction < SignedRetraction
|
||||||
include ROXML
|
|
||||||
include Diaspora::Webhooks
|
|
||||||
include Diaspora::Encryptable
|
|
||||||
|
|
||||||
xml_name :relayable_retraction
|
xml_name :relayable_retraction
|
||||||
xml_attr :target_guid
|
|
||||||
xml_attr :target_type
|
|
||||||
xml_attr :sender_handle
|
|
||||||
xml_attr :parent_author_signature
|
xml_attr :parent_author_signature
|
||||||
xml_attr :target_author_signature
|
|
||||||
|
|
||||||
attr_accessor :target_guid,
|
attr_accessor :parent_author_signature
|
||||||
:target_type,
|
|
||||||
:parent_author_signature,
|
|
||||||
:target_author_signature,
|
|
||||||
:sender
|
|
||||||
|
|
||||||
def signable_accessors
|
def signable_accessors
|
||||||
accessors = self.class.roxml_attrs.collect do |definition|
|
super - ['parent_author_signature']
|
||||||
definition.accessor
|
|
||||||
end
|
|
||||||
['target_author_signature', 'parent_author_signature'].each do |acc|
|
|
||||||
accessors.delete acc
|
|
||||||
end
|
|
||||||
accessors
|
|
||||||
end
|
|
||||||
|
|
||||||
def sender_handle= new_sender_handle
|
|
||||||
@sender = Person.where(:diaspora_handle => new_sender_handle).first
|
|
||||||
end
|
|
||||||
|
|
||||||
def sender_handle
|
|
||||||
@sender.diaspora_handle
|
|
||||||
end
|
|
||||||
|
|
||||||
def diaspora_handle
|
|
||||||
self.sender_handle
|
|
||||||
end
|
|
||||||
|
|
||||||
def subscribers(user)
|
|
||||||
self.target.subscribers(user)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.build(sender, target)
|
def self.build(sender, target)
|
||||||
retraction = self.new
|
retraction = super
|
||||||
retraction.sender = sender
|
|
||||||
retraction.target = target
|
|
||||||
retraction.target_author_signature = retraction.sign_with_key(sender.encryption_key) if sender.person == target.author
|
|
||||||
retraction.parent_author_signature = retraction.sign_with_key(sender.encryption_key) if defined?(target.parent) && sender.person == target.parent.author
|
retraction.parent_author_signature = retraction.sign_with_key(sender.encryption_key) if defined?(target.parent) && sender.person == target.parent.author
|
||||||
retraction
|
retraction
|
||||||
end
|
end
|
||||||
|
|
||||||
def target
|
|
||||||
@target ||= self.target_type.constantize.where(:guid => target_guid).first
|
|
||||||
end
|
|
||||||
|
|
||||||
def guid
|
|
||||||
target_guid
|
|
||||||
end
|
|
||||||
def target= new_target
|
|
||||||
@target = new_target
|
|
||||||
@target_type = new_target.class.to_s
|
|
||||||
@target_guid = new_target.guid
|
|
||||||
end
|
|
||||||
|
|
||||||
def parent
|
def parent
|
||||||
self.target.parent
|
self.target.parent
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform receiving_user
|
def diaspora_handle
|
||||||
Rails.logger.debug "Performing retraction for #{target_guid}"
|
self.sender_handle
|
||||||
self.target.unsocket_from_user receiving_user if target.respond_to? :unsocket_from_user
|
|
||||||
self.target.destroy
|
|
||||||
Rails.logger.info(:event => :retraction, :status => :complete, :target_type => self.target_type, :guid => self.target_guid)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def receive(recipient, sender)
|
def receive(recipient, sender)
|
||||||
|
|
@ -101,8 +48,4 @@ class RelayableRetraction
|
||||||
def parent_author_signature_valid?
|
def parent_author_signature_valid?
|
||||||
verify_signature(self.parent_author_signature, self.parent.author)
|
verify_signature(self.parent_author_signature, self.parent.author)
|
||||||
end
|
end
|
||||||
|
|
||||||
def target_author_signature_valid?
|
|
||||||
verify_signature(self.target_author_signature, self.target.author)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ class Reshare < Post
|
||||||
belongs_to :root, :class_name => 'Post'
|
belongs_to :root, :class_name => 'Post'
|
||||||
validate :root_must_be_public
|
validate :root_must_be_public
|
||||||
attr_accessible :root_id, :public
|
attr_accessible :root_id, :public
|
||||||
|
validates_presence_of :root, :on => :create
|
||||||
|
|
||||||
xml_attr :root_diaspora_id
|
xml_attr :root_diaspora_id
|
||||||
xml_attr :root_guid
|
xml_attr :root_guid
|
||||||
|
|
@ -61,7 +62,7 @@ class Reshare < Post
|
||||||
end
|
end
|
||||||
|
|
||||||
def root_must_be_public
|
def root_must_be_public
|
||||||
if !self.root.public
|
if self.root && !self.root.public
|
||||||
errors[:base] << "you must reshare public posts"
|
errors[:base] << "you must reshare public posts"
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -233,26 +233,19 @@ class User < ActiveRecord::Base
|
||||||
def retract(target, opts={})
|
def retract(target, opts={})
|
||||||
if target.respond_to?(:relayable?) && target.relayable?
|
if target.respond_to?(:relayable?) && target.relayable?
|
||||||
retraction = RelayableRetraction.build(self, target)
|
retraction = RelayableRetraction.build(self, target)
|
||||||
|
elsif target.is_a? Post
|
||||||
|
retraction = SignedRetraction.build(self, target)
|
||||||
else
|
else
|
||||||
retraction = Retraction.for(target)
|
retraction = Retraction.for(target)
|
||||||
end
|
end
|
||||||
|
|
||||||
if target.is_a?(Post) && target.reshares.size != 0
|
if target.is_a?(Post)
|
||||||
reshare_retraction = RelayableRetraction.build(self, target)
|
opts[:additional_subscribers] = target.resharers
|
||||||
end
|
end
|
||||||
|
|
||||||
# if target.is_a?(Post)
|
|
||||||
# opts[:additional_subscribers] = target.resharers
|
|
||||||
# end
|
|
||||||
|
|
||||||
mailman = Postzord::Dispatch.new(self, retraction, opts)
|
mailman = Postzord::Dispatch.new(self, retraction, opts)
|
||||||
mailman.post
|
mailman.post
|
||||||
|
|
||||||
if reshare_retraction
|
|
||||||
mailman = Postzord::Dispatch.new(self, reshare_retraction)
|
|
||||||
mailman.post
|
|
||||||
end
|
|
||||||
|
|
||||||
retraction.perform(self)
|
retraction.perform(self)
|
||||||
|
|
||||||
retraction
|
retraction
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ describe Person do
|
||||||
context 'local people' do
|
context 'local people' do
|
||||||
it 'uses the pod config url to set the diaspora_handle' do
|
it 'uses the pod config url to set the diaspora_handle' do
|
||||||
new_person = User.build(:username => "foo123", :email => "foo123@example.com", :password => "password", :password_confirmation => "password").person
|
new_person = User.build(:username => "foo123", :email => "foo123@example.com", :password => "password", :password_confirmation => "password").person
|
||||||
new_person.diaspora_handle.should == "foo123@#{AppConfig[:pod_uri].host}"
|
new_person.diaspora_handle.should == "foo123@#{AppConfig[:pod_uri].authority}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -760,9 +760,9 @@ describe User do
|
||||||
@post = Factory(:status_message, :author => bob.person, :public => true)
|
@post = Factory(:status_message, :author => bob.person, :public => true)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "regular retractions" do
|
context "posts" do
|
||||||
before do
|
before do
|
||||||
Retraction.stub(:for).and_return(@retraction)
|
SignedRetraction.stub(:build).and_return(@retraction)
|
||||||
@retraction.stub(:perform)
|
@retraction.stub(:perform)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -791,21 +791,25 @@ describe User do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "relayable retractions" do
|
context "signed retractions" do
|
||||||
before do
|
before do
|
||||||
@post.reshares << Factory.create(:reshare, :author => remote_raphael)
|
@post.reshares << Factory.create(:reshare,:root_id => @post.id, :author => Factory(:user).person)
|
||||||
@post.save!
|
@post.save!
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sends a relayable retraction if the object is relayable' do
|
it 'relays the signed retraction onwards to recipients of reshares' do
|
||||||
r_ret = RelayableRetraction.build(bob, @post)
|
r_ret = SignedRetraction.build(bob, @post)
|
||||||
RelayableRetraction.should_receive(:build).and_return(r_ret)
|
SignedRetraction.should_receive(:build).and_return(r_ret)
|
||||||
|
|
||||||
dis = mock
|
|
||||||
dis.should_receive(:post)
|
|
||||||
Postzord::Dispatch.should_receive(:new).with(bob, r_ret).and_return(dis)
|
|
||||||
|
|
||||||
bob.retract(@post)
|
dis = mock
|
||||||
|
dis_2 = mock
|
||||||
|
dis.should_receive(:post)
|
||||||
|
dis_2.should_receive(:post)
|
||||||
|
Postzord::Dispatch.should_receive(:new).with(bob, r_ret, anything()).and_return(dis, dis_2)
|
||||||
|
|
||||||
|
fantasy_resque do
|
||||||
|
bob.retract(@post)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -18,16 +18,16 @@ unless Server.all.empty?
|
||||||
#Server.all.each{|s| puts "Server at port #{s.port} still running." if s.running?}
|
#Server.all.each{|s| puts "Server at port #{s.port} still running." if s.running?}
|
||||||
WebMock::Config.instance.allow_localhost = false
|
WebMock::Config.instance.allow_localhost = false
|
||||||
end
|
end
|
||||||
|
before do
|
||||||
it 'fetches the original post from the root server' do
|
Server.all.each{|s| s.truncate_database; puts "Truncating database for server #{s}" }
|
||||||
original_post = nil
|
@original_post = nil
|
||||||
Server[0].in_scope do
|
Server[0].in_scope do
|
||||||
original_poster = Factory.create(:user_with_aspect, :username => "original_poster")
|
original_poster = Factory.create(:user_with_aspect, :username => "original_poster")
|
||||||
resharer = Factory.create(:user_with_aspect, :username => "resharer")
|
resharer = Factory.create(:user_with_aspect, :username => "resharer")
|
||||||
|
|
||||||
connect_users_with_aspects(original_poster, resharer)
|
connect_users_with_aspects(original_poster, resharer)
|
||||||
|
|
||||||
original_post = original_poster.post(:status_message,
|
@original_post = original_poster.post(:status_message,
|
||||||
:public => true,
|
:public => true,
|
||||||
:text => "Awesome Sauce!",
|
:text => "Awesome Sauce!",
|
||||||
:to => 'all')
|
:to => 'all')
|
||||||
|
|
@ -50,14 +50,28 @@ unless Server.all.empty?
|
||||||
|
|
||||||
Server[0].in_scope do
|
Server[0].in_scope do
|
||||||
r = User.find_by_username("resharer")
|
r = User.find_by_username("resharer")
|
||||||
r.post(:reshare, :root_id => original_post.id, :to => 'all')
|
r.post(:reshare, :root_id => @original_post.id, :to => 'all')
|
||||||
debugger
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fetches the original post from the root server' do
|
||||||
|
Server[1].in_scope do
|
||||||
|
Post.exists?(:guid => @original_post.guid).should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'relays the retraction for the root post to recipients of the reshare' do
|
||||||
|
Server[0].in_scope do
|
||||||
|
poster = User.find_by_username 'original_poster'
|
||||||
|
fantasy_resque do
|
||||||
|
poster.retract @original_post
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Server[1].in_scope do
|
Server[1].in_scope do
|
||||||
Post.exists?(:guid => original_post.guid).should be_true
|
Post.exists?(:guid => @original_post.guid).should be_false
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue