From dd05c824ba5fcb494faef0e0546ca0a629eba749 Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Wed, 27 Sep 2023 16:36:49 +0200 Subject: [PATCH] use cacheable security voters --- databox/api/src/Elasticsearch/AbstractSearch.php | 10 +++++++++- .../Security/Voter/AssetDataTemplateVoter.php | 5 +++++ .../src/Security/Voter/AssetFileVersionVoter.php | 5 +++++ databox/api/src/Security/Voter/AssetVoter.php | 10 ++++++++++ .../src/Security/Voter/AttributeClassVoter.php | 5 +++++ .../Security/Voter/AttributeDefinitionVoter.php | 5 +++++ .../api/src/Security/Voter/AttributeVoter.php | 5 +++++ .../api/src/Security/Voter/ChuckNorrisVoter.php | 5 +++++ .../api/src/Security/Voter/CollectionVoter.php | 16 +++++++++++++--- databox/api/src/Security/Voter/FileVoter.php | 5 +++++ .../src/Security/Voter/RenditionClassVoter.php | 5 +++++ .../Security/Voter/RenditionDefinitionVoter.php | 5 +++++ .../api/src/Security/Voter/RenditionVoter.php | 5 +++++ .../src/Security/Voter/TagFilterRuleVoter.php | 5 +++++ .../Security/Voter/TemplateAttributeVoter.php | 5 +++++ .../src/Security/Voter/WorkflowStateVoter.php | 5 +++++ .../api/src/Security/Voter/WorkspaceVoter.php | 10 ++++++++++ 17 files changed, 107 insertions(+), 4 deletions(-) diff --git a/databox/api/src/Elasticsearch/AbstractSearch.php b/databox/api/src/Elasticsearch/AbstractSearch.php index e1c186550..a489c5250 100644 --- a/databox/api/src/Elasticsearch/AbstractSearch.php +++ b/databox/api/src/Elasticsearch/AbstractSearch.php @@ -28,6 +28,13 @@ protected function createACLBoolQuery(?string $userId, array $groupIds): ?Query\ $publicWorkspaceIds = $this->getPublicWorkspaceIds(); if (null !== $userId) { + $allowedWorkspaceIds = $this->getAllowedWorkspaceIds($userId, $groupIds); + + $aclBoolQuery->addMust(new Query\Terms( + 'workspaceId', + array_values(array_unique(array_merge($allowedWorkspaceIds, $publicWorkspaceIds))) + )); + if (!empty($publicWorkspaceIds)) { $publicWorkspaceBoolQuery = new Query\BoolQuery(); $publicWorkspaceBoolQuery->addMust(new Query\Range('privacy', [ @@ -37,7 +44,6 @@ protected function createACLBoolQuery(?string $userId, array $groupIds): ?Query\ $shoulds[] = $publicWorkspaceBoolQuery; } - $allowedWorkspaceIds = $this->getAllowedWorkspaceIds($userId, $groupIds); if (!empty($allowedWorkspaceIds)) { $workspaceBoolQuery = new Query\BoolQuery(); @@ -55,6 +61,8 @@ protected function createACLBoolQuery(?string $userId, array $groupIds): ?Query\ $shoulds[] = new Query\Terms('groups', $groupIds); } } else { + $aclBoolQuery->addMust(new Query\Terms('workspaceId', $publicWorkspaceIds)); + if (!empty($publicWorkspaceIds)) { $publicWorkspaceBoolQuery = new Query\BoolQuery(); $publicWorkspaceBoolQuery->addMust(new Query\Range('privacy', [ diff --git a/databox/api/src/Security/Voter/AssetDataTemplateVoter.php b/databox/api/src/Security/Voter/AssetDataTemplateVoter.php index a9d35828f..7f482f7d5 100644 --- a/databox/api/src/Security/Voter/AssetDataTemplateVoter.php +++ b/databox/api/src/Security/Voter/AssetDataTemplateVoter.php @@ -16,6 +16,11 @@ protected function supports(string $attribute, $subject): bool return $subject instanceof AssetDataTemplate; } + public function supportsType(string $subjectType): bool + { + return is_a($subjectType, AssetDataTemplate::class, true); + } + /** * @param AssetDataTemplate $subject */ diff --git a/databox/api/src/Security/Voter/AssetFileVersionVoter.php b/databox/api/src/Security/Voter/AssetFileVersionVoter.php index 25908d7a6..c2e7f1ab9 100644 --- a/databox/api/src/Security/Voter/AssetFileVersionVoter.php +++ b/databox/api/src/Security/Voter/AssetFileVersionVoter.php @@ -14,6 +14,11 @@ protected function supports(string $attribute, $subject): bool return $subject instanceof AssetFileVersion; } + public function supportsType(string $subjectType): bool + { + return is_a($subjectType, AssetFileVersion::class, true); + } + /** * @param AssetFileVersion $subject */ diff --git a/databox/api/src/Security/Voter/AssetVoter.php b/databox/api/src/Security/Voter/AssetVoter.php index 1d97b9cc1..23bb9d2b8 100644 --- a/databox/api/src/Security/Voter/AssetVoter.php +++ b/databox/api/src/Security/Voter/AssetVoter.php @@ -22,6 +22,11 @@ protected function supports(string $attribute, $subject): bool return $subject instanceof Asset; } + public function supportsType(string $subjectType): bool + { + return is_a($subjectType, Asset::class, true); + } + /** * @param Asset $subject */ @@ -31,6 +36,11 @@ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $ $userId = $user instanceof JwtUser ? $user->getId() : false; $isOwner = fn (): bool => $userId && $subject->getOwnerId() === $userId; + $workspace = $subject->getWorkspace(); + if (!$this->security->isGranted(AbstractVoter::READ, $workspace)) { + return false; + } + switch ($attribute) { case self::CREATE: if (null !== $collection = $subject->getReferenceCollection()) { diff --git a/databox/api/src/Security/Voter/AttributeClassVoter.php b/databox/api/src/Security/Voter/AttributeClassVoter.php index 46903bd39..73debd874 100644 --- a/databox/api/src/Security/Voter/AttributeClassVoter.php +++ b/databox/api/src/Security/Voter/AttributeClassVoter.php @@ -18,6 +18,11 @@ protected function supports(string $attribute, $subject): bool return $subject instanceof AttributeClass; } + public function supportsType(string $subjectType): bool + { + return is_a($subjectType, AttributeClass::class, true); + } + /** * @param AttributeClass $subject */ diff --git a/databox/api/src/Security/Voter/AttributeDefinitionVoter.php b/databox/api/src/Security/Voter/AttributeDefinitionVoter.php index 64cc555db..1a2ad1d00 100644 --- a/databox/api/src/Security/Voter/AttributeDefinitionVoter.php +++ b/databox/api/src/Security/Voter/AttributeDefinitionVoter.php @@ -14,6 +14,11 @@ protected function supports(string $attribute, $subject): bool return $subject instanceof AttributeDefinition; } + public function supportsType(string $subjectType): bool + { + return is_a($subjectType, AttributeDefinition::class, true); + } + /** * @param AttributeDefinition $subject */ diff --git a/databox/api/src/Security/Voter/AttributeVoter.php b/databox/api/src/Security/Voter/AttributeVoter.php index 267691816..0aa117c40 100644 --- a/databox/api/src/Security/Voter/AttributeVoter.php +++ b/databox/api/src/Security/Voter/AttributeVoter.php @@ -15,6 +15,11 @@ protected function supports(string $attribute, $subject): bool return $subject instanceof Attribute; } + public function supportsType(string $subjectType): bool + { + return is_a($subjectType, Attribute::class, true); + } + /** * @param Attribute $subject */ diff --git a/databox/api/src/Security/Voter/ChuckNorrisVoter.php b/databox/api/src/Security/Voter/ChuckNorrisVoter.php index 38e46e8ad..53e9352a1 100644 --- a/databox/api/src/Security/Voter/ChuckNorrisVoter.php +++ b/databox/api/src/Security/Voter/ChuckNorrisVoter.php @@ -15,6 +15,11 @@ protected function supports(string $attribute, $subject): bool return self::ROLE !== $attribute; } + public function supportsAttribute(string $attribute): bool + { + return self::ROLE !== $attribute; + } + protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool { return $this->security->isGranted(self::ROLE); diff --git a/databox/api/src/Security/Voter/CollectionVoter.php b/databox/api/src/Security/Voter/CollectionVoter.php index 026ee7779..b35d52f4e 100644 --- a/databox/api/src/Security/Voter/CollectionVoter.php +++ b/databox/api/src/Security/Voter/CollectionVoter.php @@ -19,6 +19,11 @@ protected function supports(string $attribute, $subject): bool return $subject instanceof Collection; } + public function supportsType(string $subjectType): bool + { + return is_a($subjectType, Collection::class, true); + } + /** * @param Collection $subject */ @@ -35,19 +40,24 @@ private function doVote(string $attribute, Collection $subject, TokenInterface $ $userId = $user instanceof JwtUser ? $user->getId() : false; $isOwner = fn (): bool => $userId && $subject->getOwnerId() === $userId; + $workspace = $subject->getWorkspace(); + if (!$this->security->isGranted(AbstractVoter::READ, $workspace)) { + return false; + } + return match ($attribute) { self::CREATE => $subject->getParent() ? $this->security->isGranted(AbstractVoter::EDIT, $subject->getParent()) - : $this->security->isGranted(AbstractVoter::EDIT, $subject->getWorkspace()), + : $this->security->isGranted(AbstractVoter::EDIT, $workspace), self::LIST => $isOwner() || $subject->getPrivacy() >= WorkspaceItemPrivacyInterface::PUBLIC || ($userId && $subject->getPrivacy() >= WorkspaceItemPrivacyInterface::PRIVATE) - || ($this->security->isGranted(AbstractVoter::READ, $subject->getWorkspace()) && $subject->getPrivacy() >= WorkspaceItemPrivacyInterface::PRIVATE_IN_WORKSPACE) + || ($this->security->isGranted(AbstractVoter::READ, $workspace) && $subject->getPrivacy() >= WorkspaceItemPrivacyInterface::PRIVATE_IN_WORKSPACE) || $this->hasAcl(PermissionInterface::VIEW, $subject, $token) || (null !== $subject->getParent() && $this->security->isGranted($attribute, $subject->getParent())), self::READ => $isOwner() || $subject->getPrivacy() >= WorkspaceItemPrivacyInterface::PUBLIC || ($userId && $subject->getPrivacy() >= WorkspaceItemPrivacyInterface::PUBLIC_FOR_USERS) - || ($this->security->isGranted(AbstractVoter::READ, $subject->getWorkspace()) && $subject->getPrivacy() >= WorkspaceItemPrivacyInterface::PUBLIC_IN_WORKSPACE) + || ($this->security->isGranted(AbstractVoter::READ, $workspace) && $subject->getPrivacy() >= WorkspaceItemPrivacyInterface::PUBLIC_IN_WORKSPACE) || $this->hasAcl(PermissionInterface::VIEW, $subject, $token) || (null !== $subject->getParent() && $this->security->isGranted($attribute, $subject->getParent())), self::EDIT => $isOwner() diff --git a/databox/api/src/Security/Voter/FileVoter.php b/databox/api/src/Security/Voter/FileVoter.php index 53cca4168..f7ca20979 100644 --- a/databox/api/src/Security/Voter/FileVoter.php +++ b/databox/api/src/Security/Voter/FileVoter.php @@ -15,6 +15,11 @@ protected function supports(string $attribute, $subject): bool return $subject instanceof File; } + public function supportsType(string $subjectType): bool + { + return is_a($subjectType, File::class, true); + } + /** * @param File $subject */ diff --git a/databox/api/src/Security/Voter/RenditionClassVoter.php b/databox/api/src/Security/Voter/RenditionClassVoter.php index 662c7e549..12dabd59c 100644 --- a/databox/api/src/Security/Voter/RenditionClassVoter.php +++ b/databox/api/src/Security/Voter/RenditionClassVoter.php @@ -17,6 +17,11 @@ protected function supports(string $attribute, $subject): bool return $subject instanceof RenditionClass; } + public function supportsType(string $subjectType): bool + { + return is_a($subjectType, RenditionClass::class, true); + } + /** * @param RenditionClass $subject */ diff --git a/databox/api/src/Security/Voter/RenditionDefinitionVoter.php b/databox/api/src/Security/Voter/RenditionDefinitionVoter.php index 99736a167..802963168 100644 --- a/databox/api/src/Security/Voter/RenditionDefinitionVoter.php +++ b/databox/api/src/Security/Voter/RenditionDefinitionVoter.php @@ -17,6 +17,11 @@ protected function supports(string $attribute, $subject): bool return $subject instanceof RenditionDefinition; } + public function supportsType(string $subjectType): bool + { + return is_a($subjectType, RenditionDefinition::class, true); + } + /** * @param RenditionDefinition $subject */ diff --git a/databox/api/src/Security/Voter/RenditionVoter.php b/databox/api/src/Security/Voter/RenditionVoter.php index ddaaf726e..c74ec5076 100644 --- a/databox/api/src/Security/Voter/RenditionVoter.php +++ b/databox/api/src/Security/Voter/RenditionVoter.php @@ -20,6 +20,11 @@ protected function supports(string $attribute, $subject): bool return $subject instanceof AssetRendition; } + public function supportsType(string $subjectType): bool + { + return is_a($subjectType, AssetRendition::class, true); + } + /** * @param AssetRendition $subject */ diff --git a/databox/api/src/Security/Voter/TagFilterRuleVoter.php b/databox/api/src/Security/Voter/TagFilterRuleVoter.php index f73e391cb..51c7a21eb 100644 --- a/databox/api/src/Security/Voter/TagFilterRuleVoter.php +++ b/databox/api/src/Security/Voter/TagFilterRuleVoter.php @@ -14,6 +14,11 @@ protected function supports(string $attribute, $subject): bool return $subject instanceof TagFilterRule; } + public function supportsType(string $subjectType): bool + { + return is_a($subjectType, TagFilterRule::class, true); + } + /** * @param TagFilterRule $subject */ diff --git a/databox/api/src/Security/Voter/TemplateAttributeVoter.php b/databox/api/src/Security/Voter/TemplateAttributeVoter.php index 73c6e7856..6fc1e43b8 100644 --- a/databox/api/src/Security/Voter/TemplateAttributeVoter.php +++ b/databox/api/src/Security/Voter/TemplateAttributeVoter.php @@ -15,6 +15,11 @@ protected function supports(string $attribute, $subject): bool return $subject instanceof TemplateAttribute; } + public function supportsType(string $subjectType): bool + { + return is_a($subjectType, TemplateAttribute::class, true); + } + /** * @param TemplateAttribute $subject */ diff --git a/databox/api/src/Security/Voter/WorkflowStateVoter.php b/databox/api/src/Security/Voter/WorkflowStateVoter.php index be9fabb57..0f9ade170 100644 --- a/databox/api/src/Security/Voter/WorkflowStateVoter.php +++ b/databox/api/src/Security/Voter/WorkflowStateVoter.php @@ -14,6 +14,11 @@ protected function supports(string $attribute, $subject): bool return $subject instanceof WorkflowState; } + public function supportsType(string $subjectType): bool + { + return is_a($subjectType, WorkflowState::class, true); + } + /** * @param WorkflowState $subject */ diff --git a/databox/api/src/Security/Voter/WorkspaceVoter.php b/databox/api/src/Security/Voter/WorkspaceVoter.php index da88343a5..d10c27284 100644 --- a/databox/api/src/Security/Voter/WorkspaceVoter.php +++ b/databox/api/src/Security/Voter/WorkspaceVoter.php @@ -19,6 +19,16 @@ protected function supports(string $attribute, $subject): bool return $subject instanceof Workspace && !is_numeric($attribute); } + public function supportsAttribute(string $attribute): bool + { + return !is_numeric($attribute); + } + + public function supportsType(string $subjectType): bool + { + return is_a($subjectType, Workspace::class, true); + } + /** * @param Workspace $subject */