Protect uploads with a password
authorLunar <lunar@anargeek.net>
Thu, 8 Jul 2010 11:20:12 +0000 (13:20 +0200)
committerLunar <lunar@anargeek.net>
Thu, 8 Jul 2010 11:20:12 +0000 (13:20 +0200)
coquelicot.rb
test_coquelicot.rb

index 4f5ce34..05cc6d4 100644 (file)
@@ -1,8 +1,17 @@
 require 'sinatra'
 require 'haml'
+require 'digest/sha1'
+require 'singleton'
 
 enable :inline_templates
 
+set :upload_password, '0e5f7d398e6f9cd1f6bac5cc823e363aec636495'
+
+def password_match?(password)
+  return TRUE if settings.upload_password.nil?
+  (not password.nil?) && Digest::SHA1.hexdigest(password) == settings.upload_password
+end
+
 def uploaded_file(file)
   "#{options.root}/files/#{file}"
 end
@@ -35,6 +44,9 @@ get '/:name' do |name|
 end
 
 post '/upload' do
+  unless password_match? params[:upload_password] then
+    return 403
+  end
   if params[:file] then
     tmpfile = params[:file][:tempfile]
     name = params[:file][:filename]
index 6069f42..9f969c4 100644 (file)
@@ -5,7 +5,10 @@ require 'spec'
 require 'rack/test'
 require 'hpricot'
 
+UPLOAD_PASSWORD = 'secret'
+
 set :environment, :test
+set :upload_password, Digest::SHA1.hexdigest(UPLOAD_PASSWORD)
 
 describe 'Coquelicot' do
   include Rack::Test::Methods
@@ -22,13 +25,15 @@ describe 'Coquelicot' do
   end
 
   it "should accept an uploaded file" do
-    post '/upload', 'file' => Rack::Test::UploadedFile.new(__FILE__, 'text/x-script.ruby')
+    post '/upload', 'file' => Rack::Test::UploadedFile.new(__FILE__, 'text/x-script.ruby'),
+                    'upload_password' => UPLOAD_PASSWORD
     last_response.redirect?.should be_true
     last_response['Location'].should eql("ready/#{File.basename(__FILE__)}")
   end
 
   it "should allow retrieval of an uploaded file" do
-    post '/upload', 'file' => Rack::Test::UploadedFile.new(__FILE__, 'text/x-script.ruby')
+    post '/upload', 'file' => Rack::Test::UploadedFile.new(__FILE__, 'text/x-script.ruby'),
+                    'upload_password' => UPLOAD_PASSWORD
     follow_redirect!
     last_response.should be_ok
     doc = Hpricot(last_response.body)
@@ -40,7 +45,16 @@ describe 'Coquelicot' do
     last_response.body.should eql(File.new(__FILE__).read)
   end
 
-  it "should prevent upload without a password"
+  it "should prevent upload without a password" do
+    post '/upload', 'file' => Rack::Test::UploadedFile.new(__FILE__, 'text/x-script.ruby')
+    last_response.status.should eql(403)
+  end
+
+  it "should prevent upload with a wrong password" do
+    post '/upload', 'file' => Rack::Test::UploadedFile.new(__FILE__, 'text/x-script.ruby'),
+                    'upload_password' => "bad"
+    last_response.status.should eql(403)
+  end
 
   it "should not store an uploaded file in cleartext"