GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

U2fChallenge::process()   D
last analyzed

Complexity

Conditions 12
Paths 300

Size

Total Lines 130
Code Lines 90

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 90
nc 300
nop 2
dl 0
loc 130
rs 4.1247
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace LM\AuthAbstractor\Challenge;
6
7
use Firehed\U2F\ClientErrorException;
8
use Firehed\U2F\InvalidDataException;
9
use Firehed\U2F\SecurityException;
10
use Firehed\U2F\SignRequest;
11
use LM\AuthAbstractor\Configuration\IApplicationConfiguration;
12
use LM\AuthAbstractor\Enum\Persistence\Operation;
13
use LM\AuthAbstractor\Implementation\ChallengeResponse;
14
use LM\AuthAbstractor\Model\AuthenticationProcess;
15
use LM\AuthAbstractor\Model\IAuthenticationProcess;
16
use LM\AuthAbstractor\Model\PersistOperation;
17
use LM\AuthAbstractor\U2f\U2fAuthenticationManager;
18
use LM\Common\Enum\Scalar;
19
use LM\Common\Model\ArrayObject;
20
use LM\AuthAbstractor\Model\IU2fRegistration;
21
use LM\Common\Model\StringObject;
22
use LM\AuthAbstractor\Exception\NoRegisteredU2fTokenException;
23
use Psr\Http\Message\ServerRequestInterface;
24
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
25
use Symfony\Component\HttpFoundation\Response;
26
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
27
use LM\AuthAbstractor\Model\IChallengeResponse;
28
use Symfony\Component\Form\FormError;
29
use Symfony\Component\Form\FormFactoryInterface;
30
use Twig_Environment;
31
use UnexpectedValueException;
32
33
/**
34
 * A challenge for asking the user to prove their identity with their associated
35
 * U2F device. The challenges will be generated from the user's U2F
36
 * registrations, which are retrieved from the application configuration.
37
 */
