Ability to delete files from Cellar
This commit is contained in:
parent
741100d4f5
commit
76c72bf4e0
2 changed files with 44 additions and 13 deletions
|
@ -1,6 +1,6 @@
|
||||||
require 'base64'
|
require 'base64'
|
||||||
|
require 'net/http'
|
||||||
require 'openssl'
|
require 'openssl'
|
||||||
require 'uri'
|
|
||||||
|
|
||||||
module ActiveStorage
|
module ActiveStorage
|
||||||
class Service::CellarService < Service
|
class Service::CellarService < Service
|
||||||
|
@ -11,6 +11,16 @@ module ActiveStorage
|
||||||
@bucket = bucket
|
@bucket = bucket
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def delete(key)
|
||||||
|
instrument :delete, key: key do
|
||||||
|
Net::HTTP.start(@endpoint.host, @endpoint.port, use_ssl: true) do |http|
|
||||||
|
request = Net::HTTP::Delete.new(URI::join(@endpoint, "/#{key}"))
|
||||||
|
sign(request, key)
|
||||||
|
http.request(request)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def url(key, expires_in:, filename:, disposition:, content_type:)
|
def url(key, expires_in:, filename:, disposition:, content_type:)
|
||||||
instrument :url, key: key do |payload|
|
instrument :url, key: key do |payload|
|
||||||
generated_url = presigned_url(
|
generated_url = presigned_url(
|
||||||
|
@ -45,6 +55,13 @@ module ActiveStorage
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def sign(request, key, checksum: '')
|
||||||
|
date = Time.now.httpdate
|
||||||
|
sig = signature(method: request.method, key: key, date: date, checksum: checksum)
|
||||||
|
request['date'] = date
|
||||||
|
request['authorization'] = "AWS #{@access_key_id}:#{sig}"
|
||||||
|
end
|
||||||
|
|
||||||
def presigned_url(method:, key:, expires_in:, content_type: '', checksum: '', **query_params)
|
def presigned_url(method:, key:, expires_in:, content_type: '', checksum: '', **query_params)
|
||||||
expires = expires_in.from_now.to_i
|
expires = expires_in.from_now.to_i
|
||||||
|
|
||||||
|
@ -57,10 +74,10 @@ module ActiveStorage
|
||||||
generated_url = URI::join(@endpoint, "/#{key}","?#{query.to_query}").to_s
|
generated_url = URI::join(@endpoint, "/#{key}","?#{query.to_query}").to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
def signature(method:, key:, expires:, content_type: '', checksum: '')
|
def signature(method:, key:, expires: '', date: '', content_type: '', checksum: '')
|
||||||
canonicalized_amz_headers = ""
|
canonicalized_amz_headers = ""
|
||||||
canonicalized_resource = "/#{@bucket}/#{key}"
|
canonicalized_resource = "/#{@bucket}/#{key}"
|
||||||
string_to_sign = "#{method}\n#{checksum}\n#{content_type}\n#{expires}\n" +
|
string_to_sign = "#{method}\n#{checksum}\n#{content_type}\n#{expires}#{date}\n" +
|
||||||
"#{canonicalized_amz_headers}#{canonicalized_resource}"
|
"#{canonicalized_amz_headers}#{canonicalized_resource}"
|
||||||
Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha1'), @secret_access_key, string_to_sign)).strip
|
Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha1'), @secret_access_key, string_to_sign)).strip
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
require 'active_storage/service/cellar_service'
|
require 'active_storage/service/cellar_service'
|
||||||
require 'cgi'
|
require 'cgi'
|
||||||
|
require 'net/http'
|
||||||
require 'uri'
|
require 'uri'
|
||||||
|
|
||||||
describe 'CellarService' do
|
describe 'CellarService' do
|
||||||
|
@ -19,11 +20,12 @@ describe 'CellarService' do
|
||||||
after { Timecop.return }
|
after { Timecop.return }
|
||||||
|
|
||||||
describe 'signature generation' do
|
describe 'signature generation' do
|
||||||
|
context 'for presigned URLs' do
|
||||||
subject do
|
subject do
|
||||||
cellar_service.send(
|
cellar_service.send(
|
||||||
:signature,
|
:signature,
|
||||||
{
|
{
|
||||||
http_verb: 'GET',
|
method: 'GET',
|
||||||
key: 'fichier',
|
key: 'fichier',
|
||||||
expires: 5.minutes.from_now.to_i
|
expires: 5.minutes.from_now.to_i
|
||||||
}
|
}
|
||||||
|
@ -33,6 +35,18 @@ describe 'CellarService' do
|
||||||
it { is_expected.to eq('nzCsB6cip8oofkuOdvvJs6FafkA=') }
|
it { is_expected.to eq('nzCsB6cip8oofkuOdvvJs6FafkA=') }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'for server-side requests' do
|
||||||
|
subject do
|
||||||
|
Net::HTTP::Delete.new('https://rogets.cellar.services.clever-cloud.com/fichier')
|
||||||
|
end
|
||||||
|
|
||||||
|
before { cellar_service.send(:sign, subject, 'fichier') }
|
||||||
|
|
||||||
|
it { expect(subject['date']).to eq(Time.now.httpdate) }
|
||||||
|
it { expect(subject['authorization']).to eq('AWS AKIAJFTRSGRH3RXX6D5Q:nkvviwZYb1V9HDrKyJZmY3Z8sSA=') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'presigned url for download' do
|
describe 'presigned url for download' do
|
||||||
subject do
|
subject do
|
||||||
URI.parse(
|
URI.parse(
|
||||||
|
|
Loading…
Reference in a new issue