Skip to content

Commit 28bfe17

Browse files
authored
Merge pull request #56525 from nextcloud/backport/56451/stable31
[stable31] feat: Add option to update the public key of a user
2 parents b883fe2 + 35a86d6 commit 28bfe17

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

core/Command/User/Keys/Verify.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Console\Command\Command;
1616
use Symfony\Component\Console\Input\InputArgument;
1717
use Symfony\Component\Console\Input\InputInterface;
18+
use Symfony\Component\Console\Input\InputOption;
1819
use Symfony\Component\Console\Output\OutputInterface;
1920

2021
class Verify extends Command {
@@ -34,6 +35,12 @@ protected function configure(): void {
3435
InputArgument::REQUIRED,
3536
'User ID of the user to verify'
3637
)
38+
->addOption(
39+
'update',
40+
null,
41+
InputOption::VALUE_NONE,
42+
'Save the derived public key to match the private key'
43+
)
3744
;
3845
}
3946

@@ -72,12 +79,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
7279
$output->writeln($publicKeyDerived);
7380

7481
if ($publicKey != $publicKeyDerived) {
75-
$output->writeln('<error>Stored public key does not match stored private key</error>');
76-
return static::FAILURE;
82+
if (!$input->getOption('update')) {
83+
$output->writeln('<error>Stored public key does not match stored private key</error>');
84+
return static::FAILURE;
85+
}
86+
87+
$this->keyManager->setPublicKey($user, $publicKeyDerived);
88+
$output->writeln('<info>Derived public key did not match, successfully updated</info>');
89+
return static::SUCCESS;
7790
}
7891

7992
$output->writeln('<info>Stored public key matches stored private key</info>');
80-
8193
return static::SUCCESS;
8294
}
8395
}

lib/private/Security/IdentityProof/Manager.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,18 @@ public function getKey(IUser $user): Key {
135135
return $this->retrieveKey('user-' . $uid);
136136
}
137137

138+
/**
139+
* Set public key for $user
140+
*/
141+
public function setPublicKey(IUser $user, string $publicKey): void {
142+
$id = 'user-' . $user->getUID();
143+
144+
$folder = $this->appData->getFolder($id);
145+
$folder->newFile('public', $publicKey);
146+
147+
$this->cache->set($id . '-public', $publicKey);
148+
}
149+
138150
/**
139151
* Get instance wide public and private key
140152
*

tests/lib/Security/IdentityProof/ManagerTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,33 @@ public function testGetKeyWithExistingKeyCached(): void {
155155
$this->assertEquals($expected, $this->manager->getKey($user));
156156
}
157157

158+
public function testSetPublicKey(): void {
159+
$user = $this->createMock(IUser::class);
160+
$user
161+
->expects($this->exactly(1))
162+
->method('getUID')
163+
->willReturn('MyUid');
164+
$publicFile = $this->createMock(ISimpleFile::class);
165+
$folder = $this->createMock(ISimpleFolder::class);
166+
$folder
167+
->expects($this->once())
168+
->method('newFile')
169+
->willReturnMap([
170+
['public', 'MyNewPublicKey', $publicFile],
171+
]);
172+
$this->appData
173+
->expects($this->once())
174+
->method('getFolder')
175+
->with('user-MyUid')
176+
->willReturn($folder);
177+
$this->cache
178+
->expects($this->once())
179+
->method('set')
180+
->with('user-MyUid-public', 'MyNewPublicKey');
181+
182+
$this->manager->setPublicKey($user, 'MyNewPublicKey');
183+
}
184+
158185
public function testGetKeyWithNotExistingKey(): void {
159186
$user = $this->createMock(IUser::class);
160187
$user

0 commit comments

Comments
 (0)