doorkeeper 3.1.0 → 4.2.6

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.

Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +5 -0
  4. data/.travis.yml +16 -12
  5. data/Appraisals +14 -0
  6. data/CONTRIBUTING.md +2 -0
  7. data/Gemfile +5 -5
  8. data/NEWS.md +83 -2
  9. data/README.md +73 -43
  10. data/RELEASING.md +5 -12
  11. data/Rakefile +1 -1
  12. data/app/controllers/doorkeeper/application_controller.rb +3 -1
  13. data/app/controllers/doorkeeper/application_metal_controller.rb +3 -2
  14. data/app/controllers/doorkeeper/applications_controller.rb +3 -7
  15. data/app/controllers/doorkeeper/authorizations_controller.rb +1 -1
  16. data/app/controllers/doorkeeper/authorized_applications_controller.rb +1 -1
  17. data/app/controllers/doorkeeper/tokens_controller.rb +50 -14
  18. data/app/helpers/doorkeeper/dashboard_helper.rb +13 -11
  19. data/app/views/doorkeeper/applications/_delete_form.html.erb +1 -2
  20. data/app/views/doorkeeper/applications/_form.html.erb +1 -1
  21. data/app/views/doorkeeper/applications/show.html.erb +1 -1
  22. data/app/views/doorkeeper/authorizations/new.html.erb +1 -1
  23. data/app/views/doorkeeper/authorized_applications/_delete_form.html.erb +1 -2
  24. data/app/views/layouts/doorkeeper/admin.html.erb +1 -1
  25. data/config/locales/en.yml +3 -2
  26. data/doorkeeper.gemspec +12 -10
  27. data/gemfiles/rails_4_2.gemfile +11 -0
  28. data/gemfiles/rails_5_0.gemfile +12 -0
  29. data/gemfiles/rails_5_1.gemfile +13 -0
  30. data/lib/doorkeeper/config.rb +73 -16
  31. data/lib/doorkeeper/engine.rb +11 -7
  32. data/lib/doorkeeper/errors.rb +18 -0
  33. data/lib/doorkeeper/grape/helpers.rb +2 -1
  34. data/lib/doorkeeper/helpers/controller.rb +8 -23
  35. data/lib/doorkeeper/models/access_grant_mixin.rb +21 -5
  36. data/lib/doorkeeper/models/access_token_mixin.rb +145 -23
  37. data/lib/doorkeeper/models/application_mixin.rb +21 -9
  38. data/lib/doorkeeper/models/concerns/accessible.rb +4 -0
  39. data/lib/doorkeeper/models/concerns/expirable.rb +10 -2
  40. data/lib/doorkeeper/models/concerns/ownership.rb +6 -1
  41. data/lib/doorkeeper/models/concerns/revocable.rb +37 -2
  42. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +20 -18
  43. data/lib/doorkeeper/oauth/authorization_code_request.rb +1 -4
  44. data/lib/doorkeeper/oauth/{request_concern.rb → base_request.rb} +3 -1
  45. data/lib/doorkeeper/oauth/base_response.rb +29 -0
  46. data/lib/doorkeeper/oauth/client/credentials.rb +17 -6
  47. data/lib/doorkeeper/oauth/client.rb +0 -1
  48. data/lib/doorkeeper/oauth/client_credentials/creator.rb +1 -1
  49. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +3 -2
  50. data/lib/doorkeeper/oauth/client_credentials/validation.rb +1 -1
  51. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -8
  52. data/lib/doorkeeper/oauth/code_response.rb +16 -16
  53. data/lib/doorkeeper/oauth/error_response.rb +9 -8
  54. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -1
  55. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +2 -1
  56. data/lib/doorkeeper/oauth/invalid_token_response.rb +2 -0
  57. data/lib/doorkeeper/oauth/password_access_token_request.rb +7 -13
  58. data/lib/doorkeeper/oauth/refresh_token_request.rb +22 -14
  59. data/lib/doorkeeper/oauth/scopes.rb +2 -2
  60. data/lib/doorkeeper/oauth/token.rb +20 -21
  61. data/lib/doorkeeper/oauth/token_request.rb +1 -2
  62. data/lib/doorkeeper/oauth/token_response.rb +1 -1
  63. data/lib/doorkeeper/orm/active_record/access_token.rb +25 -0
  64. data/lib/doorkeeper/orm/active_record/application.rb +12 -12
  65. data/lib/doorkeeper/orm/active_record.rb +0 -16
  66. data/lib/doorkeeper/rails/helpers.rb +1 -3
  67. data/lib/doorkeeper/rails/routes/mapper.rb +4 -4
  68. data/lib/doorkeeper/rails/routes/mapping.rb +1 -1
  69. data/lib/doorkeeper/rails/routes.rb +4 -4
  70. data/lib/doorkeeper/request/authorization_code.rb +7 -1
  71. data/lib/doorkeeper/request/password.rb +11 -1
  72. data/lib/doorkeeper/request/refresh_token.rb +1 -1
  73. data/lib/doorkeeper/server.rb +0 -8
  74. data/lib/doorkeeper/version.rb +1 -1
  75. data/lib/doorkeeper.rb +8 -2
  76. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +29 -0
  77. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb +1 -1
  78. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb +11 -0
  79. data/lib/generators/doorkeeper/templates/initializer.rb +8 -3
  80. data/lib/generators/doorkeeper/templates/migration.rb +23 -5
  81. data/spec/controllers/application_metal_controller.rb +10 -0
  82. data/spec/controllers/authorizations_controller_spec.rb +39 -24
  83. data/spec/controllers/protected_resources_controller_spec.rb +47 -18
  84. data/spec/controllers/tokens_controller_spec.rb +1 -1
  85. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +4 -4
  86. data/spec/dummy/app/controllers/home_controller.rb +1 -1
  87. data/spec/dummy/app/controllers/metal_controller.rb +1 -1
  88. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +3 -3
  89. data/spec/dummy/app/models/user.rb +0 -4
  90. data/spec/dummy/config/application.rb +2 -36
  91. data/spec/dummy/config/environment.rb +1 -1
  92. data/spec/dummy/config/environments/test.rb +4 -15
  93. data/spec/dummy/config/initializers/active_record_belongs_to_required_by_default.rb +6 -0
  94. data/spec/dummy/config/initializers/doorkeeper.rb +2 -2
  95. data/spec/dummy/db/migrate/{20130902165751_create_doorkeeper_tables.rb → 20151223192035_create_doorkeeper_tables.rb} +24 -5
  96. data/spec/dummy/db/migrate/{20130902175349_add_owner_to_application.rb → 20151223200000_add_owner_to_application.rb} +0 -0
  97. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +11 -0
  98. data/spec/dummy/db/schema.rb +23 -22
  99. data/spec/factories.rb +3 -1
  100. data/spec/lib/config_spec.rb +19 -2
  101. data/spec/lib/doorkeeper_spec.rb +135 -13
  102. data/spec/lib/models/expirable_spec.rb +0 -1
  103. data/spec/lib/models/revocable_spec.rb +27 -4
  104. data/spec/lib/oauth/authorization/uri_builder_spec.rb +1 -2
  105. data/spec/lib/oauth/authorization_code_request_spec.rb +1 -1
  106. data/spec/lib/oauth/base_request_spec.rb +160 -0
  107. data/spec/lib/oauth/base_response_spec.rb +45 -0
  108. data/spec/lib/oauth/client/credentials_spec.rb +41 -0
  109. data/spec/lib/oauth/code_response_spec.rb +34 -0
  110. data/spec/lib/oauth/error_response_spec.rb +9 -9
  111. data/spec/lib/oauth/invalid_token_response_spec.rb +36 -8
  112. data/spec/lib/oauth/password_access_token_request_spec.rb +5 -5
  113. data/spec/lib/oauth/refresh_token_request_spec.rb +34 -3
  114. data/spec/lib/oauth/scopes_spec.rb +0 -1
  115. data/spec/lib/oauth/token_spec.rb +12 -5
  116. data/spec/lib/server_spec.rb +0 -3
  117. data/spec/models/doorkeeper/access_token_spec.rb +45 -1
  118. data/spec/models/doorkeeper/application_spec.rb +3 -11
  119. data/spec/requests/endpoints/authorization_spec.rb +5 -6
  120. data/spec/requests/flows/authorization_code_errors_spec.rb +11 -1
  121. data/spec/requests/flows/authorization_code_spec.rb +4 -12
  122. data/spec/requests/flows/password_spec.rb +26 -5
  123. data/spec/requests/flows/refresh_token_spec.rb +87 -17
  124. data/spec/requests/flows/revoke_token_spec.rb +100 -86
  125. data/spec/spec_helper.rb +2 -0
  126. data/spec/spec_helper_integration.rb +8 -1
  127. data/spec/support/helpers/model_helper.rb +27 -5
  128. data/spec/support/helpers/request_spec_helper.rb +12 -4
  129. data/spec/support/http_method_shim.rb +38 -0
  130. data/spec/support/shared/controllers_shared_context.rb +13 -4
  131. data/spec/support/shared/models_shared_examples.rb +1 -1
  132. metadata +72 -42
  133. data/lib/doorkeeper/oauth/client/methods.rb +0 -18
  134. data/lib/generators/doorkeeper/application_scopes_generator.rb +0 -34
  135. data/lib/generators/doorkeeper/templates/add_scopes_to_oauth_applications.rb +0 -5
  136. data/spec/dummy/db/migrate/20141209001746_add_scopes_to_oauth_applications.rb +0 -5
  137. data/spec/lib/oauth/client/methods_spec.rb +0 -54
