azure-blob 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c6c4e076840dd6671c28c99b5fca03057782e81686c0c06890b42cedd3b83788
4
- data.tar.gz: '00668582cecce526ad816a5c537469af7e646d6f64d7392655d1c7e60396393c'
3
+ metadata.gz: 15d8cb5bf91f904bff341c26f5f6b6392abbb14e0de1f092fab8697cabab75b1
4
+ data.tar.gz: de847a4e6a9925b31ed1900dea10e8e0d078277f4af4e4e7f434b00e4e0bc298
5
5
  SHA512:
6
- metadata.gz: fdd32b7f8547ac428bf0eb19d884860e94d1ab9471df0022356119c5ec28aca8589d1b1925d0085b2361c4c16d5898123a1fc18f57b5b2cb9ae7e53dbc4b4379
7
- data.tar.gz: 44a4592046d5d33432762cfd4d3636500f9c13db00cf5c705fbc2f472b7c322bd37bc05d9765e03079e0966dcb44d0e5cc844db303906aaa18435c8db7ee422f
6
+ metadata.gz: ef60c4be02b9725ba53209234d471a71451fe7270a58c4fad908c5e06669cb686290cd7ce75e57dfced02fc1d1efee85e3201d0d05b868881abe16e13fb77e68
7
+ data.tar.gz: 1460b8c46b849b0e1a89e2e628cf20dad0ba223dc3e090e7f8ce3bc16d124db497f0785144eed3a8c48210e2d085bb4c178f74d9ff18c77da98ce21d65f6af45
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.5.4] 2024-11-18
4
+
5
+ - Allow creating public container
6
+ - Add Azurite support
3
7
 
4
8
  ## [0.5.3] 2024-10-31
5
9
 
data/README.md CHANGED
@@ -46,6 +46,30 @@ prod:
46
46
  principal_id: 71b34410-4c50-451d-b456-95ead1b18cce
47
47
  ```
48
48
 
49
+ ### Azurite
50
+
51
+ To use Azurite, pass the `storage_blob_host` config key with the Azurite URL (`http://127.0.0.1:10000/devstoreaccount1` by default)
52
+ and the Azurite credentials (`devstoreaccount1` and `Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==` by default).
53
+
54
+ Example:
55
+
56
+ ```
57
+ dev:
58
+ service: AzureBlob
59
+ container: container_name
60
+ storage_account_name: devstoreaccount1
61
+ storage_access_key: "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="
62
+ storage_blob_host: http://127.0.0.1:10000/devstoreaccount1
63
+ ```
64
+
65
+ You'll have to create the container before you can start uploading files.
66
+ You can do so using Azure CLI, Azure Storage Explorer, or by running:
67
+
68
+ `bin/rails runner "ActiveStorage::Blob.service.client.tap{|client| client.create_container unless client.get_container_properties.present?}.tap { |client| puts 'done!' if client.get_container_properties.present?}"`
69
+
70
+ Make sure that `config.active_storage.service = :dev` is set to your azurite configuration.
71
+ Container names can't have any special characters, or you'll get an error.
72
+
49
73
  ## Standalone
50
74
 
51
75
  Instantiate a client with your account name, an access key and the container name:
data/Rakefile CHANGED
@@ -5,6 +5,7 @@ require "minitest/test_task"
5
5
  require "azure_blob"
6
6
  require_relative "test/support/app_service_vpn"
7
7
  require_relative "test/support/azure_vm_vpn"
8
+ require_relative "test/support/azurite"
8
9
 
9
10
  Minitest::TestTask.create(:test_rails) do
10
11
  self.test_globs = [ "test/rails/**/test_*.rb",
@@ -39,6 +40,28 @@ ensure
39
40
  vpn.kill
40
41
  end
41
42
 
43
+ task :test_azurite do |t|
44
+ azurite = Azurite.new
45
+ # Azurite well-known credentials
46
+ # https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite?tabs=visual-studio%2Cblob-storage#well-known-storage-account-and-key
47
+ account_name = ENV["AZURE_ACCOUNT_NAME"] = "devstoreaccount1"
48
+ access_key = ENV["AZURE_ACCESS_KEY"] = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="
49
+ host = ENV["STORAGE_BLOB_HOST"] = "http://127.0.0.1:10000/devstoreaccount1"
50
+ ENV["TESTING_AZURITE"] = "true"
51
+
52
+ # Create containers
53
+ private_container = AzureBlob::Client.new(account_name:, access_key:, host:, container: ENV["AZURE_PRIVATE_CONTAINER"])
54
+ public_container = AzureBlob::Client.new(account_name:, access_key:, host:, container: ENV["AZURE_PUBLIC_CONTAINER"])
55
+ # public_container.delete_container
56
+ private_container.create_container unless private_container.get_container_properties.present?
57
+ public_container.create_container(public_access: true) unless public_container.get_container_properties.present?
58
+
59
+ Rake::Task["test_client"].execute
60
+ Rake::Task["test_rails"].execute
61
+ ensure
62
+ azurite.kill
63
+ end
64
+
42
65
  task :test_entra_id do |t|
43
66
  ENV["AZURE_ACCESS_KEY"] = nil
44
67
  Rake::Task["test"].execute
@@ -35,13 +35,14 @@ module ActiveStorage
35
35
  class Service::AzureBlobService < Service
36
36
  attr_reader :client, :container, :signer
37
37
 
38
- def initialize(storage_account_name:, storage_access_key: nil, container:, public: false, **options)
38
+ def initialize(storage_account_name:, storage_access_key: nil, container:, storage_blob_host: nil, public: false, **options)
39
39
  @container = container
40
40
  @public = public
41
41
  @client = AzureBlob::Client.new(
42
42
  account_name: storage_account_name,
43
43
  access_key: storage_access_key,
44
44
  container: container,
45
+ host: storage_blob_host,
45
46
  **options)
46
47
  end
47
48
 
@@ -15,9 +15,10 @@ module AzureBlob
15
15
  # AzureBlob Client class. You interact with the Azure Blob api
16
16
  # through an instance of this class.
17
17
  class Client
18
- def initialize(account_name:, access_key: nil, principal_id: nil, container:, **options)
18
+ def initialize(account_name:, access_key: nil, principal_id: nil, container:, host: nil, **options)
19
19
  @account_name = account_name
20
20
  @container = container
21
+ @host = host
21
22
  @cloud_regions = options[:cloud_regions]&.to_sym || :global
22
23
 
23
24
  no_access_key = access_key.nil? || access_key&.empty?
@@ -29,8 +30,8 @@ module AzureBlob
29
30
  )
30
31
  end
31
32
  @signer = using_managed_identities ?
32
- AzureBlob::EntraIdSigner.new(account_name:, host:, principal_id:) :
33
- AzureBlob::SharedKeySigner.new(account_name:, access_key:)
33
+ AzureBlob::EntraIdSigner.new(account_name:, host: self.host, principal_id:) :
34
+ AzureBlob::SharedKeySigner.new(account_name:, access_key:, host: self.host)
34
35
  end
35
36
 
36
37
  # Create a blob of type block. Will automatically split the the blob in multiple block and send the blob in pieces (blocks) if the blob is too big.
@@ -190,8 +191,12 @@ module AzureBlob
190
191
  # Calls to {Create Container}[https://learn.microsoft.com/en-us/rest/api/storageservices/create-container]
191
192
  def create_container(options = {})
192
193
  uri = generate_uri(container)
194
+ headers = {}
195
+ headers[:"x-ms-blob-public-access"] = "blob" if options[:public_access]
196
+ headers[:"x-ms-blob-public-access"] = options[:public_access] if ["container","blob"].include?(options[:public_access])
197
+
193
198
  uri.query = URI.encode_www_form(restype: "container")
194
- response = Http.new(uri, signer:).put
199
+ response = Http.new(uri, headers, signer:).put
195
200
  end
196
201
 
197
202
  # Delete the container
@@ -7,9 +7,11 @@ require_relative "canonicalized_resource"
7
7
 
8
8
  module AzureBlob
9
9
  class SharedKeySigner # :nodoc:
10
- def initialize(account_name:, access_key:)
10
+ def initialize(account_name:, access_key:, host:)
11
11
  @account_name = account_name
12
12
  @access_key = Base64.decode64(access_key)
13
+ @host = host
14
+ @remove_prefix = @host.include?("/#{@account_name}")
13
15
  end
14
16
 
15
17
  def authorization_header(uri:, verb:, headers: {})
@@ -39,6 +41,11 @@ module AzureBlob
39
41
  end
40
42
 
41
43
  def sas_token(uri, options = {})
44
+ if remove_prefix
45
+ uri = uri.clone
46
+ uri.path = uri.path.delete_prefix("/#{account_name}")
47
+ end
48
+
42
49
  to_sign = [
43
50
  options[:permissions],
44
51
  options[:start],
@@ -99,6 +106,6 @@ module AzureBlob
99
106
  end
100
107
  end
101
108
 
102
- attr_reader :access_key, :account_name
109
+ attr_reader :access_key, :account_name, :remove_prefix
103
110
  end
104
111
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AzureBlob
4
- VERSION = "0.5.3"
4
+ VERSION = "0.5.4"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: azure-blob
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joé Dupuis