From 70410d16914c9e27cc808280dc6c96419d3447af Mon Sep 17 00:00:00 2001 From: Benjamin Neff Date: Thu, 26 Oct 2017 02:15:47 +0200 Subject: [PATCH] Ignore invalid diaspora:// links Fixes #7651 closes #7652 --- Changelog.md | 1 + app/models/reference.rb | 14 +++++++++++--- lib/diaspora/message_renderer.rb | 3 ++- spec/lib/diaspora/message_renderer_spec.rb | 11 +++++++++++ spec/shared_behaviors/references.rb | 20 ++++++++++++++++++++ 5 files changed, 45 insertions(+), 4 deletions(-) diff --git a/Changelog.md b/Changelog.md index c1f049ea8..c572b7c8a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,7 @@ ## Refactor ## Bug fixes +* Ignore invalid `diaspora://` links [#7652](https://github.com/diaspora/diaspora/pull/7652) ## Features diff --git a/app/models/reference.rb b/app/models/reference.rb index 8312ceb61..3de1ff20a 100644 --- a/app/models/reference.rb +++ b/app/models/reference.rb @@ -15,11 +15,19 @@ class Reference < ApplicationRecord def create_references text&.scan(DiasporaFederation::Federation::DiasporaUrlParser::DIASPORA_URL_REGEX)&.each do |author, type, guid| - class_name = DiasporaFederation::Entity.entity_class(type).to_s.rpartition("::").last - entity = Diaspora::Federation::Mappings.model_class_for(class_name).find_by(guid: guid) - references.find_or_create_by(target: entity) if entity.diaspora_handle == author + add_reference(author, type, guid) end end + + private + + def add_reference(author, type, guid) + class_name = DiasporaFederation::Entity.entity_class(type).to_s.rpartition("::").last + entity = Diaspora::Federation::Mappings.model_class_for(class_name).find_by(guid: guid) + references.find_or_create_by(target: entity) if entity&.diaspora_handle == author + rescue => e # rubocop:disable Lint/RescueWithoutErrorClass + logger.warn "ignoring invalid diaspora-url: diaspora://#{author}/#{type}/#{guid}: #{e.class}: #{e.message}" + end end module Target diff --git a/lib/diaspora/message_renderer.rb b/lib/diaspora/message_renderer.rb index 38bdf5863..4477ae587 100644 --- a/lib/diaspora/message_renderer.rb +++ b/lib/diaspora/message_renderer.rb @@ -98,7 +98,8 @@ module Diaspora def diaspora_links @message = @message.gsub(DiasporaFederation::Federation::DiasporaUrlParser::DIASPORA_URL_REGEX) {|match_str| - Regexp.last_match(2) == "post" ? AppConfig.url_to("/posts/#{Regexp.last_match(3)}") : match_str + guid = Regexp.last_match(3) + Regexp.last_match(2) == "post" && Post.exists?(guid: guid) ? AppConfig.url_to("/posts/#{guid}") : match_str } end end diff --git a/spec/lib/diaspora/message_renderer_spec.rb b/spec/lib/diaspora/message_renderer_spec.rb index 7789e243e..248563ed8 100644 --- a/spec/lib/diaspora/message_renderer_spec.rb +++ b/spec/lib/diaspora/message_renderer_spec.rb @@ -108,6 +108,17 @@ describe Diaspora::MessageRenderer do text = "You can create diaspora://author/type/guid links!" expect(message(text).html).to match(/#{text}/) end + + it "ignores a diaspora:// links with a unknown guid" do + text = "Try this: `diaspora://unknown@localhost:3000/post/thislookslikeavalidguid123456789`" + expect(message(text).html).to match(/#{text}/) + end + + it "ignores a diaspora:// links with an invalid entity type" do + target = FactoryGirl.create(:status_message) + text = "Try this: `diaspora://#{target.diaspora_handle}/posts/#{target.guid}`" + expect(message(text).html).to match(/#{text}/) + end end end diff --git a/spec/shared_behaviors/references.rb b/spec/shared_behaviors/references.rb index 61567a652..f744069c3 100644 --- a/spec/shared_behaviors/references.rb +++ b/spec/shared_behaviors/references.rb @@ -28,6 +28,26 @@ shared_examples_for "a reference source" do expect(post.references.map(&:target).map(&:guid)).to match_array([target1, target2].map(&:guid)) end + it "ignores a reference with a unknown guid" do + text = "Try this: `diaspora://unknown@localhost:3000/post/thislookslikeavalidguid123456789`" + + post = FactoryGirl.build(described_class.to_s.underscore.to_sym, text: text) + post.save + + expect(post.references).to be_empty + end + + it "ignores a reference with an invalid entity type" do + target = FactoryGirl.create(:status_message) + + text = "Try this: `diaspora://#{target.diaspora_handle}/posts/#{target.guid}`" + + post = FactoryGirl.build(described_class.to_s.underscore.to_sym, text: text) + post.save + + expect(post.references).to be_empty + end + it "only creates one reference, even when it is referenced twice" do target = FactoryGirl.create(:status_message) text = "Have a look at [this post](diaspora://#{target.diaspora_handle}/post/#{target.guid}) and " \