From 6e6171fc932d2c5d39141c40db6155c05eb33e34 Mon Sep 17 00:00:00 2001 From: Benjamin Neff Date: Thu, 2 Jul 2015 01:11:28 +0200 Subject: [PATCH] use person object with attributes to generate webfinger --- .rubocop.yml | 7 ++ .../webfinger_controller.rb | 2 +- lib/diaspora_federation.rb | 10 +- .../web_finger/exceptions.rb | 1 - .../web_finger/web_finger.rb | 74 ++++++------ .../webfinger_controller_spec.rb | 2 +- .../web_finger/web_finger_spec.rb | 105 ++++++------------ test/dummy/app/models/person.rb | 21 ++-- 8 files changed, 94 insertions(+), 128 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 6c82cd2..61c152f 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -155,3 +155,10 @@ Metrics/AbcSize: Metrics/ModuleLength: Max: 1500 + +Style/SingleLineMethods: + Exclude: + - "test/dummy/app/models/*" +Style/EmptyLineBetweenDefs: + Exclude: + - "test/dummy/app/models/*" diff --git a/app/controllers/diaspora_federation/webfinger_controller.rb b/app/controllers/diaspora_federation/webfinger_controller.rb index 33a33b3..5456e74 100644 --- a/app/controllers/diaspora_federation/webfinger_controller.rb +++ b/app/controllers/diaspora_federation/webfinger_controller.rb @@ -41,7 +41,7 @@ module DiasporaFederation return render nothing: true, status: 404 if person.nil? logger.info "webfinger profile request for: #{person.diaspora_handle}" - render body: WebFinger::WebFinger.from_person(person.webfinger_hash).to_xml, content_type: "application/xrd+xml" + render body: WebFinger::WebFinger.from_person(person).to_xml, content_type: "application/xrd+xml" end private diff --git a/lib/diaspora_federation.rb b/lib/diaspora_federation.rb index 781ecbb..b3168cc 100644 --- a/lib/diaspora_federation.rb +++ b/lib/diaspora_federation.rb @@ -86,7 +86,15 @@ module DiasporaFederation validate_class(@person_class, "person_class", %i( find_local_by_diaspora_handle find_local_by_guid - webfinger_hash + diaspora_handle + alias_url + hcard_url + seed_url + profile_url + atom_url + salmon_url + guid + public_key hcard_profile_hash )) logger.info "successfully configured the federation engine" diff --git a/lib/diaspora_federation/web_finger/exceptions.rb b/lib/diaspora_federation/web_finger/exceptions.rb index 795ad2c..2070438 100644 --- a/lib/diaspora_federation/web_finger/exceptions.rb +++ b/lib/diaspora_federation/web_finger/exceptions.rb @@ -9,7 +9,6 @@ module DiasporaFederation # Raised, if something is wrong with the webfinger data # # * if the +webfinger_url+ is missing or malformed in {HostMeta.from_base_url} or {HostMeta.from_xml} - # * if the +data+ given to {WebFinger.from_person} is an invalid type or doesn't contain all required entries # * if the parsed XML from {WebFinger.from_xml} is incomplete # * if the params passed to {HCard.from_profile} or {HCard.from_html} # are in some way malformed, invalid or incomplete. diff --git a/lib/diaspora_federation/web_finger/web_finger.rb b/lib/diaspora_federation/web_finger/web_finger.rb index 6ae24c8..0318e64 100644 --- a/lib/diaspora_federation/web_finger/web_finger.rb +++ b/lib/diaspora_federation/web_finger/web_finger.rb @@ -9,19 +9,19 @@ module DiasporaFederation # In the meantime an actual RFC draft has been in development, which should # serve as a base for all future changes of this implementation. # - # @example Creating a WebFinger document from account data - # wf = WebFinger.from_person({ - # acct_uri: "acct:user@server.example", - # alias_url: "https://server.example/people/0123456789abcdef", - # hcard_url: "https://server.example/hcard/users/0123456789abcdef", - # seed_url: "https://server.example/", - # profile_url: "https://server.example/u/user", - # atom_url: "https://server.example/public/user.atom", - # salmon_url: "https://server.example/receive/users/0123456789abcdef", - # guid: "0123456789abcdef", - # pubkey: "-----BEGIN PUBLIC KEY-----\nABCDEF==\n-----END PUBLIC KEY-----" - # }) - # xml_string = wf.to_xml + # @example Creating a WebFinger document from a person object + # xml_string = WebFinger.from_person(person).to_xml + # + # The person object should have the following attributes (with examples) + # diaspora_handle: "user@server.example" + # alias_url: "https://server.example/people/0123456789abcdef" + # hcard_url: "https://server.example/hcard/users/0123456789abcdef" + # seed_url: "https://server.example/" + # profile_url: "https://server.example/u/user" + # atom_url: "https://server.example/public/user.atom" + # salmon_url: "https://server.example/receive/users/0123456789abcdef" + # guid: "0123456789abcdef" + # public_key: "-----BEGIN PUBLIC KEY-----\nABCDEF==\n-----END PUBLIC KEY-----" # # @example Creating a WebFinger instance from an xml document # wf = WebFinger.from_xml(xml_string) @@ -89,7 +89,7 @@ module DiasporaFederation # DER-encoded PKCS#1 key beginning with the text # "-----BEGIN PUBLIC KEY-----" and ending with "-----END PUBLIC KEY-----". # @return [String] public key - attr_reader :pubkey + attr_reader :public_key # +hcard_url+ link relation REL_HCARD = "http://microformats.org/profile/hcard" @@ -131,26 +131,26 @@ module DiasporaFederation doc.to_xml end - # Create a WebFinger instance from the given person data Hash. - # @param [Hash] data account data + # Create a WebFinger instance from the given person. + # @param [Person] person the person object # @return [WebFinger] WebFinger instance - # @raise [InvalidData] if the given data Hash is invalid or incomplete - def self.from_person(data) - raise InvalidData, "person data incomplete" unless account_data_complete?(data) + # @raise [ArgumentError] if the given person is nil + def self.from_person(person) + raise ArgumentError, "person is nil" if person.nil? wf = allocate wf.instance_eval { - @acct_uri = data[:acct_uri] - @alias_url = data[:alias_url] - @hcard_url = data[:hcard_url] - @seed_url = data[:seed_url] - @profile_url = data[:profile_url] - @atom_url = data[:atom_url] - @salmon_url = data[:salmon_url] + @acct_uri = "acct:#{person.diaspora_handle}" + @alias_url = person.alias_url + @hcard_url = person.hcard_url + @seed_url = person.seed_url + @profile_url = person.profile_url + @atom_url = person.atom_url + @salmon_url = person.salmon_url # TODO: remove me! ######### - @guid = data[:guid] - @pubkey = data[:pubkey] + @guid = person.guid + @public_key = person.public_key ############################# } wf @@ -163,7 +163,7 @@ module DiasporaFederation def self.from_xml(webfinger_xml) data = parse_xml_and_validate(webfinger_xml) - hcard_url, seed_url, guid, profile_url, atom_url, salmon_url, pubkey = parse_links(data) + hcard_url, seed_url, guid, profile_url, atom_url, salmon_url, public_key = parse_links(data) wf = allocate wf.instance_eval { @@ -177,7 +177,7 @@ module DiasporaFederation # TODO: remove me! ########## @guid = guid - @pubkey = Base64.strict_decode64(pubkey) + @public_key = Base64.strict_decode64(public_key) ############################## } wf @@ -185,18 +185,6 @@ module DiasporaFederation private - # Checks the given account data Hash for correct type and completeness. - # @param [Hash] data account data - # @return [Boolean] validation result - def self.account_data_complete?(data) - data.instance_of?(Hash) && - %i( - acct_uri alias_url hcard_url seed_url - guid profile_url atom_url salmon_url pubkey - ).all? {|k| data.key? k } - end - private_class_method :account_data_complete? - # Parses the XML string to a Hash and does some rudimentary checking on # the data Hash. # @param [String] webfinger_xml WebFinger XML string @@ -236,7 +224,7 @@ module DiasporaFederation # TODO: remove me! ############## doc.links << {rel: REL_PUBKEY, type: "RSA", - href: Base64.strict_encode64(@pubkey)} + href: Base64.strict_encode64(@public_key)} ################################## end diff --git a/spec/controllers/diaspora_federation/webfinger_controller_spec.rb b/spec/controllers/diaspora_federation/webfinger_controller_spec.rb index e475f13..75f49b4 100644 --- a/spec/controllers/diaspora_federation/webfinger_controller_spec.rb +++ b/spec/controllers/diaspora_federation/webfinger_controller_spec.rb @@ -59,7 +59,7 @@ module DiasporaFederation end it "calls WebFinger::WebFinger.from_person" do - expect(WebFinger::WebFinger).to receive(:from_person).with(alice.webfinger_hash).and_call_original + expect(WebFinger::WebFinger).to receive(:from_person).with(alice).and_call_original get :legacy_webfinger, "q" => "acct:alice@localhost:3000" end end diff --git a/spec/lib/diaspora_federation/web_finger/web_finger_spec.rb b/spec/lib/diaspora_federation/web_finger/web_finger_spec.rb index af226e2..6b89fb9 100644 --- a/spec/lib/diaspora_federation/web_finger/web_finger_spec.rb +++ b/spec/lib/diaspora_federation/web_finger/web_finger_spec.rb @@ -1,29 +1,22 @@ module DiasporaFederation describe WebFinger::WebFinger do - let(:acct) { "acct:user@pod.example.tld" } - let(:alias_url) { "http://pod.example.tld/" } - let(:hcard_url) { "https://pod.example.tld/hcard/users/abcdef0123456789" } - let(:seed_url) { "https://pod.geraspora.de/" } - let(:guid) { "abcdef0123456789" } - let(:profile_url) { "https://pod.example.tld/u/user" } - let(:atom_url) { "https://pod.example.tld/public/user.atom" } - let(:salmon_url) { "https://pod.example.tld/receive/users/abcdef0123456789" } - let(:pubkey) { "-----BEGIN PUBLIC KEY-----\nABCDEF==\n-----END PUBLIC KEY-----" } - let(:pubkey_base64) { Base64.strict_encode64(pubkey) } + let(:person) { FactoryGirl.create(:person) } + let(:acct) { "acct:#{person.diaspora_handle}" } + let(:public_key_base64) { Base64.strict_encode64(person.public_key) } let(:xml) { <<-XML #{acct} - #{alias_url} - - - - - - - + #{person.alias_url} + + + + + + + XML } @@ -34,36 +27,12 @@ XML context "generation" do it "creates a nice XML document" do - wf = WebFinger::WebFinger.from_person( - acct_uri: acct, - alias_url: alias_url, - hcard_url: hcard_url, - seed_url: seed_url, - profile_url: profile_url, - atom_url: atom_url, - salmon_url: salmon_url, - guid: guid, - pubkey: pubkey - ) + wf = WebFinger::WebFinger.from_person(person) expect(wf.to_xml).to eq(xml) end - it "fails if some params are missing" do - expect { - WebFinger::WebFinger.from_person( - acct_uri: acct, - alias_url: alias_url, - hcard_url: hcard_url - ) - }.to raise_error(WebFinger::InvalidData) - end - - it "fails if empty was given" do - expect { WebFinger::WebFinger.from_person({}) }.to raise_error WebFinger::InvalidData - end - it "fails if nil was given" do - expect { WebFinger::WebFinger.from_person(nil) }.to raise_error WebFinger::InvalidData + expect { WebFinger::WebFinger.from_person(nil) }.to raise_error ArgumentError end end @@ -71,15 +40,15 @@ XML it "reads its own output" do wf = WebFinger::WebFinger.from_xml(xml) expect(wf.acct_uri).to eq(acct) - expect(wf.alias_url).to eq(alias_url) - expect(wf.hcard_url).to eq(hcard_url) - expect(wf.seed_url).to eq(seed_url) - expect(wf.profile_url).to eq(profile_url) - expect(wf.atom_url).to eq(atom_url) - expect(wf.salmon_url).to eq(salmon_url) + expect(wf.alias_url).to eq(person.alias_url) + expect(wf.hcard_url).to eq(person.hcard_url) + expect(wf.seed_url).to eq(person.seed_url) + expect(wf.profile_url).to eq(person.profile_url) + expect(wf.atom_url).to eq(person.atom_url) + expect(wf.salmon_url).to eq(person.salmon_url) - expect(wf.guid).to eq(guid) - expect(wf.pubkey).to eq(pubkey) + expect(wf.guid).to eq(person.guid) + expect(wf.public_key).to eq(person.public_key) end it "reads old-style XML" do @@ -87,30 +56,30 @@ XML #{acct} - #{alias_url} - - - + #{person.alias_url} + + + - - - + + + - + XML wf = WebFinger::WebFinger.from_xml(historic_xml) expect(wf.acct_uri).to eq(acct) - expect(wf.alias_url).to eq(alias_url) - expect(wf.hcard_url).to eq(hcard_url) - expect(wf.seed_url).to eq(seed_url) - expect(wf.profile_url).to eq(profile_url) - expect(wf.atom_url).to eq(atom_url) - expect(wf.salmon_url).to eq(salmon_url) + expect(wf.alias_url).to eq(person.alias_url) + expect(wf.hcard_url).to eq(person.hcard_url) + expect(wf.seed_url).to eq(person.seed_url) + expect(wf.profile_url).to eq(person.profile_url) + expect(wf.atom_url).to eq(person.atom_url) + expect(wf.salmon_url).to eq(person.salmon_url) - expect(wf.guid).to eq(guid) - expect(wf.pubkey).to eq(pubkey) + expect(wf.guid).to eq(person.guid) + expect(wf.public_key).to eq(person.public_key) end it "fails if the document is empty" do diff --git a/test/dummy/app/models/person.rb b/test/dummy/app/models/person.rb index 048eaf2..19e52c2 100644 --- a/test/dummy/app/models/person.rb +++ b/test/dummy/app/models/person.rb @@ -1,19 +1,14 @@ class Person < ActiveRecord::Base include ::Diaspora::Guid - def webfinger_hash - { - acct_uri: "acct:#{diaspora_handle}", - alias_url: "#{url}people/#{guid}", - hcard_url: "#{url}hcard/users/#{guid}", - seed_url: url, - profile_url: "#{url}u/#{diaspora_handle.split('@')[0]}", - atom_url: "#{url}public/#{diaspora_handle.split('@')[0]}.atom", - salmon_url: "#{url}receive/users/#{guid}", - guid: guid, - pubkey: serialized_public_key - } - end + def alias_url; "#{url}people/#{guid}" end + def hcard_url; "#{url}hcard/users/#{guid}" end + def profile_url; "#{url}u/#{diaspora_handle.split('@')[0]}" end + def atom_url; "#{url}public/#{diaspora_handle.split('@')[0]}.atom" end + def salmon_url; "#{url}receive/users/#{guid}" end + + alias_attribute :seed_url, :url + alias_attribute :public_key, :serialized_public_key def hcard_profile_hash {