Completed
Push — master ( 42da58...861c5b )
by Jafar
02:38
created

JwsAuthenticator::loadUser()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/*
3
 * This file is part of the Guarded Authentication package.
4
 *
5
 * (c) Jafar Jabr <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Jafar\Bundle\GuardedAuthenticationBundle\Guard;
12
13
use Jafar\Bundle\GuardedAuthenticationBundle\Api\ApiResponse\ApiProblem;
14
use Jafar\Bundle\GuardedAuthenticationBundle\Api\ApiResponse\ApiResponseFactory;
15
use Jafar\Bundle\GuardedAuthenticationBundle\Api\JWSEncoder\JWSEncoderInterface;
16
use Jafar\Bundle\GuardedAuthenticationBundle\Api\JWSExtractor\TokenExtractor;
17
use Jafar\Bundle\GuardedAuthenticationBundle\Exception\ApiException;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\Routing\RouterInterface;
20
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
21
use Symfony\Component\Security\Core\Exception\AuthenticationException;
22
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
23
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
24
use Symfony\Component\Security\Core\User\UserInterface;
25
use Symfony\Component\Security\Core\User\UserProviderInterface;
26
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
27
28
/**
29
 * {@inheritdoc}
30
 *
31
 * Class JwsAuthenticator
32
 *
33
 * @author Jafar Jabr <[email protected]>
34
 */
35
class JwsAuthenticator extends AbstractGuardAuthenticator
36
{
37
    /**
38
     * @var JWSEncoderInterface
39
     */
40
    private $jwtEncoder;
41
42
    /**
43
     * @var RouterInterface
44
     */
45
    private $router;
46
47
    /**
48
     * @var ApiResponseFactory
49
     */
50
    private $responseFactory;
51
52
    /**
53
     * @var string
54
     */
55
    private $loginRoute;
56
57
    /**
58
     * @var string
59
     */
60
    private $homeRoute;
61
62
    /**
63
     * JwsAuthenticator constructor.
64
     *
65
     * @param JWSEncoderInterface $jwtEncoder
66
     * @param RouterInterface $router
67
     * @param ApiResponseFactory $responseFactory
68
     * @param string $loginRoute
69
     * @param string $homeRoute
70
     */
71
    public function __construct(
72
        JWSEncoderInterface $jwtEncoder,
73
        RouterInterface $router,
74
        ApiResponseFactory $responseFactory,
75
        string $loginRoute,
76
        string $homeRoute
77
    )
78
    {
79
        $this->jwtEncoder = $jwtEncoder;
80
        $this->router = $router;
81
        $this->responseFactory = $responseFactory;
82
        $this->loginRoute = $loginRoute;
83
        $this->homeRoute = $homeRoute;
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89
    public function getCredentials(Request $request)
90
    {
91
        $loginRoute = $this->loginRoute;
92
        $isLoginSubmit = $request->attributes->get('_route') == $loginRoute && $request->isMethod('POST');
93
        if ($isLoginSubmit) {
94
            return null;
95
        }
96
        $extractor = new TokenExtractor('Bearer', 'Authorization');
97
        $token = $extractor->extract($request);
98
        if (!$token) {
99
            return null;
100
        }
101
102
        return $token;
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108
    public function getUser($credentials, UserProviderInterface $userProvider)
109
    {
110
        try {
111
            $data = $this->jwtEncoder->decode($credentials);
112
        } catch (ApiException $e) {
113
            throw new CustomUserMessageAuthenticationException($e->getMessage());
114
        }
115
116
        $username = $data['username'];
117
        return $this->loadUser($userProvider, $username);
118
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123
    public function checkCredentials($credentials, UserInterface $user)
124
    {
125
        return true;
126
    }
127
128
    /**
129
     * {@inheritdoc}
130
     */
131
    protected function getLoginUrl()
132
    {
133
        $loginRoute = $this->loginRoute;
134
135
        return $this->router->generate($loginRoute);
136
    }
137
138
    /**
139
     * {@inheritdoc}
140
     */
141
    public function supportsRememberMe()
142
    {
143
        return false;
144
    }
145
146
    /**
147
     * {@inheritdoc}
148
     */
149
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
150
    {
151
        $apiProblem = new ApiProblem(401);
152
        $apiProblem->set('detail', $exception->getMessageKey());
153
154
        return $this->responseFactory->createResponse($apiProblem);
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     */
160
    public function start(Request $request, AuthenticationException $authException = null)
161
    {
162
        $apiProblem = new ApiProblem(401);
163
        $message = $authException ? $authException->getMessageKey() : 'Invalid credentials';
164
        $apiProblem->set('detail', $message);
165
166
        return $this->responseFactory->createResponse($apiProblem);
167
    }
168
169
    /**
170
     * {@inheritdoc}
171
     */
172
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
173
    {
174
        return null;
175
    }
176
177
    /**
178
     * {@inheritdoc}
179
     */
180
    protected function getDefaultSuccessRedirectUrl()
181
    {
182
        $homeRoute = $this->homeRoute;
183
184
        return $this->router->generate($homeRoute);
185
    }
186
187
    /**
188
     * {@inheritdoc}
189
     */
190
    public function supports(Request $request)
191
    {
192
        return (bool)$this->getCredentials($request);
193
    }
194
195
    /**
196
     * @param UserProviderInterface $userProvider
197
     * @param string $username
198
     * @return UserInterface
199
     */
200
    private function loadUser(UserProviderInterface $userProvider, string $username)
201
    {
202
        try {
203
            $user = $userProvider->loadUserByUsername($username);
204
        } catch (UsernameNotFoundException $e) {
205
            throw new CustomUserMessageAuthenticationException($e->getMessage());
206
        }
207
        return $user;
208
    }
209
}
210