diff --git a/Gemfile b/Gemfile index 0964f1f2f86c6442e9b75f8914d9269ddaa350a9..eace32a37898634d5ccd5038638d20d77a1d98ae 100644 --- a/Gemfile +++ b/Gemfile @@ -3,11 +3,6 @@ source "https://rubygems.org" gem "rails", "4.2.3" # Legacy Rails features, remove me! - -# caches_page -gem "actionpack-action_caching" -gem "actionpack-page_caching" - # responders (class level) gem "responders", "2.1.0" @@ -15,6 +10,10 @@ gem "responders", "2.1.0" gem "unicorn", "4.9.0", require: false +# Federation + +gem "diaspora_federation-rails", "0.0.2" + # API and JSON gem "acts_as_api", "0.4.2" diff --git a/Gemfile.lock b/Gemfile.lock index 141d14d61c171094b21c9a08af0e72e04e27eecf..87e856e95deb722c228018001d1d16ec78d9d506 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -16,10 +16,6 @@ GEM rack-test (~> 0.6.2) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionpack-action_caching (1.1.1) - actionpack (>= 4.0.0, < 5.0) - actionpack-page_caching (1.0.2) - actionpack (>= 4.0.0, < 5) actionview (4.2.3) activesupport (= 4.2.3) builder (~> 3.1) @@ -157,6 +153,11 @@ GEM eventmachine (>= 1.0.5, < 1.1) http_parser.rb (~> 0.6) nokogiri (~> 1.6) + diaspora_federation (0.0.2) + nokogiri (~> 1.6, >= 1.6.6) + diaspora_federation-rails (0.0.2) + diaspora_federation (= 0.0.2) + rails (~> 4.2) diff-lcs (1.2.5) docile (1.1.5) domain_name (0.5.24) @@ -743,8 +744,6 @@ PLATFORMS ruby DEPENDENCIES - actionpack-action_caching - actionpack-page_caching active_model_serializers (= 0.9.3) activerecord-import (= 0.8.0) acts-as-taggable-on (= 3.5.0) @@ -765,6 +764,7 @@ DEPENDENCIES devise_lastseenable (= 0.0.4) diaspora-vines (~> 0.1.27) entypo-rails (= 2.2.3) + diaspora_federation-rails (= 0.0.2) eye (= 0.7.pre) facebox-rails (= 0.2.0) factory_girl_rails (= 4.5.0) diff --git a/app/controllers/publics_controller.rb b/app/controllers/publics_controller.rb index af9d57f9c7d623862a3c44219a40c4de97651c80..cca482bbd2e537c5e90c71b9a8fe9d29c7f605c2 100644 --- a/app/controllers/publics_controller.rb +++ b/app/controllers/publics_controller.rb @@ -13,36 +13,8 @@ class PublicsController < ApplicationController respond_to :html respond_to :xml, :only => :post - caches_page :host_meta, :if => Proc.new{ Rails.env == 'production'} - layout false - def hcard - @person = Person.find_by_guid_and_closed_account(params[:guid], false) - - if @person.present? && @person.local? - render 'publics/hcard' - else - render :nothing => true, :status => 404 - end - end - - def host_meta - render 'host_meta', :content_type => 'application/xrd+xml' - end - - def webfinger - @person = Person.local_by_account_identifier(params[:q]) if params[:q] - - if @person.nil? || @person.closed_account? - render :nothing => true, :status => 404 - return - end - - logger.info "webfinger profile request for: #{@person.id}" - render 'webfinger', :content_type => 'application/xrd+xml' - end - def hub render :text => params['hub.challenge'], :status => 202, :layout => false end diff --git a/app/helpers/people_helper.rb b/app/helpers/people_helper.rb index 63d39af2116e832da60ddfd77fdbc20cf9ff3304..e52612bf9d185961de3b22c04765af491e65283e 100644 --- a/app/helpers/people_helper.rb +++ b/app/helpers/people_helper.rb @@ -50,10 +50,6 @@ module PeopleHelper end end - def person_href(person, opts={}) - "href=\"#{local_or_remote_person_path(person, opts)}\"".html_safe - end - # Rails.application.routes.url_helpers is needed since this is indirectly called from a model def local_or_remote_person_path(person, opts={}) opts.merge!(:protocol => AppConfig.pod_uri.scheme, :host => AppConfig.pod_uri.authority) diff --git a/app/models/person.rb b/app/models/person.rb index 814dfe1e0a270b16eadd335071c1a82345b16e56..e419cce30f0f1ef901a043273777ab87f1408767 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -28,7 +28,7 @@ class Person < ActiveRecord::Base xml_attr :profile, :as => Profile xml_attr :exported_key - has_one :profile, :dependent => :destroy + has_one :profile, dependent: :destroy delegate :last_name, :image_url, :tag_string, :bio, :location, :gender, :birthday, :formatted_birthday, :tags, :searchable, to: :profile @@ -222,7 +222,7 @@ class Person < ActiveRecord::Base end def public_key_hash - Base64.encode64(OpenSSL::Digest::SHA256.new(self.exported_key).to_s) + Base64.encode64(OpenSSL::Digest::SHA256.new(serialized_public_key).to_s) end def public_key @@ -238,15 +238,18 @@ class Person < ActiveRecord::Base serialized_public_key = new_key end - #database calls + # database calls def self.by_account_identifier(identifier) - identifier = identifier.strip.downcase.gsub('acct:', '') - self.where(:diaspora_handle => identifier).first + identifier = identifier.strip.downcase.sub("acct:", "") + find_by(diaspora_handle: identifier) end - def self.local_by_account_identifier(identifier) - person = self.by_account_identifier(identifier) - (person.nil? || person.remote?) ? nil : person + def self.find_local_by_diaspora_handle(handle) + where(diaspora_handle: handle, closed_account: false).where.not(owner: nil).take + end + + def self.find_local_by_guid(guid) + where(guid: guid, closed_account: false).where.not(owner: nil).take end def self.create_from_webfinger(profile, hcard) diff --git a/app/views/publics/hcard.haml b/app/views/publics/hcard.haml deleted file mode 100644 index f19bffb35d5c271ebfeda8f6346861e89a8dd048..0000000000000000000000000000000000000000 --- a/app/views/publics/hcard.haml +++ /dev/null @@ -1,50 +0,0 @@ -#content - %h1= @person.name - #content_inner - #i.entity_profile.vcard.author - %h2 User profile - - %dl.entity_nickname - %dt Nickname - %dd - %a.nickname.url.uid{:href=>@person.url, :rel=>'me'}= @person.name - - %dl.entity_given_name - %dt First name - %dd - %span.given_name= @person.profile.first_name - - %dl.entity_family_name - %dt Family name - %dd - %span.family_name= @person.last_name - - %dl.entity_fn - %dt Full name - %dd - %span.fn= @person.name - - %dl.entity_url - %dt URL - %dd - %a#pod_location.url{:href=>@person.url, :rel=>'me'}= @person.url - - %dl.entity_photo - %dt Photo - %dd - %img.photo.avatar{:src=>@person.image_url, :width=>'300px', :height=>'300px'} - - %dl.entity_photo_medium - %dt Photo - %dd - %img.photo.avatar{:src=>@person.image_url(:thumb_medium), :width=>'100px', :height=>'100px'} - - %dl.entity_photo_small - %dt Photo - %dd - %img.photo.avatar{:src=>@person.image_url(:thumb_small), :width=>'50px', :height=>'50px'} - - %dl.entity_searchable - %dt Searchable - %dd - %span.searchable= @person.searchable diff --git a/app/views/publics/host_meta.erb b/app/views/publics/host_meta.erb deleted file mode 100644 index f5efcab11a9f4efb49f2abef7a0675618db77918..0000000000000000000000000000000000000000 --- a/app/views/publics/host_meta.erb +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'> - - <!-- Resource-specific Information --> - - <Link rel='lrdd' - type='application/xrd+xml' - template='<%= AppConfig.pod_uri.to_s %>webfinger?q={uri}' /> - -</XRD> diff --git a/app/views/publics/webfinger.erb b/app/views/publics/webfinger.erb deleted file mode 100644 index 3b8099441690cc2ed9e6649f739b5fbebad3dd82..0000000000000000000000000000000000000000 --- a/app/views/publics/webfinger.erb +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"> - <Subject>acct:<%=@person.diaspora_handle%></Subject> - <Alias>"<%= @person.url %>"</Alias> - <Link rel="http://microformats.org/profile/hcard" type="text/html" href="<%=@person.url%>hcard/users/<%=@person.guid%>"/> - <Link rel="http://joindiaspora.com/seed_location" type = 'text/html' href="<%=@person.url%>"/> - <Link rel="http://joindiaspora.com/guid" type = 'text/html' href="<%=@person.guid%>"/> - - <Link rel='http://webfinger.net/rel/profile-page' type='text/html' <%=person_href(@person, :absolute => true)%>/> - <Link rel="http://schemas.google.com/g/2010#updates-from" type="application/atom+xml" href="<%=@person.atom_url%>"/> - <Link rel="salmon" href="<%= @person.receive_url %>"/> - - <Link rel="diaspora-public-key" type = 'RSA' href="<%=Base64.strict_encode64(@person.exported_key)%>"/> -</XRD> diff --git a/config/initializers/diaspora_federation.rb b/config/initializers/diaspora_federation.rb new file mode 100644 index 0000000000000000000000000000000000000000..e0d16ee44de705942b21f5954434dc3def85b085 --- /dev/null +++ b/config/initializers/diaspora_federation.rb @@ -0,0 +1,47 @@ +# configure the federation engine +DiasporaFederation.configure do |config| + # the pod url + config.server_uri = AppConfig.pod_uri + + config.define_callbacks do + on :person_webfinger_fetch do |handle| + person = Person.find_local_by_diaspora_handle(handle) + if person + DiasporaFederation::WebFinger::WebFinger.new( + acct_uri: "acct:#{person.diaspora_handle}", + alias_url: url_to("/people/#{person.guid}"), + hcard_url: url_to(DiasporaFederation::Engine.routes.url_helpers.hcard_path(person.guid)), + seed_url: AppConfig.pod_uri, + profile_url: person.profile_url, + atom_url: person.atom_url, + salmon_url: person.receive_url, + guid: person.guid, + public_key: person.serialized_public_key + ) + end + end + + on :person_hcard_fetch do |guid| + person = Person.find_local_by_guid(guid) + if person + DiasporaFederation::WebFinger::HCard.new( + guid: person.guid, + nickname: person.username, + full_name: "#{person.profile.first_name} #{person.profile.last_name}".strip, + url: AppConfig.pod_uri, + photo_large_url: person.image_url, + photo_medium_url: person.image_url(:thumb_medium), + photo_small_url: person.image_url(:thumb_small), + public_key: person.serialized_public_key, + searchable: person.searchable, + first_name: person.profile.first_name, + last_name: person.profile.last_name + ) + end + end + end + + def url_to(path) + AppConfig.pod_uri.tap {|uri| uri.path = path }.to_s + end +end diff --git a/config/routes.rb b/config/routes.rb index 2d88dc78abb3d0017db0c9b58a537de304f0863a..c0fd79d2b489852efd75bada72f4e2b26f568464 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -18,6 +18,8 @@ Diaspora::Application.routes.draw do mount Sidekiq::Web => '/sidekiq', :as => 'sidekiq' end + mount DiasporaFederation::Engine => "/" + get "/atom.xml" => redirect('http://blog.diasporafoundation.org/feed/atom') #too many stupid redirects :() get 'oembed' => 'posts#oembed', :as => 'oembed' @@ -191,9 +193,6 @@ Diaspora::Application.routes.draw do # Federation controller :publics do - get 'webfinger' => :webfinger - get 'hcard/users/:guid' => :hcard - get '.well-known/host-meta' => :host_meta post 'receive/users/:guid' => :receive post 'receive/public' => :receive_public get 'hub' => :hub diff --git a/spec/helpers/people_helper_spec.rb b/spec/helpers/people_helper_spec.rb index 6d633097df405c040568a1d8933499d994bad0bb..d127ff244d273732061b58d2bafccd1662150d66 100644 --- a/spec/helpers/people_helper_spec.rb +++ b/spec/helpers/people_helper_spec.rb @@ -5,12 +5,12 @@ require 'spec_helper' describe PeopleHelper, :type => :helper do - before do + before do @user = alice @person = FactoryGirl.create(:person) end - describe "#person_image_link" do + describe "#person_image_link" do it "returns an empty string if person is nil" do expect(person_image_link(nil)).to eq("") end @@ -58,26 +58,12 @@ describe PeopleHelper, :type => :helper do @person.profile.last_name = "I'm <h1>Evil" expect(person_link(@person)).not_to include("<h1>") end - + it 'links by id for a local user' do expect(person_link(@user.person)).to include "href='#{person_path(@user.person)}'" end end - describe "#person_href" do - it "calls local_or_remote_person_path and passes through the options" do - opts = {:absolute => true} - - expect(self).to receive(:local_or_remote_person_path).with(@person, opts).exactly(1).times - - person_href(@person, opts) - end - - it "returns a href attribute" do - expect(person_href(@person)).to include "href=" - end - end - describe '#local_or_remote_person_path' do before do @user = FactoryGirl.create(:user) diff --git a/spec/models/person_spec.rb b/spec/models/person_spec.rb index 6433fafb37ff104c9826bb447655f3985a4d2919..b060569035eae14e515d598523a4aaaad7b1dc4a 100644 --- a/spec/models/person_spec.rb +++ b/spec/models/person_spec.rb @@ -457,27 +457,45 @@ describe Person, :type => :model do f = Person.by_account_identifier("tom@tom.joindiaspora.com") expect(f).to be nil end + end + describe ".find_local_by_diaspora_handle" do + it "should find local users person" do + person = Person.find_local_by_diaspora_handle(user.diaspora_handle) + expect(person).to eq(user.person) + end + + it "should not find a remote person" do + person = Person.find_local_by_diaspora_handle(@person.diaspora_handle) + expect(person).to be nil + end + it "should not find a person with closed account" do + user.person.lock_access! + person = Person.find_local_by_diaspora_handle(user.diaspora_handle) + expect(person).to be nil + end end - describe '.local_by_account_identifier' do - it 'should find local users people' do - p = Person.local_by_account_identifier(user.diaspora_handle) - expect(p).to eq(user.person) + describe ".find_local_by_guid" do + it "should find local users person" do + person = Person.find_local_by_guid(user.guid) + expect(person).to eq(user.person) end - it 'should not find a remote person' do - p = Person.local_by_account_identifier(@person.diaspora_handle) - expect(p).to be nil + it "should not find a remote person" do + person = Person.find_local_by_guid(@person.guid) + expect(person).to be nil end - it 'should call .by_account_identifier' do - expect(Person).to receive(:by_account_identifier) - Person.local_by_account_identifier(@person.diaspora_handle) + it "should not find a person with closed account" do + user.person.lock_access! + person = Person.find_local_by_guid(user.guid) + expect(person).to be nil end end end + describe '#has_photos?' do it 'returns false if the user has no photos' do expect(alice.person.has_photos?).to be false