# Changelog

## 3.7.8
* Fix: time-range filter on a VTODO having DTSTART/DUE and also CREATED/COMPLETED used the CREATED->COMPLETED duration instead of the DTSTART->DUE one, so completed tasks were missing from (or wrongly returned by) calendar-query REPORT results
* Fix: sharing/proppatch: reject in case of write-access but 'p' is in permissions
* Fix: sharing/by-map: catch collection path without trailing / (supporting "pimsync")
* Add: [report] max_expand_occurrence option to separate from max_freebusy_occurrence
* Add: [system] max_vevent_rrule_occurrence option to catch DoS by problematic RRULE early enough (workaround for missing protection in current vobject version)

## 3.7.7
* Fix: web plugin helpers httputils.serve_resource/serve_folder ignored their mimetypes and fallback_mimetype parameters and always used the built-in mapping, so custom web plugins could not serve additional file types with a correct Content-Type
* Fix: free-busy REPORT always failed with HTTP 400 ("FREEBUSY occurrences limit of 0 hit") when [reporting] max_freebusy_occurrence is set to 0 (limit disabled), because the limit check did not honor the disabled limit
* Fix: time-range filter treated a VEVENT with a whole-day DURATION (e.g. P1D, P2D) as zero-length (timedelta.seconds instead of total_seconds), so such events were missing from calendar-query REPORT results
* Fix: calendar-data expand (REPORT) left recurrence properties (e.g. RDATE) on the expanded single-occurrence VEVENTs; a single try/except around the sequential delattr() calls stopped at the first absent property (e.g. missing EXDATE), so later ones were never removed
* Fix: text-match filter on a structured property (e.g. vCard N or ADR) crashed with HTTP 500 (AttributeError: 'Name'/'Address' object has no attribute 'lower') because vobject parses these into non-string objects; their text representation is now used
* Fix: sharing bday-to-ICS conversion assigned the empty-FN fallback marker to the {nickname} placeholder instead of {fn}, so a VCARD with an empty FN got its NICKNAME overwritten with "!fn!" in the generated SUMMARY/DESCRIPTION and the {fn} fallback never resolved
* Fix: sharing/delete: add forgotten backmap

## 3.7.6
* 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 '@')
* Workaround: remove trailing spaces on TZID and TZNAME appended by buggy Microsoft clients
* Extension: [auth] imap_append_domain option (optional)

## 3.7.5
* Add: [sharing] conversion_bday_summary_template (customize summary)
* Add: [sharing] conversion_bday_description_template (customize description)
* Add: [sharing] conversion_bday_alarm_trigger_template (customize alarms)
* Add: [sharing] conversion_bday_categories (customize)
* Add: [sharing] conversion_bday_age_max (limit in case of "age" placeholder is used which blocks using RRULE)
* Extension: [sharing/bday conversion]: add STATUS + CLASS fields
* Improve: sanitize item align timezone (add/remove) of EXDATE or RDATE with DTSTART
* Fix: sharing: bday conversion backmap on PROPFIND/REPORT if script_name is active (via reverse proxy)

## 3.7.4
* Fix: sharing: PROPFIND returns now empty owner element in case of a mapped share as clients try PROPFIND on this not accessable href
* Improve: sharing: PROPFIND returns also privilege "write" in case "write-content" and "write-properties" is permitted
* Extension: WebUI dark theme with automatic browser/OS color scheme detection
* Fix: WebUI hide copy button in insecure environments
* Improve: WebUI decode URL in text field for better readability
* Fix: sharing: bday conversion hrefs for vCard filenames ending in v/c/f
* Add: [web] prefer_browser_login option

## 3.7.3
* Extension: expose RADICALE:version for authenticated users via PROPFIND
* Fix: sharing: GET request on single item with bday conversion
* Fix: sharing: PROPFIND response on single item with bday conversion
* Fix: sharing: PROPFIND response related to C:supported-calendar-component-set
* Feature: conditional log of request/response header/content by new options *_on_notice_condition
* Fix: user/path validation related to 'unicode-letter'

## 3.7.2
* Fix: broken storage/mtime granularity detection on vfat
* Improve: `path_to_filesystem()` by pre-detection of collision-free file system
* Adjustment: MKCOL/MKCALENDAR return now CONFLICT instead of BADREQUEST of file name collision
* Improve: [auth] catch bcrypt>=5.0.0 enforced max password length early and support legacy "passlib" as well as "libpass" (rework 3.6.0, "packaging" not needed anymore)
* Improve: application will stop on startup if TEMP is provided but not existing or not writable
* Extension: tox with new optional test cases to test with LinuxOS vfat, hfsplus, ntfs filesystems
* Adjust: respond with 500 in case principal collection cannot be created (e.g. filesystem issues)
* Improve: sharing supports now unicode
* Add: [server] new options validate_user_value/validate_path_value for ability to block unwanted values (autoenable "strict" on non-unicode filesystem)
* Adjust: several log levels incl. final result depending on status code
* Fix: sharing/csv: quote handling and honor stock encoding
* Extension: sharing: add ICAL:calendar-order to property overlay whitelist
* Extension: extend hook data with 'actor' to keep original 'user' before mapping a share
* Improve: WebUI (general and relating to sharing)

