pelle-oauth 0.2.7 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/History.txt +14 -0
  2. data/Manifest.txt +19 -3
  3. data/README.rdoc +73 -0
  4. data/Rakefile +34 -4
  5. data/TODO +14 -0
  6. data/bin/oauth +5 -0
  7. data/lib/oauth.rb +3 -3
  8. data/lib/oauth/cli.rb +130 -0
  9. data/lib/oauth/client/helper.rb +3 -2
  10. data/lib/oauth/consumer.rb +1 -1
  11. data/lib/oauth/helper.rb +3 -0
  12. data/lib/oauth/oauth_test_helper.rb +26 -0
  13. data/lib/oauth/request_proxy/action_controller_request.rb +2 -4
  14. data/lib/oauth/request_proxy/base.rb +31 -0
  15. data/lib/oauth/request_proxy/jabber_request.rb +42 -0
  16. data/lib/oauth/request_proxy/mock_request.rb +36 -0
  17. data/lib/oauth/request_proxy/net_http.rb +0 -2
  18. data/lib/oauth/request_proxy/rack_request.rb +1 -3
  19. data/lib/oauth/signature/base.rb +20 -7
  20. data/lib/oauth/signature/plaintext.rb +1 -1
  21. data/lib/oauth/token.rb +3 -3
  22. data/lib/oauth/version.rb +2 -8
  23. data/oauth.gemspec +43 -0
  24. data/script/txt2html +1 -1
  25. data/test/cases/oauth_case.rb +19 -0
  26. data/test/cases/spec/1_0-final/test_construct_request_url.rb +62 -0
  27. data/test/cases/spec/1_0-final/test_normalize_request_parameters.rb +88 -0
  28. data/test/cases/spec/1_0-final/test_parameter_encodings.rb +86 -0
  29. data/test/cases/spec/1_0-final/test_signature_base_strings.rb +77 -0
  30. data/test/keys/rsa.cert +11 -0
  31. data/test/keys/rsa.pem +16 -0
  32. data/test/test_action_controller_request_proxy.rb +2 -1
  33. data/test/test_consumer.rb +17 -18
  34. data/test/test_helper.rb +8 -0
  35. data/test/test_net_http_client.rb +7 -7
  36. data/test/test_net_http_request_proxy.rb +3 -3
  37. data/test/test_rack_request_proxy.rb +3 -3
  38. data/test/test_rsa_sha1.rb +59 -0
  39. data/test/test_signature_plain_text.rb +31 -0
  40. data/website/index.html +1 -1
  41. metadata +53 -14
  42. data/config/hoe.rb +0 -71
  43. data/config/requirements.rb +0 -17
data/History.txt CHANGED
@@ -1,3 +1,17 @@
1
+ Fix in plain text signatures to bug found by Andrew Arrow. Who contributed new new unit tests for plain text sigs.
2
+
3
+ == 0.3.0
4
+
5
+ * Support ActionController::Request from Edge Rails (László Bácsi)
6
+ * Correctly handle multi-valued parameters (Seth)
7
+ * Added #normalized_parameters to OAuth::RequestProxy::Base (Pelle)
8
+ * OAuth::Signature.sign and friends now yield the RequestProxy instead of the
9
+ token when the passed block's arity is 1. (Seth)
10
+ * Token requests are made to the configured URL rather than generating a
11
+ potentially incorrect one. (Kellan Elliott-McCrea)
12
+ * Command-line app for generating signatures. (Seth)
13
+ * Improved test-cases and compatibility for encoding issues. (Pelle)
14
+
1
15
  == 0.2.7 2008-9-10 The lets fix the last release release
2
16
 
3
17
  There was an error in the RSA requests using oauth tokens. Thanks to Philip Lipu Tsai for noticing this.
data/Manifest.txt CHANGED
@@ -1,20 +1,24 @@
1
1
  History.txt
2
2
  License.txt
3
3
  Manifest.txt
4
- README.txt
4
+ README.rdoc
5
5
  Rakefile
6
- config/hoe.rb
7
- config/requirements.rb
6
+ TODO
7
+ bin/oauth
8
8
  lib/oauth.rb
9
+ lib/oauth/cli.rb
9
10
  lib/oauth/client.rb
10
11
  lib/oauth/client/action_controller_request.rb
