/** * Check organization. If user try to access entity what was created in organization this user do not have access - * deny access * * @param int $result * @return int */ protected function checkOrganizationContext($result) { $object = $this->object; $token = $this->securityToken; if ($token instanceof OrganizationContextTokenInterface && $result === self::ACCESS_GRANTED && $this->extension instanceof EntityAclExtension && is_object($object) && !$object instanceof ObjectIdentity) { $className = ClassUtils::getClass($object); if ($this->configProvider->hasConfig($className)) { $config = $this->configProvider->getConfig($className); $accessLevel = $this->extension->getAccessLevel($this->triggeredMask); // we need to check organization in case if Access level is not system, // or then access level and owner type of test object is User or Business Unit (in this owner types we // do not allow to use System access level) // (do not allow to manipulate records from another organization) if ($accessLevel < AccessLevel::SYSTEM_LEVEL || $accessLevel === AccessLevel::SYSTEM_LEVEL && in_array($config->get('owner_type'), ['USER', 'BUSINESS_UNIT'])) { if ($config->has('organization_field_name')) { $accessor = PropertyAccess::createPropertyAccessor(); /** @var Organization $objectOrganization */ $objectOrganization = $accessor->getValue($object, $config->get('organization_field_name')); if ($objectOrganization && $objectOrganization->getId() !== $token->getOrganizationContext()->getId()) { $result = self::ACCESS_DENIED; } } } } } return $result; }
/** * {@inheritdoc} */ public function vote(TokenInterface $token, $object, array $attributes) { $this->securityToken = $token; $this->object = $object instanceof FieldVote ? $object->getDomainObject() : $object; $this->extension = $this->extensionSelector->select($object); // replace empty permissions with default ones for ($i = 0; $i < count($attributes); $i++) { if (empty($attributes[$i])) { $attributes[$i] = $this->extension->getDefaultPermission(); } } $result = parent::vote($token, $object, $attributes); $this->extension = null; $this->object = null; $this->securityToken = null; return $result; }
/** * {@inheritdoc} */ public function setTriggeredMask($mask) { if ($this->oneShotIsGrantedObserver !== null) { if (is_array($this->oneShotIsGrantedObserver)) { /** @var OneShotIsGrantedObserver $observer */ foreach ($this->oneShotIsGrantedObserver as $observer) { $observer->setAccessLevel($this->extension->getAccessLevel($mask)); } } else { $this->oneShotIsGrantedObserver->setAccessLevel($this->extension->getAccessLevel($mask)); } } }
/** * Updates or creates ACE with the given attributes for the given ACL * * @param ACL $acl * @param AclExtensionInterface $extension * @param bool $replace If true the mask and strategy of the existing ACE should be replaced with the given ones * @param string $type The ACE type. Can be one of AclManager::*_ACE constants * @param string|null $field The name of a field. * Set to null for class-based or object-based ACE * Set to not null class-field-based or object-field-based ACE * @param SID $sid * @param bool $granting * @param int $mask * @param string|null $strategy If null the strategy should not be changed for existing ACE * or the appropriate strategy should be selected automatically for new ACE * ALL strategy is used for $granting = true * ANY strategy is used for $granting = false * @return bool True if a permission was updated or created */ public function setPermission(ACL $acl, AclExtensionInterface $extension, $replace, $type, $field, SID $sid, $granting, $mask, $strategy = null) { $hasChanges = false; $found = false; $maskServiceBits = $extension->getServiceBits($mask); $aces = $this->getAces($acl, $type, $field); foreach ($aces as $index => $ace) { if ($sid->equals($ace->getSecurityIdentity()) && $granting === $ace->isGranting()) { if ($mask === $ace->getMask() && ($strategy === null || $strategy === $ace->getStrategy())) { $found = true; } elseif ($replace && $maskServiceBits === $extension->getServiceBits($ace->getMask())) { $this->updateAce($acl, $type, $field, $index, $mask, $strategy); $found = true; $hasChanges = true; } } } if (!$found) { $this->insertAce($acl, $type, $field, 0, $sid, $granting, $mask, $strategy); $hasChanges = true; } return $hasChanges; }
/** * @param int $result * @return int */ protected function checkOrganizationContext($result) { $object = $this->object; $token = $this->securityToken; if ($token instanceof OrganizationContextTokenInterface && $result === self::ACCESS_GRANTED && $this->extension instanceof EntityAclExtension && is_object($object) && !$object instanceof ObjectIdentity) { $className = ClassUtils::getClass($object); if ($this->configProvider->hasConfig($className)) { $config = $this->configProvider->getConfig($className); $accessLevel = $this->extension->getAccessLevel($this->triggeredMask); if ($accessLevel < AccessLevel::SYSTEM_LEVEL || $accessLevel === AccessLevel::SYSTEM_LEVEL && in_array($config->get('owner_type'), ['USER', 'BUSINESS_UNIT'])) { if ($config->has('organization_field_name')) { $accessor = PropertyAccess::createPropertyAccessor(); /** @var Organization $objectOrganization */ $objectOrganization = $accessor->getValue($object, $config->get('organization_field_name')); if ($objectOrganization && $objectOrganization->getId() !== $token->getOrganizationContext()->getId()) { $result = self::ACCESS_DENIED; } } } } } return $result; }
/** * Return AclPermission object for given permission, ACL mask and ACL privilege * * @param AclExtensionInterface $extension * @param string $permission * @param string $mask * @param AclPrivilege $privilege * @return AclPermission */ protected function getAclPermission(AclExtensionInterface $extension, $permission, $mask, AclPrivilege $privilege) { return new AclPermission($permission, $extension->getAccessLevel($mask, $permission, $privilege->getIdentity()->getId())); }
/** * Adds permissions to the given $privilege based on the given ACEs. * The $permissions argument is used to filter privileges for the given permissions only. * * @param AclPrivilege $privilege * @param string[] $permissions * @param EntryInterface[] $aces * @param AclExtensionInterface $extension * @param bool $itIsRootAcl */ protected function addAcesPermissions(AclPrivilege $privilege, array $permissions, array $aces, AclExtensionInterface $extension, $itIsRootAcl = false) { if (empty($aces)) { return; } foreach ($aces as $ace) { if (!$ace->isGranting()) { // denying ACE is not supported continue; } $mask = $ace->getMask(); if ($itIsRootAcl) { $mask = $extension->adaptRootMask($mask, $privilege->getIdentity()->getId()); } if ($extension->removeServiceBits($mask) === 0) { foreach ($permissions as $permission) { if (!$privilege->hasPermission($permission)) { $privilege->addPermission(new AclPermission($permission, AccessLevel::NONE_LEVEL)); } } } else { foreach ($extension->getPermissions($mask) as $permission) { if (!$privilege->hasPermission($permission) && in_array($permission, $permissions)) { $privilege->addPermission(new AclPermission($permission, $extension->getAccessLevel($mask, $permission))); } } } } }
/** * @param AclManager $aclManager * @param AclExtensionInterface $extension * @param SecurityIdentityInterface $sid * @param string $group */ protected function setPermissionGroup(AclManager $aclManager, AclExtensionInterface $extension, SecurityIdentityInterface $sid, $group) { $rootOid = $aclManager->getRootOid($extension->getExtensionKey()); foreach ($extension->getAllMaskBuilders() as $maskBuilder) { if ($maskBuilder->hasConst($group)) { $mask = $maskBuilder->getConst($group); $aclManager->setPermission($sid, $rootOid, $mask, true); break; } } }