panda 0.3.0 → 0.4.0

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/Rakefile CHANGED
@@ -26,6 +26,7 @@ require 'spec/rake/spectask'
26
26
  Spec::Rake::SpecTask.new(:spec) do |spec|
27
27
  spec.libs << 'lib' << 'spec'
28
28
  spec.spec_files = FileList['spec/**/*_spec.rb']
29
+ spec.ruby_opts = ['-rrubygems']
29
30
  end
30
31
 
31
32
  Spec::Rake::SpecTask.new(:rcov) do |spec|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
@@ -7,7 +7,7 @@ require 'base64'
7
7
 
8
8
  class Panda
9
9
  class ApiAuthentication
10
- def self.authenticate(verb, request_uri, host, secret_key, params_given={})
10
+ def self.generate_signature(verb, request_uri, host, secret_key, params_given={})
11
11
  # Ensure all param keys are strings
12
12
  params = {}; params_given.each {|k,v| params[k.to_s] = v }
13
13
 
@@ -21,46 +21,26 @@ class Panda
21
21
  hmac = HMAC::SHA256.new( secret_key )
22
22
  hmac.update( string_to_sign )
23
23
  # chomp is important! the base64 encoded version will have a newline at the end
24
- signature = Base64.encode64(hmac.digest).chomp
25
-
26
- return signature
27
- end
28
-
29
- # Insist on specific method of URL encoding, RFC3986.
30
- def self.url_encode(string)
31
- # It's kinda like CGI.escape, except CGI.escape is encoding a tilde when
32
- # it ought not to be, so we turn it back. Also space NEEDS to be %20 not +.
33
- return CGI.escape(string).gsub("%7E", "~").gsub("+", "%20")
24
+ Base64.encode64(hmac.digest).chomp
34
25
  end
35
26
 
36
27
  # param keys should be strings, not symbols please. return a string joined
37
28
  # by & in canonical order.
38
29
  def self.canonical_querystring(params)
39
30
  # I hope this built-in sort sorts by byte order, that's what's required.
40
- values = params.keys.sort.collect {|key| [url_encode(key), url_encode(params[key])].join("=") }
41
-
42
- return values.join("&")
43
- end
44
-
45
- def self.add_params_to_request_uri(request_uri, params)
46
- request_uri + '?' + hash_to_query(params)
47
- end
48
- # Insist on specific method of URL encoding, RFC3986.
49
- def self.url_encode(string)
50
- string = string.to_s
51
- # It's kinda like CGI.escape, except CGI.escape is encoding a tilde when
52
- # it ought not to be, so we turn it back. Also space NEEDS to be %20 not +.
53
- return CGI.escape(string).gsub("%7E", "~").gsub("+", "%20")
31
+ params.keys.sort.collect {|key| [url_encode(key), url_encode(params[key])].join("=") }.join("&")
54
32
  end
55
33
 
56
34
  # Turns a hash into a query string, returns the query string.
57
35
  # url-encodes everything to Amazon's specifications.
58
36
  def self.hash_to_query(hash)
59
- hash.collect do |key, value|
60
-
61
- url_encode(key) + "=" + url_encode(value)
37
+ hash.collect{|key, value| url_encode(key) + "=" + url_encode(value) }.join("&")
38
+ end
62
39
 
63
- end.join("&")
40
+ # It's kinda like CGI.escape, except CGI.escape is encoding a tilde when
41
+ # it ought not to be, so we turn it back. Also space NEEDS to be %20 not +.
42
+ def self.url_encode(string)
43
+ CGI.escape(string.to_s).gsub("%7E", "~").gsub("+", "%20")
64
44
  end
65
45
  end
66
46
  end
@@ -10,30 +10,26 @@ class Panda
10
10
  @secret_key = params["secret_key"] || params[:secret_key]
11
11
  @api_host = params["api_host"] || params[:api_host]
12
12
  @api_port = params["api_port"] || params[:api_port]
13
-
14
13
  @prefix = params["prefix_url"] || "v#{@api_version}"
15
-
16
14
  @connection = RestClient::Resource.new(api_url)
17
15
  end
18
16
 
19
17
  def get(request_uri, params={})
20
- append_authentication_params!("GET", request_uri, params)
21
- @connection[ApiAuthentication.add_params_to_request_uri(request_uri, params)].get
18
+ query = signed_query("GET", request_uri, params)
19
+ @connection[request_uri + '?' + query].get
22
20
  end
23
21
 
24
22
  def post(request_uri, params)
25
- append_authentication_params!("POST", request_uri, params)
26
- @connection[request_uri].post(params)
23
+ @connection[request_uri].post(signed_params("POST", request_uri, params))
27
24
  end
28
25
 
29
26
  def put(request_uri, params)
