Better freebusy occurrence limit handling and added documentation

This commit is contained in:
Ray 2024-08-16 14:57:30 -06:00
parent 3cba4b32a3
commit 408a03a3c0
4 changed files with 35 additions and 1 deletions

View file

@ -1023,6 +1023,18 @@ RabbitMQ queue type for the topic.
Default: classic Default: classic
#### reporting
##### max_freebusy_occurrence
When returning a free-busy report, a list of busy time occurrences are
generated based on a given time frame. Large time frames could
generate a lot of occurrences based on the time frame supplied. This
setting limits the lookup to prevent potential denial of service
attacks on large time frames. If the limit is reached, an HTTP error
is thrown instead of returning the results.
Default: 10000
## Supported Clients ## Supported Clients
Radicale has been tested with: Radicale has been tested with:

6
config
View file

@ -172,3 +172,9 @@
#rabbitmq_endpoint = #rabbitmq_endpoint =
#rabbitmq_topic = #rabbitmq_topic =
#rabbitmq_queue_type = classic #rabbitmq_queue_type = classic
[reporting]
# When returning a free-busy report, limit the number of returned
# occurences per event to prevent DOS attacks.
#max_freebusy_occurrence = 10000

View file

@ -117,10 +117,18 @@ def free_busy_report(base_prefix: str, path: str, xml_request: Optional[ET.Eleme
# TODO: coalesce overlapping periods # TODO: coalesce overlapping periods
if max_occurrence > 0:
n_occurrences = max_occurrence+1
else:
n_occurrences = 0
occurrences = radicale_filter.time_range_fill(item.vobject_item, occurrences = radicale_filter.time_range_fill(item.vobject_item,
time_range_element, time_range_element,
"VEVENT", "VEVENT",
n=max_occurrence) n=n_occurrences)
if len(occurrences) >= max_occurrence:
raise ValueError("FREEBUSY occurrences limit of {} hit"
.format(max_occurrence))
for occurrence in occurrences: for occurrence in occurrences:
vfb = cal.add('vfreebusy') vfb = cal.add('vfreebusy')
vfb.add('dtstamp').value = item.vobject_item.vevent.dtstamp.value vfb.add('dtstamp').value = item.vobject_item.vevent.dtstamp.value

View file

@ -1392,6 +1392,14 @@ permissions: RrWw""")
types[fbtype_val] += 1 types[fbtype_val] += 1
assert types == {'BUSY': 2, 'FREE': 1} assert types == {'BUSY': 2, 'FREE': 1}
# Test max_freebusy_occurrence limit
self.configure({"reporting": {"max_freebusy_occurrence": 1}})
code, responses = self.report(calendar_path, """\
<?xml version="1.0" encoding="utf-8" ?>
<C:free-busy-query xmlns:C="urn:ietf:params:xml:ns:caldav">
<C:time-range start="20130901T140000Z" end="20130908T220000Z"/>
</C:free-busy-query>""", 400, is_xml=False)
def _report_sync_token( def _report_sync_token(
self, calendar_path: str, sync_token: Optional[str] = None self, calendar_path: str, sync_token: Optional[str] = None
) -> Tuple[str, RESPONSES]: ) -> Tuple[str, RESPONSES]: