diff --git a/app/controllers/application.rb b/app/controllers/application.rb index 1aec04b6..3dfd3923 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -25,12 +25,38 @@ class ApplicationController < ActionController::Base protected - def wiki - $instiki_wiki_service + def authorized? + @web.nil? || + @web.password.nil? || + cookies['web_address'] == @web.password || + password_check(@params['password']) + end + + def check_authorization + if in_a_web? and + not authorized? and + not %w( login authenticate published ).include?(@action_name) + redirect_to :action => 'login' + return false + end + end + + def connect_to_model + @action_name = @params['action'] || 'index' + @web_name = @params['web'] + @wiki = wiki + @web = @wiki.webs[@web_name] unless @web_name.nil? + @page_name = @file_name = @params['id'] + @page = @wiki.read_page(@web_name, @page_name) unless @page_name.nil? + @author = cookies['author'] || 'AnonymousCoward' + check_authorization + end + + def in_a_web? + not @web_name.nil? end @@REMEMBER_NOT = ['locked', 'save'] - def remember_location if @response.headers['Status'] == '200 OK' unless @@REMEMBER_NOT.include? action_name or @request.method != :get @@ -58,28 +84,8 @@ class ApplicationController < ActionController::Base @response.headers['Content-Type'] = 'text/html; charset=UTF-8' end - def connect_to_model - @action_name = @params['action'] || 'index' - @web_name = @params['web'] - @wiki = wiki - @web = @wiki.webs[@web_name] unless @web_name.nil? - @page_name = @params['id'] - @page = @wiki.read_page(@web_name, @page_name) unless @page_name.nil? - @author = cookies['author'] || 'AnonymousCoward' - check_authorization(@action_name) - end - - def check_authorization(action_name) - if in_a_web? and - not authorized? and - not %w( login authenticate published ).include?(action_name) - redirect_to :action => 'login' - return false - end - end - - def in_a_web? - not @web_name.nil? + def wiki + $instiki_wiki_service end end diff --git a/app/controllers/file_controller.rb b/app/controllers/file_controller.rb index 006797db..cd60f1cc 100644 --- a/app/controllers/file_controller.rb +++ b/app/controllers/file_controller.rb @@ -1,31 +1,45 @@ +require 'fileutils' require 'application' +require 'instiki_errors' class FileController < ApplicationController layout 'default', :except => [:rss_feed, :rss_with_headlines, :tex, :export_tex, :export_html] def file - if have_file?(@params['id']) - render_text 'Download file' - else + if have_file? + send_file(file_path) + else render_text 'form' end end private - def have_file?(file_name) - sanitize_file_name(file_name) - @wiki.storage_path + def have_file? + sanitize_file_name + File.file?(file_path) end SANE_FILE_NAME = /[-_A-Za-z0-9]{1,255}/ - def sanitize_file_name(file_name) - unless file_name =~ SANE_FILE_NAME - raise "Invalid file name: '#{file_name}'.\n" + - "Only latin characters, digits, underscores and dashes are accepted." + + def sanitize_file_name + raise Instiki::ValidationError.new("Invalid path") unless @file_name + unless @file_name =~ SANE_FILE_NAME + raise ValidationError.new("Invalid file name: '#{@file_name}'.\n" + + "Only latin characters, digits, underscores and dashes are accepted.") end end -end + def file_area + raise Instiki::ValidationError.new("Invalid path") unless @web_name + file_area = File.expand_path("#{@wiki.storage_path}/#{@web_name}") + FileUtils.mkdir_p(file_area) unless File.directory?(file_area) + file_area + end + def file_path + "#{file_area}/#{@file_name}" + end + +end diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index ccd97eb0..4bff91b0 100755 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -80,7 +80,7 @@ class WikiController < ApplicationController def export_pdf file_name = "#{@web.address}-tex-#{@web.revised_on.strftime('%Y-%m-%d-%H-%M-%S')}" - file_path = WikiService.storage_path + file_name + file_path = @wiki.storage_path + file_name export_web_to_tex "#{file_path}.tex" unless FileTest.exists? "#{file_path}.tex" convert_tex_to_pdf "#{file_path}.tex" @@ -89,7 +89,7 @@ class WikiController < ApplicationController def export_tex file_name = "#{@web.address}-tex-#{@web.revised_on.strftime('%Y-%m-%d-%H-%M-%S')}.tex" - file_path = WikiService.storage_path + file_name + file_path = @wiki.storage_path + file_name export_web_to_tex(file_path) unless FileTest.exists?(file_path) send_file(file_path) @@ -182,7 +182,7 @@ class WikiController < ApplicationController page = wiki.read_page(@web_name, @page_name) safe_page_name = @page.name.gsub(/\W/, '') file_name = "#{safe_page_name}-#{@web.address}-#{@page.created_at.strftime('%Y-%m-%d-%H-%M-%S')}" - file_path = WikiService.storage_path + file_name + file_path = @wiki.storage_path + file_name export_page_to_tex(file_path + '.tex') unless FileTest.exists?(file_path + '.tex') # NB: this is _very_ slow @@ -263,13 +263,6 @@ class WikiController < ApplicationController private - def authorized? - @web.nil? || - @web.password.nil? || - cookies['web_address'] == @web.password || - password_check(@params['password']) - end - def convert_tex_to_pdf(tex_path) # TODO remove earlier PDF files with the same prefix # TODO handle gracefully situation where pdflatex is not available @@ -285,7 +278,7 @@ class WikiController < ApplicationController file_prefix = "#{@web.address}-#{file_type}-" timestamp = @web.revised_on.strftime('%Y-%m-%d-%H-%M-%S') - file_path = WikiService.storage_path + file_prefix + timestamp + '.zip' + file_path = @wiki.storage_path + file_prefix + timestamp + '.zip' tmp_path = "#{file_path}.tmp" Zip::ZipOutputStream.open(tmp_path) do |zip_out| @@ -305,7 +298,7 @@ class WikiController < ApplicationController EOL end end - FileUtils.rm_rf(Dir[WikiService.storage_path + file_prefix + '*.zip']) + FileUtils.rm_rf(Dir[@wiki.storage_path + file_prefix + '*.zip']) FileUtils.mv(tmp_path, file_path) send_file(file_path, :type => 'application/zip') end diff --git a/app/models/wiki_service.rb b/app/models/wiki_service.rb index 96b3afb9..baf64c18 100755 --- a/app/models/wiki_service.rb +++ b/app/models/wiki_service.rb @@ -90,6 +90,10 @@ module AbstractWikiService @webs[web_address].add_page(page) page end + + def storage_path + self.class.storage_path + end private def settings_changed?(web, markup, safe_mode, brackets_only) @@ -106,19 +110,20 @@ class WikiService # These methods do not change the state of persistent objects, and # should not be ogged by Madeleine - automatic_read_only :authenticate, :read_page, :setup?, :webs + automatic_read_only :authenticate, :read_page, :setup?, :webs, :storage_path @@storage_path = './storage/' class << self - def storage_path - @@storage_path - end - + def storage_path=(storage_path) @@storage_path = storage_path end + def storage_path + @@storage_path + end + def clean_storage MadeleineServer.clean_storage(self) end diff --git a/test/functional/file_controller_test.rb b/test/functional/file_controller_test.rb index 129355f3..2e426855 100644 --- a/test/functional/file_controller_test.rb +++ b/test/functional/file_controller_test.rb @@ -18,7 +18,7 @@ class FileControllerTest < Test::Unit::TestCase end def test_file - process 'file', 'id' => 'foo.tgz' + process 'file', 'web' => 'wiki', 'id' => 'foo.tgz' end end diff --git a/test/test_helper.rb b/test/test_helper.rb index b94a178c..7997b094 100755 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -56,7 +56,7 @@ class WikiServiceWithNoPersistence end def storage_path - RAILS_ROOT + '/storage/test' + RAILS_ROOT + '/storage/test/' end end