Skip to content

Commit

Permalink
Initial authorization prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
mattamon committed Feb 29, 2024
1 parent 6230cd1 commit c751ae9
Show file tree
Hide file tree
Showing 14 changed files with 548 additions and 1 deletion.
20 changes: 20 additions & 0 deletions config/api_platform/resources/token.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
resources:
Pimcore\Bundle\StudioApiBundle\Dto\Token:
operations:
ApiPlatform\Metadata\Post:
processor: Pimcore\Bundle\StudioApiBundle\State\Token\PostProcessor
output: Pimcore\Bundle\StudioApiBundle\Dto\Token\Output
uriTemplate: '/token/create'
openapiContext:
summary: 'Creates and returns a token'

ApiPlatform\Metadata\Put:
processor: Pimcore\Bundle\StudioApiBundle\State\Token\PutProcessor
input: Pimcore\Bundle\StudioApiBundle\Dto\Token\Refresh
output: Pimcore\Bundle\StudioApiBundle\Dto\Token\Output
uriTemplate: '/token/refresh'
openapiContext:
summary: 'Refreshes an existing token'

normalizationContext:
groups: [ 'token:read' ]
10 changes: 10 additions & 0 deletions config/serialization/token.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Pimcore\Bundle\StudioApiBundle\Dto\Token\Output:
attributes:
token:
groups: ['token:read']
username:
groups: [ 'token:read' ]
lifetime:
groups: ['token:read']
validUntil:
groups: ['token:read']
2 changes: 2 additions & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ services:

# Processors
Pimcore\Bundle\StudioApiBundle\State\ResetPasswordProcessor: ~
Pimcore\Bundle\StudioApiBundle\State\Token\PostProcessor: ~
Pimcore\Bundle\StudioApiBundle\State\Token\PutProcessor: ~

# Filters
Pimcore\Bundle\StudioApiBundle\Filter\AssetParentIdFilter:
Expand Down
18 changes: 17 additions & 1 deletion src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace Pimcore\Bundle\StudioApiBundle\DependencyInjection;


use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

Expand All @@ -23,11 +24,26 @@
*/
class Configuration implements ConfigurationInterface
{
public const ROOT_NODE = 'pimcore_studio_api';

/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder(): TreeBuilder
{
return new TreeBuilder('pimcore_studio_api');
$treeBuilder = new TreeBuilder(self::ROOT_NODE);

$rootNode = $treeBuilder->getRootNode();
$rootNode->addDefaultsIfNotSet();
$rootNode->children()
->arrayNode('api_token')
->addDefaultsIfNotSet()
->children()
->integerNode('lifetime')
->defaultValue(3600)
->end()
->end();

return $treeBuilder;
}
}
8 changes: 8 additions & 0 deletions src/DependencyInjection/PimcoreStudioApiExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
namespace Pimcore\Bundle\StudioApiBundle\DependencyInjection;

use Exception;
use Pimcore\Bundle\StudioApiBundle\State\Token\PostProcessor;
use Pimcore\Bundle\StudioApiBundle\State\Token\PutProcessor;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
Expand Down Expand Up @@ -55,6 +57,12 @@ public function load(array $configs, ContainerBuilder $container): void
'pimcore_studio_api.serializer.mapping.paths',
$config['serializer']['mapping']['paths']
);

$definition = $container->getDefinition(PostProcessor::class);
$definition->setArgument('$tokenLifetime', $config['api_token']['lifetime']);

$definition = $container->getDefinition(PutProcessor::class);
$definition->setArgument('$tokenLifetime', $config['api_token']['lifetime']);
}

public function prepend(ContainerBuilder $container): void
Expand Down
37 changes: 37 additions & 0 deletions src/Dto/Token.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under following license:
* - Pimcore Commercial License (PCL)
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license PCL
*/

namespace Pimcore\Bundle\StudioApiBundle\Dto;

/**
* @internal
*/
final readonly class Token

Check failure on line 19 in src/Dto/Token.php

