ratom 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,7 @@
1
+ == 0.5.1 2008-08-05
2
+
3
+ * Added optional AuthHMAC support
4
+
1
5
  == 0.5.0 2008-07-28
2
6
 
3
7
  * Fix bug where processing instructions break parsing.
@@ -9,6 +9,7 @@ lib/atom.rb
9
9
  lib/atom/pub.rb
10
10
  lib/atom/version.rb
11
11
  lib/atom/xml/parser.rb
12
+ lib/atom/configuration.rb
12
13
  setup.rb
13
14
  spec/app/member_entry.atom
14
15
  spec/app/service.xml
data/README.txt CHANGED
@@ -215,7 +215,8 @@ We can tell rAtom about our custom namespace and custom class using the followin
215
215
  The first method call registers an alias for the "http://custom.namespace" namespace and the second method call
216
216
  tell rAtom that when it encounters a custom:property element within a Feed it should create an instance of Custom::Property
217
217
  and pass the XML Reader to the constructor of the instance. It is then up to the constructor to populate the objects attributes
218
- from the XML.
218
+ from the XML. Note that the alias you create using +add_extension_namespace+ can be anything you want, it doesn't need
219
+ to match the alias in the actual XML itself.
219
220
 
220
221
  The custom property will then be available as a method on the rAtom class. In the above example:
221
222
 
@@ -223,6 +224,11 @@ The custom property will then be available as a method on the rAtom class. In t
223
224
  @feed.custom_property.first.name == 'foo'
224
225
  @feed.custom_property.first.value == 'bar'
225
226
 
227
+ There is one caveat to this. By using this type of extension support you are permanently modifying the rAtom classes.
228
+ So if your application process one type of atom extension and you are happy with permanently modified rAtom classes,
229
+ the extra extensibility might work for you. If on the other hand you process lots of different types of extension you might
230
+ want to stick with simpler extension mechanism using the [namespace, element] method described above.
231
+
226
232
  (Thanks to nachokb for this feature!!)
227
233
 
228
234
  === Basic Authentication
@@ -246,6 +252,10 @@ method call that requires them. This might be a bit of a pain but it does make
246
252
  for protecting your credentials, although if you are using HTTP Basic Authentication there is a good chance your credentials aren't
247
253
  very well protected anyway.
248
254
 