@@ -11,55 +11,56 @@
11
11
  #
12
12
  # It's strongly recommended that you check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(version: 20141209001746) do
14
+ ActiveRecord::Schema.define(version: 20160320211015) do
15
15
 
16
- create_table "oauth_access_grants", force: true do |t|
17
- t.integer "resource_owner_id", null: false
18
- t.integer "application_id", null: false
19
- t.string "token", null: false
20
- t.integer "expires_in", null: false
21
- t.string "redirect_uri", limit: 2048, null: false
22
- t.datetime "created_at", null: false
16
+ create_table "oauth_access_grants", force: :cascade do |t|
17
+ t.integer "resource_owner_id", null: false
18
+ t.integer "application_id", null: false
19
+ t.string "token", null: false
20
+ t.integer "expires_in", null: false
21
+ t.text "redirect_uri", null: false
22
+ t.datetime "created_at", null: false
23
23
  t.datetime "revoked_at"
24
24
  t.string "scopes"
25
25
  end
26
26
 
27
27
  add_index "oauth_access_grants", ["token"], name: "index_oauth_access_grants_on_token", unique: true
28
28
 
29
- create_table "oauth_access_tokens", force: true do |t|
29
+ create_table "oauth_access_tokens", force: :cascade do |t|
30
30
  t.integer "resource_owner_id"
