Skip to content

Add endpoint to reset the per-SP WAYF remember-choice cookie - #2094

Open
kayjoosten wants to merge 4 commits into
mainfrom
wayf-reset-endpoint
Open

kayjoosten wants to merge 4 commits into
mainfrom
wayf-reset-endpoint

Conversation

@kayjoosten

Copy link
Copy Markdown
Contributor

What

Implements #2085, adding GET /reset-remember-wayf: a public endpoint that
clears the per-SP rememberedidps cookie (introduced in #2065 / #2091) and
redirects the user to an operator-configured URL.

Stacked on #2091

This branches from wayf-remember-choice-core (#2091, not yet merged),
since it depends directly on the RememberedIdpCookie service introduced
there. The diff shown here is the incremental change for #2085 only; once
#2091 merges to main, this PR's base should be retargeted to main.

Details

  • New ResetRememberedWayfController reuses the existing
    RememberedIdpCookie service: normalize() computes the valid entry
    count for logging, clear() removes the cookie using the same
    SameSite/secure flags it was written with. Both only run when the
    cookie is actually present — a visitor with no cookie is redirected
    without any log noise.
  • Logs 'WAYF-remember-my-choice cookie removed (had %d entries)' at
    INFO level, matching the sibling log message conventions from Remember choice for WAYF per SP #2065.
  • The controller validates its configured redirect URL at construction
    time and throws if it's blank, so a missing
    wayf.reset_choice_per_idp_redirect fails fast instead of silently
    redirecting nowhere.
  • New config wayf.reset_choice_per_idp_redirect defaults to a working
    dev URL in parameters.yml.dist (matching the convention of other
    wayf.* dev defaults), so the endpoint works out of the box in
    dev/CI while still requiring operators to set a real destination in
    production.
  • The functional test asserts the redirect target against the
    configured parameter rather than merely checking for a non-empty
    Location header — this app has a global exception listener that
    also turns uncaught exceptions into a 302, which would otherwise let
    a misconfiguration pass unnoticed. (Verified locally: temporarily
    blanking the config reproduces exactly this failure mode, and the
    strengthened assertion catches it.)

Testing

All run inside the Docker dev container (PHP 8.5):

  • phpmd / phpcs / phpcs-legacy / docheader: clean.
  • eb4: 244/244. unit: 1003/1003 (999 baseline + 4 new). functional
    (APP_ENV=test): 121/121 (119 baseline + 2 new). integration:
    105/105.
  • Behat default suite: 300/300 scenarios, 5557/5557 steps.
  • Twig lint: 114/114. yarn lint: clean.

Refs: #2085

#[Test]
public function cookie_with_valid_entries_is_cleared_and_logged_with_entry_count(): void
{
$cookieService = Phake::mock(CookieService::class);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Phake is deprecated in this project

@kayjoosten
kayjoosten force-pushed the wayf-remember-choice-core branch from 9e96c15 to 31c4f4f Compare October 12, 2026 12:31
Base automatically changed from wayf-remember-choice-core to main October 12, 2026 12:59
Introduce GET /reset-remember-wayf, a public endpoint that lets a user
forget their remembered per-SP IdP choices set up in #2065. Visiting
the page clears the 'rememberedidps' cookie (if present) and redirects
to an operator-configured URL.

- ResetRememberedWayfController reuses the existing RememberedIdpCookie
  service rather than hand-rolling cookie-clearing logic: normalize()
  computes the valid entry count for logging, clear() removes the
  cookie with the same SameSite/secure flags used when it was written.
  Both only run when the cookie is actually present, so a first-time
  visitor with no cookie is redirected without any log noise.
- The controller validates its configured redirect URL at construction
  time and refuses to serve requests when it is blank, so a missing
  wayf.reset_choice_per_idp_redirect parameter fails fast instead of
  silently sending users nowhere.
- New config wayf.reset_choice_per_idp_redirect defaults to a working
  dev URL (matching the convention of other wayf.* dev defaults in
  parameters.yml.dist) so the endpoint works out of the box in
  dev/CI, while still requiring operators to set a real destination in
  production.
- The functional test asserts the redirect target against the
  configured parameter rather than merely checking for a Location
  header: the app's global exception listener also turns uncaught
  exceptions into a 302, which would otherwise let a broken
  configuration pass unnoticed.

Refs: #2085
# Why is this change needed?
Prior to this change, /reset-remember-wayf and the
wayf.reset_choice_per_idp_redirect parameter were only described in the
comments of parameters.yml.dist. This is an open source project, so operators
and integrators need to find the endpoint in the docs and the release notes.

# How does it address the issue?
This change adds a section to docs/wayf_remember_choice.md and an entry to the
CHANGELOG.
# If applied, this commit will...
Convert the remaining Phake-based mocking in ResetRememberedWayfControllerTest
to Mockery, matching the rest of the test suite.

# Why is this change needed?
Prior to this change, the test mixed Phake (for CookieService) with Mockery
(for LoggerInterface) in the same class. Phake is deprecated in this codebase
and only used in a handful of legacy test files, and mixing mocking libraries
in one test class adds unnecessary cognitive overhead.

# How does it address the issue?
This change replaces Phake::mock()/when()/verify() calls with declarative
Mockery::mock()->shouldReceive()->with()->andReturn() expectations set up
before the action under test runs. The "no interaction expected" case relies
on Mockery's default strict behaviour, which throws automatically on any
unstubbed method call, so no explicit verification call is needed.

# Provide links to any relevant tickets, articles or other resources
Addresses review comment on PR #2094.
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.

2 participants