refs #436. Improvements
parent
f9bf9b6190
commit
e4e9e3c07f
|
@ -17,6 +17,9 @@ api_platform:
|
|||
mapping:
|
||||
paths: ['%kernel.project_dir%/config/api_platform', '%kernel.project_dir%/src/Dto']
|
||||
use_symfony_listeners: true
|
||||
collection:
|
||||
pagination:
|
||||
items_per_page_parameter_name: 'itemsPerPage'
|
||||
defaults:
|
||||
pagination_client_items_per_page: true
|
||||
denormalization_context:
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
imports:
|
||||
- { resource: 'services/api_platform.yaml' }
|
||||
|
||||
parameters:
|
||||
|
||||
services:
|
||||
|
|
|
@ -4,109 +4,93 @@ services:
|
|||
arguments:
|
||||
$properties: { 'id': ~, 'name': ~, 'serialNumber': ~ }
|
||||
$orderParameterName: 'order'
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.client.search:
|
||||
parent: 'api_platform.doctrine.orm.search_filter'
|
||||
arguments: [ { 'id': 'exact', 'name': 'partial', 'serialNumber': 'exact' } ]
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
arguments: [ { 'id': 'exact', 'name': 'partial', 'serialNumber': 'exact', organizationalUnit.id: 'exact' } ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.hardware.order:
|
||||
parent: 'api_platform.doctrine.orm.order_filter'
|
||||
arguments:
|
||||
$properties: { 'id': ~, 'name': ~ }
|
||||
$orderParameterName: 'order'
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.hardware.search:
|
||||
parent: 'api_platform.doctrine.orm.search_filter'
|
||||
arguments: [ { 'id': 'exact', 'name': 'partial' } ]
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.menu.order:
|
||||
parent: 'api_platform.doctrine.orm.order_filter'
|
||||
arguments:
|
||||
$properties: { 'id': ~, 'name': ~, 'title': ~ }
|
||||
$orderParameterName: 'order'
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.menu.search:
|
||||
parent: 'api_platform.doctrine.orm.search_filter'
|
||||
arguments: [ { 'id': 'exact', 'name': 'exact', 'title': 'exact' } ]
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.organizational_unit.order:
|
||||
parent: 'api_platform.doctrine.orm.order_filter'
|
||||
arguments:
|
||||
$properties: { 'id': ~, 'name': ~, 'type': ~ }
|
||||
$orderParameterName: 'order'
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.organizational_unit.search:
|
||||
parent: 'api_platform.doctrine.orm.search_filter'
|
||||
arguments: [ { 'id': 'exact', 'name': 'exact', 'type': 'exact' } ]
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
arguments: [ { id: 'exact', name: 'partial', type: 'exact', parent.id: 'exact'} ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.partition.order:
|
||||
parent: 'api_platform.doctrine.orm.order_filter'
|
||||
arguments:
|
||||
$properties: { 'id': ~, 'usage': ~ }
|
||||
$orderParameterName: 'order'
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.partition.search:
|
||||
parent: 'api_platform.doctrine.orm.search_filter'
|
||||
arguments: [ { 'id': 'exact', 'usage': 'exact', 'diskNumber': 'exact' } ]
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.user.order:
|
||||
parent: 'api_platform.doctrine.orm.order_filter'
|
||||
arguments:
|
||||
$properties: { 'id': ~, 'username': ~ }
|
||||
$orderParameterName: 'order'
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.user.search:
|
||||
parent: 'api_platform.doctrine.orm.search_filter'
|
||||
arguments: [ { 'id': 'exact', 'username': 'partial' } ]
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.user.boolean:
|
||||
parent: 'api_platform.doctrine.orm.boolean_filter'
|
||||
arguments: [ { 'enabled': ~ } ]
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.user_group.order:
|
||||
parent: 'api_platform.doctrine.orm.order_filter'
|
||||
arguments:
|
||||
$properties: { 'id': ~, 'name': ~ }
|
||||
$orderParameterName: 'order'
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.user_group.search:
|
||||
parent: 'api_platform.doctrine.orm.search_filter'
|
||||
arguments: [ { 'id': 'exact', 'name': 'partial' } ]
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.user_group.boolean:
|
||||
parent: 'api_platform.doctrine.orm.boolean_filter'
|
||||
arguments: [ { 'enabled': ~ } ]
|
||||
tags:
|
||||
- [ 'api_platform.filter' ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
|
||||
|
|
|
@ -87,9 +87,10 @@ class MigrateHardwareAndHardwareProfileCommand extends Command
|
|||
$migrationId = $hardware['hardwares.grupoid'] === 0 ? $hardware['hardwares.idcentro'] : $hardware['hardwares.grupoid'];
|
||||
$organizationalUnit = $organizationalUnitRepository->findOneBy(['migrationId' => $migrationId]);
|
||||
|
||||
/*
|
||||
if ($organizationalUnit){
|
||||
$hardwareEntity->setOrganizationalUnit($organizationalUnit);
|
||||
}
|
||||
}*/
|
||||
|
||||
$this->entityManager->persist($hardwareEntity);
|
||||
}
|
||||
|
@ -142,8 +143,8 @@ class MigrateHardwareAndHardwareProfileCommand extends Command
|
|||
|
||||
if ($hardwareProfileEntity && $hardwareEntity){
|
||||
$hardwareProfileEntity->addHardwareCollection($hardwareEntity);
|
||||
$this->entityManager->persist($hardwareProfileEntity);
|
||||
}
|
||||
$this->entityManager->persist($hardwareProfileEntity);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -36,13 +36,26 @@ readonly class UserAllowedOrganizationalUnitExtension implements QueryCollection
|
|||
if (OrganizationalUnit::class !== $resourceClass || null === $user || in_array('ROLE_SUPER_ADMIN', $user->getRoles())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$organizationalUnitIds = [];
|
||||
foreach ($user->getAllowedOrganizationalUnits() as $allowedOrganizationalUnit) {
|
||||
$organizationalUnitIds[] = $allowedOrganizationalUnit->getId();
|
||||
$this->addOrganizationalUnitAndChildrenIds($allowedOrganizationalUnit, $organizationalUnitIds);
|
||||
}
|
||||
|
||||
$rootAlias = $queryBuilder->getRootAliases()[0];
|
||||
$queryBuilder->andWhere(sprintf('%s.id in (:ou)', $rootAlias));
|
||||
$queryBuilder->setParameter('ou', $organizationalUnitIds);
|
||||
}
|
||||
|
||||
private function addOrganizationalUnitAndChildrenIds(OrganizationalUnit $organizationalUnit, array &$organizationalUnitIds): void
|
||||
{
|
||||
if (!in_array($organizationalUnit->getId(), $organizationalUnitIds)) {
|
||||
$organizationalUnitIds[] = $organizationalUnit->getId();
|
||||
}
|
||||
|
||||
foreach ($organizationalUnit->getOrganizationalUnits() as $child) {
|
||||
$this->addOrganizationalUnitAndChildrenIds($child, $organizationalUnitIds);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Dto\Input;
|
||||
|
||||
use ApiPlatform\Metadata\ApiProperty;
|
||||
use App\Dto\Output\OrganizationalUnitOutput;
|
||||
use App\Dto\Output\UserGroupOutput;
|
||||
use App\Entity\OrganizationalUnit;
|
||||
use App\Entity\User;
|
||||
|
@ -17,7 +18,7 @@ final class UserInput
|
|||
public ?string $username = null;
|
||||
|
||||
/**
|
||||
* @var OrganizationalUnit[]
|
||||
* @var OrganizationalUnitOutput[]
|
||||
*/
|
||||
#[Groups('user:write')]
|
||||
#[ApiProperty(readableLink: false, writableLink: false)]
|
||||
|
@ -33,7 +34,7 @@ final class UserInput
|
|||
public ?bool $enabled = true;
|
||||
|
||||
/**
|
||||
* @var UserGroup[]
|
||||
* @var UserGroupOutput[]
|
||||
*/
|
||||
#[Groups('user:write')]
|
||||
#[ApiProperty(readableLink: false, writableLink: false)]
|
||||
|
@ -62,8 +63,18 @@ final class UserInput
|
|||
|
||||
$this->username = $user->getUsername();
|
||||
$this->enabled= $user->isEnabled();
|
||||
$this->userGroups = $user->getUserGroups()->toArray();
|
||||
$this->allowedOrganizationalUnits = $user->getAllowedOrganizationalUnits()->toArray();
|
||||
|
||||
if ($user->getUserGroups()) {
|
||||
foreach ($user->getUserGroups() as $userGroup) {
|
||||
$this->userGroups[] = new UserGroupOutput($userGroup);
|
||||
}
|
||||
}
|
||||
|
||||
if ($user->getAllowedOrganizationalUnits()) {
|
||||
foreach ($user->getAllowedOrganizationalUnits() as $allowedOrganizationalUnit) {
|
||||
$this->allowedOrganizationalUnits[] = new OrganizationalUnitOutput($allowedOrganizationalUnit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function createOrUpdateEntity(?User $user = null): User
|
||||
|
|
|
@ -19,14 +19,20 @@ final class ClientOutput extends AbstractOutput
|
|||
#[Groups(['client:read', 'organizational-unit:read'])]
|
||||
public string $type = self::TYPE;
|
||||
|
||||
#[Groups(['client:read', 'organizational-unit:read'])]
|
||||
public ?string $ip = '';
|
||||
|
||||
#[Groups(['client:read', 'organizational-unit:read'])]
|
||||
public ?string $mac = '';
|
||||
|
||||
#[Groups(['client:read', 'organizational-unit:read'])]
|
||||
public ?string $serialNumber = '';
|
||||
|
||||
#[Groups(['client:read'])]
|
||||
public ?string $netiface = '';
|
||||
|
||||
#[Groups(['client:read', 'organizational-unit:read'])]
|
||||
#[ApiProperty(readableLink: true )]
|
||||
#[Groups(['client:read'])]
|
||||
#[ApiProperty(readableLink: true)]
|
||||
public ?OrganizationalUnitOutput $organizationalUnit = null;
|
||||
|
||||
#[Groups(['client:read'])]
|
||||
|
@ -51,6 +57,8 @@ final class ClientOutput extends AbstractOutput
|
|||
|
||||
$this->name = $client->getName();
|
||||
$this->serialNumber = $client->getSerialNumber();
|
||||
$this->mac = $client->getMac();
|
||||
$this->ip = $client->getIp();
|
||||
$this->netiface = $client->getNetiface();
|
||||
|
||||
if ($client->getOrganizationalUnit()) {
|
||||
|
|
|
@ -42,13 +42,19 @@ final class OrganizationalUnitOutput extends AbstractOutput
|
|||
#[ApiProperty(readableLink: true)]
|
||||
public ?NetworkSettingsOutput $networkSettings = null;
|
||||
|
||||
#[Groups(['organizational-unit:read'])]
|
||||
public array $children = [];
|
||||
|
||||
#[Groups(['organizational-unit:read'])]
|
||||
public array $clients = [];
|
||||
|
||||
#[Groups(['organizational-unit:read'])]
|
||||
public \DateTime $createdAt;
|
||||
|
||||
#[Groups(['organizational-unit:read'])]
|
||||
public ?string $createdBy = null;
|
||||
|
||||
public function __construct(OrganizationalUnit $organizationalUnit)
|
||||
public function __construct(OrganizationalUnit $organizationalUnit, array $context = [])
|
||||
{
|
||||
parent::__construct($organizationalUnit);
|
||||
|
||||
|
@ -65,6 +71,18 @@ final class OrganizationalUnitOutput extends AbstractOutput
|
|||
$this->parent = new self($organizationalUnit->getParent());
|
||||
}
|
||||
|
||||
if (isset($context['groups']) && in_array('organizational-unit:read', $context['groups'])) {
|
||||
$this->children = $organizationalUnit->getOrganizationalUnits()->map(
|
||||
fn(OrganizationalUnit $organizationalUnit) => new self($organizationalUnit, $context)
|
||||
)->toArray();
|
||||
}
|
||||
|
||||
if (isset($context['groups']) && in_array('organizational-unit:read', $context['groups'])) {
|
||||
$this->clients = $organizationalUnit->getClients()->map(
|
||||
fn(Client $client) => new ClientOutput($client)
|
||||
)->toArray();
|
||||
}
|
||||
|
||||
$this->path = $organizationalUnit->getPath();
|
||||
$this->createdAt = $organizationalUnit->getCreatedAt();
|
||||
$this->createdBy = $organizationalUnit->getCreatedBy();
|
||||
|
|
|
@ -21,9 +21,9 @@ readonly class OrganizationalUnitChangeParentHandler
|
|||
return throw new \InvalidArgumentException('The organizational unit has no parent.');
|
||||
}
|
||||
|
||||
foreach ($organizationalUnit->getOrganizationalUnits() as $child) {
|
||||
$child->setParent($parent);
|
||||
$this->organizationalUnitRepository->save($child);
|
||||
foreach ($organizationalUnit->getClients() as $client) {
|
||||
$client->setOrganizationalUnit($parent);
|
||||
$this->organizationalUnitRepository->save($client);
|
||||
}
|
||||
|
||||
$this->organizationalUnitRepository->delete($organizationalUnit);
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace App\Security\Voter;
|
||||
|
||||
use App\Dto\Output\OrganizationalUnitOutput;
|
||||
use App\Entity\Client;
|
||||
use App\Entity\OrganizationalUnit;
|
||||
use App\Entity\User;
|
||||
use App\Model\UserGroupPermissions;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
||||
class ClientVoter extends Voter
|
||||
{
|
||||
public const string VIEW = 'CLIENT_VIEW';
|
||||
|
||||
protected function supports(string $attribute, mixed $subject): bool
|
||||
{
|
||||
return $attribute === self::VIEW
|
||||
&& $subject instanceof Client;
|
||||
}
|
||||
|
||||
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $token->getUser();
|
||||
|
||||
|
||||
if (!$user instanceof UserInterface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (in_array(UserGroupPermissions::ROLE_SUPER_ADMIN, $user->getRoles())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($attribute === 'CLIENT_VIEW') {
|
||||
foreach ($user->getAllowedOrganizationalUnits() as $allowedOrganizationalUnit) {
|
||||
if ($allowedOrganizationalUnit->getId() === $subject->getOrganizationalUnit()->getEntity()->getId()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -42,7 +42,7 @@ readonly class OrganizationalUnitProvider implements ProviderInterface
|
|||
|
||||
$items = new \ArrayObject();
|
||||
foreach ($paginator->getIterator() as $item){
|
||||
$items[] = new OrganizationalUnitOutput($item);
|
||||
$items[] = new OrganizationalUnitOutput($item, $context);
|
||||
}
|
||||
|
||||
return new TraversablePaginator($items, $paginator->getCurrentPage(), $paginator->getItemsPerPage(), $paginator->getTotalItems());
|
||||
|
@ -56,7 +56,7 @@ readonly class OrganizationalUnitProvider implements ProviderInterface
|
|||
throw new NotFoundHttpException('Organizational unit not found');
|
||||
}
|
||||
|
||||
return new OrganizationalUnitOutput($item);
|
||||
return new OrganizationalUnitOutput($item, $context);
|
||||
}
|
||||
|
||||
public function provideInput(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
|
||||
|
|
Loading…
Reference in New Issue