atom-tools 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
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