Skip to content

fix: who may mark an account private is decided for every door - #943

Merged
blaipr merged 1 commit into
mainfrom
fix/account-privacy-is-decided-by-the-service
Sep 24, 2026
Merged

blaipr merged 1 commit into
mainfrom
fix/account-privacy-is-decided-by-the-service

Conversation

@blaipr

@blaipr blaipr commented Sep 24, 2026

Copy link
Copy Markdown
Member

Who may mark an account private (isPrivate) or private to its group (isPrivateGroup) was decided in AccountForm::constrainPrivacyToPermission(), and only the web goes through a form. The allowed callers are:

  • an application administrator
  • the owner whose profile holds isAccPrivate()
  • for the group flag, the main group holding isAccPrivateGroup()

The API's account/create and account/edit put the caller's private / privateGroup straight into the row. So any token with edit access to an account could make it private without the permission, or strip privacy from one that had it. That matters more than it sounds: AccountAcl tests privacy before the administrator branch, so a private account disappears for account administrators too.

Change

  • One rule, Account::privacyAllowedFor(), now applied by the service on every write: create(), update(), and the history restore that already had its own copy. The form's copy is removed rather than kept alongside, so the web and the API can't drift apart.
  • On update, the rule is decided for the owner and group the account will actually have once saved. A caller who may not change the owner doesn't become it by naming themselves in the request. The form compared against the submitted owner, so the web had a narrower version of the same gap.
  • Bulk edit is unaffected: it can't write either flag.

Tests

  • Two new AccountTest cases:
    • an owner holding the permission keeps the flags they asked for
    • on an account owned by someone else, a caller holding the permission gets both flags written off, even when the request names them as owner
  • Four existing update and create tests now expect both flags off for callers without the permission. Their fixtures carried random flags that the service used to pass through untouched.
  • The form's refusal test is removed, since the rule has moved to the service.

Mutation-verified:

  • Allowing every flag fails five tests.
  • Deciding against the requested owner instead of the stored one fails the two new tests.

@blaipr
blaipr merged commit 63dceb9 into main Sep 24, 2026
8 checks passed
@blaipr
blaipr deleted the fix/account-privacy-is-decided-by-the-service branch September 24, 2026 15:09
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