doorkeeper 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +12 -0
- data/.rspec +1 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +98 -0
- data/Gemfile +6 -0
- data/README.md +42 -6
- data/app/controllers/doorkeeper/application_controller.rb +4 -11
- data/app/controllers/doorkeeper/applications_controller.rb +7 -1
- data/app/controllers/doorkeeper/authorizations_controller.rb +11 -1
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +3 -3
- data/app/controllers/doorkeeper/tokens_controller.rb +19 -5
- data/app/models/doorkeeper/access_grant.rb +28 -0
- data/app/models/doorkeeper/access_token.rb +65 -0
- data/app/models/doorkeeper/application.rb +54 -0
- data/app/views/doorkeeper/applications/index.html.erb +1 -1
- data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
- data/app/views/doorkeeper/authorizations/new.html.erb +15 -15
- data/app/views/doorkeeper/authorized_applications/index.html.erb +1 -2
- data/config/locales/en.yml +3 -0
- data/doorkeeper.gemspec +28 -0
- data/gemfiles/gemfile.rails-3.1.x +7 -0
- data/gemfiles/gemfile.rails-3.2.x +7 -0
- data/lib/doorkeeper/config.rb +73 -12
- data/lib/doorkeeper/doorkeeper_for.rb +19 -15
- data/lib/doorkeeper/engine.rb +28 -0
- data/lib/doorkeeper/models/scopes.rb +13 -0
- data/lib/doorkeeper/oauth/access_token_request.rb +9 -20
- data/lib/doorkeeper/oauth/authorization/code.rb +1 -1
- data/lib/doorkeeper/oauth/authorization/token.rb +2 -2
- data/lib/doorkeeper/oauth/authorization_request.rb +18 -23
- data/lib/doorkeeper/oauth/client/credentials.rb +21 -0
- data/lib/doorkeeper/oauth/client/methods.rb +18 -0
- data/lib/doorkeeper/oauth/client.rb +27 -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/response.rb +42 -0
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +33 -0
- data/lib/doorkeeper/oauth/client_credentials_request.rb +46 -0
- data/lib/doorkeeper/oauth/error.rb +9 -0
- data/lib/doorkeeper/oauth/error_response.rb +30 -0
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +2 -2
- data/lib/doorkeeper/oauth/password_access_token_request.rb +130 -0
- data/lib/doorkeeper/oauth/scopes.rb +60 -0
- data/lib/doorkeeper/version.rb +1 -1
- data/lib/doorkeeper.rb +23 -3
- data/lib/generators/doorkeeper/install_generator.rb +1 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +12 -7
- data/lib/generators/doorkeeper/templates/migration.rb +1 -1
- data/lib/generators/doorkeeper/views_generator.rb +15 -0
- data/script/rails +6 -0
- data/script/run_all +11 -0
- data/spec/controllers/applications_controller_spec.rb +18 -0
- data/spec/controllers/authorizations_controller_spec.rb +131 -0
- data/spec/controllers/protected_resources_controller_spec.rb +308 -0
- data/spec/controllers/tokens_controller_spec.rb +34 -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/full_protected_resources_controller.rb +12 -0
- data/spec/dummy/app/controllers/home_controller.rb +17 -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 +11 -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/application.rb +53 -0
- data/spec/dummy/config/boot.rb +10 -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 +41 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -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/routes.rb +8 -0
- data/spec/dummy/config.ru +4 -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 +42 -0
- data/spec/dummy/db/schema.rb +62 -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/install_generator_spec.rb +35 -0
- data/spec/generators/templates/routes.rb +3 -0
- data/spec/generators/views_generator_spec.rb +27 -0
- data/spec/lib/config_spec.rb +87 -0
- data/spec/lib/models/expirable_spec.rb +49 -0
- data/spec/lib/models/revocable_spec.rb +31 -0
- data/spec/lib/models/scopes_spec.rb +32 -0
- data/spec/lib/oauth/access_token_request_spec.rb +240 -0
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +37 -0
- data/spec/lib/oauth/authorization_request_spec.rb +286 -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/response_spec.rb +58 -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 +60 -0
- data/spec/lib/oauth/client_spec.rb +42 -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 +38 -0
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +64 -0
- data/spec/lib/oauth/password_access_token_request_spec.rb +152 -0
- data/spec/lib/oauth/scopes_spec.rb +115 -0
- data/spec/models/doorkeeper/access_grant_spec.rb +36 -0
- data/spec/models/doorkeeper/access_token_spec.rb +113 -0
- data/spec/models/doorkeeper/application_spec.rb +129 -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 +63 -0
- data/spec/requests/endpoints/token_spec.rb +29 -0
- data/spec/requests/flows/authorization_code_errors_spec.rb +111 -0
- data/spec/requests/flows/authorization_code_spec.rb +125 -0
- data/spec/requests/flows/client_credentials_spec.rb +56 -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 +52 -0
- data/spec/requests/flows/refresh_token_spec.rb +66 -0
- data/spec/requests/flows/skip_authorization_spec.rb +40 -0
- data/spec/requests/protected_resources/private_api_spec.rb +43 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/spec_helper_integration.rb +28 -0
- data/spec/support/dependencies/database_cleaner.rb +16 -0
- data/spec/support/dependencies/factory_girl.rb +5 -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/shared/controllers_shared_context.rb +60 -0
- data/spec/support/shared/models_shared_examples.rb +44 -0
- metadata +163 -57
- data/app/controllers/doorkeeper/application_controller.rbc +0 -675
- data/app/controllers/doorkeeper/applications_controller.rbc +0 -954
- data/app/controllers/doorkeeper/authorizations_controller.rbc +0 -659
- data/app/controllers/doorkeeper/authorized_applications_controller.rbc +0 -393
- data/app/controllers/doorkeeper/tokens_controller.rbc +0 -423
- data/app/helpers/doorkeeper/application_helper.rbc +0 -127
- data/app/models/access_grant.rb +0 -31
- data/app/models/access_grant.rbc +0 -821
- data/app/models/access_token.rb +0 -70
- data/app/models/access_token.rbc +0 -979
- data/app/models/application.rb +0 -45
- data/app/models/application.rbc +0 -753
- data/config/initializers/form_errors.rbc +0 -272
- data/config/routes.rbc +0 -366
- data/lib/doorkeeper/config/scope.rb +0 -11
- data/lib/doorkeeper/config/scopes.rb +0 -61
- data/lib/doorkeeper/config/scopes_builder.rb +0 -18
- data/lib/doorkeeper/config.rbc +0 -1385
- data/lib/doorkeeper/doorkeeper_for.rbc +0 -1029
- data/lib/doorkeeper/engine.rbc +0 -318
- data/lib/doorkeeper/oauth/access_token_request.rbc +0 -2042
- data/lib/doorkeeper/oauth/authorization_request.rbc +0 -2272
- data/lib/doorkeeper/oauth/random_string.rbc +0 -437
- data/lib/doorkeeper/validations.rbc +0 -774
- data/lib/doorkeeper/version.rbc +0 -130
- data/lib/doorkeeper.rbc +0 -407
- data/lib/generators/doorkeeper/install_generator.rbc +0 -453
- data/lib/tasks/doorkeeper_tasks.rake.compiled.rbc +0 -40
data/.gitignore
ADDED
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--colour
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
- deprecation
|
|
6
|
+
- Deprecate authorization_scopes
|
|
7
|
+
- database changes
|
|
8
|
+
- AccessToken#resource_owner_id is not nullable
|
|
9
|
+
- enhancements
|
|
10
|
+
- [#83] Add Resource Owner Password Credentials flow [@jaimeiniesta](https://github.com/jaimeiniesta)
|
|
11
|
+
- [#76] Allow token expiration to be disabled [@mattgreen](https://github.com/mattgreen)
|
|
12
|
+
- [#b6470a] Add Client Credentials flow
|
|
13
|
+
- internals
|
|
14
|
+
- [#2ece8d, #f93778] Introduce Client and ErrorResponse classes
|
|
15
|
+
|
|
16
|
+
## 0.3.4
|
|
17
|
+
|
|
18
|
+
- Fix attr_accessible for rails 3.2.x
|
|
19
|
+
|
|
20
|
+
## 0.3.3
|
|
21
|
+
|
|
22
|
+
- [#86] shrink gem package size
|
|
23
|
+
|
|
24
|
+
## 0.3.2
|
|
25
|
+
|
|
26
|
+
- enhancements
|
|
27
|
+
- [#54] Ignore Authorization: headers that are not Bearer [@miyagawa](https://github.com/miyagawa)
|
|
28
|
+
- [#58, #64] Add destroy action to applications endpoint [@jaimeiniesta](https://github.com/jaimeiniesta), [@davidfrey](https://github.com/davidfrey)
|
|
29
|
+
- [#63] TokensController responds with `401 unauthorized` [@jaimeiniesta](https://github.com/jaimeiniesta)
|
|
30
|
+
- [#67, #72] Fix for mass-assignment [@cicloid](https://github.com/cicloid)
|
|
31
|
+
- internals
|
|
32
|
+
- [#49] Add Gemnasium status image to README [@laserlemon](https://github.com/laserlemon)
|
|
33
|
+
- [#50] Fix typos [@tomekw](https://github.com/tomekw)
|
|
34
|
+
- [#51] Updated the factory_girl_rails dependency, fix expires_in response which returned a float number instead of integer [@antekpiechnik](https://github.com/antekpiechnik)
|
|
35
|
+
- [#62] Typos, .gitignore [@jaimeiniesta](https://github.com/jaimeiniesta)
|
|
36
|
+
- [#65] Change _path redirections to _url redirections [@jaimeiniesta](https://github.com/jaimeiniesta)
|
|
37
|
+
- [#75] Fix unknown method #authenticate_admin! [@mattgreen](https://github.com/mattgreen)
|
|
38
|
+
- Remove application link in authorized app view
|
|
39
|
+
|
|
40
|
+
## 0.3.1
|
|
41
|
+
|
|
42
|
+
- enhancements
|
|
43
|
+
- [#48] Add if, else options to doorkeeper_for
|
|
44
|
+
- Add views generator
|
|
45
|
+
- internals
|
|
46
|
+
- Namespace models
|
|
47
|
+
|
|
48
|
+
## 0.3.0
|
|
49
|
+
|
|
50
|
+
- enhancements
|
|
51
|
+
- [#17, #31] Add support for client credentials in basic auth header [@GoldsteinTechPartners](https://github.com/GoldsteinTechPartners)
|
|
52
|
+
- [#28] Add indices to migration [@GoldsteinTechPartners](https://github.com/GoldsteinTechPartners)
|
|
53
|
+
- [#29] Allow doorkeeper to run with rails 3.2 [@john-griffin](https://github.com/john-griffin)
|
|
54
|
+
- [#30] Improve client's redirect uri validation [@GoldsteinTechPartners](https://github.com/GoldsteinTechPartners)
|
|
55
|
+
- [#32] Add token (implicit grant) flow [@GoldsteinTechPartners](https://github.com/GoldsteinTechPartners)
|
|
56
|
+
- [#34] Add support for custom unathorized responses [@GoldsteinTechPartners](https://github.com/GoldsteinTechPartners)
|
|
57
|
+
- [#36] Remove repetitions from the Authorised Applications view [@carvil](https://github.com/carvil)
|
|
58
|
+
- When user revoke an application, all tokens for that application are revoked
|
|
59
|
+
- Error messages now can be translated
|
|
60
|
+
- Install generator copies the error messages localization file
|
|
61
|
+
- internals
|
|
62
|
+
- Fix deprecation warnings in ActiveSupport::Base64
|
|
63
|
+
- Remove deprecation in doorkeeper_for that handles hash arguments
|
|
64
|
+
- Depends on railties instead of whole rails framework
|
|
65
|
+
- CI now integrates with rails 3.1 and 3.2
|
|
66
|
+
|
|
67
|
+
## 0.2.0
|
|
68
|
+
|
|
69
|
+
- enhancements
|
|
70
|
+
- [#4] Add authorized applications endpoint
|
|
71
|
+
- [#5, #11] Add access token scopes
|
|
72
|
+
- [#10] Add access token expiration by default
|
|
73
|
+
- [#9, #12] Add refresh token flow
|
|
74
|
+
- internals
|
|
75
|
+
- [#7] Improve configuration options with :default
|
|
76
|
+
- Improve configuration options with :builder
|
|
77
|
+
- Refactor config class
|
|
78
|
+
- Improve coverage of authorization request integration
|
|
79
|
+
- bug fixes
|
|
80
|
+
- [#6, #20] Fix access token response headers
|
|
81
|
+
- Fix issue with state parameter
|
|
82
|
+
- deprecation
|
|
83
|
+
- deprecate :only and :except options in doorkeeper_for
|
|
84
|
+
|
|
85
|
+
## 0.1.1
|
|
86
|
+
|
|
87
|
+
- enhancements
|
|
88
|
+
- [#3] Authorization code must be short lived and single use
|
|
89
|
+
- [#2] Improve views provided by doorkeeper
|
|
90
|
+
- [#1] Skips authorization form if the client has been authorized by the resource owner
|
|
91
|
+
- Improve readme
|
|
92
|
+
- bugfixes
|
|
93
|
+
- Fix issue when creating the access token (wrong client id)
|
|
94
|
+
|
|
95
|
+
## 0.1.0
|
|
96
|
+
|
|
97
|
+
- Authorization Code flow
|
|
98
|
+
- OAuth applications endpoint
|
data/Gemfile
ADDED
data/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Doorkeeper - awesome oauth provider for your Rails app.
|
|
2
2
|
|
|
3
3
|
[](http://travis-ci.org/applicake/doorkeeper)
|
|
4
|
+
[](https://gemnasium.com/applicake/doorkeeper)
|
|
4
5
|
|
|
5
6
|
Doorkeeper is a gem that makes it easy to introduce OAuth 2 provider functionality to your application.
|
|
6
7
|
|
|
@@ -13,7 +14,7 @@ For more information about the supported features, check out the related [page i
|
|
|
13
14
|
Put this in your Gemfile:
|
|
14
15
|
|
|
15
16
|
``` ruby
|
|
16
|
-
gem 'doorkeeper', '~> 0.
|
|
17
|
+
gem 'doorkeeper', '~> 0.4.0'
|
|
17
18
|
```
|
|
18
19
|
|
|
19
20
|
Run the installation generator with:
|
|
@@ -48,11 +49,13 @@ You need to configure Doorkeeper in order to provide resource_owner model and au
|
|
|
48
49
|
``` ruby
|
|
49
50
|
Doorkeeper.configure do
|
|
50
51
|
resource_owner_authenticator do |routes|
|
|
51
|
-
current_user || redirect_to(
|
|
52
|
+
current_user || redirect_to(routes.login_url) # returns nil if current_user is not logged in
|
|
52
53
|
end
|
|
53
54
|
end
|
|
54
55
|
```
|
|
55
56
|
|
|
57
|
+
This block runs into the context of your Rails application, and it has access to `current_user` method, for example.
|
|
58
|
+
|
|
56
59
|
If you use [devise](https://github.com/plataformatec/devise), you may want to use warden to authenticate the block:
|
|
57
60
|
|
|
58
61
|
``` ruby
|
|
@@ -61,6 +64,8 @@ resource_owner_authenticator do |routes|
|
|
|
61
64
|
end
|
|
62
65
|
```
|
|
63
66
|
|
|
67
|
+
If you are not using devise, you may want to check other ways of authentication [here](https://github.com/applicake/doorkeeper/wiki/Authenticating-using-Clearance-DIY).
|
|
68
|
+
|
|
64
69
|
## Protecting resources with OAuth (a.k.a your API endpoint)
|
|
65
70
|
|
|
66
71
|
To protect your API with OAuth, doorkeeper only requires you to call `doorkeeper_for` helper, specifying the actions you want to protect.
|
|
@@ -70,7 +75,7 @@ For example, if you have a products controller under api/v1, you can require the
|
|
|
70
75
|
``` ruby
|
|
71
76
|
class Api::V1::ProductsController < Api::V1::ApiController
|
|
72
77
|
doorkeeper_for :all # Require access token for all actions
|
|
73
|
-
doorkeeper_for :all, :except => :index # All actions except
|
|
78
|
+
doorkeeper_for :all, :except => :index # All actions except index
|
|
74
79
|
doorkeeper_for :index, :show # Only for index and show action
|
|
75
80
|
|
|
76
81
|
# your actions
|
|
@@ -79,10 +84,29 @@ end
|
|
|
79
84
|
|
|
80
85
|
You don't need to setup any before filter, `doorkeeper_for` will handle that for you.
|
|
81
86
|
|
|
87
|
+
You can pass `if` or `unless` blocks that would specify when doorkeeper has to guard the access.
|
|
88
|
+
|
|
89
|
+
``` ruby
|
|
90
|
+
class Api::V1::ProductsController < Api::V1::ApiController
|
|
91
|
+
doorkeeper_for :all, :if => lambda { request.xhr? }
|
|
92
|
+
end
|
|
93
|
+
```
|
|
94
|
+
|
|
82
95
|
### Access Token Scopes
|
|
83
96
|
|
|
84
97
|
You can also require the access token to have specific scopes in certain actions:
|
|
85
98
|
|
|
99
|
+
First configure the scopes in `initializers/doorkeeper.rb`
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
Doorkeeper.configure do
|
|
103
|
+
default_scope :public # if no scope was requested, this will be the default
|
|
104
|
+
optional_scope :admin, :write
|
|
105
|
+
end
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The in your controllers:
|
|
109
|
+
|
|
86
110
|
```ruby
|
|
87
111
|
class Api::V1::ProductsController < Api::V1::ApiController
|
|
88
112
|
doorkeeper_for :index, :show, :scopes => [:public]
|
|
@@ -117,12 +141,24 @@ end
|
|
|
117
141
|
|
|
118
142
|
In this example, we're returning the credentials (`me.json`) of the access token owner.
|
|
119
143
|
|
|
144
|
+
## Upgrading
|
|
145
|
+
|
|
146
|
+
If you want to upgrade doorkeeper to a new version, check out the [upgrading notes](https://github.com/applicake/doorkeeper/wiki/Migration-from-old-versions) and take a look at the [changelog](https://github.com/applicake/doorkeeper/blob/master/CHANGELOG.md).
|
|
147
|
+
|
|
120
148
|
## Other resources
|
|
121
149
|
|
|
150
|
+
### Wiki
|
|
151
|
+
|
|
152
|
+
You can find everything about doorkeeper in our [wiki here](https://github.com/applicake/doorkeeper/wiki).
|
|
153
|
+
|
|
122
154
|
### Live demo
|
|
123
155
|
|
|
124
156
|
Check out this [live demo](http://doorkeeper-provider.herokuapp.com) hosted on heroku. For more demos check out [the wiki](https://github.com/applicake/doorkeeper/wiki/Example-Applications).
|
|
125
157
|
|
|
158
|
+
### Screencast
|
|
159
|
+
|
|
160
|
+
Check out this screencast from [railscasts.com](http://railscasts.com/): [#353 OAuth with Doorkeeper](http://railscasts.com/episodes/353-oauth-with-doorkeeper)
|
|
161
|
+
|
|
126
162
|
### Client applications
|
|
127
163
|
|
|
128
164
|
After you set up the provider, you may want to create a client application to test the integration. Check out these [client examples](https://github.com/applicake/doorkeeper/wiki/Example-Applications) in our wiki or follow this [tutorial here](https://github.com/applicake/doorkeeper/wiki/Testing-your-provider-with-OAuth2-gem).
|
|
@@ -135,14 +171,14 @@ Also, check out our [contributing guidelines page](https://github.com/applicake/
|
|
|
135
171
|
|
|
136
172
|
### Supported ruby versions
|
|
137
173
|
|
|
138
|
-
All supported ruby versions are [listed here](https://github.com/applicake/doorkeeper/wiki/Supported-Ruby-versions)
|
|
174
|
+
All supported ruby versions are [listed here](https://github.com/applicake/doorkeeper/wiki/Supported-Ruby-&-Rails-versions).
|
|
139
175
|
|
|
140
176
|
## Additional information
|
|
141
177
|
|
|
142
178
|
### Maintainers
|
|
143
179
|
|
|
144
|
-
- Felipe Elias Philipp ([github.com/felipeelias](https://github.com/felipeelias))
|
|
145
|
-
- Piotr Jakubowski ([github.com/piotrj](https://github.com/piotrj))
|
|
180
|
+
- Felipe Elias Philipp ([github.com/felipeelias](https://github.com/felipeelias), [twitter.com/felipeelias](https://twitter.com/felipeelias))
|
|
181
|
+
- Piotr Jakubowski ([github.com/piotrj](https://github.com/piotrj), [twitter.com/piotrjakubowski](https://twitter.com/piotrjakubowski))
|
|
146
182
|
|
|
147
183
|
### Contributors
|
|
148
184
|
|
|
@@ -2,17 +2,6 @@ module Doorkeeper
|
|
|
2
2
|
class ApplicationController < ActionController::Base
|
|
3
3
|
private
|
|
4
4
|
|
|
5
|
-
def parse_client_info_from_basic_auth
|
|
6
|
-
auth_header = request.env['HTTP_AUTHORIZATION']
|
|
7
|
-
return unless auth_header && auth_header =~ /^Basic (.*)/m
|
|
8
|
-
client_info = Base64.decode64($1).split(/:/, 2)
|
|
9
|
-
client_id = client_info[0]
|
|
10
|
-
client_secret = client_info[1]
|
|
11
|
-
return if client_id.nil? || client_secret.nil?
|
|
12
|
-
params[:client_id] = client_id
|
|
13
|
-
params[:client_secret] = client_secret
|
|
14
|
-
end
|
|
15
|
-
|
|
16
5
|
def authenticate_resource_owner!
|
|
17
6
|
current_resource_owner
|
|
18
7
|
end
|
|
@@ -21,6 +10,10 @@ module Doorkeeper
|
|
|
21
10
|
instance_exec(main_app, &Doorkeeper.configuration.authenticate_resource_owner)
|
|
22
11
|
end
|
|
23
12
|
|
|
13
|
+
def resource_owner_from_credentials
|
|
14
|
+
instance_exec(main_app, &Doorkeeper.configuration.resource_owner_from_credentials)
|
|
15
|
+
end
|
|
16
|
+
|
|
24
17
|
def authenticate_admin!
|
|
25
18
|
if block = Doorkeeper.configuration.authenticate_admin
|
|
26
19
|
instance_exec(main_app, &block)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module Doorkeeper
|
|
2
|
-
class ApplicationsController < ApplicationController
|
|
2
|
+
class ApplicationsController < Doorkeeper::ApplicationController
|
|
3
3
|
respond_to :html
|
|
4
4
|
|
|
5
5
|
before_filter :authenticate_admin!
|
|
@@ -31,5 +31,11 @@ module Doorkeeper
|
|
|
31
31
|
flash[:notice] = "Application updated" if @application.update_attributes(params[:application])
|
|
32
32
|
respond_with @application
|
|
33
33
|
end
|
|
34
|
+
|
|
35
|
+
def destroy
|
|
36
|
+
@application = Application.find(params[:id])
|
|
37
|
+
flash[:notice] = "Application deleted" if @application.destroy
|
|
38
|
+
redirect_to applications_url
|
|
39
|
+
end
|
|
34
40
|
end
|
|
35
41
|
end
|
|
@@ -10,6 +10,7 @@ class Doorkeeper::AuthorizationsController < Doorkeeper::ApplicationController
|
|
|
10
10
|
elsif authorization.redirect_on_error?
|
|
11
11
|
redirect_to authorization.invalid_redirect_uri
|
|
12
12
|
else
|
|
13
|
+
@error = authorization.error_response
|
|
13
14
|
render :error
|
|
14
15
|
end
|
|
15
16
|
end
|
|
@@ -20,6 +21,7 @@ class Doorkeeper::AuthorizationsController < Doorkeeper::ApplicationController
|
|
|
20
21
|
elsif authorization.redirect_on_error?
|
|
21
22
|
redirect_to authorization.invalid_redirect_uri
|
|
22
23
|
else
|
|
24
|
+
@error = authorization.error_response
|
|
23
25
|
render :error
|
|
24
26
|
end
|
|
25
27
|
end
|
|
@@ -31,7 +33,15 @@ class Doorkeeper::AuthorizationsController < Doorkeeper::ApplicationController
|
|
|
31
33
|
|
|
32
34
|
private
|
|
33
35
|
|
|
36
|
+
def authorization_params
|
|
37
|
+
params.has_key?(:authorization) ? params[:authorization] : params
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def client
|
|
41
|
+
@client ||= Doorkeeper::OAuth::Client.find(authorization_params[:client_id])
|
|
42
|
+
end
|
|
43
|
+
|
|
34
44
|
def authorization
|
|
35
|
-
@authorization ||= Doorkeeper::OAuth::AuthorizationRequest.new(current_resource_owner,
|
|
45
|
+
@authorization ||= Doorkeeper::OAuth::AuthorizationRequest.new(client, current_resource_owner, authorization_params)
|
|
36
46
|
end
|
|
37
47
|
end
|
|
@@ -2,11 +2,11 @@ class Doorkeeper::AuthorizedApplicationsController < Doorkeeper::ApplicationCont
|
|
|
2
2
|
before_filter :authenticate_resource_owner!
|
|
3
3
|
|
|
4
4
|
def index
|
|
5
|
-
@applications = Application.authorized_for(current_resource_owner)
|
|
5
|
+
@applications = Doorkeeper::Application.authorized_for(current_resource_owner)
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
def destroy
|
|
9
|
-
AccessToken.revoke_all_for params[:id], current_resource_owner
|
|
10
|
-
redirect_to
|
|
9
|
+
Doorkeeper::AccessToken.revoke_all_for params[:id], current_resource_owner
|
|
10
|
+
redirect_to authorized_applications_url, :notice => "Application revoked."
|
|
11
11
|
end
|
|
12
12
|
end
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
class Doorkeeper::TokensController < Doorkeeper::ApplicationController
|
|
2
|
-
|
|
3
|
-
before_filter :parse_client_info_from_basic_auth, :only => :create
|
|
4
|
-
|
|
5
2
|
def create
|
|
6
3
|
response.headers.merge!({
|
|
7
4
|
'Pragma' => 'no-cache',
|
|
@@ -10,13 +7,30 @@ class Doorkeeper::TokensController < Doorkeeper::ApplicationController
|
|
|
10
7
|
if token.authorize
|
|
11
8
|
render :json => token.authorization
|
|
12
9
|
else
|
|
13
|
-
render :json => token.error_response
|
|
10
|
+
render :json => token.error_response, :status => token.error_response.status
|
|
14
11
|
end
|
|
15
12
|
end
|
|
16
13
|
|
|
17
14
|
private
|
|
18
15
|
|
|
16
|
+
def client
|
|
17
|
+
@client ||= Doorkeeper::OAuth::Client.authenticate(credentials)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def credentials
|
|
21
|
+
methods = Doorkeeper.configuration.client_credentials_methods
|
|
22
|
+
@credentials ||= Doorkeeper::OAuth::Client::Credentials.from_request(request, *methods)
|
|
23
|
+
end
|
|
24
|
+
|
|
19
25
|
def token
|
|
20
|
-
|
|
26
|
+
case params[:grant_type]
|
|
27
|
+
when 'password'
|
|
28
|
+
owner = resource_owner_from_credentials
|
|
29
|
+
@token ||= Doorkeeper::OAuth::PasswordAccessTokenRequest.new(client, owner, params)
|
|
30
|
+
when 'client_credentials'
|
|
31
|
+
@token ||= Doorkeeper::OAuth::ClientCredentialsRequest.new(Doorkeeper.configuration, client, params)
|
|
32
|
+
else
|
|
33
|
+
@token ||= Doorkeeper::OAuth::AccessTokenRequest.new(client, params)
|
|
34
|
+
end
|
|
21
35
|
end
|
|
22
36
|
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Doorkeeper
|
|
2
|
+
class AccessGrant < ActiveRecord::Base
|
|
3
|
+
include Doorkeeper::OAuth::Helpers
|
|
4
|
+
include Doorkeeper::Models::Expirable
|
|
5
|
+
include Doorkeeper::Models::Revocable
|
|
6
|
+
include Doorkeeper::Models::Scopes
|
|
7
|
+
|
|
8
|
+
self.table_name = :oauth_access_grants
|
|
9
|
+
|
|
10
|
+
belongs_to :application
|
|
11
|
+
|
|
12
|
+
attr_accessible :resource_owner_id, :application_id, :expires_in, :redirect_uri, :scopes
|
|
13
|
+
|
|
14
|
+
validates :resource_owner_id, :application_id, :token, :expires_in, :redirect_uri, :presence => true
|
|
15
|
+
|
|
16
|
+
before_validation :generate_token, :on => :create
|
|
17
|
+
|
|
18
|
+
def accessible?
|
|
19
|
+
!expired? && !revoked?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def generate_token
|
|
25
|
+
self.token = UniqueToken.generate_for :token, self.class
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Doorkeeper
|
|
2
|
+
class AccessToken < ActiveRecord::Base
|
|
3
|
+
include Doorkeeper::OAuth::Helpers
|
|
4
|
+
include Doorkeeper::Models::Expirable
|
|
5
|
+
include Doorkeeper::Models::Revocable
|
|
6
|
+
include Doorkeeper::Models::Scopes
|
|
7
|
+
|
|
8
|
+
self.table_name = :oauth_access_tokens
|
|
9
|
+
|
|
10
|
+
belongs_to :application
|
|
11
|
+
|
|
12
|
+
scope :accessible, where(:revoked_at => nil)
|
|
13
|
+
|
|
14
|
+
validates :application_id, :token, :presence => true
|
|
15
|
+
|
|
16
|
+
attr_accessor :use_refresh_token
|
|
17
|
+
attr_accessible :application_id, :resource_owner_id, :expires_in, :scopes, :use_refresh_token
|
|
18
|
+
|
|
19
|
+
before_validation :generate_token, :on => :create
|
|
20
|
+
before_validation :generate_refresh_token, :on => :create, :if => :use_refresh_token?
|
|
21
|
+
|
|
22
|
+
def self.revoke_all_for(application_id, resource_owner)
|
|
23
|
+
where(:application_id => application_id,
|
|
24
|
+
:resource_owner_id => resource_owner.id).delete_all
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.matching_token_for(application, resource_owner_or_id, scopes)
|
|
28
|
+
token = last_authorized_token_for(application, resource_owner_or_id)
|
|
29
|
+
token if token && ScopeChecker.matches?(token.scopes, scopes)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.last_authorized_token_for(application, resource_owner_or_id)
|
|
33
|
+
resource_owner_id = resource_owner_or_id.kind_of?(ActiveRecord::Base) ? resource_owner_or_id.id : resource_owner_or_id
|
|
34
|
+
accessible.
|
|
35
|
+
where(:application_id => application.id,
|
|
36
|
+
:resource_owner_id => resource_owner_id).
|
|
37
|
+
order("created_at desc").
|
|
38
|
+
limit(1).
|
|
39
|
+
first
|
|
40
|
+
end
|
|
41
|
+
private_class_method :last_authorized_token_for
|
|
42
|
+
|
|
43
|
+
def token_type
|
|
44
|
+
"bearer"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def accessible?
|
|
48
|
+
!expired? && !revoked?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def use_refresh_token?
|
|
52
|
+
self.use_refresh_token
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def generate_refresh_token
|
|
58
|
+
self.refresh_token = UniqueToken.generate_for :refresh_token, self.class
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def generate_token
|
|
62
|
+
self.token = UniqueToken.generate_for :token, self.class
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Doorkeeper
|
|
2
|
+
class Application < ActiveRecord::Base
|
|
3
|
+
include Doorkeeper::OAuth::Helpers
|
|
4
|
+
|
|
5
|
+
self.table_name = :oauth_applications
|
|
6
|
+
|
|
7
|
+
has_many :access_grants, :dependent => :destroy
|
|
8
|
+
has_many :access_tokens, :dependent => :destroy
|
|
9
|
+
has_many :authorized_tokens, :class_name => "AccessToken", :conditions => { :revoked_at => nil }
|
|
10
|
+
has_many :authorized_applications, :through => :authorized_tokens, :source => :application
|
|
11
|
+
|
|
12
|
+
validates :name, :secret, :redirect_uri, :presence => true
|
|
13
|
+
validates :uid, :presence => true, :uniqueness => true
|
|
14
|
+
validate :validate_redirect_uri
|
|
15
|
+
|
|
16
|
+
before_validation :generate_uid, :generate_secret, :on => :create
|
|
17
|
+
|
|
18
|
+
attr_accessible :name, :redirect_uri
|
|
19
|
+
|
|
20
|
+
def self.authenticate(uid, secret)
|
|
21
|
+
find_by_uid_and_secret(uid, secret)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.column_names_with_table
|
|
25
|
+
self.column_names.map { |c| "oauth_applications.#{c}" }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.authorized_for(resource_owner)
|
|
29
|
+
joins(:authorized_applications).
|
|
30
|
+
where(:oauth_access_tokens => { :resource_owner_id => resource_owner.id }).
|
|
31
|
+
group(column_names_with_table.join(','))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def validate_redirect_uri
|
|
35
|
+
return unless redirect_uri
|
|
36
|
+
uri = URI.parse(redirect_uri)
|
|
37
|
+
errors.add(:redirect_uri, "cannot contain a fragment.") unless uri.fragment.nil?
|
|
38
|
+
errors.add(:redirect_uri, "must be an absolute URL.") if uri.scheme.nil? || uri.host.nil?
|
|
39
|
+
errors.add(:redirect_uri, "cannot contain a query parameter.") unless uri.query.nil?
|
|
40
|
+
rescue URI::InvalidURIError => e
|
|
41
|
+
errors.add(:redirect_uri, "must be a valid URI.")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def generate_uid
|
|
47
|
+
self.uid = UniqueToken.generate_for :uid, self.class
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def generate_secret
|
|
51
|
+
self.secret = UniqueToken.generate_for :secret, self.class
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
</thead>
|
|
17
17
|
<tbody>
|
|
18
18
|
<% @applications.each do |application| %>
|
|
19
|
-
<tr>
|
|
19
|
+
<tr id="application_<%= application.id %>">
|
|
20
20
|
<td><%= link_to application.name, application %></td>
|
|
21
21
|
<td><%= application.redirect_uri %></td>
|
|
22
22
|
<td><%= link_to 'Edit', edit_application_path(application) %></td>
|
|
@@ -9,29 +9,29 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
<ul>
|
|
11
11
|
<% @authorization.scopes.each do |scope| %>
|
|
12
|
-
<li><%= scope
|
|
12
|
+
<li><%= t scope, :scope => [:doorkeeper, :scopes] %></li>
|
|
13
13
|
<% end %>
|
|
14
14
|
</ul>
|
|
15
15
|
<% end %>
|
|
16
16
|
|
|
17
17
|
<div class="inline_block">
|
|
18
|
-
<%=
|
|
19
|
-
<%=
|
|
20
|
-
<%=
|
|
21
|
-
<%=
|
|
22
|
-
<%=
|
|
23
|
-
<%=
|
|
24
|
-
<%=
|
|
18
|
+
<%= form_for @authorization, :as => :authorization, :url => authorization_path, :method => :post do |f| %>
|
|
19
|
+
<%= f.hidden_field :client_id %>
|
|
20
|
+
<%= f.hidden_field :redirect_uri %>
|
|
21
|
+
<%= f.hidden_field :state %>
|
|
22
|
+
<%= f.hidden_field :response_type %>
|
|
23
|
+
<%= f.hidden_field :scope %>
|
|
24
|
+
<%= f.submit "Authorize", :class => "btn success" %> or
|
|
25
25
|
<% end %>
|
|
26
26
|
</div>
|
|
27
27
|
<div class="inline_block">
|
|
28
|
-
<%=
|
|
29
|
-
<%=
|
|
30
|
-
<%=
|
|
31
|
-
<%=
|
|
32
|
-
<%=
|
|
33
|
-
<%=
|
|
34
|
-
<%=
|
|
28
|
+
<%= form_for @authorization, :as => :authorization, :url => authorization_path, :method => :delete do |f| %>
|
|
29
|
+
<%= f.hidden_field :client_id %>
|
|
30
|
+
<%= f.hidden_field :redirect_uri %>
|
|
31
|
+
<%= f.hidden_field :state %>
|
|
32
|
+
<%= f.hidden_field :response_type %>
|
|
33
|
+
<%= f.hidden_field :scope %>
|
|
34
|
+
<%= f.submit "Deny", :class => "btn" %>
|
|
35
35
|
<% end %>
|
|
36
36
|
</div>
|
|
37
37
|
</div>
|
|
@@ -15,12 +15,11 @@
|
|
|
15
15
|
<tbody>
|
|
16
16
|
<% @applications.each do |application| %>
|
|
17
17
|
<tr>
|
|
18
|
-
<td><%=
|
|
18
|
+
<td><%= application.name %></td>
|
|
19
19
|
<td><%= application.created_at %></td>
|
|
20
20
|
<td><%= link_to 'Revoke', authorized_application_path(application), :confirm => 'Are you sure?', :method => :delete, :class => 'btn danger' %></td>
|
|
21
21
|
</tr>
|
|
22
22
|
<% end %>
|
|
23
23
|
</tbody>
|
|
24
24
|
</table>
|
|
25
|
-
|
|
26
25
|
</div>
|
data/config/locales/en.yml
CHANGED
|
@@ -18,3 +18,6 @@ en:
|
|
|
18
18
|
invalid_client: 'Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.'
|
|
19
19
|
invalid_grant: 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.'
|
|
20
20
|
unsupported_grant_type: 'The authorization grant type is not supported by the authorization server.'
|
|
21
|
+
|
|
22
|
+
# Password Access token errors
|
|
23
|
+
invalid_resource_owner: 'The provided resource owner credentials are not valid, or resource owner cannot be found'
|
data/doorkeeper.gemspec
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
2
|
+
|
|
3
|
+
require "doorkeeper/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = "doorkeeper"
|
|
7
|
+
s.version = Doorkeeper::VERSION
|
|
8
|
+
s.authors = ["Felipe Elias Philipp", "Piotr Jakubowski"]
|
|
9
|
+
s.email = ["felipe@applicake.com", "piotr.jakubowski@applicake.com"]
|
|
10
|
+
s.homepage = "https://github.com/applicake/doorkeeper"
|
|
11
|
+
s.summary = "Doorkeeper is an OAuth 2 provider for Rails."
|
|
12
|
+
s.description = "Doorkeeper is an OAuth 2 provider for Rails."
|
|
13
|
+
|
|
14
|
+
s.files = `git ls-files`.split("\n")
|
|
15
|
+
s.test_files = `git ls-files -- test/*`.split("\n")
|
|
16
|
+
s.require_paths = ["lib"]
|
|
17
|
+
|
|
18
|
+
s.add_dependency "railties", "~> 3.1"
|
|
19
|
+
|
|
20
|
+
s.add_development_dependency "sqlite3", "~> 1.3.5"
|
|
21
|
+
s.add_development_dependency "rspec-rails", "~> 2.10.0"
|
|
22
|
+
s.add_development_dependency "capybara", "~> 1.1.2"
|
|
23
|
+
s.add_development_dependency "generator_spec", "~> 0.8.5"
|
|
24
|
+
s.add_development_dependency "factory_girl", "~> 2.6.4"
|
|
25
|
+
s.add_development_dependency "timecop", "~> 0.3.5"
|
|
26
|
+
s.add_development_dependency "database_cleaner", "~> 0.7.1"
|
|
27
|
+
s.add_development_dependency "bcrypt-ruby", "~> 3.0.1"
|
|
28
|
+
end
|