azure-storage-common 1.1.0 → 2.0.1

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.
Files changed (60) hide show
  1. checksums.yaml +5 -5
  2. data/lib/azure/core.rb +47 -0
  3. data/lib/azure/core/auth/authorizer.rb +36 -0
  4. data/lib/azure/core/auth/shared_key.rb +125 -0
  5. data/lib/azure/core/auth/shared_key_lite.rb +48 -0
  6. data/lib/azure/core/auth/signer.rb +51 -0
  7. data/lib/azure/core/default.rb +23 -0
  8. data/lib/azure/core/error.rb +21 -0
  9. data/lib/azure/core/filtered_service.rb +45 -0
  10. data/lib/azure/core/http/debug_filter.rb +36 -0
  11. data/lib/azure/core/http/http_error.rb +135 -0
  12. data/lib/azure/core/http/http_filter.rb +53 -0
  13. data/lib/azure/core/http/http_request.rb +194 -0
  14. data/lib/azure/core/http/http_response.rb +102 -0
  15. data/lib/azure/core/http/retry_policy.rb +84 -0
  16. data/lib/azure/core/http/signer_filter.rb +33 -0
  17. data/lib/azure/core/service.rb +46 -0
  18. data/lib/azure/core/signed_service.rb +45 -0
  19. data/lib/azure/core/utility.rb +244 -0
  20. data/lib/azure/core/version.rb +33 -0
  21. data/lib/azure/http_response_helper.rb +38 -0
  22. data/lib/azure/storage/common.rb +26 -26
  23. data/lib/azure/storage/common/autoload.rb +62 -61
  24. data/lib/azure/storage/common/client.rb +162 -162
  25. data/lib/azure/storage/common/client_options.rb +363 -363
  26. data/lib/azure/storage/common/client_options_error.rb +41 -41
  27. data/lib/azure/storage/common/configurable.rb +212 -212
  28. data/lib/azure/storage/common/core.rb +35 -35
  29. data/lib/azure/storage/common/core/auth/anonymous_signer.rb +43 -43
  30. data/lib/azure/storage/common/core/auth/shared_access_signature.rb +30 -30
  31. data/lib/azure/storage/common/core/auth/shared_access_signature_generator.rb +399 -352
  32. data/lib/azure/storage/common/core/auth/shared_access_signature_signer.rb +57 -57
  33. data/lib/azure/storage/common/core/auth/shared_key.rb +60 -60
  34. data/lib/azure/storage/common/core/auth/token_signer.rb +43 -43
  35. data/lib/azure/storage/common/core/autoload.rb +53 -53
  36. data/lib/azure/storage/common/core/error.rb +43 -43
  37. data/lib/azure/storage/common/core/filter/exponential_retry_filter.rb +64 -64
  38. data/lib/azure/storage/common/core/filter/linear_retry_filter.rb +55 -55
  39. data/lib/azure/storage/common/core/filter/retry_filter.rb +300 -300
  40. data/lib/azure/storage/common/core/http_client.rb +79 -69
  41. data/lib/azure/storage/common/core/sr.rb +85 -85
  42. data/lib/azure/storage/common/core/token_credential.rb +64 -64
  43. data/lib/azure/storage/common/core/utility.rb +255 -255
  44. data/lib/azure/storage/common/default.rb +868 -868
  45. data/lib/azure/storage/common/service/access_policy.rb +37 -37
  46. data/lib/azure/storage/common/service/cors.rb +38 -38
  47. data/lib/azure/storage/common/service/cors_rule.rb +48 -48
  48. data/lib/azure/storage/common/service/enumeration_results.rb +32 -32
  49. data/lib/azure/storage/common/service/geo_replication.rb +40 -40
  50. data/lib/azure/storage/common/service/logging.rb +47 -47
  51. data/lib/azure/storage/common/service/metrics.rb +45 -45
  52. data/lib/azure/storage/common/service/retention_policy.rb +37 -37
  53. data/lib/azure/storage/common/service/serialization.rb +335 -335
  54. data/lib/azure/storage/common/service/signed_identifier.rb +40 -40
  55. data/lib/azure/storage/common/service/storage_service.rb +322 -322
  56. data/lib/azure/storage/common/service/storage_service_properties.rb +48 -48
  57. data/lib/azure/storage/common/service/storage_service_stats.rb +39 -39
  58. data/lib/azure/storage/common/service/user_delegation_key.rb +50 -0
  59. data/lib/azure/storage/common/version.rb +49 -49
  60. metadata +60 -18
