mirror of
https://github.com/nextcloud/server.git
synced 2026-06-24 12:24:39 +02:00
4d5841761f
Shares using the OCM multi-protocol envelope (name multi, with the secret carried in a sibling protocol entry such as webdav) were rejected with Missing sharedSecret in protocol. Scan every protocol entry for the shared secret during validation, resolve the secret from the matching entry, and let the files provider serve the webdav entry of a multi envelope. Covers the file and folder resource types. Signed-off-by: Micke Nordin <kano@sunet.se>
411 lines
8.4 KiB
PHP
411 lines
8.4 KiB
PHP
<?php
|
|
|
|
/**
|
|
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
namespace OC\Federation;
|
|
|
|
use OCP\Federation\ICloudFederationShare;
|
|
use OCP\Share\IShare;
|
|
|
|
class CloudFederationShare implements ICloudFederationShare {
|
|
private $share = [
|
|
'shareWith' => '',
|
|
'shareType' => '',
|
|
'name' => '',
|
|
'resourceType' => '',
|
|
'description' => '',
|
|
'providerId' => '',
|
|
'owner' => '',
|
|
'ownerDisplayName' => '',
|
|
'sharedBy' => '',
|
|
'sharedByDisplayName' => '',
|
|
'sender' => '',
|
|
'senderDisplayName' => '',
|
|
'protocol' => []
|
|
];
|
|
|
|
/**
|
|
* get a CloudFederationShare Object to prepare a share you want to send
|
|
*
|
|
* @param string $shareWith
|
|
* @param string $name resource name (e.g. document.odt)
|
|
* @param string $description share description (optional)
|
|
* @param string $providerId resource UID on the provider side
|
|
* @param string $owner provider specific UID of the user who owns the resource
|
|
* @param string $ownerDisplayName display name of the user who shared the item
|
|
* @param string $sharedBy provider specific UID of the user who shared the resource
|
|
* @param string $sharedByDisplayName display name of the user who shared the resource
|
|
* @param string $shareType ('group' or 'user' share)
|
|
* @param string $resourceType ('file', 'calendar',...)
|
|
* @param string $sharedSecret
|
|
* @param bool $useExchangeToken whether to use exchange-token protocol (new way) or sharedSecret (old way)
|
|
* @param string|null $remoteDomain remote domain for constructing webdav URI
|
|
*/
|
|
public function __construct($shareWith = '',
|
|
$name = '',
|
|
$description = '',
|
|
$providerId = '',
|
|
$owner = '',
|
|
$ownerDisplayName = '',
|
|
$sharedBy = '',
|
|
$sharedByDisplayName = '',
|
|
$shareType = '',
|
|
$resourceType = '',
|
|
$sharedSecret = '',
|
|
$useExchangeToken = false,
|
|
$remoteDomain = null,
|
|
) {
|
|
$this->setShareWith($shareWith);
|
|
$this->setResourceName($name);
|
|
$this->setDescription($description);
|
|
$this->setProviderId($providerId);
|
|
$this->setOwner($owner);
|
|
$this->setOwnerDisplayName($ownerDisplayName);
|
|
$this->setSharedBy($sharedBy);
|
|
$this->setSharedByDisplayName($sharedByDisplayName);
|
|
|
|
if ($useExchangeToken) {
|
|
$webdavUri = $remoteDomain ? 'https://' . $remoteDomain . '/public.php/webdav/' : '';
|
|
$this->setProtocol([
|
|
'name' => 'webdav',
|
|
'webdav' => [
|
|
'uri' => $webdavUri,
|
|
'sharedSecret' => $sharedSecret,
|
|
'permissions' => ['{http://open-cloud-mesh.org/ns}share-permissions']
|
|
]
|
|
]);
|
|
} else {
|
|
$this->setProtocol([
|
|
'name' => 'webdav',
|
|
'options' => [
|
|
'sharedSecret' => $sharedSecret,
|
|
'permissions' => '{http://open-cloud-mesh.org/ns}share-permissions'
|
|
]
|
|
]);
|
|
}
|
|
|
|
$this->setShareType($shareType);
|
|
$this->setResourceType($resourceType);
|
|
}
|
|
|
|
/**
|
|
* set uid of the recipient
|
|
*
|
|
* @param string $user
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function setShareWith($user) {
|
|
$this->share['shareWith'] = $user;
|
|
}
|
|
|
|
/**
|
|
* set resource name (e.g. document.odt)
|
|
*
|
|
* @param string $name
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function setResourceName($name) {
|
|
$this->share['name'] = $name;
|
|
}
|
|
|
|
/**
|
|
* set resource type (e.g. file, calendar, contact,...)
|
|
*
|
|
* @param string $resourceType
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function setResourceType($resourceType) {
|
|
$this->share['resourceType'] = $resourceType;
|
|
}
|
|
|
|
/**
|
|
* set resource description (optional)
|
|
*
|
|
* @param string $description
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function setDescription($description) {
|
|
$this->share['description'] = $description;
|
|
}
|
|
|
|
/**
|
|
* set provider ID (e.g. file ID)
|
|
*
|
|
* @param string $providerId
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function setProviderId($providerId) {
|
|
$this->share['providerId'] = (string)$providerId;
|
|
}
|
|
|
|
/**
|
|
* set owner UID
|
|
*
|
|
* @param string $owner
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function setOwner($owner) {
|
|
$this->share['owner'] = $owner;
|
|
}
|
|
|
|
/**
|
|
* set owner display name
|
|
*
|
|
* @param string $ownerDisplayName
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function setOwnerDisplayName($ownerDisplayName) {
|
|
$this->share['ownerDisplayName'] = $ownerDisplayName;
|
|
}
|
|
|
|
/**
|
|
* set UID of the user who sends the share
|
|
*
|
|
* @param string $sharedBy
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function setSharedBy($sharedBy) {
|
|
$this->share['sharedBy'] = $sharedBy;
|
|
$this->share['sender'] = $sharedBy;
|
|
}
|
|
|
|
/**
|
|
* set display name of the user who sends the share
|
|
*
|
|
* @param $sharedByDisplayName
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function setSharedByDisplayName($sharedByDisplayName) {
|
|
$this->share['sharedByDisplayName'] = $sharedByDisplayName;
|
|
$this->share['senderDisplayName'] = $sharedByDisplayName;
|
|
}
|
|
|
|
/**
|
|
* set protocol specification
|
|
*
|
|
* @param array $protocol
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function setProtocol(array $protocol) {
|
|
$this->share['protocol'] = $protocol;
|
|
}
|
|
|
|
/**
|
|
* share type (group or user)
|
|
*
|
|
* @param string $shareType
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function setShareType($shareType) {
|
|
if ($shareType === 'group' || $shareType === IShare::TYPE_REMOTE_GROUP) {
|
|
$this->share['shareType'] = 'group';
|
|
} else {
|
|
$this->share['shareType'] = 'user';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* get the whole share, ready to send out
|
|
*
|
|
* @return array
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function getShare() {
|
|
return $this->share;
|
|
}
|
|
|
|
/**
|
|
* get uid of the recipient
|
|
*
|
|
* @return string
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function getShareWith() {
|
|
return $this->share['shareWith'];
|
|
}
|
|
|
|
/**
|
|
* get resource name (e.g. file, calendar, contact,...)
|
|
*
|
|
* @return string
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function getResourceName() {
|
|
return $this->share['name'];
|
|
}
|
|
|
|
/**
|
|
* get resource type (e.g. file, calendar, contact,...)
|
|
*
|
|
* @return string
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function getResourceType() {
|
|
return $this->share['resourceType'];
|
|
}
|
|
|
|
/**
|
|
* get resource description (optional)
|
|
*
|
|
* @return string
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function getDescription() {
|
|
return $this->share['description'];
|
|
}
|
|
|
|
/**
|
|
* get provider ID (e.g. file ID)
|
|
*
|
|
* @return string
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function getProviderId() {
|
|
return $this->share['providerId'];
|
|
}
|
|
|
|
/**
|
|
* get owner UID
|
|
*
|
|
* @return string
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function getOwner() {
|
|
return $this->share['owner'];
|
|
}
|
|
|
|
/**
|
|
* get owner display name
|
|
*
|
|
* @return string
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function getOwnerDisplayName() {
|
|
return $this->share['ownerDisplayName'];
|
|
}
|
|
|
|
/**
|
|
* get UID of the user who sends the share
|
|
*
|
|
* @return string
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function getSharedBy() {
|
|
return $this->share['sharedBy'];
|
|
}
|
|
|
|
/**
|
|
* get display name of the user who sends the share
|
|
*
|
|
* @return string
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function getSharedByDisplayName() {
|
|
return $this->share['sharedByDisplayName'];
|
|
}
|
|
|
|
/**
|
|
* get share type (group or user)
|
|
*
|
|
* @return string
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function getShareType() {
|
|
return $this->share['shareType'];
|
|
}
|
|
|
|
/**
|
|
* get share Secret
|
|
*
|
|
* @return string
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function getShareSecret() {
|
|
$protocol = $this->share['protocol'];
|
|
if (isset($protocol['options']['sharedSecret'])) {
|
|
return $protocol['options']['sharedSecret'];
|
|
}
|
|
|
|
if (isset($protocol['name'])) {
|
|
$protocolName = $protocol['name'];
|
|
// New single-protocol format: the secret lives under the protocol name.
|
|
if (isset($protocol[$protocolName]['sharedSecret']) && is_string($protocol[$protocolName]['sharedSecret'])) {
|
|
return $protocol[$protocolName]['sharedSecret'];
|
|
}
|
|
// Multi-protocol envelope (name => 'multi'): the secret lives in one of
|
|
// the sibling protocol entries, which all carry the same share secret.
|
|
foreach ($protocol as $key => $value) {
|
|
if ($key === 'name' || $key === 'options' || !is_array($value)) {
|
|
continue;
|
|
}
|
|
if (isset($value['sharedSecret']) && is_string($value['sharedSecret'])) {
|
|
return $value['sharedSecret'];
|
|
}
|
|
}
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* get protocol specification
|
|
*
|
|
* @return array
|
|
*
|
|
* @since 14.0.0
|
|
*/
|
|
#[\Override]
|
|
public function getProtocol() {
|
|
return $this->share['protocol'];
|
|
}
|
|
}
|