255
+ === AuthHMAC authentication
256
+
257
+ As of version 0.5.1 rAtom also support authentication via HMAC request signing using the AuthHMAC[http://auth-hmac.rubyforge.org] gem. This is made available using the :hmac_access_id and :hmac_secret_key parameters which can be passed to the same methods as the HTTP Basic credentials support.
258
+
249
259
  == TODO
250
260
 
251
261
  * Support partial content responses from the server.
@@ -412,9 +412,9 @@ module Atom # :nodoc:
412
412
  end
413
413
 
414
414
  # Reloads the feed by fetching the self uri.
415
- def reload!
415
+ def reload!(opts = {})
416
416
  if links.self
417
- Feed.load_feed(URI.parse(links.self.href))
417
+ Feed.load_feed(URI.parse(links.self.href), opts)
418
418
  end
419
419
  end
420
420
 
@@ -545,9 +545,9 @@ module Atom # :nodoc:
545
545
  end
546
546
 
547
547
  # Reload the Entry by fetching the self link.
548
- def reload!
548
+ def reload!(opts = {})
549
549
  if links.self
550
- Entry.load_entry(URI.parse(links.self.href))
550
+ Entry.load_entry(URI.parse(links.self.href), opts)
551
551
  end
552
552
  end
553
553
  end
@@ -0,0 +1,24 @@
1
+ # Copyright (c) 2008 The Kaphan Foundation
2
+ #
3
+ # For licensing information see LICENSE.txt.
4
+ #
5
+ # Please visit http://www.peerworks.org/contact for further information.
6
+ #
7
+
8
+ module Atom
9
+ class Configuration
10
+ def self.auth_hmac_enabled?
11
+ unless defined?(@auth_hmac_enabled)
12
+ begin
13
+ gem 'auth-hmac'
14
+ require 'auth-hmac'
15
+ @auth_hmac_enabled = true
16
+ rescue
17
+ @auth_hmac_enabled = false
18
+ end
19
+ else
20
+ @auth_hmac_enabled
21
+ end
22
+ end
23
+ end
24
+ end
@@ -6,6 +6,7 @@
6
6
  #
7
7
 
8
8
  require 'atom'
9
+ require 'atom/configuration'
9
10
  require 'atom/xml/parser'
10
11
  require 'atom/version'
11
12
  require 'xml/libxml'
@@ -126,6 +127,12 @@ module Atom
126
127
  request = Net::HTTP::Post.new(uri.path, headers)
127
128
  if opts[:user] && opts[:pass]
128
129
  request.basic_auth(opts[:user], opts[:pass])
130
+ elsif opts[:hmac_access_id] && opts[:hmac_secret_key]
131
+ if Atom::Configuration.auth_hmac_enabled?
132
+ AuthHMAC.sign!(request, opts[:hmac_access_id], opts[:hmac_secret_key])
133
+ else
134
+ raise ArgumentError, "AuthHMAC credentials provides by auth-hmac gem is not installed"
135
+ end
129
136
  end
130
137
  response = http.request(request, entry.to_xml.to_s)
131
138
  end
@@ -171,7 +178,14 @@ module Atom
171
178
  request = Net::HTTP::Put.new(uri.path, headers)
172
179
  if opts[:user] && opts[:pass]
173
180
  request.basic_auth(opts[:user], opts[:pass])
181
+ elsif opts[:hmac_access_id] && opts[:hmac_secret_key]
182
+ if Atom::Configuration.auth_hmac_enabled?
183
+ AuthHMAC.sign!(request, opts[:hmac_access_id], opts[:hmac_secret_key])
184
+ else
185
+ raise ArgumentError, "AuthHMAC credentials provides by auth-hmac gem is not installed"
186
+ end
174
187
  end
188
+
175
189
  response = http.request(request, self.to_xml)
176
190
  end
177
191
 
@@ -193,7 +207,14 @@ module Atom
193
207
  request = Net::HTTP::Delete.new(uri.path, {'Accept' => 'application/atom+xml', 'User-Agent' => "rAtom #{Atom::VERSION::STRING}"})
194
208
  if opts[:user] && opts[:pass]
195
209
  request.basic_auth(opts[:user], opts[:pass])
210
+ elsif opts[:hmac_access_id] && opts[:hmac_secret_key]
211
+ if Atom::Configuration.auth_hmac_enabled?
212
+ AuthHMAC.sign!(request, opts[:hmac_access_id], opts[:hmac_secret_key])
213
+ else
214
+ raise ArgumentError, "AuthHMAC credentials provides by auth-hmac gem is not installed"
215
+ end
196
216
  end
217
+
197
218
  response = http.request(request)
198
219
  end
199
220
 
@@ -8,7 +8,7 @@ module Atom #:nodoc:
8
8
  module VERSION #:nodoc:
9
9
  MAJOR = 0
10
10
  MINOR = 5
11
- TINY = 0
11
+ TINY = 1
12
12
 
13
13
  STRING = [MAJOR, MINOR, TINY].join('.')
14
14
  end
@@ -271,6 +271,13 @@ module Atom
271
271
  request = Net::HTTP::Get.new(o.request_uri)
272
272
  if opts[:user] && opts[:pass]
273
273
  request.basic_auth(opts[:user], opts[:pass])
274
+ elsif opts[:hmac_access_id] && opts[:hmac_secret_key]
275
+ if Atom::Configuration.auth_hmac_enabled?
276
+ puts "Signing with HMAC"
277
+ AuthHMAC.sign!(request, opts[:hmac_access_id], opts[:hmac_secret_key])
278
+ else
279
+ raise ArgumentError, "AuthHMAC credentials provides by auth-hmac gem is not installed"
280
+ end
274
281
  end
275
282
  response = http.request(request)
276
283
  end
@@ -248,6 +248,27 @@ describe Atom::Pub do
248
248
  created = @collection.publish(entry, :user => 'user', :pass => 'pass')
249
249
  created.should == entry
250
250
  end
251
+
252
+ if Atom::Configuration.auth_hmac_enabled?
253
+ it "should send a POST with hmac authentication when an entry is published" do
254
+ entry = Atom::Entry.load_entry(File.open('spec/fixtures/entry.atom'))
255
+
256
+ response = mock_response(Net::HTTPCreated, entry.to_xml.to_s)
257
+
258
+ http = mock('http')
259
+ http.should_receive(:request) do |request, entry_xml|
260
+ request['Authorization'].should match(/^AuthHMAC access_id:[a-zA-Z0-9\/+]+=*/)
261
+ response
262
+ end
263
+
264
+ Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
265
+
266
+ created = @collection.publish(entry, :hmac_access_id => 'access_id', :hmac_secret_key => 'secret')
267
+ created.should == entry
268
+ end
269
+ else
270
+ xit "should send a POST with hmac authentication when an entry is published"
271
+ end
251
272
 
252
273
  it "should behave well when no content is returned" do
253
274
  entry = Atom::Entry.load_entry(File.open('spec/fixtures/entry.atom'))
@@ -366,6 +387,23 @@ describe Atom::Pub do
366
387
  entry.save!(:user => 'user', :pass => 'pass')
367
388
  end
368
389
 
390
+ if Atom::Configuration.auth_hmac_enabled?
391
+ it "should send a PUT with hmac auth to the edit link on save!" do
392
+ entry = Atom::Entry.load_entry(File.open('spec/app/member_entry.atom'))
393
+ response = mock_response(Net::HTTPSuccess, nil)
394
+
395
+ http = mock('http')
396
+ http.should_receive(:request) do |request, entry_xml|
397
+ request['Authorization'].should match(/^AuthHMAC access_id:[a-zA-Z0-9\/+]+=*$/)
398
+ response
399
+ end
400
+
401
+ Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
402
+
403
+ entry.save!(:hmac_access_id => 'access_id', :hmac_secret_key => 'secret')
404
+ end
405
+ end
406
+
369
407
  it "should send a DELETE to the edit link on delete!" do
370
408
  entry = Atom::Entry.load_entry(File.open('spec/app/member_entry.atom'))
371
409
  response = mock_response(Net::HTTPSuccess, nil)
@@ -380,20 +418,37 @@ describe Atom::Pub do
380
418
  entry.destroy!
381
419
  end
382
420
 
383
- it "should send a DELETE to the edit link on delete!" do
421
+ it "should send a DELETE with basic auth to the edit link on delete!" do
422
+ entry = Atom::Entry.load_entry(File.open('spec/app/member_entry.atom'))
423
+ response = mock_response(Net::HTTPSuccess, nil)
424
+
425
+ request = mock('request')
426
+ request.should_receive(:basic_auth).with('user', 'pass')
427
+ Net::HTTP::Delete.should_receive(:new).with('/member_entry.atom', an_instance_of(Hash)).and_return(request)
428
+
429
+ http = mock('http')
430
+ http.should_receive(:request).with(request).and_return(response)
431
+ Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
432
+
433
+ entry.destroy!(:user => 'user', :pass => 'pass')
434
+ end
435
+
436
+ if Atom::Configuration.auth_hmac_enabled?
437
+ it "should send a DELETE with hmac auth to the edit link on delete!" do
384
438
  entry = Atom::Entry.load_entry(File.open('spec/app/member_entry.atom'))
385
439
  response = mock_response(Net::HTTPSuccess, nil)
386
440
 
387
- request = mock('request')
388
- request.should_receive(:basic_auth).with('user', 'pass')
389
- Net::HTTP::Delete.should_receive(:new).with('/member_entry.atom', an_instance_of(Hash)).and_return(request)
390
-
391
441
  http = mock('http')
392
- http.should_receive(:request).with(request).and_return(response)
442
+ http.should_receive(:request) do |request|
443
+ request['Authorization'].should match(/^AuthHMAC access_id:[a-zA-Z0-9\/+]+=*$/)
444
+ response
445
+ end
446
+
393
447
  Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
394
448
 
395
- entry.destroy!(:user => 'user', :pass => 'pass')
449
+ entry.destroy!(:hmac_access_id => 'access_id', :hmac_secret_key => 'secret')
396
450
  end
451
+ end
397
452
 
398
453
  it "should raise exception on save! without an edit link" do
399
454
  entry = Atom::Entry.load_entry(File.open('spec/fixtures/entry.atom'))
@@ -143,9 +143,6 @@ describe Atom do
143
143
 
144
144
  lambda { Atom::Feed.load_feed(uri, :user => 'user', :pass => 'pass') }.should_not raise_error
145
145
  end
146
-
147
- it "should pass basic-auth credentials on the request" do
148
- end
149
146
  end
150
147
 
151
148
  describe 'Atom::Entry.load_entry' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ratom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peerworks
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2008-07-28 00:00:00 +09:30
13
+ date: 2008-08-11 00:00:00 +09:30
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -57,6 +57,7 @@ files:
57
57
  - lib/atom/pub.rb
58
58
  - lib/atom/version.rb
59
59
  - lib/atom/xml/parser.rb
60
+ - lib/atom/configuration.rb
60
61
  - setup.rb
61
62
  - spec/app/member_entry.atom
62
63
  - spec/app/service.xml