panjiva-oauth-plugin 0.4.1
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.
- checksums.yaml +15 -0
- data/.gitignore +12 -0
- data/CHANGELOG +178 -0
- data/Gemfile +27 -0
- data/Guardfile +8 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +531 -0
- data/Rakefile +2 -0
- data/UPGRADE.rdoc +21 -0
- data/generators/oauth_consumer/USAGE +10 -0
- data/generators/oauth_consumer/oauth_consumer_generator.rb +50 -0
- data/generators/oauth_consumer/templates/consumer_token.rb +11 -0
- data/generators/oauth_consumer/templates/controller.rb +27 -0
- data/generators/oauth_consumer/templates/index.html.erb +29 -0
- data/generators/oauth_consumer/templates/index.html.haml +18 -0
- data/generators/oauth_consumer/templates/migration.rb +20 -0
- data/generators/oauth_consumer/templates/oauth_config.rb +73 -0
- data/generators/oauth_consumer/templates/show.html.erb +7 -0
- data/generators/oauth_consumer/templates/show.html.haml +8 -0
- data/generators/oauth_provider/USAGE +20 -0
- data/generators/oauth_provider/lib/insert_routes.rb +67 -0
- data/generators/oauth_provider/oauth_provider_generator.rb +127 -0
- data/generators/oauth_provider/templates/_form.html.erb +17 -0
- data/generators/oauth_provider/templates/_form.html.haml +21 -0
- data/generators/oauth_provider/templates/access_token.rb +16 -0
- data/generators/oauth_provider/templates/authorize.html.erb +14 -0
- data/generators/oauth_provider/templates/authorize.html.haml +16 -0
- data/generators/oauth_provider/templates/authorize_failure.html.erb +1 -0
- data/generators/oauth_provider/templates/authorize_failure.html.haml +1 -0
- data/generators/oauth_provider/templates/authorize_success.html.erb +1 -0
- data/generators/oauth_provider/templates/authorize_success.html.haml +1 -0
- data/generators/oauth_provider/templates/client_application.rb +57 -0
- data/generators/oauth_provider/templates/client_application_spec.rb +29 -0
- data/generators/oauth_provider/templates/client_application_test.rb +42 -0
- data/generators/oauth_provider/templates/client_applications.yml +23 -0
- data/generators/oauth_provider/templates/clients_controller.rb +52 -0
- data/generators/oauth_provider/templates/clients_controller_spec.rb +176 -0
- data/generators/oauth_provider/templates/clients_controller_test.rb +280 -0
- data/generators/oauth_provider/templates/controller.rb +23 -0
- data/generators/oauth_provider/templates/edit.html.erb +7 -0
- data/generators/oauth_provider/templates/edit.html.haml +4 -0
- data/generators/oauth_provider/templates/index.html.erb +43 -0
- data/generators/oauth_provider/templates/index.html.haml +39 -0
- data/generators/oauth_provider/templates/migration.rb +47 -0
- data/generators/oauth_provider/templates/new.html.erb +5 -0
- data/generators/oauth_provider/templates/new.html.haml +5 -0
- data/generators/oauth_provider/templates/oauth2_authorize.html.erb +16 -0
- data/generators/oauth_provider/templates/oauth2_authorize.html.haml +17 -0
- data/generators/oauth_provider/templates/oauth2_token.rb +20 -0
- data/generators/oauth_provider/templates/oauth2_token_spec.rb +52 -0
- data/generators/oauth_provider/templates/oauth2_verifier.rb +35 -0
- data/generators/oauth_provider/templates/oauth2_verifier_spec.rb +44 -0
- data/generators/oauth_provider/templates/oauth_nonce.rb +13 -0
- data/generators/oauth_provider/templates/oauth_nonce_spec.rb +24 -0
- data/generators/oauth_provider/templates/oauth_nonce_test.rb +26 -0
- data/generators/oauth_provider/templates/oauth_nonces.yml +13 -0
- data/generators/oauth_provider/templates/oauth_token.rb +30 -0
- data/generators/oauth_provider/templates/oauth_token_spec.rb +309 -0
- data/generators/oauth_provider/templates/oauth_token_test.rb +57 -0
- data/generators/oauth_provider/templates/oauth_tokens.yml +17 -0
- data/generators/oauth_provider/templates/request_token.rb +40 -0
- data/generators/oauth_provider/templates/show.html.erb +27 -0
- data/generators/oauth_provider/templates/show.html.haml +30 -0
- data/init.rb +1 -0
- data/install.rb +2 -0
- data/lib/generators/active_record/oauth_consumer_generator.rb +33 -0
- data/lib/generators/active_record/oauth_consumer_templates/consumer_token.rb +11 -0
- data/lib/generators/active_record/oauth_consumer_templates/migration.rb +20 -0
- data/lib/generators/active_record/oauth_provider_generator.rb +39 -0
- data/lib/generators/active_record/oauth_provider_templates/access_token.rb +16 -0
- data/lib/generators/active_record/oauth_provider_templates/client_application.rb +57 -0
- data/lib/generators/active_record/oauth_provider_templates/migration.rb +47 -0
- data/lib/generators/active_record/oauth_provider_templates/oauth2_token.rb +20 -0
- data/lib/generators/active_record/oauth_provider_templates/oauth2_verifier.rb +35 -0
- data/lib/generators/active_record/oauth_provider_templates/oauth_nonce.rb +13 -0
- data/lib/generators/active_record/oauth_provider_templates/oauth_token.rb +30 -0
- data/lib/generators/active_record/oauth_provider_templates/request_token.rb +40 -0
- data/lib/generators/erb/oauth_consumer_generator.rb +14 -0
- data/lib/generators/erb/oauth_consumer_templates/index.html.erb +29 -0
- data/lib/generators/erb/oauth_consumer_templates/show.html.erb +7 -0
- data/lib/generators/erb/oauth_provider_generator.rb +23 -0
- data/lib/generators/erb/oauth_provider_templates/_form.html.erb +17 -0
- data/lib/generators/erb/oauth_provider_templates/authorize.html.erb +14 -0
- data/lib/generators/erb/oauth_provider_templates/authorize_failure.html.erb +1 -0
- data/lib/generators/erb/oauth_provider_templates/authorize_success.html.erb +1 -0
- data/lib/generators/erb/oauth_provider_templates/edit.html.erb +7 -0
- data/lib/generators/erb/oauth_provider_templates/index.html.erb +43 -0
- data/lib/generators/erb/oauth_provider_templates/new.html.erb +5 -0
- data/lib/generators/erb/oauth_provider_templates/oauth2_authorize.html.erb +16 -0
- data/lib/generators/erb/oauth_provider_templates/show.html.erb +27 -0
- data/lib/generators/haml/oauth_consumer_generator.rb +21 -0
- data/lib/generators/haml/oauth_consumer_templates/index.html.haml +18 -0
- data/lib/generators/haml/oauth_consumer_templates/show.html.haml +8 -0
- data/lib/generators/haml/oauth_provider_generator.rb +28 -0
- data/lib/generators/haml/oauth_provider_templates/_form.html.haml +21 -0
- data/lib/generators/haml/oauth_provider_templates/authorize.html.haml +16 -0
- data/lib/generators/haml/oauth_provider_templates/authorize_failure.html.haml +1 -0
- data/lib/generators/haml/oauth_provider_templates/authorize_success.html.haml +1 -0
- data/lib/generators/haml/oauth_provider_templates/edit.html.haml +4 -0
- data/lib/generators/haml/oauth_provider_templates/index.html.haml +39 -0
- data/lib/generators/haml/oauth_provider_templates/new.html.haml +5 -0
- data/lib/generators/haml/oauth_provider_templates/oauth2_authorize.html.haml +17 -0
- data/lib/generators/haml/oauth_provider_templates/show.html.haml +30 -0
- data/lib/generators/mongoid/oauth_consumer_generator.rb +15 -0
- data/lib/generators/mongoid/oauth_consumer_templates/consumer_token.rb +41 -0
- data/lib/generators/mongoid/oauth_provider_generator.rb +21 -0
- data/lib/generators/mongoid/oauth_provider_templates/access_token.rb +16 -0
- data/lib/generators/mongoid/oauth_provider_templates/client_application.rb +71 -0
- data/lib/generators/mongoid/oauth_provider_templates/oauth2_token.rb +20 -0
- data/lib/generators/mongoid/oauth_provider_templates/oauth2_verifier.rb +35 -0
- data/lib/generators/mongoid/oauth_provider_templates/oauth_nonce.rb +24 -0
- data/lib/generators/mongoid/oauth_provider_templates/oauth_token.rb +44 -0
- data/lib/generators/mongoid/oauth_provider_templates/request_token.rb +36 -0
- data/lib/generators/oauth_consumer/USAGE +11 -0
- data/lib/generators/oauth_consumer/oauth_consumer_generator.rb +31 -0
- data/lib/generators/oauth_consumer/templates/controller.rb +59 -0
- data/lib/generators/oauth_consumer/templates/oauth_config.rb +68 -0
- data/lib/generators/oauth_inflections.rb +6 -0
- data/lib/generators/oauth_plugin.rb +0 -0
- data/lib/generators/oauth_provider/USAGE +18 -0
- data/lib/generators/oauth_provider/oauth_provider_generator.rb +37 -0
- data/lib/generators/oauth_provider/templates/clients_controller.rb +52 -0
- data/lib/generators/oauth_provider/templates/controller.rb +23 -0
- data/lib/generators/rspec/oauth_provider_generator.rb +35 -0
- data/lib/generators/rspec/templates/client_application_spec.rb +29 -0
- data/lib/generators/rspec/templates/client_applications.yml +23 -0
- data/lib/generators/rspec/templates/clients_controller_spec.rb +176 -0
- data/lib/generators/rspec/templates/oauth2_token_spec.rb +52 -0
- data/lib/generators/rspec/templates/oauth2_verifier_spec.rb +44 -0
- data/lib/generators/rspec/templates/oauth_nonce_spec.rb +24 -0
- data/lib/generators/rspec/templates/oauth_nonces.yml +13 -0
- data/lib/generators/rspec/templates/oauth_token_spec.rb +309 -0
- data/lib/generators/rspec/templates/oauth_tokens.yml +17 -0
- data/lib/generators/test_unit/oauth_provider_generator.rb +33 -0
- data/lib/generators/test_unit/templates/client_application_test.rb +42 -0
- data/lib/generators/test_unit/templates/client_applications.yml +23 -0
- data/lib/generators/test_unit/templates/clients_controller_test.rb +280 -0
- data/lib/generators/test_unit/templates/oauth_nonce_test.rb +26 -0
- data/lib/generators/test_unit/templates/oauth_nonces.yml +13 -0
- data/lib/generators/test_unit/templates/oauth_token_test.rb +57 -0
- data/lib/generators/test_unit/templates/oauth_tokens.yml +17 -0
- data/lib/oauth-plugin.rb +24 -0
- data/lib/oauth-plugin/version.rb +5 -0
- data/lib/oauth/controllers/application_controller_methods.rb +136 -0
- data/lib/oauth/controllers/consumer_controller.rb +150 -0
- data/lib/oauth/controllers/provider_controller.rb +181 -0
- data/lib/oauth/models/consumers/service_loader.rb +28 -0
- data/lib/oauth/models/consumers/services/agree2_token.rb +15 -0
- data/lib/oauth/models/consumers/services/fireeagle_token.rb +39 -0
- data/lib/oauth/models/consumers/services/google_token.rb +21 -0
- data/lib/oauth/models/consumers/services/oauth2_token.rb +27 -0
- data/lib/oauth/models/consumers/services/opentransact_token.rb +15 -0
- data/lib/oauth/models/consumers/services/picomoney_token.rb +17 -0
- data/lib/oauth/models/consumers/services/twitter_token.rb +24 -0
- data/lib/oauth/models/consumers/simple_client.rb +50 -0
- data/lib/oauth/models/consumers/token.rb +93 -0
- data/lib/oauth/provider/authorizer.rb +83 -0
- data/lib/oauth/rack/oauth_filter.rb +93 -0
- data/oauth-plugin.gemspec +39 -0
- data/rails/init.rb +1 -0
- data/spec/dummy_provider_models.rb +53 -0
- data/spec/oauth/provider/authorizer_spec.rb +202 -0
- data/spec/rack/oauth_filter_spec.rb +244 -0
- data/spec/spec_helper.rb +3 -0
- data/tasks/oauth_tasks.rake +4 -0
- data/uninstall.rb +1 -0
- metadata +362 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
+
require "oauth-plugin/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = %q{panjiva-oauth-plugin}
|
|
7
|
+
s.version = Oauth::Plugin::VERSION
|
|
8
|
+
|
|
9
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
|
10
|
+
s.authors = ["Pelle Braendgaard"]
|
|
11
|
+
s.date = %q{2011-10-20}
|
|
12
|
+
s.description = %q{Rails plugin for implementing an OAuth Provider or Consumer}
|
|
13
|
+
s.email = %q{oauth-ruby@googlegroups.com}
|
|
14
|
+
s.extra_rdoc_files = [
|
|
15
|
+
"README.rdoc"
|
|
16
|
+
]
|
|
17
|
+
s.files = `git ls-files`.split("\n")
|
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
20
|
+
|
|
21
|
+
s.homepage = %q{http://github.com/pelle/oauth-plugin}
|
|
22
|
+
s.require_paths = ["lib"]
|
|
23
|
+
s.rubyforge_project = %q{oauth}
|
|
24
|
+
s.rubygems_version = %q{1.3.7}
|
|
25
|
+
s.summary = %q{Ruby on Rails Plugin for OAuth Provider and Consumer}
|
|
26
|
+
s.add_development_dependency "opentransact"
|
|
27
|
+
s.add_development_dependency "rspec", "~> 2.4.0"
|
|
28
|
+
s.add_development_dependency "fakeweb"
|
|
29
|
+
s.add_development_dependency "fuubar"
|
|
30
|
+
s.add_development_dependency "guard-rspec"
|
|
31
|
+
s.add_development_dependency "growl"
|
|
32
|
+
s.add_development_dependency "rack-test"
|
|
33
|
+
|
|
34
|
+
s.add_dependency "multi_json"
|
|
35
|
+
s.add_dependency("oauth", ["~> 0.4.4"])
|
|
36
|
+
s.add_dependency("rack")
|
|
37
|
+
s.add_dependency("panjiva-oauth2", '>= 0.5.0')
|
|
38
|
+
end
|
|
39
|
+
|
data/rails/init.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'oauth-plugin'
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Dummy implementation
|
|
2
|
+
class ClientApplication
|
|
3
|
+
attr_accessor :key
|
|
4
|
+
|
|
5
|
+
def self.find_by_key(key)
|
|
6
|
+
ClientApplication.new(key)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def initialize(key)
|
|
10
|
+
@key = key
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def tokens
|
|
14
|
+
@tokens||=[]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def secret
|
|
18
|
+
"secret"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class OauthToken
|
|
23
|
+
attr_accessor :token
|
|
24
|
+
|
|
25
|
+
def self.first(conditions_hash)
|
|
26
|
+
case conditions_hash[:conditions].last
|
|
27
|
+
when "not_authorized", "invalidated"
|
|
28
|
+
nil
|
|
29
|
+
else
|
|
30
|
+
OauthToken.new(conditions_hash[:conditions].last)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def initialize(token)
|
|
35
|
+
@token = token
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def secret
|
|
39
|
+
"secret"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class Oauth2Token < OauthToken ; end
|
|
44
|
+
class Oauth2Verifier < OauthToken ; end
|
|
45
|
+
class AccessToken < OauthToken ; end
|
|
46
|
+
class RequestToken < OauthToken ; end
|
|
47
|
+
|
|
48
|
+
class OauthNonce
|
|
49
|
+
# Always remember
|
|
50
|
+
def self.remember(nonce,timestamp)
|
|
51
|
+
true
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'multi_json'
|
|
3
|
+
require 'oauth/provider/authorizer'
|
|
4
|
+
require 'dummy_provider_models'
|
|
5
|
+
|
|
6
|
+
describe OAuth::Provider::Authorizer do
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
describe "Authorization code" do
|
|
10
|
+
|
|
11
|
+
describe "should issue code" do
|
|
12
|
+
|
|
13
|
+
before(:each) do
|
|
14
|
+
@user = double("user")
|
|
15
|
+
@app = double("app")
|
|
16
|
+
@code = double("code", :token => "secret auth code")
|
|
17
|
+
|
|
18
|
+
::ClientApplication.should_receive(:find_by_key!).with('client id').and_return(@app)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should allow" do
|
|
22
|
+
::Oauth2Verifier.should_receive(:create!).with( :client_application=>@app,
|
|
23
|
+
:user=>@user,
|
|
24
|
+
:callback_url=>'http://mysite.com/callback',
|
|
25
|
+
:scope => 'a b').and_return(@code)
|
|
26
|
+
|
|
27
|
+
@authorizer = OAuth::Provider::Authorizer.new @user, true, :response_type => 'code',
|
|
28
|
+
:scope => "a b",
|
|
29
|
+
:client_id => 'client id',
|
|
30
|
+
:redirect_uri => 'http://mysite.com/callback'
|
|
31
|
+
|
|
32
|
+
@authorizer.redirect_uri.should == "http://mysite.com/callback?code=secret%20auth%20code"
|
|
33
|
+
@authorizer.should be_authorized
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "should include state" do
|
|
38
|
+
::Oauth2Verifier.should_receive(:create!).with( :client_application=>@app,
|
|
39
|
+
:user=>@user,
|
|
40
|
+
:callback_url=>'http://mysite.com/callback',
|
|
41
|
+
:scope => 'a b').and_return(@code)
|
|
42
|
+
|
|
43
|
+
@authorizer = OAuth::Provider::Authorizer.new @user, true, :response_type => 'code',
|
|
44
|
+
:state => 'customer id',
|
|
45
|
+
:scope => "a b",
|
|
46
|
+
:client_id => 'client id',
|
|
47
|
+
:redirect_uri => 'http://mysite.com/callback'
|
|
48
|
+
|
|
49
|
+
@authorizer.redirect_uri.should == "http://mysite.com/callback?code=secret%20auth%20code&state=customer%20id"
|
|
50
|
+
@authorizer.should be_authorized
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "should allow query string in callback" do
|
|
55
|
+
::Oauth2Verifier.should_receive(:create!).with( :client_application=>@app,
|
|
56
|
+
:user=>@user,
|
|
57
|
+
:callback_url=>'http://mysite.com/callback?this=one',
|
|
58
|
+
:scope => 'a b').and_return(@code)
|
|
59
|
+
|
|
60
|
+
@authorizer = OAuth::Provider::Authorizer.new @user, true, :response_type => 'code',
|
|
61
|
+
:scope => "a b",
|
|
62
|
+
:client_id => 'client id',
|
|
63
|
+
:redirect_uri => 'http://mysite.com/callback?this=one'
|
|
64
|
+
@authorizer.should be_authorized
|
|
65
|
+
@authorizer.redirect_uri.should == "http://mysite.com/callback?this=one&code=secret%20auth%20code"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
describe "user does not authorize" do
|
|
73
|
+
|
|
74
|
+
it "should send error" do
|
|
75
|
+
@authorizer = OAuth::Provider::Authorizer.new @user, false, :response_type => 'code',
|
|
76
|
+
:scope => "a b",
|
|
77
|
+
:client_id => 'client id',
|
|
78
|
+
:redirect_uri => 'http://mysite.com/callback'
|
|
79
|
+
|
|
80
|
+
@authorizer.redirect_uri.should == "http://mysite.com/callback?error=access_denied"
|
|
81
|
+
@authorizer.should_not be_authorized
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "should send error with state and query params in callback" do
|
|
86
|
+
@authorizer = OAuth::Provider::Authorizer.new @user, false, :response_type => 'code',
|
|
87
|
+
:scope => "a b",
|
|
88
|
+
:client_id => 'client id',
|
|
89
|
+
:redirect_uri=>'http://mysite.com/callback?this=one',
|
|
90
|
+
:state => "my customer"
|
|
91
|
+
|
|
92
|
+
@authorizer.redirect_uri.should == "http://mysite.com/callback?this=one&error=access_denied&state=my%20customer"
|
|
93
|
+
@authorizer.should_not be_authorized
|
|
94
|
+
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
describe "Implict Grant" do
|
|
100
|
+
|
|
101
|
+
describe "should issue token" do
|
|
102
|
+
|
|
103
|
+
before(:each) do
|
|
104
|
+
@user = double("user")
|
|
105
|
+
@app = double("app")
|
|
106
|
+
@token = double("token", :token => "secret auth code")
|
|
107
|
+
|
|
108
|
+
::ClientApplication.should_receive(:find_by_key!).with('client id').and_return(@app)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "should allow" do
|
|
112
|
+
::Oauth2Token.should_receive(:create!).with( :client_application=>@app,
|
|
113
|
+
:user=>@user,
|
|
114
|
+
:callback_url=>'http://mysite.com/callback',
|
|
115
|
+
:scope => 'a b').and_return(@token)
|
|
116
|
+
|
|
117
|
+
@authorizer = OAuth::Provider::Authorizer.new @user, true, :response_type => 'token',
|
|
118
|
+
:scope => "a b",
|
|
119
|
+
:client_id => 'client id',
|
|
120
|
+
:redirect_uri => 'http://mysite.com/callback'
|
|
121
|
+
|
|
122
|
+
@authorizer.redirect_uri.should == "http://mysite.com/callback#access_token=secret%20auth%20code"
|
|
123
|
+
@authorizer.should be_authorized
|
|
124
|
+
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "should include state" do
|
|
128
|
+
::Oauth2Token.should_receive(:create!).with( :client_application=>@app,
|
|
129
|
+
:user=>@user,
|
|
130
|
+
:callback_url=>'http://mysite.com/callback',
|
|
131
|
+
:scope => 'a b').and_return(@token)
|
|
132
|
+
|
|
133
|
+
@authorizer = OAuth::Provider::Authorizer.new @user, true, :response_type => 'token',
|
|
134
|
+
:state => 'customer id',
|
|
135
|
+
:scope => "a b",
|
|
136
|
+
:client_id => 'client id',
|
|
137
|
+
:redirect_uri => 'http://mysite.com/callback'
|
|
138
|
+
|
|
139
|
+
@authorizer.redirect_uri.should == "http://mysite.com/callback#access_token=secret%20auth%20code&state=customer%20id"
|
|
140
|
+
@authorizer.should be_authorized
|
|
141
|
+
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "should allow query string in callback" do
|
|
145
|
+
::Oauth2Token.should_receive(:create!).with( :client_application=>@app,
|
|
146
|
+
:user=>@user,
|
|
147
|
+
:callback_url=>'http://mysite.com/callback?this=one',
|
|
148
|
+
:scope => 'a b').and_return(@token)
|
|
149
|
+
|
|
150
|
+
@authorizer = OAuth::Provider::Authorizer.new @user, true, :response_type => 'token',
|
|
151
|
+
:scope => "a b",
|
|
152
|
+
:client_id => 'client id',
|
|
153
|
+
:redirect_uri => 'http://mysite.com/callback?this=one'
|
|
154
|
+
@authorizer.should be_authorized
|
|
155
|
+
@authorizer.redirect_uri.should == "http://mysite.com/callback?this=one#access_token=secret%20auth%20code"
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
describe "user does not authorize" do
|
|
163
|
+
|
|
164
|
+
it "should send error" do
|
|
165
|
+
@authorizer = OAuth::Provider::Authorizer.new @user, false, :response_type => 'token',
|
|
166
|
+
:scope => "a b",
|
|
167
|
+
:client_id => 'client id',
|
|
168
|
+
:redirect_uri => 'http://mysite.com/callback'
|
|
169
|
+
|
|
170
|
+
@authorizer.redirect_uri.should == "http://mysite.com/callback#error=access_denied"
|
|
171
|
+
@authorizer.should_not be_authorized
|
|
172
|
+
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it "should send error with state and query params in callback" do
|
|
176
|
+
@authorizer = OAuth::Provider::Authorizer.new @user, false, :response_type => 'token',
|
|
177
|
+
:scope => "a b",
|
|
178
|
+
:client_id => 'client id',
|
|
179
|
+
:redirect_uri=>'http://mysite.com/callback?this=one',
|
|
180
|
+
:state => "my customer"
|
|
181
|
+
|
|
182
|
+
@authorizer.redirect_uri.should == "http://mysite.com/callback?this=one#error=access_denied&state=my%20customer"
|
|
183
|
+
@authorizer.should_not be_authorized
|
|
184
|
+
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
it "should handle unsupported response type" do
|
|
190
|
+
@user = double("user")
|
|
191
|
+
|
|
192
|
+
@authorizer = OAuth::Provider::Authorizer.new @user, false, :response_type => 'my new',
|
|
193
|
+
:scope => "a b",
|
|
194
|
+
:client_id => 'client id',
|
|
195
|
+
:redirect_uri => 'http://mysite.com/callback'
|
|
196
|
+
|
|
197
|
+
@authorizer.redirect_uri.should == "http://mysite.com/callback#error=unsupported_response_type"
|
|
198
|
+
@authorizer.should_not be_authorized
|
|
199
|
+
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
end
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rack/test'
|
|
3
|
+
require 'oauth/rack/oauth_filter'
|
|
4
|
+
require 'multi_json'
|
|
5
|
+
require 'forwardable'
|
|
6
|
+
require 'dummy_provider_models'
|
|
7
|
+
|
|
8
|
+
class OAuthEcho
|
|
9
|
+
def call(env)
|
|
10
|
+
response = {}
|
|
11
|
+
response[:oauth_token] = env["oauth.token"].token if env["oauth.token"]
|
|
12
|
+
response[:client_application] = env["oauth.client_application"].key if env["oauth.client_application"]
|
|
13
|
+
response[:oauth_version] = env["oauth.version"] if env["oauth.version"]
|
|
14
|
+
response[:strategies] = env["oauth.strategies"] if env["oauth.strategies"]
|
|
15
|
+
[200, { "Accept" => "application/json" }, [MultiJson.encode(response)]]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe OAuth::Rack::OAuthFilter do
|
|
20
|
+
include Rack::Test::Methods
|
|
21
|
+
|
|
22
|
+
def app
|
|
23
|
+
@app ||= OAuth::Rack::OAuthFilter.new(OAuthEcho.new)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should pass through without oauth" do
|
|
27
|
+
get '/'
|
|
28
|
+
last_response.should be_ok
|
|
29
|
+
response = MultiJson.decode(last_response.body)
|
|
30
|
+
response.should == {}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe 'OAuth1' do
|
|
34
|
+
describe 'with optional white space' do
|
|
35
|
+
it "should sign with consumer" do
|
|
36
|
+
get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer", oauth_nonce="amrLDyFE2AMztx5fOYDD1OEqWps6Mc2mAR5qyO44Rj8", oauth_signature="KCSg0RUfVFUcyhrgJo580H8ey0c%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1295039581", oauth_version="1.0"'}
|
|
37
|
+
last_response.should be_ok
|
|
38
|
+
response = MultiJson.decode(last_response.body)
|
|
39
|
+
response.should == {"client_application" => "my_consumer", "oauth_version"=>1, "strategies"=>["two_legged"]}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should sign with oauth 1 access token" do
|
|
43
|
+
client_application = ClientApplication.new "my_consumer"
|
|
44
|
+
ClientApplication.stub!(:find_by_key).and_return(client_application)
|
|
45
|
+
client_application.tokens.stub!(:first).and_return(AccessToken.new("my_token"))
|
|
46
|
+
get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer", oauth_nonce="oiFHXoN0172eigBBUfgaZLdQg7ycGekv8iTdfkCStY", oauth_signature="y35B2DqTWaNlzNX0p4wv%2FJAGzg8%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1295040394", oauth_token="my_token", oauth_version="1.0"'}
|
|
47
|
+
last_response.should be_ok
|
|
48
|
+
response = MultiJson.decode(last_response.body)
|
|
49
|
+
response.should == {"client_application" => "my_consumer", "oauth_token"=>"my_token","oauth_version"=>1, "strategies"=>["oauth10_token","token","oauth10_access_token"]}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should sign with oauth 1 request token" do
|
|
53
|
+
client_application = ClientApplication.new "my_consumer"
|
|
54
|
+
ClientApplication.stub!(:find_by_key).and_return(client_application)
|
|
55
|
+
client_application.tokens.stub!(:first).and_return(RequestToken.new("my_token"))
|
|
56
|
+
get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer", oauth_nonce="oiFHXoN0172eigBBUfgaZLdQg7ycGekv8iTdfkCStY", oauth_signature="y35B2DqTWaNlzNX0p4wv%2FJAGzg8%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1295040394", oauth_token="my_token", oauth_version="1.0"'}
|
|
57
|
+
last_response.should be_ok
|
|
58
|
+
response = MultiJson.decode(last_response.body)
|
|
59
|
+
response.should == {"client_application" => "my_consumer", "oauth_token"=>"my_token","oauth_version"=>1, "strategies"=>["oauth10_token","oauth10_request_token"]}
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
describe 'without optional white space' do
|
|
64
|
+
it "should sign with consumer" do
|
|
65
|
+
get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer",oauth_nonce="amrLDyFE2AMztx5fOYDD1OEqWps6Mc2mAR5qyO44Rj8",oauth_signature="KCSg0RUfVFUcyhrgJo580H8ey0c%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1295039581",oauth_version="1.0"'}
|
|
66
|
+
last_response.should be_ok
|
|
67
|
+
response = MultiJson.decode(last_response.body)
|
|
68
|
+
response.should == {"client_application" => "my_consumer", "oauth_version"=>1, "strategies"=>["two_legged"]}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should sign with oauth 1 access token" do
|
|
72
|
+
client_application = ClientApplication.new "my_consumer"
|
|
73
|
+
ClientApplication.stub!(:find_by_key).and_return(client_application)
|
|
74
|
+
client_application.tokens.stub!(:first).and_return(AccessToken.new("my_token"))
|
|
75
|
+
get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer",oauth_nonce="oiFHXoN0172eigBBUfgaZLdQg7ycGekv8iTdfkCStY",oauth_signature="y35B2DqTWaNlzNX0p4wv%2FJAGzg8%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1295040394",oauth_token="my_token",oauth_version="1.0"'}
|
|
76
|
+
last_response.should be_ok
|
|
77
|
+
response = MultiJson.decode(last_response.body)
|
|
78
|
+
response.should == {"client_application" => "my_consumer", "oauth_token"=>"my_token","oauth_version"=>1, "strategies"=>["oauth10_token","token","oauth10_access_token"]}
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "should sign with oauth 1 request token" do
|
|
82
|
+
client_application = ClientApplication.new "my_consumer"
|
|
83
|
+
ClientApplication.stub!(:find_by_key).and_return(client_application)
|
|
84
|
+
client_application.tokens.stub!(:first).and_return(RequestToken.new("my_token"))
|
|
85
|
+
get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer",oauth_nonce="oiFHXoN0172eigBBUfgaZLdQg7ycGekv8iTdfkCStY",oauth_signature="y35B2DqTWaNlzNX0p4wv%2FJAGzg8%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1295040394",oauth_token="my_token",oauth_version="1.0"'}
|
|
86
|
+
last_response.should be_ok
|
|
87
|
+
response = MultiJson.decode(last_response.body)
|
|
88
|
+
response.should == {"client_application" => "my_consumer", "oauth_token"=>"my_token","oauth_version"=>1, "strategies"=>["oauth10_token","oauth10_request_token"]}
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe "OAuth2" do
|
|
94
|
+
describe "token given through a HTTP Auth Header" do
|
|
95
|
+
context "authorized and non-invalidated token" do
|
|
96
|
+
it "authenticates" do
|
|
97
|
+
get '/', {}, { "HTTP_AUTHORIZATION" => "Bearer valid_token" }
|
|
98
|
+
last_response.should be_ok
|
|
99
|
+
response = MultiJson.decode(last_response.body)
|
|
100
|
+
response.should == { "oauth_token" => "valid_token", "oauth_version" => 2, "strategies"=> ["oauth20_token", "token"] }
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
context "non-authorized token" do
|
|
105
|
+
it "doesn't authenticate" do
|
|
106
|
+
get '/', {}, { "HTTP_AUTHORIZATION" => "Bearer not_authorized" }
|
|
107
|
+
last_response.should be_ok
|
|
108
|
+
response = MultiJson.decode(last_response.body)
|
|
109
|
+
response.should == {}
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context "authorized and invalidated token" do
|
|
114
|
+
it "doesn't authenticate with an invalidated token" do
|
|
115
|
+
get '/', {}, { "HTTP_AUTHORIZATION" => "Bearer invalidated" }
|
|
116
|
+
last_response.should be_ok
|
|
117
|
+
response = MultiJson.decode(last_response.body)
|
|
118
|
+
response.should == {}
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
describe "OAuth2 pre Bearer" do
|
|
124
|
+
describe "token given through a HTTP Auth Header" do
|
|
125
|
+
context "authorized and non-invalidated token" do
|
|
126
|
+
it "authenticates" do
|
|
127
|
+
get '/', {}, { "HTTP_AUTHORIZATION" => "OAuth valid_token" }
|
|
128
|
+
last_response.should be_ok
|
|
129
|
+
response = MultiJson.decode(last_response.body)
|
|
130
|
+
response.should == { "oauth_token" => "valid_token", "oauth_version" => 2, "strategies"=> ["oauth20_token", "token"] }
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
context "non-authorized token" do
|
|
135
|
+
it "doesn't authenticate" do
|
|
136
|
+
get '/', {}, { "HTTP_AUTHORIZATION" => "OAuth not_authorized" }
|
|
137
|
+
last_response.should be_ok
|
|
138
|
+
response = MultiJson.decode(last_response.body)
|
|
139
|
+
response.should == {}
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
context "authorized and invalidated token" do
|
|
144
|
+
it "doesn't authenticate with an invalidated token" do
|
|
145
|
+
get '/', {}, { "HTTP_AUTHORIZATION" => "OAuth invalidated" }
|
|
146
|
+
last_response.should be_ok
|
|
147
|
+
response = MultiJson.decode(last_response.body)
|
|
148
|
+
response.should == {}
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
describe "token given through a HTTP Auth Header following the OAuth2 pre draft" do
|
|
155
|
+
context "authorized and non-invalidated token" do
|
|
156
|
+
it "authenticates" do
|
|
157
|
+
get '/', {}, { "HTTP_AUTHORIZATION" => "Token valid_token" }
|
|
158
|
+
last_response.should be_ok
|
|
159
|
+
response = MultiJson.decode(last_response.body)
|
|
160
|
+
response.should == { "oauth_token" => "valid_token", "oauth_version" => 2, "strategies"=> ["oauth20_token", "token"] }
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
context "non-authorized token" do
|
|
165
|
+
it "doesn't authenticate" do
|
|
166
|
+
get '/', {}, { "HTTP_AUTHORIZATION" => "Token not_authorized" }
|
|
167
|
+
last_response.should be_ok
|
|
168
|
+
response = MultiJson.decode(last_response.body)
|
|
169
|
+
response.should == {}
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
context "authorized and invalidated token" do
|
|
174
|
+
it "doesn't authenticate with an invalidated token" do
|
|
175
|
+
get '/', {}, { "HTTP_AUTHORIZATION" => "Token invalidated" }
|
|
176
|
+
last_response.should be_ok
|
|
177
|
+
response = MultiJson.decode(last_response.body)
|
|
178
|
+
response.should == {}
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
['bearer_token', 'access_token', 'oauth_token'].each do |name|
|
|
184
|
+
describe "token given through the query parameter '#{name}'" do
|
|
185
|
+
context "authorized and non-invalidated token" do
|
|
186
|
+
it "authenticates" do
|
|
187
|
+
get "/?#{name}=valid_token"
|
|
188
|
+
|
|
189
|
+
last_response.should be_ok
|
|
190
|
+
response = MultiJson.decode(last_response.body)
|
|
191
|
+
response.should == { "oauth_token" => "valid_token", "oauth_version" => 2, "strategies"=> ["oauth20_token", "token"] }
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
context "non-authorized token" do
|
|
196
|
+
it "doesn't authenticate" do
|
|
197
|
+
get "/?#{name}=not_authorized"
|
|
198
|
+
last_response.should be_ok
|
|
199
|
+
response = MultiJson.decode(last_response.body)
|
|
200
|
+
response.should == {}
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
context "authorized and invalidated token" do
|
|
205
|
+
it "doesn't authenticate with an invalidated token" do
|
|
206
|
+
get "/?#{name}=invalidated"
|
|
207
|
+
last_response.should be_ok
|
|
208
|
+
response = MultiJson.decode(last_response.body)
|
|
209
|
+
response.should == {}
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
describe "token given through the post parameter '#{name}'" do
|
|
215
|
+
context "authorized and non-invalidated token" do
|
|
216
|
+
it "authenticates" do
|
|
217
|
+
post '/', name => 'valid_token'
|
|
218
|
+
last_response.should be_ok
|
|
219
|
+
response = MultiJson.decode(last_response.body)
|
|
220
|
+
response.should == { "oauth_token" => "valid_token", "oauth_version" => 2, "strategies"=> ["oauth20_token", "token"] }
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
context "non-authorized token" do
|
|
225
|
+
it "doesn't authenticate" do
|
|
226
|
+
post '/', name => 'not_authorized'
|
|
227
|
+
last_response.should be_ok
|
|
228
|
+
response = MultiJson.decode(last_response.body)
|
|
229
|
+
response.should == {}
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
context "authorized and invalidated token" do
|
|
234
|
+
it "doesn't authenticate with an invalidated token" do
|
|
235
|
+
post '/', name => 'invalidated'
|
|
236
|
+
last_response.should be_ok
|
|
237
|
+
response = MultiJson.decode(last_response.body)
|
|
238
|
+
response.should == {}
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|