Passed
Pull Request — develop (#295)
by Peter
04:30
created

ServiceProvider::allowSsoOn2fa()   A

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 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Copyright 2014 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
 */
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...
18
19
namespace Surfnet\StepupGateway\GatewayBundle\Entity;
20
21
use Psr\Log\LoggerInterface;
22
use Surfnet\SamlBundle\Entity\ServiceProvider as BaseServiceProvider;
23
use Surfnet\StepupGateway\GatewayBundle\Exception\InvalidArgumentException;
24
use Surfnet\StepupGateway\SecondFactorOnlyBundle\Adfs\Exception\AcsLocationNotAllowedException;
25
26
class ServiceProvider extends BaseServiceProvider
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class ServiceProvider
Loading history...
27
{
28
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
29
     * @return bool
30
     */
31
    public function mayUseGateway()
32
    {
33
        return !$this->mayUseSecondFactorOnly();
34
    }
35
36
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
37
     * @return bool
38
     */
39
    public function mayUseSecondFactorOnly()
40
    {
41
        return (bool) $this->get('secondFactorOnly', false);
42
    }
43
44
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
45
     * @param string $nameId
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
46
     * @return bool
0 ignored issues
show
Coding Style introduced by
Tag @return cannot be grouped with parameter tags in a doc comment
Loading history...
47
     */
48
    public function isAllowedToUseSecondFactorOnlyFor($nameId)
49
    {
50
        if (!is_string($nameId)) {
0 ignored issues
show
introduced by
The condition is_string($nameId) is always true.
Loading history...
51
            throw InvalidArgumentException::invalidType('string', 'nameId', $nameId);
52
        }
53
54
        if (empty($nameId)) {
55
            return false;
56
        }
57
58
        if (!$this->mayUseSecondFactorOnly()) {
59
            return false;
60
        }
61
62
        $nameIdPatterns = $this->get('secondFactorOnlyNameIdPatterns');
63
        foreach ($nameIdPatterns as $nameIdPattern) {
64
            if ((bool) preg_match('#^' . strtr(preg_quote($nameIdPattern, '#'), ['\*' => '.*']) . '$#', $nameId)) {
65
                return true;
66
            }
67
        }
68
        return false;
69
    }
70
71
    /**
72
     * Determine the ACS location to send the response to.
73
     *
74
     * The get getAssertionConsumerUrl() method returns a trusted ACS location
75
     * for this service provider. This value is set when the service provider
76
     * is "internal", for example when it is configured in yaml
77
     * configuration.
78
     *
79
     * Methods like Surfnet\SamlBundle\Http\PostBinding::processResponse use
80
     * this trusted value. When the ServiceProvider is external, this value is
81
     * empty and the ACS location found in the AuthnRequest should be used, if
82
     * it matches one of the configured allowed ACS locations for the service
83
     * provider. This methods checks if a given URL matches the allowed URLs.
84
     *
85
     * @param $acsLocationInAuthnRequest
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
86
     * @param LoggerInterface $logger Optional
0 ignored issues
show
Coding Style introduced by
Expected 20 spaces after parameter name; 1 found
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
87
     * @return string
0 ignored issues
show
Coding Style introduced by
Tag @return cannot be grouped with parameter tags in a doc comment
Loading history...
88
     */
89
    public function determineAcsLocation($acsLocationInAuthnRequest, LoggerInterface $logger = null)
90
    {
91
        // List of allowed ACS locations configured in middleware.
92
        $allowedAcsLocations = $this->get('allowedAcsLocations');
93
94
        if (in_array($acsLocationInAuthnRequest, $allowedAcsLocations)) {
0 ignored issues
show
Bug introduced by
It seems like $allowedAcsLocations can also be of type null; however, parameter $haystack of in_array() does only seem to accept array, 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

94
        if (in_array($acsLocationInAuthnRequest, /** @scrutinizer ignore-type */ $allowedAcsLocations)) {
Loading history...
95
            return $acsLocationInAuthnRequest;
96
        }
97
98
        if ($logger !== null) {
99
            $logger->warning(
100
                sprintf(
101
                    'AuthnRequest requests ACS location "%s" but it is not configured in the list of allowed ACS ' .
102
                    'locations, allowed locations include: [%s]',
103
                    $acsLocationInAuthnRequest,
104
                    implode($allowedAcsLocations, ', ')
0 ignored issues
show
Bug introduced by
It seems like $allowedAcsLocations can also be of type null; however, parameter $glue of implode() 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

104
                    implode(/** @scrutinizer ignore-type */ $allowedAcsLocations, ', ')
Loading history...
Bug introduced by
', ' of type string is incompatible with the type array expected by parameter $pieces of implode(). ( Ignorable by Annotation )

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

104
                    implode($allowedAcsLocations, /** @scrutinizer ignore-type */ ', ')
Loading history...
105
                )
106
            );
107
        }
108
109
        return reset($allowedAcsLocations);
0 ignored issues
show
Bug introduced by
It seems like $allowedAcsLocations can also be of type null; however, parameter $array of reset() does only seem to accept array|object, 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

109
        return reset(/** @scrutinizer ignore-type */ $allowedAcsLocations);
Loading history...
110
    }
111
112
    /**
113
     * Determine the ACS location for ADFS to send the response to.
114
     *
115
     * This method is similar to determineAcsLocation(), but does not check
116
     * for the requested ACS location to be identical to one of the configured
117
     * ACS locations, but only if matches the first part of an allowed URL.
118
     *
119
     * For example, ADFS might send an ACS location like:
120
     *
121
     *     https://example.com/consume-assertion?key=value
122
     *
123
     * Above URL is allowed if one of the configured URLs is:
124
     *
125
     *     https://example.com/consume-assertion
126
     *
127
     * Or:
128
     *
129
     *     https://example.com/consume
130
     *
131
     *
132
     * @param $acsLocationInAuthnRequest
0 ignored issues
show
Coding Style introduced by
There must be exactly one blank line before the tags in a doc comment
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
133
     * @return string
0 ignored issues
show
Coding Style introduced by
Tag @return cannot be grouped with parameter tags in a doc comment
Loading history...
134
     */
135
    public function determineAcsLocationForAdfs($acsLocationInAuthnRequest)
136
    {
137
        // List of allowed ACS locations configured in middleware.
138
        $allowedAcsLocations = $this->get('allowedAcsLocations');
139
140
        foreach ($allowedAcsLocations as $allowedAcsLocation) {
141
            if (strpos($acsLocationInAuthnRequest, $allowedAcsLocation) === 0) {
142
                return $acsLocationInAuthnRequest;
143
            }
144
        }
145
146
        // The exception listener will log relevant information to the log.
147
148
        throw new AcsLocationNotAllowedException(
149
            $acsLocationInAuthnRequest
150
        );
151
    }
152
153
    public function allowSsoOn2fa(): bool
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function allowSsoOn2fa()
Loading history...
154
    {
155
        return $this->get('allowSsoOn2fa');
156
    }
157
158
    public function allowedToSetSsoCookieOn2fa(): bool
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function allowedToSetSsoCookieOn2fa()
Loading history...
159
    {
160
        return $this->get('setSsoCookieOn2fa');
161
    }
162
}
163