diff --git a/lib/diaspora_federation.rb b/lib/diaspora_federation.rb index 0ded47c..2542a6a 100644 --- a/lib/diaspora_federation.rb +++ b/lib/diaspora_federation.rb @@ -18,6 +18,7 @@ module DiasporaFederation @callbacks = Callbacks.new %i( fetch_person_for_webfinger fetch_person_for_hcard + save_person_after_webfinger ) class << self diff --git a/lib/diaspora_federation/discovery/discovery.rb b/lib/diaspora_federation/discovery/discovery.rb index 1f7f637..b97a749 100644 --- a/lib/diaspora_federation/discovery/discovery.rb +++ b/lib/diaspora_federation/discovery/discovery.rb @@ -13,9 +13,9 @@ module DiasporaFederation @diaspora_id = clean_diaspora_id(diaspora_id) end - # fetch all metadata for the account + # fetch all metadata for the account and saves it via callback # @return [Person] - def fetch + def fetch_and_save logger.info "Fetch data for #{diaspora_id}" unless diaspora_id == clean_diaspora_id(webfinger.acct_uri) @@ -23,6 +23,7 @@ module DiasporaFederation " #{clean_diaspora_id(webfinger.acct_uri)}" end + DiasporaFederation.callbacks.trigger(:save_person_after_webfinger, person) person end @@ -67,7 +68,7 @@ module DiasporaFederation end def person - Entities::Person.new( + @person ||= Entities::Person.new( guid: hcard.guid || webfinger.guid, diaspora_id: diaspora_id, url: webfinger.seed_url, diff --git a/spec/lib/diaspora_federation/discovery/discovery_spec.rb b/spec/lib/diaspora_federation/discovery/discovery_spec.rb index e70c933..8fc1868 100644 --- a/spec/lib/diaspora_federation/discovery/discovery_spec.rb +++ b/spec/lib/diaspora_federation/discovery/discovery_spec.rb @@ -18,7 +18,7 @@ module DiasporaFederation end end - describe ".fetch" do + describe ".fetch_and_save" do it "fetches the userdata and returns a person object" do stub_request(:get, "https://localhost:3000/.well-known/host-meta") .to_return(status: 200, body: host_meta_xrd) @@ -27,7 +27,7 @@ module DiasporaFederation stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}") .to_return(status: 200, body: hcard_html) - person = Discovery::Discovery.new(account).fetch + person = Discovery::Discovery.new(account).fetch_and_save expect(person.guid).to eq(alice.guid) expect(person.diaspora_id).to eq(account) @@ -45,6 +45,24 @@ module DiasporaFederation expect(profile.image_url_small).to eq(default_image) end + it "fetches the userdata and saves the person object via callback" do + stub_request(:get, "https://localhost:3000/.well-known/host-meta") + .to_return(status: 200, body: host_meta_xrd) + stub_request(:get, "http://localhost:3000/webfinger?q=acct:#{account}") + .to_return(status: 200, body: webfinger_xrd) + stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}") + .to_return(status: 200, body: hcard_html) + + callback_person = nil + expect(DiasporaFederation.callbacks).to receive(:trigger) do |callback, person| + expect(callback).to eq(:save_person_after_webfinger) + expect(person).to be_instance_of(Entities::Person) + callback_person = person + end + + expect(Discovery::Discovery.new(account).fetch_and_save).to be(callback_person) + end + it "falls back to http if https fails with 404" do stub_request(:get, "https://localhost:3000/.well-known/host-meta") .to_return(status: 404) @@ -55,7 +73,7 @@ module DiasporaFederation stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}") .to_return(status: 200, body: hcard_html) - person = Discovery::Discovery.new(account).fetch + person = Discovery::Discovery.new(account).fetch_and_save expect(person.guid).to eq(alice.guid) expect(person.diaspora_id).to eq(account) @@ -71,7 +89,7 @@ module DiasporaFederation stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}") .to_return(status: 200, body: hcard_html) - person = Discovery::Discovery.new(account).fetch + person = Discovery::Discovery.new(account).fetch_and_save expect(person.guid).to eq(alice.guid) expect(person.diaspora_id).to eq(account) @@ -85,7 +103,7 @@ module DiasporaFederation stub_request(:get, "http://localhost:3000/webfinger?q=acct:#{account}") .to_return(status: 200, body: modified_webfinger) - expect { Discovery::Discovery.new(account).fetch }.to raise_error Discovery::DiscoveryError + expect { Discovery::Discovery.new(account).fetch_and_save }.to raise_error Discovery::DiscoveryError end it "fails if the diaspora id was not found" do @@ -94,7 +112,7 @@ module DiasporaFederation stub_request(:get, "http://localhost:3000/webfinger?q=acct:#{account}") .to_return(status: 404) - expect { Discovery::Discovery.new(account).fetch }.to raise_error Discovery::DiscoveryError + expect { Discovery::Discovery.new(account).fetch_and_save }.to raise_error Discovery::DiscoveryError end it "reads old hcard without guid and public key" do @@ -170,7 +188,7 @@ module DiasporaFederation stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}") .to_return(status: 200, body: historic_hcard_html) - person = Discovery::Discovery.new(account).fetch + person = Discovery::Discovery.new(account).fetch_and_save expect(person.guid).to eq(alice.guid) expect(person.diaspora_id).to eq(account) diff --git a/test/dummy/app/controllers/discovery_controller.rb b/test/dummy/app/controllers/discovery_controller.rb index 137ddb5..242f090 100644 --- a/test/dummy/app/controllers/discovery_controller.rb +++ b/test/dummy/app/controllers/discovery_controller.rb @@ -2,6 +2,6 @@ class DiscoveryController < ApplicationController def discovery discovery = DiasporaFederation::Discovery::Discovery.new(params[:q]) - render json: discovery.fetch + render json: discovery.fetch_and_save end end diff --git a/test/dummy/config/initializers/diaspora_federation.rb b/test/dummy/config/initializers/diaspora_federation.rb index 8a42580..5056d09 100644 --- a/test/dummy/config/initializers/diaspora_federation.rb +++ b/test/dummy/config/initializers/diaspora_federation.rb @@ -51,5 +51,12 @@ DiasporaFederation.configure do |config| ) end end + + on :save_person_after_webfinger do |person| + unless Person.exists?(diaspora_id: person.diaspora_id) + Person.new(diaspora_id: person.diaspora_id, guid: person.guid, + serialized_public_key: person.exported_key, url: person.url).save! + end + end end end