Skip to content

Commit

Permalink
Fix enforcement of AR-Group-3 (CFM-492)
Browse files Browse the repository at this point in the history
  • Loading branch information
Benn Oshrin committed Nov 20, 2025
1 parent 3d82a0b commit cc40e6a
Showing 1 changed file with 35 additions and 17 deletions.
52 changes: 35 additions & 17 deletions app/src/Model/Table/GroupsTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -467,13 +467,13 @@ public function buildRules(RulesChecker $rules): RulesChecker {
// Target Group or is a Target Group for a nesting. This and AR-Group-3
// are to avoid unexpected consequences from implicitly undoing a nesting...
// the administrator must do that first.
$rules->addUpdate([$this, 'ruleIsNested'],
$rules->addUpdate([$this, 'ruleIsNestedUpdate'],
'isNestedUpdate',
['errorField' => 'status']);

// AR-Group-3 A Group cannot be deleted if it is nested into a Target Group
// or is a Target Group for a nesting
$rules->addDelete([$this, 'ruleIsNested'],
$rules->addDelete([$this, 'ruleIsNestedDelete'],
'isNestedDelete',
['errorField' => 'status']);

Expand Down Expand Up @@ -1262,23 +1262,41 @@ public function ruleHasChildren($entity, $options) {
* @return boolean true if the Rule check passes, false otherwise
*/

public function ruleIsNested($entity, $options) {
// We check that the subject group is either a source or a target, but
// only if the $entity status is Suspended.
public function ruleIsNestedDelete($entity, $options) {
// We check that the subject group is either a source or a target.

$count = $this->GroupNestings->find('all')
->where([
'OR' => [
'GroupNestings.group_id' => $entity->id,
'GroupNestings.target_group_id' => $entity->id
]
])
->count();

if($count > 0) {
return __d('error', 'Groups.nested');
}

return true;
}

/**
* Application Rule to determine if the group is nested.
*
* @since COmanage Registry v5.2.0
* @param Entity $entity Entity to be validated
* @param array $options Application rule options
* @return boolean true if the Rule check passes, false otherwise
*/

public function ruleIsNestedUpdate($entity, $options) {
// This is the same check as ruleIsNestedDelete, except we only want it to
// run if the user is trying to suspend the Group. (Other update operations
// shouldn't matter.)

if($entity->status == SuspendableStatusEnum::Suspended) {
$count = $this->GroupNestings->find('all')
->where([
'OR' => [
'GroupNestings.group_id' => $entity->id,
'GroupNestings.target_group_id' => $entity->id
]
])
->count();

if($count > 0) {
return __d('error', 'Groups.nested');
}
return $this->ruleIsNestedDelete($entity, $options);
}

return true;
Expand Down

0 comments on commit cc40e6a

Please sign in to comment.