## 3.7.1
* Fix: share address book collection as birthday calendar not working on non-DEBUG level
* Extension: share accept now PATH and USER for matching email addresses as well
* Adjustment: replace logging/trace_on_debug by new log level "trace"
* Adjustment: sharing/token: adjust default permissions to "rp"
* Fix: sharing/propfind+proppatch: permission check related to properties
* Fix: hook/email: add support for date-only events
* Extension: hook/email: in case of mass-email was enabled but only one attendee fall-back to non-mass-email
* Fix: prevent login variable overwrite during failed cache cleanup
* Fix: performance improvement of `path_to_filesystem()` in 3.7.0 caused unexpected issue in case of softlinks are used
* Fix: sharing/delete: trigger storage hook
* Fix: WebUI generic and related to sharing

## 3.7.0

* Feature: collection sharing by map or token incl. management API and WebUI extension
* Feature: share address book collection as birthday calendar
* Add: [auth] oauth2: allow custom client_id and client_secret (optional)
* Cleanup: deprecate config option 'ldap_use_ssl' for good
* Cleanup: WebUI is now split into smaller javascript files
* Cleanup: WebUI is now fit for strict content security policy
* Cleanup: WebUI: Simplified Caching and Navigation internally
* Cleanup: WebUI: Unified error handling
* Cleanup: Added integration test for verification of end-to-end behavior of WebUI
* Performance: improve `path_to_filesystem()`
* Performance: preload access rights from file
* Add: [server] delay_on_error option
* Add: [logging] limit_content option
* Add: [headers] Content-Security-Policy is now set to be strict on new configs
* Improve: [server] max_resource_size is now also checked on storage discover+get to avoid issues with items stored outside using PUT
* Improve: hook preparation (check whether enabled, early skip if not VCALENDAR)

## 3.6.1

* Fix: MOVE failing with URL-encoded destination header
* Improve: add workaround to remove empty lines in item to avoid reject by vobject parser
* Improve: check/enforce RECURRENCE-ID MUST have the same value type as DTSTART in the recurring component (RFC 5545 3.8.4.4)
* Fix: RECURRENCE-ID comparison on all-day events
* Fix: format_ut problem on 32-bit systems (got lost in between since fixed in 3.5.8)
* Maintain: Refactor Web UI Javascript into separate files
* Maintain: code preparation for upcoming "sharing" extension and optimizations
* Improve: check if hook is enabled before constructing hook notification items
* Fix: skip by early exit email hook if notification item is not a VCALENDAR

## 3.6.0

* Extend: logwatch script
* Extend: [logging] bad_put_request_content: log checksum and hexdump of request on debug level
* Extend: [logging] request_content_on_debug: log checksum of request on debug level
* Extend: add command line option "--verify-item <file>" for dedicated item file analysis
* Extend: PROPFIND response for VADDRESSBOOK with "CR:supported-address-data" and "CS:getctag"
* Extend: conditionally announce vCard 4.0 in case vobject version is >= 1.0.0
* Fix: hook for server-side e-mail notification
* Change: dependency PyPI/passlib (stale since 2020) replaced with PyPI/libpass >= 1.9.3
* Extend: add a check whether bcrypt version is compatible with passlib(libpass) version (requires "packaging")
* Improve: autodetection of hashes in htpasswd (SHA256/SHA512 "rounds" are now supported)

## 3.5.10
* Improve: logging of broken calendar items during PUT
* Add: logging of broken contact items during PUT
* Extend: [auth] imap: add fallback support for LOGIN towards remote IMAP server (replaced in 3.5.0)
* Fix: improper detection of HTTP_X_FORWARDED_PORT on MOVE
* Extend: [logging] with profiling log per request or regular per request method
* Add: [logging] option to log response header on debug loglevel
* Adjust: [logging] header/content debug log intended by space to be skipped by logwatch
* Improve: remove unnecessary open+read for mtime+size cache
* Extend: add selected XML query properties to request result log line for improved timing analysis incl. logwatch support
* Add: [server] max_resource_size option
* Add: support PROPFIND/max-resource-size by max_resource_size (capped to 80% of max_content_length)

## 3.5.9
* Extend: [auth] add support for type http_remote_user
* Extend: logging of invalid sync-token with user, path, remote host and useragent
* Fix: typo related to collection delete hook