@@ -1,35 +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"
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"
@@ -1,43 +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
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
@@ -1,30 +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
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
@@ -1,352 +1,399 @@
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
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
+ USER_DELEGATION_KEY_MAPPINGS = {
71
+ signed_oid: :skoid,
72
+ signed_tid: :sktid,
73
+ signed_start: :skt,
74
+ signed_expiry: :ske,
75
+ signed_service: :sks,
76
+ signed_version: :skv
77
+ }
78
+
79
+ BLOB_KEY_MAPPINGS = {
80
+ resource: :sr,
81
+ timestamp: :snapshot,
82
+ cache_control: :rscc,
83
+ content_disposition: :rscd,
84
+ content_encoding: :rsce,
85
+ content_language: :rscl,
86
+ content_type: :rsct
87
+ }
88
+
89
+ TABLE_KEY_MAPPINGS = {
90
+ table_name: :tn,
91
+ startpk: :spk,
92
+ endpk: :epk,
93
+ startrk: :srk,
94
+ endrk: :erk
95
+ }
96
+
97
+ FILE_KEY_MAPPINGS = {
98
+ resource: :sr,
99
+ cache_control: :rscc,
100
+ content_disposition: :rscd,
101
+ content_encoding: :rsce,
102
+ content_language: :rscl,
103
+ content_type: :rsct
104
+ }
105
+
106
+ SERVICE_OPTIONAL_QUERY_PARAMS = [:sp, :si, :sip, :spr, :rscc, :rscd, :rsce, :rscl, :rsct, :spk, :srk, :epk, :erk]
107
+
108
+ ACCOUNT_OPTIONAL_QUERY_PARAMS = [:st, :sip, :spr]
109
+
110
+ attr :account_name
111
+
112
+ # Public: Initialize the SharedAccessSignature generator
113
+ #
114
+ # @param account_name [String] The account name. Defaults to the one in the global configuration.
115
+ # @param access_key [String] The access_key encoded in Base64. Defaults to the one in the global configuration.
116
+ # @param user_delegation_key [Azure::Storage::Common::UserDelegationKey] The user delegation key obtained from
117
+ # calling get_user_delegation_key after authenticating with an Azure Active Directory entity. If present, the
118
+ # SAS is signed with the user delegation key instead of the access key.
119
+ def initialize(account_name = "", access_key = "", user_delegation_key = nil)
120
+ if access_key.empty? && !user_delegation_key.nil?
121
+ access_key = user_delegation_key.value
122
+ end
123
+ if account_name.empty? || access_key.empty?
124
+ client = Azure::Storage::Common::Client.create_from_env
125
+ account_name = client.storage_account_name if account_name.empty?
126
+ access_key = client.storage_access_key if access_key.empty?
127
+ end
128
+ @account_name = account_name
129
+ @user_delegation_key = user_delegation_key
130
+ @signer = Azure::Core::Auth::Signer.new(access_key)
131
+ end
132
+
133
+ # Service Shared Access Signature Token for the given path and options
134
+ # @param path [String] Path of the URI or the table name
135
+ # @param options [Hash]
136
+ #
137
+ # ==== Options
138
+ #
139
+ # * +:service+ - String. Required. Service type. 'b' (blob) or 'q' (queue) or 't' (table) or 'f' (file).
140
+ # * +:resource+ - String. Required. Resource type, 'b' (blob) or 'c' (container) or 'f' (file) or 's' (share).
141
+ # * +:permissions+ - String. Optional. Combination of 'r', 'a', 'c', w','d','l' in this order for a container.
142
+ # Combination of 'r', 'a', 'c', 'w', 'd' in this order for a blob.
143
+ # Combination of 'r', 'c', 'w', 'd', 'l' in this order for a share.
144
+ # Combination of 'r', 'c', 'w', 'd' in this order for a file.
145
+ # Combination of 'r', 'a', 'u', 'p' in this order for a queue.
146
+ # Combination of 'r', 'a', 'u', 'd' in this order for a table.
147
+ # This option must be omitted if it has been specified in an associated stored access policy.
148
+ # * +:start+ - String. Optional. UTC Date/Time in ISO8601 format.
149
+ # * +:expiry+ - String. Optional. UTC Date/Time in ISO8601 format. Default now + 30 minutes.
150
+ # * +:identifier+ - String. Optional. Identifier for stored access policy.
151
+ # This option must be omitted if a user delegation key has been provided.
152
+ # * +:protocol+ - String. Optional. Permitted protocols.
153
+ # * +:ip_range+ - String. Optional. An IP address or a range of IP addresses from which to accept requests.
154
+ #
155
+ # Below options for blob serivce only
156
+ # * +:snapshot+ - String. Optional. UTC Date/Time in ISO8601 format. The blob snapshot to grant permission.
157
+ # * +:cache_control+ - String. Optional. Response header override.
158
+ # * +:content_disposition+ - String. Optional. Response header override.
159
+ # * +:content_encoding+ - String. Optional. Response header override.
160
+ # * +:content_language+ - String. Optional. Response header override.
161
+ # * +:content_type+ - String. Optional. Response header override.
162
+ #
163
+ # Below options for table service only
164
+ # * +:startpk+ - String. Optional but must accompany startrk. The start partition key of a specified partition key range.
165
+ # * +:endpk+ - String. Optional but must accompany endrk. The end partition key of a specified partition key range.
166
+ # * +:startrk+ - String. Optional. The start row key of a specified row key range.
167
+ # * +:endrk+ - String. Optional. The end row key of a specified row key range.
168
+ def generate_service_sas_token(path, options = {})
169
+ if options.key?(:service)
170
+ service_type = SERVICE_TYPE_MAPPING[options[:service].to_sym]
171
+ options.delete(:service)
172
+ end
173
+
174
+ raise Azure::Storage::Common::InvalidOptionsError, "SAS version cannot be set" if options[:version]
175
+
176
+ options = DEFAULTS.merge(options)
177
+ valid_mappings = SERVICE_KEY_MAPPINGS
178
+ if service_type == Azure::Storage::Common::ServiceType::BLOB
179
+ if options[:resource]
180
+ options.merge!(resource: options[:resource])
181
+ else
182
+ options.merge!(resource: "b")
183
+ end
184
+ valid_mappings.merge!(BLOB_KEY_MAPPINGS)
185
+ elsif service_type == Azure::Storage::Common::ServiceType::TABLE
186
+ options.merge!(table_name: path)
187
+ valid_mappings.merge!(TABLE_KEY_MAPPINGS)
188
+ elsif service_type == Azure::Storage::Common::ServiceType::FILE
189
+ if options[:resource]
190
+ options.merge!(resource: options[:resource])
191
+ else
192
+ options.merge!(resource: "f")
193
+ end
194
+ valid_mappings.merge!(FILE_KEY_MAPPINGS)
195
+ end
196
+
197
+ service_key_mappings = SERVICE_KEY_MAPPINGS
198
+ unless @user_delegation_key.nil?
199
+ valid_mappings.delete(:identifier)
200
+ USER_DELEGATION_KEY_MAPPINGS.each { |k, _| options[k] = @user_delegation_key.send(k) }
201
+ valid_mappings.merge!(USER_DELEGATION_KEY_MAPPINGS)
202
+ service_key_mappings = service_key_mappings.merge(USER_DELEGATION_KEY_MAPPINGS)
203
+ end
204
+
205
+ invalid_options = options.reject { |k, _| valid_mappings.key?(k) }
206
+ raise Azure::Storage::Common::InvalidOptionsError, "invalid options #{invalid_options} provided for SAS token generate" if invalid_options.length > 0
207
+
208
+ canonicalize_time(options)
209
+
210
+ query_hash = Hash[options.map { |k, v| [service_key_mappings[k], v] }]
211
+ .reject { |k, v| SERVICE_OPTIONAL_QUERY_PARAMS.include?(k) && v.to_s == "" }
212
+ .merge(sig: @signer.sign(signable_string_for_service(service_type, path, options)))
213
+
214
+ URI.encode_www_form(query_hash)
215
+ end
216
+
217
+ # Construct the plaintext to the spec required for signatures
218
+ # @return [String]
219
+ def signable_string_for_service(service_type, path, options)
220
+ # Order is significant
221
+ # The newlines from empty strings here are required
222
+ signable_fields =
223
+ [
224
+ options[:permissions],
225
+ options[:start],
226
+ options[:expiry],
227
+ canonicalized_resource(service_type, path)
228
+ ]
229
+
230
+ if @user_delegation_key.nil?
231
+ signable_fields.push(options[:identifier])
232
+ else
233
+ signable_fields.concat [
234
+ @user_delegation_key.signed_oid,
235
+ @user_delegation_key.signed_tid,
236
+ @user_delegation_key.signed_start,
237
+ @user_delegation_key.signed_expiry,
238
+ @user_delegation_key.signed_service,
239
+ @user_delegation_key.signed_version
240
+ ]
241
+ end
242
+
243
+ signable_fields.concat [
244
+ options[:ip_range],
245
+ options[:protocol],
246
+ Azure::Storage::Common::Default::STG_VERSION
247
+ ]
248
+
249
+ signable_fields.concat [
250
+ options[:resource],
251
+ options[:timestamp]
252
+ ] if service_type == Azure::Storage::Common::ServiceType::BLOB
253
+
254
+ signable_fields.concat [
255
+ options[:cache_control],
256
+ options[:content_disposition],
257
+ options[:content_encoding],
258
+ options[:content_language],
259
+ options[:content_type]
260
+ ] if service_type == Azure::Storage::Common::ServiceType::BLOB || service_type == Azure::Storage::Common::ServiceType::FILE
261
+
262
+ signable_fields.concat [
263
+ options[:startpk],
264
+ options[:startrk],
265
+ options[:endpk],
266
+ options[:endrk]
267
+ ] if service_type == Azure::Storage::Common::ServiceType::TABLE
268
+
269
+ signable_fields.join "\n"
270
+ end
271
+
272
+ # Account Shared Access Signature Token for the given options
273
+ # @param account_name [String] storage account name
274
+ # @param options [Hash]
275
+ #
276
+ # ==== Options
277
+ #
278
+ # * +:service+ - String. Required. Accessible services. Combination of 'b' (blob), 'q' (queue), 't' (table), 'f' (file).
279
+ # * +:resource+ - String. Required. Accessible resource types. Combination of 's' (service), 'c' (container-level), 'o'(object-level).
280
+ # * +:permissions+ - String. Required. Permissions. Combination of 'r' (read), 'w' (write), 'd'(delete), 'l'(list), 'a'(add),
281
+ # 'c'(create), 'u'(update), 'p'(process). Permissions are only valid if they match
282
+ # the specified signed resource type; otherwise they are ignored.
283
+ # * +:start+ - String. Optional. UTC Date/Time in ISO8601 format.
284
+ # * +:expiry+ - String. Optional. UTC Date/Time in ISO8601 format. Default now + 30 minutes.
285
+ # * +:protocol+ - String. Optional. Permitted protocols.
286
+ # * +:ip_range+ - String. Optional. An IP address or a range of IP addresses from which to accept requests.
287
+ # When specifying a range, note that the range is inclusive.
288
+ def generate_account_sas_token(options = {})
289
+ raise Azure::Storage::Common::InvalidOptionsError, "SAS version cannot be set" if options[:version]
290
+
291
+ options = DEFAULTS.merge(options)
292
+ valid_mappings = ACCOUNT_KEY_MAPPINGS
293
+
294
+ invalid_options = options.reject { |k, _| valid_mappings.key?(k) }
295
+ raise Azure::Storage::Common::InvalidOptionsError, "invalid options #{invalid_options} provided for SAS token generate" if invalid_options.length > 0
296
+
297
+ canonicalize_time(options)
298
+
299
+ query_hash = Hash[options.map { |k, v| [ACCOUNT_KEY_MAPPINGS[k], v] }]
300
+ .reject { |k, v| ACCOUNT_OPTIONAL_QUERY_PARAMS.include?(k) && v.to_s == "" }
301
+ .merge(sig: @signer.sign(signable_string_for_account(options)))
302
+
303
+ URI.encode_www_form(query_hash)
304
+ end
305
+
306
+ # Construct the plaintext to the spec required for signatures
307
+ # @return [String]
308
+ def signable_string_for_account(options)
309
+ # Order is significant
310
+ # The newlines from empty strings here are required
311
+ [
312
+ @account_name,
313
+ options[:permissions],
314
+ options[:service],
315
+ options[:resource],
316
+ options[:start],
317
+ options[:expiry],
318
+ options[:ip_range],
319
+ options[:protocol],
320
+ Azure::Storage::Common::Default::STG_VERSION,
321
+ ""
322
+ ].join("\n")
323
+ end
324
+
325
+ # Return the cononicalized resource representation of the blob resource
326
+ # @return [String]
327
+ def canonicalized_resource(service_type, path)
328
+ "/#{service_type}/#{account_name}#{path.start_with?('/') ? '' : '/'}#{path}"
329
+ end
330
+
331
+ def canonicalize_time(options)
332
+ options[:start] = Time.parse(options[:start]).utc.iso8601 if options[:start]
333
+ options[:expiry] = Time.parse(options[:expiry]).utc.iso8601 if options[:expiry]
334
+ options[:expiry] ||= (Time.now + 60 * 30).utc.iso8601
335
+ end
336
+
337
+ # A customised URI reflecting options for the resource signed with Shared Access Signature
338
+ # @param uri [URI] uri to resource including query options
339
+ # @param use_account_sas [Boolean] Whether uses account SAS
340
+ # @param options [Hash]
341
+ #
342
+ # ==== Options
343
+ #
344
+ # * +:start+ - String. Optional. UTC Date/Time in ISO8601 format.
345
+ # * +:expiry+ - String. Optional. UTC Date/Time in ISO8601 format. Default now + 30 minutes.
346
+ # * +:protocol+ - String. Optional. Permitted protocols.
347
+ # * +:ip_range+ - String. Optional. An IP address or a range of IP addresses from which to accept requests.
348
+ # When specifying a range, note that the range is inclusive.
349
+ #
350
+ # Below options for account SAS only
351
+ # * +:service+ - String. Required. Accessible services. Combination of 'b' (blob), 'q' (queue), 't' (table), 'f' (file).
352
+ # * +:resource+ - String. Required. Accessible resource types. Combination of 's' (service), 'c' (container-level), 'o'(object-level).
353
+ # * +:permissions+ - String. Required. Permissions. Combination of 'r' (read), 'w' (write), 'd'(delete), 'l'(list), 'a'(add),
354
+ # 'c'(create), 'u'(update), 'p'(process). Permissions are only valid if they match
355
+ # the specified signed resource type; otherwise they are ignored.
356
+ #
357
+ # Below options for service SAS only
358
+ # * +:service+ - String. Required. Service type. 'b' (blob) or 'q' (queue) or 't' (table) or 'f' (file).
359
+ # * +:resource+ - String. Required. Resource type, 'b' (blob) or 'c' (container) or 'f' (file) or 's' (share).
360
+ # * +:identifier+ - String. Optional. Identifier for stored access policy.
361
+ # * +:permissions+ - String. Optional. Combination of 'r', 'a', 'c', w','d','l' in this order for a container.
362
+ # Combination of 'r', 'a', 'c', 'w', 'd' in this order for a blob.
363
+ # Combination of 'r', 'c', 'w', 'd', 'l' in this order for a share.
364
+ # Combination of 'r', 'c', 'w', 'd' in this order for a file.
365
+ # Combination of 'r', 'a', 'u', 'p' in this order for a queue.
366
+ # Combination of 'r', 'a', 'u', 'd' in this order for a table.
367
+ #
368
+ # Below options for Blob service only
369
+ # * +:cache_control+ - String. Optional. Response header override.
370
+ # * +:content_disposition+ - String. Optional. Response header override.
371
+ # * +:content_encoding+ - String. Optional. Response header override.
372
+ # * +:content_language+ - String. Optional. Response header override.
373
+ # * +:content_type+ - String. Optional. Response header override.
374
+ #
375
+ # Below options for Table service only
376
+ # * +:table_name+ - String. Required. Table name for SAS.
377
+ # * +:startpk+ - String. Optional but must accompany startrk. The start partition key of a specified partition key range.
378
+ # * +:endpk+ - String. Optional but must accompany endrk. The end partition key of a specified partition key range.
379
+ # * +:startrk+ - String. Optional. The start row key of a specified row key range.
380
+ # * +:endrk+ - String. Optional. The end row key of a specified row key range.
381
+ def signed_uri(uri, use_account_sas, options)
382
+ CGI::parse(uri.query || "").inject({}) { |memo, (k, v)| memo[k.to_sym] = v; memo }
383
+
384
+ if options[:service] == (nil) && uri.host != (nil)
385
+ host_splits = uri.host.split(".")
386
+ options[:service] = host_splits[1].chr if host_splits.length > 1 && host_splits[0] == @account_name
387
+ end
388
+
389
+ sas_params = if use_account_sas
390
+ generate_account_sas_token(options)
391
+ else
392
+ generate_service_sas_token(uri.path, options)
393
+ end
394
+
395
+ URI.parse(uri.to_s + (uri.query.nil? ? "?" : "&") + sas_params)
396
+ end
397
+ end
398
+ end
399
+ end