5d15e3f39d
On Webs with file uploads enabled, uploaded files were stored (in version 0.16.1 and earlier) in the public/ directory. This was a security threat. A miscreant could upload a .html file. When a user clicked on the link to the file, it was opened (unsanitized) in the browser. As of version 0.16.2, uploaded files are stored in the webs/ directory. Now, when the user clicks on the link, the file is sent with the Content-Disposition: attachment header set, which causes the file to be downloaded, rather than opened in the browser. As always, files downloaded from the internets should be treated with caution. At least, this way, they are not aoutomatically opened in the browser. To move your existing uploaded files to the new location, do a rake upgrade_instiki
135 lines
4.8 KiB
Ruby
Executable file
135 lines
4.8 KiB
Ruby
Executable file
#!/usr/bin/env ruby
|
|
|
|
require File.dirname(__FILE__) + '/../test_helper'
|
|
require 'file_controller'
|
|
require 'fileutils'
|
|
require 'stringio'
|
|
|
|
# Raise errors beyond the default web-based presentation
|
|
class FileController; def rescue_action(e) logger.error(e); raise e end; end
|
|
|
|
class FileControllerTest < Test::Unit::TestCase
|
|
fixtures :webs, :pages, :revisions, :system
|
|
|
|
def setup
|
|
@controller = FileController.new
|
|
@request = ActionController::TestRequest.new
|
|
@response = ActionController::TestResponse.new
|
|
class << @request.session
|
|
attr_accessor :dbman
|
|
end
|
|
# simulate a cookie session store
|
|
@request.session.dbman = FakeSessionDbMan
|
|
@web = webs(:test_wiki)
|
|
@wiki = Wiki.new
|
|
WikiFile.delete_all
|
|
require 'fileutils'
|
|
FileUtils.rm_rf("#{RAILS_ROOT}/webs/wiki1/files/*")
|
|
end
|
|
|
|
def test_file_upload_form
|
|
get :file, :web => 'wiki1', :id => 'new_file.txt'
|
|
assert_response(:success)
|
|
assert_template 'file/file'
|
|
end
|
|
|
|
def test_file_download_text_file
|
|
@web.wiki_files.create(:file_name => 'foo.txt', :description => 'Text file',
|
|
:content => "Contents of the file")
|
|
|
|
r = get :file, :web => 'wiki1', :id => 'foo.txt'
|
|
|
|
assert_response(:success, bypass_body_parsing = true)
|
|
assert_equal "Contents of the file", r.body
|
|
assert_equal 'text/plain', r.headers['type']
|
|
end
|
|
|
|
def test_file_download_pdf_file
|
|
@web.wiki_files.create(:file_name => 'foo.pdf', :description => 'PDF file',
|
|
:content => "aaa\nbbb\n")
|
|
|
|
r = get :file, :web => 'wiki1', :id => 'foo.pdf'
|
|
|
|
assert_response(:success, bypass_body_parsing = true)
|
|
assert_equal "aaa\nbbb\n", r.body
|
|
assert_equal 'application/pdf', r.headers['type']
|
|
end
|
|
|
|
def test_pic_download_gif
|
|
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['type']
|
|
assert_equal pic.size, r.body.size
|
|
assert_equal pic, r.body
|
|
end
|
|
|
|
def test_pic_unknown_pic
|
|
r = get :file, :web => 'wiki1', :id => 'non-existant.gif'
|
|
|
|
assert_response(:success)
|
|
assert_template 'file/file'
|
|
end
|
|
|
|
def test_pic_upload_end_to_end
|
|
# edit and re-render home 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', 'HomePage', '[[rails-e2e.gif:pic]]',
|
|
Time.now, 'AnonymousBrave', renderer)
|
|
assert_equal "<p><span class='newWikiWord'>rails-e2e.gif<a href='../file/rails-e2e.gif'>" +
|
|
"?</a></span></p>",
|
|
renderer.display_content
|
|
|
|
# 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(:success)
|
|
assert_template 'file/file'
|
|
|
|
# User uploads the picture
|
|
begin # Ruby 1.9
|
|
picture = File.read("#{RAILS_ROOT}/test/fixtures/rails.gif", :encoding => 'ascii-8bit')
|
|
rescue #Ruby 1.8
|
|
picture = File.read("#{RAILS_ROOT}/test/fixtures/rails.gif")
|
|
end
|
|
# updated from post to get - post fails the spam protection (no javascript)
|
|
# Moron! If substituting GET for POST actually works, you
|
|
# have much, much bigger problems.
|
|
r = get :file, :web => 'wiki1',
|
|
:file => {:file_name => 'rails-e2e.gif',
|
|
:content => StringIO.new(picture),
|
|
:description => 'Rails, end-to-end'}
|
|
assert @web.has_file?('rails-e2e.gif')
|
|
assert_equal(picture, WikiFile.find_by_file_name('rails-e2e.gif').content)
|
|
PageRenderer.setup_url_generator(StubUrlGenerator.new)
|
|
@wiki.revise_page('wiki1', 'HomePage', 'Try [[rails-e2e.gif:pic]] again.',
|
|
Time.now, 'AnonymousBrave', renderer)
|
|
assert_equal "<p>Try <img alt='Rails, end-to-end' src='../file/rails-e2e.gif'/> again.</p>",
|
|
renderer.display_content
|
|
assert_equal "<p>Try <img alt='Rails, end-to-end' src='../file/rails-e2e.gif'/> again.</p>",
|
|
renderer.display_published
|
|
end
|
|
|
|
def test_import
|
|
# updated from post to get - post fails the spam protection (no javascript)
|
|
r = get :import, :web => 'wiki1', :file => uploaded_file("#{RAILS_ROOT}/test/fixtures/exported_markup.zip")
|
|
assert_response(:redirect)
|
|
assert @web.has_page?('ImportedPage')
|
|
end
|
|
|
|
def uploaded_file(path, content_type="application/octet-stream", filename=nil)
|
|
filename ||= File.basename(path)
|
|
t = Tempfile.new(filename)
|
|
FileUtils.copy_file(path, t.path)
|
|
(class << t; self; end;).class_eval do
|
|
alias local_path path
|
|
define_method(:original_filename) { filename }
|
|
define_method(:content_type) { content_type }
|
|
end
|
|
return t
|
|
end
|
|
|
|
end
|