commit more often

This commit is contained in:
Raphael 2010-07-15 13:29:21 -07:00
parent fd18ac6c4b
commit 2d5d3a2f2d
11 changed files with 174 additions and 71 deletions

View file

@ -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

View file

@ -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
View 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
View 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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