httparty 0.7.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of httparty might be problematic. Click here for more details.

data/History CHANGED
@@ -1,3 +1,11 @@
1
+ == 0.7.3 2011-01-20
2
+ * bug fixes
3
+ * Fix digest auth for unspecified quality of protection (bjoernalbers, mtrudel, dwo)
4
+
5
+ == 0.7.2 2011-01-20
6
+ * bug fixes
7
+ * Fix gem dependencies
8
+
1
9
  == 0.7.1 2011-01-19
2
10
  * bug fixes
3
11
  * Fix uninitialized constant HTTParty::Response::Net in 1.9.2 (cap10morgan)
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{httparty}
8
- s.version = "0.7.2"
8
+ s.version = "0.7.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["John Nunemaker", "Sandro Turriate"]
@@ -76,6 +76,7 @@ Gem::Specification.new do |s|
76
76
  "spec/fixtures/twitter.xml",
77
77
  "spec/fixtures/undefined_method_add_node_for_nil.xml",
78
78
  "spec/httparty/cookie_hash_spec.rb",
79
+ "spec/httparty/net_digest_auth_spec.rb",
79
80
  "spec/httparty/parser_spec.rb",
80
81
  "spec/httparty/request_spec.rb",
81
82
  "spec/httparty/response_spec.rb",
@@ -92,7 +93,7 @@ Gem::Specification.new do |s|
92
93
  s.homepage = %q{http://httparty.rubyforge.org}
93
94
  s.post_install_message = %q{When you HTTParty, you must party hard!}
94
95
  s.require_paths = ["lib"]
95
- s.rubygems_version = %q{1.3.7}
96
+ s.rubygems_version = %q{1.4.2}
96
97
  s.summary = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
97
98
  s.test_files = [
98
99
  "examples/aaws.rb",
@@ -105,6 +106,7 @@ Gem::Specification.new do |s|
105
106
  "examples/twitter.rb",
106
107
  "examples/whoismyrep.rb",
107
108
  "spec/httparty/cookie_hash_spec.rb",
109
+ "spec/httparty/net_digest_auth_spec.rb",
108
110
  "spec/httparty/parser_spec.rb",
109
111
  "spec/httparty/request_spec.rb",
110
112
  "spec/httparty/response_spec.rb",
@@ -117,7 +119,6 @@ Gem::Specification.new do |s|
117
119
  ]
118
120
 
119
121
  if s.respond_to? :specification_version then
120
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
121
122
  s.specification_version = 3
122
123
 
123
124
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
@@ -13,7 +13,7 @@ require dir + 'httparty/net_digest_auth'
13
13
 
14
14
  # @see HTTParty::ClassMethods
15
15
  module HTTParty
16
- VERSION = "0.7.2".freeze
16
+ VERSION = "0.7.3".freeze
17
17
  CRACK_DEPENDENCY = "0.1.8".freeze
18
18
 
19
19
  module AllowedFormatsDeprecation
@@ -3,33 +3,69 @@ require 'net/http'
3
3
 
4
4
  module Net
5
5
  module HTTPHeader
6
- def digest_auth(user, password, response)
7
- response['www-authenticate'] =~ /^(\w+) (.*)/
8
-
9
- params = {}
10
- $2.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }
11
- params.merge!("cnonce" => Digest::MD5.hexdigest("%x" % (Time.now.to_i + rand(65535))))
12
-
13
- a_1 = Digest::MD5.hexdigest("#{user}:#{params['realm']}:#{password}")
14
- a_2 = Digest::MD5.hexdigest("#{@method}:#{@path}")
15
-
16
- request_digest = Digest::MD5.hexdigest(
17
- [a_1, params['nonce'], "0", params['cnonce'], params['qop'], a_2].join(":")
18
- )
19
-
20
- header = [
21
- %Q(Digest username="#{user}"),
22
- %Q(realm="#{params['realm']}"),
23
- %Q(qop="#{params['qop']}"),
24
- %Q(uri="#{@path}"),
25
- %Q(nonce="#{params['nonce']}"),
26
- %Q(nc="0"),
27
- %Q(cnonce="#{params['cnonce']}"),
28
- %Q(opaque="#{params['opaque']}"),
29
- %Q(response="#{request_digest}")
30
- ]
31
-
32
- @header['Authorization'] = header
6
+ def digest_auth(username, password, response)
7
+ @header['Authorization'] = DigestAuthenticator.new(username, password,
8
+ @method, @path, response).authorization_header
9
+ end
10
+
11
+
12
+ class DigestAuthenticator
13
+ def initialize(username, password, method, path, response_header)
14
+ @username = username
15
+ @password = password
16
+ @method = method
17
+ @path = path
18
+ @response = parse(response_header)
19
+ end
20
+
21
+ def authorization_header
22
+ @cnonce = md5(random)
23
+ header = [%Q(Digest username="#{@username}"),
24
+ %Q(realm="#{@response['realm']}"),
25
+ %Q(nonce="#{@response['nonce']}"),
26
+ %Q(uri="#{@path}"),
27
+ %Q(response="#{request_digest}")]
28
+ [%Q(cnonce="#{@cnonce}"),
29
+ %Q(opaque="#{@response['opaque']}"),
30
+ %Q(qop="#{@response['qop']}"),
31
+ %Q(nc="0")].each { |field| header << field } if qop_present?
32
+ header
33
+ end
34
+
35
+ private
36
+
37
+ def parse(response_header)
38
+ response_header['www-authenticate'] =~ /^(\w+) (.*)/
39
+ params = {}
40
+ $2.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }
41
+ params
42
+ end
43
+
44
+ def qop_present?
45
+ @response.has_key?('qop') and not @response['qop'].empty?
46
+ end
47
+
48
+ def random
49
+ "%x" % (Time.now.to_i + rand(65535))
50
+ end
51
+
52
+ def request_digest
53
+ a = [md5(a1), @response['nonce'], md5(a2)]
54
+ a.insert(2, "0", @cnonce, @response['qop']) if qop_present?
55
+ md5(a.join(":"))
56
+ end
57
+
58
+ def md5(str)
59
+ Digest::MD5.hexdigest(str)
60
+ end
61
+
62
+ def a1
63
+ [@username, @response['realm'], @password].join(":")
64
+ end
65
+
66
+ def a2
67
+ [@method, @path].join(":")
68
+ end
33
69
  end
