diff --git a/app/models/account_deleter.rb b/app/models/account_deleter.rb index 56464c963..f57b01775 100644 --- a/app/models/account_deleter.rb +++ b/app/models/account_deleter.rb @@ -50,7 +50,7 @@ class AccountDeleter end def ignored_ar_user_associations - [:followed_tags, :invited_by, :contact_people, :applications, :aspect_memberships] + [:followed_tags, :invited_by, :contact_people, :applications, :aspect_memberships, :ignored_people] end def delete_standard_user_associations diff --git a/app/models/comment.rb b/app/models/comment.rb index 33446df3f..c84287055 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -33,10 +33,9 @@ class Comment < ActiveRecord::Base alias_attribute :post, :commentable belongs_to :author, :class_name => 'Person' - validates :text, :presence => true, :length => { :maximum => 2500 } + validates :text, :presence => true, :length => {:maximum => 2500} validates :parent, :presence => true #should be in relayable (pending on fixing Message) - scope :including_author, includes(:author => :profile) scope :for_a_stream, including_author.merge(order('created_at ASC')) diff --git a/app/models/user.rb b/app/models/user.rb index 7745330bd..585ae87da 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -40,13 +40,20 @@ class User < ActiveRecord::Base has_many :aspects, :order => 'order_id ASC' belongs_to :auto_follow_back_aspect, :class_name => 'Aspect' has_many :aspect_memberships, :through => :aspects + has_many :contacts has_many :contact_people, :through => :contacts, :source => :person + has_many :services + has_many :user_preferences + has_many :tag_followings has_many :followed_tags, :through => :tag_followings, :source => :tag, :order => 'tags.name' + has_many :blocks + has_many :ignored_people, :through => :blocks, :source => :person + has_many :notifications, :foreign_key => :recipient_id has_many :authorizations, :class_name => 'OAuth2::Provider::Models::ActiveRecord::Authorization', :foreign_key => :resource_owner_id diff --git a/lib/diaspora/relayable.rb b/lib/diaspora/relayable.rb index 8558dbf81..317068733 100644 --- a/lib/diaspora/relayable.rb +++ b/lib/diaspora/relayable.rb @@ -15,11 +15,23 @@ module Diaspora validates_associated :parent validates :author, :presence => true + validate :author_is_not_ignored delegate :public?, :to => :parent end end + def author_is_not_ignored + if self.new_record? && self.parent.present? + post_author = self.parent.author + relayable_author = self.author + + if post_author.local? && post_author.owner.ignored_people.include?(relayable_author) + self.errors.add(:author_id, 'This person is ignored by the post author') + end + end + end + # @return [Boolean] true def relayable? true @@ -49,19 +61,20 @@ module Diaspora def receive(user, person=nil) comment_or_like = self.class.where(:guid => self.guid).first || self - #check to make sure the signature of the comment or like comes from the person claiming to authoring said comment or like + # Check to make sure the signature of the comment or like comes from the person claiming to author it unless comment_or_like.parent.author == user.person || comment_or_like.verify_parent_author_signature Rails.logger.info("event=receive status=abort reason='object signature not valid' recipient=#{user.diaspora_handle} sender=#{self.parent.author.diaspora_handle} payload_type=#{self.class} parent_id=#{self.parent.id}") return end - #as the owner of the post being liked or commented on, you need to add your own signature in order to pass it to the people who received your original post + # As the owner of the post being liked or commented on, you need to add your own signature in order to + # pass it to the people who received your original post if user.owns? comment_or_like.parent comment_or_like.parent_author_signature = comment_or_like.sign_with_key(user.encryption_key) comment_or_like.save! end - #dispatch object DOWNSTREAM, received it via UPSTREAM + # Dispatch object DOWNSTREAM, received it via UPSTREAM unless user.owns?(comment_or_like) comment_or_like.save! Postzord::Dispatcher.build(user, comment_or_like).post diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index 3cdfdc6dd..b2d79b5f0 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -3,7 +3,7 @@ # the COPYRIGHT file. require 'spec_helper' -require File.join(Rails.root, "spec", "shared_behaviors", "relayable") +require Rails.root.join("spec", "shared_behaviors", "relayable") describe Comment do before do @@ -111,6 +111,8 @@ describe Comment do @object_on_remote_parent = @local_luke.comment!(@remote_parent, "Yeah, it was great") end + + let(:build_object) { alice.build_comment(:post => @status, :text => "why so formal?") } it_should_behave_like 'it is relayable' end diff --git a/spec/models/like_spec.rb b/spec/models/like_spec.rb index a166fff38..eb670073d 100644 --- a/spec/models/like_spec.rb +++ b/spec/models/like_spec.rb @@ -111,6 +111,8 @@ describe Like do @object_on_remote_parent = @local_luke.like(0, :target => @remote_parent) end + + let(:build_object) { alice.build_like(:target => @status, :positive => 1) } it_should_behave_like 'it is relayable' end diff --git a/spec/models/message_spec.rb b/spec/models/message_spec.rb index e186afe2a..b9446c40f 100644 --- a/spec/models/message_spec.rb +++ b/spec/models/message_spec.rb @@ -3,36 +3,34 @@ # the COPYRIGHT file. require 'spec_helper' -require File.join(Rails.root, "spec", "shared_behaviors", "relayable") +require Rails.root.join("spec", "shared_behaviors", "relayable") describe Message do before do - @user1 = alice - @user2 = bob - @create_hash = { - :author => @user1.person, - :participant_ids => [@user1.contacts.first.person.id, @user1.person.id], + :author => bob.person, + :participant_ids => [bob.person.id, alice.person.id], :subject => "cool stuff", - :messages_attributes => [ {:author => @user1.person, :text => 'stuff'} ] + :messages_attributes => [ {:author => bob.person, :text => 'stuff'} ] } - @cnv = Conversation.create!(@create_hash) - @message = @cnv.messages.first + @conversation = Conversation.create!(@create_hash) + @message = @conversation.messages.first @xml = @message.to_diaspora_xml end it 'validates that the author is a participant in the conversation' do - msg = Message.new(:text => 'yo', :author => eve.person, :conversation_id => @cnv.id) + message = Message.new(:text => 'yo', :author => eve.person, :conversation_id => @conversation.id) + message.should_not be_valid end describe '#notification_type' do it 'does not return anything for the author' do - @message.notification_type(@user1, @user1.person).should be_nil + @message.notification_type(bob, bob.person).should be_nil end it 'returns private mesage for an actual receiver' do - @message.notification_type(@user2, @user1.person).should == Notifications::PrivateMessage + @message.notification_type(alice, bob.person).should == Notifications::PrivateMessage end end @@ -94,13 +92,15 @@ describe Message do @object_on_remote_parent = Message.create(msg_hash) Postzord::Dispatcher.build(@local_luke, @object_on_remote_parent).post end + + let(:build_object) { Message.new(:author => @alice.person, :text => "ohai!", :conversation => @conversation) } it_should_behave_like 'it is relayable' describe '#after_receive' do it 'increments the conversation visiblity for the conversation' do ConversationVisibility.where(:conversation_id => @object_by_recipient.reload.conversation.id, :person_id => @local_luke.person.id).first.unread.should == 0 - + @object_by_recipient.receive(@local_luke, @local_leia.person) ConversationVisibility.where(:conversation_id => @object_by_recipient.reload.conversation.id, :person_id => @local_luke.person.id).first.unread.should == 1 diff --git a/spec/shared_behaviors/relayable.rb b/spec/shared_behaviors/relayable.rb index f49bce11f..08ca1f8c5 100644 --- a/spec/shared_behaviors/relayable.rb +++ b/spec/shared_behaviors/relayable.rb @@ -7,6 +7,31 @@ require 'spec_helper' describe Diaspora::Relayable do shared_examples_for "it is relayable" do + describe 'validations' do + describe 'on :author_id' do + it "is invalid if the author is on the parent post author's ignore list when object is created" do + bob.blocks.create(:person => alice.person) + relayable = build_object + relayable.should_not be_valid + relayable.should have(1).error_on(:author_id) + end + + it "works if the object has no parent" do # This can happen if we get a comment for a post that's been deleted + bob.blocks.create(:person => alice.person) + relayable = build_object + relayable.parent = nil + expect { relayable.valid? }.to_not raise_exception + end + + it "is valid if the author is added to the parent post author's ignore list later" do + relayable = build_object + relayable.save! + bob.blocks.create(:person => alice.person) + relayable.should be_valid + end + end + end + context 'encryption' do describe '#parent_author_signature' do it 'should sign the object if the user is the post author' do @@ -37,7 +62,7 @@ describe Diaspora::Relayable do context 'propagation' do describe '#receive' do it 'does not overwrite a object that is already in the db' do - lambda{ + lambda { @dup_object_by_parent_author.receive(@local_leia, @local_luke.person) }.should_not change(@dup_object_by_parent_author.class, :count) end