jedlik 0.0.1 → 0.0.4

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/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .rvmrc
2
+ Gemfile.lock
3
+ *.gem
data/Gemfile CHANGED
@@ -1 +1,3 @@
1
+ source "http://rubygems.org"
1
2
  gemspec
3
+
data/README.mkd CHANGED
@@ -23,3 +23,26 @@ request body.
23
23
 
24
24
  conn.post :GetItem, {:TableName => "table1", :Key => {:S => "foo"}}
25
25
  # => Hash
26
+
27
+ License
28
+ -------
29
+
30
+ Copyright (C) 2012, Jeremy (Hashmal) Pinat
31
+
32
+ Permission is hereby granted, free of charge, to any person obtaining a copy
33
+ of this software and associated documentation files (the "Software"), to deal
34
+ in the Software without restriction, including without limitation the rights
35
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36
+ copies of the Software, and to permit persons to whom the Software is
37
+ furnished to do so, subject to the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be included in all
40
+ copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
48
+ SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'bundler/gem_tasks'
2
+ require "rspec/core/rake_task"
3
+ RSpec::Core::RakeTask.new(:spec)
4
+ task :default => :spec
data/jedlik.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # Copyright (c) 2012, Jeremy (Hashmal) Pinat.
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'jedlik'
5
+ s.version = '0.0.4'
6
+ s.summary = "Communicate with Amazon DynamoDB."
7
+ s.description = "Communicate with Amazon DynamoDB. Raw access to the full API without having to handle temporary credentials or HTTP requests by yourself."
8
+ s.authors = ["Hashmal", "Brandon Keene"]
9
+ s.email = ["jeremypinat@gmail.com", "bkeene@gmail.com"]
10
+ s.require_path = 'lib'
11
+ s.files = `git ls-files`.split("\n")
12
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
13
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
14
+ s.homepage = 'http://github.com/hashmal/jedlik'
15
+
16
+ s.add_runtime_dependency 'typhoeus'
17
+ s.add_runtime_dependency 'yajl-ruby'
18
+
19
+ s.add_development_dependency 'rspec', '2.8.0'
20
+ s.add_development_dependency 'webmock'
21
+ end
@@ -1,3 +1,5 @@
1
+ # Copyright (c) 2012, Jeremy (Hashmal) Pinat.
2
+
1
3
  module Jedlik
2
4
 
3
5
  # Establishes a connection to Amazon DynamoDB using credentials.
@@ -17,6 +19,7 @@ module Jedlik
17
19
  opts = DEFAULTS.merge opts
18
20
  @sts = SecurityTokenService.new access_key_id, secret_access_key
19
21
  @endpoint = opts[:endpoint]
22
+ @debug = opts[:debug]
20
23
  end
21
24
 
22
25
  # Create and send a request to DynamoDB.
@@ -28,47 +31,47 @@ module Jedlik
28
31
  # http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide
29
32
  #
30
33
  def post operation, data={}
31
- request = new_request operation, data.to_json
34
+ request = new_request operation, Yajl::Encoder.encode(data)
32
35
  request.sign sts
33
- hydra.queue request; hydra.run
36
+ hydra.queue request
37
+ hydra.run
34
38
  response = request.response
39
+ puts response.inspect if @debug
35
40
 
36
- if status_ok? response
37
- JSON.parse response.body
41
+ if response.code == 200
42
+ Yajl::Parser.parse response.body
43
+ else
44
+ raise_error response
38
45
  end
39
46
  end
40
47
 
41
- private
48
+ private
42
49
 
43
50
  def hydra
44
51
  Typhoeus::Hydra.hydra
45
52
  end
46
53
 
47
54
  def new_request operation, body
48
- (Typhoeus::Request.new "https://#{@endpoint}/",
49
- :method => :post,
50
- :headers => {
51
- 'host' => @endpoint,
52
- 'content-type' => "application/x-amz-json-1.0",
53
- 'x-amz-date' => (Time.now.utc.strftime "%a, %d %b %Y %H:%M:%S GMT"),
54
- 'x-amz-security-token' => sts.session_token,
55
- 'x-amz-target' => "DynamoDB_20111205.#{operation}",
56
- },
57
- :body => body)
55
+ Typhoeus::Request.new "https://#{@endpoint}/",
56
+ :method => :post,
57
+ :body => body,
58
+ :headers => {
59
+ 'host' => @endpoint,
60
+ 'content-type' => "application/x-amz-json-1.0",
61
+ 'x-amz-date' => (Time.now.utc.strftime "%a, %d %b %Y %H:%M:%S GMT"),
62
+ 'x-amz-security-token' => sts.session_token,
63
+ 'x-amz-target' => "DynamoDB_20111205.#{operation}",
64
+ }
58
65
  end
