Merge branch 'stable' into develop

This commit is contained in:
Jonne Haß 2015-08-21 14:23:46 +02:00
commit d396d5555f
38 changed files with 210 additions and 832 deletions

View file

@ -74,6 +74,7 @@ With the port to Bootstrap 3, app/views/terms/default.haml has a new structure.
* Extract StatusMessageService from StatusMessagesController [#6280](https://github.com/diaspora/diaspora/pull/6280) * Extract StatusMessageService from StatusMessagesController [#6280](https://github.com/diaspora/diaspora/pull/6280)
* Refactor HomeController#toggle\_mobile [#6260](https://github.com/diaspora/diaspora/pull/6260) * Refactor HomeController#toggle\_mobile [#6260](https://github.com/diaspora/diaspora/pull/6260)
* Extract CommentService from CommentsController [#6307](https://github.com/diaspora/diaspora/pull/6307) * Extract CommentService from CommentsController [#6307](https://github.com/diaspora/diaspora/pull/6307)
* Extract user/profile discovery into the diaspora\_federation-rails gem [#6310](https://github.com/diaspora/diaspora/pull/6310)
## Bug fixes ## Bug fixes
* Fix indentation and a link title on the default home page [#6212](https://github.com/diaspora/diaspora/pull/6212) * Fix indentation and a link title on the default home page [#6212](https://github.com/diaspora/diaspora/pull/6212)

View file

@ -12,7 +12,7 @@ gem "unicorn", "4.9.0", require: false
# Federation # Federation
gem "diaspora_federation-rails", "0.0.3" gem "diaspora_federation-rails", "0.0.6"
# API and JSON # API and JSON

View file

@ -154,10 +154,14 @@ GEM
eventmachine (>= 1.0.5, < 1.1) eventmachine (>= 1.0.5, < 1.1)
http_parser.rb (~> 0.6) http_parser.rb (~> 0.6)
nokogiri (~> 1.6) nokogiri (~> 1.6)
diaspora_federation (0.0.3) diaspora_federation (0.0.6)
faraday (~> 0.9.0)
faraday_middleware (~> 0.10.0)
nokogiri (~> 1.6, >= 1.6.6) nokogiri (~> 1.6, >= 1.6.6)
diaspora_federation-rails (0.0.3) typhoeus (~> 0.7.0)
diaspora_federation (= 0.0.3) valid (~> 1.0.0)
diaspora_federation-rails (0.0.6)
diaspora_federation (= 0.0.6)
rails (~> 4.2) rails (~> 4.2)
diff-lcs (1.2.5) diff-lcs (1.2.5)
docile (1.1.5) docile (1.1.5)
@ -755,6 +759,7 @@ GEM
raindrops (~> 0.7) raindrops (~> 0.7)
uuid (2.3.8) uuid (2.3.8)
macaddr (~> 1.0) macaddr (~> 1.0)
valid (1.0.0)
warden (1.2.3) warden (1.2.3)
rack (>= 1.0) rack (>= 1.0)
webmock (1.21.0) webmock (1.21.0)
@ -789,7 +794,7 @@ DEPENDENCIES
devise-token_authenticatable (~> 0.4.0) devise-token_authenticatable (~> 0.4.0)
devise_lastseenable (= 0.0.6) devise_lastseenable (= 0.0.6)
diaspora-vines (~> 0.1.28) diaspora-vines (~> 0.1.28)
diaspora_federation-rails (= 0.0.3) diaspora_federation-rails (= 0.0.6)
entypo-rails (= 3.0.0.pre.rc2) entypo-rails (= 3.0.0.pre.rc2)
eye (= 0.7.pre) eye (= 0.7.pre)
factory_girl_rails (= 4.5.0) factory_girl_rails (= 4.5.0)

View file

@ -41,7 +41,7 @@ class PeopleController < ApplicationController
if diaspora_id?(search_query) if diaspora_id?(search_query)
@people = Person.where(:diaspora_handle => search_query.downcase) @people = Person.where(:diaspora_handle => search_query.downcase)
if @people.empty? if @people.empty?
Webfinger.in_background(search_query) Workers::FetchWebfinger.perform_async(search_query)
@background_query = search_query.downcase @background_query = search_query.downcase
end end
end end
@ -127,7 +127,7 @@ class PeopleController < ApplicationController
def retrieve_remote def retrieve_remote
if params[:diaspora_handle] if params[:diaspora_handle]
Webfinger.in_background(params[:diaspora_handle], :single_aspect_form => true) Workers::FetchWebfinger.perform_async(params[:diaspora_handle])
render :nothing => true render :nothing => true
else else
render :nothing => true, :status => 422 render :nothing => true, :status => 422

View file

@ -56,7 +56,7 @@ class Comment < ActiveRecord::Base
end end
def diaspora_handle= nh def diaspora_handle= nh
self.author = Webfinger.new(nh).fetch self.author = Person.find_or_fetch_by_identifier(nh)
end end
def notification_type(user, person) def notification_type(user, person)

View file

@ -43,7 +43,7 @@ class Conversation < ActiveRecord::Base
end end
def diaspora_handle= nh def diaspora_handle= nh
self.author = Webfinger.new(nh).fetch self.author = Person.find_or_fetch_by_identifier(nh)
end end
def first_unread_message(user) def first_unread_message(user)
@ -68,7 +68,7 @@ class Conversation < ActiveRecord::Base
end end
def participant_handles= handles def participant_handles= handles
handles.split(';').each do |handle| handles.split(';').each do |handle|
self.participants << Webfinger.new(handle).fetch participants << Person.find_or_fetch_by_identifier(handle)
end end
end end

View file

@ -35,7 +35,7 @@ class Message < ActiveRecord::Base
end end
def diaspora_handle= nh def diaspora_handle= nh
self.author = Webfinger.new(nh).fetch self.author = Person.find_or_fetch_by_identifier(nh)
end end
def conversation_guid def conversation_guid

View file

@ -238,6 +238,19 @@ class Person < ActiveRecord::Base
serialized_public_key = new_key serialized_public_key = new_key
end end
# discovery (webfinger)
def self.find_or_fetch_by_identifier(account)
# exiting person?
person = by_account_identifier(account)
return person if person.present? && person.profile.present?
# create or update person from webfinger
logger.info "webfingering #{account}, it is not known or needs updating"
DiasporaFederation::Discovery::Discovery.new(account).fetch_and_save
by_account_identifier(account)
end
# database calls # database calls
def self.by_account_identifier(identifier) def self.by_account_identifier(identifier)
identifier = identifier.strip.downcase.sub("acct:", "") identifier = identifier.strip.downcase.sub("acct:", "")
@ -252,32 +265,6 @@ class Person < ActiveRecord::Base
where(guid: guid, closed_account: false).where.not(owner: nil).take where(guid: guid, closed_account: false).where.not(owner: nil).take
end end
def self.create_from_webfinger(profile, hcard)
return nil if profile.nil? || !profile.valid_diaspora_profile?
new_person = Person.new
new_person.serialized_public_key = profile.public_key
new_person.guid = profile.guid
new_person.diaspora_handle = profile.account
new_person.url = profile.seed_location
#hcard_profile = HCard.find profile.hcard.first[:href]
::Logging::Logger[self].info "event=webfinger_marshal valid=#{new_person.valid?} " \
"target=#{new_person.diaspora_handle}"
new_person.assign_new_profile_from_hcard(hcard)
new_person.save!
new_person.profile.save!
new_person
end
def assign_new_profile_from_hcard(hcard)
self.profile = Profile.new(:first_name => hcard[:given_name],
:last_name => hcard[:family_name],
:image_url => hcard[:photo],
:image_url_medium => hcard[:photo_medium],
:image_url_small => hcard[:photo_small],
:searchable => hcard[:searchable])
end
def remote? def remote?
owner_id.nil? owner_id.nil?
end end
@ -359,7 +346,8 @@ class Person < ActiveRecord::Base
end end
def fix_profile def fix_profile
Webfinger.new(self.diaspora_handle).fetch logger.info "fix profile for account: #{diaspora_handle}"
self.reload DiasporaFederation::Discovery::Discovery.new(diaspora_handle).fetch_and_save
reload
end end
end end

View file

@ -1,7 +1,7 @@
class PollParticipation < ActiveRecord::Base class PollParticipation < ActiveRecord::Base
include Diaspora::Federated::Base include Diaspora::Federated::Base
include Diaspora::Guid include Diaspora::Guid
include Diaspora::Relayable include Diaspora::Relayable
belongs_to :poll belongs_to :poll
@ -37,7 +37,7 @@ class PollParticipation < ActiveRecord::Base
end end
def diaspora_handle= nh def diaspora_handle= nh
self.author = Webfinger.new(nh).fetch self.author = Person.find_or_fetch_by_identifier(nh)
end end
def not_already_participated def not_already_participated

View file

@ -462,7 +462,7 @@ class User < ActiveRecord::Base
aq = self.aspects.create(:name => I18n.t('aspects.seed.acquaintances')) aq = self.aspects.create(:name => I18n.t('aspects.seed.acquaintances'))
if AppConfig.settings.autofollow_on_join? if AppConfig.settings.autofollow_on_join?
default_account = Webfinger.new(AppConfig.settings.autofollow_on_join_user).fetch default_account = Person.find_or_fetch_by_identifier(AppConfig.settings.autofollow_on_join_user)
self.share_with(default_account, aq) if default_account self.share_with(default_account, aq) if default_account
end end
aq aq

View file

@ -7,7 +7,7 @@ module Workers
sidekiq_options queue: :socket_webfinger sidekiq_options queue: :socket_webfinger
def perform(account) def perform(account)
person = Webfinger.new(account).fetch person = Person.find_or_fetch_by_identifier(account)
# also, schedule to fetch a few public posts from that person # also, schedule to fetch a few public posts from that person
Diaspora::Fetcher::Public.queue_for(person) unless person.nil? Diaspora::Fetcher::Public.queue_for(person) unless person.nil?

View file

@ -3,11 +3,13 @@ DiasporaFederation.configure do |config|
# the pod url # the pod url
config.server_uri = AppConfig.pod_uri config.server_uri = AppConfig.pod_uri
config.certificate_authorities = AppConfig.environment.certificate_authorities.get
config.define_callbacks do config.define_callbacks do
on :person_webfinger_fetch do |handle| on :fetch_person_for_webfinger do |handle|
person = Person.find_local_by_diaspora_handle(handle) person = Person.find_local_by_diaspora_handle(handle)
if person if person
DiasporaFederation::WebFinger::WebFinger.new( DiasporaFederation::Discovery::WebFinger.new(
acct_uri: "acct:#{person.diaspora_handle}", acct_uri: "acct:#{person.diaspora_handle}",
alias_url: AppConfig.url_to("/people/#{person.guid}"), alias_url: AppConfig.url_to("/people/#{person.guid}"),
hcard_url: AppConfig.url_to(DiasporaFederation::Engine.routes.url_helpers.hcard_path(person.guid)), hcard_url: AppConfig.url_to(DiasporaFederation::Engine.routes.url_helpers.hcard_path(person.guid)),
@ -21,10 +23,10 @@ DiasporaFederation.configure do |config|
end end
end end
on :person_hcard_fetch do |guid| on :fetch_person_for_hcard do |guid|
person = Person.find_local_by_guid(guid) person = Person.find_local_by_guid(guid)
if person if person
DiasporaFederation::WebFinger::HCard.new( DiasporaFederation::Discovery::HCard.new(
guid: person.guid, guid: person.guid,
nickname: person.username, nickname: person.username,
full_name: "#{person.profile.first_name} #{person.profile.last_name}".strip, full_name: "#{person.profile.first_name} #{person.profile.last_name}".strip,
@ -39,5 +41,25 @@ DiasporaFederation.configure do |config|
) )
end end
end end
on :save_person_after_webfinger do |person|
# find existing person or create a new one
person_entity = Person.find_by(diaspora_handle: person.diaspora_id) ||
Person.new(diaspora_handle: person.diaspora_id, guid: person.guid,
serialized_public_key: person.exported_key, url: person.url)
profile = person.profile
profile_entity = person_entity.profile ||= Profile.new
# fill or update profile
profile_entity.first_name = profile.first_name
profile_entity.last_name = profile.last_name
profile_entity.image_url = profile.image_url
profile_entity.image_url_medium = profile.image_url_medium
profile_entity.image_url_small = profile.image_url_small
profile_entity.searchable = profile.searchable
person_entity.save!
end
end end
end end

View file

@ -14,13 +14,10 @@ require 'diaspora'
require 'direction_detector' require 'direction_detector'
require 'email_inviter' require 'email_inviter'
require 'evil_query' require 'evil_query'
require 'h_card'
require 'hydra_wrapper' require 'hydra_wrapper'
require 'postzord' require 'postzord'
require 'publisher' require 'publisher'
require 'pubsubhubbub' require 'pubsubhubbub'
require 'salmon' require 'salmon'
require 'stream' require 'stream'
require 'webfinger'
require 'webfinger_profile'
require 'account_deleter' require 'account_deleter'

View file

@ -14,7 +14,7 @@ module Diaspora
post = Post.where(guid: guid).first post = Post.where(guid: guid).first
return post if post return post if post
post_author = Webfinger.new(author_id).fetch post_author = Person.find_or_fetch_by_identifier(author_id)
post_author.save! unless post_author.persisted? post_author.save! unless post_author.persisted?
if fetched_post = fetch_post(post_author, guid) if fetched_post = fetch_post(post_author, guid)

View file

@ -24,7 +24,7 @@ module Federated
end end
def diaspora_handle=(nh) def diaspora_handle=(nh)
self.author = Webfinger.new(nh).fetch self.author = Person.find_or_fetch_by_identifier(nh)
end end
def parent_class def parent_class

View file

@ -1,21 +0,0 @@
# Copyright (c) 2010-2011, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
module HCard
def self.parse(doc)
{
given_name: doc.css(".given_name").text,
family_name: doc.css(".family_name").text,
url: doc.css("#pod_location").text,
photo: doc.css(".entity_photo .photo[src]").attribute("src").text,
photo_small: doc.css(".entity_photo_small .photo[src]").attribute("src").text,
photo_medium: doc.css(".entity_photo_medium .photo[src]").attribute("src").text,
searchable: doc.css(".searchable").text == "true"
}
end
def self.build(raw_hcard)
parse Nokogiri::HTML(raw_hcard)
end
end

View file

@ -9,7 +9,7 @@ class Postzord::Receiver::Private < Postzord::Receiver
@user_person = @user.person @user_person = @user.person
@salmon_xml = opts[:salmon_xml] @salmon_xml = opts[:salmon_xml]
@author = opts[:person] || Webfinger.new(salmon.author_id).fetch @author = opts[:person] || Person.find_or_fetch_by_identifier(salmon.author_id)
@object = opts[:object] @object = opts[:object]
end end
@ -56,7 +56,7 @@ class Postzord::Receiver::Private < Postzord::Receiver
if @object.respond_to?(:relayable?) if @object.respond_to?(:relayable?)
#if A and B are friends, and A sends B a comment from C, we delegate the validation to the owner of the post being commented on #if A and B are friends, and A sends B a comment from C, we delegate the validation to the owner of the post being commented on
xml_author = @user.owns?(@object.parent) ? @object.diaspora_handle : @object.parent_author.diaspora_handle xml_author = @user.owns?(@object.parent) ? @object.diaspora_handle : @object.parent_author.diaspora_handle
@author = Webfinger.new(@object.diaspora_handle).fetch if @object.author @author = Person.find_or_fetch_by_identifier(@object.diaspora_handle) if @object.author
else else
xml_author = @object.diaspora_handle xml_author = @object.diaspora_handle
end end

View file

@ -8,7 +8,7 @@ class Postzord::Receiver::Public < Postzord::Receiver
def initialize(xml) def initialize(xml)
@salmon = Salmon::Slap.from_xml(xml) @salmon = Salmon::Slap.from_xml(xml)
@author = Webfinger.new(@salmon.author_id).fetch @author = Person.find_or_fetch_by_identifier(@salmon.author_id)
end end
# @return [Boolean] # @return [Boolean]

View file

@ -1,123 +0,0 @@
# Copyright (c) 2010-2012, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
class Webfinger
include Diaspora::Logging
attr_accessor :host_meta_xrd, :webfinger_profile_xrd,
:webfinger_profile, :hcard, :hcard_xrd, :person,
:account, :ssl
def initialize(account)
self.account = account
self.ssl = true
end
def fetch
return person if existing_person_with_profile?
create_or_update_person_from_webfinger_profile!
end
def self.in_background(account, opts={})
Workers::FetchWebfinger.perform_async(account)
end
#everything below should be private I guess
def account=(str)
@account = str.strip.gsub('acct:','').to_s.downcase
end
def get(url)
logger.info "Getting: #{url} for #{account}"
begin
res = Faraday.get(url)
unless res.success?
raise "Failed to fetch #{url}: #{res.status}"
end
res.body
rescue OpenSSL::SSL::SSLError => e
logger.error "Failed to fetch #{url}: SSL setup invalid"
raise e
rescue => e
logger.error "Failed to fetch: #{url} for #{account}; #{e.message}"
raise e
end
end
def existing_person_with_profile?
cached_person.present? && cached_person.profile.present?
end
def cached_person
self.person ||= Person.by_account_identifier(account)
end
def create_or_update_person_from_webfinger_profile!
logger.info "webfingering #{account}, it is not known or needs updating"
if person #update my profile please
person.assign_new_profile_from_hcard(self.hcard)
else
person = make_person_from_webfinger
end
logger.info "successfully webfingered #{@account}" if person
person
end
#this tries the xrl url with https first, then falls back to http
def host_meta_xrd
begin
get(host_meta_url)
rescue => e
if self.ssl
self.ssl = false
retry
else
raise "there was an error getting the xrd from account #{@account}: #{e.message}"
end
end
end
def hcard
@hcard ||= HCard.build(hcard_xrd)
end
def webfinger_profile
@webfinger_profile ||= WebfingerProfile.new(account, webfinger_profile_xrd)
end
def hcard_url
self.webfinger_profile.hcard
end
def webfinger_profile_url
doc = Nokogiri::XML(self.host_meta_xrd)
return nil if doc.namespaces["xmlns"] != "http://docs.oasis-open.org/ns/xri/xrd-1.0"
swizzle doc.search('Link').find{|x| x['rel']=='lrdd'}['template']
end
def webfinger_profile_xrd
@webfinger_profile_xrd ||= get(webfinger_profile_url)
logger.warn "#{@account} doesn't exists anymore" if @webfinger_profile_xrd == false
@webfinger_profile_xrd
end
def hcard_xrd
@hcard_xrd ||= get(hcard_url)
end
def make_person_from_webfinger
Person.create_from_webfinger(webfinger_profile, hcard) unless webfinger_profile_xrd == false
end
def host_meta_url
domain = account.split('@')[1]
"http#{'s' if self.ssl}://#{domain}/.well-known/host-meta"
end
def swizzle(template)
template.gsub('{uri}', account)
end
end

View file

@ -1,53 +0,0 @@
class WebfingerProfile
include Diaspora::Logging
attr_accessor :webfinger_profile, :account, :links, :hcard, :guid, :public_key, :seed_location
def initialize(account, webfinger_profile)
@account = account
@webfinger_profile = webfinger_profile
@links = {}
set_fields
end
def valid_diaspora_profile?
!(@webfinger_profile.nil? || @account.nil? || @links.nil? || @hcard.nil? ||
@guid.nil? || @public_key.nil? || @seed_location.nil? )
end
private
def set_fields
doc = Nokogiri::XML.parse(webfinger_profile)
doc.remove_namespaces!
account_string = doc.css('Subject').text.gsub('acct:', '').strip
raise "account in profile(#{account_string}) and account requested (#{@account}) do not match" if account_string != @account
doc.css('Link').each do |l|
rel = text_of_attribute(l, 'rel')
href = text_of_attribute(l, 'href')
@links[rel] = href
case rel
when "http://microformats.org/profile/hcard"
@hcard = href
when "http://joindiaspora.com/guid"
@guid = href
when "http://joindiaspora.com/seed_location"
@seed_location = href
end
end
begin
pubkey = text_of_attribute( doc.at('Link[rel=diaspora-public-key]'), 'href')
@public_key = Base64.decode64 pubkey
rescue => e
logger.warn "event=invalid_profile identifier=#{@account}"
end
end
def text_of_attribute(doc, attr)
doc.attribute(attr) ? doc.attribute(attr).text : nil
end
end

View file

@ -1,36 +0,0 @@
# Copyright (c) 2010-2011, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
require "spec_helper"
# this is temporarily needed for fixture generation
# TODO: remove this after the parsing is also in the diaspora_federation gem
describe DiasporaFederation do
routes { DiasporaFederation::Engine.routes }
let(:fixture_path) { Rails.root.join("spec", "fixtures") }
describe DiasporaFederation::WebfingerController, type: :controller do
it "generates the host_meta fixture", fixture: true do
get :host_meta
expect(response).to be_success
expect(response.body).to match(/webfinger/)
save_fixture(response.body, "host-meta", fixture_path)
end
it "generates the webfinger fixture", fixture: true do
post :legacy_webfinger, "q" => alice.person.diaspora_handle
expect(response).to be_success
save_fixture(response.body, "webfinger", fixture_path)
end
end
describe DiasporaFederation::HCardController, type: :controller do
it "generates the hCard fixture", fixture: true do
post :hcard, "guid" => alice.person.guid.to_s
expect(response).to be_success
save_fixture(response.body, "hcard", fixture_path)
end
end
end

View file

@ -16,7 +16,7 @@ describe RegistrationsController, :type => :controller do
:password_confirmation => "password" :password_confirmation => "password"
} }
} }
allow(Webfinger).to receive_message_chain(:new, :fetch).and_return(FactoryGirl.create(:person)) allow(Person).to receive(:find_or_fetch_by_identifier).and_return(FactoryGirl.create(:person))
end end
describe '#check_registrations_open!' do describe '#check_registrations_open!' do

View file

@ -301,4 +301,33 @@ FactoryGirl.define do
end end
factory(:status, :parent => :status_message) factory(:status, :parent => :status_message)
# Factories for the DiasporaFederation-gem
factory(:federation_person_from_webfinger, class: DiasporaFederation::Entities::Person) do
sequence(:guid) { UUID.generate :compact }
sequence(:diaspora_id) {|n| "bob-person-#{n}#{r_str}@example.net" }
url AppConfig.pod_uri.to_s
exported_key OpenSSL::PKey::RSA.generate(1024).public_key.export
profile {
DiasporaFederation::Entities::Profile.new(
FactoryGirl.attributes_for(:federation_profile_from_hcard, diaspora_id: diaspora_id))
}
end
factory(:federation_profile_from_hcard, class: DiasporaFederation::Entities::Profile) do
sequence(:diaspora_id) {|n| "bob-person-#{n}#{r_str}@example.net" }
sequence(:first_name) {|n| "My Name#{n}#{r_str}" }
last_name nil
image_url "/assets/user/default.png"
image_url_medium "/assets/user/default.png"
image_url_small "/assets/user/default.png"
searchable true
end
factory :federation_profile_from_hcard_with_image_url, parent: :federation_profile_from_hcard do
image_url "http://example.com/image.jpg"
image_url_medium "http://example.com/image_mid.jpg"
image_url_small "http://example.com/image_small.jpg"
end
end end

View file

@ -1,10 +1,10 @@
require "spec_helper" require "spec_helper"
describe "diaspora federation callbacks" do describe "diaspora federation callbacks" do
describe ":person_webfinger_fetch" do describe ":fetch_person_for_webfinger" do
it "returns a WebFinger instance with the data from the person" do it "returns a WebFinger instance with the data from the person" do
person = alice.person person = alice.person
wf = DiasporaFederation.callbacks.trigger(:person_webfinger_fetch, alice.diaspora_handle) wf = DiasporaFederation.callbacks.trigger(:fetch_person_for_webfinger, alice.diaspora_handle)
expect(wf.acct_uri).to eq("acct:#{person.diaspora_handle}") expect(wf.acct_uri).to eq("acct:#{person.diaspora_handle}")
expect(wf.alias_url).to eq(AppConfig.url_to("/people/#{person.guid}")) expect(wf.alias_url).to eq(AppConfig.url_to("/people/#{person.guid}"))
expect(wf.hcard_url).to eq(AppConfig.url_to("/hcard/users/#{person.guid}")) expect(wf.hcard_url).to eq(AppConfig.url_to("/hcard/users/#{person.guid}"))
@ -17,15 +17,15 @@ describe "diaspora federation callbacks" do
end end
it "returns nil if the person was not found" do it "returns nil if the person was not found" do
wf = DiasporaFederation.callbacks.trigger(:person_webfinger_fetch, "unknown@example.com") wf = DiasporaFederation.callbacks.trigger(:fetch_person_for_webfinger, "unknown@example.com")
expect(wf).to be_nil expect(wf).to be_nil
end end
end end
describe ":person_hcard_fetch" do describe ":fetch_person_for_hcard" do
it "returns a HCard instance with the data from the person" do it "returns a HCard instance with the data from the person" do
person = alice.person person = alice.person
hcard = DiasporaFederation.callbacks.trigger(:person_hcard_fetch, alice.guid) hcard = DiasporaFederation.callbacks.trigger(:fetch_person_for_hcard, alice.guid)
expect(hcard.guid).to eq(person.guid) expect(hcard.guid).to eq(person.guid)
expect(hcard.nickname).to eq(person.username) expect(hcard.nickname).to eq(person.username)
expect(hcard.full_name).to eq("#{person.profile.first_name} #{person.profile.last_name}") expect(hcard.full_name).to eq("#{person.profile.first_name} #{person.profile.last_name}")
@ -44,13 +44,107 @@ describe "diaspora federation callbacks" do
user.person.profile.last_name = nil user.person.profile.last_name = nil
user.person.profile.save user.person.profile.save
hcard = DiasporaFederation.callbacks.trigger(:person_hcard_fetch, user.guid) hcard = DiasporaFederation.callbacks.trigger(:fetch_person_for_hcard, user.guid)
expect(hcard.full_name).to eq(user.person.profile.first_name) expect(hcard.full_name).to eq(user.person.profile.first_name)
end end
it "returns nil if the person was not found" do it "returns nil if the person was not found" do
hcard = DiasporaFederation.callbacks.trigger(:person_hcard_fetch, "1234567890abcdef") hcard = DiasporaFederation.callbacks.trigger(:fetch_person_for_hcard, "1234567890abcdef")
expect(hcard).to be_nil expect(hcard).to be_nil
end end
end end
describe ":save_person_after_webfinger" do
context "new person" do
it "creates a new person" do
person = DiasporaFederation::Entities::Person.new(FactoryGirl.attributes_for(:federation_person_from_webfinger))
DiasporaFederation.callbacks.trigger(:save_person_after_webfinger, person)
person_entity = Person.find_by(diaspora_handle: person.diaspora_id)
expect(person_entity.guid).to eq(person.guid)
expect(person_entity.serialized_public_key).to eq(person.exported_key)
expect(person_entity.url).to eq(person.url)
profile = person.profile
profile_entity = person_entity.profile
expect(profile_entity.first_name).to eq(profile.first_name)
expect(profile_entity.last_name).to eq(profile.last_name)
expect(profile_entity[:image_url]).to be_nil
expect(profile_entity[:image_url_medium]).to be_nil
expect(profile_entity[:image_url_small]).to be_nil
expect(profile_entity.searchable).to eq(profile.searchable)
end
it "creates a new person with images" do
person = DiasporaFederation::Entities::Person.new(
FactoryGirl.attributes_for(
:federation_person_from_webfinger,
profile: DiasporaFederation::Entities::Profile.new(
FactoryGirl.attributes_for(:federation_profile_from_hcard_with_image_url))
)
)
DiasporaFederation.callbacks.trigger(:save_person_after_webfinger, person)
person_entity = Person.find_by(diaspora_handle: person.diaspora_id)
expect(person_entity.guid).to eq(person.guid)
expect(person_entity.serialized_public_key).to eq(person.exported_key)
expect(person_entity.url).to eq(person.url)
profile = person.profile
profile_entity = person_entity.profile
expect(profile_entity.first_name).to eq(profile.first_name)
expect(profile_entity.last_name).to eq(profile.last_name)
expect(profile_entity.image_url).to eq(profile.image_url)
expect(profile_entity.image_url_medium).to eq(profile.image_url_medium)
expect(profile_entity.image_url_small).to eq(profile.image_url_small)
expect(profile_entity.searchable).to eq(profile.searchable)
end
end
context "update profile" do
let(:existing_person_entity) { FactoryGirl.create(:person) }
let(:person) {
DiasporaFederation::Entities::Person.new(
FactoryGirl.attributes_for(:federation_person_from_webfinger,
diaspora_id: existing_person_entity.diaspora_handle)
)
}
it "updates an existing profile" do
DiasporaFederation.callbacks.trigger(:save_person_after_webfinger, person)
person_entity = Person.find_by(diaspora_handle: existing_person_entity.diaspora_handle)
profile = person.profile
profile_entity = person_entity.profile
expect(profile_entity.first_name).to eq(profile.first_name)
expect(profile_entity.last_name).to eq(profile.last_name)
end
it "should not change the existing person" do
DiasporaFederation.callbacks.trigger(:save_person_after_webfinger, person)
person_entity = Person.find_by(diaspora_handle: existing_person_entity.diaspora_handle)
expect(person_entity.guid).to eq(existing_person_entity.guid)
expect(person_entity.serialized_public_key).to eq(existing_person_entity.serialized_public_key)
expect(person_entity.url).to eq(existing_person_entity.url)
end
it "creates profile for existing person if no profile present" do
existing_person_entity.profile = nil
existing_person_entity.save
DiasporaFederation.callbacks.trigger(:save_person_after_webfinger, person)
person_entity = Person.find_by(diaspora_handle: existing_person_entity.diaspora_handle)
profile = person.profile
profile_entity = person_entity.profile
expect(profile_entity.first_name).to eq(profile.first_name)
expect(profile_entity.last_name).to eq(profile.last_name)
end
end
end
end end

View file

@ -1,72 +0,0 @@
<body id="hcard">
<div id="wrap">
<div id="core">
<dl id="site_nav_local_views">
<dt>Local views</dt>
<dd></dd>
</dl>
<div id="content">
<h1>Evan Prodromou</h1>
<div id="content_inner">
<div id="i" class="entity_profile vcard author">
<h2>User profile</h2>
<dl class="entity_depiction">
<dt>Photo</dt>
<dd>
<img src="http://avatar.status.net/evan/1-96-20100726204409.jpeg" class="photo avatar" width="96" height="96" alt="evan"/>
</dd>
</dl>
<dl class="entity_nickname">
<dt>Nickname</dt>
<dd>
<a href="http://evan.status.net/" rel="me" class="nickname url uid">evan</a>
</dd>
</dl>
<dl class="entity_fn">
<dt>Full name</dt>
<dd>
<span class="fn">Evan Prodromou</span>
</dd>
</dl>
<dl class="entity_location">
<dt>Location</dt>
<dd class="label">Montreal, QC, Canada</dd>
</dl>
<dl class="entity_url">
<dt>URL</dt>
<dd>
<a href="http://evan.prodromou.name/" rel="me" class="url">http://evan.prodromou.name/</a>
</dd>
</dl>
<dl class="entity_note">
<dt>Note</dt>
<dd class="note">Montreal hacker and entrepreneur. Founder of identi.ca, lead developer of StatusNet, CEO of StatusNet Inc.</dd>
</dl>
</div>
</div>
</div>
</div>
<div id="footer">
<dl id="licenses">
<dt id="site_statusnet_license">StatusNet software license</dt>
<dd><p><strong>Evan Prodromou</strong> is a microblogging service brought to you by <a href="http://status.net/">Status.net</a>. It runs the <a href="http://status.net/">StatusNet</a> microblogging software, version 0.9.5, available under the <a href="http://www.fsf.org/licensing/licenses/agpl-3.0.html">GNU Affero General Public License</a>.</p>
</dd>
<dt id="site_content_license">Site content license</dt>
<dd id="site_content_license_cc">
<p>
<img id="license_cc" src="http://i.creativecommons.org/l/by/3.0/80x15.png" alt="Creative Commons Attribution 3.0" width="80" height="15"/>:w
All Evan Prodromou content and data are available under the <a class="license" rel="external license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> license.</p>
</dd>
</dl>
</div>
</div>
</body>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
<Subject>acct:tom@tom.joindiaspora.com</Subject>
<Alias>"http://tom.joindiaspora.com/"</Alias>
<Link rel="http://microformats.org/profile/hcard" type="text/html" href="http://tom.joindiaspora.com/hcard/users/4c8eccce34b7da59ff000002"/>
<Link rel="http://joindiaspora.com/seed_location" type="text/html" href="http://tom.joindiaspora.com/"/>
<Link rel="http://joindiaspora.com/guid" type="text/html" href="4c8eccce34b7da59ff000002"/>
<Link rel='http://webfinger.net/rel/profile-page' type='text/html' href="http://tom.joindiaspora.com/u/tom"/>
<Link rel="http://schemas.google.com/g/2010#updates-from" type="application/atom+xml" href="http://tom.joindiaspora.com/u/tom.atom"/>
<Link rel="diaspora-public-key" type="RSA" href="LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUNDZ0tDQWdFQXlt dHpUdWQ3SytXQklPVVYwMmxZN2Z1NjdnNWQrbTBra1ZIQlgzTk1uYXB5bnZL a0VSemoKbkxma2JrTVpEVGdPNG1UaThmWFI3Q1ZSK3Q1SFN4b2Vub0JWazVX eUFabkEzWmpTRjBPcC9RakhlYzhvK0dVSApDOFluNFJ5N01hQ0R1cUNpNnJv c2RlbUlLTm1Fa2dsVVY1VzZ4WFd4Vmtrb21oL2VCQ2FmaVdMTXFRMG82NGox Ckw3aXNjQjVOM3ZkbnBrUmU3SkFxLzNDUTI3dWhDS0ZIWG1JYm1iVmhJQTNC R0J6YStPV3NjK1Z5cjV0Mm1wSlIKU1RXMk9UL20rS0NPK21kdnpmenQ0TzEr UHc1M1pJMjRpMlc2cW1XdThFZ1Z6QVcyMStuRGJManZiNHpzVHlrNQppN1JM cG8rUFl2VUJlLy8wM1lkQUJoRlJhVXpTL0RtcWRubEVvb0VvK0VmYzRkQ1NF bWVkMUgrek01c2xqQm1rCks5amsvOHNQZDB0SVZmMWZXdW9BcWZTSmErSXdr OHNybkdZbEVlaFV1dVhIY0x2b2JlUXJKYWdiRGc1Qll5TnIKeTAzcHpKTHlS ZU9UcC9RK1p0TXpMOFJMZWJsUzlWYXdNQzNDVzc5K0RGditTWGZ0eTl3NC8w d2NpUHpKejg2bgp2VzJ5K3crTThOWG52enBWNU81dGI4azZxZ2N0WjBmRzFu eXQ0RklsSHNVaUVoNnZLZmNLSmFPeWFRSGNGcWVxCjkwUkpoMm9TMDJBdFJx TFRSWDJJQjFnYXZnWEFXN1NYanJNbUNlVzlCdVBKYU5nZkp3WFFaelVoa0tC V1k0VnMKZTRFVWRob3R5RWkvUmE0RXVZU01ZcnZEeUFRUHJsY0wveDliaU1p bHVPcU9OMEpJZ1VodEZQRUNBd0VBQVE9PQotLS0tLUVORCBSU0EgUFVCTElD IEtFWS0tLS0tCg== "/>
</XRD>

View file

@ -1,64 +0,0 @@
<div id='content'>
<h1>Alexander Hamiltom</h1>
<div id='content_inner'>
<div class='entity_profile vcard author' id='i'>
<h2>User profile</h2>
<dl class='entity_nickname'>
<dt>Nickname</dt>
<dd>
<a class='nickname url uid' href='http://localhost:3000/' rel='me'>Alexander Hamiltom</a>
</dd>
</dl>
<dl class='entity_given_name'>
<dt>First name</dt>
<dd>
<span class='given_name'>Alexander</span>
</dd>
</dl>
<dl class='entity_family_name'>
<dt>Family name</dt>
<dd>
<span class='family_name'>Hamiltom</span>
</dd>
</dl>
<dl class='entity_fn'>
<dt>Full name</dt>
<dd>
<span class='fn'>Alexander Hamiltom</span>
</dd>
</dl>
<dl class='entity_url'>
<dt>URL</dt>
<dd>
<a class='url' href='http://localhost:3000/' id='pod_location' rel='me'>http://localhost:3000/</a>
</dd>
</dl>
<dl class='entity_photo'>
<dt>Photo</dt>
<dd>
<img class='photo avatar' height='300px' src='http://localhost:3000/uploads/images/thumb_large_8rxQAwC4Vx4cf5667d37db5b0fef000003.jpg' width='300px'>
</dd>
</dl>
<dl class='entity_photo_medium'>
<dt>Photo</dt>
<dd>
<img class='photo avatar' height='100px' src='http://localhost:3000/uploads/images/thumb_medium_8rxQAwC4Vx4cf5667d37db5b0fef000003.jpg' width='100px'>
</dd>
</dl>
<dl class='entity_photo_small'>
<dt>Photo</dt>
<dd>
<img class='photo avatar' height='50px' src='http://localhost:3000/uploads/images/thumb_small_8rxQAwC4Vx4cf5667d37db5b0fef000003.jpg' width='50px'>
</dd>
</dl>
<dl class='entity_searchable'>
<dt>Searchable</dt>
<dd>
<span class='searchable'>false</span>
</dd>
</dl>
</div>
</div>
</div>

View file

@ -1,7 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>
<Link rel='lrdd'
template='http://tom.joindiaspora.com/webfinger/?q={uri}'>
<Title>Resource Descriptor</Title>
</Link>
</XRD>

View file

@ -1,15 +0,0 @@
<XRD>
<Subject>acct:evan@status.net</Subject>
<Alias>acct:evan@evan.status.net</Alias>
<Alias>http://evan.status.net/user/1</Alias>
<Link rel="http://webfinger.net/rel/profile-page" type="text/html" href="http://evan.status.net/user/1"/>
<Link rel="http://schemas.google.com/g/2010#updates-from" href="http://evan.status.net/api/statuses/user_timeline/1.atom" type="application/atom+xml"/>
<Link rel="http://microformats.org/profile/hcard" type="text/html" href="http://evan.status.net/hcard"/>
<Link rel="http://gmpg.org/xfn/11" type="text/html" href="http://evan.status.net/user/1"/>
<Link rel="describedby" type="application/rdf+xml" href="http://evan.status.net/foaf"/>
<Link rel="salmon" href="http://evan.status.net/main/salmon/user/1"/>
<Link rel="http://salmon-protocol.org/ns/salmon-replies" href="http://evan.status.net/main/salmon/user/1"/>
<Link rel="http://salmon-protocol.org/ns/salmon-mention" href="http://evan.status.net/main/salmon/user/1"/>
<Link rel="magic-public-key" href="data:application/magic-public-key,RSA.vyohOlwX03oJUg6R8BQP4V-6QQUfPg9gzOwk3ENQjqeGorHN8RNI4rhCQp7tACe9DEdEKtzZHbSvQC2zRICQ9JG_SIcpiU9jcT2imN5cPLZZQuPFZWwG4xPu_8LKRHuXeLGkzQMjvg6jFBl7qdo_iPnlbtIBb-mEuAnfRMcdUPE=.AQAB"/>
<Link rel="http://ostatus.org/schema/1.0/subscribe" template="http://evan.status.net/main/ostatussub?profile={uri}"/>
</XRD>

View file

@ -19,46 +19,6 @@ module HelperMethods
:receiving => true) :receiving => true)
end end
def stub_success(address = 'abc@example.com', opts = {})
host = address.split('@')[1]
stub_request(:get, "https://#{host}/.well-known/host-meta").to_return(:status => 200, :body => host_xrd)
stub_request(:get, "http://#{host}/.well-known/host-meta").to_return(:status => 200, :body => host_xrd)
if opts[:diaspora] || host.include?("diaspora")
stub_request(:get, /webfinger\/\?q=#{address}/).to_return(:status => 200, :body => finger_xrd)
stub_request(:get, "http://#{host}/hcard/users/4c8eccce34b7da59ff000002").to_return(:status => 200, :body => hcard_response)
else
stub_request(:get, /webfinger\/\?q=#{address}/).to_return(:status => 200, :body => nonseed_finger_xrd)
stub_request(:get, 'http://evan.status.net/hcard').to_return(:status => 200, :body => evan_hcard)
end
end
def stub_failure(address = 'abc@example.com')
host = address.split('@')[1]
stub_request(:get, "https://#{host}/.well-known/host-meta").to_return(:status => 200, :body => host_xrd)
stub_request(:get, "http://#{host}/.well-known/host-meta").to_return(:status => 200, :body => host_xrd)
stub_request(:get, /webfinger\/\?q=#{address}/).to_return(:status => 500)
end
def host_xrd
File.open(File.dirname(__FILE__) + '/fixtures/host_xrd').read
end
def finger_xrd
File.open(File.dirname(__FILE__) + '/fixtures/finger_xrd').read
end
def hcard_response
File.open(File.dirname(__FILE__) + '/fixtures/hcard_response').read
end
def nonseed_finger_xrd
File.open(File.dirname(__FILE__) + '/fixtures/nonseed_finger_xrd').read
end
def evan_hcard
File.open(File.dirname(__FILE__) + '/fixtures/evan_hcard').read
end
def uploaded_photo def uploaded_photo
fixture_filename = 'button.png' fixture_filename = 'button.png'
fixture_name = File.join(File.dirname(__FILE__), 'fixtures', fixture_filename) fixture_name = File.join(File.dirname(__FILE__), 'fixtures', fixture_filename)

View file

@ -225,11 +225,10 @@ describe 'a user receives a post', :type => :request do
Profile.where(:person_id => remote_person.id).delete_all Profile.where(:person_id => remote_person.id).delete_all
remote_person.attributes.delete(:id) # leaving a nil id causes it to try to save with id set to NULL in postgres remote_person.attributes.delete(:id) # leaving a nil id causes it to try to save with id set to NULL in postgres
m = double()
expect(Webfinger).to receive(:new).twice.with(eve.person.diaspora_handle).and_return(m)
remote_person.save(:validate => false) remote_person.save(:validate => false)
remote_person.profile = FactoryGirl.create(:profile, :person => remote_person) remote_person.profile = FactoryGirl.create(:profile, :person => remote_person)
expect(m).to receive(:fetch).twice.and_return(remote_person) expect(Person).to receive(:find_or_fetch_by_identifier).twice.with(eve.person.diaspora_handle)
.and_return(remote_person)
expect(bob.reload.visible_shareables(Post).size).to eq(1) expect(bob.reload.visible_shareables(Post).size).to eq(1)
post_in_db = StatusMessage.find(@post.id) post_in_db = StatusMessage.find(@post.id)

View file

@ -1,43 +0,0 @@
# Copyright (c) 2010-2011, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
require "spec_helper"
describe HCard do
it "should parse an hcard" do
raw_hcard = hcard_response
hcard = HCard.build raw_hcard
expect(hcard[:family_name].include?("Hamiltom")).to be true
expect(hcard[:given_name].include?("Alex")).to be true
expect(hcard[:photo].include?("thumb_large")).to be true
expect(hcard[:photo_medium].include?("thumb_medium")).to be true
expect(hcard[:photo_small].include?("thumb_small")).to be true
expect(hcard[:url]).to eq("http://localhost:3000/")
expect(hcard[:searchable]).to eq(false)
end
it "should parse an hcard with searchable true" do
raw_hcard = hcard_response.sub("<span class='searchable'>false</span>", "<span class='searchable'>true</span>")
hcard = HCard.build raw_hcard
expect(hcard[:family_name].include?("Hamiltom")).to be true
expect(hcard[:given_name].include?("Alex")).to be true
expect(hcard[:photo].include?("thumb_large")).to be true
expect(hcard[:photo_medium].include?("thumb_medium")).to be true
expect(hcard[:photo_small].include?("thumb_small")).to be true
expect(hcard[:url]).to eq("http://localhost:3000/")
expect(hcard[:searchable]).to eq(true)
end
it "should parse an hcard with empty searchable" do
raw_hcard = hcard_response.sub("<span class='searchable'>false</span>", "<span class='searchable'></span>")
hcard = HCard.build raw_hcard
expect(hcard[:family_name].include?("Hamiltom")).to be true
expect(hcard[:given_name].include?("Alex")).to be true
expect(hcard[:photo].include?("thumb_large")).to be true
expect(hcard[:photo_medium].include?("thumb_medium")).to be true
expect(hcard[:photo_small].include?("thumb_small")).to be true
expect(hcard[:url]).to eq("http://localhost:3000/")
expect(hcard[:searchable]).to eq(false)
end
end

View file

@ -13,7 +13,7 @@ describe Postzord::Receiver::Private do
describe '.initialize' do describe '.initialize' do
it 'valid for local' do it 'valid for local' do
expect(Webfinger).not_to receive(:new) expect(Person).not_to receive(:find_or_fetch_by_identifier)
expect(Salmon::EncryptedSlap).not_to receive(:from_xml) expect(Salmon::EncryptedSlap).not_to receive(:from_xml)
zord = Postzord::Receiver::Private.new(bob, :person => alice.person, :object => @alices_post) zord = Postzord::Receiver::Private.new(bob, :person => alice.person, :object => @alices_post)
@ -24,11 +24,9 @@ describe Postzord::Receiver::Private do
it 'valid for remote' do it 'valid for remote' do
salmon_double = double() salmon_double = double()
web_double = double()
expect(web_double).to receive(:fetch).and_return true
expect(salmon_double).to receive(:author_id).and_return(true) expect(salmon_double).to receive(:author_id).and_return(true)
expect(Salmon::EncryptedSlap).to receive(:from_xml).with(@salmon_xml, bob).and_return(salmon_double) expect(Salmon::EncryptedSlap).to receive(:from_xml).with(@salmon_xml, bob).and_return(salmon_double)
expect(Webfinger).to receive(:new).and_return(web_double) expect(Person).to receive(:find_or_fetch_by_identifier).and_return(true)
zord = Postzord::Receiver::Private.new(bob, :salmon_xml => @salmon_xml) zord = Postzord::Receiver::Private.new(bob, :salmon_xml => @salmon_xml)
expect(zord.instance_variable_get(:@user)).not_to be_nil expect(zord.instance_variable_get(:@user)).not_to be_nil

View file

@ -1,42 +0,0 @@
require 'spec_helper'
describe WebfingerProfile do
let(:webfinger_profile){File.open(Rails.root.join("spec", "fixtures", "finger_xrd")).read.strip}
let(:not_diaspora_webfinger){File.open(Rails.root.join("spec", "fixtures", "nonseed_finger_xrd")).read.strip}
let(:account){"tom@tom.joindiaspora.com"}
let(:profile){ WebfingerProfile.new(account, webfinger_profile) }
context "parsing a diaspora profile" do
describe '#valid_diaspora_profile?' do
it 'should check all of the required fields' do
expect(manual_nil_check(profile)).to eq(profile.valid_diaspora_profile?)
end
end
describe '#set_fields' do
it 'should check to make sure it has a the right webfinger profile' do
expect{ WebfingerProfile.new("nottom@tom.joindiaspora.com", webfinger_profile)}.to raise_error
end
it 'should handle a non-diaspora profile without blowing up' do
expect{ WebfingerProfile.new("evan@status.net", not_diaspora_webfinger)}.not_to raise_error
end
[:links, :hcard, :guid, :seed_location, :public_key].each do |field|
it 'should sets the #{field} field' do
expect(profile.send(field)).to be_present
end
end
end
end
def manual_nil_check(profile)
profile.instance_variables.each do |var|
var = var.to_s.gsub('@', '')
return false if profile.send(var).nil? == true
end
true
end
end

View file

@ -1,221 +0,0 @@
# Copyright (c) 2010-2011, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
require 'spec_helper'
describe Webfinger do
let(:host_meta_xrd) { File.open(Rails.root.join('spec', 'fixtures', 'host-meta.fixture.html')).read }
let(:webfinger_xrd) { File.open(Rails.root.join('spec', 'fixtures', 'webfinger.fixture.html')).read }
let(:hcard_xml) { File.open(Rails.root.join('spec', 'fixtures', 'hcard.fixture.html')).read }
let(:account){'foo@bar.com'}
let(:account_in_fixtures){"alice@localhost:9887"}
let(:finger){Webfinger.new(account)}
let(:host_meta_url){"http://#{AppConfig.pod_uri.authority}/webfinger?q="}
describe '#intialize' do
it 'sets account ' do
n = Webfinger.new("mbs348@gmail.com")
expect(n.account).not_to be nil
end
it "downcases account and strips whitespace, and gsub 'acct:'" do
n = Webfinger.new("acct:BIGBOY@Example.Org ")
expect(n.account).to eq('bigboy@example.org')
end
it 'should set ssl as the default' do
foo = Webfinger.new(account)
expect(foo.ssl).to be true
end
end
describe '.in_background' do
it 'enqueues a Workers::FetchWebfinger job' do
expect(Workers::FetchWebfinger).to receive(:perform_async).with(account)
Webfinger.in_background(account)
end
end
describe '#fetch' do
it 'works' do
finger = Webfinger.new(account_in_fixtures)
allow(finger).to receive(:host_meta_xrd).and_return(host_meta_xrd)
allow(finger).to receive(:hcard_xrd).and_return(hcard_xml)
allow(finger).to receive(:webfinger_profile_xrd).and_return(webfinger_xrd)
person = finger.fetch
expect(person).to be_valid
expect(person).to be_a Person
end
end
describe '#get' do
it 'makes a request and grabs the body' do
url ="https://bar.com/.well-known/host-meta"
stub_request(:get, url).
to_return(:status => 200, :body => host_meta_xrd)
expect(finger.get(url)).to eq(host_meta_xrd)
end
it 'follows redirects' do
redirect_url = "http://whereami.whatisthis/host-meta"
stub_request(:get, "https://bar.com/.well-known/host-meta").
to_return(:status => 302, :headers => { 'Location' => redirect_url })
stub_request(:get, redirect_url).
to_return(:status => 200, :body => host_meta_xrd)
finger.host_meta_xrd
expect(a_request(:get, redirect_url)).to have_been_made
end
it 'raises on 404' do
url ="https://bar.com/.well-known/host-meta"
stub_request(:get, url).
to_return(:status => 404, :body => nil)
expect {
expect(finger.get(url)).to eq(false)
}.to raise_error
end
end
describe 'existing_person_with_profile?' do
it 'returns true if cached_person is present and has a profile' do
expect(finger).to receive(:cached_person).twice.and_return(FactoryGirl.create(:person))
expect(finger.existing_person_with_profile?).to be true
end
it 'returns false if it has no person' do
allow(finger).to receive(:cached_person).and_return false
expect(finger.existing_person_with_profile?).to be false
end
it 'returns false if the person has no profile' do
p = FactoryGirl.create(:person)
p.profile = nil
allow(finger).to receive(:cached_person).and_return(p)
expect(finger.existing_person_with_profile?).to be false
end
end
describe 'cached_person' do
it 'sets the person by looking up the account from Person.by_account_identifier' do
person = double
expect(Person).to receive(:by_account_identifier).with(account).and_return(person)
expect(finger.cached_person).to eq(person)
expect(finger.person).to eq(person)
end
end
describe 'create_or_update_person_from_webfinger_profile!' do
context 'with a cached_person' do
it 'calls Person#assign_new_profile_from_hcard with the fetched hcard' do
finger.hcard_xrd = hcard_xml
allow(finger).to receive(:person).and_return(bob.person)
expect(bob.person).to receive(:assign_new_profile_from_hcard).with(finger.hcard)
finger.create_or_update_person_from_webfinger_profile!
end
end
context 'with no cached person' do
it 'sets person based on make_person_from_webfinger' do
allow(finger).to receive(:person).and_return(nil)
expect(finger).to receive(:make_person_from_webfinger)
finger.create_or_update_person_from_webfinger_profile!
end
end
end
describe '#host_meta_xrd' do
it 'calls #get with host_meta_url' do
allow(finger).to receive(:host_meta_url).and_return('meta')
expect(finger).to receive(:get).with('meta')
finger.host_meta_xrd
end
it 'should retry with ssl off a second time' do
expect(finger).to receive(:get).and_raise(StandardError)
expect(finger).to receive(:get)
finger.host_meta_xrd
expect(finger.ssl).to be false
end
end
describe '#hcard' do
it 'calls HCard.build' do
allow(finger).to receive(:hcard_xrd).and_return(hcard_xml)
expect(HCard).to receive(:build).with(hcard_xml).and_return true
expect(finger.hcard).not_to be_nil
end
end
describe '#webfinger_profile' do
it 'constructs a new WebfingerProfile object' do
allow(finger).to receive(:webfinger_profile_xrd).and_return(webfinger_xrd)
expect(WebfingerProfile).to receive(:new).with(account, webfinger_xrd)
finger.webfinger_profile
end
end
describe '#webfinger_profile_url' do
it 'returns the llrd link for a valid host meta' do
allow(finger).to receive(:host_meta_xrd).and_return(host_meta_xrd)
expect(finger.webfinger_profile_url).not_to be_nil
end
it 'returns nil if no link is found' do
allow(finger).to receive(:host_meta_xrd).and_return(nil)
expect(finger.webfinger_profile_url).to be_nil
end
end
describe '#webfinger_profile_xrd' do
it 'calls #get with the hcard_url' do
allow(finger).to receive(:hcard_url).and_return("url")
expect(finger).to receive(:get).with("url")
finger.hcard_xrd
end
end
describe '#make_person_from_webfinger' do
it 'with an hcard and a webfinger_profile, it calls Person.create_from_webfinger' do
allow(finger).to receive(:hcard).and_return("hcard")
allow(finger).to receive(:webfinger_profile_xrd).and_return("webfinger_profile_xrd")
allow(finger).to receive(:webfinger_profile).and_return("webfinger_profile")
expect(Person).to receive(:create_from_webfinger).with("webfinger_profile", "hcard")
finger.make_person_from_webfinger
end
it 'with an false xrd it does not call Person.create_from_webfinger' do
allow(finger).to receive(:webfinger_profile_xrd).and_return(false)
expect(Person).not_to receive(:create_from_webfinger)
finger.make_person_from_webfinger
end
end
describe '#host_meta_url' do
it 'should return canonical host-meta url for http' do
finger.ssl = false
expect(finger.host_meta_url).to eq("http://bar.com/.well-known/host-meta")
end
it 'can return the https version' do
expect(finger.host_meta_url).to eq("https://bar.com/.well-known/host-meta")
end
end
describe 'swizzle' do
it 'gsubs out {uri} for the account' do
string = "{uri} is the coolest"
expect(finger.swizzle(string)).to eq("#{finger.account} is the coolest")
end
end
end

View file

@ -212,9 +212,7 @@ describe Reshare, :type => :model do
@original_author.profile = @original_profile @original_author.profile = @original_profile
wf_prof_double = double expect(Person).to receive(:find_or_fetch_by_identifier).and_return(@original_author)
expect(wf_prof_double).to receive(:fetch).and_return(@original_author)
expect(Webfinger).to receive(:new).and_return(wf_prof_double)
allow(@response).to receive(:body).and_return(@root_object.to_diaspora_xml) allow(@response).to receive(:body).and_return(@root_object.to_diaspora_xml)
@ -287,10 +285,7 @@ describe Reshare, :type => :model do
@xml = @reshare.to_xml.to_s @xml = @reshare.to_xml.to_s
different_person = FactoryGirl.build(:person) different_person = FactoryGirl.build(:person)
expect(Person).to receive(:find_or_fetch_by_identifier).and_return(different_person)
wf_prof_double = double
expect(wf_prof_double).to receive(:fetch).and_return(different_person)
expect(Webfinger).to receive(:new).and_return(wf_prof_double)
allow(different_person).to receive(:url).and_return(@original_author.url) allow(different_person).to receive(:url).and_return(@original_author.url)

View file

@ -912,11 +912,9 @@ describe User, :type => :model do
context "with autofollow sharing enabled" do context "with autofollow sharing enabled" do
it "should start sharing with autofollow account" do it "should start sharing with autofollow account" do
AppConfig.settings.autofollow_on_join = true AppConfig.settings.autofollow_on_join = true
AppConfig.settings.autofollow_on_join_user = 'one' AppConfig.settings.autofollow_on_join_user = "one"
wf_double = double expect(Person).to receive(:find_or_fetch_by_identifier).with("one")
expect(wf_double).to receive(:fetch)
expect(Webfinger).to receive(:new).with('one').and_return(wf_double)
user.seed_aspects user.seed_aspects
end end
@ -926,7 +924,7 @@ describe User, :type => :model do
it "should not start sharing with the diasporahq account" do it "should not start sharing with the diasporahq account" do
AppConfig.settings.autofollow_on_join = false AppConfig.settings.autofollow_on_join = false
expect(Webfinger).not_to receive(:new) expect(Person).not_to receive(:find_or_fetch_by_identifier)
user.seed_aspects user.seed_aspects
end end

View file

@ -3,7 +3,7 @@ require "spec_helper"
describe Workers::FetchWebfinger do describe Workers::FetchWebfinger do
it "should webfinger and queue a job to fetch public posts" do it "should webfinger and queue a job to fetch public posts" do
@person = FactoryGirl.create(:person) @person = FactoryGirl.create(:person)
allow(Webfinger).to receive(:new).and_return(double(fetch: @person)) allow(Person).to receive(:find_or_fetch_by_identifier).and_return(@person)
expect(Diaspora::Fetcher::Public).to receive(:queue_for).exactly(1).times expect(Diaspora::Fetcher::Public).to receive(:queue_for).exactly(1).times
@ -11,7 +11,7 @@ describe Workers::FetchWebfinger do
end end
it "should webfinger and queue no job to fetch public posts if the person is not found" do it "should webfinger and queue no job to fetch public posts if the person is not found" do
allow(Webfinger).to receive(:new).and_return(double(fetch: nil)) allow(Person).to receive(:find_or_fetch_by_identifier).and_return(nil)
expect(Diaspora::Fetcher::Public).not_to receive(:queue_for) expect(Diaspora::Fetcher::Public).not_to receive(:queue_for)