diff --git a/app/controllers/publics_controller.rb b/app/controllers/publics_controller.rb index 1b05532f9..acbe5e814 100644 --- a/app/controllers/publics_controller.rb +++ b/app/controllers/publics_controller.rb @@ -18,8 +18,9 @@ class PublicsController < ApplicationController end def receive + user = Person.first(:id => params[:id]).owner Rails.logger.debug "PublicsController has received: #{params[:xml]}" - store_objects_from_xml params[:xml] + store_objects_from_xml params[:xml], user render :nothing => true end diff --git a/app/helpers/requests_helper.rb b/app/helpers/requests_helper.rb index 4404ec223..99f73be66 100644 --- a/app/helpers/requests_helper.rb +++ b/app/helpers/requests_helper.rb @@ -29,7 +29,6 @@ module RequestsHelper f = Redfinger.finger(identifier) action = subscription_mode(f) url = subscription_url(action, f) - { action => url } end diff --git a/app/models/person.rb b/app/models/person.rb index e10a4bbfb..f633d04c7 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -5,7 +5,6 @@ class Person xml_accessor :_id xml_accessor :email xml_accessor :url - xml_accessor :serialized_key xml_accessor :profile, :as => Profile @@ -29,7 +28,7 @@ class Person before_validation :clean_url - validates_presence_of :email, :url, :serialized_key, :profile + validates_presence_of :email, :url, :profile, :serialized_key validates_format_of :url, :with => /^(https?):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*(\.[a-z]{2,5})?(:[0-9]{1,5})?(\/.*)?$/ix diff --git a/app/models/request.rb b/app/models/request.rb index 1db410bbc..d55d1efb8 100644 --- a/app/models/request.rb +++ b/app/models/request.rb @@ -44,8 +44,8 @@ class Request end #ENCRYPTION - before_validation :sign_if_mine - validates_true_for :creator_signature, :logic => lambda {self.verify_creator_signature} + #before_validation :sign_if_mine + #validates_true_for :creator_signature, :logic => lambda {self.verify_creator_signature} xml_accessor :creator_signature key :creator_signature, String diff --git a/app/models/user.rb b/app/models/user.rb index 794c7970a..c6f7e5476 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -5,12 +5,12 @@ class User :recoverable, :rememberable, :trackable, :validatable key :friend_ids, Array - key :pending_friend_ids, Array + key :pending_request_ids, Array one :person, :class_name => 'Person', :foreign_key => :owner_id many :friends, :in => :friend_ids, :class_name => 'Person' - many :pending_friends, :in => :pending_friend_ids, :class_name => 'Person' + many :pending_requests, :in => :pending_request_ids, :class_name => 'Request' many :groups, :class_name => 'Group' @@ -39,9 +39,12 @@ class User ######### Friend Requesting ########### def send_friend_request_to(friend_url) - unless self.friends.find{ |x| x.url == friend_url} + + unless self.friends.detect{ |x| x.url == friend_url} p = Request.instantiate(:to => friend_url, :from => self.person) if p.save + self.pending_requests << p + self.save p.push_to_url friend_url end p @@ -50,7 +53,7 @@ class User def accept_friend_request(friend_request_id) request = Request.where(:id => friend_request_id).first - n = pending_friends.delete(request.person) + n = pending_requests.delete(request) friends << request.person save @@ -65,7 +68,8 @@ class User def ignore_friend_request(friend_request_id) request = Request.first(:id => friend_request_id) person = request.person - pending_friends.delete(request.person) + pending_requests.delete(request) + save person.destroy unless person.user_refs > 0 request.destroy end @@ -80,7 +84,7 @@ class User friend_request.destroy else friend_request.person.save - pending_friends << friend_request.person + pending_requests << friend_request save Rails.logger.debug("#{self.real_name} has received a friend request") friend_request.save diff --git a/config/routes.rb b/config/routes.rb index 8d0cd5c01..50811fa73 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -26,7 +26,7 @@ Diaspora::Application.routes.draw do |map| #public routes - match 'receive', :to => 'publics#receive' + match 'receive/users/:id', :to => 'publics#receive' match '.well-known/host-meta',:to => 'publics#host_meta' match 'webfinger', :to => 'publics#webfinger' match 'hcard', :to => 'publics#hcard' diff --git a/lib/diaspora/parser.rb b/lib/diaspora/parser.rb index 9feb07cdc..719264f2f 100644 --- a/lib/diaspora/parser.rb +++ b/lib/diaspora/parser.rb @@ -27,6 +27,13 @@ module Diaspora person = parse_owner_id_from_xml post person.profile = object person.save + elsif object.is_a? Request + person_string = Nokogiri::XML(xml) { |cfg| cfg.noblanks }.xpath("/XML/posts/post/request/person").to_s + person = Person.from_xml person_string + person.serialized_key ||= object.exported_key + object.person = person + object.person.save + elsif object.respond_to? :person object.person = parse_owner_from_xml post.to_s end @@ -42,7 +49,7 @@ module Diaspora objects end - def store_objects_from_xml(xml) + def store_objects_from_xml(xml, user) objects = parse_objects_from_xml(xml) objects.each do |p| Rails.logger.debug("Receiving object:\n#{p.inspect}") @@ -50,7 +57,7 @@ module Diaspora Rails.logger.debug "Got a retraction for #{p.post_id}" p.perform elsif p.is_a? Request - User.owner.receive_friend_request(p) + user.receive_friend_request(p) elsif p.is_a? Profile p.save elsif p.respond_to?(:person) && !(p.person.nil?) && !(p.person.is_a? User) diff --git a/spec/controllers/publics_controller_spec.rb b/spec/controllers/publics_controller_spec.rb index 5b84098a4..e63601d6a 100644 --- a/spec/controllers/publics_controller_spec.rb +++ b/spec/controllers/publics_controller_spec.rb @@ -10,15 +10,49 @@ describe PublicsController do end describe 'receive endpoint' do - - it 'should accept a post from anohter node and save the information' do - + it 'should have a and endpoint and return a 200 on successful receipt of a request' do + post :receive, :id =>@user.person.id + response.code.should == '200' + end + + it 'should accept a post from another node and save the information' do + pending person = Factory.create(:person) message = StatusMessage.new(:message => 'foo', :person => person) - StatusMessage.all.count.should == 0 - post :receive, {:xml => Post.build_xml_for(message)} - StatusMessage.all.count.should == 1 + StatusMessage.all.count.should be 0 + post :receive, :id => @user.person.id, :xml => Post.build_xml_for(message) + StatusMessage.all.count.should be 1 end end + + describe 'friend requests' do + before do + @user2 = Factory.create(:user) + @user2.person.save + + req = Request.instantiate(:from => @user2.person, :to => @user.person.url) + @xml = Request.build_xml_for [req] + + req.delete + end + + it 'should save requests for the specified user (LOCAL)' do + post :receive, :id => @user.person.id, :xml => @xml + + @user.reload + @user.pending_requests.size.should be 1 + end + + it 'should save requests for the specified user (REMOTE)' do + @user2.person.delete + @user2.delete + post :receive, :id => @user.person.id, :xml => @xml + + @user.reload + @user.pending_requests.size.should be 1 + end + + + end end diff --git a/spec/lib/diaspora_parser_spec.rb b/spec/lib/diaspora_parser_spec.rb index 91fdd5d99..f4cd09cc9 100644 --- a/spec/lib/diaspora_parser_spec.rb +++ b/spec/lib/diaspora_parser_spec.rb @@ -6,14 +6,14 @@ include Diaspora::Parser describe Diaspora::Parser do before do @user = Factory.create(:user, :email => "bob@aol.com") - @person = Factory.create(:person, :email => "bill@gates.com") + @person = Factory.create(:person_with_private_key, :email => "bill@gates.com") end it "should not store posts from me" do status_messages = [] 10.times { status_messages << Factory.build(:status_message, :person => @user)} xml = Post.build_xml_for(status_messages) - store_objects_from_xml(xml) + store_objects_from_xml(xml, @user) StatusMessage.count.should == 0 end @@ -25,7 +25,7 @@ describe Diaspora::Parser do \n HEY DUDE\n a@a.com\n a@a.com\n a@a.com\n " - store_objects_from_xml(xml) + store_objects_from_xml(xml, @user) Post.count.should == 0 end @@ -41,7 +41,7 @@ describe Diaspora::Parser do \n HEY DUDE\n a@a.com\n a@a.com\n a@a.com\n " - store_objects_from_xml(xml) + store_objects_from_xml(xml, @user) Post.count.should == 0 end @@ -56,7 +56,7 @@ describe Diaspora::Parser do " - store_objects_from_xml(xml) + store_objects_from_xml(xml, @user) Post.count.should == 0 end @@ -107,7 +107,7 @@ describe Diaspora::Parser do request = Post.build_xml_for( [retraction] ) StatusMessage.count.should == 1 - store_objects_from_xml( request ) + store_objects_from_xml( request, @user ) StatusMessage.count.should == 0 end @@ -116,15 +116,32 @@ describe Diaspora::Parser do original_person_id = @person.id xml = Request.build_xml_for [request] - + @person.destroy Person.all.count.should be 1 - store_objects_from_xml(xml) + store_objects_from_xml(xml, @user) Person.all.count.should be 2 Person.where(:url => request.callback_url).first.id.should == original_person_id end + it "should not create a new person if the person is already here" do + @user2 = Factory.create(:user) + request = Request.instantiate(:to =>"http://www.google.com/", :from => @user2.person) + + original_person_id = @user2.person.id + xml = Request.build_xml_for [request] + + + Person.all.count.should be 3 + store_objects_from_xml(xml, @user) + Person.all.count.should be 3 + + @user2.reload + @user2.person.serialized_key.include?("PRIVATE").should be true + + Person.where(:url => request.callback_url).first.id.should == original_person_id + end it "should activate the Person if I initiated a request to that url" do request = Request.instantiate(:to => @person.url, :from => @user).save @@ -139,7 +156,7 @@ describe Diaspora::Parser do @person.destroy request_remote.destroy - store_objects_from_xml(xml) + store_objects_from_xml(xml, @user) new_person = Person.first(:url => @person.url) new_person.nil?.should be false @user.reload @@ -152,7 +169,7 @@ describe Diaspora::Parser do request = Retraction.build_xml_for( [retraction] ) Person.count.should == 2 - store_objects_from_xml( request ) + store_objects_from_xml( request , @user) Person.count.should == 1 end @@ -178,7 +195,7 @@ describe Diaspora::Parser do old_profile.first_name.should == 'bob' #Marshal profile - store_objects_from_xml xml + store_objects_from_xml xml, @user #Check that marshaled profile is the same as old profile person = Person.first(:id => person.id) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index c7435cf03..bcc977505 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -39,6 +39,10 @@ describe User do it 'should not be able to friend request an existing friend' do friend = Factory.create(:person) + + @user.friends << friend + @user.save + @user.send_friend_request_to( friend.url ).should be nil end @@ -52,27 +56,27 @@ describe User do it 'should get the pending friends' do person_one = Factory.create :person person_two = Factory.create :person - @user.pending_friends.empty?.should be true + @user.pending_requests.empty?.should be true @user.friends.empty?.should be true request = Request.instantiate(:to => @user.url, :from => person_one) person_one.destroy @user.receive_friend_request request - @user.pending_friends.size.should be 1 + @user.pending_requests.size.should be 1 @user.friends.size.should be 0 request_two = Request.instantiate(:to => @user.url, :from => person_two) person_two.destroy @user.receive_friend_request request_two - @user.pending_friends.size.should be 2 + @user.pending_requests.size.should be 2 @user.friends.size.should be 0 @user.accept_friend_request request.id - @user.pending_friends.size.should be 1 + @user.pending_requests.size.should be 1 @user.friends.size.should be 1 @user.ignore_friend_request request_two.id - @user.pending_friends.size.should be 0 + @user.pending_requests.size.should be 0 @user.friends.size.should be 1 end end