aboutsummaryrefslogtreecommitdiffstats
path: root/apps/dav/lib/Connector/Sabre
diff options
context:
space:
mode:
authorMaxence Lange <maxence@artificial-owl.com>2023-11-14 10:01:29 -0100
committerArthur Schiwon <blizzz@arthur-schiwon.de>2023-11-14 14:38:53 +0100
commit847c687a06ccd968936e5e6ed249840180c8e187 (patch)
tree4eb88b1ca5b212712cc7435e9cb3e1f65f620b79 /apps/dav/lib/Connector/Sabre
parent281ac508694d66a1598dc76a60480b81e88cab67 (diff)
downloadnextcloud-server-847c687a06ccd968936e5e6ed249840180c8e187.tar.gz
nextcloud-server-847c687a06ccd968936e5e6ed249840180c8e187.zip
metadata must be set as editable for PROPPATCH
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
Diffstat (limited to 'apps/dav/lib/Connector/Sabre')
-rw-r--r--apps/dav/lib/Connector/Sabre/FilesPlugin.php154
1 files changed, 110 insertions, 44 deletions
diff --git a/apps/dav/lib/Connector/Sabre/FilesPlugin.php b/apps/dav/lib/Connector/Sabre/FilesPlugin.php
index c52805c9548..8c467f11d0c 100644
--- a/apps/dav/lib/Connector/Sabre/FilesPlugin.php
+++ b/apps/dav/lib/Connector/Sabre/FilesPlugin.php
@@ -35,10 +35,10 @@
namespace OCA\DAV\Connector\Sabre;
use OC\AppFramework\Http\Request;
-use OC\FilesMetadata\Model\MetadataValueWrapper;
use OCP\Constants;
use OCP\Files\ForbiddenException;
use OCP\Files\StorageNotAvailableException;
+use OCP\FilesMetadata\Exceptions\FilesMetadataException;
use OCP\FilesMetadata\Exceptions\FilesMetadataNotFoundException;
use OCP\FilesMetadata\IFilesMetadataManager;
use OCP\FilesMetadata\Model\IMetadataValueWrapper;
@@ -530,9 +530,34 @@ class FilesPlugin extends ServerPlugin {
return true;
});
+ $this->handleUpdatePropertiesMetadata($propPatch, $node);
- /** @var IFilesMetadataManager */
- $filesMetadataManager = \OCP\Server::get(IFilesMetadataManager::class);
+ /**
+ * Disable modification of the displayname property for files and
+ * folders via PROPPATCH. See PROPFIND for more information.
+ */
+ $propPatch->handle(self::DISPLAYNAME_PROPERTYNAME, function ($displayName) {
+ return 403;
+ });
+ }
+
+
+ /**
+ * handle the update of metadata from PROPPATCH requests
+ *
+ * @param PropPatch $propPatch
+ * @param Node $node
+ *
+ * @throws FilesMetadataException
+ */
+ private function handleUpdatePropertiesMetadata(PropPatch $propPatch, Node $node): void {
+ $userId = $this->userSession->getUser()?->getUID();
+ if (null === $userId) {
+ return;
+ }
+
+ $accessRight = $this->getMetadataFileAccessRight($node, $userId);
+ $filesMetadataManager = $this->initFilesMetadataManager();
$knownMetadata = $filesMetadataManager->getKnownMetadata();
foreach ($propPatch->getRemainingMutations() as $mutation) {
@@ -540,55 +565,96 @@ class FilesPlugin extends ServerPlugin {
continue;
}
- $propPatch->handle($mutation, function (mixed $value) use ($knownMetadata, $node, $mutation, $filesMetadataManager): bool {
- $metadata = $filesMetadataManager->getMetadata((int)$node->getFileId(), true);
- $metadataKey = substr($mutation, strlen(self::FILE_METADATA_PREFIX));
+ $propPatch->handle(
+ $mutation,
+ function (mixed $value) use ($accessRight, $knownMetadata, $node, $mutation, $filesMetadataManager): bool {
+ $metadata = $filesMetadataManager->getMetadata((int)$node->getFileId(), true);
+ $metadataKey = substr($mutation, strlen(self::FILE_METADATA_PREFIX));
- // If the metadata is unknown, it defaults to string.
- try {
- $type = $knownMetadata->getType($metadataKey);
- } catch (FilesMetadataNotFoundException) {
- $type = IMetadataValueWrapper::TYPE_STRING;
- }
+ // confirm metadata key is editable via PROPPATCH
+ if ($knownMetadata->getEditPermission($metadataKey) < $accessRight) {
+ throw new FilesMetadataException('you do not have enough rights to update \'' . $metadataKey . '\' on this node');
+ }
+
+ // If the metadata is unknown, it defaults to string.
+ try {
+ $type = $knownMetadata->getType($metadataKey);
+ } catch (FilesMetadataNotFoundException) {
+ $type = IMetadataValueWrapper::TYPE_STRING;
+ }
+
+ switch ($type) {
+ case IMetadataValueWrapper::TYPE_STRING:
+ $metadata->setString($metadataKey, $value, $knownMetadata->isIndex($metadataKey));
+ break;
+ case IMetadataValueWrapper::TYPE_INT:
+ $metadata->setInt($metadataKey, $value, $knownMetadata->isIndex($metadataKey));
+ break;
+ case IMetadataValueWrapper::TYPE_FLOAT:
+ $metadata->setFloat($metadataKey, $value);
+ break;
+ case IMetadataValueWrapper::TYPE_BOOL:
+ $metadata->setBool($metadataKey, $value, $knownMetadata->isIndex($metadataKey));
+ break;
+ case IMetadataValueWrapper::TYPE_ARRAY:
+ $metadata->setArray($metadataKey, $value);
+ break;
+ case IMetadataValueWrapper::TYPE_STRING_LIST:
+ $metadata->setStringList(
+ $metadataKey, $value, $knownMetadata->isIndex($metadataKey)
+ );
+ break;
+ case IMetadataValueWrapper::TYPE_INT_LIST:
+ $metadata->setIntList(
+ $metadataKey, $value, $knownMetadata->isIndex($metadataKey)
+ );
+ break;
+ }
+
+ $filesMetadataManager->saveMetadata($metadata);
- switch ($type) {
- case IMetadataValueWrapper::TYPE_STRING:
- $metadata->setString($metadataKey, $value, $knownMetadata->isIndex($metadataKey));
- break;
- case IMetadataValueWrapper::TYPE_INT:
- $metadata->setInt($metadataKey, $value, $knownMetadata->isIndex($metadataKey));
- break;
- case IMetadataValueWrapper::TYPE_FLOAT:
- $metadata->setFloat($metadataKey, $value);
- break;
- case IMetadataValueWrapper::TYPE_BOOL:
- $metadata->setBool($metadataKey, $value, $knownMetadata->isIndex($metadataKey));
- break;
- case IMetadataValueWrapper::TYPE_ARRAY:
- $metadata->setArray($metadataKey, $value);
- break;
- case IMetadataValueWrapper::TYPE_STRING_LIST:
- $metadata->setStringList($metadataKey, $value, $knownMetadata->isIndex($metadataKey));
- break;
- case IMetadataValueWrapper::TYPE_INT_LIST:
- $metadata->setIntList($metadataKey, $value, $knownMetadata->isIndex($metadataKey));
- break;
+ return true;
}
+ );
+ }
+ }
- $filesMetadataManager->saveMetadata($metadata);
- return true;
- });
+ /**
+ * init default internal metadata
+ *
+ * @return IFilesMetadataManager
+ */
+ private function initFilesMetadataManager(): IFilesMetadataManager {
+ /** @var IFilesMetadataManager $manager */
+ $manager = \OCP\Server::get(IFilesMetadataManager::class);
+ $manager->initMetadata('files-live-photo', IMetadataValueWrapper::TYPE_STRING, false, IMetadataValueWrapper::EDIT_REQ_OWNERSHIP);
+
+ return $manager;
+ }
+
+ /**
+ * based on owner and shares, returns the bottom limit to update related metadata
+ *
+ * @param Node $node
+ * @param string $userId
+ *
+ * @return int
+ */
+ private function getMetadataFileAccessRight(Node $node, string $userId): int {
+ if ($node->getOwner()?->getUID() === $userId) {
+ return IMetadataValueWrapper::EDIT_REQ_OWNERSHIP;
+ } else {
+ $filePermissions = $node->getSharePermissions($userId);
+ if ($filePermissions & Constants::PERMISSION_UPDATE) {
+ return IMetadataValueWrapper::EDIT_REQ_WRITE_PERMISSION;
+ }
}
- /**
- * Disable modification of the displayname property for files and
- * folders via PROPPATCH. See PROPFIND for more information.
- */
- $propPatch->handle(self::DISPLAYNAME_PROPERTYNAME, function ($displayName) {
- return 403;
- });
+ return IMetadataValueWrapper::EDIT_REQ_READ_PERMISSION;
}
+
+
/**
* @param string $filePath
* @param \Sabre\DAV\INode $node