atom-tools 2.0.1 → 2.0.2

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
@@ -7,7 +7,7 @@ require "spec/rake/spectask"
7
7
  require "rake/clean"
8
8
 
9
9
  NAME = "atom-tools"
10
- VERS = "2.0.1"
10
+ VERS = "2.0.2"
11
11
 
12
12
  # the following from markaby-0.5's tools/rakehelp
13
13
  def setup_tests
data/bin/atom-grep CHANGED
File without changes
data/bin/atom-post CHANGED
File without changes
data/lib/atom/element.rb CHANGED
@@ -288,7 +288,10 @@ module Atom # :nodoc:
288
288
 
289
289
  self.on_build do |e,x|
290
290
  if v = e.get(name)
291
- e.set_atom_attrb(x, name, v.to_s)
291
+ unless x.namespaces[ns[0]]
292
+ x.add_namespace *ns
293
+ end
294
+ x.attributes["#{ns[0]}:#{name}"] = v.to_s
292
295
  end
293
296
  end
294
297
  end
data/lib/atom/http.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "net/http"
2
2
  require "net/https"
3
3
  require "uri"
4
+ require "cgi"
4
5
 
5
6
  require "atom/cache"
6
7
 
@@ -16,7 +17,8 @@ class String # :nodoc:
16
17
  end
17
18
 
18
19
  module Atom
19
- UA = "atom-tools 2.0.1"
20
+ TOOLS_VERSION = '2.0.2'
21
+ UA = "atom-tools " + TOOLS_VERSION
20
22
 
21
23
  module DigestAuth
22
24
  CNONCE = Digest::MD5.hexdigest("%x" % (Time.now.to_i + rand(65535)))
@@ -130,6 +132,8 @@ module Atom
130
132
  #
131
133
  # defaults to nil
132
134
  attr_accessor :always_auth
135
+ # if this is true, we tell Net::HTTP to die if it can't verify the SSL when doing https
136
+ attr_accessor :strict_ssl
133
137
 
134
138
  # automatically handle redirects, even for POST/PUT/DELETE requests?
135
139
  #
@@ -254,10 +258,90 @@ module Atom
254
258
  req["Authorization"] = 'WSSE profile="UsernameToken"'
255
259
  end
256
260
 
257
- def authsub_authenticate req, url
261
+ def authsub_authenticate req, url, param_string = ""
258
262
  req["Authorization"] = %{AuthSub token="#{@token}"}
259
263
  end
260
264
 
265
+ # GoogleLogin support thanks to Adrian Hosey
266
+ def googlelogin_authenticate(req, url, param_string)
267
+ params_h = Hash.new
268
+ param_string.split(',').each do |p|
269
+ k, v = p.split('=')
270
+ # No whitespace in the key
271
+ k.delete!(' ')
272
+ # Values come wrapped in doublequotes - remove
273
+ v.gsub!(/^"|"$/, '')
274
+ params_h[k] = v
275
+ end
276
+
277
+ abs_url = (url + "/").to_s
278
+ user, pass = @get_auth_details.call(abs_url, params_h["realm"])
279
+ token = fetch_googlelogin_token(user, pass, params_h["realm"], params_h["service"])
280
+ if !token.nil?
281
+ req["Authorization"] = "GoogleLogin auth=#{token}"
282
+ end
283
+ end
284
+
285
+ def fetch_googlelogin_token(user, pass, url_s, service)
286
+ req, url = new_request(url_s, Net::HTTP::Post)
287
+ http_obj = Net::HTTP.new(url.host, url.port)
288
+ if url.scheme == "https"
289
+ http_obj.use_ssl = true
290
+ probe_for_cafile(http_obj)
291
+ end
292
+
293
+ body = "Email=#{CGI.escape(user)}&Passwd=#{CGI.escape(pass)}&service=#{CGI.escape(service)}"
294
+ body += "&accountType=GOOGLE&source=ruby-atom-tools-#{CGI.escape(TOOLS_VERSION)}"
295
+ res = http_obj.start do |h|
296
+ h.request(req, body)
297
+ end
298
+
299
+ retval = nil
300
+ case res
301
+ when Net::HTTPUnauthorized
302
+ raise Unauthorized, "Your authorization was rejected"
303
+ when Net::HTTPOK, Net::HTTPNonAuthoritativeInformation
304
+ res.body.each_line do |l|
305
+ k, v = l.split('=')
306
+ if k == "Auth"
307
+ retval = v.chomp
308
+ end
309
+ end
310
+ end
311
+
312
+ retval
313
+ end
314
+
315
+ # Look for a root CA file and set the relevant options on the passed-in Net::HTTP object.
316
+ def probe_for_cafile(http_obj)
317
+ ca_possibles = [
318
+ '/usr/share/curl/curl-ca-bundle.crt', # OS X
319
+ '/etc/pki/tls/certs/ca-bundle.crt', # newer Redhat
320
+ '/usr/share/ssl/certs/ca-bundle.crt', # older Redhat
321
+ '/etc/ssl/certs/ca-certificates.crt', # Ubuntu (I think)
322
+ # <irony>Dear LSB: Thank you for standardizing Linux</irony>
323
+ ]
324
+ cafile = nil
325
+ ca_possibles.each do |ca|
326
+ if File.exist? ca
327
+ cafile = ca
328
+ break
329
+ end
330
+ end
331
+ if cafile.nil?
332
+ if @strict_ssl
333
+ # set this knowing it will die, since we didn't find a good cafile
334
+ http_obj.verify_mode = OpenSSL::SSL::VERIFY_PEER
335
+ else
336
+ http_obj.verify_mode = OpenSSL::SSL::VERIFY_NONE
337
+ end
338
+ else
339
+ http_obj.ca_file = cafile
340
+ http_obj.verify_mode = OpenSSL::SSL::VERIFY_PEER
341
+ http_obj.verify_depth = 5
342
+ end
343
+ end
344
+
261
345
  def username_and_password_for_realm(url, realm)
