diff --git a/README b/README index f55caa8..a19a7a3 100644 --- a/README +++ b/README @@ -6,7 +6,7 @@ Q: What is it? A: A Rails like way to use the FCKeditor in a Rails app, it basically works just like the normal helpers. -It supports the "default" upload interface, I've though about mcpuk support +It supports the "default" upload interface, I've thought about mcpuk support but since I'm not even using this in any projects currently I don't have the need or the time to implement all that mcpuk does. Maybe one of these days. @@ -38,6 +38,13 @@ Basic install: engines fckeditor_on_rails + By default it attempts to copy a functional test into your project, if you + don't want it running the tests just remove + test/functional/fckeditor_controller_test.rb + +Uninstall: + ./script/plugin uninstall fckeditor_on_rails + This will also remove the installed functional test Contact: Michael Moen @@ -47,9 +54,15 @@ Contact: History: 2007-01-05 (0.1.0) - Clean up that ugly code a bit + Clean up that ugly code a bit, Ok it was almost a rewrite, it was ugly Make it plugin ready for Rails 1.2 Move the config to YAML + Clean up and add some tests 2005-09-11 (0.0.1) - Initial +Thanks goes out to the following for patches: + Gregg Kellogg + Markus Kristo + Scott Carson + Gabriel Birke diff --git a/app/controllers/fckeditor_controller.rb b/app/controllers/fckeditor_controller.rb index 15fddb1..28c8aa4 100644 --- a/app/controllers/fckeditor_controller.rb +++ b/app/controllers/fckeditor_controller.rb @@ -3,7 +3,7 @@ class FckeditorController < ApplicationController layout false def index - render(:nothing => true) unless RAILS_ENV == 'development' + render :nothing => true unless RAILS_ENV == 'development' end def connector @@ -41,14 +41,13 @@ def get_folders_and_files end end - render 'fckeditor/files_and_folders' + render :template => 'fckeditor/files_and_folders' end # create a new directory def create_folder begin - new_dir = @options[:dir] + params[:NewFolderName] - Dir.mkdir(new_dir) + Dir.mkdir(File.join(@options[:dir], params[:NewFolderName])) rescue Errno::EEXIST # directory already exists @error = 101 @@ -59,7 +58,7 @@ def create_folder # any other error @error = 110 end - render 'fckeditor/create_folder' + render :template => 'fckeditor/create_folder' end # upload a new file @@ -68,9 +67,8 @@ def create_folder # not sure how to catch invalid file name yet # I'm thinking there should be a permission denied error as well def upload_file - counter = 1 + counter = 1 @file_name = params[:NewFile].original_filename - # break it up into file and extension # we need this to check the types and to build new names if necessary ext = File.extname(@file_name) @@ -93,7 +91,7 @@ def upload_file @error = 202 end - render 'fckeditor/upload_file' + render :template => 'fckeditor/upload_file' end def type_allowed(filetype, ext) @@ -105,18 +103,15 @@ def type_allowed(filetype, ext) def get_options @error = 0 - @options = { - :base_dir => File.join('public', Fckeditor.config[:uploads] || 'UserFiles') - } - @options[:url] = "/#{@options[:base_dir]}/#{params[:Type]}/#{params[:CurrentFolder]}".gsub(/\/+/, '/') - @options[:dir] = File.join(RAILS_ROOT, @options[:url]) + @options = {} + @options[:url] = "/#{Fckeditor.config[:upload_dir]}/#{params[:Type]}/#{params[:CurrentFolder]}".gsub(/\/+/, '/') + @options[:dir] = File.join('public', @options[:url]) end def sanitize_directory if params[:CurrentFolder] - clean = File.expand_path(@options[:base_dir]) + clean = File.expand_path(File.join(RAILS_ROOT, 'public', Fckeditor.config[:upload_dir])) dirty = File.expand_path(@options[:dir]) - unless dirty.starts_with?(clean) render :nothing => true, :status => 403 false diff --git a/config/fckeditor.yml b/config/fckeditor.yml index 3cf057a..72616a3 100644 --- a/config/fckeditor.yml +++ b/config/fckeditor.yml @@ -15,12 +15,16 @@ # this path starts at public/ so your settings should account for that :upload_dir: '/UserFiles/' + # the starting point for uploaded files URLs + :url_base: '/' + # toolbar for fckeditor to use, can be overridden on the fly :toolbar_set: 'Default' # this controls what files are allowed to be uploaded for different Types # if there is only a deny anything other than those listed will be allowed # if there is only an allow only those listed would be allowed + # if neither exist anything can be uploaded, not a good idea # the settings here are just a starting point, pay special attention to # file deny and add anything you don't want anybody to be able to upload :file_types: @@ -62,7 +66,11 @@ - '.mpg' - '.mpeg' - :development: + :development: - :test: - :upload_dir: '../test/UserFiles' + # just like the test DB, do not let this point to the same place as your + # default location, as the tests will rm_rf this dir, leaving this is fine + # if you don't want it running the tests you can remove + # test/functional/fckeditor_controller_test.rb + :test: + :upload_dir: '../vendor/plugins/fckeditor_on_rails/test/UserFiles/' diff --git a/install.rb b/install.rb index cb134db..c109985 100644 --- a/install.rb +++ b/install.rb @@ -1,11 +1,15 @@ require 'fileutils' -FileUtils.ln_s( - File.join(File.dirname(__FILE__), 'test', 'fckeditor_controller_test.rb'), - File.join(File.dirname(__FILE__), '..', '..', 'test', 'functional', - 'fckeditor_controller_test.rb') +dest_file = File.join(File.dirname(__FILE__), '..', '..', '..', 'test', + 'functional', 'fckeditor_controller_test.rb') + +FileUtils.rm(dest_file) rescue nil + +FileUtils.cp( + File.join(File.dirname(__FILE__), 'test', 'functional', 'fckeditor_controller_test.rb'), + dest_file ) rescue puts <<-EOM -Unable to link the functional test, if you want to include fckeditor_on_rails -in your testing copy test/functional/fckeditor_controller_test.rb from the -plugin directory into your app +Unable to copy the functional test, if you want to include fckeditor_on_rails +in your testing copy #{File.dirname(__FILE__)}/test/functional/fckeditor_controller_test.rb +from the plugin directory into test/functional/ EOM diff --git a/test/files/bad_file.exe b/test/files/bad_file.exe new file mode 100644 index 0000000..a47cf5f --- /dev/null +++ b/test/files/bad_file.exe @@ -0,0 +1 @@ +this is just a text file to test upload blocking diff --git a/test/functional/fckeditor_controller_test.rb b/test/functional/fckeditor_controller_test.rb index d75447b..2c21e65 100644 --- a/test/functional/fckeditor_controller_test.rb +++ b/test/functional/fckeditor_controller_test.rb @@ -7,163 +7,242 @@ class FckeditorController; def rescue_action(e) raise e end; end class FckeditorControllerTest < Test::Unit::TestCase - TMP_DIR = "tmp/" - IMG_DIR = "Image" - IMG_SRC = "../../public/images" - IMG1 = "rails.png" - IMG2 = "rails(1).png" + FILE_DIR = File.join(RAILS_ROOT, 'vendor', 'plugins', 'fckeditor_on_rails', + 'test', 'files') + IMG1 = 'rails.png' + IMG2 = 'rails(1).png' + IMG2_RE = 'rails\\(1\\).png' + EXECUTABLE = 'bad_file.exe' def setup + rm_rf(Fckeditor.config[:upload_dir]) + Fckeditor.ensure_dirs_exist @controller = FckeditorController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new - - @test_dir = @@fixture_path - @tmp_dir = "#{@test_dir}/#{TMP_DIR}" - @img_dir = "#{@tmp_dir}/#{IMG_DIR}" - - # Create test upload structure - rm_rf(@tmp_dir) - Dir.mkdir(@tmp_dir) - Dir.mkdir(@img_dir) - Dir.mkdir("#{@img_dir}/foo") - - # Copy a test file into the structure - cp("#{@test_dir}/#{IMG_SRC}/#{IMG1}", @img_dir) end def teardown - rm_rf(@tmp_dir) + rm_rf(File.join('public', Fckeditor.config[:upload_dir])) end # Get directory and file list def test_get_folders_and_files - get :connector, { :Command => 'GetFoldersAndFiles', :ServerPath => @tmp_dir} + get :connector, { + :Command => 'GetFoldersAndFiles', + :Type => 'Image', + :CurrentFolder => '/' + } assert_response :success assert_template 'files_and_folders' assert_tag :tag => 'connector', - :attributes => {:command => "GetFoldersAndFiles", :resourcetype => 'Image'} + :attributes => { + :command => "GetFoldersAndFiles", + :resourcetype => 'Image' + } assert_tag :tag => 'currentfolder', - :attributes => {:url => "/UserFiles/Image/", :path => "/"}, - :parent => {:tag => "connector"} + :parent => { :tag => "connector" }, + :attributes => { + :url => "/#{Fckeditor.config[:upload_dir]}Image/", + :path => "/" + } assert_tag :tag => 'folders', - :parent => {:tag => "connector"} - assert_tag :tag => 'folder', - :attributes => {:name => "foo"}, - :parent => {:tag => "folders"} + :parent => { :tag => "connector" } assert_tag :tag => 'files', - :parent => {:tag => "connector"} - assert_tag :tag => 'file', - :parent => {:tag => "files"}, - :attributes => {:name => IMG1} + :parent => { :tag => "connector" } end - # Get directory and file list + # Get directory list def test_get_folders - get :connector, { :Command => 'GetFolders', :ServerPath => @tmp_dir} + get :connector, { + :Command => 'GetFolders', + :Type => 'Image', + :CurrentFolder => '/' + } assert_response :success assert_template 'files_and_folders' assert_tag :tag => 'connector', - :attributes => {:command => "GetFolders", :resourcetype => 'Image'} + :attributes => { + :command => "GetFolders", + :resourcetype => 'Image' + } assert_tag :tag => 'currentfolder', - :attributes => {:url => "/UserFiles/Image/", :path => "/"}, - :parent => {:tag => "connector"} + :parent => { :tag => "connector" }, + :attributes => { + :url => "/#{Fckeditor.config[:upload_dir]}Image/", + :path => "/" + } assert_tag :tag => 'folders', - :parent => {:tag => "connector"} - assert_tag :tag => 'folder', - :attributes => {:name => "foo"}, - :parent => {:tag => "folders"} + :parent => { :tag => "connector" } assert_no_tag :tag => 'file' end - + # File Upload def test_file_upload # Make sure there are no files uploaded - get :connector, { :Command => 'GetFoldersAndFiles', :ServerPath => @tmp_dir, :CurrentFolder => '/foo/'} + get :connector, { + :Command => 'GetFolders', + :Type => 'Image', + :CurrentFolder => '/' + } assert_response :success assert_template 'files_and_folders' - assert_no_tag :tag => 'file', - :attributes => {:name => IMG1} + assert_no_tag :tag => 'file', :attributes => { :name => IMG1 } # Do the upload - heman = uploaded_jpeg("#{@img_dir}/#{IMG1}") - post :connector, { :Command => 'FileUpload', :ServerPath => @tmp_dir, :CurrentFolder => '/foo/', :NewFile => heman} + heman = uploaded_jpeg("#{FILE_DIR}/#{IMG1}") + post :connector, { + :Command => 'FileUpload', + :Type => 'Image', + :CurrentFolder => '/', + :NewFile => heman + } assert_response :success assert_template 'upload_file' assert_tag :tag => 'script', - :attributes => {:type => "text/javascript"}, - :content => "UploadCompleted(0, '#{IMG1}'" - + :attributes => { :type => "text/javascript" }, + :content => /UploadCompleted\(0, '#{IMG1}'/ + # Make sure the file exists - get :connector, { :Command => 'GetFoldersAndFiles', :ServerPath => @tmp_dir, :CurrentFolder => '/foo/'} + get :connector, { + :Command => 'GetFoldersAndFiles', + :Type => 'Image', + :CurrentFolder => '/' + } assert_response :success assert_template 'files_and_folders' - assert_tag :tag => 'file', - :attributes => {:name => IMG1} + assert_tag :tag => 'file', :attributes => { :name => IMG1 } end - - # File Upload (muliple) + + # File Upload (multiple), test rename def test_file_upload_multiple # Do the upload - heman = uploaded_jpeg("#{@img_dir}/#{IMG1}") - post :connector, { :Command => 'FileUpload', :ServerPath => @tmp_dir, :CurrentFolder => '/foo/', :NewFile => heman} + heman = uploaded_jpeg("#{FILE_DIR}/#{IMG1}") + post :connector, { + :Command => 'FileUpload', + :Type => 'Image', + :CurrentFolder => '/', + :NewFile => heman + } assert_response :success assert_template 'upload_file' assert_tag :tag => 'script', - :attributes => {:type => "text/javascript"}, + :attributes => { :type => "text/javascript" }, :content => /UploadCompleted\(0, '#{IMG1}'/ - + # Do the upload again - post :connector, { :Command => 'FileUpload', :ServerPath => @tmp_dir, :CurrentFolder => '/foo/', :NewFile => heman} + heman = uploaded_jpeg("#{FILE_DIR}/#{IMG1}") + post :connector, { + :Command => 'FileUpload', + :Type => 'Image', + :CurrentFolder => '/', + :NewFile => heman + } assert_response :success assert_template 'upload_file' + # 201 status return indicates it was renamed assert_tag :tag => 'script', - :attributes => {:type => "text/javascript"}, - :content => "UploadCompleted\(201, '#{IMG2}'" # 201 status return indicates it was renamed - - # Make sure the files exists - get :connector, { :Command => 'GetFoldersAndFiles', :ServerPath => @tmp_dir, :CurrentFolder => '/foo/'} + :attributes => { :type => "text/javascript" }, + :content => /UploadCompleted\(201, '#{IMG2_RE}'/ + + # Make sure the files exist + get :connector, { + :Command => 'GetFoldersAndFiles', + :CurrentFolder => '/', + :Type => 'Image' + } assert_response :success assert_template 'files_and_folders' - assert_tag :tag => 'file', - :attributes => {:name => IMG1} - assert_tag :tag => 'file', - :attributes => {:name => IMG2} + assert_tag :tag => 'file', :attributes => { :name => IMG1 } + assert_tag :tag => 'file', :attributes => { :name => IMG2 } end - + # Get create folder def test_create_folder - get :connector, { :Command => 'CreateFolder', :ServerPath => @tmp_dir, :NewFolderName => 'bar'} + get :connector, { + :Command => 'CreateFolder', + :Type => 'Image', + :CurrentFolder => '/', + :NewFolderName => 'bar' + } assert_response :success assert_template 'create_folder' assert_tag :tag => 'connector', - :attributes => {:command => "CreateFolder", :resourcetype => 'Image'} + :attributes => { + :command => "CreateFolder", + :resourcetype => 'Image' + } + assert_tag :tag => 'currentfolder', - :attributes => {:url => "/UserFiles/Image/", :path => "/"}, - :parent => {:tag => "connector"} + :parent => { :tag => "connector" }, + :attributes => { + :url => "/#{Fckeditor.config[:upload_dir]}Image/", + :path => "/" + } + assert_tag :tag => 'error', - :parent => {:tag => "connector"}, - :attributes => {:number => "0"} + :parent => { :tag => "connector" }, + :attributes => { :number => "0" } end - + # Get create folder def test_create_folder_existing - get :connector, { :Command => 'CreateFolder', :ServerPath => @tmp_dir, :NewFolderName => 'foo'} + # call it once to make sure it's there + get :connector, { + :Command => 'CreateFolder', + :Type => 'Image', + :CurrentFolder => '/', + :NewFolderName => 'foo' + } + # call it again for the actual test + get :connector, { + :Command => 'CreateFolder', + :Type => 'Image', + :CurrentFolder => '/', + :NewFolderName => 'foo' + } + assert_response :success assert_template 'create_folder' assert_tag :tag => 'connector', - :attributes => {:command => "CreateFolder", :resourcetype => 'Image'} + :attributes => { + :command => "CreateFolder", + :resourcetype => 'Image' + } + assert_tag :tag => 'currentfolder', - :attributes => {:url => "/UserFiles/Image/", :path => "/"}, - :parent => {:tag => "connector"} + :parent => { :tag => "connector" }, + :attributes => { + :url => "/#{Fckeditor.config[:upload_dir]}Image/", + :path => "/" + } + assert_tag :tag => 'error', - :parent => {:tag => "connector"}, - :attributes => {:number => "101"} + :parent => { :tag => "connector" }, + :attributes => { :number => "101" } end + + def test_executable_upload + heman = uploaded_file("#{FILE_DIR}/#{EXECUTABLE}") + post :connector, { + :Command => 'FileUpload', + :Type => 'Image', + :CurrentFolder => '/', + :NewFile => heman + } + + assert_response :success + assert_template 'upload_file' + # 202 status return indicates file type not allowed + assert_tag :tag => 'script', + :attributes => { :type => "text/javascript" }, + :content => /UploadCompleted\(202, '#{EXECUTABLE}'/ + end + # get us an object that represents an uploaded file def uploaded_file(path, content_type="application/octet-stream", filename=nil) filename ||= File.basename(path) @@ -176,17 +255,17 @@ def uploaded_file(path, content_type="application/octet-stream", filename=nil) end return t end - + # a PNG helper def uploaded_png(path, filename=nil) uploaded_file(path, 'image/png', filename) end - + # a JPEG helper def uploaded_jpeg(path, filename=nil) uploaded_file(path, 'image/jpeg', filename) end - + # a GIF helper def uploaded_gif(path, filename=nil) uploaded_file(path, 'image/gif', filename) diff --git a/uninstall.rb b/uninstall.rb index 8746c74..abecef5 100644 --- a/uninstall.rb +++ b/uninstall.rb @@ -1,7 +1,7 @@ require 'fileutils' -file_path = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test', - 'functional', 'fckeditor_controller_test.rb')) +file_path = File.join(File.dirname(__FILE__), '..', '..', '..', 'test', + 'functional', 'fckeditor_controller_test.rb') -FileUtils.rm(file_path) rescue "Unable to remove #{file_path}" if - File.exist?(file_path) + +FileUtils.rm(file_path) rescue "Unable to remove #{file_path}"