diff --git a/app/controllers/diaspora_federation/h_card_controller.rb b/app/controllers/diaspora_federation/h_card_controller.rb index 021fe4b..bb80f1b 100644 --- a/app/controllers/diaspora_federation/h_card_controller.rb +++ b/app/controllers/diaspora_federation/h_card_controller.rb @@ -14,7 +14,7 @@ module DiasporaFederation return render nothing: true, status: 404 if person.nil? logger.info "hcard profile request for: #{person.diaspora_handle}" - render html: WebFinger::HCard.from_profile(person.hcard_profile_hash).to_html.html_safe + render html: WebFinger::HCard.from_person(person).to_html.html_safe end end end diff --git a/lib/diaspora_federation.rb b/lib/diaspora_federation.rb index b3168cc..5f1dba5 100644 --- a/lib/diaspora_federation.rb +++ b/lib/diaspora_federation.rb @@ -84,18 +84,11 @@ module DiasporaFederation def validate_config configuration_error "missing server_uri" unless @server_uri.respond_to? :host validate_class(@person_class, "person_class", %i( - find_local_by_diaspora_handle - find_local_by_guid - diaspora_handle - alias_url - hcard_url - seed_url - profile_url - atom_url - salmon_url - guid - public_key - hcard_profile_hash + find_local_by_diaspora_handle find_local_by_guid + diaspora_handle nickname guid public_key searchable + alias_url hcard_url seed_url profile_url atom_url salmon_url + photo_large_url photo_medium_url photo_small_url + full_name first_name last_name )) logger.info "successfully configured the federation engine" end diff --git a/lib/diaspora_federation/web_finger/exceptions.rb b/lib/diaspora_federation/web_finger/exceptions.rb index 2070438..c999dc9 100644 --- a/lib/diaspora_federation/web_finger/exceptions.rb +++ b/lib/diaspora_federation/web_finger/exceptions.rb @@ -10,8 +10,7 @@ module DiasporaFederation # # * if the +webfinger_url+ is missing or malformed in {HostMeta.from_base_url} or {HostMeta.from_xml} # * 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. + # * if the html passed to {HCard.from_html} in some way is malformed, invalid or incomplete. class InvalidData < RuntimeError end end diff --git a/lib/diaspora_federation/web_finger/h_card.rb b/lib/diaspora_federation/web_finger/h_card.rb index 153464b..23880b9 100644 --- a/lib/diaspora_federation/web_finger/h_card.rb +++ b/lib/diaspora_federation/web_finger/h_card.rb @@ -14,21 +14,21 @@ module DiasporaFederation # correctly nested according to the hCard standard and class names are # partially wrong. Also, apart from that, it's just ugly. # - # @example Creating a hCard document from account data - # hc = HCard.from_profile({ - # guid: "0123456789abcdef", - # nickname: "user", - # full_name: "User Name", - # url: "https://server.example/", - # photo_large_url: "https://server.example/uploads/l.jpg", - # photo_medium_url: "https://server.example/uploads/m.jpg", - # photo_small_url: "https://server.example/uploads/s.jpg", - # pubkey: "-----BEGIN PUBLIC KEY-----\nABCDEF==\n-----END PUBLIC KEY-----", - # searchable: true, - # first_name: "User", - # last_name: "Name" - # }) - # html_string = hc.to_html + # @example Creating a hCard document from a person object + # html_string = HCard.from_person(person).to_html + # + # The person object should have the following attributes (with examples) + # guid: "0123456789abcdef", + # nickname: "user", + # full_name: "User Name", + # seed_url: "https://server.example/", + # photo_large_url: "https://server.example/uploads/l.jpg", + # photo_medium_url: "https://server.example/uploads/m.jpg", + # photo_small_url: "https://server.example/uploads/s.jpg", + # public_key: "-----BEGIN PUBLIC KEY-----\nABCDEF==\n-----END PUBLIC KEY-----", + # searchable: true, + # first_name: "User", + # last_name: "Name" # # @example Create a HCard instance from an hCard document # hc = HCard.from_html(html_string) @@ -68,7 +68,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 # @return [String] url to the big avatar (300x300) attr_reader :photo_large_url @@ -128,7 +128,7 @@ module DiasporaFederation add_simple_property(content, :searchable, "searchable", @searchable) add_property(content, :key) do |html| - html.pre(@pubkey.to_s, class: "key") + html.pre(@public_key.to_s, class: "key") end # TODO: remove me! ################### @@ -145,28 +145,28 @@ module DiasporaFederation builder.doc.to_xhtml(indent: 2, indent_text: " ") end - # Creates a new HCard instance from the given Hash containing profile data - # @param [Hash] data account data + # Creates a new HCard instance from the given person + # @param [Person] person the person object # @return [HCard] HCard instance # @raise [InvalidData] if the account data Hash is invalid or incomplete - def self.from_profile(data) - raise InvalidData unless account_data_complete?(data) + def self.from_person(person) + raise ArgumentError, "person is nil" if person.nil? hc = allocate hc.instance_eval { - @guid = data[:guid] - @nickname = data[:nickname] - @full_name = data[:full_name] - @url = data[:url] - @photo_large_url = data[:photo_large_url] - @photo_medium_url = data[:photo_medium_url] - @photo_small_url = data[:photo_small_url] - @pubkey = data[:pubkey] - @searchable = data[:searchable] + @guid = person.guid + @nickname = person.nickname + @full_name = person.full_name + @url = person.seed_url + @photo_large_url = person.photo_large_url + @photo_medium_url = person.photo_medium_url + @photo_small_url = person.photo_small_url + @public_key = person.public_key + @searchable = person.searchable # TODO: remove me! ################### - @first_name = data[:first_name] - @last_name = data[:last_name] + @first_name = person.first_name + @last_name = person.last_name ####################################### } hc @@ -188,7 +188,7 @@ module DiasporaFederation @photo_large_url = photo_from_doc(doc, :photo) @photo_medium_url = photo_from_doc(doc, :photo_medium) @photo_small_url = photo_from_doc(doc, :photo_small) - @pubkey = content_from_doc(doc, :key) unless element_from_doc(doc, :key).nil? + @public_key = content_from_doc(doc, :key) unless element_from_doc(doc, :key).nil? @searchable = content_from_doc(doc, :searchable) == "true" # TODO: change me! ################### @@ -271,19 +271,6 @@ module DiasporaFederation end end - # 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( - guid nickname full_name url - photo_large_url photo_medium_url photo_small_url - pubkey searchable first_name last_name - ).all? {|k| data.key? k } - end - private_class_method :account_data_complete? - # Make sure some of the most important elements are present in the parsed # HTML document. # @param [LibXML::XML::Document] doc HTML document diff --git a/spec/controllers/diaspora_federation/h_card_controller_spec.rb b/spec/controllers/diaspora_federation/h_card_controller_spec.rb index 6d3e775..9172bce 100644 --- a/spec/controllers/diaspora_federation/h_card_controller_spec.rb +++ b/spec/controllers/diaspora_federation/h_card_controller_spec.rb @@ -25,7 +25,7 @@ module DiasporaFederation end it "calls WebFinger::HCard.from_profile" do - expect(WebFinger::HCard).to receive(:from_profile).with(alice.hcard_profile_hash).and_call_original + expect(WebFinger::HCard).to receive(:from_person).with(alice).and_call_original get :hcard, "guid" => alice.guid end end diff --git a/spec/lib/diaspora_federation/web_finger/h_card_spec.rb b/spec/lib/diaspora_federation/web_finger/h_card_spec.rb index d03aa6f..bcf4ac2 100644 --- a/spec/lib/diaspora_federation/web_finger/h_card_spec.rb +++ b/spec/lib/diaspora_federation/web_finger/h_card_spec.rb @@ -1,16 +1,6 @@ module DiasporaFederation describe WebFinger::HCard do - let(:guid) { "abcdef0123456789" } - let(:nickname) { "user" } - let(:first_name) { "Test" } - let(:last_name) { "Testington" } - let(:name) { "#{first_name} #{last_name}" } - let(:url) { "https://pod.example.tld/users/me" } - let(:photo_url) { "https://pod.example.tld/uploads/f.jpg" } - let(:photo_url_m) { "https://pod.example.tld/uploads/m.jpg" } - let(:photo_url_s) { "https://pod.example.tld/uploads/s.jpg" } - let(:key) { "-----BEGIN PUBLIC KEY-----\nABCDEF==\n-----END PUBLIC KEY-----" } - let(:searchable) { true } + let(:person) { FactoryGirl.create(:person) } let(:html) { <<-HTML @@ -19,77 +9,77 @@ module DiasporaFederation - #{name} + #{person.full_name}
-

