Skip to content

feat(webhook_listeners): make failed login events webhook compatible - #65930

Open
6801318d8d wants to merge 1 commit into
nextcloud:masterfrom
6801318d8d:feat/webhook-failed-login-events
Open

6801318d8d wants to merge 1 commit into
nextcloud:masterfrom
6801318d8d:feat/webhook-failed-login-events

Conversation

@6801318d8d

Copy link
Copy Markdown

Summary

webhook_listeners only accepts events that implement IWebhookCompatibleEvent. The two events that describe failed logins did not, so registering a webhook for them was rejected with "… is not an event class compatible with webhooks", and an admin could not be notified (ntfy, Gotify, a chat webhook…) when someone fails to log in.

This makes both events webhook compatible, the same way #60305 did for UserFirstTimeLoggedInEvent:

  • OCP\Authentication\Events\AnyLoginFailedEvent: the payload contains only the login name. The attempted password (getPassword()) is never serialized, and a unit test checks that.
  • OCP\Authentication\TwoFactorAuth\TwoFactorProviderChallengeFailed: the payload contains the user (uid, displayName, via JsonSerializer::serializeUser()) and the provider (id, displayName).

Webhook body for a failed login (the top-level user is null because there is no session):

{"event":{"loginName":"alice","class":"OCP\\Authentication\\Events\\AnyLoginFailedEvent"},"user":null,"time":1793024764}

Notes:

  • Failed logins can be triggered by unauthenticated clients. Brute-force protection throttles them, but every failure that matches a registered webhook queues a WebhookCall job. Nothing changes unless an admin registers a webhook for these events.
  • The remote address is not part of the event, so it is not in the payload.

How it was tested

  • New unit tests: tests/lib/Authentication/Events/AnyLoginFailedEventTest.php and tests/lib/Authentication/TwoFactorAuth/TwoFactorProviderChallengeFailedTest.php.
  • Existing tests that use these events or the webhook app pass: tests/lib/Authentication/TwoFactorAuth/ManagerTest.php, apps/admin_audit/tests/Listener/AuthEventListenerTest.php, apps/webhook_listeners/tests (PHP 8.5, SQLite).
  • End to end on a fresh instance of this branch (SQLite, PHP built-in server): POST /ocs/v2.php/apps/webhook_listeners/api/v1/webhooks accepted both events, then a failed WebDAV login (401) queued a WebhookCall job with the body above.
  • php-cs-fixer with the Nextcloud coding standard reports no changes.
  • Not done: psalm, and an end-to-end run of a failed second factor (only the unit test covers it).

TODO

  • Add the two events to the event list in the admin manual (admin_manual/webhook_listeners/index.rst in nextcloud/documentation)

Checklist

AI (if applicable)

  • The content of this PR was partly or fully generated using AI

AnyLoginFailedEvent and TwoFactorProviderChallengeFailed now implement
IWebhookCompatibleEvent, so admins can register webhooks that fire when
a login fails (wrong password or unknown login name, or a failed second
factor).

The AnyLoginFailedEvent payload only contains the login name: the
attempted password is never serialized. TwoFactorProviderChallengeFailed
sends the user and the provider id and display name.

Signed-off-by: 6801318d8d <144167388+6801318d8d@users.noreply.github.com>
Assisted-by: ClaudeCode:claude-opus-5-5
@6801318d8d
6801318d8d requested review from Altahrim, leftybournes, salmart-dev and sorbaugh and removed request for a team October 26, 2026 14:34

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make failed login events (AnyLoginFailedEvent, TwoFactorProviderChallengeFailed) available to webhook_listeners

1 participant