Skip to content

fix: the account manager cannot act on an account private to somebody else - #944

Merged
blaipr merged 1 commit into
mainfrom
fix/the-account-manager-cannot-act-on-a-private-account
Sep 24, 2026
Merged

blaipr merged 1 commit into
mainfrom
fix/the-account-manager-cannot-act-on-a-private-account

Conversation

@blaipr

@blaipr blaipr commented Sep 24, 2026

Copy link
Copy Markdown
Member

The account manager's grid deliberately isn't scoped to what the viewer may read, but it does leave out an account private to somebody else. isPrivate withholds an account from everybody but its owner, and isPrivateGroup from everybody outside its group, application administrators included. The manager's delete and bulk edit didn't apply that rule: they acted on whatever ids were posted. So a holder of mgmAccounts could delete a private account, or overwrite its client, category, tags and expiry, by posting its (sequential) id. No one but its owner can reach that account anywhere else.

Change

  • New Account::assertNotWithheldAsPrivate() applies the same rule as AccountAcl::isWithheldAsPrivate() and AccountFilter::buildFilterPrivate(). A withheld account answers "The account doesn't exist", as the grid answers by not listing it.
  • It is called from delete(), deleteByIdBatch() and updateBulk(), before anything is written or put into history. A selection holding one withheld account is refused whole.
  • Each of those paths now reads the account once. That same copy decides privacy and ownership and goes into history, via a new addHistoryFor().
  • The account view and the API delete already refused through AccountAcl; the check is the same rule for them.

Tests

  • Unit tests for each refusal:
    • delete of an account private to somebody else
    • a batch holding one private to another group
    • bulk edit
  • A unit test that the owner can still delete their own private account.
  • Integration (real container and DB): a stranger's deleteByIdBatch() of another user's private account is refused, and the owner can still read it afterwards.
  • The existing delete and bulk tests now use a non-private fixture: the generator draws both flags at random for a random owner.

Mutation-verified: disabling the owner half of the rule fails the two unit refusals and the integration test.

@blaipr
blaipr merged commit b881fc1 into main Sep 24, 2026
8 checks passed
@blaipr
blaipr deleted the fix/the-account-manager-cannot-act-on-a-private-account branch September 24, 2026 15:35
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.

1 participant