Commit a1c29241894269cda717e7c5893ec9b6d614097d

Authored by Joenio Costa
1 parent 218cf0a5

isolate proxy settings among multiple environments

app/models/external_feed.rb
@@ -12,6 +12,8 @@ class ExternalFeed < ActiveRecord::Base @@ -12,6 +12,8 @@ class ExternalFeed < ActiveRecord::Base
12 12
13 attr_accessible :address, :enabled, :only_once 13 attr_accessible :address, :enabled, :only_once
14 14
  15 + delegate :environment, :to => :blog, :allow_nil => true
  16 +
15 def add_item(title, link, date, content) 17 def add_item(title, link, date, content)
16 return if content.blank? 18 return if content.blank?
17 doc = Nokogiri::HTML.fragment content 19 doc = Nokogiri::HTML.fragment content
lib/feed_handler.rb
@@ -31,7 +31,7 @@ class FeedHandler @@ -31,7 +31,7 @@ class FeedHandler
31 end 31 end
32 end 32 end
33 33
34 - def fetch(address) 34 + def fetch(address, header = {})
35 begin 35 begin
36 content = "" 36 content = ""
37 block = lambda { |s| content = s.read } 37 block = lambda { |s| content = s.read }
@@ -42,21 +42,7 @@ class FeedHandler @@ -42,21 +42,7 @@ class FeedHandler
42 if !valid_url?(address) 42 if !valid_url?(address)
43 raise InvalidUrl.new("\"%s\" is not a valid URL" % address) 43 raise InvalidUrl.new("\"%s\" is not a valid URL" % address)
44 end 44 end
45 -  
46 - header = {"User-Agent" => "Noosfero/#{Noosfero::VERSION}"}  
47 -  
48 - environment = Environment.default  
49 -  
50 - if environment.enable_feed_proxy  
51 - if address.starts_with?("https://")  
52 - header.merge!(:proxy => environment.https_feed_proxy) if environment.https_feed_proxy  
53 - else  
54 - header.merge!(:proxy => environment.http_feed_proxy) if environment.http_feed_proxy  
55 - end  
56 - end  
57 -  
58 - header.merge!(:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE) if environment.disable_feed_ssl  
59 - 45 + header.merge!("User-Agent" => "Noosfero/#{Noosfero::VERSION}")
60 open(address, header, &block) 46 open(address, header, &block)
61 end 47 end
62 return content 48 return content
@@ -65,6 +51,17 @@ class FeedHandler @@ -65,6 +51,17 @@ class FeedHandler
65 end 51 end
66 end 52 end
67 53
  54 + def fetch_through_proxy(address, environment)
  55 + header = {}
  56 + if address.starts_with?("https://")
  57 + header.merge!(:proxy => environment.https_feed_proxy) if environment.https_feed_proxy
  58 + else
  59 + header.merge!(:proxy => environment.http_feed_proxy) if environment.http_feed_proxy
  60 + end
  61 + header.merge!(:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE) if environment.disable_feed_ssl
  62 + fetch(address, header)
  63 + end
  64 +
68 def process(container) 65 def process(container)
69 begin 66 begin
70 container.class.transaction do 67 container.class.transaction do
@@ -105,7 +102,11 @@ class FeedHandler @@ -105,7 +102,11 @@ class FeedHandler
105 102
106 def actually_process_container(container) 103 def actually_process_container(container)
107 container.clear 104 container.clear
108 - content = fetch(container.address) 105 + if container.environment.enable_feed_proxy
  106 + content = fetch_through_proxy(container.address, container.environment)
  107 + else
  108 + content = fetch(container.address)
  109 + end
109 container.fetched_at = Time.now 110 container.fetched_at = Time.now
110 parsed_feed = parse(content) 111 parsed_feed = parse(content)
111 container.feed_title = parsed_feed.title 112 container.feed_title = parsed_feed.title
test/unit/feed_handler_test.rb
@@ -27,6 +27,7 @@ class FeedHandlerTest < ActiveSupport::TestCase @@ -27,6 +27,7 @@ class FeedHandlerTest < ActiveSupport::TestCase
27 end 27 end
28 28
29 should 'process feed and populate container' do 29 should 'process feed and populate container' do
  30 + container.stubs(:environment).returns(Environment.new)
