Skip to content

Commit

Permalink
CC-32215: Agent Assist in Merchant Portal (#10720)
Browse files Browse the repository at this point in the history
CC-32215 Merchant Portal Agent Assist feature.
  • Loading branch information
dmiseev authored Feb 6, 2024
1 parent 0e440cb commit 3ba7bed
Show file tree
Hide file tree
Showing 13 changed files with 423 additions and 2 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"license": "proprietary",
"require": {
"php": ">=8.1",
"spryker/acl-extension": "^1.1.0",
"spryker/acl-extension": "^1.2.0",
"spryker/acl-merchant-portal-extension": "^1.0.0",
"spryker/config": "^3.0.0",
"spryker/event-dispatcher-extension": "^1.0.0",
Expand Down
18 changes: 18 additions & 0 deletions src/Spryker/Shared/Acl/Transfer/acl.transfer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,22 @@
<property name="aclEntityAllowList" type="string[]" singular="aclEntityAllowListItem"/>
</transfer>

<transfer name="AclUserHasGroupCollection" strict="true">
<property name="aclUserHasGroups" type="AclUserHasGroup[]" singular="aclUserHasGroup"/>
</transfer>

<transfer name="AclUserHasGroup" strict="true">
<property name="user" type="User"/>
<property name="group" type="Group"/>
</transfer>

<transfer name="AclUserHasGroupCriteria" strict="true">
<property name="aclUserHasGroupConditions" type="AclUserHasGroupConditions"/>
</transfer>

<transfer name="AclUserHasGroupConditions" strict="true">
<property name="userIds" type="int[]" singular="idUser"/>
<property name="groupNames" type="string[]" singular="groupName"/>
</transfer>

</transfers>
28 changes: 28 additions & 0 deletions src/Spryker/Zed/Acl/AclDependencyProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ class AclDependencyProvider extends AbstractBundleDependencyProvider
*/
public const PLUGINS_ACL_ROLE_POST_SAVE = 'PLUGINS_ACL_ROLE_POST_SAVE';

/**
* @var string
*/
public const PLUGINS_ACL_ACCESS_CHECKER_STRATEGY = 'PLUGINS_ACL_ACCESS_CHECKER_STRATEGY';

/**
* @param \Spryker\Zed\Kernel\Container $container
*
Expand Down Expand Up @@ -84,6 +89,7 @@ public function provideBusinessLayerDependencies(Container $container)
$container = $this->addAclInstallerPlugins($container);
$container = $this->addAclRolesExpanderPlugins($container);
$container = $this->addAclRolePostSavePlugins($container);
$container = $this->addAclAccessCheckerStrategyPlugins($container);

return $container;
}
Expand Down Expand Up @@ -196,4 +202,26 @@ protected function getAclRolePostSavePlugins(): array
{
return [];
}

/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\Kernel\Container
*/
protected function addAclAccessCheckerStrategyPlugins(Container $container): Container
{
$container->set(static::PLUGINS_ACL_ACCESS_CHECKER_STRATEGY, function () {
return $this->getAclAccessCheckerStrategyPlugins();
});

return $container;
}

/**
* @return array<\Spryker\Zed\AclExtension\Dependency\Plugin\AclAccessCheckerStrategyPluginInterface>
*/
protected function getAclAccessCheckerStrategyPlugins(): array
{
return [];
}
}
9 changes: 9 additions & 0 deletions src/Spryker/Zed/Acl/Business/AclBusinessFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public function createRuleModel()
$this->getProvidedDependency(AclDependencyProvider::FACADE_USER),
$this->createRuleValidatorHelper(),
$this->getConfig(),
$this->getAclAccessCheckerStrategyPlugins(),
);
}

Expand Down Expand Up @@ -163,4 +164,12 @@ public function getAclRolePostSavePlugins(): array
{
return $this->getProvidedDependency(AclDependencyProvider::PLUGINS_ACL_ROLE_POST_SAVE);
}

/**
* @return array<\Spryker\Zed\AclExtension\Dependency\Plugin\AclAccessCheckerStrategyPluginInterface>
*/
public function getAclAccessCheckerStrategyPlugins(): array
{
return $this->getProvidedDependency(AclDependencyProvider::PLUGINS_ACL_ACCESS_CHECKER_STRATEGY);
}
}
17 changes: 17 additions & 0 deletions src/Spryker/Zed/Acl/Business/AclFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

namespace Spryker\Zed\Acl\Business;

