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.