Completed
Push — master ( 055b70...427a37 )
by Artem
03:41
created

EventListener/UserLockout.php (1 issue)

Check that an empty catch block is always commented

Coding Style Comprehensibility Informational

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
//----------------------------------------------------------------------
4
//
5
//  Copyright (C) 2017 Artem Rodygin
6
//
7
//  You should have received a copy of the MIT License along with
8
//  this file. If not, see <http://opensource.org/licenses/MIT>.
9
//
10
//----------------------------------------------------------------------
11
12
namespace Pignus\EventListener;
13
14
use Doctrine\Common\Persistence\ObjectManager;
15
use Pignus\Model\LockAccountTrait;
16
use Psr\Log\LoggerInterface;
17
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
18
use Symfony\Component\Security\Core\AuthenticationEvents;
19
use Symfony\Component\Security\Core\Event\AuthenticationEvent;
20
use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
21
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
22
use Symfony\Component\Security\Core\User\UserInterface;
23
use Symfony\Component\Security\Core\User\UserProviderInterface;
24
25
/**
26
 * Locks/unlocks user in accordance with the authentication attempt.
27
 */
28
class UserLockout implements EventSubscriberInterface
29
{
30
    protected $logger;
31
    protected $manager;
32
    protected $provider;
33
    protected $auth_failures;
34
    protected $lock_duration;
35
36
    /**
37
     * Dependency Injection constructor.
38
     *
39
     * @param LoggerInterface       $logger
40
     * @param ObjectManager         $manager
41
     * @param UserProviderInterface $provider
42
     * @param int                   $auth_failures
43
     * @param int                   $lock_duration
44
     */
45 5
    public function __construct(
46
        LoggerInterface       $logger,
47
        ObjectManager         $manager,
48
        UserProviderInterface $provider,
49
        int                   $auth_failures = null,
50
        int                   $lock_duration = null)
51
    {
52 5
        $this->logger        = $logger;
53 5
        $this->manager       = $manager;
54 5
        $this->provider      = $provider;
55 5
        $this->auth_failures = $auth_failures;
56 5
        $this->lock_duration = $lock_duration;
57 5
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62 1
    public static function getSubscribedEvents()
63
    {
64
        return [
65 1
            AuthenticationEvents::AUTHENTICATION_SUCCESS => 'onSuccess',
66 1
            AuthenticationEvents::AUTHENTICATION_FAILURE => 'onFailure',
67
        ];
68
    }
69
70
    /**
71
     * Callback for successful authentication event.
72
     *
73
     * @param AuthenticationEvent $event
74
     */
75 1
    public function onSuccess(AuthenticationEvent $event)
76
    {
77 1
        $token = $event->getAuthenticationToken();
78
79
        /** @var LockAccountTrait $user */
80 1
        $user = $token->getUser();
81
82 1
        if ($user instanceof UserInterface && in_array(LockAccountTrait::class, class_uses($user), true)) {
83
84 1
            $this->logger->info('Authentication success', [$user->getUsername()]);
85
86 1
            $user->unlockAccount();
87
88 1
            $this->manager->persist($user);
89 1
            $this->manager->flush();
90
        }
91 1
    }
92
93
    /**
94
     * Callback for failed authentication event.
95
     *
96
     * @param AuthenticationFailureEvent $event
97
     */
98 4
    public function onFailure(AuthenticationFailureEvent $event)
99
    {
100 4
        $token = $event->getAuthenticationToken();
101
102 4
        $credentials = $token->getCredentials();
103 4
        $username    = $token->getUsername() ?: ($credentials['username'] ?? null);
104
105 4
        if ($username && $this->auth_failures !== null) {
106
107
            try {
108
                /** @var LockAccountTrait $user */
109 3
                $user = $this->provider->loadUserByUsername($username);
110
111 2
                if ($user instanceof UserInterface && in_array(LockAccountTrait::class, class_uses($user), true)) {
112
113 2
                    $this->logger->info('Authentication failure', [$username]);
114
115 2
                    if ($user->incAuthFailures() >= $this->auth_failures) {
116
117 2
                        if ($this->lock_duration === null) {
118 1
                            $user->lockAccount();
119
                        }
120
                        else {
121 1
                            $interval = sprintf('PT%dM', $this->lock_duration);
122 1
                            $user->lockAccount(date_create()->add(new \DateInterval($interval)));
123
                        }
124
                    }
125
126 2
                    $this->manager->persist($user);
127 2
                    $this->manager->flush();
128
                }
129
            }
130 1
            catch (UsernameNotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
131
            }
132
        }
133 4
    }
134
}
135