azure-blob 0.5.3 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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