refactor HCard to use the PropertiesDSL
This commit is contained in:
parent
2c50d34370
commit
6ceddae27b
6 changed files with 134 additions and 125 deletions
|
|
@ -7,12 +7,12 @@ module DiasporaFederation
|
|||
#
|
||||
# GET /hcard/users/:guid
|
||||
def hcard
|
||||
person = DiasporaFederation.person_class.find_local_by_guid(params[:guid])
|
||||
person_hcard = DiasporaFederation.callbacks.trigger(:person_hcard_fetch, params[:guid])
|
||||
|
||||
return render nothing: true, status: 404 if person.nil?
|
||||
return render nothing: true, status: 404 if person_hcard.nil?
|
||||
|
||||
logger.info "hcard profile request for: #{person.diaspora_handle}"
|
||||
render html: WebFinger::HCard.from_person(person).to_html.html_safe
|
||||
logger.info "hcard profile request for: #{person_hcard.nickname}:#{person_hcard.guid}"
|
||||
render html: person_hcard.to_html.html_safe
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -13,21 +13,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 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",
|
||||
# serialized_public_key: "-----BEGIN PUBLIC KEY-----\nABCDEF==\n-----END PUBLIC KEY-----",
|
||||
# searchable: true,
|
||||
# first_name: "User",
|
||||
# last_name: "Name"
|
||||
# @example Creating a hCard document from a person hash
|
||||
# hc = HCard.new(
|
||||
# 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",
|
||||
# serialized_public_key: "-----BEGIN PUBLIC KEY-----\nABCDEF==\n-----END PUBLIC KEY-----",
|
||||
# searchable: true,
|
||||
# first_name: "User",
|
||||
# last_name: "Name"
|
||||
# )
|
||||
# html_string = hc.to_html
|
||||
#
|
||||
# @example Create a HCard instance from an hCard document
|
||||
# hc = HCard.from_html(html_string)
|
||||
|
|
@ -39,65 +39,74 @@ module DiasporaFederation
|
|||
# @see http://microformats.org/wiki/h-card "h-card" (draft)
|
||||
# @see http://www.ietf.org/rfc/rfc2426.txt "vCard MIME Directory Profile" (obsolete)
|
||||
# @see http://www.ietf.org/rfc/rfc6350.txt "vCard Format Specification"
|
||||
class HCard
|
||||
private_class_method :new
|
||||
class HCard < Entity
|
||||
# @!attribute [r] guid
|
||||
# This is just the guid. When a user creates an account on a pod, the pod
|
||||
# MUST assign them a guid - a random hexadecimal string of at least 8
|
||||
# hexadecimal digits.
|
||||
# @return [String] guid
|
||||
property :guid
|
||||
|
||||
# This is just the guid. When a user creates an account on a pod, the pod
|
||||
# MUST assign them a guid - a random hexadecimal string of at least 8
|
||||
# hexadecimal digits.
|
||||
# @return [String] guid
|
||||
attr_reader :guid
|
||||
# @!attribute [r] nickname
|
||||
# the first part of the diaspora handle
|
||||
# @return [String] nickname
|
||||
property :nickname
|
||||
|
||||
# the first part of the diaspora handle
|
||||
# @return [String] nickname
|
||||
attr_reader :nickname
|
||||
# @!attribute [r] full_name
|
||||
# @return [String] display name of the user
|
||||
property :full_name
|
||||
|
||||
# @return [String] display name of the user
|
||||
attr_reader :full_name
|
||||
|
||||
# @deprecated should be changed to the profile url. The pod url is in
|
||||
# the WebFinger (see {WebFinger#seed_url}, will affect older Diaspora*
|
||||
# installations).
|
||||
# @!attribute [r] url
|
||||
# @deprecated should be changed to the profile url. The pod url is in
|
||||
# the WebFinger (see {WebFinger#seed_url}, will affect older Diaspora*
|
||||
# installations).
|
||||
#
|
||||
# @return [String] link to the pod
|
||||
attr_reader :url
|
||||
# @return [String] link to the pod
|
||||
property :url
|
||||
|
||||
# When a user is created on the pod, the pod MUST generate a pgp keypair
|
||||
# for them. This key is used for signing messages. The format is a
|
||||
# DER-encoded PKCS#1 key beginning with the text
|
||||
# "-----BEGIN PUBLIC KEY-----" and ending with "-----END PUBLIC KEY-----".
|
||||
# @return [String] public key
|
||||
attr_reader :public_key
|
||||
# @!attribute [r] public_key
|
||||
# When a user is created on the pod, the pod MUST generate a pgp keypair
|
||||
# for them. This key is used for signing messages. The format is a
|
||||
# DER-encoded PKCS#1 key beginning with the text
|
||||
# "-----BEGIN PUBLIC KEY-----" and ending with "-----END PUBLIC KEY-----".
|
||||
# @return [String] public key
|
||||
property :public_key
|
||||
|
||||
# @return [String] url to the big avatar (300x300)
|
||||
attr_reader :photo_large_url
|
||||
# @return [String] url to the medium avatar (100x100)
|
||||
attr_reader :photo_medium_url
|
||||
# @return [String] url to the small avatar (50x50)
|
||||
attr_reader :photo_small_url
|
||||
# @!attribute [r] photo_large_url
|
||||
# @return [String] url to the big avatar (300x300)
|
||||
property :photo_large_url
|
||||
# @!attribute [r] photo_medium_url
|
||||
# @return [String] url to the medium avatar (100x100)
|
||||
property :photo_medium_url
|
||||
# @!attribute [r] photo_small_url
|
||||
# @return [String] url to the small avatar (50x50)
|
||||
property :photo_small_url
|
||||
|
||||
# @deprecated We decided to only use one name field, these should be removed
|
||||
# in later iterations (will affect older Diaspora* installations).
|
||||
# @!attribute [r] first_name
|
||||
# @deprecated We decided to only use one name field, these should be removed
|
||||
# in later iterations (will affect older Diaspora* installations).
|
||||
#
|
||||
# @see #full_name
|
||||
# @return [String] first name
|
||||
attr_reader :first_name
|
||||
# @see #full_name
|
||||
# @return [String] first name
|
||||
property :first_name
|
||||
|
||||
# @deprecated We decided to only use one name field, these should be removed
|
||||
# in later iterations (will affect older Diaspora* installations).
|
||||
# @!attribute [r] last_name
|
||||
# @deprecated We decided to only use one name field, these should be removed
|
||||
# in later iterations (will affect older Diaspora* installations).
|
||||
#
|
||||
# @see #full_name
|
||||
# @return [String] last name
|
||||
attr_reader :last_name
|
||||
# @see #full_name
|
||||
# @return [String] last name
|
||||
property :last_name
|
||||
|
||||
# @deprecated As this is a simple property, consider move to WebFinger instead
|
||||
# of HCard. vCard has no comparable field for this information, but
|
||||
# Webfinger may declare arbitrary properties (will affect older Diaspora*
|
||||
# installations).
|
||||
# @!attribute [r] searchable
|
||||
# @deprecated As this is a simple property, consider move to WebFinger instead
|
||||
# of HCard. vCard has no comparable field for this information, but
|
||||
# Webfinger may declare arbitrary properties (will affect older Diaspora*
|
||||
# installations).
|
||||
#
|
||||
# flag if a user is searchable by name
|
||||
# @return [Boolean] searchable flag
|
||||
attr_reader :searchable
|
||||
# flag if a user is searchable by name
|
||||
# @return [Boolean] searchable flag
|
||||
property :searchable
|
||||
|
||||
# CSS selectors for finding all the hCard fields
|
||||
SELECTORS = {
|
||||
|
|
@ -144,33 +153,6 @@ module DiasporaFederation
|
|||
builder.doc.to_xhtml(indent: 2, indent_text: " ")
|
||||
end
|
||||
|
||||
# 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_person(person)
|
||||
raise ArgumentError, "person is nil" if person.nil?
|
||||
|
||||
hc = allocate
|
||||
hc.instance_eval {
|
||||
@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.serialized_public_key
|
||||
@searchable = person.searchable
|
||||
|
||||
# TODO: remove me! ###################
|
||||
@first_name = person.first_name
|
||||
@last_name = person.last_name
|
||||
#######################################
|
||||
}
|
||||
hc
|
||||
end
|
||||
|
||||
# Creates a new HCard instance from the given HTML string.
|
||||
# @param html_string [String] HTML string
|
||||
# @return [HCard] HCard instance
|
||||
|
|
|
|||
|
|
@ -24,8 +24,10 @@ module DiasporaFederation
|
|||
expect(response).to be_not_found
|
||||
end
|
||||
|
||||
it "calls WebFinger::HCard.from_profile" do
|
||||
expect(WebFinger::HCard).to receive(:from_person).with(alice).and_call_original
|
||||
it "calls the person_hcard_fetch callback" do
|
||||
expect(DiasporaFederation.callbacks).to receive(:trigger)
|
||||
.with(:person_hcard_fetch, alice.guid)
|
||||
.and_call_original
|
||||
get :hcard, "guid" => alice.guid
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
module DiasporaFederation
|
||||
describe WebFinger::HCard do
|
||||
let(:person) { FactoryGirl.create(:person) }
|
||||
let(:photo_large_url) { "#{person.url}/upload/large.png" }
|
||||
let(:photo_medium_url) { "#{person.url}/upload/medium.png" }
|
||||
let(:photo_small_url) { "#{person.url}/upload/small.png" }
|
||||
|
||||
let(:html) {
|
||||
<<-HTML
|
||||
|
|
@ -61,25 +64,25 @@ module DiasporaFederation
|
|||
<dl class="entity_url">
|
||||
<dt>Url</dt>
|
||||
<dd>
|
||||
<a id="pod_location" class="url" rel="me" href="#{person.seed_url}">#{person.seed_url}</a>
|
||||
<a id="pod_location" class="url" rel="me" href="#{person.url}">#{person.url}</a>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="entity_photo">
|
||||
<dt>Photo</dt>
|
||||
<dd>
|
||||
<img class="photo avatar" width="300" height="300" src="#{person.photo_large_url}" />
|
||||
<img class="photo avatar" width="300" height="300" src="#{photo_large_url}" />
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="entity_photo_medium">
|
||||
<dt>Photo_medium</dt>
|
||||
<dd>
|
||||
<img class="photo avatar" width="100" height="100" src="#{person.photo_medium_url}" />
|
||||
<img class="photo avatar" width="100" height="100" src="#{photo_medium_url}" />
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="entity_photo_small">
|
||||
<dt>Photo_small</dt>
|
||||
<dd>
|
||||
<img class="photo avatar" width="50" height="50" src="#{person.photo_small_url}" />
|
||||
<img class="photo avatar" width="50" height="50" src="#{photo_small_url}" />
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
|
@ -90,17 +93,29 @@ HTML
|
|||
}
|
||||
|
||||
it "must not create blank instances" do
|
||||
expect { WebFinger::HCard.new }.to raise_error NameError
|
||||
expect { WebFinger::HCard.new({}) }.to raise_error ArgumentError
|
||||
end
|
||||
|
||||
context "generation" do
|
||||
it "creates an instance from a data hash" do
|
||||
hcard = WebFinger::HCard.from_person(person)
|
||||
hcard = WebFinger::HCard.new(
|
||||
guid: person.guid,
|
||||
nickname: person.nickname,
|
||||
full_name: person.full_name,
|
||||
url: person.url,
|
||||
photo_large_url: photo_large_url,
|
||||
photo_medium_url: photo_medium_url,
|
||||
photo_small_url: photo_small_url,
|
||||
public_key: person.serialized_public_key,
|
||||
searchable: person.searchable,
|
||||
first_name: person.first_name,
|
||||
last_name: person.last_name
|
||||
)
|
||||
expect(hcard.to_html).to eq(html)
|
||||
end
|
||||
|
||||
it "fails if nil was given" do
|
||||
expect { WebFinger::HCard.from_person(nil) }.to raise_error ArgumentError
|
||||
expect { WebFinger::HCard.new(nil) }.to raise_error ArgumentError, "expected a Hash"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -110,10 +125,10 @@ HTML
|
|||
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.url).to eq(person.url)
|
||||
expect(hcard.photo_large_url).to eq(photo_large_url)
|
||||
expect(hcard.photo_medium_url).to eq(photo_medium_url)
|
||||
expect(hcard.photo_small_url).to eq(photo_small_url)
|
||||
expect(hcard.public_key).to eq(person.serialized_public_key)
|
||||
expect(hcard.searchable).to eq(person.searchable)
|
||||
|
||||
|
|
@ -142,7 +157,7 @@ HTML
|
|||
<dl class="entity_nickname">
|
||||
<dt>Nickname</dt>
|
||||
<dd>
|
||||
<a class="nickname url uid" href="#{person.seed_url}" rel="me">#{person.full_name}</a>
|
||||
<a class="nickname url uid" href="#{person.url}" rel="me">#{person.full_name}</a>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="entity_given_name">
|
||||
|
|
@ -166,25 +181,25 @@ HTML
|
|||
<dl class="entity_url">
|
||||
<dt>URL</dt>
|
||||
<dd>
|
||||
<a class="url" href="#{person.seed_url}" id="pod_location" rel="me">#{person.seed_url}</a>
|
||||
<a class="url" href="#{person.url}" id="pod_location" rel="me">#{person.url}</a>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="entity_photo">
|
||||
<dt>Photo</dt>
|
||||
<dd>
|
||||
<img class="photo avatar" height="300px" src="#{person.photo_large_url}" width="300px">
|
||||
<img class="photo avatar" height="300px" src="#{photo_large_url}" width="300px">
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="entity_photo_medium">
|
||||
<dt>Photo</dt>
|
||||
<dd>
|
||||
<img class="photo avatar" height="100px" src="#{person.photo_medium_url}" width="100px">
|
||||
<img class="photo avatar" height="100px" src="#{photo_medium_url}" width="100px">
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="entity_photo_small">
|
||||
<dt>Photo</dt>
|
||||
<dd>
|
||||
<img class="photo avatar" height="50px" src="#{person.photo_small_url}" width="50px">
|
||||
<img class="photo avatar" height="50px" src="#{photo_small_url}" width="50px">
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="entity_searchable">
|
||||
|
|
@ -199,10 +214,10 @@ HTML
|
|||
HTML
|
||||
|
||||
hcard = WebFinger::HCard.from_html(historic_html)
|
||||
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.url).to eq(person.url)
|
||||
expect(hcard.photo_large_url).to eq(photo_large_url)
|
||||
expect(hcard.photo_medium_url).to eq(photo_medium_url)
|
||||
expect(hcard.photo_small_url).to eq(photo_small_url)
|
||||
expect(hcard.searchable).to eq(person.searchable)
|
||||
|
||||
expect(hcard.first_name).to eq(person.first_name)
|
||||
|
|
|
|||
|
|
@ -3,22 +3,16 @@ class Person < ActiveRecord::Base
|
|||
|
||||
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 profile_url; "#{url}u/#{nickname}" end
|
||||
def atom_url; "#{url}public/#{nickname}.atom" end
|
||||
def salmon_url; "#{url}receive/users/#{guid}" 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 photo_default_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_guid(guid)
|
||||
# no remote? and closed_account? check ... this class is only for testing
|
||||
find_by_guid(guid)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ DiasporaFederation.configure do |config|
|
|||
end
|
||||
|
||||
on :person_hcard_fetch do |guid|
|
||||
person = Person.find_by(guid: guid)
|
||||
if person
|
||||
DiasporaFederation::WebFinger::HCard.new(
|
||||
guid: person.guid,
|
||||
nickname: person.nickname,
|
||||
full_name: person.full_name,
|
||||
url: person.url,
|
||||
photo_large_url: person.photo_default_url,
|
||||
photo_medium_url: person.photo_default_url,
|
||||
photo_small_url: person.photo_default_url,
|
||||
public_key: person.serialized_public_key,
|
||||
searchable: person.searchable,
|
||||
first_name: person.first_name,
|
||||
last_name: person.last_name
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue