commit more often
This commit is contained in:
parent
fd18ac6c4b
commit
2d5d3a2f2d
11 changed files with 174 additions and 71 deletions
|
|
@ -2,12 +2,13 @@ class Comment
|
|||
include MongoMapper::Document
|
||||
include ROXML
|
||||
include Diaspora::Webhooks
|
||||
|
||||
include Encryptable
|
||||
|
||||
xml_accessor :text
|
||||
xml_accessor :person, :as => Person
|
||||
xml_accessor :post_id
|
||||
|
||||
|
||||
key :text, String
|
||||
timestamps!
|
||||
|
||||
|
|
@ -25,10 +26,42 @@ class Comment
|
|||
(self.message == other.message) && (self.person.email == other.person.email)
|
||||
end
|
||||
|
||||
#ENCRYPTION
|
||||
|
||||
before_validation :sign_if_mine, :sign_if_my_post
|
||||
validates_true_for :creator_signature, :logic => lambda {self.verify_creator_signature}
|
||||
|
||||
xml_accessor :creator_signature
|
||||
key :creator_signature, String
|
||||
key :post_creator_signature, String
|
||||
|
||||
def signable_accessors
|
||||
accessors = self.class.roxml_attrs.collect{|definition|
|
||||
definition.accessor}
|
||||
accessors.delete 'person'
|
||||
accessors.delete 'creator_signature'
|
||||
accessors.delete 'post_creator_signature'
|
||||
accessors
|
||||
end
|
||||
|
||||
def signable_string
|
||||
signable_accessors.collect{|accessor|
|
||||
(self.send accessor.to_sym).to_s}.join ';'
|
||||
end
|
||||
|
||||
def verify_post_creator_signature
|
||||
verify_signature(post_creator_signature, post.person)
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
def sign_if_my_post
|
||||
if self.post.person == User.owner
|
||||
self.post_creator_signature = sign
|
||||
end
|
||||
end
|
||||
|
||||
def send_people_comments_on_my_posts
|
||||
def send_people_comments_on_my_posts
|
||||
if User.owner.mine?(self.post) && !(self.person.is_a? User)
|
||||
self.push_to(self.post.people_with_permissions)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ class Post
|
|||
include MongoMapper::Document
|
||||
include ROXML
|
||||
include Diaspora::Webhooks
|
||||
include Encryptable
|
||||
|
||||
xml_accessor :_id
|
||||
xml_accessor :owner_signature
|
||||
xml_accessor :person, :as => Person
|
||||
|
||||
key :person_id, ObjectId
|
||||
|
|
@ -44,45 +44,27 @@ class Post
|
|||
end
|
||||
|
||||
#ENCRYPTION
|
||||
|
||||
before_validation :sign_if_mine
|
||||
validates_true_for :owner_signature, :logic => lambda {self.verify_signature}
|
||||
validates_true_for :creator_signature, :logic => lambda {self.verify_creator_signature}
|
||||
|
||||
key :owner_signature, String
|
||||
xml_accessor :creator_signature
|
||||
key :creator_signature, String
|
||||
|
||||
def signable_accessors
|
||||
accessors = self.class.roxml_attrs.collect{|definition|
|
||||
definition.accessor}
|
||||
accessors.delete 'person'
|
||||
accessors.delete 'owner_signature'
|
||||
accessors
|
||||
end
|
||||
|
||||
def signable_string
|
||||
signable_accessors.collect{|accessor|
|
||||
(self.send accessor.to_sym).to_s}.join ';'
|
||||
end
|
||||
|
||||
def verify_signature
|
||||
return false unless owner_signature && person.key_fingerprint
|
||||
validity = nil
|
||||
GPGME::verify(owner_signature, signable_string,
|
||||
{:armor => true, :always_trust => true}){ |signature|
|
||||
validity = signature.status == GPGME::GPG_ERR_NO_ERROR &&
|
||||
signature.fpr == person.key_fingerprint
|
||||
}
|
||||
return validity
|
||||
end
|
||||
|
||||
protected
|
||||
def sign_if_mine
|
||||
if self.person == User.owner
|
||||
self.owner_signature = GPGME::sign(signable_string,nil,
|
||||
{:armor=> true, :mode => GPGME::SIG_MODE_DETACH})
|
||||
def signable_accessors
|
||||
accessors = self.class.roxml_attrs.collect{|definition|
|
||||
definition.accessor}
|
||||
accessors.delete 'person'
|
||||
accessors.delete 'creator_signature'
|
||||
accessors
|
||||
end
|
||||
end
|
||||
|
||||
def destroy_comments
|
||||
def signable_string
|
||||
signable_accessors.collect{|accessor|
|
||||
(self.send accessor.to_sym).to_s}.join ';'
|
||||
end
|
||||
|
||||
protected
|
||||
def destroy_comments
|
||||
comments.each{|c| c.destroy}
|
||||
end
|
||||
|
||||
|
|
|
|||
6
db/seeds/request.rb
Normal file
6
db/seeds/request.rb
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
require 'config/environment'
|
||||
|
||||
Request.all.each{|r|
|
||||
User.owner.accept_friend_request(r.id)
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
33
lib/encryptable.rb
Normal file
33
lib/encryptable.rb
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
module Encryptable
|
||||
def signable_string
|
||||
""
|
||||
end
|
||||
def verify_creator_signature
|
||||
verify_signature(creator_signature, person)
|
||||
end
|
||||
|
||||
def verify_signature(signature, person)
|
||||
return false unless signature && person.key_fingerprint
|
||||
validity = nil
|
||||
GPGME::verify(creator_signature, signable_string,
|
||||
{:armor => true, :always_trust => true}){ |signature|
|
||||
puts signature
|
||||
validity = signature.status == GPGME::GPG_ERR_NO_ERROR &&
|
||||
signature.fpr == person.key_fingerprint
|
||||
}
|
||||
return validity
|
||||
end
|
||||
|
||||
protected
|
||||
def sign_if_mine
|
||||
if self.person == User.owner
|
||||
self.creator_signature = sign
|
||||
end
|
||||
end
|
||||
|
||||
def sign
|
||||
GPGME::sign(signable_string,nil,
|
||||
{:armor=> true, :mode => GPGME::SIG_MODE_DETACH, :signers => [User.owner.key]})
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -4,7 +4,7 @@ describe PublicsController do
|
|||
render_views
|
||||
|
||||
before do
|
||||
@user = Factory.create(:user, :profile => Profile.create( :first_name => "bob", :last_name => "smith"))
|
||||
@user = Factory.create(:user, :profile => Profile.new( :first_name => "bob", :last_name => "smith"))
|
||||
request.env['warden'] = mock_model(Warden, :authenticate? => @user, :authenticate! => @user, :authenticate => @user)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ describe Person do
|
|||
Person.friends.all.count.should == 1
|
||||
u.unfriend(f.id)
|
||||
Person.friends.all.count.should == 0
|
||||
Person.all.count.should == 1
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -42,10 +42,11 @@ end
|
|||
end
|
||||
|
||||
def stub_signature_verification
|
||||
Post.any_instance.stubs(:verify_signature).returns(true)
|
||||
StatusMessage.any_instance.stubs(:verify_signature).returns(true)
|
||||
Blog.any_instance.stubs(:verify_signature).returns(true)
|
||||
Bookmark.any_instance.stubs(:verify_signature).returns(true)
|
||||
Post.any_instance.stubs(:verify_creator_signature).returns(true)
|
||||
StatusMessage.any_instance.stubs(:verify_creator_signature).returns(true)
|
||||
Blog.any_instance.stubs(:verify_creator_signature).returns(true)
|
||||
Bookmark.any_instance.stubs(:verify_creator_signature).returns(true)
|
||||
Comment.any_instance.stubs(:verify_creator_signature).returns(true)
|
||||
end
|
||||
|
||||
def unstub_mocha_stubs
|
||||
|
|
|
|||
|
|
@ -10,17 +10,21 @@ describe 'user encryption' do
|
|||
end
|
||||
before do
|
||||
unstub_mocha_stubs
|
||||
@u = Factory.create(:user)
|
||||
@u.send(:assign_key)
|
||||
@u.save
|
||||
@user = Factory.create(:user)
|
||||
@user.send(:assign_key)
|
||||
@user.save
|
||||
@person = Factory.create(:person,
|
||||
:key_fingerprint => GPGME.list_keys("Remote Friend").first.subkeys.first.fpr,
|
||||
:profile => Profile.new(:first_name => 'Remote',
|
||||
:last_name => 'Friend'),
|
||||
:email => 'somewhere@else.com',
|
||||
:url => 'http://distant-example.com/',
|
||||
:key_fingerprint => '57F553EE2C230991566B7C60D3638485F3960087')
|
||||
|
||||
:url => 'http://distant-example.com/')
|
||||
@person2 = Factory.create(:person,
|
||||
:key_fingerprint => GPGME.list_keys("Second Friend").first.subkeys.first.fpr,
|
||||
:profile => Profile.new(:first_name => 'Second',
|
||||
:last_name => 'Friend'),
|
||||
:email => 'elsewhere@else.com',
|
||||
:url => 'http://distanter-example.com/')
|
||||
end
|
||||
|
||||
after do
|
||||
|
|
@ -44,18 +48,18 @@ describe 'user encryption' do
|
|||
end
|
||||
|
||||
it 'should have a key fingerprint' do
|
||||
@u.key_fingerprint.should_not be nil
|
||||
@user.key_fingerprint.should_not be nil
|
||||
end
|
||||
|
||||
it 'should retrieve a user key' do
|
||||
@u.key.subkeys[0].fpr.should == @u.key_fingerprint
|
||||
@user.key.subkeys[0].fpr.should == @user.key_fingerprint
|
||||
end
|
||||
|
||||
describe 'key exchange on friending' do
|
||||
it 'should send over a public key' do
|
||||
Comment.send(:class_variable_get, :@@queue).stub!(:add_post_request)
|
||||
request = @u.send_friend_request_to("http://example.com/")
|
||||
Request.build_xml_for([request]).include?( @u.export_key).should be true
|
||||
request = @user.send_friend_request_to("http://example.com/")
|
||||
Request.build_xml_for([request]).include?( @user.export_key).should be true
|
||||
end
|
||||
|
||||
it 'should receive and marshal a public key from a request' do
|
||||
|
|
@ -70,8 +74,9 @@ describe 'user encryption' do
|
|||
|
||||
xml = Request.build_xml_for [request]
|
||||
person.destroy
|
||||
personcount = Person.all.count
|
||||
store_objects_from_xml(xml)
|
||||
Person.all.count.should == 3
|
||||
Person.all.count.should == personcount + 1
|
||||
new_person = Person.first(:url => "http://test.url/")
|
||||
new_person.key_fingerprint.nil?.should == false
|
||||
new_person.id.should == id
|
||||
|
|
@ -83,54 +88,54 @@ describe 'user encryption' do
|
|||
describe 'signing and verifying' do
|
||||
|
||||
it 'should sign a message on create' do
|
||||
message = Factory.create(:status_message, :person => @u)
|
||||
message.verify_signature.should be true
|
||||
message = Factory.create(:status_message, :person => @user)
|
||||
message.verify_creator_signature.should be true
|
||||
end
|
||||
|
||||
it 'should not be able to verify a message from a person without a key' do
|
||||
person = Factory.create(:person, :key_fingerprint => "123")
|
||||
message = Factory.build(:status_message, :person => person)
|
||||
message.save(:validate => false)
|
||||
message.verify_signature.should be false
|
||||
message.verify_creator_signature.should be false
|
||||
end
|
||||
|
||||
it 'should verify a remote signature' do
|
||||
message = Factory.build(:status_message, :person => @person)
|
||||
message.owner_signature = GPGME.sign(message.signable_string, nil,
|
||||
message.creator_signature = GPGME.sign(message.signable_string, nil,
|
||||
{:mode => GPGME::SIG_MODE_DETACH, :armor => true, :signers => [@person.key]})
|
||||
message.save(:validate => false)
|
||||
message.verify_signature.should be true
|
||||
message.verify_creator_signature.should be true
|
||||
end
|
||||
|
||||
it 'should know if the signature is from the wrong person' do
|
||||
message = Factory.build(:status_message, :person => @person)
|
||||
message.save(:validate => false)
|
||||
message.owner_signature = GPGME.sign(message.signable_string, nil,
|
||||
message.creator_signature = GPGME.sign(message.signable_string, nil,
|
||||
{:mode => GPGME::SIG_MODE_DETACH, :armor => true, :signers => [@person.key]})
|
||||
message.person = @u
|
||||
message.verify_signature.should be false
|
||||
message.person = @user
|
||||
message.verify_creator_signature.should be false
|
||||
end
|
||||
|
||||
it 'should know if the signature is for the wrong text' do
|
||||
message = Factory.build(:status_message, :person => @person)
|
||||
message.owner_signature = GPGME.sign(message.signable_string, nil,
|
||||
message.creator_signature = GPGME.sign(message.signable_string, nil,
|
||||
{:mode => GPGME::SIG_MODE_DETACH, :armor => true, :signers => [@person.key]})
|
||||
message.message = 'I love VENISON'
|
||||
message.save(:validate => false)
|
||||
message.verify_signature.should be false
|
||||
message.verify_creator_signature.should be false
|
||||
end
|
||||
end
|
||||
|
||||
describe 'sending and recieving signatures' do
|
||||
it 'should contain the signature in the xml' do
|
||||
message = Factory.create(:status_message, :person => @u)
|
||||
message = Factory.create(:status_message, :person => @user)
|
||||
xml = message.to_xml.to_s
|
||||
xml.include?(message.owner_signature).should be true
|
||||
xml.include?(message.creator_signature).should be true
|
||||
end
|
||||
it 'the signature should be verified on marshaling' do
|
||||
it 'A message with an invalid signature should be rejected' do
|
||||
message = Factory.build(:status_message, :person => @person)
|
||||
message.owner_signature = GPGME.sign(message.signable_string, nil,
|
||||
{:mode => GPGME::SIG_MODE_DETACH, :armor => true, :signers => [@u.key]})
|
||||
message.creator_signature = GPGME.sign(message.signable_string, nil,
|
||||
{:mode => GPGME::SIG_MODE_DETACH, :armor => true, :signers => [@user.key]})
|
||||
message.save
|
||||
xml = Post.build_xml_for([message])
|
||||
message.destroy
|
||||
|
|
@ -140,4 +145,46 @@ describe 'user encryption' do
|
|||
end
|
||||
|
||||
end
|
||||
describe 'comments' do
|
||||
before do
|
||||
@remote_message = Factory.build(:status_message, :person => @person)
|
||||
@remote_message.creator_signature = GPGME.sign(@remote_message.signable_string, nil,
|
||||
{:mode => GPGME::SIG_MODE_DETACH, :armor => true, :signers => [@person.key]})
|
||||
@remote_message.save
|
||||
|
||||
end
|
||||
it 'should attach the creator signature if the user is commenting' do
|
||||
@user.comment "Yeah, it was great", :on => @remote_message
|
||||
@remote_message.comments.first.verify_creator_signature.should be true
|
||||
end
|
||||
|
||||
it 'should sign the comment if the user is the post creator' do
|
||||
message = Factory.create(:status_message, :person => @user)
|
||||
@user.comment "Yeah, it was great", :on => message
|
||||
StatusMessage.first.comments.first.verify_creator_signature.should be true
|
||||
StatusMessage.first.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 = GPGME.sign(@remote_message.signable_string, nil,
|
||||
{:mode => GPGME::SIG_MODE_DETACH, :armor => true, :signers => [@person2.key]})
|
||||
comment.verify_creator_signature.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 = GPGME.sign(@remote_message.signable_string, nil,
|
||||
{:mode => GPGME::SIG_MODE_DETACH, :armor => true, :signers => [@person2.key]})
|
||||
comment.verify_creator_signature.should be true
|
||||
comment.verify_post_creator_signature.should be false
|
||||
comment.save.should be false
|
||||
end
|
||||
|
||||
it 'should receive remote comments on a user post with a creator sig' do
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue