]> cat aescling's git repositories - mastodon.git/commitdiff
Support link verification with redirects (#8735)
authorEugen Rochko <eugen@zeonfederated.com>
Wed, 19 Sep 2018 22:10:35 +0000 (00:10 +0200)
committerGitHub <noreply@github.com>
Wed, 19 Sep 2018 22:10:35 +0000 (00:10 +0200)
(e.g. URL shortener)

app/services/verify_link_service.rb
spec/services/verify_link_service_spec.rb

index 846751cd59cf9589862916aad3806590314c9ac6..7d53bc255a666d6de0a7f52b1f931b92027aee2d 100644 (file)
@@ -27,6 +27,22 @@ class VerifyLinkService < BaseService
   def link_back_present?
     return false if @body.empty?
 
-    Nokogiri::HTML(@body).xpath('//a[contains(concat(" ", normalize-space(@rel), " "), " me ")]|//link[contains(concat(" ", normalize-space(@rel), " "), " me ")]').any? { |link| link['href'] == @link_back }
+    links = Nokogiri::HTML(@body).xpath('//a[contains(concat(" ", normalize-space(@rel), " "), " me ")]|//link[contains(concat(" ", normalize-space(@rel), " "), " me ")]')
+
+    if links.any? { |link| link['href'] == @link_back }
+      true
+    elsif links.empty?
+      false
+    else
+      link_redirects_back?(links.first['href'])
+    end
+  end
+
+  def link_redirects_back?(test_url)
+    redirect_to_url = Request.new(:head, test_url, follow: false).perform do |res|
+      res.headers['Location']
+    end
+
+    redirect_to_url == @link_back
   end
 end
index acd4e851e5f4ca4ded8a2338c8e06d26d8e2685c..9b04d613642e30be92201c76375a12dacbd9649a 100644 (file)
@@ -7,6 +7,7 @@ RSpec.describe VerifyLinkService, type: :service do
   let(:field)   { Account::Field.new(account, 'name' => 'Website', 'value' => 'http://example.com') }
 
   before do
+    stub_request(:head, 'https://redirect.me/abc').to_return(status: 301, headers: { 'Location' => ActivityPub::TagManager.instance.url_for(account) })
     stub_request(:get, 'http://example.com').to_return(status: 200, body: html)
     subject.call(field)
   end
@@ -56,6 +57,21 @@ RSpec.describe VerifyLinkService, type: :service do
     end
   end
 
+  context 'when a link goes through a redirect back' do
+    let(:html) do
+      <<-HTML
+        <!doctype html>
+        <head>
+          <link type="text/html" href="https://redirect.me/abc" rel="me" />
+        </head>
+      HTML
+    end
+
+    it 'marks the field as verified' do
+      expect(field.verified?).to be true
+    end
+  end
+
   context 'when a link does not contain a link back' do
     let(:html) { '' }