use Generated\Shared\Transfer\AclUserHasGroupCollectionTransfer;
use Generated\Shared\Transfer\AclUserHasGroupCriteriaTransfer;
use Generated\Shared\Transfer\GroupCriteriaTransfer;
use Generated\Shared\Transfer\GroupTransfer;
use Generated\Shared\Transfer\NavigationItemCollectionTransfer;
Expand Down Expand Up @@ -613,4 +615,19 @@ public function isIgnorable($bundle, $controller, $action)
->createRuleModel()
->isIgnorable($bundle, $controller, $action);
}

/**
* {@inheritDoc}
*
* @api
*
* @param \Generated\Shared\Transfer\AclUserHasGroupCriteriaTransfer $aclUserHasGroupCriteriaTransfer
*
* @return \Generated\Shared\Transfer\AclUserHasGroupCollectionTransfer
*/
public function getAclUserHasGroupCollection(
AclUserHasGroupCriteriaTransfer $aclUserHasGroupCriteriaTransfer
): AclUserHasGroupCollectionTransfer {
return $this->getRepository()->getAclUserHasGroupCollection($aclUserHasGroupCriteriaTransfer);
}
}
19 changes: 19 additions & 0 deletions src/Spryker/Zed/Acl/Business/AclFacadeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

namespace Spryker\Zed\Acl\Business;

use Generated\Shared\Transfer\AclUserHasGroupCollectionTransfer;
use Generated\Shared\Transfer\AclUserHasGroupCriteriaTransfer;
use Generated\Shared\Transfer\GroupCriteriaTransfer;
use Generated\Shared\Transfer\GroupTransfer;
use Generated\Shared\Transfer\NavigationItemCollectionTransfer;
Expand Down Expand Up @@ -483,4 +485,21 @@ public function filterNavigationItemCollectionByAccessibility(
* @return bool
*/
public function isIgnorable($bundle, $controller, $action);

/**
* Specification:
* - Retrieves ACL user group entities from Persistence.
* - Uses `AclUserHasGroupCriteria.aclUserHasGroupConditions.groupNames` to filter by ACL group names.
* - Uses `AclUserHasGroupCriteria.aclUserHasGroupConditions.userIds` to filter by user IDs.
* - Returns `AclUserHasGroupCollectionTransfer` filled with found ACL user group.
*
* @api
*
* @param \Generated\Shared\Transfer\AclUserHasGroupCriteriaTransfer $aclUserHasGroupCriteriaTransfer
*
* @return \Generated\Shared\Transfer\AclUserHasGroupCollectionTransfer
*/
public function getAclUserHasGroupCollection(
AclUserHasGroupCriteriaTransfer $aclUserHasGroupCriteriaTransfer
): AclUserHasGroupCollectionTransfer;
}
43 changes: 42 additions & 1 deletion src/Spryker/Zed/Acl/Business/Model/Rule.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,25 +58,33 @@ class Rule implements RuleInterface
*/
protected $rulesTransferCache = [];

/**
* @var array<\Spryker\Zed\AclExtension\Dependency\Plugin\AclAccessCheckerStrategyPluginInterface>
*/
protected array $aclAccessCheckerStrategyPlugins;

/**
* @param \Spryker\Zed\Acl\Business\Model\GroupInterface $group
* @param \Spryker\Zed\Acl\Persistence\AclQueryContainerInterface $queryContainer
* @param \Spryker\Zed\Acl\Dependency\Facade\AclToUserInterface $facadeUser
* @param \Spryker\Zed\Acl\Business\Model\RuleValidatorInterface $rulesValidator
* @param \Spryker\Zed\Acl\AclConfig $config
* @param array<\Spryker\Zed\AclExtension\Dependency\Plugin\AclAccessCheckerStrategyPluginInterface> $aclAccessCheckerStrategyPlugins
*/
public function __construct(
GroupInterface $group,
AclQueryContainerInterface $queryContainer,
AclToUserInterface $facadeUser,
RuleValidatorInterface $rulesValidator,
AclConfig $config
AclConfig $config,
array $aclAccessCheckerStrategyPlugins
) {
$this->group = $group;
$this->queryContainer = $queryContainer;
$this->userFacade = $facadeUser;
$this->rulesValidator = $rulesValidator;
$this->config = $config;
$this->aclAccessCheckerStrategyPlugins = $aclAccessCheckerStrategyPlugins;
}

