Passed
Push — feature/add-azure-mfa-registra... ( 3767e0...d31ca4 )
by
unknown
02:11
created

ProxyStateHandler   B

Complexity

Total Complexity 50

Size/Duplication

Total Lines 292
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 74
dl 0
loc 292
rs 8.4
c 0
b 0
f 0
wmc 50

46 Methods

Rating   Name   Duplication   Size   Complexity  
A getGatewayRequestId() 0 3 1
A markAuthenticationModeForRequest() 0 3 1
A setRequiredLoaIdentifier() 0 5 1
A getSchacHomeOrganization() 0 3 1
A setAuthenticatingIdp() 0 5 1
A getRequestServiceProvider() 0 3 1
A getIdentityNameId() 0 13 3
A getPreferredLocale() 0 3 1
A setSchacHomeOrganization() 0 4 1
A setRequestAssertionConsumerServiceUrl() 0 5 1
A isSecondFactorFallback() 0 3 1
A saveAssertion() 0 5 1
A setResponseContextServiceId() 0 4 1
A getResponseAction() 0 3 1
A setVerifiedBySsoOn2faCookie() 0 5 1
A setRequestId() 0 5 1
A setSecondFactorVerified() 0 5 1
A setGatewayRequestId() 0 5 1
A setRequestServiceProvider() 0 5 1
A getResponseContextServiceId() 0 3 1
A set() 0 3 1
A getRequestId() 0 3 1
A getSsoOn2faCookieFingerprint() 0 3 1
A saveIdentityNameId() 0 5 1
A clear() 0 7 3
A getRequiredLoaIdentifier() 0 3 1
A setPreferredLocale() 0 4 1
A setSelectedSecondFactorId() 0 5 1
A isSecondFactorVerified() 0 3 1
A setRelayState() 0 5 1
A setResponseAction() 0 4 1
A isVerifiedBySsoOn2faCookie() 0 3 1
A setSecondFactorIsFallback() 0 5 1
A getAuthenticationModeForRequestId() 0 3 1
A get() 0 3 1
A getRelayState() 0 3 1
A getAuthenticatingIdp() 0 3 1
A unsetVerifiedBySsoOn2faCookie() 0 3 1
A getSelectedSecondFactorId() 0 3 1
A isForceAuthn() 0 3 1
A unsetSelectedSecondFactorId() 0 3 1
A __construct() 0 4 1
A setIsForceAuthn() 0 4 1
A getAssertion() 0 3 1
A setSsoOn2faCookieFingerprint() 0 5 1
A getRequestAssertionConsumerServiceUrl() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like ProxyStateHandler often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ProxyStateHandler, and based on these observations, apply Extract Interface, too.

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
 */
18
19
namespace Surfnet\StepupGateway\GatewayBundle\Saml\Proxy;
20
21
use Surfnet\StepupGateway\GatewayBundle\Saml\Exception\RuntimeException;
22
use Symfony\Component\HttpFoundation\RequestStack;
23
24
/**
25
 * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
26
 */
