aws-sdk-s3 1.0.0.rc1

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 (69) hide show
  1. checksums.yaml +7 -0
  2. data/lib/aws-sdk-s3.rb +66 -0
  3. data/lib/aws-sdk-s3/bucket.rb +595 -0
  4. data/lib/aws-sdk-s3/bucket_acl.rb +168 -0
  5. data/lib/aws-sdk-s3/bucket_cors.rb +146 -0
  6. data/lib/aws-sdk-s3/bucket_lifecycle.rb +164 -0
  7. data/lib/aws-sdk-s3/bucket_logging.rb +142 -0
  8. data/lib/aws-sdk-s3/bucket_notification.rb +187 -0
  9. data/lib/aws-sdk-s3/bucket_policy.rb +138 -0
  10. data/lib/aws-sdk-s3/bucket_region_cache.rb +79 -0
  11. data/lib/aws-sdk-s3/bucket_request_payment.rb +128 -0
  12. data/lib/aws-sdk-s3/bucket_tagging.rb +143 -0
  13. data/lib/aws-sdk-s3/bucket_versioning.rb +188 -0
  14. data/lib/aws-sdk-s3/bucket_website.rb +177 -0
  15. data/lib/aws-sdk-s3/client.rb +3171 -0
  16. data/lib/aws-sdk-s3/client_api.rb +1991 -0
  17. data/lib/aws-sdk-s3/customizations.rb +29 -0
  18. data/lib/aws-sdk-s3/customizations/bucket.rb +127 -0
  19. data/lib/aws-sdk-s3/customizations/multipart_upload.rb +42 -0
  20. data/lib/aws-sdk-s3/customizations/object.rb +257 -0
  21. data/lib/aws-sdk-s3/customizations/object_summary.rb +65 -0
  22. data/lib/aws-sdk-s3/customizations/types/list_object_versions_output.rb +11 -0
  23. data/lib/aws-sdk-s3/encryption.rb +19 -0
  24. data/lib/aws-sdk-s3/encryption/client.rb +369 -0
  25. data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +178 -0
  26. data/lib/aws-sdk-s3/encryption/default_cipher_provider.rb +63 -0
  27. data/lib/aws-sdk-s3/encryption/default_key_provider.rb +38 -0
  28. data/lib/aws-sdk-s3/encryption/encrypt_handler.rb +50 -0
  29. data/lib/aws-sdk-s3/encryption/errors.rb +13 -0
  30. data/lib/aws-sdk-s3/encryption/io_auth_decrypter.rb +50 -0
  31. data/lib/aws-sdk-s3/encryption/io_decrypter.rb +29 -0
  32. data/lib/aws-sdk-s3/encryption/io_encrypter.rb +69 -0
  33. data/lib/aws-sdk-s3/encryption/key_provider.rb +29 -0
  34. data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +71 -0
  35. data/lib/aws-sdk-s3/encryption/materials.rb +58 -0
  36. data/lib/aws-sdk-s3/encryption/utils.rb +79 -0
  37. data/lib/aws-sdk-s3/errors.rb +23 -0
  38. data/lib/aws-sdk-s3/file_part.rb +75 -0
  39. data/lib/aws-sdk-s3/file_uploader.rb +58 -0
  40. data/lib/aws-sdk-s3/legacy_signer.rb +186 -0
  41. data/lib/aws-sdk-s3/multipart_file_uploader.rb +187 -0
  42. data/lib/aws-sdk-s3/multipart_upload.rb +287 -0
  43. data/lib/aws-sdk-s3/multipart_upload_error.rb +16 -0
  44. data/lib/aws-sdk-s3/multipart_upload_part.rb +314 -0
  45. data/lib/aws-sdk-s3/object.rb +942 -0
  46. data/lib/aws-sdk-s3/object_acl.rb +214 -0
  47. data/lib/aws-sdk-s3/object_copier.rb +99 -0
  48. data/lib/aws-sdk-s3/object_multipart_copier.rb +179 -0
  49. data/lib/aws-sdk-s3/object_summary.rb +794 -0
  50. data/lib/aws-sdk-s3/object_version.rb +406 -0
  51. data/lib/aws-sdk-s3/plugins/accelerate.rb +92 -0
  52. data/lib/aws-sdk-s3/plugins/bucket_dns.rb +89 -0
  53. data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +23 -0
  54. data/lib/aws-sdk-s3/plugins/dualstack.rb +70 -0
  55. data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +29 -0
  56. data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +23 -0
  57. data/lib/aws-sdk-s3/plugins/http_200_errors.rb +47 -0
  58. data/lib/aws-sdk-s3/plugins/location_constraint.rb +33 -0
  59. data/lib/aws-sdk-s3/plugins/md5s.rb +79 -0
  60. data/lib/aws-sdk-s3/plugins/redirects.rb +41 -0
  61. data/lib/aws-sdk-s3/plugins/s3_signer.rb +208 -0
  62. data/lib/aws-sdk-s3/plugins/sse_cpk.rb +68 -0
  63. data/lib/aws-sdk-s3/plugins/url_encoded_keys.rb +94 -0
  64. data/lib/aws-sdk-s3/presigned_post.rb +647 -0
  65. data/lib/aws-sdk-s3/presigner.rb +160 -0
  66. data/lib/aws-sdk-s3/resource.rb +96 -0
  67. data/lib/aws-sdk-s3/types.rb +5750 -0
  68. data/lib/aws-sdk-s3/waiters.rb +178 -0
  69. metadata +154 -0
