[Bug]: Files metadata can only be set one value at a time via PROPPATCH
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 36.9k
- Forks
- 5.2k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 713
Description
⚠️ This issue respects the following points: ⚠️
- This is a bug, not a question or a configuration/webserver/proxy issue.
- This issue is not already reported on Github OR Nextcloud Community Forum (I've searched it).
- Nextcloud Server is up to date. See Maintenance and Release Schedule for supported versions.
- I agree to follow Nextcloud's Code of Conduct.
Bug description
I have some custom metadata set up in my application's boot() method, as per documentation:
$metadataManager->initMetadata('prop1', IMetadataValueWrapper::TYPE_STRING, false, IMetadataValueWrapper::EDIT_REQ_WRITE_PERMISSION);
$metadataManager->initMetadata('prop2', IMetadataValueWrapper::TYPE_STRING, false, IMetadataValueWrapper::EDIT_REQ_WRITE_PERMISSION);
Assuming that both props get set to a changed value, when I send a PROPPATCH request like this:
<?xml version="1.0" encoding="UTF-8"?>
<d:propertyupdate xmlns:d="DAV:" xmlns:nc="http://nextcloud.org/ns">
<d:set>
<d:prop>
<nc:metadata-prop1>"value1"</nc:metadata-prop1>
<nc:metadata-prop2>"value2"</nc:metadata-prop2>
</d:prop>
</d:set>
</d:propertyupdate>
the request fails:
you do not have enough rights to update 'prop2' on this node
Metadata is left in half-written state: prop1 is updated, trying to update prop2 leads to the error despite having write permission.
The exception occurs in apps/dav/lib/Connector/Sabre/FilesPlugin.php. At the bottom of handleUpdatePropertiesMetadata(), metadata is written once per entry, but $metadata is initialized with incorrect permissions: editPermission is always 0 regardless of the default set by initMetadata(). This subsequently overwrites the global configuration in oc_appconfig. When prop2 is updated, this incorrect config is read in again, leading to the exception.
The permissions get fixed the next time boot() is invoked, but for the rest of the request, configured permissions are lost unless reinitialized by a concurrent request.
I don't know how to fix this properly, but here are some thoughts:
- setString() et al. create a new value object with editPermission set to 0. Shouldn't this be the configured default from initMetadata()?
- Writing values one by one is inefficient and leads to half-written state in case of an error. This could be avoided by preparing the metadata object and only writing once in bulk when preparation is complete.
- Repeatedly reading and writing config to oc_appconfig looks superfluous to me.
Steps to reproduce
- Set up at least 2 writable metadata (example above)
- Send PROPPATCH request that sets new values for both metadata (example above)
Expected behavior
Both values should be updated without error. Global configuration in oc_appconfig should remain unchanged.
Installation method
Community Manual installation with Archive
Nextcloud Server version
28
Operating system
Other
PHP engine version
PHP 8.2
Web server
Apache (supported)
Database engine version
PostgreSQL
Is this bug present after an update or on a fresh install?
None
Are you using the Nextcloud Server Encryption module?
None
What user-backends are you using?
- Default user-backend (database)
- LDAP/ Active Directory
- SSO - SAML
- Other
Configuration report
No response
List of activated Apps
No response
Nextcloud Signing status
No response
Nextcloud Logs
No response
Additional info
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in apps/dav/lib/Connector/Sabre/FilesPlugin.php, especially handleUpdatePropertiesMetadata(), and trace metadata initialization through initMetadata() and setString(). Reproduce the multi-property PROPPATCH with two writable metadata fields, then inspect how editPermission is read and written to oc_appconfig. Done means both values update successfully without changing the configured permissions or leaving a half-written state.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100