• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemsdk / docker-symfony-api / #74

pending completion
#74

push

DKravtsov
Php 8.2, symfony 6.2, updated RabbitMQ, updated composer dependencies, refactoring.

51 of 51 new or added lines in 44 files covered. (100.0%)

1479 of 2668 relevant lines covered (55.43%)

23.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

61.29
/src/User/Transport/EventSubscriber/LockedUserSubscriber.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace App\User\Transport\EventSubscriber;
6

7
use App\Log\Application\Resource\LogLoginFailureResource;
8
use App\Log\Domain\Entity\LogLoginFailure;
9
use App\User\Application\Security\SecurityUser;
10
use App\User\Domain\Entity\User;
11
use App\User\Domain\Repository\Interfaces\UserRepositoryInterface;
12
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationFailureEvent;
13
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent;
14
use Lexik\Bundle\JWTAuthenticationBundle\Events;
15
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\HttpFoundation\RequestStack;
18
use Symfony\Component\Security\Core\Exception\LockedException;
19
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
20
use Throwable;
21

22
use function assert;
23
use function count;
24
use function is_string;
25

26
/**
27
 * Class LockedUserSubscriber
28
 *
29
 * @package App\User
30
 */
31
class LockedUserSubscriber implements EventSubscriberInterface
32
{
33
    /**
34
     * @param \App\User\Infrastructure\Repository\UserRepository $userRepository
35
     */
36
    public function __construct(
37
        private readonly UserRepositoryInterface $userRepository,
38
        private readonly LogLoginFailureResource $logLoginFailureResource,
39
        private readonly RequestStack $requestStack,
40
        private readonly int $lockUserOnLoginFailureAttempts,
41
    ) {
42
    }
19✔
43

44
    /**
45
     * {@inheritdoc}
46
     *
47
     * @return array<string, string|array<int, string|int>>
48
     */
49
    public static function getSubscribedEvents(): array
50
    {
51
        return [
×
52
            AuthenticationSuccessEvent::class => [
×
53
                'onAuthenticationSuccess',
×
54
                128,
×
55
            ],
×
56
            Events::AUTHENTICATION_SUCCESS => [
×
57
                'onAuthenticationSuccess',
×
58
                128,
×
59
            ],
×
60
            AuthenticationFailureEvent::class => 'onAuthenticationFailure',
×
61
            Events::AUTHENTICATION_FAILURE => 'onAuthenticationFailure',
×
62
        ];
×
63
    }
64

65
    /**
66
     * @throws Throwable
67
     */
68
    public function onAuthenticationSuccess(AuthenticationSuccessEvent $event): void
69
    {
70
        $user = $this->getUser($event->getUser()) ?? throw new UnsupportedUserException('Unsupported user.');
18✔
71

72
        if (
73
            $this->lockUserOnLoginFailureAttempts
18✔
74
            && count($user->getLogsLoginFailure()) > $this->lockUserOnLoginFailureAttempts
18✔
75
        ) {
76
            throw new LockedException('Locked account.');
77
        }
78

79
        $this->logLoginFailureResource->reset($user);
18✔
80
    }
81

82
    /**
83
     * @throws Throwable
84
     */
85
    public function onAuthenticationFailure(): void
86
    {
87
        $request = $this->requestStack->getCurrentRequest();
1✔
88
        assert($request instanceof Request);
89
        $user = $this->getUser(
1✔
90
            (string)($request->query->get('username') ?? $request->request->get('username', ''))
1✔
91
        );
1✔
92

93
        if ($user !== null) {
1✔
94
            $this->logLoginFailureResource->save(new LogLoginFailure($user), true);
1✔
95
        }
96
    }
97

98
    /**
99
     * @throws Throwable
100
     */
101
    private function getUser(string | object $user): ?User
102
    {
103
        return match (true) {
19✔
104
            is_string($user) => $this->userRepository->loadUserByIdentifier($user, false),
19✔
105
            $user instanceof SecurityUser => $this->userRepository->loadUserByIdentifier(
19✔
106
                $user->getUserIdentifier(),
19✔
107
                true
19✔
108
            ),
19✔
109
            default => null,
19✔
110
        };
19✔
111
    }
112
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc