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