31
31
  t.integer "application_id"
32
- t.string "token", null: false
32
+ t.string "token", null: false
33
33
  t.string "refresh_token"
34
34
  t.integer "expires_in"
35
35
  t.datetime "revoked_at"
36
- t.datetime "created_at", null: false
36
+ t.datetime "created_at", null: false
37
37
  t.string "scopes"
38
+ t.string "previous_refresh_token", default: "", null: false
38
39
  end
39
40
 
40
41
  add_index "oauth_access_tokens", ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true
41
42
  add_index "oauth_access_tokens", ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id"
42
43
  add_index "oauth_access_tokens", ["token"], name: "index_oauth_access_tokens_on_token", unique: true
43
44
 
44
- create_table "oauth_applications", force: true do |t|
45
- t.string "name", null: false
46
- t.string "uid", null: false
47
- t.string "secret", null: false
48
- t.string "redirect_uri", limit: 2048, null: false
49
- t.datetime "created_at", null: false
50
- t.datetime "updated_at", null: false
45
+ create_table "oauth_applications", force: :cascade do |t|
46
+ t.string "name", null: false
47
+ t.string "uid", null: false
48
+ t.string "secret", null: false
49
+ t.text "redirect_uri", null: false
50
+ t.string "scopes", default: "", null: false
51
+ t.datetime "created_at"
52
+ t.datetime "updated_at"
51
53
  t.integer "owner_id"
52
54
  t.string "owner_type"
53
- t.string "scopes", default: "", null: false
54
55
  end
