aws-sdk-resources 2.11.549

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 (58) hide show
  1. checksums.yaml +7 -0
  2. data/lib/aws-sdk-resources.rb +91 -0
  3. data/lib/aws-sdk-resources/batch.rb +143 -0
  4. data/lib/aws-sdk-resources/builder.rb +85 -0
  5. data/lib/aws-sdk-resources/builder_sources.rb +105 -0
  6. data/lib/aws-sdk-resources/collection.rb +107 -0
  7. data/lib/aws-sdk-resources/definition.rb +331 -0
  8. data/lib/aws-sdk-resources/documenter.rb +70 -0
  9. data/lib/aws-sdk-resources/documenter/base_operation_documenter.rb +279 -0
  10. data/lib/aws-sdk-resources/documenter/data_operation_documenter.rb +25 -0
  11. data/lib/aws-sdk-resources/documenter/has_many_operation_documenter.rb +69 -0
  12. data/lib/aws-sdk-resources/documenter/has_operation_documenter.rb +66 -0
  13. data/lib/aws-sdk-resources/documenter/operation_documenter.rb +20 -0
  14. data/lib/aws-sdk-resources/documenter/resource_operation_documenter.rb +53 -0
  15. data/lib/aws-sdk-resources/documenter/waiter_operation_documenter.rb +77 -0
  16. data/lib/aws-sdk-resources/errors.rb +15 -0
  17. data/lib/aws-sdk-resources/operation_methods.rb +83 -0
  18. data/lib/aws-sdk-resources/operations.rb +280 -0
  19. data/lib/aws-sdk-resources/options.rb +17 -0
  20. data/lib/aws-sdk-resources/request.rb +39 -0
  21. data/lib/aws-sdk-resources/request_params.rb +140 -0
  22. data/lib/aws-sdk-resources/resource.rb +243 -0
  23. data/lib/aws-sdk-resources/services/ec2.rb +21 -0
  24. data/lib/aws-sdk-resources/services/ec2/instance.rb +29 -0
  25. data/lib/aws-sdk-resources/services/iam.rb +19 -0
  26. data/lib/aws-sdk-resources/services/s3.rb +20 -0
  27. data/lib/aws-sdk-resources/services/s3/bucket.rb +131 -0
  28. data/lib/aws-sdk-resources/services/s3/encryption.rb +21 -0
  29. data/lib/aws-sdk-resources/services/s3/encryption/client.rb +369 -0
  30. data/lib/aws-sdk-resources/services/s3/encryption/decrypt_handler.rb +174 -0
  31. data/lib/aws-sdk-resources/services/s3/encryption/default_cipher_provider.rb +63 -0
  32. data/lib/aws-sdk-resources/services/s3/encryption/default_key_provider.rb +38 -0
  33. data/lib/aws-sdk-resources/services/s3/encryption/encrypt_handler.rb +50 -0
  34. data/lib/aws-sdk-resources/services/s3/encryption/errors.rb +13 -0
  35. data/lib/aws-sdk-resources/services/s3/encryption/io_auth_decrypter.rb +56 -0
  36. data/lib/aws-sdk-resources/services/s3/encryption/io_decrypter.rb +29 -0
  37. data/lib/aws-sdk-resources/services/s3/encryption/io_encrypter.rb +69 -0
  38. data/lib/aws-sdk-resources/services/s3/encryption/key_provider.rb +29 -0
  39. data/lib/aws-sdk-resources/services/s3/encryption/kms_cipher_provider.rb +71 -0
  40. data/lib/aws-sdk-resources/services/s3/encryption/materials.rb +58 -0
  41. data/lib/aws-sdk-resources/services/s3/encryption/utils.rb +79 -0
  42. data/lib/aws-sdk-resources/services/s3/file_downloader.rb +169 -0
  43. data/lib/aws-sdk-resources/services/s3/file_part.rb +75 -0
  44. data/lib/aws-sdk-resources/services/s3/file_uploader.rb +58 -0
  45. data/lib/aws-sdk-resources/services/s3/multipart_file_uploader.rb +187 -0
  46. data/lib/aws-sdk-resources/services/s3/multipart_upload.rb +42 -0
  47. data/lib/aws-sdk-resources/services/s3/multipart_upload_error.rb +16 -0
  48. data/lib/aws-sdk-resources/services/s3/object.rb +290 -0
  49. data/lib/aws-sdk-resources/services/s3/object_copier.rb +99 -0
  50. data/lib/aws-sdk-resources/services/s3/object_multipart_copier.rb +180 -0
  51. data/lib/aws-sdk-resources/services/s3/object_summary.rb +73 -0
  52. data/lib/aws-sdk-resources/services/s3/presigned_post.rb +651 -0
  53. data/lib/aws-sdk-resources/services/sns.rb +7 -0
  54. data/lib/aws-sdk-resources/services/sns/message_verifier.rb +171 -0
  55. data/lib/aws-sdk-resources/services/sqs.rb +7 -0
  56. data/lib/aws-sdk-resources/services/sqs/queue_poller.rb +521 -0
  57. data/lib/aws-sdk-resources/source.rb +39 -0
  58. metadata +118 -0