11
12
  lib/oauth/client/helper.rb
12
13
  lib/oauth/client/net_http.rb
13
14
  lib/oauth/consumer.rb
14
15
  lib/oauth/helper.rb
16
+ lib/oauth/oauth_test_helper.rb
15
17
  lib/oauth/request_proxy.rb
16
18
  lib/oauth/request_proxy/action_controller_request.rb
17
19
  lib/oauth/request_proxy/base.rb
20
+ lib/oauth/request_proxy/jabber_request.rb
21
+ lib/oauth/request_proxy/mock_request.rb
18
22
  lib/oauth/request_proxy/net_http.rb
19
23
  lib/oauth/request_proxy/rack_request.rb
20
24
  lib/oauth/server.rb
@@ -31,13 +35,22 @@ lib/oauth/signature/rsa/sha1.rb
31
35
  lib/oauth/signature/sha1.rb
32
36
  lib/oauth/token.rb
33
37
  lib/oauth/version.rb
38
+ oauth.gemspec
34
39
  script/destroy
35
40
  script/generate
36
41
  script/txt2html
37
42
  setup.rb
43
+ specs.txt
38
44
  tasks/deployment.rake
39
45
  tasks/environment.rake
40
46
  tasks/website.rake
47
+ test/cases/oauth_case.rb
48
+ test/cases/spec/1_0-final/test_construct_request_url.rb
49
+ test/cases/spec/1_0-final/test_normalize_request_parameters.rb
50
+ test/cases/spec/1_0-final/test_parameter_encodings.rb
51
+ test/cases/spec/1_0-final/test_signature_base_strings.rb
52
+ test/keys/rsa.cert
53
+ test/keys/rsa.pem
41
54
  test/test_action_controller_request_proxy.rb
42
55
  test/test_consumer.rb
43
56
  test/test_helper.rb
@@ -45,8 +58,11 @@ test/test_hmac_sha1.rb
45
58
  test/test_net_http_client.rb
46
59
  test/test_net_http_request_proxy.rb
47
60
  test/test_rack_request_proxy.rb
61
+ test/test_rsa_sha1.rb
62
+ test/test_server.rb
48
63
  test/test_signature.rb
49
64
  test/test_signature_base.rb
65
+ test/test_signature_plain_text.rb
50
66
  test/test_token.rb
51
67
  website/index.html
52
68
  website/index.txt
