Skip to content

Commit

Permalink
Merge branch 'refactor-config'
Browse files Browse the repository at this point in the history
  • Loading branch information
mariusklocke committed Dec 15, 2023
2 parents 8ddc2f4 + c47e4f0 commit aabea2a
Show file tree
Hide file tree
Showing 18 changed files with 176 additions and 174 deletions.
21 changes: 7 additions & 14 deletions src/Application/Handler/SendInviteMailHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,28 @@
use HexagonalPlayground\Application\Command\SendInviteMailCommand;
use HexagonalPlayground\Application\Email\MailerInterface;
use HexagonalPlayground\Application\Security\AuthContext;
use HexagonalPlayground\Application\Security\TokenFactoryInterface;
use HexagonalPlayground\Application\Security\TokenServiceInterface;
use HexagonalPlayground\Application\Security\UserRepositoryInterface;
use HexagonalPlayground\Application\TemplateRendererInterface;
use HexagonalPlayground\Domain\Event\Event;
use HexagonalPlayground\Domain\User;

class SendInviteMailHandler implements AuthAwareHandler
{
/** @var TokenFactoryInterface */
private TokenFactoryInterface $tokenFactory;

/** @var UserRepositoryInterface */
private TokenServiceInterface $tokenService;
private UserRepositoryInterface $userRepository;

/** @var TemplateRendererInterface */
private TemplateRendererInterface $templateRenderer;

/** @var MailerInterface */
private MailerInterface $mailer;

/**
* @param TokenFactoryInterface $tokenFactory
* @param TokenServiceInterface $tokenService
* @param UserRepositoryInterface $userRepository
* @param TemplateRendererInterface $templateRenderer
* @param MailerInterface $mailer
*/
public function __construct(TokenFactoryInterface $tokenFactory, UserRepositoryInterface $userRepository, TemplateRendererInterface $templateRenderer, MailerInterface $mailer)
public function __construct(TokenServiceInterface $tokenService, UserRepositoryInterface $userRepository, TemplateRendererInterface $templateRenderer, MailerInterface $mailer)
{
$this->tokenFactory = $tokenFactory;
$this->tokenService = $tokenService;
$this->userRepository = $userRepository;
$this->templateRenderer = $templateRenderer;
$this->mailer = $mailer;
Expand All @@ -51,11 +44,11 @@ public function __invoke(SendInviteMailCommand $command, AuthContext $authContex

/** @var User $user */
$user = $this->userRepository->find($command->getUserId());
$token = $this->tokenFactory->create($user, new DateTimeImmutable('now + 1 week'));
$token = $this->tokenService->create($user, new DateTimeImmutable('now + 1 week'));

$targetUri = $command->getBaseUri()
->withPath($command->getTargetPath())
->withQuery(http_build_query(['token' => $token->encode()]));
->withQuery(http_build_query(['token' => $this->tokenService->encode($token)]));

$message = $this->mailer->createMessage(
[$user->getEmail() => $user->getFullName()],
Expand Down
21 changes: 7 additions & 14 deletions src/Application/Handler/SendPasswordResetMailHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,28 @@
use DateTimeImmutable;
use HexagonalPlayground\Application\Command\SendPasswordResetMailCommand;
use HexagonalPlayground\Application\Email\MailerInterface;
use HexagonalPlayground\Application\Security\TokenServiceInterface;
use HexagonalPlayground\Domain\Exception\NotFoundException;
use HexagonalPlayground\Application\Security\TokenFactoryInterface;
use HexagonalPlayground\Application\Security\UserRepositoryInterface;
use HexagonalPlayground\Application\TemplateRendererInterface;
use HexagonalPlayground\Domain\Event\Event;

class SendPasswordResetMailHandler
{
/** @var TokenFactoryInterface */
private TokenFactoryInterface $tokenFactory;

/** @var UserRepositoryInterface */
private TokenServiceInterface $tokenService;
private UserRepositoryInterface $userRepository;

/** @var TemplateRendererInterface */
private TemplateRendererInterface $templateRenderer;

/** @var MailerInterface */
private MailerInterface $mailer;

/**
* @param TokenFactoryInterface $tokenFactory
* @param TokenServiceInterface $tokenService
* @param UserRepositoryInterface $userRepository
* @param TemplateRendererInterface $templateRenderer
* @param MailerInterface $mailer
*/
public function __construct(TokenFactoryInterface $tokenFactory, UserRepositoryInterface $userRepository, TemplateRendererInterface $templateRenderer, MailerInterface $mailer)
public function __construct(TokenServiceInterface $tokenService, UserRepositoryInterface $userRepository, TemplateRendererInterface $templateRenderer, MailerInterface $mailer)
{
$this->tokenFactory = $tokenFactory;
$this->tokenService = $tokenService;
$this->userRepository = $userRepository;
$this->templateRenderer = $templateRenderer;
$this->mailer = $mailer;
Expand All @@ -52,12 +45,12 @@ public function __invoke(SendPasswordResetMailCommand $command): array
return []; // Simply do nothing, when user cannot be found to prevent user discovery attacks
}

$token = $this->tokenFactory->create($user, new DateTimeImmutable('now + 1 day'));
$token = $this->tokenService->create($user, new DateTimeImmutable('now + 1 day'));

$targetUri = $command
->getBaseUri()
->withPath($command->getTargetPath())
->withQuery(http_build_query(['token' => $token->encode()]));
->withQuery(http_build_query(['token' => $this->tokenService->encode($token)]));

$message = $this->mailer->createMessage(
[$user->getEmail() => $user->getFullName()],
Expand Down
9 changes: 1 addition & 8 deletions src/Application/Security/TokenInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,4 @@ public function getUserId(): string;
* @return DateTimeImmutable
*/
public function getExpiresAt(): DateTimeImmutable;

/**
* Encodes the token into a string
*
* @return string
*/
public function encode(): string;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use DateTimeImmutable;
use HexagonalPlayground\Domain\User;

interface TokenFactoryInterface
interface TokenServiceInterface
{
/**
* Create a new token for the given user
Expand All @@ -16,4 +16,20 @@ interface TokenFactoryInterface
* @return TokenInterface
*/
public function create(User $user, DateTimeImmutable $expiresAt): TokenInterface;
}

/**
* Encodes a token to string
*
* @param TokenInterface $token
* @return string
*/
public function encode(TokenInterface $token): string;

/**
* Decodes a token from string
*
* @param string $encodedToken
* @return TokenInterface
*/
public function decode(string $encodedToken): TokenInterface;
}
6 changes: 4 additions & 2 deletions src/Infrastructure/API/LoggerProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
use DI;
use HexagonalPlayground\Application\ServiceProviderInterface;
use HexagonalPlayground\Infrastructure\Config;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;

class LoggerProvider implements ServiceProviderInterface
{
public function getDefinitions(): array
{
return [
LoggerInterface::class => DI\factory(function () {
$config = Config::getInstance();
LoggerInterface::class => DI\factory(function (ContainerInterface $container) {
/** @var Config $config */
$config = $container->get(Config::class);
$stream = fopen($config->logPath, 'w');
$logLevel = $config->logLevel;

Expand Down
23 changes: 13 additions & 10 deletions src/Infrastructure/API/Security/AuthenticationMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use DateTimeImmutable;
use HexagonalPlayground\Application\Security\AuthenticationException;
use HexagonalPlayground\Application\Security\TokenFactoryInterface;
use HexagonalPlayground\Application\Security\TokenServiceInterface;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
Expand All @@ -14,7 +14,6 @@

class AuthenticationMiddleware implements MiddlewareInterface
{
/** @var ContainerInterface */
private ContainerInterface $container;

/**
Expand Down Expand Up @@ -71,11 +70,16 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
return $handler->handle($request);
}

/** @var TokenServiceInterface $tokenService */
$tokenService = $this->container->get(TokenServiceInterface::class);

list($type, $secret) = $this->parseAuthHeader($rawHeaderValue);
switch (strtolower($type)) {
case 'basic':
/** @var PasswordAuthenticator $authenticator */
$authenticator = $this->container->get(PasswordAuthenticator::class);
list($email, $password) = $this->parseCredentials($secret);
$context = $this->container->get(PasswordAuthenticator::class)->authenticate($email, $password);
$context = $authenticator->authenticate($email, $password);
$response = $handler->handle($request->withAttribute('auth', $context));

/**
Expand All @@ -86,16 +90,15 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
* @see TokenAuthenticator::authenticate()
*/

$token = $this->container->get(TokenFactoryInterface::class)->create(
$context->getUser(),
new DateTimeImmutable('now + 1 year')
);
$token = $tokenService->create($context->getUser(), new DateTimeImmutable('now + 1 year'));

return $response->withHeader('X-Token', $token->encode());
return $response->withHeader('X-Token', $tokenService->encode($token));

case 'bearer':
$token = JsonWebToken::decode($secret);
$context = $this->container->get(TokenAuthenticator::class)->authenticate($token);
/** @var TokenAuthenticator $authenticator */
$authenticator = $this->container->get(TokenAuthenticator::class);
$token = $tokenService->decode($secret);
$context = $authenticator->authenticate($token);

return $handler->handle($request->withAttribute('auth', $context));
}
Expand Down
62 changes: 0 additions & 62 deletions src/Infrastructure/API/Security/JsonWebToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,10 @@
namespace HexagonalPlayground\Infrastructure\API\Security;

use DateTimeImmutable;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use HexagonalPlayground\Application\Security\AuthenticationException;
use HexagonalPlayground\Application\Security\TokenInterface;
use HexagonalPlayground\Infrastructure\Config;

final class JsonWebToken implements TokenInterface
{
private const DATE_FORMAT = 'U';
private const ALGORITHM = 'HS256';

/** @var string */
private string $userId;

Expand Down Expand Up @@ -55,52 +48,6 @@ public function getUserId(): string
return $this->userId;
}

/**
* @return string
*/
public function encode(): string
{
$payload = [
'sub' => $this->userId,
'iat' => $this->issuedAt->format(self::DATE_FORMAT),
'exp' => $this->expiresAt->format(self::DATE_FORMAT)
];
return JWT::encode($payload, self::getSecret(), self::ALGORITHM);
}

/**
* @param string $encoded
* @return JsonWebToken
*/
public static function decode(string $encoded): self
{
try {
$key = new Key(self::getSecret(), self::ALGORITHM);
$payload = JWT::decode($encoded, $key);
} catch (\Exception $e) {
throw new AuthenticationException('Invalid Token');
}

$subject = $payload->sub;
$issuedAt = DateTimeImmutable::createFromFormat(self::DATE_FORMAT, $payload->iat);
$expiresAt = isset($payload->exp)
? DateTimeImmutable::createFromFormat(self::DATE_FORMAT, $payload->exp)
: new DateTimeImmutable();

return new self($subject, $issuedAt, $expiresAt);
}

/**
* @return string
*/
private static function getSecret(): string
{
if (null === self::$secret) {
self::$secret = hex2bin(Config::getInstance()->jwtSecret);
}
return self::$secret;
}

/**
* Returns when the token expires
*
Expand All @@ -110,13 +57,4 @@ public function getExpiresAt(): DateTimeImmutable
{
return $this->expiresAt;
}

/**
* @param int $bytes
* @return string
*/
public static function generateSecret(int $bytes = 32): string
{
return bin2hex(random_bytes($bytes));
}
}
22 changes: 0 additions & 22 deletions src/Infrastructure/API/Security/JsonWebTokenFactory.php

This file was deleted.

Loading

0 comments on commit aabea2a

Please sign in to comment.