From 4a2926508e21e5d43193f96aed111172c25a0ff4 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Sun, 21 May 2017 17:32:26 -0500 Subject: [PATCH] api: add upload_hash for checking file hash before uploading --- app/api.rb | 16 ++++++++++++++++ models/site.rb | 6 ++++++ tests/api_tests.rb | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/app/api.rb b/app/api.rb index 18036eba..5faa25e4 100644 --- a/app/api.rb +++ b/app/api.rb @@ -5,6 +5,22 @@ get '/api' do erb :'api' end +post '/api/upload_hash' do + require_api_credentials + + res = {} + + if params[:files].blank? || !params[:files].is_a?(Hash) + api_error 400, 'no_file_hashes_provided', 'no file hashes provided' + end + + params[:files].each do |k,v| + res[k] = current_site.sha1_hash_match? k, v + end + + api_success files: res +end + get '/api/list' do require_api_credentials diff --git a/models/site.rb b/models/site.rb index cf3ce200..928d7088 100644 --- a/models/site.rb +++ b/models/site.rb @@ -1512,6 +1512,12 @@ class Site < Sequel::Model save_changes validate: false end + def sha1_hash_match?(path, sha1_hash) + relative_path = scrubbed_path path + site_file = site_files_dataset.where(path: relative_path, sha1_hash: sha1_hash).first + !site_file.nil? + end + private def store_file(path, uploaded, opts={}) diff --git a/tests/api_tests.rb b/tests/api_tests.rb index 5e894c11..30e2d97c 100644 --- a/tests/api_tests.rb +++ b/tests/api_tests.rb @@ -222,6 +222,39 @@ describe 'api key' do end end +describe 'api upload hash' do + it 'succeeds' do + create_site + basic_authorize @user, @pass + test_hash = Digest::SHA1.file('./tests/files/test.jpg').hexdigest + + post '/api/upload', { + 'test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg'), + 'test2.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg') + } + + post '/api/upload_hash', "files[test.jpg]" => test_hash, "files[test2.jpg]" => Digest::SHA1.hexdigest('herpderp') + + res[:result].must_equal 'success' + res[:files][:'test.jpg'].must_equal true + res[:files][:'test2.jpg'].must_equal false + end + + it 'throws error for missing data' do + create_site + basic_authorize @user, @pass + post '/api/upload_hash' + res[:error_type].must_equal 'no_file_hashes_provided' + end + + it 'throws errors for weird data' do + create_site + basic_authorize @user, @pass + post '/api/upload_hash', 'files[]' => 'DUMPSTER FIRE' + res[:error_type].must_equal 'no_file_hashes_provided' + end +end + describe 'api upload' do it 'fails with no auth' do post '/api/upload'