diff --git a/application/Espo/Classes/Acl/Note/AccessChecker.php b/application/Espo/Classes/Acl/Note/AccessChecker.php index 7e668677dc..6161eb33d0 100644 --- a/application/Espo/Classes/Acl/Note/AccessChecker.php +++ b/application/Espo/Classes/Acl/Note/AccessChecker.php @@ -29,6 +29,7 @@ namespace Espo\Classes\Acl\Note; +use Espo\Entities\Note; use Espo\Entities\User; use Espo\ORM\Entity; @@ -77,6 +78,9 @@ class AccessChecker implements AccessEntityCREDChecker $this->config = $config; } + /** + * @param Note $entity + */ public function checkEntityCreate(User $user, Entity $entity, ScopeData $data): bool { $parentId = $entity->get('parentId'); @@ -95,6 +99,62 @@ class AccessChecker implements AccessEntityCREDChecker return false; } + /** + * @param Note $entity + */ + public function checkEntityRead(User $user, Entity $entity, ScopeData $data): bool + { + if ($user->isAdmin()) { + return true; + } + + $parentId = $entity->getParentId(); + $parentType = $entity->getParentType(); + + if ($parentId && $parentType) { + $parent = $this->entityManager->getEntityById($parentType, $parentId); + + if (!$parent) { + return false; + } + + return $this->aclManager->checkEntityStream($user, $parent); + } + + if ($entity->getType() !== Note::TYPE_POST) { + return false; + } + + if ($entity->getCreatedById() === $user->getId()) { + return true; + } + + if ($entity->getTargetType() === Note::TARGET_ALL) { + return true; + } + + if ($entity->getTargetType() === Note::TARGET_TEAMS) { + $targetTeamIdList = $entity->getLinkMultipleIdList('teams'); + + foreach ($user->getTeamIdList() as $teamId) { + if (in_array($teamId, $targetTeamIdList)) { + return true; + } + } + + return false; + } + + if ($entity->getTargetType() === Note::TARGET_USERS) { + return in_array($user->getId(), $entity->getLinkMultipleIdList('users')); + } + + return false; + } + + /** + * @param Note $entity + */ public function checkEntityEdit(User $user, Entity $entity, ScopeData $data): bool { if ($user->isAdmin()) { @@ -106,7 +166,7 @@ class AccessChecker implements AccessEntityCREDChecker } if (!$this->aclManager->checkOwnershipOwn($user, $entity)) { - return true; + return false; } $createdAt = $entity->get('createdAt'); @@ -134,6 +194,9 @@ class AccessChecker implements AccessEntityCREDChecker return true; } + /** + * @param Note $entity + */ public function checkEntityDelete(User $user, Entity $entity, ScopeData $data): bool { if ($user->isAdmin()) { @@ -145,7 +208,7 @@ class AccessChecker implements AccessEntityCREDChecker } if (!$this->aclManager->checkOwnershipOwn($user, $entity)) { - return true; + return false; } $createdAt = $entity->get('createdAt'); diff --git a/application/Espo/Classes/Acl/Note/OwnershipChecker.php b/application/Espo/Classes/Acl/Note/OwnershipChecker.php index a1727055b0..9c134109e4 100644 --- a/application/Espo/Classes/Acl/Note/OwnershipChecker.php +++ b/application/Espo/Classes/Acl/Note/OwnershipChecker.php @@ -29,22 +29,24 @@ namespace Espo\Classes\Acl\Note; +use Espo\Entities\Note; use Espo\Entities\User; use Espo\ORM\Entity; -use Espo\Core\{ - Acl\OwnershipOwnChecker, -}; +use Espo\Core\Acl\OwnershipOwnChecker; /** * @implements OwnershipOwnChecker<\Espo\Entities\Note> */ class OwnershipChecker implements OwnershipOwnChecker { + /** + * @param Note $entity + */ public function checkOwn(User $user, Entity $entity): bool { - if ($entity->get('type') === 'Post' && $user->getId() === $entity->get('createdById')) { + if ($entity->getType() === Note::TYPE_POST && $user->getId() === $entity->getCreatedById()) { return true; } diff --git a/application/Espo/Classes/AclPortal/Note/AccessChecker.php b/application/Espo/Classes/AclPortal/Note/AccessChecker.php index da595a3f25..d7403e9f2c 100644 --- a/application/Espo/Classes/AclPortal/Note/AccessChecker.php +++ b/application/Espo/Classes/AclPortal/Note/AccessChecker.php @@ -29,6 +29,7 @@ namespace Espo\Classes\AclPortal\Note; +use Espo\Entities\Note; use Espo\Entities\User; use Espo\ORM\Entity; @@ -77,16 +78,19 @@ class AccessChecker implements AccessEntityCREDChecker $this->config = $config; } + /** + * @param Note $entity + */ public function checkEntityCreate(User $user, Entity $entity, ScopeData $data): bool { - $parentId = $entity->get('parentId'); - $parentType = $entity->get('parentType'); + $parentId = $entity->getParentId(); + $parentType = $entity->getParentType(); if (!$parentId || !$parentType) { return $this->defaultAccessChecker->checkEntityCreate($user, $entity, $data); } - $parent = $this->entityManager->getEntity($parentType, $parentId); + $parent = $this->entityManager->getEntityById($parentType, $parentId); if ($parent && $this->aclManager->checkEntityStream($user, $parent)) { return true; @@ -95,31 +99,42 @@ class AccessChecker implements AccessEntityCREDChecker return $this->defaultAccessChecker->checkEntityCreate($user, $entity, $data); } + /** + * @param Note $entity + */ public function checkEntityRead(User $user, Entity $entity, ScopeData $data): bool { - if ($entity->get('type') !== 'Post') { - return false; - } + $parentId = $entity->getParentId(); + $parentType = $entity->getParentType(); - if ($entity->get('type') === 'Post' && $entity->get('targetType')) { - return false; - } + if ($parentId && $parentType) { + $parent = $this->entityManager->getEntityById($parentType, $parentId); - if (!$entity->get('parentId') || !$entity->get('parentType')) { - return false; - } - - $parent = $this->entityManager->getEntity($entity->get('parentType'), $entity->get('parentId')); - - if ($parent) { - if ($this->aclManager->checkEntityStream($user, $parent)) { - return true; + if (!$parent) { + return false; } + + return $this->aclManager->checkEntityStream($user, $parent); + } + + if ($entity->getType() !== Note::TYPE_POST) { + return false; + } + + if ($entity->getCreatedById() === $user->getId()) { + return true; + } + + if ($entity->getTargetType() === Note::TARGET_PORTALS) { + return in_array($user->getPortalId(), $entity->getLinkMultipleIdList('portals')); } return false; } + /** + * @param Note $entity + */ public function checkEntityEdit(User $user, Entity $entity, ScopeData $data): bool { if (!$this->defaultAccessChecker->checkEntityEdit($user, $entity, $data)) { @@ -127,7 +142,7 @@ class AccessChecker implements AccessEntityCREDChecker } if (!$this->aclManager->checkOwnershipOwn($user, $entity)) { - return true; + return false; } $createdAt = $entity->get('createdAt'); @@ -155,6 +170,9 @@ class AccessChecker implements AccessEntityCREDChecker return true; } + /** + * @param Note $entity + */ public function checkEntityDelete(User $user, Entity $entity, ScopeData $data): bool { if (!$this->defaultAccessChecker->checkEntityDelete($user, $entity, $data)) { @@ -162,7 +180,7 @@ class AccessChecker implements AccessEntityCREDChecker } if (!$this->aclManager->checkOwnershipOwn($user, $entity)) { - return true; + return false; } $createdAt = $entity->get('createdAt'); diff --git a/application/Espo/Classes/AclPortal/Note/OwnershipChecker.php b/application/Espo/Classes/AclPortal/Note/OwnershipChecker.php index 4c9037a8ac..b5b62a70cd 100644 --- a/application/Espo/Classes/AclPortal/Note/OwnershipChecker.php +++ b/application/Espo/Classes/AclPortal/Note/OwnershipChecker.php @@ -29,22 +29,24 @@ namespace Espo\Classes\AclPortal\Note; +use Espo\Entities\Note; use Espo\Entities\User; use Espo\ORM\Entity; -use Espo\Core\{ - Acl\OwnershipOwnChecker, -}; +use Espo\Core\Acl\OwnershipOwnChecker; /** * @implements OwnershipOwnChecker<\Espo\Entities\Note> */ class OwnershipChecker implements OwnershipOwnChecker { + /** + * @param Note $entity + */ public function checkOwn(User $user, Entity $entity): bool { - if ($entity->get('type') === 'Post' && $user->getId() === $entity->get('createdById')) { + if ($entity->getType() === Note::TYPE_POST && $user->getId() === $entity->getCreatedById()) { return true; } diff --git a/application/Espo/Entities/Note.php b/application/Espo/Entities/Note.php index a257009aba..4353ebc114 100644 --- a/application/Espo/Entities/Note.php +++ b/application/Espo/Entities/Note.php @@ -212,6 +212,11 @@ class Note extends Entity return in_array($userId, $userIdList); } + public function getCreatedById(): ?string + { + return $this->get('createdById'); + } + public function loadAdditionalFields(): void { if ( diff --git a/application/Espo/Entities/User.php b/application/Espo/Entities/User.php index e8c854aabb..db8bfbecb8 100644 --- a/application/Espo/Entities/User.php +++ b/application/Espo/Entities/User.php @@ -232,6 +232,14 @@ class User extends Person return $value; } + /** + * Get a portal ID of the currently logged user. + */ + public function getPortalId(): ?string + { + return $this->get('portalId'); + } + public function getAccounts(): LinkMultiple { /** @var LinkMultiple */