Skip to content

Commit

Permalink
Add public voter
Browse files Browse the repository at this point in the history
  • Loading branch information
mattamon committed Mar 5, 2024
1 parent f683708 commit 1b90aa1
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 1 deletion.
1 change: 1 addition & 0 deletions config/api_platform/resources/translation.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
resources:
Pimcore\Bundle\StudioApiBundle\Dto\Translation:
security: 'is_granted("PUBLIC_API_PLATFORM", "translation")'
operations:
ApiPlatform\Metadata\Post:
processor: Pimcore\Bundle\StudioApiBundle\State\TranslationProcessor
Expand Down
8 changes: 7 additions & 1 deletion config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,10 @@ services:
class: Pimcore\Bundle\StudioApiBundle\Service\GenericData\V1\AssetQueryProvider

Pimcore\Bundle\StudioApiBundle\Service\TranslatorServiceInterface:
class: Pimcore\Bundle\StudioApiBundle\Service\TranslatorService
class: Pimcore\Bundle\StudioApiBundle\Service\TranslatorService

#Voters
Pimcore\Bundle\StudioApiBundle\Security\Voter\PublicTokenVoter:
arguments: [ '@request_stack' ]
tags:
- { name: security.voter }
25 changes: 25 additions & 0 deletions src/Exception/NoRequestException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\StudioApiBundle\Exception;

use RuntimeException;


final class NoRequestException extends RuntimeException
{

}
41 changes: 41 additions & 0 deletions src/Security/Trait/PublicTranslationTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\StudioApiBundle\Security\Trait;

use Pimcore\Bundle\StudioApiBundle\Util\Constants\PublicTranslations;
use Symfony\Component\HttpFoundation\InputBag;

trait PublicTranslationTrait
{
private const ARRAY_KEYS_INDEX = 'keys';
private function voteOnTranslation(InputBag $payload): bool
{
$parameters = $payload->all();
if(!array_key_exists(self::ARRAY_KEYS_INDEX, $parameters)) {
return false;
}

foreach($parameters[self::ARRAY_KEYS_INDEX] as $key) {
// Allow only public keys
if(!in_array($key, PublicTranslations::PUBLIC_KEYS, true)) {
return false;
}
}

return true;
}
}
70 changes: 70 additions & 0 deletions src/Security/Voter/PublicTokenVoter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\StudioApiBundle\Security\Voter;

use Pimcore\Bundle\StudioApiBundle\Exception\NoRequestException;
use Pimcore\Bundle\StudioApiBundle\Security\Trait\PublicTranslationTrait;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;

final class PublicTokenVoter extends Voter
{
use PublicTranslationTrait;

private const SUPPORTED_ATTRIBUTE = 'PUBLIC_API_PLATFORM';

private const SUPPORTED_SUBJECTS = ['translation'];

public function __construct(
private readonly RequestStack $requestStack,
) {
}

protected function supports(string $attribute, mixed $subject): bool
{
return $attribute === self::SUPPORTED_ATTRIBUTE && in_array((string)$subject, self::SUPPORTED_SUBJECTS, true);
}

protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{

$request = $this->getCurrentRequest();

// TODO Add security service once merged with PR#5
return $this->voteOnRequest($request, $subject);
}

private function getCurrentRequest(): Request
{
$request = $this->requestStack->getCurrentRequest();
if(!$request) {
throw new NoRequestException('No request found');
}

return $request;
}

private function voteOnRequest(Request $request, string $subject): bool
{
return match ($subject) {
'translation' => $this->voteOnTranslation($request->getPayload()),
default => false,
};
}
}

0 comments on commit 1b90aa1

Please sign in to comment.