Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
96.97% |
32 / 33 |
|
50.00% |
1 / 2 |
CRAP | |
0.00% |
0 / 1 |
| CheckAuthenticatedContextBuilder | |
96.97% |
32 / 33 |
|
50.00% |
1 / 2 |
12 | |
0.00% |
0 / 1 |
| __construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| process | |
96.88% |
31 / 32 |
|
0.00% |
0 / 1 |
11 | |||
| 1 | <?php |
| 2 | namespace Apie\Common\ContextBuilders; |
| 3 | |
| 4 | use Apie\Common\ContextBuilders\Exceptions\WrongTokenException; |
| 5 | use Apie\Common\Events\AddAuthenticationCookie; |
| 6 | use Apie\Common\ValueObjects\DecryptedAuthenticatedUser; |
| 7 | use Apie\Common\Wrappers\TextEncrypter; |
| 8 | use Apie\Core\Context\ApieContext; |
| 9 | use Apie\Core\ContextBuilders\ContextBuilderInterface; |
| 10 | use Apie\Core\ContextConstants; |
| 11 | use Apie\Core\Datalayers\ApieDatalayer; |
| 12 | use Exception; |
| 13 | use Psr\Http\Message\ServerRequestInterface; |
| 14 | use Psr\Log\LoggerInterface; |
| 15 | |
| 16 | class CheckAuthenticatedContextBuilder implements ContextBuilderInterface |
| 17 | { |
| 18 | public function __construct( |
| 19 | private readonly LoggerInterface $logger |
| 20 | ) { |
| 21 | } |
| 22 | |
| 23 | public function process(ApieContext $context): ApieContext |
| 24 | { |
| 25 | if (!$context->hasContext(DecryptedAuthenticatedUser::class)) { |
| 26 | $textEncrypter = $context->getContext(TextEncrypter::class, false); |
| 27 | $request = $context->getContext(ServerRequestInterface::class, false); |
| 28 | $datalayer = $context->getContext(ApieDatalayer::class, false); |
| 29 | if ($textEncrypter instanceof TextEncrypter |
| 30 | && $request instanceof ServerRequestInterface |
| 31 | && $datalayer instanceof ApieDatalayer) { |
| 32 | $name = $request->getCookieParams()[AddAuthenticationCookie::COOKIE_NAME] ?? null; |
| 33 | $this->logger->debug($request->getUri()->__toString() . ' ' . ($name ?? 'no cookie')); |
| 34 | if ($name) { |
| 35 | try { |
| 36 | $decryptedUserId = new DecryptedAuthenticatedUser($textEncrypter->decrypt($name)); |
| 37 | if ($decryptedUserId->isExpired()) { |
| 38 | throw new \LogicException('Token is expired!'); |
| 39 | } |
| 40 | $authenticated = $datalayer->find($decryptedUserId->getId()); |
| 41 | $context = $context |
| 42 | ->withContext(ContextConstants::AUTHENTICATED_USER, $authenticated) |
| 43 | ->registerInstance($decryptedUserId); |
| 44 | } catch (Exception $error) { |
| 45 | $this->logger->error( |
| 46 | 'Error decrypting auth cookie: ' . $error->getMessage(), |
| 47 | ['error' => $error] |
| 48 | ); |
| 49 | |
| 50 | throw new WrongTokenException($error); |
| 51 | } |
| 52 | } |
| 53 | } else { |
| 54 | $this->logger->debug( |
| 55 | sprintf( |
| 56 | 'Could not determine authentication cookie as a dependency is missing: encrypter: %s, request: %s, data layer: %s', |
| 57 | $textEncrypter instanceof TextEncrypter ? 'true' : 'false', |
| 58 | $request instanceof ServerRequestInterface ? 'true' : 'false', |
| 59 | $datalayer instanceof ApieDatalayer ? 'true' : 'false' |
| 60 | ) |
| 61 | ); |
| 62 | } |
| 63 | } |
| 64 | return $context; |
| 65 | } |
| 66 | } |