Complex classes like ThreemaGateway_Tfa_AbstractProvider 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 ThreemaGateway_Tfa_AbstractProvider, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
14 | abstract class ThreemaGateway_Tfa_AbstractProvider extends XenForo_Tfa_AbstractProvider |
||
15 | { |
||
16 | /** |
||
17 | * Variable, which will be filled with object of the Gateway Permissions class. |
||
18 | * |
||
19 | * @var ThreemaGateway_Handler_Permissions |
||
20 | */ |
||
21 | protected $gatewayPermissions; |
||
22 | |||
23 | /** |
||
24 | * Variable, which will be filled with object of Gateway Settings later. |
||
25 | * |
||
26 | * @var ThreemaGateway_Handler_Settings |
||
27 | */ |
||
28 | protected $gatewaySettings; |
||
29 | |||
30 | /** |
||
31 | * Variable, which will be filled with object of Gateway Handler later. |
||
32 | * |
||
33 | * It is private as {@link getSdk()} should be used. This makes sure the SDK |
||
34 | * is only initialized when it is really needed. |
||
35 | * |
||
36 | * @var ThreemaGateway_Handler_PhpSdk |
||
37 | */ |
||
38 | private $gatewaySdk = null; |
||
39 | |||
40 | /** |
||
41 | * Variable, which will be filled with object of Gateway Handler for server actions later. |
||
42 | * |
||
43 | * @var ThreemaGateway_Handler_Action_gatewayServer |
||
44 | */ |
||
45 | protected $gatewayServer; |
||
46 | |||
47 | /** |
||
48 | * Variable, which will be filled with object of Gateway Handler for sending actions later. |
||
49 | * |
||
50 | * @var ThreemaGateway_Handler_Action_Sender |
||
51 | */ |
||
52 | protected $gatewaySender; |
||
53 | |||
54 | /** |
||
55 | * Create provider. |
||
56 | * |
||
57 | * @param string $providerId Provider id |
||
58 | */ |
||
59 | public function __construct($providerId) |
||
67 | |||
68 | /** |
||
69 | * Return the title of the 2FA methode. |
||
70 | */ |
||
71 | public function getTitle() |
||
75 | |||
76 | /** |
||
77 | * Return a description of the 2FA methode. |
||
78 | */ |
||
79 | public function getDescription() |
||
83 | |||
84 | /** |
||
85 | * Called when activated. Returns inital data of 2FA method. |
||
86 | * |
||
87 | * @param array $user |
||
88 | * @param array $setupData |
||
89 | * @return array |
||
90 | */ |
||
91 | public function generateInitialData(array $user, array $setupData) |
||
97 | |||
98 | /** |
||
99 | * Called when trying to verify user. Sends Threema message. |
||
100 | * |
||
101 | * @param string $context |
||
102 | * @param array $user |
||
103 | * @param string $userIp |
||
104 | * @param array $providerData |
||
105 | * @return array |
||
106 | */ |
||
107 | public function triggerVerification($context, array $user, $userIp, array &$providerData) |
||
117 | |||
118 | /** |
||
119 | * Called when trying to verify user. Shows input for secret and such things. |
||
120 | * |
||
121 | * @param XenForo_View $view |
||
122 | * @param string $context |
||
123 | * @param array $user |
||
124 | * @param array $providerData |
||
125 | * @param array $triggerData |
||
126 | * @return string HTML code |
||
127 | */ |
||
128 | public function renderVerification(XenForo_View $view, $context, array $user, |
||
133 | |||
134 | /** |
||
135 | * Called when trying to verify user. Checks whether a given secret is valid. |
||
136 | * |
||
137 | * @param string $context |
||
138 | * @param array $input |
||
139 | * @param array $user |
||
140 | * @param array $providerData |
||
141 | * |
||
142 | * @return bool |
||
143 | */ |
||
144 | public function verifyFromInput($context, XenForo_Input $input, array $user, array &$providerData) |
||
151 | |||
152 | /** |
||
153 | * Verifies the Treema ID formally after it was entered/changed. |
||
154 | * |
||
155 | * @param XenForo_Input $input |
||
156 | * @param array $user |
||
157 | * @param array $error |
||
158 | * |
||
159 | * @return array |
||
160 | */ |
||
161 | public function verifySetupFromInput(XenForo_Input $input, array $user, &$error) |
||
182 | |||
183 | /** |
||
184 | * @return bool |
||
185 | */ |
||
186 | public function canManage() |
||
190 | |||
191 | |||
192 | /** |
||
193 | * States whether the setup is required. |
||
194 | * |
||
195 | * @return bool |
||
196 | */ |
||
197 | public function requiresSetup() |
||
201 | |||
202 | /** |
||
203 | * Called when setting up the provider before the setup page is shown. |
||
204 | * |
||
205 | * Currently this is not correctly implemented in XenForo. |
||
206 | * See {@link https://xenforo.com/community/threads/1-5-documentation-for-two-step-authentication.102846/#post-1031047} |
||
207 | * |
||
208 | * @param XenForo_View $view |
||
209 | * @param array $user |
||
210 | * |
||
211 | * @return string HTML code |
||
212 | */ |
||
213 | public function renderSetup(XenForo_View $view, array $user) |
||
218 | |||
219 | /** |
||
220 | * Handles settings of user. |
||
221 | * |
||
222 | * @param XenForo_Controller $controller |
||
223 | * @param array $user |
||
224 | * @param array $providerData |
||
225 | * |
||
226 | * @return null|ThreemaGateway_ViewPublic_TfaManage |
||
227 | */ |
||
228 | final public function handleManage(XenForo_Controller $controller, array $user, array $providerData) |
||
374 | |||
375 | /** |
||
376 | * Called when trying to verify user. Checks whether a user meets the |
||
377 | * requirements. |
||
378 | * |
||
379 | * @param array $user |
||
380 | * @param object $error |
||
381 | * |
||
382 | * @return bool |
||
383 | */ |
||
384 | public function meetsRequirements(array $user, &$error) |
||
388 | |||
389 | /** |
||
390 | * Called when verifying displaying the choose 2FA mode. |
||
391 | * |
||
392 | * @return bool |
||
393 | */ |
||
394 | public function canEnable() |
||
399 | |||
400 | /** |
||
401 | * Called before the setup verification is shown. |
||
402 | * |
||
403 | * @param array $providerData |
||
404 | * @param array $triggerData |
||
405 | * |
||
406 | * @return bool |
||
407 | */ |
||
408 | abstract protected function initiateSetupData(array &$providerData, array &$triggerData); |
||
409 | |||
410 | /** |
||
411 | * Generates the default provider options at setup time before it is |
||
412 | * displayed to the user. |
||
413 | * |
||
414 | * @return array |
||
415 | */ |
||
416 | abstract protected function generateDefaultData(); |
||
417 | |||
418 | /** |
||
419 | * Adjust the view params for managing the 2FA mode, e.g. add special |
||
420 | * params needed by your template. |
||
421 | * |
||
422 | * @param array $viewParams |
||
423 | * @param string $context |
||
424 | * @param array $user |
||
425 | * |
||
426 | * @return array |
||
427 | */ |
||
428 | abstract protected function adjustViewParams(array $viewParams, $context, array $user); |
||
429 | |||
430 | /** |
||
431 | * Saves new provider options to database. |
||
432 | * |
||
433 | * @param array $user |
||
434 | * @param array $options |
||
435 | */ |
||
436 | protected function saveProviderOptions($user, array $options) |
||
442 | |||
443 | /** |
||
444 | * Resets the provider options to make sure the current 2FA verification |
||
445 | * does not affect the next one. |
||
446 | * |
||
447 | * Please expand this if you have more values, which need to be reset, but |
||
448 | * please do not forget to call the parent. |
||
449 | * |
||
450 | * @param string $context |
||
451 | * @param array $providerData |
||
452 | */ |
||
453 | protected function resetProviderOptionsForTrigger($context, array &$providerData) |
||
458 | |||
459 | /** |
||
460 | * Sends a message to a user and chooses automatically whether E2E mode can |
||
461 | * be used. |
||
462 | * |
||
463 | * @param array $receiverId The Threema ID to who |
||
464 | * @param array $xenPhrase The message as a phrase, which should be sent |
||
465 | */ |
||
466 | final protected function sendMessage($receiverId, XenForo_Phrase $xenPhrase) |
||
475 | |||
476 | /** |
||
477 | * Generates a random numeric string consisting of digits. |
||
478 | * |
||
479 | * @param int $length The length of the string (default: 6) |
||
480 | * @return string |
||
481 | */ |
||
482 | final protected function generateRandomSecret($length = 6) |
||
512 | |||
513 | /** |
||
514 | * Gets the default Threema ID using different sources. |
||
515 | * |
||
516 | * @param array $user |
||
517 | * @return string|false |
||
518 | */ |
||
519 | final protected function getDefaultThreemaId(array $user) |
||
558 | |||
559 | /** |
||
560 | * Register a request for a new pending confirmation message. |
||
561 | * |
||
562 | * @param array $providerData |
||
563 | * @param int $pendingType What type of message request this is. |
||
564 | * You should use one of the PENDING_* constants |
||
565 | * in the Model (ThreemaGateway_Model_TfaPendingMessagesConfirmation). |
||
566 | * @param array $user |
||
567 | * @param string|int $extraData Any extra data you want to save in the database. |
||
568 | * |
||
569 | * @return bool |
||
570 | */ |
||
571 | final protected function registerPendingConfirmationMessage(array $providerData, $pendingType, array $user, $extraData = null) |
||
604 | |||
605 | /** |
||
606 | * Register a request for a new pending confirmation message. |
||
607 | * |
||
608 | * @param array $providerData |
||
609 | * @param int $pendingType What type of message request this is. |
||
610 | * You should use one of the PENDING_* constants |
||
611 | * in the Model (ThreemaGateway_Model_TfaPendingMessagesConfirmation). |
||
612 | * |
||
613 | * @return bool |
||
614 | */ |
||
615 | final protected function unregisterPendingConfirmationMessage(array $providerData, $pendingType) |
||
630 | |||
631 | /** |
||
632 | * Verifies whether the new secret is valid considering timing information |
||
633 | * about the current secret. |
||
634 | * |
||
635 | * @param array $providerData |
||
636 | * @return bool |
||
637 | */ |
||
638 | final protected function verifySecretIsInTime(array $providerData) |
||
650 | |||
651 | /** |
||
652 | * Verifies whether the new secret is valid by comparing it with the previous |
||
653 | * secret. |
||
654 | * |
||
655 | * @param array $providerData |
||
656 | * @param string $newSecret the new secret, which is currently checked/verified |
||
657 | * @return bool |
||
658 | */ |
||
659 | final protected function verifyNoReplayAttack(array $providerData, $newSecret) |
||
670 | |||
671 | /** |
||
672 | * Updates the data used by {@see verifyNoReplayAttack()} to prevent replay attacks. |
||
673 | * |
||
674 | * @param array $providerData |
||
675 | * @param string|int $secret The currently processed (& verified) secret |
||
676 | * @return bool |
||
677 | */ |
||
678 | final protected function updateReplayCheckData(array &$providerData, $secret) |
||
688 | |||
689 | /** |
||
690 | * Parse a given number of seconds to a human-readble format. |
||
691 | * |
||
692 | * @param int $seconds |
||
693 | * @return string |
||
694 | */ |
||
695 | final protected function parseTime($seconds) |
||
722 | |||
723 | /** |
||
724 | * Checks whether a string is the same (returns true) or not (returns false). |
||
725 | * |
||
726 | * This should be used for security-sensitive things as it checks the |
||
727 | * strings constant-time. |
||
728 | * |
||
729 | * @param string $string1 |
||
730 | * @param string $string2 |
||
731 | * @return bool |
||
732 | */ |
||
733 | final protected function stringCompare($string1, $string2) |
||
737 | |||
738 | /** |
||
739 | * Returns the PHP SDK object. |
||
740 | * |
||
741 | * @return ThreemaGateway_Handler_PhpSdk |
||
742 | */ |
||
743 | final protected function getSdk() |
||
751 | } |
||
752 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.