diff --git a/Gemfile.lock b/Gemfile.lock index d34538a54..673818fbe 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -148,7 +148,7 @@ GEM net-ssh-gateway (1.0.1) net-ssh (>= 1.99.1) nifty-generators (0.4.0) - nokogiri (1.4.3.1) + nokogiri (1.4.1) plucky (0.3.5) mongo (~> 1.0.8) polyglot (0.3.1) diff --git a/app/controllers/dev_utilities_controller.rb b/app/controllers/dev_utilities_controller.rb index a16c1fd56..e633d4021 100644 --- a/app/controllers/dev_utilities_controller.rb +++ b/app/controllers/dev_utilities_controller.rb @@ -30,7 +30,7 @@ def warzombie backer_email = "#{backer['username']}@#{backer['username']}.joindiaspora.com" rel_hash = relationship_flow(backer_email) logger.info "Zombefriending #{backer['given_name']} #{backer['family_name']}" - current_user.send_request(rel_hash, current_user.groups.first.id) + current_user.send_friend_request_to(rel_hash[:friend], current_user.groups.first.id) end end end diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 2f516d5bc..8f1ea9553 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -14,7 +14,7 @@ class PeopleController < ApplicationController @profile = @person.profile @groups_with_person = current_user.groups_with_person(@person) @groups_dropdown_array = current_user.groups.collect{|x| [x.to_s, x.id]} - @posts = current_user.posts_visible_to_me(:from => @person).paginate :page => params[:page], :order => 'created_at DESC' + @posts = current_user.visible_posts_from_others(:from => @person).paginate :page => params[:page], :order => 'created_at DESC' @latest_status_message = current_user.raw_visible_posts.find_all_by__type_and_person_id("StatusMessage", params[:id]).last @post_count = @posts.count respond_with @person diff --git a/app/controllers/publics_controller.rb b/app/controllers/publics_controller.rb index e606dfb0e..da7d8219e 100644 --- a/app/controllers/publics_controller.rb +++ b/app/controllers/publics_controller.rb @@ -1,35 +1,37 @@ class PublicsController < ApplicationController require 'lib/diaspora/parser' include Diaspora::Parser + layout false def hcard @person = Person.find_by_id params[:id] - + puts @person unless @person.nil? || @person.owner.nil? render 'hcard' end end def host_meta - render 'host_meta', :layout => false, :content_type => 'application/xrd+xml' + render 'host_meta', :content_type => 'application/xrd+xml' end def webfinger @person = Person.by_webfinger(params[:q]) unless @person.nil? || @person.owner.nil? - render 'webfinger', :layout => false, :content_type => 'application/xrd+xml' + render 'webfinger', :content_type => 'application/xrd+xml' end end def receive render :nothing => true + return unless params[:xml] begin @user = Person.first(:id => params[:id]).owner rescue NoMethodError => e Rails.logger.error("Received post #{params[:xml]} for nonexistent person #{params[:id]}") return end - @user.receive params[:xml] if params[:xml] + @user.receive_salmon params[:xml] end end diff --git a/app/controllers/requests_controller.rb b/app/controllers/requests_controller.rb index b62eb630e..59e58ba3c 100644 --- a/app/controllers/requests_controller.rb +++ b/app/controllers/requests_controller.rb @@ -45,7 +45,7 @@ class RequestsController < ApplicationController Rails.logger.debug("Sending request: #{rel_hash}") begin - @request = current_user.send_request(rel_hash, params[:request][:group_id]) + @request = current_user.send_friend_request_to(rel_hash[:friend], group) rescue Exception => e raise e unless e.message.include? "already friends" message = "You are already friends with #{params[:request][:destination_url]}!" diff --git a/app/helpers/requests_helper.rb b/app/helpers/requests_helper.rb index 37a5485c4..e40f6bde8 100644 --- a/app/helpers/requests_helper.rb +++ b/app/helpers/requests_helper.rb @@ -27,17 +27,12 @@ module RequestsHelper def relationship_flow(identifier) action = :none - url = nil - local_person = Person.by_webfinger identifier - if local_person - action = (local_person == current_user.person ? :none : :friend) - url = local_person.receive_url - elsif !(identifier.include?(request.host) || identifier.include?("localhost")) - f = Redfinger.finger(identifier) - action = subscription_mode(f) - url = subscription_url(action, f) + person = nil + person = Person.by_webfinger identifier + if person + action = (person == current_user.person ? :none : :friend) end - { action => url } + { action => person } end end diff --git a/app/models/comment.rb b/app/models/comment.rb index 82de5ecdf..1826efd0c 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -22,16 +22,6 @@ class Comment timestamps! - def push_upstream - Rails.logger.info("GOIN UPSTREAM") - push_to([post.person]) - end - - def push_downstream - Rails.logger.info("SWIMMIN DOWNSTREAM") - push_to(post.people_with_permissions) - end - #ENCRYPTION xml_accessor :creator_signature diff --git a/app/models/person.rb b/app/models/person.rb index 7853b9d17..ff1455010 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -1,6 +1,9 @@ +require 'lib/hcard' + class Person include MongoMapper::Document include ROXML + include Encryptor::Public xml_accessor :_id xml_accessor :email @@ -37,6 +40,13 @@ class Person def real_name "#{profile.first_name.to_s} #{profile.last_name.to_s}" end + def owns?(post) + self.id == post.person.id + end + + def receive_url + "#{self.url}receive/users/#{self.id}/" + end def encryption_key OpenSSL::PKey::RSA.new( serialized_key ) @@ -51,6 +61,10 @@ class Person Base64.encode64 OpenSSL::Digest::SHA256.new(self.exported_key).to_s end + def public_key + encryption_key.public_key + end + def exported_key encryption_key.public_key.export end @@ -60,16 +74,41 @@ class Person @serialized_key = new_key end - def owns?(post) - self.id == post.person.id - end - - def receive_url - "#{self.url}receive/users/#{self.id}/" - end - def self.by_webfinger( identifier ) - Person.first(:email => identifier.gsub('acct:', '')) + local_person = Person.first(:email => identifier.gsub('acct:', '')) + if local_person + local_person + elsif !identifier.include?("localhost") + begin + f = Redfinger.finger(identifier) + rescue SocketError => e + raise "Diaspora server for #{identifier} not found" if e.message =~ /Name or service not known/ + end + #raise "No diaspora user found at #{identifier}" + Person.from_webfinger_profile(identifier, f ) + end + end + + def self.from_webfinger_profile( identifier, profile) + new_person = Person.new + + public_key = profile.links.select{|x| x.rel == 'diaspora-public-key'}.first.href + new_person.exported_key = Base64.decode64 public_key + + guid = profile.links.select{|x| x.rel == 'http://joindiaspora.com/guid'}.first.href + new_person.id = guid + + new_person.email = identifier + + hcard = HCard.find profile.hcard.first[:href] + + new_person.url = hcard[:url] + new_person.profile = Profile.new(:first_name => hcard[:given_name], :last_name => hcard[:family_name]) + if new_person.save + new_person + else + nil + end end def remote? diff --git a/app/models/post.rb b/app/models/post.rb index 6b5688914..a072d1dc3 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -4,7 +4,6 @@ class Post include ApplicationHelper include ROXML include Diaspora::Webhooks - include Encryptable include Diaspora::Socketable xml_accessor :_id @@ -28,22 +27,6 @@ class Post self.create params.to_hash end - #ENCRYPTION - 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 'creator_signature' - accessors - end - - def signable_string - signable_accessors.collect{|accessor| - (self.send accessor.to_sym).to_s}.join ';' - end def as_json(opts={}) { diff --git a/app/models/profile.rb b/app/models/profile.rb index 486e99b96..3f8b18a30 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -23,6 +23,4 @@ class Profile self._parent_document end - ##this needs to go once we move to Salmon - def signature_valid?; true; end end diff --git a/app/models/request.rb b/app/models/request.rb index afc1349eb..a4466ad52 100644 --- a/app/models/request.rb +++ b/app/models/request.rb @@ -3,7 +3,6 @@ class Request include MongoMapper::Document include Diaspora::Webhooks include ROXML - include Encryptable xml_accessor :_id xml_accessor :person, :as => Person @@ -41,28 +40,7 @@ class Request self.save end - #ENCRYPTION - - 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 'creator_signature' - accessors - end - - def signable_string - signable_accessors.collect{|accessor| - (self.send accessor.to_sym).to_s}.join ';' - end - - def signature_valid?; true; end - - protected +protected def clean_link if self.destination_url self.destination_url = 'http://' + self.destination_url unless self.destination_url.match('https?://') diff --git a/app/models/retraction.rb b/app/models/retraction.rb index afea944f6..cf52720ed 100644 --- a/app/models/retraction.rb +++ b/app/models/retraction.rb @@ -1,7 +1,6 @@ class Retraction include ROXML include Diaspora::Webhooks - include Encryptable xml_accessor :post_id xml_accessor :person_id @@ -11,7 +10,6 @@ class Retraction attr_accessor :person_id attr_accessor :type - def self.for(object) retraction = self.new if object.is_a? User @@ -28,9 +26,8 @@ class Retraction def perform receiving_user_id Rails.logger.debug "Performing retraction for #{post_id}" begin - return unless signature_valid? Rails.logger.debug("Retracting #{self.type} id: #{self.post_id}") - target = self.type.constantize.first(self.post_id) + target = self.type.constantize.first(:id => self.post_id) target.unsocket_from_uid receiving_user_id if target.respond_to? :unsocket_from_uid target.destroy rescue NameError @@ -38,16 +35,6 @@ class Retraction end end - def signature_valid? - target = self.type.constantize.find_by_id(self.post_id) - - if target.is_a? Person - verify_signature(@creator_signature, self.type.constantize.find_by_id(self.post_id)) - else - verify_signature(@creator_signature, self.type.constantize.find_by_id(self.post_id).person) - end - end - def self.person_id_from(object) object.is_a?(Person) ? object.id : object.person.id end @@ -56,21 +43,4 @@ class Retraction Person.find_by_id(self.person_id) end - #ENCRYPTION - xml_accessor :creator_signature - - def signable_accessors - accessors = self.class.roxml_attrs.collect{|definition| - definition.accessor} - accessors.delete 'person' - accessors.delete 'creator_signature' - accessors - end - - def signable_string - signable_accessors.collect{|accessor| - (self.send accessor.to_sym).to_s - }.join ';' - end - end diff --git a/app/models/user.rb b/app/models/user.rb index 1fbc1a849..c767e3b91 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,8 +1,14 @@ require 'lib/diaspora/user/friending.rb' +require 'lib/diaspora/user/querying.rb' +require 'lib/salmon/salmon' class User include MongoMapper::Document include Diaspora::UserModules::Friending + include Diaspora::UserModules::Querying + include Encryptor::Private + QUEUE = MessageHandler.new + devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable key :username, :unique => true @@ -69,21 +75,8 @@ class User false end -##querying with permissions - def posts_visible_to_me(opts ={}) - if opts[:from].class == Person - Post.where(:person_id => opts[:from].id, :_id.in => self.visible_post_ids) - elsif opts[:from].class == Group - Post.where(:_id.in => opts[:from].post_ids) unless opts[:from].user != self - else - Post.where(:_id.in => self.visible_post_ids) - end - end - - ######## Posting ######## def post(class_name, options = {}) - options[:person] = self.person if class_name == :photo raise ArgumentError.new("No album_id given") unless options[:album_id] @@ -96,15 +89,19 @@ class User group_ids = [group_ids] if group_ids.is_a? BSON::ObjectId raise ArgumentError.new("You must post to someone.") if group_ids.nil? || group_ids.empty? - model_class = class_name.to_s.camelize.constantize - post = model_class.instantiate(options) - post.creator_signature = post.sign_with_key(encryption_key) - post.save + post = build_post(class_name, options) post.socket_to_uid(id, :group_ids => group_ids) if post.respond_to?(:socket_to_uid) - push_to_groups(post, group_ids) + post + end + + def build_post( class_name, options = {}) + options[:person] = self.person + model_class = class_name.to_s.camelize.constantize + post = model_class.instantiate(options) + post.save self.raw_visible_posts << post self.save post @@ -113,10 +110,11 @@ class User def push_to_groups( post, group_ids ) if group_ids == :all || group_ids == "all" groups = self.groups + elsif group_ids.is_a?(Array) && group_ids.first.class == Group + groups = group_ids else groups = self.groups.find_all_by_id( group_ids ) end - #send to the groups target_people = [] @@ -125,40 +123,58 @@ class User group.save target_people = target_people | group.people } - post.push_to( target_people ) + push_to_people(post, target_people) end - def visible_posts( opts = {} ) - if opts[:by_members_of] - return raw_visible_posts if opts[:by_members_of] == :all - group = self.groups.find_by_id( opts[:by_members_of].id ) - group.posts - end + def push_to_people(post, people) + people.each{|person| + salmon(post, :to => person) + } + end + + def push_to_person( person, xml ) + Rails.logger.debug("Adding xml for #{self} to message queue to #{url}") + QUEUE.add_post_request( person.receive_url, person.encrypt(xml) ) + QUEUE.process + + end + + def salmon( post, opts = {} ) + salmon = Salmon::SalmonSlap.create(self, post.to_diaspora_xml) + push_to_person( opts[:to], salmon.to_xml) + salmon end ######## Commenting ######## def comment(text, options = {}) + comment = build_comment(text, options) + if comment + dispatch_comment comment + comment.socket_to_uid id + end + comment + end + + def build_comment( text, options = {}) raise "must comment on something!" unless options[:on] comment = Comment.new(:person_id => self.person.id, :text => text, :post => options[:on]) comment.creator_signature = comment.sign_with_key(encryption_key) if comment.save - dispatch_comment comment - comment.socket_to_uid id comment else Rails.logger.warn "this failed to save: #{comment.inspect}" false end end - + def dispatch_comment( comment ) if owns? comment.post comment.post_creator_signature = comment.sign_with_key(encryption_key) comment.save - comment.push_downstream + push_to_people comment, people_in_groups(groups_with_post(comment.post.id)) elsif owns? comment comment.save - comment.push_upstream + salmon comment, :to => comment.post.person end end @@ -166,8 +182,7 @@ class User def retract( post ) post.unsocket_from_uid(self.id) if post.respond_to? :unsocket_from_uid retraction = Retraction.for(post) - retraction.creator_signature = retraction.sign_with_key( encryption_key ) - retraction.push_to( self.friends.all ) + push_to_people retraction, people_in_groups(groups_with_post(post.id)) retraction end @@ -176,7 +191,7 @@ class User params[:profile].delete(:image_url) if params[:profile][:image_url].empty? if self.person.update_attributes(params) - self.profile.push_to( self.friends.all ) + push_to_groups profile, :all true else false @@ -184,14 +199,22 @@ class User end ###### Receiving ####### + def receive_salmon ciphertext + cleartext = decrypt( ciphertext) + Rails.logger.info("Received a salmon: #{cleartext}") + salmon = Salmon::SalmonSlap.parse cleartext + if salmon.verified_for_key?(salmon.author.public_key) + self.receive(salmon.data) + end + end + def receive xml object = Diaspora::Parser.from_xml(xml) Rails.logger.debug("Receiving object for #{self.real_name}:\n#{object.inspect}") Rails.logger.debug("From: #{object.person.inspect}") if object.person - raise "In receive for #{self.real_name}, signature was not valid on: #{object.inspect}" unless object.signature_valid? if object.is_a? Retraction - if object.type == 'Person' && object.signature_valid? + if object.type == 'Person' Rails.logger.info( "the person id is #{object.post_id} the friend found is #{visible_person_by_id(object.post_id).inspect}") unfriended_by visible_person_by_id(object.post_id) @@ -219,14 +242,16 @@ class User elsif object.is_a?(Comment) object.person = Diaspora::Parser.parse_or_find_person_from_xml( xml ).save if object.person.nil? - self.visible_people << object.person + self.visible_people = self.visible_people | [object.person] self.save Rails.logger.debug("The person parsed from comment xml is #{object.person.inspect}") unless object.person.nil? object.person.save Rails.logger.debug("From: #{object.person.inspect}") if object.person raise "In receive for #{self.real_name}, signature was not valid on: #{object.inspect}" unless object.post.person == self.person || object.verify_post_creator_signature object.save - dispatch_comment object unless owns?(object) + unless owns?(object) + dispatch_comment object + end object.socket_to_uid(id) if (object.respond_to?(:socket_to_uid) && !self.owns?(object)) else Rails.logger.debug("Saving object: #{object}") @@ -268,42 +293,13 @@ class User self.password_confirmation = self.password end - def visible_person_by_id( id ) - id = id.to_id - return self.person if id == self.person.id - result = friends.detect{|x| x.id == id } - result = visible_people.detect{|x| x.id == id } unless result - result - end - - def group_by_id( id ) - id = id.to_id - groups.detect{|x| x.id == id } - end - - def album_by_id( id ) - id = id.to_id - albums.detect{|x| x.id == id } - end - - def groups_with_post( id ) - self.groups.find_all_by_post_ids( id.to_id ) - end - - def groups_with_person person - id = person.id.to_id - groups.select { |g| g.person_ids.include? id} - end - def setup_person self.person.serialized_key ||= User.generate_key.export self.person.email ||= email self.person.save! end - def all_group_ids - self.groups.all.collect{|x| x.id} - end + def as_json(opts={}) { @@ -315,12 +311,7 @@ class User } } end - - - protected - - def self.generate_key - OpenSSL::PKey::RSA::generate 1024 - end - + def self.generate_key + OpenSSL::PKey::RSA::generate 4096 + end end diff --git a/app/views/publics/hcard.erb b/app/views/publics/hcard.erb index 7cfbe5604..f8a3fef91 100644 --- a/app/views/publics/hcard.erb +++ b/app/views/publics/hcard.erb @@ -9,16 +9,28 @@ <%= @person.real_name%> -
+
Full name
- <%= @person.real_name %> + <%= @person.profile.first_name %> +
+
+
+
Full name
+
+ <%= @person.profile.last_name %> +
+
+
+
Full name
+
+ <%= @person.real_name %>
URL
- <%= @person.url%> + <%= @person.url%>
diff --git a/app/views/publics/webfinger.erb b/app/views/publics/webfinger.erb index adeb2d2db..75a2e9fe8 100644 --- a/app/views/publics/webfinger.erb +++ b/app/views/publics/webfinger.erb @@ -1,9 +1,10 @@ acct:<%=@person.email%> - "<%= @person.url %>users/#{@user.id}/hcard" - + "<%= @person.url %>" + - + + diff --git a/config/routes.rb b/config/routes.rb index 5e7a6eafc..43149ba57 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -27,7 +27,7 @@ Diaspora::Application.routes.draw do #public routes # match 'webfinger', :to => 'publics#webfinger' - match 'users/:id/hcard', :to => 'publics#hcard' + match 'hcard/users/:id', :to => 'publics#hcard' match '.well-known/host-meta',:to => 'publics#host_meta' match 'receive/users/:id', :to => 'publics#receive' diff --git a/db/seeds/dev.rb b/db/seeds/dev.rb index c44979057..92653b8d9 100644 --- a/db/seeds/dev.rb +++ b/db/seeds/dev.rb @@ -25,6 +25,6 @@ user2.person.save! # friending users group = user.group(:name => "other dudes") -request = user.send_friend_request_to(user2.receive_url, group.id) +request = user.send_friend_request_to(user2, group) reversed_request = user2.accept_friend_request( request.id, user2.group(:name => "presidents").id ) user.receive reversed_request.to_diaspora_xml diff --git a/db/seeds/tom.rb b/db/seeds/tom.rb index 864caa6f2..7a4a52f3a 100644 --- a/db/seeds/tom.rb +++ b/db/seeds/tom.rb @@ -26,7 +26,7 @@ user2.person.save! # friending users group = user.group(:name => "other dudes") -request = user.send_friend_request_to(user2.receive_url, group.id) +request = user.send_friend_request_to(user2, group) reversed_request = user2.accept_friend_request( request.id, user2.group(:name => "presidents").id ) user.receive reversed_request.to_diaspora_xml user.group(:name => "Presidents") diff --git a/lib/diaspora/user/friending.rb b/lib/diaspora/user/friending.rb index 951be0141..96161c8cd 100644 --- a/lib/diaspora/user/friending.rb +++ b/lib/diaspora/user/friending.rb @@ -1,19 +1,21 @@ module Diaspora module UserModules module Friending - def send_friend_request_to(friend_url, group_id) - raise "You are already friends with that person!" if self.friends.detect{ |x| x.receive_url == friend_url} - request = Request.instantiate(:to => friend_url, :from => self.person, :into => group_id) + def send_friend_request_to(desired_friend, group) + raise "You are already friends with that person!" if self.friends.detect{ + |x| x.receive_url == desired_friend.receive_url} + request = Request.instantiate( + :to => desired_friend.receive_url, + :from => self.person, + :into => group.id) if request.save self.pending_requests << request self.save - group = self.group_by_id(group_id) - group.requests << request group.save - request.push_to_url friend_url + salmon request, :to => desired_friend end request end @@ -29,13 +31,15 @@ module Diaspora request end - def dispatch_friend_acceptance(request) - request.push_to_url(request.callback_url) + def dispatch_friend_acceptance(request, requester) + salmon request, :to => requester request.destroy unless request.callback_url.include? url end def accept_and_respond(friend_request_id, group_id) - dispatch_friend_acceptance(accept_friend_request(friend_request_id, group_id)) + requester = Request.find_by_id(friend_request_id).person + reversed_request = accept_friend_request(friend_request_id, group_id) + dispatch_friend_acceptance reversed_request, requester end def ignore_friend_request(friend_request_id) @@ -75,7 +79,6 @@ module Diaspora def unfriend(bad_friend) Rails.logger.info("#{self.real_name} is unfriending #{bad_friend.inspect}") 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 @@ -101,21 +104,13 @@ module Diaspora remove_friend bad_friend end - def send_request(rel_hash, group) - if rel_hash[:friend] - self.send_friend_request_to(rel_hash[:friend], group) - else - raise "you can't do anything to that url" - end - end - def activate_friend(person, group) person.user_refs += 1 group.people << person friends << person + save person.save group.save - save end def request_from_me?(request) diff --git a/lib/diaspora/user/querying.rb b/lib/diaspora/user/querying.rb new file mode 100644 index 000000000..ed2bcb115 --- /dev/null +++ b/lib/diaspora/user/querying.rb @@ -0,0 +1,62 @@ +module Diaspora + module UserModules + module Querying + def visible_posts_from_others(opts ={}) + if opts[:from].class == Person + Post.where(:person_id => opts[:from].id, :_id.in => self.visible_post_ids) + elsif opts[:from].class == Group + Post.where(:_id.in => opts[:from].post_ids) unless opts[:from].user != self + else + Post.where(:_id.in => self.visible_post_ids) + end + end + + def visible_posts( opts = {} ) + if opts[:by_members_of] + return raw_visible_posts if opts[:by_members_of] == :all + group = self.groups.find_by_id( opts[:by_members_of].id ) + group.posts + end + end + + def visible_person_by_id( id ) + id = id.to_id + return self.person if id == self.person.id + result = friends.detect{|x| x.id == id } + result = visible_people.detect{|x| x.id == id } unless result + result + end + + def group_by_id( id ) + id = id.to_id + groups.detect{|x| x.id == id } + end + + def album_by_id( id ) + id = id.to_id + albums.detect{|x| x.id == id } + end + + def groups_with_post( id ) + self.groups.find_all_by_post_ids( id.to_id ) + end + + def groups_with_person person + id = person.id.to_id + groups.select { |g| g.person_ids.include? id} + end + + def people_in_groups groups + people = [] + groups.each{ |group| + people = people | group.people + } + people + end + + def all_group_ids + self.groups.all.collect{|x| x.id} + end + end + end +end diff --git a/lib/encryptable.rb b/lib/encryptable.rb index 17d8ab0c7..4c39a129e 100644 --- a/lib/encryptable.rb +++ b/lib/encryptable.rb @@ -28,5 +28,6 @@ Rails.logger.debug("Signing #{signable_string}") Base64.encode64(key.sign "SHA", signable_string) end + end diff --git a/lib/encryptor.rb b/lib/encryptor.rb new file mode 100644 index 000000000..d80aecb15 --- /dev/null +++ b/lib/encryptor.rb @@ -0,0 +1,59 @@ +module Encryptor + module Public + def encrypt cleartext + aes_key = gen_aes_key + ciphertext = aes_encrypt(cleartext, aes_key) + encrypted_key = encrypt_aes_key aes_key + cipher_hash = {:aes_key => encrypted_key, :ciphertext => ciphertext} + Base64.encode64( cipher_hash.to_json ) + end + + def gen_aes_key + cipher = OpenSSL::Cipher.new('AES-256-CBC') + key = cipher.random_key + iv = cipher.random_iv + {'key' => Base64.encode64(key), 'iv' => Base64.encode64(iv)} + end + + def aes_encrypt(txt, key) + cipher = OpenSSL::Cipher.new('AES-256-CBC') + cipher.encrypt + cipher.key = Base64.decode64 key['key'] + cipher.iv = Base64.decode64 key['iv'] + ciphertext = '' + ciphertext << cipher.update(txt) + ciphertext << cipher.final + Base64.encode64 ciphertext + end + + def encrypt_aes_key key + Base64.encode64 encryption_key.public_encrypt( key.to_json ) + end + end + + module Private + def decrypt cipher_json + json = JSON.parse(Base64.decode64 cipher_json) + aes_key = get_aes_key json['aes_key'] + aes_decrypt(json['ciphertext'], aes_key) + end + + def get_aes_key encrypted_key + clear_key = encryption_key.private_decrypt( Base64.decode64 encrypted_key ) + JSON::parse(clear_key) + end + + def aes_decrypt(ciphertext, key) + cipher = OpenSSL::Cipher.new('AES-256-CBC') + cipher.decrypt + cipher.key = Base64.decode64 key['key'] + cipher.iv = Base64.decode64 key['iv'] + txt = '' + txt << cipher.update(Base64.decode64 ciphertext) + txt << cipher.final + txt + end + + + end +end diff --git a/lib/hcard.rb b/lib/hcard.rb new file mode 100644 index 000000000..e8c1c2110 --- /dev/null +++ b/lib/hcard.rb @@ -0,0 +1,8 @@ +module HCard + def self.find url + doc = Nokogiri::HTML(Net::HTTP.get URI.parse(url)) + {:given_name => doc.css(".given_name").text, + :family_name => doc.css(".family_name").text, + :url => doc.css("#pod_location").text} + end +end diff --git a/lib/net/curl.rb b/lib/net/curl.rb deleted file mode 100644 index 4220a27f7..000000000 --- a/lib/net/curl.rb +++ /dev/null @@ -1,10 +0,0 @@ -class Curl - def self.post(s) - `curl -X POST -d #{s}`;; - end - - def self.get(s) - `curl -X GET #{s}` - end -end - diff --git a/lib/salmon/salmon.rb b/lib/salmon/salmon.rb index a20f35796..c1e14c021 100644 --- a/lib/salmon/salmon.rb +++ b/lib/salmon/salmon.rb @@ -35,8 +35,9 @@ end # Verify documents secured with Magic Signatures module Salmon + class SalmonSlap - attr_accessor :magic_sig, :user, :data, :data_type, :sig + attr_accessor :magic_sig, :author, :author_email, :data, :data_type, :sig def self.parse(xml) slap = self.new doc = Nokogiri::XML(xml) @@ -57,15 +58,15 @@ module Salmon raise ArgumentError, "Magic Signature data must be signed with RSA-SHA256, was #{slap.magic_sig.alg}" unless 'RSA-SHA256' == slap.magic_sig.alg + uri = doc.search('uri').text + slap.author_email = uri.split("acct:").last slap end - - def self.create(user, activity) salmon = self.new - salmon.user = user - salmon.magic_sig = MagicSigEnvelope.create(user, activity) + salmon.author = user.person + salmon.magic_sig = MagicSigEnvelope.create(user , activity) salmon end @@ -74,8 +75,8 @@ module Salmon - #{@user.real_name} - acct:#{@user.email} + #{@author.real_name} + acct:#{@author.email} #{@magic_sig.to_xml} @@ -83,6 +84,17 @@ ENTRY end + def author + if @author + @author + else + Person.by_webfinger @author_email + end + end + + + + # Decode URL-safe-Base64. This implements def self.decode64url(str) # remove whitespace @@ -153,15 +165,10 @@ ENTRY key end - - - - - end class MagicSigEnvelope - attr_accessor :data, :data_type, :encoding, :alg, :sig, :user + attr_accessor :data, :data_type, :encoding, :alg, :sig, :author def self.parse(doc) env = self.new ns = {'me'=>'http://salmon-protocol.org/ns/magic-env'} @@ -175,7 +182,7 @@ ENTRY def self.create(user, activity) env = MagicSigEnvelope.new - env.user = user + env.author = user.person env.data = Base64.urlsafe_encode64(activity) env.data_type = env.get_data_type env.encoding = env.get_encoding diff --git a/spec/controllers/publics_controller_spec.rb b/spec/controllers/publics_controller_spec.rb index cc6bd85b5..cc9f3064d 100644 --- a/spec/controllers/publics_controller_spec.rb +++ b/spec/controllers/publics_controller_spec.rb @@ -5,7 +5,6 @@ describe PublicsController do before do @user = Factory.create(:user) - @user.person.save sign_in :user, @user end @@ -16,11 +15,17 @@ describe PublicsController do end it 'should accept a post from another node and save the information' do - person = Factory.create(:person) - message = StatusMessage.new(:message => 'foo', :person => person) - StatusMessage.all.count.should be 0 - post :receive, :id => @user.person.id, :xml => message.to_diaspora_xml - StatusMessage.all.count.should be 1 + user2 = Factory.create(:user) + message = user2.build_post(:status_message, :message => "hi") + + @user.reload + @user.visible_post_ids.include?(message.id).should be false + xml = @user.person.encrypt(user2.salmon(message, :to => @user.person).to_xml) + + post :receive, :id => @user.person.id, :xml => xml + + @user.reload + @user.visible_post_ids.include?(message.id).should be true end end @@ -28,15 +33,13 @@ describe PublicsController do describe 'friend requests' do before do @user2 = Factory.create(:user) - @user2.person.save group = @user2.group(:name => 'disciples') @user3 = Factory.create(:user) - @user3.person.save - req = @user2.send_friend_request_to(@user.person.url, group.id) + req = @user2.send_friend_request_to(@user.person, group) - @xml = req.to_diaspora_xml + @xml = @user.person.encrypt(@user2.salmon(req, :to => @user.person).to_xml) req.delete @user2.reload @@ -51,6 +54,7 @@ describe PublicsController do end it 'should add the pending request to the right user if the target person does not exist locally' do + Person.should_receive(:by_webfinger).with(@user2.person.email).and_return(@user2.person) @user2.person.delete @user2.delete post :receive, :id => @user.person.id, :xml => @xml diff --git a/spec/controllers/requests_controller_spec.rb b/spec/controllers/requests_controller_spec.rb index 579ee620e..f6ddb849a 100644 --- a/spec/controllers/requests_controller_spec.rb +++ b/spec/controllers/requests_controller_spec.rb @@ -2,14 +2,15 @@ require File.dirname(__FILE__) + '/../spec_helper' include ApplicationHelper include RequestsHelper describe RequestsController do - before do + render_views + before do + @user = Factory.create :user @tom = Redfinger.finger('tom@tom.joindiaspora.com') @evan = Redfinger.finger('evan@status.net') @max = Redfinger.finger('mbs348@gmail.com') + sign_in :user, @user + 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 - 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 diff --git a/spec/lib/diaspora_parser_spec.rb b/spec/lib/diaspora_parser_spec.rb index 5197080dc..3d4dc3727 100644 --- a/spec/lib/diaspora_parser_spec.rb +++ b/spec/lib/diaspora_parser_spec.rb @@ -51,10 +51,10 @@ describe Diaspora::Parser do person = Factory.create(:person) message = Factory.create(:status_message, :person => person) retraction = Retraction.for(message) - request = retraction.to_diaspora_xml + xml = retraction.to_diaspora_xml StatusMessage.count.should == 1 - @user.receive request + @user.receive xml StatusMessage.count.should == 0 end @@ -96,7 +96,7 @@ describe Diaspora::Parser do end it "should activate the Person if I initiated a request to that url" do - request = @user.send_friend_request_to( @user2.receive_url, @group.id) + request = @user.send_friend_request_to( @user2.person, @group) request.reverse_for @user2 @@ -118,7 +118,7 @@ describe Diaspora::Parser do it 'should process retraction for a person' do person_count = Person.all.count - request = @user.send_friend_request_to( @user2.receive_url, @group.id) + request = @user.send_friend_request_to( @user2.person, @group) request.reverse_for @user2 xml = request.to_diaspora_xml diff --git a/spec/lib/hcard_spec.rb b/spec/lib/hcard_spec.rb new file mode 100644 index 000000000..6092e4dab --- /dev/null +++ b/spec/lib/hcard_spec.rb @@ -0,0 +1,12 @@ +require File.dirname(__FILE__) + '/../spec_helper' +require File.dirname(__FILE__) + '/../../lib/hcard' + +describe HCard do + it 'should retreive and parse an hcard' do + f = Redfinger.finger('tom@tom.joindiaspora.com') + hcard = HCard.find f.hcard.first[:href] + hcard[:family_name].include?("Hamiltom").should be true + hcard[:given_name].include?("Alex").should be true + hcard[:url].should == "http://tom.joindiaspora.com/" + end +end diff --git a/spec/lib/salmon_salmon_spec.rb b/spec/lib/salmon_salmon_spec.rb index 49ffa483d..de85fe838 100644 --- a/spec/lib/salmon_salmon_spec.rb +++ b/spec/lib/salmon_salmon_spec.rb @@ -1,41 +1,49 @@ require File.dirname(__FILE__) + '/../spec_helper' - - -require 'lib/salmon/salmon' -include ApplicationHelper -include Salmon - - - describe Salmon do - it 'should verify the signature on a roundtrip' do + before do + @user = Factory.create :user @post = @user.post :status_message, :message => "hi", :to => @user.group(:name => "sdg").id - x = Salmon::SalmonSlap.create(@user, @post.to_diaspora_xml) - - z = Salmon::SalmonSlap.parse x.to_xml - - x.magic_sig.data.should == z.magic_sig.data - - x.magic_sig.sig.should == z.magic_sig.sig - x.magic_sig.signable_string.should == z.magic_sig.signable_string - - - x.verified_for_key?(OpenSSL::PKey::RSA.new(@user.exported_key)).should be true - z.verified_for_key?(OpenSSL::PKey::RSA.new(@user.exported_key)).should be true + @sent_salmon = Salmon::SalmonSlap.create(@user, @post.to_diaspora_xml) + @parsed_salmon = Salmon::SalmonSlap.parse @sent_salmon.to_xml end + it 'should verify the signature on a roundtrip' do + + @sent_salmon.magic_sig.data.should == @parsed_salmon.magic_sig.data + + @sent_salmon.magic_sig.sig.should == @parsed_salmon.magic_sig.sig + @sent_salmon.magic_sig.signable_string.should == @parsed_salmon.magic_sig.signable_string + + + @parsed_salmon.verified_for_key?(OpenSSL::PKey::RSA.new(@user.exported_key)).should be true + @sent_salmon.verified_for_key?(OpenSSL::PKey::RSA.new(@user.exported_key)).should be true + end it 'should return the data so it can be "received"' do - @user = Factory.create :user - @post = @user.post :status_message, :message => "hi", :to => @user.group(:name => "sdg").id - x = Salmon::SalmonSlap.create(@user, @post.to_diaspora_xml) - z = Salmon::SalmonSlap.parse x.to_xml - xml = @post.to_diaspora_xml - z.data.should == xml + @parsed_salmon.data.should == xml end + + it 'should parse out the author email' do + @parsed_salmon.author_email.should == @user.person.email + end + + it 'should reference a local author' do + @parsed_salmon.author.should == @user.person + end + + it 'should reference a remote author' do + @parsed_salmon.author_email = 'tom@tom.joindiaspora.com' + @parsed_salmon.author.public_key.should_not be_nil + end + + it 'should fail to reference a nonexistent remote author' do + @parsed_salmon.author_email = 'idsfug@difgubhpsduh.rgd' + proc {@parsed_salmon.author.real_name}.should raise_error /not found/ + end + end diff --git a/spec/lib/web_hooks_spec.rb b/spec/lib/web_hooks_spec.rb index fa661049b..43f55b4d7 100644 --- a/spec/lib/web_hooks_spec.rb +++ b/spec/lib/web_hooks_spec.rb @@ -6,8 +6,11 @@ describe Diaspora do describe Webhooks do before do - @user = Factory.create(:user, :email => "bob@aol.com") + @user = Factory.create(:user) @group = @user.group(:name => "losers") + @user2 = Factory.create(:user) + @group2 = @user2.group(:name => "losers") + friend_users(@user, @group, @user2, @group2) end describe "body" do @@ -19,16 +22,6 @@ describe Diaspora do @post.respond_to?(:to_diaspora_xml).should be true end - it "should send an owners post to their people" do - message_queue.should_receive :process - @user.post :status_message, :message => "hi", :to => @group.id - end - - it "should check that it does not send a person's post to an owners people" do - message_queue.should_not_receive(:add_post_request) - Factory.create(:status_message, :person => Factory.create(:person)) - end - end end end diff --git a/spec/models/comments_spec.rb b/spec/models/comments_spec.rb index 95d2c977c..d442b22b3 100644 --- a/spec/models/comments_spec.rb +++ b/spec/models/comments_spec.rb @@ -28,56 +28,78 @@ describe Comment do it 'should not send out comments when we have no people' do status = Factory.create(:status_message, :person => @user.person) - message_queue.should_not_receive(:add_post_request) + User::QUEUE.should_not_receive(:add_post_request) @user.comment "sup dog", :on => status end describe 'comment propagation' do before do + friend_users(@user, Group.first(:id => @group.id), @user2, @group2) - - 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.activate_friend(@person, Group.first(:id => @group.id)) + @person2 = Factory.create(:person) @person_status = Factory.build(:status_message, :person => @person) - @user_status = Factory.build(:status_message, :person => @user.person) + + @user.reload + @user_status = @user.post :status_message, :message => "hi", :to => @group.id + + @group.reload + @user.reload end + it 'should have the post in the groups post list' do + group = Group.first(:id => @group.id) + group.people.size.should == 2 + group.post_ids.include?(@user_status.id).should be true + end + it "should send a user's comment on a person's post to that person" do - message_queue.should_receive(:add_post_request) + User::QUEUE.should_receive(:add_post_request) @user.comment "yo", :on => @person_status end it 'should send a user comment on his own post to lots of people' do - allowed_urls = @user.friends.map!{ |x| x = x.receive_url } - message_queue.should_receive(:add_post_request).with(allowed_urls, anything) + + User::QUEUE.should_receive(:add_post_request).twice @user.comment "yo", :on => @user_status end it 'should send a comment a person made on your post to all people' do - message_queue.should_receive(:add_post_request) comment = Comment.new(:person_id => @person.id, :text => "balls", :post => @user_status) + User::QUEUE.should_receive(:add_post_request).twice @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 + + it 'should send a comment a user made on your post to all people' do + comment = @user2.comment( "balls", :on => @user_status) + User::QUEUE.should_receive(:add_post_request).twice @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) + User::QUEUE.should_not_receive(:add_post_request) 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) + User::QUEUE.should_not_receive(:add_post_request) comment = Comment.new(:person_id => @person2.id, :text => "balls", :post => @person_status) @user.receive(comment.to_diaspora_xml) end + + it 'should not clear the group post array on receiving a comment' do + @group.post_ids.include?(@user_status.id).should be true + comment = Comment.new(:person_id => @person.id, :text => "balls", :post => @user_status) + + @user.receive(comment.to_diaspora_xml) + + @group.reload + @group.post_ids.include?(@user_status.id).should be true + end end describe 'serialization' do it 'should serialize the commenter' do diff --git a/spec/models/person_spec.rb b/spec/models/person_spec.rb index 319e2b956..fc203d593 100644 --- a/spec/models/person_spec.rb +++ b/spec/models/person_spec.rb @@ -60,7 +60,7 @@ describe Person do describe "unfriending" do it 'should delete an orphaned friend' do - request = @user.send_friend_request_to @person.receive_url, @group.id + request = @user.send_friend_request_to @person, @group @user.activate_friend(@person, @group) @user.reload @@ -74,8 +74,8 @@ describe Person do end it 'should not delete an un-orphaned friend' do - request = @user.send_friend_request_to @person.receive_url, @group.id - request2 = @user2.send_friend_request_to @person.receive_url, @group2.id + request = @user.send_friend_request_to @person, @group + request2 = @user2.send_friend_request_to @person, @group2 @user.activate_friend(@person, @group) @user2.activate_friend(@person, @group2) @@ -144,6 +144,11 @@ describe Person do it 'should search by email exactly' do Person.by_webfinger(@friend_one.email).should == @friend_one end + + it 'should create a stub for a remote user' do + tom = Person.by_webfinger('tom@tom.joindiaspora.com') + tom.real_name.include?("Hamiltom").should be true + end describe 'wall posting' do it 'should be able to post on another persons wall' do diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb index 608c17ba7..a1c391657 100644 --- a/spec/models/post_spec.rb +++ b/spec/models/post_spec.rb @@ -7,10 +7,14 @@ describe Post do end describe 'xml' do - it 'should serialize to xml with its person' do - message = Factory.create(:status_message, :person => @user.person) - message.to_xml.to_s.include?(@user.person.email).should == true + before do + @message = Factory.create(:status_message, :person => @user.person) end + + it 'should serialize to xml with its person' do + @message.to_xml.to_s.include?(@user.person.email).should == true + end + end describe 'deletion' do diff --git a/spec/models/request_spec.rb b/spec/models/request_spec.rb index c5b49cc64..b02d6e682 100644 --- a/spec/models/request_spec.rb +++ b/spec/models/request_spec.rb @@ -15,7 +15,7 @@ describe Request do it 'should generate xml for the User as a Person' do - request = @user.send_friend_request_to "http://www.google.com/", @group.id + request = @user.send_friend_request_to Factory.create(:person), @group xml = request.to_xml.to_s diff --git a/spec/models/retraction_spec.rb b/spec/models/retraction_spec.rb index bb344a039..8b6802ea1 100644 --- a/spec/models/retraction_spec.rb +++ b/spec/models/retraction_spec.rb @@ -3,10 +3,10 @@ require File.dirname(__FILE__) + '/../spec_helper' describe Retraction do before do @user = Factory.create(:user) - @post = @user.post :status_message, :message => "Destroy!", :to => @user.group(:name => "losers").id @person = Factory.create(:person) - @user.friends << @person - @user.save + @group = @user.group(:name => "Bruisers") + @user.activate_friend(@person, @group) + @post = @user.post :status_message, :message => "Destroy!", :to => @group.id end describe 'serialization' do it 'should have a post id after serialization' do @@ -18,10 +18,8 @@ describe Retraction do describe 'dispatching' do it 'should dispatch a message on delete' do Factory.create(:person) - message_queue.should_receive(:add_post_request) + User::QUEUE.should_receive :add_post_request @post.destroy end end - - end diff --git a/spec/models/user/posting_spec.rb b/spec/models/user/posting_spec.rb index 0589de13e..2365912da 100644 --- a/spec/models/user/posting_spec.rb +++ b/spec/models/user/posting_spec.rb @@ -2,10 +2,53 @@ require File.dirname(__FILE__) + '/../../spec_helper' describe User do before do - @user = Factory.create(:user) - @group = @user.group(:name => 'heroes') + @user = Factory.create :user + @group = @user.group(:name => 'heroes') + @group1 = @user.group(:name => 'heroes') + + @user2 = Factory.create(:user) + @group2 = @user2.group(:name => 'losers') + + @user3 = Factory.create(:user) + @group3 = @user3.group(:name => 'heroes') + + @user4 = Factory.create(:user) + @group4 = @user4.group(:name => 'heroes') + + friend_users(@user, @group, @user2, @group2) + friend_users(@user, @group, @user3, @group3) + friend_users(@user, @group1, @user4, @group4) end + it 'should not be able to post without a group' do proc {@user.post(:status_message, :message => "heyheyhey")}.should raise_error /You must post to someone/ end + + it 'should put the post in the group post array' do + post = @user.post(:status_message, :message => "hey", :to => @group.id) + @group.reload + @group.post_ids.include?(post.id).should be true + end + + describe 'dispatching' do + before do + @post = @user.build_post :status_message, :message => "hey" + end + it 'should push a post to a group' do + @user.should_receive(:salmon).twice + @user.push_to_groups(@post, @group.id) + end + + it 'should push a post to all groups' do + @user.should_receive(:salmon).exactly(3).times + @user.push_to_groups(@post, :all) + end + + it 'should push to people' do + @user.should_receive(:salmon).twice + @user.push_to_people(@post, [@user2.person, @user3.person]) + end + + + end end diff --git a/spec/models/user/receive_spec.rb b/spec/models/user/receive_spec.rb index 74ddfb882..4d2827545 100644 --- a/spec/models/user/receive_spec.rb +++ b/spec/models/user/receive_spec.rb @@ -165,4 +165,16 @@ describe User do @user3.visible_person_by_id(commenter_id).should_not be_nil end end + + describe 'salmon' do + before do + @post = @user.post :status_message, :message => "hello", :to => @group.id + @salmon = @user.salmon( @post, :to => @user2.person ) + end + + it 'should receive a salmon for a post' do + @user2.receive_salmon( @user2.person.encrypt(@salmon.to_xml) ) + @user2.visible_post_ids.include?(@post.id).should be true + end + end end diff --git a/spec/models/user/user_friending_spec.rb b/spec/models/user/user_friending_spec.rb index 6bf4c1117..50e5817fc 100644 --- a/spec/models/user/user_friending_spec.rb +++ b/spec/models/user/user_friending_spec.rb @@ -12,7 +12,7 @@ describe User do group = @user.group(:name => "Dudes") group.requests.size.should == 0 - @user.send_friend_request_to(friend.receive_url, group.id) + @user.send_friend_request_to(friend, group) group.reload group.requests.size.should == 1 @@ -48,7 +48,7 @@ describe User do @user.save - proc {@user.send_friend_request_to( friend.receive_url, @group.id )}.should raise_error + proc {@user.send_friend_request_to( friend, @group)}.should raise_error end @@ -183,7 +183,7 @@ describe User do @user2 = Factory.create :user @group2 = @user2.group(:name => "Gross people") - request = @user.send_friend_request_to( @user2.receive_url, @group.id) + request = @user.send_friend_request_to( @user2, @group) request.reverse_for @user2 @user2.activate_friend(@user.person, @group2) @user.receive request.to_diaspora_xml diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 548966548..54dfe9632 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -12,8 +12,6 @@ describe User do updated_profile = {:profile => {:first_name => 'bob', :last_name => 'billytown', :image_url => "http://clown.com"}} - message_queue.should_receive(:process) - @user.update_profile(updated_profile).should == true @user.profile.image_url.should == "http://clown.com" end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ff5cb46f3..3c5526e0d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -62,7 +62,7 @@ end end def friend_users(user1, group1, user2, group2) - request = user1.send_friend_request_to(user2.receive_url, group1.id) + request = user1.send_friend_request_to(user2.person, group1) reversed_request = user2.accept_friend_request( request.id, group2.id) user1.receive reversed_request.to_diaspora_xml end diff --git a/spec/user_encryption_spec.rb b/spec/user_encryption_spec.rb index 9432ac07b..99ddcc4ca 100644 --- a/spec/user_encryption_spec.rb +++ b/spec/user_encryption_spec.rb @@ -32,7 +32,7 @@ describe 'user encryption' do describe 'key exchange on friending' do it 'should send over a public key' do message_queue.stub!(:add_post_request) - request = @user.send_friend_request_to("http://example.com/", @group.id) + request = @user.send_friend_request_to(Factory.create(:person), @group) request.to_diaspora_xml.include?( @user.exported_key).should be true end @@ -44,7 +44,7 @@ describe 'user encryption' do original_key = remote_user.exported_key request = remote_user.send_friend_request_to( - @user.receive_url, remote_user.group(:name => "temp").id) + @user.person, remote_user.group(:name => "temp")) xml = request.to_diaspora_xml @@ -59,82 +59,20 @@ describe 'user encryption' do end end - describe 'signing and verifying' do - - it 'should sign a message on create' do - message = @user.post :status_message, :message => "hi", :to => @group.id - message.signature_valid?.should be true + describe 'encryption' do + before do + @message = @user.post :status_message, :message => "hi", :to => @group.id end - - it 'should sign a retraction on create' do - - unstub_mocha_stubs - message = @user.post :status_message, :message => "hi", :to => @group.id - - - retraction = @user.retract(message) - retraction.signature_valid?.should be true - - end - - it 'should not be able to verify a message from a person without a key' do - person = Factory.create(:person, :serialized_key => "lskdfhdlfjnh;klsf") - message = Factory.build(:status_message, :person => person) - message.save(:validate => false) - lambda {message.signature_valid?.should be false}.should raise_error - end - - it 'should verify a remote signature' do - message = Factory.build(:status_message, :person => @person) - message.creator_signature = message.send(:sign_with_key,@person.encryption_key) - message.save(:validate => false) - message.signature_valid?.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.creator_signature = message.send(:sign_with_key,@person.encryption_key) - message.person = @user - message.signature_valid?.should be false - end - - it 'should know if the signature is for the wrong text' do - message = Factory.build(:status_message, :person => @person) - message.creator_signature = message.send(:sign_with_key,@person.encryption_key) - message.message = 'I love VENISON' - message.save(:validate => false) - message.signature_valid?.should be false + it 'should encrypt large messages' do + ciphertext = @user.encrypt @message.to_diaspora_xml + ciphertext.include?(@message.to_diaspora_xml).should be false + @user.decrypt(ciphertext).include?(@message.to_diaspora_xml).should be true end end - describe 'sending and recieving signatures' do - it 'should contain the signature in the xml' do - message = @user.post :status_message, :message => "hi", :to => @group.id - xml = message.to_xml.to_s - xml.include?(message.creator_signature).should be true - end - - it 'A message with an invalid signature should be rejected' do - @user2 = Factory.create :user - - message = @user2.post :status_message, :message => "hey", :to => @user2.group(:name => "bruisers").id - message.creator_signature = "totally valid" - message.save(:validate => false) - - xml = message.to_diaspora_xml - message.destroy - Post.count.should be 0 - proc {@user.receive xml}.should raise_error /ignature was not valid/ - Post.count.should be 0 - end - - end describe 'comments' do before do - @remote_message = Factory.build(:status_message, :person => @person) - @remote_message.creator_signature = @remote_message.send(:sign_with_key,@person.encryption_key) - @remote_message.save + @remote_message = Factory.create(:status_message, :person => @person) @message = @user.post :status_message, :message => "hi", :to => @group.id end it 'should attach the creator signature if the user is commenting' do