Complex classes like IdTokenBuilder 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
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 IdTokenBuilder, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
32 | final class IdTokenBuilder |
||
33 | { |
||
34 | /** |
||
35 | * @var string |
||
36 | */ |
||
37 | private $issuer; |
||
38 | |||
39 | /** |
||
40 | * @var Client |
||
41 | */ |
||
42 | private $client; |
||
43 | |||
44 | /** |
||
45 | * @var UserAccount |
||
46 | */ |
||
47 | private $userAccount; |
||
48 | |||
49 | /** |
||
50 | * @var string |
||
51 | */ |
||
52 | private $redirectUri; |
||
53 | |||
54 | /** |
||
55 | * @var UserInfo |
||
56 | */ |
||
57 | private $userinfo; |
||
58 | |||
59 | /** |
||
60 | * @var JWKSet |
||
61 | */ |
||
62 | private $signatureKeys; |
||
63 | |||
64 | /** |
||
65 | * @var int |
||
66 | */ |
||
67 | private $lifetime; |
||
68 | |||
69 | /** |
||
70 | * @var string[] |
||
71 | */ |
||
72 | private $scopes = []; |
||
73 | |||
74 | /** |
||
75 | * @var array |
||
76 | */ |
||
77 | private $requestedClaims = []; |
||
78 | |||
79 | /** |
||
80 | * @var string|null |
||
81 | */ |
||
82 | private $claimsLocales = null; |
||
83 | |||
84 | /** |
||
85 | * @var AccessTokenId|null |
||
86 | */ |
||
87 | private $accessTokenId = null; |
||
88 | |||
89 | /** |
||
90 | * @var AuthorizationCodeId|null |
||
91 | */ |
||
92 | private $authorizationCodeId = null; |
||
93 | |||
94 | /** |
||
95 | * @var string|null |
||
96 | */ |
||
97 | private $nonce = null; |
||
98 | |||
99 | /** |
||
100 | * @var bool |
||
101 | */ |
||
102 | private $withAuthenticationTime = false; |
||
103 | |||
104 | /** |
||
105 | * @var JWSBuilder|null |
||
106 | */ |
||
107 | private $jwsBuilder = null; |
||
108 | |||
109 | /** |
||
110 | * @var string|null |
||
111 | */ |
||
112 | private $signatureAlgorithm = null; |
||
113 | |||
114 | /** |
||
115 | * @var JWEBuilder|null |
||
116 | */ |
||
117 | private $jweBuilder; |
||
118 | |||
119 | /** |
||
120 | * @var string|null |
||
121 | */ |
||
122 | private $keyEncryptionAlgorithm = null; |
||
123 | |||
124 | /** |
||
125 | * @var string|null |
||
126 | */ |
||
127 | private $contentEncryptionAlgorithm = null; |
||
128 | |||
129 | /** |
||
130 | * @var \DateTimeImmutable|null |
||
131 | */ |
||
132 | private $expiresAt = null; |
||
133 | |||
134 | /** |
||
135 | * IdTokenBuilder constructor. |
||
136 | * |
||
137 | * @param string $issuer |
||
138 | * @param UserInfo $userinfo |
||
139 | * @param int $lifetime |
||
140 | * @param Client $client |
||
141 | * @param UserAccount $userAccount |
||
142 | * @param string $redirectUri |
||
143 | */ |
||
144 | private function __construct(string $issuer, UserInfo $userinfo, int $lifetime, Client $client, UserAccount $userAccount, string $redirectUri) |
||
153 | |||
154 | /** |
||
155 | * @param string $issuer |
||
156 | * @param UserInfo $userinfo |
||
157 | * @param int $lifetime |
||
158 | * @param Client $client |
||
159 | * @param UserAccount $userAccount |
||
160 | * @param string $redirectUri |
||
161 | * |
||
162 | * @return IdTokenBuilder |
||
163 | */ |
||
164 | public static function create(string $issuer, UserInfo $userinfo, int $lifetime, Client $client, UserAccount $userAccount, string $redirectUri) |
||
168 | |||
169 | /** |
||
170 | * @param AccessToken $accessToken |
||
171 | * |
||
172 | * @return IdTokenBuilder |
||
173 | */ |
||
174 | public function withAccessToken(AccessToken $accessToken): self |
||
195 | |||
196 | /** |
||
197 | * @param AccessTokenId $accessTokenId |
||
198 | * |
||
199 | * @return IdTokenBuilder |
||
200 | */ |
||
201 | public function withAccessTokenId(AccessTokenId $accessTokenId): self |
||
208 | |||
209 | /** |
||
210 | * @param AuthorizationCodeId $authorizationCodeId |
||
211 | * |
||
212 | * @return IdTokenBuilder |
||
213 | */ |
||
214 | public function withAuthorizationCodeId(AuthorizationCodeId $authorizationCodeId): self |
||
221 | |||
222 | /** |
||
223 | * @param string $claimsLocales |
||
224 | * |
||
225 | * @return IdTokenBuilder |
||
226 | */ |
||
227 | public function withClaimsLocales(string $claimsLocales): self |
||
234 | |||
235 | /** |
||
236 | * @return IdTokenBuilder |
||
237 | */ |
||
238 | public function withAuthenticationTime(): self |
||
245 | |||
246 | /** |
||
247 | * @param string[] $scopes |
||
248 | * |
||
249 | * @return IdTokenBuilder |
||
250 | */ |
||
251 | public function withScope(array $scopes): self |
||
258 | |||
259 | /** |
||
260 | * @param array $requestedClaims |
||
261 | * |
||
262 | * @return IdTokenBuilder |
||
263 | */ |
||
264 | public function withRequestedClaims(array $requestedClaims): self |
||
271 | |||
272 | /** |
||
273 | * @param string $nonce |
||
274 | * |
||
275 | * @return IdTokenBuilder |
||
276 | */ |
||
277 | public function withNonce(string $nonce): self |
||
284 | |||
285 | /** |
||
286 | * @param \DateTimeImmutable $expiresAt |
||
287 | * |
||
288 | * @return IdTokenBuilder |
||
289 | */ |
||
290 | public function withExpirationAt(\DateTimeImmutable $expiresAt): self |
||
297 | |||
298 | /** |
||
299 | * @return IdTokenBuilder |
||
300 | */ |
||
301 | public function withoutAuthenticationTime(): self |
||
308 | |||
309 | /** |
||
310 | * @param JWSBuilder $jwsBuilder |
||
311 | * @param JWKSet $signatureKeys |
||
312 | * @param string $signatureAlgorithm |
||
313 | * |
||
314 | * @return IdTokenBuilder |
||
315 | */ |
||
316 | public function withSignature(JWSBuilder $jwsBuilder, JWKSet $signatureKeys, string $signatureAlgorithm): self |
||
331 | |||
332 | /** |
||
333 | * @param JWEBuilder $jweBuilder |
||
334 | * @param string $keyEncryptionAlgorithm |
||
335 | * @param string $contentEncryptionAlgorithm |
||
336 | * |
||
337 | * @return IdTokenBuilder |
||
338 | */ |
||
339 | public function withEncryption(JWEBuilder $jweBuilder, string $keyEncryptionAlgorithm, string $contentEncryptionAlgorithm): self |
||
354 | |||
355 | /** |
||
356 | * @return string |
||
357 | */ |
||
358 | public function build(): string |
||
379 | |||
380 | /** |
||
381 | * @param array $claims |
||
382 | * |
||
383 | * @return array |
||
384 | */ |
||
385 | private function updateClaimsWithJwtClaims(array $claims): array |
||
400 | |||
401 | /** |
||
402 | * @param array $claims |
||
403 | * @param UserAccount $userAccount |
||
404 | * |
||
405 | * @return array |
||
406 | */ |
||
407 | private function updateClaimsWithAuthenticationTime(array $claims, UserAccount $userAccount): array |
||
415 | |||
416 | /** |
||
417 | * @param array $claims |
||
418 | * |
||
419 | * @return array |
||
420 | */ |
||
421 | private function updateClaimsWithNonce(array $claims): array |
||
429 | |||
430 | /** |
||
431 | * @param array $claims |
||
432 | * |
||
433 | * @return array |
||
434 | */ |
||
435 | private function updateClaimsAudience(array $claims): array |
||
445 | |||
446 | /** |
||
447 | * @param array $claims |
||
448 | * @param UserAccount $userAccount |
||
449 | * |
||
450 | * @return array |
||
451 | */ |
||
452 | private function updateClaimsWithAmrAndAcrInfo(array $claims, UserAccount $userAccount): array |
||
462 | |||
463 | /** |
||
464 | * @param array $claims |
||
465 | * |
||
466 | * @return string |
||
467 | */ |
||
468 | private function computeIdToken(array $claims): string |
||
483 | |||
484 | /** |
||
485 | * @param Client $client |
||
486 | * @param string $jwt |
||
487 | * |
||
488 | * @return string |
||
489 | */ |
||
490 | private function tryToEncrypt(Client $client, string $jwt): string |
||
515 | |||
516 | /** |
||
517 | * @param string $signatureAlgorithm |
||
518 | * |
||
519 | * @return JWK |
||
520 | */ |
||
521 | private function getSignatureKey(string $signatureAlgorithm): JWK |
||
534 | |||
535 | /** |
||
536 | * @param JWK $signatureKey |
||
537 | * @param string $signatureAlgorithm |
||
538 | * |
||
539 | * @return array |
||
540 | */ |
||
541 | private function getHeaders(JWK $signatureKey, string $signatureAlgorithm): array |
||
553 | |||
554 | /** |
||
555 | * @param array $claims |
||
556 | * |
||
557 | * @return array |
||
558 | */ |
||
559 | private function updateClaimsWithTokenHash(array $claims): array |
||
573 | |||
574 | /** |
||
575 | * @param TokenId $tokenId |
||
576 | * |
||
577 | * @return string |
||
578 | */ |
||
579 | private function getHash(TokenId $tokenId): string |
||
583 | |||
584 | /** |
||
585 | * @throws \InvalidArgumentException |
||
586 | * |
||
587 | * @return string |
||
588 | */ |
||
589 | private function getHashMethod(): string |
||
612 | |||
613 | /** |
||
614 | * @throws \InvalidArgumentException |
||
615 | * |
||
616 | * @return int |
||
617 | */ |
||
618 | private function getHashSize(): int |
||
641 | } |
||
642 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.