aws-sdk-s3 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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