Skip to content
Snippets Groups Projects
Commit c4024bf4 authored by Groß-Vogt, Tobias's avatar Groß-Vogt, Tobias
Browse files

new AuthorizationConfigDefinition to simplify config of authorization

parent 6190de8b
No related branches found
No related tags found
No related merge requests found
Pipeline #232252 failed
...@@ -6,9 +6,6 @@ namespace Dbp\Relay\CoreBundle\Authorization; ...@@ -6,9 +6,6 @@ namespace Dbp\Relay\CoreBundle\Authorization;
use Dbp\Relay\CoreBundle\API\UserSessionInterface; use Dbp\Relay\CoreBundle\API\UserSessionInterface;
use Dbp\Relay\CoreBundle\Exception\ApiError; use Dbp\Relay\CoreBundle\Exception\ApiError;
use Dbp\Relay\CoreBundle\Helpers\Tools;
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface; use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
...@@ -18,21 +15,7 @@ abstract class AbstractAuthorizationService implements ContextAwareNormalizerInt ...@@ -18,21 +15,7 @@ abstract class AbstractAuthorizationService implements ContextAwareNormalizerInt
{ {
use NormalizerAwareTrait; use NormalizerAwareTrait;
/* config array keys */
private const AUTHORIZATION_ROOT_CONFIG_NODE = 'authorization';
private const ROLES_CONFIG_NODE = 'roles';
private const ATTRIBUTES_CONFIG_NODE = 'attributes';
private const ENTITIES_CONFIG_NODE = 'entities';
private const ENTITY_READ_ACCESS_CONFIG_NODE = 'read_access';
private const ENTITY_WRITE_ACCESS_CONFIG_NODE = 'write_access';
private const ENTITY_CLASS_NAME_CONFIG_NODE = 'class_name';
/* internal array keys */ /* internal array keys */
private const ROLES_KEY = 'roles';
private const ATTRIBUTES_KEY = 'attributes';
private const ENTITIES_KEY = 'entities';
private const ENTITY_READ_ACCESS_KEY = 'read_access';
private const ENTITY_WRITE_ACCESS_KEY = 'write_access';
private const ENTITY_SHORT_NAME_KEY = 'short_name'; private const ENTITY_SHORT_NAME_KEY = 'short_name';
private const ENTITY_CLASS_NAME_KEY = 'class_name'; private const ENTITY_CLASS_NAME_KEY = 'class_name';
...@@ -69,15 +52,15 @@ abstract class AbstractAuthorizationService implements ContextAwareNormalizerInt ...@@ -69,15 +52,15 @@ abstract class AbstractAuthorizationService implements ContextAwareNormalizerInt
public function setConfig(array $config) public function setConfig(array $config)
{ {
$this->config = $config[self::AUTHORIZATION_ROOT_CONFIG_NODE] ?? []; $this->config = $config[AuthorizationConfigDefinition::AUTHORIZATION_CONFIG_NODE] ?? [];
$this->loadConfig(); $this->loadConfig();
} }
public function configure(array $roleMapping = [], array $attributeMapping = []): void public function configure(array $roleMapping = [], array $attributeMapping = []): void
{ {
$this->config = [ $this->config = [
self::ROLES_CONFIG_NODE => $roleMapping, AuthorizationConfigDefinition::ROLES_CONFIG_NODE => $roleMapping,
self::ATTRIBUTES_CONFIG_NODE => $attributeMapping, AuthorizationConfigDefinition::ATTRIBUTES_CONFIG_NODE => $attributeMapping,
]; ];
$this->loadConfig(); $this->loadConfig();
} }
...@@ -155,11 +138,11 @@ abstract class AbstractAuthorizationService implements ContextAwareNormalizerInt ...@@ -155,11 +138,11 @@ abstract class AbstractAuthorizationService implements ContextAwareNormalizerInt
private function loadConfig() private function loadConfig()
{ {
if ($this->userAuthorizationChecker !== null && $this->config !== null) { if ($this->userAuthorizationChecker !== null && $this->config !== null) {
$roleExpressions = $this->config[self::ROLES_CONFIG_NODE] ?? []; $roleExpressions = $this->config[AuthorizationConfigDefinition::ROLES_CONFIG_NODE] ?? [];
$attributeExpressions = $this->config[self::ATTRIBUTES_CONFIG_NODE] ?? []; $attributeExpressions = $this->config[AuthorizationConfigDefinition::ATTRIBUTES_CONFIG_NODE] ?? [];
if (isset($this->config[self::ENTITIES_CONFIG_NODE])) { if (isset($this->config[AuthorizationConfigDefinition::ENTITIES_CONFIG_NODE])) {
$entitiesRoleExpressions = $this->loadEntityConfig($this->config[self::ENTITIES_CONFIG_NODE]); $entitiesRoleExpressions = $this->loadEntityConfig($this->config[AuthorizationConfigDefinition::ENTITIES_CONFIG_NODE]);
$roleExpressions = array_merge($roleExpressions, $entitiesRoleExpressions); $roleExpressions = array_merge($roleExpressions, $entitiesRoleExpressions);
} }
...@@ -171,9 +154,9 @@ abstract class AbstractAuthorizationService implements ContextAwareNormalizerInt ...@@ -171,9 +154,9 @@ abstract class AbstractAuthorizationService implements ContextAwareNormalizerInt
{ {
$roleExpressions = []; $roleExpressions = [];
foreach ($entitiesConfigNode as $entityShortName => $entityNode) { foreach ($entitiesConfigNode as $entityShortName => $entityNode) {
$entityClassName = $entityNode[self::ENTITY_CLASS_NAME_CONFIG_NODE]; $entityClassName = $entityNode[AuthorizationConfigDefinition::ENTITY_CLASS_NAME_CONFIG_NODE];
$attributeNames = []; $attributeNames = [];
foreach ($entityNode[self::ENTITY_READ_ACCESS_CONFIG_NODE] ?? [] as $attributeName => $attributeAuthorizationExpression) { foreach ($entityNode[AuthorizationConfigDefinition::ENTITY_READ_ACCESS_CONFIG_NODE] ?? [] as $attributeName => $attributeAuthorizationExpression) {
$roleExpressions[self::toAttributeId($entityShortName, $attributeName)] = $attributeAuthorizationExpression; $roleExpressions[self::toAttributeId($entityShortName, $attributeName)] = $attributeAuthorizationExpression;
$attributeNames[] = $attributeName; $attributeNames[] = $attributeName;
} }
...@@ -199,95 +182,6 @@ abstract class AbstractAuthorizationService implements ContextAwareNormalizerInt ...@@ -199,95 +182,6 @@ abstract class AbstractAuthorizationService implements ContextAwareNormalizerInt
return $this->userAuthorizationChecker->isGranted($this->currentAuthorizationUser, $rightName, $object, $objectAlias); return $this->userAuthorizationChecker->isGranted($this->currentAuthorizationUser, $rightName, $object, $objectAlias);
} }
/**
* Create the 'authorization' config node definition with the given config definition.
*/
public static function getAuthorizationConfigNodeDefinition(array $configDefinition): NodeDefinition
{
$treeBuilder = new TreeBuilder(self::AUTHORIZATION_ROOT_CONFIG_NODE);
$rightsNodeChildBuilder = $treeBuilder->getRootNode()->children()->arrayNode(self::ROLES_CONFIG_NODE)
->addDefaultsIfNotSet()
->children();
foreach ($configDefinition[self::ROLES_KEY] ?? [] as $roleDefinition) {
$rightsNodeChildBuilder->scalarNode($roleDefinition[0])
->defaultValue($roleDefinition[1] ?? 'false')
->info($roleDefinition[2] ?? '')
->end();
}
$attributesNodeChildBuilder = $treeBuilder->getRootNode()->children()->arrayNode(self::ATTRIBUTES_CONFIG_NODE)
->addDefaultsIfNotSet()
->children();
foreach ($configDefinition[self::ATTRIBUTES_KEY] ?? [] as $attributeDefinition) {
$attributesNodeChildBuilder->scalarNode($attributeDefinition[0])
->defaultValue($attributeDefinition[1] ?? 'null')
->info($attributeDefinition[2] ?? '')
->end();
}
$entitiesNodeChildBuilder = $treeBuilder->getRootNode()->children()->arrayNode(self::ENTITIES_CONFIG_NODE)
->children();
foreach ($configDefinition[self::ENTITIES_KEY] ?? [] as $entityDefinition) {
$entityChildBuilder = $entitiesNodeChildBuilder->arrayNode($entityDefinition[self::ENTITY_SHORT_NAME_KEY])
->children();
$entityChildBuilder->scalarNode(self::ENTITY_CLASS_NAME_CONFIG_NODE)
->defaultValue($entityDefinition[self::ENTITY_CLASS_NAME_KEY])
->info('The entity class name. There is no need to change the default value.')
->end();
$entityReadAccessChildBuilder = $entityChildBuilder->arrayNode(self::ENTITY_READ_ACCESS_CONFIG_NODE)
->children();
foreach ($entityDefinition[self::ENTITY_READ_ACCESS_KEY] ?? [] as $attributeName) {
$entityReadAccessChildBuilder->scalarNode($attributeName)
->defaultValue('false')
->info(sprintf('The conditional reader role expression for attribute \'%s\'.', $attributeName))
->end();
}
$entityWriteAccessChildBuilder = $entitiesNodeChildBuilder->arrayNode(self::ENTITY_WRITE_ACCESS_CONFIG_NODE)
->children();
foreach ($entityDefinition[self::ENTITY_WRITE_ACCESS_KEY] ?? [] as $attributeName) {
$entityWriteAccessChildBuilder->scalarNode($attributeName)
->defaultValue('false')
->info(sprintf('The conditional writer role expression for attribute \'%s\'.', $attributeName))
->end();
}
}
return $treeBuilder->getRootNode();
}
public static function configDefinitionCreate(): array
{
return [];
}
public static function configDefinitionAddRole(array &$configDefinition, string $roleName, string $defaultExpression = 'false', string $info = ''): array
{
Tools::pushToSubarray($configDefinition, self::ROLES_KEY, [$roleName, $defaultExpression, $info]);
return $configDefinition;
}
public static function configDefinitionAddAttribute(array &$configDefinition, string $attributeName, string $defaultExpression = 'false', string $info = ''): array
{
Tools::pushToSubarray($configDefinition, self::ATTRIBUTES_KEY, [$attributeName, $defaultExpression, $info]);
return $configDefinition;
}
public static function configDefinitionAddEntity(array &$configDefinition, string $entityShortName, string $entityClassName, array $readAttributes = [], array $writeAttributes = []): array
{
Tools::pushToSubarray($configDefinition, self::ENTITIES_KEY, [
self::ENTITY_SHORT_NAME_KEY => $entityShortName,
self::ENTITY_CLASS_NAME_KEY => $entityClassName,
self::ENTITY_READ_ACCESS_KEY => $readAttributes,
self::ENTITY_WRITE_ACCESS_KEY => $writeAttributes,
]);
return $configDefinition;
}
private static function toAttributeId(string $entityShortName, string $attributeName): string private static function toAttributeId(string $entityShortName, string $attributeName): string
{ {
return $entityShortName.':'.$attributeName; return $entityShortName.':'.$attributeName;
......
<?php
declare(strict_types=1);
namespace Dbp\Relay\CoreBundle\Authorization;
use Dbp\Relay\CoreBundle\Helpers\Tools;
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
class AuthorizationConfigDefinition
{
/* config array keys */
public const AUTHORIZATION_CONFIG_NODE = 'authorization';
public const ROLES_CONFIG_NODE = 'roles';
public const ATTRIBUTES_CONFIG_NODE = 'attributes';
public const ENTITIES_CONFIG_NODE = 'entities';
public const ENTITY_READ_ACCESS_CONFIG_NODE = 'read_access';
public const ENTITY_WRITE_ACCESS_CONFIG_NODE = 'write_access';
public const ENTITY_CLASS_NAME_CONFIG_NODE = 'class_name';
private const ROLES_KEY = 'roles';
private const ATTRIBUTES_KEY = 'attributes';
private const ENTITIES_KEY = 'entities';
private const ENTITY_READ_ACCESS_KEY = 'read_access';
private const ENTITY_WRITE_ACCESS_KEY = 'write_access';
private const ENTITY_SHORT_NAME_KEY = 'short_name';
private const ENTITY_CLASS_NAME_KEY = 'class_name';
/** @var array */
private $configDefinition;
public static function create(): AuthorizationConfigDefinition
{
return new AuthorizationConfigDefinition();
}
public function __construct()
{
$this->configDefinition = [];
}
public function addRole(string $roleName, string $defaultExpression = 'false', string $info = ''): AuthorizationConfigDefinition
{
Tools::pushToSubarray($this->configDefinition, self::ROLES_KEY, [$roleName, $defaultExpression, $info]);
return $this;
}
public function addAttribute(string $attributeName, string $defaultExpression = 'false', string $info = ''): AuthorizationConfigDefinition
{
Tools::pushToSubarray($this->configDefinition, self::ATTRIBUTES_KEY, [$attributeName, $defaultExpression, $info]);
return $this;
}
public function addEntity(string $entityShortName, string $entityClassName, array $readAttributes = [], array $writeAttributes = []): AuthorizationConfigDefinition
{
Tools::pushToSubarray($this->configDefinition, self::ENTITIES_KEY, [
self::ENTITY_SHORT_NAME_KEY => $entityShortName,
self::ENTITY_CLASS_NAME_KEY => $entityClassName,
self::ENTITY_READ_ACCESS_KEY => $readAttributes,
self::ENTITY_WRITE_ACCESS_KEY => $writeAttributes,
]);
return $this;
}
public function getNodeDefinition(): NodeDefinition
{
$treeBuilder = new TreeBuilder(self::AUTHORIZATION_CONFIG_NODE);
$rightsNodeChildBuilder = $treeBuilder->getRootNode()->children()->arrayNode(self::ROLES_CONFIG_NODE)
->addDefaultsIfNotSet()
->children();
foreach ($this->configDefinition[self::ROLES_KEY] ?? [] as $roleDefinition) {
$rightsNodeChildBuilder->scalarNode($roleDefinition[0])
->defaultValue($roleDefinition[1] ?? 'false')
->info($roleDefinition[2] ?? '')
->end();
}
$attributesNodeChildBuilder = $treeBuilder->getRootNode()->children()->arrayNode(self::ATTRIBUTES_CONFIG_NODE)
->addDefaultsIfNotSet()
->children();
foreach ($this->configDefinition[self::ATTRIBUTES_KEY] ?? [] as $attributeDefinition) {
$attributesNodeChildBuilder->scalarNode($attributeDefinition[0])
->defaultValue($attributeDefinition[1] ?? 'null')
->info($attributeDefinition[2] ?? '')
->end();
}
$entitiesNodeChildBuilder = $treeBuilder->getRootNode()->children()->arrayNode(self::ENTITIES_CONFIG_NODE)
->children();
foreach ($this->configDefinition[self::ENTITIES_KEY] ?? [] as $entityDefinition) {
$entityChildBuilder = $entitiesNodeChildBuilder->arrayNode($entityDefinition[self::ENTITY_SHORT_NAME_KEY])
->children();
$entityChildBuilder->scalarNode(self::ENTITY_CLASS_NAME_CONFIG_NODE)
->defaultValue($entityDefinition[self::ENTITY_CLASS_NAME_KEY])
->info('The entity class name. There is no need to change the default value.')
->end();
$entityReadAccessChildBuilder = $entityChildBuilder->arrayNode(self::ENTITY_READ_ACCESS_CONFIG_NODE)
->children();
foreach ($entityDefinition[self::ENTITY_READ_ACCESS_KEY] ?? [] as $attributeName) {
$entityReadAccessChildBuilder->scalarNode($attributeName)
->defaultValue('false')
->info(sprintf('The conditional reader role expression for attribute \'%s\'.', $attributeName))
->end();
}
$entityWriteAccessChildBuilder = $entitiesNodeChildBuilder->arrayNode(self::ENTITY_WRITE_ACCESS_CONFIG_NODE)
->children();
foreach ($entityDefinition[self::ENTITY_WRITE_ACCESS_KEY] ?? [] as $attributeName) {
$entityWriteAccessChildBuilder->scalarNode($attributeName)
->defaultValue('false')
->info(sprintf('The conditional writer role expression for attribute \'%s\'.', $attributeName))
->end();
}
}
return $treeBuilder->getRootNode();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment