vendor/nellapp/sdk-bundle/src/Permission/ChannelUserPermissionService.php line 155

Open in your IDE?
  1. <?php
  2. namespace Nellapp\Bundle\SDKBundle\Permission;
  3. use DateTime;
  4. use Nellapp\Bundle\SDKBundle\Channel\Entity\ChannelInterface;
  5. use Nellapp\Bundle\SDKBundle\Channel\Entity\ChannelUserData\AdminChannelUserDataInterface;
  6. use Nellapp\Bundle\SDKBundle\Channel\Entity\ChannelUserData\ChannelUserDataInterface;
  7. use Nellapp\Bundle\SDKBundle\Permission\Entity\ChannelPermissionResourceInterface;
  8. use Nellapp\Bundle\SDKBundle\Permission\Entity\ChannelResourceInterface;
  9. use Nellapp\Bundle\SDKBundle\Permission\Entity\ChannelUserPermissionInterface;
  10. use Nellapp\Bundle\SDKBundle\Permission\Enum\ChannelUserPermissionEnumInterface;
  11. use Nellapp\Bundle\SDKBundle\Permission\Security\Hierarchy\ChannelUserPermissionHierarchyInterface;
  12. use Nellapp\Bundle\SDKBundle\Permission\UserOwner\UserOwnerGetter;
  13. use Nellapp\Bundle\SDKBundle\Sync\ApiClient\Model\ChannelUserData;
  14. class ChannelUserPermissionService
  15. {
  16.     public function __construct(
  17.         private ChannelUserPermissionManager $channelUserPermissionManager,
  18.         private UserOwnerGetter              $userOwnerGetter,
  19.     )
  20.     {
  21.     }
  22.     public function hasAccess(ChannelUserDataInterface $channelUserDataChannelInterface|ChannelResourceInterface $subjectstring $attribute): bool
  23.     {
  24.         if (!$channelUserData instanceof AdminChannelUserDataInterface) {
  25.             return false;
  26.         }
  27.         if ($subject instanceof ChannelInterface && $this->userOwnerGetter->isOwnerOf($channelUserData->getUser(), $subject)) {
  28.             return true;
  29.         }
  30.         if ($subject instanceof ChannelInterface && $channelUserData->getUser() === $subject->getOwner()) {
  31.             return true;
  32.         }
  33.         $availableAttribute $this->isAvailableAttribute($subject$attribute);
  34.         if ($availableAttribute === false) {
  35.             return false;
  36.         }
  37.         $channelUserPermissionInterface $this->getChannelUserPermissionInterface($channelUserData$subject);
  38.         if (!$channelUserPermissionInterface) {
  39.             return false;
  40.         }
  41.         if (!$this->isChannelUserPermissionActive($channelUserPermissionInterface)) {
  42.             return false;
  43.         }
  44.         return in_array($attribute$this->getAvailablePermissions($subject$channelUserPermissionInterface));
  45.     }
  46.     public function getChannelUserPermissionInterface(ChannelUserDataInterface $channelUserDataChannelInterface|ChannelResourceInterface $subject): ?ChannelUserPermissionInterface
  47.     {
  48.         if (!$channelUserData instanceof AdminChannelUserDataInterface) {
  49.             return null;
  50.         }
  51.         if ($subject instanceof ChannelInterface) {
  52.             return $channelUserData;
  53.         }
  54.         $channelResourcePermissionRepository $this->channelUserPermissionManager->getChannelPermissionResourceRepository($subject::getPermissionResourceClass());
  55.         return $channelResourcePermissionRepository?->findOneByChannelUserDataAndResource($channelUserData$subject);
  56.     }
  57.     public function isChannelUserPermissionActive(ChannelUserPermissionInterface $channelUserPermission): bool
  58.     {
  59.         $startAt $channelUserPermission->getStartAt();
  60.         $expireAt $channelUserPermission->getExpireAt();
  61.         return $this->isBetween($startAt$expireAt);
  62.     }
  63.     public function isBetween(?\DateTimeInterface $startAt, ?\DateTimeInterface $expireAt): bool
  64.     {
  65.         $now = new DateTime();
  66.         if ($startAt !== null && $startAt $now) {
  67.             return false;
  68.         }
  69.         if ($expireAt !== null) {
  70.             $expireAtEnd DateTime::createFromInterface($expireAt);
  71.             $expireAtEnd->setTime(235959);
  72.             return $expireAtEnd >= $now;
  73.         }
  74.         return true;
  75.     }
  76.     private function getAvailablePermissions(ChannelInterface|ChannelResourceInterface $subjectChannelUserPermissionInterface $channelUserPermissionInterface): array
  77.     {
  78.         $permissionHierarchies $this->channelUserPermissionManager->getChannelUserPermissionHierarchies($subject);
  79.         if (empty($permissionHierarchies)) {
  80.             return $channelUserPermissionInterface->getPerms();
  81.         }
  82.         return array_unique(array_merge(...array_map(function (ChannelUserPermissionHierarchyInterface $channelUserPermissionHierarchy) use ($channelUserPermissionInterface) {
  83.             return $channelUserPermissionHierarchy->getReachableRoleNames($channelUserPermissionInterface->getPerms());
  84.         }, $permissionHierarchies)));
  85.     }
  86.     private function getAvailablePermissionForSubject(ChannelInterface|ChannelResourceInterface $subject): array
  87.     {
  88.         $channelUserPermissionEnums $this->channelUserPermissionManager->getChannelUserPermissionEnums($subject);
  89.         if (empty($channelUserPermissionEnums)) {
  90.             return [];
  91.         }
  92.         return array_unique(array_merge(...array_map(function (ChannelUserPermissionEnumInterface $channelUserPermissionEnum) {
  93.             return $channelUserPermissionEnum->getChoices();
  94.         }, $channelUserPermissionEnums)));
  95.     }
  96.     private function getAvailablePermissionsWithHierarchyForSubject(ChannelInterface|ChannelResourceInterface $subject): array
  97.     {
  98.         $permissionHierarchies $this->channelUserPermissionManager->getChannelUserPermissionHierarchies($subject);
  99.         if (empty($permissionHierarchies)) {
  100.             return $this->getAvailablePermissionForSubject($subject);
  101.         }
  102.         return array_unique(array_merge(...array_map(function (ChannelUserPermissionHierarchyInterface $channelUserPermissionHierarchy) use ($subject) {
  103.             return $channelUserPermissionHierarchy->getReachableRoleNames($this->getAvailablePermissionForSubject($subject));
  104.         }, $permissionHierarchies)));
  105.     }
  106.     /**
  107.      * @param array $availablePermissions
  108.      * @param string $attribute
  109.      * @return array
  110.      *
  111.      * Check if given attribute exists in the list of available permissions for the resource
  112.      */
  113.     private function isAvailableAttribute(ChannelInterface|ChannelResourceInterface $subjectstring $attribute): bool
  114.     {
  115.         return in_array($attribute$this->getAvailablePermissionsWithHierarchyForSubject($subject));
  116.     }
  117.     /**
  118.      * @param ChannelResourceInterface|ChannelInterface $subject
  119.      * @param string|string[] $perms
  120.      * @return ChannelUserData[]
  121.      */
  122.     public function getAllChannelUserDataForGivenPermissions(ChannelResourceInterface|ChannelInterface $subjectstring|array $perms): array
  123.     {
  124.         if (!is_array($perms)) {
  125.             $perms = [$perms];
  126.         }
  127.         if ($subject instanceof ChannelResourceInterface) {
  128.             return $this->getChannelUserDataForChannelResourceWithPermissions($subject$perms);
  129.         }
  130.         return $this->getChannelUserDataForChannelWithPermissions($subject$perms);
  131.     }
  132.     private function getChannelUserDataForChannelWithPermissions(ChannelInterface $channel, array $perms): array
  133.     {
  134.         return [$channel->getOwner()->getChannelUserDataByChannel($channel)];
  135.     }
  136.     private function getChannelUserDataForChannelResourceWithPermissions(ChannelResourceInterface $channelResource, array $perms): array
  137.     {
  138.         $channelUserPermissionResourceRepository $this->channelUserPermissionManager
  139.             ->getChannelPermissionResourceRepository($channelResource::getPermissionResourceClass());
  140.         if ($channelUserPermissionResourceRepository === null) {
  141.             return [];
  142.         }
  143.         $qb $channelUserPermissionResourceRepository->queryAllByResource($channelResource);
  144.         foreach ($perms as $perm) {
  145.             $qb
  146.                 ->andWhere('FIND_IN_SET(:perm, c_u_p.perms) > 0')
  147.                 ->setParameter('perm'$perm);
  148.         }
  149.         $channelPermissionResourceInterfaceList $qb
  150.             ->addSelect('channel_user_data')
  151.             ->innerJoin('c_u_p.channelUserData''channel_user_data')
  152.             ->getQuery()
  153.             ->getResult();
  154.         return array_map(function (ChannelPermissionResourceInterface $channelPermissionResourceInterface) {
  155.             return $channelPermissionResourceInterface->getChannelUserData();
  156.         }, $channelPermissionResourceInterfaceList);
  157.     }
  158.     public function getAllUserForGivenPermissions(ChannelResourceInterface|ChannelInterface $subjectstring|array $perms): array
  159.     {
  160.         return array_map(function (ChannelUserDataInterface $channelUserData) {
  161.             return $channelUserData->getUser();
  162.         }, $this->getAllChannelUserDataForGivenPermissions($subject$perms));
  163.     }
  164. }