data/README.rdoc ADDED
@@ -0,0 +1,73 @@
1
+ = Ruby OAuth GEM
2
+
3
+ == What
4
+
5
+ This is a RubyGem for implementing both OAuth clients and servers in Ruby applications.
6
+
7
+ See the OAuth specs http://oauth.net/core/1.0/
8
+
9
+ == Installing
10
+
11
+ sudo gem install oauth
12
+
13
+ You can also install it from the oauth rubyforge project http://rubyforge.org/projects/oauth/.
14
+
15
+ The source code is now hosted on the OAuth GitHub Project http://github.com/pelle/oauth/tree/master
16
+
17
+ == The basics
18
+
19
+ This is a ruby library which is intended to be used in creating Ruby Consumer and Service Provider applications. It is NOT a Rails plugin, but could easily be used for the foundation for such a Rails plugin.
20
+
21
+ As a matter of fact it has been pulled out from an OAuth Rails Plugin http://code.google.com/p/oauth-plugin/ which now requires this GEM.
22
+
23
+ == Demonstration of usage
24
+
25
+ Create a new consumer instance by passing it a configuration hash:
26
+
27
+ @consumer=OAuth::Consumer.new( "key","secret", {
28
+ :site=>"https://agree2"
29
+ })
30
+
31
+ Start the process by requesting a token
32
+
33
+ @request_token=@consumer.get_request_token
34
+ session[:request_token]=@request_token
35
+ redirect_to @request_token.authorize_url
36
+
37
+ When user returns create an access_token
38
+
39
+ @access_token=@request_token.get_access_token
40
+ @photos=@access_token.get('/photos.xml')
41
+
42
+ For more detailed instructions I have written this OAuth Client Tutorial http://stakeventures.com/articles/2008/02/23/developing-oauth-clients-in-ruby and "How to turn your rails site into an OAuth Provider ":http://stakeventures.com/articles/2007/11/26/how-to-turn-your-rails-site-into-an-oauth-provider .
43
+
44
+ Finally be sure to check out the OAuth RDoc Manual http://oauth.rubyforge.org/rdoc/ .
45
+
46
+ == Documentation Wiki
47
+
48
+ There is some documentation on the Google Code project for the "OAuth Rails Plugin":http://code.google.com/p/oauth-plugin/ :
49
+
50
+ * RequestToken http://code.google.com/p/oauth-plugin/wiki/RequestToken
51
+ * AccessToken http://code.google.com/p/oauth-plugin/wiki/AccessToken
52
+
53
+ == Forum
54
+
55
+ http://groups.google.com/group/oauth-ruby
56
+
57
+
58
+ == How to submit patches
59
+
60
+ Read the "8 steps for fixing other people's code" http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/.
61
+
62
+ The source code is now hosted on the OAuth GitHub Project http://github.com/pelle/oauth/tree/master
63
+
64
+ To submit a patch, please fork the oauth project and create a patch with tests. Once you're happy with it send a pull request and post a message to the google group.
65
+
66
+ == License
67
+
68
+ This code is free to use under the terms of the MIT license.
69
+
70
+ == Contact
71
+
72
+ Comments are welcome. Send an email to "Pelle Braendgaard" pelleb@gmail.com email via the OAuth Ruby mailing list http://groups.google.com/group/oauth-ruby
73
+
data/Rakefile CHANGED
@@ -1,4 +1,34 @@
1
- require 'config/requirements'
2
- require 'config/hoe' # setup Hoe + all gem configuration
3
-
4
- Dir['tasks/**/*.rake'].each { |rake| load rake }
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ $LOAD_PATH << File.dirname(__FILE__) + '/lib'
3
+ require 'oauth'
4
+ require 'oauth/version'
5
+
6
+ # Generate all the Rake tasks
7
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
8
+ $hoe = Hoe.new('oauth', OAuth::VERSION) do |p|
9
+ p.author = ['Pelle Braendgaard','Blaine Cook','Larry Halff','Jesse Clark','Jon Crosby', 'Seth Fitzsimmons']
10
+ p.email = "pelleb@gmail.com"
11
+ p.description = "OAuth Core Ruby implementation"
12
+ p.summary = p.description
13
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
14
+ p.rubyforge_name = p.name # TODO this is default value
15
+ p.url = "http://oauth.rubyforge.org"
16
+
17
+ p.extra_deps = [
18
+ ['ruby-hmac','>= 0.3.1']
19
+ ]
20
+ p.extra_dev_deps = [
21
+ ['newgem', ">= #{::Newgem::VERSION}"]
22
+ ]
23
+
24
+ p.clean_globs |= %w[**/.DS_Store tmp *.log **/.*.sw? *.gem .config **/.DS_Store]
25
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
26
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
27
+ p.rsync_args = '-av --delete --ignore-errors'
28
+ end
29
+
30
+ require 'newgem/tasks' # load /tasks/*.rake
31
+ Dir['tasks/**/*.rake'].each { |t| load t }
32
+
33
+ # TODO - want other tests/tasks run by default? Add them to the list
34
+ # task :default => [:spec, :features]
data/TODO ADDED
@@ -0,0 +1,14 @@
1
+ Common use-cases should be streamlined:
2
+
3
+ * I have a URL that I want to sign (given consumer key/secret, optional
4
+ token/secret, optional nonce/timestamp).
5
+ * I have a URL that I want to sign AND I want to see what the components
6
+ (e.g. signature base string, etc.) are while it's being signed (i.e. verbose
7
+ signing).
8
+ * I have a URL that I want to sign and I only want the signature.
9
+ * I have a URL that I want to sign and I want something suitable to put in
10
+ {the header, the querystring, XMPP}.
11
+ * I want to make a query to an OAuth-enabled web service (with sensible
12
+ errors, if available).
13
+ * I want to host an OAuth-enabled web service.
14
+ * I want to test my OAuth-enabled web service (i.e. test helpers)
data/bin/oauth ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "oauth/cli"
4
+
5
+ OAuth::CLI.execute(STDOUT, ARGV)
data/lib/oauth.rb CHANGED
@@ -1,3 +1,3 @@
1
- $:.unshift File.dirname(__FILE__)
2
-
3
- module OAuth; end
1
+ require 'oauth/client/helper'
2
+ require 'oauth/signature/hmac/sha1'
3
+ require 'oauth/request_proxy/mock_request'
data/lib/oauth/cli.rb ADDED
@@ -0,0 +1,130 @@
1
+ require 'optparse'
2
+ require 'oauth'
3
+
4
+ module OAuth
5
+ class CLI
6
+ SUPPORTED_COMMANDS = %w(sign)
7
+
8
+ attr_reader :command
9
+ attr_reader :options
10
+ attr_reader :stdout
11
+
12
+ def self.execute(stdout, arguments = [])
13
+ self.new.execute(stdout, arguments)
14
+ end
15
+
16
+ def execute(stdout, arguments = [])
17
+ @stdout = stdout
18
+ extract_command_and_parse_options(arguments)
19
+
20
+ if sufficient_options? && valid_command?
21
+ case command
22
+ when "sign"
23
+ request = OAuth::RequestProxy.proxy \
24
+ "method" => options[:method],
25
+ "uri" => options[:uri],
26
+ "parameters" => prepare_parameters
27
+
28
+ # can't pass options unless they respond to :secret, so use this alternative
29
+ signature = OAuth::Signature.sign \
30
+ request,
31
+ :consumer_secret => options[:oauth_consumer_secret],
32
+ :token_secret => options[:oauth_token_secret] do |request|
33
+
34
+ # while we have access to the request being signed, display some internals
35
+ if verbose?
36
+ stdout.puts "Method: #{request.method}"
37
+ stdout.puts "URI: #{request.uri}"
38
+ stdout.puts "Normalized params: #{request.normalized_parameters}"
39
+ stdout.puts "Signature base string: #{request.signature_base_string}"
40
+ end
41
+ end
42
+
43
+ if verbose?
44
+ stdout.puts "Signature: #{signature}"
45
+ stdout.puts "Escaped signature: #{OAuth::Helper.escape(signature)}"
46
+ else
47
+ stdout.puts signature
48
+ end
49
+ end
50
+ else
51
+ usage
52
+ end
53
+ end
54
+
55
+ def extract_command_and_parse_options(arguments)
56
+ @command = arguments[-1]
57
+ parse_options(arguments[0..-1])
58
+ end
59
+
60
+ def parse_options(arguments)
61
+ @options = {}
62
+ OptionParser.new do |opts|
63
+ opts.banner = "Usage: #{$0} [options] <command>"
64
+
65
+ # defaults
66
+ options[:oauth_signature_method] = "HMAC-SHA1"
67
+
68
+ opts.on("--consumer-key KEY", "Specifies the consumer key to use.") do |v|
69
+ options[:oauth_consumer_key] = v
70
+ end
71
+
72
+ opts.on("--consumer-secret SECRET", "Specifies the consumer secret to use.") do |v|
73
+ options[:oauth_consumer_secret] = v
74
+ end
75
+
76
+ opts.on("--method METHOD", "Specifies the method (e.g. GET) to use when signing.") do |v|
77
+ options[:method] = v
78
+ end
79
+
80
+ opts.on("--parameters PARAMS", "Specifies the parameters to use when signing.") do |v|
81
+ options[:params] = v
82
+ end
83
+
84
+ opts.on("--signature-method METHOD", "Specifies the signature method to use; defaults to HMAC-SHA1.") do |v|
85
+ options[:oauth_signature_method] = v
86
+ end
87
+
88
+ opts.on("--secret SECRET", "Specifies the token secret to use.") do |v|
89
+ options[:oauth_token_secret] = v
90
+ end
91
+
92
+ opts.on("--token TOKEN", "Specifies the token to use.") do |v|
93
+ options[:oauth_token] = v
94
+ end
95
+
96
+ opts.on("--uri URI", "Specifies the URI to use when signing.") do |v|
97
+ options[:uri] = v
98
+ end
99
+
100
+ opts.on("-v", "--verbose", "Be verbose.") do
101
+ options[:verbose] = true
102
+ end
103
+ end.parse!(arguments)
104
+ end
105
+
106
+ def prepare_parameters
107
+ {
108
+ "oauth_consumer_key" => options[:oauth_consumer_key],
109
+ "oauth_token" => options[:oauth_token],
110
+ "oauth_signature_method" => options[:oauth_signature_method]
111
+ }.merge(CGI.parse(options[:params]))
112
+ end
113
+
114
+ def sufficient_options?
115
+ options[:oauth_consumer_key] && options[:oauth_consumer_secret] && options[:method] && options[:uri]
116
+ end
117
+
118
+ def usage
119
+ stdout.puts "Should be generated by OptionParser"
120
+ end
121
+
122
+ def valid_command?
123
+ SUPPORTED_COMMANDS.include?(command)
124
+ end
125
+
126
+ def verbose?
127
+ options[:verbose]
128
+ end
129
+ end
130
+ end
@@ -38,7 +38,7 @@ module OAuth::Client
38
38
  'oauth_timestamp' => timestamp,
