Skip to content

Leavers Could Still Sign In

Ed Mozley edited this page Oct 11, 2026 · 1 revision

Leavers could still sign in

Fixed in 3.5.0. Found while reviewing PR #174 (analyst provisioning), not reported by anyone.

What you saw (or, more likely, didn't)

  • A requester marked as left could still use the portal. Mark as left on Assets β†’ Users (or Tickets β†’ Users) took them off the current list, and the password reset refused them. But the portal sign-in never checked, so they could still sign in with their password or through single sign-on. Anyone already signed in carried on.
  • A deactivated analyst carried on working until they signed out. Deactivating stopped new sign-ins. An analyst already signed in kept every module, and an administrator kept System, until their session ended.

Nothing told you either was happening. Both came to light because the new REST API lets an identity source deactivate people. That only means something if deactivating takes effect at once.

What was wrong

Requesters: users.is_active is what Mark as left sets, but only the password-reset path read it. The four ways into the portal never did:

  • the password form;
  • the two-factor code step;
  • SSO;
  • the session already open.

Analysts: every module page and endpoint already asks the database whether the analyst has the module, and every System endpoint asks whether they're an administrator. Neither question looked at is_active. The System screens themselves went by a flag stored in the session at sign-in.

The fix

Requesters requesterIsActive() (in includes/functions.php) is checked on every way in: the password form (after the password, so a guesser learns nothing), the two-factor code step, and SSO. It's also checked on every signed-in portal page (self-service/includes/auth.php), which signs a leaver out on their next click, with "Your account is no longer active" on the sign-in page.
Analysts An inactive analyst now has no modules (getAnalystAllowedModules()) and is not an administrator (analystIsAdmin()). Those are the questions every module page, module endpoint and System endpoint already asks, so the next click is refused. The System page gate now asks the database too, instead of the session flag.
REST API PATCH /api/v1/users/{id} takes is_active (false = marked as left), and requesters read back with is_active. Analysts are covered by PATCH /api/v1/analysts/{id} - see REST API: Analysts.

πŸ“ Files: includes/functions.php Β· self-service/includes/auth.php Β· api/self-service/login.php Β· api/self-service/verify_login_otp.php Β· api/auth/oidc_callback.php Β· system/includes/page_gate.php Β· api/v1/resources/users.php

How it was proved

All of this ran over HTTP against a live install, with a temporary requester and a temporary analyst that were deleted afterwards. Each refusal had a control showing the same step works for an active account.

  • A requester signs in and opens a portal page (control). They're marked as left, and their next page sends them to sign in with the reason shown. Signing in again is refused. A wrong password still says only invalid.
  • An administrator opens Tickets and System (control). They're deactivated, and on their next click Tickets turns them away, a Tickets endpoint answers 403, and System is closed.
  • The REST API shows is_active: false, reactivates them with true, and rejects a value that isn't true or false.

What this means for you

Nothing to do. Mark as left and Deactivate now take effect on the person's next click. If you have relied on a leaver still being able to sign in to see an old ticket, reactivate them.

Related: REST API: Analysts Β· Bugs resolved

FreeITSM

Getting Started

Modules

Multi-tenancy (planned)

Blue sky thinking

Bugs resolved

Links

Clone this wiki locally