@@ -0,0 +1,65 @@
1
+ module Aws
2
+ module S3
3
+ class ObjectSummary
4
+
5
+ alias content_length size
6
+
7
+ # @param (see Object#copy_from)
8
+ # @options (see Object#copy_from)
9
+ # @return (see Object#copy_from)
10
+ # @see Object#copy_from
11
+ def copy_from(source, options = {})
12
+ object.copy_from(source, options)
13
+ end
14
+
15
+ # @param (see Object#copy_to)
16
+ # @options (see Object#copy_to)
17
+ # @return (see Object#copy_to)
18
+ # @see Object#copy_to
19
+ def copy_to(target, options = {})
20
+ object.copy_to(target, options)
21
+ end
22
+
23
+ # @param (see Object#move_to)
24
+ # @options (see Object#move_to)
25
+ # @return (see Object#move_to)
26
+ # @see Object#move_to
27
+ def move_to(target, options = {})
28
+ object.move_to(target, options)
29
+ end
30
+
31
+ # @param (see Object#presigned_post)
32
+ # @options (see Object#presigned_post)
33
+ # @return (see Object#presigned_post)
34
+ # @see Object#presigned_post
35
+ def presigned_post(options = {})
36
+ object.presigned_post(options)
37
+ end
38
+
39
+ # @param (see Object#presigned_url)
40
+ # @options (see Object#presigned_url)
41
+ # @return (see Object#presigned_url)
42
+ # @see Object#presigned_url
43
+ def presigned_url(http_method, params = {})
44
+ object.presigned_url(http_method, params)
45
+ end
46
+
47
+ # @param (see Object#public_url)
48
+ # @options (see Object#public_url)
49
+ # @return (see Object#public_url)
50
+ # @see Object#public_url
51
+ def public_url(options = {})
52
+ object.public_url(options)
53
+ end
54
+
55
+ # @param (see Object#upload_file)
56
+ # @options (see Object#upload_file)
57
+ # @return (see Object#upload_file)
58
+ # @see Object#upload_file
59
+ def upload_file(source, options = {})
60
+ object.upload_file(source, options)
61
+ end
62
+
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,11 @@
1
+ class Aws::S3::Types::ListObjectVersionsOutput
2
+
3
+ # TODO : Remove this customization once the resource code
4
+ # generator correct handles the JMESPath || expression.
5
+ # Only used by the Bucket#object_versions collection.
6
+ # @api private
7
+ def versions_delete_markers
8
+ versions + delete_markers
9
+ end
10
+
11
+ end
@@ -0,0 +1,19 @@
1
+ require 'aws-sdk-s3/encryption/client'
2
+ require 'aws-sdk-s3/encryption/decrypt_handler'
3
+ require 'aws-sdk-s3/encryption/default_cipher_provider'
4
+ require 'aws-sdk-s3/encryption/encrypt_handler'
5
+ require 'aws-sdk-s3/encryption/errors'
6
+ require 'aws-sdk-s3/encryption/io_encrypter'
7
+ require 'aws-sdk-s3/encryption/io_decrypter'
8
+ require 'aws-sdk-s3/encryption/io_auth_decrypter'
9
+ require 'aws-sdk-s3/encryption/key_provider'
10
+ require 'aws-sdk-s3/encryption/kms_cipher_provider'
11
+ require 'aws-sdk-s3/encryption/materials'
12
+ require 'aws-sdk-s3/encryption/utils'
13
+ require 'aws-sdk-s3/encryption/default_key_provider'
14
+
15
+ module Aws
16
+ module S3
17
+ module Encryption; end
18
+ end
19
+ 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 `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