From: Clark Tomlinson Date: Mon, 30 Mar 2015 21:01:50 +0000 (-0400) Subject: moving methods to their final places X-Git-Tag: v8.1.0alpha1~78^2~78 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e6dc6944c2cd92617818a2fd029ecdb1de5ab663;p=nextcloud-server.git moving methods to their final places and updating test some. --- diff --git a/apps/encryption/appinfo/application.php b/apps/encryption/appinfo/application.php index 606c0cc5c49..f9b7a1c60da 100644 --- a/apps/encryption/appinfo/application.php +++ b/apps/encryption/appinfo/application.php @@ -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() ); }); diff --git a/apps/encryption/lib/keymanager.php b/apps/encryption/lib/keymanager.php index d9b670c3f5a..cd983be17f9 100644 --- a/apps/encryption/lib/keymanager.php +++ b/apps/encryption/lib/keymanager.php @@ -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'); diff --git a/apps/encryption/lib/recovery.php b/apps/encryption/lib/recovery.php index 457184b4b96..376d3ef83ba 100644 --- a/apps/encryption/lib/recovery.php +++ b/apps/encryption/lib/recovery.php @@ -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']); + } + + } diff --git a/apps/encryption/lib/util.php b/apps/encryption/lib/util.php index 5fc08c6cc7d..45891be5dad 100644 --- a/apps/encryption/lib/util.php +++ b/apps/encryption/lib/util.php @@ -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']); - } } diff --git a/apps/encryption/settings/settings-personal.php b/apps/encryption/settings/settings-personal.php index 3266351a07d..540897b829d 100644 --- a/apps/encryption/settings/settings-personal.php +++ b/apps/encryption/settings/settings-personal.php @@ -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(); diff --git a/apps/encryption/tests/lib/KeyManagerTest.php b/apps/encryption/tests/lib/KeyManagerTest.php index ed6048d7642..510ab179888 100644 --- a/apps/encryption/tests/lib/KeyManagerTest.php +++ b/apps/encryption/tests/lib/KeyManagerTest.php @@ -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'])); } /**