‪TYPO3CMS  11.5
MfaInfoElementTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Prophecy\Argument;
21 use Prophecy\PhpUnit\ProphecyTrait;
28 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
29 
30 class ‪MfaInfoElementTest extends FunctionalTestCase
31 {
32  use ProphecyTrait;
33 
34  protected function ‪setUp(): void
35  {
36  parent::setUp();
37  $this->importCSVDataSet(__DIR__ . '/../../../../core/Tests/Functional/Authentication/Fixtures/be_users.csv');
38 
39  ‪$GLOBALS['BE_USER'] = GeneralUtility::makeInstance(BackendUserAuthentication::class);
40  ‪$GLOBALS['BE_USER']->enablecolumns = ['deleted' => true];
41  ‪$GLOBALS['BE_USER']->setBeUserByUid(1);
42 
43  // Default LANG prophecy just returns incoming value as label if calling ->sL()
44  $languageServiceProphecy = $this->prophesize(LanguageService::class);
45  $languageServiceProphecy->loadSingleTableDescription(Argument::cetera())->willReturn(null);
46  $languageServiceProphecy->sL(Argument::cetera())->willReturnArgument(0);
47  ‪$GLOBALS['LANG'] = $languageServiceProphecy->reveal();
48  }
49 
53  public function ‪renderReturnsEmptyResultOnInvalidTableTest(): void
54  {
55  $result = $this->‪getFormElementResult([
56  'tableName' => 'some_table',
57  ]);
58 
59  self::assertEmpty($result['html']);
60  }
61 
65  public function ‪renderReturnsElementWithMfaDisabledTest(): void
66  {
67  $result = $this->‪getFormElementResult([
68  'tableName' => 'be_users',
69  'databaseRow' => [
70  'uid' => 3,
71  ],
72  'parameterArray' => [
73  'itemFormElValue' => '[]',
74  ],
75  ]);
76 
77  // MFA is disabled
78  self::assertMatchesRegularExpression('/<span.*class="label label-danger.*>LLL:EXT:core\/Resources\/Private\/Language\/locallang_core.xlf:labels.mfa.disabled/s', $result['html']);
79  self::assertDoesNotMatchRegularExpression('/<span.*class="label label-success.*>LLL:EXT:core\/Resources\/Private\/Language\/locallang_core.xlf:labels.mfa.enabled/s', $result['html']);
80  // MFA can NOT be deactivated
81  self::assertMatchesRegularExpression('/<button.*class="t3js-deactivate-mfa-button btn btn-danger disabled".*disabled="disabled"/s', $result['html']);
82  // JavaScript is NOT added
83  self::assertEmpty($result['requireJsModules']);
84  }
85 
90  {
91  $result = $this->‪getFormElementResult([
92  'tableName' => 'be_users',
93  'databaseRow' => [
94  'uid' => 4,
95  ],
96  'parameterArray' => [
97  'itemFormElValue' => '{"invalid":{"active":true}}',
98  ],
99  ]);
100 
101  // MFA is disabled
102  self::assertMatchesRegularExpression('/<span.*class="label label-danger.*>LLL:EXT:core\/Resources\/Private\/Language\/locallang_core.xlf:labels.mfa.disabled/s', $result['html']);
103  self::assertDoesNotMatchRegularExpression('/<span.*class="label label-success.*>LLL:EXT:core\/Resources\/Private\/Language\/locallang_core.xlf:labels.mfa.enabled/s', $result['html']);
104  // MFA can NOT be deactivated
105  self::assertMatchesRegularExpression('/<button.*class="t3js-deactivate-mfa-button btn btn-danger disabled".*disabled="disabled"/s', $result['html']);
106  // JavaScript is NOT added
107  self::assertEmpty($result['requireJsModules']);
108  }
109 
113  public function ‪renderReturnsElementWithMfaActiveTest(): void
114  {
115  $result = $this->‪getFormElementResult([
116  'tableName' => 'be_users',
117  'databaseRow' => [
118  'uid' => 4,
119  ],
120  'parameterArray' => [
121  'itemFormElValue' => '{"totp":{"secret":"KRMVATZTJFZUC53FONXW2ZJB","active":true,"attempts":2}}',
122  ],
123  ]);
124 
125  // Mfa is enabled
126  self::assertDoesNotMatchRegularExpression('/<span.*class="label label-danger.*>LLL:EXT:core\/Resources\/Private\/Language\/locallang_core.xlf:labels.mfa.disabled/s', $result['html']);
127  self::assertMatchesRegularExpression('/<span.*class="label label-success.*>LLL:EXT:core\/Resources\/Private\/Language\/locallang_core.xlf:labels.mfa.enabled/s', $result['html']);
128  // Totp item exist
129  self::assertMatchesRegularExpression('/<li.*class="list-group-item".*id="provider-totp"/s', $result['html']);
130  // Recovery codes item does NOT exist
131  self::assertStringNotContainsString('id="provider-recovery-codes"', $result['html']);
132  // No item is locked
133  self::assertDoesNotMatchRegularExpression('/<span.*class="label label-danger".*>LLL:EXT:core\/Resources\/Private\/Language\/locallang_core.xlf:labels.locked/s', $result['html']);
134  // Item can be deactivated
135  self::assertMatchesRegularExpression('/<button.*class="btn btn-default btn-sm float-end t3js-deactivate-provider-button"/s', $result['html']);
136  // MFA can be deactivated
137  self::assertMatchesRegularExpression('/<button.*class="t3js-deactivate-mfa-button btn btn-danger "/s', $result['html']);
138  // JavaScript is added
139  self::assertInstanceOf(JavaScriptModuleInstruction::class, $result['requireJsModules'][0]);
140  self::assertSame('TYPO3/CMS/Backend/FormEngine/Element/MfaInfoElement', $result['requireJsModules'][0]->getName());
141  }
142 
147  {
148  $result = $this->‪getFormElementResult([
149  'tableName' => 'be_users',
150  'databaseRow' => [
151  'uid' => 5,
152  ],
153  'parameterArray' => [
154  'itemFormElValue' => '{"totp":{"secret":"KRMVATZTJFZUC53FONXW2ZJB","active":true,"attempts":2},"recovery-codes":{"active":true,"attempts":3,"codes":[]}}',
155  ],
156  ]);
157 
158  // Mfa is enabled
159  self::assertDoesNotMatchRegularExpression('/<span.*class="label label-danger.*>LLL:EXT:core\/Resources\/Private\/Language\/locallang_core.xlf:labels.mfa.disabled/s', $result['html']);
160  self::assertMatchesRegularExpression('/<span.*class="label label-success.*>LLL:EXT:core\/Resources\/Private\/Language\/locallang_core.xlf:labels.mfa.enabled/s', $result['html']);
161  // Totp item exists
162  self::assertMatchesRegularExpression('/<li.*class="list-group-item".*id="provider-totp"/s', $result['html']);
163  // Recovery codes item exists
164  self::assertMatchesRegularExpression('/<li.*class="list-group-item".*id="provider-recovery-codes"/s', $result['html']);
165  // Item is locked
166  self::assertMatchesRegularExpression('/<span.*class="label label-danger".*>LLL:EXT:core\/Resources\/Private\/Language\/locallang_core.xlf:labels.locked/s', $result['html']);
167  // Items can be deactivated
168  self::assertMatchesRegularExpression('/<button.*class="btn btn-default btn-sm float-end t3js-deactivate-provider-button"/s', $result['html']);
169  // MFA can be deactivated
170  self::assertMatchesRegularExpression('/<button.*class="t3js-deactivate-mfa-button btn btn-danger "/s', $result['html']);
171  // JavaScript is added
172  self::assertInstanceOf(JavaScriptModuleInstruction::class, $result['requireJsModules'][0]);
173  self::assertSame('TYPO3/CMS/Backend/FormEngine/Element/MfaInfoElement', $result['requireJsModules'][0]->getName());
174  }
175 
180  {
181  // Make the target user a system maintainer. Since the current user (1)
182  // is only admin, he is not allowed to deactivate the providers, nor MFA.
183  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['systemMaintainers'] = ['5'];
184 
185  $result = $this->‪getFormElementResult([
186  'tableName' => 'be_users',
187  'databaseRow' => [
188  'uid' => 5,
189  ],
190  'parameterArray' => [
191  'itemFormElValue' => '{"totp":{"secret":"KRMVATZTJFZUC53FONXW2ZJB","active":true,"attempts":2},"recovery-codes":{"active":true,"attempts":3,"codes":[]}}',
192  ],
193  ]);
194 
195  // Mfa is enabled
196  self::assertDoesNotMatchRegularExpression('/<span.*class="label label-danger.*>LLL:EXT:core\/Resources\/Private\/Language\/locallang_core.xlf:labels.mfa.disabled/s', $result['html']);
197  self::assertMatchesRegularExpression('/<span.*class="label label-success.*>LLL:EXT:core\/Resources\/Private\/Language\/locallang_core.xlf:labels.mfa.enabled/s', $result['html']);
198  // Totp item exists
199  self::assertMatchesRegularExpression('/<li.*class="list-group-item".*id="provider-totp"/s', $result['html']);
200  // Recovery codes item exists
201  self::assertMatchesRegularExpression('/<li.*class="list-group-item".*id="provider-recovery-codes"/s', $result['html']);
202  // Item (recovery codes) is locked
203  self::assertMatchesRegularExpression('/<span.*class="label label-danger".*>LLL:EXT:core\/Resources\/Private\/Language\/locallang_core.xlf:labels.locked/s', $result['html']);
204  // Items deactivation button is not shown
205  self::assertStringNotContainsString('t3js-deactivate-provider-button', $result['html']);
206  // MFA deactivation button is not shown
207  self::assertStringNotContainsString('t3js-deactivate-mfa-button', $result['html']);
208  // JavaScript is NOT added
209  self::assertEmpty($result['requireJsModules']);
210  }
211 
212  protected function ‪getFormElementResult(array $data): array
213  {
214  return GeneralUtility::makeInstance(
215  MfaInfoElement::class,
216  GeneralUtility::makeInstance(NodeFactory::class),
217  $data
218  )->render();
219  }
220 }
‪TYPO3\CMS\Backend\Tests\Functional\Form\MfaInfoElementTest\renderReturnsEmptyResultOnInvalidTableTest
‪renderReturnsEmptyResultOnInvalidTableTest()
Definition: MfaInfoElementTest.php:52
‪TYPO3\CMS\Backend\Tests\Functional\Form\MfaInfoElementTest\renderReturnsElementWithMfaActiveTest
‪renderReturnsElementWithMfaActiveTest()
Definition: MfaInfoElementTest.php:112
‪TYPO3\CMS\Backend\Tests\Functional\Form\MfaInfoElementTest\renderReturnsElementWithMfaDisabledTest
‪renderReturnsElementWithMfaDisabledTest()
Definition: MfaInfoElementTest.php:64
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction
Definition: JavaScriptModuleInstruction.php:23
‪TYPO3\CMS\Backend\Tests\Functional\Form\MfaInfoElementTest\renderReturnsElementWithoutDeactivationButtonsOnMissingPermissionsTest
‪renderReturnsElementWithoutDeactivationButtonsOnMissingPermissionsTest()
Definition: MfaInfoElementTest.php:178
‪TYPO3\CMS\Backend\Tests\Functional\Form\MfaInfoElementTest
Definition: MfaInfoElementTest.php:31
‪TYPO3\CMS\Backend\Tests\Functional\Form\MfaInfoElementTest\renderReturnsElementWithoutInvalidProviderTest
‪renderReturnsElementWithoutInvalidProviderTest()
Definition: MfaInfoElementTest.php:88
‪TYPO3\CMS\Backend\Tests\Functional\Form\MfaInfoElementTest\renderReturnsElementWithMfaActiveAndLockedProvidersTest
‪renderReturnsElementWithMfaActiveAndLockedProvidersTest()
Definition: MfaInfoElementTest.php:145
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Backend\Form\NodeFactory
Definition: NodeFactory.php:37
‪TYPO3\CMS\Backend\Tests\Functional\Form\MfaInfoElementTest\setUp
‪setUp()
Definition: MfaInfoElementTest.php:33
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Tests\Functional\Form\MfaInfoElementTest\getFormElementResult
‪getFormElementResult(array $data)
Definition: MfaInfoElementTest.php:211
‪TYPO3\CMS\Backend\Tests\Functional\Form
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Backend\Form\Element\MfaInfoElement
Definition: MfaInfoElement.php:37