Skip to content

Commit 16a0592

Browse files
authored
Merge pull request #2119 from pbiering/sharing-fix-get-bday
Sharing fix GET request on bday
2 parents 514850d + d496f9e commit 16a0592

4 files changed

Lines changed: 39 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## 3.7.3.dev
44
* Extension: expose RADICALE:version for authenticated users via PROPFIND
5+
* Fix: sharing: GET request on single item with bday conversion
56

67
## 3.7.2
78
* Fix: broken storage/mtime granularity detection on vfat

radicale/app/get.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,10 @@ def do_GET(self, environ: types.WSGIEnviron, base_prefix: str, path: str,
121121
elif limited_access:
122122
return httputils.NOT_ALLOWED
123123
else:
124-
content_type = xmlutils.OBJECT_MIMETYPES[item.name]
124+
if share and share['Conversion'] == "bday":
125+
content_type = xmlutils.MIMETYPES["VCALENDAR"]
126+
else:
127+
content_type = xmlutils.OBJECT_MIMETYPES[item.name]
125128
content_disposition = ""
126129
assert item.last_modified
127130
headers = {
@@ -130,9 +133,16 @@ def do_GET(self, environ: types.WSGIEnviron, base_prefix: str, path: str,
130133
"ETag": item.etag}
131134
if content_disposition:
132135
headers["Content-Disposition"] = content_disposition
133-
if isinstance(item, storage.BaseCollection) and share and share['Conversion'] == "bday":
134-
# convert VCF to ICS
135-
answer = item.serialize(vcf_to_ics=True)
136+
if share and share['Conversion'] == "bday":
137+
if isinstance(item, storage.BaseCollection):
138+
# convert VCF to ICS
139+
answer = item.serialize(vcf_to_ics=True)
140+
else:
141+
item_converted = item.convert_vcf_to_ics()
142+
if item_converted is not None:
143+
answer = item_converted.serialize()
144+
else:
145+
return httputils.NOT_FOUND
136146
else:
137147
answer = item.serialize()
138148
return client.OK, headers, answer, None

radicale/sharing/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,9 @@ def sharing_collection_by_map_resolver(self, path: str, user: str) -> Union[dict
497497
logger.info("sharing/%s: resolved path %r->%r, user %r->%r not enabled by user", "map", path, result['PathMapped'], user, result['Owner'])
498498
return {'error': 'map-not-enabled'}
499499

500+
if result['Conversion'] == "bday" and result['PathMapped'].endswith(".ics"):
501+
result['PathMapped'] = result['PathMapped'].removesuffix(".ics") + ".vcf"
502+
500503
logger.info("sharing/%s: resolved path %r->%r, user %r->%r, Permissions=%r Conversion=%r", "map", path, result['PathMapped'], user, result['Owner'], result['Permissions'], result['Conversion'])
501504
return result
502505

radicale/tests/test_sharing.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4838,6 +4838,27 @@ def test_sharing_api_map_vcf_bday_basic(self) -> None:
48384838
assert path_shared_r + "contact3-with-bday.ics" in responses
48394839
assert path_shared_r + "contact1.ics" not in responses
48404840

4841+
# verify content as user
4842+
logging.info("\n*** GET item as user -> ok")
4843+
_, headers, answer = self.request("GET", path_shared_r + "contact2-with-bday.ics", login="user:userpw")
4844+
logging.debug("resonse: %r", answer)
4845+
assert "BEGIN:VCARD" not in answer
4846+
assert "BEGIN:VCALENDAR" in answer
4847+
assert "RRULE:FREQ=YEARLY" in answer
4848+
assert "DTSTART;VALUE=DATE:19700101" in answer
4849+
assert "DTEND;VALUE=DATE:19700102" in answer
4850+
assert "TRANSP:TRANSPARENT" in answer
4851+
assert "DESCRIPTION:BDAY=1970-01-01" in answer
4852+
# content type must be adjusted
4853+
assert 'Content-Type' in headers
4854+
assert 'text/calendar' in headers['Content-Type']
4855+
# title from Properties
4856+
assert 'Content-Disposition' not in headers
4857+
4858+
# get a single item which is not exsting on conversion
4859+
logging.info("\n*** GET item as user -> ok")
4860+
_, headers, answer = self.request("GET", path_shared_r + "contact1.ics", login="user:userpw", check=404)
4861+
48414862
# timerange filter elements as user
48424863
logging.info("\n*** REPORT collection entries with timerange user -> ok")
48434864
_, responses = self.report(path_shared_r, """\

0 commit comments

Comments
 (0)