diff --git a/app/models/comment.rb b/app/models/comment.rb index 3b574f28f12b09877c45f773cd106dcf10b08e47..b4f2fb2d97b46cafceb2b272d0fd2a3f490a63b8 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -33,9 +33,6 @@ class Comment #ENCRYPTION - before_validation :sign_if_mine, :sign_if_my_post - validates_true_for :post_creator_signature, :logic => lambda {self.verify_post_creator_signature} - xml_accessor :creator_signature xml_accessor :post_creator_signature @@ -57,11 +54,7 @@ class Comment end def verify_post_creator_signature - if person.owner.nil? - verify_signature(post_creator_signature, post.person) - else - true - end + verify_signature(post_creator_signature, post.person) end diff --git a/app/models/person.rb b/app/models/person.rb index d7fa74418dda6a55c5adf1d04c9a833fcb9df226..afd48bea51cc311d77ac053f1f0d5fca0e2fe0f5 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -51,6 +51,7 @@ class Person raise TypeError unless new_key.class == OpenSSL::PKey::RSA serialized_key = new_key.export end + def export_key encryption_key.public_key.export end @@ -61,6 +62,7 @@ class Person options[:person] = self model_class = class_name.to_s.camelize.constantize post = model_class.instantiate(options) + post.creator_signature = post.sign_with_key(encryption_key) post.notify_people post.socket_to_uid owner.id if (owner_id && post.respond_to?( :socket_to_uid)) post @@ -70,27 +72,25 @@ class Person def comment(text, options = {}) raise "must comment on something!" unless options[:on] c = Comment.new(:person_id => self.id, :text => text, :post => options[:on]) + c.creator_signature = c.sign_with_key(encryption_key) if c.save - begin dispatch_comment c - rescue Exception => e - puts e.inspect - raise e - end - c.socket_to_uid owner.id if owner_id - true + c else Rails.logger.warn "this failed to save: #{c.inspect}" + false end - false end def dispatch_comment( c ) if owns? c.post + c.post_creator_signature = c.sign_with_key(encryption_key) + c.save c.push_downstream elsif owns? c + c.save c.push_upstream end end diff --git a/app/models/post.rb b/app/models/post.rb index 12709d923d0a2bbd757404b55c1d225a7beabd87..2b2449e66af018ca8eb0915ea78a3776cc9df4ba 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -21,8 +21,8 @@ class Post @@per_page = 10 timestamps! - - before_destroy :propagate_retraction + + before_destroy :propogate_retraction after_destroy :destroy_comments def self.instantiate params @@ -39,9 +39,6 @@ class Post end #ENCRYPTION - before_validation :sign_if_mine - validates_true_for :creator_signature, :logic => lambda {self.verify_creator_signature} - xml_accessor :creator_signature key :creator_signature, String @@ -71,11 +68,8 @@ protected comments.each{|c| c.destroy} end - def propagate_retraction - Retraction.for(self).notify_people - end - - - + def propogate_retraction + self.person.owner.retract(self) + end end diff --git a/app/models/retraction.rb b/app/models/retraction.rb index c9cf8dd77237fa6beb292ee3f2b277b5d2bb7295..123a27a4ee7d18f2f9b9b1549fcc1c0d17e0b394 100644 --- a/app/models/retraction.rb +++ b/app/models/retraction.rb @@ -13,7 +13,6 @@ class Retraction retraction.type = object.class.to_s end retraction.person_id = person_id_from(object) - retraction.send(:sign_if_mine) retraction end @@ -60,21 +59,7 @@ class Retraction end #ENCRYPTION - xml_reader :creator_signature - - def creator_signature - object = self.type.constantize.first(:id => post_id) - - if object.class == Person && person_id == object.id - @creator_signature || sign_with_key(object.key) - elsif person_id == object.person.id - @creator_signature || sign_if_mine - end - end - - def creator_signature= input - @creator_signature = input - end + xml_accessor :creator_signature def signable_accessors accessors = self.class.roxml_attrs.collect{|definition| @@ -86,7 +71,8 @@ class Retraction def signable_string signable_accessors.collect{|accessor| - (self.send accessor.to_sym).to_s}.join ';' + (self.send accessor.to_sym).to_s + }.join ';' end end diff --git a/app/models/user.rb b/app/models/user.rb index dbe9fda38fcd3040bb97f452fcbb1da9ae78d7fc..d07bca481c2cadc6e16001efc17088273220893f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -39,6 +39,14 @@ class User Group.create(opts) end + ######### Posts and Such ############### + + def retract( post ) + retraction = Retraction.for(post) + retraction.creator_signature = retraction.sign_with_key( encryption_key ) + retraction.notify_people + retraction + end ######### Friend Requesting ########### def send_friend_request_to(friend_url, group_id) unless self.friends.detect{ |x| x.receive_url == friend_url} @@ -107,7 +115,9 @@ class User def unfriend(bad_friend) Rails.logger.info("#{self.real_name} is unfriending #{bad_friend.inspect}") - Retraction.for(self).push_to_url(bad_friend.receive_url) + retraction = Retraction.for(self) + retraction.creator_signature = retraction.sign_with_key(encryption_key) + retraction.push_to_url(bad_friend.receive_url) remove_friend(bad_friend) end @@ -165,7 +175,6 @@ class User def receive xml object = Diaspora::Parser.from_xml(xml) Rails.logger.debug("Receiving object:\n#{object.inspect}") - if object.is_a? Retraction if object.type == 'Person' && object.signature_valid? @@ -189,7 +198,6 @@ class User person.profile = object person.save - elsif object.is_a?(Post) && object.verify_creator_signature == true Rails.logger.debug("Saving post: #{object}") object.save @@ -198,14 +206,16 @@ class User object.socket_to_uid(id) if (object.respond_to?(:socket_to_uid) && !self.owns?(object)) dispatch_comment object if object.is_a?(Comment) && !owns?(object) + elsif object.is_a?(Comment) && object.verify_post_creator_signature - + if object.verify_creator_signature || object.person.nil? + dispatch_comment object unless owns?(object) + end elsif object.verify_creator_signature == true Rails.logger.debug("Saving object: #{object}") object.save object.socket_to_uid( id) if (object.respond_to?(:socket_to_uid) && !self.owns?(object)) - dispatch_comment object if object.is_a?(Comment) && !owns?(object) end end diff --git a/lib/encryptable.rb b/lib/encryptable.rb index 850499bff889182ff8e94414bd8e6e62d08f3090..90954924d84e3ada9959a050bfae4d1ce7c096ba 100644 --- a/lib/encryptable.rb +++ b/lib/encryptable.rb @@ -1,6 +1,6 @@ module Encryptable def signable_string - "" + raise NotImplementedException("Override this in your encryptable class") end def verify_creator_signature verify_signature(creator_signature, person) @@ -23,15 +23,9 @@ validity end - protected - def sign_if_mine - self.creator_signature = sign_with_key(person.encryption_key) unless person.owner_id.nil? - end - def sign_with_key(key) Rails.logger.debug("Signing #{signable_string}") Base64.encode64(key.sign "SHA", signable_string) - end end diff --git a/spec/helpers/requests_helper_spec.rb b/spec/helpers/requests_helper_spec.rb index 8419bd566c362ed7eb8d12010d09aa94888ceb4d..325597bf32b5927dee96970796fb50d30cf39725 100644 --- a/spec/helpers/requests_helper_spec.rb +++ b/spec/helpers/requests_helper_spec.rb @@ -10,19 +10,11 @@ describe RequestsHelper do @max = Redfinger.finger('mbs348@gmail.com') end - describe "profile" do - it 'should detect how to subscribe to a diaspora or webfinger profile' do subscription_mode(@tom).should == :friend subscription_mode(@evan).should == :none subscription_mode(@max).should == :none end - - it 'should return the correct tag and url for a given address' do - relationship_flow('tom@tom.joindiaspora.com')[:friend].include?("receive/user").should == true - end - end - end diff --git a/spec/lib/diaspora_parser_spec.rb b/spec/lib/diaspora_parser_spec.rb index 93dad920fc856e8314c03a4a494216f4de392cde..d0065cfb817d12452470e89fef72a114dc1c20d8 100644 --- a/spec/lib/diaspora_parser_spec.rb +++ b/spec/lib/diaspora_parser_spec.rb @@ -13,18 +13,6 @@ describe Diaspora::Parser do @user2 = Factory.create(:user) end - - it "should associate the post with a group" do - @user.activate_friend(@person, @group) - - status_message = Factory.build(:status_message, :message => "hey!", :person => @person) - @user.receive status_message.to_diaspora_xml - - @user.posts.count.should == 1 - end - - - describe 'with encryption' do before do unstub_mocha_stubs diff --git a/spec/models/comments_spec.rb b/spec/models/comments_spec.rb index 3be39564486b9d8579cf80a7f62564a993fd76a5..6d6aa7c3ca533641bab8c41ebbfbfd75309be047 100644 --- a/spec/models/comments_spec.rb +++ b/spec/models/comments_spec.rb @@ -31,9 +31,16 @@ describe Comment do describe 'comment propagation' do before do + @group = @user.group(:name => "Doofuses") + + @user2 = Factory.create(:user) + @group2 = @user2.group(:name => "Lame-faces") + + request = @user.send_friend_request_to(@user2.receive_url, @group.id) + reversed_request = @user2.accept_friend_request( request.id, @group2.id ) + @user.receive reversed_request.to_diaspora_xml + @person = Factory.create(:person) - @user.friends << Factory.create(:person) - @user.save @person2 = Factory.create(:person) @person_status = Factory.build(:status_message, :person => @person) @user_status = Factory.build(:status_message, :person => @user.person) @@ -52,16 +59,24 @@ describe Comment do it 'should send a comment a person made on your post to all people' do message_queue.should_receive(:add_post_request) - @person.comment "balls", :on => @user_status + comment = Comment.new(:person_id => @person.id, :text => "balls", :post => @user_status) + @user.receive(comment.to_diaspora_xml) + end + it 'should send a comment a user made on your post to all people' do + message_queue.should_receive(:add_post_request).twice + comment = @user2.comment( "balls", :on => @user_status) + @user.receive(comment.to_diaspora_xml) end it 'should not send a comment a person made on his own post to anyone' do message_queue.should_not_receive(:add_post_request) - @person.comment "balls", :on => @person_status + comment = Comment.new(:person_id => @person.id, :text => "balls", :post => @person_status) + @user.receive(comment.to_diaspora_xml) end it 'should not send a comment a person made on a person post to anyone' do message_queue.should_not_receive(:add_post_request) - @person2.comment "balls", :on => @person_status + comment = Comment.new(:person_id => @person2.id, :text => "balls", :post => @person_status) + @user.receive(comment.to_diaspora_xml) end end end diff --git a/spec/models/photo_spec.rb b/spec/models/photo_spec.rb index 3091ed74a76df149eeebc07ce2f194ec6b1742f3..de6adf50ea48179f354b778bfb6d26f163873868 100644 --- a/spec/models/photo_spec.rb +++ b/spec/models/photo_spec.rb @@ -86,7 +86,7 @@ describe Photo do end it 'should save a signed photo to GridFS' do - photo = Photo.create(:person => @user.person, :album => @album, :image => File.open(@fixture_name)) + photo = @user.post(:photo, :album => @album, :user_file => [File.open(@fixture_name)]) photo.save.should == true photo.verify_creator_signature.should be true end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index fb730c6db0feb91f720d02ea8f06ef4da7ef787e..d0b2759cbfe4b218b3f5832507f228872c754c40 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -58,6 +58,7 @@ end Retraction.any_instance.stubs(:verify_signature).returns(true) Request.any_instance.stubs(:verify_signature).returns(true) Comment.any_instance.stubs(:verify_post_creator_signature).returns(true) + Comment.any_instance.stubs(:verify_creator_signature).returns(true) end def unstub_mocha_stubs diff --git a/spec/user_encryption_spec.rb b/spec/user_encryption_spec.rb index fde3cf5a8de4c838d89365b9234f54c504c4909e..a70804ebd864b95d9af8ef185c20d744e119d3a6 100644 --- a/spec/user_encryption_spec.rb +++ b/spec/user_encryption_spec.rb @@ -69,7 +69,7 @@ describe 'user encryption' do message = @user.post :status_message, :message => "hi" - retraction = Retraction.for(message) + retraction = @user.retract(message) retraction.verify_creator_signature.should be true end @@ -145,29 +145,28 @@ describe 'user encryption' do message.comments.first.verify_creator_signature.should be true message.comments.first.verify_post_creator_signature.should be true end - + it 'should verify a comment made on a remote post by a different friend' do comment = Comment.new(:person => @person2, :text => "balls", :post => @remote_message) comment.creator_signature = comment.send(:sign_with_key,@person2.encryption_key) comment.verify_creator_signature.should be true - comment.valid?.should be false + comment.verify_post_creator_signature.should be false comment.post_creator_signature = comment.send(:sign_with_key,@person.encryption_key) comment.verify_post_creator_signature.should be true - comment.valid?.should be true end it 'should reject comments on a remote post with only a creator sig' do - comment = Comment.new(:person => @person2, :text => "balls", :post => @remote_message) - comment.creator_signature = comment.send(:sign_with_key,@person2.encryption_key) - comment.verify_creator_signature.should be true - comment.verify_post_creator_signature.should be false - comment.save.should be false + comment = Comment.new(:person => @person2, :text => "balls", :post => @remote_message) + comment.creator_signature = comment.send(:sign_with_key,@person2.encryption_key) + comment.verify_creator_signature.should be true + comment.verify_post_creator_signature.should be false end it 'should receive remote comments on a user post with a creator sig' do - comment = Comment.new(:person => @person2, :text => "balls", :post => @message) - comment.creator_signature = comment.send(:sign_with_key,@person2.encryption_key) - comment.save.should be true + comment = Comment.new(:person => @person2, :text => "balls", :post => @message) + comment.creator_signature = comment.send(:sign_with_key,@person2.encryption_key) + comment.verify_creator_signature.should be true + comment.verify_post_creator_signature.should be false end end