59
66
 
60
- def status_ok? response
67
+ def raise_error response
61
68
  case response.code
62
- when 200
63
- true
64
69
  when 400..499
65
- js = JSON.parse response.body
66
- (raise ClientError,
67
- "#{js['__type'].match(/#(.+)\Z/)[1]}: #{js["message"]}")
70
+ raise ClientError, response.body
68
71
  when 500..599
69
- raise ServerError
72
+ raise ServerError, response.code
70
73
  else
71
- false
74
+ raise Exception, response.body
72
75
  end
73
76
  end
74
77
  end
@@ -1,3 +1,5 @@
1
+ # Copyright (c) 2012, Jeremy (Hashmal) Pinat.
2
+
1
3
  module Jedlik
2
4
 
3
5
  # SecurityTokenService automatically manages the creation and renewal of
@@ -37,6 +39,19 @@ module Jedlik
37
39
  @session_token
38
40
  end
39
41
 
42
+ def signature
43
+ sign string_to_sign
44
+ end
45
+
46
+ def string_to_sign
47
+ [
48
+ "GET",
49
+ "sts.amazonaws.com",
50
+ "/",
51
+ "AWSAccessKeyId=#{@_access_key_id}&Action=GetSessionToken&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=#{CGI.escape authorization_params[:Timestamp]}&Version=2011-06-15"
52
+ ].join("\n")
53
+ end
54
+
40
55
  private
41
56
 
42
57
  # Extract the contents of a given tag.
@@ -53,44 +68,41 @@ module Jedlik
53
68
  # credentials were previously obtained, no request is made until they
54
69
  # expire.
55
70
  def obtain_credentials
56
- if (not @expiration) or (@expiration <= Time.now.utc)
57
- body = (Typhoeus::Request.get request_uri).body
71
+ if not @expiration or @expiration <= Time.now.utc
72
+ params = {
73
+ :AWSAccessKeyId => @_access_key_id,
74
+ :SignatureMethod => 'HmacSHA256',
75
+ :SignatureVersion => '2',
76
+ :Signature => signature,
77
+ }.merge authorization_params
58
78
 
59
- @session_token = (get_tag :SessionToken, body)
60
- @secret_access_key = (get_tag :SecretAccessKey, body)
61
- @expiration = (Time.parse (get_tag :Expiration, body))
62
- @access_key_id = (get_tag :AccessKeyId, body)
79
+ response = (Typhoeus::Request.get "https://sts.amazonaws.com/", :params => params)
80
+ if response.success?
81
+ body = response.body
82
+ @session_token = get_tag :SessionToken, body
83
+ @secret_access_key = get_tag :SecretAccessKey, body
84
+ @expiration = Time.parse get_tag(:Expiration, body)
85
+ @access_key_id = get_tag :AccessKeyId, body
86
+ else
87
+ raise "credential errors: #{response.inspect}"
88
+ end
63
89
  end
64
90
  end
65
91
 
66
- # Generate the params to be sent to STS.
67
- def request_params
92
+ def authorization_params
68
93
  {
69
- :AWSAccessKeyId => @_access_key_id,
70
94
  :Action => 'GetSessionToken',
71
- :DurationSeconds => '3600',
72
- :SignatureMethod => 'HmacSHA256',
73
- :SignatureVersion => '2',
74
95
  :Timestamp => Time.now.utc.iso8601,
75
96
  :Version => '2011-06-15',
76
97
  }
77
98
  end
78
99
 
79
- # Generate the URI that should be requested.
80
- def request_uri
81
- qs = (request_params).map do |key, val|
82
- [(CGI.escape key.to_s), (CGI.escape val)].join '='
83
- end.join '&'
84
-
85
- "https://sts.amazonaws.com/?#{qs}&Signature=" +
86
- (CGI.escape (sign "GET\nsts.amazonaws.com\n/\n#{qs}"))
87
- end
88
-
89
100
  # Sign (HMAC-SHA256) a string using the secret key given at
90
101
  # initialization.
91
102
  def sign string
92
- (Base64.encode64 (OpenSSL::HMAC.digest 'sha256',
93
- @_secret_access_key, string)).chomp
103
+ Base64.encode64(
104
+ OpenSSL::HMAC.digest('sha256', @_secret_access_key, string)
105
+ ).strip
94
106
  end
95
107
  end
96
108
  end
@@ -1,30 +1,29 @@
1
+ # Copyright (c) 2012, Jeremy (Hashmal) Pinat.
2
+
1
3
  module Typhoeus
