fix: #3630880 Delete tokens when their consumer is deleted

Closes https://www.drupal.org/project/simple_oauth/issues/3630880

What changed

Deleting a consumer now deletes its tokens. A token whose consumer is already gone gets a 401 with error="invalid_client" instead of a 500.

  • simple_oauth_consumer_delete() calls the new TokenExpiryTriggerHandlerInterface::handleConsumerDelete(), which deletes the consumer's tokens. It passes $include_refresh = TRUE. That finds no refresh tokens until #3630881 stores the client on them.
  • TokenAuthUser::__construct() throws OAuthServerException::invalidClient() when $token->get('client')->entity doesn't load, instead of assigning NULL to the typed Consumer property.
  • SimpleOauthAuthenticationProvider::authenticate() catches OAuthServerException from the TokenAuthUser constructor and rethrows it as OAuthUnauthorizedHttpException, like the unpublished-consumer check added in #3436728.

Behavior change to review

The TokenAuthUser constructor already threw invalidClient() when a token had no user and its consumer had no default user. Nothing caught it, so that case returned a 500 as well. With the new catch, it returns a 401 like the deleted-consumer case.

API changes

New TokenExpiryTriggerHandlerInterface::handleConsumerDelete(). The interface allows new methods in minor releases.

Testing

  • TokenExpiryTriggerHandlerTest::testOnConsumerDelete(): deleting one consumer removes only its tokens.
  • ClientCredentialsTest::testBearerTokenDeniedForDeletedConsumer(): re-creates an orphaned token after the delete and asserts a 401 with error="invalid_client" from /oauth/debug?_format=json.

Without the fix, both tests fail. Without the TokenAuthUser change, the second test throws the TypeError from the issue.

AI-Generated: Yes. I wrote this fix and description with Claude Code and reviewed both.

Merge request reports

Loading
Loading