Completed
Push — master ( 8e51ac...186982 )
by Rafael
03:50
created

LexikJWTGraphiQLAuthenticator::isAuthenticated()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 0
cts 3
cp 0
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 6
1
<?php
2
/*******************************************************************************
3
 *  This file is part of the GraphQL Bundle package.
4
 *
5
 *  (c) YnloUltratech <[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 Ynlo\GraphQLBundle\GraphiQL;
12
13
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
14
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
15
use Symfony\Component\Form\FormBuilderInterface;
16
use Symfony\Component\Form\FormInterface;
17
use Symfony\Component\HttpFoundation\Session\Session;
18
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
19
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
20
use Symfony\Component\Security\Core\User\UserProviderInterface;
21
22
class LexikJWTGraphiQLAuthenticator implements GraphiQLAuthenticationProviderInterface
23
{
24
    private const SESSION_PATH = 'graphiql_jwt_api_token';
25
26
    /**
27
     * @var EncoderFactoryInterface
28
     */
29
    private $encoder;
30
31
    /**
32
     * @var UserProviderInterface
33
     */
34
    private $userProvider;
35
36
    /**
37
     * @var JWTTokenManagerInterface
38
     */
39
    private $jwtTokenManager;
40
41
    /**
42
     * @var Session
43
     */
44
    private $session;
45
46
    /**
47
     * @var array
48
     */
49
    private $config = [];
50
51
    /**
52
     * LexikJWTGraphiQLAuthenticator constructor.
53
     *
54
     * @param UserPasswordEncoderInterface $encoder
55
     * @param UserProviderInterface        $userProvider
56
     * @param JWTTokenManagerInterface     $jwtTokenManager
57
     * @param Session                      $session
58
     */
59
    public function __construct(UserPasswordEncoderInterface $encoder, UserProviderInterface $userProvider, JWTTokenManagerInterface $jwtTokenManager, Session $session)
60
    {
61
        $this->encoder = $encoder;
0 ignored issues
show
Documentation Bug introduced by
It seems like $encoder of type Symfony\Component\Securi...asswordEncoderInterface is incompatible with the declared type Symfony\Component\Securi...EncoderFactoryInterface of property $encoder.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
62
        $this->userProvider = $userProvider;
63
        $this->jwtTokenManager = $jwtTokenManager;
64
        $this->session = $session;
65
        $this->config = [
66
            'username_label' => 'Username',
67
            'password_label' => 'Password',
68
        ];
69
    }
70
71
    /**
72
     * @param array $config
73
     */
74
    public function setConfig(array $config): void
75
    {
76
        $this->config = array_merge($this->config, $config);
77
    }
78
79
    /**
80
     * @inheritDoc
81
     */
82
    public function requireUserData(): bool
83
    {
84
        return true;
85
    }
86
87
    /**
88
     * @inheritDoc
89
     */
90
    public function buildUserForm(FormBuilderInterface $builder)
91
    {
92
        $builder
93
            ->add(
94
                'username',
95
                null,
96
                [
97
                    'label' => $this->config['username_label'],
98
                ]
99
            )
100
            ->add(
101
                'password',
102
                PasswordType::class,
103
                [
104
                    'label' => $this->config['password_label'],
105
                ]
106
            );
107
    }
108
109
    /**
110
     * @inheritDoc
111
     */
112
    public function login(?FormInterface $form = null)
113
    {
114
        if (!$form) {
115
            throw new \RuntimeException('This provider require a form');
116
        }
117
118
        $username = $form->get('username')->getData();
119
        $password = $form->get('password')->getData();
120
121
        $user = $this->userProvider->loadUserByUsername($username);
122
        if (!$user || !$this->encoder->isPasswordValid($user, $password)) {
0 ignored issues
show
Bug introduced by
The method isPasswordValid() does not exist on Symfony\Component\Securi...EncoderFactoryInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

122
        if (!$user || !$this->encoder->/** @scrutinizer ignore-call */ isPasswordValid($user, $password)) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
introduced by
$user is of type Symfony\Component\Security\Core\User\UserInterface, thus it always evaluated to true.
Loading history...
123
            throw new AuthenticationFailedException();
124
        }
125
126
        $token = $this->jwtTokenManager->create($user);
127
128
        $this->session->set(self::SESSION_PATH, $token);
129
    }
130
131
    /**
132
     * @inheritDoc
133
     */
134
    public function logout()
135
    {
136
        $this->session->remove(self::SESSION_PATH);
137
    }
138
139
    /**
140
     * @inheritDoc
141
     */
142
    public function isAuthenticated(): bool
143
    {
144
        return $this->session->has(self::SESSION_PATH) && $this->session->get(self::SESSION_PATH);
145
    }
146
147
    /**
148
     * @inheritDoc
149
     */
150
    public function prepareRequest(GraphiQLRequest $request)
151
    {
152
        $token = null;
153
        if ($this->isAuthenticated()) {
154
            $token = $this->session->get(self::SESSION_PATH);
155
        }
156
157
        $request->addHeader('Authorization', sprintf('Bearer %s', $token));
158
    }
159
}
160