aws-sdk 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,6 +13,7 @@
13
13
 
14
14
  require 'aws/http/request'
15
15
  require 'aws/authorize_v2'
16
+ require 'aws/authorize_with_session_token'
16
17
 
17
18
  module AWS
18
19
  class EC2
@@ -21,6 +22,7 @@ module AWS
21
22
  class Request < AWS::Http::Request
22
23
 
23
24
  include AuthorizeV2
25
+ include AuthorizeWithSessionToken
24
26
 
25
27
  end
26
28
  end
@@ -164,6 +164,25 @@ module AWS
164
164
  end
165
165
  end
166
166
 
167
+ # @private
168
+ module Pattern
169
+
170
+ # def validate value, context = nil
171
+ # unless value =~ regex
172
+ # raise format_error("value to match #{regex}", context)
173
+ # end
174
+ # end
175
+ #
176
+ # def self.apply option, regex
177
+ # option.extend(self)
178
+ # MetaUtils.extend_method(option, :regex) { regex }
179
+ # end
180
+
181
+ def self.apply *args
182
+ end
183
+
184
+ end
185
+
167
186
  # @private
168
187
  module ListMethods
169
188
 
@@ -333,7 +352,9 @@ module AWS
333
352
  value
334
353
  end
335
354
 
336
- def required?; false; end
355
+ def required?
356
+ false
357
+ end
337
358
 
338
359
  def format_error(expected, context = nil)
339
360
  context = context_description(context)
@@ -84,7 +84,7 @@ module AWS
84
84
  if opts.has_key?(:id) or opts.has_key?("Id")
85
85
  @id = opts[:id] || opts["Id"]
86
86
  else
87
- @id = UUIDTools::UUID.timestamp_create.to_s
87
+ @id = UUIDTools::UUID.timestamp_create.to_s.tr('-','')
88
88
  end
89
89
  if opts.has_key?(:version) or opts.has_key?("Version")
90
90
  @version = opts[:version] || opts["Version"]
@@ -119,8 +119,8 @@ module AWS
119
119
  end
120
120
  protected :hash_without_ids
121
121
 
122
- # Returns a hash representation of the policy; the
123
- # following statements are equivalent:
122
+ # Returns a hash representation of the policy. The following
123
+ # statements are equivalent:
124
124
  #
125
125
  # policy.to_h.to_json
126
126
  # policy.to_json
@@ -744,7 +744,7 @@ module AWS
744
744
  # Policy#deny to add conditions to a statement.
745
745
  # @see S3::Client
746
746
  def initialize(opts = {})
747
- self.sid = UUIDTools::UUID.timestamp_create.to_s
747
+ self.sid = UUIDTools::UUID.timestamp_create.to_s.tr('-','')
748
748
  self.conditions = ConditionBlock.new
749
749
 
750
750
  parse_options(opts)
@@ -777,6 +777,8 @@ module AWS
777
777
  "Resource" => resource_arns,
778
778
  "Condition" => (conditions.to_h if conditions)
779
779
  }
780
+ stmt.delete("Condition") if !conditions || conditions.to_h.empty?
781
+ stmt.delete("Principal") unless principals_hash
780
782
  if !translated_actions || translated_actions.empty?
781
783
  stmt["NotAction"] = translated_excluded_actions
782
784
  else
@@ -44,12 +44,19 @@ module AWS
44
44
 
45
45
  # @param [Http::Request] http_request
46
46
  # @param [Http::Response] http_request
47
- def initialize http_request = nil, http_response = nil
47
+ def initialize http_request = nil, http_response = nil, &block
48
48
  @http_request = http_request
49
49
  @http_response = http_response
50
+ @request_builder = block
51
+ rebuild_request if @request_builder && !http_request
50
52
  end
51
53
 
52
- # @return [Boolean] Teturns true unless there is a response error.
54
+ # Rebuilds the HTTP request using the block passed to the initializer
55
+ def rebuild_request
56
+ @http_request = @request_builder.call
57
+ end
58
+
59
+ # @return [Boolean] Returns true unless there is a response error.
53
60
  def successful?
54
61
  error.nil?
55
62
  end
@@ -16,6 +16,7 @@ require 'aws/http/response'
16
16
  require 'aws/base_client'
17
17
  require 'aws/s3/errors'
18
18
  require 'aws/s3/data_options'
19
+ require 'aws/uri_escape'
19
20
  require 'aws/s3/access_control_list'
20
21
  require 'aws/s3/policy'
21
22
  require 'aws/s3/client/xml'
@@ -84,6 +85,7 @@ module AWS
84
85
  }
85
86
 
86
87
  include DataOptions
88
+ include UriEscape
87
89
 
88
90
  configure_client
89
91
 
@@ -786,10 +788,13 @@ module AWS
786
788
  ) do
787
789
 
788
790
  configure_request do |req, options|
789
- # TODO : validate presence of copy source
790
791
  # TODO : validate metadata directive COPY / REPLACE
791
792
  # TODO : validate storage class STANDARD / REDUCED_REDUNDANCY
792
793
  # TODO : add validations for storage class in other places used
794
+ validate!(:copy_source, options[:copy_source]) do
795
+ "may not be blank" if options[:copy_source].to_s.empty?
796
+ end
797
+ options = options.merge(:copy_source => escape_path(options[:copy_source]))
793
798
  super(req, options)
794
799
  req.canned_acl = options[:acl]
795
800
  req.metadata = options[:metadata]
@@ -34,20 +34,51 @@ module AWS
34
34
  # @return [S3Object]
35
35
  attr_reader :object
36
36
 
37
- # Returns the value for the given name stored in the S3Objects
37
+ # Returns the value for the given name stored in the S3Object's
38
38
  # metadata:
39
39
  #
40
40
  # bucket.objects['myobject'].metadata['purpose']
41
41
  # # returns nil if the given metadata key has not been set
42
42
  #
43
+ # @param [String,Symbol] name The name of the metadata field to
44
+ # get.
45
+ #
43
46
  # @return [String,nil] Returns the metadata for the given name.
44
47
  def [] name
45
48
  to_h[name.to_s]
46
49
  end
47
50
 
51
+ # Changes the value of the given name stored in the S3Object's
52
+ # metadata:
53
+ #
54
+ # object = bucket.object['myobject']
55
+ # object.metadata['purpose'] = 'research'
56
+ # object.metadata['purpose'] # => 'research'
57
+ #
58
+ # @note The name and value of each metadata field must conform
59
+ # to US-ASCII.
60
+ #
61
+ # @param [String,Symbol] name The name of the metadata field to
62
+ # set.
63
+ #
64
+ # @param [String] value The new value of the metadata field.
65
+ #
66
+ # @return [String,nil] Returns the value that was set.
67
+ def []= name, value
68
+ raise "cannot change the metadata of an object version; "+
69
+ "use S3Object#write to create a new version with different metadata" if
70
+ @version_id
71
+ metadata = to_h.dup
72
+ metadata[name.to_s] = value
73
+ object.copy_from(object.key,
74
+ :metadata => metadata)
75
+ value
76
+ end
77
+
48
78
  # Proxies the method to {#[]}.
49
79
  # @return (see #[])
50
- def method_missing name
80
+ def method_missing name, *args, &blk
81
+ return super if !args.empty? || blk
51
82
  self[name]
52
83
  end
53
84
 
@@ -174,6 +174,10 @@ module AWS
174
174
  end
175
175
 
176
176
  def add_authorization!(signer)
177
+ if signer.respond_to?(:session_token) and
178
+ token = signer.session_token
179
+ headers["x-amz-security-token"] = token
180
+ end
177
181
  signature = URI.escape(signer.sign(string_to_sign, 'sha1'))
178
182
  headers["authorization"] = "AWS #{signer.access_key_id}:#{signature}"
179
183
  end
@@ -229,10 +229,12 @@ module AWS
229
229
  #
230
230
  # @option options [Hash] :metadata A hash of metadata to be
231
231
  # included with the object. These will be sent to S3 as
232
- # headers prefixed with +x-amz-meta+.
232
+ # headers prefixed with +x-amz-meta+. Each name, value pair
233
+ # must conform to US-ASCII.
234
+ #
235
+ # @option options [Symbol] :acl (private) A canned access
236
+ # control policy. Valid values are:
233
237
  #
234
- # @option options [Symbol] :acl A canned access control
235
- # policy. Valid values are:
236
238
  # * +:private+
237
239
  # * +:public_read+
238
240
  # * +:public_read_write+
