RespondService::resetRespondState()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Copyright 2018 SURFnet bv
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace Surfnet\StepupGateway\SecondFactorOnlyBundle\Service\Gateway;
20
21
use SAML2\Response;
22
use Surfnet\SamlBundle\Monolog\SamlAuthenticationLogger;
23
use Surfnet\StepupBundle\Service\LoaResolutionService;
24
use Surfnet\StepupBundle\Service\SecondFactorTypeService;
25
use Surfnet\StepupGateway\GatewayBundle\Saml\ResponseContext;
26
use Surfnet\StepupGateway\GatewayBundle\Service\SecondFactorService;
27
use Surfnet\StepupGateway\SecondFactorOnlyBundle\Exception\InvalidSecondFactorMethodException;
28
use Surfnet\StepupGateway\SecondFactorOnlyBundle\Saml\ResponseFactory;
29
use Surfnet\StepupGateway\SecondFactorOnlyBundle\Service\LoaAliasLookupService;
30
use Symfony\Component\HttpFoundation\Request;
31
32
class RespondService
33
{
34
    /** @var SamlAuthenticationLogger */
35
    private $samlLogger;
36
37
    /** @var LoaResolutionService */
38
    private $loaResolutionService;
39
40
    /** @var LoaAliasLookupService */
41
    private $loaAliasLookupService;
42
43
    /** @var ResponseFactory */
44
    private $responseFactory;
45
46
    /** @var SecondFactorService */
47
    private $secondFactorService;
48
49
    /** @var SecondFactorTypeService */
50
    private $secondFactorTypeService;
51
52
    /** @var ResponseValidator */
53
    private $responseValidator;
54
55
    public function __construct(
56
        SamlAuthenticationLogger $samlLogger,
57
        LoaResolutionService $loaResolutionService,
58
        LoaAliasLookupService $loaAliasLookupService,
59
        ResponseFactory $responseFactory,
60
        SecondFactorService $secondFactorService,
61
        SecondFactorTypeService $secondFactorTypeService,
62
        ResponseValidator $responseValidator
63
    ) {
64
        $this->samlLogger = $samlLogger;
65
        $this->loaResolutionService = $loaResolutionService;
66
        $this->loaAliasLookupService = $loaAliasLookupService;
67
        $this->responseFactory = $responseFactory;
68
        $this->secondFactorService = $secondFactorService;
69
        $this->secondFactorTypeService = $secondFactorTypeService;
70
        $this->responseValidator = $responseValidator;
71
    }
72
73
74
    /**
75
     * Send a SAML response back to the service provider.
76
     *
77
     * Second factor verification is finished. This method builds a AuthnResponse
78
     * to send back to the service provider in response to the AuthnRequest received in
79
     * the SecondFactorLoginService.
80
     *
81
     * @param ResponseContext $responseContext
82
     * @return Response
83
     */
84
    public function respond(ResponseContext $responseContext, Request $request)
85
    {
86
        $originalRequestId = $responseContext->getInResponseTo();
87
        $logger = $this->samlLogger->forAuthentication($originalRequestId);
0 ignored issues
show
Bug introduced by
It seems like $originalRequestId can also be of type null; however, parameter $requestId of Surfnet\SamlBundle\Monol...er::forAuthentication() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

87
        $logger = $this->samlLogger->forAuthentication(/** @scrutinizer ignore-type */ $originalRequestId);
Loading history...
88
89
        $logger->notice('Creating second-factor-only Response');
90
91
        $selectedSecondFactorUuid = $responseContext->getSelectedSecondFactor();
92
        if (!$selectedSecondFactorUuid) {
93
            throw new InvalidSecondFactorMethodException(
94
                'Cannot verify possession of an unknown second factor.'
95
            );
96
        }
97
98
        if (!$responseContext->isSecondFactorVerified()) {
99
            throw new InvalidSecondFactorMethodException(
100
                'Second factor was not verified'
101
            );
102
        }
103
104
        $secondFactor = $this->secondFactorService->findByUuid($selectedSecondFactorUuid);
105
        $loaLevel =  $this->secondFactorService->getLoaLevel($secondFactor);
106
        $this->responseValidator->validate($request, $secondFactor, $responseContext->getIdentityNameId());
107
108
        $authnContextClassRef = $this->loaAliasLookupService->findAliasByLoa($loaLevel);
109
110
        $response = $this->responseFactory->createSecondFactorOnlyResponse(
111
            $responseContext->getIdentityNameId(),
112
            $responseContext->getDestination(),
113
            $authnContextClassRef
0 ignored issues
show
Bug introduced by
It seems like $authnContextClassRef can also be of type false; however, parameter $authnContextClassRef of Surfnet\StepupGateway\Se...ondFactorOnlyResponse() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

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

113
            /** @scrutinizer ignore-type */ $authnContextClassRef
Loading history...
114
        );
115
116
        $logger->notice(sprintf(
117
            'Responding to request "%s" with newly created response "%s"',
118
            $responseContext->getInResponseTo(),
119
            $response->getId()
120
        ));
121
122
        return $response;
123
    }
124
125
    /**
126
     * Reset the state of the response
127
     *
128
     * @param ResponseContext $responseContext
129
     */
130
    public function resetRespondState(ResponseContext $responseContext): void
131
    {
132
        $responseContext->responseSent();
133
    }
134
}
135