27
class ProxyStateHandler
28
{
29
    public function __construct(
30
        private readonly RequestStack $requestStack,
31
        private $sessionPath,
32
    ) {
33
    }
34
35
    /**
36
     * Clear the complete state, leaving other states intact.
37
     */
38
    public function clear(): void
39
    {
40
        $all = $this->requestStack->getSession()->all();
41
42
        foreach (array_keys($all) as $key) {
43
            if (str_starts_with($key, $this->sessionPath)) {
44
                $this->requestStack->getSession()->remove($key);
45
            }
46
        }
47
    }
48
49
    public function setRequestId(string $originalRequestId): ProxyStateHandler
50
    {
51
        $this->set('request_id', $originalRequestId);
52
53
        return $this;
54
    }
55
56
    public function getRequestId(): ?string
57
    {
58
        return $this->get('request_id');
59
    }
60
61
    public function setRequestServiceProvider(string $serviceProvider): ProxyStateHandler
62
    {
63
        $this->set('service_provider', $serviceProvider);
64
65
        return $this;
66
    }
67
68
    public function getRequestServiceProvider(): ?string
69
    {
70
        return $this->get('service_provider');
71
    }
72
73
    public function setRequestAssertionConsumerServiceUrl(string $url): ProxyStateHandler
74
    {
75
        $this->set('assertion_consumer_service_url', $url);
76
77
        return $this;
78
    }
79
80
    public function getRequestAssertionConsumerServiceUrl(): ?string
81
    {
82
        return $this->get('assertion_consumer_service_url');
83
    }
84
85
    public function setRelayState(string $relayState): ProxyStateHandler
86
    {
87
        $this->set('relay_state', $relayState);
88
89
        return $this;
90
    }
91
92
    public function getRelayState(): ?string
93
    {
94
        return $this->get('relay_state');
95
    }
96
97
    public function setRequiredLoaIdentifier(?string $loaIdentifier): ProxyStateHandler
98
    {
99
        $this->set('loa_identifier', $loaIdentifier);
100
101
        return $this;
102
    }
103
104
    public function getRequiredLoaIdentifier(): ?string
105
    {
106
        return $this->get('loa_identifier');
107
    }
108
109
    public function setGatewayRequestId(string $requestId): ProxyStateHandler
110
    {
111
        $this->set('gateway_request_id', $requestId);
112
113
        return $this;
114
    }
115
116
    public function getGatewayRequestId(): ?string
117
    {
118
        return $this->get('gateway_request_id');
119
    }
120
121
    public function saveAssertion(string $assertionAsXmlString): ProxyStateHandler
122
    {
123
        $this->set('response_assertion', $assertionAsXmlString);
124
125
        return $this;
126
    }
127
128
    public function getAssertion(): ?string
129
    {
130
        return $this->get('response_assertion');
131
    }
132
133
    public function saveIdentityNameId(string $nameId): ProxyStateHandler
134
    {
135
        $this->set('name_id', $nameId);
136
137
        return $this;
138
    }
139
140
    public function getIdentityNameId(): string
141
    {
142
        $nameId = $this->get('name_id');
143
        if (!$nameId) {
144
            throw new RuntimeException('Unable to retrieve NameId, it was not set on the state handler');
145
        }
146
147
        if (!is_string($nameId)) {
148
            throw new RuntimeException(
149
                sprintf('Unable to retrieve NameId, must be a string, but a %s was set', gettype($nameId))
150
            );
151
        }
152
        return $nameId;
153
    }
154
155
    public function setAuthenticatingIdp(string $idpEntityId): ProxyStateHandler
156
    {
157
        $this->set('authenticating_idp', $idpEntityId);
158
159
        return $this;
160
    }
161
162
    public function getAuthenticatingIdp(): ?string
163
    {
164
        return $this->get('authenticating_idp');
165
    }
166
167
    public function setSelectedSecondFactorId(string $secondFactorId): ProxyStateHandler
168
    {
169
        $this->set('selected_second_factor', $secondFactorId);
170
171
        return $this;
172
    }
173
174
    public function unsetSelectedSecondFactorId(): void
175
    {
176
        $this->set('selected_second_factor', null);
177
    }
178
179
    public function getSelectedSecondFactorId(): ?string
180
    {
181
        return $this->get('selected_second_factor');
182
    }
183
184
    public function setSecondFactorVerified(bool $verified): ProxyStateHandler
185
    {
186
        $this->set('selected_second_factor_verified', $verified);
187
188
        return $this;
189
    }
190
191
    public function isSecondFactorVerified(): bool
192
    {
193
        return $this->get('selected_second_factor_verified') === true;
194
    }
195
196
197
    public function setSecondFactorIsFallback(bool $fallback): ProxyStateHandler
198
    {
199
        $this->set('selected_second_factor_fallback', $fallback);
200
201
        return $this;
202
    }
203
204
    public function isSecondFactorFallback(): bool
205
    {
206
        return (bool)$this->get('selected_second_factor_fallback');
207
    }
208
209
    public function setVerifiedBySsoOn2faCookie(bool $isVerifiedByCookie): ProxyStateHandler
210
    {
211
        $this->set('verified_by_sso_on_2fa_cookie', $isVerifiedByCookie);
212
213
        return $this;
214
    }
215
216
    public function unsetVerifiedBySsoOn2faCookie(): void
217
    {
218
        $this->set('verified_by_sso_on_2fa_cookie', null);
219
    }
220
221
    public function isVerifiedBySsoOn2faCookie(): bool
222
    {
223
        return $this->get('verified_by_sso_on_2fa_cookie') === true;
224
    }
225
226
    public function setSsoOn2faCookieFingerprint(string $fingerprint): ProxyStateHandler
227
    {
228
        $this->set('sso_on_2fa_cookie_fingerprint', $fingerprint);
229
230
        return $this;
231
    }
232
233
    public function getSsoOn2faCookieFingerprint()
234
    {
235
        return $this->get('sso_on_2fa_cookie_fingerprint');
236
    }
237
238
    public function setResponseAction(string $controllerName): ProxyStateHandler
239
    {
240
        $this->set('response_controller', $controllerName);
241
        return $this;
242
    }
243
244
    public function getResponseAction(): ?string
245
    {
246
        return $this->get('response_controller');
247
    }
248
249
    public function setResponseContextServiceId(string $serviceId): ProxyStateHandler
250
    {
251
        $this->set('response_context_service_id', $serviceId);
252
        return $this;
253
    }
254
255
    public function getResponseContextServiceId(): ?string
256
    {
257
        return $this->get('response_context_service_id');
258
    }
259
260
    public function setSchacHomeOrganization($organization): ProxyStateHandler
261
    {
262
        $this->set('schac_home_organization', $organization);
263
        return $this;
264
    }
265
266
    public function setIsForceAuthn(bool $forceAuthn): ProxyStateHandler
267
    {
268
        $this->set('force_authn', $forceAuthn);
269
        return $this;
270
    }
271
272
    public function isForceAuthn(): bool
273
    {
274
        return $this->get('force_authn') === true;
275
    }
276
277
    public function getSchacHomeOrganization(): ?string
278
    {
279
        return $this->get('schac_home_organization');
280
    }
281
282
283
    public function setPreferredLocale($locale): ProxyStateHandler
284
    {
285
        $this->set('locale', $locale);
286
        return $this;
287
    }
288
289
    public function getPreferredLocale(): ?string
290
    {
291
        return $this->get('locale');
292
    }
293
294
    /**
295
     * note that the authentication mode is stored outside the session path, to enable other state handlers
296
     * to retrieve the Authentication state for a given authentication request id.
297
     *
298
     * @param $requestId
299
     * @param $authenticationMode
300
     */
301
    public function markAuthenticationModeForRequest($requestId, $authenticationMode): void
302
    {
303
        $this->requestStack->getSession()->set('surfnet/gateway/auth_mode/' . $requestId, $authenticationMode);
304
    }
305
306
    public function getAuthenticationModeForRequestId($requestId)
307
    {
308
        return $this->requestStack->getSession()->get('surfnet/gateway/auth_mode/' . $requestId);
309
    }
310
311
    protected function set($key, $value): void
312
    {
313
        $this->requestStack->getSession()->set($this->sessionPath . $key, $value);
314
    }
315
316
    protected function get(string $key): mixed
317
    {
318
        return $this->requestStack->getSession()->get($this->sessionPath . $key);
319
    }
320
}
321