diff options
author | diosmosis <diosmosis@users.noreply.github.com> | 2019-05-16 03:12:05 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-16 03:12:05 +0300 |
commit | 05017ba88ec611f63bf223728990351212ff560f (patch) | |
tree | 79c20127a6584a1316bb864b329d0cba713add10 /plugins | |
parent | cecec674a65e4dc2a1aa7c33722a5380be2fd719 (diff) |
Require password confirmation before setting/removing superuser access. (#13975)
* Require password confirmation for changing superuser access and fix issue where getSiteAccess is called w/ superuser when toggling superuser access.
* apply review feedback
* Allow bypassing password confirmation in certain scenarios.
* Fixing tests & adding UI test.
* Update submodule.
* test fixes + remove return; from 2fa tests.
* update submodule
* Fixing tests
* Couple tweaks for screenshot testing.
* test fixes
* Fix TwoFactorAuthUsersManager test.
* More test fixes.
* try to disable all transitions
* More UI test fixes + disable materialize animations globally in UI tests.
* 2fa ui tests now working
Diffstat (limited to 'plugins')
44 files changed, 266 insertions, 128 deletions
diff --git a/plugins/Actions/tests/UI/ActionsDataTable_spec.js b/plugins/Actions/tests/UI/ActionsDataTable_spec.js index 3778bd3cf1..b09a55eb7c 100644 --- a/plugins/Actions/tests/UI/ActionsDataTable_spec.js +++ b/plugins/Actions/tests/UI/ActionsDataTable_spec.js @@ -32,6 +32,7 @@ describe("ActionsDataTable", function () { await page.mouse.move(-10, -10); await page.waitForNetworkIdle(); + await page.waitFor(250); // rendering expect(await page.screenshot({ fullPage: true })).to.matchImage('subtables_loaded'); }); diff --git a/plugins/Dashboard/tests/UI/Dashboard_spec.js b/plugins/Dashboard/tests/UI/Dashboard_spec.js index af060caac9..f539219829 100644 --- a/plugins/Dashboard/tests/UI/Dashboard_spec.js +++ b/plugins/Dashboard/tests/UI/Dashboard_spec.js @@ -168,8 +168,8 @@ describe("Dashboard", function () { var button = await page.jQuery('.modal.open .modal-footer a:contains(Yes)'); await button.click(); - await page.waitFor(250); await page.mouse.move(-10, -10); + await page.waitFor(250); expect(await page.screenshot({ fullPage: true })).to.matchImage('widget_move_removed'); }); @@ -181,6 +181,7 @@ describe("Dashboard", function () { var button = await page.jQuery('.modal.open .modal-footer a:contains(Save)'); await button.click(); await page.mouse.move(-10, -10); + await page.waitFor(500); // animation expect(await page.screenshot({ fullPage: true })).to.matchImage('change_layout'); }); @@ -263,6 +264,7 @@ describe("Dashboard", function () { await page.type('#createDashboardName', 'newdash2'); var button = await page.jQuery('.modal.open .modal-footer a:contains(Ok)'); await button.click(); + await page.mouse.move(-10, -10); await page.waitForNetworkIdle(); expect(await page.screenshot({ fullPage: true })).to.matchImage('create_new'); diff --git a/plugins/Dashboard/tests/UI/expected-screenshots/DashboardManager_create_new.png b/plugins/Dashboard/tests/UI/expected-screenshots/DashboardManager_create_new.png index d3b0e150b5..c0429584d7 100644 --- a/plugins/Dashboard/tests/UI/expected-screenshots/DashboardManager_create_new.png +++ b/plugins/Dashboard/tests/UI/expected-screenshots/DashboardManager_create_new.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e17ceb26b2b536e9a0f90eb78aed0681a38bd1748d569d3f0db003fcbf76cba9 -size 249197 +oid sha256:03a4cb2baeafcf12b51121737f80187f3a26dafb5bc4cc3df946c4c8f975d80f +size 247542 diff --git a/plugins/Dashboard/tests/UI/expected-screenshots/Dashboard_change_layout.png b/plugins/Dashboard/tests/UI/expected-screenshots/Dashboard_change_layout.png index 495e8a6c80..dceb3257f8 100644 --- a/plugins/Dashboard/tests/UI/expected-screenshots/Dashboard_change_layout.png +++ b/plugins/Dashboard/tests/UI/expected-screenshots/Dashboard_change_layout.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:595d831aa440d54ddd8a6a8cf4b8f731646dbc35846f22cde7f13cfa513c8d6f -size 29673 +oid sha256:26908474390de37b62d846f9a560c78286a8b0b431402a5a1c94e3006905adbd +size 28570 diff --git a/plugins/Installation/Controller.php b/plugins/Installation/Controller.php index 8dd65f6899..ee9160af07 100644 --- a/plugins/Installation/Controller.php +++ b/plugins/Installation/Controller.php @@ -26,6 +26,7 @@ use Piwik\Plugins\Diagnostics\DiagnosticService; use Piwik\Plugins\LanguagesManager\LanguagesManager; use Piwik\Plugins\SitesManager\API as APISitesManager; use Piwik\Plugins\UsersManager\API as APIUsersManager; +use Piwik\Plugins\UsersManager\UserUpdater; use Piwik\ProxyHeaders; use Piwik\SettingsPiwik; use Piwik\Tracker\TrackerCodeGenerator; @@ -680,11 +681,12 @@ class Controller extends \Piwik\Plugin\ControllerAdmin private function createSuperUser($login, $password, $email) { - $self = $this; - Access::doAsSuperUser(function () use ($self, $login, $password, $email) { + Access::doAsSuperUser(function () use ($login, $password, $email) { $api = APIUsersManager::getInstance(); $api->addUser($login, $password, $email); - $api->setSuperUserAccess($login, true); + + $userUpdater = new UserUpdater(); + $userUpdater->setSuperUserAccessWithoutCurrentPassword($login, true); }); } diff --git a/plugins/Login/tests/Integration/LoginTest.php b/plugins/Login/tests/Integration/LoginTest.php index 9f43512f0b..9ef38b17a9 100644 --- a/plugins/Login/tests/Integration/LoginTest.php +++ b/plugins/Login/tests/Integration/LoginTest.php @@ -15,6 +15,7 @@ use Piwik\DbHelper; use Piwik\NoAccessException; use Piwik\Plugins\Login\Auth; use Piwik\Plugins\UsersManager\API; +use Piwik\Plugins\UsersManager\UserUpdater; use Piwik\Tests\Framework\Mock\FakeAccess; use Piwik\Tests\Framework\TestCase\IntegrationTestCase; @@ -346,7 +347,8 @@ class LoginTest extends IntegrationTestCase private function _setUpSuperUserAccessViaDb() { - API::getInstance()->setSuperUserAccess('user', true); + $userUpdater = new UserUpdater(); + $userUpdater->setSuperUserAccessWithoutCurrentPassword('user', true); } private function authenticate($login, $tokenAuth) diff --git a/plugins/LoginLdap b/plugins/LoginLdap -Subproject c2de63df1887ec0409dceb5fa64f7fb735bce8e +Subproject 84b2d67b762ffbb66c26392c52acc7463534e0c diff --git a/plugins/TestRunner/Commands/TestsSetupFixture.php b/plugins/TestRunner/Commands/TestsSetupFixture.php index e97319b633..294a08c41c 100644 --- a/plugins/TestRunner/Commands/TestsSetupFixture.php +++ b/plugins/TestRunner/Commands/TestsSetupFixture.php @@ -10,6 +10,7 @@ namespace Piwik\Plugins\TestRunner\Commands; use Piwik\Application\Environment; use Piwik\Config; +use Piwik\Db; use Piwik\Plugin\ConsoleCommand; use Piwik\Tests\Framework\TestingEnvironmentManipulator; use Piwik\Tests\Framework\TestingEnvironmentVariables; @@ -113,7 +114,7 @@ class TestsSetupFixture extends ConsoleCommand $this->requireFixtureFiles($input); $this->setIncludePathAsInTestBootstrap(); - $host = Url::getHost(); + $host = Config::getHostname(); if (empty($host)) { $host = 'localhost'; Url::setHost('localhost'); diff --git a/plugins/TwoFactorAuth/tests/Fixtures/TwoFactorFixture.php b/plugins/TwoFactorAuth/tests/Fixtures/TwoFactorFixture.php index 37e2777214..3b71c0eba7 100644 --- a/plugins/TwoFactorAuth/tests/Fixtures/TwoFactorFixture.php +++ b/plugins/TwoFactorAuth/tests/Fixtures/TwoFactorFixture.php @@ -12,6 +12,7 @@ use Piwik\Date; use Piwik\Plugins\TwoFactorAuth\Dao\RecoveryCodeDao; use Piwik\Plugins\TwoFactorAuth\TwoFactorAuthentication; use Piwik\Plugins\UsersManager\Model; +use Piwik\Plugins\UsersManager\UserUpdater; use Piwik\Tests\Framework\Fixture; use Piwik\Plugins\UsersManager\API as UsersAPI; @@ -26,6 +27,7 @@ class TwoFactorFixture extends Fixture private $userWithout2Fa = 'without2FA'; private $userNo2Fa = 'no2FA'; private $userPassword = '123abcDk3_l3'; + private $superUserWith2Fa = 'superWith2FA'; const USER_2FA_SECRET = '1111111111111111'; @@ -68,6 +70,11 @@ class TwoFactorFixture extends Fixture public function setUpUsers() { + \Piwik\Plugins\UsersManager\API::getInstance()->addUser($this->superUserWith2Fa, $this->userPassword, + $this->superUserWith2Fa . '@matomo.org'); + $userUpdater = new UserUpdater(); + $userUpdater->setSuperUserAccessWithoutCurrentPassword($this->superUserWith2Fa, true); + foreach ([$this->userWith2Fa, $this->userWithout2Fa, $this->userWith2FaDisable, $this->userNo2Fa] as $user) { \Piwik\Plugins\UsersManager\API::getInstance()->addUser($user, $this->userPassword, $user . '@matomo.org'); // we cannot set superuser as logme won't work for super user @@ -79,7 +86,7 @@ class TwoFactorFixture extends Fixture } } - foreach ([$this->userWith2Fa, $this->userWith2FaDisable] as $user) { + foreach ([$this->userWith2Fa, $this->userWith2FaDisable, $this->superUserWith2Fa] as $user) { $this->dao->insertRecoveryCode($user, '123456'); $this->dao->insertRecoveryCode($user, '234567'); $this->dao->insertRecoveryCode($user, '345678'); diff --git a/plugins/TwoFactorAuth/tests/Integration/TwoFactorAuthTest.php b/plugins/TwoFactorAuth/tests/Integration/TwoFactorAuthTest.php index 2df336f491..07429e2916 100644 --- a/plugins/TwoFactorAuth/tests/Integration/TwoFactorAuthTest.php +++ b/plugins/TwoFactorAuth/tests/Integration/TwoFactorAuthTest.php @@ -15,6 +15,7 @@ use Piwik\Plugins\TwoFactorAuth\Dao\TwoFaSecretRandomGenerator; use Piwik\Plugins\TwoFactorAuth\SystemSettings; use Piwik\Plugins\TwoFactorAuth\TwoFactorAuthentication; use Piwik\Plugins\UsersManager\API; +use Piwik\Plugins\UsersManager\UserUpdater; use Piwik\Tests\Framework\TestCase\IntegrationTestCase; /** @@ -49,7 +50,8 @@ class TwoFactorAuthTest extends IntegrationTestCase foreach ([$this->userWith2Fa, $this->userWithout2Fa] as $user) { API::getInstance()->addUser($user, $this->userPassword, $user . '@matomo.org'); - API::getInstance()->setSuperUserAccess($user, 1); + $userUpdater = new UserUpdater(); + $userUpdater->setSuperUserAccessWithoutCurrentPassword($user, 1); } $this->dao = StaticContainer::get(RecoveryCodeDao::class); diff --git a/plugins/TwoFactorAuth/tests/UI/TwoFactorAuthUsersManager_spec.js b/plugins/TwoFactorAuth/tests/UI/TwoFactorAuthUsersManager_spec.js index 4e07f7cc97..4d5a405dbd 100644 --- a/plugins/TwoFactorAuth/tests/UI/TwoFactorAuthUsersManager_spec.js +++ b/plugins/TwoFactorAuth/tests/UI/TwoFactorAuthUsersManager_spec.js @@ -8,8 +8,6 @@ */ describe("TwoFactorAuthUsersManager", function () { - this.timeout(0); - this.fixture = "Piwik\\Plugins\\TwoFactorAuth\\tests\\Fixtures\\TwoFactorUsersManagerFixture"; var generalParams = 'idSite=1&period=day&date=2010-01-03', @@ -37,19 +35,21 @@ describe("TwoFactorAuthUsersManager", function () { await page.evaluate(function () { $('.userEditForm .menuUserTwoFa a').click(); }); + await page.waitFor(250); + await page.waitFor('.twofa-reset > p', { visible: true }); expect(await page.screenshotSelector('#content,#notificationContainer')).to.matchImage('edit_with_2fa'); }); it('should ask for confirmation before resetting 2fa', async function () { await page.click('.userEditForm .twofa-reset .resetTwoFa .btn'); - await page.waitFor(500); - const modal = await page.$('.modal.open'); + const modal = await page.waitFor('.modal.open', { visible: true }); + await page.waitFor(1000); // animation expect(await modal.screenshot()).to.matchImage('edit_with_2fa_reset_confirm'); }); it('should be possible to confirm the reset', async function () { await page.click('.twofa-confirm-modal .modal-close:not(.modal-no)'); - await page.waitFor(250); // wait for modal to close + await page.waitFor(500); // wait for modal to close expect(await page.screenshotSelector('#content,#notificationContainer')).to.matchImage('edit_with_2fa_reset_confirmed'); }); diff --git a/plugins/TwoFactorAuth/tests/UI/TwoFactorAuth_spec.js b/plugins/TwoFactorAuth/tests/UI/TwoFactorAuth_spec.js index 5e216d793d..8b702b230f 100644 --- a/plugins/TwoFactorAuth/tests/UI/TwoFactorAuth_spec.js +++ b/plugins/TwoFactorAuth/tests/UI/TwoFactorAuth_spec.js @@ -19,7 +19,7 @@ describe("TwoFactorAuth", function () { async function selectModalButton(button) { - await page.click('.modal.open .modal-footer a:contains('+button+')'); + await (await page.jQuery('.modal.open .modal-footer a:contains('+button+')')).click(); } async function loginUser(username, doAuth) @@ -70,11 +70,13 @@ describe("TwoFactorAuth", function () { async function confirmPassword() { + await page.waitFor('.confirmPasswordForm'); await page.evaluate(function(){ $('.confirmPasswordForm #login_form_password').val('123abcDk3_l3'); $('.confirmPasswordForm #login_form_submit').click(); }); - await page.waitFor(750); + await page.waitForNetworkIdle(); + await page.waitFor(100); } it('a user with 2fa can open the widgetized view by token without needing to verify', async function () { @@ -86,7 +88,7 @@ describe("TwoFactorAuth", function () { await loginUser('with2FA', false); expect(await page.screenshotSelector('.loginSection')).to.matchImage('logme_not_verified'); }); -return; + it('when logging in and providing wrong code an error is shown', async function () { await page.type('.loginTwoFaForm #login_form_authcode', '555555'); await page.evaluate(function(){ @@ -101,14 +103,18 @@ return; await page.evaluate(function(){ $('.loginTwoFaForm #login_form_submit').click(); }); - await page.waitFor(1500); - expect(await page.screenshotSelector('#content')).to.matchImage('logme_verified'); + await page.waitForNetworkIdle(); + await page.waitFor('.widget'); + expect(await page.screenshotSelector('.pageWrap')).to.matchImage('logme_verified'); }); it('should show user settings when two-fa enabled', async function () { await loginUser('with2FA'); await page.goto(userSettings); - expect(await page.screenshotSelector('.userSettings2FA')).to.matchImage('usersettings_twofa_enabled'); + await page.waitFor('.userSettings2FA', { visible: true }); + await page.waitFor(500); // animation + const elem = await page.$('.userSettings2FA'); + expect(await elem.screenshot()).to.matchImage('usersettings_twofa_enabled'); }); it('should be possible to show recovery codes step1 authentication', async function () { @@ -145,7 +151,9 @@ return; it('should be possible to disable two factor step 3 verified', async function () { await confirmPassword(); - expect(await page.screenshotSelector('.userSettings2FA')).to.matchImage('usersettings_twofa_disable_step3'); + await page.waitFor('.userSettings2FA'); + const elem = await page.$('.userSettings2FA'); + expect(await elem.screenshot()).to.matchImage('usersettings_twofa_disable_step3'); }); it('should show setup screen - step 1', async function () { @@ -157,21 +165,15 @@ return; }); it('should move to second step in setup - step 2', async function () { - console.log('start'); await page.evaluate(function(){ $('.setupTwoFactorAuthentication .backupRecoveryCode:first').click(); }); - console.log(0); await page.waitForNetworkIdle(); - console.log(1); await page.click('.setupTwoFactorAuthentication .goToStep2'); - console.log(2); await page.waitForNetworkIdle(); - console.log(3); await page.evaluate(function () { $('#qrcode').hide(); }); - console.log(4); expect(await page.screenshotSelector('#content')).to.matchImage('twofa_setup_step2'); }); @@ -190,6 +192,9 @@ return; await page.evaluate(function () { $('.setupConfirmAuthCodeForm .confirmAuthCode').click(); }); + await page.waitForNetworkIdle(); + await page.waitFor('.widget', { visible: true }); + await page.waitForNetworkIdle(); expect(await page.screenshotSelector('#content')).to.matchImage('twofa_setup_step4'); }); @@ -220,6 +225,7 @@ return; await page.evaluate(function () { $('.setupConfirmAuthCodeForm .confirmAuthCode').click(); }); + await page.waitForNetworkIdle(); expect(await page.screenshotSelector('.loginSection,#content,#notificationContainer')).to.matchImage('twofa_forced_step4'); }); diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuthUsersManager_edit_with_2fa_reset_confirmed.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuthUsersManager_edit_with_2fa_reset_confirmed.png index 631b48a8e7..820faa151d 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuthUsersManager_edit_with_2fa_reset_confirmed.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuthUsersManager_edit_with_2fa_reset_confirmed.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e51ce8c2d7cf9e6e81b84e89e83a0f6a453196102265b52da8be1eac7aa13b83 -size 28365 +oid sha256:99b7384aaf0b2a6c63fdda6611b323883bc735ecebd29e6f181f07d16a724fce +size 30075 diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuthUsersManager_list.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuthUsersManager_list.png index dd1ee87fdd..1a7af9b184 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuthUsersManager_list.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuthUsersManager_list.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7b94002780dbc44e7382858defa946a81fe67239ea2deccfeeb75217de7aa71f -size 53075 +oid sha256:baac8634397639a2ad11797e1390d5ed467ec1fe11a1c14dbe0033f78e67dbb0 +size 58717 diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_logme_not_verified_wrong_code.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_logme_not_verified_wrong_code.png index 6409ebc3c6..613960079c 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_logme_not_verified_wrong_code.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_logme_not_verified_wrong_code.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:69c1dbbf415620f8d133bfd5894d5e698a732f5f82aa3aa90d3a142f14b03c0d -size 49008 +oid sha256:7b830596d955d1db652a5877e1591e616dd611d9422dad8475271ae175964833 +size 49340 diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_logme_verified.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_logme_verified.png index db5c9c5d34..26f8a16927 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_logme_verified.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_logme_verified.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:432d04719b40530913c1c0230d3a36c98a7d04f76977ff5f4795055f3b0d395d -size 139500 +oid sha256:276d31c54153cd889f9ff5a7095c0ba0311a75f4d15a3579653e3379e4730943 +size 137776 diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_show_recovery_codes_step1.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_show_recovery_codes_step1.png index 5a439faa51..d511b3665a 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_show_recovery_codes_step1.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_show_recovery_codes_step1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b6d5c8f0591b7c3455ec903881f1f0466b6b63029f2a950d83a7a2f51d304a7a -size 13390 +oid sha256:bf4e7b2dd1d68df9db0826eb9051f796bf3c25426659a9e84792ae4879835f17 +size 13422 diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_show_recovery_codes_step2.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_show_recovery_codes_step2.png index 1fe16418ca..7a0f177274 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_show_recovery_codes_step2.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_show_recovery_codes_step2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:80a3c4babfdfbf6040181cdf4d7059502d3af8df0c0572a16f17cda3e852dc22 -size 63846 +oid sha256:9c10cc5cb40f56bd3a71513c262d91d99a474ff8f975ea67ad24ee1bb8ead0a9 +size 60823 diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_forced_step1.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_forced_step1.png index 40e3aad93f..07e63fa139 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_forced_step1.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_forced_step1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:750bbc270525ea990e3a541b7d4ce5e819aefe1a05e937dd538af5d2cec34178 -size 103348 +oid sha256:db93961069bfc3e3fb3f2fb7204921eb835545c2ce7535b068f5502474822591 +size 93376 diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_forced_step4.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_forced_step4.png index db5c9c5d34..07e63fa139 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_forced_step4.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_forced_step4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:432d04719b40530913c1c0230d3a36c98a7d04f76977ff5f4795055f3b0d395d -size 139500 +oid sha256:db93961069bfc3e3fb3f2fb7204921eb835545c2ce7535b068f5502474822591 +size 93376 diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_setup_step1.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_setup_step1.png index 2b525ac946..bab5330078 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_setup_step1.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_setup_step1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d0bc9e697dff2fd9f91451a033ba778c3742e397c2d6f934a8a6b780fa5f02aa -size 74454 +oid sha256:66a49cb6fc2e73a20ac31e54911199f3b3c8646bea27c43c66b2597f73c249ed +size 67812 diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_setup_step2.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_setup_step2.png index 474486f7df..239a6747b4 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_setup_step2.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_setup_step2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f5a3d9c0bf5c0cacfbcf1b7062a9741a5f2b3cbe093448dd3ffac81202c84f3b -size 93330 +oid sha256:7816b91a497e36536fcae8c6a361ea5b1e1ddce8c03361746de5e5e06b947a40 +size 86881 diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_setup_step3.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_setup_step3.png index 6960b50d5b..e53a9cbd52 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_setup_step3.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_twofa_setup_step3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ea30e34f67d85fad191e90f6d10f63275bd243a7357b020e9875babd1a2e2f47 -size 121508 +oid sha256:428605cbed55a690c110dd4db5c863b352d55a9add141e565398f1e7d728239e +size 115196 diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_disable_step1.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_disable_step1.png index 95fcf8073c..2fb49cb840 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_disable_step1.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_disable_step1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:035f9173979d5650c2ae6dbca4a19c80601b62c4f984c2be912b03cdf57e304a -size 21734 +oid sha256:bdd3ba9255f3e954c863fcb73e3437e8e1fcc80aa54279f67a07375d4d2021a7 +size 14250 diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_disable_step2.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_disable_step2.png index a98ade64c8..d511b3665a 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_disable_step2.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_disable_step2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9dddb94c30224362115ae13ebd5170c96caa80be88b18583f7920e0fd213117a -size 15127 +oid sha256:bf4e7b2dd1d68df9db0826eb9051f796bf3c25426659a9e84792ae4879835f17 +size 13422 diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_disable_step3.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_disable_step3.png index 0418149865..b3b8979820 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_disable_step3.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_disable_step3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8af9fbcce1498486fd7f42bf18bed791db6dc49e9fb5e9f94f21ea31ab105383 -size 45375 +oid sha256:d81de0a72d903346c4525603144ba753c40a76c3beb90031978226dc6f9fdd06 +size 43691 diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_enabled.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_enabled.png index 8d7197e95b..98a68ce59f 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_enabled.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_enabled.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d11dc17a3b0d891e8dbee1734ec31ff22230d71aa0bedab23f4389e0bb8e8e1e -size 46583 +oid sha256:34c0c73879e1a8ba3a300ba70f7dcf3b07f4713e6a411e8ca3217f38d24eb3eb +size 46631 diff --git a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_enabled_required.png b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_enabled_required.png index 2639572760..b7f9641396 100644 --- a/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_enabled_required.png +++ b/plugins/TwoFactorAuth/tests/UI/expected-screenshots/TwoFactorAuth_usersettings_twofa_enabled_required.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d6bba78762b389d8902269840b1bb590918c7bbfe17ec62f452e19411a268fc -size 52910 +oid sha256:1c6bc6770a97cd4b571f1fae0a2d21a2c43d01c302eb8f4e3d5fc170b40a9b50 +size 51621 diff --git a/plugins/UsersManager/API.php b/plugins/UsersManager/API.php index fb3fa2e3c6..2696c9ffe2 100644 --- a/plugins/UsersManager/API.php +++ b/plugins/UsersManager/API.php @@ -48,6 +48,7 @@ class API extends \Piwik\Plugin\API const OPTION_NAME_PREFERENCE_SEPARATOR = '_'; public static $UPDATE_USER_REQUIRE_PASSWORD_CONFIRMATION = true; + public static $SET_SUPERUSER_ACCESS_REQUIRE_PASSWORD_CONFIRMATION = true; /** * @var Model @@ -701,12 +702,23 @@ class API extends \Piwik\Plugin\API * @param string $userLogin the user login. * @param bool|int $hasSuperUserAccess true or '1' to grant Super User access, false or '0' to remove Super User * access. + * @param string $passwordConfirmation the current user's password. * @throws \Exception */ - public function setSuperUserAccess($userLogin, $hasSuperUserAccess) + public function setSuperUserAccess($userLogin, $hasSuperUserAccess, $passwordConfirmation = null) { Piwik::checkUserHasSuperUserAccess(); $this->checkUserIsNotAnonymous($userLogin); + + $requirePasswordConfirmation = self::$SET_SUPERUSER_ACCESS_REQUIRE_PASSWORD_CONFIRMATION; + self::$SET_SUPERUSER_ACCESS_REQUIRE_PASSWORD_CONFIRMATION = true; + + $isCliMode = Common::isPhpCliMode() && !(defined('PIWIK_TEST_MODE') && PIWIK_TEST_MODE); + if (!$isCliMode + && $requirePasswordConfirmation + ) { + $this->confirmCurrentUserPassword($passwordConfirmation); + } $this->checkUserExists($userLogin); if (!$hasSuperUserAccess && $this->isUserTheOnlyUserHavingSuperUserAccess($userLogin)) { @@ -853,9 +865,10 @@ class API extends \Piwik\Plugin\API $_isPasswordHashed = false, $passwordConfirmation = false) { $requirePasswordConfirmation = self::$UPDATE_USER_REQUIRE_PASSWORD_CONFIRMATION; - $isEmailNotificationOnInConfig = Config::getInstance()->General['enable_update_users_email']; self::$UPDATE_USER_REQUIRE_PASSWORD_CONFIRMATION = true; + $isEmailNotificationOnInConfig = Config::getInstance()->General['enable_update_users_email']; + Piwik::checkUserHasSuperUserAccessOrIsTheUser($userLogin); $this->checkUserIsNotAnonymous($userLogin); $this->checkUserExists($userLogin); @@ -901,16 +914,7 @@ class API extends \Piwik\Plugin\API } if ($changeShouldRequirePasswordConfirmation && $requirePasswordConfirmation) { - if (empty($passwordConfirmation)) { - throw new Exception(Piwik::translate('UsersManager_ConfirmWithPassword')); - } - - $passwordConfirmation = Common::unsanitizeInputValue($passwordConfirmation); - - $loginCurrentUser = Piwik::getCurrentUserLogin(); - if (!$this->passwordVerifier->isPasswordCorrect($loginCurrentUser, $passwordConfirmation)) { - throw new Exception(Piwik::translate('UsersManager_CurrentPasswordNotCorrect')); - } + $this->confirmCurrentUserPassword($passwordConfirmation); } $alias = $this->getCleanAlias($alias, $userLogin); @@ -1392,6 +1396,20 @@ class API extends \Piwik\Plugin\API return [$roles, $capabilities]; } + private function confirmCurrentUserPassword($passwordConfirmation) + { + if (empty($passwordConfirmation)) { + throw new Exception(Piwik::translate('UsersManager_ConfirmWithPassword')); + } + + $passwordConfirmation = Common::unsanitizeInputValue($passwordConfirmation); + + $loginCurrentUser = Piwik::getCurrentUserLogin(); + if (!$this->passwordVerifier->isPasswordCorrect($loginCurrentUser, $passwordConfirmation)) { + throw new Exception(Piwik::translate('UsersManager_CurrentPasswordNotCorrect')); + } + } + private function sendEmailChangedEmail($user, $newEmail) { // send the mail to both the old email and the new email diff --git a/plugins/UsersManager/UserUpdater.php b/plugins/UsersManager/UserUpdater.php index 87d748a6dd..4d49b5a50f 100644 --- a/plugins/UsersManager/UserUpdater.php +++ b/plugins/UsersManager/UserUpdater.php @@ -41,4 +41,16 @@ class UserUpdater } } + public function setSuperUserAccessWithoutCurrentPassword($userLogin, $hasSuperUserAccess) + { + API::$SET_SUPERUSER_ACCESS_REQUIRE_PASSWORD_CONFIRMATION = false; + try { + Request::processRequest('UsersManager.setSuperUserAccess', [ + 'userLogin' => $userLogin, + 'hasSuperUserAccess' => $hasSuperUserAccess, + ], $default = []); + } finally { + API::$SET_SUPERUSER_ACCESS_REQUIRE_PASSWORD_CONFIRMATION = true; + } + } }
\ No newline at end of file diff --git a/plugins/UsersManager/angularjs/user-edit-form/user-edit-form.component.html b/plugins/UsersManager/angularjs/user-edit-form/user-edit-form.component.html index a92fbd4b95..8c831c87c5 100644 --- a/plugins/UsersManager/angularjs/user-edit-form/user-edit-form.component.html +++ b/plugins/UsersManager/angularjs/user-edit-form/user-edit-form.component.html @@ -4,6 +4,7 @@ class="userEditForm" ng-class="{ loading: $ctrl.isSavingUserInfo }" > + <div class="row" piwik-form> <div class="col m2 entityList" ng-if="!$ctrl.isAdd"> <ul class="listCircle"> @@ -98,8 +99,8 @@ <div ng-if="!$ctrl.isAdd" ng-show="$ctrl.activeTab === 'permissions'" class="user-permissions"> <piwik-user-permissions-edit - user-login="$ctrl.user.login" ng-if="!$ctrl.user.superuser_access" + user-login="$ctrl.user.login" on-user-has-access-detected="$ctrl.userHasAccess = hasAccess" on-access-change="$ctrl.isUserModified = true" access-levels="$ctrl.accessLevels" @@ -120,7 +121,7 @@ piwik-field uicontrol="checkbox" name="superuser_access" - ng-model="$ctrl.user.superuser_access" + ng-model="$ctrl.superUserAccessChecked" ng-attr-title="{{:: 'UsersManager_HasSuperUserAccess'|translate }}" ng-click="$ctrl.confirmSuperUserChange()" data-disabled="$ctrl.isSavingUserInfo" @@ -130,21 +131,28 @@ <div class="superuser-confirm-modal modal"> <div class="modal-content"> <h2>{{:: 'UsersManager_AreYouSure'|translate }}</h2> - <p ng-if="!$ctrl.user.superuser_access"> + <p ng-if="$ctrl.user.superuser_access"> {{:: 'UsersManager_RemoveSuperuserAccessConfirm'|translate }} </p> - <p ng-if="$ctrl.user.superuser_access"> + <p ng-if="!$ctrl.user.superuser_access"> {{:: 'UsersManager_AddSuperuserAccessConfirm'|translate }} </p> + + <div piwik-field uicontrol="password" name="currentUserPasswordForSuperUser" autocomplete="off" + ng-model="$ctrl.passwordConfirmationForSuperUser" + full-width="true" + title="{{ 'UsersManager_YourCurrentPassword'|translate }}" + value=""> + </div> </div> <div class="modal-footer"> <a href="" class="modal-action modal-close btn" ng-click="$ctrl.toggleSuperuserAccess()">{{:: 'General_Yes'|translate }}</a> - <a href="" class="modal-action modal-close modal-no" ng-click="$ctrl.user.superuser_access = !$ctrl.user.superuser_access">{{:: 'General_No'|translate }}</a> + <a href="" class="modal-action modal-close modal-no" ng-click="$ctrl.setSuperUserAccessChecked()">{{:: 'General_No'|translate }}</a> </div> </div> </div> - <div ng-if="$ctrl.activeTab === '2fa' && $ctrl.currentUserRole == 'superuser' && !$ctrl.isAdd" class="twofa-reset"> + <div ng-show="$ctrl.activeTab === '2fa'" ng-if="$ctrl.currentUserRole == 'superuser' && !$ctrl.isAdd" class="twofa-reset"> <p>{{:: 'UsersManager_ResetTwoFactorAuthenticationInfo'|translate }}</p> <div piwik-save-button @@ -168,6 +176,7 @@ </div> </div> + <div class="change-password-modal modal"> <div class="modal-content"> <h2 piwik-translate="UsersManager_AreYouSureChangeDetails"><strong>{{ $ctrl.user.login }}</strong></h2> @@ -185,4 +194,5 @@ <a href="" class="modal-action modal-close modal-no">{{:: 'General_No'|translate }}</a> </div> </div> -</div> + +</div>
\ No newline at end of file diff --git a/plugins/UsersManager/angularjs/user-edit-form/user-edit-form.component.js b/plugins/UsersManager/angularjs/user-edit-form/user-edit-form.component.js index bb929d5749..852469dbc1 100644 --- a/plugins/UsersManager/angularjs/user-edit-form/user-edit-form.component.js +++ b/plugins/UsersManager/angularjs/user-edit-form/user-edit-form.component.js @@ -46,6 +46,7 @@ vm.saveUserInfo = saveUserInfo; vm.reset2FA = reset2FA; vm.updateUser = updateUser; + vm.setSuperUserAccessChecked = setSuperUserAccessChecked; function $onInit() { vm.firstSiteAccess = { @@ -65,6 +66,8 @@ if (!vm.isAdd) { vm.user.password = 'XXXXXXXX'; // make sure password is not stored in the client after update/save } + + setSuperUserAccessChecked(); } function getFormTitle() { @@ -105,15 +108,24 @@ method: 'UsersManager.setSuperUserAccess' }, { userLogin: vm.user.login, - hasSuperUserAccess: vm.user.superuser_access ? '1' : '0' + hasSuperUserAccess: vm.user.superuser_access ? '0' : '1', + passwordConfirmation: vm.passwordConfirmationForSuperUser, + }).then(function () { + vm.user.superuser_access = !vm.user.superuser_access; }).catch(function () { // ignore error (still displayed to user) }).then(function () { vm.isSavingUserInfo = false; vm.isUserModified = true; + vm.passwordConfirmationForSuperUser = null; + setSuperUserAccessChecked(); }); } + function setSuperUserAccessChecked() { + vm.superUserAccessChecked = !! vm.user.superuser_access; + } + function saveUserInfo() { if (vm.isAdd) { createUser(); diff --git a/plugins/UsersManager/lang/en.json b/plugins/UsersManager/lang/en.json index 69179b7cf5..866b52567a 100644 --- a/plugins/UsersManager/lang/en.json +++ b/plugins/UsersManager/lang/en.json @@ -127,8 +127,8 @@ "SuperUserIntro2": "Please use this feature carefully.", "HasSuperUserAccess": "Has Superuser Access", "AreYouSure": "Are you sure?", - "RemoveSuperuserAccessConfirm": "Removing superuser access will leave the user with no permissions (you will have to add them afterwards). Do you wish to continue?", - "AddSuperuserAccessConfirm": "Giving a user superuser access will allow the user to have full control over Matomo and should be done sparingly. Do you wish to continue?", + "RemoveSuperuserAccessConfirm": "Removing superuser access will leave the user with no permissions (you will have to add them afterwards). Enter your password to continue.", + "AddSuperuserAccessConfirm": "Giving a user superuser access will allow the user to have full control over Matomo and should be done sparingly. Enter your password to continue.", "DeleteUsers": "Delete Users", "UserSearch": "User search", "FilterByAccess": "Filter by access", diff --git a/plugins/UsersManager/tests/Fixtures/ManyUsers.php b/plugins/UsersManager/tests/Fixtures/ManyUsers.php index 13a998e456..1382a55fd2 100644 --- a/plugins/UsersManager/tests/Fixtures/ManyUsers.php +++ b/plugins/UsersManager/tests/Fixtures/ManyUsers.php @@ -9,6 +9,7 @@ namespace Piwik\Plugins\UsersManager\tests\Fixtures; use Piwik\Plugins\UsersManager\API; use Piwik\Plugins\UsersManager\Model; +use Piwik\Plugins\UsersManager\UserUpdater; use Piwik\Tests\Framework\Fixture; /** @@ -121,7 +122,8 @@ class ManyUsers extends Fixture } if ($access == 'superuser') { - $api->setSuperUserAccess($login, true); + $userUpdater = new UserUpdater(); + $userUpdater->setSuperUserAccessWithoutCurrentPassword($login, true); } else { $api->setUserAccess($login, $access, $idSites); } diff --git a/plugins/UsersManager/tests/Integration/APITest.php b/plugins/UsersManager/tests/Integration/APITest.php index a512660e6b..27c83ec306 100644 --- a/plugins/UsersManager/tests/Integration/APITest.php +++ b/plugins/UsersManager/tests/Integration/APITest.php @@ -20,6 +20,7 @@ use Piwik\Plugins\SitesManager\API as SitesManagerAPI; use Piwik\Plugins\UsersManager\API; use Piwik\Plugins\UsersManager\Model; use Piwik\Plugins\UsersManager\UsersManager; +use Piwik\Plugins\UsersManager\UserUpdater; use Piwik\Tests\Framework\Fixture; use Piwik\Tests\Framework\Mock\FakeAccess; use Piwik\Tests\Framework\TestCase\IntegrationTestCase; @@ -381,7 +382,8 @@ class APITest extends IntegrationTestCase $access = $this->api->getSitesAccessFromUser($user2); $this->assertEmpty($access); - $this->api->setSuperUserAccess($user2, true); + $userUpdater = new UserUpdater(); + $userUpdater->setSuperUserAccessWithoutCurrentPassword($user2, true); // super user has admin access for every site $access = $this->api->getSitesAccessFromUser($user2); @@ -546,7 +548,8 @@ class APITest extends IntegrationTestCase public function test_getUsersPlusRole_shouldSearchForSuperUsersCorrectly() { $this->addUserWithAccess('userLogin2', 'admin', 1); - $this->api->setSuperUserAccess('userLogin2', true); + $userUpdater = new UserUpdater(); + $userUpdater->setSuperUserAccessWithoutCurrentPassword('userLogin2', true); $this->addUserWithAccess('userLogin3', 'view', 1); $this->addUserWithAccess('userLogin4', 'superuser', 1); $this->addUserWithAccess('userLogin5', null, 1); @@ -983,6 +986,15 @@ class APITest extends IntegrationTestCase $this->assertEquals(array(View::ID, TestCap1::ID), $access); } + /** + * @expectedException \Exception + * @expectedExceptionMessage abc + */ + public function test_setSuperUserAccess_failsIfCurrentPasswordIsIncorrect() + { + $this->api->setSuperUserAccess($this->login, true, 'asldfkjds'); + } + private function getAccessInSite($login, $idSite) { $access = $this->model->getSitesAccessFromUser($login); @@ -1018,7 +1030,8 @@ class APITest extends IntegrationTestCase { $this->api->addUser($username, 'password', $email ?: "$username@password.de", $alias); if ($accessLevel == 'superuser') { - $this->api->setSuperUserAccess($username, true); + $userUpdater = new UserUpdater(); + $userUpdater->setSuperUserAccessWithoutCurrentPassword($username, true); } else if ($accessLevel) { $this->api->setUserAccess($username, $accessLevel, $idSite); } diff --git a/plugins/UsersManager/tests/Integration/UsersManagerTest.php b/plugins/UsersManager/tests/Integration/UsersManagerTest.php index abaf5d6590..43d4bbb5ee 100644 --- a/plugins/UsersManager/tests/Integration/UsersManagerTest.php +++ b/plugins/UsersManager/tests/Integration/UsersManagerTest.php @@ -10,10 +10,12 @@ namespace Piwik\Plugins\UsersManager\tests\Integration; use Piwik\Access; use Piwik\Auth\Password; +use Piwik\Common; use Piwik\Plugins\SitesManager\API as APISitesManager; use Piwik\Plugins\UsersManager\API; use Piwik\Plugins\UsersManager\Model; use Piwik\Plugins\UsersManager\UsersManager; +use Piwik\Plugins\UsersManager\UserUpdater; use Piwik\Tests\Framework\Fixture; use Piwik\Tests\Framework\Mock\FakeAccess; use Piwik\Tests\Framework\TestCase\IntegrationTestCase; @@ -380,7 +382,8 @@ class UsersManagerTest extends IntegrationTestCase //add user and set some rights $this->api->addUser("regularuser", "geqgeagae1", "test1@test.com", "alias1"); $this->api->addUser("superuser", "geqgeagae2", "test2@test.com", "alias2"); - $this->api->setSuperUserAccess('superuser', true); + $userUpdater = new UserUpdater(); + $userUpdater->setSuperUserAccessWithoutCurrentPassword('superuser', true); // delete the user $this->api->deleteUser("superuser"); @@ -604,7 +607,8 @@ class UsersManagerTest extends IntegrationTestCase public function testSetUserAccess_ShouldFail_IfLoginIsUserWithSuperUserAccess() { $this->api->addUser("gegg4564eqgeqag", "geqgegagae", "tegst@tesgt.com", "alias"); - $this->api->setSuperUserAccess('gegg4564eqgeqag', true); + $userUpdater = new UserUpdater(); + $userUpdater->setSuperUserAccessWithoutCurrentPassword('gegg4564eqgeqag', true); FakeAccess::clearAccess($superUser = false, $idSitesAdmin = array(1)); $this->api->setUserAccess('gegg4564eqgeqag', 'view', 1); @@ -806,8 +810,10 @@ class UsersManagerTest extends IntegrationTestCase */ public function testSetSuperUserAccess_ShouldFail_IfUserHasNotSuperUserPermission() { + $pwd = $this->createCurrentUser(); + FakeAccess::$superUser= false; - $this->api->setSuperUserAccess('nologin', false); + $this->api->setSuperUserAccess('nologin', false, $pwd); } /** @@ -816,7 +822,8 @@ class UsersManagerTest extends IntegrationTestCase */ public function testSetSuperUserAccess_ShouldFail_IfUserWithGivenLoginDoesNotExist() { - $this->api->setSuperUserAccess('nologin', false); + $pwd = $this->createCurrentUser(); + $this->api->setSuperUserAccess('nologin', false, $pwd); } /** @@ -825,7 +832,8 @@ class UsersManagerTest extends IntegrationTestCase */ public function testSetSuperUserAccess_ShouldFail_IfUserIsAnonymous() { - $this->api->setSuperUserAccess('anonymous', true); + $pwd = $this->createCurrentUser(); + $this->api->setSuperUserAccess('anonymous', true, $pwd); } /** @@ -834,14 +842,18 @@ class UsersManagerTest extends IntegrationTestCase */ public function testSetSuperUserAccess_ShouldFail_IfUserIsOnlyRemainingUserWithSuperUserAccess() { + $pwd = $this->createCurrentUser(); + $this->api->addUser('login1', 'password1', 'test@example.com', false); - $this->api->setSuperUserAccess('login1', true); + $this->api->setSuperUserAccess('login1', true, $pwd); - $this->api->setSuperUserAccess('login1', false); + $this->api->setSuperUserAccess('login1', false, $pwd); } public function testSetSuperUserAccess_ShouldDeleteAllExistingAccessEntries() { + $pwd = $this->createCurrentUser(); + list($id1, $id2) = $this->addSites(2); $this->api->addUser('login1', 'password1', 'test@example.com', false); $this->api->setUserAccess('login1', 'view', array($id1)); @@ -851,7 +863,7 @@ class UsersManagerTest extends IntegrationTestCase $access = $this->_flatten($this->api->getSitesAccessFromUser('login1')); $this->assertEquals(array($id1 => 'view', $id2 => 'admin'), $access); - $this->api->setSuperUserAccess('login1', true); + $this->api->setSuperUserAccess('login1', true, $pwd); // verify no longer any access $this->assertEquals(array(), $this->model->getSitesAccessFromUser('login1')); @@ -859,11 +871,13 @@ class UsersManagerTest extends IntegrationTestCase public function testSetSuperUserAccess_ShouldAddAndRemoveSuperUserAccessOnlyForGivenLogin() { + $pwd = $this->createCurrentUser(); + $this->api->addUser('login1', 'password1', 'test1@example.com', false); $this->api->addUser('login2', 'password2', 'test2@example.com', false); $this->api->addUser('login3', 'password3', 'test3@example.com', false); - $this->api->setSuperUserAccess('login2', true); + $this->api->setSuperUserAccess('login2', true, $pwd); // test add Super User access $users = $this->api->getUsers(); @@ -874,9 +888,9 @@ class UsersManagerTest extends IntegrationTestCase $this->assertEquals(0, $users[2]['superuser_access']); // should also accept string '1' to add Super User access - $this->api->setSuperUserAccess('login1', '1'); + $this->api->setSuperUserAccess('login1', '1', $pwd); // test remove Super User access - $this->api->setSuperUserAccess('login2', false); + $this->api->setSuperUserAccess('login2', false, $pwd); $users = $this->api->getUsers(); $this->assertEquals(1, $users[0]['superuser_access']); @@ -884,9 +898,9 @@ class UsersManagerTest extends IntegrationTestCase $this->assertEquals(0, $users[1]['superuser_access']); $this->assertEquals(0, $users[2]['superuser_access']); - $this->api->setSuperUserAccess('login3', true); + $this->api->setSuperUserAccess('login3', true, $pwd); // should also accept string '0' to remove Super User access - $this->api->setSuperUserAccess('login1', '0'); + $this->api->setSuperUserAccess('login1', '0', $pwd); $users = $this->api->getUsers(); $this->assertEquals(0, $users[0]['superuser_access']); @@ -1203,4 +1217,20 @@ class UsersManagerTest extends IntegrationTestCase $this->assertRegExp("(UsersManager_ExceptionUserDoesNotExist)", $expected->getMessage()); } } + + private function createCurrentUser() + { + $identity = FakeAccess::$identity; + FakeAccess::$identity = 'lskfjs'; + + $pwd = 'testpwd'; + + try { + $this->api->addUser($identity, $pwd, 'someuser@email.com'); + } finally { + FakeAccess::$identity = $identity; + } + + return $pwd; + } } diff --git a/plugins/UsersManager/tests/UI/UsersManager_spec.js b/plugins/UsersManager/tests/UI/UsersManager_spec.js index 6a7482ba5d..9ba0556c3e 100644 --- a/plugins/UsersManager/tests/UI/UsersManager_spec.js +++ b/plugins/UsersManager/tests/UI/UsersManager_spec.js @@ -74,9 +74,9 @@ describe("UsersManager", function () { }); it('should select rows when individual row select is clicked', async function () { - await (await page.jQuery('td.select-cell label:eq(0)')).click(); - await (await page.jQuery('td.select-cell label:eq(3)')).click(); - await (await page.jQuery('td.select-cell label:eq(8)')).click(); + await (await page.jQuery('td.select-cell label:eq(0)', { waitFor: true })).click(); + await (await page.jQuery('td.select-cell label:eq(3)', { waitFor: true })).click(); + await (await page.jQuery('td.select-cell label:eq(8)', { waitFor: true })).click(); await page.mouse.move(0, 0); await page.waitFor(500); // for checkbox animations @@ -116,7 +116,7 @@ describe("UsersManager", function () { await page.click('.toggle-select-all-in-search'); // reselect all in search await page.click('.bulk-actions.btn'); - await (await page.jQuery('#user-list-bulk-actions>li:first')).hover(); + await (await page.jQuery('#user-list-bulk-actions>li:first > a')).hover(); await (await page.jQuery('#bulk-set-access a:contains(Admin)')).click(); await page.waitFor(350); // wait for animation @@ -231,7 +231,7 @@ describe("UsersManager", function () { it('should add access to all websites when bulk access is used on all websites in search', async function () { await page.click('.userPermissionsEdit .bulk-actions > .dropdown-trigger.btn'); - await (await page.jQuery('#user-permissions-edit-bulk-actions>li:first')).hover(); + await (await page.jQuery('#user-permissions-edit-bulk-actions>li:first>a')).hover(); await (await page.jQuery('#user-permissions-edit-bulk-actions a:contains(Write)')).click(); await page.waitFor('.change-access-confirm-modal', { visible: true }); @@ -277,7 +277,7 @@ describe("UsersManager", function () { it('should set access to selected sites when set bulk access is used', async function () { await page.click('.userPermissionsEdit .bulk-actions > .dropdown-trigger.btn'); await page.waitFor(250); // animation - await (await page.jQuery('#user-permissions-edit-bulk-actions>li:first:visible', { waitFor: true })).hover(); + await page.evaluate(() => $('#user-permissions-edit-bulk-actions>li:first > a:visible').mouseenter()); await page.waitFor(250); // animation await (await page.jQuery('#user-permissions-edit-bulk-actions a:contains(Admin):visible', { waitFor: true })).click(); @@ -291,11 +291,12 @@ describe("UsersManager", function () { }); it('should filter the permissions when the filters are used', async function () { - await page.type('div.site-filter>input', 'nova'); await page.evaluate(function () { - $('.access-filter select').val('string:admin').change(); + $('.userPermissionsEdit .access-filter select').val('string:admin').change(); }); await page.waitForNetworkIdle(); + await page.type('.userPermissionsEdit div.site-filter>input', 'hunter'); + await page.waitForNetworkIdle(); await page.waitFor('#sitesForPermission tr', { visible: true }); await page.waitFor(1000); @@ -311,18 +312,20 @@ describe("UsersManager", function () { it('should set access to all sites selected when set bulk access is used', async function () { await page.click('.userPermissionsEdit .bulk-actions > .dropdown-trigger.btn'); - await page.waitFor(100); // animation - await (await page.jQuery('#user-permissions-edit-bulk-actions>li:first', { waitFor: true })).hover(); - await page.waitFor(100); // animation + await page.waitFor(250); // animation + await page.evaluate(() => $('#user-permissions-edit-bulk-actions>li:first > a:visible').mouseenter()); + await page.waitFor(250); // animation await (await page.jQuery('#user-permissions-edit-bulk-actions a:contains(View)', { waitFor: true })).click(); await page.waitFor(250); // animation await page.evaluate(() => $('.change-access-confirm-modal .modal-close:not(.modal-no):visible').click()); + await page.waitForNetworkIdle(); await page.evaluate(function () { // remove filter $('.access-filter select').val('string:some').change(); }); await page.waitForNetworkIdle(); + await page.waitFor(250); // animation expect(await page.screenshotSelector('.usersManager')).to.matchImage('permissions_bulk_access_set_all'); }); @@ -347,12 +350,12 @@ describe("UsersManager", function () { await page.waitFor(250); // animation - await page.evaluate(() => $('.confirmCapabilityToggle .modal-close:not(.modal-no):visible').click()); + await page.evaluate(() => $('.userPermissionsEdit .confirmCapabilityToggle .modal-close:not(.modal-no):visible').click()); await page.waitForNetworkIdle(); await page.waitFor(250); // animation - expect(await page.screenshotSelector('.admin#content')).to.matchImage('permissions_capability_single_site'); + expect(await page.screenshotSelector('.usersManager')).to.matchImage('permissions_capability_single_site'); }); it('should remove access to displayed rows when remove bulk access is clicked', async function () { @@ -394,7 +397,22 @@ describe("UsersManager", function () { expect(await elem.screenshot()).to.matchImage('superuser_confirm'); }); + it('should fail to set superuser access if password is wrong', async function () { + await page.type('input#currentUserPasswordForSuperUser', 'wrongpassword'); + await page.evaluate(() => $('.superuser-confirm-modal .modal-close:not(.modal-no):visible').click()); + await page.waitForNetworkIdle(); + + await page.waitFor('.notification-error', { visible: true }); + + const notificationHtml = await page.evaluate(() => $('.notification-error>div').html()); + expect(notificationHtml).to.equal('The current password you entered is not correct.'); + }); + it('should give the user superuser access when the superuser modal is confirmed', async function () { + await page.click('.userEditForm #superuser_access+label'); + await page.waitFor(500); + + await page.type('input#currentUserPasswordForSuperUser', 'superUserPass'); await page.evaluate(() => $('.superuser-confirm-modal .modal-close:not(.modal-no):visible').click()); await page.waitForNetworkIdle(); await page.waitFor(500); diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_manage_users_back.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_manage_users_back.png index 9ffaaa81a1..228c7cc0cd 100644 --- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_manage_users_back.png +++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_manage_users_back.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f16ad832b1d64c645664e7e64408f25e491c31f3926e2da9773cc40916193009 -size 147836 +oid sha256:434264e176f6f4aa217c247fdcf032fca1d7304d8a33359e28505dc867231fcc +size 147842 diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_bulk_access_set_all.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_bulk_access_set_all.png index 323e7bce5e..117d590b71 100644 --- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_bulk_access_set_all.png +++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_bulk_access_set_all.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4af9d284d62698df449b104597006d73dc06855761fad90333def4febc11506c -size 85673 +oid sha256:6806c1587d23ff706a62b908aeb141b98a052440f8220d14a21b688faae8b33c +size 78284 diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_capability_single_site.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_capability_single_site.png index f2623bd5fb..c12b0af534 100644 --- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_capability_single_site.png +++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_capability_single_site.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:750fa07d8b3c6b5d7da0e68ede73131af3c1460c00aee070f2f1eda0e310d036 -size 96385 +oid sha256:c700040d1c3a9c7288d7a1f5d3354089709762dffb4764aa5f114f3bbca7c65f +size 91417 diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_filters.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_filters.png index 1cda86e3aa..28b8a16607 100644 --- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_filters.png +++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_filters.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0dbb9ad0fad0e51c572ce7b84cc59db7dea7083b702fc663fd3ab5cccffdb245 -size 28695 +oid sha256:595839d882d0c1d20f5ccd23dff2dbab68b24940e01683b9da44dfbea28e4cdb +size 65467 diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_select_all.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_select_all.png index 9ffa892dc0..462864ba99 100644 --- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_select_all.png +++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_select_all.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad2b46f639d5a1d0d59299444b791011be309a71883f764cf1a22f7d712c5bbc -size 29843 +oid sha256:4162bd79000733235fe891ccf4fa90f60af9862d6a39b02cc6ef6c35d96874a1 +size 67291 diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_single_site_access.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_single_site_access.png index 2d2a9d7736..93d4420205 100644 --- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_single_site_access.png +++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_single_site_access.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5606bd6b54b2776f8a0df93ff31d5cd7a4f527e9b24fc0727a6e33286d234c01 -size 92464 +oid sha256:ae69632d1e3c8c2c8cae6d6d1bc3d0142ba4d5ff870e85d23637e149fad76311 +size 87826 diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_superuser_confirm.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_superuser_confirm.png index 604d4b89c1..d30c26ebb8 100644 --- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_superuser_confirm.png +++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_superuser_confirm.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:556e3e32f67793bfb45a7fb1b618bc3f20a5c81fca3cc8049374c88674a5ee91 -size 15764 +oid sha256:8aca0c9d68a8f97ac9a9c82947fb3dc00ce51455a8f3abb34c5e055a1004471c +size 19858 |