55
56
 
56
57
  add_index "oauth_applications", ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type"
57
58
  add_index "oauth_applications", ["uid"], name: "index_oauth_applications_on_uid", unique: true
58
59
 
59
- create_table "users", force: true do |t|
60
+ create_table "users", force: :cascade do |t|
60
61
  t.string "name"
61
- t.datetime "created_at", null: false
62
- t.datetime "updated_at", null: false
62
+ t.datetime "created_at"
63
+ t.datetime "updated_at"
63
64
  t.string "password"
64
65
  end
65
66
 
data/spec/factories.rb CHANGED
@@ -22,5 +22,7 @@ FactoryGirl.define do
22
22
  redirect_uri 'https://app.com/callback'
23
23
  end
24
24
 
25
- factory :user
25
+ # do not name this factory :user, otherwise it will conflict with factories
26
+ # from applications that use doorkeeper factories in their own tests
27
+ factory :doorkeeper_testing_user, class: :user
26
28
  end
@@ -8,7 +8,7 @@ describe Doorkeeper, 'configuration' do
8
8
  block = proc {}
9
9
  Doorkeeper.configure do
10
10
  orm DOORKEEPER_ORM
11
- resource_owner_authenticator &block
11
+ resource_owner_authenticator(&block)
12
12
  end
13
13
  expect(subject.authenticate_resource_owner).to eq(block)
14
14
  end
@@ -149,7 +149,7 @@ describe Doorkeeper, 'configuration' do
149
149
  end
150
150
  end
151
151
 
152
- describe 'access_token_credentials' do
152
+ describe 'access_token_methods' do
153
153
  it 'has defaults order' do
154
154
  expect(subject.access_token_methods).to eq([:from_bearer_authorization, :from_access_token_param, :from_bearer_param])
155
155
  end
@@ -314,4 +314,21 @@ describe Doorkeeper, 'configuration' do
314
314
  expect(subject.access_token_generator).to eq('Example')
315
315
  end
316
316
  end
317
+
318
+ describe 'base_controller' do
319
+ context 'default' do
320
+ it { expect(Doorkeeper.configuration.base_controller).to eq('ActionController::Base') }
321
+ end
322
+
323
+ context 'custom' do
324
+ before do
325
+ Doorkeeper.configure do
326
+ orm DOORKEEPER_ORM
327
+ base_controller 'ApplicationController'
328
+ end
329
+ end
330
+
331
+ it { expect(Doorkeeper.configuration.base_controller).to eq('ApplicationController') }
332
+ end
333
+ end
317
334
  end
@@ -1,28 +1,150 @@
1
1
  require 'spec_helper_integration'
2
2
 
3
3
  describe Doorkeeper do
4
- describe 'authenticate' do
5
- let(:token) { double('Token') }
6
- let(:request) { double('ActionDispatch::Request') }
4
+ describe "#authenticate" do
5
+ let(:request) { double }
6
+
7
+ it "calls OAuth::Token#authenticate" do
8
+ token_strategies = Doorkeeper.configuration.access_token_methods
9
+
10
+ expect(Doorkeeper::OAuth::Token).to receive(:authenticate).
11
+ with(request, *token_strategies)
12
+
13
+ Doorkeeper.authenticate(request)
14
+ end
15
+
16
+ it "accepts custom token strategies" do
17
+ token_strategies = [:first_way, :second_way]
18
+
19
+ expect(Doorkeeper::OAuth::Token).to receive(:authenticate).
20
+ with(request, *token_strategies)
21
+
22
+ Doorkeeper.authenticate(request, token_strategies)
23
+ end
24
+ end
25
+
26
+ describe "#configured?" do
27
+ after do
28
+ Doorkeeper.remove_instance_variable(:@config)
29
+ end
30
+
31
+ context "@config is set" do
32
+ it "returns true" do
33
+ Doorkeeper.instance_variable_set(:@config, "hi")
34
+
35
+ expect(Doorkeeper.configured?).to eq(true)
36
+ end
37
+ end
38
+
39
+ context "@config is not set" do
40
+ it "returns false" do
41
+ Doorkeeper.instance_variable_set(:@config, nil)
42
+
43
+ expect(Doorkeeper.configured?).to eq(false)
44
+ end
45
+ end
46
+
47
+ it "is deprecated" do
48
+ expect(ActiveSupport::Deprecation).to receive(:warn).
49
+ with("Method `Doorkeeper#configured?` has been deprecated without replacement.")
50
+
51
+ Doorkeeper.configured?
52
+ end
53
+ end
54
+
55
+ describe "#database_installed?" do
7
56
  before do