34
70
  end
35
71
  end
@@ -0,0 +1,93 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe Net::HTTPHeader::DigestAuthenticator do
4
+ def setup_digest(response)
5
+ digest = Net::HTTPHeader::DigestAuthenticator.new("Mufasa",
6
+ "Circle Of Life", "GET", "/dir/index.html", response)
7
+ digest.stub(:random).and_return("deadbeef")
8
+ Digest::MD5.stub(:hexdigest) { |str| "md5(#{str})" }
9
+ digest
10
+ end
11
+
12
+ def authorization_header
13
+ @digest.authorization_header.join(", ")
14
+ end
15
+
16
+
17
+ context "with specified quality of protection (qop)" do
18
+ before do
19
+ @digest = setup_digest({'www-authenticate' =>
20
+ 'Digest realm="myhost@testrealm.com", nonce="NONCE", qop="auth"'})
21
+ end
22
+
23
+ it "should set prefix" do
24
+ authorization_header.should =~ /^Digest /
25
+ end
26
+
27
+ it "should set username" do
28
+ authorization_header.should include(%Q(username="Mufasa"))
29
+ end
30
+
31
+ it "should set digest-uri" do
32
+ authorization_header.should include(%Q(uri="/dir/index.html"))
33
+ end
34
+
35
+ it "should set qop" do
36
+ authorization_header.should include(%Q(qop="auth"))
37
+ end
38
+
39
+ it "should set cnonce" do
40
+ authorization_header.should include(%Q(cnonce="md5(deadbeef)"))
41
+ end
42
+
43
+ it "should set nonce-count" do
44
+ authorization_header.should include(%Q(nc="0"))
45
+ end
46
+
47
+ it "should set response" do
48
+ request_digest =
49
+ "md5(md5(Mufasa:myhost@testrealm.com:Circle Of Life)" +
50
+ ":NONCE:0:md5(deadbeef):auth:md5(GET:/dir/index.html))"
51
+ authorization_header.should include(%Q(response="#{request_digest}"))
52
+ end
53
+ end
54
+
55
+
56
+ context "with unspecified quality of protection (qop)" do
57
+ before do
58
+ @digest = setup_digest({'www-authenticate' =>
59
+ 'Digest realm="myhost@testrealm.com", nonce="NONCE"'})
60
+ end
61
+
62
+ it "should set prefix" do
63
+ authorization_header.should =~ /^Digest /
64
+ end
65
+
66
+ it "should set username" do
67
+ authorization_header.should include(%Q(username="Mufasa"))
68
+ end
69
+
70
+ it "should set digest-uri" do
71
+ authorization_header.should include(%Q(uri="/dir/index.html"))
72
+ end
73
+
74
+ it "should not set qop" do
75
+ authorization_header.should_not include(%Q(qop=))
76
+ end
77
+
78
+ it "should not set cnonce" do
79
+ authorization_header.should_not include(%Q(cnonce=))
80
+ end
81
+
82
+ it "should not set nonce-count" do
83
+ authorization_header.should_not include(%Q(nc=))
84
+ end
85
+
86
+ it "should set response" do
87
+ request_digest =
88
+ "md5(md5(Mufasa:myhost@testrealm.com:Circle Of Life)" +
89
+ ":NONCE:md5(GET:/dir/index.html))"
90
+ authorization_header.should include(%Q(response="#{request_digest}"))
91
+ end
92
+ end
93
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httparty
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
5
- prerelease: false
4
+ hash: 5
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 7
9
- - 2
10
- version: 0.7.2
9
+ - 3
10
+ version: 0.7.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - John Nunemaker
@@ -118,12 +118,13 @@ dependencies:
118
118
  requirements:
