From 155dc8889107d6eb2e32a91d2757fe22781bd1f4 Mon Sep 17 00:00:00 2001 From: Jacques Distler Date: Wed, 17 Jun 2009 11:17:25 -0500 Subject: [PATCH] Uploaded files in published webs should be accessible File retrieval (but not file uploads) should be allowed on a published web (this includes BlahTeX/PNG support). (Reported by Ari Stern). --- CHANGELOG | 1 + app/controllers/application_controller.rb | 5 +- app/controllers/file_controller.rb | 14 +++- test/functional/file_controller_test.rb | 86 +++++++++++++++++++++++ 4 files changed, 101 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 7e1fdc2b..8ddd619a 100755 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,6 +15,7 @@ Bugs Fixed: * Add a flash message for redirection to "new" page when the target of "show" action is not found. * Flash[:info] messages use Web's colour scheme. +* Uploaded files in published webs should be accessible ------------------------------------------------------------------------------ * 0.16.6 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 7db0049a..e3a762f9 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -222,15 +222,14 @@ class ApplicationController < ActionController::Base end def authorization_needed? - not %w( login authenticate feeds published atom_with_headlines atom_with_content).include?(action_name) + not %w(login authenticate feeds published atom_with_headlines atom_with_content s5 file blahtex_png).include?(action_name) end def authorized? @web.nil? or @web.password.nil? or cookies[CGI.escape(@web_name)] == @web.password or - password_check(params['password']) or - (@web.published? and action_name == 's5') + password_check(params['password']) end end diff --git a/app/controllers/file_controller.rb b/app/controllers/file_controller.rb index 17885ab1..0c57eb2c 100644 --- a/app/controllers/file_controller.rb +++ b/app/controllers/file_controller.rb @@ -28,7 +28,7 @@ class FileController < ApplicationController # no form supplied, this is a request to download the file file = @web.files_path + '/' + @file_name if File.exists?(file) - send_file(file) + send_file(file) if check_authorized else return unless check_allow_uploads @file = WikiFile.new(:file_name => @file_name) @@ -86,10 +86,20 @@ class FileController < ApplicationController end protected + + def check_authorized + if authorized? or @web.published? + return true + else + @hide_navigation = true + render(:status => 403, :text => 'This web is private', :layout => true) + return false + end + end def check_allow_uploads render(:status => 404, :text => "Web #{params['web'].inspect} not found", :layout => 'error') and return false unless @web - if @web.allow_uploads? + if @web.allow_uploads? and authorized? return true else @hide_navigation = true diff --git a/test/functional/file_controller_test.rb b/test/functional/file_controller_test.rb index 0fbb6944..348407b0 100755 --- a/test/functional/file_controller_test.rb +++ b/test/functional/file_controller_test.rb @@ -80,7 +80,32 @@ class FileControllerTest < ActionController::TestCase assert_equal pic, r.body assert_equal 'inline; filename="rails.gif"', r.headers['Content-Disposition'] end + + def test_pic_download_gif_published_web + @web.update_attribute(:published, true) + @web.update_attribute(:password, 'pswd') + pic = File.open("#{RAILS_ROOT}/test/fixtures/rails.gif", 'rb') { |f| f.read } + @web.wiki_files.create(:file_name => 'rails.gif', :description => 'An image', :content => pic) + + r = get :file, :web => 'wiki1', :id => 'rails.gif' + + assert_response(:success, bypass_body_parsing = true) + assert_equal 'image/gif', r.headers['Content-Type'] + assert_equal pic.size, r.body.size + assert_equal pic, r.body + assert_equal 'inline; filename="rails.gif"', r.headers['Content-Disposition'] + end + def test_pic_download_gif_unpublished_web + @web.update_attribute(:published, false) + @web.update_attribute(:password, 'pswd') + pic = File.open("#{RAILS_ROOT}/test/fixtures/rails.gif", 'rb') { |f| f.read } + @web.wiki_files.create(:file_name => 'rails.gif', :description => 'An image', :content => pic) + r = get :file, :web => 'wiki1', :id => 'rails.gif' + + assert_response(:forbidden) + end + def test_pic_x_sendfile pic = File.open("#{RAILS_ROOT}/test/fixtures/rails.gif", 'rb') { |f| f.read } @web.wiki_files.create(:file_name => 'rails.gif', :description => 'An image', :content => pic) @@ -94,6 +119,33 @@ class FileControllerTest < ActionController::TestCase assert_equal 'inline; filename="rails.gif"', r.headers['Content-Disposition'] end + def test_pic_x_sendfile_published_web + @web.update_attribute(:published, true) + @web.update_attribute(:password, 'pswd') + pic = File.open("#{RAILS_ROOT}/test/fixtures/rails.gif", 'rb') { |f| f.read } + @web.wiki_files.create(:file_name => 'rails.gif', :description => 'An image', :content => pic) + @request.env.update({ 'HTTP_X_SENDFILE_TYPE' => 'foo' }) + @request.remote_addr = '127.0.0.1' + r = get :file, :web => 'wiki1', :id => 'rails.gif' + + assert_response(:success, bypass_body_parsing = true) + assert_match '/rails.gif', r.headers['X-Sendfile'] + assert_equal 'image/gif', r.headers['Content-Type'] + assert_equal 'inline; filename="rails.gif"', r.headers['Content-Disposition'] + end + + def test_pic_x_sendfile_unpublished_web + @web.update_attribute(:published, false) + @web.update_attribute(:password, 'pswd') + pic = File.open("#{RAILS_ROOT}/test/fixtures/rails.gif", 'rb') { |f| f.read } + @web.wiki_files.create(:file_name => 'rails.gif', :description => 'An image', :content => pic) + @request.env.update({ 'HTTP_X_SENDFILE_TYPE' => 'foo' }) + @request.remote_addr = '127.0.0.1' + r = get :file, :web => 'wiki1', :id => 'rails.gif' + + assert_response(:forbidden) + end + def test_pic_x_sendfile_type_nonlocal pic = File.open("#{RAILS_ROOT}/test/fixtures/rails.gif", 'rb') { |f| f.read } @web.wiki_files.create(:file_name => 'rails.gif', :description => 'An image', :content => pic) @@ -114,6 +166,40 @@ class FileControllerTest < ActionController::TestCase assert_template 'file/file' end + def test_pic_upload_published_web + @web.update_attribute(:published, true) + @web.update_attribute(:password, 'pswd') + @web.update_attribute(:allow_uploads, true) + # edit and re-render a page so that it has an "unknown file" link to 'rails-e2e.gif' + PageRenderer.setup_url_generator(StubUrlGenerator.new) + renderer = PageRenderer.new + @wiki.revise_page('wiki1', 'Oak', 'Oak', '[[rails-e2e.gif:pic]]', + Time.now, 'AnonymousBrave', renderer) + assert_equal "

rails-e2e.gif

", + renderer.display_published + + # rails-e2e.gif is unknown to the system, so pic action goes to the file [upload] form + r = get :file, :web => 'wiki1', :id => 'rails-e2e.gif' + assert_response(:forbidden) + end + + def test_pic_upload_unpublished_web + @web.update_attribute(:published, false) + @web.update_attribute(:password, 'pswd') + @web.update_attribute(:allow_uploads, true) + # edit and re-render a page so that it has an "unknown file" link to 'rails-e2e.gif' + PageRenderer.setup_url_generator(StubUrlGenerator.new) + renderer = PageRenderer.new + @wiki.revise_page('wiki1', 'Oak', 'Oak', '[[rails-e2e.gif:pic]]', + Time.now, 'AnonymousBrave', renderer) + assert_equal "

rails-e2e.gif

", + renderer.display_published + + # rails-e2e.gif is unknown to the system, so pic action goes to the file [upload] form + r = get :file, :web => 'wiki1', :id => 'rails-e2e.gif' + assert_response(:forbidden) + end + def test_pic_upload_end_to_end # edit and re-render a page so that it has an "unknown file" link to 'rails-e2e.gif' PageRenderer.setup_url_generator(StubUrlGenerator.new)