@@ -333,10 +335,12 @@ module AWS
333
335
  #
334
336
  # @option options [Hash] :metadata A hash of metadata to be
335
337
  # included with the object. These will be sent to S3 as
336
- # headers prefixed with +x-amz-meta+.
338
+ # headers prefixed with +x-amz-meta+. Each name, value pair
339
+ # must conform to US-ASCII.
340
+ #
341
+ # @option options [Symbol] :acl (private) A canned access
342
+ # control policy. Valid values are:
337
343
  #
338
- # @option options [Symbol] :acl A canned access control
339
- # policy. Valid values are:
340
344
  # * +:private+
341
345
  # * +:public_read+
342
346
  # * +:public_read_write+
@@ -344,9 +348,9 @@ module AWS
344
348
  # * +:bucket_owner_read+
345
349
  # * +:bucket_owner_full_control+
346
350
  #
347
- # @option options [Boolean] :reduced_redundancy If true,
348
- # Reduced Redundancy Storage will be enabled for the
349
- # uploaded object.
351
+ # @option options [Boolean] :reduced_redundancy (false) If true,
352
+ # Reduced Redundancy Storage will be enabled for the uploaded
353
+ # object.
350
354
  #
351
355
  # @option options :cache_control [String] Can be used to specify
352
356
  # caching behavior. See
@@ -403,18 +407,36 @@ module AWS
403
407
  # metadata of the object when copying.
404
408
  #
405
409
  # @param [Mixed] source
410
+ #
406
411
  # @param [Hash] options
412
+ #
407
413
  # @option options [String] :bucket_name The name of the bucket
408
414
  # the source object can be found in. Defaults to the current
409
415
  # object's bucket.
410
- # @option options [Bucket] :bucket The bucket the source object can
411
- # be found in. Defaults to the current object's bucket.
412
- # @option options [Hash] :metadata A hash of metadata to save with
413
- # the copied object. When blank, the sources metadata is copied.
416
+ #
417
+ # @option options [Bucket] :bucket The bucket the source object
418
+ # can be found in. Defaults to the current object's bucket.
419
+ #
420
+ # @option options [Hash] :metadata A hash of metadata to save
421
+ # with the copied object. Each name, value pair must conform
422
+ # to US-ASCII. When blank, the sources metadata is copied.
423
+ #
414
424
  # @option options [Boolean] :reduced_redundancy (false) If true the
415
425
  # object is stored with reduced redundancy in S3 for a lower cost.
416
- # @option options [String] :version_id (nil) Causes the copy to
426
+ #
427
+ # @option options [String] :version_id (nil) Causes the copy to
417
428
  # read a specific version of the source object.
429
+ #
430
+ # @option options [Symbol] :acl (private) A canned access
431
+ # control policy. Valid values are:
432
+ #
433
+ # * +:private+
434
+ # * +:public_read+
435
+ # * +:public_read_write+
436
+ # * +:authenticated_read+
437
+ # * +:bucket_owner_read+
438
+ # * +:bucket_owner_full_control+
439
+ #
418
440
  # @return [nil]
419
441
  def copy_from source, options = {}
420
442
 
@@ -441,10 +463,14 @@ module AWS
441
463
  copy_opts[:metadata_directive] = 'COPY'
442
464
  end
443
465
 
466
+ copy_opts[:acl] = options[:acl] if options[:acl]
444
467
  copy_opts[:version_id] = options[:version_id] if options[:version_id]
445
468
 
446
- copy_opts[:storage_class] = 'REDUCED_REDUNDANCY' if
447
- options[:reduced_redundancy]
469
+ if options[:reduced_redundancy]
470
+ copy_opts[:storage_class] = 'REDUCED_REDUNDANCY'
471
+ else
472
+ copy_opts[:storage_class] = 'STANDARD'
473
+ end
448
474
 
449
475
  client.copy_object(copy_opts)
450
476
 
@@ -460,16 +486,24 @@ module AWS
460
486
  #
461
487
  # @param [S3Object,String] target An S3Object, or a string key of
462
488
  # and object to copy to.
489
+ #
463
490
  # @param [Hash] options
491
+ #
464
492
  # @option options [String] :bucket_name The name of the bucket
465
493
  # the object should be copied into. Defaults to the current object's
466
494
  # bucket.