119
119
  - - "="
120
120
  - !ruby/object:Gem::Version
121
- hash: -1876988191
121
+ hash: 1923831981
122
122
  segments:
123
123
  - 1
124
124
  - 2
125
125
  - 0
126
- - pre2
126
+ - pre
127
+ - 2
127
128
  version: 1.2.0.pre2
128
129
  type: :development
129
130
  version_requirements: *id007
@@ -194,6 +195,7 @@ files:
194
195
  - spec/fixtures/twitter.xml
195
196
  - spec/fixtures/undefined_method_add_node_for_nil.xml
196
197
  - spec/httparty/cookie_hash_spec.rb
198
+ - spec/httparty/net_digest_auth_spec.rb
197
199
  - spec/httparty/parser_spec.rb
198
200
  - spec/httparty/request_spec.rb
199
201
  - spec/httparty/response_spec.rb
@@ -236,7 +238,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
236
238
  requirements: []
237
239
 
238
240
  rubyforge_project:
239
- rubygems_version: 1.3.7
241
+ rubygems_version: 1.4.2
240
242
  signing_key:
241
243
  specification_version: 3
242
244
  summary: Makes http fun! Also, makes consuming restful web services dead easy.
@@ -251,6 +253,7 @@ test_files:
251
253
  - examples/twitter.rb
252
254
  - examples/whoismyrep.rb
253
255
  - spec/httparty/cookie_hash_spec.rb
256
+ - spec/httparty/net_digest_auth_spec.rb
254
257
  - spec/httparty/parser_spec.rb
255
258
  - spec/httparty/request_spec.rb
256
259
  - spec/httparty/response_spec.rb