diff --git a/src/Security/Voter/AttachmentVoter.php b/src/Security/Voter/AttachmentVoter.php index ad04010e..3cb8d543 100644 --- a/src/Security/Voter/AttachmentVoter.php +++ b/src/Security/Voter/AttachmentVoter.php @@ -106,7 +106,7 @@ class AttachmentVoter extends ExtendedVoter { if (is_a($subject, Attachment::class, true)) { //These are the allowed attributes - return in_array($attribute, ['view', 'edit', 'delete', 'create', 'show_private'], true); + return in_array($attribute, ['read', 'view', 'edit', 'delete', 'create', 'show_private'], true); } //Allow class name as subject diff --git a/src/Security/Voter/ParameterVoter.php b/src/Security/Voter/ParameterVoter.php new file mode 100644 index 00000000..503b5bcd --- /dev/null +++ b/src/Security/Voter/ParameterVoter.php @@ -0,0 +1,102 @@ +security = $security; + parent::__construct($resolver, $entityManager); + } + + protected function voteOnUser(string $attribute, $subject, User $user): bool + { + //return $this->resolver->inherit($user, 'attachments', $attribute) ?? false; + + if (!$subject instanceof AbstractParameter) { + return false; + } + + //If the attachment has no element (which should not happen), we deny access, as we can not determine if the user is allowed to access the associated element + $target_element = $subject->getElement(); + if ($target_element !== null) { + //Depending on the operation delegate either to the attachments element or to the attachment permission + switch ($attribute) { + //We can view the attachment if we can view the element + case 'read': + case 'view': + return $this->security->isGranted('read', $target_element); + //We can edit/create/delete the attachment if we can edit the element + case 'edit': + case 'create': + case 'delete': + return $this->security->isGranted('edit', $target_element); + } + } + + //If we do not have a concrete element, we delegate to the different categories + if ($subject instanceof AttachmentTypeParameter) { + $param = 'attachment_types'; + } elseif ($subject instanceof CategoryParameter) { + $param = 'categories'; + } elseif ($subject instanceof CurrencyParameter) { + $param = 'currencies'; + } elseif ($subject instanceof DeviceParameter) { + $param = 'devices'; + } elseif ($subject instanceof FootprintParameter) { + $param = 'footprints'; + } elseif ($subject instanceof GroupParameter) { + $param = 'groups'; + } elseif ($subject instanceof ManufacturerParameter) { + $param = 'manufacturers'; + } elseif ($subject instanceof MeasurementUnitParameter) { + $param = 'measurement_units'; + } elseif ($subject instanceof PartParameter) { + $param = 'parts'; + } elseif ($subject instanceof StorelocationParameter) { + $param = 'storelocations'; + } elseif ($subject instanceof SupplierParameter) { + $param = 'suppliers'; + } else { + throw new RuntimeException('Encountered unknown Parameter type: ' . get_class($subject)); + } + + return $this->resolver->inherit($user, $param, $attribute) ?? false; + } + + protected function supports(string $attribute, $subject) + { + if (is_a($subject, AbstractParameter::class, true)) { + //These are the allowed attributes + return in_array($attribute, ['read', 'edit', 'delete', 'create'], true); + } + + //Allow class name as subject + return false; + } +} \ No newline at end of file