jeff 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/README.md +1 -7
- data/Rakefile +6 -6
- data/jeff.gemspec +2 -5
- data/lib/jeff/version.rb +1 -1
- data/lib/jeff.rb +3 -11
- data/spec/jeff_spec.rb +59 -131
- metadata +6 -38
- data/spec/jeff/secret_spec.rb +0 -21
- data/spec/spec_helper.rb +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cfe902c5b3047b523b062b2d60fef3fd9fc0a9c4
|
4
|
+
data.tar.gz: 3ee4e4b1218dc82a02f9861eaaed85469a49d9b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6eb8b274d4af06e24c873727414512702f689f9261cb97b16d9106f3ccdaaf3e452f27d105cce9815b260cba37c148177e676d013d205db2e513b8b07f33f953
|
7
|
+
data.tar.gz: 7d89bff0a31977696c623bc854f88689bb6dd17072276191b99150b5e83d681796221674336bb05a02d47d2afbb71bc2e6dbdd76bce77be9577f449216886b66
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,14 +1,8 @@
|
|
1
1
|
# Jeff
|
2
2
|
|
3
|
-
[
|
4
|
-
|
5
|
-
**Jeff** mixes in [authentication][sign] and other client behaviour for some
|
6
|
-
[Amazon Web Services (AWS)][aws].
|
3
|
+
Jeff [signs][sign] Amazon Web Services requests.
|
7
4
|
|
8
5
|
![jeff][jeff]
|
9
6
|
|
10
|
-
[stat]: https://secure.travis-ci.org/papercavalier/jeff.png
|
11
|
-
[trav]: http://travis-ci.org/papercavalier/jeff
|
12
7
|
[sign]: http://docs.amazonwebservices.com/general/latest/gr/signature-version-2.html
|
13
|
-
[aws]: http://aws.amazon.com/
|
14
8
|
[jeff]: http://f.cl.ly/items/0a3R3J0k1R2f423k1q2l/jeff.jpg
|
data/Rakefile
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
#!/usr/bin/env rake
|
2
1
|
require 'bundler/gem_tasks'
|
3
|
-
require '
|
2
|
+
require 'rake/testtask'
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
t.
|
4
|
+
Rake::TestTask.new do |t|
|
5
|
+
t.libs.push 'lib'
|
6
|
+
t.test_files = FileList['spec/*_spec.rb']
|
7
|
+
t.verbose = true
|
8
8
|
end
|
9
9
|
|
10
|
-
task :default => [:
|
10
|
+
task :default => [:test]
|
data/jeff.gemspec
CHANGED
@@ -5,20 +5,17 @@ require File.expand_path('../lib/jeff/version.rb', __FILE__)
|
|
5
5
|
Gem::Specification.new do |gem|
|
6
6
|
gem.authors = ['Hakan Ensari']
|
7
7
|
gem.email = ['hakan.ensari@papercavalier.com']
|
8
|
-
gem.description = %q{
|
8
|
+
gem.description = %q{An Amazon Web Services client}
|
9
9
|
gem.summary = %q{AWS client}
|
10
10
|
gem.homepage = 'https://github.com/papercavalier/jeff'
|
11
11
|
|
12
12
|
gem.files = `git ls-files`.split($\)
|
13
|
-
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
14
13
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
15
14
|
gem.name = 'jeff'
|
16
15
|
gem.require_paths = ['lib']
|
17
16
|
gem.version = Jeff::VERSION
|
18
17
|
|
19
|
-
gem.add_dependency
|
20
|
-
gem.add_development_dependency 'rake'
|
21
|
-
gem.add_development_dependency 'rspec'
|
18
|
+
gem.add_dependency 'excon', '~> 0.22.0'
|
22
19
|
|
23
20
|
gem.required_ruby_version = '>= 1.9'
|
24
21
|
end
|
data/lib/jeff/version.rb
CHANGED
data/lib/jeff.rb
CHANGED
@@ -111,7 +111,7 @@ module Jeff
|
|
111
111
|
|
112
112
|
def build_options(opts)
|
113
113
|
opts[:headers] ||= {}
|
114
|
-
opts[:headers].update('Host' =>
|
114
|
+
opts[:headers].update('Host' => connection.data[:host])
|
115
115
|
|
116
116
|
if opts[:body]
|
117
117
|
opts[:headers].update('Content-MD5' => calculate_md5(opts[:body]))
|
@@ -124,14 +124,6 @@ module Jeff
|
|
124
124
|
Base64.encode64(Digest::MD5.digest(body)).strip
|
125
125
|
end
|
126
126
|
|
127
|
-
def connection_host
|
128
|
-
connection.data[:host]
|
129
|
-
end
|
130
|
-
|
131
|
-
def connection_path
|
132
|
-
connection.data[:path]
|
133
|
-
end
|
134
|
-
|
135
127
|
def escape(val)
|
136
128
|
val.to_s.gsub(UNRESERVED) do
|
137
129
|
'%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
|
@@ -143,8 +135,8 @@ module Jeff
|
|
143
135
|
|
144
136
|
string_to_sign = [
|
145
137
|
opts[:method].upcase,
|
146
|
-
|
147
|
-
opts[:path] ||
|
138
|
+
connection.data[:host],
|
139
|
+
opts[:path] || connection.data[:path],
|
148
140
|
query
|
149
141
|
].join("\n")
|
150
142
|
signature = secret.sign(string_to_sign)
|
data/spec/jeff_spec.rb
CHANGED
@@ -1,167 +1,95 @@
|
|
1
|
-
require '
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'minitest/pride'
|
3
|
+
require 'jeff'
|
2
4
|
|
3
|
-
|
4
|
-
let(:klass) { Class.new { include Jeff } }
|
5
|
-
let(:client) { klass.new }
|
6
|
-
|
7
|
-
describe '.headers' do
|
8
|
-
subject { klass.headers }
|
9
|
-
|
10
|
-
it { should have_key 'User-Agent' }
|
5
|
+
Excon.defaults[:mock] = true
|
11
6
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
should have_key 'Foo'
|
7
|
+
describe Jeff do
|
8
|
+
before do
|
9
|
+
@klass = Class.new do
|
10
|
+
include Jeff
|
18
11
|
end
|
19
12
|
end
|
20
13
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
it { should have_key 'AWSAccessKeyId' }
|
25
|
-
|
26
|
-
it { should have_key 'SignatureMethod' }
|
27
|
-
|
28
|
-
it { should have_key 'SignatureVersion' }
|
29
|
-
|
30
|
-
it { should have_key 'Timestamp' }
|
31
|
-
|
32
|
-
it 'should be configurable' do
|
33
|
-
klass.instance_eval do
|
34
|
-
params 'Foo' => 'bar'
|
35
|
-
end
|
36
|
-
|
37
|
-
should have_key 'Foo'
|
38
|
-
end
|
14
|
+
it 'has a User-Agent request header' do
|
15
|
+
assert @klass.headers.has_key?('User-Agent')
|
39
16
|
end
|
40
17
|
|
41
|
-
|
42
|
-
|
43
|
-
|
18
|
+
it 'configures request headers' do
|
19
|
+
@klass.instance_eval do
|
20
|
+
headers 'Foo' => 'bar'
|
44
21
|
end
|
45
|
-
end
|
46
22
|
|
47
|
-
|
48
|
-
it 'should require a value' do
|
49
|
-
expect { client.key }.to raise_error Jeff::MissingKey
|
50
|
-
end
|
23
|
+
assert @klass.headers.has_key?('Foo')
|
51
24
|
end
|
52
25
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
26
|
+
it 'has the required request query parameters' do
|
27
|
+
%w(AWSAccessKeyId SignatureMethod SignatureVersion Timestamp)
|
28
|
+
.each { |key| assert @klass.params.has_key?(key) }
|
57
29
|
end
|
58
30
|
|
59
|
-
|
60
|
-
|
61
|
-
|
31
|
+
it 'configures the request query parameters' do
|
32
|
+
@klass.instance_eval do
|
33
|
+
params 'Foo' => 'bar'
|
62
34
|
end
|
63
35
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
it 'should include the key' do
|
68
|
-
subject['AWSAccessKeyId'].should eql client.key
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'should generate a timestamp' do
|
72
|
-
subject['Timestamp'].should be_a String
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe '#build_query' do
|
77
|
-
subject { client.build_query 'A10' => 1, 'A1' => 1 }
|
36
|
+
assert @klass.params.has_key?('Foo')
|
37
|
+
end
|
78
38
|
|
79
|
-
|
80
|
-
|
81
|
-
|
39
|
+
it 'requires an endpoint' do
|
40
|
+
proc { @klass.new.endpoint }.must_raise Jeff::MissingEndpoint
|
41
|
+
end
|
82
42
|
|
83
|
-
|
84
|
-
|
85
|
-
end
|
86
|
-
end
|
43
|
+
it 'requires a key' do
|
44
|
+
proc { @klass.new.key }.must_raise Jeff::MissingKey
|
87
45
|
end
|
88
46
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
end
|
47
|
+
it 'requires a secret' do
|
48
|
+
proc { @klass.new.secret }.must_raise Jeff::MissingSecret
|
49
|
+
end
|
93
50
|
|
94
|
-
|
95
|
-
|
96
|
-
|
51
|
+
it 'sorts the request query parameters of the client lexicographically' do
|
52
|
+
client = @klass.new
|
53
|
+
client.key = 'foo'
|
54
|
+
query = client.build_query 'A10' => 1, 'A1' => 1
|
97
55
|
|
98
|
-
|
56
|
+
query.must_match(/^A1=1&A10=.*Timestamp/)
|
57
|
+
end
|
99
58
|
|
100
|
-
|
101
|
-
|
102
|
-
|
59
|
+
it 'sets the request headers of the client connection' do
|
60
|
+
client = @klass.new
|
61
|
+
client.endpoint = 'http://example.com/'
|
103
62
|
|
104
|
-
|
105
|
-
subject.should be client.connection
|
106
|
-
end
|
107
|
-
end
|
63
|
+
client.connection.data[:headers].must_equal @klass.headers
|
108
64
|
end
|
109
65
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
client.key = 'key'
|
114
|
-
client.secret = 'secret'
|
115
|
-
end
|
116
|
-
|
117
|
-
Excon::HTTP_VERBS.each do |method|
|
118
|
-
describe "##{method}" do
|
119
|
-
subject { client.send(method, mock: true).body }
|
66
|
+
Excon::HTTP_VERBS.each do |method|
|
67
|
+
it "makes a #{method.upcase} request" do
|
68
|
+
Excon.stub({ }, { status: 200 })
|
120
69
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
end
|
70
|
+
client = @klass.new
|
71
|
+
client.endpoint = 'http://example.com/'
|
72
|
+
client.key = 'foo'
|
73
|
+
client.secret = 'bar'
|
126
74
|
|
127
|
-
|
75
|
+
client.send(method).status.must_equal 200
|
128
76
|
|
129
|
-
|
130
|
-
should eql method
|
131
|
-
end
|
132
|
-
end
|
77
|
+
Excon.stubs.clear
|
133
78
|
end
|
79
|
+
end
|
134
80
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
before do
|
139
|
-
Excon.stub({ method: :get }) do |params|
|
140
|
-
{ status: 200, body: params[:headers]['Content-MD5'] }
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
after { Excon.stubs.clear }
|
145
|
-
|
146
|
-
it "should add an Content-MD5 header" do
|
147
|
-
should_not be_empty
|
148
|
-
end
|
81
|
+
it 'adds a Content-MD5 request header if there is a request body' do
|
82
|
+
Excon.stub({ }) do |params|
|
83
|
+
{ body: params[:headers]['Content-MD5'] }
|
149
84
|
end
|
150
85
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
end
|
156
|
-
end
|
86
|
+
client = @klass.new
|
87
|
+
client.endpoint = 'http://example.com/'
|
88
|
+
client.key = 'foo'
|
89
|
+
client.secret = 'bar'
|
157
90
|
|
158
|
-
|
91
|
+
client.post(body: 'foo').body.wont_be_empty
|
159
92
|
|
160
|
-
|
161
|
-
expect {
|
162
|
-
client.get mock: true
|
163
|
-
}.to raise_error Excon::Errors::HTTPStatusError
|
164
|
-
end
|
165
|
-
end
|
93
|
+
Excon.stubs.clear
|
166
94
|
end
|
167
95
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jeff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hakan Ensari
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: excon
|
@@ -16,43 +16,15 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.22.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
27
|
-
|
28
|
-
name: rake
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - '>='
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - '>='
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - '>='
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - '>='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
description: Minimum-viable Amazon Web Services (AWS) client
|
26
|
+
version: 0.22.0
|
27
|
+
description: An Amazon Web Services client
|
56
28
|
email:
|
57
29
|
- hakan.ensari@papercavalier.com
|
58
30
|
executables: []
|
@@ -69,9 +41,7 @@ files:
|
|
69
41
|
- lib/jeff.rb
|
70
42
|
- lib/jeff/secret.rb
|
71
43
|
- lib/jeff/version.rb
|
72
|
-
- spec/jeff/secret_spec.rb
|
73
44
|
- spec/jeff_spec.rb
|
74
|
-
- spec/spec_helper.rb
|
75
45
|
homepage: https://github.com/papercavalier/jeff
|
76
46
|
licenses: []
|
77
47
|
metadata: {}
|
@@ -91,11 +61,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
61
|
version: '0'
|
92
62
|
requirements: []
|
93
63
|
rubyforge_project:
|
94
|
-
rubygems_version: 2.0.
|
64
|
+
rubygems_version: 2.0.2
|
95
65
|
signing_key:
|
96
66
|
specification_version: 4
|
97
67
|
summary: AWS client
|
98
68
|
test_files:
|
99
|
-
- spec/jeff/secret_spec.rb
|
100
69
|
- spec/jeff_spec.rb
|
101
|
-
- spec/spec_helper.rb
|
data/spec/jeff/secret_spec.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Jeff
|
4
|
-
describe Secret do
|
5
|
-
let(:secret) { Secret.new 'key' }
|
6
|
-
|
7
|
-
describe '#sign' do
|
8
|
-
after { secret.sign 'message' }
|
9
|
-
|
10
|
-
it 'should digest' do
|
11
|
-
secret.should_receive(:digest)
|
12
|
-
.and_return double.as_null_object
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'should Base64-encode' do
|
16
|
-
Base64.should_receive(:encode64)
|
17
|
-
.and_return double.as_null_object
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|