/**
Expand Down Expand Up @@ -328,6 +336,11 @@ public function isAllowed(UserTransfer $userTransfer, $bundle, $controller, $act

$this->provideUserRuleWhitelist();

$isAllowed = $this->executeAclAccessCheckerStrategyPlugins($userTransfer, $bundle, $controller, $action);
if ($isAllowed !== null) {
return $isAllowed;
}

foreach ($groupsTransfer->getGroups() as $groupTransfer) {
$rulesTransfer = $this->getRulesTransferByIdGroup($groupTransfer->getIdAclGroup());

Expand Down Expand Up @@ -393,4 +406,32 @@ protected function provideUserRuleWhitelist()
$this->rulesValidator->addRule($rulesTransfer);
}
}

/**
* @param \Generated\Shared\Transfer\UserTransfer $userTransfer
* @param string $bundle
* @param string $controller
* @param string $action
*
* @return bool|null
*/
protected function executeAclAccessCheckerStrategyPlugins(
UserTransfer $userTransfer,
string $bundle,
string $controller,
string $action
): ?bool {
$isAllowed = null;
$ruleTransfer = (new RuleTransfer())->setBundle($bundle)->setAction($action)->setController($controller);

foreach ($this->aclAccessCheckerStrategyPlugins as $aclAccessCheckerStrategyPlugin) {
if ($aclAccessCheckerStrategyPlugin->isApplicable($userTransfer, $ruleTransfer)) {
$isAllowed = $aclAccessCheckerStrategyPlugin->checkAccess($userTransfer, $ruleTransfer);

break;
}
}

return $isAllowed;
}
}
51 changes: 51 additions & 0 deletions src/Spryker/Zed/Acl/Persistence/AclRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
namespace Spryker\Zed\Acl\Persistence;

use Generated\Shared\Transfer\AclRoleCriteriaTransfer;
use Generated\Shared\Transfer\AclUserHasGroupCollectionTransfer;
use Generated\Shared\Transfer\AclUserHasGroupCriteriaTransfer;
use Generated\Shared\Transfer\GroupCriteriaTransfer;
use Generated\Shared\Transfer\GroupTransfer;
use Generated\Shared\Transfer\RoleTransfer;
use Orm\Zed\Acl\Persistence\SpyAclUserHasGroupQuery;
use Spryker\Zed\Kernel\Persistence\AbstractRepository;

/**
Expand Down Expand Up @@ -61,4 +64,52 @@ public function findRole(AclRoleCriteriaTransfer $aclRoleCriteriaTransfer): ?Rol
->createAclMapper()
->mapAclRoleEntityToRoleTransfer($aclRoleEntity, new RoleTransfer());
}

/**
* @param \Generated\Shared\Transfer\AclUserHasGroupCriteriaTransfer $aclUserHasGroupCriteriaTransfer
*
* @return \Generated\Shared\Transfer\AclUserHasGroupCollectionTransfer
*/
public function getAclUserHasGroupCollection(
AclUserHasGroupCriteriaTransfer $aclUserHasGroupCriteriaTransfer
): AclUserHasGroupCollectionTransfer {
$userHasGroupQuery = $this->getFactory()->createUserHasGroupQuery();
$userHasGroupQuery = $this->applyAclUserHasGroupFilters($userHasGroupQuery, $aclUserHasGroupCriteriaTransfer);

return $this->getFactory()
->createAclMapper()
->mapAclUserHasGroupEntitiesToAclUserHasGroupCollectionTransfer(
$userHasGroupQuery->find(),
new AclUserHasGroupCollectionTransfer(),
);
}

/**
* @param \Orm\Zed\Acl\Persistence\SpyAclUserHasGroupQuery $aclUserHasGroupQuery
* @param \Generated\Shared\Transfer\AclUserHasGroupCriteriaTransfer $aclUserHasGroupCriteriaTransfer
*
* @return \Orm\Zed\Acl\Persistence\SpyAclUserHasGroupQuery
*/
protected function applyAclUserHasGroupFilters(
SpyAclUserHasGroupQuery $aclUserHasGroupQuery,
AclUserHasGroupCriteriaTransfer $aclUserHasGroupCriteriaTransfer
): SpyAclUserHasGroupQuery {
$aclUserHasGroupConditionsTransfer = $aclUserHasGroupCriteriaTransfer->getAclUserHasGroupConditions();

if (!$aclUserHasGroupConditionsTransfer) {
return $aclUserHasGroupQuery;
}

if ($aclUserHasGroupConditionsTransfer->getGroupNames()) {
$aclUserHasGroupQuery->useSpyAclGroupQuery()
->filterByName_In($aclUserHasGroupConditionsTransfer->getGroupNames())
->endUse();
}

if ($aclUserHasGroupConditionsTransfer->getUserIds()) {
$aclUserHasGroupQuery->filterByFkUser_In($aclUserHasGroupConditionsTransfer->getUserIds());
}

return $aclUserHasGroupQuery;
}
}
11 changes: 11 additions & 0 deletions src/Spryker/Zed/Acl/Persistence/AclRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
namespace Spryker\Zed\Acl\Persistence;

