doorkeeper 0.7.4 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of doorkeeper might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/Gemfile +0 -2
- data/README.md +1 -1
- data/app/controllers/doorkeeper/tokens_controller.rb +2 -0
- data/app/views/doorkeeper/applications/_delete_form.html.erb +16 -0
- data/app/views/doorkeeper/applications/index.html.erb +6 -2
- data/app/views/doorkeeper/applications/show.html.erb +1 -1
- data/app/views/doorkeeper/authorized_applications/index.html.erb +1 -1
- data/app/views/layouts/doorkeeper/application.html.erb +0 -1
- data/doorkeeper.gemspec +0 -1
- data/lib/doorkeeper/doorkeeper_for.rb +2 -2
- data/lib/doorkeeper/models/access_token.rb +5 -2
- data/lib/doorkeeper/models/application.rb +2 -2
- data/lib/doorkeeper/oauth/password_access_token_request.rb +13 -8
- data/lib/doorkeeper/oauth/refresh_token_request.rb +38 -12
- data/lib/doorkeeper/oauth/token_response.rb +1 -1
- data/lib/doorkeeper/request/password.rb +5 -5
- data/lib/doorkeeper/request/refresh_token.rb +5 -5
- data/lib/doorkeeper/version.rb +1 -1
- data/lib/generators/doorkeeper/templates/migration.rb +1 -1
- data/spec/controllers/applications_controller_spec.rb +9 -0
- data/spec/controllers/protected_resources_controller_spec.rb +2 -2
- data/spec/controllers/tokens_controller_spec.rb +1 -1
- data/spec/dummy/app/views/layouts/application.html.erb +0 -2
- data/spec/dummy/config/environments/test.rb +11 -2
- data/spec/dummy/db/migrate/20130902165751_create_doorkeeper_tables.rb +1 -1
- data/spec/dummy/db/schema.rb +1 -1
- data/spec/factories/access_token.rb +4 -0
- data/spec/lib/models/revocable_spec.rb +2 -2
- data/spec/lib/oauth/authorization_code_request_spec.rb +1 -1
- data/spec/lib/oauth/client/credentials_spec.rb +2 -2
- data/spec/lib/oauth/client/methods_spec.rb +4 -4
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +4 -4
- data/spec/lib/oauth/client_credentials/validation_spec.rb +2 -2
- data/spec/lib/oauth/client_credentials_request_spec.rb +4 -4
- data/spec/lib/oauth/client_spec.rb +5 -5
- data/spec/lib/oauth/code_request_spec.rb +3 -3
- data/spec/lib/oauth/error_response_spec.rb +3 -3
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +2 -2
- data/spec/lib/oauth/password_access_token_request_spec.rb +26 -10
- data/spec/lib/oauth/pre_authorization_spec.rb +2 -2
- data/spec/lib/oauth/refresh_token_request_spec.rb +52 -10
- data/spec/lib/oauth/token_request_spec.rb +3 -3
- data/spec/lib/oauth/token_response_spec.rb +8 -5
- data/spec/lib/oauth/token_spec.rb +8 -8
- data/spec/lib/server_spec.rb +1 -1
- data/spec/models/doorkeeper/access_token_spec.rb +6 -9
- data/spec/models/doorkeeper/application_spec.rb +16 -1
- data/spec/requests/applications/applications_request_spec.rb +3 -3
- data/spec/requests/flows/password_spec.rb +20 -0
- data/spec/requests/protected_resources/private_api_spec.rb +8 -0
- metadata +5 -21
- data/app/assets/javascripts/doorkeeper/application.js +0 -2
- data/spec/dummy/app/assets/javascripts/application.js +0 -9
- data/spec/dummy/app/assets/stylesheets/application.css +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c87a791f0146a97560be08975e4e0fd05b72e2d
|
4
|
+
data.tar.gz: 19030e24765e04a10ef4338dee46b6d9faf13620
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a12c6bec0463233f4b7dd69dfc33f88b2a3b42e94fe9fb9bc542c94aadd51f2c39c29f73921616424493d68bc3100f6f937c032119438e72d9a083a4607c13b
|
7
|
+
data.tar.gz: 1b7ce3260177a092ed16e511750f751ec3f8f172cd372c0b31de46d65eaab2c04a5f7d9524c6344dd5ee73938275651d78181f8a0618fee5fb83cfbd99c9b90b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,29 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.0.0.rc1
|
4
|
+
|
5
|
+
- bug (spec)
|
6
|
+
- [#228] token response `expires_in` value is now in seconds, relative to
|
7
|
+
request time
|
8
|
+
- [#296] client is optional for password grant type.
|
9
|
+
- [#319] If client credentials are present on password grant type they are validated
|
10
|
+
- [#326] If client credentials are present in refresh token they are validated
|
11
|
+
- [#326] If authenticated client does not match original client that
|
12
|
+
obtained a refresh token it responds `invalid_grant` instead of
|
13
|
+
`invalid_client`. Previous usage was invalid according to Section 5.2 of
|
14
|
+
the spec.
|
15
|
+
- [#329] access tokens' `scopes` string wa being compared against
|
16
|
+
`default_scopes` symbols, always unauthorizing.
|
17
|
+
- enhancements
|
18
|
+
- [#293] Adds ActionController::Instrumentation in TokensController
|
19
|
+
- [#313] `AccessToken.revoke_all_for` actually revokes all non-revoked
|
20
|
+
tokens for an application/owner instead of deleting them.
|
21
|
+
[@bryanrite](https://github.com/bryanrite)
|
22
|
+
- internals
|
23
|
+
- Removes jQuery dependency [fixes #300] [PR #312 is related]
|
24
|
+
- [#294] Client uid and secret will be generated only if not present.
|
25
|
+
- [#316] Test warnings addressed.
|
26
|
+
|
3
27
|
## 0.7.4
|
4
28
|
|
5
29
|
- bug
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -98,7 +98,7 @@ You need to configure Doorkeeper in order to provide resource_owner model and au
|
|
98
98
|
``` ruby
|
99
99
|
Doorkeeper.configure do
|
100
100
|
resource_owner_authenticator do
|
101
|
-
User.
|
101
|
+
User.find_by_id(session[:current_user_id]) || redirect_to(login_url)
|
102
102
|
end
|
103
103
|
end
|
104
104
|
```
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<style>
|
2
|
+
input[type=submit] {
|
3
|
+
padding: 0;
|
4
|
+
border: none;
|
5
|
+
box-shadow: none;
|
6
|
+
background: none;
|
7
|
+
color: #0069d6;
|
8
|
+
}
|
9
|
+
input[type=submit]:hover {
|
10
|
+
text-decoration: underline;
|
11
|
+
}
|
12
|
+
</style>
|
13
|
+
<%= form_for [:oauth, application] do |f| %>
|
14
|
+
<input type="hidden" name="_method" value="delete">
|
15
|
+
<%= f.submit value: 'Remove', onclick: "return confirm('Are you sure?')" %>
|
16
|
+
<% end %>
|
@@ -1,3 +1,8 @@
|
|
1
|
+
<style>
|
2
|
+
input[type=submit] {
|
3
|
+
margin-top: 15px;
|
4
|
+
}
|
5
|
+
</style>
|
1
6
|
<div class="span16">
|
2
7
|
<header class="page-header">
|
3
8
|
<h2>Your applications</h2>
|
@@ -20,10 +25,9 @@
|
|
20
25
|
<td><%= link_to application.name, [:oauth, application] %></td>
|
21
26
|
<td><%= application.redirect_uri %></td>
|
22
27
|
<td><%= link_to 'Edit', edit_oauth_application_path(application) %></td>
|
23
|
-
<td><%=
|
28
|
+
<td><%= render 'delete_form', application: application %></td>
|
24
29
|
</tr>
|
25
30
|
<% end %>
|
26
31
|
</tbody>
|
27
32
|
</table>
|
28
|
-
|
29
33
|
</div>
|
@@ -22,5 +22,5 @@
|
|
22
22
|
<h3>Actions</h3>
|
23
23
|
<p><%= link_to 'List all', oauth_applications_path %></p>
|
24
24
|
<p><%= link_to 'Edit', edit_oauth_application_path(@application) %></p>
|
25
|
-
<p><%=
|
25
|
+
<p><%= render 'delete_form', application: @application %></p>
|
26
26
|
</div>
|
data/doorkeeper.gemspec
CHANGED
@@ -17,7 +17,6 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.require_paths = ["lib"]
|
18
18
|
|
19
19
|
s.add_dependency "railties", ">= 3.1"
|
20
|
-
s.add_dependency "jquery-rails", ">= 2.0.2"
|
21
20
|
|
22
21
|
s.add_development_dependency "sqlite3", "~> 1.3.5"
|
23
22
|
s.add_development_dependency "rspec-rails", ">= 2.11.4"
|
@@ -23,7 +23,7 @@ module Doorkeeper
|
|
23
23
|
|
24
24
|
private
|
25
25
|
def scopes(scopes)
|
26
|
-
@scopes = scopes
|
26
|
+
@scopes = scopes.map(&:to_s)
|
27
27
|
end
|
28
28
|
|
29
29
|
def if(if_block)
|
@@ -37,7 +37,7 @@ module Doorkeeper
|
|
37
37
|
# TODO: move this to Token class
|
38
38
|
def validate_token_scopes(token)
|
39
39
|
return true if @scopes.blank?
|
40
|
-
token.scopes.any? { |scope| @scopes.include? scope}
|
40
|
+
token.scopes.any? { |scope| @scopes.include? scope }
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -8,7 +8,7 @@ module Doorkeeper
|
|
8
8
|
|
9
9
|
belongs_to :application, :class_name => "Doorkeeper::Application", :inverse_of => :access_tokens
|
10
10
|
|
11
|
-
validates :
|
11
|
+
validates :token, :presence => true
|
12
12
|
validates :token, :uniqueness => true
|
13
13
|
validates :refresh_token, :uniqueness => true, :if => :use_refresh_token?
|
14
14
|
|
@@ -29,7 +29,10 @@ module Doorkeeper
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def self.revoke_all_for(application_id, resource_owner)
|
32
|
-
|
32
|
+
where(:application_id => application_id,
|
33
|
+
:resource_owner_id => resource_owner.id,
|
34
|
+
:revoked_at => nil)
|
35
|
+
.map(&:revoke)
|
33
36
|
end
|
34
37
|
|
35
38
|
def self.matching_token_for(application, resource_owner_or_id, scopes)
|
@@ -30,11 +30,11 @@ module Doorkeeper
|
|
30
30
|
private
|
31
31
|
|
32
32
|
def generate_uid
|
33
|
-
self.uid
|
33
|
+
self.uid ||= UniqueToken.generate
|
34
34
|
end
|
35
35
|
|
36
36
|
def generate_secret
|
37
|
-
self.secret
|
37
|
+
self.secret ||= UniqueToken.generate
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -7,13 +7,16 @@ module Doorkeeper::OAuth
|
|
7
7
|
validate :resource_owner, :error => :invalid_resource_owner
|
8
8
|
validate :scopes, :error => :invalid_scope
|
9
9
|
|
10
|
-
attr_accessor :server, :resource_owner, :
|
10
|
+
attr_accessor :server, :resource_owner, :credentials, :access_token
|
11
|
+
attr_accessor :client
|
11
12
|
|
12
|
-
def initialize(server,
|
13
|
+
def initialize(server, credentials, resource_owner, parameters = {})
|
13
14
|
@server = server
|
14
15
|
@resource_owner = resource_owner
|
15
|
-
@
|
16
|
+
@credentials = credentials
|
16
17
|
@original_scopes = parameters[:scope]
|
18
|
+
|
19
|
+
@client = Doorkeeper::Application.authenticate(credentials.uid, credentials.secret) if credentials
|
17
20
|
end
|
18
21
|
|
19
22
|
def authorize
|
@@ -41,8 +44,10 @@ module Doorkeeper::OAuth
|
|
41
44
|
private
|
42
45
|
|
43
46
|
def issue_token
|
47
|
+
application_id = client.id if client
|
48
|
+
|
44
49
|
@access_token = Doorkeeper::AccessToken.create!({
|
45
|
-
:application_id =>
|
50
|
+
:application_id => application_id,
|
46
51
|
:resource_owner_id => resource_owner.id,
|
47
52
|
:scopes => scopes.to_s,
|
48
53
|
:expires_in => server.access_token_expires_in,
|
@@ -50,10 +55,6 @@ module Doorkeeper::OAuth
|
|
50
55
|
})
|
51
56
|
end
|
52
57
|
|
53
|
-
def validate_client
|
54
|
-
!!client
|
55
|
-
end
|
56
|
-
|
57
58
|
def validate_scopes
|
58
59
|
return true unless @original_scopes.present?
|
59
60
|
ScopeChecker.valid?(@original_scopes, @server.scopes)
|
@@ -62,5 +63,9 @@ module Doorkeeper::OAuth
|
|
62
63
|
def validate_resource_owner
|
63
64
|
!!resource_owner
|
64
65
|
end
|
66
|
+
|
67
|
+
def validate_client
|
68
|
+
!credentials || !!client
|
69
|
+
end
|
65
70
|
end
|
66
71
|
end
|
@@ -2,26 +2,32 @@ module Doorkeeper
|
|
2
2
|
module OAuth
|
3
3
|
class RefreshTokenRequest
|
4
4
|
include Doorkeeper::Validations
|
5
|
+
include Doorkeeper::OAuth::Helpers
|
5
6
|
|
6
|
-
validate :token,
|
7
|
-
validate :client,
|
7
|
+
validate :token, :error => :invalid_request
|
8
|
+
validate :client, :error => :invalid_client
|
9
|
+
validate :client_match, :error => :invalid_grant
|
10
|
+
validate :scope, :error => :invalid_scope
|
8
11
|
|
9
|
-
attr_accessor :server, :refresh_token, :
|
12
|
+
attr_accessor :server, :refresh_token, :credentials, :access_token
|
13
|
+
attr_accessor :client
|
10
14
|
|
11
|
-
|
12
|
-
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@
|
15
|
+
def initialize(server, refresh_token, credentials, parameters = {})
|
16
|
+
@server = server
|
17
|
+
@refresh_token = refresh_token
|
18
|
+
@credentials = credentials
|
19
|
+
@requested_scopes = parameters[:scopes]
|
20
|
+
|
21
|
+
@client = Doorkeeper::Application.authenticate(credentials.uid, credentials.secret) if credentials
|
16
22
|
end
|
17
23
|
|
18
24
|
def authorize
|
19
25
|
validate
|
20
26
|
@response = if valid?
|
21
27
|
revoke_and_create_access_token
|
22
|
-
|
28
|
+
TokenResponse.new access_token
|
23
29
|
else
|
24
|
-
|
30
|
+
ErrorResponse.from_request self
|
25
31
|
end
|
26
32
|
end
|
27
33
|
|
@@ -29,6 +35,14 @@ module Doorkeeper
|
|
29
35
|
self.error.nil?
|
30
36
|
end
|
31
37
|
|
38
|
+
def scopes
|
39
|
+
@scopes ||= if @requested_scopes.present?
|
40
|
+
Scopes.from_string @requested_scopes
|
41
|
+
else
|
42
|
+
refresh_token.scopes
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
32
46
|
private
|
33
47
|
|
34
48
|
def revoke_and_create_access_token
|
@@ -40,7 +54,7 @@ module Doorkeeper
|
|
40
54
|
@access_token = Doorkeeper::AccessToken.create!({
|
41
55
|
:application_id => refresh_token.application_id,
|
42
56
|
:resource_owner_id => refresh_token.resource_owner_id,
|
43
|
-
:scopes =>
|
57
|
+
:scopes => scopes.to_s,
|
44
58
|
:expires_in => server.access_token_expires_in,
|
45
59
|
:use_refresh_token => true
|
46
60
|
})
|
@@ -51,7 +65,19 @@ module Doorkeeper
|
|
51
65
|
end
|
52
66
|
|
53
67
|
def validate_client
|
54
|
-
|
68
|
+
(!credentials || !!client)
|
69
|
+
end
|
70
|
+
|
71
|
+
def validate_client_match
|
72
|
+
!client || refresh_token.application_id == client.id
|
73
|
+
end
|
74
|
+
|
75
|
+
def validate_scope
|
76
|
+
if @requested_scopes.present?
|
77
|
+
ScopeChecker.valid?(@requested_scopes, refresh_token.scopes)
|
78
|
+
else
|
79
|
+
true
|
80
|
+
end
|
55
81
|
end
|
56
82
|
end
|
57
83
|
end
|
@@ -11,7 +11,7 @@ module Doorkeeper
|
|
11
11
|
{
|
12
12
|
'access_token' => token.token,
|
13
13
|
'token_type' => token.token_type,
|
14
|
-
'expires_in' => token.
|
14
|
+
'expires_in' => token.expires_in_seconds,
|
15
15
|
'refresh_token' => token.refresh_token,
|
16
16
|
'scope' => token.scopes_string
|
17
17
|
}.reject { |_, value| value.blank? }
|
@@ -2,17 +2,17 @@ module Doorkeeper
|
|
2
2
|
module Request
|
3
3
|
class Password
|
4
4
|
def self.build(server)
|
5
|
-
new(server.
|
5
|
+
new(server.credentials, server.resource_owner, server)
|
6
6
|
end
|
7
7
|
|
8
|
-
attr_accessor :
|
8
|
+
attr_accessor :credentials, :resource_owner, :server
|
9
9
|
|
10
|
-
def initialize(
|
11
|
-
@
|
10
|
+
def initialize(credentials, resource_owner, server)
|
11
|
+
@credentials, @resource_owner, @server = credentials, resource_owner, server
|
12
12
|
end
|
13
13
|
|
14
14
|
def request
|
15
|
-
@request ||= OAuth::PasswordAccessTokenRequest.new(Doorkeeper.configuration,
|
15
|
+
@request ||= OAuth::PasswordAccessTokenRequest.new(Doorkeeper.configuration, credentials, resource_owner, server.parameters)
|
16
16
|
end
|
17
17
|
|
18
18
|
def authorize
|
@@ -2,17 +2,17 @@ module Doorkeeper
|
|
2
2
|
module Request
|
3
3
|
class RefreshToken
|
4
4
|
def self.build(server)
|
5
|
-
new(server.current_refresh_token, server.
|
5
|
+
new(server.current_refresh_token, server.credentials, server)
|
6
6
|
end
|
7
7
|
|
8
|
-
attr_accessor :refresh_token, :
|
8
|
+
attr_accessor :refresh_token, :credentials, :server
|
9
9
|
|
10
|
-
def initialize(refresh_token,
|
11
|
-
@refresh_token, @
|
10
|
+
def initialize(refresh_token, credentials, server)
|
11
|
+
@refresh_token, @credentials, @server = refresh_token, credentials, server
|
12
12
|
end
|
13
13
|
|
14
14
|
def request
|
15
|
-
@request ||= OAuth::RefreshTokenRequest.new(Doorkeeper.configuration, refresh_token,
|
15
|
+
@request ||= OAuth::RefreshTokenRequest.new(Doorkeeper.configuration, refresh_token, credentials, server.parameters)
|
16
16
|
end
|
17
17
|
|
18
18
|
def authorize
|
data/lib/doorkeeper/version.rb
CHANGED
@@ -25,7 +25,7 @@ class CreateDoorkeeperTables < ActiveRecord::Migration
|
|
25
25
|
|
26
26
|
create_table :oauth_access_tokens do |t|
|
27
27
|
t.integer :resource_owner_id
|
28
|
-
t.integer :application_id
|
28
|
+
t.integer :application_id
|
29
29
|
t.string :token, :null => false
|
30
30
|
t.string :refresh_token
|
31
31
|
t.integer :expires_in
|
@@ -37,6 +37,15 @@ module Doorkeeper
|
|
37
37
|
expect(response).to be_redirect
|
38
38
|
end
|
39
39
|
|
40
|
+
it "does not allow mass assignment of uid or secret" do
|
41
|
+
application = FactoryGirl.create(:application)
|
42
|
+
put :update, id: application.id, application: {
|
43
|
+
uid: '1A2B3C4D',
|
44
|
+
secret: '1A2B3C4D' }
|
45
|
+
|
46
|
+
application.reload.uid.should_not eq '1A2B3C4D'
|
47
|
+
end
|
48
|
+
|
40
49
|
it "updates application" do
|
41
50
|
application = FactoryGirl.create(:application)
|
42
51
|
put :update, id: application.id, application: {
|
@@ -167,14 +167,14 @@ describe "Doorkeeper_for helper" do
|
|
167
167
|
let(:token_string) { "1A2DUWE" }
|
168
168
|
|
169
169
|
it "allows if the token has particular scopes" do
|
170
|
-
token = double(Doorkeeper::AccessToken, :accessible? => true, :scopes => [
|
170
|
+
token = double(Doorkeeper::AccessToken, :accessible? => true, :scopes => ['write', 'public'])
|
171
171
|
Doorkeeper::AccessToken.should_receive(:authenticate).with(token_string).and_return(token)
|
172
172
|
get :index, :access_token => token_string
|
173
173
|
expect(response).to be_success
|
174
174
|
end
|
175
175
|
|
176
176
|
it "does not allow if the token does not include given scope" do
|
177
|
-
token = double(Doorkeeper::AccessToken, :accessible? => true, :scopes => [
|
177
|
+
token = double(Doorkeeper::AccessToken, :accessible? => true, :scopes => ['public'])
|
178
178
|
Doorkeeper::AccessToken.should_receive(:authenticate).with(token_string).and_return(token)
|
179
179
|
get :index, :access_token => token_string
|
180
180
|
expect(response.status).to eq 401
|