8
- allow(Doorkeeper::OAuth::Token).to receive(:authenticate).
9
- with(request, *token_strategies) { token }
57
+ ["AccessToken", "AccessGrant", "Application"].each do |klass|
58
+ @original_classes ||= {}
59
+ @original_classes[klass] = Doorkeeper.const_get(klass)
60
+ Doorkeeper.send(:remove_const, klass)
61
+ end
62
+ end
63
+
64
+ after do
65
+ ["AccessToken", "AccessGrant", "Application"].each do |klass|
66
+ Doorkeeper.send(:remove_const, klass)
67
+ Doorkeeper.const_set(klass, @original_classes[klass])
68
+ end
10
69
  end
11
70
 
12
- context 'with specific access token strategies' do
13
- let(:token_strategies) { [:first_way, :second_way] }
71
+ context "all tables exist" do
72
+ before do
73
+ klass = double table_exists?: true
74
+
75
+ Doorkeeper.const_set(:AccessToken, klass)
76
+ Doorkeeper.const_set(:AccessGrant, klass)
77
+ Doorkeeper.const_set(:Application, klass)
78
+ end
14
79
 
15
- it 'authenticates the token from the request' do
16
- expect(Doorkeeper.authenticate(request, token_strategies)).to eq(token)
80
+ it "returns true" do
81
+ expect(Doorkeeper.database_installed?).to eq(true)
82
+ end
83
+
84
+ it "is deprecated" do
85
+ expect(ActiveSupport::Deprecation).to receive(:warn).
86
+ with("Method `Doorkeeper#database_installed?` has been deprecated without replacement.")
87
+
88
+ Doorkeeper.database_installed?
17
89
  end
18
90
  end
19
91
 
20
- context 'with default access token strategies' do
21
- let(:token_strategies) { Doorkeeper.configuration.access_token_methods }
92
+ context "all tables do not exist" do
93
+ before do
94
+ klass = double table_exists?: false
95
+
96
+ Doorkeeper.const_set(:AccessToken, klass)
97
+ Doorkeeper.const_set(:AccessGrant, klass)
98
+ Doorkeeper.const_set(:Application, klass)
99
+ end
100
+
101
+ it "returns false" do
102
+ expect(Doorkeeper.database_installed?).to eq(false)
103
+ end
104
+
105
+ it "is deprecated" do
106
+ expect(ActiveSupport::Deprecation).to receive(:warn).
107
+ with("Method `Doorkeeper#database_installed?` has been deprecated without replacement.")
22
108
 
23
- it 'authenticates the token from the request' do
24
- expect(Doorkeeper.authenticate(request)).to eq(token)
109
+ Doorkeeper.database_installed?
25
110
  end
26
111
  end
27
112
  end
113
+
114
+ describe "#installed?" do
115
+ context "methods return true" do
116
+ before do
117
+ allow(Doorkeeper).to receive(:configured?).and_return(true).once
118
+ allow(Doorkeeper).to receive(:database_installed?).and_return(true).once
119
+ end
120
+
121
+ it "returns true" do
122
+ expect(Doorkeeper.installed?).to eq(true)
123
+ end
124
+ end
125
+
126
+ context "methods return false" do
127
+ before do
128
+ allow(Doorkeeper).to receive(:configured?).and_return(false).once
129
+ allow(Doorkeeper).to receive(:database_installed?).and_return(false).once
130
+ end
131
+
132
+ it "returns false" do
133
+ expect(Doorkeeper.installed?).to eq(false)
134
+ end
135
+ end
136
+
137
+ it "is deprecated" do
138
+ expect(ActiveSupport::Deprecation).to receive(:warn).
139
+ with("Method `Doorkeeper#configured?` has been deprecated without replacement.")
140
+
141
+ expect(ActiveSupport::Deprecation).to receive(:warn).
142
+ with("Method `Doorkeeper#database_installed?` has been deprecated without replacement.")
143
+
144
+ expect(ActiveSupport::Deprecation).to receive(:warn).
145
+ with("Method `Doorkeeper#installed?` has been deprecated without replacement.")
146
+
147
+ Doorkeeper.installed?
148
+ end
149
+ end
28
150
  end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'timecop'
