diff --git a/CHANGELOG.md b/CHANGELOG.md index 602339e0c..572bf8926 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ User-visible changes worth mentioning. ## main +- [#1834] Fix default `allow_token_introspection` returning `false` when a custom `application_class` is configured. The default proc compared application objects with `==`, which fails when the authorized client and the introspected token's application are resolved as different classes (e.g. a base `Doorkeeper::Application` vs. a configured subclass) even though they reference the same record. It now compares application ids instead. - Please add here ## 5.9.2 diff --git a/lib/doorkeeper/config.rb b/lib/doorkeeper/config.rb index b326938e7..de19ebf60 100644 --- a/lib/doorkeeper/config.rb +++ b/lib/doorkeeper/config.rb @@ -444,9 +444,9 @@ def configure_secrets_for(type, using:, fallback:) option :allow_token_introspection, default: (lambda do |token, authorized_client, authorized_token| if authorized_token - authorized_token.application == token&.application + authorized_token.application_id == token&.application_id elsif token&.application - authorized_client == token.application + authorized_client.id == token.application_id else true end diff --git a/spec/controllers/tokens_controller_spec.rb b/spec/controllers/tokens_controller_spec.rb index 780bcb22b..00710fdb9 100644 --- a/spec/controllers/tokens_controller_spec.rb +++ b/spec/controllers/tokens_controller_spec.rb @@ -371,6 +371,31 @@ def create end end + context "when application_class is configured to a custom subclass" do + # Regression test for doorkeeper#1833: the default allow_token_introspection + # proc compared application objects with `==`, which fails when the + # authorized client is resolved as a different (sub)class than the + # introspected token's application, even though they reference the same row. + let(:custom_application_class) { Class.new(Doorkeeper::Application) } + + before do + stub_const("CustomDoorkeeperApplication", custom_application_class) + allow(Doorkeeper.config).to receive(:application_model).and_return(CustomDoorkeeperApplication) + end + + it "responds with full token introspection when authorized via Client Credentials" do + # token_for_introspection.application is a Doorkeeper::Application, while the + # authorized client is resolved as CustomDoorkeeperApplication for the same row. + expect(token_for_introspection.application).to be_an_instance_of(Doorkeeper::Application) + + request.headers["Authorization"] = basic_auth_header_for_client(client) + + post :introspect, params: { token: token_for_introspection.token } + + expect(json_response).to include("active" => true) + end + end + context "when token introspection disabled" do before do Doorkeeper.configure do