Skip to content

Commit

Permalink
Merge pull request #10 from irontec/CDD-4-activate-administrators
Browse files Browse the repository at this point in the history
Activate administrators
  • Loading branch information
danigargar authored Feb 20, 2024
2 parents ad00064 + b3436b5 commit 8a75c2b
Show file tree
Hide file tree
Showing 13 changed files with 277 additions and 2 deletions.
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
);
}
}
}

0 comments on commit 8a75c2b

Please sign in to comment.