77
88namespace OCA \CloudFederationAPI \Controller ;
99
10+ use OC \Authentication \Token \PublicKeyTokenProvider ;
1011use OC \OCM \OCMSignatoryManager ;
1112use OCA \CloudFederationAPI \Config ;
1213use OCA \CloudFederationAPI \Db \FederatedInviteMapper ;
14+ use OCA \CloudFederationAPI \Db \OcmTokenMapMapper ;
1315use OCA \CloudFederationAPI \Events \FederatedInviteAcceptedEvent ;
1416use OCA \CloudFederationAPI \ResponseDefinitions ;
1517use OCP \AppFramework \Controller ;
3941use OCP \OCM \IOCMDiscoveryService ;
4042use OCP \Security \Signature \Exceptions \IncomingRequestException ;
4143use OCP \Security \Signature \IIncomingSignedRequest ;
44+ use OCP \Server ;
4245use OCP \Share \Exceptions \ShareNotFound ;
4346use OCP \Util ;
4447use Psr \Log \LoggerInterface ;
@@ -85,7 +88,7 @@ public function __construct(
8588 * @param string|null $ownerDisplayName Display name of the user who shared the item
8689 * @param string|null $sharedBy Provider specific UID of the user who shared the resource
8790 * @param string|null $sharedByDisplayName Display name of the user who shared the resource
88- * @param array{name: list <string>, options : array<string, mixed>} $protocol e,.g. ['name' => 'webdav', 'options ' => ['username ' => 'john ', 'permissions' => 31 ]]
91+ * @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' => [...]]] or Multi format: ['name' => 'multi', 'webdav' => [... ]]
8992 * @param string $shareType 'group' or 'user' share
9093 * @param string $resourceType 'file', 'calendar',...
9194 *
@@ -120,9 +123,6 @@ public function addShare($shareWith, $name, $description, $providerId, $owner, $
120123 || $ shareType === null
121124 || !is_array ($ protocol )
122125 || !isset ($ protocol ['name ' ])
123- || !isset ($ protocol ['options ' ])
124- || !is_array ($ protocol ['options ' ])
125- || !isset ($ protocol ['options ' ]['sharedSecret ' ])
126126 ) {
127127 return new JSONResponse (
128128 [
@@ -133,6 +133,33 @@ public function addShare($shareWith, $name, $description, $providerId, $owner, $
133133 );
134134 }
135135
136+ $ protocolName = $ protocol ['name ' ];
137+ $ hasOldFormat = isset ($ protocol ['options ' ]) && is_array ($ protocol ['options ' ]) && isset ($ protocol ['options ' ]['sharedSecret ' ]);
138+ $ hasNewFormat = isset ($ protocol [$ protocolName ]) && is_array ($ protocol [$ protocolName ]) && isset ($ protocol [$ protocolName ]['sharedSecret ' ]);
139+
140+ // For multi-protocol, we only consider webdav
141+ $ hasMultiFormat = false ;
142+ if ($ protocolName === 'multi ' ) {
143+ if (isset ($ protocol ['webdav ' ]) && is_array ($ protocol ['webdav ' ]) && isset ($ protocol ['webdav ' ]['sharedSecret ' ])) {
144+ $ hasMultiFormat = true ;
145+ $ protocol = [
146+ 'name ' => 'webdav ' ,
147+ 'webdav ' => $ protocol ['webdav ' ]
148+ ];
149+ $ protocolName = 'webdav ' ;
150+ }
151+ }
152+
153+ if (!$ hasOldFormat && !$ hasNewFormat && !$ hasMultiFormat ) {
154+ return new JSONResponse (
155+ [
156+ 'message ' => 'Missing sharedSecret in protocol ' ,
157+ 'validationErrors ' => [],
158+ ],
159+ Http::STATUS_BAD_REQUEST
160+ );
161+ }
162+
136163 $ supportedShareTypes = $ this ->config ->getSupportedShareTypes ($ resourceType );
137164 if (!in_array ($ shareType , $ supportedShareTypes )) {
138165 return new JSONResponse (
@@ -142,6 +169,7 @@ public function addShare($shareWith, $name, $description, $providerId, $owner, $
142169 }
143170
144171 $ cloudId = $ this ->cloudIdManager ->resolveCloudId ($ shareWith );
172+ $ shareWithCloudId = $ shareWith ; // preserve full cloud ID for factory capability discovery
145173 $ shareWith = $ cloudId ->getUser ();
146174
147175 if ($ shareType === 'user ' ) {
@@ -186,7 +214,10 @@ public function addShare($shareWith, $name, $description, $providerId, $owner, $
186214
187215 try {
188216 $ provider = $ this ->cloudFederationProviderManager ->getCloudFederationProvider ($ resourceType );
189- $ share = $ this ->factory ->getCloudFederationShare ($ shareWith , $ name , $ description , $ providerId , $ owner , $ ownerDisplayName , $ sharedBy , $ sharedByDisplayName , '' , $ shareType , $ resourceType );
217+ // Pass the original cloud ID so the factory can discover capabilities without warning.
218+ // Then reset shareWith to the local username that shareReceived() needs for user lookup.
219+ $ share = $ this ->factory ->getCloudFederationShare ($ shareWithCloudId , $ name , $ description , $ providerId , $ owner , $ ownerDisplayName , $ sharedBy , $ sharedByDisplayName , '' , $ shareType , $ resourceType );
220+ $ share ->setShareWith ($ shareWith );
190221 $ share ->setProtocol ($ protocol );
191222 $ provider ->shareReceived ($ share );
192223 } catch (ProviderDoesNotExistsException |ProviderCouldNotAddShareException $ e ) {
@@ -478,6 +509,12 @@ private function confirmNotificationIdentity(
478509 $ provider = $ this ->cloudFederationProviderManager ->getCloudFederationProvider ($ resourceType );
479510 if ($ provider instanceof ISignedCloudFederationProvider || $ provider instanceof \NCU \Federation \ISignedCloudFederationProvider) {
480511 $ identity = $ provider ->getFederationIdFromSharedSecret ($ sharedSecret , $ notification );
512+ if ($ identity === '' ) {
513+ $ tokenProvider = Server::get (PublicKeyTokenProvider::class);
514+ $ accessTokenDb = $ tokenProvider ->getToken ($ sharedSecret );
515+ $ mapping = Server::get (OcmTokenMapMapper::class)->getByAccessTokenId ($ accessTokenDb ->getId ());
516+ $ identity = $ provider ->getFederationIdFromSharedSecret ($ mapping ->getRefreshToken (), $ notification );
517+ }
481518 } else {
482519 $ this ->logger ->debug ('cloud federation provider {provider} does not implements ISignedCloudFederationProvider ' , ['provider ' => $ provider ::class]);
483520 return ;
0 commit comments