38
class U2fChallenge implements IChallenge
39
{
40
    /** @var IApplicationConfiguration */
41
    private $appConfig;
42
43
    /** @var FormFactoryInterface */
44
    private $formFactory;
45
46
    /** @var HttpFoundationFactory */
47
    private $httpFoundationFactory;
48
49
    /** @var Twig_Environment */
50
    private $twig;
51
52
    /** @var U2fAuthenticationManager */
53
    private $u2fAuthenticationManager;
54
55
    /**
56
     * @internal
57
     */
58
    public function __construct(
59
        IApplicationConfiguration $appConfig,
60
        FormFactoryInterface $formFactory,
61
        HttpFoundationFactory $httpFoundationFactory,
62
        Twig_Environment $twig,
63
        U2fAuthenticationManager $u2fAuthenticationManager
64
    ) {
65
        $this->appConfig = $appConfig;
66
        $this->formFactory = $formFactory;
67
        $this->httpFoundationFactory = $httpFoundationFactory;
68
        $this->twig = $twig;
69
        $this->u2fAuthenticationManager = $u2fAuthenticationManager;
70
    }
71
72
    /**
73
     * @internal
74
     * @todo It is using the public key to identify the U2F registrations.
75
     * Could be better.
76
     */
77
    public function process(
78
        IAuthenticationProcess $process,
79
        ?ServerRequestInterface $httpRequest
80
    ): IChallengeResponse {
81
        $username = $process
0 ignored issues
show
Deprecated Code introduced by
The function LM\AuthAbstractor\Model\...nProcess::getTypedMap() has been deprecated. ( Ignorable by Annotation )

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

81
        $username = /** @scrutinizer ignore-deprecated */ $process
Loading history...
82
            ->getTypedMap()
83
            ->get('username', StringObject::class)
84
            ->toString()
85
        ;
86
87
        $usedU2fKeys = $process
0 ignored issues
show
Deprecated Code introduced by
The function LM\AuthAbstractor\Model\...nProcess::getTypedMap() has been deprecated. ( Ignorable by Annotation )

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

87
        $usedU2fKeys = /** @scrutinizer ignore-deprecated */ $process
Loading history...
88
            ->getTypedMap()
89
            ->get('used_u2f_key_public_keys', ArrayObject::class)
90
            ->toArray(Scalar::_STR)
91
        ;
92
93
        $registrations = $this
94
                ->appConfig
95
                ->getU2fRegistrations($username)
96
        ;
97
98
        foreach ($registrations as $key => $registration) {
99
            if (in_array($registration->getPublicKey(), $usedU2fKeys, true)) {
100
                unset($registrations[$key]);
101
            }
102
        }
103
104
        $form = $this
105
            ->formFactory
106
            ->createBuilder()
107
            ->add('u2fTokenResponse', HiddenType::class)
108
            ->getForm()
109
        ;
110
111
        if (null !== $httpRequest) {
112
            $form->handleRequest($this->httpFoundationFactory->createRequest($httpRequest));
113
        }
114
        try {
115
            if ($form->isSubmitted() && $form->isValid()) {
116
                $signRequests = $process
0 ignored issues
show
Deprecated Code introduced by
The function LM\AuthAbstractor\Model\...nProcess::getTypedMap() has been deprecated. ( Ignorable by Annotation )

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

116
                $signRequests = /** @scrutinizer ignore-deprecated */ $process
Loading history...
117
                    ->getTypedMap()
118
                    ->get('u2f_sign_requests', ArrayObject::class)
119
                ;
120
                $newRegistration = $this
121
                    ->u2fAuthenticationManager
122
                    ->processResponse(
123
                        new ArrayObject($registrations, IU2fRegistration::class),
0 ignored issues
show
Deprecated Code introduced by
The class LM\Common\Model\ArrayObject has been deprecated. ( Ignorable by Annotation )

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

123
                        /** @scrutinizer ignore-deprecated */ new ArrayObject($registrations, IU2fRegistration::class),
Loading history...
124
                        $signRequests,
125
                        $form['u2fTokenResponse']->getData()
126
                    )
127
                ;
128
                foreach ($registrations as $key => $registration) {
129
                    if ($registration->getPublicKey() === $newRegistration->getPublicKey()) {
130
                        $registrations[$key] = $newRegistration;
131
                        break;
132
                    }
133
                }
134
                $newDm = $process
0 ignored issues
show
Deprecated Code introduced by
The function LM\AuthAbstractor\Model\...nProcess::getTypedMap() has been deprecated. ( Ignorable by Annotation )

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

134
                $newDm = /** @scrutinizer ignore-deprecated */ $process
Loading history...
135
                    ->getTypedMap()
136
                    ->set(
137
                        'u2f_registrations',
138
                        $registrations,
139
                        Scalar::_ARRAY
140
                    )
141
                    ->set(
142
                        'used_u2f_key_public_keys',
143
                        (new ArrayObject($usedU2fKeys, Scalar::_STR))->add($newRegistration->getPublicKey(), Scalar::_STR),
0 ignored issues
show
Deprecated Code introduced by
The class LM\Common\Model\ArrayObject has been deprecated. ( Ignorable by Annotation )

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

143
                        (/** @scrutinizer ignore-deprecated */ new ArrayObject($usedU2fKeys, Scalar::_STR))->add($newRegistration->getPublicKey(), Scalar::_STR),
Loading history...
144
                        ArrayObject::class
145
                    )
146
                    ->set(
147
                        'persist_operations',
148
                        $process
0 ignored issues
show
Deprecated Code introduced by
The function LM\AuthAbstractor\Model\...nProcess::getTypedMap() has been deprecated. ( Ignorable by Annotation )

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

148
                        /** @scrutinizer ignore-deprecated */ $process
Loading history...
149
                            ->getTypedMap()
150
                            ->get('persist_operations', ArrayObject::class)
151
                            ->add(
152
                                new PersistOperation($newRegistration, new Operation(Operation::UPDATE)),
153
                                PersistOperation::class
154
                            ),
155
                        ArrayObject::class
156
                    )
157
                ;
158
159
                return new ChallengeResponse(
160
                    new AuthenticationProcess($newDm),
161
                    null,
162
                    false,
163
                    true
164
                )
165
                ;
166
            }
167
        } catch (ClientErrorException $e) {
168
            $form->addError(new FormError('You took too long to activate your U2F device, or the U2F device you plugged in is invalid. Please try again.'));
169
        } catch (SecurityException $e) {
170
            $form->addError(new FormError('The U2F key is not recognised.'));
171
        } catch (NoRegisteredU2fTokenException $e) {
172
            return new ChallengeResponse(
173
                new AuthenticationProcess($process),
0 ignored issues
show
Bug introduced by
$process of type LM\AuthAbstractor\Model\IAuthenticationProcess is incompatible with the type LM\Common\DataStructure\TypedMap|null expected by parameter $typedMap of LM\AuthAbstractor\Model\...nProcess::__construct(). ( Ignorable by Annotation )

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

173
                new AuthenticationProcess(/** @scrutinizer ignore-type */ $process),
Loading history...
174
                $httpResponse,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $httpResponse seems to be never defined.
Loading history...
175
                true,
176
                false
177
            )
178
            ;
179
        } catch (UnexpectedValueException|InvalidDataException $e) {
180
            $form->addError(new FormError('An error happened. Please try again.'));
181
        }
182
183
        $signRequests = $this
184
                    ->u2fAuthenticationManager
185
                    ->generate($username, new ArrayObject($registrations, IU2fRegistration::class))
0 ignored issues
show
Deprecated Code introduced by
The class LM\Common\Model\ArrayObject has been deprecated. ( Ignorable by Annotation )

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

185
                    ->generate($username, /** @scrutinizer ignore-deprecated */ new ArrayObject($registrations, IU2fRegistration::class))
Loading history...
186
        ;
187
188
        $httpResponse = new Response($this->twig->render("u2f_authentication.html.twig", [
189
            "form" => $form->createView(),
190
            "sign_requests_json" => json_encode(array_values($signRequests)),
191
            'nUsedU2fKeys' => count($usedU2fKeys),
192
        ]));
193
        $newDm = $process
0 ignored issues
show
Deprecated Code introduced by
The function LM\AuthAbstractor\Model\...nProcess::getTypedMap() has been deprecated. ( Ignorable by Annotation )

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

193
        $newDm = /** @scrutinizer ignore-deprecated */ $process
Loading history...
194
            ->getTypedMap()
195
            ->set(
196
                'u2f_sign_requests',
197
                new ArrayObject($signRequests, SignRequest::class),
0 ignored issues
show
Deprecated Code introduced by
The class LM\Common\Model\ArrayObject has been deprecated. ( Ignorable by Annotation )

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

197
                /** @scrutinizer ignore-deprecated */ new ArrayObject($signRequests, SignRequest::class),
Loading history...
198
                ArrayObject::class
199
            )
200
        ;
201
202
        return new ChallengeResponse(
203
            new AuthenticationProcess($newDm),
204
            $httpResponse,
205
            $form->isSubmitted(),
206
            false
207
        )
208
        ;
209
    }
210
}
211