From 2a36bca4c006850be29eb67918cd3c3a6b2902ea Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Wed, 3 Dec 2014 01:13:26 -0800 Subject: [PATCH] no whitelist for catbus and fatcat --- app.rb | 8 ++++---- models/site.rb | 5 +++++ tests/api_tests.rb | 30 +++++++++++++++++++++++++++--- tests/site_file_tests.rb | 17 +++++++++++++++++ 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/app.rb b/app.rb index c4d83822..07204491 100644 --- a/app.rb +++ b/app.rb @@ -1026,8 +1026,8 @@ post '/site_files/upload' do if current_site.file_size_too_large? file[:tempfile].size file_upload_response "#{params[:dir]}/#{file[:filename]} is too large, upload cancelled." end - if !Site.valid_file_type? file - file_upload_response "#{params[:dir]}/#{file[:filename]}: file type (or content in file) is not allowed on Neocities, upload cancelled." + if !current_site.okay_to_upload? file + file_upload_response "#{params[:dir]}/#{file[:filename]}: file type (or content in file) is not allowed on this site, upload cancelled. You can upgrade your account to remove the file type restrictions." end end @@ -1243,8 +1243,8 @@ post '/api/upload' do end files.each do |file| - if !Site.valid_file_type?(file) - api_error 400, 'invalid_file_type', "#{file[:filename]} is not a valid file type (or contains not allowed content), files have not been uploaded" + if !current_site.okay_to_upload?(file) + api_error 400, 'invalid_file_type', "#{file[:filename]} is not a valid file type (or contains not allowed content) for this site, files have not been uploaded" end if File.directory? file[:filename] diff --git a/models/site.rb b/models/site.rb index 268f047a..3042cb38 100644 --- a/models/site.rb +++ b/models/site.rb @@ -459,6 +459,11 @@ class Site < Sequel::Model !username.empty? && username.match(/^[a-zA-Z0-9_\-]+$/i) end + def okay_to_upload?(uploaded_file) + return true if [:catbus, :fatcat].include?(plan_type.to_sym) + self.class.valid_file_type?(uploaded_file) + end + def self.valid_file_type?(uploaded_file) mime_type = Magic.guess_file_mime_type uploaded_file[:tempfile].path diff --git a/tests/api_tests.rb b/tests/api_tests.rb index 930eda3b..16265269 100644 --- a/tests/api_tests.rb +++ b/tests/api_tests.rb @@ -3,9 +3,13 @@ require 'rack/test' include Rack::Test::Methods -def create_site +def app + Sinatra::Application +end + +def create_site(opts={}) site_attr = Fabricate.attributes_for :site - @site = Site.create site_attr + @site = Site.create site_attr.merge(opts) @user = site_attr[:username] @pass = site_attr[:password] end @@ -219,10 +223,30 @@ describe 'api upload' do site_file_exists?('test.jpg').must_equal true site_file_exists?('test2.jpg').must_equal true end + + it 'fails with unwhitelisted file' do + create_site + basic_authorize @user, @pass + post '/api/upload', 'flowercrime.wav' => Rack::Test::UploadedFile.new('./tests/files/flowercrime.wav', 'audio/x-wav') + res[:result].must_equal 'error' + res[:error_type].must_equal 'invalid_file_type' + site_file_exists?('flowercrime.wav').must_equal false + end + + it 'succeeds for unwhitelisted file on supported plans' do + no_file_restriction_plans = Site::PLAN_FEATURES.select {|p,v| v[:no_file_restrictions] == true} + no_file_restriction_plans.each do |plan_type,hash| + create_site plan_type: plan_type + basic_authorize @user, @pass + post '/api/upload', 'flowercrime.wav' => Rack::Test::UploadedFile.new('./tests/files/flowercrime.wav', 'audio/x-wav') + res[:result].must_equal 'success' + site_file_exists?('flowercrime.wav').must_equal true + end + end end def site_file_exists?(file) - File.exist?(@site.files_path('test.jpg')) + File.exist?(@site.files_path(file)) end def res diff --git a/tests/site_file_tests.rb b/tests/site_file_tests.rb index 62ed59ca..1a478385 100644 --- a/tests/site_file_tests.rb +++ b/tests/site_file_tests.rb @@ -65,6 +65,23 @@ describe 'site_files' do @site.site_changed.must_equal false end + it 'fails with unsupported file' do + upload 'files[]' => Rack::Test::UploadedFile.new('./tests/files/flowercrime.wav', 'audio/x-wav') + last_response.body.must_match /not allowed on this site/i + File.exists?(@site.files_path('flowercrime.wav')).must_equal false + @site.site_changed.must_equal false + end + + it 'succeeds for usually unsupported file on supported plans' do + no_file_restriction_plans = Site::PLAN_FEATURES.select {|p,v| v[:no_file_restrictions] == true} + no_file_restriction_plans.each do |plan_type,hash| + @site = Fabricate :site, plan_type: plan_type + upload 'files[]' => Rack::Test::UploadedFile.new('./tests/files/flowercrime.wav', 'audio/x-wav') + last_response.body.must_match /successfully uploaded/i + File.exists?(@site.files_path('flowercrime.wav')).must_equal true + end + end + it 'overwrites existing file with new file' do upload 'files[]' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg') last_response.body.must_match /successfully uploaded/i