2
4
  class Request
3
5
  def sign sts
4
- headers.merge!({'x-amzn-authorization' => [
5
- "AWS3 AWSAccessKeyId=#{sts.access_key_id}",
6
- "Algorithm=HmacSHA256",
7
- "Signature=#{digest sts.secret_access_key}"
8
- ].join(',')})
6
+ headers.merge! 'x-amzn-authorization' => "AWS3 AWSAccessKeyId=#{sts.access_key_id},Algorithm=HmacSHA256,Signature=#{digest sts.secret_access_key}"
9
7
  end
10
8
 
11
9
  private
12
10
 
13
11
  def digest secret_key
14
- (Base64.encode64 (OpenSSL::HMAC.digest 'sha256',
15
- secret_key, (Digest::SHA256.digest string_to_sign))).chomp
12
+ Base64.encode64(
13
+ OpenSSL::HMAC.digest('sha256', secret_key, Digest::SHA256.digest(string_to_sign))
14
+ ).strip
16
15
  end
17
16
 
18
17
  def string_to_sign
19
- ["POST\n/\n\nhost:#{@parsed_uri.host}", amz_to_sts, body].join "\n"
18
+ "POST\n/\n\nhost:#{@parsed_uri.host}\n#{amz_to_sts}\n#{body}"
20
19
  end
21
20
 
22
21
  def amz_to_sts
23
- get_amz_headers.sort.map{|key, val| ([key, val].join ':') + "\n"}.join
22
+ get_amz_headers.sort.map {|key, val| [key, val].join(':') + "\n"}.join
24
23
  end
25
24
 
26
25
  def get_amz_headers
27
- headers.select{|key, val| key =~ /\Ax-amz-/}
26
+ headers.select {|key, val| key =~ /\Ax-amz-/}
28
27
  end
29
28
  end
30
29
  end
data/lib/jedlik.rb CHANGED
@@ -1,16 +1,17 @@
1
+ # Copyright (c) 2012, Jeremy (Hashmal) Pinat.
2
+
1
3
  require 'typhoeus'
2
4
  require 'time'
3
5
  require 'base64'
4
6
  require 'openssl'
5
7
  require 'cgi'
6
- require 'json'
8
+ require 'yajl'
7
9
 
8
10
  module Jedlik
9
11
  class ClientError < Exception; end
10
12
  class ServerError < Exception; end
11
13
 
12
14
  require 'jedlik/typhoeus/request'
13
-
14
15
  require 'jedlik/security_token_service'
15
16
  require 'jedlik/connection'
16
17
  end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ require 'benchmark'
3
+
4
+ describe Jedlik::Connection do
5
+ describe "#post" do
6
+ before do
7
+ Time.stub!(:now).and_return(Time.at(1332635893)) # Sat Mar 24 20:38:13 -0400 2012
8
+ end
9
+
10
+ it "signs and posts a request" do
11
+ mock_service = mock(Jedlik::SecurityTokenService,
12
+ :session_token => "session_token",
13
+ :access_key_id => "access_key_id",
14
+ :secret_access_key => "secret_access_key"
15
+ )
16
+
17
+ stub_request(:post, "https://dynamodb.us-east-1.amazonaws.com/").
18
+ with(
19
+ :body => "{}",
20
+ :headers => {
21
+ 'Content-Type' => 'application/x-amz-json-1.0',
22
+ 'Host' => 'dynamodb.us-east-1.amazonaws.com',
23
+ 'X-Amz-Date' => 'Sun, 25 Mar 2012 00:38:13 GMT',
24
+ 'X-Amz-Security-Token' => 'session_token',
25
+ 'X-Amz-Target' => 'DynamoDB_20111205.ListTables',
26
+ 'X-Amzn-Authorization' => 'AWS3 AWSAccessKeyId=access_key_id,Algorithm=HmacSHA256,Signature=2xa6v0WW+980q8Hgt+ym3/7C0D1DlkueGMugi1NWE+o='
27
+ }
28
+ ).
29
+ to_return(
30
+ :status => 200,
31
+ :body => '{"TableNames":["example"]}',
32
+ :headers => {}
33
+ )
34
+
35
+ Jedlik::SecurityTokenService.stub!(:new).and_return(mock_service)
36
+ connection = Jedlik::Connection.new("key_id", "secret")
37
+ result = connection.post :ListTables
38
+ result.should == {"TableNames" => ["example"]}
39
+ end
40
+ end
41
+ end
@@ -1,3 +1,5 @@
1
+ # Copyright (c) 2012, Jeremy (Hashmal) Pinat.
2
+
1
3
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
4
 
