pelle-oauth 0.2.7 → 0.3.0

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.
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