doorkeeper 3.1.0 → 5.6.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of doorkeeper might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +1079 -0
- data/README.md +114 -326
- data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
- data/app/controllers/doorkeeper/application_controller.rb +7 -6
- data/app/controllers/doorkeeper/application_metal_controller.rb +9 -12
- data/app/controllers/doorkeeper/applications_controller.rb +66 -21
- data/app/controllers/doorkeeper/authorizations_controller.rb +100 -18
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +23 -4
- data/app/controllers/doorkeeper/token_info_controller.rb +16 -4
- data/app/controllers/doorkeeper/tokens_controller.rb +138 -22
- data/app/helpers/doorkeeper/dashboard_helper.rb +15 -9
- data/app/views/doorkeeper/applications/_delete_form.html.erb +4 -3
- data/app/views/doorkeeper/applications/_form.html.erb +33 -21
- data/app/views/doorkeeper/applications/edit.html.erb +1 -1
- data/app/views/doorkeeper/applications/index.html.erb +18 -6
- data/app/views/doorkeeper/applications/new.html.erb +1 -1
- data/app/views/doorkeeper/applications/show.html.erb +40 -16
- data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
- data/app/views/doorkeeper/authorizations/form_post.html.erb +15 -0
- data/app/views/doorkeeper/authorizations/new.html.erb +17 -11
- data/app/views/doorkeeper/authorized_applications/_delete_form.html.erb +1 -2
- data/app/views/doorkeeper/authorized_applications/index.html.erb +0 -1
- data/app/views/layouts/doorkeeper/admin.html.erb +16 -14
- data/config/locales/en.yml +37 -9
- data/lib/doorkeeper/config/abstract_builder.rb +28 -0
- data/lib/doorkeeper/config/option.rb +82 -0
- data/lib/doorkeeper/config/validations.rb +53 -0
- data/lib/doorkeeper/config.rb +602 -142
- data/lib/doorkeeper/engine.rb +22 -7
- data/lib/doorkeeper/errors.rb +37 -10
- data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
- data/lib/doorkeeper/grant_flow/flow.rb +44 -0
- data/lib/doorkeeper/grant_flow/registry.rb +50 -0
- data/lib/doorkeeper/grant_flow.rb +45 -0
- data/lib/doorkeeper/grape/authorization_decorator.rb +6 -4
- data/lib/doorkeeper/grape/helpers.rb +24 -12
- data/lib/doorkeeper/helpers/controller.rb +49 -27
- data/lib/doorkeeper/models/access_grant_mixin.rb +99 -16
- data/lib/doorkeeper/models/access_token_mixin.rb +386 -77
- data/lib/doorkeeper/models/application_mixin.rb +73 -30
- data/lib/doorkeeper/models/concerns/accessible.rb +6 -0
- data/lib/doorkeeper/models/concerns/expirable.rb +20 -6
- data/lib/doorkeeper/models/concerns/expiration_time_sql_math.rb +88 -0
- data/lib/doorkeeper/models/concerns/orderable.rb +15 -0
- data/lib/doorkeeper/models/concerns/ownership.rb +4 -2
- data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
- data/lib/doorkeeper/models/concerns/reusable.rb +19 -0
- data/lib/doorkeeper/models/concerns/revocable.rb +13 -2
- data/lib/doorkeeper/models/concerns/scopes.rb +12 -2
- data/lib/doorkeeper/models/concerns/secret_storable.rb +106 -0
- data/lib/doorkeeper/oauth/authorization/code.rb +48 -12
- data/lib/doorkeeper/oauth/authorization/context.rb +17 -0
- data/lib/doorkeeper/oauth/authorization/token.rb +72 -28
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +22 -18
- data/lib/doorkeeper/oauth/authorization_code_request.rb +64 -14
- data/lib/doorkeeper/oauth/base_request.rb +66 -0
- data/lib/doorkeeper/oauth/base_response.rb +31 -0
- data/lib/doorkeeper/oauth/client/credentials.rb +23 -10
- data/lib/doorkeeper/oauth/client.rb +10 -12
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +48 -4
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +17 -9
- data/lib/doorkeeper/oauth/client_credentials/validator.rb +55 -0
- data/lib/doorkeeper/oauth/client_credentials_request.rb +14 -15
- data/lib/doorkeeper/oauth/code_request.rb +8 -12
- data/lib/doorkeeper/oauth/code_response.rb +31 -19
- data/lib/doorkeeper/oauth/error.rb +5 -3
- data/lib/doorkeeper/oauth/error_response.rb +41 -20
- data/lib/doorkeeper/oauth/forbidden_token_response.rb +11 -3
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +24 -19
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +20 -3
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +55 -4
- data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
- data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
- data/lib/doorkeeper/oauth/invalid_token_response.rb +31 -5
- data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
- data/lib/doorkeeper/oauth/password_access_token_request.rb +46 -18
- data/lib/doorkeeper/oauth/pre_authorization.rb +135 -26
- data/lib/doorkeeper/oauth/refresh_token_request.rb +67 -30
- data/lib/doorkeeper/oauth/scopes.rb +26 -12
- data/lib/doorkeeper/oauth/token.rb +28 -25
- data/lib/doorkeeper/oauth/token_introspection.rb +202 -0
- data/lib/doorkeeper/oauth/token_request.rb +8 -21
- data/lib/doorkeeper/oauth/token_response.rb +14 -10
- data/lib/doorkeeper/oauth.rb +13 -0
- data/lib/doorkeeper/orm/active_record/access_grant.rb +6 -4
- data/lib/doorkeeper/orm/active_record/access_token.rb +5 -17
- data/lib/doorkeeper/orm/active_record/application.rb +6 -20
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +69 -0
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +81 -0
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +214 -0
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +66 -0
- data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +33 -0
- data/lib/doorkeeper/orm/active_record.rb +36 -26
- data/lib/doorkeeper/rails/helpers.rb +14 -15
- data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
- data/lib/doorkeeper/rails/routes/mapper.rb +4 -2
- data/lib/doorkeeper/rails/routes/mapping.rb +10 -8
- data/lib/doorkeeper/rails/routes/registry.rb +45 -0
- data/lib/doorkeeper/rails/routes.rb +45 -28
- data/lib/doorkeeper/rake/db.rake +40 -0
- data/lib/doorkeeper/rake/setup.rake +6 -0
- data/lib/doorkeeper/rake.rb +14 -0
- data/lib/doorkeeper/request/authorization_code.rb +12 -4
- data/lib/doorkeeper/request/client_credentials.rb +3 -3
- data/lib/doorkeeper/request/code.rb +1 -1
- data/lib/doorkeeper/request/password.rb +5 -4
- data/lib/doorkeeper/request/refresh_token.rb +6 -5
- data/lib/doorkeeper/request/strategy.rb +4 -2
- data/lib/doorkeeper/request/token.rb +1 -1
- data/lib/doorkeeper/request.rb +62 -29
- data/lib/doorkeeper/secret_storing/base.rb +64 -0
- data/lib/doorkeeper/secret_storing/bcrypt.rb +60 -0
- data/lib/doorkeeper/secret_storing/plain.rb +33 -0
- data/lib/doorkeeper/secret_storing/sha256_hash.rb +26 -0
- data/lib/doorkeeper/server.rb +9 -19
- data/lib/doorkeeper/stale_records_cleaner.rb +24 -0
- data/lib/doorkeeper/validations.rb +5 -2
- data/lib/doorkeeper/version.rb +12 -1
- data/lib/doorkeeper.rb +112 -56
- data/lib/generators/doorkeeper/application_owner_generator.rb +28 -13
- data/lib/generators/doorkeeper/confidential_applications_generator.rb +33 -0
- data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
- data/lib/generators/doorkeeper/install_generator.rb +19 -9
- data/lib/generators/doorkeeper/migration_generator.rb +27 -10
- data/lib/generators/doorkeeper/pkce_generator.rb +33 -0
- data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +41 -0
- data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +9 -0
- data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +13 -0
- data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +8 -0
- data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +417 -32
- data/lib/generators/doorkeeper/templates/migration.rb.erb +88 -0
- data/lib/generators/doorkeeper/views_generator.rb +8 -4
- data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
- metadata +163 -280
- data/.gitignore +0 -14
- data/.hound.yml +0 -13
- data/.rspec +0 -1
- data/.travis.yml +0 -22
- data/CONTRIBUTING.md +0 -45
- data/Gemfile +0 -10
- data/NEWS.md +0 -525
- data/RELEASING.md +0 -17
- data/Rakefile +0 -20
- data/app/validators/redirect_uri_validator.rb +0 -34
- data/doorkeeper.gemspec +0 -27
- data/lib/doorkeeper/oauth/client/methods.rb +0 -18
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +0 -45
- data/lib/doorkeeper/oauth/request_concern.rb +0 -48
- data/lib/generators/doorkeeper/application_scopes_generator.rb +0 -34
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb +0 -7
- data/lib/generators/doorkeeper/templates/add_scopes_to_oauth_applications.rb +0 -5
- data/lib/generators/doorkeeper/templates/migration.rb +0 -50
- data/spec/controllers/applications_controller_spec.rb +0 -58
- data/spec/controllers/authorizations_controller_spec.rb +0 -203
- data/spec/controllers/protected_resources_controller_spec.rb +0 -271
- data/spec/controllers/token_info_controller_spec.rb +0 -52
- data/spec/controllers/tokens_controller_spec.rb +0 -88
- data/spec/dummy/Rakefile +0 -7
- data/spec/dummy/app/controllers/application_controller.rb +0 -3
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -7
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -12
- data/spec/dummy/app/controllers/home_controller.rb +0 -17
- data/spec/dummy/app/controllers/metal_controller.rb +0 -11
- data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -11
- data/spec/dummy/app/helpers/application_helper.rb +0 -5
- data/spec/dummy/app/models/user.rb +0 -9
- data/spec/dummy/app/views/home/index.html.erb +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +0 -14
- data/spec/dummy/config/application.rb +0 -57
- data/spec/dummy/config/boot.rb +0 -9
- data/spec/dummy/config/database.yml +0 -15
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/development.rb +0 -29
- data/spec/dummy/config/environments/production.rb +0 -62
- data/spec/dummy/config/environments/test.rb +0 -55
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummy/config/initializers/doorkeeper.rb +0 -96
- data/spec/dummy/config/initializers/secret_token.rb +0 -9
- data/spec/dummy/config/initializers/session_store.rb +0 -8
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
- data/spec/dummy/config/routes.rb +0 -52
- data/spec/dummy/config.ru +0 -4
- data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -9
- data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -5
- data/spec/dummy/db/migrate/20130902165751_create_doorkeeper_tables.rb +0 -41
- data/spec/dummy/db/migrate/20130902175349_add_owner_to_application.rb +0 -7
- data/spec/dummy/db/migrate/20141209001746_add_scopes_to_oauth_applications.rb +0 -5
- data/spec/dummy/db/schema.rb +0 -66
- data/spec/dummy/public/404.html +0 -26
- data/spec/dummy/public/422.html +0 -26
- data/spec/dummy/public/500.html +0 -26
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +0 -6
- data/spec/factories.rb +0 -26
- data/spec/generators/application_owner_generator_spec.rb +0 -22
- data/spec/generators/install_generator_spec.rb +0 -31
- data/spec/generators/migration_generator_spec.rb +0 -20
- data/spec/generators/templates/routes.rb +0 -3
- data/spec/generators/views_generator_spec.rb +0 -27
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -24
- data/spec/lib/config_spec.rb +0 -317
- data/spec/lib/doorkeeper_spec.rb +0 -28
- data/spec/lib/models/expirable_spec.rb +0 -51
- data/spec/lib/models/revocable_spec.rb +0 -36
- data/spec/lib/models/scopes_spec.rb +0 -43
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -42
- data/spec/lib/oauth/authorization_code_request_spec.rb +0 -80
- data/spec/lib/oauth/client/credentials_spec.rb +0 -47
- data/spec/lib/oauth/client/methods_spec.rb +0 -54
- data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -44
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -86
- data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -54
- data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
- data/spec/lib/oauth/client_credentials_request_spec.rb +0 -104
- data/spec/lib/oauth/client_spec.rb +0 -39
- data/spec/lib/oauth/code_request_spec.rb +0 -45
- data/spec/lib/oauth/error_response_spec.rb +0 -61
- data/spec/lib/oauth/error_spec.rb +0 -23
- data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -23
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -64
- data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -20
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -104
- data/spec/lib/oauth/invalid_token_response_spec.rb +0 -28
- data/spec/lib/oauth/password_access_token_request_spec.rb +0 -90
- data/spec/lib/oauth/pre_authorization_spec.rb +0 -155
- data/spec/lib/oauth/refresh_token_request_spec.rb +0 -123
- data/spec/lib/oauth/scopes_spec.rb +0 -123
- data/spec/lib/oauth/token_request_spec.rb +0 -98
- data/spec/lib/oauth/token_response_spec.rb +0 -85
- data/spec/lib/oauth/token_spec.rb +0 -109
- data/spec/lib/request/strategy_spec.rb +0 -53
- data/spec/lib/server_spec.rb +0 -52
- data/spec/models/doorkeeper/access_grant_spec.rb +0 -36
- data/spec/models/doorkeeper/access_token_spec.rb +0 -350
- data/spec/models/doorkeeper/application_spec.rb +0 -187
- data/spec/requests/applications/applications_request_spec.rb +0 -94
- data/spec/requests/applications/authorized_applications_spec.rb +0 -30
- data/spec/requests/endpoints/authorization_spec.rb +0 -72
- data/spec/requests/endpoints/token_spec.rb +0 -64
- data/spec/requests/flows/authorization_code_errors_spec.rb +0 -66
- data/spec/requests/flows/authorization_code_spec.rb +0 -156
- data/spec/requests/flows/client_credentials_spec.rb +0 -58
- data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -32
- data/spec/requests/flows/implicit_grant_spec.rb +0 -61
- data/spec/requests/flows/password_spec.rb +0 -94
- data/spec/requests/flows/refresh_token_spec.rb +0 -104
- data/spec/requests/flows/revoke_token_spec.rb +0 -143
- data/spec/requests/flows/skip_authorization_spec.rb +0 -59
- data/spec/requests/protected_resources/metal_spec.rb +0 -14
- data/spec/requests/protected_resources/private_api_spec.rb +0 -81
- data/spec/routing/custom_controller_routes_spec.rb +0 -71
- data/spec/routing/default_routes_spec.rb +0 -35
- data/spec/routing/scoped_routes_spec.rb +0 -31
- data/spec/spec_helper.rb +0 -2
- data/spec/spec_helper_integration.rb +0 -56
- data/spec/support/dependencies/factory_girl.rb +0 -2
- data/spec/support/helpers/access_token_request_helper.rb +0 -11
- data/spec/support/helpers/authorization_request_helper.rb +0 -41
- data/spec/support/helpers/config_helper.rb +0 -9
- data/spec/support/helpers/model_helper.rb +0 -45
- data/spec/support/helpers/request_spec_helper.rb +0 -76
- data/spec/support/helpers/url_helper.rb +0 -55
- data/spec/support/orm/active_record.rb +0 -3
- data/spec/support/shared/controllers_shared_context.rb +0 -60
- data/spec/support/shared/models_shared_examples.rb +0 -52
- data/spec/validators/redirect_uri_validator_spec.rb +0 -78
data/README.md
CHANGED
@@ -1,341 +1,155 @@
|
|
1
|
-
# Doorkeeper
|
1
|
+
# Doorkeeper — awesome OAuth 2 provider for your Rails / Grape app.
|
2
2
|
|
3
|
-
[![Build Status](https://travis-ci.org/doorkeeper-gem/doorkeeper.svg?branch=master)](https://travis-ci.org/doorkeeper-gem/doorkeeper)
|
4
|
-
[![Dependency Status](https://gemnasium.com/applicake/doorkeeper.svg?travis)](https://gemnasium.com/applicake/doorkeeper)
|
5
|
-
[![Code Climate](https://codeclimate.com/github/applicake/doorkeeper.svg)](https://codeclimate.com/github/applicake/doorkeeper)
|
6
3
|
[![Gem Version](https://badge.fury.io/rb/doorkeeper.svg)](https://rubygems.org/gems/doorkeeper)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
[
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
4
|
+
[![CI](https://github.com/doorkeeper-gem/doorkeeper/actions/workflows/ci.yml/badge.svg)](https://github.com/doorkeeper-gem/doorkeeper/actions/workflows/ci.yml)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/doorkeeper-gem/doorkeeper.svg)](https://codeclimate.com/github/doorkeeper-gem/doorkeeper)
|
6
|
+
[![Coverage Status](https://coveralls.io/repos/github/doorkeeper-gem/doorkeeper/badge.svg?branch=main)](https://coveralls.io/github/doorkeeper-gem/doorkeeper?branch=main)
|
7
|
+
[![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com)
|
8
|
+
[![GuardRails badge](https://badges.guardrails.io/doorkeeper-gem/doorkeeper.svg?token=66768ce8f6995814df81f65a2cff40f739f688492704f973e62809e15599bb62)](https://dashboard.guardrails.io/default/gh/doorkeeper-gem/doorkeeper)
|
9
|
+
[![Dependabot](https://img.shields.io/badge/dependabot-enabled-success.svg)](https://dependabot.com)
|
10
|
+
|
11
|
+
Doorkeeper is a gem (Rails engine) that makes it easy to introduce OAuth 2 provider
|
12
|
+
functionality to your Ruby on Rails or Grape application.
|
13
|
+
|
14
|
+
Supported features:
|
15
|
+
|
16
|
+
- [The OAuth 2.0 Authorization Framework](https://datatracker.ietf.org/doc/html/rfc6749)
|
17
|
+
- [Authorization Code Flow](https://datatracker.ietf.org/doc/html/rfc6749#section-4.1)
|
18
|
+
- [Access Token Scopes](https://datatracker.ietf.org/doc/html/rfc6749#section-3.3)
|
19
|
+
- [Refresh token](https://datatracker.ietf.org/doc/html/rfc6749#section-1.5)
|
20
|
+
- [Implicit grant](https://datatracker.ietf.org/doc/html/rfc6749#section-4.2)
|
21
|
+
- [Resource Owner Password Credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3)
|
22
|
+
- [Client Credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-4.4)
|
23
|
+
- [OAuth 2.0 Token Revocation](https://datatracker.ietf.org/doc/html/rfc7009)
|
24
|
+
- [OAuth 2.0 Token Introspection](https://datatracker.ietf.org/doc/html/rfc7662)
|
25
|
+
- [OAuth 2.0 Threat Model and Security Considerations](https://datatracker.ietf.org/doc/html/rfc6819)
|
26
|
+
- [OAuth 2.0 for Native Apps](https://datatracker.ietf.org/doc/html/rfc8252)
|
27
|
+
- [Proof Key for Code Exchange by OAuth Public Clients](https://datatracker.ietf.org/doc/html/rfc7636)
|
18
28
|
|
19
29
|
## Table of Contents
|
20
30
|
|
21
31
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
22
32
|
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
23
|
-
|
33
|
+
|
34
|
+
|
35
|
+
- [Documentation](#documentation)
|
24
36
|
- [Installation](#installation)
|
25
|
-
- [
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
- [
|
32
|
-
- [Protect your API with OAuth when using Grape](#protect-your-api-with-oauth-when-using-grape)
|
33
|
-
- [Route Constraints and other integrations](#route-constraints-and-other-integrations)
|
34
|
-
- [Access Token Scopes](#access-token-scopes)
|
35
|
-
- [Custom Access Token Generator](#custom-access-token-generator)
|
36
|
-
- [Authenticated resource owner](#authenticated-resource-owner)
|
37
|
-
- [Applications list](#applications-list)
|
38
|
-
- [Other customizations](#other-customizations)
|
39
|
-
- [Upgrading](#upgrading)
|
37
|
+
- [Ruby on Rails](#ruby-on-rails)
|
38
|
+
- [Grape](#grape)
|
39
|
+
- [ORMs](#orms)
|
40
|
+
- [Extensions](#extensions)
|
41
|
+
- [Example Applications](#example-applications)
|
42
|
+
- [Tutorials](#tutorials)
|
43
|
+
- [Sponsors](#sponsors)
|
40
44
|
- [Development](#development)
|
41
45
|
- [Contributing](#contributing)
|
42
|
-
- [
|
43
|
-
|
44
|
-
- [Screencast](#screencast)
|
45
|
-
- [Client applications](#client-applications)
|
46
|
-
- [Contributors](#contributors)
|
47
|
-
- [IETF Standards](#ietf-standards)
|
48
|
-
- [License](#license)
|
49
|
-
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
50
|
-
|
51
|
-
|
52
|
-
## Useful links
|
53
|
-
|
54
|
-
- For documentation, please check out our [wiki](https://github.com/doorkeeper-gem/doorkeeper/wiki)
|
55
|
-
- For general questions, please post it in [stack overflow](http://stackoverflow.com/questions/tagged/doorkeeper)
|
56
|
-
|
57
|
-
## Installation
|
58
|
-
|
59
|
-
Put this in your Gemfile:
|
60
|
-
|
61
|
-
``` ruby
|
62
|
-
gem 'doorkeeper'
|
63
|
-
```
|
64
|
-
|
65
|
-
Run the installation generator with:
|
66
|
-
|
67
|
-
rails generate doorkeeper:install
|
68
|
-
|
69
|
-
This will install the doorkeeper initializer into `config/initializers/doorkeeper.rb`.
|
70
|
-
|
71
|
-
## Configuration
|
72
|
-
|
73
|
-
### Active Record
|
74
|
-
|
75
|
-
By default doorkeeper is configured to use active record, so to start you have
|
76
|
-
to generate the migration tables:
|
77
|
-
|
78
|
-
rails generate doorkeeper:migration
|
79
|
-
|
80
|
-
Don't forget to run the migration with:
|
81
|
-
|
82
|
-
rake db:migrate
|
83
|
-
|
84
|
-
### Other ORMs
|
85
|
-
|
86
|
-
See [doorkeeper-mongodb project] for mongoid and mongomapper support. Follow along
|
87
|
-
the implementation in that repository to extend doorkeeper with other ORMs.
|
88
|
-
|
89
|
-
[doorkeeper-mongodb project]: https://github.com/doorkeeper-gem/doorkeeper-mongodb
|
90
|
-
|
91
|
-
### Routes
|
92
|
-
|
93
|
-
The installation script will also automatically add the Doorkeeper routes into
|
94
|
-
your app, like this:
|
95
|
-
|
96
|
-
``` ruby
|
97
|
-
Rails.application.routes.draw do
|
98
|
-
use_doorkeeper
|
99
|
-
# your routes
|
100
|
-
end
|
101
|
-
```
|
102
|
-
|
103
|
-
This will mount following routes:
|
104
|
-
|
105
|
-
GET /oauth/authorize/:code
|
106
|
-
GET /oauth/authorize
|
107
|
-
POST /oauth/authorize
|
108
|
-
DELETE /oauth/authorize
|
109
|
-
POST /oauth/token
|
110
|
-
POST /oauth/revoke
|
111
|
-
resources /oauth/applications
|
112
|
-
GET /oauth/authorized_applications
|
113
|
-
DELETE /oauth/authorized_applications/:id
|
114
|
-
GET /oauth/token/info
|
115
|
-
|
116
|
-
For more information on how to customize routes, check out [this page on the
|
117
|
-
wiki](https://github.com/doorkeeper-gem/doorkeeper/wiki/Customizing-routes).
|
118
|
-
|
119
|
-
### Authenticating
|
120
|
-
|
121
|
-
You need to configure Doorkeeper in order to provide `resource_owner` model
|
122
|
-
and authentication block `initializers/doorkeeper.rb`
|
123
|
-
|
124
|
-
``` ruby
|
125
|
-
Doorkeeper.configure do
|
126
|
-
resource_owner_authenticator do
|
127
|
-
User.find_by_id(session[:current_user_id]) || redirect_to(login_url)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
```
|
131
|
-
|
132
|
-
This code is run in the context of your application so you have access to your
|
133
|
-
models, session or routes helpers. However, since this code is not run in the
|
134
|
-
context of your application's `ApplicationController` it doesn't have access to
|
135
|
-
the methods defined over there.
|
136
|
-
|
137
|
-
You may want to check other ways of authentication
|
138
|
-
[here](https://github.com/doorkeeper-gem/doorkeeper/wiki/Authenticating-using-Clearance-or-DIY).
|
139
|
-
|
140
|
-
|
141
|
-
### Internationalization (I18n)
|
142
|
-
|
143
|
-
See language files in [the I18n repository](https://github.com/doorkeeper-gem/doorkeeper-i18n).
|
144
|
-
|
145
|
-
|
146
|
-
## Protecting resources with OAuth (a.k.a your API endpoint)
|
147
|
-
|
148
|
-
To protect your API with OAuth, you just need to setup `before_action`s
|
149
|
-
specifying the actions you want to protect. For example:
|
150
|
-
|
151
|
-
``` ruby
|
152
|
-
class Api::V1::ProductsController < Api::V1::ApiController
|
153
|
-
before_action :doorkeeper_authorize! # Require access token for all actions
|
154
|
-
|
155
|
-
# your actions
|
156
|
-
end
|
157
|
-
```
|
158
|
-
|
159
|
-
You can pass any option `before_action` accepts, such as `if`, `only`,
|
160
|
-
`except`, and others.
|
46
|
+
- [Contributors](#contributors)
|
47
|
+
- [License](#license)
|
161
48
|
|
162
|
-
|
163
|
-
|
164
|
-
As of [PR 567] doorkeeper has helpers for Grape. One of them is
|
165
|
-
`doorkeeper_authorize!` and can be used in a similar way as an example above.
|
166
|
-
Note that you have to use `require 'doorkeeper/grape/helpers'` and
|
167
|
-
`helpers Doorkeeper::Grape::Helpers`.
|
168
|
-
|
169
|
-
For more information about integration with Grape see the [Wiki].
|
170
|
-
|
171
|
-
[PR 567]: https://github.com/doorkeeper-gem/doorkeeper/pull/567
|
172
|
-
[Wiki]: https://github.com/doorkeeper-gem/doorkeeper/wiki/Grape-Integration
|
173
|
-
|
174
|
-
``` ruby
|
175
|
-
require 'doorkeeper/grape/helpers'
|
49
|
+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
176
50
|
|
177
|
-
|
178
|
-
module V1
|
179
|
-
class Users < Grape::API
|
180
|
-
helpers Doorkeeper::Grape::Helpers
|
51
|
+
## Documentation
|
181
52
|
|
182
|
-
|
183
|
-
|
184
|
-
end
|
53
|
+
This documentation is valid for `main` branch. Please check the documentation for the version of doorkeeper you are using in:
|
54
|
+
https://github.com/doorkeeper-gem/doorkeeper/releases.
|
185
55
|
|
186
|
-
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
190
|
-
```
|
56
|
+
Additionally, other resources can be found on:
|
191
57
|
|
58
|
+
- [Guides](https://doorkeeper.gitbook.io/guides/) with how-to get started and configuration documentation
|
59
|
+
- See the [Wiki](https://github.com/doorkeeper-gem/doorkeeper/wiki) with articles and other documentation
|
60
|
+
- Screencast from [railscasts.com](http://railscasts.com/): [#353
|
61
|
+
OAuth with
|
62
|
+
Doorkeeper](http://railscasts.com/episodes/353-oauth-with-doorkeeper)
|
63
|
+
- See [upgrade guides](https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions)
|
64
|
+
- For general questions, please post on [Stack Overflow](http://stackoverflow.com/questions/tagged/doorkeeper)
|
65
|
+
- See [SECURITY.md](SECURITY.md) for this project's security disclose
|
66
|
+
policy
|
192
67
|
|
193
|
-
|
68
|
+
## Installation
|
194
69
|
|
195
|
-
|
196
|
-
`Doorkeeper::OAuth::Token` based on the current request. You can then ensure
|
197
|
-
that token is still good, find its associated `#resource_owner_id`, etc.
|
70
|
+
Installation depends on the framework you're using. The first step is to add the following to your Gemfile:
|
198
71
|
|
199
72
|
```ruby
|
200
|
-
|
201
|
-
class Authenticated
|
202
|
-
|
203
|
-
def matches?(request)
|
204
|
-
token = Doorkeeper.authenticate(request)
|
205
|
-
token && token.accessible?
|
206
|
-
end
|
207
|
-
|
208
|
-
end
|
209
|
-
end
|
73
|
+
gem 'doorkeeper'
|
210
74
|
```
|
211
75
|
|
212
|
-
|
213
|
-
related wiki
|
214
|
-
page](https://github.com/doorkeeper-gem/doorkeeper/wiki/ActionController::Metal-with-doorkeeper).
|
76
|
+
And run `bundle install`. After this, check out the guide related to the framework you're using.
|
215
77
|
|
216
|
-
###
|
78
|
+
### Ruby on Rails
|
217
79
|
|
218
|
-
|
219
|
-
actions:
|
80
|
+
Doorkeeper currently supports Ruby on Rails >= 5.0. See the guide [here](https://doorkeeper.gitbook.io/guides/ruby-on-rails/getting-started).
|
220
81
|
|
221
|
-
|
82
|
+
### Grape
|
222
83
|
|
223
|
-
|
224
|
-
Doorkeeper.configure do
|
225
|
-
default_scopes :public # if no scope was requested, this will be the default
|
226
|
-
optional_scopes :admin, :write
|
227
|
-
end
|
228
|
-
```
|
84
|
+
Guide for integration with Grape framework can be found [here](https://doorkeeper.gitbook.io/guides/grape/grape).
|
229
85
|
|
230
|
-
|
86
|
+
## ORMs
|
231
87
|
|
232
|
-
|
233
|
-
class Api::V1::ProductsController < Api::V1::ApiController
|
234
|
-
before_action -> { doorkeeper_authorize! :public }, only: :index
|
235
|
-
before_action only: [:create, :update, :destroy] do
|
236
|
-
doorkeeper_authorize! :admin, :write
|
237
|
-
end
|
238
|
-
end
|
239
|
-
```
|
88
|
+
Doorkeeper supports Active Record by default, but can be configured to work with the following ORMs:
|
240
89
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
90
|
+
| ORM | Support via |
|
91
|
+
| :--- | :--- |
|
92
|
+
| Active Record | by default |
|
93
|
+
| MongoDB | [doorkeeper-gem/doorkeeper-mongodb](https://github.com/doorkeeper-gem/doorkeeper-mongodb) |
|
94
|
+
| Sequel | [nbulaj/doorkeeper-sequel](https://github.com/nbulaj/doorkeeper-sequel) |
|
95
|
+
| Couchbase | [acaprojects/doorkeeper-couchbase](https://github.com/acaprojects/doorkeeper-couchbase) |
|
96
|
+
| RethinkDB | [aca-labs/doorkeeper-rethinkdb](https://github.com/aca-labs/doorkeeper-rethinkdb) |
|
245
97
|
|
246
|
-
|
247
|
-
use multiple `doorkeeper_authorize!`, for example:
|
98
|
+
## Extensions
|
248
99
|
|
249
|
-
|
250
|
-
class Api::V1::ProductsController < Api::V1::ApiController
|
251
|
-
before_action -> { doorkeeper_authorize! :public }, only: :index
|
252
|
-
before_action only: [:create, :update, :destroy] do
|
253
|
-
doorkeeper_authorize! :admin
|
254
|
-
doorkeeper_authorize! :write
|
255
|
-
end
|
256
|
-
end
|
257
|
-
```
|
258
|
-
|
259
|
-
In above example, a client can call `:create` action only if its access token
|
260
|
-
have both `:admin` and `:write` scopes.
|
261
|
-
|
262
|
-
### Custom Access Token Generator
|
263
|
-
|
264
|
-
By default a 128 bit access token will be generated. If you require a custom
|
265
|
-
token, such as [JWT](http://jwt.io), specify an object that responds to
|
266
|
-
`.generate(options = {})` and returns a string to be used as the token.
|
267
|
-
|
268
|
-
```ruby
|
269
|
-
Doorkeeper.configure do
|
270
|
-
access_token_generator "Doorkeeper::JWT"
|
271
|
-
end
|
272
|
-
```
|
100
|
+
Extensions that are not included by default and can be installed separately.
|
273
101
|
|
274
|
-
|
275
|
-
|
102
|
+
| | Link |
|
103
|
+
| :--- | :--- |
|
104
|
+
| OpenID Connect extension | [doorkeeper-gem/doorkeeper-openid\_connect](https://github.com/doorkeeper-gem/doorkeeper-openid_connect) |
|
105
|
+
| JWT Token support | [doorkeeper-gem/doorkeeper-jwt](https://github.com/doorkeeper-gem/doorkeeper-jwt) |
|
106
|
+
| Assertion grant extension | [doorkeeper-gem/doorkeeper-grants\_assertion](https://github.com/doorkeeper-gem/doorkeeper-grants_assertion) |
|
107
|
+
| I18n translations | [doorkeeper-gem/doorkeeper-i18n](https://github.com/doorkeeper-gem/doorkeeper-i18n) |
|
108
|
+
| CIBA - Client Initiated Backchannel Authentication Flow extention | [doorkeeper-ciba](https://github.com/autoseg/doorkeeper-ciba) |
|
109
|
+
| Device Authorization Grant | [doorkeeper-device_authorization_grant](https://github.com/exop-group/doorkeeper-device_authorization_grant) |
|
276
110
|
|
111
|
+
## Example Applications
|
277
112
|
|
278
|
-
|
113
|
+
These applications show how Doorkeeper works and how to integrate with it. Start with the oAuth2 server and use the clients to connect with the server.
|
279
114
|
|
280
|
-
|
281
|
-
|
282
|
-
|
115
|
+
| Application | Link |
|
116
|
+
| :--- | :--- |
|
117
|
+
| OAuth2 Server with Doorkeeper | [doorkeeper-gem/doorkeeper-provider-app](https://github.com/doorkeeper-gem/doorkeeper-provider-app) |
|
118
|
+
| Sinatra Client connected to Provider App | [doorkeeper-gem/doorkeeper-sinatra-client](https://github.com/doorkeeper-gem/doorkeeper-sinatra-client) |
|
119
|
+
| Devise + Omniauth Client | [doorkeeper-gem/doorkeeper-devise-client](https://github.com/doorkeeper-gem/doorkeeper-devise-client) |
|
283
120
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
121
|
+
You may want to create a client application to
|
122
|
+
test the integration. Check out these [client
|
123
|
+
examples](https://github.com/doorkeeper-gem/doorkeeper/wiki/Example-Applications)
|
124
|
+
in our wiki or follow this [tutorial
|
125
|
+
here](https://github.com/doorkeeper-gem/doorkeeper/wiki/Testing-your-provider-with-OAuth2-gem).
|
288
126
|
|
289
|
-
|
290
|
-
def me
|
291
|
-
respond_with current_resource_owner
|
292
|
-
end
|
127
|
+
## Tutorials
|
293
128
|
|
294
|
-
|
129
|
+
See [list of tutorials](https://github.com/doorkeeper-gem/doorkeeper/wiki#how-tos--tutorials) in order to learn how to use the gem or integrate it with other solutions / gems.
|
295
130
|
|
296
|
-
|
297
|
-
def current_resource_owner
|
298
|
-
User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
|
299
|
-
end
|
300
|
-
end
|
301
|
-
```
|
131
|
+
## Sponsors
|
302
132
|
|
303
|
-
|
304
|
-
|
133
|
+
[![OpenCollective](https://opencollective.com/doorkeeper-gem/backers/badge.svg)](#backers)
|
134
|
+
[![OpenCollective](https://opencollective.com/doorkeeper-gem/sponsors/badge.svg)](#sponsors)
|
305
135
|
|
306
|
-
|
136
|
+
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/doorkeeper-gem#sponsor)]
|
307
137
|
|
308
|
-
|
309
|
-
To protect the endpoint you should uncomment these lines:
|
138
|
+
<a href="https://codecademy.com/about/careers?utm_source=doorkeeper-gem" target="_blank"><img src="https://static-assets.codecademy.com/marketing/codecademy_logo_padded.png"/></a>
|
310
139
|
|
311
|
-
|
312
|
-
# config/initializers/doorkeeper.rb
|
313
|
-
Doorkeeper.configure do
|
314
|
-
admin_authenticator do |routes|
|
315
|
-
Admin.find_by_id(session[:admin_id]) || redirect_to(routes.new_admin_session_url)
|
316
|
-
end
|
317
|
-
end
|
318
|
-
```
|
140
|
+
> Codecademy supports open source as part of its mission to democratize tech. Come help us build the education the world deserves: [https://codecademy.com/about/careers](https://codecademy.com/about/careers?utm_source=doorkeeper-gem)
|
319
141
|
|
320
|
-
|
321
|
-
since the application list is just a scaffold, it's recommended to either
|
322
|
-
customize the controller used by the list or skip the controller at all. For
|
323
|
-
more information see the page [in the
|
324
|
-
wiki](https://github.com/doorkeeper-gem/doorkeeper/wiki/Customizing-routes).
|
142
|
+
<br>
|
325
143
|
|
326
|
-
|
144
|
+
<a href="https://oauth.io/?utm_source=doorkeeper-gem" target="_blank"><img src="https://oauth.io/img/logo_text.png"/></a>
|
327
145
|
|
328
|
-
|
329
|
-
- [CORS - Cross Origin Resource Sharing](https://github.com/doorkeeper-gem/doorkeeper/wiki/%5BCORS%5D-Cross-Origin-Resource-Sharing)
|
146
|
+
> If you prefer not to deal with the gory details of OAuth 2, need dedicated customer support & consulting, try the cloud-based SaaS version: [https://oauth.io](https://oauth.io/?utm_source=doorkeeper-gem)
|
330
147
|
|
331
|
-
|
148
|
+
<br>
|
332
149
|
|
333
|
-
|
334
|
-
notes](https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions)
|
335
|
-
and take a look at the
|
336
|
-
[changelog](https://github.com/doorkeeper-gem/doorkeeper/blob/master/NEWS.md).
|
150
|
+
<a href="https://www.wealthsimple.com/?utm_source=doorkeeper-gem" target="_blank"><img src="https://wealthsimple.s3.amazonaws.com/branding/medium-black.svg"/></a>
|
337
151
|
|
338
|
-
|
152
|
+
> Wealthsimple is a financial company on a mission to help everyone achieve financial freedom by providing products and advice that are accessible and affordable. Using smart technology, Wealthsimple takes financial services that are often confusing, opaque and expensive and makes them simple, transparent, and low-cost. See what Investing on Autopilot is all about: [https://www.wealthsimple.com](https://www.wealthsimple.com/?utm_source=doorkeeper-gem)
|
339
153
|
|
340
154
|
## Development
|
341
155
|
|
@@ -343,17 +157,18 @@ To run the local engine server:
|
|
343
157
|
|
344
158
|
```
|
345
159
|
bundle install
|
346
|
-
bundle exec
|
160
|
+
bundle exec rake doorkeeper:server
|
347
161
|
````
|
348
162
|
|
349
163
|
By default, it uses the latest Rails version with ActiveRecord. To run the
|
350
|
-
tests with a specific
|
164
|
+
tests with a specific Rails version:
|
351
165
|
|
352
166
|
```
|
353
|
-
|
167
|
+
BUNDLE_GEMFILE=gemfiles/rails_6_0.gemfile bundle exec rake
|
354
168
|
```
|
355
169
|
|
356
|
-
|
170
|
+
You can also experiment with the changes using `bin/console`. It uses in-memory SQLite database and default
|
171
|
+
Doorkeeper config, but you can reestablish connection or reconfigure the gem if you need.
|
357
172
|
|
358
173
|
## Contributing
|
359
174
|
|
@@ -363,42 +178,15 @@ create [example
|
|
363
178
|
apps](https://github.com/doorkeeper-gem/doorkeeper/wiki/Example-Applications),
|
364
179
|
integrate the gem with your app and let us know!
|
365
180
|
|
366
|
-
Also, check out our [contributing guidelines
|
367
|
-
page](https://github.com/doorkeeper-gem/doorkeeper/wiki/Contributing).
|
368
|
-
|
369
|
-
## Other resources
|
181
|
+
Also, check out our [contributing guidelines page](CONTRIBUTING.md).
|
370
182
|
|
371
|
-
|
372
|
-
|
373
|
-
You can find everything about doorkeeper in our [wiki
|
374
|
-
here](https://github.com/doorkeeper-gem/doorkeeper/wiki).
|
375
|
-
|
376
|
-
### Screencast
|
377
|
-
|
378
|
-
Check out this screencast from [railscasts.com](http://railscasts.com/): [#353
|
379
|
-
OAuth with
|
380
|
-
Doorkeeper](http://railscasts.com/episodes/353-oauth-with-doorkeeper)
|
381
|
-
|
382
|
-
### Client applications
|
383
|
-
|
384
|
-
After you set up the provider, you may want to create a client application to
|
385
|
-
test the integration. Check out these [client
|
386
|
-
examples](https://github.com/doorkeeper-gem/doorkeeper/wiki/Example-Applications)
|
387
|
-
in our wiki or follow this [tutorial
|
388
|
-
here](https://github.com/doorkeeper-gem/doorkeeper/wiki/Testing-your-provider-with-OAuth2-gem).
|
389
|
-
|
390
|
-
### Contributors
|
183
|
+
## Contributors
|
391
184
|
|
392
185
|
Thanks to all our [awesome
|
393
186
|
contributors](https://github.com/doorkeeper-gem/doorkeeper/graphs/contributors)!
|
394
187
|
|
188
|
+
<a href="https://github.com/doorkeeper-gem/doorkeeper/graphs/contributors"><img src="https://opencollective.com/doorkeeper-gem/contributors.svg?width=890&button=false" /></a>
|
395
189
|
|
396
|
-
|
397
|
-
|
398
|
-
* [The OAuth 2.0 Authorization Framework](http://tools.ietf.org/html/rfc6749)
|
399
|
-
* [OAuth 2.0 Threat Model and Security Considerations](http://tools.ietf.org/html/rfc6819)
|
400
|
-
* [OAuth 2.0 Token Revocation](http://tools.ietf.org/html/rfc7009)
|
401
|
-
|
402
|
-
### License
|
190
|
+
## License
|
403
191
|
|
404
|
-
MIT License.
|
192
|
+
MIT License. Created in Applicake. Maintained by the community.
|
@@ -1,13 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doorkeeper
|
2
|
-
class ApplicationController <
|
4
|
+
class ApplicationController <
|
5
|
+
Doorkeeper.config.resolve_controller(:base)
|
3
6
|
include Helpers::Controller
|
7
|
+
include ActionController::MimeResponds if Doorkeeper.config.api_only
|
4
8
|
|
5
|
-
|
6
|
-
protect_from_forgery
|
7
|
-
else
|
9
|
+
unless Doorkeeper.config.api_only
|
8
10
|
protect_from_forgery with: :exception
|
11
|
+
helper "doorkeeper/dashboard"
|
9
12
|
end
|
10
|
-
|
11
|
-
helper 'doorkeeper/dashboard'
|
12
13
|
end
|
13
14
|
end
|
@@ -1,16 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doorkeeper
|
2
|
-
class ApplicationMetalController <
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
ActionController::Renderers::All,
|
9
|
-
Helpers::Controller
|
10
|
-
]
|
4
|
+
class ApplicationMetalController <
|
5
|
+
Doorkeeper.config.resolve_controller(:base_metal)
|
6
|
+
include Helpers::Controller
|
7
|
+
|
8
|
+
before_action :enforce_content_type,
|
9
|
+
if: -> { Doorkeeper.config.enforce_content_type }
|
11
10
|
|
12
|
-
|
13
|
-
include mod
|
14
|
-
end
|
11
|
+
ActiveSupport.run_load_hooks(:doorkeeper_metal_controller, self)
|
15
12
|
end
|
16
13
|
end
|