3
5
  VALID_RESPONSE_BODY = "<GetSessionTokenResponse " +
@@ -5,9 +7,9 @@ VALID_RESPONSE_BODY = "<GetSessionTokenResponse " +
5
7
  <GetSessionTokenResult>
6
8
  <Credentials>
7
9
  <SessionToken>SESSION_TOKEN</SessionToken>
8
- <SecretAccessKey>SECRET_ACCESS_KEY</SecretAccessKey>
9
- <Expiration>2036-03-19T01:03:22.276Z</Expiration>
10
- <AccessKeyId>ACCESS_KEY_ID</AccessKeyId>
10
+ <SecretAccessKey>secret_access_key</SecretAccessKey>
11
+ <Expiration>2012-03-24T23:10:38Z</Expiration>
12
+ <AccessKeyId>access_key_id</AccessKeyId>
11
13
  </Credentials>
12
14
  </GetSessionTokenResult>
13
15
  <ResponseMetadata>
@@ -18,48 +20,71 @@ VALID_RESPONSE_BODY = "<GetSessionTokenResponse " +
18
20
 
19
21
  module Jedlik
20
22
  describe SecurityTokenService do
21
- let(:sts){SecurityTokenService.new "access_key_id", "secret_access_key"}
22
- let(:response){(Typhoeus::Response.new body: VALID_RESPONSE_BODY)}
23
-
24
- before{Typhoeus::Request.stub(:get).and_return response}
23
+ let(:sts) { SecurityTokenService.new("access_key_id", "secret_access_key") }
25
24
 
26
- shared_examples_for 'cached' do |method|
27
- it 'sends a request to Amazon STS at first call' do
28
- Typhoeus::Request.should_receive(:get).and_return response
29
- sts.send method
30
- end
25
+ before do
26
+ Time.stub(:now).and_return(Time.parse("2012-03-24T22:10:38Z"))
27
+ stub_request(:get, "https://sts.amazonaws.com/").
28
+ with(:query => {
29
+ "AWSAccessKeyId" => "access_key_id",
30
+ "Action" => "GetSessionToken",
31
+ "Signature" => "8h1VJkZsuVP3y+BkqwABrFBgTuTCUNHcHPZPARfQHJw=",
32
+ "SignatureMethod" => "HmacSHA256",
33
+ "SignatureVersion" => "2",
34
+ "Timestamp" => "2012-03-24T22:10:38Z",
35
+ "Version" => "2011-06-15"
36
+ }).to_return(:status => 200, :body => VALID_RESPONSE_BODY)
37
+ end
31
38
 
32
- it 'signs the request'
39
+ it "computes proper signature" do
40
+ s = SecurityTokenService.new("access_key_id", "secret_access_key")
41
+ s.string_to_sign.should == [
42
+ "GET",
43
+ "sts.amazonaws.com",
44
+ "/",
45
+ "AWSAccessKeyId=access_key_id&Action=GetSessionToken&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2012-03-24T22%3A10%3A38Z&Version=2011-06-15"
46
+ ].join("\n")
47
+ s.signature.should == "8h1VJkZsuVP3y+BkqwABrFBgTuTCUNHcHPZPARfQHJw="
48
+ end
33
49
 
34
- it 'caches its value' do
35
- Typhoeus::Request.should_receive(:get).and_return response
36
- sts.send method
37
- sts.send method
38
- end
50
+ it "returns session_token" do
51
+ sts.session_token.should == "SESSION_TOKEN"
39
52
  end
40
53
 
41
- describe 'access_key_id' do
42
- it_behaves_like 'cached', :access_key_id
54
+ it "returns access_key_id" do
55
+ sts.access_key_id.should == "access_key_id"
56
+ end
43
57
 
44
- it 'returns a value' do
45
- sts.access_key_id.should == "ACCESS_KEY_ID"
46
- end
58
+ it "returns secret_access_key" do
59
+ sts.secret_access_key.should == "secret_access_key"
47
60
  end
48
61
 
49
- describe 'secret_access_key' do
50
- it_behaves_like 'cached', :secret_access_key
62
+ # a memoized timestamp would cause a bug when temporary credentials
63
+ # expire and new ones are requested.
64
+ it "updates the timestamp for different requests" do
65
+ s = SecurityTokenService.new("access_key_id", "secret_access_key")
66
+ s.string_to_sign.should == [
67
+ "GET",
68
+ "sts.amazonaws.com",
69
+ "/",
70
+ "AWSAccessKeyId=access_key_id&Action=GetSessionToken&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2012-03-24T22%3A10%3A38Z&Version=2011-06-15"
71
+ ].join("\n")
51
72
 