39
39
  'oauth_nonce' => nonce,
40
40
  'oauth_version' => '1.0'
41
- }
41
+ }.reject { |k,v| v == "" }
42
42
  end
43
43
 
44
44
  def signature(extra_options = {})
@@ -60,7 +60,8 @@ module OAuth::Client
60
60
 
61
61
  header_params_str = parameters.map { |k,v| "#{k}=\"#{escape(v)}\"" }.join(', ')
62
62
 
63
- return "OAuth realm=\"#{options[:realm]||''}\", #{header_params_str}"
63
+ realm = "realm=\"#{options[:realm]}\", " if options[:realm]
64
+ "OAuth #{realm}#{header_params_str}"
64
65
  end
65
66
 
66
67
  def parameters
@@ -91,7 +91,7 @@ module OAuth
91
91
  # @request_token=@consumer.get_request_token
92
92
  #
93
93
  def get_request_token(request_options={}, *arguments)
94
- response=token_request(http_method,request_token_path, nil, request_options, *arguments)
94
+ response=token_request(http_method,request_token_url, nil, request_options, *arguments)
95
95
  OAuth::RequestToken.new(self,response[:oauth_token],response[:oauth_token_secret])
96
96
  end
97
97
 
data/lib/oauth/helper.rb CHANGED
@@ -1,7 +1,10 @@
1
1
  require 'openssl'
