Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Activate administrators #10

Merged
merged 2 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions app/config/api/raw/demo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@
## Raw
########################################
Demo\Domain\Model\Administrator\Administrator:
itemOperations:
get: ~
put: ~
delete: ~
post_send_administrator_activation_email:
method: 'POST'
path: '/administrators/{id}/send_activation_email'
route_name: 'post_send_administrator_activation_email'
requirements:
id: '\d+'
swagger_context:
summary: 'Sends activation email to an Administrator'
parameters:
- in: body # avoid api platform to inject default parameters
produces:
- 'application/json'
responses:
'200':
description: Verification email sent
'404':
description: Resource not found
'400':
description: Bad request
attributes:
access_control: '"ROLE_ADMIN" in roles'
order:
Expand Down
4 changes: 4 additions & 0 deletions app/config/packages/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ security:
pattern: ^/token/refresh
stateless: true

activate_admin:
pattern: ^/activate_admin/\d+$
security: false

api:
pattern: ^/.+
stateless: true
Expand Down
18 changes: 18 additions & 0 deletions app/config/routes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,21 @@ api_base_path:

api_admin_login:
path: admin_login

post_send_administrator_activation_email:
path: '/administrators/{id}/send_activation_email'
methods: ['POST']
requirements:
id: '\d+'
defaults:
_controller: App\Controller\Administrator\SendActivationEmail
_api_item_operation_name: 'send_activacion_email'
_api_receive: false

get_activate_administrator:
path: '/activate_admin/{id}'
methods: ['GET']
requirements:
id: '\d+'
defaults:
_controller: App\Controller\Administrator\Activate
24 changes: 24 additions & 0 deletions app/src/App/Controller/Administrator/Activate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace App\Controller\Administrator;

use Demo\Application\Service\Administrator\ActivateAdministrator;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;

class Activate
{
public function __construct(
private ActivateAdministrator $activateAdministrator
) {
}

public function __invoke(Request $request): Response
{
$administratorId = (int) $request->get('id');

$this->activateAdministrator->execute($administratorId);

return new Response('Administrator activated', 200);
}
}
35 changes: 35 additions & 0 deletions app/src/App/Controller/Administrator/SendActivationEmail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace App\Controller\Administrator;

use Demo\Domain\Model\Administrator\AdministratorRepository;
use Demo\Domain\Service\Administrator\SendActivationEmailInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class SendActivationEmail
{
public function __construct(
private SendActivationEmailInterface $sendActivationEmail,
private AdministratorRepository $administratorRepository
) {
}

public function __invoke(Request $request): Response
{
$response = new Response();

$administratorId = (int) $request->attributes->get('id');

$administrator = $this->administratorRepository->find($administratorId);
if ($administrator === null) {
throw new \DomainException("Resource not found", 404);
}

$this->sendActivationEmail->execute($administrator);
$response->setStatusCode(200);

return $response;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Demo\Application\Service\Administrator;

use Demo\Domain\Model\Administrator\AdministratorDto;
use Demo\Domain\Model\Administrator\AdministratorRepository;
use Ivoz\Core\Domain\Service\EntityTools;

class ActivateAdministrator
{
public function __construct(
private AdministratorRepository $administratorRepository,
private EntityTools $entityTools
) {
}

public function execute(int $administratorId): void
{
$administrator = $this->administratorRepository->find($administratorId);

if ($administrator === null) {
throw new \DomainException('Administrator not found.', 404);
}

/** @var AdministratorDto $administratorDto */
$administratorDto = $this->entityTools->entityToDto($administrator);
$administratorDto->setActive(1);
$this->entityTools->persistDto($administratorDto, $administrator);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Demo\Domain\Service\Administrator;

use Demo\Domain\Model\Administrator\AdministratorInterface;
use Ivoz\Core\Domain\Service\LifecycleEventHandlerInterface;

interface AdministratorLifecycleEventHandlerInterface extends LifecycleEventHandlerInterface
{
public function execute(AdministratorInterface $administrator): void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Demo\Domain\Service\Administrator;

use Ivoz\Core\Domain\Assert\Assertion;
use Ivoz\Core\Domain\Model\EntityInterface;
use Ivoz\Core\Domain\Service\DomainEventSubscriberInterface;
use Ivoz\Core\Domain\Service\LifecycleEventHandlerInterface;
use Ivoz\Core\Domain\Service\LifecycleServiceCollectionInterface;
use Ivoz\Core\Domain\Service\LifecycleServiceCollectionTrait;

class AdministratorLifecycleServiceCollection implements LifecycleServiceCollectionInterface
{
use LifecycleServiceCollectionTrait;

/** @var array<array-key, array> $bindedBaseServices */
public static $bindedBaseServices = [
"on_commit" =>
[
\Demo\Domain\Service\Administrator\SendActivationEmail::class => 200,
],
];

protected function addService(string $event, LifecycleEventHandlerInterface|DomainEventSubscriberInterface $service): void
{
Assertion::isInstanceof($service, AdministratorLifecycleEventHandlerInterface::class);
$this->services[$event][] = $service;
}
}
45 changes: 45 additions & 0 deletions app/src/Demo/Domain/Service/Administrator/SendActivationEmail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Demo\Domain\Service\Administrator;

use Demo\Domain\Model\Administrator\AdministratorInterface;
use Psr\Log\LoggerInterface;

class SendActivationEmail implements AdministratorLifecycleEventHandlerInterface
{
public const ON_COMMIT_PRIORITY = self::PRIORITY_NORMAL;

public function __construct(
private SendActivationEmailInterface $sendActivationEmail,
private LoggerInterface $logger
) {
}

/**
* @return array<string, int>
*/
public static function getSubscribedEvents(): array
{
return [
self::EVENT_ON_COMMIT => self::ON_COMMIT_PRIORITY
];
}

/**
* @throws \DomainException
*/
public function execute(AdministratorInterface $administrator): void
{
$isNew = $administrator->isNew();
if (!$isNew) {
return;
}

$isActive = $administrator->getActive();
if ($isActive) {
return;
}

$this->sendActivationEmail->execute($administrator);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Demo\Domain\Service\Administrator;

use Demo\Domain\Model\Administrator\AdministratorInterface;

interface SendActivationEmailInterface
{
public function execute(AdministratorInterface $administrator): void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ public function findByUsername(string $username): ?AdministratorInterface

return $administrator;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ public function __construct(
$entityPersisterInterface
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace Demo\Infrastructure\Service\Administrator;

use Demo\Domain\Model\Administrator\AdministratorInterface;
use Demo\Domain\Model\Administrator\AdministratorRepository;
use Demo\Domain\Service\Administrator\SendActivationEmailInterface;
use Ivoz\Core\Domain\Model\Mailer\Message;
use Ivoz\Core\Domain\Service\MailerClientInterface;
use Psr\Log\LoggerInterface;

class SendActivationEmail implements SendActivationEmailInterface
{
public function __construct(
private MailerClientInterface $mailer,
private LoggerInterface $logger
) {
}

public function execute(AdministratorInterface $administrator): void
{
$administratorId = $administrator->getId();
$body = 'Hello, please activate your account following this link: ' . PHP_EOL
. 'https://10.189.4.23/demo/api/activate_admin/' . $administratorId . PHP_EOL;

$mail = new Message();
$mail->setBody($body, 'text/plain')
->setSubject('Activate your new account')
->setFromAddress('[email protected]')
->setFromName('Irontec demo')
->setToAddress($administrator->getEmail());

try {
$this->mailer->send($mail);
} catch (\Exception $e) {
$errorMsg = 'Unable to send activation email';
$this->logger->error($errorMsg . ':' . $e->getMessage());

throw new \DomainException(
$errorMsg,
$e->getCode(),
$e
);
}
}
}
Loading