diff --git a/Changelog.md b/Changelog.md index 64e6494cda42f6524343777bb91facd4528f543c..be126faecce6d4c873e3aab661786c0ceae766e8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -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) * 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 user/profile discovery into the diaspora\_federation-rails gem [#6310](https://github.com/diaspora/diaspora/pull/6310) ## Bug fixes * Fix indentation and a link title on the default home page [#6212](https://github.com/diaspora/diaspora/pull/6212) diff --git a/Gemfile b/Gemfile index 4b4bb3b016b0317cae94ba8abf34475810f028ad..ee5e9bf203a584bd55fa23ef9e4453fc5f068da1 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,7 @@ gem "unicorn", "4.9.0", require: false # Federation -gem "diaspora_federation-rails", "0.0.3" +gem "diaspora_federation-rails", "0.0.6" # API and JSON diff --git a/Gemfile.lock b/Gemfile.lock index f7e89f649d49f83a58e02e1d5468ad6e08cede7d..e1c51db28113a16bfbac15b3659f4cb4b1f4ad8a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -154,10 +154,14 @@ GEM eventmachine (>= 1.0.5, < 1.1) http_parser.rb (~> 0.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) - diaspora_federation-rails (0.0.3) - diaspora_federation (= 0.0.3) + typhoeus (~> 0.7.0) + valid (~> 1.0.0) + diaspora_federation-rails (0.0.6) + diaspora_federation (= 0.0.6) rails (~> 4.2) diff-lcs (1.2.5) docile (1.1.5) @@ -755,6 +759,7 @@ GEM raindrops (~> 0.7) uuid (2.3.8) macaddr (~> 1.0) + valid (1.0.0) warden (1.2.3) rack (>= 1.0) webmock (1.21.0) @@ -789,7 +794,7 @@ DEPENDENCIES devise-token_authenticatable (~> 0.4.0) devise_lastseenable (= 0.0.6) diaspora-vines (~> 0.1.28) - diaspora_federation-rails (= 0.0.3) + diaspora_federation-rails (= 0.0.6) entypo-rails (= 3.0.0.pre.rc2) eye (= 0.7.pre) factory_girl_rails (= 4.5.0) diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index a79a1df1edb517b0b57b39f76d37809c624484fa..d8cfbcde91d706ad72d86d113cfea795a9979236 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -41,7 +41,7 @@ class PeopleController < ApplicationController if diaspora_id?(search_query) @people = Person.where(:diaspora_handle => search_query.downcase) if @people.empty? - Webfinger.in_background(search_query) + Workers::FetchWebfinger.perform_async(search_query) @background_query = search_query.downcase end end @@ -127,7 +127,7 @@ class PeopleController < ApplicationController def retrieve_remote if params[:diaspora_handle] - Webfinger.in_background(params[:diaspora_handle], :single_aspect_form => true) + Workers::FetchWebfinger.perform_async(params[:diaspora_handle]) render :nothing => true else render :nothing => true, :status => 422 diff --git a/app/models/comment.rb b/app/models/comment.rb index f6cd6f3532d5c77d5cb3387305596b4c83bf2843..9e0eca2c74804fbd65b9fcea46e21fe90fce19bc 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -56,7 +56,7 @@ class Comment < ActiveRecord::Base end def diaspora_handle= nh - self.author = Webfinger.new(nh).fetch + self.author = Person.find_or_fetch_by_identifier(nh) end def notification_type(user, person) diff --git a/app/models/conversation.rb b/app/models/conversation.rb index 45777b82a163d8eb20551e10eab9843bd32db284..afd4d798c0283467e1d7cc2e7c016ef8d610f381 100644 --- a/app/models/conversation.rb +++ b/app/models/conversation.rb @@ -43,7 +43,7 @@ class Conversation < ActiveRecord::Base end def diaspora_handle= nh - self.author = Webfinger.new(nh).fetch + self.author = Person.find_or_fetch_by_identifier(nh) end def first_unread_message(user) @@ -68,7 +68,7 @@ class Conversation < ActiveRecord::Base end def participant_handles= handles handles.split(';').each do |handle| - self.participants << Webfinger.new(handle).fetch + participants << Person.find_or_fetch_by_identifier(handle) end end diff --git a/app/models/message.rb b/app/models/message.rb index f73fc87b9fde24a223f8968c3d88d7801c7339df..91ef0405792c08cdba60a3410d5996cf696d1308 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -35,7 +35,7 @@ class Message < ActiveRecord::Base end def diaspora_handle= nh - self.author = Webfinger.new(nh).fetch + self.author = Person.find_or_fetch_by_identifier(nh) end def conversation_guid diff --git a/app/models/person.rb b/app/models/person.rb index 511bc47285eb7e9c4d854d03de11c3a5f322a01e..052ee76d3363f9fa342f2434784b7a08c4ffedd3 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -238,6 +238,19 @@ class Person < ActiveRecord::Base serialized_public_key = new_key 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 def self.by_account_identifier(identifier) 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 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? owner_id.nil? end @@ -359,7 +346,8 @@ class Person < ActiveRecord::Base end def fix_profile - Webfinger.new(self.diaspora_handle).fetch - self.reload + logger.info "fix profile for account: #{diaspora_handle}" + DiasporaFederation::Discovery::Discovery.new(diaspora_handle).fetch_and_save + reload end end diff --git a/app/models/poll_participation.rb b/app/models/poll_participation.rb index 23bd6dd7806313e354713ab9cc2affee94bd3353..64dd32ac519a3b563985c882d576887cf2198c1f 100644 --- a/app/models/poll_participation.rb +++ b/app/models/poll_participation.rb @@ -1,7 +1,7 @@ class PollParticipation < ActiveRecord::Base include Diaspora::Federated::Base - + include Diaspora::Guid include Diaspora::Relayable belongs_to :poll @@ -37,7 +37,7 @@ class PollParticipation < ActiveRecord::Base end def diaspora_handle= nh - self.author = Webfinger.new(nh).fetch + self.author = Person.find_or_fetch_by_identifier(nh) end def not_already_participated diff --git a/app/models/user.rb b/app/models/user.rb index dbc587f911edd72127d07b40cd31305eae2ee5b9..2e39dec9dafefda508ae18a6bb64a33bbe323659 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -462,7 +462,7 @@ class User < ActiveRecord::Base aq = self.aspects.create(:name => I18n.t('aspects.seed.acquaintances')) 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 end aq diff --git a/app/workers/fetch_webfinger.rb b/app/workers/fetch_webfinger.rb index 5dda819efbb2f9554e25fb4a2771183ab6e3993a..3b277824de14ce66f4d3692828413cb76e15da55 100644 --- a/app/workers/fetch_webfinger.rb +++ b/app/workers/fetch_webfinger.rb @@ -7,7 +7,7 @@ module Workers sidekiq_options queue: :socket_webfinger 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 Diaspora::Fetcher::Public.queue_for(person) unless person.nil? diff --git a/config/initializers/diaspora_federation.rb b/config/initializers/diaspora_federation.rb index cedbf2e000c86477788bd212a181006180b0fbbd..f15dcf5cf74c96407b8c84ff6558486c0479a2b9 100644 --- a/config/initializers/diaspora_federation.rb +++ b/config/initializers/diaspora_federation.rb @@ -3,11 +3,13 @@ DiasporaFederation.configure do |config| # the pod url config.server_uri = AppConfig.pod_uri + config.certificate_authorities = AppConfig.environment.certificate_authorities.get + 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) if person - DiasporaFederation::WebFinger::WebFinger.new( + DiasporaFederation::Discovery::WebFinger.new( acct_uri: "acct:#{person.diaspora_handle}", alias_url: AppConfig.url_to("/people/#{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 - on :person_hcard_fetch do |guid| + on :fetch_person_for_hcard do |guid| person = Person.find_local_by_guid(guid) if person - DiasporaFederation::WebFinger::HCard.new( + DiasporaFederation::Discovery::HCard.new( guid: person.guid, nickname: person.username, full_name: "#{person.profile.first_name} #{person.profile.last_name}".strip, @@ -39,5 +41,25 @@ DiasporaFederation.configure do |config| ) 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 diff --git a/config/initializers/load_libraries.rb b/config/initializers/load_libraries.rb index f0dfd8c0c8b54cf0c5d65cf996f1e7898cd3c8cd..86d701d33d8827b6be113648b6469a92548e0113 100644 --- a/config/initializers/load_libraries.rb +++ b/config/initializers/load_libraries.rb @@ -14,13 +14,10 @@ require 'diaspora' require 'direction_detector' require 'email_inviter' require 'evil_query' -require 'h_card' require 'hydra_wrapper' require 'postzord' require 'publisher' require 'pubsubhubbub' require 'salmon' require 'stream' -require 'webfinger' -require 'webfinger_profile' require 'account_deleter' diff --git a/lib/diaspora/fetcher/single.rb b/lib/diaspora/fetcher/single.rb index 4e8340132c45c14c323f712e3afa32780929fdd6..797fc3cccafd32549be8d8baa0e282d174fa7de5 100644 --- a/lib/diaspora/fetcher/single.rb +++ b/lib/diaspora/fetcher/single.rb @@ -14,7 +14,7 @@ module Diaspora post = Post.where(guid: guid).first 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? if fetched_post = fetch_post(post_author, guid) diff --git a/lib/federated/relayable.rb b/lib/federated/relayable.rb index a6cf6bf83cbd17c65e4826f4d94f08063ca1d4aa..7a1b13d6ccbd023f2fdd492f72ee9a308117dab0 100644 --- a/lib/federated/relayable.rb +++ b/lib/federated/relayable.rb @@ -24,7 +24,7 @@ module Federated end def diaspora_handle=(nh) - self.author = Webfinger.new(nh).fetch + self.author = Person.find_or_fetch_by_identifier(nh) end def parent_class diff --git a/lib/h_card.rb b/lib/h_card.rb deleted file mode 100644 index 2fda6aa2ed60da8ca4408dee0896abb1809bf0e6..0000000000000000000000000000000000000000 --- a/lib/h_card.rb +++ /dev/null @@ -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 diff --git a/lib/postzord/receiver/private.rb b/lib/postzord/receiver/private.rb index b29898df51ae024fdfbf60af16789e8ed2491549..5e545b9955a5475308eb665426cbee8ca401867a 100644 --- a/lib/postzord/receiver/private.rb +++ b/lib/postzord/receiver/private.rb @@ -9,7 +9,7 @@ class Postzord::Receiver::Private < Postzord::Receiver @user_person = @user.person @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] end @@ -56,7 +56,7 @@ class Postzord::Receiver::Private < Postzord::Receiver 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 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 xml_author = @object.diaspora_handle end diff --git a/lib/postzord/receiver/public.rb b/lib/postzord/receiver/public.rb index c96f0d340685d3aa69a5a4d1705f7ddc392f714b..fc870ba42325364e9005ad37a6173ecd5b2259fd 100644 --- a/lib/postzord/receiver/public.rb +++ b/lib/postzord/receiver/public.rb @@ -8,7 +8,7 @@ class Postzord::Receiver::Public < Postzord::Receiver def initialize(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 # @return [Boolean] diff --git a/lib/webfinger.rb b/lib/webfinger.rb deleted file mode 100644 index 5c28a4e90d19ab0f248d094bfdd2426e6ae6d360..0000000000000000000000000000000000000000 --- a/lib/webfinger.rb +++ /dev/null @@ -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 diff --git a/lib/webfinger_profile.rb b/lib/webfinger_profile.rb deleted file mode 100644 index 44259e200196c3b3a72f24aac8817ecc2d4ceb97..0000000000000000000000000000000000000000 --- a/lib/webfinger_profile.rb +++ /dev/null @@ -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 diff --git a/spec/controllers/diaspora_federation_controller_spec.rb b/spec/controllers/diaspora_federation_controller_spec.rb deleted file mode 100644 index 8799220ee88660fe188f0c03bbe956382d3ea815..0000000000000000000000000000000000000000 --- a/spec/controllers/diaspora_federation_controller_spec.rb +++ /dev/null @@ -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 diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index 32ee54b4f612ddaf44a88914a12f8f3f7229afaf..6866b712e5d88189d55f1fed6dc452181a42e35f 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -16,7 +16,7 @@ describe RegistrationsController, :type => :controller do :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 describe '#check_registrations_open!' do diff --git a/spec/factories.rb b/spec/factories.rb index a9989e077cfbde23e43c165b044d0d3ea1127147..02bfa2fc091ff09333f812a9389895a50553842d 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -301,4 +301,33 @@ FactoryGirl.define do end 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 diff --git a/spec/federation_callbacks_spec.rb b/spec/federation_callbacks_spec.rb index b0502198fb79eda84dbed5c5a7e01a74350b5f72..a2f3432b582cc50689d31d8bf6fe06bd8dcf3fec 100644 --- a/spec/federation_callbacks_spec.rb +++ b/spec/federation_callbacks_spec.rb @@ -1,10 +1,10 @@ require "spec_helper" 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 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.alias_url).to eq(AppConfig.url_to("/people/#{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 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 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 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.nickname).to eq(person.username) 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.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) end 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 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 diff --git a/spec/fixtures/evan_hcard b/spec/fixtures/evan_hcard deleted file mode 100644 index 8944ef1e3d114158d2a0bd319a11bda22672837b..0000000000000000000000000000000000000000 --- a/spec/fixtures/evan_hcard +++ /dev/null @@ -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> diff --git a/spec/fixtures/finger_xrd b/spec/fixtures/finger_xrd deleted file mode 100644 index 5ede32d744fdeceaa2e56468534e3c37710547f0..0000000000000000000000000000000000000000 --- a/spec/fixtures/finger_xrd +++ /dev/null @@ -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> diff --git a/spec/fixtures/hcard_response b/spec/fixtures/hcard_response deleted file mode 100644 index 302c02430441d47e07fae1f8e1d373003c98bec2..0000000000000000000000000000000000000000 --- a/spec/fixtures/hcard_response +++ /dev/null @@ -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> - diff --git a/spec/fixtures/host_xrd b/spec/fixtures/host_xrd deleted file mode 100644 index ca2d3b5fcbe9c16a047255138fd7473d5465697e..0000000000000000000000000000000000000000 --- a/spec/fixtures/host_xrd +++ /dev/null @@ -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> diff --git a/spec/fixtures/nonseed_finger_xrd b/spec/fixtures/nonseed_finger_xrd deleted file mode 100644 index b26e7d15d6449c3fa4e123ec82d7eca2921925de..0000000000000000000000000000000000000000 --- a/spec/fixtures/nonseed_finger_xrd +++ /dev/null @@ -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> diff --git a/spec/helper_methods.rb b/spec/helper_methods.rb index e0df90faa383ff051a1e4ce1faa35c3a6ac14c04..ad4371a347a1de12a7211364d0807c8f05a7a30b 100644 --- a/spec/helper_methods.rb +++ b/spec/helper_methods.rb @@ -19,46 +19,6 @@ module HelperMethods :receiving => true) 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 fixture_filename = 'button.png' fixture_name = File.join(File.dirname(__FILE__), 'fixtures', fixture_filename) diff --git a/spec/integration/receiving_spec.rb b/spec/integration/receiving_spec.rb index 1d31116e91cccbb5b204cfc307c79bf7313b4411..c62241cf7a15db4f7e48af69ede4245eee259feb 100644 --- a/spec/integration/receiving_spec.rb +++ b/spec/integration/receiving_spec.rb @@ -225,11 +225,10 @@ describe 'a user receives a post', :type => :request do 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 - m = double() - expect(Webfinger).to receive(:new).twice.with(eve.person.diaspora_handle).and_return(m) remote_person.save(:validate => false) 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) post_in_db = StatusMessage.find(@post.id) diff --git a/spec/lib/h_card_spec.rb b/spec/lib/h_card_spec.rb deleted file mode 100644 index d4197c0b44699a1b81c3b8641a95765d1e3c6814..0000000000000000000000000000000000000000 --- a/spec/lib/h_card_spec.rb +++ /dev/null @@ -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 diff --git a/spec/lib/postzord/receiver/private_spec.rb b/spec/lib/postzord/receiver/private_spec.rb index 717dbe8c13c063bf84fd1b1fbd2a16708531db6d..088df5ecf835fdc255766c6dd4b4fa52a94670dc 100644 --- a/spec/lib/postzord/receiver/private_spec.rb +++ b/spec/lib/postzord/receiver/private_spec.rb @@ -13,7 +13,7 @@ describe Postzord::Receiver::Private do describe '.initialize' 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) 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 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::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) expect(zord.instance_variable_get(:@user)).not_to be_nil diff --git a/spec/lib/webfinger_profile_spec.rb b/spec/lib/webfinger_profile_spec.rb deleted file mode 100644 index 51991f084589802449ab3b17961a67455bba33fb..0000000000000000000000000000000000000000 --- a/spec/lib/webfinger_profile_spec.rb +++ /dev/null @@ -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 diff --git a/spec/lib/webfinger_spec.rb b/spec/lib/webfinger_spec.rb deleted file mode 100644 index c3515bebe26ee3c294f0e8c3ad9cab3e3d8e6b93..0000000000000000000000000000000000000000 --- a/spec/lib/webfinger_spec.rb +++ /dev/null @@ -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 diff --git a/spec/models/reshare_spec.rb b/spec/models/reshare_spec.rb index ff1781b9a330de3f85865f72ff29acc0867af9a9..e235c40666cf3595af469c99728b9487184aabc0 100644 --- a/spec/models/reshare_spec.rb +++ b/spec/models/reshare_spec.rb @@ -212,9 +212,7 @@ describe Reshare, :type => :model do @original_author.profile = @original_profile - wf_prof_double = double - expect(wf_prof_double).to receive(:fetch).and_return(@original_author) - expect(Webfinger).to receive(:new).and_return(wf_prof_double) + expect(Person).to receive(:find_or_fetch_by_identifier).and_return(@original_author) 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 different_person = FactoryGirl.build(: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) + expect(Person).to receive(:find_or_fetch_by_identifier).and_return(different_person) allow(different_person).to receive(:url).and_return(@original_author.url) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 03f50b9c02e41253dbb9f7a10bfe3f2bdeac32d6..c9cede84e6661801608c1e00c7c6a4bedfc26190 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -912,11 +912,9 @@ describe User, :type => :model do context "with autofollow sharing enabled" do it "should start sharing with autofollow account" do AppConfig.settings.autofollow_on_join = true - AppConfig.settings.autofollow_on_join_user = 'one' + AppConfig.settings.autofollow_on_join_user = "one" - wf_double = double - expect(wf_double).to receive(:fetch) - expect(Webfinger).to receive(:new).with('one').and_return(wf_double) + expect(Person).to receive(:find_or_fetch_by_identifier).with("one") user.seed_aspects end @@ -926,7 +924,7 @@ describe User, :type => :model do it "should not start sharing with the diasporahq account" do 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 end diff --git a/spec/workers/fetch_webfinger_spec.rb b/spec/workers/fetch_webfinger_spec.rb index cfa83b24a24b65cddb715eb0842653036443a9eb..0a9469c75d7304d01de45631e8e3da723e540758 100644 --- a/spec/workers/fetch_webfinger_spec.rb +++ b/spec/workers/fetch_webfinger_spec.rb @@ -3,7 +3,7 @@ require "spec_helper" describe Workers::FetchWebfinger do it "should webfinger and queue a job to fetch public posts" do @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 @@ -11,7 +11,7 @@ describe Workers::FetchWebfinger do end 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)