Completed
Pull Request — master (#144)
by
unknown
12:26
created

ApiKeyAuthenticator::onAuthenticationFailure()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 28
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 1
Metric Value
cc 2
eloc 20
nc 2
nop 2
dl 0
loc 28
rs 8.8571
c 2
b 1
f 1
1
<?php
2
3
namespace AppBundle\Security;
4
5
use AppBundle\Entity\Client;
6
use Monolog\Logger;
7
use Doctrine\Common\Persistence\ManagerRegistry;
8
use Symfony\Component\HttpFoundation\Request;
9
use Symfony\Component\HttpFoundation\JsonResponse;
10
use Symfony\Component\HttpFoundation\Response;
11
use Symfony\Component\Security\Core\User\UserInterface;
12
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
13
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
14
use Symfony\Component\Security\Core\Exception\AuthenticationException;
15
use Symfony\Component\Security\Core\User\UserProviderInterface;
16
use Symfony\Component\HttpKernel\Exception\HttpException;
17
18
class ApiKeyAuthenticator extends AbstractGuardAuthenticator
19
{
20
    /**
21
     * @var ManagerRegistry
22
     */
23
    private $registry;
24
    /**
25
     * @var Logger
26
     */
27
    private $logger;
28
29
    public function __construct(ManagerRegistry $registry, Logger $logger)
30
    {
31
        $this->registry = $registry;
32
        $this->logger = $logger;
33
    }
34
35
    /**
36
     * {@inheritdoc}
37
     */
38
    public function getCredentials(Request $request)
39
    {
40
        $client = $this->registry->getRepository('AppBundle:Client')
41
            ->findIpBanned($request->getClientIp());
42
43
        if ($client) {
44
            throw new HttpException(403, 'Forbidden. You\'re banned!');
45
        }
46
47
        if (!$token = $request->headers->get('API-Key-Token')) {
48
            return null;
49
        }
50
51
        return array(
52
            'token' => $token,
53
        );
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59
    public function getUser($credentials, UserProviderInterface $userProvider)
60
    {
61
        $apiKey = $credentials['token'];
62
63
        $user = $this->registry->getRepository('AppBundle:User')
64
            ->findOneBy(['apiKey' => $apiKey]);
65
66
        return $user;
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72
    public function checkCredentials($credentials, UserInterface $user)
73
    {
74
        return true;
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
81
    {
82
        return null;
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
89
    {
90
        $data = [
91
            'code' => '403',
92
            'message' => 'Forbidden. You don\'t have necessary permissions for the resource',
93
        ];
94
        $client = $this->registry->getRepository('AppBundle:Client')
95
            ->findOneBy(['ip' => $request->getClientIp()]);
96
97
        if ($client) {
98
            $countAttempts = $client->getCountAttempts();
99
            $client->setCountAttempts(++$countAttempts);
100
            $this->registry->getManager()->flush();
101
            $this->writeLogger($client);
102
103
            return new JsonResponse($data, Response::HTTP_FORBIDDEN);
104
        }
105
106
        $client = new Client();
107
        $client->setCountAttempts(1);
108
        $client->setIp($request->getClientIp());
109
        $client->setBanned(false);
110
        $this->registry->getManager()->persist($client);
111
        $this->registry->getManager()->flush();
112
        $this->writeLogger($client);
113
114
        return new JsonResponse($data, Response::HTTP_FORBIDDEN);
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120
    public function start(Request $request, AuthenticationException $authException = null)
121
    {
122
        $data = [
123
            'code' => '401',
124
            'message' => 'Authentication required',
125
        ];
126
127
        return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
128
    }
129
130
    /**
131
     * {@inheritdoc}
132
     */
133
    public function supportsRememberMe()
134
    {
135
        return false;
136
    }
137
138
    /**
139
     * {@inheritdoc}
140
     */
141
    private function writeLogger($client)
142
    {
143
        if ($client->getCountAttempts() % 50 == 0 || $client->getCountAttempts() == 1) {
144
            $this->logger->err('403. api_key not valid!');
145
        }
146
    }
147
}
148