Merge pull request #10645 from nextcloud/fix-password-reset

only warn about data lose on password reset if per-user keys are used
This commit is contained in:
Björn Schießle 2018-08-15 17:08:27 +02:00 committed by GitHub
commit 78ca6f9f87
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 2 deletions

View file

@ -37,6 +37,7 @@ use OCP\AppFramework\Http\JSONResponse;
use \OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Defaults;
use OCP\Encryption\IEncryptionModule;
use OCP\Encryption\IManager;
use \OCP\IURLGenerator;
use \OCP\IRequest;
@ -260,7 +261,15 @@ class LostController extends Controller {
}
if ($this->encryptionManager->isEnabled() && !$proceed) {
return $this->error('', array('encryption' => true));
$encryptionModules = $this->encryptionManager->getEncryptionModules();
foreach ($encryptionModules as $module) {
/** @var IEncryptionModule $instance */
$instance = call_user_func($module['callback']);
// this way we can find out whether per-user keys are used or a system wide encryption key
if ($instance->needDetailedAccessList()) {
return $this->error('', array('encryption' => true));
}
}
}
try {

View file

@ -27,6 +27,7 @@ use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Defaults;
use OCP\Encryption\IEncryptionModule;
use OCP\Encryption\IManager;
use OCP\IConfig;
use OCP\IL10N;
@ -713,10 +714,49 @@ class LostControllerTest extends \Test\TestCase {
$this->assertEquals($expectedResponse, $response);
}
public function testSetPasswordEncryptionDontProceed() {
public function testSetPasswordEncryptionDontProceedPerUserKey() {
/** @var IEncryptionModule|PHPUnit_Framework_MockObject_MockObject $encryptionModule */
$encryptionModule = $this->createMock(IEncryptionModule::class);
$encryptionModule->expects($this->once())->method('needDetailedAccessList')->willReturn(true);
$this->encryptionManager->expects($this->once())->method('getEncryptionModules')
->willReturn([0 => ['callback' => function() use ($encryptionModule) { return $encryptionModule; }]]);
$response = $this->lostController->setPassword('myToken', 'user', 'newpass', false);
$expectedResponse = ['status' => 'error', 'msg' => '', 'encryption' => true];
$this->assertSame($expectedResponse, $response);
}
public function testSetPasswordDontProceedMasterKey() {
$encryptionModule = $this->createMock(IEncryptionModule::class);
$encryptionModule->expects($this->once())->method('needDetailedAccessList')->willReturn(false);
$this->encryptionManager->expects($this->once())->method('getEncryptionModules')
->willReturn([0 => ['callback' => function() use ($encryptionModule) { return $encryptionModule; }]]);
$this->config->method('getUserValue')
->with('ValidTokenUser', 'core', 'lostpassword', null)
->willReturn('encryptedData');
$this->existingUser->method('getLastLogin')
->will($this->returnValue(12344));
$this->existingUser->expects($this->once())
->method('setPassword')
->with('NewPassword')
->willReturn(true);
$this->userManager->method('get')
->with('ValidTokenUser')
->willReturn($this->existingUser);
$this->config->expects($this->once())
->method('deleteUserValue')
->with('ValidTokenUser', 'core', 'lostpassword');
$this->timeFactory->method('getTime')
->will($this->returnValue(12348));
$this->crypto->method('decrypt')
->with(
$this->equalTo('encryptedData'),
$this->equalTo('test@example.comSECRET')
)->willReturn('12345:TheOnlyAndOnlyOneTokenToResetThePassword');
$response = $this->lostController->setPassword('TheOnlyAndOnlyOneTokenToResetThePassword', 'ValidTokenUser', 'NewPassword', false);
$expectedResponse = array('user' => 'ValidTokenUser', 'status' => 'success');
$this->assertSame($expectedResponse, $response);
}
}