Skip to content

Feature | UserController MFA Integration, Device Trust Cookie Management, Audit Wiring, and 2FA Rate Limiting#136

Open
matiasperrone-exo wants to merge 1 commit into
feat/mfa-gateservice--two-factor-gate-decision-service---cu-86ba2zfj8from
feat/mfa---usercontroller-mfa-integration-device-trust-cookie-management-audit-wiring-and-2fa-rate-limiting---cu-86ba2zc6p
Open

Feature | UserController MFA Integration, Device Trust Cookie Management, Audit Wiring, and 2FA Rate Limiting#136
matiasperrone-exo wants to merge 1 commit into
feat/mfa-gateservice--two-factor-gate-decision-service---cu-86ba2zfj8from
feat/mfa---usercontroller-mfa-integration-device-trust-cookie-management-audit-wiring-and-2fa-rate-limiting---cu-86ba2zc6p

Conversation

@matiasperrone-exo
Copy link
Copy Markdown
Contributor

Task:

Ref: https://app.clickup.com/t/9014802374/86ba2zc6p

What Changed

UserController (app/Http/Controllers/UserController.php)

  • Injected IDeviceTrustService, ITwoFactorAuditService, and ITwoFactorGateService via constructor.
  • Password flow now validates credentials without creating a session first. If MFAGateService::requiresChallenge() returns true, issues a challenge (via
    AuthService::issueMFAChallenge) and returns { error_code: "mfa_required", ... } — no session created yet.
  • Added resolveClientFromMemento() private helper to extract the OAuth2 client from a pending session memento (deduplicates logic previously repeated in password and OTP flows).
  • Added postVerify2FA(), postResend2FA(), and postRecovery2FA() action methods to handle the full MFA step-up login lifecycle.
  • Applied MFACookieManager trait for reading/writing the trusted-device cookie.

MFACookieManager trait (app/Http/Controllers/Traits/MFACookieManager.php) — new file

  • Provides getCookieToken(): ?string (reads raw token from cookie).
  • Provides queueDeviceTrustCookie(User $user): void (calls IDeviceTrustService::trustDevice and queues a secure, HttpOnly cookie).
  • Contains no Doctrine/repository logic — cookie transport only.

TwoFactorRateLimitMiddleware (app/Http/Middleware/TwoFactorRateLimitMiddleware.php) — new file

  • Throttles verify, recovery, and resend MFA endpoints.
  • Counters stored in cache (not session) with a fixed-window TTL.
  • verify / recovery: increments only on failed response (mfa_verification_failed, mfa_invalid_recovery).
  • resend: increments on every request.
  • Returns HTTP 429 with error_code: mfa_rate_limit when the limit is exceeded.
  • Registered in app/Http/Kernel.php and wired to the new routes in routes/web.php.

AuthService (app/libs/Auth/AuthService.php) and IAuthService (app/libs/Utils/Services/IAuthService.php)

  • Added validateCredentials(string $username, string $password): User — validates without creating a session.
  • Added loginUser(User $user, bool $remember): void — establishes the session for an already-validated user.
  • Added issueMFAChallenge(User $user, MFAChallengeStrategy $strategy, ?Client $client, bool $remember): array — triggers the challenge strategy and stores pending state.

DeviceTrustService and TwoFactorAuditService (minor fixes)

  • Resolved wiring/dependency issues surfaced during integration testing.

config/two_factor.phpnew file

  • Centralizes MFA configuration: cookie_name, device_trust_lifetime_days, rate-limit thresholds per action.

EncryptCookies middleware

  • Excluded the device_trust_token cookie from encryption (raw HMAC token must be read as-is by IDeviceTrustService).

Tests

File What it covers
tests/TwoFactorLoginFlowTest.php (new) End-to-end: password→MFA challenge→verify→session; device trust skip; rate limiting; recovery codes; resend.
tests/DeviceTrustServiceTest.php Expanded with cookie integration assertions.
tests/Unit/TwoFactorAuditServiceTest.php Expanded with new event types.
tests/Unit/MFA/EmailOTPMFAChallengeStrategyTest.php Added cases for issueMFAChallenge path.
phpunit.xml Registered Two Factor Authentication Test Suite.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 3, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3ed1b55c-1fe8-4142-ac21-7956aa3431e0

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/mfa---usercontroller-mfa-integration-device-trust-cookie-management-audit-wiring-and-2fa-rate-limiting---cu-86ba2zc6p

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 and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 3, 2026

📘 OpenAPI / Swagger preview

➡️ https://OpenStackweb.github.io/openstackid/openapi/pr-136/

This page is automatically updated on each push to this PR.

@matiasperrone-exo matiasperrone-exo force-pushed the feat/mfa---usercontroller-mfa-integration-device-trust-cookie-management-audit-wiring-and-2fa-rate-limiting---cu-86ba2zc6p branch from 77c0c4f to 0fb9adf Compare June 3, 2026 20:07
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 3, 2026

📘 OpenAPI / Swagger preview

➡️ https://OpenStackweb.github.io/openstackid/openapi/pr-136/

This page is automatically updated on each push to this PR.

@matiasperrone-exo matiasperrone-exo force-pushed the feat/mfa---usercontroller-mfa-integration-device-trust-cookie-management-audit-wiring-and-2fa-rate-limiting---cu-86ba2zc6p branch from 0fb9adf to 84252f7 Compare June 3, 2026 20:29
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 3, 2026

📘 OpenAPI / Swagger preview

➡️ https://OpenStackweb.github.io/openstackid/openapi/pr-136/

This page is automatically updated on each push to this PR.

@matiasperrone-exo matiasperrone-exo force-pushed the feat/mfa---usercontroller-mfa-integration-device-trust-cookie-management-audit-wiring-and-2fa-rate-limiting---cu-86ba2zc6p branch from 84252f7 to 56e1468 Compare June 3, 2026 20:32
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 3, 2026

📘 OpenAPI / Swagger preview

➡️ https://OpenStackweb.github.io/openstackid/openapi/pr-136/

This page is automatically updated on each push to this PR.

$oauth_auth_request = OAuth2AuthorizationRequestFactory::getInstance()->build
(
OAuth2Message::buildFromMemento($this->oauth2_memento_service->load())
if ($flow == "password") {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@matiasperrone-exo please move flow to constants on
IAuthService::AuthenticationFlowPassword
and
IAuthService::AuthenticationFlowOTP

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.

3 participants