Passed
Push — dependabot/composer/php-prod-f... ( f24868...5d725d )
by
unknown
10:19 queued 08:31
created

AuthenticationLogger::getStateHandler()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
nc 3
nop 1
dl 0
loc 9
rs 10
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * Copyright 2015 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\GatewayBundle\Monolog\Logger;
20
21
use DateTime;
22
use Surfnet\SamlBundle\Monolog\SamlAuthenticationLogger;
23
use Surfnet\StepupBundle\Value\Loa;
24
use Surfnet\StepupGateway\GatewayBundle\Exception\InvalidArgumentException;
25
use Surfnet\StepupGateway\GatewayBundle\Saml\ResponseContext;
26
use Surfnet\StepupGateway\GatewayBundle\Service\SecondFactorService;
27
use Surfnet\StepupBundle\Service\LoaResolutionService;
28
29
class AuthenticationLogger
30
{
31
32
    /**
33
     * @var SecondFactorService
34
     */
35
    private $secondFactorService;
36
37
    private LoaResolutionService $loaResolutionService;
38
    /**
39
     * @var SamlAuthenticationLogger
40
     */
41
    private $authenticationChannelLogger;
42
    private ResponseContext $sfoResponseContext;
43
    private ResponseContext $ssoResponseContext;
44
45
46
    public function __construct(
47
        SecondFactorService $secondFactorService,
48
        LoaResolutionService $loaResolutionService,
49
        SamlAuthenticationLogger $authenticationChannelLogger,
50
        ResponseContext     $sfoResponseContext,
51
        ResponseContext     $ssoResponseContext,
52
    ) {
53
        $this->secondFactorService  = $secondFactorService;
54
        $this->loaResolutionService = $loaResolutionService;
55
        $this->authenticationChannelLogger = $authenticationChannelLogger;
56
        $this->sfoResponseContext = $sfoResponseContext;
57
        $this->ssoResponseContext = $ssoResponseContext;
58
    }
59
60
61
    /**
62
     * @param string $requestId The SAML authentication request ID of the original request (not the proxy request).
63
     */
64
    public function logIntrinsicLoaAuthentication(string $requestId, string $authenticationMode): void
65
    {
66
        $data = [
67
            'second_factor_id'      => '',
68
            'second_factor_type'    => '',
69
            'institution'           => '',
70
            'authentication_result' => 'NONE',
71
            'resulting_loa'         => (string) $this->loaResolutionService->getLoaByLevel(Loa::LOA_1),
72
        ];
73
74
        $this->log('Intrinsic Loa Requested', $data, $requestId, $authenticationMode);
75
    }
76
77
    /**
78
     * @param string $requestId The SAML authentication request ID of the original request (not the proxy request).
79
     * @param string $authenticationMode
80
     */
81
    public function logSecondFactorAuthentication(string $requestId, string $authenticationMode): void
82
    {
83
        $context = $this->getResponseContext($authenticationMode);
84
85
        $secondFactor = $this->secondFactorService->findByUuid($context->getSelectedSecondFactor());
86
        $loa = $this->secondFactorService->getLoaLevel($secondFactor);
87
88
        $data = [
89
            'second_factor_id'      => $secondFactor->getSecondFactorId(),
90
            'second_factor_type'    => $secondFactor->getSecondFactorType(),
91
            'institution'           => $secondFactor->getInstitution(),
92
            'authentication_result' => $context->isSecondFactorVerified() ? 'OK' : 'FAILED',
93
            'resulting_loa'         => (string) $loa,
94
            'sso' => $context->isVerifiedBySsoOn2faCookie() ? 'YES': 'NO',
95
        ];
96
97
        if ($context->isVerifiedBySsoOn2faCookie()) {
98
            $data['sso_cookie_id'] = $context->getSsoOn2faCookieFingerprint();
99
        }
100
101
        $this->log('Second Factor Authenticated', $data, $requestId, $authenticationMode);
102
    }
103
104
    /**
105
     * @param string $message
106
     * @param array  $data
107
     * @param string $requestId
108
     */
109
    private function log(string $message, array $data, string $requestId, string $authenticationMode): void
110
    {
111
        $context = $this->getResponseContext($authenticationMode);
112
113
        $data['identity_id']        = $context->getIdentityNameId();
114
        $data['authenticating_idp'] = $context->getAuthenticatingIdp();
115
        $data['requesting_sp']      = $context->getRequestServiceProvider();
116
        $data['datetime']           = (new DateTime())->format('Y-m-d\\TH:i:sP');
117
118
        $this->authenticationChannelLogger->forAuthentication($requestId)->notice($message, $data);
119
    }
120
121
    private function getResponseContext(string $authenticationMode): ResponseContext
122
    {
123
        if ($authenticationMode === 'sfo') {
124
            return $this->sfoResponseContext;
125
        } elseif ($authenticationMode === 'sso') {
126
            return $this->ssoResponseContext;
127
        }
128
        throw new InvalidArgumentException(
129
            sprintf('Retrieving a response context for authentication type %s is not supported', $authenticationMode)
130
        );
131
    }
132
}
133