262
346
  abs_url = (url + "/").to_s
263
347
  user, pass = @get_auth_details.call(abs_url, realm)
@@ -313,7 +397,10 @@ module Atom
313
397
  end
314
398
 
315
399
  http_obj = Net::HTTP.new(url.host, url.port)
316
- http_obj.use_ssl = true if url.scheme == "https"
400
+ if url.scheme == "https"
401
+ http_obj.use_ssl = true
402
+ probe_for_cafile(http_obj)
403
+ end
317
404
 
318
405
  res = http_obj.start do |h|
319
406
  h.request(req, body)
data/test/runtests.rb CHANGED
File without changes
data/test/test_general.rb CHANGED
File without changes
data/test/test_http.rb CHANGED
@@ -24,7 +24,7 @@ class AtomHTTPTest < Test::Unit::TestCase
24
24
  def test_parse_wwwauth
25
25
  # a Basic WWW-Authenticate
26
26
  header = 'realm="SokEvo"'
27
-
27
+
28
28
  params = @http.send :parse_quoted_wwwauth, header
29
29
  assert_equal "SokEvo", params[:realm]
30
30
 
@@ -272,29 +272,6 @@ class AtomHTTPTest < Test::Unit::TestCase
272
272
  assert_authenticates
273
273
  end
274
274
 
275
- def test_https
276
- require 'webrick/https'
277
-
278
- @s = WEBrick::HTTPServer.new(
279
- :Port => (@port + 1),
280
- :DocumentRoot => Dir::pwd + "/htdocs",
281
- :Logger => WEBrick::Log.new($stderr, WEBrick::Log::FATAL),
282
- :AccessLog => [],
283
- :SSLEnable => true,
284
- :SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE,
285
- :SSLCertName => [ ["C","CA"], ["O","localhost"], ["CN", "WWW"] ]
286
- )
287
-
288
- mount_one_shot do |req,res|
289
- res.body = SECRET_DATA
290
- end
291
-
292
- res = @http.get("https://localhost:#{@port + 1}/")
293
-
294
- assert_equal "200", res.code
295
- assert_equal SECRET_DATA, res.body
296
- end
297
-
298
275
  # mount a block on the test server, shutting the server down after a
299
276
  # single request
300
277
  def mount_one_shot &block
@@ -309,8 +286,8 @@ class AtomHTTPTest < Test::Unit::TestCase
309
286
  # test that we authenticated properly
310
287
  def assert_authenticates
311
288
  get_root
312
- assert_equal "200", @res.code
313
- assert_equal SECRET_DATA, @res.body
289
+ assert_equal "200", @res.code
290
+ assert_equal SECRET_DATA, @res.body
314
291
  end
315
292
 
316
293
  # performs a GET on the test server
@@ -2,6 +2,9 @@ require "test/unit"
2
2
 
3
3
  require "atom/service"
4
4
 
5
+ # needed for hpricot
6
+ require "rubygems"
7
+
5
8
  class FakeHTTP
6
9
  Response = Struct.new(:body, :code, :content_type)
7
10
 
