diff --git a/core/Command/User/Keys/Verify.php b/core/Command/User/Keys/Verify.php index 024e9346072..053a51049e8 100644 --- a/core/Command/User/Keys/Verify.php +++ b/core/Command/User/Keys/Verify.php @@ -15,6 +15,7 @@ use OCP\IUserManager; 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 @@ class Verify extends Command { 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 @@ class Verify extends Command { $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 c16b8314beb..ef0faeb6ad6 100644 --- a/lib/private/Security/IdentityProof/Manager.php +++ b/lib/private/Security/IdentityProof/Manager.php @@ -135,6 +135,18 @@ class Manager { 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 921d72388a1..608b1cd4c30 100644 --- a/tests/lib/Security/IdentityProof/ManagerTest.php +++ b/tests/lib/Security/IdentityProof/ManagerTest.php @@ -153,6 +153,33 @@ class ManagerTest extends TestCase { $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