doorkeeper 0.5.0 → 0.6.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.

Files changed (105) hide show
  1. data/.travis.yml +15 -6
  2. data/CHANGELOG.md +19 -1
  3. data/Gemfile +23 -7
  4. data/README.md +62 -27
  5. data/app/controllers/doorkeeper/application_controller.rb +1 -1
  6. data/app/controllers/doorkeeper/authorizations_controller.rb +45 -35
  7. data/app/controllers/doorkeeper/token_info_controller.rb +10 -9
  8. data/app/controllers/doorkeeper/tokens_controller.rb +13 -32
  9. data/app/validators/redirect_uri_validator.rb +11 -0
  10. data/app/views/doorkeeper/applications/_form.html.erb +6 -1
  11. data/app/views/doorkeeper/applications/edit.html.erb +2 -2
  12. data/app/views/doorkeeper/applications/new.html.erb +2 -2
  13. data/app/views/doorkeeper/applications/show.html.erb +4 -1
  14. data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
  15. data/app/views/doorkeeper/authorizations/new.html.erb +17 -17
  16. data/app/views/doorkeeper/authorizations/show.html.erb +4 -0
  17. data/config/locales/en.yml +10 -0
  18. data/doorkeeper.gemspec +3 -3
  19. data/lib/doorkeeper.rb +11 -2
  20. data/lib/doorkeeper/config.rb +6 -1
  21. data/lib/doorkeeper/errors.rb +15 -0
  22. data/lib/doorkeeper/helpers/controller.rb +24 -0
  23. data/lib/doorkeeper/models/access_grant.rb +1 -1
  24. data/lib/doorkeeper/models/access_token.rb +2 -3
  25. data/lib/doorkeeper/models/active_record/access_token.rb +6 -0
  26. data/lib/doorkeeper/models/mongo_mapper/access_grant.rb +28 -0
  27. data/lib/doorkeeper/models/mongo_mapper/access_token.rb +51 -0
  28. data/lib/doorkeeper/models/mongo_mapper/application.rb +30 -0
  29. data/lib/doorkeeper/models/mongo_mapper/revocable.rb +15 -0
  30. data/lib/doorkeeper/models/{mongoid → mongoid2}/access_grant.rb +1 -1
  31. data/lib/doorkeeper/models/{mongoid → mongoid2}/access_token.rb +6 -0
  32. data/lib/doorkeeper/models/{mongoid → mongoid2}/application.rb +2 -2
  33. data/lib/doorkeeper/models/mongoid3/access_grant.rb +22 -0
  34. data/lib/doorkeeper/models/mongoid3/access_token.rb +41 -0
  35. data/lib/doorkeeper/models/mongoid3/application.rb +22 -0
  36. data/lib/doorkeeper/oauth/authorization/code.rb +9 -17
  37. data/lib/doorkeeper/oauth/authorization/token.rb +8 -18
  38. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +2 -0
  39. data/lib/doorkeeper/oauth/authorization_code_request.rb +82 -0
  40. data/lib/doorkeeper/oauth/client_credentials_request.rb +2 -4
  41. data/lib/doorkeeper/oauth/code_request.rb +28 -0
  42. data/lib/doorkeeper/oauth/code_response.rb +37 -0
  43. data/lib/doorkeeper/oauth/error_response.rb +23 -9
  44. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +4 -0
  45. data/lib/doorkeeper/oauth/password_access_token_request.rb +21 -65
  46. data/lib/doorkeeper/oauth/pre_authorization.rb +62 -0
  47. data/lib/doorkeeper/oauth/refresh_token_request.rb +58 -0
  48. data/lib/doorkeeper/oauth/token_request.rb +28 -0
  49. data/lib/doorkeeper/oauth/token_response.rb +29 -0
  50. data/lib/doorkeeper/rails/routes.rb +4 -3
  51. data/lib/doorkeeper/request.rb +33 -0
  52. data/lib/doorkeeper/request/authorization_code.rb +23 -0
  53. data/lib/doorkeeper/request/client_credentials.rb +23 -0
  54. data/lib/doorkeeper/request/code.rb +24 -0
  55. data/lib/doorkeeper/request/password.rb +23 -0
  56. data/lib/doorkeeper/request/refresh_token.rb +23 -0
  57. data/lib/doorkeeper/request/token.rb +24 -0
  58. data/lib/doorkeeper/server.rb +54 -0
  59. data/lib/doorkeeper/validations.rb +1 -0
  60. data/lib/doorkeeper/version.rb +1 -1
  61. data/lib/generators/doorkeeper/mongo_mapper/indexes_generator.rb +12 -0
  62. data/lib/generators/doorkeeper/templates/README +15 -1
  63. data/lib/generators/doorkeeper/templates/indexes.rb +3 -0
  64. data/lib/generators/doorkeeper/templates/initializer.rb +8 -1
  65. data/script/run_all +9 -9
  66. data/spec/controllers/authorizations_controller_spec.rb +8 -19
  67. data/spec/controllers/token_info_controller_spec.rb +9 -9
  68. data/spec/controllers/tokens_controller_spec.rb +2 -1
  69. data/spec/dummy/app/models/user.rb +11 -4
  70. data/spec/dummy/config/application.rb +8 -1
  71. data/spec/dummy/config/boot.rb +1 -1
  72. data/spec/dummy/config/initializers/doorkeeper.rb +9 -1
  73. data/spec/dummy/config/mongo.yml +11 -0
  74. data/spec/dummy/config/{mongoid.yml → mongoid2.yml} +3 -1
  75. data/spec/dummy/config/mongoid3.yml +18 -0
  76. data/spec/generators/install_generator_spec.rb +1 -0
  77. data/spec/lib/oauth/authorization_code_request_spec.rb +80 -0
  78. data/spec/lib/oauth/client_credentials_request_spec.rb +1 -3
  79. data/spec/lib/oauth/code_request_spec.rb +44 -0
  80. data/spec/lib/oauth/error_response_spec.rb +7 -7
  81. data/spec/lib/oauth/password_access_token_request_spec.rb +30 -143
  82. data/spec/lib/oauth/pre_authorization_spec.rb +80 -0
  83. data/spec/lib/oauth/refresh_token_request_spec.rb +56 -0
  84. data/spec/lib/oauth/token_request_spec.rb +46 -0
  85. data/spec/lib/oauth/{client_credentials/response_spec.rb → token_response_spec.rb} +13 -19
  86. data/spec/lib/server_spec.rb +24 -0
  87. data/spec/requests/endpoints/authorization_spec.rb +11 -27
  88. data/spec/requests/endpoints/token_spec.rb +17 -0
  89. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -45
  90. data/spec/requests/flows/authorization_code_spec.rb +12 -2
  91. data/spec/requests/flows/client_credentials_spec.rb +1 -1
  92. data/spec/requests/flows/password_spec.rb +1 -0
  93. data/spec/requests/flows/refresh_token_spec.rb +6 -4
  94. data/spec/spec_helper_integration.rb +4 -2
  95. data/spec/support/orm/mongo_mapper.rb +26 -0
  96. data/spec/support/orm/mongoid.rb +7 -2
  97. data/spec/validators/redirect_uri_validator_spec.rb +11 -4
  98. metadata +67 -42
  99. data/gemfiles/gemfile.rails-3.1.x +0 -17
  100. data/gemfiles/gemfile.rails-3.2.x +0 -17
  101. data/lib/doorkeeper/oauth/access_token_request.rb +0 -139
  102. data/lib/doorkeeper/oauth/authorization_request.rb +0 -114
  103. data/lib/doorkeeper/oauth/client_credentials/response.rb +0 -42
  104. data/spec/lib/oauth/access_token_request_spec.rb +0 -246
  105. data/spec/lib/oauth/authorization_request_spec.rb +0 -287