30
- append_authentication_params!("PUT", request_uri, params)
31
- @connection[request_uri].put(params)
27
+ @connection[request_uri].put(signed_params("PUT", request_uri, params))
32
28
  end
33
29
 
34
30
  def delete(request_uri, params={})
35
- append_authentication_params!("DELETE", request_uri, params)
36
- @connection[ApiAuthentication.add_params_to_request_uri(request_uri, params)].delete
31
+ query = signed_query("DELETE", request_uri, params)
32
+ @connection[request_uri + '?' + query].delete
37
33
  end
38
34
 
39
35
  def authentication_params(verb, request_uri, params)
@@ -45,13 +41,20 @@ class Panda
45
41
  return auth_params
46
42
  end
47
43
 
48
- def api_url
49
- "http://#{@api_host}:#{@api_port}/#{@prefix}"
44
+ def signed_query(*args)
45
+ ApiAuthentication.hash_to_query(signed_params(*args))
46
+ end
47
+
48
+ def signed_params(verb, request_uri, params = {}, timestamp_str = nil)
49
+ auth_params = params
50
+ auth_params['cloud_id'] = @cloud_id
51
+ auth_params['access_key'] = @access_key
52
+ auth_params['timestamp'] = timestamp_str || Time.now.iso8601(6)
53
+ auth_params['signature'] = ApiAuthentication.generate_signature(verb, request_uri, @api_host, @secret_key, params.merge(auth_params))
54
+ auth_params
50
55
  end
51
- private
52
56
 
53
- def append_authentication_params!(verb, request_uri, params)
54
- auth_params = authentication_params(verb, request_uri, params)
55
- params.merge!(auth_params)
57
+ def api_url
58
+ "http://#{@api_host}:#{@api_port}/#{@prefix}"
56
59
  end
57
60
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{panda}
8
- s.version = "0.3.0"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["New Bamboo"]
12
- s.date = %q{2010-02-22}
12
+ s.date = %q{2010-02-23}
13
13
  s.description = %q{Panda Client}
14
14
  s.email = %q{info@pandastream.com}
15
15
  s.extra_rdoc_files = [
@@ -4,7 +4,6 @@ describe Panda do
4
4
  before(:each) do
5
5
  FakeWeb.allow_net_connect = false
6
6
  @panda = Panda.new({"access_key" => "my_access_key", "secret_key" => "my_secret_key", "api_host" => "myapihost", "api_port" => 85, "cloud_id" => 'my_cloud_id' })
7
- # Panda.connect!({"access_key" => "my_access_key", "secret_key" => "my_secret_key", "api_host" => "myapihost", "api_port" => 85, "cloud_id" => 'my_cloud_id' })
8
7
  Time.stub!(:now).and_return(mock("time", :iso8601 => "2009-11-04T17:54:11+00:00"))
9
8
  end
10
9
 
@@ -20,5 +19,28 @@ describe Panda do
20
19
  FakeWeb.should have_requested(:delete, "http://myapihost:85/v2/videos/1?timestamp=2009-11-04T17%3A54%3A11%2B00%3A00&signature=t0IYclDXgjZFRYaMf0Gbg%2B5vOqp7q8QQRN8tlQ3bk8Q%3D&access_key=my_access_key&cloud_id=my_cloud_id")
21
20
  end
22
21
 
22
+ it "should create a signed version of the parameters" do
23
+ signed_params = @panda.signed_params('POST',
24
+ '/videos.json',
25
+ {"param1" => 'one', "param2" => 'two'}
26
+ )
27
+ signed_params.should == {
28
+ 'access_key' => "my_access_key",
29
+ 'timestamp' => "2009-11-04T17:54:11+00:00",
30
+ 'cloud_id' => 'my_cloud_id',
31
+ 'signature' => 'w66goW6Ve5CT9Ibbx3ryvq4XM8OfIfSZe5oapgZBaUs=',
32
+ 'param1' => 'one',
33
+ 'param2' => 'two'
34
+ }
35
+ end
36
+
37
+ it "should create a signed version of the parameters without additional arguments" do
38
+ @panda.signed_params('POST', '/videos.json').should == {
39
+ 'access_key' => "my_access_key",
40
+ 'timestamp' => "2009-11-04T17:54:11+00:00",
41
+ 'cloud_id' => 'my_cloud_id',
42
+ 'signature' => 'TI2n/dsSllxFhxcEShRGKWtDSqxu+kuJUPs335NavMo='
43
+ }
44
+ end
23
45
 
24
46
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 3
7
+ - 4
8
8
  - 0
9
- version: 0.3.0
9
+ version: 0.4.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - New Bamboo
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-02-22 00:00:00 +00:00
17
+ date: 2010-02-23 00:00:00 +00:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency