ProxyStateHandler   C
last analyzed

Complexity

Total Complexity 53

Size/Duplication

Total Lines 310
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 79
c 0
b 0
f 0
dl 0
loc 310
rs 6.96
wmc 53

49 Methods

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