Completed
Pull Request — master (#74)
by Simone
13:47
created

RefreshTokenAuthenticator   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 53
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 8

Test Coverage

Coverage 14.81%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 7
c 2
b 0
f 0
lcom 0
cbo 8
dl 0
loc 53
ccs 4
cts 27
cp 0.1481
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A supportsToken() 0 4 2
A onAuthenticationFailure() 0 4 1
A createToken() 0 10 1
B authenticateToken() 0 29 3
1
<?php
2
3
/*
4
 * This file is part of the GesdinetJWTRefreshTokenBundle package.
5
 *
6
 * (c) Gesdinet <http://www.gesdinet.com/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Gesdinet\JWTRefreshTokenBundle\Security\Authenticator;
13
14
use Gesdinet\JWTRefreshTokenBundle\Request\RequestRefreshToken;
15
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
16
use Symfony\Component\Security\Core\Exception\AuthenticationException;
17
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\Security\Core\User\UserProviderInterface;
20
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
21
use Symfony\Component\HttpFoundation\Response;
22
use Gesdinet\JWTRefreshTokenBundle\Security\Provider\RefreshTokenProvider;
23
24 1
if (interface_exists('Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface')) {
25
    abstract class RefreshTokenAuthenticatorBase implements \Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface
26
    {
27
    }
28
} else {
29
    abstract class RefreshTokenAuthenticatorBase implements \Symfony\Component\Security\Core\Authentication\SimplePreAuthenticatorInterface
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
Comprehensibility Best Practice introduced by
The type Gesdinet\JWTRefreshToken...hTokenAuthenticatorBase has been defined more than once; this definition is ignored, only the first definition in this file (L25-27) is considered.

This check looks for classes that have been defined more than once in the same file.

If you can, we would recommend to use standard object-oriented programming techniques. For example, to avoid multiple types, it might make sense to create a common interface, and then multiple, different implementations for that interface.

This also has the side-effect of providing you with better IDE auto-completion, static analysis and also better OPCode caching from PHP.

Loading history...
30
    {
31
    }
32
}
33
34
/**
35
 * Class RefreshTokenAuthenticator.
36
 */
37
class RefreshTokenAuthenticator extends RefreshTokenAuthenticatorBase implements AuthenticationFailureHandlerInterface
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
38
{
39
    public function createToken(Request $request, $providerKey)
40
    {
41
        $refreshTokenString = RequestRefreshToken::getRefreshToken($request);
42
43
        return new PreAuthenticatedToken(
44
            '',
45
            $refreshTokenString,
46
            $providerKey
47
        );
48
    }
49
50
    public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
51
    {
52
        if (!$userProvider instanceof RefreshTokenProvider) {
53
            throw new \InvalidArgumentException(
54
                sprintf(
55
                    'The user provider must be an instance of RefreshTokenProvider (%s was given).',
56
                    get_class($userProvider)
57
                )
58
            );
59
        }
60
61
        $refreshToken = $token->getCredentials();
62
        $username = $userProvider->getUsernameForRefreshToken($refreshToken);
63
64
        if (!$username) {
65
            throw new AuthenticationException(
66
                sprintf('Refresh token "%s" does not exist.', $refreshToken)
67
            );
68
        }
69
70
        $user = $userProvider->loadUserByUsername($username);
71
72
        return new PreAuthenticatedToken(
73
            $user,
74
            $refreshToken,
75
            $providerKey,
76
            $user->getRoles()
0 ignored issues
show
Documentation introduced by
$user->getRoles() is of type array<integer,object<Sym...Core\Role\Role>|string>, but the function expects a array<integer,object<Sym...\RoleInterface>|string>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
77
        );
78
    }
79
80 1
    public function supportsToken(TokenInterface $token, $providerKey)
81
    {
82 1
        return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
83
    }
84
85 1
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
86
    {
87 1
        return new Response('Refresh token authentication failed.', 403);
88
    }
89
}
90