Skip to content

ATS-PFM-SEC-009Maintain console memberships: Capability Test Specification

Markdown

ATS-PFM-SEC-009

Maintain console memberships: Capability Test Specification

Markdown
  • DocumentProposed

KindAcceptance test setProduct areaPlatformModuleSecurity, Customers and WorkspacesRevision2

Read atservices-platform ad3f6a65react-console baf6dae3

Coverage

  • Rule gap: FND-PFM-SEC-066
  • Transition covered
  • Validation covered
  • Permission gap: FND-PFM-SEC-066
  • Edge gap: FND-PFM-SEC-066
  • Failure covered
  • Boundary covered
  • Concurrency covered
  • Invariant covered
  • Interaction covered

Test Scenarios

20 scenarios proving CAP-PFM-SEC-009; 11 bound to an existing test.

01 Check customer user-list scope and paginationboundaryapinegativetest
Proves
BR-CAP-PFM-SEC-009-01
Preconditions
Prepare console users with varied statuses and roles.
Steps
Page by surname, filter status, request another customer and call using platform staff authority alone.
Expected
Pagination and filters select the expected memberships; outside-customer access returns 404 and unrelated staff authority is refused.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#answers a page of the customer’s console users, by surname
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#walks the page with the cursor it answered, and stops answering one at the end
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#narrows to a status, and leaves the others out
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#answers 404 for a customer the caller does not reach, saying nothing about whether it exists
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#refuses a platform-scope caller the users of a customer they are not of, because this route is console
Source
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#answers a page of the customer’s console users, by surname
02 Check the allowed profile fields and versionconcurrencyapinegativetest
Proves
BR-CAP-PFM-SEC-009-03
Preconditions
Read a membership at version n.
Steps
Change names at n, repeat with a stale version, submit a disallowed field and call as a reader.
Expected
The valid change advances version; stale, malformed and unauthorized attempts return 409, 400 and 403 respectively.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#changes the names and answers the person again, at the next version
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#refuses a version the record has moved past as 409, and changes nothing
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#refuses a body that states anything but the five detail fields as 400
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#refuses the caller who may only read as 403, before the handler runs
Source
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#changes the names and answers the person again, at the next version
03 Check suspension and self-protectiontransitionapinegativetest
Proves
BR-CAP-PFM-SEC-009-04
Preconditions
Prepare an active member and the administrator’s own identity.
Steps
Suspend the member, inspect the lifecycle result and try self-suspension.
Expected
Outstanding invitations are withdrawn, successful pool disablement is reported and a flush job is submitted; self-suspension fails. Job submission does not establish cache eviction.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#suspends an account, revoking its invitation with it, disabling its pool account and flushing the caches
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses an administrator who tries to suspend or revoke their own account
services-platform:modules/security/tests/unit/services/invitations/suspend-revoke.spec.js#refuses a caller suspending their own account, writing nothing
react-console:e2e/security/users.spec.ts#deactivating really shuts somebody out, and reactivating lets them back in
Source
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#suspends an account, revoking its invitation with it, disabling its pool account and flushing the caches
04 Check reinstatement lifecycle restrictionstransitionunitnegativetest
Proves
BR-CAP-PFM-SEC-009-05
Preconditions
Prepare suspended and revoked memberships.
Steps
Attempt reinstatement for each.
Expected
The suspended membership becomes active and pool enablement is attempted; the revoked membership must return through invitation and is refused.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/unit/services/invitations/suspend-revoke.spec.js#re-enables the pool account and makes the membership active again
services-platform:modules/security/tests/unit/services/invitations/suspend-revoke.spec.js#refuses an account that is not suspended (a revoked one comes back as a fresh invitation)
Source
services-platform:modules/security/tests/unit/services/invitations/suspend-revoke.spec.js#re-enables the pool account and makes the membership active again
05 Check membership revocation cascadestransitionapinegativetest
Proves
BR-CAP-PFM-SEC-009-06
Preconditions
Prepare a member holding assignments.
Steps
Revoke the membership.
Expected
Membership, invitations and assignments end; reinstatement cannot undo revocation, while reinvitation remains the return path.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#revokes a membership with every assignment it held, and nothing undoes it
services-platform:modules/security/tests/unit/services/invitations/suspend-revoke.spec.js#ends the membership, its invitations and every assignment it held in one transaction
Source
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#revokes a membership with every assignment it held, and nothing undoes it
06 Check rollback when the last administrator would be lostinvariantapinegativetest
Proves
BR-CAP-PFM-SEC-009-07 INV-DOM-PFM-SEC-003-12
Preconditions
Prepare a customer with one qualifying administrator.
Steps
Try suspension, revocation, role withdrawal and deletion of that administrator.
Expected
Each guarded reduction returns the last-administrator refusal, rolls back and records the refused attempt.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/unit/services/invitations/suspend-revoke.spec.js#refuses a suspension that would leave the customer with no security administrator, and suspends nobody
services-platform:modules/security/tests/integration/services/membership/manage-assignments.integration.spec.js#refuses the withdrawal that would leave the customer with no security administrator, and withdraws nothing
react-console:e2e/security/users.spec.ts#refuses to remove the Administrator role from the last person who holds it
Source
services-platform:modules/security/tests/unit/services/invitations/suspend-revoke.spec.js#refuses a suspension that would leave the customer with no security administrator, and suspends nobody
07 Check deletion attribution and dependency refusalsinvariantapinegativetest
Proves
BR-CAP-PFM-SEC-009-08 INV-DOM-PFM-SEC-003-21
Preconditions
Prepare unreferenced and referenced members, the caller and Rhythm’s last Administrator.
Steps
Attempt deletion for each.
Expected
The safe deletion retains attribution and audit history; dependent, self and last-staff-administrator cases fail.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/users.e2e.spec.js#keeps the name behind the id, so every record the person touched can still say who it was
services-platform:modules/security/tests/e2e/users.e2e.spec.js#answers 409 and user_undeletable for somebody other records still point at
services-platform:modules/security/tests/e2e/users.e2e.spec.js#refuses an administrator deleting their own account, and says so rather than hiding it
services-platform:modules/security/tests/e2e/users.e2e.spec.js#answers 409 for Rhythm’s last Rhythm Administrator, and deletes nobody
Source
services-platform:modules/security/tests/e2e/users.e2e.spec.js#keeps the name behind the id, so every record the person touched can still say who it was
08 Check retried pool-account removalfailureapitest
Proves
BR-CAP-PFM-SEC-009-09
Preconditions
Prepare a deleted membership whose pool operation fails once.
Steps
Dispatch removal work and deliver the queue item twice.
Expected
Failure remains retryable with the pool account present; subsequent success removes it and records completion.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/integration/services/dispatch/pool-account-removals.integration.spec.js#leaves the account in the pool when the call failed: nothing pretends it went
services-platform:modules/security/tests/integration/services/dispatch/pool-account-removals.integration.spec.js#removes the account on the second delivery, and tells SQS the item is done
services-platform:modules/security/tests/integration/services/dispatch/pool-account-removals.integration.spec.js#records the removal on the security trail, which is what lasts once the queue row is gone
Source
services-platform:modules/security/tests/integration/services/dispatch/pool-account-removals.integration.spec.js#queues the removal of the login the delete read before the row went
09 Check identity separation and immutable ownershipinvariantapinegativetest
Proves
BR-CAP-PFM-SEC-009-10 INV-DOM-PFM-SEC-003-01
Preconditions
Prepare a customer and workspace.
Steps
Create console and portal memberships sharing an address, duplicate within a boundary, edit lifecycle and attempt a cross-customer move.
Expected
Cross-boundary identities remain distinct, same-boundary duplication fails, lifecycle edits have no effect and moving ownership fails.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/users.e2e.spec.js#creates a portal user of one of the customer’s tenants, and the same e-mail in another wall is a different user
services-platform:modules/security/tests/e2e/users.e2e.spec.js#refuses a duplicate e-mail in the same wall (400) and a wall the access type does not allow (400)
services-platform:modules/security/tests/e2e/users.e2e.spec.js#replaces and patches a user in scope; the lifecycle is untouchable by the generic update and a move out of the customer is refused
Source
services-platform:modules/security/tests/e2e/users.e2e.spec.js#creates a portal user of one of the customer’s tenants, and the same e-mail in another wall is a different user
10 Check canonical linking against verified pool factsvalidationunitnegativetest
Proves
BR-CAP-PFM-SEC-009-11 INV-DOM-PFM-SEC-003-05
Preconditions
Prepare enabled pool accounts with matching and mismatched verified addresses.
Steps
Attempt linking both.
Expected
The matching account and supported federated identities link; the mismatch fails.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/unit/services/identity/link-cognito-identity.spec.js#never links on the request's say-so: the pool user must exist, be enabled, and carry the user's verified e-mail
services-platform:modules/security/tests/e2e/users.e2e.spec.js#links the Cognito account from the pool of the user's own wall, records its federated identities, and refuses a mismatch
Source
services-platform:modules/security/tests/unit/services/identity/link-cognito-identity.spec.js#never links on the request's say-so: the pool user must exist, be enabled, and carry the user's verified e-mail
11 Check console edits and lifecycle actionsinteractionbrowsertest
Proves
AS-JNY-PFM-SEC-003-03
Preconditions
Prepare a security administrator and colleague.
Steps
Save profile changes, reload, deactivate and reactivate.
Expected
The saved profile persists across reload and the tested membership checks follow suspension and reinstatement.
Data
Use the records described in the setup.
Bound to
react-console:e2e/security/users.spec.ts#edits a person's details and keeps them through a reload
react-console:e2e/security/users.spec.ts#deactivating really shuts somebody out, and reactivating lets them back in
Source
react-console:e2e/security/users.spec.ts#edits a person's details and keeps them through a reload
12 Membership status: active to suspendedtransitionapiproposed
Proves
BR-CAP-PFM-SEC-009-04
Preconditions
Use an isolated membership status in active state, with the required authority and guard fixtures.
Steps
[ { "do": "Suspend the active member and inspect post-commit provider synchronization separately.", "expect": "Read the resulting membership status as suspended; inspect the associated records and recorded history for this transition.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/invitations/suspend-user.ts", "services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts, activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts; services/membership/lockout.ts, last-administrator.ts." ] } ]
Expected
Read the resulting membership status as suspended; inspect the associated records and recorded history for this transition.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/invitations/suspend-user.ts,services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts, activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts; services/membership/lockout.ts, last-administrator.ts.
13 Membership status: suspended to activetransitionapiproposed
Proves
BR-CAP-PFM-SEC-009-05
Preconditions
Use an isolated membership status in suspended state, with the required authority and guard fixtures.
Steps
[ { "do": "Reinstate the suspended member with authority covering all retained assignments.", "expect": "Read the resulting membership status as active; inspect the associated records and recorded history for this transition.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/invitations/suspend-user.ts", "services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts, activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts; services/membership/lockout.ts, last-administrator.ts." ] } ]
Expected
Read the resulting membership status as active; inspect the associated records and recorded history for this transition.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/invitations/suspend-user.ts,services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts, activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts; services/membership/lockout.ts, last-administrator.ts.
14 Membership status: active to revokedtransitionapiproposed
Proves
BR-CAP-PFM-SEC-009-06
Preconditions
Use an isolated membership status in active state, with the required authority and guard fixtures.
Steps
[ { "do": "Revoke the active member and inspect assignment, invitation and queued removal records.", "expect": "Read the resulting membership status as revoked; inspect the associated records and recorded history for this transition.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/invitations/revoke-user.ts", "services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts, activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts; services/membership/lockout.ts, last-administrator.ts." ] } ]
Expected
Read the resulting membership status as revoked; inspect the associated records and recorded history for this transition.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/invitations/revoke-user.ts,services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts, activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts; services/membership/lockout.ts, last-administrator.ts.
15 Membership status: suspended to revokedtransitionapiproposed
Proves
BR-CAP-PFM-SEC-009-06
Preconditions
Use an isolated membership status in suspended state, with the required authority and guard fixtures.
Steps
[ { "do": "Revoke the suspended member and inspect queued provider removal.", "expect": "Read the resulting membership status as revoked; inspect the associated records and recorded history for this transition.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/invitations/revoke-user.ts", "services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts, activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts; services/membership/lockout.ts, last-administrator.ts." ] } ]
Expected
Read the resulting membership status as revoked; inspect the associated records and recorded history for this transition.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/invitations/revoke-user.ts,services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts, activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts; services/membership/lockout.ts, last-administrator.ts.
16 Invitation: live to revokedtransitionapiproposed
Proves
BR-CAP-PFM-SEC-009-04
Preconditions
Use an isolated invitation in live state, with the required authority and guard fixtures.
Steps
[ { "do": "Suspend or revoke the membership and attempt to use its outstanding link.", "expect": "Read the resulting invitation as revoked; inspect the associated records and recorded history for this transition.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/persistence/invitations.ts:revokeOutstandingInvitations", "services-platform at ad3f6a65: modules/security/db/user-invitations.table.ts; services/persistence/invitations.ts; services/invitations/invitation-lifetime.ts, resend-invitation.ts, accept-invitation.ts; services/provisioning/provision-user.ts." ] } ]
Expected
Read the resulting invitation as revoked; inspect the associated records and recorded history for this transition.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/persistence/invitations.ts:revokeOutstandingInvitations,services-platform at ad3f6a65: modules/security/db/user-invitations.table.ts; services/persistence/invitations.ts; services/invitations/invitation-lifetime.ts, resend-invitation.ts, accept-invitation.ts; services/provisioning/provision-user.ts.
17 Maintain console memberships with offer and manage an invitationinteractionapinegativeproposed
Proves
BR-CAP-PFM-SEC-008-03 BR-CAP-PFM-SEC-009-05
Preconditions
A console member has a pending invitation and offered assignments.
Steps
Revoke the membership, inspect the old offer, and invite the same address again.
Expected
The old offer cannot activate access; reinvitation reuses membership identity with a new offer.
Data
An isolated customer with two workspaces, ordinary and staff identities, and records owned by this run.
Source
services-platform:modules/security/tests/unit/services/invitations/invite-user.spec.js#refuses somebody already invited to that wall as already_invited, telling the administrator to resend,services-platform:modules/security/services/invitations/suspend-user.ts:reinstateUser
18 Maintain console memberships with assign roles within a controlled scopeinteractionapiproposed
Proves
BR-CAP-PFM-SEC-009-07 BR-CAP-PFM-SEC-010-07
Preconditions
Only one active qualifying customer administrator remains.
Steps
Try withdrawing the qualifying assignment and suspending its holder; read membership and assignments after each refusal.
Expected
Both operations leave the active administrator and qualifying assignment intact.
Data
An isolated customer with two workspaces, ordinary and staff identities, and records owned by this run.
Source
services-platform:modules/security/services/membership/lockout.ts:assertNotLockedOut,services-platform:modules/security/tests/integration/services/membership/manage-assignments.integration.spec.js#revokes the grant, keeps the row, and audits what was withdrawn
19 Maintain console memberships with review security changes and refused attemptsinteractionapiproposed
Proves
BR-CAP-PFM-SEC-009-08 BR-CAP-PFM-SEC-011-07
Preconditions
A reachable member has a retained history and can be deleted.
Steps
Delete the member and read security history with explanation permission.
Expected
The successful deletion event remains attributable through the former-user identity.
Data
An isolated customer with two workspaces, ordinary and staff identities, and records owned by this run.
Source
services-platform:modules/security/tests/unit/services/invitations/user-deletion.spec.js#refuses a delete that would leave the customer with nobody who can administer its security,services-platform:modules/security/tests/e2e/users.e2e.spec.js#writes the deletion to the security trail, naming who deleted whom
20 Maintain console memberships with administer rhythm staff membershipsinteractionapinegativeproposed
Proves
BR-CAP-PFM-SEC-009-07 BR-CAP-PFM-SEC-016-06
Preconditions
A customer administrator and a sole Rhythm Administrator each have active memberships.
Steps
Attempt a removal that would strand each administration boundary.
Expected
Each removal is refused within its own boundary without treating one administrator as the other boundary’s replacement.
Data
An isolated customer with two workspaces, ordinary and staff identities, and records owned by this run.
Source
services-platform:modules/security/services/membership/lockout.ts:assertNotLockedOut,services-platform:modules/security/tests/integration/services/invitations/delete-user.integration.spec.js#refuses the delete as the staff guard does, naming its machine code

The Markdown files under specs/ in rhythmsoftware/rhythm-v2-docs are the canonical source of truth. This reader is a generated, read-only projection of them.