Message handlers for symfony messenger
This commit is contained in:
parent
7516ec60cb
commit
1e99455b65
@ -53,6 +53,12 @@ class Configuration implements ConfigurationInterface
|
|||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
|
->arrayNode('messenger')
|
||||||
|
->children()
|
||||||
|
->scalarNode('message_handler')->isRequired()->defaultValue('simple_console_runner')->end()
|
||||||
|
->scalarNode('process_timeout')->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
->end();
|
->end();
|
||||||
|
|
||||||
return $treeBuilder;
|
return $treeBuilder;
|
||||||
|
@ -4,6 +4,7 @@ namespace RetailCrm\ServiceBundle\DependencyInjection;
|
|||||||
|
|
||||||
use RetailCrm\ServiceBundle\ArgumentResolver\CallbackValueResolver;
|
use RetailCrm\ServiceBundle\ArgumentResolver\CallbackValueResolver;
|
||||||
use RetailCrm\ServiceBundle\ArgumentResolver\ClientValueResolver;
|
use RetailCrm\ServiceBundle\ArgumentResolver\ClientValueResolver;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\MessageHandler;
|
||||||
use RetailCrm\ServiceBundle\Response\ErrorJsonResponseFactory;
|
use RetailCrm\ServiceBundle\Response\ErrorJsonResponseFactory;
|
||||||
use RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator;
|
use RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator;
|
||||||
use RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator;
|
use RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator;
|
||||||
@ -49,6 +50,18 @@ class RetailCrmServiceExtension extends Extension
|
|||||||
$config['request_schema']['client']['serializer']
|
$config['request_schema']['client']['serializer']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$container->setParameter(
|
||||||
|
'retail_crm_service.messenger.message_handler',
|
||||||
|
$config['messenger']['message_handler']
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isset($config['messenger']['process_timeout'])) {
|
||||||
|
$container->setParameter(
|
||||||
|
'retail_crm_service.messenger.process_timeout',
|
||||||
|
$config['messenger']['process_timeout']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$container
|
$container
|
||||||
->register(SymfonySerializerAdapter::class)
|
->register(SymfonySerializerAdapter::class)
|
||||||
->setAutowired(true);
|
->setAutowired(true);
|
||||||
@ -90,5 +103,28 @@ class RetailCrmServiceExtension extends Extension
|
|||||||
$container
|
$container
|
||||||
->register(FrontApiClientAuthenticator::class)
|
->register(FrontApiClientAuthenticator::class)
|
||||||
->setAutowired(true);
|
->setAutowired(true);
|
||||||
|
|
||||||
|
$container
|
||||||
|
->register(MessageHandler\SimpleConsoleRunner::class)
|
||||||
|
->setAutowired(true);
|
||||||
|
$container->setAlias('simple_console_runner', MessageHandler\SimpleConsoleRunner::class);
|
||||||
|
|
||||||
|
$timeout = $container->hasParameter('retail_crm_service.messenger.process_timeout')
|
||||||
|
? $container->getParameter('retail_crm_service.messenger.process_timeout')
|
||||||
|
: null;
|
||||||
|
|
||||||
|
$container
|
||||||
|
->register(MessageHandler\InNewProcessRunner::class)
|
||||||
|
->setArgument('$timeout', $timeout)
|
||||||
|
->setAutowired(true);
|
||||||
|
$container->setAlias('in_new_process_runner', MessageHandler\InNewProcessRunner::class);
|
||||||
|
|
||||||
|
$container
|
||||||
|
->register(MessageHandler::class)
|
||||||
|
->addTag('messenger.message_handler')
|
||||||
|
->setArguments([
|
||||||
|
new Reference($container->getParameter('retail_crm_service.messenger.message_handler'))
|
||||||
|
])
|
||||||
|
->setAutowired(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
99
Messenger/CommandMessage.php
Normal file
99
Messenger/CommandMessage.php
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Messenger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Message
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Messenger
|
||||||
|
*/
|
||||||
|
abstract class CommandMessage
|
||||||
|
{
|
||||||
|
/** @var string */
|
||||||
|
protected $commandName;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
protected $options = [];
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
protected $arguments = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCommandName(): string
|
||||||
|
{
|
||||||
|
return $this->commandName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $commandName
|
||||||
|
*/
|
||||||
|
public function setCommandName(string $commandName): void
|
||||||
|
{
|
||||||
|
$this->commandName = $commandName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getOptions(): array
|
||||||
|
{
|
||||||
|
return $this->options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $options
|
||||||
|
*/
|
||||||
|
public function setOptions(array $options): void
|
||||||
|
{
|
||||||
|
$this->options = $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getArguments(): array
|
||||||
|
{
|
||||||
|
return $this->arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $arguments
|
||||||
|
*/
|
||||||
|
public function setArguments(array $arguments): void
|
||||||
|
{
|
||||||
|
$this->arguments = $arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @param string $value
|
||||||
|
*/
|
||||||
|
public function addOption(string $key, string $value): void
|
||||||
|
{
|
||||||
|
$this->options[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @param string $value
|
||||||
|
*/
|
||||||
|
public function addArgument(string $key, string $value): void
|
||||||
|
{
|
||||||
|
$this->arguments[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getFormattedOptions(): array
|
||||||
|
{
|
||||||
|
$options = [];
|
||||||
|
foreach ($this->options as $option => $value) {
|
||||||
|
$options['--' . $option] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
}
|
40
Messenger/MessageHandler.php
Normal file
40
Messenger/MessageHandler.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Messenger;
|
||||||
|
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\MessageHandler\JobRunner;
|
||||||
|
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class MessageHandler
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Messenger
|
||||||
|
*/
|
||||||
|
class MessageHandler implements MessageHandlerInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var JobRunner
|
||||||
|
*/
|
||||||
|
private $runner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CommandQueueHandler constructor.
|
||||||
|
*
|
||||||
|
* @param JobRunner $runner
|
||||||
|
*/
|
||||||
|
public function __construct(JobRunner $runner)
|
||||||
|
{
|
||||||
|
$this->runner = $runner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param CommandMessage $message
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function __invoke(CommandMessage $message): void
|
||||||
|
{
|
||||||
|
$this->runner->run($message);
|
||||||
|
}
|
||||||
|
}
|
109
Messenger/MessageHandler/InNewProcessRunner.php
Normal file
109
Messenger/MessageHandler/InNewProcessRunner.php
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Messenger\MessageHandler;
|
||||||
|
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\CommandMessage;
|
||||||
|
use Symfony\Component\HttpKernel\KernelInterface;
|
||||||
|
use Symfony\Component\Process\Exception\ProcessTimedOutException;
|
||||||
|
use Symfony\Component\Process\PhpExecutableFinder;
|
||||||
|
use Symfony\Component\Process\Process;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class InNewProcessRunner
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Messenger\MessageHandler
|
||||||
|
*/
|
||||||
|
class InNewProcessRunner implements JobRunner
|
||||||
|
{
|
||||||
|
/** @var int Default timeout for process */
|
||||||
|
public const DEFAULT_TIMEOUT = 3600;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var KernelInterface
|
||||||
|
*/
|
||||||
|
private $kernel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $timeout = self::DEFAULT_TIMEOUT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CommandQueueHandler constructor.
|
||||||
|
*
|
||||||
|
* @param LoggerInterface $logger
|
||||||
|
* @param KernelInterface $kernel
|
||||||
|
* @param int|null $timeout
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
LoggerInterface $logger,
|
||||||
|
KernelInterface $kernel,
|
||||||
|
?int $timeout = null
|
||||||
|
) {
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->kernel = $kernel;
|
||||||
|
|
||||||
|
if (null !== $timeout) {
|
||||||
|
$this->timeout = $timeout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function run(CommandMessage $message): void
|
||||||
|
{
|
||||||
|
$phpBinaryPath = (new PhpExecutableFinder)->find();
|
||||||
|
$consoleCommand = [
|
||||||
|
'php' => $phpBinaryPath ?: 'php',
|
||||||
|
'console' => sprintf('%s/bin/console', $this->kernel->getContainer()->getParameter('kernel.project_dir')),
|
||||||
|
'command' => $message->getCommandName()
|
||||||
|
];
|
||||||
|
|
||||||
|
$process = new Process(
|
||||||
|
array_merge(
|
||||||
|
array_values($consoleCommand),
|
||||||
|
array_values($message->getArguments()),
|
||||||
|
array_values($this->getOptions($message)),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$process
|
||||||
|
->setTimeout($this->timeout)
|
||||||
|
->run(static function(string $type, string $buffer) {
|
||||||
|
echo $buffer;
|
||||||
|
})
|
||||||
|
;
|
||||||
|
} catch (ProcessTimedOutException $processTimedOutException) {
|
||||||
|
$this->logger->error(
|
||||||
|
sprintf(
|
||||||
|
'Process "%s" killed after %d seconds of execution',
|
||||||
|
$processTimedOutException->getProcess()->getCommandLine(),
|
||||||
|
$processTimedOutException->getProcess()->getTimeout()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param CommandMessage $message
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getOptions(CommandMessage $message): array
|
||||||
|
{
|
||||||
|
$options = [];
|
||||||
|
foreach ($message->getFormattedOptions() as $option => $value) {
|
||||||
|
$options[] = $option . '=' . $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
}
|
18
Messenger/MessageHandler/JobRunner.php
Normal file
18
Messenger/MessageHandler/JobRunner.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Messenger\MessageHandler;
|
||||||
|
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\CommandMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface JobRunner
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Messenger\MessageHandler
|
||||||
|
*/
|
||||||
|
interface JobRunner
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param CommandMessage $message
|
||||||
|
*/
|
||||||
|
public function run(CommandMessage $message): void;
|
||||||
|
}
|
66
Messenger/MessageHandler/SimpleConsoleRunner.php
Normal file
66
Messenger/MessageHandler/SimpleConsoleRunner.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Messenger\MessageHandler;
|
||||||
|
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\CommandMessage;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||||
|
use Symfony\Component\Console\Input\ArrayInput;
|
||||||
|
use Symfony\Component\Console\Output\BufferedOutput;
|
||||||
|
use Symfony\Component\HttpKernel\KernelInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SimpleConsoleRunner
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Messenger\MessageHandler
|
||||||
|
*/
|
||||||
|
class SimpleConsoleRunner implements JobRunner
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var KernelInterface
|
||||||
|
*/
|
||||||
|
private $kernel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CommandQueueHandler constructor.
|
||||||
|
*
|
||||||
|
* @param LoggerInterface $logger
|
||||||
|
* @param KernelInterface $kernel
|
||||||
|
*/
|
||||||
|
public function __construct(LoggerInterface $logger, KernelInterface $kernel)
|
||||||
|
{
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->kernel = $kernel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function run(CommandMessage $message): void
|
||||||
|
{
|
||||||
|
$application = new Application($this->kernel);
|
||||||
|
$application->setAutoExit(false);
|
||||||
|
|
||||||
|
$input = new ArrayInput(
|
||||||
|
array_merge(
|
||||||
|
['command' => $message->getCommandName()],
|
||||||
|
$message->getFormattedOptions(),
|
||||||
|
$message->getArguments()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$output = new BufferedOutput();
|
||||||
|
if ($application->run($input, $output) > 0) {
|
||||||
|
$this->logger->error($output->fetch());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $output->fetch();
|
||||||
|
}
|
||||||
|
}
|
60
Resources/doc/Messenger.md
Normal file
60
Resources/doc/Messenger.md
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
### Messenger
|
||||||
|
|
||||||
|
#### Messages
|
||||||
|
|
||||||
|
The library provides a basic message for executing console commands as message handlers - `RetailCrm\ServiceBundle\Messenger\CommandMessage`.
|
||||||
|
This makes it easier to create new message types. For example:
|
||||||
|
|
||||||
|
* Create your message
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
namespace App\Message;
|
||||||
|
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\CommandMessage;
|
||||||
|
|
||||||
|
class MyMessage extends CommandMessage
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->commandName = \App\Command\MyCommand::getDefaultName();
|
||||||
|
$this->options = ['optionName' => 'optionValue'];
|
||||||
|
$this->arguments = ['argumentName' => 'argumentValue'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
* Add a message to a routing
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# config/packages/messenger.yaml
|
||||||
|
framework:
|
||||||
|
messenger:
|
||||||
|
transports:
|
||||||
|
async: "%env(MESSENGER_TRANSPORT_DSN)%"
|
||||||
|
|
||||||
|
routing:
|
||||||
|
'App\Message\MyMessage': async
|
||||||
|
```
|
||||||
|
|
||||||
|
Now when sending this message through messenger (```$messageBus->dispatch(new MyMessage())```) the message handler will run the associated command
|
||||||
|
|
||||||
|
#### Message handlers
|
||||||
|
|
||||||
|
Two messages handlers are is supported:
|
||||||
|
|
||||||
|
* all messages handling in one worker process
|
||||||
|
* each message is a processed in a separate process
|
||||||
|
|
||||||
|
By default, messages will be processed in one process. To set up a handler to run in a separate process, add to the bundle config:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
retail_crm_service:
|
||||||
|
messenger:
|
||||||
|
message_handler: in_new_process_runner
|
||||||
|
process_timeout: 60
|
||||||
|
```
|
||||||
|
|
||||||
|
`process_timeout` - an optional parameter that only makes sense when `message_handler` is equal `in_new_process_runner` and determines the lifetime of the process.
|
||||||
|
By default, process timeout - 3600 (in seconds).
|
71
Resources/doc/Requests.md
Normal file
71
Resources/doc/Requests.md
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
### Deserialize incoming requests
|
||||||
|
|
||||||
|
#### Callbacks (form data)
|
||||||
|
|
||||||
|
To automatically get the callback request parameter
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
class AppController extends AbstractController
|
||||||
|
{
|
||||||
|
public function activityAction(\App\Dto\Callback\Activity $activity): Response
|
||||||
|
{
|
||||||
|
// handle activity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
add to the config:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
retail_crm_service:
|
||||||
|
request_schema:
|
||||||
|
callback:
|
||||||
|
supports:
|
||||||
|
- { type: App\Dto\Callback\Activity, params: ["activity"] }
|
||||||
|
```
|
||||||
|
|
||||||
|
request automatically will be deserialization to $activity.
|
||||||
|
|
||||||
|
#### Body json content
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
class AppController extends AbstractController
|
||||||
|
{
|
||||||
|
public function someAction(\App\Dto\Body $activity): Response
|
||||||
|
{
|
||||||
|
// handle activity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
add to the config:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
retail_crm_service:
|
||||||
|
request_schema:
|
||||||
|
client:
|
||||||
|
supports:
|
||||||
|
- App\Dto\Body
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Serializers
|
||||||
|
At this time supported [Symfony serializer](https://symfony.com/doc/current/components/serializer.html) and [JMS serializer](https://jmsyst.com/libs/serializer).
|
||||||
|
By default, the library using a Symfony serializer. For use JMS install JMS serializer bundle - `composer require jms/serializer-bundle`
|
||||||
|
You can explicitly specify the type of serializer used for request schema:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
retail_crm_service:
|
||||||
|
request_schema:
|
||||||
|
client:
|
||||||
|
supports:
|
||||||
|
# types
|
||||||
|
serializer: retail_crm_service.symfony_serializer.adapter # or retail_crm_service.jms_serializer.adapter
|
||||||
|
callback:
|
||||||
|
supports:
|
||||||
|
# types
|
||||||
|
serializer: retail_crm_service.jms_serializer.adapter # or retail_crm_service.symfony_serializer.adapter
|
||||||
|
```
|
70
Resources/doc/Security.md
Normal file
70
Resources/doc/Security.md
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
### Authentication
|
||||||
|
|
||||||
|
Example security configuration:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
security:
|
||||||
|
providers:
|
||||||
|
client:
|
||||||
|
entity:
|
||||||
|
class: 'App\Entity\Connection' # must implements UserInterface
|
||||||
|
property: 'clientId'
|
||||||
|
firewalls:
|
||||||
|
api:
|
||||||
|
pattern: ^/api
|
||||||
|
provider: client
|
||||||
|
anonymous: ~
|
||||||
|
lazy: true
|
||||||
|
stateless: false
|
||||||
|
guard:
|
||||||
|
authenticators:
|
||||||
|
- RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator
|
||||||
|
callback:
|
||||||
|
pattern: ^/callback
|
||||||
|
provider: client
|
||||||
|
anonymous: ~
|
||||||
|
lazy: true
|
||||||
|
stateless: true
|
||||||
|
guard:
|
||||||
|
authenticators:
|
||||||
|
- RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator
|
||||||
|
main:
|
||||||
|
anonymous: true
|
||||||
|
lazy: true
|
||||||
|
|
||||||
|
access_control:
|
||||||
|
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } # login for programmatically authentication user
|
||||||
|
- { path: ^/api, roles: ROLE_USER }
|
||||||
|
- { path: ^/callback, roles: ROLE_USER }
|
||||||
|
```
|
||||||
|
|
||||||
|
To authenticate the user after creating it, you can use the following code
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
|
||||||
|
use RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
|
class AppController extends AbstractController
|
||||||
|
{
|
||||||
|
public function someAction(
|
||||||
|
Request $request,
|
||||||
|
GuardAuthenticatorHandler $guardAuthenticatorHandler,
|
||||||
|
FrontApiClientAuthenticator $frontApiClientAuthenticator,
|
||||||
|
ConnectionManager $manager
|
||||||
|
): Response {
|
||||||
|
$user = $manager->getUser(); // getting user
|
||||||
|
|
||||||
|
$guardAuthenticatorHandler->authenticateUserAndHandleSuccess(
|
||||||
|
$user,
|
||||||
|
$request,
|
||||||
|
$frontApiClientAuthenticator,
|
||||||
|
'api'
|
||||||
|
);
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
`composer require retailcrm/service-bundle`
|
`composer require retailcrm/service-bundle`
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Enable bundle in `config/bundles.php`:
|
Enable bundle in `config/bundles.php`:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
@ -23,147 +21,10 @@ retail_crm_service:
|
|||||||
request_schema:
|
request_schema:
|
||||||
callback: ~
|
callback: ~
|
||||||
client: ~
|
client: ~
|
||||||
|
messenger: ~
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deserializing incoming requests
|
## Usage
|
||||||
|
* [Handling incoming requests data](./Requests.md)
|
||||||
#### Callbacks (form data)
|
* [Security](./Security.md)
|
||||||
|
* [Messenger](./Messenger.md)
|
||||||
To automatically get the callback request parameter
|
|
||||||
|
|
||||||
```php
|
|
||||||
|
|
||||||
class AppController extends AbstractController
|
|
||||||
{
|
|
||||||
public function activityAction(\App\Dto\Callback\Activity $activity): Response
|
|
||||||
{
|
|
||||||
// handle activity
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
add to the config:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
retail_crm_service:
|
|
||||||
request_schema:
|
|
||||||
callback:
|
|
||||||
supports:
|
|
||||||
- { type: App\Dto\Callback\Activity, params: ["activity"] }
|
|
||||||
```
|
|
||||||
|
|
||||||
request automatically will be deserialization to $activity.
|
|
||||||
|
|
||||||
#### Body json content
|
|
||||||
|
|
||||||
```php
|
|
||||||
|
|
||||||
class AppController extends AbstractController
|
|
||||||
{
|
|
||||||
public function someAction(\App\Dto\Body $activity): Response
|
|
||||||
{
|
|
||||||
// handle activity
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
add to the config:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
retail_crm_service:
|
|
||||||
request_schema:
|
|
||||||
client:
|
|
||||||
supports:
|
|
||||||
- App\Dto\Body
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Serializers
|
|
||||||
At this time supported [Symfony serializer](https://symfony.com/doc/current/components/serializer.html) and [JMS serializer](https://jmsyst.com/libs/serializer).
|
|
||||||
By default, the library using a Symfony serializer. For use JMS install JMS serializer bundle - `composer require jms/serializer-bundle`
|
|
||||||
You can explicitly specify the type of serializer used for request schema:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
retail_crm_service:
|
|
||||||
request_schema:
|
|
||||||
client:
|
|
||||||
supports:
|
|
||||||
# types
|
|
||||||
serializer: retail_crm_service.symfony_serializer.adapter # or retail_crm_service.jms_serializer.adapter
|
|
||||||
callback:
|
|
||||||
supports:
|
|
||||||
# types
|
|
||||||
serializer: retail_crm_service.jms_serializer.adapter # or retail_crm_service.symfony_serializer.adapter
|
|
||||||
```
|
|
||||||
|
|
||||||
### Authentication
|
|
||||||
|
|
||||||
Example security configuration:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
security:
|
|
||||||
providers:
|
|
||||||
client:
|
|
||||||
entity:
|
|
||||||
class: 'App\Entity\Connection' # must implements UserInterface
|
|
||||||
property: 'clientId'
|
|
||||||
firewalls:
|
|
||||||
api:
|
|
||||||
pattern: ^/api
|
|
||||||
provider: client
|
|
||||||
anonymous: ~
|
|
||||||
lazy: true
|
|
||||||
stateless: false
|
|
||||||
guard:
|
|
||||||
authenticators:
|
|
||||||
- RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator
|
|
||||||
callback:
|
|
||||||
pattern: ^/callback
|
|
||||||
provider: client
|
|
||||||
anonymous: ~
|
|
||||||
lazy: true
|
|
||||||
stateless: true
|
|
||||||
guard:
|
|
||||||
authenticators:
|
|
||||||
- RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator
|
|
||||||
main:
|
|
||||||
anonymous: true
|
|
||||||
lazy: true
|
|
||||||
|
|
||||||
access_control:
|
|
||||||
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } # login for programmatically authentication user
|
|
||||||
- { path: ^/api, roles: ROLE_USER }
|
|
||||||
- { path: ^/callback, roles: ROLE_USER }
|
|
||||||
```
|
|
||||||
|
|
||||||
To authenticate the user after creating it, you can use the following code
|
|
||||||
|
|
||||||
```php
|
|
||||||
|
|
||||||
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
|
|
||||||
use RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
|
|
||||||
class AppController extends AbstractController
|
|
||||||
{
|
|
||||||
public function someAction(
|
|
||||||
Request $request,
|
|
||||||
GuardAuthenticatorHandler $guardAuthenticatorHandler,
|
|
||||||
FrontApiClientAuthenticator $frontApiClientAuthenticator,
|
|
||||||
ConnectionManager $manager
|
|
||||||
): Response {
|
|
||||||
$user = $manager->getUser(); // getting user
|
|
||||||
|
|
||||||
$guardAuthenticatorHandler->authenticateUserAndHandleSuccess(
|
|
||||||
$user,
|
|
||||||
$request,
|
|
||||||
$frontApiClientAuthenticator,
|
|
||||||
'api'
|
|
||||||
);
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
15
Tests/DataFixtures/TestMessage.php
Normal file
15
Tests/DataFixtures/TestMessage.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\DataFixtures;
|
||||||
|
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\CommandMessage;
|
||||||
|
|
||||||
|
class TestMessage extends CommandMessage
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->commandName = 'test';
|
||||||
|
$this->arguments = ['argument' => 'argument'];
|
||||||
|
$this->options = ['option' => 'option'];
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,10 @@ class ConfigurationTest extends TestCase
|
|||||||
'type2'
|
'type2'
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
],
|
||||||
|
'messenger' => [
|
||||||
|
'message_handler' => 'simple_console_runner',
|
||||||
|
'process_timeout' => 60
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
@ -71,6 +75,9 @@ class ConfigurationTest extends TestCase
|
|||||||
'type',
|
'type',
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
],
|
||||||
|
'messenger' => [
|
||||||
|
'message_handler' => 'simple_console_runner'
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
@ -34,6 +34,9 @@ class RetailCrmServiceExtensionTest extends TestCase
|
|||||||
'request_schema' => [
|
'request_schema' => [
|
||||||
'callback' => [],
|
'callback' => [],
|
||||||
'client' => []
|
'client' => []
|
||||||
|
],
|
||||||
|
'messenger' => [
|
||||||
|
'message_handler' => 'simple_console_runner'
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
33
Tests/Fixtures/App/Kernel.php
Normal file
33
Tests/Fixtures/App/Kernel.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Fixtures\App;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
||||||
|
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
|
||||||
|
class Kernel extends \Symfony\Component\HttpKernel\Kernel
|
||||||
|
{
|
||||||
|
use MicroKernelTrait;
|
||||||
|
|
||||||
|
public function registerBundles()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function configureContainer(ContainerBuilder $container/*, LoaderInterface $loader*/): void
|
||||||
|
{
|
||||||
|
$container
|
||||||
|
->register(TestCommand::class, TestCommand::class)
|
||||||
|
->addTag('console.command', ['command' => TestCommand::getDefaultName()])
|
||||||
|
;
|
||||||
|
|
||||||
|
$container->setParameter('kernel.project_dir', __DIR__ . '/..');
|
||||||
|
}
|
||||||
|
|
||||||
|
// public function registerContainerConfiguration(LoaderInterface $loader)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
}
|
36
Tests/Fixtures/App/TestCommand.php
Normal file
36
Tests/Fixtures/App/TestCommand.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Fixtures\App;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
class TestCommand extends Command
|
||||||
|
{
|
||||||
|
protected static $defaultName = 'test';
|
||||||
|
|
||||||
|
protected function configure(): void
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->addArgument(
|
||||||
|
'argument',
|
||||||
|
InputArgument::REQUIRED
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'option',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_REQUIRED
|
||||||
|
)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
|
{
|
||||||
|
echo self::$defaultName . ' ' . $input->getArgument('argument') . ' ' . $input->getOption('option');
|
||||||
|
|
||||||
|
return Command::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
15
Tests/Fixtures/App/TestCommandMessage.php
Normal file
15
Tests/Fixtures/App/TestCommandMessage.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Fixtures\App;
|
||||||
|
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\CommandMessage;
|
||||||
|
|
||||||
|
class TestCommandMessage extends CommandMessage
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->commandName = 'test';
|
||||||
|
$this->arguments = ['argument' => 'test'];
|
||||||
|
$this->options = ['option' => 'test'];
|
||||||
|
}
|
||||||
|
}
|
9
Tests/Fixtures/bin/console
Normal file
9
Tests/Fixtures/bin/console
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../../../vendor/autoload.php';
|
||||||
|
|
||||||
|
$input = new Symfony\Component\Console\Input\ArgvInput();
|
||||||
|
$kernel = new RetailCrm\ServiceBundle\Tests\Fixtures\App\Kernel('test', true);
|
||||||
|
$application = new Symfony\Bundle\FrameworkBundle\Console\Application($kernel);
|
||||||
|
$application->run($input);
|
38
Tests/Messenger/CommandMessageTest.php
Normal file
38
Tests/Messenger/CommandMessageTest.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Messenger;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use RetailCrm\ServiceBundle\Tests\DataFixtures\TestMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class CommandMessageTest
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Tests\Messenger
|
||||||
|
*/
|
||||||
|
class CommandMessageTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testMessage(): void
|
||||||
|
{
|
||||||
|
$message = new TestMessage();
|
||||||
|
|
||||||
|
static::assertEquals('test', $message->getCommandName());
|
||||||
|
static::assertEquals(['argument' => 'argument'], $message->getArguments());
|
||||||
|
static::assertEquals(['option' => 'option'], $message->getOptions());
|
||||||
|
static::assertEquals(['--option' => 'option'], $message->getFormattedOptions());
|
||||||
|
|
||||||
|
$message->addOption('option2', 'option2');
|
||||||
|
$message->addArgument('argument2', 'argument2');
|
||||||
|
|
||||||
|
static::assertEquals(['argument' => 'argument', 'argument2' => 'argument2'], $message->getArguments());
|
||||||
|
static::assertEquals(['option' => 'option', 'option2' => 'option2'], $message->getOptions());
|
||||||
|
static::assertEquals(['--option' => 'option', '--option2' => 'option2'], $message->getFormattedOptions());
|
||||||
|
|
||||||
|
$message->setOptions(['option' => 'option']);
|
||||||
|
$message->setArguments(['argument' => 'argument']);
|
||||||
|
|
||||||
|
static::assertEquals(['argument' => 'argument'], $message->getArguments());
|
||||||
|
static::assertEquals(['option' => 'option'], $message->getOptions());
|
||||||
|
static::assertEquals(['--option' => 'option'], $message->getFormattedOptions());
|
||||||
|
}
|
||||||
|
}
|
32
Tests/Messenger/MessageHandler/InNewProcessRunnerTest.php
Normal file
32
Tests/Messenger/MessageHandler/InNewProcessRunnerTest.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Messenger\MessageHandler;
|
||||||
|
|
||||||
|
use Psr\Log\NullLogger;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\MessageHandler\InNewProcessRunner;
|
||||||
|
use RetailCrm\ServiceBundle\Tests\Fixtures\App\TestCommandMessage;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class InNewProcessRunnerTest
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Tests\Messenger\MessageHandler
|
||||||
|
*/
|
||||||
|
class InNewProcessRunnerTest extends KernelTestCase
|
||||||
|
{
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
self::bootKernel(['environment' => 'test']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRun(): void
|
||||||
|
{
|
||||||
|
$runner = new InNewProcessRunner(new NullLogger, self::$kernel);
|
||||||
|
|
||||||
|
ob_clean();
|
||||||
|
ob_start();
|
||||||
|
$runner->run(new TestCommandMessage());
|
||||||
|
|
||||||
|
static::assertEquals('test test test', ob_get_clean());
|
||||||
|
}
|
||||||
|
}
|
32
Tests/Messenger/MessageHandler/SimpleConsoleRunnerTest.php
Normal file
32
Tests/Messenger/MessageHandler/SimpleConsoleRunnerTest.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Messenger\MessageHandler;
|
||||||
|
|
||||||
|
use Psr\Log\NullLogger;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\MessageHandler\SimpleConsoleRunner;
|
||||||
|
use RetailCrm\ServiceBundle\Tests\Fixtures\App\TestCommandMessage;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SimpleConsoleRunnerTest
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Tests\Messenger\MessageHandler
|
||||||
|
*/
|
||||||
|
class SimpleConsoleRunnerTest extends KernelTestCase
|
||||||
|
{
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
self::bootKernel(['environment' => 'test']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRun(): void
|
||||||
|
{
|
||||||
|
$runner = new SimpleConsoleRunner(new NullLogger, self::$kernel);
|
||||||
|
|
||||||
|
ob_clean();
|
||||||
|
ob_start();
|
||||||
|
$runner->run(new TestCommandMessage());
|
||||||
|
|
||||||
|
static::assertEquals('test test test', ob_get_clean());
|
||||||
|
}
|
||||||
|
}
|
26
Tests/Messenger/MessageHandlerTest.php
Normal file
26
Tests/Messenger/MessageHandlerTest.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Messenger;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\CommandMessage;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\MessageHandler;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\MessageHandler\JobRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class MessageHandlerTest
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Tests\Messenger
|
||||||
|
*/
|
||||||
|
class MessageHandlerTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testRun(): void
|
||||||
|
{
|
||||||
|
$runner = $this->createMock(JobRunner::class);
|
||||||
|
$runner->expects(static::once())->method('run');
|
||||||
|
$message = $this->createMock(CommandMessage::class);
|
||||||
|
|
||||||
|
$handler = new MessageHandler($runner);
|
||||||
|
$handler->__invoke($message);
|
||||||
|
}
|
||||||
|
}
|
@ -5,11 +5,14 @@ namespace RetailCrm\ServiceBundle\Tests\Security;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use RetailCrm\ServiceBundle\Response\ErrorJsonResponseFactory;
|
use RetailCrm\ServiceBundle\Response\ErrorJsonResponseFactory;
|
||||||
use RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator;
|
use RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator;
|
||||||
|
use RetailCrm\ServiceBundle\Tests\DataFixtures\User;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
|
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CallbackClientAuthenticatorTest
|
* Class CallbackClientAuthenticatorTest
|
||||||
@ -99,7 +102,7 @@ class CallbackClientAuthenticatorTest extends TestCase
|
|||||||
);
|
);
|
||||||
|
|
||||||
$auth = new CallbackClientAuthenticator($errorResponseFactory);
|
$auth = new CallbackClientAuthenticator($errorResponseFactory);
|
||||||
$result = $auth->start(new Request(), new AuthenticationException());
|
$result = $auth->onAuthenticationFailure(new Request(), new AuthenticationException());
|
||||||
|
|
||||||
static::assertInstanceOf(JsonResponse::class, $result);
|
static::assertInstanceOf(JsonResponse::class, $result);
|
||||||
static::assertEquals(Response::HTTP_FORBIDDEN, $result->getStatusCode());
|
static::assertEquals(Response::HTTP_FORBIDDEN, $result->getStatusCode());
|
||||||
@ -132,4 +135,34 @@ class CallbackClientAuthenticatorTest extends TestCase
|
|||||||
|
|
||||||
static::assertFalse($result);
|
static::assertFalse($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetUser(): void
|
||||||
|
{
|
||||||
|
$errorResponseFactory = $this->createMock(ErrorJsonResponseFactory::class);
|
||||||
|
$user = new User();
|
||||||
|
$auth = new CallbackClientAuthenticator($errorResponseFactory);
|
||||||
|
|
||||||
|
$userProvider = $this->createMock(UserProviderInterface::class);
|
||||||
|
$userProvider
|
||||||
|
->expects(static::once())
|
||||||
|
->method('loadUserByUsername')
|
||||||
|
->with('clientId')
|
||||||
|
->willReturn($user)
|
||||||
|
;
|
||||||
|
|
||||||
|
$result = $auth->getUser('clientId', $userProvider);
|
||||||
|
static::assertEquals($user, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOnAuthenticationSuccess(): void
|
||||||
|
{
|
||||||
|
$errorResponseFactory = $this->createMock(ErrorJsonResponseFactory::class);
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$token = $this->createMock(TokenInterface::class);
|
||||||
|
$auth = new CallbackClientAuthenticator($errorResponseFactory);
|
||||||
|
|
||||||
|
$result = $auth->onAuthenticationSuccess($request, $token, 'key');
|
||||||
|
|
||||||
|
static::assertNull($result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,15 @@ namespace RetailCrm\ServiceBundle\Tests\Security;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use RetailCrm\ServiceBundle\Response\ErrorJsonResponseFactory;
|
use RetailCrm\ServiceBundle\Response\ErrorJsonResponseFactory;
|
||||||
use RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator;
|
|
||||||
use RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator;
|
use RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator;
|
||||||
use RetailCrm\ServiceBundle\Tests\DataFixtures\User;
|
use RetailCrm\ServiceBundle\Tests\DataFixtures\User;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
use Symfony\Component\Security\Core\Security;
|
use Symfony\Component\Security\Core\Security;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class FrontApiClientAuthenticatorTest
|
* Class FrontApiClientAuthenticatorTest
|
||||||
@ -45,11 +45,11 @@ class FrontApiClientAuthenticatorTest extends TestCase
|
|||||||
$security = $this->createMock(Security::class);
|
$security = $this->createMock(Security::class);
|
||||||
|
|
||||||
$auth = new FrontApiClientAuthenticator($errorResponseFactory, $security);
|
$auth = new FrontApiClientAuthenticator($errorResponseFactory, $security);
|
||||||
$result = $auth->getCredentials(new Request([], [CallbackClientAuthenticator::AUTH_FIELD => '123']));
|
$result = $auth->getCredentials(new Request([], [FrontApiClientAuthenticator::AUTH_FIELD => '123']));
|
||||||
|
|
||||||
static::assertEquals('123', $result);
|
static::assertEquals('123', $result);
|
||||||
|
|
||||||
$result = $auth->getCredentials(new Request([CallbackClientAuthenticator::AUTH_FIELD => '123']));
|
$result = $auth->getCredentials(new Request([FrontApiClientAuthenticator::AUTH_FIELD => '123']));
|
||||||
|
|
||||||
static::assertEquals('123', $result);
|
static::assertEquals('123', $result);
|
||||||
}
|
}
|
||||||
@ -120,4 +120,37 @@ class FrontApiClientAuthenticatorTest extends TestCase
|
|||||||
|
|
||||||
static::assertTrue($result);
|
static::assertTrue($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetUser(): void
|
||||||
|
{
|
||||||
|
$errorResponseFactory = $this->createMock(ErrorJsonResponseFactory::class);
|
||||||
|
$security = $this->createMock(Security::class);
|
||||||
|
|
||||||
|
$user = new User();
|
||||||
|
$auth = new FrontApiClientAuthenticator($errorResponseFactory, $security);
|
||||||
|
|
||||||
|
$userProvider = $this->createMock(UserProviderInterface::class);
|
||||||
|
$userProvider
|
||||||
|
->expects(static::once())
|
||||||
|
->method('loadUserByUsername')
|
||||||
|
->with('clientId')
|
||||||
|
->willReturn($user)
|
||||||
|
;
|
||||||
|
|
||||||
|
$result = $auth->getUser('clientId', $userProvider);
|
||||||
|
static::assertEquals($user, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOnAuthenticationSuccess(): void
|
||||||
|
{
|
||||||
|
$errorResponseFactory = $this->createMock(ErrorJsonResponseFactory::class);
|
||||||
|
$security = $this->createMock(Security::class);
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$token = $this->createMock(TokenInterface::class);
|
||||||
|
$auth = new FrontApiClientAuthenticator($errorResponseFactory, $security);
|
||||||
|
|
||||||
|
$result = $auth->onAuthenticationSuccess($request, $token, 'key');
|
||||||
|
|
||||||
|
static::assertNull($result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,11 @@
|
|||||||
"symfony/serializer": "^5.2",
|
"symfony/serializer": "^5.2",
|
||||||
"symfony/http-kernel": "^4.0|^5.0",
|
"symfony/http-kernel": "^4.0|^5.0",
|
||||||
"symfony/validator": "^4.0|^5.0",
|
"symfony/validator": "^4.0|^5.0",
|
||||||
"symfony/security-guard": "^4.0|^5.0"
|
"symfony/security-guard": "^4.0|^5.0",
|
||||||
|
"symfony/console": "^5.2",
|
||||||
|
"symfony/messenger": "^5.2",
|
||||||
|
"symfony/process": "^5.2",
|
||||||
|
"symfony/event-dispatcher": "^5.2"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
@ -10,6 +10,9 @@
|
|||||||
stopOnFailure="false"
|
stopOnFailure="false"
|
||||||
bootstrap="vendor/autoload.php"
|
bootstrap="vendor/autoload.php"
|
||||||
>
|
>
|
||||||
|
<php>
|
||||||
|
<server name="KERNEL_CLASS" value="RetailCrm\ServiceBundle\Tests\Fixtures\App\Kernel" />
|
||||||
|
</php>
|
||||||
<coverage>
|
<coverage>
|
||||||
<include>
|
<include>
|
||||||
<directory>./</directory>
|
<directory>./</directory>
|
||||||
|
Loading…
Reference in New Issue
Block a user