Introduce isReadyForUser and verify in file transfer ownership - fixes #23786
This commit is contained in:
parent
5911ce530b
commit
50e20e531e
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -98,6 +98,12 @@ class TransferOwnership extends Command {
|
||||||
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";
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,25 @@ class Manager implements IManager {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
*
|
*
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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');
|
||||||
|
|
Loading…
Reference in New Issue