30 handler.process(container) 31 handler.process(container)
31 assert_equal 'Feed for unit tests', container.feed_title 32 assert_equal 'Feed for unit tests', container.feed_title
32 assert_equivalent ["First POST", "Second POST", "Last POST"], container.feed_items.map {|item| item[:title]} 33 assert_equivalent ["First POST", "Second POST", "Last POST"], container.feed_items.map {|item| item[:title]}
@@ -61,6 +62,7 @@ class FeedHandlerTest < ActiveSupport::TestCase @@ -61,6 +62,7 @@ class FeedHandlerTest < ActiveSupport::TestCase
61 end 62 end
62 63
63 should 'save only latest N posts from feed' do 64 should 'save only latest N posts from feed' do
  65 + container.stubs(:environment).returns(Environment.new)
64 container.limit = 1 66 container.limit = 1
65 handler.process(container) 67 handler.process(container)
66 assert_equal 1, container.feed_items.size 68 assert_equal 1, container.feed_items.size
@@ -83,9 +85,6 @@ class FeedHandlerTest < ActiveSupport::TestCase @@ -83,9 +85,6 @@ class FeedHandlerTest < ActiveSupport::TestCase
83 end 85 end
84 86
85 should 'identifies itself as noosfero user agent' do 87 should 'identifies itself as noosfero user agent' do
86 - Environment.any_instance.expects(:enable_feed_proxy).returns(false)  
87 - Environment.any_instance.expects(:disable_feed_ssl).returns(false)  
88 -  
89 handler.expects(:open).with('http://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}"}, anything).returns('bli content') 88 handler.expects(:open).with('http://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}"}, anything).returns('bli content')
90 89
91 assert_equal 'bli content', handler.fetch('http://site.org/feed.xml') 90 assert_equal 'bli content', handler.fetch('http://site.org/feed.xml')
@@ -154,52 +153,72 @@ class FeedHandlerTest < ActiveSupport::TestCase @@ -154,52 +153,72 @@ class FeedHandlerTest < ActiveSupport::TestCase
154 end 153 end
155 154
156 should 'set proxy when http_feed_proxy is setted from env' do 155 should 'set proxy when http_feed_proxy is setted from env' do
157 - Environment.any_instance.expects(:enable_feed_proxy).returns(true)  
158 - Environment.any_instance.expects(:disable_feed_ssl).returns(false)  
159 - Environment.any_instance.expects(:http_feed_proxy).twice.returns('http://127.0.0.1:3128') 156 + env = Environment.new
  157 + env.expects(:disable_feed_ssl).returns(false)
  158 + env.expects(:http_feed_proxy).twice.returns('http://127.0.0.1:3128')
160 159
161 handler.expects(:open).with('http://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}", :proxy => 'http://127.0.0.1:3128'}, anything).returns('bli content') 160 handler.expects(:open).with('http://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}", :proxy => 'http://127.0.0.1:3128'}, anything).returns('bli content')
162 161
163 - assert_equal 'bli content', handler.fetch('http://site.org/feed.xml') 162 + assert_equal 'bli content', handler.fetch_through_proxy('http://site.org/feed.xml', env)
164 end 163 end
165 164
166 should 'set proxy when https_feed_proxy is setted from env' do 165 should 'set proxy when https_feed_proxy is setted from env' do
167 - Environment.any_instance.expects(:enable_feed_proxy).returns(true)  
168 - Environment.any_instance.expects(:disable_feed_ssl).returns(false)  
169 - Environment.any_instance.expects(:https_feed_proxy).twice.returns('http://127.0.0.1:3128') 166 + env = Environment.new
  167 + env.expects(:disable_feed_ssl).returns(false)
  168 + env.expects(:https_feed_proxy).twice.returns('http://127.0.0.1:3128')
170 169
171 handler.expects(:open).with('https://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}", :proxy => 'http://127.0.0.1:3128'}, anything).returns('bli content') 170 handler.expects(:open).with('https://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}", :proxy => 'http://127.0.0.1:3128'}, anything).returns('bli content')
172 171
173 - assert_equal 'bli content', handler.fetch('https://site.org/feed.xml') 172 + assert_equal 'bli content', handler.fetch_through_proxy('https://site.org/feed.xml', env)
174 end 173 end
175 174
176 should 'use https proxy for https address when both env variables were defined' do 175 should 'use https proxy for https address when both env variables were defined' do
177 - Environment.any_instance.expects(:enable_feed_proxy).returns(true)  
178 - Environment.any_instance.expects(:disable_feed_ssl).returns(false)  
179 - Environment.any_instance.expects(:https_feed_proxy).twice.returns('http://127.0.0.2:3128') 176 + env = Environment.new
  177 + env.expects(:disable_feed_ssl).returns(false)
  178 + env.expects(:https_feed_proxy).twice.returns('http://127.0.0.2:3128')
180 179
181 handler.expects(:open).with('https://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}", :proxy => 'http://127.0.0.2:3128'}, anything).returns('bli content') 180 handler.expects(:open).with('https://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}", :proxy => 'http://127.0.0.2:3128'}, anything).returns('bli content')
182 181
183 - assert_equal 'bli content', handler.fetch('https://site.org/feed.xml') 182 + assert_equal 'bli content', handler.fetch_through_proxy('https://site.org/feed.xml', env)
184 end 183 end
185 184
186 should 'use http proxy for http address when both env variables were defined' do 185 should 'use http proxy for http address when both env variables were defined' do
187 - Environment.any_instance.expects(:enable_feed_proxy).returns(true)  
188 - Environment.any_instance.expects(:disable_feed_ssl).returns(false)  
189 - Environment.any_instance.expects(:http_feed_proxy).twice.returns('http://127.0.0.1:3128') 186 + env = Environment.new
  187 + env.expects(:disable_feed_ssl).returns(false)
  188 + env.expects(:http_feed_proxy).twice.returns('http://127.0.0.1:3128')
190 189
191 handler.expects(:open).with('http://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}", :proxy => 'http://127.0.0.1:3128'}, anything).returns('bli content') 190 handler.expects(:open).with('http://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}", :proxy => 'http://127.0.0.1:3128'}, anything).returns('bli content')
192 191
193 - assert_equal 'bli content', handler.fetch('http://site.org/feed.xml') 192 + assert_equal 'bli content', handler.fetch_through_proxy('http://site.org/feed.xml', env)
194 end 193 end
195 194
196 should 'not verify ssl when define env parameter SSL_VERIFY_NONE' do 195 should 'not verify ssl when define env parameter SSL_VERIFY_NONE' do
197 - Environment.any_instance.expects(:enable_feed_proxy).returns(false)  
198 - Environment.any_instance.expects(:disable_feed_ssl).returns(true) 196 + env = Environment.new
  197 + env.expects(:disable_feed_ssl).returns(true)
199 198
200 handler.expects(:open).with('http://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}", :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE}, anything) 199 handler.expects(:open).with('http://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}", :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE}, anything)
201 200
202 - handler.fetch('http://site.org/feed.xml') 201 + handler.fetch_through_proxy('http://site.org/feed.xml', env)
  202 + end
  203 +
  204 + [:external_feed, :feed_reader_block].each do |container_class|
  205 + should "not use proxy settings for #{container_class} from one environment on another" do
  206 + one = create(:environment)
  207 + one.expects(:enable_feed_proxy).returns(true)
  208 + container_one = create(container_class)
  209 + container_one.stubs(:environment).returns(one)
  210 +
  211 + handler.expects(:fetch_through_proxy).with(container_one.address, one)
  212 + handler.process(container_one)
  213 +
  214 + another = create(:environment)
  215 + another.expects(:enable_feed_proxy).returns(false)
  216 + container_another = create(container_class)
  217 + container_another.stubs(:environment).returns(another)
  218 +
  219 + handler.expects(:fetch_through_proxy).never.with(container_another.address, another)
  220 + handler.process(container_another)
  221 + end
203 end 222 end
204 223
205 end 224 end