simple_aws 0.0.1c → 0.0.1d

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.
data/README.md CHANGED
@@ -122,10 +122,6 @@ These are the following Amazon APIs that SimpleAWS currently handles:
122
122
  * Mechanical Turk
123
123
  * SQS (Simple Queue Service)
124
124
  * SES (Simple Email Service)
125
-
126
- Yet to be Implemented
127
- ---------------------
128
-
129
125
  * CloudFront
130
126
 
131
127
  Currently Out-Of-Scope
@@ -0,0 +1,117 @@
1
+ require 'aws/api'
2
+ require 'aws/core/util'
3
+
4
+ module AWS
5
+
6
+ ##
7
+ # Amazon's CloudFront
8
+ #
9
+ # http://docs.amazonwebservices.com/AmazonCloudFront/latest/APIReference/Welcome.html
10
+ #
11
+ # As CloudFront is much closer to a RESTful service than the other AWS APIs, all
12
+ # calls through this API are done through these four HTTP METHODS:
13
+ # GET, PUT, DELETE, and POST.
14
+ #
15
+ # The paths for all request get the version prepended on to them, you do not
16
+ # have to worry about that part of the path. Outside of this, in keeping with
17
+ # the goals of SimpleAWS, everything else should be exactly as you read it in
18
+ # the AWS API docs in the link above.
19
+ #
20
+ # So "GET Distribution List" is
21
+ #
22
+ # cloud_front.get "/distribution"
23
+ #
24
+ # For requests that need extra parameters, use the :params option
25
+ #
26
+ # cloud_front.get "/distribution", :params => {
27
+ # "MaxItems" => 10
28
+ # }
29
+ #
30
+ # Like :params, use :headers to add headers to the request
31
+ #
32
+ # cloud_front.get "/distribution", :headers => {
33
+ # "x-amz-security-token" => "security string"
34
+ # }
35
+ #
36
+ # The details of CloudFront requests are all passed through XML bodies.
37
+ # To make this as simple and painless as possible, this API supports the
38
+ # :xml option to turn a Hash into an XML string
39
+ #
40
+ # cloud_front.post "/distribution", :xml => {
41
+ # :DistributionConfig => {
42
+ # ...
43
+ # }
44
+ # }
45
+ #
46
+ # Do note that this XML building is very simple, does not support attributes,
47
+ # and will only work on Hashes, Arrays, and objects that can be easily #to_s-ed.
48
+ # Anything else will error out or might result in invalid request bodies.
49
+ #
50
+ # If you already have the XML string and just need to give it to the
51
+ # request, you can use :body to set the raw value of the request body:
52
+ #
53
+ # cloud_front.post "/distribution", :body => raw_body_xml
54
+ #
55
+ # All responses are wrapped in an AWS::Response object.
56
+ ##
57
+ class CloudFront < API
58
+ endpoint "cloudfront"
59
+ use_https true
60
+ version "2010-11-01"
61
+
62
+ def initialize(key, secret)
63
+ super(key, secret)
64
+ end
65
+
66
+ [:get, :post, :put, :delete].each do |method|
67
+ define_method(method) do |*args|
68
+ self.call method, *args
69
+ end
70
+ end
71
+
72
+ def call(method, path, options = {})
73
+ request = AWS::Request.new method, self.uri, "/#{self.version}#{path}"
74
+
75
+ (options[:params] || {}).each do |k, v|
76
+ request.params[k] = v
77
+ end
78
+
79
+ (options[:headers] || {}).each do |k, v|
80
+ request.headers[k] = v
81
+ end
82
+
83
+ if xml = options[:xml]
84
+ raise ":xml must be a Hash" unless xml.is_a?(Hash)
85
+
86
+ namespace = "http://cloudfront.amazonaws.com/doc/#{self.version}"
87
+ request.body = AWS::Util.build_xml_from xml, namespace
88
+ request.headers["Content-Type"] = "text/xml"
89
+ else
90
+ request.body = options[:body]
91
+ end
92
+
93
+ connection = AWS::Connection.new
94
+ connection.call finish_and_sign_request(request)
95
+ end
96
+
97
+ protected
98
+
99
+ ##
100
+ # Build and sign the final request, as per the rules here:
101
+ # http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/RESTAuthentication.html
102
+ ##
103
+ def finish_and_sign_request(request)
104
+ request.headers["Date"] = Time.now.utc.httpdate
105
+ request.headers["Authorization"] =
106
+ "AWS #{self.access_key}:#{Base64.encode64(build_signature_for(request)).chomp}"
107
+
108
+ request
109
+ end
110
+
111
+ def build_signature_for(request)
112
+ date = request.headers["x-amz-date"] || request.headers["Date"]
113
+
114
+ OpenSSL::HMAC.digest("sha1", self.secret_key, date)
115
+ end
116
+ end
117
+ end
data/lib/aws/core/util.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'ox'
2
+
1
3
  module AWS