495
+ #
467
496
  # @option options [Bucket] :bucket The bucket the target object
468
497
  # should be copied into. Defaults to the current object's bucket.
469
- # @option options [Hash] :metadata A hash of metadata to save with
470
- # the copied object. When blank, the sources metadata is copied.
471
- # @option options [Boolean] :reduced_redundancy (false) If true the
472
- # object is stored with reduced redundancy in S3 for a lower cost.
498
+ #
499
+ # @option options [Hash] :metadata A hash of metadata to save
500
+ # with the copied object. Each name, value pair must conform
501
+ # to US-ASCII. When blank, the sources metadata is copied.
502
+ #
503
+ # @option options [Boolean] :reduced_redundancy (false) If true
504
+ # the object is stored with reduced redundancy in S3 for a
505
+ # lower cost.
506
+ #
473
507
  # @return (see #copy_from)
474
508
  def copy_to target, options = {}
475
509
 
@@ -689,6 +723,23 @@ module AWS
689
723
  PresignedPost.new(bucket, options.merge(:key => key))
690
724
  end
691
725
 
726
+ # @note Changing the storage class of an object incurs a COPY
727
+ # operation.
728
+ #
729
+ # Changes the storage class of the object to enable or disable
730
+ # Reduced Redundancy Storage (RRS).
731
+ #
732
+ # @param [true,false] value If this is true, the object will be
733
+ # copied in place and stored with reduced redundancy at a
734
+ # lower cost. Otherwise, the object will be copied and stored
735
+ # with the standard storage class.
736
+ #
737
+ # @return [true,false] The +value+ parameter.
738
+ def reduced_redundancy= value
739
+ copy_from(key, :reduced_redundancy => value)
740
+ value
741
+ end
742
+
692
743
  # @private
693
744
  private
694
745
  def build_uri(secure, request)
@@ -13,6 +13,7 @@
13
13
 
14
14
  require 'aws/http/request'
15
15
  require 'aws/authorize_v2'
16
+ require 'aws/authorize_with_session_token'
16
17
 
17
18
  module AWS
18
19
  class SNS
@@ -21,6 +22,7 @@ module AWS
21
22
  class Request < AWS::Http::Request
22
23
 
23
24
  include AuthorizeV2
25
+ include AuthorizeWithSessionToken
24
26
 
25
27
  end
26
28
  end
@@ -13,6 +13,7 @@
13
13
 
14
14
  require 'aws/http/request'
15
15
  require 'aws/authorize_v2'
16
+ require 'aws/authorize_with_session_token'
16
17
 
17
18
  module AWS
18
19
  class SQS
@@ -21,7 +22,8 @@ module AWS
21
22
  class Request < AWS::Http::Request
22
23
 
23
24
  include AuthorizeV2
24
-
25
+ include AuthorizeWithSessionToken
26
+
25
27
  def path
26
28
  full_url.path
27
29
  end
