Simulators
User lifecycle and passwords
The user lifecycle is how an onboarding and offboarding flow moves a user between statuses, and how it changes the user’s password. Every transition happens in the request that asks for it. Create a staged user, activate it, suspend it, then deactivate and purge it:
curl -s -X POST "$RYSTIC_URL/_rystic/scenario" -d '{"name":"design_studio"}' -o /dev/null
u="$RYSTIC_URL/api/v1/users"
curl -s "$u?activate=false" -H 'Authorization: SSWS placeholder' -H 'Content-Type: application/json' -d '{"profile":{"firstName":"New","lastName":"Hire","email":"new.hire@wdcontractors.example","login":"new.hire@wdcontractors.example"}}' | jq -c '{id, status}'
# -> {"id":"00u00000000000000001","status":"STAGED"}
curl -s -X POST "$u/00u00000000000000001/lifecycle/activate?sendEmail=false" -H 'Authorization: SSWS placeholder' | jq -c '{activationToken}'
# -> {"activationToken":"actvTok0000000000001"}
curl -s -X POST "$u/00u00000000000000001/lifecycle/suspend" -H 'Authorization: SSWS placeholder' -o /dev/null -w '%{http_code}\n'
# -> 200
curl -s "$u/00u00000000000000001" -H 'Authorization: SSWS placeholder' | jq -c '{status}'
# -> {"status":"SUSPENDED"}
curl -s -X POST "$u/00u00000000000000001/lifecycle/deactivate" -H 'Authorization: SSWS placeholder' -o /dev/null -w '%{http_code}\n'
# -> 200
curl -s "$u?filter=status%20eq%20%22DEPROVISIONED%22" -H 'Authorization: SSWS placeholder' | jq -c 'length'
# -> 4
curl -s -X DELETE "$u/00u00000000000000001" -H 'Authorization: SSWS placeholder' -o /dev/null -w '%{http_code}\n'
# -> 204
curl -s "$u/00u00000000000000001" -H 'Authorization: SSWS placeholder' -o /dev/null -w '%{http_code}\n'
# -> 404
Statuses and routes
A user is STAGED when created with activate=false, and ACTIVE once created with the default activate=true or activated.
Differs from Okta: a user activated without a password lands ACTIVE at once, where Okta can leave it PROVISIONED until the user completes activation. Passwordless activation is not modeled.
These routes sit under /api/v1/users/{id}/lifecycle/:
activate,deactivate,suspend,unsuspendandreactivateexpire_passwordandexpire_password_with_temp_passwordreset_passwordandreset_factors
expire_password leaves the user PASSWORD_EXPIRED. What activate and reset_password return depends on sendEmail:
| Route | Without sendEmail | With sendEmail=false | With sendEmail=true |
|---|---|---|---|
activate | as true | an activationUrl | {} |
reset_password | as false | a resetPasswordUrl | {} |
Differs from Okta: Okta documents sendEmail as required on reset_password, while the simulator takes a missing one as false.
Differs from Okta: each URL is on the simulator’s own origin and serves nothing.
Differs from Okta: no email is sent, whatever sendEmail says.
Differs from Okta: nobody signs in, so lastLogin never moves and LOCKED_OUT is reachable only from a seed.
Deactivating and purging
A first DELETE on a user deactivates it (DEPROVISIONED) and a second purges it, so the read in the example returns 404. A plain user list leaves DEPROVISIONED users out, while search and filter include them.
Deactivating or purging a user removes its application assignments, direct and group-derived. Activating the user again restores the group-derived ones only (Bookmark applications).
Adding a deactivated user to a group returns 403 E0000038. So does a POST or PUT that edits a deactivated user’s profile. That is the policy of the Okta org the simulator was measured against.
Passwords
POST /api/v1/users/{userId}/credentials/change_password takes oldPassword and newPassword and returns the user’s credentials.
Differs from Okta: the simulator has no password policy, so it accepts any password.