2
4
  ##
3
5
  # Collection of helper methods used in the library
@@ -7,7 +9,7 @@ module AWS
7
9
  ##
8
10
  # Simpler version of ActiveSupport's camelize
9
11
  ##
10
- def self.camelcase(string, lower_first_char = false)
12
+ def camelcase(string, lower_first_char = false)
11
13
  return string if string =~ /[A-Z]/
12
14
 
13
15
  if lower_first_char
@@ -19,7 +21,7 @@ module AWS
19
21
 
20
22
 
21
23
  # AWS URI escaping, as implemented by Fog
22
- def self.uri_escape(string)
24
+ def uri_escape(string)
23
25
  # Quick hack for already escaped string, don't escape again
24
26
  # I don't think any requests require a % in a parameter, but if
25
27
  # there is one I'll need to rethink this
@@ -30,5 +32,52 @@ module AWS
30
32
  }
31
33
  end
32
34
 
35
+ ##
36
+ # Take a hash and build a simple XML string from
37
+ # that Hash. This does not support properties on elements,
38
+ # and is meant for request bodies like what CloudFront expects.
39
+ #
40
+ # The hash body can contain symbols, strings, arrays and hashes
41
+ ##
42
+ def build_xml_from(hash, namespace = nil)
43
+ doc = Ox::Document.new(:version => 1.0, :standalone => true)
44
+
45
+ root_key = hash.keys.first
46
+ root = Ox::Element.new root_key
47
+ root[:xmlns] = namespace if namespace
48
+
49
+ doc << root
50
+
51
+ build_body root, hash[root_key]
52
+
53
+ %|<?xml version="1.0" encoding="UTF-8"?>#{Ox.dump doc}|
54
+ end
55
+
56
+ extend self
57
+
58
+ protected
59
+
60
+ def build_body(parent, hash)
61
+ hash.each do |key, value|
62
+ case value
63
+ when Hash
64
+ node = build_node(key)
65
+ build_body node, value
66
+ parent << node
67
+ when Array
68
+ value.each do |entry|
69
+ build_body parent, {key => entry}
70
+ end
71
+ else
72
+ parent << build_node(key, value)
73
+ end
74
+ end
75
+ end
76
+
77
+ def build_node(key, value = nil)
78
+ child = Ox::Element.new key
79
+ child << value.to_s unless value.nil?
80
+ child
81
+ end
33
82
  end
34
83
  end
data/lib/aws/s3.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'aws/api'
2
- require 'aws/signing/authorization_header'
3
2
 
4
3
  module AWS
5
4
 
@@ -9,7 +8,7 @@ module AWS
9
8
  # http://docs.amazonwebservices.com/AmazonS3/latest/API/Welcome.html
10
9
  #
11
10
  # As S3 is much closer to a RESTful service than the other AWS APIs, all
12
- # calls through this API are done through the four handled HTTP METHODS:
11
+ # calls through this API are done through these five handled HTTP METHODS:
13
12
  # GET, PUT, DELETE, POST and HEAD. When sending a request, follow exactly what
14
13
  # is described in the AWS API docs in the link above.
15
14
  #
@@ -107,8 +106,6 @@ module AWS
107
106
  connection.call finish_and_sign_request(request)
108
107
  end
109
108
 
110
- include Signing::AuthorizationHeader
111
-
112
109
  ##
113
110
  # S3 handles region endpoints a little differently
114
111
  ##
@@ -122,6 +119,39 @@ module AWS
122
119
  @uri
123
120
  end
124
121
 
