devise_oauth2_providable 1.0.5 → 1.1.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/lib/devise/oauth2_providable/expirable_token.rb +2 -2
- data/lib/devise/oauth2_providable/strategies/oauth2_authorization_code_grant_type_strategy.rb +2 -2
- data/lib/devise/oauth2_providable/strategies/oauth2_grant_type_strategy.rb +14 -5
- data/lib/devise/oauth2_providable/strategies/oauth2_password_grant_type_strategy.rb +2 -2
- data/lib/devise/oauth2_providable/strategies/oauth2_refresh_token_grant_type_strategy.rb +2 -2
- data/lib/devise/oauth2_providable/version.rb +1 -1
- data/spec/integration/oauth2_authorization_token_grant_type_strategy_spec.rb +77 -3
- data/spec/integration/oauth2_password_grant_type_strategy_spec.rb +99 -5
- data/spec/integration/oauth2_refresh_token_grant_type_strategy_spec.rb +33 -9
- metadata +4 -4
@@ -20,10 +20,9 @@ module Devise
|
|
20
20
|
validates :client, :presence => true
|
21
21
|
validates :token, :presence => true, :uniqueness => true
|
22
22
|
|
23
|
-
|
23
|
+
default_scope lambda {
|
24
24
|
where(self.arel_table[:expires_at].gteq(Time.now.utc))
|
25
25
|
}
|
26
|
-
default_scope not_expired
|
27
26
|
|
28
27
|
include LocalInstanceMethods
|
29
28
|
end
|
@@ -55,3 +54,4 @@ module Devise
|
|
55
54
|
end
|
56
55
|
|
57
56
|
ActiveRecord::Base.send :include, Devise::Oauth2Providable::ExpirableToken
|
57
|
+
|
data/lib/devise/oauth2_providable/strategies/oauth2_authorization_code_grant_type_strategy.rb
CHANGED
@@ -7,8 +7,8 @@ module Devise
|
|
7
7
|
'authorization_code'
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
if
|
10
|
+
def authenticate_grant_type(client)
|
11
|
+
if code = client.authorization_codes.find_by_token(params[:code])
|
12
12
|
success! code.user
|
13
13
|
elsif !halted?
|
14
14
|
oauth_error! :invalid_grant, 'invalid authorization code request'
|
@@ -11,12 +11,21 @@ module Devise
|
|
11
11
|
def grant_type
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
# defined by subclass
|
15
|
+
def authenticate_grant_type(client)
|
16
|
+
end
|
17
|
+
|
18
|
+
def authenticate!
|
19
|
+
client_id, client_secret = request.authorization ? decode_credentials : [params[:client_id], params[:client_secret]]
|
20
|
+
client = Devise::Oauth2Providable::Client.find_by_identifier client_id
|
21
|
+
if client && client.secret == client_secret
|
22
|
+
env[Devise::Oauth2Providable::CLIENT_ENV_REF] = client
|
23
|
+
authenticate_grant_type(client)
|
24
|
+
else
|
25
|
+
oauth_error! :invalid_client, 'invalid client credentials'
|
26
|
+
end
|
19
27
|
end
|
28
|
+
|
20
29
|
# return custom error response in accordance with the oauth spec
|
21
30
|
# see http://tools.ietf.org/html/draft-ietf-oauth-v2-16#section-4.3
|
22
31
|
def oauth_error!(error_code = :invalid_request, description = nil)
|
@@ -7,9 +7,9 @@ module Devise
|
|
7
7
|
'password'
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
10
|
+
def authenticate_grant_type(client)
|
11
11
|
resource = mapping.to.find_for_authentication(mapping.to.authentication_keys.first => params[:username])
|
12
|
-
if
|
12
|
+
if validate(resource) { resource.valid_password?(params[:password]) }
|
13
13
|
success! resource
|
14
14
|
elsif !halted?
|
15
15
|
oauth_error! :invalid_grant, 'invalid password authentication request'
|
@@ -7,8 +7,8 @@ module Devise
|
|
7
7
|
'refresh_token'
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
if
|
10
|
+
def authenticate_grant_type(client)
|
11
|
+
if refresh_token = client.refresh_tokens.find_by_token(params[:refresh_token])
|
12
12
|
env[Devise::Oauth2Providable::REFRESH_TOKEN_ENV_REF] = refresh_token
|
13
13
|
success! refresh_token.user
|
14
14
|
elsif !halted?
|
@@ -31,6 +31,33 @@ describe Devise::Strategies::Oauth2AuthorizationCodeGrantTypeStrategy do
|
|
31
31
|
response.body.should match_json(expected)
|
32
32
|
end
|
33
33
|
end
|
34
|
+
context 'with expired authorization_code' do
|
35
|
+
with :client
|
36
|
+
with :user
|
37
|
+
before do
|
38
|
+
timenow = 2.days.from_now
|
39
|
+
Time.stub!(:now).and_return(timenow)
|
40
|
+
@authorization_code = user.authorization_codes.create(:client_id => client, :redirect_uri => client.redirect_uri)
|
41
|
+
params = {
|
42
|
+
:grant_type => 'authorization_code',
|
43
|
+
:client_id => client.identifier,
|
44
|
+
:client_secret => client.secret,
|
45
|
+
:code => @authorization_code.token
|
46
|
+
}
|
47
|
+
Time.stub!(:now).and_return(timenow + 10.minutes)
|
48
|
+
|
49
|
+
post '/oauth2/token', params
|
50
|
+
end
|
51
|
+
it { response.code.to_i.should == 400 }
|
52
|
+
it { response.content_type.should == 'application/json' }
|
53
|
+
it 'returns json' do
|
54
|
+
expected = {
|
55
|
+
:error => 'invalid_grant',
|
56
|
+
:error_description => 'invalid authorization code request'
|
57
|
+
}
|
58
|
+
response.body.should match_json(expected)
|
59
|
+
end
|
60
|
+
end
|
34
61
|
context 'with invalid authorization_code' do
|
35
62
|
with :client
|
36
63
|
with :user
|
@@ -40,7 +67,7 @@ describe Devise::Strategies::Oauth2AuthorizationCodeGrantTypeStrategy do
|
|
40
67
|
:grant_type => 'authorization_code',
|
41
68
|
:client_id => client.identifier,
|
42
69
|
:client_secret => client.secret,
|
43
|
-
:
|
70
|
+
:code => 'invalid'
|
44
71
|
}
|
45
72
|
|
46
73
|
post '/oauth2/token', params
|
@@ -48,8 +75,6 @@ describe Devise::Strategies::Oauth2AuthorizationCodeGrantTypeStrategy do
|
|
48
75
|
it { response.code.to_i.should == 400 }
|
49
76
|
it { response.content_type.should == 'application/json' }
|
50
77
|
it 'returns json' do
|
51
|
-
token = Devise::Oauth2Providable::AccessToken.last
|
52
|
-
refresh_token = @refresh_token
|
53
78
|
expected = {
|
54
79
|
:error => 'invalid_grant',
|
55
80
|
:error_description => 'invalid authorization code request'
|
@@ -57,6 +82,55 @@ describe Devise::Strategies::Oauth2AuthorizationCodeGrantTypeStrategy do
|
|
57
82
|
response.body.should match_json(expected)
|
58
83
|
end
|
59
84
|
end
|
85
|
+
context 'with invalid client_secret' do
|
86
|
+
with :user
|
87
|
+
with :client
|
88
|
+
before do
|
89
|
+
@authorization_code = user.authorization_codes.create(:client_id => client, :redirect_uri => client.redirect_uri)
|
90
|
+
params = {
|
91
|
+
:grant_type => 'authorization_code',
|
92
|
+
:client_id => client.identifier,
|
93
|
+
:client_secret => 'invalid',
|
94
|
+
:code => @authorization_code.token
|
95
|
+
}
|
96
|
+
|
97
|
+
post '/oauth2/token', params
|
98
|
+
end
|
99
|
+
it { response.code.to_i.should == 400 }
|
100
|
+
it { response.content_type.should == 'application/json' }
|
101
|
+
it 'returns json' do
|
102
|
+
expected = {
|
103
|
+
:error => 'invalid_client',
|
104
|
+
:error_description => 'invalid client credentials'
|
105
|
+
}
|
106
|
+
response.body.should match_json(expected)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
context 'with invalid client_id' do
|
110
|
+
with :user
|
111
|
+
with :client
|
112
|
+
before do
|
113
|
+
@authorization_code = user.authorization_codes.create(:client_id => client, :redirect_uri => client.redirect_uri)
|
114
|
+
params = {
|
115
|
+
:grant_type => 'authorization_code',
|
116
|
+
:client_id => 'invalid',
|
117
|
+
:client_secret => client.secret,
|
118
|
+
:code => @authorization_code.token
|
119
|
+
}
|
120
|
+
|
121
|
+
post '/oauth2/token', params
|
122
|
+
end
|
123
|
+
it { response.code.to_i.should == 400 }
|
124
|
+
it { response.content_type.should == 'application/json' }
|
125
|
+
it 'returns json' do
|
126
|
+
expected = {
|
127
|
+
:error => 'invalid_client',
|
128
|
+
:error_description => 'invalid client credentials'
|
129
|
+
}
|
130
|
+
response.body.should match_json(expected)
|
131
|
+
end
|
132
|
+
end
|
60
133
|
end
|
61
134
|
end
|
62
135
|
end
|
136
|
+
|
@@ -26,7 +26,74 @@ describe Devise::Strategies::Oauth2PasswordGrantTypeStrategy do
|
|
26
26
|
response.body.should match_json(expected)
|
27
27
|
end
|
28
28
|
end
|
29
|
-
context 'with
|
29
|
+
context 'with valid params and client id/secret in basic auth header' do
|
30
|
+
with :client
|
31
|
+
before do
|
32
|
+
@user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
|
33
|
+
|
34
|
+
params = {
|
35
|
+
:grant_type => 'password',
|
36
|
+
:username => @user.email,
|
37
|
+
:password => 'test'
|
38
|
+
}
|
39
|
+
|
40
|
+
auth_header = ActionController::HttpAuthentication::Basic.encode_credentials client.identifier, client.secret
|
41
|
+
post '/oauth2/token', params, 'HTTP_AUTHORIZATION' => auth_header
|
42
|
+
end
|
43
|
+
it { response.code.to_i.should == 200 }
|
44
|
+
it { response.content_type.should == 'application/json' }
|
45
|
+
it 'returns json' do
|
46
|
+
puts response.body
|
47
|
+
token = Devise::Oauth2Providable::AccessToken.last
|
48
|
+
expected = token.token_response
|
49
|
+
response.body.should match_json(expected)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
context 'with invalid client id in basic auth header' do
|
53
|
+
with :client
|
54
|
+
before do
|
55
|
+
@user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
|
56
|
+
params = {
|
57
|
+
:grant_type => 'password',
|
58
|
+
:username => @user.email,
|
59
|
+
:password => 'test'
|
60
|
+
}
|
61
|
+
auth_header = ActionController::HttpAuthentication::Basic.encode_credentials 'invalid client id', client.secret
|
62
|
+
post '/oauth2/token', params, 'HTTP_AUTHORIZATION' => auth_header
|
63
|
+
end
|
64
|
+
it { response.code.to_i.should == 400 }
|
65
|
+
it { response.content_type.should == 'application/json' }
|
66
|
+
it 'returns json' do
|
67
|
+
expected = {
|
68
|
+
:error_description => "invalid client credentials",
|
69
|
+
:error => "invalid_client"
|
70
|
+
}
|
71
|
+
response.body.should match_json(expected)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
context 'with invalid client secret in basic auth header' do
|
75
|
+
with :client
|
76
|
+
before do
|
77
|
+
@user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
|
78
|
+
params = {
|
79
|
+
:grant_type => 'password',
|
80
|
+
:username => @user.email,
|
81
|
+
:password => 'test'
|
82
|
+
}
|
83
|
+
auth_header = ActionController::HttpAuthentication::Basic.encode_credentials client.identifier, 'invalid secret'
|
84
|
+
post '/oauth2/token', params, 'HTTP_AUTHORIZATION' => auth_header
|
85
|
+
end
|
86
|
+
it { response.code.to_i.should == 400 }
|
87
|
+
it { response.content_type.should == 'application/json' }
|
88
|
+
it 'returns json' do
|
89
|
+
expected = {
|
90
|
+
:error_description => "invalid client credentials",
|
91
|
+
:error => "invalid_client"
|
92
|
+
}
|
93
|
+
response.body.should match_json(expected)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
context 'with invalid password' do
|
30
97
|
with :client
|
31
98
|
before do
|
32
99
|
@user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
|
@@ -51,13 +118,39 @@ describe Devise::Strategies::Oauth2PasswordGrantTypeStrategy do
|
|
51
118
|
response.body.should match_json(expected)
|
52
119
|
end
|
53
120
|
end
|
54
|
-
context 'with invalid
|
121
|
+
context 'with invalid client_id' do
|
122
|
+
with :client
|
55
123
|
before do
|
56
124
|
@user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
|
57
125
|
|
58
126
|
params = {
|
59
127
|
:grant_type => 'password',
|
60
|
-
:client_id => '
|
128
|
+
:client_id => 'invalid',
|
129
|
+
:client_secret => client.secret,
|
130
|
+
:username => @user.email,
|
131
|
+
:password => 'test'
|
132
|
+
}
|
133
|
+
|
134
|
+
post '/oauth2/token', params
|
135
|
+
end
|
136
|
+
it { response.code.to_i.should == 400 }
|
137
|
+
it { response.content_type.should == 'application/json' }
|
138
|
+
it 'returns json' do
|
139
|
+
expected = {
|
140
|
+
:error_description => "invalid client credentials",
|
141
|
+
:error => "invalid_client"
|
142
|
+
}
|
143
|
+
response.body.should match_json(expected)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
context 'with invalid client_secret' do
|
147
|
+
with :client
|
148
|
+
before do
|
149
|
+
@user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
|
150
|
+
|
151
|
+
params = {
|
152
|
+
:grant_type => 'password',
|
153
|
+
:client_id => client.identifier,
|
61
154
|
:client_secret => 'invalid',
|
62
155
|
:username => @user.email,
|
63
156
|
:password => 'test'
|
@@ -69,8 +162,8 @@ describe Devise::Strategies::Oauth2PasswordGrantTypeStrategy do
|
|
69
162
|
it { response.content_type.should == 'application/json' }
|
70
163
|
it 'returns json' do
|
71
164
|
expected = {
|
72
|
-
:error_description => "invalid
|
73
|
-
:error => "
|
165
|
+
:error_description => "invalid client credentials",
|
166
|
+
:error => "invalid_client"
|
74
167
|
}
|
75
168
|
response.body.should match_json(expected)
|
76
169
|
end
|
@@ -78,3 +171,4 @@ describe Devise::Strategies::Oauth2PasswordGrantTypeStrategy do
|
|
78
171
|
end
|
79
172
|
end
|
80
173
|
end
|
174
|
+
|
@@ -31,6 +31,33 @@ describe Devise::Strategies::Oauth2RefreshTokenGrantTypeStrategy do
|
|
31
31
|
response.body.should match_json(expected)
|
32
32
|
end
|
33
33
|
end
|
34
|
+
context 'with expired refresh_token' do
|
35
|
+
with :user
|
36
|
+
with :client
|
37
|
+
before do
|
38
|
+
timenow = 2.days.from_now
|
39
|
+
Time.stub!(:now).and_return(timenow)
|
40
|
+
@refresh_token = client.refresh_tokens.create! :user => user
|
41
|
+
params = {
|
42
|
+
:grant_type => 'refresh_token',
|
43
|
+
:client_id => client.identifier,
|
44
|
+
:client_secret => client.secret,
|
45
|
+
:refresh_token => @refresh_token.token
|
46
|
+
}
|
47
|
+
Time.stub!(:now).and_return(timenow + 2.months)
|
48
|
+
|
49
|
+
post '/oauth2/token', params
|
50
|
+
end
|
51
|
+
it { response.code.to_i.should == 400 }
|
52
|
+
it { response.content_type.should == 'application/json' }
|
53
|
+
it 'returns json' do
|
54
|
+
expected = {
|
55
|
+
:error => 'invalid_grant',
|
56
|
+
:error_description => 'invalid refresh token'
|
57
|
+
}
|
58
|
+
response.body.should match_json(expected)
|
59
|
+
end
|
60
|
+
end
|
34
61
|
context 'with invalid refresh_token' do
|
35
62
|
with :user
|
36
63
|
with :client
|
@@ -74,11 +101,9 @@ describe Devise::Strategies::Oauth2RefreshTokenGrantTypeStrategy do
|
|
74
101
|
it { response.code.to_i.should == 400 }
|
75
102
|
it { response.content_type.should == 'application/json' }
|
76
103
|
it 'returns json' do
|
77
|
-
token = Devise::Oauth2Providable::AccessToken.last
|
78
|
-
refresh_token = @refresh_token
|
79
104
|
expected = {
|
80
|
-
:error => '
|
81
|
-
:error_description => 'invalid
|
105
|
+
:error => 'invalid_client',
|
106
|
+
:error_description => 'invalid client credentials'
|
82
107
|
}
|
83
108
|
response.body.should match_json(expected)
|
84
109
|
end
|
@@ -91,7 +116,7 @@ describe Devise::Strategies::Oauth2RefreshTokenGrantTypeStrategy do
|
|
91
116
|
params = {
|
92
117
|
:grant_type => 'refresh_token',
|
93
118
|
:client_id => client.identifier,
|
94
|
-
:client_secret =>
|
119
|
+
:client_secret => 'invalid',
|
95
120
|
:refresh_token => @refresh_token.token
|
96
121
|
}
|
97
122
|
|
@@ -100,11 +125,9 @@ describe Devise::Strategies::Oauth2RefreshTokenGrantTypeStrategy do
|
|
100
125
|
it { response.code.to_i.should == 400 }
|
101
126
|
it { response.content_type.should == 'application/json' }
|
102
127
|
it 'returns json' do
|
103
|
-
token = Devise::Oauth2Providable::AccessToken.last
|
104
|
-
refresh_token = @refresh_token
|
105
128
|
expected = {
|
106
|
-
:error => '
|
107
|
-
:error_description => 'invalid
|
129
|
+
:error => 'invalid_client',
|
130
|
+
:error_description => 'invalid client credentials'
|
108
131
|
}
|
109
132
|
response.body.should match_json(expected)
|
110
133
|
end
|
@@ -112,3 +135,4 @@ describe Devise::Strategies::Oauth2RefreshTokenGrantTypeStrategy do
|
|
112
135
|
end
|
113
136
|
end
|
114
137
|
end
|
138
|
+
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise_oauth2_providable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 1.0.5
|
10
|
+
version: 1.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ryan Sonnek
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
18
|
+
date: 2012-02-18 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|