Groups, Snapshots and Tags add/edit checked the ids from MonitorIds or
EventIds when the request had them, but Model::save() links the HABTM
entry (Monitor, Event) and ignores those fields on edit. A Groups=Edit
user could send {"Group":{"MonitorIds":"<current members>"},"Monitor":[]}:
the membership check saw no monitor moved, the save emptied the group and
lifted the Groups_Permissions deny on its monitors. On add, an empty
MonitorIds or EventIds next to a Monitor/Event list let monitors the user
may not edit into a new group, and events the user may not view into a
snapshot.
requestAssociatedIds() now reads the list the way save() does and
rewrites the request's entry to that plain list of ids, so a row given as
a join record links only its MonitorId/EventId. add() copies MonitorIds
or EventIds into the entry before the check, as it did before the save.
Test: tests/php/test_api_associated_ids.php
(cherry picked from commit 6bf015530e)
Group membership feeds per-monitor access through Groups_Permissions, but
the classic group actions and the Groups API checked only the global
Groups permission. A Groups editor could add a monitor they are denied to
a group they have access through, or remove it from, or delete, the group
that denies it.
Add Group::canEditMembership() and require it, in both the classic UI and
the API, for every monitor added to or removed from a group, for all of a
group's monitors when it is re-parented, and for all of them when it is
deleted. The API also pins the record id and omits monitors the user may
not view from the groups it lists.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>