Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
9 / 9
75.00% covered (warning)
75.00%
6 / 8
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
AltchaAuthenticator
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
9 / 9
75.00% covered (warning)
75.00%
6 / 8
100.00% covered (success)
100.00%
5 / 5
7.77
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 authenticate
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
5 / 5
50.00% covered (danger)
50.00%
2 / 4
100.00% covered (success)
100.00%
1 / 1
4.12
 supports
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onAuthenticationSuccess
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onAuthenticationFailure
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace App\Security\Authenticator;
4
5use App\Security\ApiUser;
6use App\Security\Service\AltchaServiceInterface;
7use Symfony\Component\DependencyInjection\Attribute\Autowire;
8use Symfony\Component\HttpFoundation\JsonResponse;
9use Symfony\Component\HttpFoundation\Request;
10use Symfony\Component\HttpFoundation\Response;
11use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
12use Symfony\Component\Security\Core\Exception\AuthenticationException;
13use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
14use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
15use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
16use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
17
18/**
19 * @author Wilhelm Zwertvaegher
20 */
21class AltchaAuthenticator extends AbstractAuthenticator
22{
23    public function __construct(
24        private readonly AltchaServiceInterface $altchaService,
25        #[Autowire('%altcha.header_payload_key%')]
26        private readonly string $headerPayloadKey,
27    ) {
28    }
29
30    public function authenticate(Request $request): Passport
31    {
32        $payload = $request->headers->get($this->headerPayloadKey);
33
34        if (!$payload || !$this->altchaService->verifySolution($payload)) {
35            throw new AuthenticationException('Captcha invalid');
36        }
37
38        return new SelfValidatingPassport(
39            new UserBadge('frontend', fn (string $userIdentifier) => new ApiUser($userIdentifier, ['ROLE_FRONTEND']))
40        );
41    }
42
43    public function supports(Request $request): ?bool
44    {
45        return $request->headers->has($this->headerPayloadKey);
46    }
47
48    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
49    {
50        return null;
51    }
52
53    public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
54    {
55        $data = [
56            'message' => $exception->getMessage(),
57        ];
58
59        return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
60    }
61}