GssfConsumeAssertionController   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 99
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 52
dl 0
loc 99
rs 10
c 1
b 0
f 0
wmc 8

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A redirectToStatusReportForm() 0 6 1
B consumeAssertion() 0 78 6
1
<?php
2
3
declare(strict_types = 1);
4
5
/**
6
 * Copyright 2015 SURFnet bv
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *     http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
Coding Style introduced by
Missing @package tag in file comment
Loading history...
Coding Style introduced by
Missing @author tag in file comment
Loading history...
Coding Style introduced by
Missing @license tag in file comment
Loading history...
Coding Style introduced by
Missing @link tag in file comment
Loading history...
20
21
namespace Surfnet\StepupSelfService\SelfServiceBundle\Controller\Registration\Gssf;
22
23
use Exception;
24
use Psr\Log\LoggerInterface;
25
use Surfnet\SamlBundle\Http\PostBinding;
26
use Surfnet\SamlBundle\SAML2\Attribute\AttributeDictionary;
27
use Surfnet\SamlBundle\SAML2\Response\Assertion\InResponseTo;
28
use Surfnet\StepupSelfService\SamlStepupProviderBundle\Provider\Provider;
29
use Surfnet\StepupSelfService\SamlStepupProviderBundle\Provider\ProviderRepository;
30
use Surfnet\StepupSelfService\SelfServiceBundle\Service\ControllerCheckerService;
31
use Surfnet\StepupSelfService\SelfServiceBundle\Service\GssfService;
0 ignored issues
show
Bug introduced by
The type Surfnet\StepupSelfServic...dle\Service\GssfService was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
32
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
33
use Symfony\Component\HttpFoundation\RedirectResponse;
34
use Symfony\Component\HttpFoundation\Request;
35
use Symfony\Component\HttpFoundation\Response;
36
use Symfony\Component\Routing\Attribute\Route;
37
38
/**
39
 * Controls registration with Generic SAML Stepup Providers (GSSPs), yielding Generic SAML Second Factors (GSSFs).
40
 */
0 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @package tag in class comment
Loading history...
Coding Style introduced by
Missing @author tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
41
final class GssfConsumeAssertionController extends AbstractController
42
{
43
    public function __construct(
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __construct()
Loading history...
44
        private readonly LoggerInterface           $logger,
45
        private readonly ProviderRepository        $providerRepository,
46
        private readonly PostBinding               $postBinding,
47
        private readonly GssfService               $gssfService,
48
        private readonly AttributeDictionary       $attributeDictionary,
49
        private readonly ControllerCheckerService $checkerService,
50
    ) {
51
    }
52
53
    #[Route(
54
        path: '/registration/gssf/{provider}/consume-assertion',
55
        name: 'ss_registration_gssf_consume_assertion',
56
        methods: ['POST'],
57
    )]
58
    public function consumeAssertion(Request $httpRequest, string $provider): array|Response
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function consumeAssertion()
Loading history...
59
    {
60
        $this->checkerService->assertSecondFactorEnabled($provider);
61
62
        $provider = $this->providerRepository->get($provider);
63
64
        $this->logger->notice(
65
            sprintf('Received GSSP "%s" SAMLResponse through Gateway, attempting to process', $provider->getName())
66
        );
67
68
        try {
69
            $assertion = $this->postBinding->processResponse(
70
                $httpRequest,
71
                $provider->getRemoteIdentityProvider(),
72
                $provider->getServiceProvider()
73
            );
74
        } catch (Exception $exception) {
75
            $provider->getStateHandler()->clear();
76
77
            $this->logger->error(
78
                sprintf('Could not process received Response, error: "%s"', $exception->getMessage())
79
            );
80
81
            return $this->redirectToStatusReportForm(
82
                $provider,
83
                ['authenticationFailed' => true]
84
            );
85
        }
86
87
        $expectedResponseTo = $provider->getStateHandler()->getRequestId();
88
        $provider->getStateHandler()->clear();
89
90
        if (!InResponseTo::assertEquals($assertion, $expectedResponseTo)) {
91
            $this->logger->critical(sprintf(
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
92
                'Received Response with unexpected InResponseTo, %s',
93
                ($expectedResponseTo ? 'expected "' . $expectedResponseTo . '"' : ' no response expected')
94
            ));
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
95
96
            return $this->redirectToStatusReportForm(
97
                $provider,
98
                ['authenticationFailed' => true]
99
            );
100
        }
101
102
        $this->logger->notice(
103
            sprintf('Processed GSSP "%s" SAMLResponse received through Gateway successfully', $provider->getName())
104
        );
105
106
        $gssfId = $this->attributeDictionary->translate($assertion)->getNameID();
107
108
        $secondFactorId = $this->gssfService->provePossession($this->getUser()->getIdentity()->id, $provider->getName(), $gssfId);
0 ignored issues
show
Bug introduced by
The method getIdentity() does not exist on Symfony\Component\Security\Core\User\UserInterface. It seems like you code against a sub-type of Symfony\Component\Security\Core\User\UserInterface such as Surfnet\StepupSelfServic...n\AuthenticatedIdentity. ( Ignorable by Annotation )

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

108
        $secondFactorId = $this->gssfService->provePossession($this->getUser()->/** @scrutinizer ignore-call */ getIdentity()->id, $provider->getName(), $gssfId);
Loading history...
109
110
        if ($secondFactorId) {
111
            $this->logger->notice('GSSF possession has been proven successfully');
112
113
            if ($this->checkerService->emailVerificationIsRequired()) {
114
                return $this->redirectToRoute(
115
                    'ss_registration_email_verification_email_sent',
116
                    ['secondFactorId' => $secondFactorId]
117
                );
118
            } else {
119
                return $this->redirectToRoute(
120
                    'ss_second_factor_vetting_types',
121
                    ['secondFactorId' => $secondFactorId]
122
                );
123
            }
124
        }
125
126
        $this->logger->error('Unable to prove GSSF possession');
127
128
        return $this->redirectToStatusReportForm(
129
            $provider,
130
            ['proofOfPossessionFailed' => true]
131
        );
132
    }
133
134
    private function redirectToStatusReportForm(Provider $provider, array $options): RedirectResponse
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function redirectToStatusReportForm()
Loading history...
Coding Style introduced by
Private method name "GssfConsumeAssertionController::redirectToStatusReportForm" must be prefixed with an underscore
Loading history...
135
    {
136
        return $this->redirectToRoute(
137
            'ss_registration_gssf_status_report',
138
            $options + [
139
                'provider' => $provider->getName(),
140
            ]
141
        );
142
    }
143
}
144