Merge pull request #13172 from nextcloud/fix-can-change-password-check

fix can change password check in case of encryption is enabled
This commit is contained in:
Roeland Jago Douma 2019-01-04 09:53:10 +01:00 committed by GitHub
commit fe3d8ffc90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 95 additions and 21 deletions

View File

@ -41,6 +41,7 @@ namespace OC\Settings\Controller;
use OC\Accounts\AccountManager;
use OC\AppFramework\Http;
use OC\Encryption\Exceptions\ModuleDoesNotExistsException;
use OC\ForbiddenException;
use OC\Security\IdentityProof\Manager;
use OCA\User_LDAP\User_Proxy;
@ -167,12 +168,7 @@ class UsersController extends Controller {
}
}
/* ENCRYPTION CONFIG */
$isEncryptionEnabled = $this->encryptionManager->isEnabled();
$useMasterKey = $this->config->getAppValue('encryption', 'useMasterKey', true);
// If masterKey enabled, then you can change password. This is to avoid data loss!
$canChangePassword = ($isEncryptionEnabled && $useMasterKey) || $useMasterKey;
$canChangePassword = $this->canAdminChangeUserPasswords();
/* GROUPS */
$groupsInfo = new \OC\Group\MetaData(
@ -254,6 +250,38 @@ class UsersController extends Controller {
return new TemplateResponse('settings', 'settings-vue', ['serverData' => $serverData]);
}
/**
* check if the admin can change the users password
*
* The admin can change the passwords if:
*
* - no encryption module is loaded and encryption is disabled
* - encryption module is loaded but it doesn't require per user keys
*
* The admin can not change the passwords if:
*
* - an encryption module is loaded and it uses per-user keys
* - encryption is enabled but no encryption modules are loaded
*
* @return bool
*/
protected function canAdminChangeUserPasswords() {
$isEncryptionEnabled = $this->encryptionManager->isEnabled();
try {
$noUserSpecificEncryptionKeys =!$this->encryptionManager->getEncryptionModule()->needDetailedAccessList();
$isEncryptionModuleLoaded = true;
} catch (ModuleDoesNotExistsException $e) {
$noUserSpecificEncryptionKeys = true;
$isEncryptionModuleLoaded = false;
}
$canChangePassword = ($isEncryptionEnabled && $isEncryptionModuleLoaded && $noUserSpecificEncryptionKeys)
|| (!$isEncryptionEnabled && !$isEncryptionModuleLoaded)
|| (!$isEncryptionEnabled && $isEncryptionModuleLoaded && $noUserSpecificEncryptionKeys);
return $canChangePassword;
}
/**
* @NoAdminRequired
* @NoSubadminRequired

View File

@ -11,6 +11,7 @@
namespace Tests\Settings\Controller;
use OC\Accounts\AccountManager;
use OC\Encryption\Exceptions\ModuleDoesNotExistsException;
use OC\Group\Group;
use OC\Group\Manager;
use OC\Settings\Controller\UsersController;
@ -513,4 +514,49 @@ class UsersControllerTest extends \Test\TestCase {
$this->assertSame(Http::STATUS_BAD_REQUEST, $result->getStatus());
}
/**
* @dataProvider dataTestCanAdminChangeUserPasswords
*
* @param bool $encryptionEnabled
* @param bool $encryptionModuleLoaded
* @param bool $masterKeyEnabled
* @param bool $expected
*/
public function testCanAdminChangeUserPasswords($encryptionEnabled,
$encryptionModuleLoaded,
$masterKeyEnabled,
$expected) {
$controller = $this->getController();
$this->encryptionManager->expects($this->any())
->method('isEnabled')
->willReturn($encryptionEnabled);
$this->encryptionManager->expects($this->any())
->method('getEncryptionModule')
->willReturnCallback(function() use ($encryptionModuleLoaded) {
if ($encryptionModuleLoaded) return $this->encryptionModule;
else throw new ModuleDoesNotExistsException();
});
$this->encryptionModule->expects($this->any())
->method('needDetailedAccessList')
->willReturn(!$masterKeyEnabled);
$result = $this->invokePrivate($controller, 'canAdminChangeUserPasswords', []);
$this->assertSame($expected, $result);
}
public function dataTestCanAdminChangeUserPasswords() {
return [
// encryptionEnabled, encryptionModuleLoaded, masterKeyEnabled, expectedResult
[true, true, true, true],
[false, true, true, true],
[true, false, true, false],
[false, false, true, true],
[true, true, false, false],
[false, true, false, false],
[true, false, false, false],
[false, false, false, true],
];
}
}