Skip to content
Aabha AI Academy

Stage 6 · L28

Reload the current actor and reject inactive identity

Core · original Session 6

Native checkpoint 06

Download starter · Download solution

Use the starter for this stage's focused examples. The cumulative transfer and solution belong at the stage-end capstone. Baseline checks pass; transfer checks initially fail. Downloads contain the matching native starter and solution for this stage.

current_actor resolves a verified access token into current stored identity. It opens its own session, reads the UUID subject, rejects missing/inactive/version-changed users and returns a frozen Actor containing only id, email and current role. The session closes before that value reaches another service or an async provider call.

Current state matters after issuance. The baseline deactivates an account in a separate transaction while keeping the same token, then verifies that /auth/me returns401. Stage07 changes a stored role and confirms the same token loses write permission. A role copied into a long-lived JWT would otherwise continue granting stale authority.

Rental creation now receives equipment_id and quantity only. The router inserts actor.id into the internal RentalIn. A caller-supplied owner_id is an extra field and rejected. This removes a client-controlled owner boundary; the authenticated actor is still not sufficient for reading or changing every existing rental, which stage07 scopes.

/auth/me exposes id/email/role, never password hash, credential version, action tokens or private mailbox data. User is an ORM row with persistence responsibilities; Actor is a plain trusted identity value. Passing a session-bound User object across a background or await boundary can trigger accidental lazy I/O and muddle ownership.

Tests must patch the session factory where current_actor uses it: equipment.api.SessionLocal, imported inside the function. Patching a similarly named symbol in an unused module gives false confidence. The provider-stage fixture observes this actual factory and proves both authentication and preparation sessions close before outbound HTTP begins.

The stage-end reset capstone combines already-taught trust and transaction boundaries: validate the reset-purpose token, lock its current user row, require the expected stored credential version, replace the password hash and advance that version in one transaction. A used reset token and earlier access token then have stale versions. Complete reset_password before running its reset walkthrough; an untouched starter deliberately returns501 exercise_pending. The focused actor walkthrough above works before this implementation.

Valid signature and access purpose; Stored user still exists and active; Credential version still matches; Read current role from PostgreSQL; Close session before returning Actor
Valid signature and access purpose; Stored user still exists and active; Credential version still matches; Read current role from PostgreSQL; Close session before returning Actor

Follow the running code

Focused lesson example; see the end-of-stage capstone for the cumulative app · stage 06

python run_checks.py --stage 06 --role starter --walkthrough actor
# Fresh synthetic registration/verification/login.
# GET /auth/me → 200; disable that local user → 401; restore → 200.

Predict and observe this focused example using the concepts explained above. Its boundary is stated in the focused answer.

Guided lab

  1. Read the current-account explanation and predict how a signed token relates to stored active/version state.
  2. Run --until actor before implementing reset. Predict the current-user response while the just-created synthetic account is active, temporarily disabled, and active again.
  3. Compare200/401/200 with the focused answer; leave reset to the capstone.

From the extracted stage starter root, after completing its README setup:

python run_checks.py --stage 06 --role starter --walkthrough actor

Expected: A correctly signed access token returns the current account only while its stored active/version checks pass. The owned walkthrough temporarily disables only its newly created synthetic user, observes401, restores active state and observes200 again. No reset implementation is required for this focused actor exercise. Implement and test credential reset separately in the stage capstone.

  • A correctly signed token can become stale after the account is disabled or its credential version changes.

Focused exercise and answer

Complete this focused exercise before reading its answer. The full native transfer is introduced only at the end of the stage.

Your transfer task: Run --until actor before implementing reset. Predict the current-user response while the just-created synthetic account is active, temporarily disabled, and active again.

  1. Run --until actor before implementing reset. Predict the current-user response while the just-created synthetic account is active, temporarily disabled, and active again.
Inspect the matching answer

This answer addresses the focused exercise above; the cumulative implementation is shown only after the stage prerequisites.

A correctly signed access token returns the current account only while its stored active/version checks pass. The owned walkthrough temporarily disables only its newly created synthetic user, observes401, restores active state and observes200 again. No reset implementation is required for this focused actor exercise. Implement and test credential reset separately in the stage capstone.

Stage 06 capstone — after these prerequisites

Implement one-use credential reset: trusted purpose, locked current version, new hash/version and old-token/replay rejection.

Use the downloaded starter after completing this stage's focused exercises. The cumulative implementation below is a stage transfer answer, not an answer to an earlier lesson.

python run_checks.py --stage 06 --role starter --prepare
python run_checks.py --stage 06 --role starter
python run_checks.py --stage 06 --role starter --transfer

From this extracted starter: preparation and baseline pass; transfer initially fails only at the named unfinished target. After implementing it, rerun the same starter --transfer command and expect success.

After implementing this capstone

After implementing reset_password in this starter, run the reset walkthrough below. Before implementation it deliberately returns501 exercise_pending and the walkthrough fails; this is not the focused actor exercise.

python run_checks.py --stage 06 --role starter --walkthrough reset
Optional comparison in a separate solution directory

Optional comparison: download and extract this stage’s solution ZIP into a separate directory. Change your terminal into that extracted solution root (beside checkpoint.json and run_checks.py) before running the following commands. Your starter remains a starter even after you implement its task.

python run_checks.py --stage 06 --role solution --transfer
python run_checks.py --stage 06 --role solution --walkthrough reset
Inspect the cumulative capstone implementation
def reset_password(session, payload):
    claims = action_claims(payload.token.get_secret_value(), "reset")
    with session.begin():
        user = session.scalar(select(User).where(User.id == UUID(claims["sub"])).with_for_update())
        if user is None or not user.active or user.credential_version != claims["cv"]:
            raise DomainError(400, "invalid_action_token", "Action token is invalid or expired")
        user.password_hash = PASSWORDS.hash(payload.new_password.get_secret_value())
        user.credential_version += 1
    return {"reset": True}

Check your reasoning

Can a signed access token prove the account is still active?

Show the explanation

No. Reload the current stored account and credential version; reject disabled, missing or version-stale identity before returning an Actor.

Reading progress

54 lessons remain open to guests. Marking a lesson read records reading only; it does not award assessment credit or a certificate.

Device reading marks require browser storage. Reading is always available.

Sign in or create an account to save separate account progress. Your current page is kept.