@@ -0,0 +1,143 @@
1
+ # Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+ require 'aws/service_interface'
15
+ require 'aws/sts/client'
16
+ require 'aws/sts/session'
17
+ require 'aws/sts/federated_session'
18
+ require 'aws/sts/policy'
19
+
20
+ module AWS
21
+
22
+ # This class is a starting point for working with the AWS Security
23
+ # Token Service. The AWS Security Token Service is a web service
24
+ # that enables you to request temporary, limited-privilege
25
+ # credentials for users that you authenticate (federated users), or
26
+ # IAM users.
27
+ #
28
+ # @example Getting temporary credentials and using them to make an EC2 request
29
+ # sts = AWS::STS.new(:access_key_id => "LONG_TERM_KEY",
30
+ # :secret_access_key => "LONG_TERM_SECRET")
31
+ # session = AWS::STS.new.new_session(:duration => 60*60)
32
+ # ec2 = AWS::EC2.new(session.credentials)
33
+ # ec2.instances.to_a
34
+ #
35
+ # @example Getting temporary credentials with restricted permissions
36
+ # policy = AWS::STS::Policy.new
37
+ # policy.allow(:actions => ["s3:*", "ec2:*"],
38
+ # :resources => :any)
39
+ # session = sts.new_federated_session("TemporaryUser", :policy => policy)
40
+ # ec2 = AWS::EC2.new(session.credentials)
41
+ # ec2.instances.to_a
42
+ #
43
+ class STS
44
+
45
+ include ServiceInterface
46
+
47
+ # Returns a set of temporary credentials for an AWS account or IAM
48
+ # User. The credentials consist of an Access Key ID, a Secret
49
+ # Access Key, and a security token. These credentials are valid
50
+ # for the specified duration only. The session duration for IAM
51
+ # users can be between one and 36 hours, with a default of 12
52
+ # hours. The session duration for AWS account owners is restricted
53
+ # to one hour.
54
+ #
55
+ # @param [Hash] opts Options for getting temporary credentials.
56
+ #
57
+ # @option opts [Integer] :duration The duration, in seconds, that
58
+ # the session should last. Acceptable durations for IAM user
59
+ # sessions range from 3600s (one hour) to 129600s (36 hours),
60
+ # with 43200s (12 hours) as the default. Sessions for AWS
61
+ # account owners are restricted to a maximum of 3600s (one
62
+ # hour).
63
+ #
64
+ # @return [Session]
65
+ def new_session(opts = {})
66
+ get_session(:get_session_token, opts) do |resp, session_opts|
67
+ Session.new(session_opts)
68
+ end
69
+ end
70
+
71
+ # Returns a set of temporary credentials for a federated user with
72
+ # the user name and policy specified in the request. The
73
+ # credentials consist of an Access Key ID, a Secret Access Key,
74
+ # and a security token. The credentials are valid for the
75
+ # specified duration, between one and 36 hours.
76
+ #
77
+ # The federated user who holds these credentials has only those
78
+ # permissions allowed by intersection of the specified policy and
79
+ # any resource or user policies that apply to the caller of the
80
+ # GetFederationToken API. For more information about how token
81
+ # permissions work, see
82
+ # {http://docs.amazonwebservices.com/IAM/latest/UserGuide/TokenPermissions.html
83
+ # Controlling Token Permissions} in Using AWS Identity and Access
84
+ # Management.
85
+ #
86
+ # @param [String] name The name of the federated user associated
87
+ # with the session. Must be between 2 and 32 characters in
88
+ # length.
89
+ #
90
+ # @param [Hash] opts Options for getting temporary credentials.
91
+ #
92
+ # @option opts [Integer] :duration The duration, in seconds, that
93
+ # the session should last. Acceptable durations for federation
94
+ # sessions range from 3600s (one hour) to 129600s (36 hours),
95
+ # with 43200s (12 hours) as the default.
96
+ #
97
+ # @option opts [String, AWS::STS::Policy] :policy A policy
98
+ # specifying the permissions to associate with the session. The
99
+ # caller can delegate their own permissions by specifying a
100
+ # policy for the session, and both policies will be checked when
101
+ # a service call is made. In other words, permissions of the
102
+ # session credentials are the intersection of the policy
103
+ # specified in the API and the policies associated with the user
104
+ # who issued the session.
105
+ #
106
+ # @return [FederatedSession]
107
+ def new_federated_session(name, opts = {})
108
+ opts = opts.merge(:name => name)
109
+ case
110
+ when opts[:policy].kind_of?(String) || !opts[:policy]
111
+ # leave it alone
112
+ when opts[:policy].respond_to?(:to_json)
113
+ opts[:policy] = opts[:policy].to_json
114
+ end
115
+ get_session(:get_federation_token, opts) do |resp, session_opts|
116
+ session_opts.merge!(:user_id => resp.federated_user.federated_user_id,
117
+ :user_arn => resp.federated_user.arn,
118
+ :packed_policy_size => resp.packed_policy_size)
119
+ FederatedSession.new(session_opts)
120
+ end
121
+ end
122
+
123
+ # @private
124
+ protected
125
+ def get_session(method, opts = {})
126
+ opts[:duration_seconds] = opts.delete(:duration) if
127
+ opts[:duration]
128
+ resp = client.send(method, opts)
129
+ credentials = resp.credentials
130
+ session_opts = {
131
+ :credentials => {
132
+ :access_key_id => credentials.access_key_id,
133
+ :secret_access_key => credentials.secret_access_key,
134
+ :session_token => credentials.session_token
135
+ },
136
+ :expires_at => credentials.expiration
137
+ }
138
+ yield(resp, session_opts)
139
+ end
140
+
141
+ end
142
+
143
+ end