## 3.5.8
* Extend: [auth] re-factor & overhaul LDAP authentication, especially for Python's ldap module
* Fix: out-of-range timestamp on 32-bit systems
* Feature: extend logging with response size in bytes and flag served as plain or gzip
* Feature: [storage] strict_preconditions: new config option to enforce strict preconditions check on PUT in case item already exists [RFC6352#9.2]
* Fix: format_ut problem on 32-bit systems
* Doc: Telugu translation

## 3.5.7
* Extend: [auth] dovecot: add support for version >= 2.4
* Fix: report/getetag with enabled expand
* Adjust: use of option [auth] ldap_ignore_attribute_create_modify_timestamp for support of Authentik LDAP server

## 3.5.6
* Fix: broken start when UID does not exist (potential container startup case)
* Improve: user/group retrievement for running service and directories
* Extend/Improve: [auth] ldap: group membership lookup
* Add: [auth] remote_ip_source: set the remote IP source for auth algorithms

## 3.5.5
* Improve: [auth] ldap: do not read server info by bind to avoid needless network traffic
* Fix: [storage] broken support of 'folder_umask'
* Improve: add details about platform and effective user on startup
* Improve: display owner+permissions on directories on startup, extend error message in case of missing permissions
* Feature: add hook for server-side e-mail notification
* Fix: logging ignores not retrievable get_native_id if not supported by OS
* Fix: report with enabled expand honors now provided filter proper
* Improve: add options [logging] trace_on_debug and trace_filter for supporting trace logging
* Fix: catch case where getpwuid is not returning a username
* Fix: add support for query without comp-type
* Fix: expanded event with dates are missing VALUE=DATE
* Add: [hook] dryrun: option to disable real hook action for testing, add tests for email+rabbitmq
* Fix: storage hook path now added to DELETE, MKCOL, MKCALENDAR, MOVE, and PROPPATCH
* Add: storage hook placeholder now supports "request" and "to_path" (MOVE only)
* Improve: catch items having tzinfo only on dtstart or dtend set for whatever reason, overtake tzinfo from the other one
* Improve: conditional log level for base_prefix strip action depending on auth and web type

## 3.5.4
* Improve: item filter enhanced for 3rd level supporting VALARM and honoring TRIGGER (offset or absolute)
* Enhancement: add Caddy config file example (see contrib directory)

## 3.5.3
* Add: [auth] htpasswd: support for Argon2 hashes
* Improve: catch error on calendar collection upload and display problematic item content on debug level
* Add: [auth] urldecode_username: optional decode provided username (e.g. encoded email address)

## 3.5.2
* Adjust: [auth] ldap: use ldap_user_attr either first element of list or directly 
* Fix: use value of property for time range filter
* Add: [auth] ldap: option ldap_security (none, startls, tls) for additional support of STARTTLS, deprecate ldap_use_ssl
* Fix: return 204 instead of 201 in case PUT updates an item
* Extend: log PYTHONPATH on startup if found in environment

## 3.5.1
* Fix: auth/htpasswd related to detection and use of bcrypt
* Add: option [auth] ldap_ignore_attribute_create_modify_timestamp for support of Authentik LDAP server
* Extend: [storage] hook supports now placeholder for "cwd" and "path" (and catches unsupported placeholders)
* Fix: location of lock file for in case of dedicated cache folder is activated
* Extend: log and create base folders if not existing during startup
* Adjust: [auth] ldap: use ldap_user_attr as string

## 3.5.0

* Add: option [auth] type oauth2 by code migration from https://gitlab.mim-libre.fr/alphabet/radicale_oauth/-/blob/dev/oauth2/
* Fix: catch OS errors on PUT MKCOL MKCALENDAR MOVE PROPPATCH (insufficient storage, access denied, internal server error)
* Test: skip bcrypt related tests if module is missing
* Improve: relax mtime check on storage filesystem, change test file location to "collection-root" directory
* Add: option [auth] type pam by code migration from v1, add new option pam_serivce
* Cosmetics: extend list of used modules with their version on startup
* Improve: WebUI
* Add: option [server] script_name for reverse proxy base_prefix handling
* Fix: proper base_prefix stripping if running behind reverse proxy
* Review: Apache reverse proxy config example
* Add: on-the-fly link activation and default content adjustment in case of bundled InfCloud (tested with 0.13.1)
* Adjust: [auth] imap: use AUTHENTICATE PLAIN instead of LOGIN towards remote IMAP server
* Improve: log client IP on SSL error and SSL protocol+cipher if successful
* Improve: catch htpasswd hash verification errors
* Improve: add support for more bcrypt algos on autodetection, extend logging for autodetection fallback to PLAIN in case of hash length is not matching
* Add: warning in case of started standalone and not listen on loopback interface but trusting external authentication
* Adjust: Change default [auth] type from "none" to "denyall" for secure-by-default

## 3.4.1
* Add: option [auth] dovecot_connection_type / dovecot_host / dovecot_port
* Add: option [auth] type imap by code migration from https://github.com/Unrud/RadicaleIMAP/

## 3.4.0
* Add: option [auth] cache_logins/cache_successful_logins_expiry/cache_failed_logins for caching logins
* Improve: [auth] log used hash method and result on debug for htpasswd authentication
* Improve: [auth] htpasswd file now read and verified on start
* Add: option [auth] htpasswd_cache to automatic re-read triggered on change (mtime or size) instead reading on each request
* Improve: [auth] htpasswd: module 'bcrypt' is no longer mandatory in case digest method not used in file
* Improve: [auth] successful/failed login logs now type and whether result was taken from cache
* Improve: [auth] constant execution time for failed logins independent of external backend or by htpasswd used digest method
* Drop: support for Python 3.8
* Add: option [auth] ldap_user_attribute
* Add: option [auth] ldap_groups_attribute as a more flexible replacement of removed ldap_load_groups

## 3.3.3
* Add: display mtime_ns precision of storage folder with condition warning if too less
* Improve: disable fsync during storage verification
* Improve: suppress duplicate log lines on startup
* Contrib: logwatch config and script
* Improve: log precondition result on PUT request

## 3.3.2
* Fix: debug logging in rights/from_file
* Add: option [storage] use_cache_subfolder_for_item for storing 'item' cache outside collection-root
* Fix: ignore empty RRULESET in item
* Add: option [storage] filesystem_cache_folder for defining location of cache outside collection-root
* Add: option [storage] use_cache_subfolder_for_history for storing 'history' cache outside collection-root
* Add: option [storage] use_cache_subfolder_for_synctoken for storing 'sync-token' cache outside collection-root
* Add: option [storage] folder_umask for configuration of umask (overwrite system-default)
* Fix: also remove 'item' from cache on delete
* Improve: avoid automatically invalid cache on upgrade in case no change on cache structure
* Improve: log important module versions on startup
* Improve: auth.ldap config shown on startup, terminate in case no password is supplied for bind user
* Add: option [auth] uc_username for uppercase conversion (similar to existing lc_username)
* Add: option [logging] storage_cache_action_on_debug for conditional logging
* Fix: set PRODID on collection upload (instead of vobject is inserting default one)
* Add: option [storage] use_mtime_and_size_for_item_cache for changing cache lookup from SHA256 to mtime_ns + size
* Fix: buggy cache file content creation on collection upload

## 3.3.1

* Add: option [auth] type=dovecot
* Enhancement: log content in case of multiple main components error
* Fix: expand does not take timezones into account 
* Fix: expand does not support overridden recurring events
* Fix: expand does not honor start and end times
* Add: option [server] protocol + ciphersuite for optional restrictions on SSL socket
* Enhancement: [storage] hook documentation, logging, error behavior (no longer throwing an exception)

## 3.3.0

* Adjustment: option [auth] htpasswd_encryption change default from "md5" to "autodetect"
* Add: option [auth] type=ldap with (group) rights management via LDAP/LDAPS
* Enhancement: permit_delete_collection can be now controlled also per collection by rights 'D' or 'd'
* Add: option [rights] permit_overwrite_collection (default=True) which can be also controlled per collection by rights 'O' or 'o'
* Fix: only expand VEVENT on REPORT request containing 'expand'
* Adjustment: switch from setup.py to pyproject.toml (but keep files for legacy packaging)
* Adjustment: 'rights' file is now read only during startup
* Cleanup: Python 3.7 leftovers

## 3.2.3
* Add: support for Python 3.13
* Fix: Using icalendar's tzinfo on created datetime to fix issue with icalendar
* Fix: typos in code
* Enhancement: Added free-busy report
* Enhancement: Added 'max_freebusy_occurrences` setting to avoid potential DoS on reports
* Enhancement: remove unexpected control codes from uploaded items
* Enhancement: add 'strip_domain' setting for username handling
* Enhancement: add option to toggle debug log of rights rule with doesn't match
* Drop: remove unused requirement "typeguard"
* Improve: Refactored some date parsing code

## 3.2.2
* Enhancement: add support for auth.type=denyall (will be default for security reasons in upcoming releases)
* Enhancement: display warning in case only default config is active
* Enhancement: display warning in case no user authentication is active
* Enhancement: add option to skip broken item to avoid triggering exception (default: enabled)
* Enhancement: add support for predefined collections for new users
* Enhancement: add options to enable several parts in debug log like backtrace, request_header, request_content, response_content (default: disabled)
* Enhancement: rights/from_file: display resulting permission of a match in debug log
* Enhancement: add Apache config file example (see contrib directory)
* Fix: "verify-collection" skips non-collection directories, logging improved

## 3.2.1

* Enhancement: add option for logging bad PUT request content
* Enhancement: extend logging with step where bad PUT request failed
* Fix: support for recurrence "full day"
* Fix: list of web_files related to HTML pages
* Test: update/adjustments for workflows (pytest>=7, typeguard<4.3)

## 3.2.0

* Enhancement: add hook support for event changes+deletion hooks (initial support: "rabbitmq")
* Dependency: pika >= 1.1.0
* Enhancement: add support for webcal subscriptions
* Enhancement: major update of WebUI (design+features)
* Adjust: change default loglevel to "info"
* Enhancement: support "expand-property" on REPORT request
* Drop: support for Python 3.7 (EOSL, can't be tested anymore)
* Fix: allow quoted-printable encoding for vObjects

## 3.1.9

* Add: support for Python 3.11 + 3.12
* Drop: support for Python 3.6
* Fix: MOVE in case listen on non-standard ports or behind reverse proxy
* Fix: stricter requirements of Python 3.11
* Fix: HTML pages
* Fix: Main Component is missing when only recurrence id exists
* Fix: passlib don't support bcrypt>=4.1
* Fix: web login now proper encodes passwords containing %XX (hexdigits)
* Enhancement: user-selectable log formats
* Enhancement: autodetect logging to systemd journal
* Enhancement: test code
* Enhancement: option for global permit to delete collection
* Enhancement: auth type 'htpasswd' supports now 'htpasswd_encryption' sha256/sha512 and "autodetect" for smooth transition
* Improve: Dockerfiles
* Improve: server socket listen code + address format in log
* Update: documentations + examples
* Dependency: limit typegard version < 3
* General: code cosmetics

## 3.1.8

* Fix setuptools requirement if installing wheel
* Tests: Switch from `python setup.py test` to `tox`
* Small changes to build system configuration and tests

## 3.1.7

* Fix random href fallback

## 3.1.6

* Ignore `Not a directory` error for optional config paths
* Fix upload of whole address book/calendar with UIDs that collide on
  case-insensitive filesystem
* Remove runtime dependency on setuptools for Python>=3.9
* Windows: Block ADS paths

## 3.1.5

* Ignore configuration file if access is denied
* Use F_FULLFSYNC with PyPy on MacOS
* Fallback if F_FULLFSYNC is not supported by the filesystem

## 3.1.4

* Fallback if RENAME_EXCHANGE is not supported by the filesystem
* Assume POSIX compatibility if `sys.platform` is not `win32`

## 3.1.3

* Redirect '…/.well-known/caldav' and '…/.well-known/carddav' to base prefix
* Warning instead of error when base prefix ends with '/'

## 3.1.2

* Verify that base prefix starts with '/' but doesn't end with '/'
* Improve base prefix log message
* Never send body for HEAD requests (again)

## 3.1.1

* Workaround for contact photo bug in InfCloud
* Redirect GET and HEAD requests under `/.web` to sanitized path
* Set `Content-Length` header for HEAD requests
* Never send body for HEAD requests
* Improve error messages for `from_file` rights backend
* Don't sanitize WSGI script name

## 3.1.0

* Single `<D:propstat>` element in PROPPATCH response
* Allow multiple `<D:set>` and `<D:remove>` elements
* Improve log messages
* Fix date filter
* Improve sanitization of collection properties
* Cancel mkcalendar request on error
* Use **renameat2** on Linux for atomic overwriting of collections
* Command Line Parser
  * Disallow abbreviated arguments
  * Support backend specific options and HTTP headers
  * Optional argument for boolean options
  * Load no config file for `--config` without argument
* Allow float for server->timeout setting
* Fix **is-not-defined** filter in **addressbook-query** report
* Add python type hints
* Add **multifilesystem_nolock** storage
* Add support for Python 3.9 and 3.10
* Drop support for Python 3.5
* Fix compatibility with Evolution (Exceptions from recurrence rules)

## 3.0.6

* Allow web plugins to handle POST requests

## 3.0.5

* Start storage hook in own process group
* Kill storage hook on error or exit
* Try to kill child processes of storage hook
* Internal Server: Exit immediately when signal is received
  (do not wait for clients or storage hook to finish)

## 3.0.4

* Fix internal server on FreeBSD

## 3.0.3

* Fix internal server on OpenBSD

## 3.0.2

* Use 403 response for supported-report and valid-sync-token errors
* Internal server: Handle missing IPv6 support

## 3.0.1

* Fix XML error messages

## 3.0.0

This release is incompatible with previous releases.
See the upgrade checklist below.

* Parallel write requests
* Support PyPy
* Protect against XML denial-of-service attacks
* Check for duplicated UIDs in calendars/address books
* Only add missing UIDs for uploaded whole calendars/address books
* Switch from md5 to sha256 for UIDs and tokens
* Code cleanup:
  * All plugin interfaces were simplified and are incompatible with
    old plugins
  * Major refactor
  * Never sanitize paths multiple times (check if they are sanitized)
* Config
  * Multiple configuration files separated by `:` (resp. `;`
    on Windows)
  * Optional configuration files by prepending file path with `?`
  * Check validity of every configuration file and command line
    arguments separately
    * Report the source of invalid configuration parameters in
      error messages
  * Code cleanup:
    * Store configuration as parsed values
    * Use Schema that describes configuration and allow plugins to apply
      their own schemas
    * Mark internal settings with `_`
* Internal server
  * Bind to IPv4 and IPv6 address, when both are available for hostname
  * Set default address to `localhost:5232`
  * Remove settings for SSL ciphers and protocol versions (enforce safe
    defaults instead)
  * Remove settings for file locking because they are of little use
  * Remove daemonization (should be handled by service managers)
* Logging
  * Replace complex Python logger configuration with simple
    `logging.level` setting
  * Write PID and `threadName` instead of cryptic id's in log messages
  * Use `wsgi.errors` for logging (as required by the WSGI spec)
  * Code cleanup:
    * Don't pass logger object around (use `logging.getLogger()`
      instead)
* Auth
  * Use `md5` as default for `htpasswd_encryption` setting
  * Move setting `realm` from section `server` to `auth`
* Rights
  * Use permissions `RW` for non-leaf collections and `rw` for
    address books/calendars
  * New permission `i` that only allows access with HTTP method GET
    (CalDAV/CardDAV is susceptible to expensive search requests)
* Web
  * Add upload dialog for calendars/address books from file
  * Show startup loading message
  * Show warning if JavaScript is disabled
  * Pass HTML Validator
* Storage
  * Check for missing UIDs in items
  * Check for child collections in address books and calendars
  * Code cleanup:
    * Split BaseCollection in BaseStorage and BaseCollection

## Upgrade checklist

* Config
  * Some settings were removed
  * The default of `auth.htpasswd_encryption` changed to `md5`
  * The setting `server.realm` moved to `auth.realm`
  * The setting `logging.debug` was replaced by `logging.level`
  * The format of the `rights.file` configuration file changed:
    * Permission `r` replaced by `Rr`
    * Permission `w` replaced by `Ww`
    * New permission `i` added as subset of `r`
    * Replaced variable `%(login)s` by `{user}`
    * Removed variable `%(path)s`
    * `{` must be escaped as `{{` and `}` as `}}` in regexes
* File system storage
  * The storage format is compatible with Radicale 2.x.x
  * Run `radicale --verify-storage` to check for errors
* Custom plugins:
  * `auth` and `web` plugins require minor adjustments
  * `rights` plugins must be adapted to the new permission model
  * `storage` plugins require major changes

## 2.1.10 - Wild Radish

This release is compatible with version 2.0.0.

* Update required versions for dependencies
* Get `RADICALE_CONFIG` from WSGI environ
* Improve HTTP status codes
* Fix race condition in storage lock creation
* Raise default limits for content length and timeout
* Log output from hook

## 2.1.9 - Wild Radish

This release is compatible with version 2.0.0.

* Specify versions for dependencies
* Move WSGI initialization into module
* Check if `REPORT` method is actually supported
* Include `rights` file in source distribution
* Specify `md5` and `bcrypt` as extras
* Improve logging messages
* Windows: Fix crash when item path is a directory

## 2.1.8 - Wild Radish

This release is compatible with version 2.0.0.

* Flush files before fsync'ing

## 2.1.7 - Wild Radish

This release is compatible with version 2.0.0.

* Don't print warning when cache format changes
* Add documentation for `BaseAuth`
* Add `is_authenticated2(login, user, password)` to `BaseAuth`
* Fix names of custom properties in PROPFIND requests with
  `D:propname` or `D:allprop`
* Return all properties in PROPFIND requests with `D:propname` or
  `D:allprop`
* Allow `D:displayname` property on all collections
* Answer with `D:unauthenticated` for `D:current-user-principal` property
  when not logged in
* Remove non-existing `ICAL:calendar-color` and `C:calendar-timezone`
  properties from PROPFIND requests with `D:propname` or `D:allprop`
* Add `D:owner` property to calendar and address book objects
* Remove `D:getetag` and `D:getlastmodified` properties from regular
  collections

## 2.1.6 - Wild Radish

This release is compatible with version 2.0.0.

* Fix content-type of VLIST
* Specify correct COMPONENT in content-type of VCALENDAR
* Cache COMPONENT of calendar objects (improves speed with some clients)
* Stricter parsing of filters
* Improve support for CardDAV filter
* Fix some smaller bugs in CalDAV filter
* Add X-WR-CALNAME and X-WR-CALDESC to calendars downloaded via HTTP/WebDAV
* Use X-WR-CALNAME and X-WR-CALDESC from calendars published via WebDAV

## 2.1.5 - Wild Radish

This release is compatible with version 2.0.0.

* Add `--verify-storage` command-line argument
* Allow comments in the htpasswd file
* Don't strip whitespaces from user names and passwords in the htpasswd file
* Remove cookies from logging output
* Allow uploads of whole collections with many components
* Show warning message if server.timeout is used with Python < 3.5.2

## 2.1.4 - Wild Radish

This release is compatible with version 2.0.0.

* Fix incorrect time range matching and calculation for some edge-cases with
  rescheduled recurrences
* Fix owner property

## 2.1.3 - Wild Radish

This release is compatible with version 2.0.0.

* Enable timeout for SSL handshakes and move them out of the main thread
* Create cache entries during upload of items
* Stop built-in server on Windows when Ctrl+C is pressed
* Prevent slow down when multiple requests hit a collection during cache warm-up

## 2.1.2 - Wild Radish

This release is compatible with version 2.0.0.

* Remove workarounds for bugs in VObject < 0.9.5
* Error checking of collection tags and associated components
* Improve error checking of uploaded collections and components
* Don't delete empty collection properties implicitly
* Improve logging of VObject serialization

## 2.1.1 - Wild Radish Again

This release is compatible with version 2.0.0.

* Add missing UIDs instead of failing
* Improve error checking of calendar and address book objects
* Fix upload of whole address books

## 2.1.0 - Wild Radish

This release is compatible with version 2.0.0.

* Built-in web interface for creating and managing address books and calendars
  * can be extended with web plugins
* Much faster storage backend
* Significant reduction in memory usage
* Improved logging
  * Include paths (of invalid items / requests) in log messages
  * Include configuration values causing problems in log messages
  * Log warning message for invalid requests by clients
  * Log error message for invalid files in the storage backend
  * No stack traces unless debugging is enabled
* Time range filter also regards overwritten recurrences
* Items that couldn't be filtered because of bugs in VObject are always
  returned (and a warning message is logged)
* Basic error checking of configuration files
* File system locking isn't disabled implicitly anymore, instead a new
  configuration option gets introduced
* The permissions of the lock file are not changed anymore
* Support for sync-token
* Support for client-side SSL certificates
* Rights plugins can decide if access to an item is granted explicitly
  * Respond with 403 instead of 404 for principal collections of non-existing
    users when `owner_only` plugin is used (information leakage)
* Authentication plugins can provide the login and password from the
  environment
  * new `remote_user` plugin, that gets the login from the `REMOTE_USER`
    environment variable (for WSGI server)
  * new `http_x_remote_user` plugin, that gets the login from the
    `X-Remote-User` HTTP header (for reverse proxies)

## 2.0.0 - Little Big Radish

This feature is not compatible with the 1.x.x versions. Follow our
[migration guide](https://radicale.org/2.1.html#documentation/migration-from-1xx-to-2xx)
if you want to switch from 1.x.x to 2.0.0.

* Support Python 3.3+ only, Python 2 is not supported anymore
* Keep only one simple filesystem-based storage system
* Remove built-in Git support
* Remove built-in authentication modules
* Keep the WSGI interface, use Python HTTP server by default
* Use a real iCal parser, rely on the "vobject" external module
* Add a solid calendar discovery
* Respect the difference between "files" and "folders", don't rely on slashes
* Remove the calendar creation with GET requests
* Be stateless
* Use a file locker
* Add threading
* Get atomic writes
* Support new filters
* Support read-only permissions
* Allow External plugins for authentication, rights management, storage and
  version control

## 1.1.4 - Fifth Law of Nature

* Use `shutil.move` for `--export-storage`

## 1.1.3 - Fourth Law of Nature

* Add a `--export-storage=FOLDER` command-line argument (by Unrud, see #606)

## 1.1.2 - Third Law of Nature

* **Security fix**: Add a random timer to avoid timing oracles and simple
  bruteforce attacks when using the htpasswd authentication method.
* Various minor fixes.

## 1.1.1 - Second Law of Nature

* Fix the owner_write rights rule

## 1.1 - Law of Nature

One feature in this release is **not backward compatible**:

* Use the first matching section for rights (inspired from daald)

Now, the first section matching the path and current user in your custom rights
file is used. In the previous versions, the most permissive rights of all the
matching sections were applied. This new behaviour gives a simple way to make
specific rules at the top of the file independent from the generic ones.

Many **improvements in this release are related to security**, you should
upgrade Radicale as soon as possible:

* Improve the regex used for well-known URIs (by Unrud)
* Prevent regex injection in rights management (by Unrud)
* Prevent crafted HTTP request from calling arbitrary functions (by Unrud)
* Improve URI sanitation and conversion to filesystem path (by Unrud)
* Decouple the daemon from its parent environment (by Unrud)

Some bugs have been fixed and little enhancements have been added:

* Assign new items to correct key (by Unrud)
* Avoid race condition in PID file creation (by Unrud)
* Improve the docker version (by cdpb)
* Encode message and committer for git commits
* Test with Python 3.5

## 1.0.1 - Sunflower Again

* Update the version because of a **stupid** "feature"™ of PyPI

## 1.0 - Sunflower

* Enhanced performances (by Mathieu Dupuy)
* Add MD5-APR1 and BCRYPT for htpasswd-based authentication (by Jan-Philip Gehrcke)
* Use PAM service (by Stephen Paul Weber)
* Don't discard PROPPATCH on empty collections (by Markus Unterwaditzer)
* Write the path of the collection in the git message (by Matthew Monaco)
* Tests launched on Travis

## 0.10 - Lovely Endless Grass

* Support well-known URLs (by Mathieu Dupuy)
* Fix collection discovery (by Markus Unterwaditzer)
* Reload logger config on SIGHUP (by Élie Bouttier)
* Remove props files when deleting a collection (by Vincent Untz)
* Support salted SHA1 passwords (by Marc Kleine-Budde)
* Don't spam the logs about non-SSL IMAP connections to localhost (by Giel van Schijndel)

## 0.9 - Rivers

* Custom handlers for auth, storage and rights (by Sergey Fursov)
* 1-file-per-event storage (by Jean-Marc Martins)
* Git support for filesystem storages (by Jean-Marc Martins)
* DB storage working with PostgreSQL, MariaDB and SQLite (by Jean-Marc Martins)
* Clean rights manager based on regular expressions (by Sweil)
* Support of contacts for Apple's clients
* Support colors (by Jochen Sprickerhof)
* Decode URLs in XML (by Jean-Marc Martins)
* Fix PAM authentication (by Stepan Henek)
* Use consistent etags (by 9m66p93w)
* Use consistent sorting order (by Daniel Danner)
* Return 401 on unauthorized DELETE requests (by Eduard Braun)
* Move pid file creation in child process (by Mathieu Dupuy)
* Allow requests without base_prefix (by jheidemann)

## 0.8 - Rainbow

* New authentication and rights management modules (by Matthias Jordan)
* Experimental database storage
* Command-line option for custom configuration file (by Mark Adams)
* Root URL not at the root of a domain (by Clint Adams, Fabrice Bellet, Vincent Untz)
* Improved support for iCal, CalDAVSync, CardDAVSync, CalDavZAP and CardDavMATE
* Empty PROPFIND requests handled (by Christoph Polcin)
* Colon allowed in passwords
* Configurable realm message

## 0.7.1 - Waterfalls

* Many address books fixes
* New IMAP ACL (by Daniel Aleksandersen)
* PAM ACL fixed (by Daniel Aleksandersen)
* Courier ACL fixed (by Benjamin Frank)
* Always set display name to collections (by Oskari Timperi)
* Various DELETE responses fixed

## 0.7 - Eternal Sunshine

* Repeating events
* Collection deletion
* Courier and PAM authentication methods
* CardDAV support
* Custom LDAP filters supported

## 0.6.4 - Tulips

* Fix the installation with Python 3.1

## 0.6.3 - Red Roses

* MOVE requests fixed
* Faster REPORT answers
* Executable script moved into the package

## 0.6.2 - Seeds

* iPhone and iPad support fixed
* Backslashes replaced by slashes in PROPFIND answers on Windows
* PyPI archive set as default download URL

## 0.6.1 - Growing Up

* Example files included in the tarball
* htpasswd support fixed
* Redirection loop bug fixed
* Testing message on GET requests

## 0.6 - Sapling

* WSGI support
* IPv6 support
* Smart, verbose and configurable logs
* Apple iCal 4 and iPhone support (by Łukasz Langa)
* KDE KOrganizer support
* LDAP auth backend (by Corentin Le Bail)
* Public and private calendars (by René Neumann)
* PID file
* MOVE requests management
* Journal entries support
* Drop Python 2.5 support

## 0.5 - Historical Artifacts

* Calendar depth
* MacOS and Windows support
* HEAD requests management
* htpasswd user from calendar path

## 0.4 - Hot Days Back

* Personal calendars
* Last-Modified HTTP header
* `no-ssl` and `foreground` options
* Default configuration file

## 0.3 - Dancing Flowers

* Evolution support
* Version management

## 0.2 - Snowflakes

* Sunbird pre-1.0 support
* SSL connection
* Htpasswd authentication
* Daemon mode
* User configuration
* Twisted dependency removed
* Python 3 support
* Real URLs for PUT and DELETE
* Concurrent modification reported to users
* Many bugs fixed (by Roger Wenham)

## 0.1 - Crazy Vegetables

* First release
* Lightning/Sunbird 0.9 compatibility
* Easy installer