52
- it 'returns a value' do
53
- sts.secret_access_key.should == "SECRET_ACCESS_KEY"
54
- end
73
+ Time.stub(:now).and_return(Time.parse("2012-03-24T23:11:38Z"))
74
+ s.string_to_sign.should == [
75
+ "GET",
76
+ "sts.amazonaws.com",
77
+ "/",
78
+ "AWSAccessKeyId=access_key_id&Action=GetSessionToken&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2012-03-24T23%3A11%3A38Z&Version=2011-06-15"
79
+ ].join("\n")
55
80
  end
56
81
 
57
- describe 'session_token' do
58
- it_behaves_like 'cached', :session_token
59
-
60
- it 'returns a value' do
61
- sts.session_token.should == "SESSION_TOKEN"
62
- end
82
+ it "does not update the timestamp for the same request" do
83
+ Time.stub(:now).and_return(
84
+ Time.parse("2012-03-24T22:10:38Z"),
85
+ Time.parse("2012-03-24T22:10:39Z")
86
+ )
87
+ sts.session_token
63
88
  end
64
89
  end
65
90
  end
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,10 @@
1
+ # Copyright (c) 2012, Jeremy (Hashmal) Pinat.
2
+
1
3
  require 'rspec'
4
+ require 'webmock/rspec'
2
5
 
3
- $:.unshift (File.join (File.dirname __FILE__), 'lib')
6
+ $:.unshift File.join(File.dirname __FILE__), 'lib'
4
7
  require 'jedlik'
5
8
 
6
9
  RSpec.configure do |config|
7
- config.color = true
8
- config.formatter = :documentation
9
10
  end
metadata CHANGED
@@ -1,25 +1,26 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jedlik
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Hashmal
9
+ - Brandon Keene
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2012-03-23 00:00:00.000000000Z
13
+ date: 2012-03-27 00:00:00.000000000Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
- name: rspec
16
+ name: typhoeus
16
17
  requirement: !ruby/object:Gem::Requirement
17
18
  none: false
18
19
  requirements:
19
20
  - - ! '>='
20
21
  - !ruby/object:Gem::Version
21
22
  version: '0'
22
- type: :development
23
+ type: :runtime
23
24
  prerelease: false
24
25
  version_requirements: !ruby/object:Gem::Requirement
25
26
  none: false
@@ -28,7 +29,7 @@ dependencies:
28
29
  - !ruby/object:Gem::Version
29
30
  version: '0'
30
31
  - !ruby/object:Gem::Dependency
31
- name: typhoeus
32
+ name: yajl-ruby
32
33
  requirement: !ruby/object:Gem::Requirement
33
34
  none: false
34
35
  requirements:
@@ -43,19 +44,57 @@ dependencies:
43
44
  - - ! '>='
44
45
  - !ruby/object:Gem::Version
45
46
  version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 2.8.0
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - '='
61
+ - !ruby/object:Gem::Version
62
+ version: 2.8.0
63
+ - !ruby/object:Gem::Dependency
64
+ name: webmock
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
46
79
  description: Communicate with Amazon DynamoDB. Raw access to the full API without
47
80
  having to handle temporary credentials or HTTP requests by yourself.
48
- email: jeremypinat@gmail.com
81
+ email:
82
+ - jeremypinat@gmail.com
83
+ - bkeene@gmail.com
49
84
  executables: []
50
85
  extensions: []
51
86
  extra_rdoc_files: []
52
87
  files:
88
+ - .gitignore
89
+ - Gemfile
90
+ - README.mkd
91
+ - Rakefile
92
+ - jedlik.gemspec
93
+ - lib/jedlik.rb
53
94
  - lib/jedlik/connection.rb
54
95
  - lib/jedlik/security_token_service.rb
55
96
  - lib/jedlik/typhoeus/request.rb
56
- - lib/jedlik.rb
57
- - Gemfile
58
- - README.mkd
97
+ - spec/jedlik/connection_spec.rb
59
98
  - spec/jedlik/security_token_service_spec.rb
60
99
  - spec/spec_helper.rb
61
100
  homepage: http://github.com/hashmal/jedlik
@@ -82,4 +121,7 @@ rubygems_version: 1.8.19
82
121
  signing_key:
83
122
  specification_version: 3
84
123
  summary: Communicate with Amazon DynamoDB.
85
- test_files: []
124
+ test_files:
125
+ - spec/jedlik/connection_spec.rb
126
+ - spec/jedlik/security_token_service_spec.rb
127
+ - spec/spec_helper.rb