diff --git a/app/controllers/diaspora_federation/h_card_controller.rb b/app/controllers/diaspora_federation/h_card_controller.rb new file mode 100644 index 0000000..021fe4b --- /dev/null +++ b/app/controllers/diaspora_federation/h_card_controller.rb @@ -0,0 +1,20 @@ +require_dependency "diaspora_federation/application_controller" + +module DiasporaFederation + ## + # this controller generates the hcard + class HCardController < ApplicationController + ## + # returns the hcard of the user + # + # GET /hcard/users/:guid + def hcard + person = DiasporaFederation.person_class.find_local_by_guid(params[:guid]) + + 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 + end + end +end diff --git a/config/routes.rb b/config/routes.rb index 1da5a0b..43d9109 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,4 +8,8 @@ DiasporaFederation::Engine.routes.draw do get ".well-known/host-meta" => :host_meta, :as => "host_meta" get "webfinger" => :legacy_webfinger, :as => "legacy_webfinger" end + + controller :h_card do + get "hcard/users/:guid" => :hcard + end end diff --git a/lib/diaspora_federation.rb b/lib/diaspora_federation.rb index 70191bb..a63b718 100644 --- a/lib/diaspora_federation.rb +++ b/lib/diaspora_federation.rb @@ -27,10 +27,13 @@ module DiasporaFederation # This class must have the following methods: # # *find_local_by_diaspora_handle* - # This should return a +Person+, which is on this pod. + # This should return a +Person+, which is on this pod and the account is not closed. + # + # *find_local_by_guid* + # This should return a +Person+, which is on this pod and the account is not closed. # # *webfinger_hash* - # This should return a +Hash+ with the followong informations: + # This should return a +Hash+ with the following information: # { # acct_uri: "acct:user@server.example", # alias_url: "https://server.example/people/0123456789abcdef", @@ -42,6 +45,22 @@ module DiasporaFederation # guid: "0123456789abcdef", # pubkey: "-----BEGIN PUBLIC KEY-----\nABCDEF==\n-----END PUBLIC KEY-----" # } + # + # *hcard_profile_hash* + # This should return a +Hash+ with the following information: + # { + # guid: "0123456789abcdef", + # nickname: "user", + # full_name: "User Name", + # url: "https://server.example/", + # photo_full_url: "https://server.example/uploads/f.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" + # } attr_accessor :person_class def person_class const_get(@person_class) @@ -66,7 +85,9 @@ module DiasporaFederation 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 webfinger_hash + hcard_profile_hash )) logger.info "successfully configured the federation engine" end diff --git a/spec/controllers/diaspora_federation/h_card_controller_spec.rb b/spec/controllers/diaspora_federation/h_card_controller_spec.rb new file mode 100644 index 0000000..6d3e775 --- /dev/null +++ b/spec/controllers/diaspora_federation/h_card_controller_spec.rb @@ -0,0 +1,33 @@ +module DiasporaFederation + describe HCardController, type: :controller do + routes { DiasporaFederation::Engine.routes } + + describe "GET #hcard" do + it "succeeds when the person exists", fixture: true do + get :hcard, "guid" => alice.guid + expect(response).to be_success + save_fixture(response.body, "hcard") + end + + it "contains the guid" do + get :hcard, "guid" => alice.guid + expect(response.body).to include "#{alice.guid}" + end + + it "contains the username" do + get :hcard, "guid" => alice.guid + expect(response.body).to include "alice" + end + + it "404s when the person does not exist" do + get :hcard, "guid" => "unknown_guid" + expect(response).to be_not_found + end + + it "calls WebFinger::HCard.from_profile" do + expect(WebFinger::HCard).to receive(:from_profile).with(alice.hcard_profile_hash).and_call_original + get :hcard, "guid" => alice.guid + end + end + end +end diff --git a/spec/controllers/diaspora_federation/webfinger_controller_spec.rb b/spec/controllers/diaspora_federation/webfinger_controller_spec.rb index 3d2814c..e475f13 100644 --- a/spec/controllers/diaspora_federation/webfinger_controller_spec.rb +++ b/spec/controllers/diaspora_federation/webfinger_controller_spec.rb @@ -59,7 +59,6 @@ module DiasporaFederation end it "calls WebFinger::WebFinger.from_person" do - alice = Person.find_local_by_diaspora_handle("alice@localhost:3000") expect(WebFinger::WebFinger).to receive(:from_person).with(alice.webfinger_hash).and_call_original get :legacy_webfinger, "q" => "acct:alice@localhost:3000" end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 6b40338..2e97a0a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,6 +22,12 @@ require "rspec/rails" # load factory girl factories require "factories" +# some helper methods + +def alice + @alice ||= Person.find_local_by_diaspora_handle("alice@localhost:3000") +end + # Force fixture rebuild FileUtils.rm_f(Rails.root.join("tmp", "fixture_builder.yml")) diff --git a/test/dummy/app/assets/images/user/default.png b/test/dummy/app/assets/images/user/default.png new file mode 100644 index 0000000..53d10ff Binary files /dev/null and b/test/dummy/app/assets/images/user/default.png differ diff --git a/test/dummy/app/models/person.rb b/test/dummy/app/models/person.rb index ff2557f..ecd792c 100644 --- a/test/dummy/app/models/person.rb +++ b/test/dummy/app/models/person.rb @@ -15,12 +15,29 @@ class Person < ActiveRecord::Base } end - def self.find_by_diaspora_handle(identifier) - find_by(diaspora_handle: identifier) + def hcard_profile_hash + { + guid: guid, + nickname: diaspora_handle.split("@")[0], + full_name: "Dummy User", + url: url, + photo_full_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 self.find_local_by_diaspora_handle(identifier) - # no remote? check ... this class is only for testing + # no remote? and closed_account? check ... this class is only for testing find_by_diaspora_handle(identifier) end + + def self.find_local_by_guid(guid) + # no remote? and closed_account? check ... this class is only for testing + find_by_guid(guid) + end end