Showing preview only (930K chars total). Download the full file or copy to clipboard to get everything.
Repository: applicake/doorkeeper
Branch: main
Commit: df16e5553035
Files: 326
Total size: 843.7 KB
Directory structure:
gitextract_wns691gx/
├── .codeclimate.yml
├── .coveralls.yml
├── .dockerignore
├── .editorconfig
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── dependabot.yml
│ └── workflows/
│ ├── changelog.yml
│ ├── ci.yml
│ └── rubocop.yml
├── .gitignore
├── .hound.yml
├── .rspec
├── .rubocop.yml
├── .rubocop_todo.yml
├── AGENTS.md
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── Gemfile
├── MIT-LICENSE
├── NEWS.md
├── README.md
├── RELEASING.md
├── Rakefile
├── SECURITY.md
├── UPGRADE.md
├── app/
│ ├── assets/
│ │ └── stylesheets/
│ │ └── doorkeeper/
│ │ ├── admin/
│ │ │ └── application.css
│ │ └── application.css
│ ├── controllers/
│ │ └── doorkeeper/
│ │ ├── application_controller.rb
│ │ ├── application_metal_controller.rb
│ │ ├── applications_controller.rb
│ │ ├── authorizations_controller.rb
│ │ ├── authorized_applications_controller.rb
│ │ ├── token_info_controller.rb
│ │ └── tokens_controller.rb
│ ├── helpers/
│ │ └── doorkeeper/
│ │ └── dashboard_helper.rb
│ └── views/
│ ├── doorkeeper/
│ │ ├── applications/
│ │ │ ├── _delete_form.html.erb
│ │ │ ├── _form.html.erb
│ │ │ ├── edit.html.erb
│ │ │ ├── index.html.erb
│ │ │ ├── new.html.erb
│ │ │ └── show.html.erb
│ │ ├── authorizations/
│ │ │ ├── error.html.erb
│ │ │ ├── form_post.html.erb
│ │ │ ├── new.html.erb
│ │ │ └── show.html.erb
│ │ └── authorized_applications/
│ │ ├── _delete_form.html.erb
│ │ └── index.html.erb
│ └── layouts/
│ └── doorkeeper/
│ ├── admin.html.erb
│ └── application.html.erb
├── benchmark/
│ ├── ruby/
│ │ └── client_credentials.rb
│ └── wrk/
│ └── .keep
├── bin/
│ └── console
├── config/
│ └── locales/
│ └── en.yml
├── doorkeeper.gemspec
├── gemfiles/
│ ├── rails_7_0.gemfile
│ ├── rails_7_1.gemfile
│ ├── rails_7_2.gemfile
│ ├── rails_8_0.gemfile
│ └── rails_edge.gemfile
├── lib/
│ ├── doorkeeper/
│ │ ├── config/
│ │ │ ├── abstract_builder.rb
│ │ │ ├── option.rb
│ │ │ └── validations.rb
│ │ ├── config.rb
│ │ ├── engine.rb
│ │ ├── errors.rb
│ │ ├── grant_flow/
│ │ │ ├── fallback_flow.rb
│ │ │ ├── flow.rb
│ │ │ └── registry.rb
│ │ ├── grant_flow.rb
│ │ ├── grape/
│ │ │ ├── authorization_decorator.rb
│ │ │ └── helpers.rb
│ │ ├── helpers/
│ │ │ └── controller.rb
│ │ ├── models/
│ │ │ ├── access_grant_mixin.rb
│ │ │ ├── access_token_mixin.rb
│ │ │ ├── application_mixin.rb
│ │ │ └── concerns/
│ │ │ ├── accessible.rb
│ │ │ ├── expirable.rb
│ │ │ ├── expiration_time_sql_math.rb
│ │ │ ├── orderable.rb
│ │ │ ├── ownership.rb
│ │ │ ├── polymorphic_resource_owner.rb
│ │ │ ├── resource_ownerable.rb
│ │ │ ├── reusable.rb
│ │ │ ├── revocable.rb
│ │ │ ├── scopes.rb
│ │ │ ├── secret_storable.rb
│ │ │ └── write_to_primary.rb
│ │ ├── oauth/
│ │ │ ├── authorization/
│ │ │ │ ├── code.rb
│ │ │ │ ├── context.rb
│ │ │ │ ├── token.rb
│ │ │ │ └── uri_builder.rb
│ │ │ ├── authorization_code_request.rb
│ │ │ ├── base_request.rb
│ │ │ ├── base_response.rb
│ │ │ ├── client/
│ │ │ │ └── credentials.rb
│ │ │ ├── client.rb
│ │ │ ├── client_credentials/
│ │ │ │ ├── creator.rb
│ │ │ │ ├── issuer.rb
│ │ │ │ └── validator.rb
│ │ │ ├── client_credentials_request.rb
│ │ │ ├── code_request.rb
│ │ │ ├── code_response.rb
│ │ │ ├── error.rb
│ │ │ ├── error_response.rb
│ │ │ ├── forbidden_token_response.rb
│ │ │ ├── helpers/
│ │ │ │ ├── scope_checker.rb
│ │ │ │ ├── unique_token.rb
│ │ │ │ └── uri_checker.rb
│ │ │ ├── hooks/
│ │ │ │ └── context.rb
│ │ │ ├── invalid_request_response.rb
│ │ │ ├── invalid_token_response.rb
│ │ │ ├── nonstandard.rb
│ │ │ ├── password_access_token_request.rb
│ │ │ ├── pre_authorization.rb
│ │ │ ├── refresh_token_request.rb
│ │ │ ├── scopes.rb
│ │ │ ├── token.rb
│ │ │ ├── token_introspection.rb
│ │ │ ├── token_request.rb
│ │ │ └── token_response.rb
│ │ ├── oauth.rb
│ │ ├── orm/
│ │ │ ├── active_record/
│ │ │ │ ├── access_grant.rb
│ │ │ │ ├── access_token.rb
│ │ │ │ ├── application.rb
│ │ │ │ ├── mixins/
│ │ │ │ │ ├── access_grant.rb
│ │ │ │ │ ├── access_token.rb
│ │ │ │ │ └── application.rb
│ │ │ │ ├── redirect_uri_validator.rb
│ │ │ │ └── stale_records_cleaner.rb
│ │ │ └── active_record.rb
│ │ ├── rails/
│ │ │ ├── helpers.rb
│ │ │ ├── routes/
│ │ │ │ ├── abstract_router.rb
│ │ │ │ ├── mapper.rb
│ │ │ │ ├── mapping.rb
│ │ │ │ └── registry.rb
│ │ │ └── routes.rb
│ │ ├── rake/
│ │ │ ├── db.rake
│ │ │ └── setup.rake
│ │ ├── rake.rb
│ │ ├── request/
│ │ │ ├── authorization_code.rb
│ │ │ ├── client_credentials.rb
│ │ │ ├── code.rb
│ │ │ ├── password.rb
│ │ │ ├── refresh_token.rb
│ │ │ ├── strategy.rb
│ │ │ └── token.rb
│ │ ├── request.rb
│ │ ├── revocable_tokens/
│ │ │ ├── revocable_access_token.rb
│ │ │ └── revocable_refresh_token.rb
│ │ ├── secret_storing/
│ │ │ ├── base.rb
│ │ │ ├── bcrypt.rb
│ │ │ ├── plain.rb
│ │ │ └── sha256_hash.rb
│ │ ├── server.rb
│ │ ├── stale_records_cleaner.rb
│ │ ├── validations.rb
│ │ └── version.rb
│ ├── doorkeeper.rb
│ └── generators/
│ └── doorkeeper/
│ ├── application_owner_generator.rb
│ ├── confidential_applications_generator.rb
│ ├── enable_polymorphic_resource_owner_generator.rb
│ ├── install_generator.rb
│ ├── migration_generator.rb
│ ├── pkce_generator.rb
│ ├── previous_refresh_token_generator.rb
│ ├── remove_applications_secret_not_null_constraint_generator.rb
│ ├── templates/
│ │ ├── README
│ │ ├── add_confidential_to_applications.rb.erb
│ │ ├── add_owner_to_application_migration.rb.erb
│ │ ├── add_previous_refresh_token_to_access_tokens.rb.erb
│ │ ├── enable_pkce_migration.rb.erb
│ │ ├── enable_polymorphic_resource_owner_migration.rb.erb
│ │ ├── initializer.rb
│ │ ├── migration.rb.erb
│ │ └── remove_applications_secret_not_null_constraint.rb.erb
│ └── views_generator.rb
└── spec/
├── controllers/
│ ├── application_controller_spec.rb
│ ├── application_metal_controller_spec.rb
│ ├── applications_controller_spec.rb
│ ├── authorizations_controller_spec.rb
│ ├── protected_resources_controller_spec.rb
│ ├── token_info_controller_spec.rb
│ └── tokens_controller_spec.rb
├── doorkeeper/
│ ├── redirect_uri_validator_spec.rb
│ ├── server_spec.rb
│ ├── stale_records_cleaner_spec.rb
│ └── version_spec.rb
├── dummy/
│ ├── Rakefile
│ ├── app/
│ │ ├── assets/
│ │ │ └── config/
│ │ │ └── manifest.js
│ │ ├── controllers/
│ │ │ ├── application_controller.rb
│ │ │ ├── custom_authorizations_controller.rb
│ │ │ ├── full_protected_resources_controller.rb
│ │ │ ├── home_controller.rb
│ │ │ ├── metal_controller.rb
│ │ │ └── semi_protected_resources_controller.rb
│ │ ├── helpers/
│ │ │ └── application_helper.rb
│ │ ├── models/
│ │ │ └── user.rb
│ │ └── views/
│ │ ├── home/
│ │ │ └── index.html.erb
│ │ └── layouts/
│ │ └── application.html.erb
│ ├── config/
│ │ ├── application.rb
│ │ ├── boot.rb
│ │ ├── database.yml
│ │ ├── environment.rb
│ │ ├── environments/
│ │ │ ├── development.rb
│ │ │ ├── production.rb
│ │ │ └── test.rb
│ │ ├── initializers/
│ │ │ ├── backtrace_silencers.rb
│ │ │ ├── doorkeeper.rb
│ │ │ ├── secret_token.rb
│ │ │ ├── session_store.rb
│ │ │ └── wrap_parameters.rb
│ │ ├── locales/
│ │ │ └── doorkeeper.en.yml
│ │ └── routes.rb
│ ├── config.ru
│ ├── db/
│ │ ├── migrate/
│ │ │ ├── 20111122132257_create_users.rb
│ │ │ ├── 20120312140401_add_password_to_users.rb
│ │ │ ├── 20151223192035_create_doorkeeper_tables.rb
│ │ │ ├── 20151223200000_add_owner_to_application.rb
│ │ │ ├── 20160320211015_add_previous_refresh_token_to_access_tokens.rb
│ │ │ ├── 20170822064514_enable_pkce.rb
│ │ │ ├── 20180210183654_add_confidential_to_applications.rb
│ │ │ └── 20230205064514_add_custom_attributes.rb
│ │ └── schema.rb
│ ├── public/
│ │ ├── 404.html
│ │ ├── 422.html
│ │ └── 500.html
│ └── script/
│ └── rails
├── factories.rb
├── generators/
│ ├── application_owner_generator_spec.rb
│ ├── confidential_applications_generator_spec.rb
│ ├── enable_polymorphic_resource_owner_generator_spec.rb
│ ├── install_generator_spec.rb
│ ├── migration_generator_spec.rb
│ ├── pkce_generator_spec.rb
│ ├── previous_refresh_token_generator_spec.rb
│ ├── remove_applications_secret_not_null_constraint_generator_spec.rb
│ ├── templates/
│ │ └── routes.rb
│ └── views_generator_spec.rb
├── grape/
│ └── grape_integration_spec.rb
├── helpers/
│ └── doorkeeper/
│ └── dashboard_helper_spec.rb
├── lib/
│ ├── config_spec.rb
│ ├── doorkeeper/
│ │ └── orm/
│ │ └── active_record_spec.rb
│ ├── doorkeeper_spec.rb
│ ├── grant_flow/
│ │ └── flow_spec.rb
│ ├── grant_flow_spec.rb
│ ├── models/
│ │ ├── concerns/
│ │ │ └── write_to_primary_spec.rb
│ │ ├── expirable_spec.rb
│ │ ├── reusable_spec.rb
│ │ ├── revocable_spec.rb
│ │ ├── scopes_spec.rb
│ │ └── secret_storable_spec.rb
│ ├── oauth/
│ │ ├── authorization/
│ │ │ ├── code_spec.rb
│ │ │ └── uri_builder_spec.rb
│ │ ├── authorization_code_request_spec.rb
│ │ ├── base_request_spec.rb
│ │ ├── base_response_spec.rb
│ │ ├── client/
│ │ │ └── credentials_spec.rb
│ │ ├── client_credentials/
│ │ │ ├── creator_spec.rb
│ │ │ ├── issuer_spec.rb
│ │ │ └── validation_spec.rb
│ │ ├── client_credentials_integration_spec.rb
│ │ ├── client_credentials_request_spec.rb
│ │ ├── client_spec.rb
│ │ ├── code_request_spec.rb
│ │ ├── code_response_spec.rb
│ │ ├── error_response_spec.rb
│ │ ├── error_spec.rb
│ │ ├── forbidden_token_response_spec.rb
│ │ ├── helpers/
│ │ │ ├── scope_checker_spec.rb
│ │ │ ├── unique_token_spec.rb
│ │ │ └── uri_checker_spec.rb
│ │ ├── invalid_request_response_spec.rb
│ │ ├── invalid_token_response_spec.rb
│ │ ├── password_access_token_request_spec.rb
│ │ ├── pre_authorization_spec.rb
│ │ ├── refresh_token_request_spec.rb
│ │ ├── scopes_spec.rb
│ │ ├── token_request_spec.rb
│ │ ├── token_response_spec.rb
│ │ └── token_spec.rb
│ ├── option_spec.rb
│ ├── request/
│ │ └── strategy_spec.rb
│ └── secret_storing/
│ ├── base_spec.rb
│ ├── bcrypt_spec.rb
│ ├── plain_spec.rb
│ └── sha256_hash_spec.rb
├── models/
│ └── doorkeeper/
│ ├── access_grant_spec.rb
│ ├── access_token_spec.rb
│ └── application_spec.rb
├── requests/
│ ├── applications/
│ │ ├── applications_request_spec.rb
│ │ └── authorized_applications_spec.rb
│ ├── endpoints/
│ │ ├── authorization_spec.rb
│ │ └── token_spec.rb
│ ├── flows/
│ │ ├── authorization_code_errors_spec.rb
│ │ ├── authorization_code_spec.rb
│ │ ├── client_credentials_spec.rb
│ │ ├── implicit_grant_errors_spec.rb
│ │ ├── implicit_grant_spec.rb
│ │ ├── password_spec.rb
│ │ ├── refresh_token_spec.rb
│ │ ├── revoke_token_spec.rb
│ │ └── skip_authorization_spec.rb
│ └── protected_resources/
│ ├── metal_spec.rb
│ └── private_api_spec.rb
├── routing/
│ ├── custom_controller_routes_spec.rb
│ ├── default_routes_spec.rb
│ └── scoped_routes_spec.rb
├── spec_helper.rb
├── spec_helper_integration.rb
└── support/
├── dependencies/
│ └── factory_bot.rb
├── doorkeeper_rspec.rb
├── helpers/
│ ├── access_token_request_helper.rb
│ ├── authorization_request_helper.rb
│ ├── config_helper.rb
│ ├── model_helper.rb
│ ├── request_spec_helper.rb
│ └── url_helper.rb
├── orm/
│ └── active_record.rb
├── render_with_matcher.rb
└── shared/
├── controllers_shared_context.rb
├── hashing_shared_context.rb
└── models_shared_examples.rb
================================================
FILE CONTENTS
================================================
================================================
FILE: .codeclimate.yml
================================================
exclude_patterns:
- "lib/doorkeeper/config.rb"
- "spec/"
================================================
FILE: .coveralls.yml
================================================
service_name: travis-ci
================================================
FILE: .dockerignore
================================================
Gemfile.lock
================================================
FILE: .editorconfig
================================================
root = true
[*.{rb,json}]
indent_style = space
indent_size = 2
insert_final_newline = true
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
open_collective: doorkeeper-gem
================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
### Steps to reproduce
What we need to do to see your problem or bug?
The more detailed the issue, the more likely that we will fix it ASAP.
Don't use GitHub issues for questions like "How can I do that?" —
use [StackOverflow](https://stackoverflow.com/questions/tagged/doorkeeper)
instead with the corresponding tag.
### Expected behavior
Tell us what should happen
### Actual behavior
Tell us what happens instead
### System configuration
You can help us to understand your problem if you will share some very
useful information about your project environment (don't forget to
remove any confidential data if it exists).
**Doorkeeper initializer**:
```ruby
# config/initializers/doorkeeper.rb
Doorkeeper.configure do
# ...
end
```
**Ruby version**: ``
**Gemfile.lock**:
<details>
<summary>Gemfile.lock content</summary>
```
Place your Gemfile.lock content here
```
</details>
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
### Summary
Provide a general description of the code changes in your pull
request... were there any bugs you had fixed? If so, mention them. If
these bugs have open GitHub issues, be sure to tag them here as well,
to keep the conversation linked together.
### Other Information
If there's anything else that's important and relevant to your pull
request, mention that information here. This could include
benchmarks, or other information.
If you are updating CHANGELOG.md file or are asked to update it by reviewers,
please add the changelog entry at the top of the file.
Thanks for contributing to Doorkeeper project!
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: bundler
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
================================================
FILE: .github/workflows/changelog.yml
================================================
name: "Changelog verifier"
on:
pull_request:
# The specific activity types are listed here to include "labeled" and "unlabeled"
# (which are not included by default for the "pull_request" trigger).
# This is needed to allow skipping enforcement of the changelog in PRs with specific labels,
# as defined in the (optional) "skipLabels" property.
types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]
jobs:
# Enforces the update of a changelog file on every pull request
changelog:
runs-on: ubuntu-latest
steps:
- uses: dangoslen/changelog-enforcer@v3
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on: [push, pull_request]
permissions:
contents: read
jobs:
build:
name: >-
Ruby ${{ matrix.ruby }} (${{ matrix.gemfile }})
env:
CI: true
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
runs-on: ${{ matrix.os }}
if: |
!( contains(github.event.pull_request.title, '[ci skip]')
|| contains(github.event.pull_request.title, '[skip ci]'))
strategy:
fail-fast: true
matrix:
os: [ubuntu-latest]
ruby:
- "3.1"
- "3.2"
- "3.3"
- "3.4"
gemfile:
- gemfiles/rails_7_0.gemfile
- gemfiles/rails_7_1.gemfile
- gemfiles/rails_7_2.gemfile
- gemfiles/rails_8_0.gemfile
exclude:
- ruby: 3.1
gemfile: gemfiles/rails_8_0.gemfile
steps:
- name: Repo checkout
uses: actions/checkout@v6.0.2
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
rubygems: latest
- name: Run tests
timeout-minutes: 10
run: bundle exec rake spec
rails_edge:
runs-on: ubuntu-latest
env:
BUNDLE_GEMFILE: gemfiles/rails_edge.gemfile
steps:
- uses: actions/checkout@v6.0.2
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.4"
bundler-cache: true
- run: bundle exec rake spec || echo "Rails edge test is done."
ruby_edge:
strategy:
matrix:
gemfile:
- gemfiles/rails_7_0.gemfile
- gemfiles/rails_7_1.gemfile
- gemfiles/rails_7_2.gemfile
- gemfiles/rails_8_0.gemfile
runs-on: ubuntu-latest
env:
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
steps:
- uses: actions/checkout@v6.0.2
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "ruby-head"
bundler-cache: true
- run: bundle exec rake spec || echo "Ruby edge test is done."
================================================
FILE: .github/workflows/rubocop.yml
================================================
name: rubocop
on:
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
rubocop:
name: runner / rubocop
runs-on: ubuntu-latest
env:
BUNDLE_ONLY: rubocop
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: ruby/setup-ruby@1a615958ad9d422dd932dc1d5823942ee002799f # v1.227.0
with:
ruby-version: '3.1'
bundler-cache: true
- uses: reviewdog/action-rubocop@b6d5e953a5fc0bf3ab65254e77730ea2174d6d6d # v2.22.0
with:
reporter: github-pr-review # Default is github-pr-check
skip_install: true
use_bundler: true
================================================
FILE: .gitignore
================================================
.bundle/
vendor/bundle/
.rbx
*.rbc
log/*.log
pkg/
spec/dummy/db/*.sqlite3
spec/dummy/log/*.log
spec/dummy/tmp/
spec/generators/tmp
Gemfile.lock
gemfiles/*.lock
.rvmrc
*.swp
.idea
/.yardoc/
/_yardoc/
/doc/
/rdoc/
coverage
*.gem
gemfiles/vendor
vendor/bundle/
================================================
FILE: .hound.yml
================================================
rubocop:
config_file: .rubocop.yml
version: 1.5.2
================================================
FILE: .rspec
================================================
--colour
================================================
FILE: .rubocop.yml
================================================
inherit_from: .rubocop_todo.yml
plugins:
- rubocop-capybara
- rubocop-factory_bot
- rubocop-performance
- rubocop-rails
- rubocop-rspec
- rubocop-rspec_rails
AllCops:
TargetRubyVersion: 3.1
Exclude:
- "spec/generators/tmp/**/*"
- "spec/dummy/db/*"
- "spec/dummy/config/*"
- "Dangerfile"
- "gemfiles/*.gemfile"
Layout/MultilineMethodCallIndentation:
EnforcedStyle: indented
Layout/TrailingEmptyLines:
Enabled: true
Layout/DotPosition:
EnforcedStyle: leading
Layout/LineLength:
Exclude:
- spec/**/*
Metrics/BlockLength:
Exclude:
- spec/**/*
- lib/doorkeeper/rake/*
- doorkeeper.gemspec
Metrics/MethodLength:
Exclude:
- spec/dummy/db/**/*
Style/CaseEquality:
Exclude:
- lib/doorkeeper/grant_flow/flow.rb
Style/StringLiterals:
EnforcedStyle: double_quotes
Style/StringLiteralsInInterpolation:
EnforcedStyle: double_quotes
Style/FrozenStringLiteralComment:
Enabled: true
Style/TrailingCommaInHashLiteral:
EnforcedStyleForMultiline: consistent_comma
Style/TrailingCommaInArrayLiteral:
EnforcedStyleForMultiline: consistent_comma
Style/TrailingCommaInArguments:
EnforcedStyleForMultiline: consistent_comma
Style/SymbolArray:
MinSize: 3
Style/WordArray:
MinSize: 3
Style/ClassAndModuleChildren:
Enabled: false
Style/NumericPredicate:
Enabled: false
Style/DoubleNegation:
Enabled: false
Style/HashEachMethods:
Enabled: true
Style/HashTransformKeys:
Enabled: true
Style/HashTransformValues:
Enabled: true
Rails/DynamicFindBy:
Whitelist:
- find_by_sql
- find_by_plaintext_token
- find_by_fallback_token
Rails/HttpPositionalArguments:
Exclude:
- spec/grape/*
Rails/HttpStatus:
Enabled: false
Rails/RakeEnvironment:
Exclude:
- Rakefile
Rails/ReflectionClassName:
Exclude:
- "lib/doorkeeper/orm/active_record/mixins/access_grant.rb"
- "lib/doorkeeper/orm/active_record/mixins/access_token.rb"
- "lib/doorkeeper/orm/active_record/mixins/application.rb"
Rails/SkipsModelValidations:
Enabled: false
RSpec/BeforeAfterAll:
Exclude:
- "spec/routing/scoped_routes_spec.rb"
- "spec/routing/custom_controller_routes_spec.rb"
RSpec/ContextWording:
Exclude:
- "spec/support/shared/controllers_shared_context.rb"
RSpec/DescribeClass:
Enabled: false
RSpec/ExampleLength:
Enabled: false
RSpec/SpecFilePathFormat:
Enabled: false
RSpec/MultipleExpectations:
Enabled: false
RSpec/NestedGroups:
Enabled: false
RSpec/NoExpectationExample:
Enabled: true
Exclude:
- "spec/requests/**/*"
================================================
FILE: .rubocop_todo.yml
================================================
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2020-06-04 00:15:49 +0300 using RuboCop version 0.84.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 13
# Configuration parameters: IgnoredMethods.
Metrics/AbcSize:
Max: 33
# Offense count: 2
# Configuration parameters: CountComments, ExcludedMethods.
# ExcludedMethods: refine
Metrics/BlockLength:
Max: 85
# Offense count: 2
# Configuration parameters: CountComments.
Metrics/ClassLength:
Max: 242
# Offense count: 2
# Configuration parameters: IgnoredMethods.
Metrics/CyclomaticComplexity:
Max: 10
# Offense count: 24
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/MethodLength:
Max: 29
# Offense count: 1
# Configuration parameters: CountComments.
Metrics/ModuleLength:
Max: 209
# Offense count: 2
# Configuration parameters: IgnoredMethods.
Metrics/PerceivedComplexity:
Max: 11
# Offense count: 1
# Configuration parameters: EnforcedStyleForLeadingUnderscores.
# SupportedStylesForLeadingUnderscores: disallowed, required, optional
Naming/MemoizedInstanceVariableName:
Exclude:
- 'lib/doorkeeper/config.rb'
# Offense count: 10
RSpec/AnyInstance:
Exclude:
- 'spec/generators/previous_refresh_token_generator_spec.rb'
- 'spec/lib/oauth/authorization_code_request_spec.rb'
- 'spec/lib/oauth/client_credentials/creator_spec.rb'
- 'spec/lib/oauth/password_access_token_request_spec.rb'
- 'spec/lib/oauth/token_request_spec.rb'
- 'spec/requests/flows/authorization_code_spec.rb'
- 'spec/requests/flows/refresh_token_spec.rb'
# Offense count: 2
RSpec/ExpectInHook:
Exclude:
- 'spec/controllers/protected_resources_controller_spec.rb'
# Offense count: 300
# Configuration parameters: AssignmentOnly.
RSpec/InstanceVariable:
Enabled: false
# Offense count: 22
RSpec/LeakyConstantDeclaration:
Exclude:
- 'spec/controllers/authorizations_controller_spec.rb'
- 'spec/controllers/protected_resources_controller_spec.rb'
- 'spec/lib/config_spec.rb'
- 'spec/lib/option_spec.rb'
- 'spec/models/doorkeeper/access_token_spec.rb'
# Offense count: 7
RSpec/MessageChain:
Exclude:
- 'spec/controllers/authorizations_controller_spec.rb'
- 'spec/controllers/tokens_controller_spec.rb'
# Offense count: 98
# Configuration parameters: .
# SupportedStyles: have_received, receive
RSpec/MessageSpies:
EnforcedStyle: receive
# Offense count: 39
RSpec/SubjectStub:
Exclude:
- 'spec/lib/models/expirable_spec.rb'
- 'spec/lib/models/reusable_spec.rb'
- 'spec/lib/models/revocable_spec.rb'
- 'spec/lib/oauth/base_request_spec.rb'
- 'spec/lib/oauth/client_credentials_request_spec.rb'
- 'spec/support/shared/models_shared_examples.rb'
# Offense count: 73
# Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
RSpec/VerifiedDoubles:
Enabled: false
# Offense count: 4
# Configuration parameters: MinBodyLength.
Style/GuardClause:
Exclude:
- 'lib/doorkeeper/config.rb'
- 'lib/doorkeeper/helpers/controller.rb'
- 'lib/doorkeeper/oauth/client/credentials.rb'
- 'lib/doorkeeper/oauth/token.rb'
================================================
FILE: AGENTS.md
================================================
# Doorkeeper Codebase Guide for AI Coding Agents
This is the code base of the OAuth 2 provider for Ruby web applications.
## Architecture Overview
Doorkeeper is a Ruby gem which is a Rails engine. It provides a set of models, controllers, and views that can be
mounted into a Rails application to handle OAuth 2 authorization flows.
**Key principle**: all the changes should conform OAuth 2 published specifications such as RFC 6749, RFC 6819 and etc.
## Testing Commands
From within the root directory (preferred method):
```bash
bundle exec rake spec
```
## Code Conventions
### Changelog Updates
When fixing bugs or adding features:
- Add an entry to the top of `CHANGELOG.md`
- Format: `- [PR number] Brief description`
- See existing entries for style
### Code Style
- Run RuboCop: `bundle exec rubocop` (there's a project-wide `.rubocop.yml`)
## Documentation
- API docs use YARD/RDoc format
================================================
FILE: CHANGELOG.md
================================================
# Changelog
See https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions for
upgrade guides.
User-visible changes worth mentioning.
## main
- [#1781] Honor `handle_auth_errors :raise` in `AuthorizationsController#authorize_response`
- [#1795] Fix: detailed error 'insufficient_scope' in protected resources 403s
- [#1797] Fix `doorkeeper:db:cleanup` rake task failure on PostgreSQL
- [#1800] Set `@grant_type` in `ClientCredentialsRequest` and `RefreshTokenRequest` constructors so `request.grant_type` returns
the correct value in hooks like `before_successful_strategy_response`.
- [#1802] Fix `filter_parameters` not applied when `Doorkeeper.configure` is called inside to_prepare.
- [#1804] Use `ActiveSupport.on_load(:active_record)` in ORM hooks to prevent loading ActiveRecord models too early
- [#1806] Fix token revocation bypass for public clients (RFC 7009)
- [#1815] Expose `current_resource_owner` as a view helper in `Doorkeeper::ApplicationController`.
- [#1818] Fix token introspection returning `exp: 0` for non-expiring tokens.
- [#1784] Remove hardcoded colons from view templates, move punctuation to i18n translation strings.
**[IMPORTANT]**: if you have customized Doorkeeper views (`authorizations/new`, `authorizations/show`,
`applications/show`) or overridden the default `en.yml` translations, you may need to update them.
Colons are no longer hardcoded in the views — they are now part of the translation strings.
Update the [doorkeeper-i18n](https://github.com/doorkeeper-gem/doorkeeper-i18n) gem to get the
updated translations for all locales.
## 5.9.0
- [#1791] Add support for Rails read replicas with automatic role switching via `enable_multiple_database_roles` configuration option
- [#1792] Consider expires_in when clear expired tokens with StaleRecordsCleaner.
- [#1790] Fix race condition in refresh token revocation check by moving InvalidGrantReuse check inside the lock block
- [#1788] Fix regex for basic auth to be case-insensitive
- [#1775] Fix Applications Secret Not Null Constraint generator
- [#1779] Only lock previous access token model when creating a new token from its refresh token if revoke_previous_refresh_token_on_use is false
- [#1778] Ensure that token revocation is idempotent by checking that that token has not already been revoked before revoking.
## 5.8.2
- [#1755] Fix the error message for force_pkce
- [#1761] Memoize authentication failure
- [#1762] Allow missing client to trigger invalid client error when force_pkce is enabled
- [#1767] Make sure error handling happens on a controller level opposed to action level to account for the controller being extended
## 5.8.1
- [#1752] Bump the range of supported Ruby and Rails versions
- [#1747] Fix unknown pkce method error when configured
- [#1744] Allow for expired refresh tokens to be revoked
- [#1754] Fix refresh tokens with dynamic scopes
## 5.8.0
- [#1739] Add support for dynamic scopes
- [#1715] Fix token introspection invalid request reason
- [#1714] Fix `Doorkeeper::AccessToken.find_or_create_for` with empty scopes which raises NoMethodError
- [#1712] Add `Pragma: no-cache` to token response
- [#1726] Refactor token introspection class.
- [#1727] Allow to set null secret value for Applications if they are public.
- [#1735] Add `pkce_code_challenge_methods` config option.
## 5.7.1
- [#1705] Add `force_pkce` option that requires non-confidential clients to use PKCE when requesting an access_token using an authorization code
## 5.7.0
- [#1696] Add missing `#issued_token` method to `OAuth::TokenResponse`
- [#1697] Allow a TokenResponse body to be customized (memoize response body).
- [#1702] Fix bugs for error response in the form_post and error view
- [#1660] Custom access token attributes are now considered when finding matching tokens (fixes #1665).
Introduce `revoke_previous_client_credentials_token` configuration option.
## 5.6.9
- [#1691] Make new Doorkeeper errors backward compatible with older extensions.
## 5.6.8
- [#1680] Fix handle_auth_errors :raise NotImplementedError
## 5.6.7
- [#1662] Specify uri_redirect validation class explicitly.
- [#1652] Add custom attributes support to token generator.
- [#1667] Pass `client` instead of `grant.application` to `find_or_create_access_token`.
- [#1673] Honor `custom_access_token_attributes` in client credentials grant flow.
- [#1676] Improve AuthorizationsController error response handling
- [#1677] Fix URIHelper.valid_for_authorization? breaking for non url URIs.
## 5.6.6
- [#1644] Update HTTP headers.
- [#1646] Block public clients automatic authorization skip.
- [#1648] Add custom token attributes to Refresh Token Request.
- [#1649] Fixed custom_access_token_attributes related errors.
## 5.6.5
- [#1602] Allow custom data to be stored inside access grants/tokens.
- [#1634] Code refactoring for custom token attributes.
- [#1639] Add grant type validation to avoid Internal Server Error for DELETE /oauth/authorize endpoint.
## 5.6.4
- [#1633] Apply ORM configuration in #to_prepare block to avoid autoloading errors.
## 5.6.3
- [#1622] Drop support for Rubies 2.5 and 2.6
- [#1605] Fix URI validation for Ruby 3.2+.
- [#1625] Exclude endless access tokens from `StaleRecordsCleaner`.
- [#1626] Remove deprecated `active_record_options` config option.
- [#1631] Fix regression with redirect behavior after token lookup optimizations (redirect to app URI when found).
- [#1630] Special case unique index creation for refresh_token on SQL Server.
- [#1627] Lazy evaluate Doorkeeper config when loading files and executing initializers.
## 5.6.2
- [#1604] Fix fetching of the application when custom application_class defined.
## 5.6.1
- [#1593] Add support for Trilogy ActiveRecord adapter.
- [#1597] Add optional support to use the url path for the native authorization code flow. Ports forward [#1143] from 4.4.3
- [#1599] Remove unnecessarily re-fetch of application object when creating an access token.
## 5.6.0
- [#1581] Consider `token_type_hint` when searching for access token in TokensController to avoid extra database calls.
## 5.6.0.rc2
- [#1558] Fixed bug: able to obtain a token with default scopes even if they are not present in the
application scopes when using client credentials.
- [#1567] Only filter `code` parameter if authorization_code grant flow is enabled.
## 5.6.0.rc1
- [#1551] Change lazy loading for ORM to be Ruby standard autoload.
- [#1552] Remove duplicate IDs on Auth form to improve accessibility.
- [#1542] Improve performance of `Doorkeeper::AccessToken#matching_token_for` using database specific SQL time math.
**[IMPORTANT]**: API of the `Doorkeeper::AccessToken#matching_token_for` method has changed and now it returns
only **active** access tokens (previously they were just not revoked). Please remember that the idea of the
`reuse_access_token` option is to check for existing _active_ token (see configuration option description).
## 5.5.4
- [#1535] Revert changes introduced in #1528 to allow query params in `redirect_uri` as per the spec.
## 5.5.3
- [#1528] Don't allow extra query params in redirect_uri.
- [#1525] I18n source for forbidden token error is now `doorkeeper.errors.messages.forbidden_token.missing_scope`.
- [#1531] Disable `strict-loading` for Doorkeeper models by default.
- [#1532] Add support for Rails 7.
## 5.5.2
- [#1502] Drop support for Ruby 2.4 because of EOL.
- [#1504] Updated the url fragment in the comment for code documentation.
- [#1512] Fix form behavior when response mode is form_post.
- [#1511] Fix that authorization code is returned by fragment if response_mode is fragment.
## 5.5.1
- [#1496] Revoke `old_refresh_token` if `previous_refresh_token` is present.
- [#1495] Fix `respond_to` undefined in API-only mode
- [#1488] Verify client authentication for Resource Owner Password Grant when
`config.skip_client_authentication_for_password_grant` is set and the client credentials
are sent in a HTTP Basic auth header.
## 5.5.0
- [#1482] Simplify `TokenInfoController` to be overridable (extract response rendering).
- [#1478] Fix ownership association and Rake tasks when custom models configured.
- [#1477] Respect `ActiveRecord::Base.pluralize_table_names` for Doorkeeper table names.
## 5.5.0.rc2
- [#1473] Enable `Applications` and `AuthorizedApplications` controllers in API mode.
**[IMPORTANT]** you can still skip these controllers using `skip_controllers` in
`use_doorkeeper` inside `routes.rb`. Please do it in case you don't need them.
- [#1472] Fix `establish_connection` configuration for custom defined models.
- [#1471] Add support for Ruby 3.0.
- [#1469] Check if `redirect_uri` exists.
- [#1465] Memoize nil doorkeeper_token.
- [#1459] Use built-in Ruby option to remove padding in PKCE code challenge value.
- [#1457] Make owner_id a bigint for newly-generated owner migrations
- [#1452] Empty previous_refresh_token only if present.
- [#1440] Validate empty host in redirect_uri.
- [#1438] Add form post response mode.
- [#1458] Make `config.skip_client_authentication_for_password_grant` a long term configuration option.
## 5.5.0.rc1
- [#1435] Make error response not redirectable when client is unauthorized
- [#1426] Ensure ActiveRecord callbacks are executed on token revocation.
- [#1407] Remove redundant and complex to support helpers froms tests (`should_have_json`, etc).
- [#1416] Don't add introspection route if token introspection completely disabled.
- [#1410] Properly memoize `current_resource_owner` value (consider `nil` and `false` values).
- [#1415] Ignore PKCE params for non-PKCE grants.
- [#1418] Add ability to register custom OAuth Grant Flows.
- [#1420] Require client authentication for Resource Owner Password Grant as stated in OAuth RFC.
**[IMPORTANT]** you need to create a new OAuth client (`Doorkeeper::Application`) if you didn't
have it before and use client credentials in HTTP Basic auth if you previously used this grant
flow without client authentication. To opt out of this you could set the
`skip_client_authentication_for_password_grant` configuration option to `true`, but note that
this is in violation of the OAuth spec and represents a security risk.
All the users of your provider application now need to include client credentials when they use
this grant flow.
- [#1421] Add Resource Owner instance to authorization hook context for `custom_access_token_expires_in`
configuration option to allow resource owner based Access Tokens TTL.
## 5.4.0
- [#1404] Make `Doorkeeper::Application#read_attribute_for_serialization` public.
## 5.4.0.rc2
- [#1371] Add `#as_json` method and attributes serialization restriction for Application model.
Fixes information disclosure vulnerability (CVE-2020-10187).
**[IMPORTANT]** you need to re-implement `#as_json` method for Doorkeeper Application model
if you previously used `#to_json` serialization with custom options or attributes or rely on
JSON response from /oauth/applications.json or /oauth/authorized_applications.json. This change
is a breaking change which restricts serialized attributes to a very small set of columns.
- [#1395] Fix `NameError: uninitialized constant Doorkeeper::AccessToken` for Rake tasks.
- [#1397] Add `as: :doorkeeper_application` on Doorkeeper application form in order to support
custom configured application model.
- [#1400] Correctly yield the application instance to `allow_grant_flow_for_client?` config
option (fixes #1398).
- [#1402] Handle trying authorization with client credentials.
## 5.4.0.rc1
- [#1366] Sets expiry of token generated using `refresh_token` to that of original token. (Fixes #1364)
- [#1354] Add `authorize_resource_owner_for_client` option to authorize the calling user to access an application.
- [#1355] Allow to enable polymorphic Resource Owner association for Access Token & Grant
models (`use_polymorphic_resource_owner` configuration option).
**[IMPORTANT]** Review your custom patches or extensions for Doorkeeper internals if you
have such - since now Doorkeeper passes Resource Owner instance to every objects and not
just it's ID. See PR description for details.
- [#1356] Remove duplicated scopes from Access Tokens and Grants on attribute assignment.
- [#1357] Fix `Doorkeeper::OAuth::PreAuthorization#as_json` method causing
`Stack level too deep` error with AMS (fix #1312).
- [#1358] Deprecate `active_record_options` configuration option.
- [#1359] Refactor Doorkeeper configuration options DSL to make it easy to reuse it
in external extensions.
- [#1360] Increase `matching_token_for` lookup size to 10 000 and make it configurable.
- [#1371] Fix controllers to use valid classes in case Doorkeeper has custom models configured.
- [#1370] Fix revocation response for invalid token and unauthorized requests to conform with RFC 7009 (fixes #1362).
**[IMPORTANT]** now fully according to RFC 7009 nobody can do a revocation request without `client_id`
(for public clients) and `client_secret` (for private clients). Please update your apps to include that
info in the revocation request payload.
- [#1373] Make Doorkeeper routes mapper reusable in extensions.
- [#1374] Revoke and issue client credentials token in a transaction with a row lock.
- [#1384] Add context object with auth/pre_auth and issued_token for authorization hooks.
- [#1387] Add `AccessToken#create_for` and use in `RefreshTokenRequest`.
- [#1392] Fix `enable_polymorphic_resource_owner` migration template to have proper index name.
- [#1393] Improve Applications #show page with more informative data on client secret and scopes.
- [#1394] Use Ruby `autoload` feature to load Doorkeeper files.
## 5.3.3
- [#1404] Backport: Make `Doorkeeper::Application#read_attribute_for_serialization` public.
## 5.3.2
- [#1371] Backport: add `#as_json` method and attributes serialization restriction for Application model.
Fixes information disclosure vulnerability (CVE-2020-10187).
## 5.3.1
- [#1360] Backport: Increase `matching_token_for` batch lookup size to 10 000 and make it configurable.
## 5.3.0
- [#1339] Validate Resource Owner in `PasswordAccessTokenRequest` against `nil` and `false` values.
- [#1341] Fix `refresh_token_revoked_on_use` with `hash_token_secrets` enabled.
- [#1343] Fix ruby 2.7 kwargs warning in InvalidTokenResponse.
- [#1345] Allow to set custom classes for Doorkeeper models, extract reusable AR mixins.
- [#1346] Refactor `Doorkeeper::Application#to_json` into convenient `#as_json` (fix #1344).
- [#1349] Fix `Doorkeeper::Application` AR associations using an incorrect foreign key name when using a custom class.
- [#1318] Make existing token revocation for client credentials optional and disable it by default.
**[IMPORTANT]** This is a change compared to the behaviour of version 5.2.
If you were relying on access tokens being revoked once the same client
requested a new access token, reenable it with `revoke_previous_client_credentials_token` in Doorkeeper
initialization file.
## 5.2.6
- [#1404] Backport: Make `Doorkeeper::Application#read_attribute_for_serialization` public.
## 5.2.5
- [#1371] Backport: add `#as_json` method and attributes serialization restriction for Application model.
Fixes information disclosure vulnerability (CVE-2020-10187).
## 5.2.4
- [#1360] Backport: Increase `matching_token_for` batch lookup size to 10 000 and make it configurable.
## 5.2.3
- [#1334] Remove `application_secret` flash helper and `redirect_to` keyword.
- [#1331] Move redirect_uri_validator to where it is used (`Application` model).
- [#1326] Move response_type check in pre_authorization to a method to be easily to override.
- [#1329] Fix `find_in_batches` order warning.
## 5.2.2
- [#1320] Call configured `authenticate_resource_owner` method once per request.
- [#1315] Allow generation of new secret with `Doorkeeper::Application#renew_secret`.
- [#1309] Allow `Doorkeeper::Application#to_json` to work without arguments.
## 5.2.1
- [#1308] Fix flash types for `api_only` mode (no flashes for `ActionController::API`).
- [#1306] Fix interpolation of `missing_param` I18n.
## 5.2.0
- [#1305] Make `Doorkeeper::ApplicationController` to inherit from `ActionController::API` in cases
when `api_mode` enabled (fixes #1302).
## 5.2.0.rc3
- [#1298] Slice strong params so doesn't error with Rails forms.
- [#1300] Limiting access to attributes of pre_authorization.
- [#1296] Adding client_id to strong parameters.
**[IMPORTANT]** `Doorkeeper::Server#client_via_uid` was removed.
- [#1293] Move ar specific redirect uri validator to ar orm directory.
- [#1288] Allow to pass attributes to the `Doorkeeper::OAuth::PreAuthorization#as_json` method to customize
the PreAuthorization response.
- [#1286] Add ability to customize grant flows per application (OAuth client) (#1245 , #1207)
- [#1283] Allow to customize base class for `Doorkeeper::ApplicationMetalController` (new configuration
option called `base_metal_controller` (fix #1273).
- [#1277] Prevent requested scope be empty on authorization request, handle and add description for invalid request.
## 5.2.0.rc2
- [#1270] Find matching tokens in batches for `reuse_access_token` option (fix #1193).
- [#1271] Reintroduce existing token revocation for client credentials.
**[IMPORTANT]** If you rely on being able to fetch multiple access tokens from the same
client using client credentials flow, you should skip to version 5.3, where this behaviour
is deactivated by default.
- [#1269] Update initializer template documentation.
- [#1266] Use strong parameters within pre-authorization.
- [#1264] Add :before_successful_authorization and :after_successful_authorization hooks in TokensController
- [#1263] Response properly when introspection fails and fix configurations's user guide.
## 5.2.0.rc1
- [#1260], [#1262] Improve Token Introspection configuration option (access to tokens, client).
- [#1257] Add constraint configuration when using client authentication on introspection endpoint.
- [#1252] Returning `unauthorized` when the revocation of the token should not be performed due to wrong permissions.
- [#1249] Specify case sensitive uniqueness to remove Rails 6 deprecation message
- [#1248] Display the Application Secret in HTML after creating a new application even when `hash_application_secrets` is used.
- [#1248] Return the unhashed Application Secret in the JSON response after creating new application even when `hash_application_secrets` is used.
- [#1238] Better support for native app with support for custom scheme and localhost redirection.
## 5.1.2
- [#1404] Backport: Make `Doorkeeper::Application#read_attribute_for_serialization` public.
## 5.1.1
- [#1371] Backport: add `#as_json` method and attributes serialization restriction for Application model.
Fixes information disclosure vulnerability (CVE-2020-10187).
## 5.1.0
- [#1243] Add nil check operator in token checking at token introspection.
- [#1241] Explaining foreign key options for resource owner in a single place
- [#1237] Allow to set blank redirect URI if Doorkeeper configured to use redirect URI-less grant flows.
- [#1234] Fix `StaleRecordsCleaner` to properly work with big amount of records.
- [#1228] Allow to explicitly set non-expiring tokens in `custom_access_token_expires_in` configuration
option using `Float::INFINITY` return value.
- [#1224] Do not try to store token if not found by fallback hashing strategy.
- [#1223] Update Hound/Rubocop rules, correct Doorkeeper codebase to follow style-guides.
- [#1220] Drop Rails 4.2 & Ruby < 2.4 support.
## 5.1.0.rc2
- [#1208] Unify hashing implementation into secret storing strategies
**[IMPORTANT]** If you have been using the master branch of doorkeeper with bcrypt in your Gemfile.lock,
your application secrets have been hashed using BCrypt. To restore this behavior, use the initializer option
`hash_application_secrets using: 'Doorkeeper::SecretStoring::BCrypt`.
- [#1216] Add nil check to `expires_at` method.
- [#1215] Fix deprecates for Rails 6.
- [#1214] Scopes field accepts array.
- [#1209] Fix tokens validation for Token Introspection request.
- [#1202] Use correct HTTP status codes for error responses.
**[IMPORTANT]**: this change might break your application if you were relying on the previous
401 status codes, this is now a 400 by default, or a 401 for `invalid_client` and `invalid_token` errors.
- [#1201] Fix custom TTL block `client` parameter to always be an `Doorkeeper::Application` instance.
**[IMPORTANT]**: those who defined `custom_access_token_expires_in` configuration option need to check
their block implementation: if you are using `oauth_client.application` to get `Doorkeeper::Application`
instance, then you need to replace it with just `oauth_client`.
- [#1200] Increase default Doorkeeper access token value complexity (`urlsafe_base64` instead of just `hex`)
matching RFC6749/RFC6750.
**[IMPORTANT]**: this change have possible side-effects in case you have custom database constraints for
access token value, application secrets, refresh tokens or you patched Doorkeeper models and introduced
token value validations, or you are using database with case-insensitive WHERE clause like MySQL
(you can face some collisions). Before this change access token value matched `[a-f0-9]` regex, and now
it matches `[a-zA-Z0-9\-_]`. In case you have such restrictions and your don't use custom token generator
please change configuration option `default_generator_method` to `:hex`.
- [#1195] Allow to customize Token Introspection response (fixes #1194).
- [#1189] Option to set `token_reuse_limit`.
- [#1191] Try to load bcrypt for hashing of application secrets, but add fallback.
## 5.1.0.rc1
- [#1188] Use `params` instead of `request.POST` in tokens controller (fixes #1183).
- [#1182] Fix loopback IP redirect URIs to conform with RFC8252, p. 7.3 (fixes #1170).
- [#1179] Authorization Code Grant Flow without client id returns invalid_client error.
- [#1177] Allow to limit `scopes` for certain `grant_types`
- [#1176] Fix test factory support for `factory_bot_rails`
- [#1175] Internal refactor: use `scopes_string` inside `scopes`.
- [#1168] Allow optional hashing of tokens and secrets.
- [#1164] Fix error when `root_path` is not defined.
- [#1162] Fix `enforce_content_type` for requests without body.
## 5.0.3
- [#1371] Backport: add `#as_json` method and attributes serialization restriction for Application model.
Fixes information disclosure vulnerability (CVE-2020-10187).
## 5.0.2
- [#1158] Fix initializer template: change `handle_auth_errors` option
- [#1157] Remove redundant index from migration template.
## 5.0.1
- [#1154] Refactor `StaleRecordsCleaner` to be ORM agnostic.
- [#1152] Fix migration template: change resource owner data type from integer to Rails generic `references`
- [#1151] Fix Refresh Token strategy: add proper validation of client credentials both for Public & Private clients.
- [#1149] Fix for `URIChecker#valid_for_authorization?` false negative when query is blank, but `?` present.
- [#1140] Allow rendering custom errors from exceptions (issue #844). Originally opened as [#944].
- [#1138] Revert regression bug (check for token expiration in Authorizations controller so authorization
triggers every time)
## 5.0.0
- [#1127] Change the token_type initials of the Banner Token to uppercase to comply with the RFC6750 specification.
## 5.0.0.rc2
- [#1122] Fix AuthorizationsController#new error response to be in JSON format
- [#1119] Fix token revocation for OAuth apps using "implicit" grant flow
- [#1116] `AccessGrant`s will now be revoked along with `AccessToken`s when
hitting the `AuthorizedApplicationController#destroy` route.
- [#1114] Make token info endpoint's attributes consistent with token creation
- [#1108] Simple formatting of callback URLs when listing oauth applications
- [#1106] Restrict access to AdminController with 'Forbidden 403' if admin_authenticator is not
configured by developers.
## 5.0.0.rc1
- [#1103] Allow customizing use_refresh_token
- [#1089] Removed enable_pkce_without_secret configuration option
- [#1102] Expiration time based on scopes
- [#1099] All the configuration variables in `Doorkeeper.configuration` now
always return a non-nil value (`true` or `false`)
- [#1099] ORM / Query optimization: Do not revoke the refresh token if it is not enabled
in `doorkeeper.rb`
- [#996] Expiration Time Base On Grant Type
- [#997] Allow PKCE authorization_code flow as specified in RFC7636
- [#907] Fix lookup for matching tokens in certain edge-cases
- [#992] Add API option to use Doorkeeper without management views for API only
Rails applications (`api_only`)
- [#1045] Validate redirect_uri as the native URI when making authorization code requests
- [#1048] Remove deprecated `Doorkeeper#configured?`, `Doorkeeper#database_installed?`, and
`Doorkeeper#installed?` method
- [#1031] Allow public clients to authenticate without `client_secret`. Define an app as
either public or private/confidential
**[IMPORTANT]**: all the applications (clients) now are considered as private by default.
You need to manually change `confidential` column to `false` if you are using public clients,
in other case your mobile (or other) applications will not be able to authorize.
See [#1142](https://github.com/doorkeeper-gem/doorkeeper/issues/1142) for more details.
- [#1010] Add configuration to enforce configured scopes (`default_scopes` and
`optional_scopes`) for applications
- [#1060] Ensure that the native redirect_uri parameter matches with redirect_uri of the client
- [#1064] Add :before_successful_authorization and :after_successful_authorization hooks
- [#1069] Upgrade Bootstrap to 4 for Admin
- [#1068] Add rake task to cleanup databases that can become large over time
- [#1072] AuthorizationsController: Memoize strategy.authorize_response result to enable
subclasses to use the response object.
- [#1075] Call `before_successful_authorization` and `after_successful_authorization` hooks
on `create` action as well as `new`
- [#1082] Fix #916: remember routes mapping and use it required places (fix error with
customized Token Info route).
- [#1086, #1088] Fix bug with receiving default scopes in the token even if they are
not present in the application scopes (use scopes intersection).
- [#1076] Add config to enforce content type to application/x-www-form-urlencoded
- Fix bug with `force_ssl_in_redirect_uri` when it breaks existing applications with an
SSL redirect_uri.
## 4.4.3
- [#1143] Adds a config option `opt_out_native_route_change` to opt out of the breaking api
changed introduced in https://github.com/doorkeeper-gem/doorkeeper/pull/1003
## 4.4.2
- [#1130] Backport fix for native redirect_uri from 5.x.
## 4.4.1
- [#1127] Backport token type to comply with the RFC6750 specification.
- [#1125] Backport Quote surround I18n yes/no keys
## 4.4.0
- [#1120] Backport security fix from 5.x for token revocation when using public clients
**[IMPORTANT]**: all the applications (clients) now are considered as private by default.
You need to manually change `confidential` column to `false` if you are using public clients,
in other case your mobile (or other) applications will not be able to authorize.
See [#1142](https://github.com/doorkeeper-gem/doorkeeper/issues/1142) for more details.
## 4.3.2
- [#1053] Support authorizing with query params in the request `redirect_uri` if explicitly present in app's `Application#redirect_uri`
## 4.3.1
- Remove `BaseRecord` and introduce additional concern for ordering methods to fix
braking changes for Doorkeeper models.
- [#1032] Refactor BaseRequest callbacks into configurable lambdas
- [#1040] Clear mixins from ActiveRecord DSL and save only overridable API. It
allows to use this mixins in Doorkeeper ORM extensions with minimum code boilerplate.
## 4.3.0
- [#976] Fix to invalidate the second redirect URI when the first URI is the native URI
- [#1035] Allow `Application#redirect_uri=` to handle array of URIs.
- [#1036] Allow to forbid Application redirect URI's with specific rules.
- [#1029] Deprecate `order_method` and introduce `ordered_by`. Sort applications
by `created_at` in index action.
- [#1033] Allow Doorkeeper configuration option #force_ssl_in_redirect_uri to be a callable object.
- Fix Grape integration & add specs for it
- [#913] Deferred ORM (ActiveRecord) models loading
- [#943] Fix Access Token token generation when certain errors occur in custom token generators
- [#1026] Implement RFC7662 - OAuth 2.0 Token Introspection
- [#985] Generate valid migration files for Rails >= 5
- [#972] Replace Struct subclassing with block-form initialization
- [#1003] Use URL query param to pass through native redirect auth code so automated apps can find it.
**[IMPORTANT]**: Previously authorization code response route was `/oauth/authorize/<code>`,
now it is `oauth/authorize/native?code=<code>` (in order to help applications to automatically find the code value).
- [#868] `Scopes#&` and `Scopes#+` now take an array or any other enumerable
object.
- [#1019] Remove translation not in use: `invalid_resource_owner`.
- Use Ruby 2 hash style syntax (min required Ruby version = 2.1)
- [#948] Make Scopes.<=> work with any "other" value.
- [#974] Redirect URI is checked without query params within AuthorizationCodeRequest.
- [#1004] More explicit help text for `native_redirect_uri`.
- [#1023] Update Ruby versions and test against 2.5.0 on Travis CI.
- [#1024] Migrate from FactoryGirl to FactoryBot.
- [#1025] Improve documentation for adding foreign keys
- [#1028] Make it possible to have composite strategy names.
## 4.2.6
- [#970] Escape certain attributes in authorization forms.
## 4.2.5
- [#936] Deprecate `Doorkeeper#configured?`, `Doorkeeper#database_installed?`, and
`Doorkeeper#installed?`
- [#909] Add `InvalidTokenResponse#reason` reader method to allow read the kind
of invalid token error.
- [#928] Test against more recent Ruby versions
- Small refactorings within the codebase
- [#921] Switch to Appraisal, and test against Rails master
- [#892] Add minimum Ruby version requirement
## 4.2.0
- Security fix: Address CVE-2016-6582, implement token revocation according to
spec (tokens might not be revoked if client follows the spec).
- [#873] Add hooks to Doorkeeper::ApplicationMetalController
- [#871] Allow downstream users to better utilize doorkeeper spec factories by
eliminating name conflict on `:user` factory.
## 4.1.0
- [#845] Allow customising the `Doorkeeper::ApplicationController` base
controller
## 4.0.0
- [#834] Fix AssetNotPrecompiled error with Sprockets 4
- [#843] Revert "Fix validation error messages"
- [#847] Specify Null option to timestamps
## 4.0.0.rc4
- [#777] Add support for public client in password grant flow
- [#823] Make configuration and specs ORM independent
- [#745] Add created_at timestamp to token generation options
- [#838] Drop `Application#scopes` generator and warning, introduced for
upgrading doorkeeper from v2 to v3.
- [#801] Fix Rails 5 warning messages
- Test against Rails 5 RC1
## 4.0.0.rc3
- [#769] Revoke refresh token on access token use. To make use of the new config
add `previous_refresh_token` column to `oauth_access_tokens`:
```
rails generate doorkeeper:previous_refresh_token
```
- [#811] Toughen parameters filter with exact match
- [#813] Applications admin bugfix
- [#799] Fix Ruby Warnings
- Drop `attr_accessible` from models
### Backward incompatible changes
- [#730] Force all timezones to use UTC to prevent comparison issues.
- [#802] Remove `config.i18n.fallbacks` from engine
## 4.0.0.rc2
- Fix optional belongs_to for Rails 5
- Fix Ruby warnings
## 4.0.0.rc1
### Backward incompatible changes
- Drops support for Rails 4.1 and earlier
- Drops support for Ruby 2.0
- [#778] Bug fix: use the remaining time that a token is still valid when
building the redirect URI for the implicit grant flow
### Other changes
- [#771] Validation error messages fixes
- Adds foreign key constraints in generated migrations between tokens and
grants, and applications
- Support Rails 5
## 3.1.0
- [#736] Existing valid tokens are now reused in client_credentials flow
- [#749] Allow user to raise authorization error with custom messages.
Under `resource_owner_authenticator` block a user can
`raise Doorkeeper::Errors::DoorkeeperError.new('custom_message')`
- [#762] Check doesn’t abort the actual migration, so it runs
- [#722] `doorkeeper_forbidden_render_options` now supports returning a 404 by
specifying `respond_not_found_when_forbidden: true` in the
`doorkeeper_forbidden_render_options` method.
- [#734] Simplify and remove duplication in request strategy classes
## 3.0.1
- [#712] Wrap exchange of grant token for access token and access token refresh
in transactions
- [#704] Allow applications scopes to be mass assigned
- [#707] Fixed order of Mixin inclusion and table_name configuration in models
- [#712] Wrap access token and refresh grants in transactions
- Adds JRuby support
- Specs, views and documentation adjustments
## 3.0.0
### Other changes
- [#693] Updates `en.yml`.
## 3.0.0 (rc2)
### Backward incompatible changes
- [#678] Change application-specific scopes to take precedence over server-wide
scopes. This removes the previous behavior where the intersection between
application and server scopes was used.
### Other changes
- [#671] Fixes `NoMethodError - undefined method 'getlocal'` when calling
the /oauth/token path. Switch from using a DateTime object to update
AR to using a Time object. (Issue #668)
- [#677] Support editing application-specific scopes via the standard forms
- [#682] Pass error hash to Grape `error!`
- [#683] Generate application secret/UID if fields are blank strings
## 3.0.0 (rc1)
### Backward incompatible changes
- [#648] Extracts mongodb ORMs to
https://github.com/doorkeeper-gem/doorkeeper-mongodb. If you use ActiveRecord
you don’t need to do any change, otherwise you will need to install the new
plugin.
- [#665] `doorkeeper_unauthorized_render_options(error:)` and
`doorkeeper_forbidden_render_options(error:)` now accept `error` keyword
argument.
### Removed deprecations
- Removes `doorkeeper_for` deprecation notice.
- Remove `applications.scopes` upgrade notice.
## 2.2.2
- [#541] Fixed `undefined method attr_accessible` problem on Rails 4
(happens only when ProtectedAttributes gem is used) in #599
## 2.2.1
- [#636] `custom_access_token_expires_in` bugfixes
- [#641] syntax error fix (Issue #612)
- [#633] Send extra details to Custom Token Generator
- [#628] Refactor: improve orm adapters to ease extension
- [#637] Upgrade to rspec to 3.2
## 2.2.0 - 2015-04-19
- [#611] Allow custom access token generators to be used
- [#632] Properly fallback to `default_scopes` when no scope is specified
- [#622] Clarify that there is a logical OR between scopes for authorizing
- [#635] Upgrade to rspec 3
- [#627] i18n fallbacks to english
- Moved CHANGELOG to NEWS.md
## 2.1.4 - 2015-03-27
- [#595] HTTP spec: Add `scope` for refresh token scope param
- [#596] Limit scopes in app scopes for client credentials
- [#567] Add Grape helpers for easier integration with Grape framework
- [#606] Add custom access token expiration support for Client Credentials flow
## 2.1.3 - 2015-03-01
- [#588] Fixes scopes_match? bug that skipped authorization form in some cases
## 2.1.2 - 2015-02-25
- [#574] Remove unused update authorization route.
- [#576] Filter out sensitive parameters from logs.
- [#582] The Authorization HTTP header fields are now case insensitive.
- [#583] Database connection bugfix in certain scenarios.
- Testing improvements
## 2.1.1 - 2015-02-06
- Remove `wildcard_redirect_url` option
- [#481] Customize token flow OAuth expirations with a config lambda
- [#568] TokensController: Memoize strategy.authorize_response result to enable
subclasses to use the response object.
- [#571] Fix database initialization issues in some configurations.
- Documentation improvements
## 2.1.0 - 2015-01-13
- [#540] Include `created_at` in response.
- [#538] Check application-level scopes in client_credentials and password flow.
- [5596227] Check application scopes in AccessToken when present. Fixes a bug in
doorkeeper 2.0.0 and 2.0.1 referring to application specific scopes.
- [#534] Internationalizes doorkeeper views.
- [#545] Ensure there is a connection to the database before checking for
missing columns
- [#546] Use `Doorkeeper::` prefix when referencing `Application` to avoid
possible application model name conflict.
- [#538] Test with Rails ~> 4.2.
### Potentially backward incompatible changes
- Enable by default `authorization_code` and `client_credentials` grant flows.
Disables implicit and password grant flows by default.
- [#510, #544, 722113f] Revoked refresh token response bugfix.
## 2.0.1 - 2014-12-17
- [#525, #526, #527] Fix `ActiveRecord::NoDatabaseError` on gem load.
## 2.0.0 - 2014-12-16
### Backward incompatible changes
- [#448] Removes `doorkeeper_for` helper. Now we use
`before_action :doorkeeper_authorize!`.
- [#469] Allow client applications to restrict the set of allowable scopes.
Fixes #317. `oauth_applications` relation needs a new `scopes` string column,
non nullable, which defaults to an empty string. To add the column run:
```
rails generate doorkeeper:application_scopes
```
If you’d rather do it by hand, your ActiveRecord migration should contain:
```ruby
add_column :oauth_applications, :scopes, :string, null: false, default: ‘’
```
### Removed deprecations
- Removes `test_redirect_uri` option. It is now called `native_redirect_uri`.
- [#446] Removes `mount Doorkeeper::Engine`. Now we use `use_doorkeeper`.
### Others
- [#484] Performance improvement - avoid performing order_by when not required.
- [#450] When password is invalid in Password Credentials Grant, Doorkeeper
returned 'invalid_resource_owner' instead of 'invalid_grant', as the spec
declares. Fixes #444.
- [#452] Allows `revoked_at` to be set in the future, for future expiry.
Rationale: https://github.com/doorkeeper-gem/doorkeeper/pull/452#issuecomment-51431459
- [#480] For Implicit grant flow, access tokens can now be reused. Fixes #421.
- [#491] Reworks of @jasl's #454 and #478. ORM refactor that allows doorkeeper
to be extended more easily with unsupported ORMs. It also marks the boundaries
between shared model code and ORM specifics inside of the gem.
- [#496] Tests with Rails 4.2.
- [#489] Adds `force_ssl_in_redirect_uri` to force the usage of the HTTPS
protocol in non-native redirect uris.
- [#516] SECURITY: Adds `protect_from_forgery` to `Doorkeeper::ApplicationController`
- [#518] Fix random failures in mongodb.
---
## 1.4.2 - 2015-03-02
- [#576] Filter out sensitive parameters from logs
## 1.4.1 - 2014-12-17
- [#516] SECURITY: Adds `protect_from_forgery` to `Doorkeeper::ApplicationController`
## 1.4.0 - 2014-07-31
- internals
- [#427] Adds specs expectations.
- [#428] Error response refactor.
- [#417] Moves token validation into Access Token class.
- [#439] Removes redundant module includes.
- [#443] TokensController and TokenInfoController inherit from ActionController::Metal
- bug
- [#418] fixes #243, requests with insufficient scope now respond 403 instead
of 401. (API change)
- [#438] fixes #398, native redirect for implicit token grant bug.
- [#440] namespace fixes
- enhancements
- [#432] Keeps query parameters
## 1.3.1 - 2014-07-06
- enhancements
- [#405] Adds facade to more easily get the token from a request in a route
constraint.
- [#415] Extend Doorkeeper TokenResponse with an `after_successful_response`
callback that allows handling of `response` object.
- internals
- [#409] Deprecates `test_redirect_uri` in favor of `native_redirect_uri`.
See discussion in: [#351].
- [#411] Clean rspec deprecations. General test improvements.
- [#412] rspec line width can go longer than 80 (hound CI config).
- bug
- [#413] fixes #340, routing scope is now taken into account in redirect.
- [#401] and [#425] application is not required any longer for access_token.
## 1.3.0 - 2014-05-23
- enhancements
- [#387] Adds reuse_access_token configuration option.
## 1.2.0 - 2014-05-02
- enhancements
- [#376] Allow users to enable basic header authorization for access tokens.
- [#374] Token revocation implementation [RFC 7009]
- [#295] Only enable specific grant flows.
- internals
- [#381] Locale source fix.
- [#380] Renames `errors_for` to `doorkeeper_errors_for`.
- [#390] Style adjustments in accordance with Ruby Style Guide form
Thoughtbot.
## 1.1.0 - 2014-03-29
- enhancements
- [#336] mongoid4 support.
- [#372] Allow users to set ActiveRecord table_name_prefix/suffix options
- internals
- [#343] separate OAuth's admin and user end-point to different layouts, upgrade theme to Bootstrap 3.1.
- [#348] Move render_options in filter after `@error` has been set
## 1.0.0 - 2014-01-13
- bug (spec)
- [#228] token response `expires_in` value is now in seconds, relative to
request time
- [#296] client is optional for password grant type.
- [#319] If client credentials are present on password grant type they are validated
- [#326] If client credentials are present in refresh token they are validated
- [#326] If authenticated client does not match original client that
obtained a refresh token it responds `invalid_grant` instead of
`invalid_client`. Previous usage was invalid according to Section 5.2 of
the spec.
- [#329] access tokens' `scopes` string wa being compared against
`default_scopes` symbols, always unauthorizing.
- [#318] Include "WWW-Authenticate" header with Unauthorized responses
- enhancements
- [#293] Adds ActionController::Instrumentation in TokensController
- [#298] Support for multiple redirect_uris added.
- [#313] `AccessToken.revoke_all_for` actually revokes all non-revoked
tokens for an application/owner instead of deleting them.
- [#333] Rails 4.1 support
- internals
- Removes jQuery dependency [fixes #300][pr #312 is related]
- [#294] Client uid and secret will be generated only if not present.
- [#316] Test warnings addressed.
- [#338] Rspec 3 syntax.
---
## 0.7.4 - 2013-12-01
- bug
- Symbols instead of strings for user input.
## 0.7.3 - 2013-10-04
- enhancements
- [#204] Allow to overwrite scope in routes
- internals
- Returns only present keys in Token Response (may imply a backwards
incompatible change). https://github.com/doorkeeper-gem/doorkeeper/issues/220
- bug
- [#290] Support for Rails 4 when 'protected_attributes' gem is present.
## 0.7.2 - 2013-09-11
- enhancements
- [#272] Allow issuing multiple access_tokens for one user/application for multiple devices
- [#170] Increase length of allowed redirect URIs
- [#239] Do not try to load unavailable Request class for the current phase.
- [#273] Relax jquery-rails gem dependency
## 0.7.1 - 2013-08-30
- bug
- [#269] Rails 3.2 raised `ActiveModel::MassAssignmentSecurity::Error`.
## 0.7.0 - 2013-08-21
- enhancements
- [#229] Rails 4!
- internals
- [#203] Changing table name to be specific in column_names_with_table
- [#215] README update
- [#227] Use Rails.config.paths["config/routes"] instead of assuming "config/routes.rb" exists
- [#262] Add jquery as gem dependency
- [#263] Add a configuration for ActiveRecord.establish_connection
- Deprecation and Ruby warnings (PRs merged outside of GitHub).
## 0.6.7 - 2013-01-13
- internals
- [#188] Add IDs to the show views for integration testing [@egtann](https://github.com/egtann)
## 0.6.6 - 2013-01-04
- enhancements
- [#187] Raise error if configuration is not set
## 0.6.5 - 2012-12-26
- enhancements
- [#184] Vendor the Bootstrap CSS [@tylerhunt](https://github.com/tylerhunt)
## 0.6.4 - 2012-12-15
- bug
- [#180] Add localization to authorized_applications destroy notice [@aalvarado](https://github.com/aalvarado)
## 0.6.3 - 2012-12-07
- bugfixes
- [#163] Error response content-type header should be application/json [@ggayan](https://github.com/ggayan)
- [#175] Make token.expires_in_seconds return nil when expires_in is nil [@miyagawa](https://github.com/miyagawa)
- enhancements
- [#166, #172, #174] Behavior to automatically authorize based on a configured proc
- internals
- [#168] Using expectation syntax for controller specs [@rdsoze](https://github.com/rdsoze)
## 0.6.2 - 2012-11-10
- bugfixes
- [#162] Remove ownership columns from base migration template [@rdsoze](https://github.com/rdsoze)
## 0.6.1 - 2012-11-07
- bugfixes
- [#160] Removed |routes| argument from initializer authenticator blocks
- documentation
- [#160] Fixed description of context of authenticator blocks
## 0.6.0 - 2012-11-05
- enhancements
- Mongoid `orm` configuration accepts only :mongoid2 or :mongoid3
- Authorization endpoint does not redirect in #new action anymore. It wasn't specified by OAuth spec
- TokensController now inherits from ActionController::Metal. There might be performance upgrades
- Add link to authorization in Applications scaffold
- [#116] MongoMapper support [@carols10cents](https://github.com/carols10cents)
- [#122] Mongoid3 support [@petergoldstein](https://github.com/petergoldstein)
- [#150] Introduce test redirect uri for applications
- bugfixes
- [#157] Response token status should be `:ok`, not `:success` [@theycallmeswift](https://github.com/theycallmeswift)
- [#159] Remove ActionView::Base.field_error_proc override (fixes #145)
- internals
- Update development dependencies
- Several refactorings
- Rails/ORM are easily swichable with env vars (rails and orm)
- Travis now tests against Mongoid v2
## 0.5.0 - 2012-10-20
Official support for rubinius was removed.
- enhancements
- Configure the way access token is retrieved from request (default to bearer header)
- Authorization Code expiration time is now configurable
- Add support for mongoid
- [#78, #128, #137, #138] Application Ownership
- [#92] Allow users to skip controllers
- [#99] Remove deprecated warnings for data-\* attributes [@towerhe](https://github.com/towerhe)
- [#101] Return existing access_token for PasswordAccessTokenRequest [@benoist](https://github.com/benoist)
- [#104] Changed access token scopes example code to default_scopes and optional_scopes [@amkirwan](https://github.com/amkirwan)
- [#107] Fix typos in initializer
- [#123] i18n for validator, flash messages [@petergoldstein](https://github.com/petergoldstein)
- [#140] ActiveRecord is the default value for the ORM [@petergoldstein](https://github.com/petergoldstein)
- internals
- [#112, #120] Replacing update_attribute with update_column to eliminate deprecation warnings [@rmoriz](https://github.com/rmoriz), [@petergoldstein](https://github.com/petergoldstein)
- [#121] Updating all development dependencies to recent versions. [@petergoldstein](https://github.com/petergoldstein)
- [#144] Adding MongoDB dependency to .travis.yml [@petergoldstein](https://github.com/petergoldstein)
- [#143] Displays errors for unconfigured error messages [@timgaleckas](https://github.com/timgaleckas)
- bugfixes
- [#102] Not returning 401 when access token generation fails [@cslew](https://github.com/cslew)
- [#125] Doorkeeper is using ActiveRecord version of as_json in ORM agnostic code [@petergoldstein](https://github.com/petergoldstein)
- [#142] Prevent double submission of password based authentication [@bdurand](https://github.com/bdurand)
- documentation
- [#141] Add rack-cors middleware to readme [@gottfrois](https://github.com/gottfrois)
## 0.4.2 - 2012-06-05
- bugfixes:
- [#94] Uninitialized Constant in Password Flow
## 0.4.1 - 2012-06-02
- enhancements:
- Backport: Move doorkeeper_for extension to Filter helper
## 0.4.0 - 2012-05-26
- deprecation
- Deprecate authorization_scopes
- database changes
- AccessToken#resource_owner_id is not nullable
- enhancements
- [#83] Add Resource Owner Password Credentials flow [@jaimeiniesta](https://github.com/jaimeiniesta)
- [#76] Allow token expiration to be disabled [@mattgreen](https://github.com/mattgreen)
- [#89] Configure the way client credentials are retrieved from request
- [#b6470a] Add Client Credentials flow
- internals
- [#2ece8d, #f93778] Introduce Client and ErrorResponse classes
## 0.3.4 - 2012-05-24
- Fix attr_accessible for rails 3.2.x
## 0.3.3 - 2012-05-07
- [#86] shrink gem package size
## 0.3.2 - 2012-04-29
- enhancements
- [#54] Ignore Authorization: headers that are not Bearer [@miyagawa](https://github.com/miyagawa)
- [#58, #64] Add destroy action to applications endpoint [@jaimeiniesta](https://github.com/jaimeiniesta), [@davidfrey](https://github.com/davidfrey)
- [#63] TokensController responds with `401 unauthorized` [@jaimeiniesta](https://github.com/jaimeiniesta)
- [#67, #72] Fix for mass-assignment [@cicloid](https://github.com/cicloid)
- internals
- [#49] Add Gemnasium status image to README [@laserlemon](https://github.com/laserlemon)
- [#50] Fix typos [@tomekw](https://github.com/tomekw)
- [#51] Updated the factory_girl_rails dependency, fix expires_in response which returned a float number instead of integer [@antekpiechnik](https://github.com/antekpiechnik)
- [#62] Typos, .gitignore [@jaimeiniesta](https://github.com/jaimeiniesta)
- [#65] Change \_path redirections to \_url redirections [@jaimeiniesta](https://github.com/jaimeiniesta)
- [#75] Fix unknown method #authenticate_admin! [@mattgreen](https://github.com/mattgreen)
- Remove application link in authorized app view
## 0.3.1 - 2012-02-17
- enhancements
- [#48] Add if, else options to doorkeeper_for
- Add views generator
- internals
- Namespace models
## 0.3.0 - 2012-02-11
- enhancements
- [#17, #31] Add support for client credentials in basic auth header [@GoldsteinTechPartners](https://github.com/GoldsteinTechPartners)
- [#28] Add indices to migration [@GoldsteinTechPartners](https://github.com/GoldsteinTechPartners)
- [#29] Allow doorkeeper to run with rails 3.2 [@john-griffin](https://github.com/john-griffin)
- [#30] Improve client's redirect uri validation [@GoldsteinTechPartners](https://github.com/GoldsteinTechPartners)
- [#32] Add token (implicit grant) flow [@GoldsteinTechPartners](https://github.com/GoldsteinTechPartners)
- [#34] Add support for custom unathorized responses [@GoldsteinTechPartners](https://github.com/GoldsteinTechPartners)
- [#36] Remove repetitions from the Authorised Applications view [@carvil](https://github.com/carvil)
- When user revoke an application, all tokens for that application are revoked
- Error messages now can be translated
- Install generator copies the error messages localization file
- internals
- Fix deprecation warnings in ActiveSupport::Base64
- Remove deprecation in doorkeeper_for that handles hash arguments
- Depends on railties instead of whole rails framework
- CI now integrates with rails 3.1 and 3.2
## 0.2.0 - 2011-12-17
- enhancements
- [#4] Add authorized applications endpoint
- [#5, #11] Add access token scopes
- [#10] Add access token expiration by default
- [#9, #12] Add refresh token flow
- internals
- [#7] Improve configuration options with :default
- Improve configuration options with :builder
- Refactor config class
- Improve coverage of authorization request integration
- bug fixes
- [#6, #20] Fix access token response headers
- Fix issue with state parameter
- deprecation
- deprecate :only and :except options in doorkeeper_for
## 0.1.1 - 2011-11-30
- enhancements
- [#3] Authorization code must be short lived and single use
- [#2] Improve views provided by doorkeeper
- [#1] Skips authorization form if the client has been authorized by the resource owner
- Improve readme
- bugfixes
- Fix issue when creating the access token (wrong client id)
## 0.1.0 - 2011-11-25
- Authorization Code flow
- OAuth applications endpoint
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team members or current maintainer email, specified in gemspec. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
We love pull requests from everyone. By participating in this project, you agree
to abide by the [code of conduct](CODE_OF_CONDUCT.md).
Fork, then clone the repo:
git clone git@github.com:your-username/doorkeeper.git
### Docker Setup
Build the container image with: `docker build --pull -t doorkeeper:test .`
Run the tests with: `docker run -it --rm doorkeeper:test`
### Local Setup
* Set up Ruby dependencies via Bundler
bundle install
* Make sure the tests pass:
rake spec
* Make your changes.
* Write tests.
* Follow our [style guides](.rubocop.yml).
* Make the tests pass:
rake spec
* Add notes about your changes to the `CHANGELOG.md` file.
* Write a [good commit message][commit].
* Push to your fork.
* [Submit a pull request][pr].
[commit]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
[pr]: https://github.com/doorkeeper-gem/doorkeeper/compare/
* If [Rubocop] catches style violations, fix them. If our bot suggested changes — please add them.
* Wait for us. We try to at least comment on pull requests within one business day.
* We may suggest changes.
* Please, squash your commits to a single one if you introduced a new changes or pushed more than
one commit. Let's keep the history clean.
Thank you for your contribution! :handshake:
================================================
FILE: Dockerfile
================================================
FROM ruby:3.3.4-alpine
# Linux UID (user id) for the doorkeeper user, change with [--build-arg UID=1234]
ARG UID="991"
# Linux GID (group id) for the doorkeeper user, change with [--build-arg GID=1234]
ARG GID="991"
# Timezone used by the Docker container and runtime, change with [--build-arg TZ=Europe/Berlin]
ARG TZ="Etc/UTC"
# Apply timezone
ENV TZ=${TZ}
RUN addgroup -g "${GID}" doorkeeper; \
adduser -u "${UID}" -G "doorkeeper" -h /srv doorkeeper; \
echo "${TZ}" > /etc/localtime;
RUN apk add --no-cache \
ca-certificates \
wget \
openssl \
bash \
build-base \
git \
sqlite-dev \
tzdata
ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US:en
ENV LC_ALL=en_US.UTF-8
ENV BUNDLER_VERSION=2.5.11
RUN gem install bundler -v ${BUNDLER_VERSION} -i /usr/local/lib/ruby/gems/$(ls /usr/local/lib/ruby/gems) --force
WORKDIR /srv
COPY Gemfile doorkeeper.gemspec /srv/
COPY lib/doorkeeper/version.rb /srv/lib/doorkeeper/version.rb
# This is a fix for sqlite alpine issues
RUN bundle config force_ruby_platform true
RUN bundle install
COPY . /srv/
RUN chown -R doorkeeper:doorkeeper /srv/coverage /srv/spec/dummy/tmp /srv/spec/generators/tmp
# Set the running user for resulting container
USER doorkeeper
CMD ["rake"]
================================================
FILE: Gemfile
================================================
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gemspec
gem "rails", ">= 7.0", "< 8.1"
gem "sprockets-rails"
gem "rspec-core"
gem "rspec-expectations"
gem "rspec-mocks"
gem "rspec-rails", "~> 8.0"
gem "rspec-support"
group :development, :rubocop do
gem "rubocop", "~> 1.72"
gem "rubocop-capybara", "~> 2.22", require: false
gem "rubocop-factory_bot", "~> 2.27", require: false
gem "rubocop-performance", "~> 1.24", require: false
gem "rubocop-rails", "~> 2.30", require: false
gem "rubocop-rspec", "~> 3.5", require: false
gem "rubocop-rspec_rails", "~> 2.31", require: false
end
gem "bcrypt", "~> 3.1", require: false
gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
gem "sqlite3", "~> 2.3", platform: [:ruby, :mswin, :mingw, :x64_mingw]
gem "tzinfo-data", platforms: %i[mingw mswin x64_mingw]
gem "timecop"
gem 'irb', '~> 1.8'
# Interactive Debugging tools
gem 'debug', '~> 1.8'
================================================
FILE: MIT-LICENSE
================================================
Copyright 2011 Applicake. http://applicake.com
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: NEWS.md
================================================
Document moved [here](CHANGELOG.md)
================================================
FILE: README.md
================================================
# Doorkeeper — awesome OAuth 2 provider for your Rails / Grape app.
[](https://rubygems.org/gems/doorkeeper)
[](https://github.com/doorkeeper-gem/doorkeeper/actions/workflows/ci.yml)
[](https://qlty.sh/gh/doorkeeper-gem/projects/doorkeeper)
[](https://coveralls.io/github/doorkeeper-gem/doorkeeper?branch=main)
[](https://dashboard.guardrails.io/gh/doorkeeper-gem/repos/21183)
[](https://dependabot.com)
Doorkeeper is a gem (Rails engine) that makes it easy to introduce OAuth 2 provider
functionality to your Ruby on Rails or Grape application.
Supported features:
- [The OAuth 2.0 Authorization Framework](https://datatracker.ietf.org/doc/html/rfc6749)
- [Authorization Code Flow](https://datatracker.ietf.org/doc/html/rfc6749#section-4.1)
- [Access Token Scopes](https://datatracker.ietf.org/doc/html/rfc6749#section-3.3)
- [Refresh token](https://datatracker.ietf.org/doc/html/rfc6749#section-1.5)
- [Implicit grant](https://datatracker.ietf.org/doc/html/rfc6749#section-4.2)
- [Resource Owner Password Credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3)
- [Client Credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-4.4)
- [OAuth 2.0 Token Revocation](https://datatracker.ietf.org/doc/html/rfc7009)
- [OAuth 2.0 Token Introspection](https://datatracker.ietf.org/doc/html/rfc7662)
- [OAuth 2.0 Threat Model and Security Considerations](https://datatracker.ietf.org/doc/html/rfc6819)
- [OAuth 2.0 for Native Apps](https://datatracker.ietf.org/doc/html/rfc8252)
- [Proof Key for Code Exchange by OAuth Public Clients](https://datatracker.ietf.org/doc/html/rfc7636)
## Table of Contents
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Documentation](#documentation)
- [Installation](#installation)
- [Ruby on Rails](#ruby-on-rails)
- [Grape](#grape)
- [ORMs](#orms)
- [Extensions](#extensions)
- [Example Applications](#example-applications)
- [Sponsors](#sponsors)
- [Development](#development)
- [Contributing](#contributing)
- [Contributors](#contributors)
- [License](#license)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Documentation
This documentation is valid for `main` branch. Please check the documentation for the version of doorkeeper you are using in:
https://github.com/doorkeeper-gem/doorkeeper/releases.
Additionally, other resources can be found on:
- [Guides](https://doorkeeper.gitbook.io/guides/) with how-to get started and configuration documentation
- See the [Wiki](https://github.com/doorkeeper-gem/doorkeeper/wiki) for articles on how to integrate with other solutions
- Screencast from [railscasts.com](http://railscasts.com/): [#353
OAuth with
Doorkeeper](http://railscasts.com/episodes/353-oauth-with-doorkeeper)
- See [upgrade guides](https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions)
- For general questions, please post on [Stack Overflow](http://stackoverflow.com/questions/tagged/doorkeeper)
- See [SECURITY.md](SECURITY.md) for this project's security disclose
policy
## Installation
Installation depends on the framework you're using. The first step is to add the following to your Gemfile:
```ruby
gem 'doorkeeper'
```
And run `bundle install`. After this, check out the guide related to the framework you're using.
### Ruby on Rails
Doorkeeper currently supports Ruby on Rails >= 5.0. See the guide [here](https://doorkeeper.gitbook.io/guides/ruby-on-rails/getting-started).
### Grape
Guide for integration with Grape framework can be found [here](https://doorkeeper.gitbook.io/guides/grape/grape).
## ORMs
Doorkeeper supports Active Record by default, but can be configured to work with the following ORMs:
| ORM | Support via |
| :--- | :--- |
| Active Record | by default |
| MongoDB | [doorkeeper-gem/doorkeeper-mongodb](https://github.com/doorkeeper-gem/doorkeeper-mongodb) |
| Sequel | [nbulaj/doorkeeper-sequel](https://github.com/nbulaj/doorkeeper-sequel) |
| Couchbase | [acaprojects/doorkeeper-couchbase](https://github.com/acaprojects/doorkeeper-couchbase) |
| RethinkDB | [aca-labs/doorkeeper-rethinkdb](https://github.com/aca-labs/doorkeeper-rethinkdb) |
## Extensions
Extensions that are not included by default and can be installed separately.
| | Link |
| :--- | :--- |
| OpenID Connect extension | [doorkeeper-gem/doorkeeper-openid\_connect](https://github.com/doorkeeper-gem/doorkeeper-openid_connect) |
| JWT Token support | [doorkeeper-gem/doorkeeper-jwt](https://github.com/doorkeeper-gem/doorkeeper-jwt) |
| Assertion grant extension | [doorkeeper-gem/doorkeeper-grants\_assertion](https://github.com/doorkeeper-gem/doorkeeper-grants_assertion) |
| I18n translations | [doorkeeper-gem/doorkeeper-i18n](https://github.com/doorkeeper-gem/doorkeeper-i18n) |
| CIBA - Client Initiated Backchannel Authentication Flow extension | [doorkeeper-ciba](https://github.com/autoseg/doorkeeper-ciba) |
| Device Authorization Grant | [doorkeeper-device_authorization_grant](https://github.com/exop-group/doorkeeper-device_authorization_grant) |
## Example Applications
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.
| Application | Link |
| :--- | :--- |
| OAuth2 Server with Doorkeeper | [doorkeeper-gem/doorkeeper-provider-app](https://github.com/doorkeeper-gem/doorkeeper-provider-app) |
| Sinatra Client connected to Provider App | [doorkeeper-gem/doorkeeper-sinatra-client](https://github.com/doorkeeper-gem/doorkeeper-sinatra-client) |
| Devise + Omniauth Client | [doorkeeper-gem/doorkeeper-devise-client](https://github.com/doorkeeper-gem/doorkeeper-devise-client) |
You may want to create a client application to
test the integration. Check out these [client
examples](https://github.com/doorkeeper-gem/doorkeeper/wiki/Example-Applications)
in our wiki or follow this [tutorial
here](https://github.com/doorkeeper-gem/doorkeeper/wiki/Testing-your-provider-with-OAuth2-gem).
## Sponsors
[](#backers)
[](#sponsors)
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)]
<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>
> 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)
<br>
<a href="https://oauth.io/?utm_source=doorkeeper-gem" target="_blank"><img src="https://oauth.io/img/logo_text.png"/></a>
> 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)
<br>
<a href="https://www.wealthsimple.com/?utm_source=doorkeeper-gem" target="_blank"><img src="https://wealthsimple.s3.amazonaws.com/branding/medium-black.svg"/></a>
> 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)
## Development
To run the local engine server:
```
bundle install
bundle exec rake doorkeeper:server
````
By default, it uses the latest Rails version with ActiveRecord. To run the
tests with a specific Rails version:
```
BUNDLE_GEMFILE=gemfiles/rails_6_0.gemfile bundle exec rake
```
You can also experiment with the changes using `bin/console`. It uses in-memory SQLite database and default
Doorkeeper config, but you can reestablish connection or reconfigure the gem if you need.
## Contributing
Want to contribute and don't know where to start? Check out [features we're
missing](https://github.com/doorkeeper-gem/doorkeeper/wiki/Supported-Features),
create [example
apps](https://github.com/doorkeeper-gem/doorkeeper/wiki/Example-Applications),
integrate the gem with your app and let us know!
Also, check out our [contributing guidelines page](CONTRIBUTING.md).
## Contributors
Thanks to all our [awesome
contributors](https://github.com/doorkeeper-gem/doorkeeper/graphs/contributors)!
<a href="https://github.com/doorkeeper-gem/doorkeeper/graphs/contributors"><img src="https://opencollective.com/doorkeeper-gem/contributors.svg?width=890&button=false" /></a>
## License
MIT License. Created in Applicake. Maintained by the community.
================================================
FILE: RELEASING.md
================================================
# Releasing Doorkeeper
How to release Doorkeeper in five easy steps!
1. Update `lib/doorkeeper/version.rb` file accordingly.
2. Update `CHANGELOG.md` to reflect the changes since last release.
3. Commit changes: `git commit -am 'Bump to vVERSION'`.
4. Build and publish the gem.
4. Create GitHub release.
5. Announce the new release, making sure to say “thank you” to the contributors
who helped shape this version!
================================================
FILE: Rakefile
================================================
# frozen_string_literal: true
require "bundler/setup"
require "rspec/core/rake_task"
desc "Default: run specs."
task default: :spec
desc "Run all specs"
RSpec::Core::RakeTask.new(:spec) do |config|
config.verbose = false
end
namespace :doorkeeper do
desc "Install doorkeeper in dummy app"
task :install do
cd "spec/dummy"
system "bundle exec rails g doorkeeper:install --force"
end
desc "Runs local test server"
task :server do
cd "spec/dummy"
system "bundle exec rails server"
end
end
Bundler::GemHelper.install_tasks
================================================
FILE: SECURITY.md
================================================
# Reporting security issues in Doorkeeper
Hello! Thank you for wanting to disclose a possible security
vulnerability within the Doorkeeper gem! Please follow our disclosure
policy as outlined below:
1. Do NOT open up a GitHub issue with your report. Security reports
should be kept private until a possible fix is determined.
2. Send an email to Nikita Bulai at bulaj.nikita AT gmail.com or one of
the others Doorkeeper maintainers listed in gemspec. You should receive
a prompt response.
3. Be patient. Since Doorkeeper is in a stable maintenance phase, we want to
do as little as possible to rock the boat of the project.
Thank you very much for adhering for these policies!
================================================
FILE: UPGRADE.md
================================================
See [Upgrade Guides](https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions)
in the project Wiki.
================================================
FILE: app/assets/stylesheets/doorkeeper/admin/application.css
================================================
/*
*= require doorkeeper/bootstrap.min
*
*= require_self
*= require_tree .
*/
.doorkeeper-admin .form-group > .field_with_errors {
width: 16.66667%;
}
================================================
FILE: app/assets/stylesheets/doorkeeper/application.css
================================================
/*
*= require doorkeeper/bootstrap.min
*
*= require_self
*= require_tree .
*/
body {
background-color: #eee;
font-size: 14px;
}
#container {
background-color: #fff;
border: 1px solid #999;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 6px;
-webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
box-shadow: 0 3px 20px rgba(0, 0, 0, 0.3);
margin: 2em auto;
max-width: 600px;
outline: 0;
padding: 1em;
width: 80%;
}
.page-header {
margin-top: 20px;
}
#oauth-permissions {
width: 260px;
}
.actions {
border-top: 1px solid #eee;
margin-top: 1em;
padding-top: 9px;
}
.actions > form > .btn {
margin-top: 5px;
}
.separator {
color: #eee;
padding: 0 .5em;
}
.inline_block {
display: inline-block;
}
#oauth {
margin-bottom: 1em;
}
#oauth > .btn {
width: 7em;
}
td {
vertical-align: middle !important;
}
================================================
FILE: app/controllers/doorkeeper/application_controller.rb
================================================
# frozen_string_literal: true
module Doorkeeper
class ApplicationController <
Doorkeeper.config.resolve_controller(:base)
include Helpers::Controller
include ActionController::MimeResponds if Doorkeeper.config.api_only
unless Doorkeeper.config.api_only
protect_from_forgery with: :exception
helper "doorkeeper/dashboard"
end
end
end
================================================
FILE: app/controllers/doorkeeper/application_metal_controller.rb
================================================
# frozen_string_literal: true
module Doorkeeper
class ApplicationMetalController <
Doorkeeper.config.resolve_controller(:base_metal)
include Helpers::Controller
before_action :enforce_content_type,
if: -> { Doorkeeper.config.enforce_content_type }
ActiveSupport.run_load_hooks(:doorkeeper_metal_controller, self)
end
end
================================================
FILE: app/controllers/doorkeeper/applications_controller.rb
================================================
# frozen_string_literal: true
module Doorkeeper
class ApplicationsController < Doorkeeper::ApplicationController
layout "doorkeeper/admin" unless Doorkeeper.configuration.api_only
before_action :authenticate_admin!
before_action :set_application, only: %i[show edit update destroy]
def index
@applications = Doorkeeper.config.application_model.ordered_by(:created_at)
respond_to do |format|
format.html
format.json { head :no_content }
end
end
def show
respond_to do |format|
format.html
format.json { render json: @application, as_owner: true }
end
end
def new
@application = Doorkeeper.config.application_model.new
end
def create
@application = Doorkeeper.config.application_model.new(application_params)
if @application.save
flash[:notice] = I18n.t(:notice, scope: %i[doorkeeper flash applications create])
flash[:application_secret] = @application.plaintext_secret
respond_to do |format|
format.html { redirect_to oauth_application_url(@application) }
format.json { render json: @application, as_owner: true }
end
else
respond_to do |format|
format.html { render :new }
format.json do
errors = @application.errors.full_messages
render json: { errors: errors }, status: :unprocessable_entity
end
end
end
end
def edit; end
def update
if @application.update(application_params)
flash[:notice] = I18n.t(:notice, scope: i18n_scope(:update))
respond_to do |format|
format.html { redirect_to oauth_application_url(@application) }
format.json { render json: @application, as_owner: true }
end
else
respond_to do |format|
format.html { render :edit }
format.json do
errors = @application.errors.full_messages
render json: { errors: errors }, status: :unprocessable_entity
end
end
end
end
def destroy
flash[:notice] = I18n.t(:notice, scope: i18n_scope(:destroy)) if @application.destroy
respond_to do |format|
format.html { redirect_to oauth_applications_url }
format.json { head :no_content }
end
end
private
def set_application
@application = Doorkeeper.config.application_model.find(params[:id])
end
def application_params
params.require(:doorkeeper_application)
.permit(:name, :redirect_uri, :scopes, :confidential)
end
def i18n_scope(action)
%i[doorkeeper flash applications] << action
end
end
end
================================================
FILE: app/controllers/doorkeeper/authorizations_controller.rb
================================================
# frozen_string_literal: true
module Doorkeeper
class AuthorizationsController < Doorkeeper::ApplicationController
before_action :authenticate_resource_owner!
def new
if pre_auth.authorizable?
render_success
else
render_error
end
end
def create
redirect_or_render(authorize_response)
end
def destroy
redirect_or_render(authorization.deny)
rescue Doorkeeper::Errors::InvalidTokenStrategy => e
error_response = get_error_response_from_exception(e)
if Doorkeeper.configuration.api_only
render json: error_response.body, status: :bad_request
else
render :error, locals: { error_response: error_response }
end
end
private
def render_success
if skip_authorization? || can_authorize_response?
redirect_or_render(authorize_response)
elsif Doorkeeper.configuration.api_only
render json: pre_auth
else
render :new
end
end
def render_error
pre_auth.error_response.raise_exception! if Doorkeeper.config.raise_on_errors?
if Doorkeeper.configuration.redirect_on_errors? && pre_auth.error_response.redirectable?
redirect_or_render(pre_auth.error_response)
elsif Doorkeeper.configuration.api_only
render json: pre_auth.error_response.body, status: pre_auth.error_response.status
else
render :error, locals: { error_response: pre_auth.error_response }, status: pre_auth.error_response.status
end
end
def can_authorize_response?
Doorkeeper.config.custom_access_token_attributes.empty? && pre_auth.client.application.confidential? && matching_token?
end
# Active access token issued for the same client and resource owner with
# the same set of the scopes exists?
def matching_token?
# We don't match tokens on the custom attributes here - we're in the pre-auth here,
# so they haven't been supplied yet (there are no custom attributes to match on yet)
@matching_token ||= Doorkeeper.config.access_token_model.matching_token_for(
pre_auth.client,
current_resource_owner,
pre_auth.scopes,
)
end
def redirect_or_render(auth)
if auth.redirectable?
if Doorkeeper.configuration.api_only
if pre_auth.form_post_response?
render(
json: { status: :post, redirect_uri: pre_auth.redirect_uri, body: auth.body },
status: auth.status,
)
else
render(
json: { status: :redirect, redirect_uri: auth.redirect_uri },
status: auth.status,
)
end
elsif pre_auth.form_post_response?
render :form_post, locals: { auth: auth }
else
redirect_to auth.redirect_uri, allow_other_host: true
end
else
render json: auth.body, status: auth.status
end
end
def pre_auth
@pre_auth ||= OAuth::PreAuthorization.new(
Doorkeeper.configuration,
pre_auth_params,
current_resource_owner,
)
end
def pre_auth_params
params.slice(*pre_auth_param_fields).permit(*pre_auth_param_fields)
end
def pre_auth_param_fields
custom_access_token_attributes + %i[
client_id
code_challenge
code_challenge_method
response_type
response_mode
redirect_uri
scope
state
]
end
def custom_access_token_attributes
Doorkeeper.config.custom_access_token_attributes.map(&:to_sym)
end
def authorization
@authorization ||= strategy.request
end
def strategy
@strategy ||= server.authorization_request(pre_auth.response_type)
end
def authorize_response
@authorize_response ||= begin
unless pre_auth.authorizable?
response = pre_auth.error_response
response.raise_exception! if Doorkeeper.config.raise_on_errors?
return response
end
context = build_context(pre_auth: pre_auth)
before_successful_authorization(context)
auth = strategy.authorize
context = build_context(auth: auth)
after_successful_authorization(context)
auth
end
end
def build_context(**attributes)
Doorkeeper::OAuth::Hooks::Context.new(**attributes)
end
def before_successful_authorization(context = nil)
Doorkeeper.config.before_successful_authorization.call(self, context)
end
def after_successful_authorization(context)
Doorkeeper.config.after_successful_authorization.call(self, context)
end
end
end
================================================
FILE: app/controllers/doorkeeper/authorized_applications_controller.rb
================================================
# frozen_string_literal: true
module Doorkeeper
class AuthorizedApplicationsController < Doorkeeper::ApplicationController
before_action :authenticate_resource_owner!
def index
@applications = Doorkeeper.config.application_model.authorized_for(current_resource_owner)
respond_to do |format|
format.html
format.json { render json: @applications, current_resource_owner: current_resource_owner }
end
end
def destroy
Doorkeeper.config.application_model.revoke_tokens_and_grants_for(
params[:id],
current_resource_owner,
)
respond_to do |format|
format.html do
redirect_to oauth_authorized_applications_url, notice: I18n.t(
:notice, scope: %i[doorkeeper flash authorized_applications destroy],
)
end
format.json { head :no_content }
end
end
end
end
================================================
FILE: app/controllers/doorkeeper/token_info_controller.rb
================================================
# frozen_string_literal: true
module Doorkeeper
class TokenInfoController < Doorkeeper::ApplicationMetalController
def show
if doorkeeper_token&.accessible?
render json: doorkeeper_token_to_json, status: :ok
else
error = OAuth::InvalidTokenResponse.new
response.headers.merge!(error.headers)
render json: error_to_json(error), status: error.status
end
end
protected
def doorkeeper_token_to_json
doorkeeper_token
end
def error_to_json(error)
error.body
end
end
end
================================================
FILE: app/controllers/doorkeeper/tokens_controller.rb
================================================
# frozen_string_literal: true
module Doorkeeper
class TokensController < Doorkeeper::ApplicationMetalController
before_action :validate_presence_of_client, only: [:revoke]
rescue_from Errors::DoorkeeperError do |e|
handle_token_exception(e)
end
def create
headers.merge!(authorize_response.headers)
render json: authorize_response.body,
status: authorize_response.status
end
# OAuth 2.0 Token Revocation - https://datatracker.ietf.org/doc/html/rfc7009
def revoke
# The authorization server responds with HTTP status code 200 if the client
# submitted an invalid token or the token has been revoked successfully.
if token.blank?
render json: {}, status: 200
# The authorization server validates [...] and whether the token
# was issued to the client making the revocation request. If this
# validation fails, the request is refused and the client is informed
# of the error by the authorization server as described below.
elsif authorized?
revoke_token
render json: {}, status: 200
else
render json: revocation_error_response, status: :forbidden
end
end
# OAuth 2.0 Token Introspection - https://datatracker.ietf.org/doc/html/rfc7662
def introspect
introspection = OAuth::TokenIntrospection.new(server, token)
if introspection.authorized?
render json: introspection.to_json, status: 200
else
error = introspection.error_response
headers.merge!(error.headers)
render json: error.body, status: error.status
end
end
private
def validate_presence_of_client
return if Doorkeeper.config.skip_client_authentication_for_password_grant
# @see 2.1. Revocation Request
#
# The client constructs the request by including the following
# parameters using the "application/x-www-form-urlencoded" format in
# the HTTP request entity-body:
# token REQUIRED.
# token_type_hint OPTIONAL.
#
# The client also includes its authentication credentials as described
# in Section 2.3. of [RFC6749].
#
# The authorization server first validates the client credentials (in
# case of a confidential client) and then verifies whether the token
# was issued to the client making the revocation request.
return if server.client
# If this validation [client credentials / token ownership] fails, the request is
# refused and the client is informed of the error by the authorization server as
# described below.
#
# @see 2.2.1. Error Response
#
# The error presentation conforms to the definition in Section 5.2 of [RFC6749].
render json: revocation_error_response, status: :forbidden
end
# OAuth 2.0 Section 2.1 defines two client types, "public" & "confidential".
#
# RFC7009
# Section 5. Security Considerations
# A malicious client may attempt to guess valid tokens on this endpoint
# by making revocation requests against potential token strings.
# According to this specification, a client's request must contain a
# valid client_id, in the case of a public client, or valid client
# credentials, in the case of a confidential client. The token being
# revoked must also belong to the requesting client.
#
# Once a client is authenticated, it must be authorized to
# revoke the provided access or refresh token. This ensures one client
# cannot revoke another's tokens.
#
# Doorkeeper checks token ownership for any token that has an
# application_id set. Tokens issued without a client (application_id
# is null) can be revoked without client authorization.
#
# https://datatracker.ietf.org/doc/html/rfc6749#section-2.1
# https://datatracker.ietf.org/doc/html/rfc7009
def authorized?
# Token belongs to specific client, so we need to check if
# authenticated client could access it.
if token.application_id?
# We authorize client by comparing client and token application IDs
server.client && server.client.id == token.application_id
else
# Token was issued without client, authorization unnecessary
true
end
end
def revoke_token
# The authorization server responds with HTTP status code 200 if the token
# has been revoked successfully or if the client submitted an invalid
# token
revocable_token.revoke if revocable_token.revocable?
end
def token
revocable_token&.token
end
def revocable_token
return @revocable_token if defined? @revocable_token
@revocable_token =
if params[:token_type_hint] == "refresh_token"
refresh_token
else
access_token || refresh_token
end
end
def refresh_token
token = Doorkeeper.config.access_token_model.by_refresh_token(params["token"])
return unless token
RevocableTokens::RevocableRefreshToken.new(token)
end
def access_token
token = Doorkeeper.config.access_token_model.by_token(params["token"])
return unless token
RevocableTokens::RevocableAccessToken.new(token)
end
def strategy
@strategy ||= server.token_request(params[:grant_type])
end
def authorize_response
@authorize_response ||= begin
before_successful_authorization
auth = strategy.authorize
context = build_context(auth: auth)
after_successful_authorization(context) unless auth.is_a?(Doorkeeper::OAuth::ErrorResponse)
auth
end
end
def build_context(**attributes)
Doorkeeper::OAuth::Hooks::Context.new(**attributes)
end
def before_successful_authorization(context = nil)
Doorkeeper.config.before_successful_authorization.call(self, context)
end
def after_successful_authorization(context)
Doorkeeper.config.after_successful_authorization.call(self, context)
end
def revocation_error_response
error_description = I18n.t(:unauthorized, scope: %i[doorkeeper errors messages revoke])
{ error: :unauthorized_client, error_description: error_description }
end
end
end
================================================
FILE: app/helpers/doorkeeper/dashboard_helper.rb
================================================
# frozen_string_literal: true
module Doorkeeper
module DashboardHelper
def doorkeeper_errors_for(object, method)
return if object.errors[method].blank?
output = object.errors[method].map do |msg|
content_tag(:span, class: "invalid-feedback") do
msg.capitalize
end
end
safe_join(output)
end
def doorkeeper_submit_path(application)
application.persisted? ? oauth_application_path(application) : oauth_applications_path
end
end
end
================================================
FILE: app/views/doorkeeper/applications/_delete_form.html.erb
================================================
<%- submit_btn_css ||= 'btn btn-link' %>
<%= form_tag oauth_application_path(application), method: :delete do %>
<%= submit_tag t('doorkeeper.applications.buttons.destroy'),
onclick: "return confirm('#{ t('doorkeeper.applications.confirmations.destroy') }')",
class: submit_btn_css %>
<% end %>
================================================
FILE: app/views/doorkeeper/applications/_form.html.erb
================================================
<%= form_for application, url: doorkeeper_submit_path(application), as: :doorkeeper_application, html: { role: 'form' } do |f| %>
<% if application.errors.any? %>
<div class="alert alert-danger" data-alert><p><%= t('doorkeeper.applications.form.error') %></p></div>
<% end %>
<div class="form-group row">
<%= f.label :name, class: 'col-sm-2 col-form-label font-weight-bold' %>
<div class="col-sm-10">
<%= f.text_field :name, class: "form-control #{ 'is-invalid' if application.errors[:name].present? }", required: true %>
<%= doorkeeper_errors_for application, :name %>
</div>
</div>
<div class="form-group row">
<%= f.label :redirect_uri, class: 'col-sm-2 col-form-label font-weight-bold' %>
<div class="col-sm-10">
<%= f.text_area :redirect_uri, class: "form-control #{ 'is-invalid' if application.errors[:redirect_uri].present? }" %>
<%= doorkeeper_errors_for application, :redirect_uri %>
<span class="form-text text-secondary">
<%= t('doorkeeper.applications.help.redirect_uri') %>
</span>
<% if Doorkeeper.configuration.allow_blank_redirect_uri?(application) %>
<span class="form-text text-secondary">
<%= t('doorkeeper.applications.help.blank_redirect_uri') %>
</span>
<% end %>
</div>
</div>
<div class="form-group row">
<%= f.label :confidential, class: 'col-sm-2 form-check-label font-weight-bold' %>
<div class="col-sm-10">
<%= f.check_box :confidential, class: "checkbox #{ 'is-invalid' if application.errors[:confidential].present? }" %>
<%= doorkeeper_errors_for application, :confidential %>
<span class="form-text text-secondary">
<%= t('doorkeeper.applications.help.confidential') %>
</span>
</div>
</div>
<div class="form-group row">
<%= f.label :scopes, class: 'col-sm-2 col-form-label font-weight-bold' %>
<div class="col-sm-10">
<%= f.text_field :scopes, class: "form-control #{ 'has-error' if application.errors[:scopes].present? }" %>
<%= doorkeeper_errors_for application, :scopes %>
<span class="form-text text-secondary">
<%= t('doorkeeper.applications.help.scopes') %>
</span>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<%= f.submit t('doorkeeper.applications.buttons.submit'), class: 'btn btn-primary' %>
<%= link_to t('doorkeeper.applications.buttons.cancel'), oauth_applications_path, class: 'btn btn-secondary' %>
</div>
</div>
<% end %>
================================================
FILE: app/views/doorkeeper/applications/edit.html.erb
================================================
<div class="border-bottom mb-4">
<h1><%= t('.title') %></h1>
</div>
<%= render 'form', application: @application %>
================================================
FILE: app/views/doorkeeper/applications/index.html.erb
================================================
<div class="border-bottom mb-4">
<h1><%= t('.title') %></h1>
</div>
<p><%= link_to t('.new'), new_oauth_application_path, class: 'btn btn-success' %></p>
<table class="table table-striped">
<thead>
<tr>
<th><%= t('.name') %></th>
<th><%= t('.callback_url') %></th>
<th><%= t('.confidential') %></th>
<th><%= t('.actions') %></th>
<th></th>
</tr>
</thead>
<tbody>
<% @applications.each do |application| %>
<tr id="application_<%= application.id %>">
<td class="align-middle">
<%= link_to application.name, oauth_application_path(application) %>
</td>
<td class="align-middle">
<%= simple_format(application.redirect_uri) %>
</td>
<td class="align-middle">
<%= application.confidential? ? t('doorkeeper.applications.index.confidentiality.yes') : t('doorkeeper.applications.index.confidentiality.no') %>
</td>
<td class="align-middle">
<%= link_to t('doorkeeper.applications.buttons.edit'), edit_oauth_application_path(application), class: 'btn btn-link' %>
</td>
<td class="align-middle">
<%= render 'delete_form', application: application %>
</td>
</tr>
<% end %>
</tbody>
</table>
================================================
FILE: app/views/doorkeeper/applications/new.html.erb
================================================
<div class="border-bottom mb-4">
<h1><%= t('.title') %></h1>
</div>
<%= render 'form', application: @application %>
================================================
FILE: app/views/doorkeeper/applications/show.html.erb
================================================
<div class="border-bottom mb-4">
<h1><%= t('.title', name: @application.name) %></h1>
</div>
<div class="row">
<div class="col-md-8">
<h4><%= t('.application_id') %></h4>
<p><code class="bg-light" id="application_id"><%= @application.uid %></code></p>
<h4><%= t('.secret') %></h4>
<p>
<code class="bg-light" id="secret">
<% secret = flash[:application_secret].presence || @application.plaintext_secret %>
<% if secret.blank? && Doorkeeper.config.application_secret_hashed? %>
<span class="bg-light font-italic text-uppercase text-muted"><%= t('.secret_hashed') %></span>
<% else %>
<%= secret %>
<% end %>
</code>
</p>
<h4><%= t('.scopes') %></h4>
<p>
<code class="bg-light" id="scopes">
<% if @application.scopes.present? %>
<%= @application.scopes %>
<% else %>
<span class="bg-light font-italic text-uppercase text-muted"><%= t('.not_defined') %></span>
<% end %>
</code>
</p>
<h4><%= t('.confidential') %></h4>
<p><code class="bg-light" id="confidential"><%= @application.confidential? %></code></p>
<h4><%= t('.callback_urls') %></h4>
<% if @application.redirect_uri.present? %>
<table>
<% @application.redirect_uri.split.each do |uri| %>
<tr>
<td>
<code class="bg-light"><%= uri %></code>
</td>
<td>
<%= link_to t('doorkeeper.applications.buttons.authorize'), oauth_authorization_path(client_id: @application.uid, redirect_uri: uri, response_type: 'code', scope: @application.scopes), class: 'btn btn-success', target: '_blank' %>
</td>
</tr>
<% end %>
</table>
<% else %>
<span class="bg-light font-italic text-uppercase text-muted"><%= t('.not_defined') %></span>
<% end %>
</div>
<div class="col-md-4">
<h3><%= t('.actions') %></h3>
<p><%= link_to t('doorkeeper.applications.buttons.edit'), edit_oauth_application_path(@application), class: 'btn btn-primary' %></p>
<p><%= render 'delete_form', application: @application, submit_btn_css: 'btn btn-danger' %></p>
</div>
</div>
================================================
FILE: app/views/doorkeeper/authorizations/error.html.erb
================================================
<div class="border-bottom mb-4">
<h1><%= t('doorkeeper.authorizations.error.title') %></h1>
</div>
<main role="main">
<pre>
<%= (local_assigns[:error_response] ? error_response : @pre_auth.error_response).body[:error_description] %>
</pre>
</main>
================================================
FILE: app/views/doorkeeper/authorizations/form_post.html.erb
================================================
<header class="page-header">
<h1><%= t('.title') %></h1>
</header>
<%= form_tag @pre_auth.redirect_uri, method: :post, name: :redirect_form, authenticity_token: false do %>
<% auth.body.compact.each do |key, value| %>
<%= hidden_field_tag key, value %>
<% end %>
<% end %>
<script>
window.onload = function () {
document.forms['redirect_form'].submit();
};
</script>
================================================
FILE: app/views/doorkeeper/authorizations/new.html.erb
================================================
<header class="page-header" role="banner">
<h1><%= t('.title') %></h1>
</header>
<main role="main">
<p class="h4">
<%= raw t('.prompt', client_name: content_tag(:strong, class: 'text-info') { @pre_auth.client.name }) %>
</p>
<% if @pre_auth.scopes.count > 0 %>
<div id="oauth-permissions">
<p><%= t('.able_to') %></p>
<ul class="text-info">
<% @pre_auth.scopes.each do |scope| %>
<li><%= t scope, scope: [:doorkeeper, :scopes] %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="actions">
<%= form_tag oauth_authorization_path, method: :post do %>
<%= hidden_field_tag :client_id, @pre_auth.client.uid, id: nil %>
<%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri, id: nil %>
<%= hidden_field_tag :state, @pre_auth.state, id: nil %>
<%= hidden_field_tag :response_type, @pre_auth.response_type, id: nil %>
<%= hidden_field_tag :response_mode, @pre_auth.response_mode, id: nil %>
<%= hidden_field_tag :scope, @pre_auth.scope, id: nil %>
<%= hidden_field_tag :code_challenge, @pre_auth.code_challenge, id: nil %>
<%= hidden_field_tag :code_challenge_method, @pre_auth.code_challenge_method, id: nil %>
<%= submit_tag t('doorkeeper.authorizations.buttons.authorize'), class: "btn btn-success btn-lg btn-block" %>
<% end %>
<%= form_tag oauth_authorization_path, method: :delete do %>
<%= hidden_field_tag :client_id, @pre_auth.client.uid, id: nil %>
<%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri, id: nil %>
<%= hidden_field_tag :state, @pre_auth.state, id: nil %>
<%= hidden_field_tag :response_type, @pre_auth.response_type, id: nil %>
<%= hidden_field_tag :response_mode, @pre_auth.response_mode, id: nil %>
<%= hidden_field_tag :scope, @pre_auth.scope, id: nil %>
<%= hidden_field_tag :code_challenge, @pre_auth.code_challenge, id: nil %>
<%= hidden_field_tag :code_challenge_method, @pre_auth.code_challenge_method, id: nil %>
<%= submit_tag t('doorkeeper.authorizations.buttons.deny'), class: "btn btn-danger btn-lg btn-block" %>
<% end %>
</div>
</main>
================================================
FILE: app/views/doorkeeper/authorizations/show.html.erb
================================================
<header class="page-header">
<h1><%= t('.title') %></h1>
</header>
<main role="main">
<code id="authorization_code"><%= params[:code] %></code>
</main>
================================================
FILE: app/views/doorkeeper/authorized_applications/_delete_form.html.erb
================================================
<%- submit_btn_css ||= 'btn btn-link' %>
<%= form_tag oauth_authorized_application_path(application), method: :delete do %>
<%= submit_tag t('doorkeeper.authorized_applications.buttons.revoke'), onclick: "return confirm('#{ t('doorkeeper.authorized_applications.confirmations.revoke') }')", class: submit_btn_css %>
<% end %>
================================================
FILE: app/views/doorkeeper/authorized_applications/index.html.erb
================================================
<header class="page-header">
<h1><%= t('doorkeeper.authorized_applications.index.title') %></h1>
</header>
<main role="main">
<table class="table table-striped">
<thead>
<tr>
<th><%= t('doorkeeper.authorized_applications.index.application') %></th>
<th><%= t('doorkeeper.authorized_applications.index.created_at') %></th>
<th></th>
</tr>
</thead>
<tbody>
<% @applications.each do |application| %>
<tr>
<td><%= application.name %></td>
<td><%= application.created_at.strftime(t('doorkeeper.authorized_applications.index.date_format')) %></td>
<td><%= render 'delete_form', application: application %></td>
</tr>
<% end %>
</tbody>
</table>
</main>
================================================
FILE: app/views/layouts/doorkeeper/admin.html.erb
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= t('doorkeeper.layouts.admin.title') %></title>
<%= stylesheet_link_tag "doorkeeper/admin/application" %>
<%= csrf_meta_tags %>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-5">
<%= link_to t('doorkeeper.layouts.admin.nav.oauth2_provider'), oauth_applications_path, class: 'navbar-brand' %>
<div class="collapse navbar-collapse">
<ul class="navbar-nav mr-auto">
<li class="nav-item <%= 'active' if request.path == oauth_applications_path %>">
<%= link_to t('doorkeeper.layouts.admin.nav.applications'), oauth_applications_path, class: 'nav-link' %>
</li>
<% if respond_to?(:root_path) %>
<li class="nav-item">
<%= link_to t('doorkeeper.layouts.admin.nav.home'), root_path, class: 'nav-link' %>
</li>
<% end %>
</ul>
</div>
</nav>
<div class="doorkeeper-admin container">
<%- if flash[:notice].present? %>
<div class="alert alert-info">
<%= flash[:notice] %>
</div>
<% end -%>
<%= yield %>
</div>
</body>
</html>
================================================
FILE: app/views/layouts/doorkeeper/application.html.erb
================================================
<!DOCTYPE html>
<html>
<head>
<title><%= t('doorkeeper.layouts.application.title') %></title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<%= stylesheet_link_tag "doorkeeper/application" %>
<%= csrf_meta_tags %>
</head>
<body>
<div id="container">
<%- if flash[:notice].present? %>
<div class="alert alert-info">
<%= flash[:notice] %>
</div>
<% end -%>
<%= yield %>
</div>
</body>
</html>
================================================
FILE: benchmark/ruby/client_credentials.rb
================================================
# frozen_string_literal: true
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "..", "lib"))
begin
require "bundler/inline"
rescue LoadError => e
warn "Bundler version 1.10 or later is required. Please update your Bundler"
raise e
end
gemfile(true) do
source "https://rubygems.org"
gem "sqlite3"
gem "rails"
gem "benchmark-ips"
end
require "benchmark/ips"
require "ostruct"
require "doorkeeper"
require "active_support/all"
require "active_record/railtie"
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = ENV["LOGGER"].present? ? Logger.new(STDOUT) : nil
# Load database schema
load File.expand_path("../../spec/dummy/db/schema.rb", __dir__)
Doorkeeper.configure do
orm :active_record
grant_flows %w[password authorization_code client_credentials]
skip_authorization do
true
end
end
client = Doorkeeper::Application.create!(
name: "test",
uid: "123456789",
secret: "987654321",
redirect_uri: "https://doorkeeper.test",
)
context = OpenStruct.new
request = OpenStruct.new
request.parameters = {
client_id: client.uid,
client_secret: client.secret,
}.with_indifferent_access
context.request = request
Benchmark.ips do |ips|
ips.report("Client credentials") do
server = Doorkeeper::Server.new(context)
strategy = server.token_request("client_credentials")
strategy.authorize
end
end
================================================
FILE: benchmark/wrk/.keep
================================================
================================================
FILE: bin/console
================================================
#!/usr/bin/env ruby
# frozen_string_literal: true
require "bundler/setup"
require "rails/all"
require "active_support/all"
require "irb"
require "debug"
require "doorkeeper"
Rails.logger = Logger.new(STDOUT)
Rails.logger.info("Doorkeeper version: #{Doorkeeper::VERSION::STRING}")
Rails.logger.info("Rails version: #{Rails::VERSION::STRING}")
# Default Doorkeeper config
Doorkeeper.configure do
orm :active_record
end
# Generate in-memory database for testing
ActiveRecord::Base.establish_connection(
adapter: "sqlite3",
database: ":memory:",
)
# Load database schema
load File.expand_path("../spec/dummy/db/schema.rb", __dir__)
IRB.start(__FILE__)
================================================
FILE: config/locales/en.yml
================================================
en:
activerecord:
attributes:
doorkeeper/application:
name: 'Name'
redirect_uri: 'Redirect URI'
errors:
models:
doorkeeper/application:
attributes:
redirect_uri:
fragment_present: 'cannot contain a fragment.'
invalid_uri: 'must be a valid URI.'
unspecified_scheme: 'must specify a scheme.'
relative_uri: 'must be an absolute URI.'
secured_uri: 'must be an HTTPS/SSL URI.'
forbidden_uri: 'is forbidden by the server.'
scopes:
not_match_configured: "doesn't match those configured on the server."
doorkeeper:
applications:
confirmations:
destroy: 'Are you sure?'
buttons:
edit: 'Edit'
destroy: 'Destroy'
submit: 'Submit'
cancel: 'Cancel'
authorize: 'Authorize'
form:
error: 'Whoops! Check your form for possible errors'
help:
confidential: 'Application will be used where the client secret can be kept confidential. Native mobile apps and Single Page Apps are considered non-confidential.'
redirect_uri: 'Use one line per URI'
blank_redirect_uri: "Leave it blank if you configured your provider to use Client Credentials, Resource Owner Password Credentials or any other grant type that doesn't require a redirect URI."
scopes: 'Separate scopes with spaces. Leave blank to use the default scopes.'
edit:
title: 'Edit application'
index:
title: 'Your applications'
new: 'New Application'
name: 'Name'
callback_url: 'Callback URL'
confidential: 'Confidential?'
actions: 'Actions'
confidentiality:
'yes': 'Yes'
'no': 'No'
new:
title: 'New Application'
show:
title: 'Application: %{name}'
application_id: 'UID:'
secret: 'Secret:'
secret_hashed: 'Secret hashed'
scopes: 'Scopes:'
confidential: 'Confidential:'
callback_urls: 'Callback URLs:'
actions: 'Actions'
not_defined: 'Not defined'
authorizations:
buttons:
authorize: 'Authorize'
deny: 'Deny'
error:
title: 'An error has occurred'
new:
title: 'Authorization required'
prompt: 'Authorize %{client_name} to use your account?'
able_to: 'This application will be able to:'
show:
title: 'Authorization code:'
form_post:
title: 'Submit this form'
authorized_applications:
confirmations:
revoke: 'Are you sure?'
buttons:
revoke: 'Revoke'
index:
title: 'Your authorized applications'
application: 'Application'
created_at: 'Created At'
date_format: '%Y-%m-%d %H:%M:%S'
pre_authorization:
status: 'Pre-authorization'
errors:
messages:
# Common error messages
invalid_request:
unknown: 'The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.'
missing_param: 'Missing required parameter: %{value}.'
request_not_authorized: 'Request needs to be authorized. Required parameter for authorizing the request is missing or invalid.'
invalid_code_challenge: 'Code challenge is required.'
invalid_redirect_uri: "The requested redirect URI is malformed or doesn't match the client redirect URI."
unauthorized_client: 'The client is not authorized to perform this request using this method.'
access_denied: 'The resource owner or authorization server denied the request.'
invalid_scope: 'The requested scope is invalid, unknown, or malformed.'
invalid_code_challenge_method:
zero: 'The authorization server does not support PKCE as there are no accepted code_challenge_method values.'
one: 'The code_challenge_method must be %{challenge_methods}.'
other: 'The code_challenge_method must be one of %{challenge_methods}.'
server_error: 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.'
temporarily_unavailable: 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.'
# Configuration error messages
credential_flow_not_configured: 'Resource Owner Password Credentials flow failed due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured.'
resource_owner_authenticator_not_configured: 'Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfigured.'
admin_authenticator_not_configured: 'Access to admin panel is forbidden due to Doorkeeper.configure.admin_authenticator being unconfigured.'
# Access grant errors
unsupported_response_type: 'The authorization server does not support this response type.'
unsupported_response_mode: 'The authorization server does not support this response mode.'
# Access token errors
invalid_client: 'Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.'
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.'
unsupported_grant_type: 'The authorization grant type is not supported by the authorization server.'
invalid_token:
revoked: "The access token was revoked"
expired: "The access token expired"
unknown: "The access token is invalid"
revoke:
unauthorized: "You are not authorized to revoke this token"
forbidden_token:
missing_scope: 'Access to this resource requires scope "%{oauth_scopes}".'
flash:
applications:
create:
notice: 'Application created.'
destroy:
notice: 'Application deleted.'
update:
notice: 'Application updated.'
authorized_applications:
destroy:
notice: 'Application revoked.'
layouts:
admin:
title: 'Doorkeeper'
nav:
oauth2_provider: 'OAuth2 Provider'
applications: 'Applications'
home: 'Home'
application:
title: 'OAuth authorization required'
================================================
FILE: doorkeeper.gemspec
================================================
# frozen_string_literal: true
$LOAD_PATH.unshift(File.expand_path("lib", __dir__))
require "doorkeeper/version"
Gem::Specification.new do |gem|
gem.name = "doorkeeper"
gem.version = Doorkeeper::VERSION::STRING
gem.authors = ["Felipe Elias Philipp", "Tute Costa", "Jon Moss", "Nikita Bulai"]
gem.email = %w[bulaj.nikita@gmail.com]
gem.homepage = "https://github.com/doorkeeper-gem/doorkeeper"
gem.summary = "OAuth 2 provider for Rails and Grape"
gem.description = "Doorkeeper is an OAuth 2 provider for Rails and Grape."
gem.license = "MIT"
gem.files = Dir[
"{app,config,lib,vendor}/**/*",
"CHANGELOG.md",
"MIT-LICENSE",
"README.md",
]
gem.require_paths = ["lib"]
gem.metadata = {
"homepage_uri" => "https://github.com/doorkeeper-gem/doorkeeper",
"changelog_uri" => "https://github.com/doorkeeper-gem/doorkeeper/blob/main/CHANGELOG.md",
"source_code_uri" => "https://github.com/doorkeeper-gem/doorkeeper",
"bug_tracker_uri" => "https://github.com/doorkeeper-gem/doorkeeper/issues",
"documentation_uri" => "https://doorkeeper.gitbook.io/guides/",
"funding_uri" => "https://opencollective.com/doorkeeper-gem",
}
gem.add_dependency "railties", ">= 5"
gem.required_ruby_version = ">= 2.7"
gem.add_development_dependency "appraisal"
gem.add_development_dependency "capybara"
gem.add_development_dependency "coveralls_reborn"
gem.add_development_dependency "database_cleaner", "~> 2.0"
gem.add_development_dependency "factory_bot", "~> 6.0"
gem.add_development_dependency "generator_spec", "~> 0.10.0"
gem.add_development_dependency "grape"
gem.add_development_dependency "rake", ">= 11.3.0"
gem.add_development_dependency "rspec-rails"
gem.add_development_dependency "timecop"
end
================================================
FILE: gemfiles/rails_7_0.gemfile
================================================
# This file was generated by Appraisal
source "https://rubygems.org"
gem "rails", "~> 7.0.0"
gem "rspec-core"
gem "rspec-expectations"
gem "rspec-mocks"
gem "rspec-rails", "~> 5.0"
gem "rspec-support"
gem "rubocop", "~> 1.4"
gem "rubocop-performance", require: false
gem "rubocop-rails", require: false
gem "rubocop-rspec", require: false
gem "bcrypt", "~> 3.1", require: false
gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
gem "sprockets-rails"
gem "sqlite3", "~> 1.4", platform: [:ruby, :mswin, :mingw, :x64_mingw]
gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw]
gem "timecop"
gem "base64"
gem "drb"
gem "mutex_m"
gem "concurrent-ruby", "1.3.4"
gemspec path: "../"
================================================
FILE: gemfiles/rails_7_1.gemfile
================================================
# This file was generated by Appraisal
source "https://rubygems.org"
gem "rails", "~> 7.1.0"
gem "rspec-core"
gem "rspec-expectations"
gem "rspec-mocks"
gem "rspec-rails", "~> 7.1"
gem "rspec-support"
gem "rubocop", "~> 1.4"
gem "rubocop-performance", require: false
gem "rubocop-rails", require: false
gem "rubocop-rspec", require: false
gem "bcrypt", "~> 3.1", require: false
gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
gem "sprockets-rails"
gem "sqlite3", "~> 1.4", platform: [:ruby, :mswin, :mingw, :x64_mingw]
gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw]
gem "timecop"
gemspec path: "../"
================================================
FILE: gemfiles/rails_7_2.gemfile
================================================
# This file was generated by Appraisal
source "https://rubygems.org"
gem "rails", "~> 7.2.0"
gem "rspec-core"
gem "rspec-expectations"
gem "rspec-mocks"
gem "rspec-rails", "~> 7.1"
gem "rspec-support"
gem "rubocop", "~> 1.4"
gem "rubocop-performance", require: false
gem "rubocop-rails", require: false
gem "rubocop-rspec", require: false
gem "bcrypt", "~> 3.1", require: false
gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
gem "sprockets-rails"
gem "sqlite3", "~> 1.4", platform: [:ruby, :mswin, :mingw, :x64_mingw]
gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw]
gem "timecop"
gemspec path: "../"
================================================
FILE: gemfiles/rails_8_0.gemfile
================================================
# This file was generated by Appraisal
source "https://rubygems.org"
gem "rails", "~> 8.0.0"
gem "rspec-core"
gem "rspec-expectations"
gem "rspec-mocks"
gem "rspec-rails", "~> 7.1"
gem "rspec-support"
gem "rubocop", "~> 1.4"
gem "rubocop-performance", require: false
gem "rubocop-rails", require: false
gem "rubocop-rspec", require: false
gem "bcrypt", "~> 3.1", require: false
gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
gem "sprockets-rails"
gem "sqlite3", "~> 2.3", platform: [:ruby, :mswin, :mingw, :x64_mingw]
gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw]
gem "timecop"
gemspec path: "../"
================================================
FILE: gemfiles/rails_edge.gemfile
================================================
# This file was generated by Appraisal
source "https://rubygems.org"
gem "rails", git: "https://github.com/rails/rails"
gem "rspec-core"
gem "rspec-expectations"
gem "rspec-mocks"
gem "rspec-rails", "~> 7.1"
gem "rspec-support"
gem "rubocop", "~> 1.4"
gem "rubocop-performance", require: false
gem "rubocop-rails", require: false
gem "rubocop-rspec", require: false
gem "bcrypt", "~> 3.1", require: false
gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
gem "sprockets-rails"
gem "sqlite3", "~> 2.3", platform: [:ruby, :mswin, :mingw, :x64_mingw]
gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw]
gem "timecop"
gemspec path: "../"
================================================
FILE: lib/doorkeeper/config/abstract_builder.rb
================================================
# frozen_string_literal: true
module Doorkeeper
class Config
# Abstract base class for Doorkeeper and it's extensions configuration
# builder. Instantiates and validates gem configuration.
#
class AbstractBuilder
attr_reader :config
# @param [Class] config class
#
def initialize(config = Config.new, &block)
@config = config
instance_eval(&block) if block_given?
end
# Builds and validates configuration.
#
# @return [Doorkeeper::Config] config instance
#
def build
@config.validate! if @config.respond_to?(:validate!)
@config
end
end
end
end
================================================
FILE: lib/doorkeeper/config/option.rb
================================================
# frozen_string_literal: true
module Doorkeeper
class Config
# Doorkeeper configuration option DSL
module Option
# Defines configuration option
#
# When you call option, it defines two methods. One method will take place
# in the +Config+ class and the other method will take place in the
# +Builder+ class.
#
# The +name+ parameter will set both builder method and config attribute.
# If the +:as+ option is defined, the builder method will be the specified
# option while the config attribute will be the +name+ parameter.
#
# If you want to introduce another level of config DSL you can
# define +builder_class+ parameter.
# Builder should take a block as the initializer parameter and respond to function +build+
# that returns the value of the config attribute.
#
# ==== Options
#
# * [:+as+] Set the builder method that goes inside +configure+ block
# * [+:default+] The default value in case no option was set
# * [+:builder_class+] Configuration option builder class
#
# ==== Examples
#
# option :name
# option :name, as: :set_name
# option :name, default: 'My Name'
# option :scopes builder_class: ScopesBuilder
#
def option(name, options = {})
attribute = options[:as] || name
attribute_builder = options[:builder_class]
builder_class.instance_eval do
if method_defined?(name)
Kernel.warn "[DOORKEEPER] Option #{name} already defined and will be overridden"
remove_method name
end
define_method name do |*args, &block|
if (deprecation_opts = options[:deprecated])
warning = "[DOORKEEPER] #{name} has been deprecated and will soon be removed"
warning = "#{warning}\n#{deprecation_opts.fetch(:message)}" if deprecation_opts.is_a?(Hash)
Kernel.warn(warning)
end
value = if attribute_builder
attribute_builder.new(&block).build
else
block || args.first
end
@config.instance_variable_set(:"@#{attribute}", value)
end
end
define_method attribute do |*_args|
if instance_variable_defined?(:"@#{attribute}")
instance_variable_get(:"@#{attribute}")
else
options[:default]
end
end
public attribute
end
def self.extended(base)
return if base.respond_to?(:builder_class)
raise Doorkeeper::MissingConfigurationBuilderClass, "Define `self.builder_class` method " \
"for #{base} that returns your custom Builder class to use options DSL!"
end
end
end
end
================================================
FILE: lib/doorkeeper/config/validations.rb
================================================
# frozen_string_literal: true
module Doorkeeper
class Config
# Doorkeeper configuration validator.
#
module Validations
# Validates configuration options to be set properly.
#
def validate!
validate_reuse_access_token_value
validate_token_reuse_limit
validate_secret_strategies
validate_pkce_code_challenge_methods
end
private
# Determine whether +reuse_access_token+ and a non-restorable
# +token_secret_strategy+ have both been activated.
#
# In that case, disable reuse_access_token value and warn the user.
def validate_reuse_access_token_value
strategy = token_secret_strategy
return if !reuse_access_token || strategy.allows_restoring_secrets?
::Rails.logger.warn(
"[DOORKEEPER] You have configured both reuse_access_token " \
"AND '#{strategy}' strategy which cannot restore tokens. " \
"This combination is unsupported. reuse_access_token will be disabled",
)
@reuse_access_token = false
end
# Validate that the provided strategies are valid for
# tokens and applications
def validate_secret_strategies
token_secret_strategy.validate_for(:token)
application_secret_strategy.validate_for(:application)
end
def validate_token_reuse_limit
return if !reuse_access_token ||
(token_reuse_limit > 0 && token_reuse_limit <= 100)
::Rails.logger.warn(
"[DOORKEEPER] You have configured an invalid value for token_reuse_limit option. " \
"It will be set to default 100",
)
@token_reuse_limit = 100
end
def validate_pkce_code_challenge_methods
return if pkce_code_challenge_methods.all? {|method| method =~ /^plain$|^S256$/ }
::Rails.logger.warn(
"[DOORKEEPER] You have configured an invalid value for pkce_code_challenge_methods option. " \
"It will be set to default ['plain', 'S256']",
)
@pkce_code_challenge_methods = ['plain', 'S256']
end
end
end
end
================================================
FILE: lib/doorkeeper/config.rb
================================================
# frozen_string_literal: true
require "doorkeeper/config/abstract_builder"
require "doorkeeper/config/option"
require "doorkeeper/config/validations"
module Doorkeeper
# Doorkeeper option DSL could be reused in extensions to build their own
# configurations. To use the Option DSL gems need to define `builder_class` method
# that returns configuration Builder class. This exception raises when they don't
# define it.
#
class Config
# Default Doorkeeper configuration builder
class Builder < AbstractBuilder
# Provide support for an owner to be assigned to each registered
# application (disabled by default)
# Optional parameter confirmation: true (default false) if you want
# to enforce ownership of a registered application
#
# @param opts [Hash] the options to confirm if an application owner
# is present
# @option opts[Boolean] :confirmation (false)
# Set confirm_application_owner variable
def enable_application_owner(opts = {})
@config.instance_variable_set(:@enable_application_owner, true)
confirm_application_owner if opts[:confirmation].present? && opts[:confirmation]
end
def confirm_application_owner
@config.instance_variable_set(:@confirm_application_owner, true)
end
# Provide support for dynamic scopes (e.g. user:*) (disabled by default)
# Optional parameter delimiter (default ":") if you want to customize
# the delimiter separating the scope name and matching value.
#
# @param opts [Hash] the options to configure dynamic scopes
def enable_dynamic_scopes(opts = {})
@config.instance_variable_set(:@enable_dynamic_scopes, true)
@config.instance_variable_set(:@dynamic_scopes_delimiter, opts[:delimiter] || ':')
end
# Define default access token scopes for your provider
#
# @param scopes [Array] Default set of access (OAuth::Scopes.new)
# token scopes
def default_scopes(*scopes)
@config.instance_variable_set(:@default_scopes, OAuth::Scopes.from_array(scopes))
end
# Define default access token scopes for your provider
#
# @param scopes [Array] Optional set of access (OAuth::Scopes.new)
# token scopes
def optional_scopes(*scopes)
@config.instance_variable_set(:@optional_scopes, OAuth::Scopes.from_array(scopes))
end
# Define scopes_by_grant_type to limit certain scope to certain grant_type
# @param { Hash } with grant_types as keys.
# Default set to {} i.e. no limitation on scopes usage
def scopes_by_grant_type(hash = {})
@config.instance_variable_set(:@scopes_by_grant_type, hash)
end
# Change the way client credentials are retrieved from the request object.
# By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
# falls back to the `:client_id` and `:client_secret` params from the
# `params` object.
#
# @param methods [Array] Define client credentials
def client_credentials(*methods)
@config.instance_variable_set(:@client_credentials_methods, methods)
end
# Change the way access token is authenticated from the request object.
# By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
# falls back to the `:access_token` or `:bearer_token` params from the
# `params` object.
#
# @param methods [Array] Define access token methods
def access_token_methods(*methods)
@config.instance_variable_set(:@access_token_methods, methods)
end
# Issue access tokens with refresh token (disabled if not set)
def use_refresh_token(enabled = true, &block)
@config.instance_variable_set(
:@refresh_token_enabled,
block || enabled,
)
end
# Reuse access token for the same resource owner within an application
# (disabled by default)
# Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
def reuse_access_token
@config.instance_variable_set(:@reuse_access_token, true)
end
# Enable support for multiple database configurations with read replicas.
# When enabled, wraps database write operations to ensure they use the primary
# (writable) database when automatic role switching is enabled.
#
# For ActiveRecord (Rails 6.1+), this uses `ActiveRecord::Base.connected_to(role: :writing)`.
# Other ORM extensions can implement their own primary database targeting logic.
#
# This prevents `ActiveRecord::ReadOnlyError` when using read replicas with Rails
# automatic role switching. Enable this if your application uses multiple databases
# with automatic role switching for read replicas.
#
# See: https://guides.rubyonrails.org/active_record_multiple_databases.html#activating-automatic-role-switching
def enable_multiple_database_roles
@config.instance_variable_set(:@enable_multiple_database_roles, true)
end
# Choose to use the url path for native autorization codes
# Enabling this flag sets the authorization code response route for
# native redirect uris to oauth/authorize/<code>. The default is
# oauth/authorize/native?code=<code>.
# Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1143
def use_url_path_for_native_authorization
@config.instance_variable_set(:@use_url_path_for_native_authorization, true)
end
# TODO: maybe make it more generic for other flows too?
# Only allow one valid access token obtained via client credentials
# per client. If a new access token is obtained before the old one
# expired, the old one gets revoked (disabled by default)
def revoke_previous_client_credentials_token
@config.instance_variable_set(:@revoke_previous_client_credentials_token, true)
end
# Only allow one valid access token obtained via authorization code
# per client. If a new access token is obtained before the old one
# expired, the old one gets revoked (disabled by default)
def revoke_previous_authorization_code_token
@config.instance_variable_set(:@revoke_previous_authorization_code_token, true)
end
# Require non-confidential apps to use PKCE (send a code_verifier) when requesting
# an access_token using an authorization code (disabled by default)
def force_pkce
@config.instance_variable_set(:@force_pkce, true)
end
# Use an API mode for applications generated with --api argument
# It will skip applications controller, disable forgery protection
def api_only
@config.instance_variable_set(:@api_only, true)
end
# Enables polymorphic Resource Owner association for Access Grant and
# Access Token models. Requires additional database columns to be setup.
def use_polymorphic_resource_owner
@config.instance_variable_set(:@polymorphic_resource_owner, true)
end
# Forbids creating/updating applications with arbitrary scopes that are
# not in configuration, i.e. `default_scopes` or `optional_scopes`.
# (disabled by default)
def enforce_configured_scopes
@config.instance_variable_set(:@enforce_configured_scopes, true)
end
# Enforce request content type as the spec requires:
# disabled by default for backward compatibility.
def enforce_content_type
@config.instance_variable_set(:@enforce_content_type, true)
end
# Allow optional hashing of input tokens before persisting them.
# Will be used for hashing of input token and grants.
#
# @param using
# Provide a different secret storage implementation class for tokens
# @param fallback
# Provide a fallback secret storage implementation class for tokens
# or use :plain to fallback to plain tokens
def hash_token_secrets(using: nil, fallback: nil)
default = "::Doorkeeper::SecretStoring::Sha256Hash"
configure_secrets_for :token,
using: using || default,
fallback: fallback
end
# Allow optional hashing of application secrets before persisting them.
# Will be used for hashing of input token and grants.
#
# @param using
# Provide a different secret storage implementation for applications
# @param fallback
# Provide a fallback secret storage implementation for applications
# or use :plain to fallback to plain application secrets
def hash_application_secrets(using: nil, fallback: nil)
default = "::Doorkeeper::SecretStoring::Sha256Hash"
configure_secrets_for :application,
using: using || default,
fallback: fallback
end
private
# Configure the secret storing functionality
def configure_secrets_for(type, using:, fallback:)
raise ArgumentError, "Invalid type #{type}" if %i[application token].exclude?(type)
@config.instance_variable_set(:"@#{type}_secret_strategy", using.constantize)
if fallback.nil?
return
elsif fallback.to_sym == :plain
fallback = "::Doorkeeper::SecretStoring::Plain"
end
@config.instance_variable_set(:"@#{type}_secret_fallback_strategy", fallback.constantize)
end
end
# Replace with `default: Builder` when we drop support of Rails < 5.2
mattr_reader(:builder_class) { Builder }
extend Option
include Validations
option :resource_owner_authenticator,
as: :authenticate_resource_owner,
default: (lambda do |_routes|
::Rails.logger.warn(
I18n.t("doorkeeper.errors.messages.resource_owner_authenticator_not_configured"),
)
nil
end)
option :admin_authenticator,
as: :authenticate_admin,
default: (lambda do |_routes|
::Rails.logger.warn(
I18n.t("doorkeeper.errors.messages.admin_authenticator_not_configured"),
)
head :forbidden
end)
option :resource_owner_from_credentials,
default: (lambda do |_routes|
::Rails.logger.warn(
I18n.t("doorkeeper.errors.messages.credential_flow_not_configured"),
)
nil
end)
# Hooks for authorization
option :before_successful_authorization, default: ->(_controller, _context = nil) {}
option :after_successful_authorization, default: ->(_controller, _context = nil) {}
# Hooks for strategies responses
option :before_successful_strategy_response, default: ->(_request) {}
option :after_successful_strategy_response, default: ->(_request, _response) {}
# Allows to customize Token Introspection response
option :custom_introspection_response, default: ->(_token, _context) { {} }
option :skip_authorization, default: ->(_routes) {}
option :access_token_expires_in, default: 7200
option :custom_access_token_expires_in, default: ->(_context) { nil }
option :authorization_code_expires_in, default: 600
option :orm, default: :active_record
option :native_redirect_uri, default: "urn:ietf:wg:oauth:2.0:oob", deprecated: true
option :grant_flows, default: %w[authorization_code client_credentials]
option :pkce_code_challenge_methods, default: %w[plain S256]
option :handle_auth_errors, default: :render
option :token_lookup_batch_size, default: 10_000
# Sets the token_reuse_limit
# It will be used only when reuse_access_token option in enabled
# By default it will be 100
# It will be used for token reusablity to some threshold percentage
# Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1189
option :token_reuse_limit, default: 100
# Don't require client authentication for password grants. If client credentials
# are present they will still be validated, and the grant rejected if the credentials
# are invalid.
#
# This is discouraged. Spec says that password grants always require a client.
#
# See https://github.com/doorkeeper-gem/doorkeeper/issues/1412#issuecomment-632750422
# and https://github.com/doorkeeper-gem/doorkeeper/pull/1420
#
# Since many applications use this unsafe behavior in the wild, this is kept as a
# not-recommended option. You should be aware that you are not following the OAuth
# spec, and understand the security implications of doing so.
option :skip_client_authentication_for_password_grant,
default: false
# Hook to allow arbitrary user-client authorization
option :authorize_resource_owner_for_client,
default: ->(_client, _resource_owner) { true }
# Allows to customize OAuth grant flows that +each+ application support.
# You can configure a custom block (or use a class respond to `#call`) that must
# return `true` in case Application instance supports requested OAuth grant flow
# during the authorization request to the server. This configuration +doesn't+
# set flows per application, it only allows to check if application supports
# specific grant flow.
#
# For example you can add an additional database column to `oauth_applications` table,
# say `t.array :grant_flows, default: []`, and store allowed grant flows that can
# be used with this application there. Then when authorization requested Doorkeeper
# will call this block to check if specific Application (passed with client_id and/or
# client_secret) is allowed to perform the request for the specific grant type
# (authorization, password, client_credentials, etc).
#
# Example of the block:
#
# ->(flow, client) { client.grant_flows.include?(flow) }
#
# In case this option invocation result is `false`, Doorkeeper server returns
# :unauthorized_client error and stops the request.
#
# @param allow_grant_flow_for_client [Proc] Block or any object respond to #call
# @return [Boolean] `true` if allow or `false` if forbid the request
#
option :allow_grant_flow_for_client, default: ->(_grant_flow, _client) { true }
# Allows to forbid specific Application redirect URI's by custom rules.
# Doesn't forbid any URI by default.
#
# @param forbid_redirect_uri [Proc] Block or any object respond to #call
#
option :forbid_redirect_uri, default: ->(_uri) { false }
# WWW-Authenticate Realm (default "Doorkeeper").
#
# @param realm [String] ("Doorkeeper") Authentication realm
#
option :realm, default: "Doorkeeper"
# Forces the usage of the HTTPS protocol in non-native redirect uris
# (enabled by default in non-development environments). OAuth2
# delegates security in communication to the HTTPS protocol so it is
# wise to keep this enabled.
#
# @param [Boolean] boolean_or_block value for the parameter, true by default in
# non-development environment
#
# @yield [uri] Conditional usage of SSL redirect uris.
# @yieldparam [URI] Redirect URI
# @yieldreturn [Boolean] Indicates necessity of usage of the HTTPS protocol
# in non-native redirect uris
#
option :force_ssl_in_redirect_uri, default: !Rails.env.development?
# Use a custom class for generating the access token.
# https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-access-token-generator
#
# @param access_token_generator [String]
# the name of the access token generator class
#
option :access_token_generator,
default: "Doorkeeper::OAuth::Helpers::UniqueToken"
# Allows additional data to be received when granting access to an Application, and for this
# additional data to be sent with subsequently generated access tokens. The access grant and
# access token models will both need to respond to the specified attribute names.
#
# @param attributes [Array] The array of custom attribute names to be saved
#
option :custom_access_token_attributes,
default: []
# Use a custom class for generating the application secret.
# https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-application-secret-generator
#
# @param application_secret_generator [String]
# the name of the application secret generator class
#
option :application_secret_generator,
default: "Doorkeeper::OAuth::Helpers::UniqueToken"
# Default access token generator is a SecureRandom class from Ruby stdlib.
# This option defines which method will be used to generate a unique token value.
#
# @param default_generator_method [Symbol]
# the method name of the default access token generator
#
option :default_generator_method, default: :urlsafe_base64
# The controller Doorkeeper::ApplicationController inherits from.
# Defaults to ActionController::Base.
# https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-controllers
#
# @param base_controller [String] the name of the base controller
option :base_controller,
default: (lambda do
api_only ? "ActionController::API" : "ActionController::Base"
end)
# The controller Doorkeeper::ApplicationMetalController inherits from.
# Defaults to ActionController::API.
#
# @param base_metal_controller [String] the name of the base controller
option :base_metal_controller,
default: "ActionController::API"
option :access_token_class,
default: "Doorkeeper::AccessToken"
option :access_grant_class,
default: "Doorkeeper::AccessGrant"
option :application_class,
default: "Doorkeeper::Application"
# Allows to set blank redirect URIs for Applications in case
# server configured to use URI-less grant flows.
#
option :allow_blank_redirect_uri,
default: (lambda do |grant_flows, _application|
grant_flows.exclude?("authorization_code") &&
grant_flows.exclude?("implicit")
end)
# Configure protection of token introspection request.
# By default this configuration allows to introspect a token by
# another token of the same application, or to introspect the token
# that belongs to authorized client, or access token has been introspected
# is a public one (doesn't belong to any client)
#
# You can define any custom rule you need or just disable token
# introspection at all.
#
# @param token [Doorkeeper::AccessToken]
# token to be introspected
#
# @param authorized_client [Doorkeeper::Application]
# authorized client (if request is authorized using Basic auth with
# Client Credentials for example)
#
# @param authorized_token [Doorkeeper::AccessToken]
# Bearer token used to authorize the request
#
option :allow_token_introspection,
default: (lambda do |token, authorized_client, authorized_token|
if authorized_token
authorized_token.application == token&.application
elsif token&.application
authorized_client == token.application
else
true
end
end)
attr_reader :reuse_access_token,
:enable_multiple_database_roles,
:token_secret_fallback_strategy,
:application_secret_fallback_strategy
def clear_cache!
%i[
application_model
access_token_model
access_grant_model
].each do |var|
remove_instance_variable("@#{var}") if instance_variable_defined?("@#{var}")
end
end
# Doorkeeper Access Token model class.
#
# @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
#
def access_token_model
@access_token_model ||= access_token_class.constantize
end
# Doorkeeper Access Grant model class.
#
# @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
#
def access_grant_model
@access_grant_model ||= access_grant_class.constantize
end
# Doorkeeper Application model class.
#
# @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
#
def application_model
@application_model ||= application_class.constantize
end
def api_only
@api_only ||= false
end
def enforce_content_type
@enforce_content_type ||= false
end
def refresh_token_enabled?
if defined?(@refresh_token_enabled)
@refresh_token_enabled
else
false
end
end
def resolve_controller(name)
config_option = public_send(:"#{name}_controller")
controller_name = if config_option.respond_to?(:call)
instance_exec(&config_option)
else
config_option
end
controller_name.constantize
end
def revoke_previous_client_credentials_token?
option_set? :revoke_previous_client_credentials_token
end
def revoke_previous_authorization_code_token?
option_set? :revoke_previous_authorization_code_token
end
def force_pkce?
option_set? :force_pkce
end
def enforce_configured_scopes?
option_set? :enforce_configured_scopes
end
def enable_application_owner?
option_set? :enable_application_owner
end
def enable_dynamic_scopes?
option_set? :enable_dynamic_scopes
end
def dynamic_scopes_delimiter
@dynamic_scopes_delimiter
end
def polymorphic_resource_owner?
option_set? :polymorphic_resource_owner
end
def confirm_application_owner?
option_set? :confirm_application_owner
end
def raise_on_errors?
handle_auth_errors == :raise
end
def redirect_on_errors?
handle_auth_errors == :redirect
end
def application_secret_hashed?
instance_variable_defined?(:"@application_secret_strategy")
end
def token_secret_strategy
@token_secret_strategy ||= ::Doorkeeper::SecretStoring::Plain
end
def application_secret_strategy
@application_secret_strategy ||= ::Doorkeeper::SecretStoring::Plain
end
def default_scopes
@default_scopes ||= OAuth::Scopes.new
end
def optional_scopes
@optional_scopes ||= OAuth::Scopes.new
end
def scopes
@scopes ||= default_scopes + optional_scopes
end
def scopes_by_grant_type
@scopes_by_grant_type ||= {}
end
def pkce_code_challenge_methods_supported
return [] unless access_grant_model.pkce_supported?
pkce_code_challenge_methods
end
def client_credentials_methods
@client_credentials_methods ||= %i[from_basic from_params]
end
def access_token_methods
@access_token_methods ||= %i[
from_bearer_authorization
from_access_token_param
from_bearer_param
]
end
def enabled_grant_flows
@enabled_grant_flows ||= calculate_grant_flows.map { |name| Doorkeeper::GrantFlow.get(name) }.compact
end
def authorization_response_flows
@authorization_response_flows ||= enabled_grant_flows.select(&:handles_response_type?) +
deprecated_authorization_flows
end
def token_grant_flows
@token_grant_flows ||= calculate_token_grant_flows
end
def authorization_response_types
authorization_response_flows.map(&:response_type_matches)
end
def token_grant_types
token_grant_flows.map(&:grant_type_matches)
end
# [NOTE]: deprecated and will be removed soon
def deprecated_token_grant_types_resolver
@deprecated_token_grant_types ||= calculate_token_grant_types
end
def native_authorization_code_route
@use_url_path_for_native_authorization = false unless defined?(@use_url_path_for_native_authorization)
@use_url_path_for_native_authorization ? '/:code' : '/native'
end
# [NOTE]: deprecated and will be removed soon
def deprecated_authorization_flows
response_types = calculate_authorization_response_types
if response_types.any?
::Kernel.warn <<~WARNING
Please, don't patch Doorkeeper::Config#calculate_authorization_response_types method.
Register your custom grant flows using the public API:
`Doorkeeper::GrantFlow.register(grant_flow_name, **options)`.
WARNING
end
response_types.map do |response_type|
Doorkeeper::GrantFlow::FallbackFlow.new(response_type, response_type_matches: response_type)
end
end
# [NOTE]: deprecated and will be removed soon
def calculate_authorization_response_types
[]
end
# [NOTE]: deprecated and will be removed soon
def calculate_token_grant_types
types = grant_flows - ["implicit"]
types << "refresh_token" if refresh_token_enabled?
types
end
# Calculates grant flows configured by the user in Doorkeeper
# configuration considering registered aliases that is exposed
# to single or multiple other flows.
#
def calculate_grant_flows
configured_flows = grant_flows.map(&:to_s)
aliases = Doorkeeper::GrantFlow.aliases.keys.map(&:to_s)
flows = configured_flows - aliases
aliases.each do |flow_alias|
next unless configured_flows.include?(flow_alias)
flows.concat(Doorkeeper::GrantFlow.expand_alias(flow_alias))
end
flows.flatten.uniq
end
def allow_blank_redirect_uri?(application = nil)
if allow_blank_redirect_uri.respond_to?(:call)
allow_blank_redirect_uri.call(grant_flows, application)
else
allow_blank_redirect_uri
end
end
def allow_grant_flow_for_client?(grant_flow, client)
return true unless option_defined?(:allow_grant_flow_for_client)
allow_grant_flow_for_client.call(grant_flow, client)
end
def option_defined?(name)
instance_variable_defined?("@#{name}")
end
private
# Helper to read boolearized configuration option
def option_set?(instance_key)
var = instance_variable_get("@#{instance_key}")
!!(defined?(var) && var)
end
def calculate_token_grant_flows
flows = enabled_grant_flows.select(&:handles_grant_type?)
flows << Doorkeeper::GrantFlow.get("refresh_token") if refresh_token_enabled?
flows
end
end
end
================================================
FILE: lib/doorkeeper/engine.rb
================================================
# frozen_string_literal: true
module Doorkeeper
class Engine < Rails::Engine
initializer "doorkeeper.params.filter", after: :load_config_initializers do |app|
app.config.to_prepare do
Doorkeeper.setup_filter_parameters
end
end
initializer "doorkeeper.routes" do
Doorkeeper::Rails::Routes.install!
end
initializer "doorkeeper.helpers" do
ActiveSupport.on_load(:action_controller) do
include Doorkeeper::Rails::Helpers
end
end
config.to_prepare do
Doorkeeper.run_orm_hooks
end
if defined?(Sprockets) && Sprockets::VERSION.chr.to_i >= 4
initializer "doorkeeper.assets.precompile" do |app|
# Force users to use:
# //= link doorkeeper/admin/application.css
# in Doorkeeper 5 for Sprockets 4 instead of precompile.
# Add note to official docs & Wiki
app.config.assets.precompile += %w[
doorkeeper/application.css
doorkeeper/admin/application.css
]
end
end
end
end
================================================
FILE: lib/doorkeeper/errors.rb
================================================
# frozen_string_literal: true
module Doorkeeper
module Errors
class DoorkeeperError < StandardError
def type
message
end
def self.translate_options
{}
end
end
class InvalidGrantReuse < DoorkeeperError
def type
:invalid_grant
end
end
class InvalidTokenStrategy < DoorkeeperError
def type
:unsupported_grant_type
end
end
class MissingRequiredParameter < DoorkeeperError
attr_reader :missing_param
def initialize(missing_param)
super
@missing_param = missing_param
end
def type
:invalid_request
end
end
class BaseResponseError < DoorkeeperError
attr_reader :response
def initialize(response)
@response = response
end
def self.name_for_response
self.name.demodulize.underscore.to_sym
end
end
class InvalidCodeChallengeMethod < BaseResponseError
def self.translate_options
challenge_methods = Doorkeeper.config.pkce_code_challenge_methods_supported
{
challenge_methods: challenge_methods.join(", "),
count: challenge_methods.length
}
end
end
UnableToGenerateToken = Class.new(DoorkeeperError)
TokenGeneratorNotFound = Class.new(DoorkeeperError)
NoOrmCleaner = Class.new(DoorkeeperError)
InvalidRequest = Class.new(BaseResponseError)
InvalidToken = Class.new(BaseResponseError)
InvalidClient = Class.new(BaseResponseError)
InvalidScope = Class.new(BaseResponseError)
InvalidRedirectUri = Class.new(BaseResponseError)
InvalidGrant = Class.new(BaseResponseError)
UnauthorizedClient = Class.new(BaseResponseError)
UnsupportedResponseType = Class.new(BaseResponseError)
UnsupportedResponseMode = Class.new(BaseResponseError)
AccessDenied = Class.new(BaseResponseError)
ServerError = Class.new(BaseResponseError)
TokenExpired = Class.new(InvalidToken)
TokenRevoked = Class.new(InvalidToken)
TokenUnknown = Class.new(InvalidToken)
TokenForbidden = Class.new(InvalidToken)
end
end
================================================
FILE: lib/doorkeeper/grant_flow/fallback_flow.rb
================================================
# frozen_string_literal: true
module Doorkeeper
module GrantFlow
class FallbackFlow < Flow
def handles_grant_type?
false
end
def handles_response_type?
false
end
end
end
end
================================================
FILE: lib/doorkeeper/grant_flow/flow.rb
================================================
# frozen_string_literal: true
module Doorkeeper
module GrantFlow
class Flow
attr_reader :name, :grant_type_matches, :grant_type_strategy,
:response_type_matches, :response_type_strategy,
:response_mode_matches
def initialize(name, **options)
@name = name
@grant_type_matches = options[:grant_type_matches]
@grant_type_strategy = options[:grant_type_strategy]
@response_type_matches = options[:response_type_matches]
@response_type_strategy = options[:response_type_strategy]
@response_mode_matches = options[:response_mode_matches]
end
def handles_grant_type?
grant_type_matches.present?
end
def handles_response_type?
response_type_matches.present?
end
def matches_grant_type?(value)
grant_type_matches === value
end
def matches_response_type?(value)
response_type_matches === value
end
def default_response_mode
response_mode_matches[0]
end
def matches_response_mode?(value)
response_mode_matches.include?(value)
end
end
end
end
================================================
FILE: lib/doorkeeper/grant_flow/registry.rb
================================================
# frozen_string_literal: true
module Doorkeeper
module GrantFlow
module Registry
mattr_accessor :flows
self.flows = {}
mattr_accessor :aliases
self.aliases = {}
# Allows to register custom OAuth grant flow so that Doorkeeper
# could recognize and process it.
#
def register(name_or_flow, **options)
unless name_or_flow.is_a?(Doorkeeper::GrantFlow::Flow)
name_or_flow = Flow.new(name_or_flow, **options)
end
flow_key = name_or_flow.name.to_sym
if flows.key?(flow_key)
::Kernel.warn <<~WARNING
[DOORKEEPER] '#{flow_key}' grant flow already registered and will be overridden
in #{caller(1..1).first}
WARNING
end
flows[flow_key] = name_or_flow
end
# Allows to register aliases that could be used in `grant_flows`
# configuration option. It is possible to have aliases like 1:1 or
# 1:N, i.e. "implicit_oidc" => ['token', 'id_token', 'id_token token'].
#
def register_alias(alias_name, **options)
aliases[alias_name.to_sym] = Array.wrap(options.fetch(:as))
end
def expand_alias(alias_name)
aliases.fetch(alias_name.to_sym, [])
end
# [NOTE]: make it to use #fetch after removing fallbacks
def get(name)
flows[name.to_sym]
end
end
end
end
================================================
FILE: lib/doorkeeper/grant_flow.rb
================================================
# frozen_string_literal: true
require "doorkeeper/grant_flow/flow"
require "doorkeeper/grant_flow/fallback_flow"
require "doorkeeper/grant_flow/registry"
module Doorkeeper
module GrantFlow
extend Registry
register(
:implicit,
response_type_matches: "token",
response_mode_matches: %w[fragment form_post],
response_type_strategy: Doorkeeper::Request::Token,
)
register(
:authorization_code,
response_type_matches: "code",
response_mode_matches: %w[query fragment form_post],
response_type_strategy: Doorkeeper::Request::Code,
grant_type_matches: "authorization_code",
grant_type_strategy: Doorkeeper::Request::AuthorizationCode,
)
register(
:client_credentials,
grant_type_matches: "client_credentials",
grant_type_strategy: Doorkeeper::Request::ClientCredentials,
)
register(
:password,
grant_type_matches: "password",
grant_type_strategy: Doorkeeper::Request::Password,
)
register(
:refresh_token,
grant_type_matches: "refresh_token",
grant_type_strategy: Doorkeeper::Request::RefreshToken,
)
end
end
================================================
FILE: lib/doorkeeper/grape/authorization_decorator.rb
================================================
# frozen_string_literal: true
module Doorkeeper
module Grape
class AuthorizationDecorator < SimpleDelegator
def parameters
params
end
def authorization
env = __getobj__.env
env["HTTP_AUTHORIZATION"] ||
env["X-HTTP_AUTHORIZATION"] ||
env["X_HTTP_AUTHORIZATION"] ||
env["REDIRECT_X_HTTP_AUTHORIZATION"]
end
end
end
end
================================================
FILE: lib/doorkeeper/grape/helpers.rb
================================================
# frozen_string_literal: true
require "doorkeeper/grape/authorization_decorator"
module Doorkeeper
module Grape
# Doorkeeper helpers for Grape applications.
# Provides helpers for endpoints authorization based on defined set of scopes.
module Helpers
# These helpers are for grape >= 0.10
extend ::Grape::API::Helpers
include Doorkeeper::Rails::Helpers
# endpoint specific scopes > parameter scopes > default scopes
def doorkeeper_authorize!(*scopes)
endpoint_scopes = endpoint.route_setting(:scopes) ||
endpoint.options[:route_options][:scopes]
scopes = if endpoint_scopes
Doorkeeper::OAuth::Scopes.from_array(endpoint_scopes)
elsif scopes.present?
Doorkeeper::OAuth::Scopes.from_array(scopes)
end
super(*scopes)
end
def doorkeeper_render_error_with(error)
status_code = error_status_codes[error.status]
error!({ error: error.description }, status_code, error.headers)
end
private
def endpoint
env["api.endpoint"]
end
def doorkeeper_token
@doorkeeper_token ||= OAuth::Token.authenticate(
decorated_request,
*Doorkeeper.config.access_token_methods,
)
end
def decorated_request
AuthorizationDecorator.new(request)
end
def error_status_codes
{
unauthorized: 401,
forbidden: 403,
}
end
end
end
end
================================================
FILE: lib/doorkeeper/helpers/controller.rb
================================================
# frozen_string_literal: true
# Define methods that can be called in any controller that inherits from
# Doorkeeper::ApplicationMetalController or Doorkeeper::ApplicationController
module Doorkeeper
module Helpers
# Rails controller helpers.
#
module Controller
def self.included(base)
base.helper_method :current_resource_owner if base.respond_to?(:helper_method)
end
private
# :doc:
def authenticate_resource_owner!
current_resource_owner
end
# :doc:
def current_resource_owner
return @current_resource_owner if defined?(@current_resource_owner)
@current_resource_owner ||= begin
instance_eval(&Doorkeeper.config.authenticate_resource_owner)
end
end
def resource_owner_from_credentials
instance_eval(&Doorkeeper.config.resource_owner_from_credentials)
end
# :doc:
def authenticate_admin!
instance_eval(&Doorkeeper.config.authenticate_admin)
end
def server
@server ||= Server.new(self)
end
# :doc:
def doorkeeper_token
return @doorkeeper_token if defined?(@doorkeeper_token)
@doorkeeper_token ||= OAuth::Token.authenticate(request, *config_methods)
end
def config_methods
@config_methods ||= Doorkeeper.config.access_token_methods
end
def get_error_response_from_exception(exception)
if exception.respond_to?(:response)
exception.response
elsif exception.type == :invalid_request
OAuth::InvalidRequestResponse.new(
name: exception.type,
state: params[:state],
missing_param: exception.missing_param,
)
else
OAuth::ErrorResponse.new(name: exception.type, state: params[:state])
end
end
def handle_token_exception(exception)
error = get_error_response_from_exception(exception)
headers.merge!(error.headers)
self.response_body = error.body.to_json
self.status = error.status
end
def skip_authorization?
!!instance_exec(
[server.current_resource_owner, @pre_auth.client],
&Doorkeeper.config.skip_authorization
)
end
def enforce_content_type
if (request.put? || request.post? || request.patch?) && !x_www_form_urlencoded?
render json: {}, status: :unsupported_media_type
end
end
def x_www_form_urlencoded?
request.media_type == "application/x-www-form-urlencoded"
end
end
end
end
================================================
FILE: lib/doorkeeper/models/access_grant_mixin.rb
================================================
# frozen_string_literal: true
module Doorkeeper
module AccessGrantMixin
extend ActiveSupport::Concern
include OAuth::Helpers
include Models::Expirable
include Models::Revocable
include Models::Accessible
include Models::Orderable
include Models::SecretStorable
include Models::Scopes
include Models::ResourceOwnerable
include Models::Concerns::WriteToPrimary
include Models::ExpirationTimeSqlMath
# Never uses PKCE if PKCE migrations were not generated
def uses_pkce?
self.class.pkce_supported? && code_challenge.present?
end
module ClassMethods
# Searches for Doorkeeper::AccessGrant record with the
# specific token value.
#
# @param token [#to_s] token value (any object that responds to `#to_s`)
#
# @return [Doorkeeper::AccessGrant, nil]
# AccessGrant object or nil if there is no record with such token
#
def by_token(token)
find_by_plaintext_token(:token, token)
end
# Revokes AccessGrant records that have not been revoked and associated
# with the specific Application and Resource Owner.
#
# @param application_id [Integer]
# ID of the Application
# @param resource_owner [ActiveRecord::Base, Integer]
# instance of the Resource Owner model or it's ID
#
def revoke_all_for(application_id, resource_owner, clock = Time)
with_primary_role do
by_resource_owner(resource_owner)
.where(
application_id: application_id,
revoked_at: nil,
)
.update_all(revoked_at: clock.now.utc)
end
end
# Implements PKCE code_challenge encoding without base64 padding as described in the spec.
# https://datatracker.ietf.org/doc/html/rfc7636#appendix-A
# Appendix A. Notes on Implementing Base64url Encoding without Padding
#
# This appendix describes how to implement a base64url-encoding
# function without padding, based upon the standard base64-encoding
# function that uses padding.
#
# To be concrete, example C# code implementing these functions is shown
# below. Similar code could be used in other languages.
#
# static string base64urlencode(byte [] arg)
# {
# string s = Convert.ToBase64String(arg); // Regular base64 encoder
# s = s.Split('=')[0]; // Remove any trailing '='s
# s = s.Replace('+', '-'); // 62nd char of encoding
# s = s.Replace('/', '_'); // 63rd char of encoding
# return s;
# }
#
# An example correspondence between unencoded and encoded values
# follows. The octet sequence below encodes into the string below,
# which when decoded, reproduces the octet sequence.
#
# 3 236 255 224 193
#
# A-z_4ME
#
# https://ruby-doc.org/stdlib-2.1.3/libdoc/base64/rdoc/Base64.html#method-i-urlsafe_encode64
#
# urlsafe_encode64(bin)
# Returns the Base64-encoded version of bin. This method complies with
# "Base 64 Encoding with URL and Filename Safe Alphabet" in RFC 4648.
# The alphabet uses '-' instead of '+' and '_' instead of '/'.
# @param code_verifier [#to_s] a one time use value (any object that responds to `#to_s`)
#
# @return [#to_s] An encoded code challenge based on the provided verifier
# suitable for PKCE validation
#
def generate_code_challenge(code_verifier)
Base64.urlsafe_encode64(Digest::SHA256.digest(code_verifier), padding: false)
end
def pkce_supported?
column_names.include?("code_challenge")
end
##
# Determines the secret storing transformer
# Unless configured otherwise, uses the plain secret strategy
#
# @return [Doorkeeper::SecretStoring::Base]
#
def secret_strategy
::Doorkeeper.config.token_secret_strategy
end
##
# Determine the fallback storing strategy
# Unless configured, there will be no fallback
#
# @return [Doorkeeper::SecretStoring::Base]
#
def fallback_secret_strategy
::Doorkeeper.config.token_secret_fallback_strategy
end
end
end
end
================================================
FILE: lib/doorkeeper/models/access_token_mixin.rb
================================================
# frozen_string_literal: true
module Doorkeeper
module AccessTokenMixin
extend ActiveSupport::Concern
include OAuth::Helpers
include Models::Expirable
include Models::Reusable
include Models::Revocable
include Models::Accessible
include Models::Orderable
include Models::SecretStorable
include Models::Scopes
include Models::ResourceOwnerable
include Models::ExpirationTimeSqlMath
include Models::Concerns::WriteToPrimary
module ClassMethods
# Returns an instance of the Doorkeeper::AccessToken with
# specific plain text token value.
#
# @param token [#to_s]
# Plain text token value (any object that responds to `#to_s`)
#
# @return [Doorkeeper::AccessToken, nil] AccessToken object or nil
# if there is no record with such token
#
def by_token(token)
find_by_plaintext_token(:token, token)
end
# Returns an instance of the Doorkeeper::AccessToken
# with specific token value.
#
# @param refresh_token [#to_s]
# refresh token value (any object that responds to `#to_s`)
#
# @return [Doorkeeper::AccessToken, nil] AccessToken object or nil
# if there is no record with such refresh token
#
def by_refresh_token(refresh_token)
find_by_plaintext_token(:refresh_token, refresh_token)
end
# Returns an instance of the Doorkeeper::AccessToken
# found by previous refresh token. Keep in mind that value
# of the previous_refresh_token isn't encrypted using
# secrets strategy.
#
# @param previous_refresh_token [#to_s]
# previous refresh token value (any object that responds to `#to_s`)
#
# @return [Doorkeeper::AccessToken, nil] AccessToken object or nil
# if there is no record with such refresh token
#
def by_previous_refresh_token(previous_refresh_token)
find_by(refresh_token: previous_refresh_token)
end
# Revokes AccessToken records that have not been revoked and associated
# with the specific Application and Resource Owner.
#
# @param application_id [Integer]
# ID of the Application
# @param resource_owner [ActiveRecord::Base, Integer]
# instance of the Resource Owner model or it's ID
#
def revoke_all_for(application_id, resource_owner, clock = Time)
with_primary_role do
by_resource_owner(resource_owner)
.where(
application_id: application_id,
revoked_at: nil,
)
.update_all(revoked_at: clock.now.utc)
end
end
# Looking for not revoked Access Token with a matching set of scopes
# that belongs to specific Application and Resource Owner.
#
# @param application [Doorkeeper::Application]
# Application instance
# @param resource_owner [ActiveRecord::Base, Integer]
# Resource Owner model instance or it's ID
# @param scopes [String, Doorkeeper::OAuth::Scopes]
# set of scopes
# @param custom_attributes [Nilable Hash]
# A nil value, or hash with keys corresponding to the custom attributes
# configured with the `custom_access_token_attributes` config option.
# A nil value will ignore custom attributes.
#
# @return [Doorkeeper::AccessToken, nil] Access Token instance or
# nil if matching record was not found
#
def matching_token_for(application, resource_owner, scopes, custom_attributes: nil, include_expired: true)
tokens = authorized_tokens_for(application&.id, resource_owner)
tokens = tokens.not_expired unless include_expired
find_matching_token(tokens, application, custom_attributes, scopes)
end
# Interface to enumerate access token records in batches in order not
# to bloat the memory. Could be overloaded in any ORM extension.
#
def find_access_token_in_batches(relation, **args, &block)
relation.find_in_batches(**args, &block)
end
# Enumerates AccessToken records in batches to find a matching token.
# Batching is required in order not to pollute the memory if Application
# has huge amount of associated records.
#
# ActiveRecord 5.x - 6.x ignores custom ordering so we can't perform a
# database sort by created_at, so we need to load all the matching records,
# sort them and find latest one.
#
# @param relation [ActiveRecord::Relation]
# Access tokens relation
# @param application [Doorkeeper::Application]
# Application instance
# @param scopes [String, Doorkeeper::OAuth::Scopes]
# set of scopes
# @param custom_attributes [Nilable Hash]
# A nil value, or hash with keys corresponding to the custom attributes
# configured with the `custom_access_token_attributes` config option.
# A nil value will ignore custom attributes.
#
# @return [Doorkeeper::AccessToken, nil] Access Token instance or
# nil if matching record was not found
#
def find_matching_token(relation, application, custom_attributes, scopes)
return nil unless relation
matching_tokens = []
batch_size = Doorkeeper.configuration.token_lookup_batch_size
find_access_token_in_batches(relation, batch_size: batch_size) do |batch|
tokens = batch.select do |token|
scopes_match?(token.scopes, scopes, application&.scopes) &&
custom_attributes_match?(token, custom_attributes)
end
matching_tokens.concat(tokens)
end
matching_tokens.max_by(&:created_at)
end
# Checks whether the token scopes match the scopes from the parameters
#
# @param token_scopes [#to_s]
# set of scopes (any object that responds to `#to_s`)
# @param param_scopes [Doorkeeper::OAuth::Scopes]
# scopes from params
# @param app_scopes [Doorkeeper::OAuth::Scopes]
# Application scopes
#
# @return [Boolean] true if the param scopes match the token scopes,
# and all the param scopes are defined in the application (or in the
# server configuration if the application doesn't define any scopes),
# and false in other cases
#
def scopes_match?(token_scopes, param_scopes, app_scopes)
return true if token_scopes.empty? && param_scopes.empty?
(token_scopes.sort == param_scopes.sort) &&
Doorkeeper::OAuth::Helpers::ScopeChecker.valid?(
scope_str: param_scopes.to_s,
server_scopes: Doorkeeper.config.scopes,
app_scopes: app_scopes,
)
end
# Checks whether the token custom attribute values match the custom
# attributes from the parameters.
#
# @param token [Doorkeeper::AccessToken]
# The access token whose custom attributes are being compared
# to the custom_attributes.
#
# @param custom_attributes [Hash]
# A hash of the attributes for which we want to determine whether
# the token's custom attributes match.
#
# @return [Boolean] true if the token's custom attribute values
# match those in the custom_attributes, or if both are empty/blank.
# False otherwise.
def custom_attributes_match?(token, custom_attributes)
return true if custom_attributes.nil?
token_attribs = token.custom_attributes
return true if token_attribs.blank? && custom_attributes.blank?
Doorkeeper.config.custom_access_token_attributes.all? do |attribute|
token_attribs[attribute] == custom_attributes[attribute]
end
end
# Looking for not expired AccessToken record with a matching set of
# scopes that belongs to specific Application and Resource Owner.
# If it doesn't exists - then creates it.
#
# @param application [Doorkeeper::Application]
# Application instance
# @param resource_owner [ActiveRecord::Base, Integer]
# Resource Owner model instance or it's ID
# @param scopes [#to_s]
# set of scopes (any object that responds to `#to_s`)
# @param token_attributes [Hash]
# Additional attributes to use when creating a token
# @option token_attributes [Integer] :expires_in
# token lifetime in seconds
# @option token_attributes [Boolean] :use_refresh_token
# whether to use the refresh token
#
# @return [Doorkeeper::AccessToken] existing record or a new one
#
def find_or_create_for(application:, resource_owner:, scopes:, **token_attributes)
scopes = Doorkeeper::OAuth::Scopes.from_string(scopes) if scopes.is_a?(String)
if Doorkeeper.config.reuse_access_token
custom_attributes = extract_custom_attributes(token_attributes).presence
access_token = matching_token_for(
application, resource_owner, scopes, custom_attributes: custom_attributes, include_expired: false)
return access_token if access_token&.reusable?
end
create_for(
application: application,
resource_owner: resource_owner,
scopes: scopes,
**token_attributes,
)
end
# Creates a not expired AccessToken record with a matching set of
# scopes that belongs to specific Application and Resource Owner.
#
# @param application [Doorkeeper::Application]
# Application instance
# @param resource_owner [ActiveRecord::Base, Integer]
# Resource Owner model instance or it's ID
# @param scopes [#to_s]
# set of scopes (any object that responds to `#to_s`)
# @param token_attributes [Hash]
# Additional attributes to use when creating a token
# @option token_attributes [Integer] :expires_in
# token lifetime in seconds
# @option token_attributes [Boolean] :use_refresh_token
# whether to use the refresh token
#
# @return [Doorkeeper::AccessToken] new access token
#
def create_for(application:, resource_owner:, scopes:, **token_attributes)
token_attributes[:application] = application
token_attributes[:scopes] = scopes.to_s
if Doorkeeper.config.polymorphic_resource_owner?
token_attributes[:resource_owner] = resource_owner
else
token_attributes[:resource_owner_id] = resource_owner_id_for(resource_owner)
end
with_primary_role do
create!(token_attributes)
end
end
# Looking for not revoked Access Token records that belongs to specific
# Application and Resource Owner.
#
# @param application_id [Integer]
# ID of the Application model instance
# @param resource_owner [ActiveRecord::Base, Integer]
# Resource Owner model instance or it's ID
#
# @return [ActiveRecord::Relation]
# collection of matching AccessToken objects
#
def authorized_tokens_for(application_id, resource_owner)
by_resource_owner(resource_owner).where(
application_id: application_id,
revoked_at: nil,
)
end
# Convenience method for backwards-compatibility, return the last
# matching token for the given Application and Resource Owner.
#
# @param application_id [Integer]
# ID of the Application model instance
# @param resource_owner [ActiveRecord::Base, Integer]
# ID of the Resource Owner model instance
#
# @return [Doorkeeper::AccessToken, nil] matching AccessToken object or
# nil if nothing was found
#
def last_authorized_token_for(application_id, resource_owner)
authorized_tokens_for(application_id, resource_owner)
.ordered_by(:created_at, :desc)
.first
end
##
# Determines the secret storing transformer
# Unless configured otherwise, uses the plain secret strategy
#
# @return [Doorkeeper::SecretStoring::Base]
#
def secret_strategy
::Doorkeeper.config.token_secret_strategy
end
##
# Determine the fallback storing strategy
# Unless configured, there will be no fallback
def fallback_secret_strategy
::Doorkeeper.config.token_secret_fallback_strategy
end
# Extracts the token's custom attributes (defined by the
# custom_access_token_attributes config option) from the token's attributes.
#
# @para
gitextract_wns691gx/
├── .codeclimate.yml
├── .coveralls.yml
├── .dockerignore
├── .editorconfig
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── dependabot.yml
│ └── workflows/
│ ├── changelog.yml
│ ├── ci.yml
│ └── rubocop.yml
├── .gitignore
├── .hound.yml
├── .rspec
├── .rubocop.yml
├── .rubocop_todo.yml
├── AGENTS.md
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── Gemfile
├── MIT-LICENSE
├── NEWS.md
├── README.md
├── RELEASING.md
├── Rakefile
├── SECURITY.md
├── UPGRADE.md
├── app/
│ ├── assets/
│ │ └── stylesheets/
│ │ └── doorkeeper/
│ │ ├── admin/
│ │ │ └── application.css
│ │ └── application.css
│ ├── controllers/
│ │ └── doorkeeper/
│ │ ├── application_controller.rb
│ │ ├── application_metal_controller.rb
│ │ ├── applications_controller.rb
│ │ ├── authorizations_controller.rb
│ │ ├── authorized_applications_controller.rb
│ │ ├── token_info_controller.rb
│ │ └── tokens_controller.rb
│ ├── helpers/
│ │ └── doorkeeper/
│ │ └── dashboard_helper.rb
│ └── views/
│ ├── doorkeeper/
│ │ ├── applications/
│ │ │ ├── _delete_form.html.erb
│ │ │ ├── _form.html.erb
│ │ │ ├── edit.html.erb
│ │ │ ├── index.html.erb
│ │ │ ├── new.html.erb
│ │ │ └── show.html.erb
│ │ ├── authorizations/
│ │ │ ├── error.html.erb
│ │ │ ├── form_post.html.erb
│ │ │ ├── new.html.erb
│ │ │ └── show.html.erb
│ │ └── authorized_applications/
│ │ ├── _delete_form.html.erb
│ │ └── index.html.erb
│ └── layouts/
│ └── doorkeeper/
│ ├── admin.html.erb
│ └── application.html.erb
├── benchmark/
│ ├── ruby/
│ │ └── client_credentials.rb
│ └── wrk/
│ └── .keep
├── bin/
│ └── console
├── config/
│ └── locales/
│ └── en.yml
├── doorkeeper.gemspec
├── gemfiles/
│ ├── rails_7_0.gemfile
│ ├── rails_7_1.gemfile
│ ├── rails_7_2.gemfile
│ ├── rails_8_0.gemfile
│ └── rails_edge.gemfile
├── lib/
│ ├── doorkeeper/
│ │ ├── config/
│ │ │ ├── abstract_builder.rb
│ │ │ ├── option.rb
│ │ │ └── validations.rb
│ │ ├── config.rb
│ │ ├── engine.rb
│ │ ├── errors.rb
│ │ ├── grant_flow/
│ │ │ ├── fallback_flow.rb
│ │ │ ├── flow.rb
│ │ │ └── registry.rb
│ │ ├── grant_flow.rb
│ │ ├── grape/
│ │ │ ├── authorization_decorator.rb
│ │ │ └── helpers.rb
│ │ ├── helpers/
│ │ │ └── controller.rb
│ │ ├── models/
│ │ │ ├── access_grant_mixin.rb
│ │ │ ├── access_token_mixin.rb
│ │ │ ├── application_mixin.rb
│ │ │ └── concerns/
│ │ │ ├── accessible.rb
│ │ │ ├── expirable.rb
│ │ │ ├── expiration_time_sql_math.rb
│ │ │ ├── orderable.rb
│ │ │ ├── ownership.rb
│ │ │ ├── polymorphic_resource_owner.rb
│ │ │ ├── resource_ownerable.rb
│ │ │ ├── reusable.rb
│ │ │ ├── revocable.rb
│ │ │ ├── scopes.rb
│ │ │ ├── secret_storable.rb
│ │ │ └── write_to_primary.rb
│ │ ├── oauth/
│ │ │ ├── authorization/
│ │ │ │ ├── code.rb
│ │ │ │ ├── context.rb
│ │ │ │ ├── token.rb
│ │ │ │ └── uri_builder.rb
│ │ │ ├── authorization_code_request.rb
│ │ │ ├── base_request.rb
│ │ │ ├── base_response.rb
│ │ │ ├── client/
│ │ │ │ └── credentials.rb
│ │ │ ├── client.rb
│ │ │ ├── client_credentials/
│ │ │ │ ├── creator.rb
│ │ │ │ ├── issuer.rb
│ │ │ │ └── validator.rb
│ │ │ ├── client_credentials_request.rb
│ │ │ ├── code_request.rb
│ │ │ ├── code_response.rb
│ │ │ ├── error.rb
│ │ │ ├── error_response.rb
│ │ │ ├── forbidden_token_response.rb
│ │ │ ├── helpers/
│ │ │ │ ├── scope_checker.rb
│ │ │ │ ├── unique_token.rb
│ │ │ │ └── uri_checker.rb
│ │ │ ├── hooks/
│ │ │ │ └── context.rb
│ │ │ ├── invalid_request_response.rb
│ │ │ ├── invalid_token_response.rb
│ │ │ ├── nonstandard.rb
│ │ │ ├── password_access_token_request.rb
│ │ │ ├── pre_authorization.rb
│ │ │ ├── refresh_token_request.rb
│ │ │ ├── scopes.rb
│ │ │ ├── token.rb
│ │ │ ├── token_introspection.rb
│ │ │ ├── token_request.rb
│ │ │ └── token_response.rb
│ │ ├── oauth.rb
│ │ ├── orm/
│ │ │ ├── active_record/
│ │ │ │ ├── access_grant.rb
│ │ │ │ ├── access_token.rb
│ │ │ │ ├── application.rb
│ │ │ │ ├── mixins/
│ │ │ │ │ ├── access_grant.rb
│ │ │ │ │ ├── access_token.rb
│ │ │ │ │ └── application.rb
│ │ │ │ ├── redirect_uri_validator.rb
│ │ │ │ └── stale_records_cleaner.rb
│ │ │ └── active_record.rb
│ │ ├── rails/
│ │ │ ├── helpers.rb
│ │ │ ├── routes/
│ │ │ │ ├── abstract_router.rb
│ │ │ │ ├── mapper.rb
│ │ │ │ ├── mapping.rb
│ │ │ │ └── registry.rb
│ │ │ └── routes.rb
│ │ ├── rake/
│ │ │ ├── db.rake
│ │ │ └── setup.rake
│ │ ├── rake.rb
│ │ ├── request/
│ │ │ ├── authorization_code.rb
│ │ │ ├── client_credentials.rb
│ │ │ ├── code.rb
│ │ │ ├── password.rb
│ │ │ ├── refresh_token.rb
│ │ │ ├── strategy.rb
│ │ │ └── token.rb
│ │ ├── request.rb
│ │ ├── revocable_tokens/
│ │ │ ├── revocable_access_token.rb
│ │ │ └── revocable_refresh_token.rb
│ │ ├── secret_storing/
│ │ │ ├── base.rb
│ │ │ ├── bcrypt.rb
│ │ │ ├── plain.rb
│ │ │ └── sha256_hash.rb
│ │ ├── server.rb
│ │ ├── stale_records_cleaner.rb
│ │ ├── validations.rb
│ │ └── version.rb
│ ├── doorkeeper.rb
│ └── generators/
│ └── doorkeeper/
│ ├── application_owner_generator.rb
│ ├── confidential_applications_generator.rb
│ ├── enable_polymorphic_resource_owner_generator.rb
│ ├── install_generator.rb
│ ├── migration_generator.rb
│ ├── pkce_generator.rb
│ ├── previous_refresh_token_generator.rb
│ ├── remove_applications_secret_not_null_constraint_generator.rb
│ ├── templates/
│ │ ├── README
│ │ ├── add_confidential_to_applications.rb.erb
│ │ ├── add_owner_to_application_migration.rb.erb
│ │ ├── add_previous_refresh_token_to_access_tokens.rb.erb
│ │ ├── enable_pkce_migration.rb.erb
│ │ ├── enable_polymorphic_resource_owner_migration.rb.erb
│ │ ├── initializer.rb
│ │ ├── migration.rb.erb
│ │ └── remove_applications_secret_not_null_constraint.rb.erb
│ └── views_generator.rb
└── spec/
├── controllers/
│ ├── application_controller_spec.rb
│ ├── application_metal_controller_spec.rb
│ ├── applications_controller_spec.rb
│ ├── authorizations_controller_spec.rb
│ ├── protected_resources_controller_spec.rb
│ ├── token_info_controller_spec.rb
│ └── tokens_controller_spec.rb
├── doorkeeper/
│ ├── redirect_uri_validator_spec.rb
│ ├── server_spec.rb
│ ├── stale_records_cleaner_spec.rb
│ └── version_spec.rb
├── dummy/
│ ├── Rakefile
│ ├── app/
│ │ ├── assets/
│ │ │ └── config/
│ │ │ └── manifest.js
│ │ ├── controllers/
│ │ │ ├── application_controller.rb
│ │ │ ├── custom_authorizations_controller.rb
│ │ │ ├── full_protected_resources_controller.rb
│ │ │ ├── home_controller.rb
│ │ │ ├── metal_controller.rb
│ │ │ └── semi_protected_resources_controller.rb
│ │ ├── helpers/
│ │ │ └── application_helper.rb
│ │ ├── models/
│ │ │ └── user.rb
│ │ └── views/
│ │ ├── home/
│ │ │ └── index.html.erb
│ │ └── layouts/
│ │ └── application.html.erb
│ ├── config/
│ │ ├── application.rb
│ │ ├── boot.rb
│ │ ├── database.yml
│ │ ├── environment.rb
│ │ ├── environments/
│ │ │ ├── development.rb
│ │ │ ├── production.rb
│ │ │ └── test.rb
│ │ ├── initializers/
│ │ │ ├── backtrace_silencers.rb
│ │ │ ├── doorkeeper.rb
│ │ │ ├── secret_token.rb
│ │ │ ├── session_store.rb
│ │ │ └── wrap_parameters.rb
│ │ ├── locales/
│ │ │ └── doorkeeper.en.yml
│ │ └── routes.rb
│ ├── config.ru
│ ├── db/
│ │ ├── migrate/
│ │ │ ├── 20111122132257_create_users.rb
│ │ │ ├── 20120312140401_add_password_to_users.rb
│ │ │ ├── 20151223192035_create_doorkeeper_tables.rb
│ │ │ ├── 20151223200000_add_owner_to_application.rb
│ │ │ ├── 20160320211015_add_previous_refresh_token_to_access_tokens.rb
│ │ │ ├── 20170822064514_enable_pkce.rb
│ │ │ ├── 20180210183654_add_confidential_to_applications.rb
│ │ │ └── 20230205064514_add_custom_attributes.rb
│ │ └── schema.rb
│ ├── public/
│ │ ├── 404.html
│ │ ├── 422.html
│ │ └── 500.html
│ └── script/
│ └── rails
├── factories.rb
├── generators/
│ ├── application_owner_generator_spec.rb
│ ├── confidential_applications_generator_spec.rb
│ ├── enable_polymorphic_resource_owner_generator_spec.rb
│ ├── install_generator_spec.rb
│ ├── migration_generator_spec.rb
│ ├── pkce_generator_spec.rb
│ ├── previous_refresh_token_generator_spec.rb
│ ├── remove_applications_secret_not_null_constraint_generator_spec.rb
│ ├── templates/
│ │ └── routes.rb
│ └── views_generator_spec.rb
├── grape/
│ └── grape_integration_spec.rb
├── helpers/
│ └── doorkeeper/
│ └── dashboard_helper_spec.rb
├── lib/
│ ├── config_spec.rb
│ ├── doorkeeper/
│ │ └── orm/
│ │ └── active_record_spec.rb
│ ├── doorkeeper_spec.rb
│ ├── grant_flow/
│ │ └── flow_spec.rb
│ ├── grant_flow_spec.rb
│ ├── models/
│ │ ├── concerns/
│ │ │ └── write_to_primary_spec.rb
│ │ ├── expirable_spec.rb
│ │ ├── reusable_spec.rb
│ │ ├── revocable_spec.rb
│ │ ├── scopes_spec.rb
│ │ └── secret_storable_spec.rb
│ ├── oauth/
│ │ ├── authorization/
│ │ │ ├── code_spec.rb
│ │ │ └── uri_builder_spec.rb
│ │ ├── authorization_code_request_spec.rb
│ │ ├── base_request_spec.rb
│ │ ├── base_response_spec.rb
│ │ ├── client/
│ │ │ └── credentials_spec.rb
│ │ ├── client_credentials/
│ │ │ ├── creator_spec.rb
│ │ │ ├── issuer_spec.rb
│ │ │ └── validation_spec.rb
│ │ ├── client_credentials_integration_spec.rb
│ │ ├── client_credentials_request_spec.rb
│ │ ├── client_spec.rb
│ │ ├── code_request_spec.rb
│ │ ├── code_response_spec.rb
│ │ ├── error_response_spec.rb
│ │ ├── error_spec.rb
│ │ ├── forbidden_token_response_spec.rb
│ │ ├── helpers/
│ │ │ ├── scope_checker_spec.rb
│ │ │ ├── unique_token_spec.rb
│ │ │ └── uri_checker_spec.rb
│ │ ├── invalid_request_response_spec.rb
│ │ ├── invalid_token_response_spec.rb
│ │ ├── password_access_token_request_spec.rb
│ │ ├── pre_authorization_spec.rb
│ │ ├── refresh_token_request_spec.rb
│ │ ├── scopes_spec.rb
│ │ ├── token_request_spec.rb
│ │ ├── token_response_spec.rb
│ │ └── token_spec.rb
│ ├── option_spec.rb
│ ├── request/
│ │ └── strategy_spec.rb
│ └── secret_storing/
│ ├── base_spec.rb
│ ├── bcrypt_spec.rb
│ ├── plain_spec.rb
│ └── sha256_hash_spec.rb
├── models/
│ └── doorkeeper/
│ ├── access_grant_spec.rb
│ ├── access_token_spec.rb
│ └── application_spec.rb
├── requests/
│ ├── applications/
│ │ ├── applications_request_spec.rb
│ │ └── authorized_applications_spec.rb
│ ├── endpoints/
│ │ ├── authorization_spec.rb
│ │ └── token_spec.rb
│ ├── flows/
│ │ ├── authorization_code_errors_spec.rb
│ │ ├── authorization_code_spec.rb
│ │ ├── client_credentials_spec.rb
│ │ ├── implicit_grant_errors_spec.rb
│ │ ├── implicit_grant_spec.rb
│ │ ├── password_spec.rb
│ │ ├── refresh_token_spec.rb
│ │ ├── revoke_token_spec.rb
│ │ └── skip_authorization_spec.rb
│ └── protected_resources/
│ ├── metal_spec.rb
│ └── private_api_spec.rb
├── routing/
│ ├── custom_controller_routes_spec.rb
│ ├── default_routes_spec.rb
│ └── scoped_routes_spec.rb
├── spec_helper.rb
├── spec_helper_integration.rb
└── support/
├── dependencies/
│ └── factory_bot.rb
├── doorkeeper_rspec.rb
├── helpers/
│ ├── access_token_request_helper.rb
│ ├── authorization_request_helper.rb
│ ├── config_helper.rb
│ ├── model_helper.rb
│ ├── request_spec_helper.rb
│ └── url_helper.rb
├── orm/
│ └── active_record.rb
├── render_with_matcher.rb
└── shared/
├── controllers_shared_context.rb
├── hashing_shared_context.rb
└── models_shared_examples.rb
SYMBOL INDEX (1168 symbols across 159 files)
FILE: app/controllers/doorkeeper/application_controller.rb
type Doorkeeper (line 3) | module Doorkeeper
class ApplicationController (line 4) | class ApplicationController <
FILE: app/controllers/doorkeeper/application_metal_controller.rb
type Doorkeeper (line 3) | module Doorkeeper
class ApplicationMetalController (line 4) | class ApplicationMetalController <
FILE: app/controllers/doorkeeper/applications_controller.rb
type Doorkeeper (line 3) | module Doorkeeper
class ApplicationsController (line 4) | class ApplicationsController < Doorkeeper::ApplicationController
method index (line 10) | def index
method show (line 19) | def show
method new (line 26) | def new
method create (line 30) | def create
method edit (line 53) | def edit; end
method update (line 55) | def update
method destroy (line 75) | def destroy
method set_application (line 86) | def set_application
method application_params (line 90) | def application_params
method i18n_scope (line 95) | def i18n_scope(action)
FILE: app/controllers/doorkeeper/authorizations_controller.rb
type Doorkeeper (line 3) | module Doorkeeper
class AuthorizationsController (line 4) | class AuthorizationsController < Doorkeeper::ApplicationController
method new (line 7) | def new
method create (line 15) | def create
method destroy (line 19) | def destroy
method render_success (line 33) | def render_success
method render_error (line 43) | def render_error
method can_authorize_response? (line 55) | def can_authorize_response?
method matching_token? (line 61) | def matching_token?
method redirect_or_render (line 71) | def redirect_or_render(auth)
method pre_auth (line 95) | def pre_auth
method pre_auth_params (line 103) | def pre_auth_params
method pre_auth_param_fields (line 107) | def pre_auth_param_fields
method custom_access_token_attributes (line 120) | def custom_access_token_attributes
method authorization (line 124) | def authorization
method strategy (line 128) | def strategy
method authorize_response (line 132) | def authorize_response
method build_context (line 152) | def build_context(**attributes)
method before_successful_authorization (line 156) | def before_successful_authorization(context = nil)
method after_successful_authorization (line 160) | def after_successful_authorization(context)
FILE: app/controllers/doorkeeper/authorized_applications_controller.rb
type Doorkeeper (line 3) | module Doorkeeper
class AuthorizedApplicationsController (line 4) | class AuthorizedApplicationsController < Doorkeeper::ApplicationContro...
method index (line 7) | def index
method destroy (line 16) | def destroy
FILE: app/controllers/doorkeeper/token_info_controller.rb
type Doorkeeper (line 3) | module Doorkeeper
class TokenInfoController (line 4) | class TokenInfoController < Doorkeeper::ApplicationMetalController
method show (line 5) | def show
method doorkeeper_token_to_json (line 17) | def doorkeeper_token_to_json
method error_to_json (line 21) | def error_to_json(error)
FILE: app/controllers/doorkeeper/tokens_controller.rb
type Doorkeeper (line 3) | module Doorkeeper
class TokensController (line 4) | class TokensController < Doorkeeper::ApplicationMetalController
method create (line 11) | def create
method revoke (line 18) | def revoke
method introspect (line 36) | def introspect
method validate_presence_of_client (line 50) | def validate_presence_of_client
method authorized? (line 100) | def authorized?
method revoke_token (line 112) | def revoke_token
method token (line 119) | def token
method revocable_token (line 123) | def revocable_token
method refresh_token (line 134) | def refresh_token
method access_token (line 141) | def access_token
method strategy (line 148) | def strategy
method authorize_response (line 152) | def authorize_response
method build_context (line 162) | def build_context(**attributes)
method before_successful_authorization (line 166) | def before_successful_authorization(context = nil)
method after_successful_authorization (line 170) | def after_successful_authorization(context)
method revocation_error_response (line 174) | def revocation_error_response
FILE: app/helpers/doorkeeper/dashboard_helper.rb
type Doorkeeper (line 3) | module Doorkeeper
type DashboardHelper (line 4) | module DashboardHelper
function doorkeeper_errors_for (line 5) | def doorkeeper_errors_for(object, method)
function doorkeeper_submit_path (line 17) | def doorkeeper_submit_path(application)
FILE: lib/doorkeeper.rb
type Doorkeeper (line 8) | module Doorkeeper
type Helpers (line 23) | module Helpers
type Request (line 27) | module Request
type RevocableTokens (line 37) | module RevocableTokens
type OAuth (line 42) | module OAuth
type Authorization (line 65) | module Authorization
class Client (line 72) | class Client
type ClientCredentials (line 76) | module ClientCredentials
type Helpers (line 82) | module Helpers
type Hooks (line 88) | module Hooks
type Models (line 93) | module Models
type Concerns (line 105) | module Concerns
type Orm (line 110) | module Orm
type Rails (line 114) | module Rails
type SecretStoring (line 119) | module SecretStoring
function configure (line 129) | def configure(&block)
function configuration (line 137) | def configuration
function configured? (line 141) | def configured?
function setup (line 147) | def setup
function setup_filter_parameters (line 157) | def setup_filter_parameters
function setup_orm_adapter (line 167) | def setup_orm_adapter
function run_orm_hooks (line 179) | def run_orm_hooks
function setup_orm_models (line 193) | def setup_orm_models
function setup_application_owner (line 197) | def setup_application_owner
function authenticate (line 201) | def authenticate(request, methods = Doorkeeper.config.access_token_met...
function gem_version (line 205) | def gem_version
FILE: lib/doorkeeper/config.rb
type Doorkeeper (line 7) | module Doorkeeper
class Config (line 13) | class Config
class Builder (line 15) | class Builder < AbstractBuilder
method enable_application_owner (line 25) | def enable_application_owner(opts = {})
method confirm_application_owner (line 30) | def confirm_application_owner
method enable_dynamic_scopes (line 39) | def enable_dynamic_scopes(opts = {})
method default_scopes (line 48) | def default_scopes(*scopes)
method optional_scopes (line 56) | def optional_scopes(*scopes)
method scopes_by_grant_type (line 63) | def scopes_by_grant_type(hash = {})
method client_credentials (line 73) | def client_credentials(*methods)
method access_token_methods (line 83) | def access_token_methods(*methods)
method use_refresh_token (line 88) | def use_refresh_token(enabled = true, &block)
method reuse_access_token (line 98) | def reuse_access_token
method enable_multiple_database_roles (line 114) | def enable_multiple_database_roles
method use_url_path_for_native_authorization (line 123) | def use_url_path_for_native_authorization
method revoke_previous_client_credentials_token (line 131) | def revoke_previous_client_credentials_token
method revoke_previous_authorization_code_token (line 138) | def revoke_previous_authorization_code_token
method force_pkce (line 144) | def force_pkce
method api_only (line 150) | def api_only
method use_polymorphic_resource_owner (line 156) | def use_polymorphic_resource_owner
method enforce_configured_scopes (line 163) | def enforce_configured_scopes
method enforce_content_type (line 169) | def enforce_content_type
method hash_token_secrets (line 181) | def hash_token_secrets(using: nil, fallback: nil)
method hash_application_secrets (line 196) | def hash_application_secrets(using: nil, fallback: nil)
method configure_secrets_for (line 206) | def configure_secrets_for(type, using:, fallback:)
method clear_cache! (line 460) | def clear_cache!
method access_token_model (line 474) | def access_token_model
method access_grant_model (line 482) | def access_grant_model
method application_model (line 490) | def application_model
method api_only (line 494) | def api_only
method enforce_content_type (line 498) | def enforce_content_type
method refresh_token_enabled? (line 502) | def refresh_token_enabled?
method resolve_controller (line 510) | def resolve_controller(name)
method revoke_previous_client_credentials_token? (line 521) | def revoke_previous_client_credentials_token?
method revoke_previous_authorization_code_token? (line 525) | def revoke_previous_authorization_code_token?
method force_pkce? (line 529) | def force_pkce?
method enforce_configured_scopes? (line 533) | def enforce_configured_scopes?
method enable_application_owner? (line 537) | def enable_application_owner?
method enable_dynamic_scopes? (line 541) | def enable_dynamic_scopes?
method dynamic_scopes_delimiter (line 545) | def dynamic_scopes_delimiter
method polymorphic_resource_owner? (line 549) | def polymorphic_resource_owner?
method confirm_application_owner? (line 553) | def confirm_application_owner?
method raise_on_errors? (line 557) | def raise_on_errors?
method redirect_on_errors? (line 561) | def redirect_on_errors?
method application_secret_hashed? (line 565) | def application_secret_hashed?
method token_secret_strategy (line 569) | def token_secret_strategy
method application_secret_strategy (line 573) | def application_secret_strategy
method default_scopes (line 577) | def default_scopes
method optional_scopes (line 581) | def optional_scopes
method scopes (line 585) | def scopes
method scopes_by_grant_type (line 589) | def scopes_by_grant_type
method pkce_code_challenge_methods_supported (line 593) | def pkce_code_challenge_methods_supported
method client_credentials_methods (line 599) | def client_credentials_methods
method access_token_methods (line 603) | def access_token_methods
method enabled_grant_flows (line 611) | def enabled_grant_flows
method authorization_response_flows (line 615) | def authorization_response_flows
method token_grant_flows (line 620) | def token_grant_flows
method authorization_response_types (line 624) | def authorization_response_types
method token_grant_types (line 628) | def token_grant_types
method deprecated_token_grant_types_resolver (line 633) | def deprecated_token_grant_types_resolver
method native_authorization_code_route (line 637) | def native_authorization_code_route
method deprecated_authorization_flows (line 643) | def deprecated_authorization_flows
method calculate_authorization_response_types (line 660) | def calculate_authorization_response_types
method calculate_token_grant_types (line 665) | def calculate_token_grant_types
method calculate_grant_flows (line 675) | def calculate_grant_flows
method allow_blank_redirect_uri? (line 689) | def allow_blank_redirect_uri?(application = nil)
method allow_grant_flow_for_client? (line 697) | def allow_grant_flow_for_client?(grant_flow, client)
method option_defined? (line 703) | def option_defined?(name)
method option_set? (line 710) | def option_set?(instance_key)
method calculate_token_grant_flows (line 715) | def calculate_token_grant_flows
FILE: lib/doorkeeper/config/abstract_builder.rb
type Doorkeeper (line 3) | module Doorkeeper
class Config (line 4) | class Config
class AbstractBuilder (line 8) | class AbstractBuilder
method initialize (line 13) | def initialize(config = Config.new, &block)
method build (line 22) | def build
FILE: lib/doorkeeper/config/option.rb
type Doorkeeper (line 3) | module Doorkeeper
class Config (line 4) | class Config
type Option (line 6) | module Option
function option (line 35) | def option(name, options = {})
function extended (line 74) | def self.extended(base)
FILE: lib/doorkeeper/config/validations.rb
type Doorkeeper (line 3) | module Doorkeeper
class Config (line 4) | class Config
type Validations (line 7) | module Validations
function validate! (line 10) | def validate!
function validate_reuse_access_token_value (line 23) | def validate_reuse_access_token_value
function validate_secret_strategies (line 37) | def validate_secret_strategies
function validate_token_reuse_limit (line 42) | def validate_token_reuse_limit
function validate_pkce_code_challenge_methods (line 53) | def validate_pkce_code_challenge_methods
FILE: lib/doorkeeper/engine.rb
type Doorkeeper (line 3) | module Doorkeeper
class Engine (line 4) | class Engine < Rails::Engine
FILE: lib/doorkeeper/errors.rb
type Doorkeeper (line 3) | module Doorkeeper
type Errors (line 4) | module Errors
class DoorkeeperError (line 5) | class DoorkeeperError < StandardError
method type (line 6) | def type
method translate_options (line 10) | def self.translate_options
class InvalidGrantReuse (line 15) | class InvalidGrantReuse < DoorkeeperError
method type (line 16) | def type
class InvalidTokenStrategy (line 21) | class InvalidTokenStrategy < DoorkeeperError
method type (line 22) | def type
class MissingRequiredParameter (line 27) | class MissingRequiredParameter < DoorkeeperError
method initialize (line 30) | def initialize(missing_param)
method type (line 35) | def type
class BaseResponseError (line 40) | class BaseResponseError < DoorkeeperError
method initialize (line 43) | def initialize(response)
method name_for_response (line 47) | def self.name_for_response
class InvalidCodeChallengeMethod (line 52) | class InvalidCodeChallengeMethod < BaseResponseError
method translate_options (line 53) | def self.translate_options
FILE: lib/doorkeeper/grant_flow.rb
type Doorkeeper (line 7) | module Doorkeeper
type GrantFlow (line 8) | module GrantFlow
FILE: lib/doorkeeper/grant_flow/fallback_flow.rb
type Doorkeeper (line 3) | module Doorkeeper
type GrantFlow (line 4) | module GrantFlow
class FallbackFlow (line 5) | class FallbackFlow < Flow
method handles_grant_type? (line 6) | def handles_grant_type?
method handles_response_type? (line 10) | def handles_response_type?
FILE: lib/doorkeeper/grant_flow/flow.rb
type Doorkeeper (line 3) | module Doorkeeper
type GrantFlow (line 4) | module GrantFlow
class Flow (line 5) | class Flow
method initialize (line 10) | def initialize(name, **options)
method handles_grant_type? (line 19) | def handles_grant_type?
method handles_response_type? (line 23) | def handles_response_type?
method matches_grant_type? (line 27) | def matches_grant_type?(value)
method matches_response_type? (line 31) | def matches_response_type?(value)
method default_response_mode (line 35) | def default_response_mode
method matches_response_mode? (line 39) | def matches_response_mode?(value)
FILE: lib/doorkeeper/grant_flow/registry.rb
type Doorkeeper (line 3) | module Doorkeeper
type GrantFlow (line 4) | module GrantFlow
type Registry (line 5) | module Registry
function register (line 15) | def register(name_or_flow, **options)
function register_alias (line 36) | def register_alias(alias_name, **options)
function expand_alias (line 40) | def expand_alias(alias_name)
function get (line 45) | def get(name)
FILE: lib/doorkeeper/grape/authorization_decorator.rb
type Doorkeeper (line 3) | module Doorkeeper
type Grape (line 4) | module Grape
class AuthorizationDecorator (line 5) | class AuthorizationDecorator < SimpleDelegator
method parameters (line 6) | def parameters
method authorization (line 10) | def authorization
FILE: lib/doorkeeper/grape/helpers.rb
type Doorkeeper (line 5) | module Doorkeeper
type Grape (line 6) | module Grape
type Helpers (line 9) | module Helpers
function doorkeeper_authorize! (line 15) | def doorkeeper_authorize!(*scopes)
function doorkeeper_render_error_with (line 28) | def doorkeeper_render_error_with(error)
function endpoint (line 35) | def endpoint
function doorkeeper_token (line 39) | def doorkeeper_token
function decorated_request (line 46) | def decorated_request
function error_status_codes (line 50) | def error_status_codes
FILE: lib/doorkeeper/helpers/controller.rb
type Doorkeeper (line 5) | module Doorkeeper
type Helpers (line 6) | module Helpers
type Controller (line 9) | module Controller
function included (line 10) | def self.included(base)
function authenticate_resource_owner! (line 17) | def authenticate_resource_owner!
function current_resource_owner (line 22) | def current_resource_owner
function resource_owner_from_credentials (line 30) | def resource_owner_from_credentials
function authenticate_admin! (line 35) | def authenticate_admin!
function server (line 39) | def server
function doorkeeper_token (line 44) | def doorkeeper_token
function config_methods (line 50) | def config_methods
function get_error_response_from_exception (line 54) | def get_error_response_from_exception(exception)
function handle_token_exception (line 68) | def handle_token_exception(exception)
function skip_authorization? (line 75) | def skip_authorization?
function enforce_content_type (line 82) | def enforce_content_type
function x_www_form_urlencoded? (line 88) | def x_www_form_urlencoded?
FILE: lib/doorkeeper/models/access_grant_mixin.rb
type Doorkeeper (line 3) | module Doorkeeper
type AccessGrantMixin (line 4) | module AccessGrantMixin
function uses_pkce? (line 19) | def uses_pkce?
type ClassMethods (line 23) | module ClassMethods
function by_token (line 32) | def by_token(token)
function revoke_all_for (line 44) | def revoke_all_for(application_id, resource_owner, clock = Time)
function generate_code_challenge (line 95) | def generate_code_challenge(code_verifier)
function pkce_supported? (line 99) | def pkce_supported?
function secret_strategy (line 109) | def secret_strategy
function fallback_secret_strategy (line 119) | def fallback_secret_strategy
FILE: lib/doorkeeper/models/access_token_mixin.rb
type Doorkeeper (line 3) | module Doorkeeper
type AccessTokenMixin (line 4) | module AccessTokenMixin
type ClassMethods (line 19) | module ClassMethods
function by_token (line 29) | def by_token(token)
function by_refresh_token (line 42) | def by_refresh_token(refresh_token)
function by_previous_refresh_token (line 57) | def by_previous_refresh_token(previous_refresh_token)
function revoke_all_for (line 69) | def revoke_all_for(application_id, resource_owner, clock = Time)
function matching_token_for (line 97) | def matching_token_for(application, resource_owner, scopes, custom...
function find_access_token_in_batches (line 106) | def find_access_token_in_batches(relation, **args, &block)
function find_matching_token (line 132) | def find_matching_token(relation, application, custom_attributes, ...
function scopes_match? (line 164) | def scopes_match?(token_scopes, param_scopes, app_scopes)
function custom_attributes_match? (line 189) | def custom_attributes_match?(token, custom_attributes)
function find_or_create_for (line 219) | def find_or_create_for(application:, resource_owner:, scopes:, **t...
function create_for (line 256) | def create_for(application:, resource_owner:, scopes:, **token_att...
function authorized_tokens_for (line 282) | def authorized_tokens_for(application_id, resource_owner)
function last_authorized_token_for (line 300) | def last_authorized_token_for(application_id, resource_owner)
function secret_strategy (line 312) | def secret_strategy
function fallback_secret_strategy (line 319) | def fallback_secret_strategy
function extract_custom_attributes (line 330) | def extract_custom_attributes(attributes)
function token_type (line 340) | def token_type
function use_refresh_token? (line 344) | def use_refresh_token?
function as_json (line 352) | def as_json(_options = {})
function custom_attributes (line 370) | def custom_attributes
function same_credential? (line 381) | def same_credential?(access_token)
function same_resource_owner? (line 393) | def same_resource_owner?(access_token)
function acceptable? (line 408) | def acceptable?(scopes)
function plaintext_refresh_token (line 414) | def plaintext_refresh_token
function plaintext_token (line 428) | def plaintext_token
function revoke_previous_refresh_token! (line 439) | def revoke_previous_refresh_token!
function old_refresh_token (line 459) | def old_refresh_token
function generate_refresh_token (line 467) | def generate_refresh_token
function generate_token (line 482) | def generate_token
function attributes_for_token_generator (line 495) | def attributes_for_token_generator
function token_generator (line 513) | def token_generator
FILE: lib/doorkeeper/models/application_mixin.rb
type Doorkeeper (line 3) | module Doorkeeper
type ApplicationMixin (line 4) | module ApplicationMixin
type ClassMethods (line 13) | module ClassMethods
function by_uid_and_secret (line 26) | def by_uid_and_secret(uid, secret)
function by_uid (line 42) | def by_uid(uid)
function secret_strategy (line 49) | def secret_strategy
function fallback_secret_strategy (line 56) | def fallback_secret_strategy
function redirect_uri= (line 67) | def redirect_uri=(uris)
function secret_matches? (line 79) | def secret_matches?(input)
FILE: lib/doorkeeper/models/concerns/accessible.rb
type Doorkeeper (line 3) | module Doorkeeper
type Models (line 4) | module Models
type Accessible (line 5) | module Accessible
function accessible? (line 10) | def accessible?
FILE: lib/doorkeeper/models/concerns/expirable.rb
type Doorkeeper (line 3) | module Doorkeeper
type Models (line 4) | module Models
type Expirable (line 5) | module Expirable
function expired? (line 10) | def expired?
function expires_in_seconds (line 18) | def expires_in_seconds
function expires_at (line 31) | def expires_at
FILE: lib/doorkeeper/models/concerns/expiration_time_sql_math.rb
type Doorkeeper (line 3) | module Doorkeeper
type Models (line 4) | module Models
type ExpirationTimeSqlMath (line 5) | module ExpirationTimeSqlMath
class ExpirationTimeSqlGenerator (line 16) | class ExpirationTimeSqlGenerator
method initialize (line 21) | def initialize(model)
method generate_sql (line 25) | def generate_sql
class MySqlExpirationTimeSqlGenerator (line 30) | class MySqlExpirationTimeSqlGenerator < ExpirationTimeSqlGenerator
method generate_sql (line 31) | def generate_sql
class SqlLiteExpirationTimeSqlGenerator (line 36) | class SqlLiteExpirationTimeSqlGenerator < ExpirationTimeSqlGenerator
method generate_sql (line 37) | def generate_sql
class SqlServerExpirationTimeSqlGenerator (line 42) | class SqlServerExpirationTimeSqlGenerator < ExpirationTimeSqlGener...
method generate_sql (line 43) | def generate_sql
class OracleExpirationTimeSqlGenerator (line 48) | class OracleExpirationTimeSqlGenerator < ExpirationTimeSqlGenerator
method generate_sql (line 49) | def generate_sql
class PostgresExpirationTimeSqlGenerator (line 54) | class PostgresExpirationTimeSqlGenerator < ExpirationTimeSqlGenerator
method generate_sql (line 55) | def generate_sql
type ClassMethods (line 72) | module ClassMethods
function supports_expiration_time_math? (line 73) | def supports_expiration_time_math?
function expiration_time_sql (line 78) | def expiration_time_sql
function expiration_time_sql_expression (line 86) | def expiration_time_sql_expression
function adapter_name (line 90) | def adapter_name
FILE: lib/doorkeeper/models/concerns/orderable.rb
type Doorkeeper (line 3) | module Doorkeeper
type Models (line 4) | module Models
type Orderable (line 5) | module Orderable
type ClassMethods (line 8) | module ClassMethods
function ordered_by (line 9) | def ordered_by(attribute, direction = :asc)
FILE: lib/doorkeeper/models/concerns/ownership.rb
type Doorkeeper (line 3) | module Doorkeeper
type Models (line 4) | module Models
type Ownership (line 5) | module Ownership
function validate_owner? (line 13) | def validate_owner?
FILE: lib/doorkeeper/models/concerns/polymorphic_resource_owner.rb
type Doorkeeper (line 3) | module Doorkeeper
type Models (line 4) | module Models
type PolymorphicResourceOwner (line 5) | module PolymorphicResourceOwner
type ForAccessGrant (line 6) | module ForAccessGrant
type ForAccessToken (line 18) | module ForAccessToken
FILE: lib/doorkeeper/models/concerns/resource_ownerable.rb
type Doorkeeper (line 3) | module Doorkeeper
type Models (line 4) | module Models
type ResourceOwnerable (line 5) | module ResourceOwnerable
type ClassMethods (line 8) | module ClassMethods
function by_resource_owner (line 18) | def by_resource_owner(resource_owner)
function resource_owner_id_for (line 37) | def resource_owner_id_for(resource_owner)
FILE: lib/doorkeeper/models/concerns/reusable.rb
type Doorkeeper (line 3) | module Doorkeeper
type Models (line 4) | module Models
type Reusable (line 5) | module Reusable
function reusable? (line 10) | def reusable?
FILE: lib/doorkeeper/models/concerns/revocable.rb
type Doorkeeper (line 3) | module Doorkeeper
type Models (line 4) | module Models
type Revocable (line 5) | module Revocable
function revoke (line 11) | def revoke(clock = Time)
function revoked? (line 26) | def revoked?
FILE: lib/doorkeeper/models/concerns/scopes.rb
type Doorkeeper (line 3) | module Doorkeeper
type Models (line 4) | module Models
type Scopes (line 5) | module Scopes
function scopes (line 6) | def scopes
function scopes= (line 10) | def scopes=(value)
function scopes_string (line 18) | def scopes_string
function includes_scope? (line 22) | def includes_scope?(*required_scopes)
FILE: lib/doorkeeper/models/concerns/secret_storable.rb
type Doorkeeper (line 3) | module Doorkeeper
type Models (line 4) | module Models
type SecretStorable (line 8) | module SecretStorable
type ClassMethods (line 16) | module ClassMethods
function find_by_plaintext_token (line 42) | def find_by_plaintext_token(attr, token)
function find_by_fallback_token (line 61) | def find_by_fallback_token(attr, plain_secret)
function upgrade_fallback_value (line 85) | def upgrade_fallback_value(instance, attr, plain_secret)
function secret_strategy (line 93) | def secret_strategy
function fallback_secret_strategy (line 100) | def fallback_secret_strategy
FILE: lib/doorkeeper/models/concerns/write_to_primary.rb
type Doorkeeper (line 3) | module Doorkeeper
type Models (line 4) | module Models
type Concerns (line 5) | module Concerns
type WriteToPrimary (line 19) | module WriteToPrimary
function with_primary_role (line 29) | def with_primary_role(&block)
function should_use_primary_role? (line 43) | def should_use_primary_role?
FILE: lib/doorkeeper/oauth.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
FILE: lib/doorkeeper/oauth/authorization/code.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
type Authorization (line 5) | module Authorization
class Code (line 6) | class Code
method initialize (line 9) | def initialize(pre_auth, resource_owner)
method issue_token! (line 14) | def issue_token!
method oob_redirect (line 22) | def oob_redirect
method access_grant? (line 26) | def access_grant?
method authorization_code_expires_in (line 32) | def authorization_code_expires_in
method access_grant_attributes (line 36) | def access_grant_attributes
method custom_attributes (line 53) | def custom_attributes
method pkce_attributes (line 59) | def pkce_attributes
method pkce_supported? (line 70) | def pkce_supported?
FILE: lib/doorkeeper/oauth/authorization/context.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
type Authorization (line 5) | module Authorization
class Context (line 6) | class Context
method initialize (line 9) | def initialize(**attributes)
FILE: lib/doorkeeper/oauth/authorization/token.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
type Authorization (line 5) | module Authorization
class Token (line 6) | class Token
method build_context (line 10) | def build_context(pre_auth_or_oauth_client, grant_type, scopes, ...
method access_token_expires_in (line 27) | def access_token_expires_in(configuration, context)
method refresh_token_enabled? (line 38) | def refresh_token_enabled?(server, context)
method initialize (line 47) | def initialize(pre_auth, resource_owner)
method issue_token! (line 52) | def issue_token!
method application (line 71) | def application
method oob_redirect (line 77) | def oob_redirect
method access_token? (line 85) | def access_token?
method controller (line 91) | def controller
FILE: lib/doorkeeper/oauth/authorization/uri_builder.rb
type Doorkeeper (line 5) | module Doorkeeper
type OAuth (line 6) | module OAuth
type Authorization (line 7) | module Authorization
class URIBuilder (line 8) | class URIBuilder
method uri_with_query (line 10) | def uri_with_query(url, parameters = {})
method uri_with_fragment (line 17) | def uri_with_fragment(url, parameters = {})
method build_query (line 25) | def build_query(parameters = {})
FILE: lib/doorkeeper/oauth/authorization_code_request.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class AuthorizationCodeRequest (line 5) | class AuthorizationCodeRequest < BaseRequest
method initialize (line 16) | def initialize(server, grant, client, parameters = {})
method before_successful_response (line 27) | def before_successful_response
method resource_owner (line 50) | def resource_owner
method pkce_supported? (line 58) | def pkce_supported?
method validate_params (line 62) | def validate_params
method validate_client (line 75) | def validate_client
method validate_grant (line 79) | def validate_grant
method validate_redirect_uri (line 85) | def validate_redirect_uri
method validate_code_verifier (line 94) | def validate_code_verifier
method generate_code_challenge (line 107) | def generate_code_challenge(code_verifier)
method custom_token_attributes_with_data (line 111) | def custom_token_attributes_with_data
method revoke_previous_tokens (line 119) | def revoke_previous_tokens(application, resource_owner)
FILE: lib/doorkeeper/oauth/base_request.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class BaseRequest (line 5) | class BaseRequest
method authorize (line 12) | def authorize
method scopes (line 25) | def scopes
method find_or_create_access_token (line 29) | def find_or_create_access_token(client, resource_owner, scopes, cu...
method before_successful_response (line 45) | def before_successful_response
method after_successful_response (line 49) | def after_successful_response
method build_scopes (line 55) | def build_scopes
FILE: lib/doorkeeper/oauth/base_response.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class BaseResponse (line 5) | class BaseResponse
method body (line 6) | def body
method description (line 10) | def description
method headers (line 14) | def headers
method redirectable? (line 18) | def redirectable?
method redirect_uri (line 22) | def redirect_uri
method status (line 26) | def status
FILE: lib/doorkeeper/oauth/client.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class Client (line 5) | class Client
method initialize (line 10) | def initialize(application)
method find (line 14) | def self.find(uid, method = Doorkeeper.config.application_model.me...
method authenticate (line 20) | def self.authenticate(credentials, method = Doorkeeper.config.appl...
FILE: lib/doorkeeper/oauth/client/credentials.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class Client (line 5) | class Client
method from_request (line 8) | def from_request(request, *credentials_methods)
method from_params (line 16) | def from_params(request)
method from_basic (line 20) | def from_basic(request)
FILE: lib/doorkeeper/oauth/client_credentials/creator.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
type ClientCredentials (line 5) | module ClientCredentials
class Creator (line 6) | class Creator
method call (line 7) | def call(client, scopes, attributes = {})
method with_revocation (line 28) | def with_revocation(existing_token:)
method lookup_existing_token? (line 42) | def lookup_existing_token?
method find_active_existing_token_for (line 47) | def find_active_existing_token_for(client, scopes, attributes)
FILE: lib/doorkeeper/oauth/client_credentials/issuer.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
type ClientCredentials (line 5) | module ClientCredentials
class Issuer (line 6) | class Issuer
method initialize (line 9) | def initialize(server, validator)
method create (line 14) | def create(client, scopes, attributes = {}, creator = Creator.new)
method create_token (line 28) | def create_token(client, scopes, attributes, creator)
FILE: lib/doorkeeper/oauth/client_credentials/validator.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
type ClientCredentials (line 5) | module ClientCredentials
class Validator (line 6) | class Validator
method initialize (line 14) | def initialize(server, request)
method validate_client (line 24) | def validate_client
method validate_client_supports_grant_flow (line 28) | def validate_client_supports_grant_flow
method validate_scopes (line 37) | def validate_scopes
FILE: lib/doorkeeper/oauth/client_credentials_request.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class ClientCredentialsRequest (line 5) | class ClientCredentialsRequest < BaseRequest
method initialize (line 12) | def initialize(server, client, parameters = {})
method access_token (line 21) | def access_token
method issuer (line 25) | def issuer
method valid? (line 34) | def valid?
method custom_token_attributes_with_data (line 38) | def custom_token_attributes_with_data
FILE: lib/doorkeeper/oauth/code_request.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class CodeRequest (line 5) | class CodeRequest
method initialize (line 8) | def initialize(pre_auth, resource_owner)
method authorize (line 13) | def authorize
method deny (line 19) | def deny
FILE: lib/doorkeeper/oauth/code_response.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class CodeResponse (line 5) | class CodeResponse < BaseResponse
method initialize (line 10) | def initialize(pre_auth, auth, options = {})
method redirectable? (line 16) | def redirectable?
method issued_token (line 20) | def issued_token
method body (line 24) | def body
method redirect_uri (line 40) | def redirect_uri
FILE: lib/doorkeeper/oauth/error.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
function description (line 6) | def description
FILE: lib/doorkeeper/oauth/error_response.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class ErrorResponse (line 5) | class ErrorResponse < BaseResponse
method from_request (line 10) | def self.from_request(request, attributes = {})
method error_name_for (line 22) | def self.error_name_for(error)
method exception_class_for (line 26) | def self.exception_class_for(error)
method initialize (line 36) | def initialize(attributes = {})
method body (line 43) | def body
method status (line 51) | def status
method redirectable? (line 59) | def redirectable?
method redirect_uri (line 63) | def redirect_uri
method headers (line 71) | def headers
method raise_exception! (line 79) | def raise_exception!
method realm (line 85) | def realm
method exception_class (line 89) | def exception_class
method authenticate_info (line 96) | def authenticate_info
method sanitize_error_values (line 107) | def sanitize_error_values(string)
FILE: lib/doorkeeper/oauth/forbidden_token_response.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class ForbiddenTokenResponse (line 5) | class ForbiddenTokenResponse < ErrorResponse
method from_scopes (line 6) | def self.from_scopes(scopes, attributes = {})
method initialize (line 10) | def initialize(attributes = {})
method status (line 15) | def status
method description (line 19) | def description
method exception_class (line 26) | def exception_class
FILE: lib/doorkeeper/oauth/helpers/scope_checker.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
type Helpers (line 5) | module Helpers
type ScopeChecker (line 6) | module ScopeChecker
class Validator (line 7) | class Validator
method initialize (line 10) | def initialize(scope_str, server_scopes, app_scopes, grant_type)
method valid? (line 18) | def valid?
method valid_scopes (line 27) | def valid_scopes(server_scopes, app_scopes)
method permitted_to_grant_type? (line 31) | def permitted_to_grant_type?
function valid? (line 39) | def self.valid?(scope_str:, server_scopes:, app_scopes: nil, gra...
FILE: lib/doorkeeper/oauth/helpers/unique_token.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
type Helpers (line 5) | module Helpers
type UniqueToken (line 9) | module UniqueToken
function generate (line 10) | def self.generate(options = {})
function default_generator_method (line 24) | def self.default_generator_method
FILE: lib/doorkeeper/oauth/helpers/uri_checker.rb
type Doorkeeper (line 5) | module Doorkeeper
type OAuth (line 6) | module OAuth
type Helpers (line 7) | module Helpers
type URIChecker (line 8) | module URIChecker
function valid? (line 9) | def self.valid?(url)
function matches? (line 18) | def self.matches?(url, client_url)
function loopback_uri? (line 41) | def self.loopback_uri?(uri)
function valid_for_authorization? (line 47) | def self.valid_for_authorization?(url, client_url)
function as_uri (line 51) | def self.as_uri(url)
function query_matches? (line 55) | def self.query_matches?(query, client_query)
function valid_scheme? (line 63) | def self.valid_scheme?(uri)
function hypertext_scheme? (line 69) | def self.hypertext_scheme?(uri)
function iff_host? (line 73) | def self.iff_host?(uri)
function oob_uri? (line 77) | def self.oob_uri?(uri)
FILE: lib/doorkeeper/oauth/hooks/context.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
type Hooks (line 5) | module Hooks
class Context (line 6) | class Context
method initialize (line 9) | def initialize(**attributes)
method issued_token (line 15) | def issued_token
FILE: lib/doorkeeper/oauth/invalid_request_response.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class InvalidRequestResponse (line 5) | class InvalidRequestResponse < ErrorResponse
method from_request (line 8) | def self.from_request(request, attributes = {})
method initialize (line 19) | def initialize(attributes = {})
method status (line 25) | def status
method description (line 29) | def description
method exception_class (line 38) | def exception_class
method redirectable? (line 42) | def redirectable?
FILE: lib/doorkeeper/oauth/invalid_token_response.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class InvalidTokenResponse (line 5) | class InvalidTokenResponse < ErrorResponse
method from_access_token (line 8) | def self.from_access_token(access_token, attributes = {})
method initialize (line 20) | def initialize(attributes = {})
method status (line 25) | def status
method description (line 29) | def description
method exception_class (line 39) | def exception_class
method errors_mapping (line 45) | def errors_mapping
FILE: lib/doorkeeper/oauth/nonstandard.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class NonStandard (line 5) | class NonStandard
FILE: lib/doorkeeper/oauth/password_access_token_request.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class PasswordAccessTokenRequest (line 5) | class PasswordAccessTokenRequest < BaseRequest
method initialize (line 15) | def initialize(server, client, credentials, resource_owner, parame...
method before_successful_response (line 27) | def before_successful_response
method validate_scopes (line 32) | def validate_scopes
method validate_resource_owner (line 43) | def validate_resource_owner
method validate_client (line 62) | def validate_client
method validate_client_supports_grant_flow (line 70) | def validate_client_supports_grant_flow
FILE: lib/doorkeeper/oauth/pre_authorization.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class PreAuthorization (line 5) | class PreAuthorization
method initialize (line 25) | def initialize(server, parameters = {}, resource_owner = nil)
method authorizable? (line 39) | def authorizable?
method scopes (line 43) | def scopes
method scope (line 47) | def scope
method error_response (line 51) | def error_response
method as_json (line 62) | def as_json(_options = nil)
method form_post_response? (line 66) | def form_post_response?
method build_scopes (line 74) | def build_scopes
method validate_client_id (line 83) | def validate_client_id
method validate_client (line 88) | def validate_client
method validate_client_supports_grant_flow (line 93) | def validate_client_supports_grant_flow
method validate_resource_owner_authorize_for_client (line 97) | def validate_resource_owner_authorize_for_client
method validate_redirect_uri (line 102) | def validate_redirect_uri
method validate_params (line 111) | def validate_params
method validate_response_type (line 121) | def validate_response_type
method validate_response_mode (line 130) | def validate_response_mode
method validate_scopes (line 139) | def validate_scopes
method validate_code_challenge (line 148) | def validate_code_challenge
method validate_code_challenge_method (line 157) | def validate_code_challenge_method
method response_on_fragment? (line 164) | def response_on_fragment?
method grant_type (line 170) | def grant_type
method pre_auth_hash (line 174) | def pre_auth_hash
FILE: lib/doorkeeper/oauth/refresh_token_request.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class RefreshTokenRequest (line 5) | class RefreshTokenRequest < BaseRequest
method initialize (line 17) | def initialize(server, refresh_token, credentials, parameters = {})
method load_client (line 29) | def load_client(credentials)
method before_successful_response (line 33) | def before_successful_response
method refresh_token_revoked_on_use? (line 53) | def refresh_token_revoked_on_use?
method default_scopes (line 57) | def default_scopes
method create_access_token (line 61) | def create_access_token
method validate_token_presence (line 98) | def validate_token_presence
method validate_token (line 104) | def validate_token
method validate_client (line 108) | def validate_client
method validate_client_match (line 116) | def validate_client_match
method validate_scope (line 122) | def validate_scope
method custom_token_attributes_with_data (line 133) | def custom_token_attributes_with_data
FILE: lib/doorkeeper/oauth/scopes.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class Scopes (line 5) | class Scopes
method from_string (line 11) | def self.from_string(string)
method from_array (line 18) | def self.from_array(array)
method initialize (line 26) | def initialize
method exists? (line 30) | def exists?(scope)
method add (line 42) | def add(*scopes)
method all (line 47) | def all
method to_s (line 51) | def to_s
method scopes? (line 55) | def scopes?(scopes)
method + (line 61) | def +(other)
method <=> (line 65) | def <=>(other)
method & (line 79) | def &(other)
method allowed (line 90) | def allowed(other)
method dynamic_scopes_enabled? (line 97) | def dynamic_scopes_enabled?
method dynamic_scope_delimiter (line 101) | def dynamic_scope_delimiter
method dynamic_scopes_present? (line 107) | def dynamic_scopes_present?(allowed, requested)
method dynamic_scope_match? (line 111) | def dynamic_scope_match?(allowed, requested)
method to_array (line 123) | def to_array(other)
FILE: lib/doorkeeper/oauth/token.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class Token (line 5) | class Token
method from_request (line 7) | def from_request(request, *methods)
method authenticate (line 15) | def authenticate(request, *methods)
method from_access_token_param (line 25) | def from_access_token_param(request)
method from_bearer_param (line 29) | def from_bearer_param(request)
method from_bearer_authorization (line 33) | def from_bearer_authorization(request)
method from_basic_authorization (line 39) | def from_basic_authorization(request)
method token_from_basic_header (line 47) | def token_from_basic_header(header, pattern)
method decode_basic_credentials_token (line 52) | def decode_basic_credentials_token(encoded_header)
method token_from_header (line 56) | def token_from_header(header, pattern)
method match? (line 60) | def match?(header, pattern)
FILE: lib/doorkeeper/oauth/token_introspection.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class TokenIntrospection (line 8) | class TokenIntrospection
method initialize (line 11) | def initialize(server, token)
method authorized? (line 16) | def authorized?
method error_response (line 21) | def error_response
method to_json (line 33) | def to_json(*)
method authorize! (line 58) | def authorize!
method authorize_using_basic_auth! (line 70) | def authorize_using_basic_auth!
method authorize_using_bearer_token! (line 80) | def authorize_using_bearer_token!
method authorized_client (line 94) | def authorized_client
method authorized_token (line 99) | def authorized_token
method success_response (line 104) | def success_response
method failure_response (line 130) | def failure_response
method active? (line 171) | def active?
method valid_token? (line 180) | def valid_token?
method valid_authorized_token? (line 184) | def valid_authorized_token?
method authorized_token_matches_introspected? (line 191) | def authorized_token_matches_introspected?
method token_introspection_allowed? (line 196) | def token_introspection_allowed?(auth_client: nil, auth_token: nil)
method customize_response (line 209) | def customize_response(response)
FILE: lib/doorkeeper/oauth/token_request.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class TokenRequest (line 5) | class TokenRequest
method initialize (line 8) | def initialize(pre_auth, resource_owner)
method authorize (line 13) | def authorize
method deny (line 19) | def deny
FILE: lib/doorkeeper/oauth/token_response.rb
type Doorkeeper (line 3) | module Doorkeeper
type OAuth (line 4) | module OAuth
class TokenResponse (line 5) | class TokenResponse
method initialize (line 10) | def initialize(token)
method body (line 14) | def body
method status (line 25) | def status
method headers (line 29) | def headers
FILE: lib/doorkeeper/orm/active_record.rb
type Doorkeeper (line 3) | module Doorkeeper
type Models (line 9) | module Models
type Orm (line 21) | module Orm
type ActiveRecord (line 22) | module ActiveRecord
type Mixins (line 25) | module Mixins
function run_hooks (line 31) | def self.run_hooks
function initialize_configured_associations (line 35) | def self.initialize_configured_associations
FILE: lib/doorkeeper/orm/active_record/access_grant.rb
type Doorkeeper (line 5) | module Doorkeeper
class AccessGrant (line 6) | class AccessGrant < ::ActiveRecord::Base
FILE: lib/doorkeeper/orm/active_record/access_token.rb
type Doorkeeper (line 5) | module Doorkeeper
class AccessToken (line 6) | class AccessToken < ::ActiveRecord::Base
FILE: lib/doorkeeper/orm/active_record/application.rb
type Doorkeeper (line 6) | module Doorkeeper
class Application (line 7) | class Application < ::ActiveRecord::Base
FILE: lib/doorkeeper/orm/active_record/mixins/access_grant.rb
type Doorkeeper::Orm::ActiveRecord::Mixins (line 3) | module Doorkeeper::Orm::ActiveRecord::Mixins
type AccessGrant (line 4) | module AccessGrant
function plaintext_token (line 33) | def plaintext_token
function generate_token (line 47) | def generate_token
type ClassMethods (line 53) | module ClassMethods
function compute_doorkeeper_table_name (line 56) | def compute_doorkeeper_table_name
FILE: lib/doorkeeper/orm/active_record/mixins/access_token.rb
type Doorkeeper::Orm::ActiveRecord::Mixins (line 3) | module Doorkeeper::Orm::ActiveRecord::Mixins
type AccessToken (line 4) | module AccessToken
type ClassMethods (line 29) | module ClassMethods
function active_for (line 39) | def active_for(resource_owner)
function refresh_token_revoked_on_use? (line 65) | def refresh_token_revoked_on_use?
function not_expired (line 70) | def not_expired
function compute_doorkeeper_table_name (line 87) | def compute_doorkeeper_table_name
FILE: lib/doorkeeper/orm/active_record/mixins/application.rb
type Doorkeeper::Orm::ActiveRecord::Mixins (line 3) | module Doorkeeper::Orm::ActiveRecord::Mixins
type Application (line 4) | module Application
function renew_secret (line 48) | def renew_secret
function plaintext_secret (line 59) | def plaintext_secret
function as_json (line 75) | def as_json(options = {})
function authorized_for_resource_owner? (line 90) | def authorized_for_resource_owner?(resource_owner)
function read_attribute_for_serialization (line 99) | def read_attribute_for_serialization(key)
function secret_generator (line 107) | def secret_generator
function generate_uid (line 118) | def generate_uid
function generate_secret (line 122) | def generate_secret
function scopes_match_configured (line 128) | def scopes_match_configured
function enforce_scopes? (line 137) | def enforce_scopes?
function secret_required? (line 141) | def secret_required?
function extract_serializable_attributes (line 154) | def extract_serializable_attributes(options = {})
function client_serializable_attributes (line 175) | def client_serializable_attributes
type ClassMethods (line 182) | module ClassMethods
function authorized_for (line 192) | def authorized_for(resource_owner)
function revoke_tokens_and_grants_for (line 203) | def revoke_tokens_and_grants_for(id, resource_owner)
function compute_doorkeeper_table_name (line 210) | def compute_doorkeeper_table_name
FILE: lib/doorkeeper/orm/active_record/redirect_uri_validator.rb
type Doorkeeper (line 5) | module Doorkeeper
class RedirectUriValidator (line 8) | class RedirectUriValidator < ActiveModel::EachValidator
method validate_each (line 9) | def validate_each(record, attribute, value)
method oob_redirect_uri? (line 33) | def oob_redirect_uri?(uri)
method forbidden_uri? (line 37) | def forbidden_uri?(uri)
method unspecified_scheme? (line 41) | def unspecified_scheme?(uri)
method unspecified_host? (line 47) | def unspecified_host?(uri)
method relative_uri? (line 51) | def relative_uri?(uri)
method invalid_ssl_uri? (line 55) | def invalid_ssl_uri?(uri)
FILE: lib/doorkeeper/orm/active_record/stale_records_cleaner.rb
type Doorkeeper (line 3) | module Doorkeeper
type Orm (line 4) | module Orm
type ActiveRecord (line 5) | module ActiveRecord
class StaleRecordsCleaner (line 9) | class StaleRecordsCleaner
method initialize (line 10) | def initialize(base_scope)
method clean_revoked (line 15) | def clean_revoked
method clean_expired (line 25) | def clean_expired(ttl)
FILE: lib/doorkeeper/rails/helpers.rb
type Doorkeeper (line 3) | module Doorkeeper
type Rails (line 4) | module Rails
type Helpers (line 5) | module Helpers
function doorkeeper_authorize! (line 6) | def doorkeeper_authorize!(*scopes)
function doorkeeper_unauthorized_render_options (line 12) | def doorkeeper_unauthorized_render_options(**); end
function doorkeeper_forbidden_render_options (line 14) | def doorkeeper_forbidden_render_options(**); end
function valid_doorkeeper_token? (line 16) | def valid_doorkeeper_token?
function doorkeeper_render_error (line 22) | def doorkeeper_render_error
function doorkeeper_render_error_with (line 30) | def doorkeeper_render_error_with(error)
function doorkeeper_error (line 44) | def doorkeeper_error
function doorkeeper_render_options (line 52) | def doorkeeper_render_options(error)
function doorkeeper_status_for_error (line 60) | def doorkeeper_status_for_error(error, respond_not_found_when_forb...
function doorkeeper_invalid_token_response? (line 68) | def doorkeeper_invalid_token_response?
function doorkeeper_token (line 72) | def doorkeeper_token
FILE: lib/doorkeeper/rails/routes.rb
type Doorkeeper (line 8) | module Doorkeeper
type Rails (line 9) | module Rails
class Routes (line 10) | class Routes # :nodoc:
type Helper (line 11) | module Helper
function use_doorkeeper (line 12) | def use_doorkeeper(options = {}, &block)
method install! (line 24) | def self.install!
method initialize (line 30) | def initialize(routes, mapper = Mapper.new, &block)
method generate_routes! (line 34) | def generate_routes!(options)
method authorization_routes (line 48) | def authorization_routes(mapping)
method token_routes (line 61) | def token_routes(mapping)
method revoke_routes (line 70) | def revoke_routes(mapping)
method introspect_routes (line 74) | def introspect_routes(mapping)
method token_info_routes (line 78) | def token_info_routes(mapping)
method application_routes (line 87) | def application_routes(mapping)
method authorized_applications_routes (line 94) | def authorized_applications_routes(mapping)
method native_authorization_code_route (line 100) | def native_authorization_code_route
method introspection_routes? (line 104) | def introspection_routes?
FILE: lib/doorkeeper/rails/routes/abstract_router.rb
type Doorkeeper (line 3) | module Doorkeeper
type Rails (line 4) | module Rails
type AbstractRouter (line 10) | module AbstractRouter
function initialize (line 15) | def initialize(routes, mapper = Mapper.new, &block)
function generate_routes! (line 20) | def generate_routes!(**_options)
function map_route (line 26) | def map_route(name, method)
FILE: lib/doorkeeper/rails/routes/mapper.rb
type Doorkeeper (line 3) | module Doorkeeper
type Rails (line 4) | module Rails
class Routes (line 5) | class Routes # :nodoc:
class Mapper (line 6) | class Mapper
method initialize (line 7) | def initialize(mapping = Mapping.new)
method map (line 11) | def map(&block)
method controllers (line 16) | def controllers(controller_names = {})
method skip_controllers (line 20) | def skip_controllers(*controller_names)
method as (line 24) | def as(alias_names = {})
FILE: lib/doorkeeper/rails/routes/mapping.rb
type Doorkeeper (line 3) | module Doorkeeper
type Rails (line 4) | module Rails
class Routes (line 5) | class Routes # :nodoc:
class Mapping (line 6) | class Mapping
method initialize (line 9) | def initialize
method [] (line 27) | def [](routes)
method skipped? (line 34) | def skipped?(controller)
FILE: lib/doorkeeper/rails/routes/registry.rb
type Doorkeeper (line 3) | module Doorkeeper
type Rails (line 4) | module Rails
class Routes (line 5) | class Routes
type Registry (line 10) | module Registry
function registered_routes (line 20) | def registered_routes
function register_routes (line 31) | def register_routes(routes)
FILE: lib/doorkeeper/rake.rb
type Doorkeeper (line 3) | module Doorkeeper
type Rake (line 4) | module Rake
function load_tasks (line 6) | def load_tasks
FILE: lib/doorkeeper/request.rb
type Doorkeeper (line 3) | module Doorkeeper
type Request (line 4) | module Request
function authorization_strategy (line 6) | def authorization_strategy(response_type)
function token_strategy (line 20) | def token_strategy(grant_type)
function authorization_flows (line 43) | def authorization_flows
function token_flows (line 47) | def token_flows
function available (line 53) | def available
function build_fallback_strategy_class (line 57) | def build_fallback_strategy_class(grant_or_request_type)
FILE: lib/doorkeeper/request/authorization_code.rb
type Doorkeeper (line 3) | module Doorkeeper
type Request (line 4) | module Request
class AuthorizationCode (line 5) | class AuthorizationCode < Strategy
method request (line 8) | def request
method grant (line 19) | def grant
FILE: lib/doorkeeper/request/client_credentials.rb
type Doorkeeper (line 3) | module Doorkeeper
type Request (line 4) | module Request
class ClientCredentials (line 5) | class ClientCredentials < Strategy
method request (line 8) | def request
FILE: lib/doorkeeper/request/code.rb
type Doorkeeper (line 3) | module Doorkeeper
type Request (line 4) | module Request
class Code (line 5) | class Code < Strategy
method pre_auth (line 8) | def pre_auth
method request (line 12) | def request
FILE: lib/doorkeeper/request/password.rb
type Doorkeeper (line 3) | module Doorkeeper
type Request (line 4) | module Request
class Password (line 5) | class Password < Strategy
method request (line 8) | def request
FILE: lib/doorkeeper/request/refresh_token.rb
type Doorkeeper (line 3) | module Doorkeeper
type Request (line 4) | module Request
class RefreshToken (line 5) | class RefreshToken < Strategy
method refresh_token (line 8) | def refresh_token
method request (line 12) | def request
FILE: lib/doorkeeper/request/strategy.rb
type Doorkeeper (line 3) | module Doorkeeper
type Request (line 4) | module Request
class Strategy (line 5) | class Strategy
method initialize (line 10) | def initialize(server)
method request (line 14) | def request
FILE: lib/doorkeeper/request/token.rb
type Doorkeeper (line 3) | module Doorkeeper
type Request (line 4) | module Request
class Token (line 5) | class Token < Strategy
method pre_auth (line 8) | def pre_auth
method request (line 12) | def request
FILE: lib/doorkeeper/revocable_tokens/revocable_access_token.rb
type Doorkeeper (line 3) | module Doorkeeper
type RevocableTokens (line 4) | module RevocableTokens
class RevocableAccessToken (line 5) | class RevocableAccessToken
method initialize (line 8) | def initialize(token)
method revocable? (line 12) | def revocable?
method revoke (line 16) | def revoke
FILE: lib/doorkeeper/revocable_tokens/revocable_refresh_token.rb
type Doorkeeper (line 3) | module Doorkeeper
type RevocableTokens (line 4) | module RevocableTokens
class RevocableRefreshToken (line 5) | class RevocableRefreshToken
method initialize (line 8) | def initialize(token)
method revocable? (line 12) | def revocable?
method revoke (line 16) | def revoke
FILE: lib/doorkeeper/secret_storing/base.rb
type Doorkeeper (line 3) | module Doorkeeper
type SecretStoring (line 4) | module SecretStoring
class Base (line 7) | class Base
method transform_secret (line 12) | def self.transform_secret(_plain_secret)
method store_secret (line 22) | def self.store_secret(resource, attribute, plain_secret)
method restore_secret (line 34) | def self.restore_secret(_resource, _attribute)
method allows_restoring_secrets? (line 42) | def self.allows_restoring_secrets?
method validate_for (line 48) | def self.validate_for(model)
method secret_matches? (line 58) | def self.secret_matches?(input, stored)
FILE: lib/doorkeeper/secret_storing/bcrypt.rb
type Doorkeeper (line 3) | module Doorkeeper
type SecretStoring (line 4) | module SecretStoring
class BCrypt (line 9) | class BCrypt < Base
method transform_secret (line 13) | def self.transform_secret(plain_secret)
method secret_matches? (line 20) | def self.secret_matches?(input, stored)
method allows_restoring_secrets? (line 30) | def self.allows_restoring_secrets?
method validate_for (line 36) | def self.validate_for(model)
method bcrypt_present? (line 52) | def self.bcrypt_present?
FILE: lib/doorkeeper/secret_storing/plain.rb
type Doorkeeper (line 3) | module Doorkeeper
type SecretStoring (line 4) | module SecretStoring
class Plain (line 9) | class Plain < Base
method transform_secret (line 13) | def self.transform_secret(plain_secret)
method restore_secret (line 22) | def self.restore_secret(resource, attribute)
method allows_restoring_secrets? (line 28) | def self.allows_restoring_secrets?
FILE: lib/doorkeeper/secret_storing/sha256_hash.rb
type Doorkeeper (line 3) | module Doorkeeper
type SecretStoring (line 4) | module SecretStoring
class Sha256Hash (line 9) | class Sha256Hash < Base
method transform_secret (line 13) | def self.transform_secret(plain_secret)
method allows_restoring_secrets? (line 21) | def self.allows_restoring_secrets?
FILE: lib/doorkeeper/server.rb
type Doorkeeper (line 3) | module Doorkeeper
class Server (line 4) | class Server
method initialize (line 7) | def initialize(context)
method authorization_request (line 11) | def authorization_request(strategy)
method token_request (line 16) | def token_request(strategy)
method parameters (line 22) | def parameters
method client (line 26) | def client
method current_resource_owner (line 30) | def current_resource_owner
method resource_owner (line 35) | def resource_owner
method credentials (line 39) | def credentials
FILE: lib/doorkeeper/stale_records_cleaner.rb
type Doorkeeper (line 3) | module Doorkeeper
class StaleRecordsCleaner (line 4) | class StaleRecordsCleaner
method for (line 7) | def self.for(base_scope)
method new (line 16) | def self.new(base_scope)
method configured_orm (line 20) | def self.configured_orm
FILE: lib/doorkeeper/validations.rb
type Doorkeeper (line 3) | module Doorkeeper
type Validations (line 4) | module Validations
function validate (line 9) | def validate
function valid? (line 18) | def valid?
type ClassMethods (line 23) | module ClassMethods
function validate (line 24) | def validate(attribute, options = {})
function validations (line 28) | def validations
FILE: lib/doorkeeper/version.rb
type Doorkeeper (line 3) | module Doorkeeper
type VERSION (line 4) | module VERSION
FILE: lib/generators/doorkeeper/application_owner_generator.rb
type Doorkeeper (line 6) | module Doorkeeper
class ApplicationOwnerGenerator (line 10) | class ApplicationOwnerGenerator < ::Rails::Generators::Base
method application_owner (line 15) | def application_owner
method next_migration_number (line 23) | def self.next_migration_number(dirname)
method migration_version (line 29) | def migration_version
FILE: lib/generators/doorkeeper/confidential_applications_generator.rb
type Doorkeeper (line 6) | module Doorkeeper
class ConfidentialApplicationsGenerator (line 10) | class ConfidentialApplicationsGenerator < ::Rails::Generators::Base
method confidential_applications (line 15) | def confidential_applications
method next_migration_number (line 23) | def self.next_migration_number(dirname)
method migration_version (line 29) | def migration_version
FILE: lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb
type Doorkeeper (line 6) | module Doorkeeper
class EnablePolymorphicResourceOwnerGenerator (line 11) | class EnablePolymorphicResourceOwnerGenerator < ::Rails::Generators::Base
method enable_polymorphic_resource_owner (line 16) | def enable_polymorphic_resource_owner
method next_migration_number (line 29) | def self.next_migration_number(dirname)
method migration_version (line 35) | def migration_version
FILE: lib/generators/doorkeeper/install_generator.rb
type Doorkeeper (line 6) | module Doorkeeper
class InstallGenerator (line 9) | class InstallGenerator < ::Rails::Generators::Base
method install (line 14) | def install
FILE: lib/generators/doorkeeper/migration_generator.rb
type Doorkeeper (line 6) | module Doorkeeper
class MigrationGenerator (line 9) | class MigrationGenerator < ::Rails::Generators::Base
method install (line 14) | def install
method next_migration_number (line 22) | def self.next_migration_number(dirname)
method migration_version (line 28) | def migration_version
FILE: lib/generators/doorkeeper/pkce_generator.rb
type Doorkeeper (line 6) | module Doorkeeper
class PkceGenerator (line 10) | class PkceGenerator < ::Rails::Generators::Base
method pkce (line 15) | def pkce
method next_migration_number (line 23) | def self.next_migration_number(dirname)
method migration_version (line 29) | def migration_version
FILE: lib/generators/doorkeeper/previous_refresh_token_generator.rb
type Doorkeeper (line 6) | module Doorkeeper
class PreviousRefreshTokenGenerator (line 10) | class PreviousRefreshTokenGenerator < ::Rails::Generators::Base
method next_migration_number (line 15) | def self.next_migration_number(path)
method previous_refresh_token (line 19) | def previous_refresh_token
method migration_version (line 30) | def migration_version
method no_previous_refresh_token_column? (line 34) | def no_previous_refresh_token_column?
FILE: lib/generators/doorkeeper/remove_applications_secret_not_null_constraint_generator.rb
type Doorkeeper (line 6) | module Doorkeeper
class RemoveApplicationsSecretNotNullConstraintGenerator (line 10) | class RemoveApplicationsSecretNotNullConstraintGenerator < ::Rails::Ge...
method remove_applications_secret_not_null_constraint (line 15) | def remove_applications_secret_not_null_constraint
method next_migration_number (line 23) | def self.next_migration_number(dirname)
method migration_version (line 29) | def migration_version
FILE: lib/generators/doorkeeper/views_generator.rb
type Doorkeeper (line 3) | module Doorkeeper
type Generators (line 4) | module Generators
class ViewsGenerator (line 7) | class ViewsGenerator < ::Rails::Generators::Base
method manifest (line 12) | def manifest
FILE: spec/controllers/application_controller_spec.rb
function index (line 8) | def index
FILE: spec/controllers/application_metal_controller_spec.rb
function index (line 9) | def index
function create (line 13) | def create
FILE: spec/controllers/authorizations_controller_spec.rb
class ActionDispatch::TestResponse (line 10) | class ActionDispatch::TestResponse
method query_params (line 11) | def query_params
FILE: spec/controllers/protected_resources_controller_spec.rb
type ControllerActions (line 5) | module ControllerActions
function index (line 6) | def index
function show (line 10) | def show
function doorkeeper_unauthorized_render_options (line 14) | def doorkeeper_unauthorized_render_options(*); end
function doorkeeper_forbidden_render_options (line 16) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_unauthorized_render_options (line 160) | def doorkeeper_unauthorized_render_options(error: nil)
function doorkeeper_unauthorized_render_options (line 170) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_unauthorized_render_options (line 190) | def doorkeeper_unauthorized_render_options(**)
function doorkeeper_unauthorized_render_options (line 200) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_forbidden_render_options (line 224) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_forbidden_render_options (line 250) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 271) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 289) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 308) | def doorkeeper_forbidden_render_options(*)
function index (line 26) | def index
type ControllerActions (line 157) | module ControllerActions
function index (line 6) | def index
function show (line 10) | def show
function doorkeeper_unauthorized_render_options (line 14) | def doorkeeper_unauthorized_render_options(*); end
function doorkeeper_forbidden_render_options (line 16) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_unauthorized_render_options (line 160) | def doorkeeper_unauthorized_render_options(error: nil)
function doorkeeper_unauthorized_render_options (line 170) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_unauthorized_render_options (line 190) | def doorkeeper_unauthorized_render_options(**)
function doorkeeper_unauthorized_render_options (line 200) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_forbidden_render_options (line 224) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_forbidden_render_options (line 250) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 271) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 289) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 308) | def doorkeeper_forbidden_render_options(*)
type ControllerActions (line 167) | module ControllerActions
function index (line 6) | def index
function show (line 10) | def show
function doorkeeper_unauthorized_render_options (line 14) | def doorkeeper_unauthorized_render_options(*); end
function doorkeeper_forbidden_render_options (line 16) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_unauthorized_render_options (line 160) | def doorkeeper_unauthorized_render_options(error: nil)
function doorkeeper_unauthorized_render_options (line 170) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_unauthorized_render_options (line 190) | def doorkeeper_unauthorized_render_options(**)
function doorkeeper_unauthorized_render_options (line 200) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_forbidden_render_options (line 224) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_forbidden_render_options (line 250) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 271) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 289) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 308) | def doorkeeper_forbidden_render_options(*)
type ControllerActions (line 187) | module ControllerActions
function index (line 6) | def index
function show (line 10) | def show
function doorkeeper_unauthorized_render_options (line 14) | def doorkeeper_unauthorized_render_options(*); end
function doorkeeper_forbidden_render_options (line 16) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_unauthorized_render_options (line 160) | def doorkeeper_unauthorized_render_options(error: nil)
function doorkeeper_unauthorized_render_options (line 170) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_unauthorized_render_options (line 190) | def doorkeeper_unauthorized_render_options(**)
function doorkeeper_unauthorized_render_options (line 200) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_forbidden_render_options (line 224) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_forbidden_render_options (line 250) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 271) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 289) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 308) | def doorkeeper_forbidden_render_options(*)
type ControllerActions (line 197) | module ControllerActions
function index (line 6) | def index
function show (line 10) | def show
function doorkeeper_unauthorized_render_options (line 14) | def doorkeeper_unauthorized_render_options(*); end
function doorkeeper_forbidden_render_options (line 16) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_unauthorized_render_options (line 160) | def doorkeeper_unauthorized_render_options(error: nil)
function doorkeeper_unauthorized_render_options (line 170) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_unauthorized_render_options (line 190) | def doorkeeper_unauthorized_render_options(**)
function doorkeeper_unauthorized_render_options (line 200) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_forbidden_render_options (line 224) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_forbidden_render_options (line 250) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 271) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 289) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 308) | def doorkeeper_forbidden_render_options(*)
type ControllerActions (line 221) | module ControllerActions
function index (line 6) | def index
function show (line 10) | def show
function doorkeeper_unauthorized_render_options (line 14) | def doorkeeper_unauthorized_render_options(*); end
function doorkeeper_forbidden_render_options (line 16) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_unauthorized_render_options (line 160) | def doorkeeper_unauthorized_render_options(error: nil)
function doorkeeper_unauthorized_render_options (line 170) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_unauthorized_render_options (line 190) | def doorkeeper_unauthorized_render_options(**)
function doorkeeper_unauthorized_render_options (line 200) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_forbidden_render_options (line 224) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_forbidden_render_options (line 250) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 271) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 289) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 308) | def doorkeeper_forbidden_render_options(*)
type ControllerActions (line 247) | module ControllerActions
function index (line 6) | def index
function show (line 10) | def show
function doorkeeper_unauthorized_render_options (line 14) | def doorkeeper_unauthorized_render_options(*); end
function doorkeeper_forbidden_render_options (line 16) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_unauthorized_render_options (line 160) | def doorkeeper_unauthorized_render_options(error: nil)
function doorkeeper_unauthorized_render_options (line 170) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_unauthorized_render_options (line 190) | def doorkeeper_unauthorized_render_options(**)
function doorkeeper_unauthorized_render_options (line 200) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_forbidden_render_options (line 224) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_forbidden_render_options (line 250) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 271) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 289) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 308) | def doorkeeper_forbidden_render_options(*)
type ControllerActions (line 269) | module ControllerActions
function index (line 6) | def index
function show (line 10) | def show
function doorkeeper_unauthorized_render_options (line 14) | def doorkeeper_unauthorized_render_options(*); end
function doorkeeper_forbidden_render_options (line 16) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_unauthorized_render_options (line 160) | def doorkeeper_unauthorized_render_options(error: nil)
function doorkeeper_unauthorized_render_options (line 170) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_unauthorized_render_options (line 190) | def doorkeeper_unauthorized_render_options(**)
function doorkeeper_unauthorized_render_options (line 200) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_forbidden_render_options (line 224) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_forbidden_render_options (line 250) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 271) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 289) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 308) | def doorkeeper_forbidden_render_options(*)
type ControllerActions (line 286) | module ControllerActions
function index (line 6) | def index
function show (line 10) | def show
function doorkeeper_unauthorized_render_options (line 14) | def doorkeeper_unauthorized_render_options(*); end
function doorkeeper_forbidden_render_options (line 16) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_unauthorized_render_options (line 160) | def doorkeeper_unauthorized_render_options(error: nil)
function doorkeeper_unauthorized_render_options (line 170) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_unauthorized_render_options (line 190) | def doorkeeper_unauthorized_render_options(**)
function doorkeeper_unauthorized_render_options (line 200) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_forbidden_render_options (line 224) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_forbidden_render_options (line 250) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 271) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 289) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 308) | def doorkeeper_forbidden_render_options(*)
type ControllerActions (line 305) | module ControllerActions
function index (line 6) | def index
function show (line 10) | def show
function doorkeeper_unauthorized_render_options (line 14) | def doorkeeper_unauthorized_render_options(*); end
function doorkeeper_forbidden_render_options (line 16) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_unauthorized_render_options (line 160) | def doorkeeper_unauthorized_render_options(error: nil)
function doorkeeper_unauthorized_render_options (line 170) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_unauthorized_render_options (line 190) | def doorkeeper_unauthorized_render_options(**)
function doorkeeper_unauthorized_render_options (line 200) | def doorkeeper_unauthorized_render_options(error: nil); end
function doorkeeper_forbidden_render_options (line 224) | def doorkeeper_forbidden_render_options(*); end
function doorkeeper_forbidden_render_options (line 250) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 271) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 289) | def doorkeeper_forbidden_render_options(*)
function doorkeeper_forbidden_render_options (line 308) | def doorkeeper_forbidden_render_options(*)
FILE: spec/controllers/tokens_controller_spec.rb
function create (line 99) | def create
FILE: spec/dummy/app/controllers/application_controller.rb
class ApplicationController (line 3) | class ApplicationController < ActionController::Base
FILE: spec/dummy/app/controllers/custom_authorizations_controller.rb
class CustomAuthorizationsController (line 3) | class CustomAuthorizationsController < ::ApplicationController
FILE: spec/dummy/app/controllers/full_protected_resources_controller.rb
class FullProtectedResourcesController (line 3) | class FullProtectedResourcesController < ApplicationController
method index (line 7) | def index
method show (line 11) | def show
FILE: spec/dummy/app/controllers/home_controller.rb
class HomeController (line 3) | class HomeController < ApplicationController
method index (line 4) | def index; end
method sign_in (line 6) | def sign_in
method callback (line 15) | def callback
FILE: spec/dummy/app/controllers/metal_controller.rb
class MetalController (line 3) | class MetalController < ActionController::Metal
method index (line 10) | def index
FILE: spec/dummy/app/controllers/semi_protected_resources_controller.rb
class SemiProtectedResourcesController (line 3) | class SemiProtectedResourcesController < ApplicationController
method index (line 6) | def index
method show (line 10) | def show
FILE: spec/dummy/app/helpers/application_helper.rb
type ApplicationHelper (line 3) | module ApplicationHelper
function current_user (line 4) | def current_user
FILE: spec/dummy/app/models/user.rb
class ApplicationRecord (line 3) | class ApplicationRecord < ::ActiveRecord::Base
class User (line 7) | class User < ApplicationRecord
method authenticate! (line 8) | def self.authenticate!(name, password)
FILE: spec/dummy/config/application.rb
type Dummy (line 30) | module Dummy
class Application (line 31) | class Application < Rails::Application
FILE: spec/dummy/db/migrate/20111122132257_create_users.rb
class CreateUsers (line 3) | class CreateUsers < ActiveRecord::Migration[4.2]
method change (line 4) | def change
FILE: spec/dummy/db/migrate/20120312140401_add_password_to_users.rb
class AddPasswordToUsers (line 3) | class AddPasswordToUsers < ActiveRecord::Migration[4.2]
method change (line 4) | def change
FILE: spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb
class CreateDoorkeeperTables (line 3) | class CreateDoorkeeperTables < ActiveRecord::Migration[4.2]
method change (line 4) | def change
FILE: spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb
class AddOwnerToApplication (line 3) | class AddOwnerToApplication < ActiveRecord::Migration[4.2]
method change (line 4) | def change
FILE: spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb
class AddPreviousRefreshTokenToAccessTokens (line 3) | class AddPreviousRefreshTokenToAccessTokens < ActiveRecord::Migration[4.2]
method change (line 4) | def change
FILE: spec/dummy/db/migrate/20170822064514_enable_pkce.rb
class EnablePkce (line 3) | class EnablePkce < ActiveRecord::Migration[4.2]
method change (line 4) | def change
FILE: spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb
class AddConfidentialToApplications (line 3) | class AddConfidentialToApplications < ActiveRecord::Migration[5.1]
method change (line 4) | def change
FILE: spec/dummy/db/migrate/20230205064514_add_custom_attributes.rb
class AddCustomAttributes (line 3) | class AddCustomAttributes < ActiveRecord::Migration[4.2]
method change (line 4) | def change
FILE: spec/grape/grape_integration_spec.rb
type GrapeApp (line 9) | module GrapeApp
class API (line 10) | class API < Grape::API
function app (line 66) | def app
function json_body (line 70) | def json_body
FILE: spec/lib/config_spec.rb
class ApplicationWithOwner (line 397) | class ApplicationWithOwner < ActiveRecord::Base
class ApplicationWithOwner (line 427) | class ApplicationWithOwner < ActiveRecord::Base
class FakeCustomModel (line 656) | class FakeCustomModel < ::ActiveRecord::Base
FILE: spec/lib/doorkeeper/orm/active_record_spec.rb
function name (line 65) | def self.name
function name (line 96) | def self.name
function name (line 123) | def self.name
FILE: spec/lib/models/concerns/write_to_primary_spec.rb
function create_record (line 10) | def self.create_record
FILE: spec/lib/models/secret_storable_spec.rb
function find_by (line 10) | def self.find_by(*)
function update_column (line 14) | def update_column(*)
function token (line 18) | def token
FILE: spec/lib/oauth/client/credentials_spec.rb
class Doorkeeper::OAuth::Client (line 5) | class Doorkeeper::OAuth::Client
FILE: spec/lib/oauth/helpers/unique_token_spec.rb
type Doorkeeper::OAuth::Helpers (line 5) | module Doorkeeper::OAuth::Helpers
FILE: spec/lib/oauth/token_spec.rb
type Doorkeeper (line 5) | module Doorkeeper
class AccessToken (line 7) | class AccessToken
FILE: spec/lib/option_spec.rb
class Extension (line 6) | class Extension
method configure (line 7) | def self.configure(&block)
method configuration (line 11) | def self.configuration
class Config (line 15) | class Config
class Builder (line 16) | class Builder < Doorkeeper::Config::AbstractBuilder
method enforce_something (line 17) | def enforce_something
method enforce_something? (line 22) | def enforce_something?
method builder_class (line 30) | def self.builder_class
FILE: spec/lib/request/strategy_spec.rb
function request (line 33) | def request
FILE: spec/models/doorkeeper/access_token_spec.rb
type CustomGeneratorArgs (line 16) | module CustomGeneratorArgs
function generate (line 17) | def self.generate; end
function generate (line 111) | def self.generate(opts = {})
function generate (line 137) | def self.generate(opts = {})
function generate (line 157) | def self.generate(opts = {})
function generate (line 178) | def self.generate(opts = {})
function generate (line 194) | def self.generate(opts = {})
function generate (line 211) | def self.generate(opts = {})
function generate (line 247) | def self.generate(_opts = {})
type CustomGeneratorArgs (line 110) | module CustomGeneratorArgs
function generate (line 17) | def self.generate; end
function generate (line 111) | def self.generate(opts = {})
function generate (line 137) | def self.generate(opts = {})
function generate (line 157) | def self.generate(opts = {})
function generate (line 178) | def self.generate(opts = {})
function generate (line 194) | def self.generate(opts = {})
function generate (line 211) | def self.generate(opts = {})
function generate (line 247) | def self.generate(_opts = {})
type CustomGeneratorArgs (line 136) | module CustomGeneratorArgs
function generate (line 17) | def self.generate; end
function generate (line 111) | def self.generate(opts = {})
function generate (line 137) | def self.generate(opts = {})
function generate (line 157) | def self.generate(opts = {})
function generate (line 178) | def self.generate(opts = {})
function generate (line 194) | def self.generate(opts = {})
function generate (line 211) | def self.generate(opts = {})
function generate (line 247) | def self.generate(_opts = {})
type CustomGeneratorArgs (line 156) | module CustomGeneratorArgs
function generate (line 17) | def self.generate; end
function generate (line 111) | def self.generate(opts = {})
function generate (line 137) | def self.generate(opts = {})
function generate (line 157) | def self.generate(opts = {})
function generate (line 178) | def self.generate(opts = {})
function generate (line 194) | def self.generate(opts = {})
function generate (line 211) | def self.generate(opts = {})
function generate (line 247) | def self.generate(_opts = {})
type CustomGeneratorArgs (line 177) | module CustomGeneratorArgs
function generate (line 17) | def self.generate; end
function generate (line 111) | def self.generate(opts = {})
function generate (line 137) | def self.generate(opts = {})
function generate (line 157) | def self.generate(opts = {})
function generate (line 178) | def self.generate(opts = {})
function generate (line 194) | def self.generate(opts = {})
function generate (line 211) | def self.generate(opts = {})
function generate (line 247) | def self.generate(_opts = {})
type CustomGeneratorArgs (line 193) | module CustomGeneratorArgs
function generate (line 17) | def self.generate; end
function generate (line 111) | def self.generate(opts = {})
function generate (line 137) | def self.generate(opts = {})
function generate (line 157) | def self.generate(opts = {})
function generate (line 178) | def self.generate(opts = {})
function generate (line 194) | def self.generate(opts = {})
function generate (line 211) | def self.generate(opts = {})
function generate (line 247) | def self.generate(_opts = {})
type CustomGeneratorArgs (line 210) | module CustomGeneratorArgs
function generate (line 17) | def self.generate; end
function generate (line 111) | def self.generate(opts = {})
function generate (line 137) | def self.generate(opts = {})
function generate (line 157) | def self.generate(opts = {})
function generate (line 178) | def self.generate(opts = {})
function generate (line 194) | def self.generate(opts = {})
function generate (line 211) | def self.generate(opts = {})
function generate (line 247) | def self.generate(_opts = {})
type NoGenerate (line 227) | module NoGenerate
type CustomGeneratorArgs (line 246) | module CustomGeneratorArgs
function generate (line 17) | def self.generate; end
function generate (line 111) | def self.generate(opts = {})
function generate (line 137) | def self.generate(opts = {})
function generate (line 157) | def self.generate(opts = {})
function generate (line 178) | def self.generate(opts = {})
function generate (line 194) | def self.generate(opts = {})
function generate (line 211) | def self.generate(opts = {})
function generate (line 247) | def self.generate(_opts = {})
FILE: spec/models/doorkeeper/application_spec.rb
type CustomGeneratorArgs (line 92) | module CustomGeneratorArgs
function generate (line 93) | def self.generate
class CustomApp (line 529) | class CustomApp < ::ActiveRecord::Base
FILE: spec/requests/flows/authorization_code_spec.rb
function authorize (line 67) | def authorize(redirect_url)
FILE: spec/requests/flows/client_credentials_spec.rb
function authorization (line 229) | def authorization(username, password)
FILE: spec/requests/flows/refresh_token_spec.rb
function last_token (line 276) | def last_token
FILE: spec/support/doorkeeper_rspec.rb
type Doorkeeper (line 3) | module Doorkeeper
class RSpec (line 4) | class RSpec
method print_configuration_info (line 7) | def self.print_configuration_info
method detect_orm (line 17) | def self.detect_orm
FILE: spec/support/helpers/access_token_request_helper.rb
type AccessTokenRequestHelper (line 3) | module AccessTokenRequestHelper
function client_is_authorized (line 4) | def client_is_authorized(client, resource_owner, access_token_attribut...
FILE: spec/support/helpers/authorization_request_helper.rb
type AuthorizationRequestHelper (line 3) | module AuthorizationRequestHelper
function resource_owner_is_authenticated (line 4) | def resource_owner_is_authenticated(resource_owner = nil)
function resource_owner_is_not_authenticated (line 9) | def resource_owner_is_not_authenticated
function default_scopes_exist (line 13) | def default_scopes_exist(*scopes)
function optional_scopes_exist (line 17) | def optional_scopes_exist(*scopes)
function client_should_be_authorized (line 21) | def client_should_be_authorized(client)
function client_should_not_be_authorized (line 25) | def client_should_not_be_authorized(client)
function i_should_be_on_client_callback (line 29) | def i_should_be_on_client_callback(client)
function allowing_forgery_protection (line 33) | def allowing_forgery_protection(&_block)
FILE: spec/support/helpers/config_helper.rb
type ConfigHelper (line 3) | module ConfigHelper
function config_is_set (line 4) | def config_is_set(setting, value = nil, &block)
FILE: spec/support/helpers/model_helper.rb
type ModelHelper (line 3) | module ModelHelper
function client_exists (line 4) | def client_exists(client_attributes = {})
function create_resource_owner (line 8) | def create_resource_owner
function authorization_code_exists (line 12) | def authorization_code_exists(options = {})
function access_token_exists (line 16) | def access_token_exists(options = {})
function access_grant_should_exist_for (line 20) | def access_grant_should_exist_for(client, resource_owner)
function access_token_should_exist_for (line 29) | def access_token_should_exist_for(client, resource_owner)
function access_grant_should_not_exist (line 38) | def access_grant_should_not_exist
function access_token_should_not_exist (line 42) | def access_token_should_not_exist
function access_grant_should_have_scopes (line 46) | def access_grant_should_have_scopes(*args)
function access_token_should_have_scopes (line 51) | def access_token_should_have_scopes(*args)
function uniqueness_error (line 56) | def uniqueness_error
FILE: spec/support/helpers/request_spec_helper.rb
type RequestSpecHelper (line 3) | module RequestSpecHelper
function i_am_logged_in (line 4) | def i_am_logged_in
function i_should_see (line 8) | def i_should_see(content)
function i_should_not_see (line 12) | def i_should_not_see(content)
function i_should_be_on (line 16) | def i_should_be_on(path)
function url_should_have_param (line 20) | def url_should_have_param(param, value)
function url_should_not_have_param (line 24) | def url_should_not_have_param(param)
function current_params (line 28) | def current_params
function current_uri (line 32) | def current_uri
function request_response (line 36) | def request_response
function json_response (line 40) | def json_response
function should_have_status (line 44) | def should_have_status(status)
function with_access_token_header (line 48) | def with_access_token_header(token)
function with_header (line 52) | def with_header(header, value)
function basic_auth_header_for_client (line 56) | def basic_auth_header_for_client(client)
function sign_in (line 60) | def sign_in
function create_access_token (line 65) | def create_access_token(authorization_code, client, code_verifier = nil)
function i_should_see_translated_error_message (line 69) | def i_should_see_translated_error_message(key)
function i_should_not_see_translated_error_message (line 73) | def i_should_not_see_translated_error_message(key)
function translated_error_message (line 77) | def translated_error_message(key)
function i_should_see_translated_invalid_request_error_message (line 81) | def i_should_see_translated_invalid_request_error_message(key, value)
function translated_invalid_request_error_message (line 85) | def translated_invalid_request_error_message(key, value)
function response_status_should_be (line 89) | def response_status_should_be(status)
FILE: spec/support/helpers/url_helper.rb
type UrlHelper (line 3) | module UrlHelper
function token_endpoint_url (line 4) | def token_endpoint_url(options = {})
function password_token_endpoint_url (line 17) | def password_token_endpoint_url(options = {})
function authorization_endpoint_url (line 30) | def authorization_endpoint_url(options = {})
function refresh_token_endpoint_url (line 44) | def refresh_token_endpoint_url(options = {})
function revocation_token_endpoint_url (line 54) | def revocation_token_endpoint_url
function build_query (line 58) | def build_query(hash)
FILE: spec/support/render_with_matcher.rb
type RenderWithMatcher (line 7) | module RenderWithMatcher
function included (line 8) | def self.included(base)
Condensed preview — 326 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (924K chars).
[
{
"path": ".codeclimate.yml",
"chars": 57,
"preview": "exclude_patterns:\n- \"lib/doorkeeper/config.rb\"\n- \"spec/\"\n"
},
{
"path": ".coveralls.yml",
"chars": 24,
"preview": "service_name: travis-ci\n"
},
{
"path": ".dockerignore",
"chars": 13,
"preview": "Gemfile.lock\n"
},
{
"path": ".editorconfig",
"chars": 92,
"preview": "root = true\n\n[*.{rb,json}]\nindent_style = space\nindent_size = 2\ninsert_final_newline = true\n"
},
{
"path": ".github/FUNDING.yml",
"chars": 79,
"preview": "# These are supported funding model platforms\n\nopen_collective: doorkeeper-gem\n"
},
{
"path": ".github/ISSUE_TEMPLATE.md",
"chars": 895,
"preview": "### Steps to reproduce\nWhat we need to do to see your problem or bug?\n\nThe more detailed the issue, the more likely that"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 625,
"preview": "### Summary\n\nProvide a general description of the code changes in your pull\nrequest... were there any bugs you had fixed"
},
{
"path": ".github/dependabot.yml",
"chars": 245,
"preview": "version: 2\nupdates:\n- package-ecosystem: bundler\n directory: \"/\"\n schedule:\n interval: daily\n open-pull-requests-l"
},
{
"path": ".github/workflows/changelog.yml",
"chars": 612,
"preview": "name: \"Changelog verifier\"\non:\n pull_request:\n # The specific activity types are listed here to include \"labeled\" an"
},
{
"path": ".github/workflows/ci.yml",
"chars": 2057,
"preview": "name: CI\n\non: [push, pull_request]\n\npermissions:\n contents: read\n\njobs:\n build:\n name: >-\n Ruby ${{ matrix.rub"
},
{
"path": ".github/workflows/rubocop.yml",
"chars": 668,
"preview": "name: rubocop\non:\n pull_request:\npermissions:\n contents: read\n pull-requests: write\njobs:\n rubocop:\n name: runner"
},
{
"path": ".gitignore",
"chars": 258,
"preview": ".bundle/\nvendor/bundle/\n.rbx\n*.rbc\nlog/*.log\npkg/\nspec/dummy/db/*.sqlite3\nspec/dummy/log/*.log\nspec/dummy/tmp/\nspec/gene"
},
{
"path": ".hound.yml",
"chars": 54,
"preview": "rubocop:\n config_file: .rubocop.yml\n version: 1.5.2\n"
},
{
"path": ".rspec",
"chars": 9,
"preview": "--colour\n"
},
{
"path": ".rubocop.yml",
"chars": 2533,
"preview": "inherit_from: .rubocop_todo.yml\nplugins:\n - rubocop-capybara\n - rubocop-factory_bot\n - rubocop-performance\n - ruboco"
},
{
"path": ".rubocop_todo.yml",
"chars": 3351,
"preview": "# This configuration was generated by\n# `rubocop --auto-gen-config`\n# on 2020-06-04 00:15:49 +0300 using RuboCop version"
},
{
"path": "AGENTS.md",
"chars": 914,
"preview": "# Doorkeeper Codebase Guide for AI Coding Agents\n\nThis is the code base of the OAuth 2 provider for Ruby web application"
},
{
"path": "CHANGELOG.md",
"chars": 52379,
"preview": "# Changelog\n\nSee https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions for\nupgrade guides.\n\nUser"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 3297,
"preview": "# Contributor Covenant Code of Conduct\r\n\r\n## Our Pledge\r\n\r\nIn the interest of fostering an open and welcoming environmen"
},
{
"path": "CONTRIBUTING.md",
"chars": 1327,
"preview": "# Contributing\n\nWe love pull requests from everyone. By participating in this project, you agree\nto abide by the [code o"
},
{
"path": "Dockerfile",
"chars": 1232,
"preview": "FROM ruby:3.3.4-alpine\n\n# Linux UID (user id) for the doorkeeper user, change with [--build-arg UID=1234]\nARG UID=\"991\"\n"
},
{
"path": "Gemfile",
"chars": 989,
"preview": "# frozen_string_literal: true\n\nsource \"https://rubygems.org\"\ngit_source(:github) { |repo| \"https://github.com/#{repo}.gi"
},
{
"path": "MIT-LICENSE",
"chars": 1071,
"preview": "Copyright 2011 Applicake. http://applicake.com\n\nPermission is hereby granted, free of charge, to any person obtaining\na "
},
{
"path": "NEWS.md",
"chars": 36,
"preview": "Document moved [here](CHANGELOG.md)\n"
},
{
"path": "README.md",
"chars": 9642,
"preview": "# Doorkeeper — awesome OAuth 2 provider for your Rails / Grape app.\n\n[\nin the project Wiki."
},
{
"path": "app/assets/stylesheets/doorkeeper/admin/application.css",
"chars": 158,
"preview": "/*\n *= require doorkeeper/bootstrap.min\n *\n *= require_self\n *= require_tree .\n*/\n\n.doorkeeper-admin .form-group > .fiel"
},
{
"path": "app/assets/stylesheets/doorkeeper/application.css",
"chars": 912,
"preview": "/*\n *= require doorkeeper/bootstrap.min\n *\n *= require_self\n *= require_tree .\n*/\n\nbody {\n background-color: #eee;\n "
},
{
"path": "app/controllers/doorkeeper/application_controller.rb",
"chars": 371,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n class ApplicationController <\n Doorkeeper.config.resolve_controlle"
},
{
"path": "app/controllers/doorkeeper/application_metal_controller.rb",
"chars": 362,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n class ApplicationMetalController <\n Doorkeeper.config.resolve_cont"
},
{
"path": "app/controllers/doorkeeper/applications_controller.rb",
"chars": 2719,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n class ApplicationsController < Doorkeeper::ApplicationController\n "
},
{
"path": "app/controllers/doorkeeper/authorizations_controller.rb",
"chars": 4686,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n class AuthorizationsController < Doorkeeper::ApplicationController\n "
},
{
"path": "app/controllers/doorkeeper/authorized_applications_controller.rb",
"chars": 905,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n class AuthorizedApplicationsController < Doorkeeper::ApplicationContr"
},
{
"path": "app/controllers/doorkeeper/token_info_controller.rb",
"chars": 562,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n class TokenInfoController < Doorkeeper::ApplicationMetalController\n "
},
{
"path": "app/controllers/doorkeeper/tokens_controller.rb",
"chars": 6317,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n class TokensController < Doorkeeper::ApplicationMetalController\n b"
},
{
"path": "app/helpers/doorkeeper/dashboard_helper.rb",
"chars": 509,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module DashboardHelper\n def doorkeeper_errors_for(object, method)\n"
},
{
"path": "app/views/doorkeeper/applications/_delete_form.html.erb",
"chars": 331,
"preview": "<%- submit_btn_css ||= 'btn btn-link' %>\n<%= form_tag oauth_application_path(application), method: :delete do %>\n <%= s"
},
{
"path": "app/views/doorkeeper/applications/_form.html.erb",
"chars": 2553,
"preview": "<%= form_for application, url: doorkeeper_submit_path(application), as: :doorkeeper_application, html: { role: 'form' } "
},
{
"path": "app/views/doorkeeper/applications/edit.html.erb",
"chars": 119,
"preview": "<div class=\"border-bottom mb-4\">\n <h1><%= t('.title') %></h1>\n</div>\n\n<%= render 'form', application: @application %>\n"
},
{
"path": "app/views/doorkeeper/applications/index.html.erb",
"chars": 1229,
"preview": "<div class=\"border-bottom mb-4\">\n <h1><%= t('.title') %></h1>\n</div>\n\n<p><%= link_to t('.new'), new_oauth_application_p"
},
{
"path": "app/views/doorkeeper/applications/new.html.erb",
"chars": 119,
"preview": "<div class=\"border-bottom mb-4\">\n <h1><%= t('.title') %></h1>\n</div>\n\n<%= render 'form', application: @application %>\n"
},
{
"path": "app/views/doorkeeper/applications/show.html.erb",
"chars": 2222,
"preview": "<div class=\"border-bottom mb-4\">\n <h1><%= t('.title', name: @application.name) %></h1>\n</div>\n\n<div class=\"row\">\n <div"
},
{
"path": "app/views/doorkeeper/authorizations/error.html.erb",
"chars": 259,
"preview": "<div class=\"border-bottom mb-4\">\n <h1><%= t('doorkeeper.authorizations.error.title') %></h1>\n</div>\n\n<main role=\"main\">"
},
{
"path": "app/views/doorkeeper/authorizations/form_post.html.erb",
"chars": 387,
"preview": "<header class=\"page-header\">\n <h1><%= t('.title') %></h1>\n</header>\n\n<%= form_tag @pre_auth.redirect_uri, method: :post"
},
{
"path": "app/views/doorkeeper/authorizations/new.html.erb",
"chars": 2179,
"preview": "<header class=\"page-header\" role=\"banner\">\n <h1><%= t('.title') %></h1>\n</header>\n\n<main role=\"main\">\n <p class=\"h4\">\n"
},
{
"path": "app/views/doorkeeper/authorizations/show.html.erb",
"chars": 157,
"preview": "<header class=\"page-header\">\n <h1><%= t('.title') %></h1>\n</header>\n\n<main role=\"main\">\n <code id=\"authorization_code\""
},
{
"path": "app/views/doorkeeper/authorized_applications/_delete_form.html.erb",
"chars": 328,
"preview": "<%- submit_btn_css ||= 'btn btn-link' %>\n<%= form_tag oauth_authorized_application_path(application), method: :delete do"
},
{
"path": "app/views/doorkeeper/authorized_applications/index.html.erb",
"chars": 740,
"preview": "<header class=\"page-header\">\n <h1><%= t('doorkeeper.authorized_applications.index.title') %></h1>\n</header>\n\n<main role"
},
{
"path": "app/views/layouts/doorkeeper/admin.html.erb",
"chars": 1235,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n <meta n"
},
{
"path": "app/views/layouts/doorkeeper/application.html.erb",
"chars": 527,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <title><%= t('doorkeeper.layouts.application.title') %></title>\n <meta charset=\"utf-8\">"
},
{
"path": "benchmark/ruby/client_credentials.rb",
"chars": 1418,
"preview": "# frozen_string_literal: true\n\n$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), \"..\", \"..\", \"lib\"))\n\nbegin\n require"
},
{
"path": "benchmark/wrk/.keep",
"chars": 0,
"preview": ""
},
{
"path": "bin/console",
"chars": 661,
"preview": "#!/usr/bin/env ruby\n# frozen_string_literal: true\n\nrequire \"bundler/setup\"\nrequire \"rails/all\"\nrequire \"active_support/a"
},
{
"path": "config/locales/en.yml",
"chars": 6533,
"preview": "en:\n activerecord:\n attributes:\n doorkeeper/application:\n name: 'Name'\n redirect_uri: 'Redirect U"
},
{
"path": "doorkeeper.gemspec",
"chars": 1804,
"preview": "# frozen_string_literal: true\n\n$LOAD_PATH.unshift(File.expand_path(\"lib\", __dir__))\n\nrequire \"doorkeeper/version\"\n\nGem::"
},
{
"path": "gemfiles/rails_7_0.gemfile",
"chars": 692,
"preview": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"rails\", \"~> 7.0.0\"\ngem \"rspec-core\"\ngem \"rsp"
},
{
"path": "gemfiles/rails_7_1.gemfile",
"chars": 624,
"preview": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"rails\", \"~> 7.1.0\"\ngem \"rspec-core\"\ngem \"rsp"
},
{
"path": "gemfiles/rails_7_2.gemfile",
"chars": 624,
"preview": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"rails\", \"~> 7.2.0\"\ngem \"rspec-core\"\ngem \"rsp"
},
{
"path": "gemfiles/rails_8_0.gemfile",
"chars": 624,
"preview": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"rails\", \"~> 8.0.0\"\ngem \"rspec-core\"\ngem \"rsp"
},
{
"path": "gemfiles/rails_edge.gemfile",
"chars": 651,
"preview": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"rails\", git: \"https://github.com/rails/rails"
},
{
"path": "lib/doorkeeper/config/abstract_builder.rb",
"chars": 669,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n class Config\n # Abstract base class for Doorkeeper and it's extens"
},
{
"path": "lib/doorkeeper/config/option.rb",
"chars": 2870,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n class Config\n # Doorkeeper configuration option DSL\n module Opt"
},
{
"path": "lib/doorkeeper/config/validations.rb",
"chars": 2136,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n class Config\n # Doorkeeper configuration validator.\n #\n modu"
},
{
"path": "lib/doorkeeper/config.rb",
"chars": 27026,
"preview": "# frozen_string_literal: true\n\nrequire \"doorkeeper/config/abstract_builder\"\nrequire \"doorkeeper/config/option\"\nrequire \""
},
{
"path": "lib/doorkeeper/engine.rb",
"chars": 1042,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n class Engine < Rails::Engine\n initializer \"doorkeeper.params.filte"
},
{
"path": "lib/doorkeeper/errors.rb",
"chars": 2144,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Errors\n class DoorkeeperError < StandardError\n def typ"
},
{
"path": "lib/doorkeeper/grant_flow/fallback_flow.rb",
"chars": 228,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module GrantFlow\n class FallbackFlow < Flow\n def handles_gran"
},
{
"path": "lib/doorkeeper/grant_flow/flow.rb",
"chars": 1173,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module GrantFlow\n class Flow\n attr_reader :name, :grant_type_"
},
{
"path": "lib/doorkeeper/grant_flow/registry.rb",
"chars": 1399,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module GrantFlow\n module Registry\n mattr_accessor :flows\n "
},
{
"path": "lib/doorkeeper/grant_flow.rb",
"chars": 1171,
"preview": "# frozen_string_literal: true\n\nrequire \"doorkeeper/grant_flow/flow\"\nrequire \"doorkeeper/grant_flow/fallback_flow\"\nrequir"
},
{
"path": "lib/doorkeeper/grape/authorization_decorator.rb",
"chars": 409,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Grape\n class AuthorizationDecorator < SimpleDelegator\n "
},
{
"path": "lib/doorkeeper/grape/helpers.rb",
"chars": 1554,
"preview": "# frozen_string_literal: true\n\nrequire \"doorkeeper/grape/authorization_decorator\"\n\nmodule Doorkeeper\n module Grape\n "
},
{
"path": "lib/doorkeeper/helpers/controller.rb",
"chars": 2607,
"preview": "# frozen_string_literal: true\n\n# Define methods that can be called in any controller that inherits from\n# Doorkeeper::Ap"
},
{
"path": "lib/doorkeeper/models/access_grant_mixin.rb",
"chars": 4348,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module AccessGrantMixin\n extend ActiveSupport::Concern\n\n includ"
},
{
"path": "lib/doorkeeper/models/access_token_mixin.rb",
"chars": 19117,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module AccessTokenMixin\n extend ActiveSupport::Concern\n\n includ"
},
{
"path": "lib/doorkeeper/models/application_mixin.rb",
"chars": 3050,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module ApplicationMixin\n extend ActiveSupport::Concern\n\n includ"
},
{
"path": "lib/doorkeeper/models/concerns/accessible.rb",
"chars": 341,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Models\n module Accessible\n # Indicates whether the obj"
},
{
"path": "lib/doorkeeper/models/concerns/expirable.rb",
"chars": 1018,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Models\n module Expirable\n # Indicates whether the obje"
},
{
"path": "lib/doorkeeper/models/concerns/expiration_time_sql_math.rb",
"chars": 3316,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Models\n module ExpirationTimeSqlMath\n extend ::ActiveS"
},
{
"path": "lib/doorkeeper/models/concerns/orderable.rb",
"chars": 281,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Models\n module Orderable\n extend ActiveSupport::Concer"
},
{
"path": "lib/doorkeeper/models/concerns/ownership.rb",
"chars": 383,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Models\n module Ownership\n extend ActiveSupport::Concer"
},
{
"path": "lib/doorkeeper/models/concerns/polymorphic_resource_owner.rb",
"chars": 706,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Models\n module PolymorphicResourceOwner\n module ForAcc"
},
{
"path": "lib/doorkeeper/models/concerns/resource_ownerable.rb",
"chars": 1379,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Models\n module ResourceOwnerable\n extend ActiveSupport"
},
{
"path": "lib/doorkeeper/models/concerns/reusable.rb",
"chars": 533,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Models\n module Reusable\n # Indicates whether the objec"
},
{
"path": "lib/doorkeeper/models/concerns/revocable.rb",
"chars": 844,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Models\n module Revocable\n # Revokes the object (update"
},
{
"path": "lib/doorkeeper/models/concerns/scopes.rb",
"chars": 612,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Models\n module Scopes\n def scopes\n OAuth::Scope"
},
{
"path": "lib/doorkeeper/models/concerns/secret_storable.rb",
"chars": 3412,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Models\n ##\n # Storable finder to provide lookups for inp"
},
{
"path": "lib/doorkeeper/models/concerns/write_to_primary.rb",
"chars": 2093,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Models\n module Concerns\n # Provides support for Rails "
},
{
"path": "lib/doorkeeper/oauth/authorization/code.rb",
"chars": 2128,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n module Authorization\n class Code\n attr_r"
},
{
"path": "lib/doorkeeper/oauth/authorization/context.rb",
"chars": 386,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n module Authorization\n class Context\n att"
},
{
"path": "lib/doorkeeper/oauth/authorization/token.rb",
"chars": 3080,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n module Authorization\n class Token\n attr_"
},
{
"path": "lib/doorkeeper/oauth/authorization/uri_builder.rb",
"chars": 807,
"preview": "# frozen_string_literal: true\n\nrequire \"rack/utils\"\n\nmodule Doorkeeper\n module OAuth\n module Authorization\n cla"
},
{
"path": "lib/doorkeeper/oauth/authorization_code_request.rb",
"chars": 3606,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class AuthorizationCodeRequest < BaseRequest\n v"
},
{
"path": "lib/doorkeeper/oauth/base_request.rb",
"chars": 2040,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class BaseRequest\n include Validations\n\n a"
},
{
"path": "lib/doorkeeper/oauth/base_response.rb",
"chars": 359,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class BaseResponse\n def body\n {}\n e"
},
{
"path": "lib/doorkeeper/oauth/client/credentials.rb",
"chars": 1039,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class Client\n Credentials = Struct.new(:uid, :s"
},
{
"path": "lib/doorkeeper/oauth/client.rb",
"chars": 755,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class Client\n attr_reader :application\n\n d"
},
{
"path": "lib/doorkeeper/oauth/client_credentials/creator.rb",
"chars": 1830,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n module ClientCredentials\n class Creator\n "
},
{
"path": "lib/doorkeeper/oauth/client_credentials/issuer.rb",
"chars": 1173,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n module ClientCredentials\n class Issuer\n "
},
{
"path": "lib/doorkeeper/oauth/client_credentials/validator.rb",
"chars": 1467,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n module ClientCredentials\n class Validator\n "
},
{
"path": "lib/doorkeeper/oauth/client_credentials_request.rb",
"chars": 1104,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class ClientCredentialsRequest < BaseRequest\n a"
},
{
"path": "lib/doorkeeper/oauth/code_request.rb",
"chars": 604,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class CodeRequest\n attr_reader :pre_auth, :reso"
},
{
"path": "lib/doorkeeper/oauth/code_response.rb",
"chars": 1256,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class CodeResponse < BaseResponse\n include OAut"
},
{
"path": "lib/doorkeeper/oauth/error.rb",
"chars": 360,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n Error = Struct.new(:name, :state, :translate_options"
},
{
"path": "lib/doorkeeper/oauth/error_response.rb",
"chars": 3601,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class ErrorResponse < BaseResponse\n include OAu"
},
{
"path": "lib/doorkeeper/oauth/forbidden_token_response.rb",
"chars": 751,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class ForbiddenTokenResponse < ErrorResponse\n d"
},
{
"path": "lib/doorkeeper/oauth/helpers/scope_checker.rb",
"chars": 1386,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n module Helpers\n module ScopeChecker\n cla"
},
{
"path": "lib/doorkeeper/oauth/helpers/unique_token.rb",
"chars": 1015,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n module Helpers\n # Default Doorkeeper token gene"
},
{
"path": "lib/doorkeeper/oauth/helpers/uri_checker.rb",
"chars": 2285,
"preview": "# frozen_string_literal: true\n\nrequire \"ipaddr\"\n\nmodule Doorkeeper\n module OAuth\n module Helpers\n module URIChe"
},
{
"path": "lib/doorkeeper/oauth/hooks/context.rb",
"chars": 415,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n module Hooks\n class Context\n attr_reader"
},
{
"path": "lib/doorkeeper/oauth/invalid_request_response.rb",
"chars": 1150,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class InvalidRequestResponse < ErrorResponse\n a"
},
{
"path": "lib/doorkeeper/oauth/invalid_token_response.rb",
"chars": 1221,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class InvalidTokenResponse < ErrorResponse\n att"
},
{
"path": "lib/doorkeeper/oauth/nonstandard.rb",
"chars": 2135,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class NonStandard\n # These are not part of the "
},
{
"path": "lib/doorkeeper/oauth/password_access_token_request.rb",
"chars": 2516,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class PasswordAccessTokenRequest < BaseRequest\n "
},
{
"path": "lib/doorkeeper/oauth/pre_authorization.rb",
"chars": 5760,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class PreAuthorization\n include Validations\n\n "
},
{
"path": "lib/doorkeeper/oauth/refresh_token_request.rb",
"chars": 4644,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class RefreshTokenRequest < BaseRequest\n includ"
},
{
"path": "lib/doorkeeper/oauth/scopes.rb",
"chars": 3438,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class Scopes\n include Enumerable\n include "
},
{
"path": "lib/doorkeeper/oauth/token.rb",
"chars": 1920,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class Token\n class << self\n def from_req"
},
{
"path": "lib/doorkeeper/oauth/token_introspection.rb",
"chars": 8594,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n # RFC7662 OAuth 2.0 Token Introspection\n #\n # "
},
{
"path": "lib/doorkeeper/oauth/token_request.rb",
"chars": 574,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class TokenRequest\n attr_reader :pre_auth, :res"
},
{
"path": "lib/doorkeeper/oauth/token_response.rb",
"chars": 851,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n class TokenResponse\n attr_reader :token\n\n "
},
{
"path": "lib/doorkeeper/oauth.rb",
"chars": 302,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module OAuth\n GRANT_TYPES = [\n AUTHORIZATION_CODE = \"authoriz"
},
{
"path": "lib/doorkeeper/orm/active_record/access_grant.rb",
"chars": 225,
"preview": "# frozen_string_literal: true\n\nrequire \"doorkeeper/orm/active_record/mixins/access_grant\"\n\nmodule Doorkeeper\n class Acc"
},
{
"path": "lib/doorkeeper/orm/active_record/access_token.rb",
"chars": 225,
"preview": "# frozen_string_literal: true\n\nrequire \"doorkeeper/orm/active_record/mixins/access_token\"\n\nmodule Doorkeeper\n class Acc"
},
{
"path": "lib/doorkeeper/orm/active_record/application.rb",
"chars": 288,
"preview": "# frozen_string_literal: true\n\nrequire \"doorkeeper/orm/active_record/redirect_uri_validator\"\nrequire \"doorkeeper/orm/act"
},
{
"path": "lib/doorkeeper/orm/active_record/mixins/access_grant.rb",
"chars": 1938,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper::Orm::ActiveRecord::Mixins\n module AccessGrant\n extend ActiveSuppor"
},
{
"path": "lib/doorkeeper/orm/active_record/mixins/access_token.rb",
"chars": 3471,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper::Orm::ActiveRecord::Mixins\n module AccessToken\n extend ActiveSuppor"
},
{
"path": "lib/doorkeeper/orm/active_record/mixins/application.rb",
"chars": 7756,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper::Orm::ActiveRecord::Mixins\n module Application\n extend ActiveSuppor"
},
{
"path": "lib/doorkeeper/orm/active_record/redirect_uri_validator.rb",
"chars": 1950,
"preview": "# frozen_string_literal: true\n\nrequire \"uri\"\n\nmodule Doorkeeper\n # ActiveModel validator for redirect URI validation in"
},
{
"path": "lib/doorkeeper/orm/active_record/stale_records_cleaner.rb",
"chars": 1332,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Orm\n module ActiveRecord\n # Helper class to clear stal"
},
{
"path": "lib/doorkeeper/orm/active_record.rb",
"chars": 1834,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n autoload :AccessGrant, \"doorkeeper/orm/active_record/access_grant\"\n "
},
{
"path": "lib/doorkeeper/rails/helpers.rb",
"chars": 2319,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Rails\n module Helpers\n def doorkeeper_authorize!(*scop"
},
{
"path": "lib/doorkeeper/rails/routes/abstract_router.rb",
"chars": 778,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Rails\n # Abstract router module that implements base behavi"
},
{
"path": "lib/doorkeeper/rails/routes/mapper.rb",
"chars": 631,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Rails\n class Routes # :nodoc:\n class Mapper\n de"
},
{
"path": "lib/doorkeeper/rails/routes/mapping.rb",
"chars": 920,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Rails\n class Routes # :nodoc:\n class Mapping\n a"
},
{
"path": "lib/doorkeeper/rails/routes/registry.rb",
"chars": 1248,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Rails\n class Routes\n # Thread-safe registry of any Doo"
},
{
"path": "lib/doorkeeper/rails/routes.rb",
"chars": 3189,
"preview": "# frozen_string_literal: true\n\nrequire \"doorkeeper/rails/routes/mapping\"\nrequire \"doorkeeper/rails/routes/mapper\"\nrequir"
},
{
"path": "lib/doorkeeper/rake/db.rake",
"chars": 1483,
"preview": "# frozen_string_literal: true\n\nnamespace :doorkeeper do\n namespace :db do\n desc \"Removes stale data from doorkeeper "
},
{
"path": "lib/doorkeeper/rake/setup.rake",
"chars": 96,
"preview": "# frozen_string_literal: true\n\nnamespace :doorkeeper do\n task setup: :environment do\n end\nend\n"
},
{
"path": "lib/doorkeeper/rake.rb",
"chars": 277,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Rake\n class << self\n def load_tasks\n glob = Fil"
},
{
"path": "lib/doorkeeper/request/authorization_code.rb",
"chars": 553,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Request\n class AuthorizationCode < Strategy\n delegate "
},
{
"path": "lib/doorkeeper/request/client_credentials.rb",
"chars": 338,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Request\n class ClientCredentials < Strategy\n delegate "
},
{
"path": "lib/doorkeeper/request/code.rb",
"chars": 338,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Request\n class Code < Strategy\n delegate :current_reso"
},
{
"path": "lib/doorkeeper/request/password.rb",
"chars": 411,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Request\n class Password < Strategy\n delegate :credenti"
},
{
"path": "lib/doorkeeper/request/refresh_token.rb",
"chars": 488,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Request\n class RefreshToken < Strategy\n delegate :cred"
},
{
"path": "lib/doorkeeper/request/strategy.rb",
"chars": 341,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Request\n class Strategy\n attr_reader :server\n\n de"
},
{
"path": "lib/doorkeeper/request/token.rb",
"chars": 340,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Request\n class Token < Strategy\n delegate :current_res"
},
{
"path": "lib/doorkeeper/request.rb",
"chars": 2277,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Request\n class << self\n def authorization_strategy(res"
},
{
"path": "lib/doorkeeper/revocable_tokens/revocable_access_token.rb",
"chars": 317,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module RevocableTokens\n class RevocableAccessToken\n attr_read"
},
{
"path": "lib/doorkeeper/revocable_tokens/revocable_refresh_token.rb",
"chars": 316,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module RevocableTokens\n class RevocableRefreshToken\n attr_rea"
},
{
"path": "lib/doorkeeper/secret_storing/base.rb",
"chars": 2129,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module SecretStoring\n ##\n # Base class for secret storing, incl"
},
{
"path": "lib/doorkeeper/secret_storing/bcrypt.rb",
"chars": 1684,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module SecretStoring\n ##\n # Plain text secret storing, which is"
},
{
"path": "lib/doorkeeper/secret_storing/plain.rb",
"chars": 908,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module SecretStoring\n ##\n # Plain text secret storing, which is"
},
{
"path": "lib/doorkeeper/secret_storing/sha256_hash.rb",
"chars": 777,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module SecretStoring\n ##\n # Plain text secret storing, which is"
},
{
"path": "lib/doorkeeper/server.rb",
"chars": 996,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n class Server\n attr_reader :context\n\n def initialize(context)\n "
},
{
"path": "lib/doorkeeper/stale_records_cleaner.rb",
"chars": 572,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n class StaleRecordsCleaner\n CLEANER_CLASS = \"StaleRecordsCleaner\"\n\n"
},
{
"path": "lib/doorkeeper/validations.rb",
"chars": 637,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Validations\n extend ActiveSupport::Concern\n\n attr_access"
},
{
"path": "lib/doorkeeper/version.rb",
"chars": 241,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module VERSION\n # Semantic versioning\n MAJOR = 5\n MINOR = 9\n"
},
{
"path": "lib/doorkeeper.rb",
"chars": 7540,
"preview": "# frozen_string_literal: true\n\nrequire \"doorkeeper/config\"\nrequire \"doorkeeper/engine\"\n\n# Main Doorkeeper namespace.\n#\nm"
},
{
"path": "lib/generators/doorkeeper/application_owner_generator.rb",
"chars": 899,
"preview": "# frozen_string_literal: true\n\nrequire \"rails/generators\"\nrequire \"rails/generators/active_record\"\n\nmodule Doorkeeper\n "
},
{
"path": "lib/generators/doorkeeper/confidential_applications_generator.rb",
"chars": 926,
"preview": "# frozen_string_literal: true\n\nrequire \"rails/generators\"\nrequire \"rails/generators/active_record\"\n\nmodule Doorkeeper\n "
},
{
"path": "lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb",
"chars": 1159,
"preview": "# frozen_string_literal: true\n\nrequire \"rails/generators\"\nrequire \"rails/generators/active_record\"\n\nmodule Doorkeeper\n "
},
{
"path": "lib/generators/doorkeeper/install_generator.rb",
"chars": 655,
"preview": "# frozen_string_literal: true\n\nrequire \"rails/generators\"\nrequire \"rails/generators/active_record\"\n\nmodule Doorkeeper\n "
},
{
"path": "lib/generators/doorkeeper/migration_generator.rb",
"chars": 826,
"preview": "# frozen_string_literal: true\n\nrequire \"rails/generators\"\nrequire \"rails/generators/active_record\"\n\nmodule Doorkeeper\n "
},
{
"path": "lib/generators/doorkeeper/pkce_generator.rb",
"chars": 826,
"preview": "# frozen_string_literal: true\n\nrequire \"rails/generators\"\nrequire \"rails/generators/active_record\"\n\nmodule Doorkeeper\n "
},
{
"path": "lib/generators/doorkeeper/previous_refresh_token_generator.rb",
"chars": 1132,
"preview": "# frozen_string_literal: true\n\nrequire \"rails/generators\"\nrequire \"rails/generators/active_record\"\n\nmodule Doorkeeper\n "
},
{
"path": "lib/generators/doorkeeper/remove_applications_secret_not_null_constraint_generator.rb",
"chars": 1036,
"preview": "# frozen_string_literal: true\n\nrequire \"rails/generators\"\nrequire \"rails/generators/active_record\"\n\nmodule Doorkeeper\n "
},
{
"path": "lib/generators/doorkeeper/templates/README",
"chars": 499,
"preview": "===============================================================================\n\nThere is a setup that you need to do be"
},
{
"path": "lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb",
"chars": 265,
"preview": "# frozen_string_literal: true\n\nclass AddConfidentialToApplications < ActiveRecord::Migration<%= migration_version %>\n d"
},
{
"path": "lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb",
"chars": 328,
"preview": "# frozen_string_literal: true\n\nclass AddOwnerToApplication < ActiveRecord::Migration<%= migration_version %>\n def chang"
},
{
"path": "lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb",
"chars": 281,
"preview": "# frozen_string_literal: true\n\nclass AddPreviousRefreshTokenToAccessTokens < ActiveRecord::Migration<%= migration_versio"
},
{
"path": "lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb",
"chars": 276,
"preview": "# frozen_string_literal: true\n\nclass EnablePkce < ActiveRecord::Migration<%= migration_version %>\n def change\n add_c"
},
{
"path": "lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb",
"chars": 658,
"preview": "# frozen_string_literal: true\n\nclass EnablePolymorphicResourceOwner < ActiveRecord::Migration<%= migration_version %>\n "
},
{
"path": "lib/generators/doorkeeper/templates/initializer.rb",
"chars": 23890,
"preview": "# frozen_string_literal: true\n\nDoorkeeper.configure do\n # Change the ORM that doorkeeper will use (requires ORM extensi"
},
{
"path": "lib/generators/doorkeeper/templates/migration.rb.erb",
"chars": 3979,
"preview": "# frozen_string_literal: true\n\nclass CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>\n def chan"
},
{
"path": "lib/generators/doorkeeper/templates/remove_applications_secret_not_null_constraint.rb.erb",
"chars": 210,
"preview": "# frozen_string_literal: true\n\nclass RemoveApplicationsSecretNotNullConstraint < ActiveRecord::Migration<%= migration_ve"
},
{
"path": "lib/generators/doorkeeper/views_generator.rb",
"chars": 502,
"preview": "# frozen_string_literal: true\n\nmodule Doorkeeper\n module Generators\n # Generates doorkeeper views for Rails applicat"
},
{
"path": "spec/controllers/application_controller_spec.rb",
"chars": 666,
"preview": "# frozen_string_literal: true\n\nrequire \"spec_helper_integration\"\n\nRSpec.describe Doorkeeper::ApplicationController, type"
},
{
"path": "spec/controllers/application_metal_controller_spec.rb",
"chars": 1868,
"preview": "# frozen_string_literal: true\n\nrequire \"spec_helper_integration\"\n\nRSpec.describe Doorkeeper::ApplicationMetalController,"
},
{
"path": "spec/controllers/applications_controller_spec.rb",
"chars": 8842,
"preview": "# frozen_string_literal: true\n\nrequire \"spec_helper\"\n\nRSpec.describe Doorkeeper::ApplicationsController, type: :controll"
},
{
"path": "spec/controllers/authorizations_controller_spec.rb",
"chars": 44479,
"preview": "# frozen_string_literal: true\n\nrequire \"spec_helper\"\n\nRSpec.describe Doorkeeper::AuthorizationsController, type: :contro"
},
{
"path": "spec/controllers/protected_resources_controller_spec.rb",
"chars": 10994,
"preview": "# frozen_string_literal: true\n\nrequire \"spec_helper\"\n\nmodule ControllerActions\n def index\n render plain: \"index\"\n e"
},
{
"path": "spec/controllers/token_info_controller_spec.rb",
"chars": 1505,
"preview": "# frozen_string_literal: true\n\nrequire \"spec_helper\"\n\nRSpec.describe Doorkeeper::TokenInfoController, type: :controller "
},
{
"path": "spec/controllers/tokens_controller_spec.rb",
"chars": 21537,
"preview": "# frozen_string_literal: true\n\nrequire \"spec_helper\"\n\nRSpec.describe Doorkeeper::TokensController, type: :controller do\n"
},
{
"path": "spec/doorkeeper/redirect_uri_validator_spec.rb",
"chars": 6603,
"preview": "# frozen_string_literal: true\n\nrequire \"spec_helper\"\n\nRSpec.describe Doorkeeper::RedirectUriValidator do\n subject(:clie"
},
{
"path": "spec/doorkeeper/server_spec.rb",
"chars": 1539,
"preview": "# frozen_string_literal: true\n\nrequire \"spec_helper\"\n\nRSpec.describe Doorkeeper::Server do\n subject(:server) do\n des"
},
{
"path": "spec/doorkeeper/stale_records_cleaner_spec.rb",
"chars": 6266,
"preview": "# frozen_string_literal: true\n\nrequire \"spec_helper\"\n\nRSpec.describe Doorkeeper::StaleRecordsCleaner do\n let(:cleaner) "
},
{
"path": "spec/doorkeeper/version_spec.rb",
"chars": 409,
"preview": "# frozen_string_literal: true\n\nrequire \"spec_helper\"\n\nRSpec.describe Doorkeeper::VERSION do\n describe \"#gem_version\" do"
},
{
"path": "spec/dummy/Rakefile",
"chars": 297,
"preview": "#!/usr/bin/env rake\n# frozen_string_literal: true\n\n# Add your own tasks in files placed in lib/tasks ending in .rake,\n# "
},
{
"path": "spec/dummy/app/assets/config/manifest.js",
"chars": 25,
"preview": "// JS and CSS bundles\n//\n"
},
{
"path": "spec/dummy/app/controllers/application_controller.rb",
"chars": 128,
"preview": "# frozen_string_literal: true\n\nclass ApplicationController < ActionController::Base\n protect_from_forgery with: :except"
},
{
"path": "spec/dummy/app/controllers/custom_authorizations_controller.rb",
"chars": 232,
"preview": "# frozen_string_literal: true\n\nclass CustomAuthorizationsController < ::ApplicationController\n %w[index show new create"
},
{
"path": "spec/dummy/app/controllers/full_protected_resources_controller.rb",
"chars": 312,
"preview": "# frozen_string_literal: true\n\nclass FullProtectedResourcesController < ApplicationController\n before_action -> { doork"
},
{
"path": "spec/dummy/app/controllers/home_controller.rb",
"chars": 413,
"preview": "# frozen_string_literal: true\n\nclass HomeController < ApplicationController\n def index; end\n\n def sign_in\n session["
},
{
"path": "spec/dummy/app/controllers/metal_controller.rb",
"chars": 298,
"preview": "# frozen_string_literal: true\n\nclass MetalController < ActionController::Metal\n include AbstractController::Callbacks\n "
},
{
"path": "spec/dummy/app/controllers/semi_protected_resources_controller.rb",
"chars": 263,
"preview": "# frozen_string_literal: true\n\nclass SemiProtectedResourcesController < ApplicationController\n before_action :doorkeepe"
},
{
"path": "spec/dummy/app/helpers/application_helper.rb",
"chars": 143,
"preview": "# frozen_string_literal: true\n\nmodule ApplicationHelper\n def current_user\n @current_user ||= User.find_by(id: sessio"
}
]
// ... and 126 more files (download for full content)
About this extraction
This page contains the full source code of the applicake/doorkeeper GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 326 files (843.7 KB), approximately 214.3k tokens, and a symbol index with 1168 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.