From cca0c9eec4d7e10242e21bc9fde9aba83122ae30 Mon Sep 17 00:00:00 2001 From: Dennis Schubert Date: Sat, 8 Nov 2014 20:03:34 +0100 Subject: [PATCH] Some refactorings, safer regex --- lib/diaspora.rb | 11 +++---- lib/diaspora/camo.rb | 31 ++++++++++++++++++++ lib/diaspora/camo_url.rb | 16 ---------- lib/diaspora/message_renderer.rb | 4 +-- spec/lib/diaspora/camo_spec.rb | 50 ++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+), 24 deletions(-) create mode 100644 lib/diaspora/camo.rb delete mode 100644 lib/diaspora/camo_url.rb create mode 100644 spec/lib/diaspora/camo_spec.rb diff --git a/lib/diaspora.rb b/lib/diaspora.rb index 161dbae8f..6f6d2002c 100644 --- a/lib/diaspora.rb +++ b/lib/diaspora.rb @@ -3,12 +3,13 @@ # the COPYRIGHT file. module Diaspora + require 'diaspora/camo' require 'diaspora/exceptions' - require 'diaspora/parser' - require 'diaspora/fetcher' - require 'diaspora/markdownify' - require 'diaspora/message_renderer' - require 'diaspora/mentionable' require 'diaspora/exporter' require 'diaspora/federated' + require 'diaspora/fetcher' + require 'diaspora/markdownify' + require 'diaspora/mentionable' + require 'diaspora/message_renderer' + require 'diaspora/parser' end diff --git a/lib/diaspora/camo.rb b/lib/diaspora/camo.rb new file mode 100644 index 000000000..6338b9076 --- /dev/null +++ b/lib/diaspora/camo.rb @@ -0,0 +1,31 @@ +# implicitly requires OpenSSL +module Diaspora + module Camo + def self.from_markdown(markdown_text) + markdown_text.gsub(/(!\[(.*?)\]\s?\([ \t]*()?[ \t]*((['"])(.*?)\6[ \t]*)?\))/m) do |link| + link.gsub($4, self.image_url($4)) + end + end + + def self.image_url(url) + return unless url + return url unless self.url_eligible?(url) + + digest = OpenSSL::HMAC.hexdigest( + OpenSSL::Digest.new('sha1'), + AppConfig.privacy.camo.key, + url + ) + + encoded_url = url.to_enum(:each_byte).map {|byte| '%02x' % byte}.join + "#{AppConfig.privacy.camo.root}#{digest}/#{encoded_url}" + end + + def self.url_eligible?(url) + return false unless url.start_with?('http', '//') + return false if url.start_with?(AppConfig.environment.url.to_s, + AppConfig.privacy.camo.root.to_s) + true + end + end +end diff --git a/lib/diaspora/camo_url.rb b/lib/diaspora/camo_url.rb deleted file mode 100644 index f0cbb0da2..000000000 --- a/lib/diaspora/camo_url.rb +++ /dev/null @@ -1,16 +0,0 @@ -# implicitly requires OpenSSL - -module Diaspora - module CamoUrl - def self.image_url(url) - digest = OpenSSL::HMAC.hexdigest( - OpenSSL::Digest.new("sha1"), - AppConfig.privacy.camo.key, - url - ) - encoded_url = url.to_enum(:each_byte).map {|byte| "%02x" % byte}.join - - "#{AppConfig.privacy.camo.root}#{digest}/#{encoded_url}" - end - end -end diff --git a/lib/diaspora/message_renderer.rb b/lib/diaspora/message_renderer.rb index 3549d3721..cd007d925 100644 --- a/lib/diaspora/message_renderer.rb +++ b/lib/diaspora/message_renderer.rb @@ -89,9 +89,7 @@ module Diaspora end def camo_urls - @message = @message.gsub(/!\[.*?\]\((.+?)\)/) do |link| - link.gsub($1, Diaspora::CamoUrl::image_url($1)) - end + @message = Diaspora::Camo::from_markdown(@message) end end diff --git a/spec/lib/diaspora/camo_spec.rb b/spec/lib/diaspora/camo_spec.rb new file mode 100644 index 000000000..c2def5fad --- /dev/null +++ b/spec/lib/diaspora/camo_spec.rb @@ -0,0 +1,50 @@ +# Copyright (c) 2010, Diaspora Inc. This file is +# licensed under the Affero General Public License version 3 or later. See +# the COPYRIGHT file. + +require 'spec_helper' + +describe Diaspora::Camo do + before do + AppConfig.privacy.camo.root = 'http://localhost:3000/camo/' + AppConfig.privacy.camo.key = 'kittenpower' + + @raw_image_url = 'http://example.com/kitten.jpg' + @camo_image_url = "#{AppConfig.privacy.camo.root}5bc5b9d7ebd202841ab0667c4fc8d4304278f902/687474703a2f2f6578616d706c652e636f6d2f6b697474656e2e6a7067" + end + + describe '#image_url' do + it 'should not rewrite local URLs' do + local_image = "#{AppConfig.environment.url}kitten.jpg" + expect(Diaspora::Camo::image_url(local_image)).to eq(local_image) + end + + it 'should not rewrite relative URLs' do + relative_image = "/kitten.jpg" + expect(Diaspora::Camo::image_url(relative_image)).to eq(relative_image) + end + + it 'should not rewrite already camo-fied URLs' do + camo_image = "#{AppConfig.privacy.camo.root}1234/56789abcd" + expect(Diaspora::Camo::image_url(camo_image)).to eq(camo_image) + end + + it 'should rewrite external URLs' do + expect(Diaspora::Camo::image_url(@raw_image_url)).to eq(@camo_image_url) + end + end + + describe '#from_markdown' do + it 'should rewrite plain markdown images' do + expect(Diaspora::Camo::from_markdown("![](#{@raw_image_url})")).to include(@camo_image_url) + end + + it 'should rewrite markdown images with alt texts' do + expect(Diaspora::Camo::from_markdown("![a kitten](#{@raw_image_url})")).to include(@camo_image_url) + end + + it 'should rewrite markdown images with title texts' do + expect(Diaspora::Camo::from_markdown("![](#{@raw_image_url}) \"title\"")).to include(@camo_image_url) + end + end +end