Completed
Push — main ( d02cfb...38ec3a )
by
unknown
22s queued 15s
created

AuthenticationLogger::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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