2
2
  require 'base64'
3
+ require 'cgi'
3
4
  module OAuth
4
5
  module Helper
6
+ extend self
7
+
5
8
  def escape(value)
6
9
  CGI.escape(value.to_s).gsub("%7E", '~').gsub("+", "%20")
7
10
  end
@@ -0,0 +1,26 @@
1
+ require 'action_controller'
2
+ require 'action_controller/test_process'
3
+ module OAuth
4
+ module OAuthTestHelper
5
+
6
+ def mock_incoming_request_with_query(request)
7
+ incoming=ActionController::TestRequest.new(request.to_hash)
8
+ incoming.request_uri=request.path
9
+ incoming.env["SERVER_PORT"]=request.uri.port
10
+ incoming.host=request.uri.host
11
+ incoming.env['REQUEST_METHOD']=request.http_method
12
+ incoming
13
+ end
14
+
15
+ def mock_incoming_request_with_authorize_header(request)
16
+ incoming=ActionController::TestRequest.new
17
+ incoming.env["HTTP_AUTHORIZATION"]=request.to_auth_string
18
+ incoming.request_uri=request.path
19
+ incoming.env["SERVER_PORT"]=request.uri.port
20
+ incoming.host=request.uri.host
21
+ incoming.env['REQUEST_METHOD']=request.http_method
22
+ incoming
23
+ end
24
+
25
+ end
26
+ end
@@ -6,16 +6,14 @@ require 'uri'
6
6
 
7
7
  module OAuth::RequestProxy
8
8
  class ActionControllerRequest < OAuth::RequestProxy::Base
9
- proxies ActionController::AbstractRequest
9
+ proxies(defined?(ActionController::AbstractRequest) ? ActionController::AbstractRequest : ActionController::Request)
10
10
 
11
11
  def method
12
12
  request.method.to_s.upcase
13
13
  end
14
14
 
15
15
  def uri
16
- uri = URI.parse(request.protocol + request.host + request.port_string + request.path)
17
- uri.query = nil
18
- uri.to_s
16
+ request.url
19
17
  end
20
18
 
21
19
  def parameters