122
+ protected
123
+
124
+ ##
125
+ # Build and sign the final request, as per the rules here:
126
+ # http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html
127
+ ##
128
+ def finish_and_sign_request(request)
129
+ request.headers["Date"] = Time.now.utc.httpdate
130
+ request.headers["Authorization"] =
131
+ "AWS #{self.access_key}:#{Base64.encode64(build_signature_for(request)).chomp}"
132
+
133
+ request
134
+ end
135
+
136
+ def build_signature_for(request)
137
+ amazon_headers = request.headers.select {|k, v|
138
+ k =~ /^x-amz/i
139
+ }.map {|k, v|
140
+ "#{k.downcase}:#{v}".chomp
141
+ }
142
+
143
+ to_sign = [
144
+ request.method.to_s.upcase,
145
+ request.headers["Content-Md5"] || "",
146
+ request.headers["Content-Type"] || "",
147
+ request.headers["Date"],
148
+ amazon_headers,
149
+ request.path
150
+ ].flatten.join("\n")
151
+
152
+ OpenSSL::HMAC.digest("sha1", self.secret_key, to_sign)
153
+ end
154
+
125
155
  end
126
156
 
127
157
  end
@@ -0,0 +1,52 @@
1
+ $: << File.expand_path("../../lib", __FILE__)
2
+
3
+ require 'aws/cloud_front'
4
+
5
+ ##
6
+ # Expects your Amazon keys to be in the environment, something like
7
+ #
8
+ # export AWS_KEY="KEY"
9
+ # export AWS_SECRET="SECRET"
10
+ ##
11
+
12
+ cloud_front = AWS::CloudFront.new ENV["AWS_KEY"], ENV["AWS_SECRET"]
13
+
14
+ puts "First ten distribution items:", ""
15
+
16
+ cloud_front.get("/distribution", :params => {"MaxItems" => 10}).distribution_summary.each do |d|
17
+ puts "ID: #{d.id}"
18
+ puts "Domain: #{d.domain_name}"
19
+ if d["CustomOrigin"]
20
+ puts "Custom Origin: #{d.custom_origin.inspect}"
21
+ elsif d["S3Origin"]
22
+ puts "S3 Origin: #{d.s3_origin.inspect}"
23
+ end
24
+ puts "Status: #{d.status}"
25
+ puts ""
26
+ end
27
+
28
+ # Leaving this commented out. It works, but you can't quickly
29
+ # delete the new distribution so you'll have to clean up manually
30
+ #
31
+ #puts "", "Creating new test distribution", ""
32
+ #
33
+ #response = cloud_front.post "/distribution", :xml => {
34
+ # "DistributionConfig" => {
35
+ # "CustomOrigin" => {
36
+ # "DNSName" => "cnd.example.com",
37
+ # "HTTPPort" => 80,
38
+ # "OriginProtocolPolicy" => "http-only"
39
+ # },
40
+ # "CallerReference" => "simple_aws_testing_#{rand(100_000)}",
41
+ # "Enabled" => false
42
+ # }
43
+ #}
44
+ #
45
+ #p response
46
+ #
47
+ #id = response.id
48
+ #etag = response.headers["etag"]
49
+ #
50
+ #puts ""
51
+ #puts "Created distribution with id #{id} and etag #{etag}."
52
+ #puts "It's at domain #{response.domain_name}"
data/simple_aws.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "simple_aws"
3
- s.version = "0.0.1c"
3
+ s.version = "0.0.1d"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.authors = ["Jason Roelofs"]
6
6
  s.email = ["jameskilton@gmail.com"]
