summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Müller <thomas.mueller@tmit.eu>2016-04-14 17:32:25 +0200
committerThomas Müller <thomas.mueller@tmit.eu>2016-04-15 15:07:40 +0200
commit50e20e531ea942d900c50b510c8c13a6a1dd1465 (patch)
treedb641d3406f9930dce8ba6223dd69e79b36f7627
parent5911ce530b003d46348f59e9280b610f684de85a (diff)
downloadnextcloud-server-50e20e531ea942d900c50b510c8c13a6a1dd1465.tar.gz
nextcloud-server-50e20e531ea942d900c50b510c8c13a6a1dd1465.zip
Introduce isReadyForUser and verify in file transfer ownership - fixes #23786
-rw-r--r--apps/encryption/lib/crypto/encryption.php13
-rw-r--r--apps/encryption/lib/keymanager.php1
-rw-r--r--apps/files/command/transferownership.php6
-rw-r--r--lib/private/encryption/manager.php19
-rw-r--r--lib/public/encryption/iencryptionmodule.php12
-rw-r--r--tests/lib/files/storage/wrapper/encryption.php9
-rw-r--r--tests/lib/files/stream/encryption.php2
7 files changed, 57 insertions, 5 deletions
diff --git a/apps/encryption/lib/crypto/encryption.php b/apps/encryption/lib/crypto/encryption.php
index 907a6437f5b..6eff66e72be 100644
--- a/apps/encryption/lib/crypto/encryption.php
+++ b/apps/encryption/lib/crypto/encryption.php
@@ -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);
+ }
}
diff --git a/apps/encryption/lib/keymanager.php b/apps/encryption/lib/keymanager.php
index 12fa5f92bd5..0accfb7900a 100644
--- a/apps/encryption/lib/keymanager.php
+++ b/apps/encryption/lib/keymanager.php
@@ -493,6 +493,7 @@ class KeyManager {
*/
public function userHasKeys($userId) {
$privateKey = $publicKey = true;
+ $exception = null;
try {
$this->getPrivateKey($userId);
diff --git a/apps/files/command/transferownership.php b/apps/files/command/transferownership.php
index 6bf2fae6bdf..1f46efdde0d 100644
--- a/apps/files/command/transferownership.php
+++ b/apps/files/command/transferownership.php
@@ -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";
diff --git a/lib/private/encryption/manager.php b/lib/private/encryption/manager.php
index d45bbf07ee9..8714d161807 100644
--- a/lib/private/encryption/manager.php
+++ b/lib/private/encryption/manager.php
@@ -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
diff --git a/lib/public/encryption/iencryptionmodule.php b/lib/public/encryption/iencryptionmodule.php
index df30dd57cee..8d20a1ab57d 100644
--- a/lib/public/encryption/iencryptionmodule.php
+++ b/lib/public/encryption/iencryptionmodule.php
@@ -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);
+
}
diff --git a/tests/lib/files/storage/wrapper/encryption.php b/tests/lib/files/storage/wrapper/encryption.php
index 651299a3eab..21f7d9f09b9 100644
--- a/tests/lib/files/storage/wrapper/encryption.php
+++ b/tests/lib/files/storage/wrapper/encryption.php
@@ -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')
diff --git a/tests/lib/files/stream/encryption.php b/tests/lib/files/stream/encryption.php
index afb31f2822d..20a4100d2ff 100644
--- a/tests/lib/files/stream/encryption.php
+++ b/tests/lib/files/stream/encryption.php
@@ -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');