warden_oauth_provider 1.0.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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.textile +58 -0
- data/Rakefile +2 -0
- data/lib/generators/warden_oauth_provider/install/install_generator.rb +27 -0
- data/lib/generators/warden_oauth_provider/install/templates/migration.rb +45 -0
- data/lib/warden_oauth_provider.rb +19 -0
- data/lib/warden_oauth_provider/client_application.rb +21 -0
- data/lib/warden_oauth_provider/nonce.rb +15 -0
- data/lib/warden_oauth_provider/provider_strategy.rb +82 -0
- data/lib/warden_oauth_provider/token/access.rb +11 -0
- data/lib/warden_oauth_provider/token/base.rb +32 -0
- data/lib/warden_oauth_provider/token/request.rb +29 -0
- data/lib/warden_oauth_provider/token_strategy.rb +40 -0
- data/lib/warden_oauth_provider/version.rb +3 -0
- data/spec/access_token_spec.rb +214 -0
- data/spec/all_steps_spec.rb +79 -0
- data/spec/authorize_spec.rb +43 -0
- data/spec/client_application_spec.rb +41 -0
- data/spec/helpers/factories.rb +16 -0
- data/spec/helpers/request_helper.rb +87 -0
- data/spec/nonce_spec.rb +23 -0
- data/spec/oauth_request_spec.rb +161 -0
- data/spec/request_token_spec.rb +169 -0
- data/spec/spec_helper.rb +66 -0
- data/spec/token_spec.rb +222 -0
- data/spec/token_strategy_spec.rb +158 -0
- data/warden_oauth_provider.gemspec +27 -0
- metadata +214 -0
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Request token" do
|
4
|
+
|
5
|
+
context "Success", :wip => true do
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
@client_application = Factory.create(:client_application)
|
9
|
+
|
10
|
+
auth_str = oauth_header({
|
11
|
+
:realm => "MoneyBird",
|
12
|
+
:oauth_consumer_key => @client_application.key,
|
13
|
+
:oauth_signature_method => "PLAINTEXT",
|
14
|
+
:oauth_timestamp => Time.now.to_i,
|
15
|
+
:oauth_nonce => Time.now.to_f,
|
16
|
+
:oauth_callback => "oob",
|
17
|
+
:oauth_signature => @client_application.secret + "%26"
|
18
|
+
})
|
19
|
+
|
20
|
+
env = env_with_params("/oauth/request_token", {}, {
|
21
|
+
"HTTP_AUTHORIZATION" => auth_str
|
22
|
+
})
|
23
|
+
@response = setup_rack.call(env)
|
24
|
+
@oauth_response = Hash[*@response.last.first.split("&").collect { |v| v.split("=") }.flatten]
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should have an oauth token" do
|
28
|
+
@oauth_response.keys.should include("oauth_token")
|
29
|
+
@oauth_response["oauth_token"].should_not be_nil
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should have an oauth token secret" do
|
33
|
+
@oauth_response.keys.should include("oauth_token_secret")
|
34
|
+
@oauth_response["oauth_token_secret"].should_not be_nil
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should have an oauth callback confirmed header" do
|
38
|
+
@oauth_response.keys.should include("oauth_callback_confirmed")
|
39
|
+
@oauth_response["oauth_callback_confirmed"].should == "true"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should have created a new request token in the database" do
|
43
|
+
WardenOauthProvider::Token::Request.where(:token => @oauth_response["oauth_token"], :secret => @oauth_response["oauth_token_secret"]).count.should == 1
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
context "Success with GET" do
|
49
|
+
before(:all) do
|
50
|
+
@client_application = Factory.create(:client_application)
|
51
|
+
|
52
|
+
auth_params = {
|
53
|
+
:realm => "MoneyBird",
|
54
|
+
:oauth_consumer_key => @client_application.key,
|
55
|
+
:oauth_signature_method => "PLAINTEXT",
|
56
|
+
:oauth_timestamp => Time.now.to_i,
|
57
|
+
:oauth_nonce => Time.now.to_f,
|
58
|
+
:oauth_callback => "oob",
|
59
|
+
:oauth_signature => @client_application.secret+"&"
|
60
|
+
}
|
61
|
+
|
62
|
+
env = env_with_params("/oauth/request_token", auth_params, {})
|
63
|
+
@response = setup_rack.call(env)
|
64
|
+
@oauth_response = Hash[*@response.last.first.split("&").collect { |v| v.split("=") }.flatten]
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should have an oauth token" do
|
68
|
+
@oauth_response.keys.should include("oauth_token")
|
69
|
+
@oauth_response["oauth_token"].should_not be_nil
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should have an oauth token secret" do
|
73
|
+
@oauth_response.keys.should include("oauth_token_secret")
|
74
|
+
@oauth_response["oauth_token_secret"].should_not be_nil
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should have an oauth callback confirmed header" do
|
78
|
+
@oauth_response.keys.should include("oauth_callback_confirmed")
|
79
|
+
@oauth_response["oauth_callback_confirmed"].should == "true"
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should have created a new request token in the database" do
|
83
|
+
WardenOauthProvider::Token::Request.where(:token => @oauth_response["oauth_token"], :secret => @oauth_response["oauth_token_secret"]).count.should == 1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "Failure" do
|
88
|
+
|
89
|
+
before(:all) do
|
90
|
+
@client_application = Factory.create(:client_application)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should response with a 401 if the second request contains the same nonce" do
|
94
|
+
auth_str = oauth_header({
|
95
|
+
:realm => "MoneyBird",
|
96
|
+
:oauth_consumer_key => @client_application.key,
|
97
|
+
:oauth_signature_method => "PLAINTEXT",
|
98
|
+
:oauth_timestamp => Time.now.to_i,
|
99
|
+
:oauth_nonce => Time.now.to_f,
|
100
|
+
:oauth_callback => "oob",
|
101
|
+
:oauth_signature => @client_application.secret + "%26"
|
102
|
+
})
|
103
|
+
env1 = env_with_params("/oauth/request_token", {}, {
|
104
|
+
"HTTP_AUTHORIZATION" => auth_str
|
105
|
+
})
|
106
|
+
env2 = env_with_params("/oauth/request_token", {}, {
|
107
|
+
"HTTP_AUTHORIZATION" => auth_str
|
108
|
+
})
|
109
|
+
|
110
|
+
@response1 = setup_rack.call(env1)
|
111
|
+
@response2 = setup_rack.call(env2)
|
112
|
+
@response2.first.should == 401
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should response with a 401 if consumer key is invalid" do
|
116
|
+
auth_str = oauth_header({
|
117
|
+
:realm => "MoneyBird",
|
118
|
+
:oauth_consumer_key => @client_application.key + "invalid",
|
119
|
+
:oauth_signature_method => "PLAINTEXT",
|
120
|
+
:oauth_timestamp => Time.now.to_i,
|
121
|
+
:oauth_nonce => Time.now.to_f,
|
122
|
+
:oauth_callback => "oob",
|
123
|
+
:oauth_signature => @client_application.secret + "%26"
|
124
|
+
})
|
125
|
+
|
126
|
+
env = env_with_params("/oauth/request_token", {}, {
|
127
|
+
"HTTP_AUTHORIZATION" => auth_str
|
128
|
+
})
|
129
|
+
@response = setup_rack.call(env)
|
130
|
+
@response.first.should == 401
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should response with a 401 if signature is invalid" do
|
134
|
+
auth_str = oauth_header({
|
135
|
+
:realm => "MoneyBird",
|
136
|
+
:oauth_consumer_key => @client_application.key,
|
137
|
+
:oauth_signature_method => "PLAINTEXT",
|
138
|
+
:oauth_timestamp => Time.now.to_i,
|
139
|
+
:oauth_nonce => Time.now.to_f,
|
140
|
+
:oauth_callback => "oob",
|
141
|
+
:oauth_signature => @client_application.secret + "%26" + "invalid"
|
142
|
+
})
|
143
|
+
|
144
|
+
env = env_with_params("/oauth/request_token", {}, {
|
145
|
+
"HTTP_AUTHORIZATION" => auth_str
|
146
|
+
})
|
147
|
+
@response = setup_rack.call(env)
|
148
|
+
@response.first.should == 401
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should response with a 401 if consumer key or signature are invalid" do
|
152
|
+
auth_str = oauth_header({
|
153
|
+
:realm => "MoneyBird",
|
154
|
+
:oauth_consumer_key => @client_application.key + "invalid",
|
155
|
+
:oauth_signature_method => "PLAINTEXT",
|
156
|
+
:oauth_timestamp => Time.now.to_i,
|
157
|
+
:oauth_nonce => Time.now.to_f,
|
158
|
+
:oauth_callback => "oob",
|
159
|
+
:oauth_signature => @client_application.secret + "%26" + "invalid"
|
160
|
+
})
|
161
|
+
|
162
|
+
env = env_with_params("/oauth/request_token", {}, {
|
163
|
+
"HTTP_AUTHORIZATION" => auth_str
|
164
|
+
})
|
165
|
+
@response = setup_rack.call(env)
|
166
|
+
@response.first.should == 401
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'rspec'
|
4
|
+
require 'rspec/mocks'
|
5
|
+
require 'warden_oauth_provider'
|
6
|
+
require 'rack'
|
7
|
+
require 'sqlite3'
|
8
|
+
require 'factory_girl'
|
9
|
+
require 'logger'
|
10
|
+
|
11
|
+
require 'helpers/factories'
|
12
|
+
require 'helpers/request_helper'
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
config.mock_with :rspec
|
16
|
+
|
17
|
+
config.include(RequestHelper)
|
18
|
+
end
|
19
|
+
|
20
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
21
|
+
ActiveRecord::Migration.verbose = false
|
22
|
+
ActiveRecord::Base.logger = Logger.new("test.log")
|
23
|
+
|
24
|
+
ActiveRecord::Schema.define do
|
25
|
+
create_table :client_applications, :force => true do |t|
|
26
|
+
t.string :name
|
27
|
+
t.string :url
|
28
|
+
t.string :support_url
|
29
|
+
t.string :callback_url
|
30
|
+
t.string :key, :limit => 40
|
31
|
+
t.string :secret, :limit => 40
|
32
|
+
t.integer :user_id
|
33
|
+
|
34
|
+
t.timestamps
|
35
|
+
end
|
36
|
+
add_index :client_applications, :key, :unique => true
|
37
|
+
|
38
|
+
create_table :oauth_tokens, :force => true do |t|
|
39
|
+
t.integer :user_id
|
40
|
+
t.string :type, :limit => 20
|
41
|
+
t.integer :client_application_id
|
42
|
+
t.string :token, :limit => 40
|
43
|
+
t.string :secret, :limit => 40
|
44
|
+
t.string :callback_url
|
45
|
+
t.string :verifier, :limit => 20
|
46
|
+
t.string :scope
|
47
|
+
t.timestamp :authorized_at, :invalidated_at, :valid_to
|
48
|
+
t.timestamps
|
49
|
+
end
|
50
|
+
add_index :oauth_tokens, :token, :unique => true
|
51
|
+
|
52
|
+
create_table :oauth_nonces do |t|
|
53
|
+
t.string :nonce
|
54
|
+
t.integer :timestamp
|
55
|
+
|
56
|
+
t.timestamps
|
57
|
+
end
|
58
|
+
add_index :oauth_nonces,[:nonce, :timestamp], :unique
|
59
|
+
|
60
|
+
create_table :users, :force => true do |t|
|
61
|
+
t.string :name
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class User < ActiveRecord::Base
|
66
|
+
end
|
data/spec/token_spec.rb
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe WardenOauthProvider::Token::Request do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
@client_application = Factory(:client_application)
|
7
|
+
end
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
@token = WardenOauthProvider::Token::Request.create :client_application_id => @client_application.id
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be valid" do
|
14
|
+
@token.should be_valid
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should not have errors" do
|
18
|
+
@token.errors.should_not == []
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have a token" do
|
22
|
+
@token.token.should_not be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have a secret" do
|
26
|
+
@token.secret.should_not be_nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should not be authorized" do
|
30
|
+
@token.should_not be_authorized
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should not be invalidated" do
|
34
|
+
@token.should_not be_invalidated
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should not have a verifier" do
|
38
|
+
@token.verifier.should be_nil
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should be oob" do
|
42
|
+
@token.should be_oob
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "OAuth 1.0a" do
|
46
|
+
|
47
|
+
describe "with provided callback" do
|
48
|
+
before(:each) do
|
49
|
+
@token.callback_url="http://test.com/callback"
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should not be oob" do
|
53
|
+
@token.should_not be_oob
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "authorize request" do
|
57
|
+
before(:each) do
|
58
|
+
@user = Factory(:user)
|
59
|
+
@token.authorize!(@user)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should be authorized" do
|
63
|
+
@token.should be_authorized
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should have authorized at" do
|
67
|
+
@token.authorized_at.should_not be_nil
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should have user set" do
|
71
|
+
@token.user.should == @user
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should have verifier" do
|
75
|
+
@token.verifier.should_not be_nil
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "exchange for access token" do
|
79
|
+
|
80
|
+
before(:each) do
|
81
|
+
@access = @token.exchange!(@token.verifier)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should be valid" do
|
85
|
+
@access.should be_valid
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should have no error messages" do
|
89
|
+
@access.errors.full_messages.should==[]
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should invalidate request token" do
|
93
|
+
@token.should be_invalidated
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should set user on access token" do
|
97
|
+
@access.user.should == @user
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should authorize accesstoken" do
|
101
|
+
@access.should be_authorized
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "attempt exchange with invalid verifier (OAuth 1.0a)" do
|
106
|
+
|
107
|
+
before(:each) do
|
108
|
+
@value = @token.exchange!("invalidverifier")
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should return false" do
|
112
|
+
@value.should==false
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should not invalidate request token" do
|
116
|
+
@token.should_not be_invalidated
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "attempt exchange with out authorization" do
|
123
|
+
|
124
|
+
before(:each) do
|
125
|
+
@value = @token.exchange!("invalidverifier")
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should return false" do
|
129
|
+
@value.should==false
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should not invalidate request token" do
|
133
|
+
@token.should_not be_invalidated
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
describe "with oob callback" do
|
140
|
+
before(:each) do
|
141
|
+
@token.callback_url='oob'
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should be oob" do
|
145
|
+
@token.should be_oob
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "authorize request" do
|
149
|
+
before(:each) do
|
150
|
+
@user = Factory(:user)
|
151
|
+
@token.authorize!(@user)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should be authorized" do
|
155
|
+
@token.should be_authorized
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should have authorized at" do
|
159
|
+
@token.authorized_at.should_not be_nil
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should have user set" do
|
163
|
+
@token.user.should == @user
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should have verifier" do
|
167
|
+
@token.verifier.should_not be_nil
|
168
|
+
end
|
169
|
+
|
170
|
+
describe "exchange for access token" do
|
171
|
+
|
172
|
+
before(:each) do
|
173
|
+
@access = @token.exchange!(@token.verifier)
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should invalidate request token" do
|
177
|
+
@token.should be_invalidated
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should set user on access token" do
|
181
|
+
@access.user.should == @user
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should authorize accesstoken" do
|
185
|
+
@access.should be_authorized
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe "attempt exchange with invalid verifier (OAuth 1.0a)" do
|
190
|
+
|
191
|
+
before(:each) do
|
192
|
+
@value = @token.exchange!("foobar")
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should return false" do
|
196
|
+
@value.should==false
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should not invalidate request token" do
|
200
|
+
@token.should_not be_invalidated
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
describe "attempt exchange with out authorization invalid verifier" do
|
207
|
+
|
208
|
+
before(:each) do
|
209
|
+
@value = @token.exchange!("foobar")
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should return false" do
|
213
|
+
@value.should==false
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should not invalidate request token" do
|
217
|
+
@token.should_not be_invalidated
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|