SecondFactorVerificationService   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 86
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 37
c 2
b 0
f 0
dl 0
loc 86
rs 10
wmc 5

2 Methods

Rating   Name   Duplication   Size   Complexity  
A sendSecondFactorVerificationAuthnRequest() 0 48 4
A __construct() 0 5 1
1
<?php
2
/**
3
 * Copyright 2018 SURFnet bv
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
namespace Surfnet\StepupGateway\SamlStepupProviderBundle\Service\Gateway;
19
20
use Surfnet\SamlBundle\Monolog\SamlAuthenticationLogger;
21
use Surfnet\SamlBundle\SAML2\AuthnRequest;
22
use Surfnet\SamlBundle\SAML2\AuthnRequestFactory;
23
use Surfnet\StepupGateway\GatewayBundle\Saml\ResponseContext;
24
use Surfnet\StepupGateway\SamlStepupProviderBundle\Exception\InvalidSubjectException;
25
use Surfnet\StepupGateway\SamlStepupProviderBundle\Provider\Provider;
26
27
class SecondFactorVerificationService
28
{
29
    /** @var SamlAuthenticationLogger */
30
    private $samlLogger;
31
32
    /** @var ResponseContext */
33
    private $responseContext;
34
35
    /** @var ResponseContext */
36
    private $sfoResponseContext;
37
38
    /**
39
     * SecondFactorVerificationService constructor.
40
     * @param SamlAuthenticationLogger $samlLogger
41
     * @param ResponseContext $responseContext
42
     * @param ResponseContext $sfoResponseContext
43
     */
44
    public function __construct(SamlAuthenticationLogger $samlLogger, ResponseContext $responseContext, ResponseContext $sfoResponseContext)
45
    {
46
        $this->samlLogger = $samlLogger;
47
        $this->responseContext = $responseContext;
48
        $this->sfoResponseContext = $sfoResponseContext;
49
    }
50
51
    /**
52
     * Proxy a GSSP authentication request for use in the remote GSSP SSO endpoint.
53
     *
54
     * The user is about to be sent to the remote GSSP application for
55
     * registration or authentication.
56
     *
57
     * The service provider in this context is SelfService (when registering
58
     * a token) or RA (when vetting a token).
59
     *
60
     * @param Provider $provider
61
     * @param string $subjectNameId
62
     * @param string $responseContextServiceId
63
     * @return AuthnRequest
64
     */
65
    public function sendSecondFactorVerificationAuthnRequest(
66
        Provider $provider,
67
        string $subjectNameId,
68
        string $responseContextServiceId
69
    ) {
70
        $stateHandler = $provider->getStateHandler();
71
72
        if ($responseContextServiceId === 'second_factor_only.response_context') {
73
            $originalRequestId = $this->sfoResponseContext->getInResponseTo();
74
        } else {
75
            $originalRequestId = $this->responseContext->getInResponseTo();
76
        }
77
78
        $subject = $stateHandler->getSubject();
79
        if (!empty($subject) && strtolower($subjectNameId) !== strtolower($subject)) {
80
            throw new InvalidSubjectException(
81
                sprintf(
82
                    'The subject required for authentication (%s) does not match the one found in the state handler (%s)',
83
                    $subjectNameId,
84
                    $stateHandler->getSubject()
85
                )
86
            );
87
        }
88
89
        $authnRequest = AuthnRequestFactory::createNewRequest(
90
            $provider->getServiceProvider(),
91
            $provider->getRemoteIdentityProvider()
92
        );
93
        $authnRequest->setSubject($subjectNameId);
94
95
        $stateHandler
96
            ->setRequestId($originalRequestId)
0 ignored issues
show
Bug introduced by
It seems like $originalRequestId can also be of type null; however, parameter $originalRequestId of Surfnet\StepupGateway\Ga...Handler::setRequestId() 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

96
            ->setRequestId(/** @scrutinizer ignore-type */ $originalRequestId)
Loading history...
97
            ->setGatewayRequestId($authnRequest->getRequestId())
98
            ->setSubject($subjectNameId)
99
            ->setResponseContextServiceId($responseContextServiceId)
100
            ->markRequestAsSecondFactorVerification();
101
102
        /** @var \Surfnet\SamlBundle\Monolog\SamlAuthenticationLogger $logger */
103
        $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

103
        $logger = $this->samlLogger->forAuthentication(/** @scrutinizer ignore-type */ $originalRequestId);
Loading history...
104
        $logger->notice(sprintf(
105
            'Sending AuthnRequest to verify Second Factor with request ID: "%s" to GSSP "%s" at "%s" for subject "%s"',
106
            $authnRequest->getRequestId(),
107
            $provider->getName(),
108
            $provider->getRemoteIdentityProvider()->getSsoUrl(),
109
            $subjectNameId
110
        ));
111
112
        return $authnRequest;
113
    }
114
}
115