3
2
  require 'active_support/time'
4
3
  require 'doorkeeper/models/concerns/expirable'
5
4
 
@@ -11,20 +11,21 @@ describe 'Revocable' do
11
11
 
12
12
  describe :revoke do
13
13
  it 'updates :revoked_at attribute with current time' do
14
- clock = double now: double
15
- expect(subject).to receive(:update_attribute).with(:revoked_at, clock.now)
14
+ utc = double utc: double
15
+ clock = double now: utc
16
+ expect(subject).to receive(:update_attribute).with(:revoked_at, clock.now.utc)
16
17
  subject.revoke(clock)
17
18
  end
18
19
  end
19
20
 
20
21
  describe :revoked? do
21
22
  it 'is revoked if :revoked_at has passed' do
22
- allow(subject).to receive(:revoked_at).and_return(Time.now - 1000)
23
+ allow(subject).to receive(:revoked_at).and_return(Time.now.utc - 1000)
23
24
  expect(subject).to be_revoked
24
25
  end
25
26
 
26
27
  it 'is not revoked if :revoked_at has not passed' do
27
- allow(subject).to receive(:revoked_at).and_return(Time.now + 1000)
28
+ allow(subject).to receive(:revoked_at).and_return(Time.now.utc + 1000)
28
29
  expect(subject).not_to be_revoked
29
30
  end
30
31
 
@@ -33,4 +34,26 @@ describe 'Revocable' do
33
34
  expect(subject).not_to be_revoked
34
35
  end
35
36
  end
37
+
38
+ describe :revoke_previous_refresh_token! do
39
+ it "revokes the previous token if existing, and resets the
40
+ `previous_refresh_token` attribute" do
41
+ previous_token = FactoryGirl.create(
42
+ :access_token,
43
+ refresh_token: "refresh_token"
44
+ )
45
+ current_token = FactoryGirl.create(
46
+ :access_token,
47
+ previous_refresh_token: previous_token.refresh_token
48
+ )
49
+
50
+ expect_any_instance_of(
51
+ Doorkeeper::AccessToken
52
+ ).to receive(:revoke).and_call_original
53
+ current_token.revoke_previous_refresh_token!
54
+
55
+ expect(current_token.previous_refresh_token).to be_empty
56
+ expect(previous_token.reload).to be_revoked
57
+ end
58
+ end
36
59
  end
@@ -6,8 +6,7 @@ require 'doorkeeper/oauth/authorization/uri_builder'
6
6
 
7
7
  module Doorkeeper::OAuth::Authorization
8
8
  describe URIBuilder do
9
-
10
- subject { Object.new.class.send :include, URIBuilder }
9
+ subject { URIBuilder }
11
10
 
12
11
  describe :uri_with_query do
13
12
  it 'returns the uri with query' do
@@ -18,7 +18,7 @@ module Doorkeeper::OAuth
18
18
  it 'issues a new token for the client' do
19
19
  expect do
20
20
  subject.authorize
21
- end.to change { client.access_tokens.count }.by(1)
21
+ end.to change { client.reload.access_tokens.count }.by(1)
22
22
  end
23
23
 
24
24
  it "issues the token with same grant's scopes" do