@@ -1,114 +0,0 @@
1
- module Doorkeeper::OAuth
2
- class AuthorizationRequest
3
- include Doorkeeper::Validations
4
- include Doorkeeper::OAuth::Authorization::URIBuilder
5
- include Doorkeeper::OAuth::Helpers
6
-
7
- ATTRIBUTES = [
8
- :response_type,
9
- :redirect_uri,
10
- :scope,
11
- :state
12
- ]
13
-
14
- validate :client, :error => :invalid_client
15
- validate :redirect_uri, :error => :invalid_redirect_uri
16
- validate :attributes, :error => :invalid_request
17
- validate :response_type, :error => :unsupported_response_type
18
- validate :scope, :error => :invalid_scope
19
-
20
- attr_accessor *ATTRIBUTES
21
- attr_accessor :resource_owner, :client, :error
22
-
23
- def initialize(client, resource_owner, attributes)
24
- ATTRIBUTES.each { |attr| instance_variable_set("@#{attr}", attributes[attr]) }
25
- @resource_owner = resource_owner
26
- @client = client
27
- validate
28
- end
29
-
30
- def authorize
31
- return false unless valid?
32
- @authorization = authorization_method.new(self)
33
- @authorization.issue_token
34
- end
35
-
36
- def access_token_exists?
37
- Doorkeeper::AccessToken.matching_token_for(client, resource_owner, scopes).present?
38
- end
39
-
40
- def deny
41
- self.error = :access_denied
42
- end
43
-
44
- def error_response
45
- Doorkeeper::OAuth::ErrorResponse.from_request(self)
46
- end
47
-
48
- def success_redirect_uri
49
- @authorization.callback
50
- end
51
-
52
- def invalid_redirect_uri
53
- uri_builder = is_token_request? ? :uri_with_fragment : :uri_with_query
54
- send(uri_builder, redirect_uri, error_response.attributes)
55
- end
56
-
57
- def redirect_on_error?
58
- (error != :invalid_redirect_uri) && (error != :invalid_client)
59
- end
60
-
61
- def scopes
62
- @scopes ||= if scope.present?
63
- Doorkeeper::OAuth::Scopes.from_string(scope)
64
- else
65
- Doorkeeper.configuration.default_scopes
66
- end
67
- end
68
-
69
- def client_id
70
- client.uid
71
- end
72
-
73
- private
74
-
75
- def validate_attributes
76
- response_type.present?
77
- end
78
-
79
- def validate_client
80
- !!client
81
- end
82
-
83
- def validate_redirect_uri
84
- return false unless redirect_uri
85
- URIChecker.valid_for_authorization?(redirect_uri, client.redirect_uri)
86
- end
87
-
88
- def validate_response_type
89
- is_code_request? || is_token_request?
90
- end
91
-
92
- def validate_scope
93
- return true unless scope.present?
94
- ScopeChecker.valid?(scope, configuration.scopes)
95
- end
96
-
97
- def is_code_request?
98
- response_type == "code"
99
- end
100
-
101
- def is_token_request?
102
- response_type == "token"
103
- end
104
-
105
- def configuration
106
- Doorkeeper.configuration
107
- end
108
-
109
- def authorization_method
110
- klass = is_code_request? ? "Code" : "Token"
111
- "Doorkeeper::OAuth::Authorization::#{klass}".constantize
112
- end
113
- end
114
- end
@@ -1,42 +0,0 @@
1
- require 'active_model'
2
-
3
- module Doorkeeper
4
- module OAuth
5
- class ClientCredentialsRequest
6
- class Response
7
- include ActiveModel::Serializers::JSON
8
-
9
- self.include_root_in_json = false
10
-
11
- delegate :token, :expires_in, :scopes_string, :to => :@token
12
- alias :access_token :token
13
- alias :scope :scopes_string
14
-
15
- def initialize(token)
16
- @token = token
17
- end
18
-
19
- def attributes
20
- {
21
- 'access_token' => token,
22
- 'token_type' => token_type,
23
- 'expires_in' => expires_in,
24
- 'scope' => scopes_string
25
- }
26
- end
27
-
28
- def status
29
- :success
30
- end
31
-
32
- def token_type
33
- 'bearer'
34
- end
35
-
36
- def headers
37
- { 'Cache-Control' => 'no-store', 'Pragma' => 'no-cache' }
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,246 +0,0 @@
1
- require 'spec_helper_integration'
2
-
3
- module Doorkeeper::OAuth
4
- describe AccessTokenRequest do
5
- let(:client) { FactoryGirl.create(:application) }
6
- let(:grant) { FactoryGirl.create(:access_grant, :application => client) }
7
- let(:params) {
8
- {
9
- :code => grant.token,
10
- :grant_type => "authorization_code",
11
- :redirect_uri => client.redirect_uri
12
- }
13
- }
14
-
15
- describe "with a valid authorization code and client" do
16
- subject { AccessTokenRequest.new(client, params) }
17
-
18
- before { subject.authorize }
19
-
20
- it { should be_valid }
21
- its(:token_type) { should == "bearer" }
22
- its(:error) { should be_nil }
23
- its(:refresh_token) { should be_nil }
24
-
25
- it "has an access token" do
26
- subject.access_token.token.should =~ /\w+/
27
- end
28
- end
29
-
30
- describe "creating the access token" do
31
- subject { AccessTokenRequest.new(client, params) }
32
-
33
- it "creates with correct params" do
34
- Doorkeeper::AccessToken.should_receive(:create!).with({
35
- :application_id => client.id,
36
- :resource_owner_id => grant.resource_owner_id,
37
- :expires_in => 2.hours,
38
- :scopes =>"public write",
39
- :use_refresh_token => false,
40
- })
41
- subject.authorize
42
- end
43
- end
44
-
45
- describe "with a valid authorization code, client and existing valid access token" do
46
- subject { AccessTokenRequest.new(client, params) }
47
-
48
- before { subject.authorize }
49
- it { should be_valid }
50
- its(:error) { should be_nil }
51
-
52
- it "will not create a new token" do
53
- subject.should_not_receive(:create_access_token)
54
- subject.authorize
55
- end
56
- end
57
-
58
- describe "with a valid authorization code, client and existing expired access token" do
59
- before do
60
- AccessTokenRequest.new(client, params).authorize
61
- last_token = Doorkeeper::AccessToken.last
62
- # TODO: make this better, maybe with an expire! method?
63
- last_token.update_column :created_at, 10.days.ago
64
- end
65
-
66
- it "will create a new token" do
67
- grant = FactoryGirl.create(:access_grant, :application => client)
68
- authorization = AccessTokenRequest.new(client, params.merge(:code => grant.token))
69
- expect {
70
- authorization.authorize
71
- }.to change { Doorkeeper::AccessToken.count }.by(1)
72
- end
73
- end
74
-
75
- describe "finding the current access token" do
76
- subject { AccessTokenRequest.new(client, params) }
77
- it { should be_valid }
78
- its(:error) { should be_nil }
79
-
80
- before { subject.authorize }
81
-
82
- it "should find the access token and not create a new one" do
83
- subject.should_not_receive(:create_access_token)
84
- access_token = subject.authorize
85
- subject.access_token.should eq(access_token)
86
- end
87
- end
88
-
89
- describe "creating the first access_token" do
90
- subject { AccessTokenRequest.new(client, params) }
91
- it { should be_valid }
92
- its(:error) { should be_nil }
93
-
94
- it "should create a new access token" do
95
- subject.should_receive(:create_access_token)
96
- subject.authorize
97
- end
98
- end
99
-
100
- describe "with errors" do
101
- def token(params)
102
- AccessTokenRequest.new(client, params)
103
- end
104
-
105
- it "includes the error in the response" do
106
- access_token = token(params.except(:grant_type))
107
- access_token.error_response.name.should == :invalid_request
108
- end
109
-
110
- [:grant_type, :code, :redirect_uri].each do |param|
111
- describe "when :#{param} is missing" do
112
- subject { token(params.except(param)) }
113
- its(:error) { should == :invalid_request }
114
- end
115
- end
116
-
117
- describe "when client is not present" do
118
- subject { AccessTokenRequest.new(nil, params) }
119
- its(:error) { should == :invalid_client }
120
- end
121
-
122
- describe "when :code does not exist" do
123
- subject { token(params.merge(:code => "inexistent")) }
124
- its(:error) { should == :invalid_grant }
125
- end
126
-
127
- describe "when :redirect_uri does not match with grant's one" do
128
- subject { token(params.merge(:redirect_uri => "another")) }
129
- its(:error) { should == :invalid_grant }
130
- end
131
-
132
- describe "when :grant_type is not 'authorization_code'" do
133
- subject { token(params.merge(:grant_type => "invalid")) }
134
- its(:error) { should == :unsupported_grant_type }
135
- end
136
-
137
- describe "when granted application does not match" do
138
- subject { token(params) }
139
-
140
- before do
141
- grant.application = FactoryGirl.create(:application)
142
- grant.save!
143
- end
144
-
145
- its(:error) { should == :invalid_grant }
146
- end
147
-
148
- describe "when :code is expired" do
149
- it "error is :invalid_grant" do
150
- grant # create grant instance
151
- Timecop.freeze(Time.now + 700.seconds) do
152
- expired = token(params)
153
- expired.error.should == :invalid_grant
154
- end
155
- end
156
- end
157
- end
158
- end
159
-
160
- describe AccessTokenRequest, "refresh token" do
161
- let(:client) { FactoryGirl.create(:application) }
162
- let(:access) { FactoryGirl.create(:access_token, :application => client, :use_refresh_token => true) }
163
- let(:params) {
164
- {
165
- :refresh_token => access.refresh_token,
166
- :grant_type => "refresh_token",
167
- }
168
- }
169
-
170
- before do
171
- Doorkeeper.configure {
172
- orm DOORKEEPER_ORM
173
- use_refresh_token
174
- }
175
- end
176
-
177
- describe "with a valid authorization code and client" do
178
- subject { AccessTokenRequest.new(client, params) }
179
-
180
- before do
181
- subject.authorize
182
- end
183
-
184
- it { should be_valid }
185
- its(:token_type) { should == "bearer" }
186
- its(:error) { should be_nil }
187
- its(:refresh_token) { should_not be_nil }
188
-
189
- it "has an access token" do
190
- subject.access_token.token.should =~ /\w+/
191
- end
192
- end
193
-
194
- describe "with errors" do
195
- def token(params)
196
- AccessTokenRequest.new(client, params)
197
- end
198
-
199
- it "includes the error in the response" do
200
- access_token = token(params.except(:grant_type))
201
- access_token.error_response.name.should == :invalid_request
202
- end
203
-
204
- [:grant_type, :refresh_token].each do |param|
205
- describe "when :#{param} is missing" do
206
- subject { token(params.except(param)) }
207
- its(:error) { should == :invalid_request }
208
- end
209
- end
210
-
211
- describe "when client is not present" do
212
- subject { AccessTokenRequest.new(nil, params) }
213
- its(:error) { should == :invalid_client }
214
- end
215
-
216
- describe "when :refresh_token does not exist" do
217
- subject { token(params.merge(:refresh_token => "inexistent")) }
218
- its(:error) { should == :invalid_grant }
219
- end
220
-
221
- describe "when :grant_type is not 'refresh_token'" do
222
- subject { token(params.merge(:grant_type => "invalid")) }
223
- its(:error) { should == :invalid_request }
224
- end
225
-
226
- describe "when granted application does not match" do
227
- subject { token(params) }
228
-
229
- before do
230
- access.application = FactoryGirl.create(:application)
231
- access.save!
232
- end
233
-
234
- its(:error) { should == :invalid_grant }
235
- end
236
-
237
- describe "when :refresh_token is revoked" do
238
- it "error is :invalid_grant" do
239
- access.revoke # create grant instance
240
- revoked = token(params)
241
- revoked.error.should == :invalid_grant
242
- end
243
- end
244
- end
245
- end
246
- end
@@ -1,287 +0,0 @@
1
- require 'spec_helper_integration'
2
-
3
- module Doorkeeper::OAuth
4
- describe AuthorizationRequest do
5
- let(:resource_owner) { double(:resource_owner, :id => 1) }
6
- let(:client) { FactoryGirl.create(:application) }
7
- let(:base_attributes) do
8
- {
9
- :redirect_uri => client.redirect_uri,
10
- :scope => "public write",
11
- :state => "return-this"
12
- }
13
- end
14
-
15
- before :each do
16
- Doorkeeper.configuration.stub(:confirm_application_owner?).and_return(false)
17
- Doorkeeper.configuration.stub(:default_scopes).and_return(Doorkeeper::OAuth::Scopes.from_string('public write'))
18
- end
19
-
20
- describe "with a code response_type" do
21
- let(:attributes) { base_attributes.merge!(:response_type => "code") }
22
-
23
- describe "with valid attributes" do
24
- subject { AuthorizationRequest.new(client, resource_owner, attributes) }
25
-
26
- describe "after authorization" do
27
- before { subject.authorize }
28
-
29
- its(:response_type) { should == "code" }
30
- its(:client_id) { should == client.uid }
31
- its(:scope) { should == "public write" }
32
- its(:state) { should == "return-this" }
33
- its(:error) { should be_nil }
34
-
35
- describe ".success_redirect_uri" do
36
- let(:query) { URI.parse(subject.success_redirect_uri).query }
37
-
38
- it "includes the grant code" do
39
- query.should =~ %r{code=\w+}
40
- end
41
-
42
- it "includes the state previous assumed" do
43
- query.should =~ %r{state=return-this}
44
- end
45
- end
46
- end
47
-
48
- describe :authorize do
49
- let(:authorization_request) { AuthorizationRequest.new(client, resource_owner, attributes) }
50
- subject { authorization_request.authorize }
51
-
52
- it "returns Doorkeeper::AccessGrant object" do
53
- subject.is_a? Doorkeeper::AccessGrant
54
- end
55
-
56
- it "returns instance saved in the database" do
57
- subject.should be_persisted
58
- end
59
-
60
- it "returns object that has scopes attribute same as scope attribute of authorization request" do
61
- subject.scopes == authorization_request.scope
62
- end
63
- end
64
- end
65
-
66
- describe "with a redirect_uri with query params" do
67
- let(:original_query_params) { "abc=123&def=456" }
68
- let(:attributes_with_query_params) {
69
- u = URI.parse(client.redirect_uri)
70
- u.query = original_query_params
71
- attributes[:redirect_uri] = u.to_s
72
- attributes
73
- }
74
- subject { AuthorizationRequest.new(client, resource_owner, attributes_with_query_params) }
75
-
76
- it "preservers the original query when error"
77
-
78
- describe "after authorization" do
79
- before { subject.authorize }
80
-
81
- describe ".success_redirect_uri" do
82
- let(:query) { URI.parse(subject.success_redirect_uri).query }
83
-
84
- it "includes the grant code" do
85
- query.should =~ %r{code=\w+}
86
- end
87
-
88
- it "includes the state previous assumed" do
89
- query.should =~ %r{state=return-this}
90
- end
91
-
92
- it "preserves the original query parameters" do
93
- query.should =~ /abc=123/
94
- query.should =~ /def=456/
95
- end
96
- end
97
- end
98
- end
99
-
100
- describe "if no scope given" do
101
- it "sets the scope to the default one" do
102
- request = AuthorizationRequest.new(client, resource_owner, attributes.except(:scope))
103
- request.scopes.to_s.should == "public write"
104
- end
105
- end
106
-
107
- describe "with errors" do
108
- before do
109
- Doorkeeper::AccessGrant.should_not_receive(:create)
110
- end
111
-
112
- describe "when :response_type is missing" do
113
- subject { auth(attributes.except(:response_type)) }
114
- its(:error) { should == :invalid_request }
115
- end
116
-
117
- describe "when :redirect_uri is missing" do
118
- subject { auth(attributes.except(:redirect_uri)) }
119
- its(:error) { should == :invalid_redirect_uri }
120
- end
121
-
122
- describe "when client is not present" do
123
- subject { AuthorizationRequest.new(nil, resource_owner, attributes) }
124
- its(:error) { should == :invalid_client }
125
- end
126
-
127
- describe "when :redirect_uri mismatches" do
128
- subject { auth(attributes.merge(:redirect_uri => "http://example.com/mismatch")) }
129
- its(:error) { should == :invalid_redirect_uri }
130
- end
131
-
132
- describe "when :redirect_uri contains a fragment" do
133
- subject { auth(attributes.merge(:redirect_uri => (client.redirect_uri + "#abc"))) }
134
- its(:error) { should == :invalid_redirect_uri }
135
- end
136
-
137
- describe "when :redirect_uri is not a valid URI" do
138
- subject { auth(attributes.merge(:redirect_uri => "invalid")) }
139
- its(:error) { should == :invalid_redirect_uri }
140
- end
141
-
142
- describe "when :response_type is not 'code' or 'token'" do
143
- subject { auth(attributes.merge(:response_type => "invalid")) }
144
- its(:error) { should == :unsupported_response_type }
145
- end
146
-
147
- describe "when :scope contains scopes that are note registered in the provider" do
148
- subject { auth(attributes.merge(:scope => "public strange")) }
149
- its(:error) { should == :invalid_scope }
150
- end
151
- end
152
- end
153
-
154
- describe "with a token response_type" do
155
- before do
156
- Doorkeeper.configuration.stub(:access_token_expires_in).and_return(7200)
157
- end
158
-
159
- let(:attributes) { base_attributes.merge!(:response_type => "token") }
160
-
161
- describe "with valid attributes" do
162
- subject { AuthorizationRequest.new(client, resource_owner, attributes) }
163
-
164
- describe "after authorization" do
165
- before { subject.authorize }
166
-
167
- its(:response_type) { should == "token" }
168
- its(:scope) { should == "public write" }
169
- its(:state) { should == "return-this" }
170
- its(:error) { should be_nil }
171
-
172
- describe ".success_redirect_uri" do
173
- let(:fragment) { URI.parse(subject.success_redirect_uri).fragment }
174
-
175
- it "has a fragment" do
176
- fragment.should_not be_nil
177
- end
178
-
179
- it "doesn't have query parameters" do
180
- URI.parse(subject.success_redirect_uri).query.should be_nil
181
- end
182
-
183
- it "includes the access token" do
184
- fragment.should =~ %r{access_token=\w+}
185
- end
186
-
187
- it "includes the token type" do
188
- fragment.should =~ %r{token_type=bearer}
189
- end
190
-
191
- it "includes the expires in" do
192
- fragment.should =~ %r{expires_in=\w+}
193
- end
194
-
195
- it "includes the state previous assumed" do
196
- fragment.should =~ %r{state=return-this}
197
- end
198
- end
199
- end
200
-
201
- describe :authorize do
202
- let(:authorization_request) { AuthorizationRequest.new(client, resource_owner, attributes) }
203
- subject { authorization_request.authorize }
204
-
205
- it "returns Doorkeeper::AccessGrant object" do
206
- subject.is_a? Doorkeeper::AccessGrant
207
- end
208
-
209
- it "returns instance saved in the database" do
210
- subject.should be_persisted
211
- end
212
-
213
- it "returns object that has scopes attribute same as scope attribute of authorization request" do
214
- subject.scopes == authorization_request.scope
215
- end
216
- end
217
- end
218
-
219
- describe "if no scope given" do
220
- it "sets the scope to the default one" do
221
- request = AuthorizationRequest.new(client, resource_owner, attributes.except(:scope))
222
- request.scopes.to_s.should == "public write"
223
- end
224
- end
225
-
226
- describe "with errors" do
227
- before do
228
- Doorkeeper::AccessGrant.should_not_receive(:create)
229
- end
230
-
231
- describe "when :response_type is missing" do
232
- subject { auth(attributes.except(:response_type)) }
233
- its(:error) { should == :invalid_request }
234
- end
235
-
236
- describe "when :redirect_uri is missing" do
237
- subject { auth(attributes.except(:redirect_uri)) }
238
- its(:error) { should == :invalid_redirect_uri }
239
- end
240
-
241
- describe "when client is not present" do
242
- subject { AuthorizationRequest.new(nil, resource_owner, attributes) }
243
- its(:error) { should == :invalid_client }
244
- end
245
-
246
- describe "when :redirect_uri has a fragment" do
247
- subject { auth(attributes.merge(:redirect_uri => client.redirect_uri + "#xyz")) }
248
- its(:error) { should == :invalid_redirect_uri }
249
- end
250
-
251
- describe "when :redirect_uri is a relative URI" do
252
- subject { auth(attributes.merge(:redirect_uri => "/abcdef")) }
253
- its(:error) { should == :invalid_redirect_uri }
254
- end
255
-
256
- describe "when :redirect_uri mismatches" do
257
- subject { auth(attributes.merge(:redirect_uri => "http://example.com/mismatch")) }
258
- its(:error) { should == :invalid_redirect_uri }
259
- end
260
-
261
- describe "when :redirect_uri contains a fragment" do
262
- subject { auth(attributes.merge(:redirect_uri => (client.redirect_uri + "#abc"))) }
263
- its(:error) { should == :invalid_redirect_uri }
264
- end
265
-
266
- describe "when :redirect_uri is not a valid URI" do
267
- subject { auth(attributes.merge(:redirect_uri => "invalid")) }
268
- its(:error) { should == :invalid_redirect_uri }
269
- end
270
-
271
- describe "when :response_type is not 'code' or 'token'" do
272
- subject { auth(attributes.merge(:response_type => "invalid")) }
273
- its(:error) { should == :unsupported_response_type }
274
- end
275
-
276
- describe "when :scope contains scopes that are note registered in the provider" do
277
- subject { auth(attributes.merge(:scope => "public strange")) }
278
- its(:error) { should == :invalid_scope }
279
- end
280
- end
281
- end
282
-
283
- def auth(attributes)
284
- AuthorizationRequest.new(client, resource_owner, attributes)
285
- end
286
- end
287
- end