mirror of
https://github.com/nextcloud/server.git
synced 2026-10-15 02:57:15 +02:00
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>
99 lines
3.3 KiB
PHP
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'],
|
|
);
|
|
}
|
|
}
|