@@ -25,6 +28,17 @@ class FakeHTTP
25
28
  end
26
29
 
27
30
  class AtomProtocolTest < Test::Unit::TestCase
31
+ attr_reader :have_hpricot
32
+
33
+ def initialize *args
34
+ super
35
+
36
+ require "hpricot"
37
+ @have_hpricot = true
38
+ rescue LoadError
39
+ puts "skipping hpricot tests"
40
+ end
41
+
28
42
  def test_introspection
29
43
  doc = <<END
30
44
  <service xmlns="http://www.w3.org/2007/app"
@@ -123,6 +137,8 @@ END
123
137
  end
124
138
 
125
139
  def test_autodiscover_service_link
140
+ return unless have_hpricot
141
+
126
142
  http = FakeHTTP.new \
127
143
  'http://example.org/' => [ 'text/html', '<html><link rel="service" href="svc">' ],
128
144
  'http://example.org/xhtml' => [ 'text/html', '<html><head><link rel="service" href="svc"/></head></html>' ],
@@ -136,6 +152,8 @@ END
136
152
  end
137
153
 
138
154
  def test_autodiscover_rsd
155
+ return unless have_hpricot
156
+
139
157
  http = FakeHTTP.new \
140
158
  'http://example.org/' => [ 'text/html', '<html><link rel="EditURI" href="rsd">' ],
141
159
  'http://example.org/svc' => [ 'application/atomsvc+xml', '<service xmlns="http://www.w3.org/2007/app"/>' ],
@@ -154,6 +172,8 @@ END
154
172
  end
155
173
 
156
174
  def test_cant_autodiscover
175
+ return unless have_hpricot
176
+
157
177
  http = FakeHTTP.new 'http://example.org/h' => [ 'text/html', '<html>' ],
158
178
  'http://example.org/t' => [ 'text/plain', 'no joy.' ]
159
179
 
data/test/test_xml.rb CHANGED
File without changes
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atom-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brendan Taylor
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-05-13 00:00:00 -06:00
12
+ date: 2009-05-01 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -28,7 +28,6 @@ files:
28
28
  - setup.rb
29
29
  - bin/atom-grep
30
30
  - bin/atom-post
31
- - bin/atom-show
32
31
  - bin/atom-purge
33
32
  - bin/atom-cp
34
33
  - test/test_constructs.rb
@@ -76,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
75
  requirements: []
77
76
 
78
77
  rubyforge_project: ibes
79
- rubygems_version: 1.1.1
78
+ rubygems_version: 1.3.1
80
79
  signing_key:
81
80
  specification_version: 2
82
81
  summary: Tools for working with Atom Entries, Feeds and Collections
data/bin/atom-show DELETED
@@ -1,70 +0,0 @@
1
- #!/usr/bin/ruby
2
-
3
- =begin
4
- Usage: atom-show [options] source
5
- displays a feed human-readably
6
-
7
- 'source' can be a path on the local filesystem, the
8
- URL of an Atom Collection or '-' for stdin.
9
- =end
10
-
11
- require 'atom/tools'
12
- include Atom::Tools
13
-
14
- def parse_options
15
- options = { }
16
-
17
- opts = OptionParser.new do |opts|
18
- opts.banner = <<END
19
- Usage: #{$0} [options] [source]
20
- displays a feed human-readably
21
-
22
- 'source' can be a path on the local filesystem, the
23
- URL of an Atom Collection or '-' for stdin.
24
- END
25
-
26
- opts.on('-c', '--complete', "Follow previous and next links in the source feed to obtain the entire logical feed") do
27
- options[:complete] = true
28
- end
29
-
30
- opts.on('-n', '--content [MAX-LENGTH]', "Display max-length words of each entry's content") do |length|
31
- options[:content] = length ? length.to_i : 0
32
- end
33
-
34
- atom_options opts, options
35
- end
36
-
37
- opts.parse!(ARGV)
38
-
39
- if ARGV.length > 1
40
- puts opts
41
- exit
42
- end
43
-
44
- options
45
- end
46
-
47
- if __FILE__ == $0
48
- require 'optparse'
49
-
50
- options = parse_options
51
-
52
- source = ARGV[0]
53
- source ||= '-'
54
-
55
- entries = parse_input source, options
56
-
57
- entries.each do |e|
58
- puts e.title
59
-
60
- if options[:content]
61
- if options[:content].zero?
62
- puts e.content.to_s
63
- else
64
- puts e.content.to_s.split(' ')[0,options[:content]].join(' ')
65
- end
66
- end
67
-
68
- puts
69
- end
70
- end