Install the ACL feature
Edit on GitHubThis document describes how to install the ACL feature.
Prerequisites
Install the required features:
NAME | VERSION | INSTALLATION GUIDE |
---|---|---|
Spryker Core | 202404.0 | Install the Spryker Core feature |
Spryker Core Back Office | 202404.0 | Install the Spryker Core feature |
1) Install the required modules
composer require spryker-feature/acl:"202404.0" --update-with-dependencies
Make sure the following modules have been installed:
MODULE | EXPECTED DIRECTORY |
---|---|
Acl | vendor/spryker/acl |
AclDataImport | vendor/spryker/acl-data-import |
AclEntity | vendor/spryker/acl-entity |
AclEntityDataImport | vendor/spryker/acl-entity-data-import |
AclEntityExtension (optional) | vendor/spryker/acl-entity-extension |
AclExtension (optional) | vendor/spryker/acl-extension |
2) Set up the database schema
Apply database changes and to generate entity and transfer changes:
console transfer:generate
console propel:install
console transfer:generate
Make sure the following changes have been applied to the database:
DATABASE ENTITY | TYPE | EVENT |
---|---|---|
spy_acl_role | table | created |
spy_acl_rule | table | created |
spy_acl_group | table | created |
spy_acl_user_has_group | table | created |
spy_acl_groups_has_roles | table | created |
spy_acl_entity_segment | table | created |
spy_acl_entity_rule | table | created |
Make sure the following changes have been applied in transfer objects:
TRANSFER | TYPE | EVENT | PATH |
---|---|---|---|
Group | object | Created | src/Generated/Shared/Transfer/GroupTransfer |
AclEntityRule | object | Created | src/Generated/Shared/Transfer/AclEntityRuleTransfer |
AclEntitySegment | object | Created | src/Generated/Shared/Transfer/AclEntitySegmentTransfer |
AclEntitySegmentRequest | object | Created | src/Generated/Shared/Transfer/AclEntitySegmentRequestTransfer |
AclEntityRuleRequest | object | Created | src/Generated/Shared/Transfer/AclEntityRuleRequestTransfer |
AclEntityRuleCollection | object | Created | src/Generated/Shared/Transfer/AclEntityRuleCollectionTransfer |
AclEntitySegmentResponse | object | Created | src/Generated/Shared/Transfer/AclEntitySegmentResponseTransfer |
AclEntitySegmentCriteria | object | Created | src/Generated/Shared/Transfer/AclEntitySegmentCriteriaTransfer |
AclEntityRuleCriteria | object | Created | src/Generated/Shared/Transfer/AclEntityRuleCriteriaTransfer |
AclEntityRuleResponse | object | Created | src/Generated/Shared/Transfer/AclEntityRuleResponseTransfer |
AclEntityMetadata | object | Created | src/Generated/Shared/Transfer/AclEntityMetadataTransfer |
AclEntityParentMetadata | object | Created | src/Generated/Shared/Transfer/AclEntityParentMetadataTransfer |
AclEntityParentConnectionMetadata | object | Created | src/Generated/Shared/Transfer/AclEntityParentConnectionMetadataTransfer |
AclEntityMetadataCollection | object | Created | src/Generated/Shared/Transfer/AclEntityMetadataCollectionTransfer |
AclEntityMetadataConfig | object | Created | src/Generated/Shared/Transfer/AclEntityMetadataConfigTransfer |
AclRoleCriteria | object | Created | src/Generated/Shared/Transfer/AclRoleCriteriaTransfer |
GroupCriteria | object | Created | src/Generated/Shared/Transfer/GroupCriteriaTransfer |
Groups | object | Created | src/Generated/Shared/Transfer/GroupsTransfer |
Role | object | Created | src/Generated/Shared/Transfer/RoleTransfer |
Roles | object | Created | src/Generated/Shared/Transfer/RolesTransfer |
Rule | object | Created | src/Generated/Shared/Transfer/RuleTransfer |
Rules | object | Created | src/Generated/Shared/Transfer/Transfer |
User | object | Created | src/Generated/Shared/Transfer/UserTransfer |
NavigationItem | object | Created | src/Generated/Shared/Transfer/NavigationItemTransfer |
NavigationItemCollection | object | Created | src/Generated/Shared/Transfer/NavigationItemCollection |
AclUserHasGroupCollection | object | Created | src/Generated/Shared/Transfer/AclUserHasGroupCollection |
AclUserHasGroup | object | Created | src/Generated/Shared/Transfer/AclUserHasGroup |
AclUserHasGroupCriteria | object | Created | src/Generated/Shared/Transfer/AclUserHasGroupCriteria |
AclUserHasGroupConditions | object | Created | src/Generated/Shared/Transfer/AclUserHasGroupConditions |
4) Import the ACL groups and roles
- Prepare your data according to your requirements using our demo data:
data/import/common/common/acl_group.csv
>name,reference
root_group,root_group
COLUMN | REQUIRED | DATA TYPE | DATA EXAMPLE | DATA EXPLANATION |
---|---|---|---|---|
name | ✓ | string | root_group | The name of the ACL group. |
reference | x | string | root_group | Key of the ACL group that is used as a reference in the data import. |
data/import/common/common/acl_role.csv
>name,reference
root_role,root_role
COLUMN | REQUIRED | DATA TYPE | DATA EXAMPLE | DATA EXPLANATION |
---|---|---|---|---|
name | ✓ | string | root_role | The name of the ACL role. |
reference | x | string | root_role | Key of the ACL role that is used as a reference in the data import. |
data/import/common/common/acl_group_role.csv
>group_name,role_name
root_group,root_role
COLUMN | REQUIRED | DATA TYPE | DATA EXAMPLE | DATA EXPLANATION |
---|---|---|---|---|
group_name | ✓ | string | root_group | The name of the ACL group. |
role_name | ✓ | string | root_role | The name of the ACL role. |
- Extend the data import configuration:
/data/import/local/full_EU.yml
# ...
# Acl import
- data_entity: acl-role
source: data/import/common/common/acl_role.csv
- data_entity: acl-group
source: data/import/common/common/acl_group.csv
- data_entity: acl-group-role
source: data/import/common/common/acl_group_role.csv
- Register the following data import plugins:
PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
---|---|---|---|
AclGroupDataImportPlugin | Imports ACL group data from the specified file. | \Spryker\Zed\AclDataImport\Communication\Plugin | |
AclRoleDataImportPlugin | Imports ACL role data from the specified file. | \Spryker\Zed\AclDataImport\Communication\Plugin | |
AclGroupRoleDataImportPlugin | Imports the connection between ACL role and ACL group from the specified file. | \Spryker\Zed\AclDataImport\Communication\Plugin |
src/Pyz/Zed/DataImport/DataImportDependencyProvider.php
<?php
namespace Pyz\Zed\DataImport;
use Spryker\Zed\DataImport\DataImportDependencyProvider as SprykerDataImportDependencyProvider;
use Spryker\Zed\AclDataImport\Communication\Plugin\AclGroupDataImportPlugin;
use Spryker\Zed\AclDataImport\Communication\Plugin\AclGroupRoleDataImportPlugin;
use Spryker\Zed\AclDataImport\Communication\Plugin\AclRoleDataImportPlugin;
class DataImportDependencyProvider extends SprykerDataImportDependencyProvider
{
/**
* @return list<\Spryker\Zed\DataImport\Dependency\Plugin\DataImportPluginInterface>
*/
protected function getDataImporterPlugins(): array
{
return [
new AclGroupDataImportPlugin(),
new AclRoleDataImportPlugin(),
new AclGroupRoleDataImportPlugin(),
];
}
}
- Enable the behaviors by registering the console commands:
src/Pyz/Zed/Console/ConsoleDependencyProvider.php
<?php
namespace Pyz\Zed\Console;
use Spryker\Zed\Kernel\Container;
use Spryker\Zed\Console\ConsoleDependencyProvider as SprykerConsoleDependencyProvider;
use Spryker\Zed\DataImport\Communication\Console\DataImportConsole;
use Spryker\Zed\AclDataImport\AclDataImportConfig;
class ConsoleDependencyProvider extends SprykerConsoleDependencyProvider
{
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return list<\Symfony\Component\Console\Command\Command>
*/
protected function getConsoleCommands(Container $container)
{
$commands = [
new DataImportConsole(DataImportConsole::DEFAULT_NAME . static::COMMAND_SEPARATOR . AclDataImportConfig::IMPORT_TYPE_ACL_GROUP),
new DataImportConsole(DataImportConsole::DEFAULT_NAME . static::COMMAND_SEPARATOR . AclDataImportConfig::IMPORT_TYPE_ACL_ROLE),
new DataImportConsole(DataImportConsole::DEFAULT_NAME . static::COMMAND_SEPARATOR . AclDataImportConfig::IMPORT_TYPE_ACL_GROUP_ROLE),
];
return $commands;
}
}
- Run the following commands to import the data:
console data:import:data:import:acl-role
console data:import:data:import:acl-group
console data:import:data:import:acl-group-role
Make sure the configured data has been added to the following database tables:
spy_acl_group
spy_acl_role
spy_acl_groups_has_roles
5) Set up behavior
- Enable the following behaviors by registering the plugins:
PLUGIN | DESCRIPTION | PREREQUISITES | NAMESPACE |
---|---|---|---|
AccessControlEventDispatcherPlugin | Adds a listener to \Symfony\Component\HttpKernel\KernelEvents::REQUEST which checks if the user is allowed to access the current resource. |
Spryker\Zed\Acl\Communication\Plugin\EventDispatcher | |
AclNavigationItemCollectionFilterPlugin | Checks if the navigation item can be accessed by the current user. | Spryker\Zed\Acl\Communication\Plugin\Navigation | |
AclInstallerPlugin | Fills the database with required ACL data. | Spryker\Zed\Acl\Communication\Plugin | |
GroupPlugin | Provides Acl Groups for User. | Spryker\Zed\Acl\Communication\Plugin | |
AclEntityAclRolePostSavePlugin | Saves RoleTransfer.aclEntityRules to database. |
Spryker\Zed\AclEntity\Communication\Plugin\Acl | |
AclRulesAclRolesExpanderPlugin | Expands the Roles transfer object with ACL rules. |
Spryker\Zed\AclEntity\Communication\Plugin\Acl | |
AclEntityApplicationPlugin | Enables ACL for the whole Application. | Spryker\Zed\AclEntity\Communication\Plugin\Application |
src/Pyz/Zed/EventDispatcher/EventDispatcherDependencyProvider.php
<?php
namespace Pyz\Zed\EventDispatcher;
use Spryker\Zed\Acl\Communication\Plugin\EventDispatcher\AccessControlEventDispatcherPlugin;
use Spryker\Zed\EventDispatcher\EventDispatcherDependencyProvider as SprykerEventDispatcherDependencyProvider;
class EventDispatcherDependencyProvider extends SprykerEventDispatcherDependencyProvider
{
/**
* @return array<\Spryker\Shared\EventDispatcherExtension\Dependency\Plugin\EventDispatcherPluginInterface>
*/
protected function getEventDispatcherPlugins(): array
{
return [
new AccessControlEventDispatcherPlugin(),
];
}
}
src/Pyz/Zed/ZedNavigation/ZedNavigationDependencyProvider.php
<?php
namespace Pyz\Zed\ZedNavigation;
use Spryker\Zed\Acl\Communication\Plugin\Navigation\AclNavigationItemCollectionFilterPlugin;
use Spryker\Zed\ZedNavigation\ZedNavigationDependencyProvider as SprykerZedNavigationDependencyProvider;
class ZedNavigationDependencyProvider extends SprykerZedNavigationDependencyProvider
{
/**
* @return array<\Spryker\Zed\ZedNavigationExtension\Dependency\Plugin\NavigationItemCollectionFilterPluginInterface>
*/
protected function getNavigationItemCollectionFilterPlugins(): array
{
return [
new AclNavigationItemCollectionFilterPlugin(),
];
}
}
src/Pyz/Zed/Installer/InstallerDependencyProvider.php
<?php
namespace Pyz\Zed\Installer;
use Spryker\Zed\Acl\Communication\Plugin\AclInstallerPlugin;
use Spryker\Zed\Installer\InstallerDependencyProvider as SprykerInstallerDependencyProvider;
class InstallerDependencyProvider extends SprykerInstallerDependencyProvider
{
/**
* @return array<\Spryker\Zed\Installer\Dependency\Plugin\InstallerPluginInterface>
*/
public function getInstallerPlugins()
{
return [
new AclInstallerPlugin(),
];
}
}
src/Pyz/Zed/User/UserDependencyProvider.php
<?php
namespace Pyz\Zed\User;
use Spryker\Zed\Acl\Communication\Plugin\GroupPlugin;
use Spryker\Zed\Kernel\Container;
use Spryker\Zed\User\UserDependencyProvider as SprykerUserDependencyProvider;
class InstallerDependencyProvider extends SprykerUserDependencyProvider
{
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\Kernel\Container
*/
protected function addGroupPlugin(Container $container)
{
$container->set(static::PLUGIN_GROUP, function (Container $container) {
return new GroupPlugin();
});
return $container;
}
}
src/Pyz/Zed/Acl/AclDependencyProvider.php
<?php
namespace Pyz\Zed\Acl;
use Spryker\Zed\Acl\AclDependencyProvider as SprykerAclDependencyProvider;
use Spryker\Zed\AclEntity\Communication\Plugin\Acl\AclEntityAclRolePostSavePlugin;
use Spryker\Zed\AclEntity\Communication\Plugin\Acl\AclRulesAclRolesExpanderPlugin;
class AclDependencyProvider extends SprykerAclDependencyProvider
{
/**
* @return array<\Spryker\Zed\AclExtension\Dependency\Plugin\AclRolesExpanderPluginInterface>
*/
protected function getAclRolesExpanderPlugins(): array
{
return [
new AclRulesAclRolesExpanderPlugin(),
];
}
/**
* @return array<\Spryker\Zed\AclExtension\Dependency\Plugin\AclRolePostSavePluginInterface>
*/
protected function getAclRolePostSavePlugins(): array
{
return [
new AclEntityAclRolePostSavePlugin(),
];
}
}
- To enable the ACL Entity feature for the
MerchantPortalApplication
, register theAclEntityApplicationPlugin
plugin. The ACL Entity feature lets you manage access to the entities in the store of different merchants separately.
src/Pyz/Zed/MerchantPortalApplication/MerchantPortalApplicationDependencyProvider.php
<?php
namespace Pyz\Zed\MerchantPortalApplication;
use Spryker\Zed\AclEntity\Communication\Plugin\Application\AclEntityApplicationPlugin;
use Spryker\Zed\MerchantPortalApplication\MerchantPortalApplicationDependencyProvider as SprykerMerchantPortalApplicationDependencyProvider;
class MerchantPortalApplicationDependencyProvider extends SprykerMerchantPortalApplicationDependencyProvider
{
/**
* @return array<\Spryker\Shared\ApplicationExtension\Dependency\Plugin\ApplicationPluginInterface>
*/
protected function getMerchantPortalApplicationPlugins(): array
{
return [
new AclEntityApplicationPlugin(),
];
}
}
6) Install the database data for ACL
console setup:init-db
Make sure the following works correctly:
- The request to access the Merchant Portal doesn’t succeed for users without permissions.
- The marketplace user can see only the allowed Merchant Portal menu links.
- The
spy_acl_role
,spy_acl_group
, andspy_acl_user_has_group
tables contain default data. - You can edit a user’s ACL groups when editing users in the Back Office.
- When a
RoleTransfer
is saved and containsAclEntityRules
,AclEntityRule
is created inspy_acl_entity_rule
. RolesTransfer
contains the neededAclEntityRules
.- Users without permissions to access an entity or endpoint can’t access them.
Thank you!
For submitting the form