SelfVetMarshaller::isAllowed()   B
last analyzed

Complexity

Conditions 7
Paths 7

Size

Total Lines 36
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 22
nc 7
nop 2
dl 0
loc 36
rs 8.6346
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types = 1);
4
5
/**
6
 * Copyright 2021 SURFnet B.V.
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\Service;
22
23
use Psr\Log\LoggerInterface;
24
use Surfnet\StepupBundle\Service\SecondFactorTypeService;
25
use Surfnet\StepupBundle\Value\SecondFactorType;
26
use Surfnet\StepupBundle\Value\VettingType;
27
use Surfnet\StepupMiddlewareClientBundle\Identity\Dto\Identity;
28
use Surfnet\StepupMiddlewareClientBundle\Identity\Dto\VettedSecondFactor;
29
30
class SelfVetMarshaller implements VettingMarshaller
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class SelfVetMarshaller
Loading history...
31
{
32
    public function __construct(
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __construct()
Loading history...
33
        private readonly SecondFactorService $secondFactorService,
34
        private readonly SecondFactorTypeService $secondFactorTypeService,
35
        private readonly InstitutionConfigurationOptionsService $institutionConfigurationService,
36
        private readonly AuthorizationService $authorizationService,
37
        private readonly LoggerInterface $logger
38
    ) {
39
    }
40
41
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $identity should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $secondFactorId should have a doc-comment as per coding-style.
Loading history...
42
     * You are allowed to self vet when:
43
     * 1. You already have a vetted token
44
     * 2. The vetted token has higher LoA (or equal) to the one being vetted
45
     *
46
     * Or
47
     *
48
     * When you have a self asserted token, you are allowed to self-vet any
49
     * token with the self-vetted token. Resulting in tokens that are of the
50
     * self-asserted token type.
51
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
52
    public function isAllowed(Identity $identity, string $secondFactorId): bool
53
    {
54
        if (!$this->isSelfVettingEnabledFor($identity)) {
55
            return false;
56
        }
57
        $vettedSecondFactors = $this->secondFactorService->findVettedByIdentity($identity->id);
0 ignored issues
show
Bug introduced by
It seems like $identity->id can also be of type null; however, parameter $identityId of Surfnet\StepupSelfServic...:findVettedByIdentity() 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

57
        $vettedSecondFactors = $this->secondFactorService->findVettedByIdentity(/** @scrutinizer ignore-type */ $identity->id);
Loading history...
58
        if ($vettedSecondFactors->getTotalItems() === 0) {
59
            $this->logger->info('Self vetting is not allowed, no vetted tokens are available');
60
            return false;
61
        }
62
        $candidateToken = $this->secondFactorService->findOneVerified($secondFactorId);
63
        if ($candidateToken !== null) {
64
            /** @var VettedSecondFactor $authoringSecondFactor */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
65
            foreach ($vettedSecondFactors->getElements() as $authoringSecondFactor) {
66
                $hasSuitableToken = $this->secondFactorTypeService->hasEqualOrLowerLoaComparedTo(
67
                    new SecondFactorType($candidateToken->type),
68
                    new VettingType(VettingType::TYPE_SELF_VET),
69
                    new SecondFactorType($authoringSecondFactor->type),
70
                    new VettingType($authoringSecondFactor->vettingType)
71
                );
72
                if ($hasSuitableToken) {
73
                    $this->logger->info('Self vetting is allowed, a suitable token was found');
74
                    return true;
75
                }
76
            }
77
        }
78
79
        // Finally, we allow vetting with self-asserted tokens. Using the SAT authorization service
80
        // we ascertain if the user is allowed to use SAT.
81
        if ($this->authorizationService->maySelfVetSelfAssertedTokens($identity)) {
82
            $this->logger->info('Self vetting is allowed, by utilizing self-asserted tokens');
83
            return true;
84
        }
85
86
        $this->logger->info('Self vetting is not allowed, no suitable tokens are available');
87
        return false;
88
    }
89
90
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $identity should have a doc-comment as per coding-style.
Loading history...
91
     * Does the institution allow for self vetting?
92
     */
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
Coding Style introduced by
Missing @return tag in function comment
Loading history...
93
94
    private function isSelfVettingEnabledFor(Identity $identity): bool
0 ignored issues
show
Coding Style introduced by
Private method name "SelfVetMarshaller::isSelfVettingEnabledFor" must be prefixed with an underscore
Loading history...
95
    {
96
        $this->logger->info('Determine if self vetting is allowed');
97
        $configurationOptions = $this->institutionConfigurationService->getInstitutionConfigurationOptionsFor(
98
            $identity->institution
99
        );
100
        if ($configurationOptions->selfVet === false) {
101
            $this->logger->info(
102
                sprintf(
103
                    'Self vetting is not allowed, as the option is not enabled for institution %s',
104
                    $identity->institution
105
                )
106
            );
107
            return false;
108
        }
109
        $this->logger->info(sprintf('Self vetting is allowed for %s', $identity->institution));
110
        return true;
111
    }
112
}
113