@@ -0,0 +1,160 @@
1
+ require 'spec_helper_integration'
2
+
3
+ module Doorkeeper::OAuth
4
+ describe BaseRequest do
5
+ let(:access_token) do
6
+ double :access_token,
7
+ token: "some-token",
8
+ expires_in: "3600",
9
+ expires_in_seconds: "300",
10
+ scopes_string: "two scopes",
11
+ refresh_token: "some-refresh-token",
12
+ token_type: "bearer",
13
+ created_at: 0
14
+ end
15
+
16
+ let(:client) do
17
+ double :client,
18
+ id: '1'
19
+ end
20
+
21
+ let(:scopes_array) do
22
+ %w(public write)
23
+ end
24
+
25
+ let(:server) do
26
+ double :server,
27
+ access_token_expires_in: 100,
28
+ custom_access_token_expires_in: ->(_) { nil },
29
+ refresh_token_enabled?: false
30
+ end
31
+
32
+ subject do
33
+ BaseRequest.new
34
+ end
35
+
36
+ describe "#authorize" do
37
+ before do
38
+ allow(subject).to receive(:access_token).and_return(access_token)
39
+ end
40
+
41
+ it "validates itself" do
42
+ expect(subject).to receive(:validate).once
43
+ subject.authorize
44
+ end
45
+
46
+ context "valid" do
47
+ before do
48
+ allow(subject).to receive(:valid?).and_return(true)
49
+ end
50
+
51
+ it "calls callback methods" do
52
+ expect(subject).to receive(:before_successful_response).once
53
+ expect(subject).to receive(:after_successful_response).once
54
+ subject.authorize
55
+ end
56
+
57
+ it "returns a TokenResponse object" do
58
+ result = subject.authorize
59
+
60
+ expect(result).to be_an_instance_of(TokenResponse)
61
+ expect(result.body).to eq(
62
+ TokenResponse.new(access_token).body
63
+ )
64
+ end
65
+ end
66
+
67
+ context "invalid" do
68
+ before do
69
+ allow(subject).to receive(:valid?).and_return(false)
70
+ allow(subject).to receive(:error).and_return("server_error")
71
+ allow(subject).to receive(:state).and_return("hello")
72
+ end
73
+
74
+ it "returns an ErrorResponse object" do
75
+ error_description = I18n.translate(
76
+ "server_error",
77
+ scope: [:doorkeeper, :errors, :messages]
78
+ )
79
+
80
+ result = subject.authorize
81
+
82
+ expect(result).to be_an_instance_of(ErrorResponse)
83
+
84
+ expect(result.body).to eq(
85
+ error: "server_error",
86
+ error_description: error_description,
87
+ state: "hello"
88
+ )
89
+ end
90
+ end
91
+ end
92
+
93
+ describe "#default_scopes" do
94
+ it "delegates to the server" do
95
+ expect(subject).to receive(:server).and_return(server).once
96
+ expect(server).to receive(:default_scopes).once
97
+
98
+ subject.default_scopes
99
+ end
100
+ end
101
+
102
+ describe "#find_or_create_access_token" do
103
+ it "returns an instance of AccessToken" do
104
+ result = subject.find_or_create_access_token(
105
+ client,
106
+ "1",
107
+ "public",
108
+ server
109
+ )
110
+
111
+ expect(result).to be_an_instance_of(Doorkeeper::AccessToken)
112
+ end
113
+ end
114
+
115
+ describe "#scopes" do
116
+ context "@original_scopes is present" do
117
+ before do
118
+ subject.instance_variable_set(:@original_scopes, "public write")
119
+ end
120
+
121
+ it "returns array of @original_scopes" do
122
+ result = subject.scopes
123
+
124
+ expect(result).to eq(scopes_array)
125
+ end
126
+ end
127
+
128
+ context "@original_scopes is not present" do
129
+ before do
130
+ subject.instance_variable_set(:@original_scopes, "")
131
+ end
132
+
133
+ it "calls #default_scopes" do
134
+ allow(subject).to receive(:server).and_return(server).once
135
+ allow(server).to receive(:default_scopes).and_return(scopes_array).once
136
+
137
+ result = subject.scopes
138
+
139
+ expect(result).to eq(scopes_array)
140
+ end
141
+ end
142
+ end
143
+
144
+ describe "#valid?" do
145
+ context "error is nil" do
146
+ it "returns true" do
147
+ allow(subject).to receive(:error).and_return(nil).once
148
+ expect(subject.valid?).to eq(true)
149
+ end
150
+ end
151
+
152
+ context "error is not nil" do
153
+ it "returns false" do
154
+ allow(subject).to receive(:error).and_return(Object.new).once
155
+ expect(subject.valid?).to eq(false)
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper_integration'
2
+
3
+ module Doorkeeper::OAuth
4
+ describe BaseResponse do
5
+ subject do
6
+ BaseResponse.new
7
+ end
8
+
9
+ describe "#body" do
10
+ it "returns an empty Hash" do
11
+ expect(subject.body).to eq({})
12
+ end
13
+ end
14
+
15
+ describe "#description" do
16
+ it "returns an empty String" do
17
+ expect(subject.description).to eq("")
18
+ end
19
+ end
20
+
21
+ describe "#headers" do
22
+ it "returns an empty Hash" do
23
+ expect(subject.headers).to eq({})
24
+ end
25
+ end
26
+
27
+ describe "#redirectable?" do
28
+ it "returns false" do
29
+ expect(subject.redirectable?).to eq(false)
30
+ end
31
+ end
32
+
33
+ describe "#redirect_uri" do
34
+ it "returns an empty String" do
35
+ expect(subject.redirect_uri).to eq("")
36
+ end
37
+ end
38
+
39
+ describe "#status" do
40
+ it "returns :ok" do
41
+ expect(subject.status).to eq(:ok)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -4,6 +4,9 @@ require 'doorkeeper/oauth/client'
4
4
 
