make encryption configurable for home storage

This commit is contained in:
Bjoern Schiessle 2015-10-13 17:54:06 +02:00 committed by Björn Schießle
parent d7d5a3bab5
commit 5fad45b230
11 changed files with 247 additions and 61 deletions

View File

@ -201,7 +201,8 @@ class Application extends \OCP\AppFramework\App {
$c->query('KeyManager'),
$c->query('Crypt'),
$c->query('Session'),
$server->getSession()
$server->getSession(),
$c->query('Util')
);
});

View File

@ -35,6 +35,11 @@ namespace OCA\Encryption\AppInfo;
'url' => '/ajax/updatePrivateKeyPassword',
'verb' => 'POST'
],
[
'name' => 'Settings#setEncryptHomeStorage',
'url' => '/ajax/setEncryptHomeStorage',
'verb' => 'POST'
],
[
'name' => 'Recovery#changeRecoveryPassword',
'url' => '/ajax/changeRecoveryPassword',

View File

@ -25,6 +25,7 @@ namespace OCA\Encryption\Controller;
use OCA\Encryption\Crypto\Crypt;
use OCA\Encryption\KeyManager;
use OCA\Encryption\Session;
use OCA\Encryption\Util;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
@ -57,6 +58,9 @@ class SettingsController extends Controller {
/** @var ISession */
private $ocSession;
/** @var Util */
private $util;
/**
* @param string $AppName
* @param IRequest $request
@ -67,6 +71,7 @@ class SettingsController extends Controller {
* @param Crypt $crypt
* @param Session $session
* @param ISession $ocSession
* @param Util $util
*/
public function __construct($AppName,
IRequest $request,
@ -76,7 +81,9 @@ class SettingsController extends Controller {
KeyManager $keyManager,
Crypt $crypt,
Session $session,
ISession $ocSession) {
ISession $ocSession,
Util $util
) {
parent::__construct($AppName, $request);
$this->l = $l10n;
$this->userSession = $userSession;
@ -85,6 +92,7 @@ class SettingsController extends Controller {
$this->crypt = $crypt;
$this->session = $session;
$this->ocSession = $ocSession;
$this->util = $util;
}
@ -143,4 +151,15 @@ class SettingsController extends Controller {
}
}
/**
* @UseSession
*
* @param bool $encryptHomeStorage
* @return DataResponse
*/
public function setEncryptHomeStorage($encryptHomeStorage) {
$this->util->setEncryptHomeStorage($encryptHomeStorage);
return new DataResponse();
}
}

View File

@ -76,4 +76,13 @@ $(document).ready(function () {
});
});
$('#encryptHomeStorage').change(function() {
$.post(
OC.generateUrl('/apps/encryption/ajax/setEncryptHomeStorage'),
{
encryptHomeStorage: this.checked
}
);
});
});

View File

@ -378,6 +378,12 @@ class Encryption implements IEncryptionModule {
* @return boolean
*/
public function shouldEncrypt($path) {
if ($this->util->shouldEncryptHomeStorage() === false) {
$storage = $this->util->getStorage($path);
if ($storage->instanceOfStorage('\OCP\Files\IHomeStorage')) {
return false;
}
}
$parts = explode('/', $path);
if (count($parts) < 4) {
return false;

View File

@ -94,11 +94,40 @@ class Util {
$recoveryMode = $this->config->getUserValue($uid,
'encryption',
'recoveryEnabled',
0);
'0');
return ($recoveryMode === '1');
}
/**
* check if the home storage should be encrypted
*
* @return bool
*/
public function shouldEncryptHomeStorage() {
$encryptHomeStorage = $this->config->getAppValue(
'encryption',
'encryptHomeStorage',
'1'
);
return ($encryptHomeStorage === '1');
}
/**
* check if the home storage should be encrypted
*
* @param bool $encryptHomeStorage
*/
public function setEncryptHomeStorage($encryptHomeStorage) {
$value = $encryptHomeStorage ? '1' : '0';
$this->config->setAppValue(
'encryption',
'encryptHomeStorage',
$value
);
}
/**
* check if master key is enabled
*
@ -157,4 +186,15 @@ class Util {
return $owner;
}
/**
* get storage of path
*
* @param string $path
* @return \OC\Files\Storage\Storage
*/
public function getStorage($path) {
$storage = $this->files->getMount($path)->getStorage();
return $storage;
}
}

View File

@ -25,12 +25,27 @@
$tmpl = new OCP\Template('encryption', 'settings-admin');
$crypt = new \OCA\Encryption\Crypto\Crypt(
\OC::$server->getLogger(),
\OC::$server->getUserSession(),
\OC::$server->getConfig());
$util = new \OCA\Encryption\Util(
new \OC\Files\View(),
$crypt,
\OC::$server->getLogger(),
\OC::$server->getUserSession(),
\OC::$server->getConfig(),
\OC::$server->getUserManager());
// Check if an adminRecovery account is enabled for recovering files after lost pwd
$recoveryAdminEnabled = \OC::$server->getConfig()->getAppValue('encryption', 'recoveryAdminEnabled', '0');
$session = new \OCA\Encryption\Session(\OC::$server->getSession());
$encryptHomeStorage = $util->shouldEncryptHomeStorage($user);
$tmpl->assign('recoveryEnabled', $recoveryAdminEnabled);
$tmpl->assign('initStatus', $session->getStatus());
$tmpl->assign('encryptHomeStorage', $encryptHomeStorage);
return $tmpl->fetchPage();

View File

@ -9,56 +9,63 @@ style('encryption', 'settings-admin');
<?php if(!$_["initStatus"]): ?>
<?php p($l->t("Encryption App is enabled but your keys are not initialized, please log-out and log-in again")); ?>
<?php else: ?>
<p id="encryptionSetRecoveryKey">
<?php $_["recoveryEnabled"] === '0' ? p($l->t("Enable recovery key")) : p($l->t("Disable recovery key")); ?>
<span class="msg"></span>
<br/>
<em>
<?php p($l->t("The recovery key is an extra encryption key that is used to encrypt files. It allows recovery of a user's files if the user forgets his or her password.")) ?>
</em>
<br/>
<input type="password"
name="encryptionRecoveryPassword"
id="encryptionRecoveryPassword"
placeholder="<?php p($l->t("Recovery key password")); ?>"/>
<input type="password"
name="encryptionRecoveryPassword"
id="repeatEncryptionRecoveryPassword"
placeholder="<?php p($l->t("Repeat recovery key password")); ?>"/>
<input type="button"
name="enableRecoveryKey"
id="enableRecoveryKey"
status="<?php p($_["recoveryEnabled"]) ?>"
value="<?php $_["recoveryEnabled"] === '0' ? p($l->t("Enable recovery key")) : p($l->t("Disable recovery key")); ?>"/>
</p>
<br/><br/>
<p name="changeRecoveryPasswordBlock" id="encryptionChangeRecoveryKey" <?php if($_['recoveryEnabled'] === '0') print_unescaped('class="hidden"');?>>
<?php p($l->t("Change recovery key password:")); ?>
<span class="msg"></span>
<br/>
<input
type="password"
name="changeRecoveryPassword"
id="oldEncryptionRecoveryPassword"
placeholder="<?php p($l->t("Old recovery key password")); ?>"/>
<p id="encryptHomeStorageSetting">
<input type="checkbox" class="checkbox" name="encrypt_home_storage" id="encryptHomeStorage"
value="1" <?php if ($_['encryptHomeStorage']) print_unescaped('checked="checked"'); ?> />
<label for="encryptHomeStorage"><?php p($l->t('Encrypt the home storage'));?></label></br>
<em><?php p( $l->t( "Enabling this option encrypts all files stored on the main storage, otherwise only files on external storage will be encrypted" ) ); ?></em>
</p>
<br />
<input
type="password"
name="changeRecoveryPassword"
id="newEncryptionRecoveryPassword"
placeholder="<?php p($l->t("New recovery key password")); ?>"/>
<input
type="password"
name="changeRecoveryPassword"
id="repeatedNewEncryptionRecoveryPassword"
placeholder="<?php p($l->t("Repeat new recovery key password")); ?>"/>
<p id="encryptionSetRecoveryKey">
<?php $_["recoveryEnabled"] === '0' ? p($l->t("Enable recovery key")) : p($l->t("Disable recovery key")); ?>
<span class="msg"></span>
<br/>
<em>
<?php p($l->t("The recovery key is an extra encryption key that is used to encrypt files. It allows recovery of a user's files if the user forgets his or her password.")) ?>
</em>
<br/>
<input type="password"
name="encryptionRecoveryPassword"
id="encryptionRecoveryPassword"
placeholder="<?php p($l->t("Recovery key password")); ?>"/>
<input type="password"
name="encryptionRecoveryPassword"
id="repeatEncryptionRecoveryPassword"
placeholder="<?php p($l->t("Repeat recovery key password")); ?>"/>
<input type="button"
name="enableRecoveryKey"
id="enableRecoveryKey"
status="<?php p($_["recoveryEnabled"]) ?>"
value="<?php $_["recoveryEnabled"] === '0' ? p($l->t("Enable recovery key")) : p($l->t("Disable recovery key")); ?>"/>
</p>
<br/><br/>
<button
type="button"
name="submitChangeRecoveryKey">
<p name="changeRecoveryPasswordBlock" id="encryptionChangeRecoveryKey" <?php if($_['recoveryEnabled'] === '0') print_unescaped('class="hidden"');?>>
<?php p($l->t("Change recovery key password:")); ?>
<span class="msg"></span>
<br/>
<input
type="password"
name="changeRecoveryPassword"
id="oldEncryptionRecoveryPassword"
placeholder="<?php p($l->t("Old recovery key password")); ?>"/>
<br />
<input
type="password"
name="changeRecoveryPassword"
id="newEncryptionRecoveryPassword"
placeholder="<?php p($l->t("New recovery key password")); ?>"/>
<input
type="password"
name="changeRecoveryPassword"
id="repeatedNewEncryptionRecoveryPassword"
placeholder="<?php p($l->t("Repeat new recovery key password")); ?>"/>
<button
type="button"
name="submitChangeRecoveryKey">
<?php p($l->t("Change Password")); ?>
</button>
</p>
</button>
</p>
<?php endif; ?>
</form>

View File

@ -56,6 +56,9 @@ class SettingsControllerTest extends TestCase {
/** @var \PHPUnit_Framework_MockObject_MockObject */
private $ocSessionMock;
/** @var \PHPUnit_Framework_MockObject_MockObject */
private $utilMock;
protected function setUp() {
parent::setUp();
@ -106,6 +109,10 @@ class SettingsControllerTest extends TestCase {
$this->sessionMock = $this->getMockBuilder('OCA\Encryption\Session')
->disableOriginalConstructor()->getMock();
$this->utilMock = $this->getMockBuilder('OCA\Encryption\Util')
->disableOriginalConstructor()
->getMock();
$this->controller = new SettingsController(
'encryption',
$this->requestMock,
@ -115,7 +122,8 @@ class SettingsControllerTest extends TestCase {
$this->keyManagerMock,
$this->cryptMock,
$this->sessionMock,
$this->ocSessionMock
$this->ocSessionMock,
$this->utilMock
);
}
@ -234,4 +242,10 @@ class SettingsControllerTest extends TestCase {
$data['message']);
}
function testSetEncryptHomeStorage() {
$value = true;
$this->utilMock->expects($this->once())->method('setEncryptHomeStorage')->with($value);
$this->controller->setEncryptHomeStorage($value);
}
}

View File

@ -39,6 +39,9 @@ class UtilTest extends TestCase {
/** @var \PHPUnit_Framework_MockObject_MockObject */
private $userManagerMock;
/** @var \PHPUnit_Framework_MockObject_MockObject */
private $mountMock;
/** @var Util */
private $instance;
@ -65,6 +68,7 @@ class UtilTest extends TestCase {
protected function setUp() {
parent::setUp();
$this->mountMock = $this->getMock('\OCP\Files\Mount\IMountPoint');
$this->filesMock = $this->getMock('OC\Files\View');
$this->userManagerMock = $this->getMock('\OCP\IUserManager');
@ -151,4 +155,52 @@ class UtilTest extends TestCase {
];
}
/**
* @dataProvider dataTestShouldEncryptHomeStorage
* @param $returnValue return value from getAppValue()
* @param $expected
*/
public function testShouldEncryptHomeStorage($returnValue, $expected) {
$this->configMock->expects($this->once())->method('getAppValue')
->with('encryption', 'encryptHomeStorage', '1')
->willReturn($returnValue);
$this->assertSame($expected,
$this->instance->shouldEncryptHomeStorage());
}
public function dataTestShouldEncryptHomeStorage() {
return [
['1', true],
['0', false]
];
}
/**
* @dataProvider dataTestSetEncryptHomeStorage
* @param $value
* @param $expected
*/
public function testSetEncryptHomeStorage($value, $expected) {
$this->configMock->expects($this->once())->method('setAppValue')
->with('encryption', 'encryptHomeStorage', $expected);
$this->instance->setEncryptHomeStorage($value);
}
public function dataTestSetEncryptHomeStorage() {
return [
[true, '1'],
[false, '0']
];
}
public function testGetStorage() {
$path = '/foo/bar.txt';
$this->filesMock->expects($this->once())->method('getMount')->with($path)
->willReturn($this->mountMock);
$this->mountMock->expects($this->once())->method('getStorage')->willReturn(true);
$this->assertTrue($this->instance->getStorage($path));
}
}

View File

@ -55,9 +55,14 @@ class EncryptionTest extends TestCase {
/** @var \PHPUnit_Framework_MockObject_MockObject */
private $l10nMock;
/** @var \PHPUnit_Framework_MockObject_MockObject */
private $storageMock;
public function setUp() {
parent::setUp();
$this->storageMock = $this->getMockBuilder('OCP\Files\Storage')
->disableOriginalConstructor()->getMock();
$this->cryptMock = $this->getMockBuilder('OCA\Encryption\Crypto\Crypt')
->disableOriginalConstructor()
->getMock();
@ -312,7 +317,17 @@ class EncryptionTest extends TestCase {
*
* @dataProvider dataTestShouldEncrypt
*/
public function testShouldEncrypt($path, $expected) {
public function testShouldEncrypt($path, $shouldEncryptHomeStorage, $isHomeStorage, $expected) {
$this->utilMock->expects($this->once())->method('shouldEncryptHomeStorage')
->willReturn($shouldEncryptHomeStorage);
if ($shouldEncryptHomeStorage === false) {
$this->storageMock->expects($this->once())->method('instanceOfStorage')
->with('\OCP\Files\IHomeStorage')->willReturn($isHomeStorage);
$this->utilMock->expects($this->once())->method('getStorage')->with($path)
->willReturn($this->storageMock);
}
$this->assertSame($expected,
$this->instance->shouldEncrypt($path)
);
@ -320,14 +335,17 @@ class EncryptionTest extends TestCase {
public function dataTestShouldEncrypt() {
return array(
array('/user1/files/foo.txt', true),
array('/user1/files_versions/foo.txt', true),
array('/user1/files_trashbin/foo.txt', true),
array('/user1/some_folder/foo.txt', false),
array('/user1/foo.txt', false),
array('/user1/files', false),
array('/user1/files_trashbin', false),
array('/user1/files_versions', false),
array('/user1/files/foo.txt', true, true, true),
array('/user1/files_versions/foo.txt', true, true, true),
array('/user1/files_trashbin/foo.txt', true, true, true),
array('/user1/some_folder/foo.txt', true, true, false),
array('/user1/foo.txt', true, true, false),
array('/user1/files', true, true, false),
array('/user1/files_trashbin', true, true, false),
array('/user1/files_versions', true, true, false),
// test if shouldEncryptHomeStorage is set to false
array('/user1/files/foo.txt', false, true, false),
array('/user1/files_versions/foo.txt', false, false, true),
);
}