Add event listener to remove matching background jobs for trusted server url. Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>pull/53760/head
parent
d0f819ba99
commit
8b1ac839d7
@ -0,0 +1,57 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/** |
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
namespace OCA\Federation\Listener; |
||||
|
||||
use OCA\Federation\BackgroundJob\GetSharedSecret; |
||||
use OCA\Federation\BackgroundJob\RequestSharedSecret; |
||||
use OCP\BackgroundJob\IJobList; |
||||
use OCP\EventDispatcher\Event; |
||||
use OCP\EventDispatcher\IEventListener; |
||||
use OCP\Federation\Events\TrustedServerRemovedEvent; |
||||
|
||||
/** @template-implements IEventListener<TrustedServerRemovedEvent> */ |
||||
class TrustedServerRemovedListener implements IEventListener { |
||||
public function __construct( |
||||
private readonly IJobList $jobList, |
||||
) { |
||||
} |
||||
|
||||
public function handle(Event $event): void { |
||||
if (!$event instanceof TrustedServerRemovedEvent) { |
||||
return; |
||||
} |
||||
|
||||
if ($event->getUrl() === null) { |
||||
return; // safe guard |
||||
} |
||||
|
||||
$this->removeJobsByUrl(RequestSharedSecret::class, $event->getUrl()); |
||||
$this->removeJobsByUrl(GetSharedSecret::class, $event->getUrl()); |
||||
} |
||||
|
||||
/** |
||||
* Remove RequestSharedSecret or GetSharedSecret jobs from the job list by their URL. |
||||
* The jobs are scheduled with url, token, and created as arguments. |
||||
* Thus, we have to loop over the jobs here and cannot use IJobList.remove. |
||||
*/ |
||||
private function removeJobsByUrl(string $class, string $url): void { |
||||
foreach ($this->jobList->getJobsIterator($class, null, 0) as $job) { |
||||
$arguments = $job->getArgument(); |
||||
if (isset($arguments['url']) && $arguments['url'] === $url) { |
||||
try { |
||||
$this->jobList->removeById($job->getId()); |
||||
} catch (\Exception) { |
||||
// Removing the background jobs is optional because they will expire sometime. |
||||
// Therefore, we are using catch and ignore. |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,71 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/** |
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
namespace OCA\Federation\Tests\Listener; |
||||
|
||||
use OC\AppFramework\Utility\TimeFactory; |
||||
use OCA\Federation\BackgroundJob\GetSharedSecret; |
||||
use OCA\Federation\Listener\TrustedServerRemovedListener; |
||||
use OCA\Federation\TrustedServers; |
||||
use OCP\BackgroundJob\IJobList; |
||||
use OCP\Federation\Events\TrustedServerRemovedEvent; |
||||
use OCP\Http\Client\IClientService; |
||||
use OCP\IConfig; |
||||
use OCP\IURLGenerator; |
||||
use OCP\OCS\IDiscoveryService; |
||||
use Psr\Log\NullLogger; |
||||
use Test\BackgroundJob\DummyJobList; |
||||
use Test\TestCase; |
||||
|
||||
class TrustedServerRemovedListenerTest extends TestCase { |
||||
|
||||
private IJobList $jobList; |
||||
private TrustedServerRemovedListener $listener; |
||||
|
||||
protected function setUp(): void { |
||||
parent::setUp(); |
||||
|
||||
$this->jobList = new DummyJobList(); |
||||
$this->listener = new TrustedServerRemovedListener($this->jobList); |
||||
} |
||||
|
||||
public function testHandle(): void { |
||||
// Arrange |
||||
$url = 'https://example.com'; |
||||
$event = new TrustedServerRemovedEvent(md5($url), $url); // we are using a different hashing in the tests. |
||||
$job1 = $this->createGetSharedSecretMock(); |
||||
$job2 = $this->createGetSharedSecretMock(); |
||||
$job3 = $this->createGetSharedSecretMock(); |
||||
$job4 = $this->createGetSharedSecretMock(); |
||||
$this->jobList->add($job1, ['url' => 'https://example.org', 'token' => 'nei0dooX', 'created' => 0]); |
||||
$this->jobList->add($job2, ['url' => 'https://example.net', 'token' => 'ci6Shah7', 'created' => 0]); |
||||
$this->jobList->add($job3, ['url' => $url, 'token' => 'ieXie6Me', 'created' => 0]); |
||||
$this->jobList->add($job4, ['url' => $url, 'token' => 'thoQu8th', 'created' => 0]); |
||||
|
||||
// Act |
||||
$this->listener->handle($event); |
||||
$jobs = iterator_to_array($this->jobList->getJobsIterator(GetSharedSecret::class, null, 0), false); |
||||
|
||||
// Assert |
||||
$this->assertCount(2, $jobs); |
||||
} |
||||
|
||||
private function createGetSharedSecretMock(): GetSharedSecret { |
||||
return new GetSharedSecret( |
||||
$this->createMock(IClientService::class), |
||||
$this->createMock(IURLGenerator::class), |
||||
$this->jobList, |
||||
$this->createMock(TrustedServers::class), |
||||
new NullLogger(), |
||||
$this->createMock(IDiscoveryService::class), |
||||
new TimeFactory(), |
||||
$this->createMock(IConfig::class), |
||||
); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue