Change verify link service to use CSS selectors instead of a complex XPath query (#31815)

pull/2839/head^2
Mike Dalessio 2024-09-08 14:50:22 -04:00 committed by GitHub
parent 10143d053a
commit afa2e257e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 8 deletions

View File

@ -26,7 +26,7 @@ class VerifyLinkService < BaseService
def link_back_present? def link_back_present?
return false if @body.blank? return false if @body.blank?
links = Nokogiri::HTML5(@body).xpath('//a[contains(concat(" ", normalize-space(@rel), " "), " me ")]|//link[contains(concat(" ", normalize-space(@rel), " "), " me ")]') links = Nokogiri::HTML5(@body).css("a[rel~='me'],link[rel~='me']")
if links.any? { |link| link['href']&.downcase == @link_back.downcase } if links.any? { |link| link['href']&.downcase == @link_back.downcase }
true true

View File

@ -11,13 +11,14 @@ RSpec.describe VerifyLinkService do
before do before do
stub_request(:head, 'https://redirect.me/abc').to_return(status: 301, headers: { 'Location' => ActivityPub::TagManager.instance.url_for(account) }) stub_request(:head, 'https://redirect.me/abc').to_return(status: 301, headers: { 'Location' => ActivityPub::TagManager.instance.url_for(account) })
stub_request(:head, 'http://unrelated-site.com').to_return(status: 301)
stub_request(:get, 'http://example.com').to_return(status: 200, body: html) stub_request(:get, 'http://example.com').to_return(status: 200, body: html)
subject.call(field) subject.call(field)
end end
context 'when a link contains an <a> back' do context 'when a link contains an <a> back' do
let(:html) do let(:html) do
<<-HTML <<~HTML
<!doctype html> <!doctype html>
<body> <body>
<a href="#{ActivityPub::TagManager.instance.url_for(account)}" rel="me">Follow me on Mastodon</a> <a href="#{ActivityPub::TagManager.instance.url_for(account)}" rel="me">Follow me on Mastodon</a>
@ -30,9 +31,9 @@ RSpec.describe VerifyLinkService do
end end
end end
context 'when a link contains an <a rel="noopener noreferrer"> back' do context 'when a link contains an <a rel="me noopener noreferrer"> back' do
let(:html) do let(:html) do
<<-HTML <<~HTML
<!doctype html> <!doctype html>
<body> <body>
<a href="#{ActivityPub::TagManager.instance.url_for(account)}" rel="me noopener noreferrer" target="_blank">Follow me on Mastodon</a> <a href="#{ActivityPub::TagManager.instance.url_for(account)}" rel="me noopener noreferrer" target="_blank">Follow me on Mastodon</a>
@ -47,7 +48,7 @@ RSpec.describe VerifyLinkService do
context 'when a link contains a <link> back' do context 'when a link contains a <link> back' do
let(:html) do let(:html) do
<<-HTML <<~HTML
<!doctype html> <!doctype html>
<head> <head>
<link type="text/html" href="#{ActivityPub::TagManager.instance.url_for(account)}" rel="me" /> <link type="text/html" href="#{ActivityPub::TagManager.instance.url_for(account)}" rel="me" />
@ -62,7 +63,7 @@ RSpec.describe VerifyLinkService do
context 'when a link goes through a redirect back' do context 'when a link goes through a redirect back' do
let(:html) do let(:html) do
<<-HTML <<~HTML
<!doctype html> <!doctype html>
<head> <head>
<link type="text/html" href="https://redirect.me/abc" rel="me" /> <link type="text/html" href="https://redirect.me/abc" rel="me" />
@ -113,7 +114,7 @@ RSpec.describe VerifyLinkService do
context 'when link has no `href` attribute' do context 'when link has no `href` attribute' do
let(:html) do let(:html) do
<<-HTML <<~HTML
<!doctype html> <!doctype html>
<head> <head>
<link type="text/html" rel="me" /> <link type="text/html" rel="me" />
@ -128,6 +129,21 @@ RSpec.describe VerifyLinkService do
expect(field.verified?).to be false expect(field.verified?).to be false
end end
end end
context 'when a link contains a link to an unexpected URL' do
let(:html) do
<<~HTML
<!doctype html>
<body>
<a href="http://unrelated-site.com" rel="me">Follow me on Unrelated Site</a>
</body>
HTML
end
it 'does not mark the field as verified' do
expect(field.verified?).to be false
end
end
end end
context 'when given a remote account' do context 'when given a remote account' do
@ -141,7 +157,7 @@ RSpec.describe VerifyLinkService do
context 'when a link contains an <a> back' do context 'when a link contains an <a> back' do
let(:html) do let(:html) do
<<-HTML <<~HTML
<!doctype html> <!doctype html>
<body> <body>
<a href="https://profile.example.com/alice" rel="me">Follow me on Mastodon</a> <a href="https://profile.example.com/alice" rel="me">Follow me on Mastodon</a>