Skip to content

Commit c0ad41d

Browse files
committed
feat(cloud_federation_api): adapt to new format for share creation
Signed-off-by: Enrique Pérez Arnaud <[email protected]>
1 parent 7236566 commit c0ad41d

File tree

4 files changed

+114
-14
lines changed

4 files changed

+114
-14
lines changed

apps/cloud_federation_api/lib/Controller/RequestHandlerController.php

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public function __construct(
9494
* @param string|null $ownerDisplayName Display name of the user who shared the item
9595
* @param string|null $sharedBy Provider specific UID of the user who shared the resource
9696
* @param string|null $sharedByDisplayName Display name of the user who shared the resource
97-
* @param array{name: list<string>, options: array<string, mixed>} $protocol e,.g. ['name' => 'webdav', 'options' => ['username' => 'john', 'permissions' => 31]]
97+
* @param array{name: string, options?: array<string, mixed>, webdav?: array<string, mixed>} $protocol Old format: ['name' => 'webdav', 'options' => ['sharedSecret' => '...', 'permissions' => '...']] or New format: ['name' => 'webdav', 'webdav' => ['uri' => '...', 'sharedSecret' => '...', 'permissions' => [...]]]
9898
* @param string $shareType 'group' or 'user' share
9999
* @param string $resourceType 'file', 'calendar',...
100100
*
@@ -129,9 +129,6 @@ public function addShare($shareWith, $name, $description, $providerId, $owner, $
129129
|| $shareType === null
130130
|| !is_array($protocol)
131131
|| !isset($protocol['name'])
132-
|| !isset($protocol['options'])
133-
|| !is_array($protocol['options'])
134-
|| !isset($protocol['options']['sharedSecret'])
135132
) {
136133
return new JSONResponse(
137134
[
@@ -142,6 +139,20 @@ public function addShare($shareWith, $name, $description, $providerId, $owner, $
142139
);
143140
}
144141

142+
$protocolName = $protocol['name'];
143+
$hasOldFormat = isset($protocol['options']) && is_array($protocol['options']) && isset($protocol['options']['sharedSecret']);
144+
$hasNewFormat = isset($protocol[$protocolName]) && is_array($protocol[$protocolName]) && isset($protocol[$protocolName]['sharedSecret']);
145+
146+
if (!$hasOldFormat && !$hasNewFormat) {
147+
return new JSONResponse(
148+
[
149+
'message' => 'Missing sharedSecret in protocol',
150+
'validationErrors' => [],
151+
],
152+
Http::STATUS_BAD_REQUEST
153+
);
154+
}
155+
145156
$supportedShareTypes = $this->config->getSupportedShareTypes($resourceType);
146157
if (!in_array($shareType, $supportedShareTypes)) {
147158
return new JSONResponse(

lib/private/Federation/CloudFederationFactory.php

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,18 @@
99
use OCP\Federation\ICloudFederationFactory;
1010
use OCP\Federation\ICloudFederationNotification;
1111
use OCP\Federation\ICloudFederationShare;
12+
use OCP\Federation\ICloudIdManager;
13+
use OCP\OCM\IOCMDiscoveryService;
14+
use OCP\OCM\Exceptions\OCMProviderException;
15+
use Psr\Log\LoggerInterface;
1216

1317
class CloudFederationFactory implements ICloudFederationFactory {
18+
public function __construct(
19+
private IOCMDiscoveryService $ocmDiscoveryService,
20+
private ICloudIdManager $cloudIdManager,
21+
private LoggerInterface $logger,
22+
) {
23+
}
1424
/**
1525
* get a CloudFederationShare Object to prepare a share you want to send
1626
*
@@ -30,7 +40,52 @@ class CloudFederationFactory implements ICloudFederationFactory {
3040
* @since 14.0.0
3141
*/
3242
public function getCloudFederationShare($shareWith, $name, $description, $providerId, $owner, $ownerDisplayName, $sharedBy, $sharedByDisplayName, $sharedSecret, $shareType, $resourceType) {
33-
return new CloudFederationShare($shareWith, $name, $description, $providerId, $owner, $ownerDisplayName, $sharedBy, $sharedByDisplayName, $shareType, $resourceType, $sharedSecret);
43+
$useExchangeToken = false;
44+
$remoteDomain = null;
45+
46+
try {
47+
$cloudId = $this->cloudIdManager->resolveCloudId($shareWith);
48+
$remoteDomain = $cloudId->getRemote();
49+
50+
try {
51+
$remoteProvider = $this->ocmDiscoveryService->discover($remoteDomain);
52+
$capabilities = $remoteProvider->getCapabilities();
53+
54+
$useExchangeToken = in_array('exchange-token', $capabilities, true);
55+
56+
$this->logger->debug('OCM provider capabilities discovered', [
57+
'remote' => $remoteDomain,
58+
'capabilities' => $capabilities,
59+
'useExchangeToken' => $useExchangeToken,
60+
]);
61+
} catch (OCMProviderException $e) {
62+
$this->logger->warning('Failed to discover OCM provider, using legacy share method', [
63+
'remote' => $remoteDomain,
64+
'exception' => $e->getMessage(),
65+
]);
66+
}
67+
} catch (\InvalidArgumentException $e) {
68+
$this->logger->warning('Invalid cloud ID format, using legacy share method', [
69+
'shareWith' => $shareWith,
70+
'exception' => $e->getMessage(),
71+
]);
72+
}
73+
74+
return new CloudFederationShare(
75+
$shareWith,
76+
$name,
77+
$description,
78+
$providerId,
79+
$owner,
80+
$ownerDisplayName,
81+
$sharedBy,
82+
$sharedByDisplayName,
83+
$shareType,
84+
$resourceType,
85+
$sharedSecret,
86+
$useExchangeToken,
87+
$remoteDomain
88+
);
3489
}
3590

3691
/**

lib/private/Federation/CloudFederationShare.php

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class CloudFederationShare implements ICloudFederationShare {
4040
* @param string $shareType ('group' or 'user' share)
4141
* @param string $resourceType ('file', 'calendar',...)
4242
* @param string $sharedSecret
43+
* @param bool $useExchangeToken whether to use exchange-token protocol (new way) or sharedSecret (old way)
44+
* @param string|null $remoteDomain remote domain for constructing webdav URI
4345
*/
4446
public function __construct($shareWith = '',
4547
$name = '',
@@ -52,6 +54,8 @@ public function __construct($shareWith = '',
5254
$shareType = '',
5355
$resourceType = '',
5456
$sharedSecret = '',
57+
$useExchangeToken = false,
58+
$remoteDomain = null,
5559
) {
5660
$this->setShareWith($shareWith);
5761
$this->setResourceName($name);
@@ -61,13 +65,27 @@ public function __construct($shareWith = '',
6165
$this->setOwnerDisplayName($ownerDisplayName);
6266
$this->setSharedBy($sharedBy);
6367
$this->setSharedByDisplayName($sharedByDisplayName);
64-
$this->setProtocol([
65-
'name' => 'webdav',
66-
'options' => [
67-
'sharedSecret' => $sharedSecret,
68-
'permissions' => '{http://open-cloud-mesh.org/ns}share-permissions'
69-
]
70-
]);
68+
69+
if ($useExchangeToken) {
70+
$webdavUri = $remoteDomain ? 'https://' . $remoteDomain . '/public.php/webdav/' : '';
71+
$this->setProtocol([
72+
'name' => 'webdav',
73+
'webdav' => [
74+
'uri' => $webdavUri,
75+
'sharedSecret' => $sharedSecret,
76+
'permissions' => ['{http://open-cloud-mesh.org/ns}share-permissions']
77+
]
78+
]);
79+
} else {
80+
$this->setProtocol([
81+
'name' => 'webdav',
82+
'options' => [
83+
'sharedSecret' => $sharedSecret,
84+
'permissions' => '{http://open-cloud-mesh.org/ns}share-permissions'
85+
]
86+
]);
87+
}
88+
7189
$this->setShareType($shareType);
7290
$this->setResourceType($resourceType);
7391
}
@@ -328,7 +346,19 @@ public function getShareType() {
328346
* @since 14.0.0
329347
*/
330348
public function getShareSecret() {
331-
return $this->share['protocol']['options']['sharedSecret'];
349+
$protocol = $this->share['protocol'];
350+
if (isset($protocol['options']['sharedSecret'])) {
351+
return $protocol['options']['sharedSecret'];
352+
}
353+
354+
if (isset($protocol['name'])) {
355+
$protocolName = $protocol['name'];
356+
if (isset($protocol[$protocolName]['sharedSecret'])) {
357+
return $protocol[$protocolName]['sharedSecret'];
358+
}
359+
}
360+
361+
return '';
332362
}
333363

334364
/**

lib/private/Server.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1167,7 +1167,11 @@ public function __construct($webRoot, \OC\Config $config) {
11671167
$this->registerAlias(\OCP\GlobalScale\IConfig::class, \OC\GlobalScale\Config::class);
11681168
$this->registerAlias(ICloudFederationProviderManager::class, CloudFederationProviderManager::class);
11691169
$this->registerService(ICloudFederationFactory::class, function (Server $c) {
1170-
return new CloudFederationFactory();
1170+
return new CloudFederationFactory(
1171+
$c->get(\OCP\OCM\IOCMDiscoveryService::class),
1172+
$c->get(\OCP\Federation\ICloudIdManager::class),
1173+
$c->get(\Psr\Log\LoggerInterface::class)
1174+
);
11711175
});
11721176

11731177
$this->registerAlias(\OCP\AppFramework\Utility\IControllerMethodReflector::class, \OC\AppFramework\Utility\ControllerMethodReflector::class);

0 commit comments

Comments
 (0)