diff --git a/lib/fog/hp/models/storage/file.rb b/lib/fog/hp/models/storage/file.rb index 573a8b48c..b1f4067d9 100644 --- a/lib/fog/hp/models/storage/file.rb +++ b/lib/fog/hp/models/storage/file.rb @@ -70,6 +70,11 @@ module Fog self.collection.get_cdn_ssl_url(self.key) end + def temp_signed_url(expires_secs, method) + requires :directory, :key + connection.get_object_temp_url(directory.key, key, expires_secs, method) + end + def save(options = {}) requires :body, :directory, :key options['Content-Type'] = content_type if content_type diff --git a/lib/fog/hp/requests/storage/get_object_temp_url.rb b/lib/fog/hp/requests/storage/get_object_temp_url.rb new file mode 100644 index 000000000..019f6c298 --- /dev/null +++ b/lib/fog/hp/requests/storage/get_object_temp_url.rb @@ -0,0 +1,31 @@ +module Fog + module Storage + class HP + + class Real + + # Generate a temporary url for an object + # + # ==== Parameters + # * container<~String> - Name of container + # * object<~String> - Name of object + # * expires<~Integer> - Time the temporary url expire in secs. + # * method<~String> - Allowed HTTP method GET, PUT, HEAD only + def get_object_temp_url(container, object, expires, method) + generate_object_temp_url(container, object, expires, method) + end + + end + + class Mock # :nodoc:all + + def get_object_temp_url(container, object, expires, method) + @hp_storage_uri = "https://swift-cluster.example.com:443/v1/account" + + generate_object_temp_url(container, object, expires, method) + end + end + + end + end +end \ No newline at end of file diff --git a/lib/fog/hp/storage.rb b/lib/fog/hp/storage.rb index 21fd3e8e6..8ba015aad 100644 --- a/lib/fog/hp/storage.rb +++ b/lib/fog/hp/storage.rb @@ -20,6 +20,7 @@ module Fog request :get_container request :get_containers request :get_object + request :get_object_temp_url request :head_container request :head_containers request :head_object @@ -81,6 +82,39 @@ module Fog acl = "public-read-write" end end + + def generate_object_temp_url(container, object, expires_secs, method) + return unless (container && object && expires_secs && method) + + # POST not allowed + allowed_methods = %w{GET PUT HEAD} + unless allowed_methods.include?(method) + raise ArgumentError.new("Invalid method '#{method}' specified. Valid methods are: #{allowed_methods.join(', ')}") + end + + expires = (Time.now + expires_secs.to_i).to_i + + # split up the storage uri + uri = URI.parse(@hp_storage_uri) + host = uri.host + path = uri.path + port = uri.port + scheme = uri.scheme + + # do not encode before signature generation, encode after + sig_path = "#{path}/#{container}/#{object}" + encoded_path = "#{path}/#{Fog::HP.escape(container)}/#{Fog::HP.escape(object)}" + + string_to_sign = "#{method}\n#{expires}\n#{sig_path}" + signed_string = Digest::HMAC.hexdigest(string_to_sign, @hp_secret_key, Digest::SHA1) + + signature = @hp_tenant_id.to_s + ":" + @hp_account_id.to_s + ":" + signed_string + signature = Fog::HP.escape(signature) + + # generate the temp url using the signature and expiry + temp_url = "#{scheme}://#{host}:#{port}#{encoded_path}?temp_url_sig=#{signature}&temp_url_expires=#{expires}" + end + end class Mock @@ -109,6 +143,7 @@ module Fog require 'mime/types' @hp_secret_key = options[:hp_secret_key] @hp_account_id = options[:hp_account_id] + @hp_tenant_id = options[:hp_tenant_id] end def data diff --git a/tests/hp/models/storage/directories_tests.rb b/tests/hp/models/storage/directories_tests.rb new file mode 100644 index 000000000..f92c97766 --- /dev/null +++ b/tests/hp/models/storage/directories_tests.rb @@ -0,0 +1,17 @@ +Shindo.tests('Fog::Storage[:hp] | directories', ['hp', 'storage']) do + + collection_tests(Fog::Storage[:hp].directories, {:key => "fogdirtests"}, true) + + tests('success') do + + tests("#head('fogdirtests')").succeeds do + Fog::Storage[:hp].directories.head('fogdirtests') + end + + tests("#get('fogdirtests')").succeeds do + Fog::Storage[:hp].directories.get('fogdirtests') + end + + end + +end \ No newline at end of file diff --git a/tests/hp/models/storage/directory_tests.rb b/tests/hp/models/storage/directory_tests.rb new file mode 100644 index 000000000..3389db1ea --- /dev/null +++ b/tests/hp/models/storage/directory_tests.rb @@ -0,0 +1,50 @@ +Shindo.tests('Fog::Storage[:hp] | directory', ['hp', 'storage']) do + + model_tests(Fog::Storage[:hp].directories, {:key => "fogdirtests"}, true) do + + tests('success') do + + tests("#acl='public-read'").succeeds do + @instance.acl = 'public-read' + tests("public?").returns(true) do + @instance.public? + end + end + + @instance.files.create(:key => 'sample.txt', :body => lorem_file) + tests("#files").succeeds do + @instance.files + end + @instance.files.get('sample.txt').destroy + + tests("#cdn_enable=(true)").succeeds do + @instance.cdn_enable=(true) + tests("cdn_enabled?").returns(true) do + pending if Fog.mocking? + @instance.cdn_enable? + end + end + + tests("#cdn_public_url").succeeds do + pending if Fog.mocking? + @instance.cdn_public_url + end + + tests("#cdn_public_ssl_url").succeeds do + pending if Fog.mocking? + @instance.cdn_public_ssl_url + end + + end + + tests('failure') do + + tests("#acl='invalid-acl'").raises(ArgumentError) do + @instance.acl = 'invalid-acl' + end + + end + + end + +end diff --git a/tests/hp/models/storage/file_tests.rb b/tests/hp/models/storage/file_tests.rb new file mode 100644 index 000000000..47a2211da --- /dev/null +++ b/tests/hp/models/storage/file_tests.rb @@ -0,0 +1,44 @@ +Shindo.tests('Fog::Storage[:hp] | directory', ['hp', 'storage']) do + + file_attributes = { + :key => 'fog_file_tests', + :body => lorem_file, + :public => true + } + + directory_attributes = { + :key => 'fogfilestests' + } + + @directory = Fog::Storage[:hp].directories.create(directory_attributes) + + model_tests(@directory.files, file_attributes, true) do + + @file = @directory.files.get('fog_file_tests') + + tests('success') do + + tests("#directory").returns(@directory.key) do + @file.directory.key + end + + tests("#cdn_public_url").succeeds do + pending if Fog.mocking? + @file.cdn_public_url + end + + tests("#cdn_public_ssl_url").succeeds do + pending if Fog.mocking? + @file.cdn_public_ssl_url + end + + tests("#temp_signed_url(60, 'GET')").succeeds do + @file.temp_signed_url(60, 'GET') + end + + end + end + + @directory.destroy + +end \ No newline at end of file diff --git a/tests/hp/models/storage/files_tests.rb b/tests/hp/models/storage/files_tests.rb new file mode 100644 index 000000000..4a12d1cc5 --- /dev/null +++ b/tests/hp/models/storage/files_tests.rb @@ -0,0 +1,42 @@ +Shindo.tests('Fog::Storage[:hp] | files', ['hp', 'storage']) do + + file_attributes = { + :key => 'fog_files_tests', + :body => lorem_file + } + + directory_attributes = { + :key => 'fogfilestests' + } + + @directory = Fog::Storage[:hp].directories.create(directory_attributes) + + collection_tests(@directory.files, file_attributes, true) do + + tests('success') do + + tests("#get_url('#{@directory.key}')").succeeds do + @directory.files.get_url("#{@directory.key}") + end + + tests("#get_cdn_url('#{@directory.key}')").succeeds do + pending if Fog.mocking? + @directory.files.get_cdn_url("#{@directory.key}") + end + + tests("#get_cdn_ssl_url('#{@directory.key}')").succeeds do + pending if Fog.mocking? + @directory.files.get_cdn_ssl_url("#{@directory.key}") + end + + tests("#head('#{@directory.key}')").succeeds do + @directory.files.head("#{@directory.key}") + end + + end + + end + + @directory.destroy + +end \ No newline at end of file diff --git a/tests/hp/requests/storage/object_tests.rb b/tests/hp/requests/storage/object_tests.rb index c228f9180..dca0098c6 100644 --- a/tests/hp/requests/storage/object_tests.rb +++ b/tests/hp/requests/storage/object_tests.rb @@ -1,4 +1,4 @@ -Shindo.tests('Fog::Storage[:hp] | object requests', [:hp]) do +Shindo.tests('Fog::Storage[:hp] | object requests', ['hp', 'storage']) do @directory = Fog::Storage[:hp].directories.create(:key => 'fogobjecttests') @dir_name = @directory.identity @@ -25,6 +25,10 @@ Shindo.tests('Fog::Storage[:hp] | object requests', [:hp]) do Fog::Storage[:hp].head_object(@dir_name, 'fog_object') end + tests("#get_object_temp_url('#{@dir_name}', 'fog_object', 60, 'GET')").succeeds do + Fog::Storage[:hp].get_object_temp_url(@dir_name, 'fog_object', 60, 'GET') + end + # copy a file within the same container tests("#put_object('#{@dir_name}', 'fog_other_object', nil, {'X-Copy-From' => '/#{@dir_name}/fog_object'})" ).succeeds do Fog::Storage[:hp].put_object(@dir_name, 'fog_other_object', nil, {'X-Copy-From' => "/#{@dir_name}/fog_object"}) @@ -58,6 +62,10 @@ Shindo.tests('Fog::Storage[:hp] | object requests', [:hp]) do Fog::Storage[:hp].get_object('fognoncontainer', 'fog_non_object') end + tests("#get_object_temp_url('#{@dir_name}', 'fog_object', 60, 'POST')").raises(ArgumentError) do + Fog::Storage[:hp].get_object_temp_url(@dir_name, 'fog_object', 60, 'POST') + end + tests("#head_object('#{@dir_name}', 'fog_non_object')").raises(Fog::Storage::HP::NotFound) do Fog::Storage[:hp].head_object(@dir_name, 'fog_non_object') end