use Generated\Shared\Transfer\AclRoleCriteriaTransfer;
use Generated\Shared\Transfer\AclUserHasGroupCollectionTransfer;
use Generated\Shared\Transfer\AclUserHasGroupCriteriaTransfer;
use Generated\Shared\Transfer\GroupCriteriaTransfer;
use Generated\Shared\Transfer\GroupTransfer;
use Generated\Shared\Transfer\RoleTransfer;
Expand All @@ -27,4 +29,13 @@ public function findGroup(GroupCriteriaTransfer $groupCriteriaTransfer): ?GroupT
* @return \Generated\Shared\Transfer\RoleTransfer|null
*/
public function findRole(AclRoleCriteriaTransfer $aclRoleCriteriaTransfer): ?RoleTransfer;

/**
* @param \Generated\Shared\Transfer\AclUserHasGroupCriteriaTransfer $aclUserHasGroupCriteriaTransfer
*
* @return \Generated\Shared\Transfer\AclUserHasGroupCollectionTransfer
*/
public function getAclUserHasGroupCollection(
AclUserHasGroupCriteriaTransfer $aclUserHasGroupCriteriaTransfer
): AclUserHasGroupCollectionTransfer;
}
43 changes: 43 additions & 0 deletions src/Spryker/Zed/Acl/Persistence/Propel/Mapper/AclMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@

namespace Spryker\Zed\Acl\Persistence\Propel\Mapper;

use Generated\Shared\Transfer\AclUserHasGroupCollectionTransfer;
use Generated\Shared\Transfer\AclUserHasGroupTransfer;
use Generated\Shared\Transfer\GroupTransfer;
use Generated\Shared\Transfer\RoleTransfer;
use Generated\Shared\Transfer\UserTransfer;
use Orm\Zed\Acl\Persistence\SpyAclGroup;
use Orm\Zed\Acl\Persistence\SpyAclRole;
use Orm\Zed\Acl\Persistence\SpyAclUserHasGroup;
use Propel\Runtime\Collection\ObjectCollection;

class AclMapper
{
Expand Down Expand Up @@ -65,4 +70,42 @@ public function mapAclRoleTransferToRoleEntity(RoleTransfer $roleTransfer, SpyAc

return $aclRoleEntity;
}

/**
* @param \Propel\Runtime\Collection\ObjectCollection<\Orm\Zed\Acl\Persistence\SpyAclUserHasGroup> $aclUserHasGroupEntities
* @param \Generated\Shared\Transfer\AclUserHasGroupCollectionTransfer $aclUserHasGroupCollectionTransfer
*
* @return \Generated\Shared\Transfer\AclUserHasGroupCollectionTransfer
*/
public function mapAclUserHasGroupEntitiesToAclUserHasGroupCollectionTransfer(
ObjectCollection $aclUserHasGroupEntities,
AclUserHasGroupCollectionTransfer $aclUserHasGroupCollectionTransfer
): AclUserHasGroupCollectionTransfer {
foreach ($aclUserHasGroupEntities as $aclUserHasGroupEntity) {
$aclUserHasGroupCollectionTransfer->addAclUserHasGroup(
$this->mapAclUserHasGroupEntityToAclUserHasGroupTransfer(
$aclUserHasGroupEntity,
new AclUserHasGroupTransfer(),
),
);
}

return $aclUserHasGroupCollectionTransfer;
}

/**
* @param \Orm\Zed\Acl\Persistence\SpyAclUserHasGroup $aclUserHasGroupEntity
* @param \Generated\Shared\Transfer\AclUserHasGroupTransfer $aclUserHasGroupTransfer
*
* @return \Generated\Shared\Transfer\AclUserHasGroupTransfer
*/
protected function mapAclUserHasGroupEntityToAclUserHasGroupTransfer(
SpyAclUserHasGroup $aclUserHasGroupEntity,
AclUserHasGroupTransfer $aclUserHasGroupTransfer
): AclUserHasGroupTransfer {
$aclUserHasGroupTransfer->setUser((new UserTransfer())->setIdUser($aclUserHasGroupEntity->getFkUser()))
->setGroup((new GroupTransfer())->setIdAclGroup($aclUserHasGroupEntity->getFkAclGroup()));

return $aclUserHasGroupTransfer;
}
}
Loading

0 comments on commit 3ba7bed

Please sign in to comment.