View workflow job for this annotation

GitHub Actions / Qodana for PHP

Language level

'readonly' classes are only allowed since PHP 8.2
{
public function __construct(
private string $username,
private string $password
)
{
}

public function getUsername(): string
{
return $this->username;
}

public function getPassword(): string
{
return $this->password;
}
}
43 changes: 43 additions & 0 deletions src/Dto/Token/Info.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under following license:
* - Pimcore Commercial License (PCL)
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license PCL
*/

namespace Pimcore\Bundle\StudioApiBundle\Dto\Token;

/**
* @internal
*/
final readonly class Info

Check failure on line 19 in src/Dto/Token/Info.php

View workflow job for this annotation

GitHub Actions / Qodana for PHP

Language level

'readonly' classes are only allowed since PHP 8.2
{
public function __construct(
private string $token,
private string $tmpStoreId,
private string $username
)
{
}

public function getToken(): string
{
return $this->token;
}

public function getTmpStoreId(): string
{
return $this->tmpStoreId;
}

public function getUsername(): string
{
return $this->username;
}
}
50 changes: 50 additions & 0 deletions src/Dto/Token/Output.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under following license:
* - Pimcore Commercial License (PCL)
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license PCL
*/

namespace Pimcore\Bundle\StudioApiBundle\Dto\Token;

use Carbon\Carbon;

/**
* @internal
*/
final readonly class Output

Check failure on line 21 in src/Dto/Token/Output.php

View workflow job for this annotation

GitHub Actions / Qodana for PHP

Language level

'readonly' classes are only allowed since PHP 8.2
{
public function __construct(
private string $token,
private int $lifetime,
private string $username
)
{
}

public function getToken(): string
{
return $this->token;
}

public function getUsername(): string
{
return $this->username;
}

public function getLifetime(): int
{
return $this->lifetime;
}

public function validUntil(): string
{
return Carbon::now()->addSeconds($this->lifetime)->toDateTimeString();
}
}
31 changes: 31 additions & 0 deletions src/Dto/Token/Refresh.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under following license:
* - Pimcore Commercial License (PCL)
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license PCL
*/

namespace Pimcore\Bundle\StudioApiBundle\Dto\Token;

/**
* @internal
*/
final readonly class Refresh

Check failure on line 19 in src/Dto/Token/Refresh.php

View workflow job for this annotation

GitHub Actions / Qodana for PHP

Language level

'readonly' classes are only allowed since PHP 8.2
{
public function __construct(
private string $token
)
{
}

public function getToken(): string
{
return $this->token;
}
}
36 changes: 36 additions & 0 deletions src/Service/SecurityService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under following license:
* - Pimcore Commercial License (PCL)
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license PCL
*/

namespace Pimcore\Bundle\StudioApiBundle\Service;

use Pimcore\Bundle\StaticResolverBundle\Models\Tool\TmpStoreResolverInterface;

/**
* @internal
*/
final readonly class SecurityService implements SecurityServiceInterface

Check failure on line 21 in src/Service/SecurityService.php

View workflow job for this annotation

GitHub Actions / Qodana for PHP

Language level

'readonly' classes are only allowed since PHP 8.2
{
public function __construct(private TmpStoreResolverInterface $tmpStoreResolver)
{
}

public function isAllowed(string $token): bool
{
$userIds = $this->tmpStoreResolver->getIdsByTag($token);
if(count($userIds) === 0 || count($userIds) > 1) {
return false;
}
$entry = $this->tmpStoreResolver->get($userIds[0]);
return $entry && $entry->getTag() === $token;
}
}
22 changes: 22 additions & 0 deletions src/Service/SecurityServiceInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under following license:
* - Pimcore Commercial License (PCL)
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license PCL
*/

namespace Pimcore\Bundle\StudioApiBundle\Service;

/**
* @internal
*/
interface SecurityServiceInterface
{
public function isAllowed(string $token): bool;
}
Loading

0 comments on commit c751ae9

Please sign in to comment.