azure-storage-common 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/common/lib/azure/storage/common.rb +26 -0
  3. data/common/lib/azure/storage/common/autoload.rb +61 -0
  4. data/common/lib/azure/storage/common/client.rb +159 -0
  5. data/common/lib/azure/storage/common/client_options.rb +356 -0
  6. data/common/lib/azure/storage/common/client_options_error.rb +41 -0
  7. data/common/lib/azure/storage/common/configurable.rb +212 -0
  8. data/common/lib/azure/storage/common/core.rb +35 -0
  9. data/common/lib/azure/storage/common/core/auth/anonymous_signer.rb +43 -0
  10. data/common/lib/azure/storage/common/core/auth/shared_access_signature.rb +30 -0
  11. data/common/lib/azure/storage/common/core/auth/shared_access_signature_generator.rb +352 -0
  12. data/common/lib/azure/storage/common/core/auth/shared_access_signature_signer.rb +57 -0
  13. data/common/lib/azure/storage/common/core/auth/shared_key.rb +60 -0
  14. data/common/lib/azure/storage/common/core/autoload.rb +50 -0
  15. data/common/lib/azure/storage/common/core/error.rb +43 -0
  16. data/common/lib/azure/storage/common/core/filter/exponential_retry_filter.rb +64 -0
  17. data/common/lib/azure/storage/common/core/filter/linear_retry_filter.rb +55 -0
  18. data/common/lib/azure/storage/common/core/filter/retry_filter.rb +302 -0
  19. data/common/lib/azure/storage/common/core/http_client.rb +65 -0
  20. data/common/lib/azure/storage/common/core/sr.rb +85 -0
  21. data/common/lib/azure/storage/common/core/utility.rb +255 -0
  22. data/common/lib/azure/storage/common/default.rb +868 -0
  23. data/common/lib/azure/storage/common/service/access_policy.rb +37 -0
  24. data/common/lib/azure/storage/common/service/cors.rb +38 -0
  25. data/common/lib/azure/storage/common/service/cors_rule.rb +48 -0
  26. data/common/lib/azure/storage/common/service/enumeration_results.rb +32 -0
  27. data/common/lib/azure/storage/common/service/geo_replication.rb +40 -0
  28. data/common/lib/azure/storage/common/service/logging.rb +47 -0
  29. data/common/lib/azure/storage/common/service/metrics.rb +45 -0
  30. data/common/lib/azure/storage/common/service/retention_policy.rb +37 -0
  31. data/common/lib/azure/storage/common/service/serialization.rb +335 -0
  32. data/common/lib/azure/storage/common/service/signed_identifier.rb +40 -0
  33. data/common/lib/azure/storage/common/service/storage_service.rb +322 -0
  34. data/common/lib/azure/storage/common/service/storage_service_properties.rb +48 -0
  35. data/common/lib/azure/storage/common/service/storage_service_stats.rb +39 -0
  36. data/common/lib/azure/storage/common/version.rb +49 -0
  37. metadata +216 -0
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ #-------------------------------------------------------------------------
4
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
5
+ #
6
+ # The MIT License(MIT)
7
+
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files(the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions :
14
+
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #--------------------------------------------------------------------------
26
+
27
+ require "azure/storage/common/core"
28
+
29
+ module Azure::Storage::Common
30
+ class InvalidConnectionStringError < Core::StorageError
31
+ def initialize(message = Azure::Storage::Common::Core::SR::INVALID_CONNECTION_STRING)
32
+ super(message)
33
+ end
34
+ end
35
+
36
+ class InvalidOptionsError < Core::StorageError
37
+ def initialize(message = Azure::Storage::Common::Core::SR::INVALID_CLIENT_OPTIONS)
38
+ super(message)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,212 @@
1
+ # frozen_string_literal: true
2
+
3
+ #-------------------------------------------------------------------------
4
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
5
+ #
6
+ # The MIT License(MIT)
7
+
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files(the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions :
14
+
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #--------------------------------------------------------------------------
26
+
27
+ module Azure::Storage::Common
28
+ # The Azure::Storage::Common::Configurable module provides basic configuration for Azure storage activities.
29
+ module Configurable
30
+ # @!attribute [w] storage_access_key
31
+ # @return [String] Azure Storage access key.
32
+ # @!attribute storage_account_name
33
+ # @return [String] Azure Storage account name.
34
+ # @!attribute storage_connection_string
35
+ # @return [String] Azure Storage connection string.
36
+ # @!attribute storage_blob_host
37
+ # @return [String] Set the host for the Blob service. Only set this if you want
38
+ # something custom (like, for example, to point this to a LocalStorage
39
+ # emulator). This should be the complete host, including http:// at the
40
+ # start. When using the emulator, make sure to include your account name at
41
+ # the end.
42
+ # @!attribute storage_table_host
43
+ # @return [String] Set the host for the Table service. Only set this if you want
44
+ # something custom (like, for example, to point this to a LocalStorage
45
+ # emulator). This should be the complete host, including http:// at the
46
+ # start. When using the emulator, make sure to include your account name at
47
+ # the end.
48
+ # @!attribute storage_queue_host
49
+ # @return [String] Set the host for the Queue service. Only set this if you want
50
+ # something custom (like, for example, to point this to a LocalStorage
51
+ # emulator). This should be the complete host, including http:// at the
52
+ # start. When using the emulator, make sure to include your account name at
53
+ # the end.
54
+
55
+ attr_accessor :storage_access_key,
56
+ :storage_account_name,
57
+ :storage_connection_string,
58
+ :storage_sas_token
59
+
60
+ attr_writer :storage_table_host,
61
+ :storage_blob_host,
62
+ :storage_queue_host,
63
+ :storage_file_host,
64
+ :storage_table_host_secondary,
65
+ :storage_blob_host_secondary,
66
+ :storage_queue_host_secondary,
67
+ :storage_file_host_secondary
68
+
69
+ attr_reader :signer
70
+
71
+ class << self
72
+ # List of configurable keys for {Azure::Client}
73
+ # @return [Array] of option keys
74
+ def keys
75
+ @keys ||= [
76
+ :storage_access_key,
77
+ :storage_account_name,
78
+ :storage_connection_string,
79
+ :storage_sas_token,
80
+ :storage_table_host,
81
+ :storage_blob_host,
82
+ :storage_queue_host,
83
+ :storage_file_host,
84
+ :signer
85
+ ]
86
+ end
87
+ end
88
+
89
+ # Set configuration options using a block
90
+ def configure
91
+ yield self
92
+ end
93
+
94
+ def config
95
+ self
96
+ end
97
+
98
+ # Reset configuration options to default values
99
+ def reset_config!(options = {})
100
+ Azure::Storage::Common::Configurable.keys.each do |key|
101
+ value =
102
+ if self == Azure::Storage::Common
103
+ Azure::Storage::Common::Default.options[key]
104
+ else
105
+ self.send(key)
106
+ end
107
+ instance_variable_set(:"@#{key}", options.fetch(key, value))
108
+
109
+ # Set the secondary endpoint if the primary one is given
110
+ if key.to_s.include? "host"
111
+ instance_variable_set(:"@#{key}_secondary", secondary_endpoint(options.fetch(key, value)))
112
+ end
113
+ end
114
+ self.send(:reset_agents!) if self.respond_to?(:reset_agents!)
115
+ setup_signer_for_service(options[:api_version])
116
+ self
117
+ end
118
+
119
+ alias setup reset_config!
120
+
121
+ # Storage queue host
122
+ # @return [String]
123
+ def storage_queue_host(isSecondary = false)
124
+ if isSecondary
125
+ @storage_queue_host_secondary || default_host(:queue, true)
126
+ else
127
+ @storage_queue_host || default_host(:queue, false)
128
+ end
129
+ end
130
+
131
+ # Storage blob host
132
+ # @return [String]
133
+ def storage_blob_host(isSecondary = false)
134
+ if isSecondary
135
+ @storage_blob_host_secondary || default_host(:blob, true)
136
+ else
137
+ @storage_blob_host || default_host(:blob, false)
138
+ end
139
+ end
140
+
141
+ # Storage table host
142
+ # @return [String]
143
+ def storage_table_host(isSecondary = false)
144
+ if isSecondary
145
+ @storage_table_host_secondary || default_host(:table, true)
146
+ else
147
+ @storage_table_host || default_host(:table, false)
148
+ end
149
+ end
150
+
151
+ # Storage file host
152
+ # @return [String]
153
+ def storage_file_host(isSecondary = false)
154
+ if isSecondary
155
+ @storage_file_host_secondary || default_host(:file, true)
156
+ else
157
+ @storage_file_host || default_host(:file, false)
158
+ end
159
+ end
160
+
161
+ private
162
+
163
+ def default_host(service, isSecondary = false)
164
+ "https://#{storage_account_name}#{isSecondary ? "-secondary" : ""}.#{service}.core.windows.net" if storage_account_name
165
+ end
166
+
167
+ def setup_options
168
+ opts = {}
169
+ Azure::Storage::Common::Configurable.keys.map do |key|
170
+ opts[key] = self.send(key) if self.send(key)
171
+ end
172
+ opts
173
+ end
174
+
175
+ def account_name_from_endpoint(endpoint)
176
+ return nil if endpoint.nil?
177
+ uri = URI::parse endpoint
178
+ fields = uri.host.split "."
179
+ fields[0]
180
+ end
181
+
182
+ def secondary_endpoint(primary_endpoint)
183
+ return nil if primary_endpoint.nil?
184
+ account_name = account_name_from_endpoint primary_endpoint
185
+ primary_endpoint.sub account_name, account_name + "-secondary"
186
+ end
187
+
188
+ def determine_account_name
189
+ if instance_variable_get(:@storage_account_name).nil?
190
+ hosts = [@storage_blob_host, @storage_table_host, @storage_queue_host, @storage_file_host]
191
+ account_name = nil;
192
+ hosts.each do |host|
193
+ parsed = account_name_from_endpoint host
194
+ if account_name.nil?
195
+ account_name = parsed
196
+ elsif !account_name.nil? && !parsed.nil? && (account_name <=> parsed) != (0)
197
+ raise InvalidOptionsError, "Ambiguous account name in service hosts."
198
+ end
199
+ end
200
+ raise InvalidOptionsError, "Cannot identify account name." if account_name.nil?
201
+ @storage_account_name = account_name
202
+ end
203
+ end
204
+
205
+ def setup_signer_for_service(api_ver)
206
+ if @storage_sas_token
207
+ determine_account_name
208
+ @signer = Azure::Storage::Common::Core::Auth::SharedAccessSignatureSigner.new api_ver, @storage_account_name, @storage_sas_token
209
+ end
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ #-------------------------------------------------------------------------
4
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
5
+ #
6
+ # The MIT License(MIT)
7
+
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files(the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions :
14
+
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #--------------------------------------------------------------------------
26
+
27
+ module Azure
28
+ module Storage
29
+ end
30
+ end
31
+
32
+ require "azure/storage/common/core/error"
33
+ require "azure/storage/common/default"
34
+ require "azure/storage/common/core/sr"
35
+ require "azure/storage/common/core/utility"
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ #-------------------------------------------------------------------------
4
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
5
+ #
6
+ # The MIT License(MIT)
7
+
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files(the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions :
14
+
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #--------------------------------------------------------------------------
26
+
27
+ require "base64"
28
+
29
+ module Azure::Storage::Common::Core
30
+ module Auth
31
+ class AnonymousSigner < Azure::Core::Auth::Signer
32
+ # Public: Initialize the Anonymous Signer
33
+ def initialize()
34
+ # Use mock key to initialize super class
35
+ super(Base64.strict_encode64("accesskey"))
36
+ end
37
+
38
+ def sign_request(req)
39
+ # Do nothing.
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ #-------------------------------------------------------------------------
4
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
5
+ #
6
+ # The MIT License(MIT)
7
+
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files(the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions :
14
+
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #--------------------------------------------------------------------------
26
+
27
+ require "azure/storage/common/core/auth/shared_access_signature_generator"
28
+ require "azure/storage/common/core/auth/shared_access_signature_signer"
29
+
30
+ include Azure::Storage::Common::Core::Auth
@@ -0,0 +1,352 @@
1
+ # frozen_string_literal: true
2
+
3
+ #-------------------------------------------------------------------------
4
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
5
+ #
6
+ # The MIT License(MIT)
7
+
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files(the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions :
14
+
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #--------------------------------------------------------------------------
26
+
27
+ require "azure/storage/common/core"
28
+ require "azure/storage/common/client_options_error"
29
+ require "azure/core/auth/signer"
30
+ require "time"
31
+ require "uri"
32
+
33
+ # @see https://msdn.microsoft.com/library/azure/dn140255.aspx for more information on construction
34
+ module Azure::Storage::Common::Core
35
+ module Auth
36
+ class SharedAccessSignature
37
+ DEFAULTS = {
38
+ permissions: "r",
39
+ version: Azure::Storage::Common::Default::STG_VERSION
40
+ }
41
+
42
+ SERVICE_TYPE_MAPPING = {
43
+ b: Azure::Storage::Common::ServiceType::BLOB,
44
+ t: Azure::Storage::Common::ServiceType::TABLE,
45
+ q: Azure::Storage::Common::ServiceType::QUEUE,
46
+ f: Azure::Storage::Common::ServiceType::FILE
47
+ }
48
+
49
+ ACCOUNT_KEY_MAPPINGS = {
50
+ version: :sv,
51
+ service: :ss,
52
+ resource: :srt,
53
+ permissions: :sp,
54
+ start: :st,
55
+ expiry: :se,
56
+ protocol: :spr,
57
+ ip_range: :sip
58
+ }
59
+
60
+ SERVICE_KEY_MAPPINGS = {
61
+ version: :sv,
62
+ permissions: :sp,
63
+ start: :st,
64
+ expiry: :se,
65
+ identifier: :si,
66
+ protocol: :spr,
67
+ ip_range: :sip
68
+ }
69
+
70
+ BLOB_KEY_MAPPINGS = {
71
+ resource: :sr,
72
+ cache_control: :rscc,
73
+ content_disposition: :rscd,
74
+ content_encoding: :rsce,
75
+ content_language: :rscl,
76
+ content_type: :rsct
77
+ }
78
+
79
+ TABLE_KEY_MAPPINGS = {
80
+ table_name: :tn,
81
+ startpk: :spk,
82
+ endpk: :epk,
83
+ startrk: :srk,
84
+ endrk: :erk
85
+ }
86
+
87
+ FILE_KEY_MAPPINGS = {
88
+ resource: :sr,
89
+ cache_control: :rscc,
90
+ content_disposition: :rscd,
91
+ content_encoding: :rsce,
92
+ content_language: :rscl,
93
+ content_type: :rsct
94
+ }
95
+
96
+ SERVICE_OPTIONAL_QUERY_PARAMS = [:sp, :si, :sip, :spr, :rscc, :rscd, :rsce, :rscl, :rsct, :spk, :srk, :epk, :erk]
97
+
98
+ ACCOUNT_OPTIONAL_QUERY_PARAMS = [:st, :sip, :spr]
99
+
100
+ attr :account_name
101
+
102
+ # Public: Initialize the SharedAccessSignature generator
103
+ #
104
+ # @param account_name [String] The account name. Defaults to the one in the global configuration.
105
+ # @param access_key [String] The access_key encoded in Base64. Defaults to the one in the global configuration.
106
+ def initialize(account_name = "", access_key = "")
107
+ if account_name.empty? || access_key.empty?
108
+ client = Azure::Storage::Common::Client.create_from_env
109
+ account_name = client.storage_account_name if account_name.empty?
110
+ access_key = client.storage_access_key if access_key.empty?
111
+ end
112
+ @account_name = account_name
113
+ @signer = Azure::Core::Auth::Signer.new(access_key)
114
+ end
115
+
116
+ # Service Shared Access Signature Token for the given path and options
117
+ # @param path [String] Path of the URI or the table name
118
+ # @param options [Hash]
119
+ #
120
+ # ==== Options
121
+ #
122
+ # * +:service+ - String. Required. Service type. 'b' (blob) or 'q' (queue) or 't' (table) or 'f' (file).
123
+ # * +:resource+ - String. Required. Resource type, 'b' (blob) or 'c' (container) or 'f' (file) or 's' (share).
124
+ # * +:permissions+ - String. Optional. Combination of 'r', 'a', 'c', w','d','l' in this order for a container.
125
+ # Combination of 'r', 'a', 'c', 'w', 'd' in this order for a blob.
126
+ # Combination of 'r', 'c', 'w', 'd', 'l' in this order for a share.
127
+ # Combination of 'r', 'c', 'w', 'd' in this order for a file.
128
+ # Combination of 'r', 'a', 'u', 'p' in this order for a queue.
129
+ # Combination of 'r', 'a', 'u', 'd' in this order for a table.
130
+ # This option must be omitted if it has been specified in an associated stored access policy.
131
+ # * +:start+ - String. Optional. UTC Date/Time in ISO8601 format.
132
+ # * +:expiry+ - String. Optional. UTC Date/Time in ISO8601 format. Default now + 30 minutes.
133
+ # * +:identifier+ - String. Optional. Identifier for stored access policy.
134
+ # * +:protocol+ - String. Optional. Permitted protocols.
135
+ # * +:ip_range+ - String. Optional. An IP address or a range of IP addresses from which to accept requests.
136
+ #
137
+ # Below options for blob serivce only
138
+ # * +:cache_control+ - String. Optional. Response header override.
139
+ # * +:content_disposition+ - String. Optional. Response header override.
140
+ # * +:content_encoding+ - String. Optional. Response header override.
141
+ # * +:content_language+ - String. Optional. Response header override.
142
+ # * +:content_type+ - String. Optional. Response header override.
143
+ #
144
+ # Below options for table service only
145
+ # * +:startpk+ - String. Optional but must accompany startrk. The start partition key of a specified partition key range.
146
+ # * +:endpk+ - String. Optional but must accompany endrk. The end partition key of a specified partition key range.
147
+ # * +:startrk+ - String. Optional. The start row key of a specified row key range.
148
+ # * +:endrk+ - String. Optional. The end row key of a specified row key range.
149
+ def generate_service_sas_token(path, options = {})
150
+ if options.key?(:service)
151
+ service_type = SERVICE_TYPE_MAPPING[options[:service].to_sym]
152
+ options.delete(:service)
153
+ end
154
+
155
+ raise Azure::Storage::Common::InvalidOptionsError, "SAS version cannot be set" if options[:version]
156
+
157
+ options = DEFAULTS.merge(options)
158
+ valid_mappings = SERVICE_KEY_MAPPINGS
159
+ if service_type == Azure::Storage::Common::ServiceType::BLOB
160
+ if options[:resource]
161
+ options.merge!(resource: options[:resource])
162
+ else
163
+ options.merge!(resource: "b")
164
+ end
165
+ valid_mappings.merge!(BLOB_KEY_MAPPINGS)
166
+ elsif service_type == Azure::Storage::Common::ServiceType::TABLE
167
+ options.merge!(table_name: path)
168
+ valid_mappings.merge!(TABLE_KEY_MAPPINGS)
169
+ elsif service_type == Azure::Storage::Common::ServiceType::FILE
170
+ if options[:resource]
171
+ options.merge!(resource: options[:resource])
172
+ else
173
+ options.merge!(resource: "f")
174
+ end
175
+ valid_mappings.merge!(FILE_KEY_MAPPINGS)
176
+ end
177
+
178
+ invalid_options = options.reject { |k, _| valid_mappings.key?(k) }
179
+ raise Azure::Storage::Common::InvalidOptionsError, "invalid options #{invalid_options} provided for SAS token generate" if invalid_options.length > 0
180
+
181
+ canonicalize_time(options)
182
+
183
+ query_hash = Hash[options.map { |k, v| [SERVICE_KEY_MAPPINGS[k], v] }]
184
+ .reject { |k, v| SERVICE_OPTIONAL_QUERY_PARAMS.include?(k) && v.to_s == "" }
185
+ .merge(sig: @signer.sign(signable_string_for_service(service_type, path, options)))
186
+
187
+ URI.encode_www_form(query_hash)
188
+ end
189
+
190
+ # Construct the plaintext to the spec required for signatures
191
+ # @return [String]
192
+ def signable_string_for_service(service_type, path, options)
193
+ # Order is significant
194
+ # The newlines from empty strings here are required
195
+ signable_fields =
196
+ [
197
+ options[:permissions],
198
+ options[:start],
199
+ options[:expiry],
200
+ canonicalized_resource(service_type, path),
201
+ options[:identifier],
202
+ options[:ip_range],
203
+ options[:protocol],
204
+ Azure::Storage::Common::Default::STG_VERSION
205
+ ]
206
+
207
+ signable_fields.concat [
208
+ options[:cache_control],
209
+ options[:content_disposition],
210
+ options[:content_encoding],
211
+ options[:content_language],
212
+ options[:content_type]
213
+ ] if service_type == Azure::Storage::Common::ServiceType::BLOB || service_type == Azure::Storage::Common::ServiceType::FILE
214
+
215
+ signable_fields.concat [
216
+ options[:startpk],
217
+ options[:startrk],
218
+ options[:endpk],
219
+ options[:endrk]
220
+ ] if service_type == Azure::Storage::Common::ServiceType::TABLE
221
+
222
+ signable_fields.join "\n"
223
+ end
224
+
225
+ # Account Shared Access Signature Token for the given options
226
+ # @param account_name [String] storage account name
227
+ # @param options [Hash]
228
+ #
229
+ # ==== Options
230
+ #
231
+ # * +:service+ - String. Required. Accessible services. Combination of 'b' (blob), 'q' (queue), 't' (table), 'f' (file).
232
+ # * +:resource+ - String. Required. Accessible resource types. Combination of 's' (service), 'c' (container-level), 'o'(object-level).
233
+ # * +:permissions+ - String. Required. Permissions. Combination of 'r' (read), 'w' (write), 'd'(delete), 'l'(list), 'a'(add),
234
+ # 'c'(create), 'u'(update), 'p'(process). Permissions are only valid if they match
235
+ # the specified signed resource type; otherwise they are ignored.
236
+ # * +:start+ - String. Optional. UTC Date/Time in ISO8601 format.
237
+ # * +:expiry+ - String. Optional. UTC Date/Time in ISO8601 format. Default now + 30 minutes.
238
+ # * +:protocol+ - String. Optional. Permitted protocols.
239
+ # * +:ip_range+ - String. Optional. An IP address or a range of IP addresses from which to accept requests.
240
+ # When specifying a range, note that the range is inclusive.
241
+ def generate_account_sas_token(options = {})
242
+ raise Azure::Storage::Common::InvalidOptionsError, "SAS version cannot be set" if options[:version]
243
+
244
+ options = DEFAULTS.merge(options)
245
+ valid_mappings = ACCOUNT_KEY_MAPPINGS
246
+
247
+ invalid_options = options.reject { |k, _| valid_mappings.key?(k) }
248
+ raise Azure::Storage::Common::InvalidOptionsError, "invalid options #{invalid_options} provided for SAS token generate" if invalid_options.length > 0
249
+
250
+ canonicalize_time(options)
251
+
252
+ query_hash = Hash[options.map { |k, v| [ACCOUNT_KEY_MAPPINGS[k], v] }]
253
+ .reject { |k, v| ACCOUNT_OPTIONAL_QUERY_PARAMS.include?(k) && v.to_s == "" }
254
+ .merge(sig: @signer.sign(signable_string_for_account(options)))
255
+
256
+ URI.encode_www_form(query_hash)
257
+ end
258
+
259
+ # Construct the plaintext to the spec required for signatures
260
+ # @return [String]
261
+ def signable_string_for_account(options)
262
+ # Order is significant
263
+ # The newlines from empty strings here are required
264
+ [
265
+ @account_name,
266
+ options[:permissions],
267
+ options[:service],
268
+ options[:resource],
269
+ options[:start],
270
+ options[:expiry],
271
+ options[:ip_range],
272
+ options[:protocol],
273
+ Azure::Storage::Common::Default::STG_VERSION,
274
+ ""
275
+ ].join("\n")
276
+ end
277
+
278
+ # Return the cononicalized resource representation of the blob resource
279
+ # @return [String]
280
+ def canonicalized_resource(service_type, path)
281
+ "/#{service_type}/#{account_name}#{path.start_with?('/') ? '' : '/'}#{path}"
282
+ end
283
+
284
+ def canonicalize_time(options)
285
+ options[:start] = Time.parse(options[:start]).utc.iso8601 if options[:start]
286
+ options[:expiry] = Time.parse(options[:expiry]).utc.iso8601 if options[:expiry]
287
+ options[:expiry] ||= (Time.now + 60 * 30).utc.iso8601
288
+ end
289
+
290
+ # A customised URI reflecting options for the resource signed with Shared Access Signature
291
+ # @param uri [URI] uri to resource including query options
292
+ # @param use_account_sas [Boolean] Whether uses account SAS
293
+ # @param options [Hash]
294
+ #
295
+ # ==== Options
296
+ #
297
+ # * +:start+ - String. Optional. UTC Date/Time in ISO8601 format.
298
+ # * +:expiry+ - String. Optional. UTC Date/Time in ISO8601 format. Default now + 30 minutes.
299
+ # * +:protocol+ - String. Optional. Permitted protocols.
300
+ # * +:ip_range+ - String. Optional. An IP address or a range of IP addresses from which to accept requests.
301
+ # When specifying a range, note that the range is inclusive.
302
+ #
303
+ # Below options for account SAS only
304
+ # * +:service+ - String. Required. Accessible services. Combination of 'b' (blob), 'q' (queue), 't' (table), 'f' (file).
305
+ # * +:resource+ - String. Required. Accessible resource types. Combination of 's' (service), 'c' (container-level), 'o'(object-level).
306
+ # * +:permissions+ - String. Required. Permissions. Combination of 'r' (read), 'w' (write), 'd'(delete), 'l'(list), 'a'(add),
307
+ # 'c'(create), 'u'(update), 'p'(process). Permissions are only valid if they match
308
+ # the specified signed resource type; otherwise they are ignored.
309
+ #
310
+ # Below options for service SAS only
311
+ # * +:service+ - String. Required. Service type. 'b' (blob) or 'q' (queue) or 't' (table) or 'f' (file).
312
+ # * +:resource+ - String. Required. Resource type, 'b' (blob) or 'c' (container) or 'f' (file) or 's' (share).
313
+ # * +:identifier+ - String. Optional. Identifier for stored access policy.
314
+ # * +:permissions+ - String. Optional. Combination of 'r', 'a', 'c', w','d','l' in this order for a container.
315
+ # Combination of 'r', 'a', 'c', 'w', 'd' in this order for a blob.
316
+ # Combination of 'r', 'c', 'w', 'd', 'l' in this order for a share.
317
+ # Combination of 'r', 'c', 'w', 'd' in this order for a file.
318
+ # Combination of 'r', 'a', 'u', 'p' in this order for a queue.
319
+ # Combination of 'r', 'a', 'u', 'd' in this order for a table.
320
+ #
321
+ # Below options for Blob service only
322
+ # * +:cache_control+ - String. Optional. Response header override.
323
+ # * +:content_disposition+ - String. Optional. Response header override.
324
+ # * +:content_encoding+ - String. Optional. Response header override.
325
+ # * +:content_language+ - String. Optional. Response header override.
326
+ # * +:content_type+ - String. Optional. Response header override.
327
+ #
328
+ # Below options for Table service only
329
+ # * +:table_name+ - String. Required. Table name for SAS.
330
+ # * +:startpk+ - String. Optional but must accompany startrk. The start partition key of a specified partition key range.
331
+ # * +:endpk+ - String. Optional but must accompany endrk. The end partition key of a specified partition key range.
332
+ # * +:startrk+ - String. Optional. The start row key of a specified row key range.
333
+ # * +:endrk+ - String. Optional. The end row key of a specified row key range.
334
+ def signed_uri(uri, use_account_sas, options)
335
+ CGI::parse(uri.query || "").inject({}) { |memo, (k, v)| memo[k.to_sym] = v; memo }
336
+
337
+ if options[:service] == (nil) && uri.host != (nil)
338
+ host_splits = uri.host.split(".")
339
+ options[:service] = host_splits[1].chr if host_splits.length > 1 && host_splits[0] == @account_name
340
+ end
341
+
342
+ sas_params = if use_account_sas
343
+ generate_account_sas_token(options)
344
+ else
345
+ generate_service_sas_token(uri.path, options)
346
+ end
347
+
348
+ URI.parse(uri.to_s + (uri.query.nil? ? "?" : "&") + sas_params)
349
+ end
350
+ end
351
+ end
352
+ end