gregwebs-oauth 0.3.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +102 -0
- data/License.txt +20 -0
- data/Manifest.txt +84 -0
- data/README.rdoc +71 -0
- data/Rakefile +36 -0
- data/TODO +31 -0
- data/bin/oauth +5 -0
- data/examples/yql.rb +44 -0
- data/lib/oauth.rb +4 -0
- data/lib/oauth/cli.rb +378 -0
- data/lib/oauth/client.rb +4 -0
- data/lib/oauth/client/action_controller_request.rb +54 -0
- data/lib/oauth/client/helper.rb +85 -0
- data/lib/oauth/client/net_http.rb +103 -0
- data/lib/oauth/consumer.rb +354 -0
- data/lib/oauth/errors.rb +3 -0
- data/lib/oauth/errors/error.rb +4 -0
- data/lib/oauth/errors/problem.rb +14 -0
- data/lib/oauth/errors/unauthorized.rb +12 -0
- data/lib/oauth/helper.rb +78 -0
- data/lib/oauth/oauth.rb +11 -0
- data/lib/oauth/oauth_test_helper.rb +25 -0
- data/lib/oauth/request_proxy.rb +24 -0
- data/lib/oauth/request_proxy/action_controller_request.rb +61 -0
- data/lib/oauth/request_proxy/base.rb +166 -0
- data/lib/oauth/request_proxy/jabber_request.rb +41 -0
- data/lib/oauth/request_proxy/mock_request.rb +44 -0
- data/lib/oauth/request_proxy/net_http.rb +68 -0
- data/lib/oauth/request_proxy/rack_request.rb +40 -0
- data/lib/oauth/server.rb +66 -0
- data/lib/oauth/signature.rb +40 -0
- data/lib/oauth/signature/base.rb +91 -0
- data/lib/oauth/signature/hmac/base.rb +12 -0
- data/lib/oauth/signature/hmac/md5.rb +9 -0
- data/lib/oauth/signature/hmac/rmd160.rb +9 -0
- data/lib/oauth/signature/hmac/sha1.rb +9 -0
- data/lib/oauth/signature/hmac/sha2.rb +9 -0
- data/lib/oauth/signature/md5.rb +13 -0
- data/lib/oauth/signature/plaintext.rb +23 -0
- data/lib/oauth/signature/rsa/sha1.rb +45 -0
- data/lib/oauth/signature/sha1.rb +13 -0
- data/lib/oauth/token.rb +7 -0
- data/lib/oauth/tokens/access_token.rb +68 -0
- data/lib/oauth/tokens/consumer_token.rb +33 -0
- data/lib/oauth/tokens/request_token.rb +32 -0
- data/lib/oauth/tokens/server_token.rb +9 -0
- data/lib/oauth/tokens/token.rb +17 -0
- data/lib/oauth/version.rb +3 -0
- data/oauth.gemspec +49 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/test/cases/oauth_case.rb +19 -0
- data/test/cases/spec/1_0-final/test_construct_request_url.rb +62 -0
- data/test/cases/spec/1_0-final/test_normalize_request_parameters.rb +88 -0
- data/test/cases/spec/1_0-final/test_parameter_encodings.rb +86 -0
- data/test/cases/spec/1_0-final/test_signature_base_strings.rb +77 -0
- data/test/keys/rsa.cert +11 -0
- data/test/keys/rsa.pem +16 -0
- data/test/test_access_token.rb +26 -0
- data/test/test_action_controller_request_proxy.rb +129 -0
- data/test/test_consumer.rb +362 -0
- data/test/test_helper.rb +14 -0
- data/test/test_hmac_sha1.rb +20 -0
- data/test/test_net_http_client.rb +185 -0
- data/test/test_net_http_request_proxy.rb +72 -0
- data/test/test_oauth_helper.rb +49 -0
- data/test/test_rack_request_proxy.rb +40 -0
- data/test/test_request_token.rb +51 -0
- data/test/test_rsa_sha1.rb +59 -0
- data/test/test_server.rb +40 -0
- data/test/test_signature.rb +19 -0
- data/test/test_signature_base.rb +32 -0
- data/test/test_signature_plain_text.rb +31 -0
- data/test/test_token.rb +14 -0
- data/website/index.html +87 -0
- data/website/index.txt +73 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.rhtml +48 -0
- metadata +217 -0
data/History.txt
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
== 0.3.6 2009-09-14
|
2
|
+
|
3
|
+
* Added -B CLI option to use the :body authentication scheme (Seth)
|
4
|
+
* Respect `--method` in `authorize` CLI command (Seth)
|
5
|
+
* Support POST and PUT with raw bodies (Yu-Shan Fung et al)
|
6
|
+
* Test clean-up (Xavier Shay, Hannes Tydén)
|
7
|
+
* Added :ca_file consumer option to allow consumer specific certificate
|
8
|
+
override. (Pelle)
|
9
|
+
|
10
|
+
== 0.3.5 2009-06-03
|
11
|
+
|
12
|
+
* `query` CLI command to access protected resources (Seth)
|
13
|
+
* Added -H, -Q CLI options for specifying the authentication scheme (Seth)
|
14
|
+
* Added -O CLI option for specifying a file containing options (Seth)
|
15
|
+
* Support streamable body contents for large request bodies (Seth Cousins)
|
16
|
+
* Support for OAuth 1.0a (Seth)
|
17
|
+
* Added proxy support to OAuth::Consumer (Marshall Huss)
|
18
|
+
* Added --scope CLI option for Google's 'scope' parameter (Seth)
|
19
|
+
|
20
|
+
== 0.3.4 2009-05-06
|
21
|
+
|
22
|
+
* OAuth::Client::Helper uses OAuth::VERSION (chadisfaction)
|
23
|
+
* Fix OAuth::RequestProxy::ActionControllerRequest's handling of params
|
24
|
+
(Tristan Groléat)
|
25
|
+
|
26
|
+
== 0.3.3 2009-05-04
|
27
|
+
|
28
|
+
* Corrected OAuth XMPP namespace (Seth)
|
29
|
+
* Improved error handling for invalid Authorization headers (Matt Sanford)
|
30
|
+
* Fixed signatures for non-ASCII under $KCODE other than 'u' (Matt Sanford)
|
31
|
+
* Fixed edge cases in ActionControllerRequestProxy where params were being
|
32
|
+
incorrectly signed (Marcos Wright Kuhns)
|
33
|
+
* Support for arguments in OAuth::Consumer#get_access_token (Matt Sanford)
|
34
|
+
* Add gem version to user-agent header (Matt Sanford)
|
35
|
+
* Handle input from aggressive form encoding libraries (Matt Wood)
|
36
|
+
|
37
|
+
== 0.3.2 2009-03-23
|
38
|
+
|
39
|
+
* 2xx statuses should be treated as success (Anders Conbere)
|
40
|
+
* Support applications using the MethodOverride Rack middleware (László Bácsi)
|
41
|
+
* `authorize` command for `oauth` CLI (Seth)
|
42
|
+
* Initial support for Problem Reporting extension (Seth)
|
43
|
+
* Verify SSL certificates if CA certificates are available (Seth)
|
44
|
+
* Fixed ActionController parameter escaping behavior (Thiago Arrais, László
|
45
|
+
Bácsi, Brett Gibson, et al)
|
46
|
+
* Fixed signature calculation when both options and a block were provided to
|
47
|
+
OAuth::Signature::Base#initialize (Seth)
|
48
|
+
* Added help to the 'oauth' CLI (Seth)
|
49
|
+
* Fixed a problem when attempting to normalize MockRequest URIs (Seth)
|
50
|
+
|
51
|
+
== 0.3.1 2009-1-26
|
52
|
+
|
53
|
+
* Fixed a problem with relative and absolute token request paths. (Michael
|
54
|
+
Wood)
|
55
|
+
|
56
|
+
== 0.3.0 2009-1-25
|
57
|
+
|
58
|
+
* Support ActionController::Request from Edge Rails (László Bácsi)
|
59
|
+
* Correctly handle multi-valued parameters (Seth)
|
60
|
+
* Added #normalized_parameters to OAuth::RequestProxy::Base (Pelle)
|
61
|
+
* OAuth::Signature.sign and friends now yield the RequestProxy instead of the
|
62
|
+
token when the passed block's arity is 1. (Seth)
|
63
|
+
* Token requests are made to the configured URL rather than generating a
|
64
|
+
potentially incorrect one. (Kellan Elliott-McCrea)
|
65
|
+
* Command-line app for generating signatures. (Seth)
|
66
|
+
* Improved test-cases and compatibility for encoding issues. (Pelle)
|
67
|
+
|
68
|
+
== 0.2.7 2008-9-10 The lets fix the last release release
|
69
|
+
|
70
|
+
* Fixed plain text signatures (Andrew Arrow)
|
71
|
+
* Fixed RSA requests using OAuthTokens. (Philip Lipu Tsai)
|
72
|
+
|
73
|
+
== 0.2.6 2008-9-9 The lets RSA release
|
74
|
+
|
75
|
+
* Improved support for Ruby 1.8.7 (Bill Kocik)
|
76
|
+
* Fixed RSA verification to support RSA providers
|
77
|
+
now using Ruby and RSA
|
78
|
+
* Improved RSA testing
|
79
|
+
* Omit token when signing with RSA
|
80
|
+
* Added support for 'private_key_file' option for RSA signatures (Chris Mear)
|
81
|
+
* Fixed several edge cases where params were being incorrectly signed (Scott
|
82
|
+
Hill)
|
83
|
+
* Fixed RSA signing (choonkeat)
|
84
|
+
|
85
|
+
== 0.2.2 2008-2-22 Lets actually support SSL release
|
86
|
+
|
87
|
+
* Use HTTPS when required.
|
88
|
+
|
89
|
+
== 0.2 2008-1-19 All together now release
|
90
|
+
|
91
|
+
This is a big release, where we have merged the efforts of various parties into one common library. This means there are definitely some API changes you should be aware of. They should be minimal but please have a look at the unit tests.
|
92
|
+
|
93
|
+
== 0.1.2 2007-12-1
|
94
|
+
|
95
|
+
* Fixed checks for missing OAuth params to improve performance
|
96
|
+
* Includes Pat's fix for getting the realm out.
|
97
|
+
|
98
|
+
== 0.1.1 2007-11-26
|
99
|
+
|
100
|
+
* First release as a GEM
|
101
|
+
* Moved all non-Rails functionality from the Rails plugin:
|
102
|
+
http://code.google.com/p/oauth-plugin/
|
data/License.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007 Blaine Cook, Larry Halff, Pelle Braendgaard
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest.txt
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
History.txt
|
2
|
+
License.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.rdoc
|
5
|
+
Rakefile
|
6
|
+
TODO
|
7
|
+
bin/oauth
|
8
|
+
examples/yql.rb
|
9
|
+
lib/oauth.rb
|
10
|
+
lib/oauth/oauth.rb
|
11
|
+
lib/oauth/cli.rb
|
12
|
+
lib/oauth/client.rb
|
13
|
+
lib/oauth/client/action_controller_request.rb
|
14
|
+
lib/oauth/client/helper.rb
|
15
|
+
lib/oauth/client/net_http.rb
|
16
|
+
lib/oauth/consumer.rb
|
17
|
+
lib/oauth/errors.rb
|
18
|
+
lib/oauth/errors/error.rb
|
19
|
+
lib/oauth/errors/problem.rb
|
20
|
+
lib/oauth/errors/unauthorized.rb
|
21
|
+
lib/oauth/helper.rb
|
22
|
+
lib/oauth/oauth_test_helper.rb
|
23
|
+
lib/oauth/request_proxy.rb
|
24
|
+
lib/oauth/request_proxy/action_controller_request.rb
|
25
|
+
lib/oauth/request_proxy/base.rb
|
26
|
+
lib/oauth/request_proxy/jabber_request.rb
|
27
|
+
lib/oauth/request_proxy/mock_request.rb
|
28
|
+
lib/oauth/request_proxy/net_http.rb
|
29
|
+
lib/oauth/request_proxy/rack_request.rb
|
30
|
+
lib/oauth/server.rb
|
31
|
+
lib/oauth/signature.rb
|
32
|
+
lib/oauth/signature/base.rb
|
33
|
+
lib/oauth/signature/hmac/base.rb
|
34
|
+
lib/oauth/signature/hmac/md5.rb
|
35
|
+
lib/oauth/signature/hmac/rmd160.rb
|
36
|
+
lib/oauth/signature/hmac/sha1.rb
|
37
|
+
lib/oauth/signature/hmac/sha2.rb
|
38
|
+
lib/oauth/signature/md5.rb
|
39
|
+
lib/oauth/signature/plaintext.rb
|
40
|
+
lib/oauth/signature/rsa/sha1.rb
|
41
|
+
lib/oauth/signature/sha1.rb
|
42
|
+
lib/oauth/token.rb
|
43
|
+
lib/oauth/tokens/access_token.rb
|
44
|
+
lib/oauth/tokens/consumer_token.rb
|
45
|
+
lib/oauth/tokens/request_token.rb
|
46
|
+
lib/oauth/tokens/server_token.rb
|
47
|
+
lib/oauth/tokens/token.rb
|
48
|
+
lib/oauth/version.rb
|
49
|
+
oauth.gemspec
|
50
|
+
script/destroy
|
51
|
+
script/generate
|
52
|
+
script/txt2html
|
53
|
+
setup.rb
|
54
|
+
tasks/deployment.rake
|
55
|
+
tasks/environment.rake
|
56
|
+
tasks/website.rake
|
57
|
+
test/cases/oauth_case.rb
|
58
|
+
test/cases/spec/1_0-final/test_construct_request_url.rb
|
59
|
+
test/cases/spec/1_0-final/test_normalize_request_parameters.rb
|
60
|
+
test/cases/spec/1_0-final/test_parameter_encodings.rb
|
61
|
+
test/cases/spec/1_0-final/test_signature_base_strings.rb
|
62
|
+
test/keys/rsa.cert
|
63
|
+
test/keys/rsa.pem
|
64
|
+
test/test_access_token.rb
|
65
|
+
test/test_action_controller_request_proxy.rb
|
66
|
+
test/test_consumer.rb
|
67
|
+
test/test_helper.rb
|
68
|
+
test/test_hmac_sha1.rb
|
69
|
+
test/test_net_http_client.rb
|
70
|
+
test/test_net_http_request_proxy.rb
|
71
|
+
test/test_oauth_helper.rb
|
72
|
+
test/test_rack_request_proxy.rb
|
73
|
+
test/test_request_token.rb
|
74
|
+
test/test_rsa_sha1.rb
|
75
|
+
test/test_server.rb
|
76
|
+
test/test_signature.rb
|
77
|
+
test/test_signature_base.rb
|
78
|
+
test/test_signature_plain_text.rb
|
79
|
+
test/test_token.rb
|
80
|
+
website/index.html
|
81
|
+
website/index.txt
|
82
|
+
website/javascripts/rounded_corners_lite.inc.js
|
83
|
+
website/stylesheets/screen.css
|
84
|
+
website/template.rhtml
|
data/README.rdoc
ADDED
@@ -0,0 +1,71 @@
|
|
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/mojodna/oauth
|
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", :site => "https://agree2")
|
28
|
+
|
29
|
+
Start the process by requesting a token
|
30
|
+
|
31
|
+
@request_token = @consumer.get_request_token
|
32
|
+
session[:request_token] = @request_token
|
33
|
+
redirect_to @request_token.authorize_url
|
34
|
+
|
35
|
+
When user returns create an access_token
|
36
|
+
|
37
|
+
@access_token = @request_token.get_access_token
|
38
|
+
@photos = @access_token.get('/photos.xml')
|
39
|
+
|
40
|
+
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 .
|
41
|
+
|
42
|
+
Finally be sure to check out the OAuth RDoc Manual http://oauth.rubyforge.org/rdoc/ .
|
43
|
+
|
44
|
+
== Documentation Wiki
|
45
|
+
|
46
|
+
There is some documentation on the Google Code project for the "OAuth Rails Plugin":http://code.google.com/p/oauth-plugin/ :
|
47
|
+
|
48
|
+
* RequestToken http://code.google.com/p/oauth-plugin/wiki/RequestToken
|
49
|
+
* AccessToken http://code.google.com/p/oauth-plugin/wiki/AccessToken
|
50
|
+
|
51
|
+
== Forum
|
52
|
+
|
53
|
+
http://groups.google.com/group/oauth-ruby
|
54
|
+
|
55
|
+
|
56
|
+
== How to submit patches
|
57
|
+
|
58
|
+
Read the "8 steps for fixing other people's code" http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/.
|
59
|
+
|
60
|
+
The source code is now hosted on the OAuth GitHub Project http://github.com/mojodna/oauth
|
61
|
+
|
62
|
+
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.
|
63
|
+
|
64
|
+
== License
|
65
|
+
|
66
|
+
This code is free to use under the terms of the MIT license.
|
67
|
+
|
68
|
+
== Contact
|
69
|
+
|
70
|
+
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
|
71
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
%w[rubygems rake rake/clean fileutils newgem rubigen hoe].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 = "oauth-ruby@googlegroups.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
|
+
['actionpack'],
|
23
|
+
['rack']
|
24
|
+
]
|
25
|
+
|
26
|
+
p.clean_globs |= %w[**/.DS_Store tmp *.log **/.*.sw? *.gem .config **/.DS_Store]
|
27
|
+
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
|
28
|
+
p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
|
29
|
+
p.rsync_args = '-av --delete --ignore-errors'
|
30
|
+
end
|
31
|
+
|
32
|
+
require 'newgem/tasks' # load /tasks/*.rake
|
33
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
34
|
+
|
35
|
+
# TODO - want other tests/tasks run by default? Add them to the list
|
36
|
+
# task :default => [:spec, :features]
|
data/TODO
ADDED
@@ -0,0 +1,31 @@
|
|
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)
|
15
|
+
|
16
|
+
Example applications for:
|
17
|
+
* Ning
|
18
|
+
* Fire Eagle
|
19
|
+
* Google (blogger, contacts)
|
20
|
+
* Twitter
|
21
|
+
* YOS / YQL
|
22
|
+
* Netflix
|
23
|
+
|
24
|
+
In addition to providing best practices of use, these can also be part of
|
25
|
+
the pre-release checks to make sure that there have been no regressions.
|
26
|
+
|
27
|
+
Random TODOs:
|
28
|
+
* finish CLI
|
29
|
+
* sensible Exception hierarchy
|
30
|
+
* Tokens as Modules
|
31
|
+
* don't tie to Net::HTTP
|
data/bin/oauth
ADDED
data/examples/yql.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby -rubygems
|
2
|
+
|
3
|
+
# Sample queries:
|
4
|
+
# ./yql.rb --consumer-key <key> --consumer-secret <secret> "show tables"
|
5
|
+
# ./yql.rb --consumer-key <key> --consumer-secret <secret> "select * from flickr.photos.search where text='Cat' limit 10"
|
6
|
+
|
7
|
+
require 'oauth'
|
8
|
+
require 'optparse'
|
9
|
+
require 'json'
|
10
|
+
require 'pp'
|
11
|
+
|
12
|
+
options = {}
|
13
|
+
|
14
|
+
option_parser = OptionParser.new do |opts|
|
15
|
+
opts.banner = "Usage: #{$0} [options] <query>"
|
16
|
+
|
17
|
+
opts.on("--consumer-key KEY", "Specifies the consumer key to use.") do |v|
|
18
|
+
options[:consumer_key] = v
|
19
|
+
end
|
20
|
+
|
21
|
+
opts.on("--consumer-secret SECRET", "Specifies the consumer secret to use.") do |v|
|
22
|
+
options[:consumer_secret] = v
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
option_parser.parse!
|
27
|
+
query = ARGV.pop
|
28
|
+
query = STDIN.read if query == "-"
|
29
|
+
|
30
|
+
if options[:consumer_key].nil? || options[:consumer_secret].nil? || query.nil?
|
31
|
+
puts option_parser.help
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
|
35
|
+
consumer = OAuth::Consumer.new \
|
36
|
+
options[:consumer_key],
|
37
|
+
options[:consumer_secret],
|
38
|
+
:site => "http://query.yahooapis.com"
|
39
|
+
|
40
|
+
access_token = OAuth::AccessToken.new(consumer)
|
41
|
+
|
42
|
+
response = access_token.request(:get, "/v1/yql?q=#{OAuth::Helper.escape(query)}&format=json")
|
43
|
+
rsp = JSON.parse(response.body)
|
44
|
+
pp rsp
|
data/lib/oauth.rb
ADDED
data/lib/oauth/cli.rb
ADDED
@@ -0,0 +1,378 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'oauth'
|
3
|
+
|
4
|
+
module OAuth
|
5
|
+
class CLI
|
6
|
+
SUPPORTED_COMMANDS = {
|
7
|
+
"authorize" => "Obtain an access token and secret for a user",
|
8
|
+
"debug" => "Verbosely generate an OAuth signature",
|
9
|
+
"query" => "Query a protected resource",
|
10
|
+
"sign" => "Generate an OAuth signature",
|
11
|
+
"version" => "Display the current version of the library"
|
12
|
+
}
|
13
|
+
|
14
|
+
attr_reader :command
|
15
|
+
attr_reader :options
|
16
|
+
attr_reader :stdout, :stdin
|
17
|
+
|
18
|
+
def self.execute(stdout, stdin, stderr, arguments = [])
|
19
|
+
self.new.execute(stdout, stdin, stderr, arguments)
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@options = {}
|
24
|
+
|
25
|
+
# don't dump a backtrace on a ^C
|
26
|
+
trap(:INT) {
|
27
|
+
exit
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def execute(stdout, stdin, stderr, arguments = [])
|
32
|
+
@stdout = stdout
|
33
|
+
@stdin = stdin
|
34
|
+
@stderr = stderr
|
35
|
+
extract_command_and_parse_options(arguments)
|
36
|
+
|
37
|
+
if sufficient_options? && valid_command?
|
38
|
+
if command == "debug"
|
39
|
+
@command = "sign"
|
40
|
+
@options[:verbose] = true
|
41
|
+
end
|
42
|
+
|
43
|
+
case command
|
44
|
+
# TODO move command logic elsewhere
|
45
|
+
when "authorize"
|
46
|
+
begin
|
47
|
+
consumer = OAuth::Consumer.new \
|
48
|
+
options[:oauth_consumer_key],
|
49
|
+
options[:oauth_consumer_secret],
|
50
|
+
:access_token_url => options[:access_token_url],
|
51
|
+
:authorize_url => options[:authorize_url],
|
52
|
+
:request_token_url => options[:request_token_url],
|
53
|
+
:scheme => options[:scheme],
|
54
|
+
:http_method => options[:method].to_s.downcase.to_sym
|
55
|
+
|
56
|
+
# parameters for OAuth 1.0a
|
57
|
+
oauth_verifier = nil
|
58
|
+
|
59
|
+
# get a request token
|
60
|
+
request_token = consumer.get_request_token({ :oauth_callback => options[:oauth_callback] }, { "scope" => options[:scope] })
|
61
|
+
|
62
|
+
if request_token.callback_confirmed?
|
63
|
+
stdout.puts "Server appears to support OAuth 1.0a; enabling support."
|
64
|
+
options[:version] = "1.0a"
|
65
|
+
end
|
66
|
+
|
67
|
+
stdout.puts "Please visit this url to authorize:"
|
68
|
+
stdout.puts request_token.authorize_url
|
69
|
+
|
70
|
+
if options[:version] == "1.0a"
|
71
|
+
stdout.puts "Please enter the verification code provided by the SP (oauth_verifier):"
|
72
|
+
oauth_verifier = stdin.gets.chomp
|
73
|
+
else
|
74
|
+
stdout.puts "Press return to continue..."
|
75
|
+
stdin.gets
|
76
|
+
end
|
77
|
+
|
78
|
+
begin
|
79
|
+
# get an access token
|
80
|
+
access_token = request_token.get_access_token(:oauth_verifier => oauth_verifier)
|
81
|
+
|
82
|
+
stdout.puts "Response:"
|
83
|
+
access_token.params.each do |k,v|
|
84
|
+
stdout.puts " #{k}: #{v}" unless k.is_a?(Symbol)
|
85
|
+
end
|
86
|
+
rescue OAuth::Unauthorized => e
|
87
|
+
stderr.puts "A problem occurred while attempting to obtain an access token:"
|
88
|
+
stderr.puts e
|
89
|
+
stderr.puts e.request.body
|
90
|
+
end
|
91
|
+
rescue OAuth::Unauthorized => e
|
92
|
+
stderr.puts "A problem occurred while attempting to authorize:"
|
93
|
+
stderr.puts e
|
94
|
+
stderr.puts e.request.body
|
95
|
+
end
|
96
|
+
when "query"
|
97
|
+
consumer = OAuth::Consumer.new \
|
98
|
+
options[:oauth_consumer_key],
|
99
|
+
options[:oauth_consumer_secret],
|
100
|
+
:scheme => options[:scheme]
|
101
|
+
|
102
|
+
access_token = OAuth::AccessToken.new(consumer, options[:oauth_token], options[:oauth_token_secret])
|
103
|
+
|
104
|
+
# append params to the URL
|
105
|
+
uri = URI.parse(options[:uri])
|
106
|
+
params = prepare_parameters.map { |k,v| v.map { |v2| "#{URI.encode(k)}=#{URI.encode(v2)}" } * "&" }
|
107
|
+
uri.query = [uri.query, *params].reject { |x| x.nil? } * "&"
|
108
|
+
p uri.to_s
|
109
|
+
|
110
|
+
response = access_token.request(options[:method].downcase.to_sym, uri.to_s)
|
111
|
+
puts "#{response.code} #{response.message}"
|
112
|
+
puts response.body
|
113
|
+
when "sign"
|
114
|
+
parameters = prepare_parameters
|
115
|
+
|
116
|
+
request = OAuth::RequestProxy.proxy \
|
117
|
+
"method" => options[:method],
|
118
|
+
"uri" => options[:uri],
|
119
|
+
"parameters" => parameters
|
120
|
+
|
121
|
+
if verbose?
|
122
|
+
stdout.puts "OAuth parameters:"
|
123
|
+
request.oauth_parameters.each do |k,v|
|
124
|
+
stdout.puts " " + [k, v] * ": "
|
125
|
+
end
|
126
|
+
stdout.puts
|
127
|
+
|
128
|
+
if request.non_oauth_parameters.any?
|
129
|
+
stdout.puts "Parameters:"
|
130
|
+
request.non_oauth_parameters.each do |k,v|
|
131
|
+
stdout.puts " " + [k, v] * ": "
|
132
|
+
end
|
133
|
+
stdout.puts
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
request.sign! \
|
138
|
+
:consumer_secret => options[:oauth_consumer_secret],
|
139
|
+
:token_secret => options[:oauth_token_secret]
|
140
|
+
|
141
|
+
if verbose?
|
142
|
+
stdout.puts "Method: #{request.method}"
|
143
|
+
stdout.puts "URI: #{request.uri}"
|
144
|
+
stdout.puts "Normalized params: #{request.normalized_parameters}" unless options[:xmpp]
|
145
|
+
stdout.puts "Signature base string: #{request.signature_base_string}"
|
146
|
+
|
147
|
+
if options[:xmpp]
|
148
|
+
stdout.puts
|
149
|
+
stdout.puts "XMPP Stanza:"
|
150
|
+
stdout.puts <<-EOS
|
151
|
+
<oauth xmlns='urn:xmpp:oauth:0'>
|
152
|
+
<oauth_consumer_key>#{request.oauth_consumer_key}</oauth_consumer_key>
|
153
|
+
<oauth_token>#{request.oauth_token}</oauth_token>
|
154
|
+
<oauth_signature_method>#{request.oauth_signature_method}</oauth_signature_method>
|
155
|
+
<oauth_signature>#{request.oauth_signature}</oauth_signature>
|
156
|
+
<oauth_timestamp>#{request.oauth_timestamp}</oauth_timestamp>
|
157
|
+
<oauth_nonce>#{request.oauth_nonce}</oauth_nonce>
|
158
|
+
<oauth_version>#{request.oauth_version}</oauth_version>
|
159
|
+
</oauth>
|
160
|
+
EOS
|
161
|
+
stdout.puts
|
162
|
+
stdout.puts "Note: You may want to use bare JIDs in your URI."
|
163
|
+
stdout.puts
|
164
|
+
else
|
165
|
+
stdout.puts "OAuth Request URI: #{request.signed_uri}"
|
166
|
+
stdout.puts "Request URI: #{request.signed_uri(false)}"
|
167
|
+
stdout.puts "Authorization header: #{request.oauth_header(:realm => options[:realm])}"
|
168
|
+
end
|
169
|
+
stdout.puts "Signature: #{request.oauth_signature}"
|
170
|
+
stdout.puts "Escaped signature: #{OAuth::Helper.escape(request.oauth_signature)}"
|
171
|
+
else
|
172
|
+
stdout.puts request.oauth_signature
|
173
|
+
end
|
174
|
+
when "version"
|
175
|
+
puts "OAuth for Ruby #{OAuth::VERSION}"
|
176
|
+
end
|
177
|
+
else
|
178
|
+
usage
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
protected
|
183
|
+
|
184
|
+
def extract_command_and_parse_options(arguments)
|
185
|
+
@command = arguments[-1]
|
186
|
+
parse_options(arguments[0..-1])
|
187
|
+
end
|
188
|
+
|
189
|
+
def option_parser(arguments = "")
|
190
|
+
# TODO add realm parameter
|
191
|
+
# TODO add user-agent parameter
|
192
|
+
option_parser = OptionParser.new do |opts|
|
193
|
+
opts.banner = "Usage: #{$0} [options] <command>"
|
194
|
+
|
195
|
+
# defaults
|
196
|
+
options[:oauth_nonce] = OAuth::Helper.generate_key
|
197
|
+
options[:oauth_signature_method] = "HMAC-SHA1"
|
198
|
+
options[:oauth_timestamp] = OAuth::Helper.generate_timestamp
|
199
|
+
options[:oauth_version] = "1.0"
|
200
|
+
options[:method] = :post
|
201
|
+
options[:params] = []
|
202
|
+
options[:scheme] = :header
|
203
|
+
options[:version] = "1.0"
|
204
|
+
|
205
|
+
## Common Options
|
206
|
+
|
207
|
+
opts.on("-B", "--body", "Use the request body for OAuth parameters.") do
|
208
|
+
options[:scheme] = :body
|
209
|
+
end
|
210
|
+
|
211
|
+
opts.on("--consumer-key KEY", "Specifies the consumer key to use.") do |v|
|
212
|
+
options[:oauth_consumer_key] = v
|
213
|
+
end
|
214
|
+
|
215
|
+
opts.on("--consumer-secret SECRET", "Specifies the consumer secret to use.") do |v|
|
216
|
+
options[:oauth_consumer_secret] = v
|
217
|
+
end
|
218
|
+
|
219
|
+
opts.on("-H", "--header", "Use the 'Authorization' header for OAuth parameters (default).") do
|
220
|
+
options[:scheme] = :header
|
221
|
+
end
|
222
|
+
|
223
|
+
opts.on("-Q", "--query-string", "Use the query string for OAuth parameters.") do
|
224
|
+
options[:scheme] = :query_string
|
225
|
+
end
|
226
|
+
|
227
|
+
opts.on("-O", "--options FILE", "Read options from a file") do |v|
|
228
|
+
arguments.unshift(*open(v).readlines.map { |l| l.chomp.split(" ") }.flatten)
|
229
|
+
end
|
230
|
+
|
231
|
+
## Options for signing and making requests
|
232
|
+
|
233
|
+
opts.separator("\n options for signing and querying")
|
234
|
+
|
235
|
+
opts.on("--method METHOD", "Specifies the method (e.g. GET) to use when signing.") do |v|
|
236
|
+
options[:method] = v
|
237
|
+
end
|
238
|
+
|
239
|
+
opts.on("--nonce NONCE", "Specifies the none to use.") do |v|
|
240
|
+
options[:oauth_nonce] = v
|
241
|
+
end
|
242
|
+
|
243
|
+
opts.on("--parameters PARAMS", "Specifies the parameters to use when signing.") do |v|
|
244
|
+
options[:params] << v
|
245
|
+
end
|
246
|
+
|
247
|
+
opts.on("--signature-method METHOD", "Specifies the signature method to use; defaults to HMAC-SHA1.") do |v|
|
248
|
+
options[:oauth_signature_method] = v
|
249
|
+
end
|
250
|
+
|
251
|
+
opts.on("--secret SECRET", "Specifies the token secret to use.") do |v|
|
252
|
+
options[:oauth_token_secret] = v
|
253
|
+
end
|
254
|
+
|
255
|
+
opts.on("--timestamp TIMESTAMP", "Specifies the timestamp to use.") do |v|
|
256
|
+
options[:oauth_timestamp] = v
|
257
|
+
end
|
258
|
+
|
259
|
+
opts.on("--token TOKEN", "Specifies the token to use.") do |v|
|
260
|
+
options[:oauth_token] = v
|
261
|
+
end
|
262
|
+
|
263
|
+
opts.on("--realm REALM", "Specifies the realm to use.") do |v|
|
264
|
+
options[:realm] = v
|
265
|
+
end
|
266
|
+
|
267
|
+
opts.on("--uri URI", "Specifies the URI to use when signing.") do |v|
|
268
|
+
options[:uri] = v
|
269
|
+
end
|
270
|
+
|
271
|
+
opts.on(:OPTIONAL, "--version VERSION", "Specifies the OAuth version to use.") do |v|
|
272
|
+
if v
|
273
|
+
options[:oauth_version] = v
|
274
|
+
else
|
275
|
+
@command = "version"
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
opts.on("--no-version", "Omit oauth_version.") do
|
280
|
+
options[:oauth_version] = nil
|
281
|
+
end
|
282
|
+
|
283
|
+
opts.on("--xmpp", "Generate XMPP stanzas.") do
|
284
|
+
options[:xmpp] = true
|
285
|
+
options[:method] ||= "iq"
|
286
|
+
end
|
287
|
+
|
288
|
+
opts.on("-v", "--verbose", "Be verbose.") do
|
289
|
+
options[:verbose] = true
|
290
|
+
end
|
291
|
+
|
292
|
+
## Options for authorization
|
293
|
+
|
294
|
+
opts.separator("\n options for authorization")
|
295
|
+
|
296
|
+
opts.on("--access-token-url URL", "Specifies the access token URL.") do |v|
|
297
|
+
options[:access_token_url] = v
|
298
|
+
end
|
299
|
+
|
300
|
+
opts.on("--authorize-url URL", "Specifies the authorization URL.") do |v|
|
301
|
+
options[:authorize_url] = v
|
302
|
+
end
|
303
|
+
|
304
|
+
opts.on("--callback-url URL", "Specifies a callback URL.") do |v|
|
305
|
+
options[:oauth_callback] = v
|
306
|
+
end
|
307
|
+
|
308
|
+
opts.on("--request-token-url URL", "Specifies the request token URL.") do |v|
|
309
|
+
options[:request_token_url] = v
|
310
|
+
end
|
311
|
+
|
312
|
+
opts.on("--scope SCOPE", "Specifies the scope (Google-specific).") do |v|
|
313
|
+
options[:scope] = v
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
def parse_options(arguments)
|
319
|
+
option_parser(arguments).parse!(arguments)
|
320
|
+
end
|
321
|
+
|
322
|
+
def prepare_parameters
|
323
|
+
escaped_pairs = options[:params].collect do |pair|
|
324
|
+
if pair =~ /:/
|
325
|
+
Hash[*pair.split(":", 2)].collect do |k,v|
|
326
|
+
[CGI.escape(k.strip), CGI.escape(v.strip)] * "="
|
327
|
+
end
|
328
|
+
else
|
329
|
+
pair
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
querystring = escaped_pairs * "&"
|
334
|
+
cli_params = CGI.parse(querystring)
|
335
|
+
|
336
|
+
{
|
337
|
+
"oauth_consumer_key" => options[:oauth_consumer_key],
|
338
|
+
"oauth_nonce" => options[:oauth_nonce],
|
339
|
+
"oauth_timestamp" => options[:oauth_timestamp],
|
340
|
+
"oauth_token" => options[:oauth_token],
|
341
|
+
"oauth_signature_method" => options[:oauth_signature_method],
|
342
|
+
"oauth_version" => options[:oauth_version]
|
343
|
+
}.reject { |k,v| v.nil? || v == "" }.merge(cli_params)
|
344
|
+
end
|
345
|
+
|
346
|
+
def sufficient_options?
|
347
|
+
case command
|
348
|
+
# TODO move command logic elsewhere
|
349
|
+
when "authorize"
|
350
|
+
options[:oauth_consumer_key] && options[:oauth_consumer_secret] &&
|
351
|
+
options[:access_token_url] && options[:authorize_url] &&
|
352
|
+
options[:request_token_url]
|
353
|
+
when "version"
|
354
|
+
true
|
355
|
+
else
|
356
|
+
options[:oauth_consumer_key] && options[:oauth_consumer_secret] &&
|
357
|
+
options[:method] && options[:uri]
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
def usage
|
362
|
+
stdout.puts option_parser.help
|
363
|
+
stdout.puts
|
364
|
+
stdout.puts "Available commands:"
|
365
|
+
SUPPORTED_COMMANDS.each do |command, desc|
|
366
|
+
puts " #{command.ljust(15)}#{desc}"
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
def valid_command?
|
371
|
+
SUPPORTED_COMMANDS.keys.include?(command)
|
372
|
+
end
|
373
|
+
|
374
|
+
def verbose?
|
375
|
+
options[:verbose]
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|