@@ -0,0 +1,109 @@
1
+ require 'test_helper'
2
+ require 'aws/cloud_front'
3
+
4
+ describe AWS::CloudFront do
5
+
6
+ before do
7
+ @api = AWS::CloudFront.new "key", "secret"
8
+ end
9
+
10
+ it "points to the endpoint" do
11
+ @api.uri.must_equal "https://cloudfront.amazonaws.com"
12
+ end
13
+
14
+ it "does not support region selection" do
15
+ lambda {
16
+ AWS::CloudFront.new "key", "secret", "us-east-1"
17
+ }.must_raise ArgumentError
18
+ end
19
+
20
+ it "works with the current version" do
21
+ @api.version.must_equal "2010-11-01"
22
+ end
23
+
24
+ describe "API calls" do
25
+
26
+ [:get, :post, :put, :delete].each do |method|
27
+ it "supports the #{method} HTTP method" do
28
+ AWS::Connection.any_instance.expects(:call).with do |request|
29
+ request.method.must_equal method
30
+ true
31
+ end
32
+
33
+ @api.send method, "/"
34
+ end
35
+ end
36
+
37
+ it "pre-pends the version to the path for every request" do
38
+ AWS::Connection.any_instance.expects(:call).with do |request|
39
+ request.path.must_equal "/2010-11-01/"
40
+ true
41
+ end
42
+
43
+ @api.get "/"
44
+ end
45
+
46
+ it "takes parameters" do
47
+ AWS::Connection.any_instance.expects(:call).with do |request|
48
+ request.params["Parameter1"].must_equal "Value2"
49
+ true
50
+ end
51
+
52
+ @api.get "/", :params => { "Parameter1" => "Value2" }
53
+ end
54
+
55
+ it "takes a raw body" do
56
+ AWS::Connection.any_instance.expects(:call).with do |request|
57
+ request.body.must_equal "This is a body of text"
58
+ true
59
+ end
60
+
61
+ @api.get "/", :body => "This is a body of text"
62
+ end
63
+
64
+ it "uses :xml to take a hash and build XML from it" do
65
+ AWS::Connection.any_instance.expects(:call).with do |request|
66
+ request.headers["Content-Type"].must_equal "text/xml"
67
+ request.body.must_match(/amazonaws\.com\/doc\//)
68
+ request.body.must_match(/<InnerNode>/)
69
+ true
70
+ end
71
+
72
+ @api.get "/", :xml => {:RootNode => { :InnerNode => "Value" } }
73
+ end
74
+
75
+ it "complains if :xml doesn't contain a Hash" do
76
+ error = lambda {
77
+ @api.get "/", :xml => "not a hash"
78
+ }.must_raise RuntimeError
79
+
80
+ error.message.must_match /must be a Hash/
81
+ end
82
+
83
+ it "takes extra headers" do
84
+ AWS::Connection.any_instance.expects(:call).with do |request|
85
+ request.headers["Header14"].must_equal "Out to Lunch"
86
+ true
87
+ end
88
+
89
+ @api.get "/", :headers => { "Header14" => "Out to Lunch" }
90
+ end
91
+
92
+ it "signs the given request according to Version 3 rules" do
93
+ AWS::Connection.any_instance.expects(:call).with do |request|
94
+ request.headers["Authorization"].wont_be_nil
95
+ header = request.headers["Authorization"]
96
+ parts = header.split(":")
97
+
98
+ parts[0].must_equal "AWS key"
99
+ parts[1].wont_be_nil
100
+
101
+ Time.parse(request.headers["Date"]).wont_be_nil
102
+ true
103
+ end.returns
104
+
105
+ @api.get "/"
106
+ end
107
+ end
108
+
109
+ end
@@ -0,0 +1,86 @@
1
+ require 'test_helper'
2
+ require 'aws/core/util'
3
+
4
+ describe AWS::Util do
5
+
6
+ describe "#build_xml_from" do
7
+ it "takes a hash and builds XML" do
8
+ response = AWS::Util.build_xml_from :RootNode => { :InnerNode => "Value" }
9
+
10
+ response.must_equal <<END
11
+ <?xml version="1.0" encoding="UTF-8"?>
12
+ <RootNode>
13
+ <InnerNode>Value</InnerNode>
14
+ </RootNode>
15
+ END
16
+ end
17
+
18
+ it "will add namespace to the root node" do
19
+ response = AWS::Util.build_xml_from(
20
+ {:RootNode => { :InnerNode => "Value" }},
21
+ "http://cloudfront.amazonaws.com/doc/2010-11-01/"
22
+ )
23
+
24
+ response.must_equal <<END
25
+ <?xml version="1.0" encoding="UTF-8"?>
26
+ <RootNode xmlns="http://cloudfront.amazonaws.com/doc/2010-11-01/">
27
+ <InnerNode>Value</InnerNode>
28
+ </RootNode>
29
+ END
30
+ end
31
+
32
+ it "works with arrays of items" do
33
+ response = AWS::Util.build_xml_from(
34
+ {:RootNode => { :InnerNode => ["Value1", "Value2", "Value3"] }}
35
+ )
36
+
37
+ response.must_equal <<END
38
+ <?xml version="1.0" encoding="UTF-8"?>
39
+ <RootNode>
40
+ <InnerNode>Value1</InnerNode>
41
+ <InnerNode>Value2</InnerNode>
42
+ <InnerNode>Value3</InnerNode>
43
+ </RootNode>
44
+ END
45
+ end
46
+
47
+ it "works at any nestedness of hashes" do
48
+ response = AWS::Util.build_xml_from(
49
+ :RootNode => {
50
+ :InnerNode => [
51
+ {:Child => "Value1"},
52
+ {:Child => "Value2"}
53
+ ]
54
+ }
55
+ )
56
+
57
+ response.must_equal <<END
58
+ <?xml version="1.0" encoding="UTF-8"?>
59
+ <RootNode>
60
+ <InnerNode>
61
+ <Child>Value1</Child>
62
+ </InnerNode>
63
+ <InnerNode>
64
+ <Child>Value2</Child>
65
+ </InnerNode>
66
+ </RootNode>
67
+ END
68
+ end
69
+
70
+ it "auto-strings all leaf nodes" do
71
+ response = AWS::Util.build_xml_from(
72
+ :RootNode => { :BoolVal => true, :Number => 12, :BadBool => false }
73
+ )
74
+
75
+ response.must_equal <<END
76
+ <?xml version="1.0" encoding="UTF-8"?>
77
+ <RootNode>
78
+ <BoolVal>true</BoolVal>
79
+ <Number>12</Number>
80
+ <BadBool>false</BadBool>
81
+ </RootNode>
82
+ END
83
+ end
84
+ end
85
+
86
+ end
data/test/aws/s3_test.rb CHANGED
@@ -96,13 +96,20 @@ describe AWS::S3 do
96
96
  @api.get "/", :file => "This is a body of text"
97
97
  end
98
98
 
99
- it "signs the request using the Authorization header" do
99
+ it "signs the given request according to Version 3 rules" do
100
100
  AWS::Connection.any_instance.expects(:call).with do |request|
101
- request.headers["Authorization"].wont_be_nil
101
+ header = request.headers["Authorization"]
102
+ parts = header.split(":")
103
+
104
+ parts[0].must_equal "AWS key"
105
+ parts[1].wont_be_nil
106
+
107
+ Time.parse(request.headers["Date"]).wont_be_nil
102
108
  true
103
- end
109
+ end.returns
104
110
 
105
111
  @api.get "/"
106
112
  end
113
+
107
114
  end
108
115
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_aws
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1c
4
+ version: 0.0.1d
5
5
  prerelease: 5
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-01-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ox
16
- requirement: &70146086124160 !ruby/object:Gem::Requirement
16
+ requirement: &70172190923080 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70146086124160
24
+ version_requirements: *70172190923080
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: httparty
27
- requirement: &70146086123740 !ruby/object:Gem::Requirement
27
+ requirement: &70172190922660 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70146086123740
35
+ version_requirements: *70172190922660
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: httmultiparty
38
- requirement: &70146086123280 !ruby/object:Gem::Requirement
38
+ requirement: &70172190922220 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70146086123280
46
+ version_requirements: *70172190922220
47
47
  description: The simplest and easiest to use and maintain AWS communication library
48
48
  email:
49
49
  - jameskilton@gmail.com
@@ -60,6 +60,7 @@ files:
60
60
  - lib/aws/auto_scaling.rb
61
61
  - lib/aws/call_types/action_param.rb
62
62
  - lib/aws/cloud_formation.rb
63
+ - lib/aws/cloud_front.rb
63
64
  - lib/aws/cloud_watch.rb
64
65
  - lib/aws/core/connection.rb
65
66
  - lib/aws/core/request.rb
@@ -76,11 +77,11 @@ files:
76
77
  - lib/aws/rds.rb
77
78
  - lib/aws/s3.rb
78
79
  - lib/aws/ses.rb
79
- - lib/aws/signing/authorization_header.rb
80
80
  - lib/aws/signing/version2.rb
81
81
  - lib/aws/signing/version3.rb
82
82
  - lib/aws/sns.rb
83
83
  - lib/aws/sqs.rb
84
+ - samples/cloud_front.rb
84
85
  - samples/ec2.rb
85
86
  - samples/elb.rb
86
87
  - samples/iam.rb
@@ -92,10 +93,12 @@ files:
92
93
  - test/aws/auto_scaling_test.rb
93
94
  - test/aws/call_types/action_param_test.rb
94
95
  - test/aws/cloud_formation_test.rb
96
+ - test/aws/cloud_front_test.rb
95
97
  - test/aws/cloud_watch_test.rb
96
98
  - test/aws/core/connection_test.rb
97
99
  - test/aws/core/request_test.rb
98
100
  - test/aws/core/response_test.rb
101
+ - test/aws/core/util_test.rb
99
102
  - test/aws/ec2_test.rb
100
103
  - test/aws/elasti_cache_test.rb
101
104
  - test/aws/elastic_beanstalk_test.rb
@@ -107,7 +110,6 @@ files:
107
110
  - test/aws/rds_test.rb
108
111
  - test/aws/s3_test.rb
109
112
  - test/aws/ses.rb
110
- - test/aws/signing/authorization_header_test.rb
111
113
  - test/aws/signing/version2_test.rb
112
114
  - test/aws/signing/version3.rb
113
115
  - test/aws/sns_test.rb
@@ -142,10 +144,12 @@ test_files:
142
144
  - test/aws/auto_scaling_test.rb
143
145
  - test/aws/call_types/action_param_test.rb
144
146
  - test/aws/cloud_formation_test.rb
147
+ - test/aws/cloud_front_test.rb
145
148
  - test/aws/cloud_watch_test.rb
146
149
  - test/aws/core/connection_test.rb
147
150
  - test/aws/core/request_test.rb
148
151
  - test/aws/core/response_test.rb
152
+ - test/aws/core/util_test.rb
149
153
  - test/aws/ec2_test.rb
150
154
  - test/aws/elasti_cache_test.rb
151
155
  - test/aws/elastic_beanstalk_test.rb
@@ -157,7 +161,6 @@ test_files:
157
161
  - test/aws/rds_test.rb
158
162
  - test/aws/s3_test.rb
159
163
  - test/aws/ses.rb
160
- - test/aws/signing/authorization_header_test.rb
161
164
  - test/aws/signing/version2_test.rb
162
165
  - test/aws/signing/version3.rb
163
166
  - test/aws/sns_test.rb
@@ -1,43 +0,0 @@
1
- require 'openssl'
2
-
3
- module AWS
4
- module Signing
5
- ##
6
- # Implementation of signing using the Authorization header, as used by S3 and CloudFront
7
- ##
8
- module AuthorizationHeader
9
-
10
- ##
11
- # Build and sign the final request, as per the rules here:
12
- # http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html
13
- ##
14
- def finish_and_sign_request(request)
15
- request.headers["Date"] = Time.now.utc.httpdate
16
- request.headers["Authorization"] =
17
- "AWS #{self.access_key}:#{Base64.encode64(build_signature_for(request)).chomp}"
18
-
19
- request
20
- end
21
-
22
- def build_signature_for(request)
23
- amazon_headers = request.headers.select {|k, v|
24
- k =~ /^x-amz/i
25
- }.map {|k, v|
26
- "#{k.downcase}:#{v}".chomp
27
- }
28
-
29
- to_sign = [
30
- request.method.to_s.upcase,
31
- request.headers["Content-Md5"] || "",
32
- request.headers["Content-Type"] || "",
33
- request.headers["Date"],
34
- amazon_headers,
35
- request.path
36
- ].flatten.join("\n")
37
-
38
- OpenSSL::HMAC.digest("sha1", self.secret_key, to_sign)
39
- end
40
-
41
- end
42
- end
43
- end
@@ -1,33 +0,0 @@
1
- require 'test_helper'
2
- require 'aws/api'
3
- require 'aws/call_types/action_param'
4
- require 'aws/signing/authorization_header'
5
-
6
- describe AWS::Signing::AuthorizationHeader do
7
-
8
- class SigningAuthHeaderTestAPI < AWS::API
9
- endpoint "aptest"
10
- version "2011-01-01"
11
- use_https true
12
-
13
- include AWS::CallTypes::ActionParam
14
- include AWS::Signing::AuthorizationHeader
15
- end
16
-
17
- it "signs the given request according to Version 3 rules" do
18
- AWS::Connection.any_instance.expects(:call).with do |request|
19
- header = request.headers["Authorization"]
20
- parts = header.split(":")
21
-
22
- parts[0].must_equal "AWS key"
23
- parts[1].wont_be_nil
24
-
25
- Time.parse(request.headers["Date"]).wont_be_nil
26
- true
27
- end.returns
28
-
29
- obj = SigningAuthHeaderTestAPI.new "key", "secret"
30
- obj.describe_instances
31
- end
32
-
33
- end