Merge pull request #2170 from arkj/fix-map-share-href-encoding

sharing: make share-href backmap URL-encode-aware (fixes editing shared collections for '@' principals)
This commit is contained in:
Peter Bieringer
2026-06-24 07:41:21 +03:00
committed by GitHub
3 changed files with 10 additions and 6 deletions

View File

@@ -3,6 +3,7 @@
## 3.7.6.dev
* Extension: item verification on commandline
* Improvement: catch lack of support of PERIOD in vobject <= 0.9.9
* Fix: sharing: backmap of REPORT/PROPPATCH hrefs is now URL-encode-aware (edit of a shared collection failed when the principal contains '@')
## 3.7.5
* Add: [sharing] conversion_bday_summary_template (customize summary)

View File

@@ -25,6 +25,7 @@ import socket
import xml.etree.ElementTree as ET
from http import client
from typing import Dict, Optional, Union, cast
from urllib.parse import quote
import defusedxml.ElementTree as DefusedET
@@ -49,8 +50,8 @@ def xml_proppatch(base_prefix: str, path: str,
href = ET.Element(xmlutils.make_clark("D:href"))
href.text = xmlutils.make_href(base_prefix, path)
if share:
# backmap
href.text = href.text.replace(share['PathMapped'], share['PathOrToken'])
# backmap; quote so the encoded href and raw share path compare
href.text = href.text.replace(quote(share['PathMapped']), quote(str(share['PathOrToken'])))
response.append(href)
# Create D:propstat element for props with status 200 OK
propstat = ET.Element(xmlutils.make_clark("D:propstat"))

View File

@@ -31,7 +31,7 @@ import xml.etree.ElementTree as ET
from http import client
from typing import (Callable, Iterable, Iterator, List, Optional, Sequence,
Tuple, Union)
from urllib.parse import unquote, urlparse
from urllib.parse import quote, unquote, urlparse
import vobject
import vobject.base
@@ -741,9 +741,11 @@ def xml_item_response(base_prefix: str, href: str,
href_element.text = xmlutils.make_href(base_prefix, href)
logger.trace("REPORT/xml_report: href=%r base_prefix=%r", href_element.text, base_prefix)
if share:
# backmap
if href_element.text.startswith(base_prefix + share['PathMapped']):
href_element.text = base_prefix + str(share['PathOrToken']) + href_element.text.removeprefix(base_prefix + share['PathMapped'])
# backmap; quote so the encoded href and raw share path compare
mapped = quote(share['PathMapped'])
token = quote(str(share['PathOrToken']))
if href_element.text.startswith(base_prefix + mapped):
href_element.text = base_prefix + token + href_element.text.removeprefix(base_prefix + mapped)
if share_bday_automap and href_element.text.endswith(".vcf"):
href_element.text = href_element.text.removesuffix(".vcf") + ".ics"
logger.trace("REPORT/xml_report: href=%r (backmapped)", href_element.text)