@@ -547,4 +547,17 @@ class Encryption implements IEncryptionModule { | |||
return $path; | |||
} | |||
/** | |||
* Check if the module is ready to be used by that specific user. | |||
* In case a module is not ready - because e.g. key pairs have not been generated | |||
* upon login this method can return false before any operation starts and might | |||
* cause issues during operations. | |||
* | |||
* @param string $user | |||
* @return boolean | |||
* @since 9.1.0 | |||
*/ | |||
public function isReadyForUser($user) { | |||
return $this->keyManager->userHasKeys($user); | |||
} | |||
} |
@@ -493,6 +493,7 @@ class KeyManager { | |||
*/ | |||
public function userHasKeys($userId) { | |||
$privateKey = $publicKey = true; | |||
$exception = null; | |||
try { | |||
$this->getPrivateKey($userId); |
@@ -97,6 +97,12 @@ class TransferOwnership extends Command { | |||
$output->writeln("<error>Unknown destination user $this->destinationUser</error>"); | |||
return; | |||
} | |||
// target user has to be ready | |||
if (!\OC::$server->getEncryptionManager()->isReadyForUser($this->destinationUser)) { | |||
$output->writeln("<error>The target user is not ready to accept files. The user has at least to be logged in once.</error>"); | |||
return; | |||
} | |||
$date = date('c'); | |||
$this->finalTarget = "$this->destinationUser/files/transferred from $this->sourceUser on $date"; |
@@ -117,6 +117,25 @@ class Manager implements IManager { | |||
} | |||
/** | |||
* @param string $user | |||
*/ | |||
public function isReadyForUser($user) { | |||
if (!$this->isReady()) { | |||
return false; | |||
} | |||
foreach ($this->getEncryptionModules() as $module) { | |||
/** @var IEncryptionModule $m */ | |||
$m = call_user_func($module['callback']); | |||
if (!$m->isReadyForUser($user)) { | |||
return false; | |||
} | |||
} | |||
return true; | |||
} | |||
/** | |||
* Registers an callback function which must return an encryption module instance | |||
* | |||
* @param string $id |
@@ -168,4 +168,16 @@ interface IEncryptionModule { | |||
*/ | |||
public function prepareDecryptAll(InputInterface $input, OutputInterface $output, $user = ''); | |||
/** | |||
* Check if the module is ready to be used by that specific user. | |||
* In case a module is not ready - because e.g. key pairs have not been generated | |||
* upon login this method can return false before any operation starts and might | |||
* cause issues during operations. | |||
* | |||
* @param string $user | |||
* @return boolean | |||
* @since 9.1.0 | |||
*/ | |||
public function isReadyForUser($user); | |||
} |
@@ -5,6 +5,7 @@ namespace Test\Files\Storage\Wrapper; | |||
use OC\Encryption\Util; | |||
use OC\Files\Storage\Temporary; | |||
use OC\Files\View; | |||
use OC\User\Manager; | |||
use Test\Files\Storage\Storage; | |||
class Encryption extends Storage { | |||
@@ -118,7 +119,7 @@ class Encryption extends Storage { | |||
$this->util = $this->getMock( | |||
'\OC\Encryption\Util', | |||
['getUidAndFilename', 'isFile', 'isExcluded'], | |||
[new View(), new \OC\User\Manager(), $this->groupManager, $this->config, $this->arrayCache]); | |||
[new View(), new Manager(), $this->groupManager, $this->config, $this->arrayCache]); | |||
$this->util->expects($this->any()) | |||
->method('getUidAndFilename') | |||
->willReturnCallback(function ($path) { | |||
@@ -200,7 +201,7 @@ class Encryption extends Storage { | |||
protected function buildMockModule() { | |||
$this->encryptionModule = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule') | |||
->disableOriginalConstructor() | |||
->setMethods(['getId', 'getDisplayName', 'begin', 'end', 'encrypt', 'decrypt', 'update', 'shouldEncrypt', 'getUnencryptedBlockSize', 'isReadable', 'encryptAll', 'prepareDecryptAll']) | |||
->setMethods(['getId', 'getDisplayName', 'begin', 'end', 'encrypt', 'decrypt', 'update', 'shouldEncrypt', 'getUnencryptedBlockSize', 'isReadable', 'encryptAll', 'prepareDecryptAll', 'isReadyForUser']) | |||
->getMock(); | |||
$this->encryptionModule->expects($this->any())->method('getId')->willReturn('UNIT_TEST_MODULE'); | |||
@@ -543,7 +544,7 @@ class Encryption extends Storage { | |||
->setConstructorArgs( | |||
[ | |||
new View(), | |||
new \OC\User\Manager(), | |||
new Manager(), | |||
$this->groupManager, | |||
$this->config, | |||
$this->arrayCache | |||
@@ -608,7 +609,7 @@ class Encryption extends Storage { | |||
->disableOriginalConstructor()->getMock(); | |||
$util = $this->getMockBuilder('\OC\Encryption\Util') | |||
->setConstructorArgs([new View(), new \OC\User\Manager(), $this->groupManager, $this->config, $this->arrayCache]) | |||
->setConstructorArgs([new View(), new Manager(), $this->groupManager, $this->config, $this->arrayCache]) | |||
->getMock(); | |||
$cache = $this->getMockBuilder('\OC\Files\Cache\Cache') |
@@ -311,7 +311,7 @@ class Encryption extends \Test\TestCase { | |||
protected function buildMockModule() { | |||
$encryptionModule = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule') | |||
->disableOriginalConstructor() | |||
->setMethods(['getId', 'getDisplayName', 'begin', 'end', 'encrypt', 'decrypt', 'update', 'shouldEncrypt', 'getUnencryptedBlockSize', 'isReadable', 'encryptAll', 'prepareDecryptAll']) | |||
->setMethods(['getId', 'getDisplayName', 'begin', 'end', 'encrypt', 'decrypt', 'update', 'shouldEncrypt', 'getUnencryptedBlockSize', 'isReadable', 'encryptAll', 'prepareDecryptAll', 'isReadyForUser']) | |||
->getMock(); | |||
$encryptionModule->expects($this->any())->method('getId')->willReturn('UNIT_TEST_MODULE'); |