couchkeeper 0.6.7
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 +14 -0
- data/.rspec +1 -0
- data/.travis.yml +28 -0
- data/CHANGELOG.md +198 -0
- data/Gemfile +32 -0
- data/MIT-LICENSE +20 -0
- data/README.md +290 -0
- data/Rakefile +18 -0
- data/app/assets/javascripts/doorkeeper/application.js +2 -0
- data/app/assets/stylesheets/doorkeeper/application.css +18 -0
- data/app/assets/stylesheets/doorkeeper/form.css +13 -0
- data/app/controllers/doorkeeper/application_controller.rb +7 -0
- data/app/controllers/doorkeeper/applications_controller.rb +60 -0
- data/app/controllers/doorkeeper/authorizations_controller.rb +57 -0
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +12 -0
- data/app/controllers/doorkeeper/token_info_controller.rb +12 -0
- data/app/controllers/doorkeeper/tokens_controller.rb +20 -0
- data/app/helpers/doorkeeper/form_errors_helper.rb +9 -0
- data/app/validators/redirect_uri_validator.rb +23 -0
- data/app/views/doorkeeper/applications/_form.html.erb +34 -0
- data/app/views/doorkeeper/applications/edit.html.erb +13 -0
- data/app/views/doorkeeper/applications/index.html.erb +29 -0
- data/app/views/doorkeeper/applications/new.html.erb +13 -0
- data/app/views/doorkeeper/applications/show.html.erb +26 -0
- data/app/views/doorkeeper/authorizations/error.html.erb +6 -0
- data/app/views/doorkeeper/authorizations/new.html.erb +37 -0
- data/app/views/doorkeeper/authorizations/show.html.erb +4 -0
- data/app/views/doorkeeper/authorized_applications/index.html.erb +25 -0
- data/app/views/layouts/doorkeeper/application.html.erb +33 -0
- data/config/locales/en.yml +68 -0
- data/doorkeeper.gemspec +28 -0
- data/lib/doorkeeper.rb +64 -0
- data/lib/doorkeeper/config.rb +194 -0
- data/lib/doorkeeper/doorkeeper_for.rb +76 -0
- data/lib/doorkeeper/engine.rb +19 -0
- data/lib/doorkeeper/errors.rb +15 -0
- data/lib/doorkeeper/helpers/controller.rb +58 -0
- data/lib/doorkeeper/helpers/filter.rb +38 -0
- data/lib/doorkeeper/models/access_grant.rb +24 -0
- data/lib/doorkeeper/models/access_token.rb +95 -0
- data/lib/doorkeeper/models/accessible.rb +9 -0
- data/lib/doorkeeper/models/active_record/access_grant.rb +5 -0
- data/lib/doorkeeper/models/active_record/access_token.rb +21 -0
- data/lib/doorkeeper/models/active_record/application.rb +20 -0
- data/lib/doorkeeper/models/application.rb +33 -0
- data/lib/doorkeeper/models/couchbase/access_grant.rb +10 -0
- data/lib/doorkeeper/models/couchbase/access_token.rb +7 -0
- data/lib/doorkeeper/models/couchbase/application.rb +35 -0
- data/lib/doorkeeper/models/doorkeeper_access_grant/by_token/map.js +5 -0
- data/lib/doorkeeper/models/doorkeeper_access_token/by_application_id/map.js +5 -0
- data/lib/doorkeeper/models/doorkeeper_access_token/by_application_id_and_resource_owner_id/map.js +5 -0
- data/lib/doorkeeper/models/doorkeeper_access_token/by_refresh_token/map.js +5 -0
- data/lib/doorkeeper/models/doorkeeper_access_token/by_resource_owner_id/map.js +5 -0
- data/lib/doorkeeper/models/doorkeeper_access_token/by_token/map.js +5 -0
- data/lib/doorkeeper/models/doorkeeper_application/by_uid/map.js +5 -0
- data/lib/doorkeeper/models/doorkeeper_application/by_uid_and_secret/map.js +5 -0
- data/lib/doorkeeper/models/doorkeeper_application/show_all/map.js +6 -0
- data/lib/doorkeeper/models/expirable.rb +21 -0
- data/lib/doorkeeper/models/mongo_mapper/access_grant.rb +28 -0
- data/lib/doorkeeper/models/mongo_mapper/access_token.rb +51 -0
- data/lib/doorkeeper/models/mongo_mapper/application.rb +30 -0
- data/lib/doorkeeper/models/mongo_mapper/revocable.rb +15 -0
- data/lib/doorkeeper/models/mongoid/revocable.rb +15 -0
- data/lib/doorkeeper/models/mongoid/scopes.rb +15 -0
- data/lib/doorkeeper/models/mongoid2/access_grant.rb +22 -0
- data/lib/doorkeeper/models/mongoid2/access_token.rb +41 -0
- data/lib/doorkeeper/models/mongoid2/application.rb +22 -0
- data/lib/doorkeeper/models/mongoid3/access_grant.rb +22 -0
- data/lib/doorkeeper/models/mongoid3/access_token.rb +41 -0
- data/lib/doorkeeper/models/mongoid3/application.rb +22 -0
- data/lib/doorkeeper/models/ownership.rb +16 -0
- data/lib/doorkeeper/models/scopes.rb +17 -0
- data/lib/doorkeeper/oauth/authorization.rb +10 -0
- data/lib/doorkeeper/oauth/authorization/code.rb +32 -0
- data/lib/doorkeeper/oauth/authorization/token.rb +28 -0
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +29 -0
- data/lib/doorkeeper/oauth/authorization_code_request.rb +82 -0
- data/lib/doorkeeper/oauth/client.rb +29 -0
- data/lib/doorkeeper/oauth/client/credentials.rb +21 -0
- data/lib/doorkeeper/oauth/client/methods.rb +18 -0
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +29 -0
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +35 -0
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +33 -0
- data/lib/doorkeeper/oauth/client_credentials_request.rb +47 -0
- data/lib/doorkeeper/oauth/code_request.rb +28 -0
- data/lib/doorkeeper/oauth/code_response.rb +37 -0
- data/lib/doorkeeper/oauth/error.rb +9 -0
- data/lib/doorkeeper/oauth/error_response.rb +44 -0
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +18 -0
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +13 -0
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +32 -0
- data/lib/doorkeeper/oauth/password_access_token_request.rb +84 -0
- data/lib/doorkeeper/oauth/pre_authorization.rb +62 -0
- data/lib/doorkeeper/oauth/refresh_token_request.rb +58 -0
- data/lib/doorkeeper/oauth/scopes.rb +60 -0
- data/lib/doorkeeper/oauth/token.rb +36 -0
- data/lib/doorkeeper/oauth/token_request.rb +28 -0
- data/lib/doorkeeper/oauth/token_response.rb +29 -0
- data/lib/doorkeeper/rails/routes.rb +90 -0
- data/lib/doorkeeper/rails/routes/mapper.rb +28 -0
- data/lib/doorkeeper/rails/routes/mapping.rb +39 -0
- data/lib/doorkeeper/request.rb +33 -0
- data/lib/doorkeeper/request/authorization_code.rb +23 -0
- data/lib/doorkeeper/request/client_credentials.rb +23 -0
- data/lib/doorkeeper/request/code.rb +24 -0
- data/lib/doorkeeper/request/password.rb +23 -0
- data/lib/doorkeeper/request/refresh_token.rb +23 -0
- data/lib/doorkeeper/request/token.rb +24 -0
- data/lib/doorkeeper/server.rb +54 -0
- data/lib/doorkeeper/validations.rb +30 -0
- data/lib/doorkeeper/version.rb +3 -0
- data/lib/generators/doorkeeper/application_owner_generator.rb +15 -0
- data/lib/generators/doorkeeper/install_generator.rb +12 -0
- data/lib/generators/doorkeeper/migration_generator.rb +15 -0
- data/lib/generators/doorkeeper/mongo_mapper/indexes_generator.rb +12 -0
- data/lib/generators/doorkeeper/templates/README +44 -0
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb +7 -0
- data/lib/generators/doorkeeper/templates/indexes.rb +3 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +67 -0
- data/lib/generators/doorkeeper/templates/migration.rb +42 -0
- data/lib/generators/doorkeeper/views_generator.rb +15 -0
- data/script/rails +6 -0
- data/script/run_all +14 -0
- data/spec/controllers/applications_controller_spec.rb +18 -0
- data/spec/controllers/authorizations_controller_spec.rb +154 -0
- data/spec/controllers/protected_resources_controller_spec.rb +304 -0
- data/spec/controllers/token_info_controller_spec.rb +54 -0
- data/spec/controllers/tokens_controller_spec.rb +36 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +9 -0
- data/spec/dummy/app/assets/stylesheets/application.css +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +7 -0
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +12 -0
- data/spec/dummy/app/controllers/home_controller.rb +17 -0
- data/spec/dummy/app/controllers/metal_controller.rb +11 -0
- data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +11 -0
- data/spec/dummy/app/helpers/application_helper.rb +5 -0
- data/spec/dummy/app/models/user.rb +27 -0
- data/spec/dummy/app/views/home/index.html.erb +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +16 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +54 -0
- data/spec/dummy/config/boot.rb +6 -0
- data/spec/dummy/config/database.yml +15 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +30 -0
- data/spec/dummy/config/environments/production.rb +60 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/doorkeeper.rb +56 -0
- data/spec/dummy/config/initializers/secret_token.rb +9 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/doorkeeper.en.yml +5 -0
- data/spec/dummy/config/mongo.yml +11 -0
- data/spec/dummy/config/mongoid2.yml +9 -0
- data/spec/dummy/config/mongoid3.yml +18 -0
- data/spec/dummy/config/routes.rb +38 -0
- data/spec/dummy/db/migrate/20111122132257_create_users.rb +9 -0
- data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +5 -0
- data/spec/dummy/db/migrate/20120524202412_create_doorkeeper_tables.rb +44 -0
- data/spec/dummy/db/schema.rb +64 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/factories/access_grant.rb +9 -0
- data/spec/factories/access_token.rb +7 -0
- data/spec/factories/application.rb +6 -0
- data/spec/generators/application_owner_generator_spec.rb +23 -0
- data/spec/generators/install_generator_spec.rb +31 -0
- data/spec/generators/migration_generator_spec.rb +20 -0
- data/spec/generators/templates/routes.rb +3 -0
- data/spec/generators/views_generator_spec.rb +27 -0
- data/spec/lib/config_spec.rb +170 -0
- data/spec/lib/models/expirable_spec.rb +51 -0
- data/spec/lib/models/revocable_spec.rb +31 -0
- data/spec/lib/models/scopes_spec.rb +32 -0
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +37 -0
- data/spec/lib/oauth/authorization_code_request_spec.rb +80 -0
- data/spec/lib/oauth/client/credentials_spec.rb +47 -0
- data/spec/lib/oauth/client/methods_spec.rb +54 -0
- data/spec/lib/oauth/client_credentials/creator_spec.rb +47 -0
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +57 -0
- data/spec/lib/oauth/client_credentials/validation_spec.rb +29 -0
- data/spec/lib/oauth/client_credentials_integration_spec.rb +27 -0
- data/spec/lib/oauth/client_credentials_request_spec.rb +64 -0
- data/spec/lib/oauth/client_spec.rb +39 -0
- data/spec/lib/oauth/code_request_spec.rb +44 -0
- data/spec/lib/oauth/error_response_spec.rb +40 -0
- data/spec/lib/oauth/error_spec.rb +19 -0
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +74 -0
- data/spec/lib/oauth/helpers/unique_token_spec.rb +20 -0
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +64 -0
- data/spec/lib/oauth/password_access_token_request_spec.rb +65 -0
- data/spec/lib/oauth/pre_authorization_spec.rb +80 -0
- data/spec/lib/oauth/refresh_token_request_spec.rb +56 -0
- data/spec/lib/oauth/scopes_spec.rb +115 -0
- data/spec/lib/oauth/token_request_spec.rb +46 -0
- data/spec/lib/oauth/token_response_spec.rb +52 -0
- data/spec/lib/oauth/token_spec.rb +83 -0
- data/spec/lib/server_spec.rb +24 -0
- data/spec/models/doorkeeper/access_grant_spec.rb +36 -0
- data/spec/models/doorkeeper/access_token_spec.rb +153 -0
- data/spec/models/doorkeeper/application_spec.rb +162 -0
- data/spec/requests/applications/applications_request_spec.rb +92 -0
- data/spec/requests/applications/authorized_applications_spec.rb +30 -0
- data/spec/requests/endpoints/authorization_spec.rb +47 -0
- data/spec/requests/endpoints/token_spec.rb +46 -0
- data/spec/requests/flows/authorization_code_errors_spec.rb +66 -0
- data/spec/requests/flows/authorization_code_spec.rb +135 -0
- data/spec/requests/flows/client_credentials_spec.rb +58 -0
- data/spec/requests/flows/implicit_grant_errors_spec.rb +31 -0
- data/spec/requests/flows/implicit_grant_spec.rb +19 -0
- data/spec/requests/flows/password_spec.rb +78 -0
- data/spec/requests/flows/refresh_token_spec.rb +71 -0
- data/spec/requests/flows/skip_authorization_spec.rb +40 -0
- data/spec/requests/protected_resources/metal_spec.rb +14 -0
- data/spec/requests/protected_resources/private_api_spec.rb +50 -0
- data/spec/routing/custom_controller_routes_spec.rb +44 -0
- data/spec/routing/default_routes_spec.rb +32 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/spec_helper_integration.rb +40 -0
- data/spec/support/dependencies/factory_girl.rb +2 -0
- data/spec/support/helpers/access_token_request_helper.rb +11 -0
- data/spec/support/helpers/authorization_request_helper.rb +32 -0
- data/spec/support/helpers/config_helper.rb +9 -0
- data/spec/support/helpers/model_helper.rb +45 -0
- data/spec/support/helpers/request_spec_helper.rb +72 -0
- data/spec/support/helpers/url_helper.rb +51 -0
- data/spec/support/orm/active_record.rb +11 -0
- data/spec/support/orm/mongo_mapper.rb +26 -0
- data/spec/support/orm/mongoid.rb +31 -0
- data/spec/support/shared/controllers_shared_context.rb +60 -0
- data/spec/support/shared/models_shared_examples.rb +60 -0
- data/spec/validators/redirect_uri_validator_spec.rb +47 -0
- data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +356 -0
- metadata +430 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper_integration'
|
2
|
+
|
3
|
+
feature 'Adding applications' do
|
4
|
+
context 'in application form' do
|
5
|
+
background do
|
6
|
+
visit '/oauth/applications/new'
|
7
|
+
end
|
8
|
+
|
9
|
+
scenario 'adding a valid app' do
|
10
|
+
fill_in 'Name', :with => 'My Application'
|
11
|
+
fill_in 'Redirect uri', :with => 'http://example.com'
|
12
|
+
click_button 'Submit'
|
13
|
+
i_should_see 'Application created'
|
14
|
+
i_should_see 'My Application'
|
15
|
+
end
|
16
|
+
|
17
|
+
scenario 'adding invalid app' do
|
18
|
+
click_button 'Submit'
|
19
|
+
i_should_see 'Whoops! Check your form for possible errors'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
feature 'Listing applications' do
|
25
|
+
background do
|
26
|
+
FactoryGirl.create :application, :name => 'Oauth Dude'
|
27
|
+
FactoryGirl.create :application, :name => 'Awesome App'
|
28
|
+
end
|
29
|
+
|
30
|
+
scenario 'application list' do
|
31
|
+
visit '/oauth/applications'
|
32
|
+
i_should_see 'Awesome App'
|
33
|
+
i_should_see 'Oauth Dude'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
feature 'Show application' do
|
38
|
+
let :app do
|
39
|
+
FactoryGirl.create :application, :name => 'Just another oauth app'
|
40
|
+
end
|
41
|
+
|
42
|
+
scenario 'visiting application page' do
|
43
|
+
visit "/oauth/applications/#{app.id}"
|
44
|
+
i_should_see 'Just another oauth app'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
feature 'Edit application' do
|
49
|
+
let :app do
|
50
|
+
FactoryGirl.create :application, :name => 'OMG my app'
|
51
|
+
end
|
52
|
+
|
53
|
+
background do
|
54
|
+
visit "/oauth/applications/#{app.id}/edit"
|
55
|
+
end
|
56
|
+
|
57
|
+
scenario 'updating a valid app' do
|
58
|
+
fill_in :name, :with => "Serious app"
|
59
|
+
click_button 'Submit'
|
60
|
+
i_should_see "Application updated"
|
61
|
+
i_should_see "Serious app"
|
62
|
+
i_should_not_see "OMG my app"
|
63
|
+
end
|
64
|
+
|
65
|
+
scenario 'updating an invalid app' do
|
66
|
+
fill_in :name, :with => ""
|
67
|
+
click_button 'Submit'
|
68
|
+
i_should_see 'Whoops! Check your form for possible errors'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
feature 'Destroy application' do
|
73
|
+
background do
|
74
|
+
@app = FactoryGirl.create :application
|
75
|
+
end
|
76
|
+
|
77
|
+
scenario 'deleting an application from list' do
|
78
|
+
visit "/oauth/applications"
|
79
|
+
i_should_see @app.name
|
80
|
+
within(:css, "tr#application_#{@app.id}") do
|
81
|
+
click_link "Destroy"
|
82
|
+
end
|
83
|
+
i_should_see "Application deleted"
|
84
|
+
i_should_not_see @app.name
|
85
|
+
end
|
86
|
+
|
87
|
+
scenario 'deleting an application from show' do
|
88
|
+
visit "/oauth/applications/#{@app.id}"
|
89
|
+
click_link 'Remove'
|
90
|
+
i_should_see "Application deleted"
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper_integration'
|
2
|
+
|
3
|
+
feature 'Authorized applications' do
|
4
|
+
background do
|
5
|
+
@user = User.create!(:name => "Joe", :password => "sekret")
|
6
|
+
@client = client_exists(:name => "Amazing Client App")
|
7
|
+
resource_owner_is_authenticated @user
|
8
|
+
client_is_authorized @client, @user
|
9
|
+
end
|
10
|
+
|
11
|
+
scenario "display user's authorized applications" do
|
12
|
+
visit '/oauth/authorized_applications'
|
13
|
+
i_should_see 'Amazing Client App'
|
14
|
+
end
|
15
|
+
|
16
|
+
scenario "do not display other user's authorized applications" do
|
17
|
+
client = client_exists(:name => "Another Client App")
|
18
|
+
client_is_authorized client, User.create!(:name => "Joe", :password => "sekret")
|
19
|
+
visit '/oauth/authorized_applications'
|
20
|
+
i_should_not_see 'Another Client App'
|
21
|
+
end
|
22
|
+
|
23
|
+
scenario "user revoke access to application" do
|
24
|
+
visit '/oauth/authorized_applications'
|
25
|
+
i_should_see 'Amazing Client App'
|
26
|
+
click_on 'Revoke'
|
27
|
+
i_should_see 'Application revoked'
|
28
|
+
i_should_not_see 'Amazing Client App'
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper_integration'
|
2
|
+
|
3
|
+
feature 'Authorization endpoint' do
|
4
|
+
background do
|
5
|
+
config_is_set(:authenticate_resource_owner) { User.first || redirect_to('/sign_in') }
|
6
|
+
client_exists(:name => "MyApp")
|
7
|
+
end
|
8
|
+
|
9
|
+
scenario 'requires resource owner to be authenticated' do
|
10
|
+
visit authorization_endpoint_url(:client => @client)
|
11
|
+
i_should_see "Sign in"
|
12
|
+
i_should_be_on "/"
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'with authenticated resource owner' do
|
16
|
+
background do
|
17
|
+
create_resource_owner
|
18
|
+
sign_in
|
19
|
+
end
|
20
|
+
|
21
|
+
scenario 'displays the authorization form' do
|
22
|
+
visit authorization_endpoint_url(:client => @client)
|
23
|
+
i_should_see "Authorize MyApp to use your account?"
|
24
|
+
end
|
25
|
+
|
26
|
+
scenario "displays all requested scopes" do
|
27
|
+
default_scopes_exist :public
|
28
|
+
optional_scopes_exist :write
|
29
|
+
visit authorization_endpoint_url(:client => @client, :scope => "public write")
|
30
|
+
i_should_see "Access your public data"
|
31
|
+
i_should_see "Update your data"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'with a invalid request' do
|
36
|
+
background do
|
37
|
+
create_resource_owner
|
38
|
+
sign_in
|
39
|
+
end
|
40
|
+
|
41
|
+
scenario "displays the related error" do
|
42
|
+
visit authorization_endpoint_url(:client => @client, :response_type => "")
|
43
|
+
i_should_not_see "Authorize"
|
44
|
+
i_should_see_translated_error_message :unsupported_response_type
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper_integration'
|
2
|
+
|
3
|
+
feature 'Token endpoint' do
|
4
|
+
background do
|
5
|
+
client_exists
|
6
|
+
authorization_code_exists :application => @client, :scopes => "public"
|
7
|
+
end
|
8
|
+
|
9
|
+
scenario 'respond with correct headers' do
|
10
|
+
post token_endpoint_url(:code => @authorization.token, :client => @client)
|
11
|
+
should_have_header 'Pragma', 'no-cache'
|
12
|
+
should_have_header 'Cache-Control', 'no-store'
|
13
|
+
should_have_header 'Content-Type', 'application/json; charset=utf-8'
|
14
|
+
end
|
15
|
+
|
16
|
+
scenario 'accepts client credentials with basic auth header' do
|
17
|
+
post token_endpoint_url(:code => @authorization.token, :redirect_uri => @client.redirect_uri),
|
18
|
+
{} ,
|
19
|
+
{ 'HTTP_AUTHORIZATION' => basic_auth_header_for_client(@client) }
|
20
|
+
|
21
|
+
should_have_json 'access_token', Doorkeeper::AccessToken.first.token
|
22
|
+
end
|
23
|
+
|
24
|
+
scenario 'returns null for expires_in when a permanent token is set' do
|
25
|
+
config_is_set(:access_token_expires_in, nil)
|
26
|
+
post token_endpoint_url(:code => @authorization.token, :client => @client)
|
27
|
+
should_have_json 'access_token', Doorkeeper::AccessToken.first.token
|
28
|
+
should_have_json 'expires_in', nil
|
29
|
+
end
|
30
|
+
|
31
|
+
scenario 'returns unsupported_grant_type for invalid grant_type param' do
|
32
|
+
post token_endpoint_url(:code => @authorization.token, :client => @client, :grant_type => 'nothing')
|
33
|
+
|
34
|
+
should_not_have_json 'access_token'
|
35
|
+
should_have_json 'error', 'unsupported_grant_type'
|
36
|
+
should_have_json 'error_description', translated_error_message('unsupported_grant_type')
|
37
|
+
end
|
38
|
+
|
39
|
+
scenario 'returns invalid_request if grant_type is missing' do
|
40
|
+
post token_endpoint_url(:code => @authorization.token, :client => @client, :grant_type => '')
|
41
|
+
|
42
|
+
should_not_have_json 'access_token'
|
43
|
+
should_have_json 'error', 'invalid_request'
|
44
|
+
should_have_json 'error_description', translated_error_message('invalid_request')
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper_integration'
|
2
|
+
|
3
|
+
feature 'Authorization Code Flow Errors' do
|
4
|
+
background do
|
5
|
+
config_is_set(:authenticate_resource_owner) { User.first || redirect_to('/sign_in') }
|
6
|
+
client_exists
|
7
|
+
create_resource_owner
|
8
|
+
sign_in
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
access_grant_should_not_exist
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when access was denied' do
|
16
|
+
scenario 'redirects with error' do
|
17
|
+
visit authorization_endpoint_url(:client => @client)
|
18
|
+
click_on "Deny"
|
19
|
+
|
20
|
+
i_should_be_on_client_callback @client
|
21
|
+
url_should_not_have_param "code"
|
22
|
+
url_should_have_param "error", "access_denied"
|
23
|
+
url_should_have_param "error_description", translated_error_message(:access_denied)
|
24
|
+
end
|
25
|
+
|
26
|
+
scenario 'redirects with state parameter' do
|
27
|
+
visit authorization_endpoint_url(:client => @client, :state => "return-this")
|
28
|
+
click_on "Deny"
|
29
|
+
|
30
|
+
i_should_be_on_client_callback @client
|
31
|
+
url_should_not_have_param "code"
|
32
|
+
url_should_have_param "state", "return-this"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
feature 'Authorization Code Flow Errors', 'after authorization' do
|
38
|
+
background do
|
39
|
+
client_exists
|
40
|
+
authorization_code_exists :application => @client
|
41
|
+
end
|
42
|
+
|
43
|
+
scenario "returns :invalid_grant error when posting an already revoked grant code" do
|
44
|
+
# First successful request
|
45
|
+
post token_endpoint_url(:code => @authorization.token, :client => @client)
|
46
|
+
|
47
|
+
# Second attempt with same token
|
48
|
+
expect {
|
49
|
+
post token_endpoint_url(:code => @authorization.token, :client => @client)
|
50
|
+
}.to_not change { Doorkeeper::AccessToken.count }
|
51
|
+
|
52
|
+
should_not_have_json 'access_token'
|
53
|
+
should_have_json 'error', 'invalid_grant'
|
54
|
+
should_have_json 'error_description', translated_error_message('invalid_grant')
|
55
|
+
end
|
56
|
+
|
57
|
+
scenario "returns :invalid_grant error for invalid grant code" do
|
58
|
+
post token_endpoint_url(:code => "invalid", :client => @client)
|
59
|
+
|
60
|
+
access_token_should_not_exist
|
61
|
+
|
62
|
+
should_not_have_json 'access_token'
|
63
|
+
should_have_json 'error', 'invalid_grant'
|
64
|
+
should_have_json 'error_description', translated_error_message('invalid_grant')
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'spec_helper_integration'
|
2
|
+
|
3
|
+
feature 'Authorization Code Flow' do
|
4
|
+
background do
|
5
|
+
config_is_set(:authenticate_resource_owner) { User.first || redirect_to('/sign_in') }
|
6
|
+
client_exists
|
7
|
+
create_resource_owner
|
8
|
+
sign_in
|
9
|
+
end
|
10
|
+
|
11
|
+
scenario 'resource owner authorizes the client' do
|
12
|
+
visit authorization_endpoint_url(:client => @client)
|
13
|
+
click_on "Authorize"
|
14
|
+
|
15
|
+
access_grant_should_exist_for(@client, @resource_owner)
|
16
|
+
|
17
|
+
i_should_be_on_client_callback(@client)
|
18
|
+
|
19
|
+
url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
|
20
|
+
url_should_not_have_param("state")
|
21
|
+
url_should_not_have_param("error")
|
22
|
+
end
|
23
|
+
|
24
|
+
scenario 'resource owner authorizes using test url' do
|
25
|
+
@client.redirect_uri = Doorkeeper.configuration.test_redirect_uri
|
26
|
+
@client.save!
|
27
|
+
visit authorization_endpoint_url(:client => @client)
|
28
|
+
click_on "Authorize"
|
29
|
+
|
30
|
+
access_grant_should_exist_for(@client, @resource_owner)
|
31
|
+
|
32
|
+
i_should_see 'Authorization code:'
|
33
|
+
i_should_see Doorkeeper::AccessGrant.first.token
|
34
|
+
end
|
35
|
+
|
36
|
+
scenario 'resource owner authorizes the client with state parameter set' do
|
37
|
+
visit authorization_endpoint_url(:client => @client, :state => "return-me")
|
38
|
+
click_on "Authorize"
|
39
|
+
url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
|
40
|
+
url_should_have_param("state", "return-me")
|
41
|
+
end
|
42
|
+
|
43
|
+
scenario 'returns the same token if it is still accessible' do
|
44
|
+
client_is_authorized(@client, @resource_owner)
|
45
|
+
visit authorization_endpoint_url(:client => @client)
|
46
|
+
|
47
|
+
authorization_code = Doorkeeper::AccessGrant.first.token
|
48
|
+
post token_endpoint_url(:code => authorization_code, :client => @client)
|
49
|
+
|
50
|
+
Doorkeeper::AccessToken.count.should be(1)
|
51
|
+
|
52
|
+
should_have_json 'access_token', Doorkeeper::AccessToken.first.token
|
53
|
+
end
|
54
|
+
|
55
|
+
scenario 'revokes and return new token if it is has expired' do
|
56
|
+
client_is_authorized(@client, @resource_owner)
|
57
|
+
token = Doorkeeper::AccessToken.first
|
58
|
+
token.update_column :expires_in, -100
|
59
|
+
visit authorization_endpoint_url(:client => @client)
|
60
|
+
|
61
|
+
authorization_code = Doorkeeper::AccessGrant.first.token
|
62
|
+
post token_endpoint_url(:code => authorization_code, :client => @client)
|
63
|
+
|
64
|
+
token.reload.should be_revoked
|
65
|
+
Doorkeeper::AccessToken.count.should be(2)
|
66
|
+
|
67
|
+
should_have_json 'access_token', Doorkeeper::AccessToken.last.token
|
68
|
+
end
|
69
|
+
|
70
|
+
scenario 'resource owner requests an access token with authorization code' do
|
71
|
+
visit authorization_endpoint_url(:client => @client)
|
72
|
+
click_on "Authorize"
|
73
|
+
|
74
|
+
authorization_code = Doorkeeper::AccessGrant.first.token
|
75
|
+
post token_endpoint_url(:code => authorization_code, :client => @client)
|
76
|
+
|
77
|
+
access_token_should_exist_for(@client, @resource_owner)
|
78
|
+
|
79
|
+
should_not_have_json 'error'
|
80
|
+
|
81
|
+
should_have_json 'access_token', Doorkeeper::AccessToken.first.token
|
82
|
+
should_have_json 'token_type', "bearer"
|
83
|
+
should_have_json 'expires_in', Doorkeeper::AccessToken.first.expires_in
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'with scopes' do
|
87
|
+
background do
|
88
|
+
default_scopes_exist :public
|
89
|
+
optional_scopes_exist :write
|
90
|
+
end
|
91
|
+
|
92
|
+
scenario 'resource owner authorizes the client with default scopes' do
|
93
|
+
visit authorization_endpoint_url(:client => @client)
|
94
|
+
click_on "Authorize"
|
95
|
+
access_grant_should_exist_for(@client, @resource_owner)
|
96
|
+
access_grant_should_have_scopes :public
|
97
|
+
end
|
98
|
+
|
99
|
+
scenario 'resource owner authorizes the client with required scopes' do
|
100
|
+
visit authorization_endpoint_url(:client => @client, :scope => "public write")
|
101
|
+
click_on "Authorize"
|
102
|
+
access_grant_should_have_scopes :public, :write
|
103
|
+
end
|
104
|
+
|
105
|
+
scenario 'resource owner authorizes the client with required scopes (without defaults)' do
|
106
|
+
visit authorization_endpoint_url(:client => @client, :scope => "write")
|
107
|
+
click_on "Authorize"
|
108
|
+
access_grant_should_have_scopes :write
|
109
|
+
end
|
110
|
+
|
111
|
+
scenario 'new access token matches required scopes' do
|
112
|
+
visit authorization_endpoint_url(:client => @client, :scope => "public write")
|
113
|
+
click_on "Authorize"
|
114
|
+
|
115
|
+
authorization_code = Doorkeeper::AccessGrant.first.token
|
116
|
+
post token_endpoint_url(:code => authorization_code, :client => @client)
|
117
|
+
|
118
|
+
access_token_should_exist_for(@client, @resource_owner)
|
119
|
+
access_token_should_have_scopes :public, :write
|
120
|
+
end
|
121
|
+
|
122
|
+
scenario 'returns new token if scopes have changed' do
|
123
|
+
client_is_authorized(@client, @resource_owner, :scopes => "public write")
|
124
|
+
visit authorization_endpoint_url(:client => @client, :scope => "public")
|
125
|
+
click_on "Authorize"
|
126
|
+
|
127
|
+
authorization_code = Doorkeeper::AccessGrant.first.token
|
128
|
+
post token_endpoint_url(:code => authorization_code, :client => @client)
|
129
|
+
|
130
|
+
Doorkeeper::AccessToken.count.should be(2)
|
131
|
+
|
132
|
+
should_have_json 'access_token', Doorkeeper::AccessToken.last.token
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper_integration'
|
2
|
+
|
3
|
+
describe 'Client Credentials Request' do
|
4
|
+
let(:client) { FactoryGirl.create :application }
|
5
|
+
|
6
|
+
context 'a valid request' do
|
7
|
+
it 'authorizes the client and returns the token response' do
|
8
|
+
headers = authorization client.uid, client.secret
|
9
|
+
params = { :grant_type => 'client_credentials' }
|
10
|
+
|
11
|
+
post '/oauth/token', params, headers
|
12
|
+
|
13
|
+
should_have_json 'access_token', Doorkeeper::AccessToken.first.token
|
14
|
+
should_have_json 'expires_in', Doorkeeper.configuration.access_token_expires_in
|
15
|
+
should_have_json 'scope', ''
|
16
|
+
should_have_json 'refresh_token', nil
|
17
|
+
|
18
|
+
should_not_have_json 'error'
|
19
|
+
should_not_have_json 'error_description'
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with scopes' do
|
23
|
+
before do
|
24
|
+
optional_scopes_exist :write
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'adds the scope to the token an returns in the response' do
|
28
|
+
headers = authorization client.uid, client.secret
|
29
|
+
params = { :grant_type => 'client_credentials', :scope => 'write' }
|
30
|
+
|
31
|
+
post '/oauth/token', params, headers
|
32
|
+
|
33
|
+
should_have_json 'access_token', Doorkeeper::AccessToken.first.token
|
34
|
+
should_have_json 'scope', 'write'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'an invalid request' do
|
40
|
+
it 'does not authorize the client and returns the error' do
|
41
|
+
headers = {}
|
42
|
+
params = { :grant_type => 'client_credentials' }
|
43
|
+
|
44
|
+
post '/oauth/token', params, headers
|
45
|
+
|
46
|
+
should_have_json 'error', 'invalid_client'
|
47
|
+
should_have_json 'error_description', translated_error_message(:invalid_client)
|
48
|
+
should_not_have_json 'access_token'
|
49
|
+
|
50
|
+
response.status.should == 401
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def authorization(username, password)
|
55
|
+
credentials = ActionController::HttpAuthentication::Basic.encode_credentials username, password
|
56
|
+
{ 'HTTP_AUTHORIZATION' => credentials }
|
57
|
+
end
|
58
|
+
end
|