require 'faraday' require 'base64' require 'openssl' require 'digest' class AzureBlobService CONNECTION_STRING = Rails.application.credentials.azure_storage_connection_string STORAGE_ACCOUNT = CONNECTION_STRING.match(/AccountName=(.*?);/)[1] ACCESS_KEY = CONNECTION_STRING.match(/AccountKey=(.*?);/)[1] def initialize(container) @container = container end def list_blobs date = Time.now.httpdate resource = "/#{STORAGE_ACCOUNT}/#{@container}\ncomp:list\nrestype:container" url = "https://#{STORAGE_ACCOUNT}.blob.core.windows.net/#{@container}?restype=container&comp=list" headers = { 'x-ms-date' => date, 'x-ms-version' => '2018-03-28', 'Authorization' => generate_auth_header('GET', date, resource) } connection = Faraday.new(url: url) response = connection.get do |req| headers.each do |key, value| req.headers[key] = value end end response.body end def get_blob(path) date = Time.now.httpdate resource = "/#{STORAGE_ACCOUNT}/#{@container}/#{path}" url = "https://#{STORAGE_ACCOUNT}.blob.core.windows.net/#{@container}/#{path}" headers = { 'x-ms-date' => date, 'x-ms-version' => '2018-03-28', 'Authorization' => generate_auth_header('GET', date, resource) } connection = Faraday.new(url: url) response = connection.get do |req| headers.each do |key, value| req.headers[key] = value end end response.body end private def generate_auth_header(http_method, date, resource) signature_string = "#{http_method}\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:#{date}\nx-ms-version:2018-03-28\n#{resource}" hash = OpenSSL::HMAC.digest('sha256', Base64.decode64(ACCESS_KEY), signature_string) signature = Base64.encode64(hash) auth_header = "SharedKey #{STORAGE_ACCOUNT}:#{signature}".strip return auth_header end end