diff --git a/core/Command/User/Keys/Verify.php b/core/Command/User/Keys/Verify.php
index 024e93460724d..053a51049e863 100644
--- a/core/Command/User/Keys/Verify.php
+++ b/core/Command/User/Keys/Verify.php
@@ -15,6 +15,7 @@
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class Verify extends Command {
@@ -34,6 +35,12 @@ protected function configure(): void {
InputArgument::REQUIRED,
'User ID of the user to verify'
)
+ ->addOption(
+ 'update',
+ null,
+ InputOption::VALUE_NONE,
+ 'Save the derived public key to match the private key'
+ )
;
}
@@ -72,12 +79,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$output->writeln($publicKeyDerived);
if ($publicKey != $publicKeyDerived) {
- $output->writeln('Stored public key does not match stored private key');
- return static::FAILURE;
+ if (!$input->getOption('update')) {
+ $output->writeln('Stored public key does not match stored private key');
+ return static::FAILURE;
+ }
+
+ $this->keyManager->setPublicKey($user, $publicKeyDerived);
+ $output->writeln('Derived public key did not match, successfully updated');
+ return static::SUCCESS;
}
$output->writeln('Stored public key matches stored private key');
-
return static::SUCCESS;
}
}
diff --git a/lib/private/Security/IdentityProof/Manager.php b/lib/private/Security/IdentityProof/Manager.php
index c16b8314beb31..ef0faeb6ad632 100644
--- a/lib/private/Security/IdentityProof/Manager.php
+++ b/lib/private/Security/IdentityProof/Manager.php
@@ -135,6 +135,18 @@ public function getKey(IUser $user): Key {
return $this->retrieveKey('user-' . $uid);
}
+ /**
+ * Set public key for $user
+ */
+ public function setPublicKey(IUser $user, string $publicKey): void {
+ $id = 'user-' . $user->getUID();
+
+ $folder = $this->appData->getFolder($id);
+ $folder->newFile('public', $publicKey);
+
+ $this->cache->set($id . '-public', $publicKey);
+ }
+
/**
* Get instance wide public and private key
*
diff --git a/tests/lib/Security/IdentityProof/ManagerTest.php b/tests/lib/Security/IdentityProof/ManagerTest.php
index 921d72388a1ad..608b1cd4c30e8 100644
--- a/tests/lib/Security/IdentityProof/ManagerTest.php
+++ b/tests/lib/Security/IdentityProof/ManagerTest.php
@@ -153,6 +153,33 @@ public function testGetKeyWithExistingKeyCached(): void {
$this->assertEquals($expected, $this->manager->getKey($user));
}
+ public function testSetPublicKey(): void {
+ $user = $this->createMock(IUser::class);
+ $user
+ ->expects($this->exactly(1))
+ ->method('getUID')
+ ->willReturn('MyUid');
+ $publicFile = $this->createMock(ISimpleFile::class);
+ $folder = $this->createMock(ISimpleFolder::class);
+ $folder
+ ->expects($this->once())
+ ->method('newFile')
+ ->willReturnMap([
+ ['public', 'MyNewPublicKey', $publicFile],
+ ]);
+ $this->appData
+ ->expects($this->once())
+ ->method('getFolder')
+ ->with('user-MyUid')
+ ->willReturn($folder);
+ $this->cache
+ ->expects($this->once())
+ ->method('set')
+ ->with('user-MyUid-public', 'MyNewPublicKey');
+
+ $this->manager->setPublicKey($user, 'MyNewPublicKey');
+ }
+
public function testGetKeyWithNotExistingKey(): void {
$user = $this->createMock(IUser::class);
$user