Skip to content

Add coverage for the authentication system - #1583

Open
wpjscc wants to merge 1 commit into
wintercms:developfrom
wpjscc:tests/271-authentication-coverage
Open

wpjscc wants to merge 1 commit into
wintercms:developfrom
wpjscc:tests/271-authentication-coverage

Conversation

@wpjscc

@wpjscc wpjscc commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds test coverage for the authentication system, as listed in #271. The tests exercise the real backend stack (BackendAuth, Backend\Models\User, Backend\Models\UserThrottle) through PluginTestCase, so they run against the migrated schema and the actual manager configuration.

17 tests, 61 assertions

Coverage

Area Tests
Login valid credentials log the user in, persist the session and stamp last_login; wrong passwords and unknown logins are rejected
Throttling failed attempts are recorded; the account is suspended after auth.throttle.attemptLimit attempts; a suspended account is rejected even with valid credentials; a successful login clears the attempts
Banning a banned account cannot authenticate
Logout the auth session is cleared, the user is forgotten and the session id is regenerated
Deleted accounts soft deleted users cannot authenticate
Activation enforced when the manager requires it (StrictActivationAuthManager fixture); the backend manager's own policy ($requireActivation = false, so administrators can log in while inactive) is pinned down
Impersonation switches the session user, filters the impersonatee's permissions down to what the impersonator also holds, restores the impersonator on stopImpersonate(), and refuses super users / impersonators without backend.impersonate_users
Permissions role permissions are inherited, individual permissions are merged, wildcard permissions match as documented, super users bypass checks
Registration creates an activated user and logs them in

Two things I found while writing these

  1. Winter\Storm\Auth\Manager::guest() is hard-coded to return false; (a StatefulGuard method that never reports a guest). The tests therefore assert "not logged in" through check(). Not changing it here, but it looks unintended.
  2. impersonate() re-loads the impersonator from the session (getPersistCodeFromSession() → findUserById()), so the $impersonator === $this guard in Backend\Models\User::canBeImpersonated() can never match in the session flow — self-impersonation is therefore not blocked by that check. I dropped the test for it rather than assert the current behaviour; worth a separate issue/PR if you agree it should be blocked.

Out of scope

  • Frontend/public user registration doesn't exist in the core modules, so registration is covered through the manager's register().
  • Group permissions are not part of getMergedPermissions() in the Storm base model (only role + individual permissions), so inheritance is covered for roles.

Verification

  • php vendor/bin/phpunit modules/backend/tests/models/UserAuthenticationTest.php — 17 tests, 61 assertions, green.
  • Full suite: Tests: 1124, Assertions: 3749, Skipped: 29 — green (previous baseline 1107 tests).
  • phpcs on the new file: clean.

Refs #271

Summary by CodeRabbit

  • Tests
    • Expanded automated coverage for backend authentication scenarios, including successful and failed sign-ins, throttling, bans, logout, activation requirements, and deleted accounts.
    • Added checks for impersonation and permission filtering, role inheritance, superuser access, and user registration.
    • These changes improve confidence in existing authentication behavior; no end-user functionality changes are included.

Covers the areas listed in wintercms#271 against the real backend stack (BackendAuth,
Backend\Models\User, UserThrottle):

- login with valid credentials, and rejection of a wrong password / unknown login
- failed attempts are recorded, and the account is suspended once the configured
  attempt limit is reached; a suspended account is rejected even with valid
  credentials
- a successful login clears the recorded attempts
- banned and soft deleted accounts cannot authenticate
- logout clears the auth session and regenerates the session id
- activation is enforced when the manager requires it, and the backend manager's
  own policy (activation not required) is pinned down
- impersonation switches the session user, filters the impersonatee's permissions
  to those the impersonator also holds, and restores the impersonator afterwards;
  super users and users without `backend.impersonate_users` cannot be impersonated
- role permissions are inherited and wildcard permissions match as documented,
  and super users bypass permission checks
- registration creates an activated user and logs them in

Two behaviours worth noting, both documented in the tests themselves:

- `Manager::guest()` is hard-coded to return false, so "not logged in" is asserted
  through `check()`.
- `impersonate()` re-loads the impersonator from the session, so the
  `$impersonator === $this` self-impersonation guard in `canBeImpersonated()`
  cannot match in the session flow. Not covered here; worth a separate look.

Refs wintercms#271
@coderabbitai

coderabbitai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f2a3fef5-848c-423a-8907-f2090fd74a80
Commits

Reviewing files that changed from the base of the PR and between 50e207c and fba0635.

Files selected for processing: 1
  • modules/backend/tests/models/UserAuthenticationTest.php

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

Walkthrough

Adds a backend authentication test suite. It covers login success and failure, throttling, bans, logout, account activation and deletion, impersonation, permissions, and registration. It also adds a strict-activation auth manager for testing activation-required login behavior.

Priority: Low

Estimated code review effort: 2 (Simple) | ~12 minutes

Merge Risk: Minimal · up to fba06

The change adds authentication tests without altering production behavior; no merge-blocking regression was identified.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 38.89% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surv… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title "Add coverage for the authentication system" matches the main change. The PR adds UserAuthenticationTest, a PluginTestCase suite that covers login, throttling, banning, logout, activation, i…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title "Add coverage for the authentication system" matches the main change. The PR adds UserAuthenticationTest, a PluginTestCase suite that covers login, throttling, banning, logout, activation, impersonation, permissions, and registration. The title is somewhat broad, since it does not name the backend or the test file, but it names the real primary change and is not vague or misleading.

Full details: Docstring Coverage

Explanation

Docstring coverage is 38.89% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 18 functions across 1 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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.

1 participant