#{name}

+

#{person.full_name}

User profile

Uid
- #{guid} + #{person.guid}
Nickname
- #{nickname} + #{person.nickname}
Full_name
- #{name} + #{person.full_name}
Searchable
- #{searchable} + #{person.searchable}
Key
-
#{key}
+
#{person.public_key}
First_name
- #{first_name} + #{person.first_name}
Family_name
- #{last_name} + #{person.last_name}
Url
- #{url} + #{person.seed_url}
Photo
- +
Photo_medium
- +
Photo_small
- +
@@ -105,60 +95,35 @@ HTML context "generation" do it "creates an instance from a data hash" do - hcard = WebFinger::HCard.from_profile( - guid: guid, - nickname: nickname, - full_name: name, - url: url, - photo_large_url: photo_url, - photo_medium_url: photo_url_m, - photo_small_url: photo_url_s, - pubkey: key, - searchable: searchable, - first_name: first_name, - last_name: last_name - ) + hcard = WebFinger::HCard.from_person(person) expect(hcard.to_html).to eq(html) end - it "fails if some params are missing" do - expect { - WebFinger::HCard.from_profile( - guid: guid, - nickname: nickname - ) - }.to raise_error WebFinger::InvalidData - end - - it "fails if nothing was given" do - expect { WebFinger::HCard.from_profile({}) }.to raise_error WebFinger::InvalidData - end - it "fails if nil was given" do - expect { WebFinger::HCard.from_profile(nil) }.to raise_error WebFinger::InvalidData + expect { WebFinger::HCard.from_person(nil) }.to raise_error ArgumentError end end context "parsing" do it "reads its own output" do hcard = WebFinger::HCard.from_html(html) - expect(hcard.guid).to eq(guid) - expect(hcard.nickname).to eq(nickname) - expect(hcard.full_name).to eq(name) - expect(hcard.url).to eq(url) - expect(hcard.photo_large_url).to eq(photo_url) - expect(hcard.photo_medium_url).to eq(photo_url_m) - expect(hcard.photo_small_url).to eq(photo_url_s) - expect(hcard.pubkey).to eq(key) - expect(hcard.searchable).to eq(searchable) + expect(hcard.guid).to eq(person.guid) + expect(hcard.nickname).to eq(person.nickname) + expect(hcard.full_name).to eq(person.full_name) + expect(hcard.url).to eq(person.seed_url) + expect(hcard.photo_large_url).to eq(person.photo_large_url) + expect(hcard.photo_medium_url).to eq(person.photo_medium_url) + expect(hcard.photo_small_url).to eq(person.photo_small_url) + expect(hcard.public_key).to eq(person.public_key) + expect(hcard.searchable).to eq(person.searchable) - expect(hcard.first_name).to eq(first_name) - expect(hcard.last_name).to eq(last_name) + expect(hcard.first_name).to eq(person.first_name) + expect(hcard.last_name).to eq(person.last_name) end it "searchable is false, if it is empty in html" do changed_html = html.sub( - "class=\"searchable\">#{searchable}<", + "class=\"searchable\">#{person.searchable}<", "class=\"searchable\"><" ) @@ -170,62 +135,62 @@ HTML it "reads old-style HTML" do historic_html = <<-HTML
-