5
5
  class Doorkeeper::OAuth::Client
6
6
  describe Credentials do
7
+ let(:client_id) { 'some-uid' }
8
+ let(:client_secret) { 'some-secret' }
9
+
7
10
  it 'is blank when any of the credentials is blank' do
8
11
  expect(Credentials.new(nil, 'something')).to be_blank
9
12
  expect(Credentials.new('something', nil)).to be_blank
@@ -43,5 +46,43 @@ class Doorkeeper::OAuth::Client
43
46
  expect(credentials.secret).to eq('secret')
44
47
  end
45
48
  end
49
+
50
+ describe :from_params do
51
+ it 'returns credentials from parameters when Authorization header is not available' do
52
+ request = double parameters: { client_id: client_id, client_secret: client_secret }
53
+ uid, secret = Credentials.from_params(request)
54
+
55
+ expect(uid).to eq('some-uid')
56
+ expect(secret).to eq('some-secret')
57
+ end
58
+
59
+ it 'is blank when there are no credentials' do
60
+ request = double parameters: {}
61
+ uid, secret = Credentials.from_params(request)
62
+
63
+ expect(uid).to be_blank
64
+ expect(secret).to be_blank
65
+ end
66
+ end
67
+
68
+ describe :from_basic do
69
+ let(:credentials) { Base64.encode64("#{client_id}:#{client_secret}") }
70
+
71
+ it 'decodes the credentials' do
72
+ request = double authorization: "Basic #{credentials}"
73
+ uid, secret = Credentials.from_basic(request)
74
+
75
+ expect(uid).to eq('some-uid')
76
+ expect(secret).to eq('some-secret')
77
+ end
78
+
79
+ it 'is blank if Authorization is not Basic' do
80
+ request = double authorization: "#{credentials}"
81
+ uid, secret = Credentials.from_basic(request)
82
+
83
+ expect(uid).to be_blank
84
+ expect(secret).to be_blank
85
+ end
86
+ end
46
87
  end
47
88
  end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ module Doorkeeper
4
+ module OAuth
5
+ describe CodeResponse do
6
+ describe '.redirect_uri' do
7
+ context 'when generating the redirect URI for an implicit grant' do
8
+ let :pre_auth do
9
+ double(
10
+ :pre_auth,
11
+ client: double(:application, id: 1),
12
+ redirect_uri: 'http://tst.com/cb',
13
+ state: nil,
14
+ scopes: Scopes.from_string('public'),
15
+ )
16
+ end
17
+
18
+ let :auth do
19
+ Authorization::Token.new(pre_auth, double(id: 1)).tap do |c|
20
+ c.issue_token
21
+ allow(c.token).to receive(:expires_in_seconds).and_return(3600)
22
+ end
23
+ end
24
+
25
+ subject { CodeResponse.new(pre_auth, auth, response_on_fragment: true).redirect_uri }
26
+
27
+ it 'includes the remaining TTL of the token relative to the time the token was generated' do
28
+ expect(subject).to include('expires_in=3600')
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end