Merge pull request #24004 from owncloud/dont-transfer-files-to-not-ready-user

Introduce isReadyForUser and verify in file transfer ownership
This commit is contained in:
Thomas Müller 2016-04-19 15:56:47 +02:00
commit 5b2ef92eb2
7 changed files with 57 additions and 5 deletions

View File

@ -547,4 +547,17 @@ class Encryption implements IEncryptionModule {
return $path; 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);
}
} }

View File

@ -493,6 +493,7 @@ class KeyManager {
*/ */
public function userHasKeys($userId) { public function userHasKeys($userId) {
$privateKey = $publicKey = true; $privateKey = $publicKey = true;
$exception = null;
try { try {
$this->getPrivateKey($userId); $this->getPrivateKey($userId);

View File

@ -97,6 +97,12 @@ class TransferOwnership extends Command {
$output->writeln("<error>Unknown destination user $this->destinationUser</error>"); $output->writeln("<error>Unknown destination user $this->destinationUser</error>");
return; 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'); $date = date('c');
$this->finalTarget = "$this->destinationUser/files/transferred from $this->sourceUser on $date"; $this->finalTarget = "$this->destinationUser/files/transferred from $this->sourceUser on $date";

View File

@ -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 * Registers an callback function which must return an encryption module instance
* *
* @param string $id * @param string $id

View File

@ -168,4 +168,16 @@ interface IEncryptionModule {
*/ */
public function prepareDecryptAll(InputInterface $input, OutputInterface $output, $user = ''); 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);
} }

View File

@ -5,6 +5,7 @@ namespace Test\Files\Storage\Wrapper;
use OC\Encryption\Util; use OC\Encryption\Util;
use OC\Files\Storage\Temporary; use OC\Files\Storage\Temporary;
use OC\Files\View; use OC\Files\View;
use OC\User\Manager;
use Test\Files\Storage\Storage; use Test\Files\Storage\Storage;
class Encryption extends Storage { class Encryption extends Storage {
@ -118,7 +119,7 @@ class Encryption extends Storage {
$this->util = $this->getMock( $this->util = $this->getMock(
'\OC\Encryption\Util', '\OC\Encryption\Util',
['getUidAndFilename', 'isFile', 'isExcluded'], ['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()) $this->util->expects($this->any())
->method('getUidAndFilename') ->method('getUidAndFilename')
->willReturnCallback(function ($path) { ->willReturnCallback(function ($path) {
@ -200,7 +201,7 @@ class Encryption extends Storage {
protected function buildMockModule() { protected function buildMockModule() {
$this->encryptionModule = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule') $this->encryptionModule = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule')
->disableOriginalConstructor() ->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(); ->getMock();
$this->encryptionModule->expects($this->any())->method('getId')->willReturn('UNIT_TEST_MODULE'); $this->encryptionModule->expects($this->any())->method('getId')->willReturn('UNIT_TEST_MODULE');
@ -543,7 +544,7 @@ class Encryption extends Storage {
->setConstructorArgs( ->setConstructorArgs(
[ [
new View(), new View(),
new \OC\User\Manager(), new Manager(),
$this->groupManager, $this->groupManager,
$this->config, $this->config,
$this->arrayCache $this->arrayCache
@ -608,7 +609,7 @@ class Encryption extends Storage {
->disableOriginalConstructor()->getMock(); ->disableOriginalConstructor()->getMock();
$util = $this->getMockBuilder('\OC\Encryption\Util') $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(); ->getMock();
$cache = $this->getMockBuilder('\OC\Files\Cache\Cache') $cache = $this->getMockBuilder('\OC\Files\Cache\Cache')

View File

@ -311,7 +311,7 @@ class Encryption extends \Test\TestCase {
protected function buildMockModule() { protected function buildMockModule() {
$encryptionModule = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule') $encryptionModule = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule')
->disableOriginalConstructor() ->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(); ->getMock();
$encryptionModule->expects($this->any())->method('getId')->willReturn('UNIT_TEST_MODULE'); $encryptionModule->expects($this->any())->method('getId')->willReturn('UNIT_TEST_MODULE');