#{name}

+

#{person.full_name}

User profile

Nickname
-#{name} +#{person.full_name}
First name
-#{first_name} +#{person.first_name}
Family name
-#{last_name} +#{person.last_name}
Full name
-#{name} +#{person.full_name}
URL
-#{url} +#{person.seed_url}
Photo
- +
Photo
- +
Photo
- +
Searchable
-#{searchable} +#{person.searchable}
@@ -234,20 +199,20 @@ HTML HTML hcard = WebFinger::HCard.from_html(historic_html) - expect(hcard.url).to eq(url) - expect(hcard.photo_large_url).to eq(photo_url) - expect(hcard.photo_medium_url).to eq(photo_url_m) - expect(hcard.photo_small_url).to eq(photo_url_s) - expect(hcard.searchable).to eq(searchable) + expect(hcard.url).to eq(person.seed_url) + expect(hcard.photo_large_url).to eq(person.photo_large_url) + expect(hcard.photo_medium_url).to eq(person.photo_medium_url) + expect(hcard.photo_small_url).to eq(person.photo_small_url) + expect(hcard.searchable).to eq(person.searchable) - expect(hcard.first_name).to eq(first_name) - expect(hcard.last_name).to eq(last_name) + expect(hcard.first_name).to eq(person.first_name) + expect(hcard.last_name).to eq(person.last_name) end it "fails if the document is incomplete" do invalid_html = <<-HTML
- #{name} + #{person.full_name}
HTML expect { WebFinger::HCard.from_html(invalid_html) }.to raise_error WebFinger::InvalidData diff --git a/test/dummy/app/models/person.rb b/test/dummy/app/models/person.rb index 19e52c2..fd684ca 100644 --- a/test/dummy/app/models/person.rb +++ b/test/dummy/app/models/person.rb @@ -10,21 +10,15 @@ class Person < ActiveRecord::Base alias_attribute :seed_url, :url alias_attribute :public_key, :serialized_public_key - def hcard_profile_hash - { - guid: guid, - nickname: diaspora_handle.split("@")[0], - full_name: "Dummy User", - url: url, - photo_large_url: "#{url}assets/user/default.png", - photo_medium_url: "#{url}assets/user/default.png", - photo_small_url: "#{url}assets/user/default.png", - pubkey: serialized_public_key, - searchable: true, - first_name: "Dummy", - last_name: "User" - } - end + def nickname; diaspora_handle.split("@")[0] end + def photo_large_url; "#{url}assets/user/default.png" end + def photo_medium_url; "#{url}assets/user/default.png" end + def photo_small_url; "#{url}assets/user/default.png" end + + def searchable; true end + def full_name; "Dummy User" end + def first_name; "Dummy" end + def last_name; "User" end def self.find_local_by_diaspora_handle(identifier) # no remote? and closed_account? check ... this class is only for testing