Files
nextcloud-server-mirror/tests/lib/OCM/OCMProviderTest.php
Micke Nordin 410d8c144b feat(ocm): align RFC 9421 http-sig with updated OCM spec
Implements the changes from cs3org/OCM-API#391 and closes the
remaining gaps with the HTTP Message Signatures section:

- discover peer JWK Sets via the new `jwksUri` discovery field
  instead of the fixed /.well-known/jwks.json path; advertise
  our own jwksUri and require it (https) from peers advertising
  the `http-sig` capability
- stop covering the Date header; freshness is anchored on the
  `created` signature parameter
- mark and select the OCM signature by its integrity-protected
  tag="ocm" parameter instead of the dictionary label
- require the JWK `alg` parameter and derive the signature
  algorithm from it, accepting fully-specified RFC 9864 names
- reject signed requests whose verification key cannot be
  resolved instead of treating them as unsigned
- derive the signer origin from the spec-canonical fqdn#id
  keyid form

Signed-off-by: Micke Nordin <kano@sunet.se>
2026-08-09 16:21:06 +02:00

99 lines
3.3 KiB
PHP

<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\OCM;
use OC\OCM\Model\OCMProvider;
use OCP\OCM\IOCMResource;
use Test\TestCase;
class OCMProviderTest extends TestCase {
private OCMProvider $provider;
#[\Override]
protected function setUp(): void {
parent::setUp();
$this->provider = new OCMProvider();
}
private function resource(string $name, array $shareTypes, array $protocols): IOCMResource {
$resource = $this->provider->createNewResourceType();
$resource->setName($name)
->setShareTypes($shareTypes)
->setProtocols($protocols);
return $resource;
}
public function testAddResourceTypeKeepsDistinctNames(): void {
$this->provider->addResourceType($this->resource('file', ['user'], ['webdav' => '/dav/']));
$this->provider->addResourceType($this->resource('folder', ['user'], ['webapp' => []]));
$this->assertCount(2, $this->provider->getResourceTypes());
}
public function testAddResourceTypeMergesSameName(): void {
$this->provider->addResourceType($this->resource('folder', ['user'], ['webapp' => []]));
$this->provider->addResourceType($this->resource('folder', ['user'], ['webapp-receive' => ['targets' => ['blank', 'iframe']]]));
$resourceTypes = $this->provider->getResourceTypes();
$this->assertCount(1, $resourceTypes);
$this->assertSame(
['webapp' => [], 'webapp-receive' => ['targets' => ['blank', 'iframe']]],
$resourceTypes[0]->getProtocols(),
);
}
public function testAddResourceTypeDedupesShareTypes(): void {
$this->provider->addResourceType($this->resource('folder', ['user'], ['webapp' => []]));
$this->provider->addResourceType($this->resource('folder', ['user', 'group'], ['webapp-receive' => []]));
$shareTypes = $this->provider->getResourceTypes()[0]->getShareTypes();
$this->assertSame(['user', 'group'], $shareTypes);
// Deduplication must not leave key gaps, or shareTypes would
// serialize as a JSON object instead of an array.
$this->assertSame('["user","group"]', json_encode($shareTypes));
}
public function testAddResourceTypeMergeOverwritesSameProtocol(): void {
$this->provider->addResourceType($this->resource('folder', ['user'], ['webapp' => ['a' => 1]]));
$this->provider->addResourceType($this->resource('folder', ['user'], ['webapp' => ['b' => 2]]));
$this->assertSame(
['webapp' => ['b' => 2]],
$this->provider->getResourceTypes()[0]->getProtocols(),
);
}
public function testJwksUriImportedFromDiscoveryData(): void {
$this->provider->import([
'enabled' => true,
'apiVersion' => '1.1.0',
'endPoint' => 'https://cloud.example.org/ocm',
'capabilities' => ['http-sig'],
'jwksUri' => 'https://cloud.example.org/ocm/jwks',
]);
$this->assertSame('https://cloud.example.org/ocm/jwks', $this->provider->getJwksUri());
}
public function testJwksUriSerializedOnlyWhenSet(): void {
$this->provider->setEnabled(true)
->setApiVersion('1.1.0')
->setEndPoint('https://cloud.example.org/ocm');
$this->assertArrayNotHasKey('jwksUri', $this->provider->jsonSerialize());
$this->provider->setJwksUri('https://cloud.example.org/ocm/jwks');
$this->assertSame(
'https://cloud.example.org/ocm/jwks',
$this->provider->jsonSerialize()['jwksUri'],
);
}
}