AclRetriever.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Authorization\Model\Acl;
  7. use Magento\Authorization\Model\ResourceModel\Role\CollectionFactory as RoleCollectionFactory;
  8. use Magento\Authorization\Model\ResourceModel\Rules\CollectionFactory as RulesCollectionFactory;
  9. use Magento\Authorization\Model\Role;
  10. use Magento\Authorization\Model\UserContextInterface;
  11. use Magento\Framework\Acl\Builder as AclBuilder;
  12. use Magento\Framework\Exception\AuthorizationException;
  13. use Magento\Framework\Exception\LocalizedException;
  14. use Psr\Log\LoggerInterface as Logger;
  15. /**
  16. * Permission tree retriever
  17. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  18. */
  19. class AclRetriever
  20. {
  21. const PERMISSION_ANONYMOUS = 'anonymous';
  22. const PERMISSION_SELF = 'self';
  23. /**
  24. * @var \Psr\Log\LoggerInterface
  25. */
  26. protected $logger;
  27. /**
  28. * @var \Magento\Authorization\Model\ResourceModel\Rules\CollectionFactory
  29. */
  30. protected $rulesCollectionFactory;
  31. /**
  32. * @var \Magento\Framework\Acl\Builder
  33. */
  34. protected $aclBuilder;
  35. /**
  36. * @var \Magento\Authorization\Model\ResourceModel\Role\CollectionFactory
  37. */
  38. protected $roleCollectionFactory;
  39. /**
  40. * Initialize dependencies.
  41. *
  42. * @param AclBuilder $aclBuilder
  43. * @param RoleCollectionFactory $roleCollectionFactory
  44. * @param RulesCollectionFactory $rulesCollectionFactory
  45. * @param Logger $logger
  46. */
  47. public function __construct(
  48. AclBuilder $aclBuilder,
  49. RoleCollectionFactory $roleCollectionFactory,
  50. RulesCollectionFactory $rulesCollectionFactory,
  51. Logger $logger
  52. ) {
  53. $this->logger = $logger;
  54. $this->rulesCollectionFactory = $rulesCollectionFactory;
  55. $this->aclBuilder = $aclBuilder;
  56. $this->roleCollectionFactory = $roleCollectionFactory;
  57. }
  58. /**
  59. * Get a list of available resources using user details
  60. *
  61. * @param string $userType
  62. * @param int $userId
  63. * @return string[]
  64. * @throws AuthorizationException
  65. * @throws LocalizedException
  66. */
  67. public function getAllowedResourcesByUser($userType, $userId)
  68. {
  69. if ($userType == UserContextInterface::USER_TYPE_GUEST) {
  70. return [self::PERMISSION_ANONYMOUS];
  71. } elseif ($userType == UserContextInterface::USER_TYPE_CUSTOMER) {
  72. return [self::PERMISSION_SELF];
  73. }
  74. try {
  75. $role = $this->_getUserRole($userType, $userId);
  76. if (!$role) {
  77. throw new AuthorizationException(
  78. __("The role wasn't found for the user. Verify the role and try again.")
  79. );
  80. }
  81. $allowedResources = $this->getAllowedResourcesByRole($role->getId());
  82. } catch (AuthorizationException $e) {
  83. throw $e;
  84. } catch (\Exception $e) {
  85. $this->logger->critical($e);
  86. throw new LocalizedException(
  87. __(
  88. 'Something went wrong while compiling a list of allowed resources. '
  89. . 'You can find out more in the exceptions log.'
  90. )
  91. );
  92. }
  93. return $allowedResources;
  94. }
  95. /**
  96. * Get a list of available resource using user role id
  97. *
  98. * @param string $roleId
  99. * @return string[]
  100. */
  101. public function getAllowedResourcesByRole($roleId)
  102. {
  103. $allowedResources = [];
  104. $rulesCollection = $this->rulesCollectionFactory->create();
  105. $rulesCollection->getByRoles($roleId)->load();
  106. $acl = $this->aclBuilder->getAcl();
  107. /** @var \Magento\Authorization\Model\Rules $ruleItem */
  108. foreach ($rulesCollection->getItems() as $ruleItem) {
  109. $resourceId = $ruleItem->getResourceId();
  110. if ($acl->has($resourceId) && $acl->isAllowed($roleId, $resourceId)) {
  111. $allowedResources[] = $resourceId;
  112. }
  113. }
  114. return $allowedResources;
  115. }
  116. /**
  117. * Identify user role from user identifier.
  118. *
  119. * @param string $userType
  120. * @param int $userId
  121. * @return \Magento\Authorization\Model\Role|bool False if no role associated with provided user was found.
  122. * @throws \LogicException
  123. */
  124. protected function _getUserRole($userType, $userId)
  125. {
  126. if (!$this->_canRoleBeCreatedForUserType($userType)) {
  127. throw new \LogicException(
  128. "The role with user type '{$userType}' does not exist and cannot be created"
  129. );
  130. }
  131. $roleCollection = $this->roleCollectionFactory->create();
  132. /** @var Role $role */
  133. $role = $roleCollection->setUserFilter($userId, $userType)->getFirstItem();
  134. return $role->getId() ? $role : false;
  135. }
  136. /**
  137. * Check if the role can be associated with user having provided user type.
  138. *
  139. * Roles can be created for integrations and admin users only.
  140. *
  141. * @param int $userType
  142. * @return bool
  143. */
  144. protected function _canRoleBeCreatedForUserType($userType)
  145. {
  146. return ($userType == UserContextInterface::USER_TYPE_INTEGRATION)
  147. || ($userType == UserContextInterface::USER_TYPE_ADMIN);
  148. }
  149. }