@@ -0,0 +1,29 @@
1
+ require 'openssl'
2
+
3
+ module Aws
4
+ module EC2
5
+ class Instance
6
+
7
+ # @param [String, Pathname] key_pair_path
8
+ # @return [String]
9
+ def decrypt_windows_password(key_pair_path)
10
+ decoded = Base64.decode64(encrypted_password)
11
+ pem_bytes = File.open(key_pair_path, 'rb') { |f| f.read }
12
+ private_key = OpenSSL::PKey::RSA.new(pem_bytes)
13
+ private_key.private_decrypt(decoded)
14
+ end
15
+
16
+ private
17
+
18
+ def encrypted_password
19
+ bytes = client.get_password_data(instance_id: id).password_data
20
+ if bytes == ''
21
+ raise 'password not available yet'
22
+ else
23
+ bytes
24
+ end
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,19 @@
1
+ module Aws
2
+ module IAM
3
+ class Resource
4
+
5
+ # @return [Seahorse::Client::Response, false] Returns the response
6
+ # from {Client#delete_account_alias} if an alias was deleted.
7
+ # Returns `false` if this account had no alias to remove.
8
+ # @see Client#delete_account_alias
9
+ def delete_account_alias
10
+ if name = @client.list_account_aliases.account_aliases.first
11
+ @client.delete_account_alias(account_alias: name)
12
+ else
13
+ false
14
+ end
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ module Aws
2
+ module S3
3
+
4
+ require 'aws-sdk-resources/services/s3/bucket'
5
+ require 'aws-sdk-resources/services/s3/object'
6
+ require 'aws-sdk-resources/services/s3/object_summary'
7
+ require 'aws-sdk-resources/services/s3/multipart_upload'
8
+
9
+ autoload :Encryption, 'aws-sdk-resources/services/s3/encryption'
10
+ autoload :FilePart, 'aws-sdk-resources/services/s3/file_part'
11
+ autoload :FileUploader, 'aws-sdk-resources/services/s3/file_uploader'
12
+ autoload :FileDownloader, 'aws-sdk-resources/services/s3/file_downloader'
13
+ autoload :MultipartFileUploader, 'aws-sdk-resources/services/s3/multipart_file_uploader'
14
+ autoload :MultipartUploadError, 'aws-sdk-resources/services/s3/multipart_upload_error'
15
+ autoload :ObjectCopier, 'aws-sdk-resources/services/s3/object_copier'
16
+ autoload :ObjectMultipartCopier, 'aws-sdk-resources/services/s3/object_multipart_copier'
17
+ autoload :PresignedPost, 'aws-sdk-resources/services/s3/presigned_post'
18
+
19
+ end
20
+ end
@@ -0,0 +1,131 @@
1
+ require 'uri'
2
+
3
+ module Aws
4
+ module S3
5
+ class Bucket
6
+
7
+ # Deletes all objects and versioned objects from this bucket
8
+ #
9
+ # @example
10
+ #
11
+ # bucket.clear!
12
+ #
13
+ # @return [void]
14
+ def clear!
15
+ object_versions.batch_delete!
16
+ end
17
+
18
+ # Deletes all objects and versioned objects from this bucket and
19
+ # then deletes the bucket.
20
+ #
21
+ # @example
22
+ #
23
+ # bucket.delete!
24
+ #
25
+ # @option options [Integer] :max_attempts (3) Maximum number of times to
26
+ # attempt to delete the empty bucket before raising
27
+ # `Aws::S3::Errors::BucketNotEmpty`.
28
+ #
29
+ # @option options [Float] :initial_wait (1.3) Seconds to wait before
30
+ # retrying the call to delete the bucket, exponentially increased for
31
+ # each attempt.
32
+ #
33
+ # @return [void]
34
+ def delete! options = { }
35
+ options = {
36
+ initial_wait: 1.3,
37
+ max_attempts: 3,
38
+ }.merge(options)
39
+
40
+ attempts = 0
41
+ begin
42
+ clear!
43
+ delete
44
+ rescue Errors::BucketNotEmpty
45
+ attempts += 1
46
+ if attempts >= options[:max_attempts]
47
+ raise
48
+ else
49
+ Kernel.sleep(options[:initial_wait] ** attempts)
50
+ retry
51
+ end
52
+ end
53
+ end
54
+
55
+ # Returns a public URL for this bucket.
56
+ #
57
+ # bucket = s3.bucket('bucket-name')
58
+ # bucket.url
59
+ # #=> "https://bucket-name.s3.amazonaws.com"
60
+ #
61
+ # You can pass `virtual_host: true` to use the bucket name as the
62
+ # host name.
63
+ #
64
+ # bucket = s3.bucket('my.bucket.com', virtual_host: true)
65
+ # bucket.url
66
+ # #=> "http://my.bucket.com"
67
+ #
68
+ # @option options [Boolean] :virtual_host (false) When `true`,
69
+ # the bucket name will be used as the host name. This is useful
70
+ # when you have a CNAME configured for this bucket.
71
+ #
72
+ # @return [String] the URL for this bucket.
73
+ def url(options = {})
74
+ if options[:virtual_host]
75
+ "http://#{name}"
76
+ else
77
+ s3_bucket_url
78
+ end
79
+ end
80
+
81
+ # Creates a {PresignedPost} that makes it easy to upload a file from
82
+ # a web browser direct to Amazon S3 using an HTML post form with
83
+ # a file field.
84
+ #
85
+ # See the {PresignedPost} documentation for more information.
86
+ # @note You must specify `:key` or `:key_starts_with`. All other options
87
+ # are optional.
88
+ # @option (see PresignedPost#initialize)
89
+ # @return [PresignedPost]
90
+ # @see PresignedPost
91
+ def presigned_post(options = {})
92
+ PresignedPost.new(
93
+ client.config.credentials,
94
+ client.config.region,
95
+ name,
96
+ {url: url}.merge(options)
97
+ )
98
+ end
99
+
100
+ # @api private
101
+ def load
102
+ @data = client.list_buckets.buckets.find { |b| b.name == name }
103
+ raise "unable to load bucket #{name}" if @data.nil?
104
+ self
105
+ end
106
+
107
+ private
108
+
109
+ def s3_bucket_url
110
+ url = client.config.endpoint.dup
111
+ if bucket_as_hostname?(url.scheme == 'https')
112
+ url.host = "#{name}.#{url.host}"
113
+ else
114
+ url.path += '/' unless url.path[-1] == '/'
115
+ url.path += Seahorse::Util.uri_escape(name)
116
+ end
117
+ if (client.config.region == 'us-east-1') &&
118
+ (client.config.s3_us_east_1_regional_endpoint == 'legacy')
119
+ url.host = Plugins::S3IADRegionalEndpoint.legacy_host(url.host)
120
+ end
121
+ url.to_s
122
+ end
123
+
124
+ def bucket_as_hostname?(https)
125
+ Plugins::S3BucketDns.dns_compatible?(name, https) &&
126
+ !client.config.force_path_style
127
+ end
128
+
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,21 @@
1
+ module Aws
2
+ module S3
3
+ module Encryption
4
+
5
+ autoload :Client, 'aws-sdk-resources/services/s3/encryption/client'
6
+ autoload :DecryptHandler, 'aws-sdk-resources/services/s3/encryption/decrypt_handler'
7
+ autoload :DefaultCipherProvider, 'aws-sdk-resources/services/s3/encryption/default_cipher_provider'
8
+ autoload :DefaultKeyProvider, 'aws-sdk-resources/services/s3/encryption/default_key_provider'
9
+ autoload :EncryptHandler, 'aws-sdk-resources/services/s3/encryption/encrypt_handler'
10
+ autoload :Errors, 'aws-sdk-resources/services/s3/encryption/errors'
11
+ autoload :IOEncrypter, 'aws-sdk-resources/services/s3/encryption/io_encrypter'
12
+ autoload :IOAuthDecrypter, 'aws-sdk-resources/services/s3/encryption/io_auth_decrypter'
13
+ autoload :IODecrypter, 'aws-sdk-resources/services/s3/encryption/io_decrypter'
14
+ autoload :KeyProvider, 'aws-sdk-resources/services/s3/encryption/key_provider'
15
+ autoload :KmsCipherProvider, 'aws-sdk-resources/services/s3/encryption/kms_cipher_provider'
16
+ autoload :Materials, 'aws-sdk-resources/services/s3/encryption/materials'
17
+ autoload :Utils, 'aws-sdk-resources/services/s3/encryption/utils'
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,369 @@
1
+ module Aws
2
+ module S3
3
+
4
+ # Provides an encryption client that encrypts and decrypts data client-side,
5
+ # storing the encrypted data in Amazon S3.
6
+ #
7
+ # This client uses a process called "envelope encryption". Your private
8
+ # encryption keys and your data's plain-text are **never** sent to
9
+ # Amazon S3. **If you lose you encryption keys, you will not be able to
10
+ # decrypt your data.**
11
+ #
12
+ # ## Envelope Encryption Overview
13
+ #
14
+ # The goal of envelope encryption is to combine the performance of
15
+ # fast symmetric encryption while maintaining the secure key management
16
+ # that asymmetric keys provide.
17
+ #
18
+ # A one-time-use symmetric key (envelope key) is generated client-side.
19
+ # This is used to encrypt the data client-side. This key is then
20
+ # encrypted by your master key and stored alongside your data in Amazon
21
+ # S3.
22
+ #
23
+ # When accessing your encrypted data with the encryption client,
24
+ # the encrypted envelope key is retrieved and decrypted client-side
25
+ # with your master key. The envelope key is then used to decrypt the
26
+ # data client-side.
27
+ #
28
+ # One of the benefits of envelope encryption is that if your master key
29
+ # is compromised, you have the option of jut re-encrypting the stored
30
+ # envelope symmetric keys, instead of re-encrypting all of the
31
+ # data in your account.
32
+ #
33
+ # ## Basic Usage
34
+ #
35
+ # The encryption client requires an {Aws::S3::Client}. If you do not
36
+ # provide a `:client`, then a client will be constructed for you.
37
+ #
38
+ # require 'openssl'
39
+ # key = OpenSSL::PKey::RSA.new(1024)
40
+ #
41
+ # # encryption client
42
+ # s3 = Aws::S3::Encryption::Client.new(encryption_key: key)
43
+ #
44
+ # # round-trip an object, encrypted/decrypted locally
45
+ # s3.put_object(bucket:'aws-sdk', key:'secret', body:'handshake')
46
+ # s3.get_object(bucket:'aws-sdk', key:'secret').body.read
47
+ # #=> 'handshake'
48
+ #
49
+ # # reading encrypted object without the encryption client
50
+ # # results in the getting the cipher text
51
+ # Aws::S3::Client.new.get_object(bucket:'aws-sdk', key:'secret').body.read
52
+ # #=> "... cipher text ..."
53
+ #
54
+ # ## Keys
55
+ #
56
+ # For client-side encryption to work, you must provide one of the following:
57
+ #
58
+ # * An encryption key
59
+ # * A {KeyProvider}
60
+ # * A KMS encryption key id
61
+ #
62
+ # ### An Encryption Key
63
+ #
64
+ # You can pass a single encryption key. This is used as a master key
65
+ # encrypting and decrypting all object keys.
66
+ #
67
+ # key = OpenSSL::Cipher.new("AES-256-ECB").random_key # symmetric key
68
+ # key = OpenSSL::PKey::RSA.new(1024) # asymmetric key pair
69
+ #
70
+ # s3 = Aws::S3::Encryption::Client.new(encryption_key: key)
71
+ #
72
+ # ### Key Provider
73
+ #
74
+ # Alternatively, you can use a {KeyProvider}. A key provider makes
75
+ # it easy to work with multiple keys and simplifies key rotation.
76
+ #
77
+ # ### KMS Encryption Key Id
78
+ #
79
+ # If you pass the id to an AWS Key Management Service (KMS) key,
80
+ # then KMS will be used to generate, encrypt and decrypt object keys.
81
+ #
82
+ # # keep track of the kms key id
83
+ # kms = Aws::KMS::Client.new
84
+ # key_id = kms.create_key.key_metadata.key_id
85
+ #
86
+ # Aws::S3::Encryption::Client.new(
87
+ # kms_key_id: key_id,
88
+ # kms_client: kms,
89
+ # )
90
+ #
91
+ # ## Custom Key Providers
92
+ #
93
+ # A {KeyProvider} is any object that responds to:
94
+ #
95
+ # * `#encryption_materials`
96
+ # * `#key_for(materials_description)`
97
+ #
98
+ # Here is a trivial implementation of an in-memory key provider.
99
+ # This is provided as a demonstration of the key provider interface,
100
+ # and should not be used in production:
101
+ #
102
+ # class KeyProvider
103
+ #
104
+ # def initialize(default_key_name, keys)
105
+ # @keys = keys
106
+ # @encryption_materials = Aws::S3::Encryption::Materials.new(
107
+ # key: @keys[default_key_name],
108
+ # description: JSON.dump(key: default_key_name),
109
+ # )
110
+ # end
111
+ #
112
+ # attr_reader :encryption_materials
113
+ #
114
+ # def key_for(matdesc)
115
+ # key_name = JSON.load(matdesc)['key']
116
+ # if key = @keys[key_name]
117
+ # key
118
+ # else
119
+ # raise "encryption key not found for: #{matdesc.inspect}"
120
+ # end
121
+ # end
122
+ # end
123
+ #
124
+ # Given the above key provider, you can create an encryption client that
125
+ # chooses the key to use based on the materials description stored with
126
+ # the encrypted object. This makes it possible to use multiple keys
127
+ # and simplifies key rotation.
128
+ #
129
+ # # uses "new-key" for encrypting objects, uses either for decrypting
130
+ # keys = KeyProvider.new('new-key', {
131
+ # "old-key" => Base64.decode64("kM5UVbhE/4rtMZJfsadYEdm2vaKFsmV2f5+URSeUCV4="),
132
+ # "new-key" => Base64.decode64("w1WLio3agRWRTSJK/Ouh8NHoqRQ6fn5WbSXDTHjXMSo="),
133
+ # }),
134
+ #
135
+ # # chooses the key based on the materials description stored
136
+ # # with the encrypted object
137
+ # s3 = Aws::S3::Encryption::Client.new(key_provider: keys)
138
+ #
139
+ # ## Materials Description
140
+ #
141
+ # A materials description is JSON document string that is stored
142
+ # in the metadata (or instruction file) of an encrypted object.
143
+ # The {DefaultKeyProvider} uses the empty JSON document `"{}"`.
144
+ #
145
+ # When building a key provider, you are free to store whatever
146
+ # information you need to identify the master key that was used
147
+ # to encrypt the object.
148
+ #
149
+ # ## Envelope Location
150
+ #
151
+ # By default, the encryption client store the encryption envelope
152
+ # with the object, as metadata. You can choose to have the envelope
153
+ # stored in a separate "instruction file". An instruction file
154
+ # is an object, with the key of the encrypted object, suffixed with
155
+ # `".instruction"`.
156
+ #
157
+ # Specify the `:envelope_location` option as `:instruction_file` to
158
+ # use an instruction file for storing the envelope.
159
+ #
160
+ # # default behavior
161
+ # s3 = Aws::S3::Encryption::Client.new(
162
+ # key_provider: ...,
163
+ # envelope_location: :metadata,
164
+ # )
165
+ #
166
+ # # store envelope in a separate object
167
+ # s3 = Aws::S3::Encryption::Client.new(
168
+ # key_provider: ...,
169
+ # envelope_location: :instruction_file,
170
+ # instruction_file_suffix: '.instruction' # default
171
+ # )
172
+ #
173
+ # When using an instruction file, multiple requests are made when
174
+ # putting and getting the object. **This may cause issues if you are
175
+ # issuing concurrent PUT and GET requests to an encrypted object.**
176
+ #
177
+ module Encryption
178
+ class Client
179
+
180
+ extend Deprecations
181
+
182
+ # Creates a new encryption client. You must provide on of the following
183
+ # options:
184
+ #
185
+ # * `:encryption_key`
186
+ # * `:kms_key_id`
187
+ # * `:key_provider`
188
+ #
189
+ # You may also pass any other options accepted by {S3::Client#initialize}.
190
+ #
191
+ # @option options [S3::Client] :client A basic S3 client that is used
192
+ # to make api calls. If a `:client` is not provided, a new {S3::Client}
193
+ # will be constructed.
194
+ #
195
+ # @option options [OpenSSL::PKey::RSA, String] :encryption_key The master
196
+ # key to use for encrypting/decrypting all objects.
197
+ #
198
+ # @option options [String] :kms_key_id When you provide a `:kms_key_id`,
199
+ # then AWS Key Management Service (KMS) will be used to manage the
200
+ # object encryption keys. By default a {KMS::Client} will be
201
+ # constructed for KMS API calls. Alternatively, you can provide
202
+ # your own via `:kms_client`.
203
+ #
204
+ # @option options [#key_for] :key_provider Any object that responds
205
+ # to `#key_for`. This method should accept a materials description
206
+ # JSON document string and return return an encryption key.
207
+ #
208
+ # @option options [Symbol] :envelope_location (:metadata) Where to
209
+ # store the envelope encryption keys. By default, the envelope is
210
+ # stored with the encrypted object. If you pass `:instruction_file`,
211
+ # then the envelope is stored in a separate object in Amazon S3.
212
+ #
213
+ # @option options [String] :instruction_file_suffix ('.instruction')
214
+ # When `:envelope_location` is `:instruction_file` then the
215
+ # instruction file uses the object key with this suffix appended.
216
+ #
217
+ # @option options [KMS::Client] :kms_client A default {KMS::Client}
218
+ # is constructed when using KMS to manage encryption keys.
219
+ #
220
+ def initialize(options = {})
221
+ @client = extract_client(options)
222
+ @cipher_provider = cipher_provider(options)
223
+ @envelope_location = extract_location(options)
224
+ @instruction_file_suffix = extract_suffix(options)
225
+ end
226
+
227
+ # @return [S3::Client]
228
+ attr_reader :client
229
+
230
+ # @return [KeyProvider, nil] Returns `nil` if you are using
231
+ # AWS Key Management Service (KMS).
232
+ attr_reader :key_provider
233
+
234
+ # @return [Symbol<:metadata, :instruction_file>]
235
+ attr_reader :envelope_location
236
+
237
+ # @return [String] When {#envelope_location} is `:instruction_file`,
238
+ # the envelope is stored in the object with the object key suffixed
239
+ # by this string.
240
+ attr_reader :instruction_file_suffix
241
+
242
+ # Uploads an object to Amazon S3, encrypting data client-side.
243
+ # See {S3::Client#put_object} for documentation on accepted
244
+ # request parameters.
245
+ # @option (see S3::Client#put_object)
246
+ # @return (see S3::Client#put_object)
247
+ # @see S3::Client#put_object
248
+ def put_object(params = {})
249
+ req = @client.build_request(:put_object, params)
250
+ req.handlers.add(EncryptHandler, priority: 95)
251
+ req.context[:encryption] = {
252
+ cipher_provider: @cipher_provider,
253
+ envelope_location: @envelope_location,
254
+ instruction_file_suffix: @instruction_file_suffix,
255
+ }
256
+ req.send_request
257
+ end
258
+
259
+ # Gets an object from Amazon S3, decrypting data locally.
260
+ # See {S3::Client#get_object} for documentation on accepted
261
+ # request parameters.
262
+ # @option params [String] :instruction_file_suffix The suffix
263
+ # used to find the instruction file containing the encryption
264
+ # envelope. You should not set this option when the envelope
265
+ # is stored in the object metadata. Defaults to
266
+ # {#instruction_file_suffix}.
267
+ # @option params [String] :instruction_file_suffix
268
+ # @option (see S3::Client#get_object)
269
+ # @return (see S3::Client#get_object)
270
+ # @see S3::Client#get_object
271
+ # @note The `:range` request parameter is not yet supported.
272
+ def get_object(params = {}, &block)
273
+ if params[:range]
274
+ raise NotImplementedError, '#get_object with :range not supported yet'
275
+ end
276
+ envelope_location, instruction_file_suffix = envelope_options(params)
277
+ req = @client.build_request(:get_object, params)
278
+ req.handlers.add(DecryptHandler)
279
+ req.context[:encryption] = {
280
+ cipher_provider: @cipher_provider,
281
+ envelope_location: envelope_location,
282
+ instruction_file_suffix: instruction_file_suffix,
283
+ }
284
+ req.send_request(target: block)
285
+ end
286
+
287
+ private
288
+
289
+ def extract_client(options)
290
+ options[:client] || begin
291
+ options = options.dup
292
+ options.delete(:kms_key_id)
293
+ options.delete(:kms_client)
294
+ options.delete(:key_provider)
295
+ options.delete(:encryption_key)
296
+ options.delete(:envelope_location)
297
+ options.delete(:instruction_file_suffix)
298
+ S3::Client.new(options)
299
+ end
300
+ end
301
+
302
+ def kms_client(options)
303
+ options[:kms_client] || begin
304
+ KMS::Client.new(
305
+ region: @client.config.region,
306
+ credentials: @client.config.credentials,
307
+ )
308
+ end
309
+ end
310
+
311
+ def cipher_provider(options)
312
+ if options[:kms_key_id]
313
+ KmsCipherProvider.new(
314
+ kms_key_id: options[:kms_key_id],
315
+ kms_client: kms_client(options),
316
+ )
317
+ else
318
+ # kept here for backwards compatability, {#key_provider} is deprecated
319
+ @key_provider = extract_key_provider(options)
320
+ DefaultCipherProvider.new(key_provider: @key_provider)
321
+ end
322
+ end
323
+
324
+ def extract_key_provider(options)
325
+ if options[:key_provider]
326
+ options[:key_provider]
327
+ elsif options[:encryption_key]
328
+ DefaultKeyProvider.new(options)
329
+ else
330
+ msg = "you must pass a :kms_key_id, :key_provider, or :encryption_key"
331
+ raise ArgumentError, msg
332
+ end
333
+ end
334
+
335
+ def envelope_options(params)
336
+ location = params.delete(:envelope_location) || @envelope_location
337
+ suffix = params.delete(:instruction_file_suffix)
338
+ if suffix
339
+ [:instruction_file, suffix]
340
+ else
341
+ [location, @instruction_file_suffix]
342
+ end
343
+ end
344
+
345
+ def extract_location(options)
346
+ location = options[:envelope_location] || :metadata
347
+ if [:metadata, :instruction_file].include?(location)
348
+ location
349
+ else
350
+ msg = ":envelope_location must be :metadata or :instruction_file "
351
+ msg << "got #{location.inspect}"
352
+ raise ArgumentError, msg
353
+ end
354
+ end
355
+
356
+ def extract_suffix(options)
357
+ suffix = options[:instruction_file_suffix] || '.instruction'
358
+ if String === suffix
359
+ suffix
360
+ else
361
+ msg = ":instruction_file_suffix must be a String"
362
+ raise ArgumentError, msg
363
+ end
364
+ end
365
+
366
+ end
367
+ end
368
+ end
369
+ end