Skip to content
Extraits de code Groupes Projets
Valider be00a2f1 rédigé par maxwell's avatar maxwell Validation de Raphael
Parcourir les fichiers

webfingering is now syncrounous

parent 9aa093a0
Branches
Étiquettes
Aucune requête de fusion associée trouvée
......@@ -30,7 +30,7 @@ class Retraction
if self.type.constantize.find_by_id(post_id)
unless Post.first(:diaspora_handle => person.diaspora_handle, :id => post_id)
Rails.logger.info("event=retraction status=abort reason='no post found authored by retractor' sender=#{person.diaspora_handle} post_id=#{post_id}")
raise "#{person.inspect} is trying to retract a post that either doesn't exist or is not by them"
return
end
begin
......
......@@ -6,23 +6,25 @@ module Diaspora
def receive_salmon salmon_xml
salmon = Salmon::SalmonSlap.parse salmon_xml, self
webfinger = EMWebfinger.new(salmon.author_email)
webfinger.on_person { |response|
if response.is_a? Person
salmon_author = response
if salmon.verified_for_key?(salmon_author.public_key)
self.receive(salmon.parsed_data, salmon_author)
end
begin
salmon_author = webfinger.fetch
rescue Exception => e
Rails.logger.info("event=receive status=abort recipient=#{self.diaspora_handle} sender=#{salmon.author_email} reason='#{e.message}'")
end
if salmon_author
if salmon.verified_for_key?(salmon_author.public_key)
self.receive(salmon.parsed_data, salmon_author)
else
Rails.logger.info("event=receive status=abort recipient=#{self.diaspora_handle} sender=#{salmon.author_email} reason='#{response}'")
Rails.logger.info("event=receive status=abort recipient=#{self.diaspora_handle} sender=#{salmon.author_email} reason='not_verified for key'")
end
}
end
end
def receive xml, salmon_author
object = Diaspora::Parser.from_xml(xml)
Rails.logger.info("event=receive status=start recipient=#{self.diaspora_handle} payload_type=#{object.class} sender=#{salmon_author.diaspora_handle}")
if object.is_a?(Request)
salmon_author.save
object.sender_handle = salmon_author.diaspora_handle
......@@ -41,17 +43,23 @@ module Diaspora
e = EMWebfinger.new(object.diaspora_handle)
e.on_person do |person|
if person.class == Person
object.person = person if object.respond_to? :person=
unless object.is_a?(Request) || self.contact_for(salmon_author)
Rails.logger.info("event=receive status=abort reason='sender not connected to recipient' recipient=#{self.diaspora_handle} sender=#{salmon_author.diaspora_handle} payload_type=#{object.class}")
return
else
receive_object(object,person)
Rails.logger.info("event=receive status=complete recipient=#{self.diaspora_handle} sender=#{salmon_author.diaspora_handle} payload_type#{object.class}")
return object
end
begin
person = e.fetch
rescue Exception => e
Rails.logger.info("event=receive status=abort reason='#{e.message}' payload_type=#{object.class} recipient=#{self.diaspora_handle} sender=#{salmon_author.diaspora_handle}")
return
end
if person
object.person = person if object.respond_to? :person=
unless object.is_a?(Request) || self.contact_for(salmon_author)
Rails.logger.info("event=receive status=abort reason='sender not connected to recipient' recipient=#{self.diaspora_handle} sender=#{salmon_author.diaspora_handle} payload_type=#{object.class}")
return
else
receive_object(object,person)
Rails.logger.info("event=receive status=complete recipient=#{self.diaspora_handle} sender=#{salmon_author.diaspora_handle} payload_type#{object.class}")
return object
end
end
end
......@@ -102,7 +110,7 @@ module Diaspora
def receive_comment comment
commenter = comment.person
unless comment.post.person == self.person || comment.verify_post_creator_signature
Rails.logger.info("event=receive status=abort reason='comment signature not valid' recipient=#{self.diaspora_handle} sender=#{comment.post.person.diaspora_handle} payload_type=#{comment.class} post_id=#{comment.post_id}")
return
......@@ -136,10 +144,10 @@ module Diaspora
def receive_post post
#exsists locally, but you dont know about it
#does not exsist locally, and you dont know about it
#exsists_locally?
#you know about it, and it is mutable
#you know about it, and it is not mutable
#you know about it, and it is mutable
#you know about it, and it is not mutable
#
on_pod = exsists_on_pod?(post)
if on_pod && on_pod.diaspora_handle == post.diaspora_handle
......
......@@ -7,7 +7,6 @@ class EMWebfinger
OPTS = {:timeout => TIMEOUT, :redirects => REDIRECTS}
def initialize(account)
@account = account.strip.gsub('acct:','').to_s
@callbacks = []
@ssl = true
Rails.logger.info("event=EMWebfinger status=initialized target=#{account}")
# Raise an error if identifier has a port number
......@@ -15,67 +14,53 @@ class EMWebfinger
# Raise an error if identifier is not a valid email (generous regexp)
#raise "Identifier is invalid" if !(@account=~ /^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/)
end
def fetch
if @callbacks.empty?
Rails.logger.info("event=EMWebfinger status=abort target=#{@account} callbacks=empty")
raise 'you need to set a callback before calling fetch'
end
person = Person.by_account_identifier(@account)
if person
Rails.logger.info("event=EMWebfinger status=local target=#{@account}")
process_callbacks person
return person
else
Rails.logger.info("event=EMWebfinger status=remote target=#{@account}")
profile_url = get_xrd
webfinger_profile = get_webfinger_profile(profile_url) if profile_url
fingered_person = make_person_from_webfinger(webfinger_profile) if webfinger_profile
process_callbacks(fingered_person)
profile_url = get_xrd
webfinger_profile = get_webfinger_profile(profile_url)
fingered_person = make_person_from_webfinger(webfinger_profile)
fingered_person
end
end
def on_person(&block)
@callbacks << block
self.fetch
end
private
def get_xrd
begin
http = RestClient.get xrd_url, OPTS
profile_url = webfinger_profile_url(http.body)
if profile_url
return profile_url
else
raise "no profile URL"
end
rescue
if @ssl
@ssl = false
retry
else
process_callbacks I18n.t('webfinger.xrd_fetch_failed', :account => @account)
return
end
end
begin
http = RestClient.get xrd_url, OPTS
profile_url = webfinger_profile_url(http.body)
if profile_url
return profile_url
else
raise "no profile URL"
end
rescue Exception => e
if @ssl
@ssl = false
retry
else
raise e
raise I18n.t('webfinger.xrd_fetch_failed', :account => @account)
end
end
end
def get_webfinger_profile(profile_url)
begin
http = RestClient.get(profile_url, OPTS)
return http.body
rescue Exception => e
puts e.message
process_callbacks I18n.t('webfinger.fetch_failed', :profile_url => profile_url)
return
end
rescue
raise I18n.t('webfinger.fetch_failed', :profile_url => profile_url)
end
return http.body
end
def make_person_from_webfinger(webfinger_profile)
......@@ -86,9 +71,8 @@ class EMWebfinger
begin
hcard = RestClient.get(wf_profile.hcard, OPTS)
rescue
process_callbacks I18n.t('webfinger.hcard_fetch_failed', :account => @account)
return
end
return I18n.t('webfinger.hcard_fetch_failed', :account => @account)
end
card = HCard.build hcard.body
p = Person.build_from_webfinger(wf_profile, card)
......@@ -96,19 +80,6 @@ class EMWebfinger
end
def process_callbacks(person)
Rails.logger.info("event=EMWebfinger status=callbacks_started target=#{@account} response='#{person.is_a?(String) ? person : person.id}'")
@callbacks.each { |c|
begin
c.call(person)
rescue Exception => e
Rails.logger.info("event=EMWebfinger status=error_on_callback error='#{e.inspect}'")
end
}
Rails.logger.info("event=EMWebfinger status=complete target=#{@account}")
end
##helpers
private
......@@ -122,7 +93,7 @@ class EMWebfinger
domain = @account.split('@')[1]
"http#{'s' if @ssl}://#{domain}/.well-known/host-meta"
end
def swizzle(template)
template.gsub '{uri}', @account
end
......
......@@ -42,35 +42,6 @@ describe EMWebfinger do
end
end
describe '#on_person' do
it 'should set a callback' do
n = EMWebfinger.new("mbs@gmail.com")
n.stub(:fetch).and_return(true)
n.on_person{|person| 1+1}
n.instance_variable_get(:@callbacks).count.should be 1
end
it 'should not blow up if the returned xrd is nil' do
http = FakeHttpRequest.new(:success)
fake_account = 'foo@example.com'
http.callbacks = ['']
EventMachine::HttpRequest.should_receive(:new).and_return(http)
n = EMWebfinger.new("foo@example.com")
n.on_person{|person|
person.should == "webfinger does not seem to be enabled for #{fake_account}'s host"
}
end
end
describe '#fetch' do
it 'should require a callback' do
proc{finger.fetch }.should raise_error "you need to set a callback before calling fetch"
end
end
context 'webfinger query chain processing' do
describe '#webfinger_profile_url' do
it 'should parse out the webfinger template' do
......@@ -101,81 +72,31 @@ describe EMWebfinger do
context 'webfingering local people' do
it 'should return a person from the database if it matches its handle' do
person.save
EM.run do
finger.on_person { |p|
p.should == person
EM.stop
}
finger.fetch.id.should == person.id
end
end
it 'should fetch a diaspora webfinger and make a person for them' do
good_request.callbacks = [diaspora_xrd, diaspora_finger, hcard_xml]
diaspora_xrd.stub!(:body).and_return(diaspora_xrd)
hcard_xml.stub!(:body).and_return(hcard_xml)
diaspora_finger.stub!(:body).and_return(diaspora_finger)
RestClient.stub!(:get).and_return(diaspora_xrd, diaspora_finger, hcard_xml)
#new_person = Factory.build(:person, :diaspora_handle => "tom@tom.joindiaspora.com")
# http://tom.joindiaspora.com/.well-known/host-meta
f = EMWebfinger.new("tom@tom.joindiaspora.com")
EventMachine::HttpRequest.should_receive(:new).exactly(3).times.and_return(good_request)
f = EMWebfinger.new("tom@tom.joindiaspora.com").fetch
f.should be_valid
EM.run {
f.on_person{ |p|
p.valid?.should be true
EM.stop
}
}
end
it 'should retry with http if https fails' do
good_request.callbacks = [nil, diaspora_xrd, diaspora_finger, hcard_xml]
#new_person = Factory.build(:person, :diaspora_handle => "tom@tom.joindiaspora.com")
# http://tom.joindiaspora.com/.well-known/host-meta
f = EMWebfinger.new("tom@tom.joindiaspora.com")
EventMachine::HttpRequest.should_receive(:new).exactly(4).times.and_return(good_request)
diaspora_xrd.stub!(:body).and_return(diaspora_xrd)
RestClient.should_receive(:get).twice.and_return(nil, diaspora_xrd)
f.should_receive(:xrd_url).twice
EM.run {
f.on_person{ |p|
EM.stop
}
}
f.send(:get_xrd)
f.instance_variable_get(:@ssl).should == false
end
it 'must try https first' do
single_request = FakeHttpRequest.new(:success)
single_request.callbacks = [diaspora_xrd]
good_request.callbacks = [diaspora_finger, hcard_xml]
EventMachine::HttpRequest.should_receive(:new).with("https://tom.joindiaspora.com/.well-known/host-meta").and_return(single_request)
EventMachine::HttpRequest.should_receive(:new).exactly(2).and_return(good_request)
f = EMWebfinger.new("tom@tom.joindiaspora.com")
EM.run {
f.on_person{ |p|
EM.stop
}
}
end
it 'should retry with http if https fails with an http error code' do
bad_request = FakeHttpRequest.new(:failure)
good_request.callbacks = [diaspora_xrd, diaspora_finger, hcard_xml]
EventMachine::HttpRequest.should_receive(:new).with("https://tom.joindiaspora.com/.well-known/host-meta").and_return(bad_request)
EventMachine::HttpRequest.should_receive(:new).exactly(3).and_return(good_request)
f = EMWebfinger.new("tom@tom.joindiaspora.com")
EM.run {
f.on_person{ |p|
EM.stop
}
}
end
end
end
end
......@@ -61,7 +61,7 @@ describe User do
describe '#receive_salmon' do
it 'should handle the case where the webfinger fails' do
Person.should_receive(:by_account_identifier).and_return("not a person")
EMWebfinger.stub!(:fetch).and_return(nil)
proc{
user2.post :status_message, :message => "store this!", :to => aspect2.id
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter