moving methods to their final places

and updating test some.
remotes/origin/poc-doctrine-migrations
Clark Tomlinson 2015-03-30 17:01:50 +07:00 committed by Thomas Müller
parent 1b42b492dc
commit e6dc6944c2
6 changed files with 188 additions and 127 deletions

@ -127,7 +127,8 @@ class Application extends \OCP\AppFramework\App {
$server->getConfig(),
$server->getUserSession(),
$server->getSession(),
$server->getLogger()
$server->getLogger(),
$c->query('Recovery')
);
});
@ -168,13 +169,7 @@ class Application extends \OCP\AppFramework\App {
function (IAppContainer $c) {
$server = $c->getServer();
return new Util(new View(),
new Filesystem(),
$c->query('Crypt'),
$c->query('KeyManager'),
$server->getLogger(),
$server->getUserSession(),
$server->getConfig()
return new Util(new View(), $c->query('Crypt'), $c->query('KeyManager'), $server->getLogger(), $server->getUserSession(), $server->getConfig()
);
});

@ -27,8 +27,6 @@ use OC\Encryption\Exceptions\PrivateKeyMissingException;
use OC\Encryption\Exceptions\PublicKeyMissingException;
use OCA\Encryption\Crypto\Crypt;
use OCP\Encryption\Keys\IStorage;
use OCP\ICache;
use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\ILogger;
use OCP\IUserSession;
@ -86,6 +84,10 @@ class KeyManager {
* @var ILogger
*/
private $log;
/**
* @var Recovery
*/
private $recovery;
/**
* @param IStorage $keyStorage
@ -94,6 +96,7 @@ class KeyManager {
* @param IUserSession $userSession
* @param \OCP\ISession $session
* @param ILogger $log
* @param Recovery $recovery
*/
public function __construct(
IStorage $keyStorage,
@ -101,7 +104,9 @@ class KeyManager {
IConfig $config,
IUserSession $userSession,
ISession $session,
ILogger $log) {
ILogger $log,
Recovery $recovery
) {
self::$session = $session;
$this->keyStorage = $keyStorage;
@ -115,7 +120,9 @@ class KeyManager {
if (empty($this->publicShareKeyId)) {
$this->publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8);
$this->config->setAppValue('encryption', 'publicShareKeyId', $this->publicShareKeyId);
$this->config->setAppValue('encryption',
'publicShareKeyId',
$this->publicShareKeyId);
$keyPair = $this->crypt->createKeyPair();
@ -125,9 +132,11 @@ class KeyManager {
$keyPair['publicKey']);
// Encrypt private key empty passphrase
$encryptedKey = $this->crypt->symmetricEncryptFileContent($keyPair['privateKey'], '');
$encryptedKey = $this->crypt->symmetricEncryptFileContent($keyPair['privateKey'],
'');
if ($encryptedKey) {
$this->keyStorage->setSystemUserKey($this->publicShareKeyId . '.privateKey', $encryptedKey);
$this->keyStorage->setSystemUserKey($this->publicShareKeyId . '.privateKey',
$encryptedKey);
} else {
$this->log->error('Could not create public share keys');
}
@ -136,6 +145,7 @@ class KeyManager {
$this->keyId = $userSession && $userSession->isLoggedIn() ? $userSession->getUser()->getUID() : false;
$this->log = $log;
$this->recovery = $recovery;
}
/**
@ -386,7 +396,7 @@ class KeyManager {
$this->setPrivateKey($user, $encryptedKey);
if ($recoveryPassword) { // if recovery key is set we can re-encrypt the key files
$util->recoverUsersFiles($recoveryPassword);
$this->recovery->recoverUsersFiles($recoveryPassword);
}
} else {
$this->log->error('Encryption Could not update users encryption password');

@ -29,6 +29,7 @@ use OCP\IUser;
use OCP\IUserSession;
use OCP\PreConditionNotMetException;
use OCP\Security\ISecureRandom;
use OCP\Share;
class Recovery {
@ -54,10 +55,12 @@ class Recovery {
*/
private $config;
/**
* @var IEncryptionKeyStorage
* @var IStorage
*/
private $keyStorage;
private $recoveryKeyId;
/**
* @param IUserSession $user
* @param Crypt $crypt
@ -90,7 +93,9 @@ class Recovery {
if ($recoveryKeyId === null) {
$recoveryKeyId = $this->random->getLowStrengthGenerator();
$appConfig->setAppValue('encryption', 'recoveryKeyId', $recoveryKeyId);
$appConfig->setAppValue('encryption',
'recoveryKeyId',
$recoveryKeyId);
}
$keyManager = $this->keyManager;
@ -98,7 +103,9 @@ class Recovery {
if (!$keyManager->recoveryKeyExists()) {
$keyPair = $this->crypt->createKeyPair();
return $this->keyManager->storeKeyPair($this->user->getUID(), $password, $keyPair);
return $this->keyManager->storeKeyPair($this->user->getUID(),
$password,
$keyPair);
}
if ($keyManager->checkRecoveryPassword($password)) {
@ -143,6 +150,7 @@ class Recovery {
return ($recoveryMode === '1');
}
/**
* @param $enabled
* @return bool
@ -165,12 +173,79 @@ class Recovery {
* @param $recoveryPassword
*/
public function recoverUsersFiles($recoveryPassword) {
// todo: get system private key here
// $this->keyManager->get
$encryptedKey = $this->keyManager->getSystemPrivateKey();
$privateKey = $this->crypt->decryptPrivateKey($encryptedKey,
$recoveryPassword);
$this->recoverAllFiles('/', $privateKey);
}
/**
* @param $path
* @param $privateKey
*/
private function recoverAllFiles($path, $privateKey) {
$dirContent = $this->files->getDirectoryContent($path);
foreach ($dirContent as $item) {
// Get relative path from encryption/keyfiles
$filePath = substr($item['path'], strlen('encryption/keys'));
if ($this->files->is_dir($this->user->getUID() . '/files' . '/' . $filePath)) {
$this->recoverAllFiles($filePath . '/', $privateKey);
} else {
$this->recoverFile($filePath, $privateKey);
}
}
}
/**
* @param $filePath
* @param $privateKey
*/
private function recoverFile($filePath, $privateKey) {
$sharingEnabled = Share::isEnabled();
$uid = $this->user->getUID();
// Find out who, if anyone, is sharing the file
if ($sharingEnabled) {
$result = Share::getUsersSharingFile($filePath,
$uid,
true);
$userIds = $result['users'];
$userIds[] = 'public';
} else {
$userIds = [
$uid,
$this->recoveryKeyId
];
}
$filteredUids = $this->filterShareReadyUsers($userIds);
// Decrypt file key
$encKeyFile = $this->keyManager->getFileKey($filePath,
$uid);
$shareKey = $this->keyManager->getShareKey($filePath,
$uid);
$plainKeyFile = $this->crypt->multiKeyDecrypt($encKeyFile,
$shareKey,
$privateKey);
// Encrypt the file key again to all users, this time with the new publick keyt for the recovered user
$userPublicKeys = $this->keyManager->getPublicKeys($filteredUids['ready']);
$multiEncryptionKey = $this->crypt->multiKeyEncrypt($plainKeyFile,
$userPublicKeys);
$this->keyManager->setFileKey($multiEncryptionKey['data'],
$uid);
$this->keyManager->setShareKey($filePath,
$uid,
$multiEncryptionKey['keys']);
}
}

@ -26,7 +26,6 @@ namespace OCA\Encryption;
use OC\Files\Filesystem;
use OC\Files\View;
use OCA\Encryption\Crypto\Crypt;
use OCA\Files_Versions\Storage;
use OCP\App;
use OCP\IConfig;
use OCP\ILogger;
@ -40,10 +39,6 @@ class Util {
* @var View
*/
private $files;
/**
* @var Filesystem
*/
private $filesystem;
/**
* @var Crypt
*/
@ -69,24 +64,20 @@ class Util {
* Util constructor.
*
* @param View $files
* @param Filesystem $filesystem
* @param Crypt $crypt
* @param KeyManager $keyManager
* @param ILogger $logger
* @param IUserSession $userSession
* @param IConfig $config
*/
public function __construct(
View $files,
Filesystem $filesystem,
Crypt $crypt,
KeyManager $keyManager,
ILogger $logger,
IUserSession $userSession,
IConfig $config
public function __construct(View $files,
Crypt $crypt,
KeyManager $keyManager,
ILogger $logger,
IUserSession $userSession,
IConfig $config
) {
$this->files = $files;
$this->filesystem = $filesystem;
$this->crypt = $crypt;
$this->keyManager = $keyManager;
$this->logger = $logger;
@ -94,16 +85,6 @@ class Util {
$this->config = $config;
}
/**
* @param $filePath
* @return array
*/
private function splitPath($filePath) {
$normalized = $this->filesystem->normalizePath($filePath);
return explode('/', $normalized);
}
/**
* @return bool
*/
@ -154,71 +135,5 @@ class Util {
return $this->files->file_exists($uid . '/files');
}
/**
* @param $path
* @param $privateKey
*/
private function recoverAllFiles($path, $privateKey) {
// Todo relocate to storage
$dirContent = $this->files->getDirectoryContent($path);
foreach ($dirContent as $item) {
// Get relative path from encryption/keyfiles
$filePath = substr($item['path'], strlen('encryption/keys'));
if ($this->files->is_dir($this->user->getUID() . '/files' . '/' . $filePath)) {
$this->recoverAllFiles($filePath . '/', $privateKey);
} else {
$this->recoverFile($filePath, $privateKey);
}
}
}
/**
* @param $filePath
* @param $privateKey
*/
private function recoverFile($filePath, $privateKey) {
$sharingEnabled = Share::isEnabled();
$uid = $this->user->getUID();
// Find out who, if anyone, is sharing the file
if ($sharingEnabled) {
$result = Share::getUsersSharingFile($filePath,
$uid,
true);
$userIds = $result['users'];
$userIds[] = 'public';
} else {
$userIds = [
$uid,
$this->recoveryKeyId
];
}
$filteredUids = $this->filterShareReadyUsers($userIds);
// Decrypt file key
$encKeyFile = $this->keyManager->getFileKey($filePath,
$uid);
$shareKey = $this->keyManager->getShareKey($filePath,
$uid);
$plainKeyFile = $this->crypt->multiKeyDecrypt($encKeyFile,
$shareKey,
$privateKey);
// Encrypt the file key again to all users, this time with the new publick keyt for the recovered user
$userPublicKeys = $this->keyManager->getPublicKeys($filteredUids['ready']);
$multiEncryptionKey = $this->crypt->multiKeyEncrypt($plainKeyFile,
$userPublicKeys);
$this->keyManager->setFileKey($multiEncryptionKey['data'],
$uid);
$this->keyManager->setShareKey($filePath,
$uid,
$multiEncryptionKey['keys']);
}
}

@ -20,20 +20,14 @@ $keymanager = new \OCA\Encryption\KeyManager(
\OC::$server->getConfig(),
\OC::$server->getUserSession(),
\OC::$server->getSession(),
\OC::$server->getLogger());
\OC::$server->getLogger(),);
$user = \OCP\User::getUser();
$view = new \OC\Files\View('/');
$util = new \OCA\Encryption\Util(
new \OC\Files\View(),
new \OC\Files\Filesystem(),
$crypt,
$keymanager,
\OC::$server->getLogger(),
\OC::$server->getUserSession(),
\OC::$server->getConfig());
new \OC\Files\View(), $crypt, $keymanager, \OC::$server->getLogger(), \OC::$server->getUserSession(), \OC::$server->getConfig());
$session = \OC::$server->getSession();

@ -10,26 +10,64 @@
namespace OCA\Encryption\Tests;
use OC\Files\View;
use OCA\Encryption\KeyManager;
use Test\TestCase;
class KeyManagerTest extends TestCase {
/**
* @var bool
*/
private static $trashbinState;
/**
* @var KeyManager
*/
private $instance;
/**
* @var
* @var string
*/
private $userId;
private static $testUser = 'test-keyManager-user.dot';
/**
* @var
*/
private $dummyKeys;
/**
* @var string
*/
private $userId;
/**
* @var string
*/
private $userPassword;
/**
* @var \OC\Files\View
*/
private $view;
/**
* @var string
*/
private $dataDir;
/**
*
*/
public static function setUpBeforeClass() {
parent::setUpBeforeClass();
// Remember files_trashbin state
self::$trashbinState = \OC_App::isEnabled('files_trashbin');
// We dont want tests with app files_trashbin enabled
\OC_App::disable('files_trashbin');
$userManager = \OC::$server->getUserManager();
$userManager->createUser(self::$testUser,
self::$testUser);
// Create test user
parent::loginAsUser(self::$testUser);
}
public function setUp() {
parent::setUp();
$keyStorageMock = $this->getMock('OCP\Encryption\Keys\IStorage');
@ -47,18 +85,52 @@ class KeyManagerTest extends TestCase {
->will($this->returnValue('admin'));
$sessionMock = $this->getMock('OCP\ISession');
$logMock = $this->getMock('OCP\ILogger');
$this->userId = 'admin';
$recoveryMock = $this->getMockBuilder('OCA\Encryption\Recovery')
->disableOriginalConstructor()
->getMock();
$this->instance = new KeyManager($keyStorageMock,
$cryptMock,
$configMock,
$userMock,
$sessionMock,
$logMock);
$logMock,
$recoveryMock);
self::loginAsUser(self::$testUser);
$this->userId = self::$testUser;
$this->userPassword = self::$testUser;
$this->view = new View('/');
$this->dummyKeys = [
'privateKey' => 'superinsecureprivatekey',
'publicKey' => 'superinsecurepublickey'
];
$this->dummyKeys = ['public' => 'randomweakpublickeyhere',
'private' => 'randomweakprivatekeyhere'];
$userManager = \OC::$server->getUserManager();
$userHome = $userManager->get($this->userId)->getHome();
$this->dataDir = str_replace('/' . $this->userId, '', $userHome);
}
protected function tearDown() {
parent::tearDown();
$this->view->deleteAll('/' . self::$testUser . '/files_encryption/keys');
}
public static function tearDownAfterClass() {
parent::tearDownAfterClass();
// Cleanup Test user
\OC::$server->getUserManager()->get(self::$testUser)->delete();
// Reset app files_trashbin
if (self::$trashbinState) {
\OC_App::enable('files_trashbin');
}
}
/**
* @expectedException \OC\Encryption\Exceptions\PrivateKeyMissingException
*/
@ -93,7 +165,7 @@ class KeyManagerTest extends TestCase {
public function testSetPublicKey() {
$this->assertTrue($this->instance->setPublicKey($this->userId,
$this->dummyKeys['public']));
$this->dummyKeys['publicKey']));
}
/**
@ -101,7 +173,7 @@ class KeyManagerTest extends TestCase {
*/
public function testSetPrivateKey() {
$this->assertTrue($this->instance->setPrivateKey($this->userId,
$this->dummyKeys['private']));
$this->dummyKeys['privateKey']));
}
/**