Lint markdown
This commit is contained in:
		
							
								
								
									
										4
									
								
								.mdl.style
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.mdl.style
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | all | ||||||
|  | rule 'MD026', :punctuation => '.,;:!' | ||||||
|  | exclude_rule 'MD001' | ||||||
|  | exclude_rule 'MD024' | ||||||
							
								
								
									
										378
									
								
								DOCUMENTATION.md
									
									
									
									
									
								
							
							
						
						
									
										378
									
								
								DOCUMENTATION.md
									
									
									
									
									
								
							| @@ -1,42 +1,46 @@ | |||||||
| # Getting started | # Documentation | ||||||
| ### About Radicale |  | ||||||
|  | ## Getting started | ||||||
|  |  | ||||||
|  | #### About Radicale | ||||||
|  |  | ||||||
| Radicale is a small but powerful CalDAV (calendars, to-do lists) and CardDAV | Radicale is a small but powerful CalDAV (calendars, to-do lists) and CardDAV | ||||||
| (contacts) server, that: | (contacts) server, that: | ||||||
|  |  | ||||||
|   * Shares calendars and contact lists through CalDAV, CardDAV and HTTP. | * Shares calendars and contact lists through CalDAV, CardDAV and HTTP. | ||||||
|   * Supports events, todos, journal entries and business cards. | * Supports events, todos, journal entries and business cards. | ||||||
|   * Works out-of-the-box, no complicated setup or configuration required. | * Works out-of-the-box, no complicated setup or configuration required. | ||||||
|   * Can limit access by authentication. | * Can limit access by authentication. | ||||||
|   * Can secure connections with TLS. | * Can secure connections with TLS. | ||||||
|   * Works with many | * Works with many | ||||||
|   [CalDAV and CardDAV clients](#documentation/supported-clients). |   [CalDAV and CardDAV clients](#documentation/supported-clients). | ||||||
|   * Stores all data on the file system in a simple folder structure. | * Stores all data on the file system in a simple folder structure. | ||||||
|   * Can be extended with plugins. | * Can be extended with plugins. | ||||||
|   * Is GPLv3-licensed free software. | * Is GPLv3-licensed free software. | ||||||
|  |  | ||||||
| ### Installation | #### Installation | ||||||
|  |  | ||||||
| Radicale is really easy to install and works out-of-the-box. | Radicale is really easy to install and works out-of-the-box. | ||||||
|  |  | ||||||
| ```bash | ```bash | ||||||
| $ python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz | python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz | ||||||
| $ python3 -m radicale --storage-filesystem-folder=~/.var/lib/radicale/collections | python3 -m radicale --storage-filesystem-folder=~/.var/lib/radicale/collections | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| When the server is launched, open http://localhost:5232/ in your browser! | When the server is launched, open <http://localhost:5232> in your browser! | ||||||
| You can login with any username and password. | You can login with any username and password. | ||||||
|  |  | ||||||
| Want more? Check the [tutorials](#tutorials) and the | Want more? Check the [tutorials](#tutorials) and the | ||||||
| [documentation](#documentation). | [documentation](#documentation). | ||||||
|  |  | ||||||
| ### What's New? | #### What's New? | ||||||
|  |  | ||||||
| Read the | Read the | ||||||
| [changelog on GitHub.](https://github.com/Kozea/Radicale/blob/master/NEWS.md) | [changelog on GitHub.](https://github.com/Kozea/Radicale/blob/master/NEWS.md) | ||||||
|  |  | ||||||
| # Tutorials | ## Tutorials | ||||||
| ## Simple 5-minute setup |  | ||||||
|  | ### Simple 5-minute setup | ||||||
|  |  | ||||||
| You want to try Radicale but only have 5 minutes free in your calendar? Let's | You want to try Radicale but only have 5 minutes free in your calendar? Let's | ||||||
| go right now and play a bit with Radicale! | go right now and play a bit with Radicale! | ||||||
| @@ -49,7 +53,7 @@ user name and password. If Radicale fits your needs, it may be time for | |||||||
|  |  | ||||||
| Follow one of the chapters below depending on your operating system. | Follow one of the chapters below depending on your operating system. | ||||||
|  |  | ||||||
| ### Linux / \*BSD | #### Linux / \*BSD | ||||||
|  |  | ||||||
| First, make sure that **python** 3.5 or later (**python** ≥ 3.6 is | First, make sure that **python** 3.5 or later (**python** ≥ 3.6 is | ||||||
| recommended) and **pip** are installed. On most distributions it should be | recommended) and **pip** are installed. On most distributions it should be | ||||||
| @@ -64,10 +68,10 @@ $ python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/mas | |||||||
| $ python3 -m radicale --storage-filesystem-folder=~/.var/lib/radicale/collections | $ python3 -m radicale --storage-filesystem-folder=~/.var/lib/radicale/collections | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| Victory! Open http://localhost:5232/ in your browser! | Victory! Open <http://localhost:5232> in your browser! | ||||||
| You can log in with any username and password. | You can log in with any username and password. | ||||||
|  |  | ||||||
| ### Windows | #### Windows | ||||||
|  |  | ||||||
| The first step is to install Python. Go to | The first step is to install Python. Go to | ||||||
| [python.org](https://python.org) and download the latest version of Python 3. | [python.org](https://python.org) and download the latest version of Python 3. | ||||||
| @@ -82,10 +86,10 @@ C:\Users\User> python -m pip install --upgrade https://github.com/Kozea/Radicale | |||||||
| C:\Users\User> python -m radicale --storage-filesystem-folder=~/radicale/collections | C:\Users\User> python -m radicale --storage-filesystem-folder=~/radicale/collections | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| Victory! Open http://localhost:5232/ in your browser! | Victory! Open <http://localhost:5232> in your browser! | ||||||
| You can log in with any username and password. | You can log in with any username and password. | ||||||
|  |  | ||||||
| ## Basic Configuration | ### Basic Configuration | ||||||
|  |  | ||||||
| Installation instructions can be found in the | Installation instructions can be found in the | ||||||
| [simple 5-minute setup](#tutorials/simple-5-minute-setup) tutorial. | [simple 5-minute setup](#tutorials/simple-5-minute-setup) tutorial. | ||||||
| @@ -104,7 +108,7 @@ passed via command line arguments.) | |||||||
| All configuration options are described in detail in the | All configuration options are described in detail in the | ||||||
| [Configuration](#documentation/configuration) section. | [Configuration](#documentation/configuration) section. | ||||||
|  |  | ||||||
| ### Authentication | #### Authentication | ||||||
|  |  | ||||||
| In its default configuration Radicale doesn't check user names or passwords. | In its default configuration Radicale doesn't check user names or passwords. | ||||||
| If the server is reachable over a network, you should change this. | If the server is reachable over a network, you should change this. | ||||||
| @@ -112,7 +116,7 @@ If the server is reachable over a network, you should change this. | |||||||
| First a `users` file with all user names and passwords must be created. | First a `users` file with all user names and passwords must be created. | ||||||
| It can be stored in the same directory as the configuration file. | It can be stored in the same directory as the configuration file. | ||||||
|  |  | ||||||
| #### The secure way | ##### The secure way | ||||||
|  |  | ||||||
| The `users` file can be created and managed with | The `users` file can be created and managed with | ||||||
| [htpasswd](https://httpd.apache.org/docs/current/programs/htpasswd.html): | [htpasswd](https://httpd.apache.org/docs/current/programs/htpasswd.html): | ||||||
| @@ -138,7 +142,7 @@ htpasswd_filename = /path/to/users | |||||||
| htpasswd_encryption = md5 | htpasswd_encryption = md5 | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| #### The simple but insecure way | ##### The simple but insecure way | ||||||
|  |  | ||||||
| Create the `users` file by hand with lines containing the user name and | Create the `users` file by hand with lines containing the user name and | ||||||
| password separated by `:`. Example: | password separated by `:`. Example: | ||||||
| @@ -158,7 +162,7 @@ htpasswd_filename = /path/to/users | |||||||
| htpasswd_encryption = plain | htpasswd_encryption = plain | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### Addresses | #### Addresses | ||||||
|  |  | ||||||
| The default configuration binds the server to localhost. It can't be reached | The default configuration binds the server to localhost. It can't be reached | ||||||
| from other computers. This can be changed with the following configuration | from other computers. This can be changed with the following configuration | ||||||
| @@ -169,7 +173,7 @@ options (IPv4 and IPv6): | |||||||
| hosts = 0.0.0.0:5232, [::]:5232 | hosts = 0.0.0.0:5232, [::]:5232 | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### Storage | #### Storage | ||||||
|  |  | ||||||
| Data is stored in the folder `/var/lib/radicale/collections`. The path can | Data is stored in the folder `/var/lib/radicale/collections`. The path can | ||||||
| be changed with the following configuration: | be changed with the following configuration: | ||||||
| @@ -184,7 +188,7 @@ filesystem_folder = /path/to/storage | |||||||
| > You can find OS dependent instructions in the | > You can find OS dependent instructions in the | ||||||
| > [Running as a service](#tutorials/running-as-a-service) section. | > [Running as a service](#tutorials/running-as-a-service) section. | ||||||
|  |  | ||||||
| ### Limits | #### Limits | ||||||
|  |  | ||||||
| Radicale enforces limits on the maximum number of parallel connections, | Radicale enforces limits on the maximum number of parallel connections, | ||||||
| the maximum file size (important for contacts with big photos) and the rate of | the maximum file size (important for contacts with big photos) and the rate of | ||||||
| @@ -204,16 +208,16 @@ timeout = 30 | |||||||
| delay = 1 | delay = 1 | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ## Running as a service | ### Running as a service | ||||||
|  |  | ||||||
| The method to run Radicale as a service depends on your host operating system. | The method to run Radicale as a service depends on your host operating system. | ||||||
| Follow one of the chapters below depending on your operating system and | Follow one of the chapters below depending on your operating system and | ||||||
| requirements. | requirements. | ||||||
|  |  | ||||||
| ### Linux with systemd system-wide | #### Linux with systemd system-wide | ||||||
|  |  | ||||||
| Create the **radicale** user and group for the Radicale service. | Create the **radicale** user and group for the Radicale service. (Run | ||||||
| (Run `useradd --system --user-group --home-dir / --shell /sbin/nologin radicale` as root.) | `useradd --system --user-group --home-dir / --shell /sbin/nologin radicale` as root.) | ||||||
| The storage folder must be writable by **radicale**. (Run | The storage folder must be writable by **radicale**. (Run | ||||||
| `mkdir -p /var/lib/radicale/collections && chown -R radicale:radicale /var/lib/radicale/collections` | `mkdir -p /var/lib/radicale/collections && chown -R radicale:radicale /var/lib/radicale/collections` | ||||||
| as root.) | as root.) | ||||||
| @@ -249,6 +253,7 @@ ReadWritePaths=/var/lib/radicale/collections | |||||||
| [Install] | [Install] | ||||||
| WantedBy=multi-user.target | WantedBy=multi-user.target | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| Radicale will load the configuration file from `/etc/radicale/config`. | Radicale will load the configuration file from `/etc/radicale/config`. | ||||||
|  |  | ||||||
| To enable and manage the service run: | To enable and manage the service run: | ||||||
| @@ -264,7 +269,7 @@ $ systemctl status radicale | |||||||
| $ journalctl --unit radicale.service | $ journalctl --unit radicale.service | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### Linux with systemd as a user | #### Linux with systemd as a user | ||||||
|  |  | ||||||
| Create the file `~/.config/systemd/user/radicale.service`: | Create the file `~/.config/systemd/user/radicale.service`: | ||||||
|  |  | ||||||
| @@ -297,16 +302,16 @@ $ systemctl --user status radicale | |||||||
| $ journalctl --user --unit radicale.service | $ journalctl --user --unit radicale.service | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### Windows with "NSSM - the Non-Sucking Service Manager" | #### Windows with "NSSM - the Non-Sucking Service Manager" | ||||||
|  |  | ||||||
| First install [NSSM](https://nssm.cc/) and start `nssm install` in a command | First install [NSSM](https://nssm.cc/) and start `nssm install` in a command | ||||||
| prompt. Apply the following configuration: | prompt. Apply the following configuration: | ||||||
|  |  | ||||||
|   * Service name: `Radicale` | * Service name: `Radicale` | ||||||
|   * Application | * Application | ||||||
|   * Path: `C:\Path\To\Python\python.exe` |   * Path: `C:\Path\To\Python\python.exe` | ||||||
|   * Arguments: `-m radicale --config C:\Path\To\Config` |   * Arguments: `-m radicale --config C:\Path\To\Config` | ||||||
|   * I/O redirection | * I/O redirection | ||||||
|   * Error: `C:\Path\To\Radicale.log` |   * Error: `C:\Path\To\Radicale.log` | ||||||
|  |  | ||||||
| > **Security:** Be aware that the service runs in the local system account, | > **Security:** Be aware that the service runs in the local system account, | ||||||
| @@ -321,7 +326,7 @@ The service is configured to start automatically when the computer starts. | |||||||
| To start the service manually open **Services** in **Computer Management** and | To start the service manually open **Services** in **Computer Management** and | ||||||
| start the **Radicale** service. | start the **Radicale** service. | ||||||
|  |  | ||||||
| ## Reverse Proxy | ### Reverse Proxy | ||||||
|  |  | ||||||
| When a reverse proxy is used, the path at which Radicale is available must | When a reverse proxy is used, the path at which Radicale is available must | ||||||
| be provided via the `X-Script-Name` header. The proxy must remove the location | be provided via the `X-Script-Name` header. The proxy must remove the location | ||||||
| @@ -367,7 +372,7 @@ Be reminded that Radicale's default configuration enforces limits on the | |||||||
| maximum number of parallel connections, the maximum file size and the rate of | maximum number of parallel connections, the maximum file size and the rate of | ||||||
| incorrect authentication attempts. Connections are terminated after a timeout. | incorrect authentication attempts. Connections are terminated after a timeout. | ||||||
|  |  | ||||||
| ### Manage user accounts with the reverse proxy | #### Manage user accounts with the reverse proxy | ||||||
|  |  | ||||||
| Set the configuration option `type` in the `auth` section to | Set the configuration option `type` in the `auth` section to | ||||||
| `http_x_remote_user`. | `http_x_remote_user`. | ||||||
| @@ -427,7 +432,7 @@ RequestHeader set X-Remote-User expr=%{REMOTE_USER} | |||||||
| > **Security:** Untrusted clients should not be able to access the Radicale | > **Security:** Untrusted clients should not be able to access the Radicale | ||||||
| > server directly. Otherwise, they can authenticate as any user. | > server directly. Otherwise, they can authenticate as any user. | ||||||
|  |  | ||||||
| ### Secure connection between Radicale and the reverse proxy | #### Secure connection between Radicale and the reverse proxy | ||||||
|  |  | ||||||
| SSL certificates can be used to encrypt and authenticate the connection between | SSL certificates can be used to encrypt and authenticate the connection between | ||||||
| Radicale and the reverse proxy. First you have to generate a certificate for | Radicale and the reverse proxy. First you have to generate a certificate for | ||||||
| @@ -437,8 +442,10 @@ information about the certificate, the values don't matter and you can keep the | |||||||
| defaults. | defaults. | ||||||
|  |  | ||||||
| ```bash | ```bash | ||||||
| $ openssl req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem -nodes -days 9999 | openssl req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem \ | ||||||
| $ openssl req -x509 -newkey rsa:4096 -keyout client_key.pem -out client_cert.pem -nodes -days 9999 |         -nodes -days 9999 | ||||||
|  | openssl req -x509 -newkey rsa:4096 -keyout client_key.pem -out client_cert.pem \ | ||||||
|  |         -nodes -days 9999 | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| Use the following configuration for Radicale: | Use the following configuration for Radicale: | ||||||
| @@ -464,7 +471,7 @@ location /radicale/ { | |||||||
| } | } | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ## WSGI Server | ### WSGI Server | ||||||
|  |  | ||||||
| Radicale is compatible with the WSGI specification. | Radicale is compatible with the WSGI specification. | ||||||
|  |  | ||||||
| @@ -486,16 +493,17 @@ env = RADICALE_CONFIG=/etc/radicale/config | |||||||
| Example **Gunicorn** configuration: | Example **Gunicorn** configuration: | ||||||
|  |  | ||||||
| ```bash | ```bash | ||||||
| gunicorn --bind '127.0.0.1:5232' --workers 8 --env 'RADICALE_CONFIG=/etc/radicale/config' radicale | gunicorn --bind '127.0.0.1:5232' --env 'RADICALE_CONFIG=/etc/radicale/config' \ | ||||||
|  |          --workers 8 radicale | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### Manage user accounts with the WSGI server | #### Manage user accounts with the WSGI server | ||||||
|  |  | ||||||
| Set the configuration option `type` in the `auth` section to `remote_user`. | Set the configuration option `type` in the `auth` section to `remote_user`. | ||||||
| Radicale uses the user name provided by the WSGI server and disables | Radicale uses the user name provided by the WSGI server and disables | ||||||
| authentication over HTTP. | authentication over HTTP. | ||||||
|  |  | ||||||
| ## Versioning with Git | ### Versioning with Git | ||||||
|  |  | ||||||
| This tutorial describes how to keep track of all changes to calendars and | This tutorial describes how to keep track of all changes to calendars and | ||||||
| address books with **git** (or any other version control system). | address books with **git** (or any other version control system). | ||||||
| @@ -504,7 +512,7 @@ The repository must be initialized by running `git init` in the file | |||||||
| system folder. Internal files of Radicale can be excluded by creating the | system folder. Internal files of Radicale can be excluded by creating the | ||||||
| file `.gitignore` with the following content: | file `.gitignore` with the following content: | ||||||
|  |  | ||||||
| ``` | ```gitignore | ||||||
| .Radicale.cache | .Radicale.cache | ||||||
| .Radicale.lock | .Radicale.lock | ||||||
| .Radicale.tmp-* | .Radicale.tmp-* | ||||||
| @@ -520,8 +528,9 @@ git add -A && (git diff --cached --quiet || git commit -m "Changes by "%(user)s) | |||||||
| The command gets executed after every change to the storage and commits | The command gets executed after every change to the storage and commits | ||||||
| the changes into the **git** repository. | the changes into the **git** repository. | ||||||
|  |  | ||||||
| # Documentation | ## Documentation | ||||||
| ## Configuration |  | ||||||
|  | ### Configuration | ||||||
|  |  | ||||||
| Radicale can be configured with a configuration file or with | Radicale can be configured with a configuration file or with | ||||||
| command line arguments. | command line arguments. | ||||||
| @@ -552,7 +561,9 @@ Paths that start with `?` are optional. | |||||||
| The same example configuration via command line arguments looks like: | The same example configuration via command line arguments looks like: | ||||||
|  |  | ||||||
| ```bash | ```bash | ||||||
| python3 -m radicale --server-hosts 0.0.0.0:5232,[::]:5232 --auth-type htpasswd --auth-htpasswd-filename ~/.config/radicale/users --auth-htpasswd-encryption md5 | python3 -m radicale --server-hosts 0.0.0.0:5232,[::]:5232 \ | ||||||
|  |         --auth-type htpasswd --auth-htpasswd-filename ~/.config/radicale/users \ | ||||||
|  |         --auth-htpasswd-encryption md5 | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| Add the argument `--config ""` to stop Radicale from loading the default | Add the argument `--config ""` to stop Radicale from loading the default | ||||||
| @@ -560,54 +571,54 @@ configuration files. Run `python3 -m radicale --help` for more information. | |||||||
|  |  | ||||||
| In the following, all configuration categories and options are described. | In the following, all configuration categories and options are described. | ||||||
|  |  | ||||||
| ### server | #### server | ||||||
|  |  | ||||||
| The configuration options in this category are only relevant in standalone | The configuration options in this category are only relevant in standalone | ||||||
| mode. All options are ignored, when Radicale runs via WSGI. | mode. All options are ignored, when Radicale runs via WSGI. | ||||||
|  |  | ||||||
| #### hosts | ##### hosts | ||||||
|  |  | ||||||
| A comma separated list of addresses that the server will bind to. | A comma separated list of addresses that the server will bind to. | ||||||
|  |  | ||||||
| Default: `localhost:5232` | Default: `localhost:5232` | ||||||
|  |  | ||||||
| #### max_connections | ##### max_connections | ||||||
|  |  | ||||||
| The maximum number of parallel connections. Set to `0` to disable the limit. | The maximum number of parallel connections. Set to `0` to disable the limit. | ||||||
|  |  | ||||||
| Default: `8` | Default: `8` | ||||||
|  |  | ||||||
| #### max_content_length | ##### max_content_length | ||||||
|  |  | ||||||
| The maximum size of the request body. (bytes) | The maximum size of the request body. (bytes) | ||||||
|  |  | ||||||
| Default: `100000000` | Default: `100000000` | ||||||
|  |  | ||||||
| #### timeout | ##### timeout | ||||||
|  |  | ||||||
| Socket timeout. (seconds) | Socket timeout. (seconds) | ||||||
|  |  | ||||||
| Default: `30` | Default: `30` | ||||||
|  |  | ||||||
| #### ssl | ##### ssl | ||||||
|  |  | ||||||
| Enable transport layer encryption. | Enable transport layer encryption. | ||||||
|  |  | ||||||
| Default: `False` | Default: `False` | ||||||
|  |  | ||||||
| #### certificate | ##### certificate | ||||||
|  |  | ||||||
| Path of the SSL certifcate. | Path of the SSL certifcate. | ||||||
|  |  | ||||||
| Default: `/etc/ssl/radicale.cert.pem` | Default: `/etc/ssl/radicale.cert.pem` | ||||||
|  |  | ||||||
| #### key | ##### key | ||||||
|  |  | ||||||
| Path to the private key for SSL. Only effective if `ssl` is enabled. | Path to the private key for SSL. Only effective if `ssl` is enabled. | ||||||
|  |  | ||||||
| Default: `/etc/ssl/radicale.key.pem` | Default: `/etc/ssl/radicale.key.pem` | ||||||
|  |  | ||||||
| #### certificate_authority | ##### certificate_authority | ||||||
|  |  | ||||||
| Path to the CA certificate for validating client certificates. This can be used | Path to the CA certificate for validating client certificates. This can be used | ||||||
| to secure TCP traffic between Radicale and a reverse proxy. If you want to | to secure TCP traffic between Radicale and a reverse proxy. If you want to | ||||||
| @@ -616,21 +627,23 @@ authentication plugin that extracts the user name from the certificate. | |||||||
|  |  | ||||||
| Default: | Default: | ||||||
|  |  | ||||||
| ### encoding | #### encoding | ||||||
| #### request |  | ||||||
|  | ##### request | ||||||
|  |  | ||||||
| Encoding for responding requests. | Encoding for responding requests. | ||||||
|  |  | ||||||
| Default: `utf-8` | Default: `utf-8` | ||||||
|  |  | ||||||
| #### stock | ##### stock | ||||||
|  |  | ||||||
| Encoding for storing local collections | Encoding for storing local collections | ||||||
|  |  | ||||||
| Default: `utf-8` | Default: `utf-8` | ||||||
|  |  | ||||||
| ### auth | #### auth | ||||||
| #### type |  | ||||||
|  | ##### type | ||||||
|  |  | ||||||
| The method to verify usernames and passwords. | The method to verify usernames and passwords. | ||||||
|  |  | ||||||
| @@ -656,13 +669,13 @@ Available backends: | |||||||
|  |  | ||||||
| Default: `none` | Default: `none` | ||||||
|  |  | ||||||
| #### htpasswd_filename | ##### htpasswd_filename | ||||||
|  |  | ||||||
| Path to the htpasswd file. | Path to the htpasswd file. | ||||||
|  |  | ||||||
| Default: | Default: | ||||||
|  |  | ||||||
| #### htpasswd_encryption | ##### htpasswd_encryption | ||||||
|  |  | ||||||
| The encryption method that is used in the htpasswd file. Use the | The encryption method that is used in the htpasswd file. Use the | ||||||
| [htpasswd](https://httpd.apache.org/docs/current/programs/htpasswd.html) | [htpasswd](https://httpd.apache.org/docs/current/programs/htpasswd.html) | ||||||
| @@ -673,6 +686,7 @@ Available methods: | |||||||
| `plain` | `plain` | ||||||
| : Passwords are stored in plaintext. This is obviously not secure! | : Passwords are stored in plaintext. This is obviously not secure! | ||||||
|   The htpasswd file for this can be created by hand and looks like: |   The htpasswd file for this can be created by hand and looks like: | ||||||
|  |  | ||||||
|   ```htpasswd |   ```htpasswd | ||||||
|   user1:password1 |   user1:password1 | ||||||
|   user2:password2 |   user2:password2 | ||||||
| @@ -687,20 +701,21 @@ Available methods: | |||||||
|  |  | ||||||
| Default: `md5` | Default: `md5` | ||||||
|  |  | ||||||
| #### delay | ##### delay | ||||||
|  |  | ||||||
| Average delay after failed login attempts in seconds. | Average delay after failed login attempts in seconds. | ||||||
|  |  | ||||||
| Default: `1` | Default: `1` | ||||||
|  |  | ||||||
| #### realm | ##### realm | ||||||
|  |  | ||||||
| Message displayed in the client when a password is needed. | Message displayed in the client when a password is needed. | ||||||
|  |  | ||||||
| Default: `Radicale - Password Required` | Default: `Radicale - Password Required` | ||||||
|  |  | ||||||
| ### rights | #### rights | ||||||
| #### type |  | ||||||
|  | ##### type | ||||||
|  |  | ||||||
| The backend that is used to check the access rights of collections. | The backend that is used to check the access rights of collections. | ||||||
|  |  | ||||||
| @@ -728,13 +743,14 @@ Available backends: | |||||||
|  |  | ||||||
| Default: `owner_only` | Default: `owner_only` | ||||||
|  |  | ||||||
| #### file | ##### file | ||||||
|  |  | ||||||
| File for the rights backend `from_file`.  See the | File for the rights backend `from_file`.  See the | ||||||
| [Rights](#documentation/authentication-and-rights) section. | [Rights](#documentation/authentication-and-rights) section. | ||||||
|  |  | ||||||
| ### storage | #### storage | ||||||
| #### type |  | ||||||
|  | ##### type | ||||||
|  |  | ||||||
| The backend that is used to store data. | The backend that is used to store data. | ||||||
|  |  | ||||||
| @@ -744,31 +760,33 @@ Available backends: | |||||||
| : Stores the data in the filesystem. | : Stores the data in the filesystem. | ||||||
|  |  | ||||||
| `multifilesystem_nolock` | `multifilesystem_nolock` | ||||||
| : The `multifilesystem` backend without file-based locking. Must only be used with a single process. | : The `multifilesystem` backend without file-based locking. | ||||||
|  |   Must only be used with a single process. | ||||||
|  |  | ||||||
| Default: `multifilesystem` | Default: `multifilesystem` | ||||||
|  |  | ||||||
| #### filesystem_folder | ##### filesystem_folder | ||||||
|  |  | ||||||
| Folder for storing local collections, created if not present. | Folder for storing local collections, created if not present. | ||||||
|  |  | ||||||
| Default: `/var/lib/radicale/collections` | Default: `/var/lib/radicale/collections` | ||||||
|  |  | ||||||
| #### max_sync_token_age | ##### max_sync_token_age | ||||||
|  |  | ||||||
| Delete sync-token that are older than the specified time. (seconds) | Delete sync-token that are older than the specified time. (seconds) | ||||||
|  |  | ||||||
| Default: `2592000` | Default: `2592000` | ||||||
|  |  | ||||||
| #### hook | ##### hook | ||||||
|  |  | ||||||
| Command that is run after changes to storage. Take a look at the | Command that is run after changes to storage. Take a look at the | ||||||
| [Versioning with Git](#tutorials/versioning-with-git) tutorial for an example. | [Versioning with Git](#tutorials/versioning-with-git) tutorial for an example. | ||||||
|  |  | ||||||
| Default: | Default: | ||||||
|  |  | ||||||
| ### web | #### web | ||||||
| #### type |  | ||||||
|  | ##### type | ||||||
|  |  | ||||||
| The backend that provides the web interface of Radicale. | The backend that provides the web interface of Radicale. | ||||||
|  |  | ||||||
| @@ -782,8 +800,9 @@ Available backends: | |||||||
|  |  | ||||||
| Default: `internal` | Default: `internal` | ||||||
|  |  | ||||||
| ### logging | #### logging | ||||||
| #### level |  | ||||||
|  | ##### level | ||||||
|  |  | ||||||
| Set the logging level. | Set the logging level. | ||||||
|  |  | ||||||
| @@ -791,13 +810,13 @@ Available levels: **debug**, **info**, **warning**, **error**, **critical** | |||||||
|  |  | ||||||
| Default: `warning` | Default: `warning` | ||||||
|  |  | ||||||
| #### mask_passwords | ##### mask_passwords | ||||||
|  |  | ||||||
| Don't include passwords in logs. | Don't include passwords in logs. | ||||||
|  |  | ||||||
| Default: `True` | Default: `True` | ||||||
|  |  | ||||||
| ### headers | #### headers | ||||||
|  |  | ||||||
| In this section additional HTTP headers that are sent to clients can be | In this section additional HTTP headers that are sent to clients can be | ||||||
| specified. | specified. | ||||||
| @@ -808,38 +827,38 @@ An example to relax the same-origin policy: | |||||||
| Access-Control-Allow-Origin = * | Access-Control-Allow-Origin = * | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ## Supported Clients | ### Supported Clients | ||||||
|  |  | ||||||
| Radicale has been tested with: | Radicale has been tested with: | ||||||
|  |  | ||||||
|   * [Android](https://android.com/) with | * [Android](https://android.com/) with | ||||||
|   [DAVx⁵](https://www.davx5.com/) (formerly DAVdroid) |   [DAVx⁵](https://www.davx5.com/) (formerly DAVdroid) | ||||||
|   * [GNOME Calendar](https://wiki.gnome.org/Apps/Calendar), | * [GNOME Calendar](https://wiki.gnome.org/Apps/Calendar), | ||||||
|   [Contacts](https://wiki.gnome.org/Apps/Contacts) and |   [Contacts](https://wiki.gnome.org/Apps/Contacts) and | ||||||
|   [Evolution](https://wiki.gnome.org/Apps/Evolution) |   [Evolution](https://wiki.gnome.org/Apps/Evolution) | ||||||
|   * [Mozilla Thunderbird](https://www.mozilla.org/thunderbird/) with | * [Mozilla Thunderbird](https://www.mozilla.org/thunderbird/) with | ||||||
|   [CardBook](https://addons.mozilla.org/thunderbird/addon/cardbook/) and |   [CardBook](https://addons.mozilla.org/thunderbird/addon/cardbook/) and | ||||||
|   [Lightning](https://www.mozilla.org/projects/calendar/) |   [Lightning](https://www.mozilla.org/projects/calendar/) | ||||||
|   * [InfCloud](https://www.inf-it.com/open-source/clients/infcloud/), | * [InfCloud](https://www.inf-it.com/open-source/clients/infcloud/), | ||||||
|   [CalDavZAP](https://www.inf-it.com/open-source/clients/caldavzap/) and |   [CalDavZAP](https://www.inf-it.com/open-source/clients/caldavzap/) and | ||||||
|   [CardDavMATE](https://www.inf-it.com/open-source/clients/carddavmate/) |   [CardDavMATE](https://www.inf-it.com/open-source/clients/carddavmate/) | ||||||
|  |  | ||||||
| Many clients do not support the creation of new calendars and address books. | Many clients do not support the creation of new calendars and address books. | ||||||
| You can use Radicale's web interface | You can use Radicale's web interface | ||||||
| (e.g. http://localhost:5232) to create and manage address books and calendars. | (e.g. <http://localhost:5232>) to create and manage address books and calendars. | ||||||
|  |  | ||||||
| In some clients you can just enter the URL of the Radicale server | In some clients you can just enter the URL of the Radicale server | ||||||
| (e.g. `http://localhost:5232`) and your user name. In others, you have to | (e.g. `http://localhost:5232`) and your user name. In others, you have to | ||||||
| enter the URL of the collection directly | enter the URL of the collection directly | ||||||
| (e.g. `http://localhost:5232/user/calendar`). | (e.g. `http://localhost:5232/user/calendar`). | ||||||
|  |  | ||||||
| ### DAVx⁵ | #### DAVx⁵ | ||||||
|  |  | ||||||
| Enter the URL of the Radicale server (e.g. `http://localhost:5232`) and your | Enter the URL of the Radicale server (e.g. `http://localhost:5232`) and your | ||||||
| user name. DAVx⁵ will show all existing calendars and address books and you | user name. DAVx⁵ will show all existing calendars and address books and you | ||||||
| can create new. | can create new. | ||||||
|  |  | ||||||
| ### GNOME Calendar, Contacts and Evolution | #### GNOME Calendar, Contacts and Evolution | ||||||
|  |  | ||||||
| **GNOME Calendar** and **Contacts** do not support adding WebDAV calendars | **GNOME Calendar** and **Contacts** do not support adding WebDAV calendars | ||||||
| and address books directly, but you can add them in **Evolution**. | and address books directly, but you can add them in **Evolution**. | ||||||
| @@ -849,14 +868,15 @@ Enter the URL of the Radicale server (e.g. `http://localhost:5232`) and your | |||||||
| user name. Clicking on the search button will list the existing calendars and | user name. Clicking on the search button will list the existing calendars and | ||||||
| address books. | address books. | ||||||
|  |  | ||||||
| ### Thunderbird | #### Thunderbird | ||||||
| #### CardBook |  | ||||||
|  | ##### CardBook | ||||||
|  |  | ||||||
| Add a new address book on the network with CardDAV. You have to enter the full | Add a new address book on the network with CardDAV. You have to enter the full | ||||||
| URL of the collection (e.g. `http://localhost:5232/user/addressbook`) and | URL of the collection (e.g. `http://localhost:5232/user/addressbook`) and | ||||||
| your user name. | your user name. | ||||||
|  |  | ||||||
| #### Lightning | ##### Lightning | ||||||
|  |  | ||||||
| Add a new calendar on the network with `CalDAV`. (Don't use `iCalendar (ICS)`!) | Add a new calendar on the network with `CalDAV`. (Don't use `iCalendar (ICS)`!) | ||||||
| You have to enter the full URL of the collection (e.g. | You have to enter the full URL of the collection (e.g. | ||||||
| @@ -864,7 +884,7 @@ You have to enter the full URL of the collection (e.g. | |||||||
| different users on the same server, you can specify the user name in the URL | different users on the same server, you can specify the user name in the URL | ||||||
| (e.g. `http://user@localhost...`) | (e.g. `http://user@localhost...`) | ||||||
|  |  | ||||||
| ### InfCloud, CalDavZAP and CardDavMATE | #### InfCloud, CalDavZAP and CardDavMATE | ||||||
|  |  | ||||||
| You can integrate InfCloud into Radicale's web interface with | You can integrate InfCloud into Radicale's web interface with | ||||||
| [RadicaleInfCloud](https://github.com/Unrud/RadicaleInfCloud). No additional | [RadicaleInfCloud](https://github.com/Unrud/RadicaleInfCloud). No additional | ||||||
| @@ -877,7 +897,7 @@ the Radicale server, because of the | |||||||
| You have to add additional HTTP header in the `headers` section of Radicale's | You have to add additional HTTP header in the `headers` section of Radicale's | ||||||
| configuration. The documentation of **InfCloud** has more details on this. | configuration. The documentation of **InfCloud** has more details on this. | ||||||
|  |  | ||||||
| ### Command line | #### Command line | ||||||
|  |  | ||||||
| This is not the recommended way of creating and managing your calendars and | This is not the recommended way of creating and managing your calendars and | ||||||
| address books. Use Radicale's web interface or a client with support for it | address books. Use Radicale's web interface or a client with support for it | ||||||
| @@ -935,10 +955,10 @@ children of the path `/USERNAME/`. | |||||||
| Delete the collections by running something like: | Delete the collections by running something like: | ||||||
|  |  | ||||||
| ```bash | ```bash | ||||||
| $ curl -u user -X DELETE 'http://localhost:5232/user/calendar' | curl -u user -X DELETE 'http://localhost:5232/user/calendar' | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ## Authentication and Rights | ### Authentication and Rights | ||||||
|  |  | ||||||
| This section describes the format of the rights file for the `from_file` | This section describes the format of the rights file for the `from_file` | ||||||
| authentication backend. The configuration option `file` in the `rights` | authentication backend. The configuration option `file` in the `rights` | ||||||
| @@ -993,14 +1013,14 @@ if you want to use regular curly braces in the `user` and `collection` regexes. | |||||||
|  |  | ||||||
| The following `permissions` are recognized: | The following `permissions` are recognized: | ||||||
|  |  | ||||||
|   * **R:** read collections (excluding address books and calendars) | * **R:** read collections (excluding address books and calendars) | ||||||
|   * **r:** read address book and calendar collections | * **r:** read address book and calendar collections | ||||||
|   * **i:** subset of **r** that only allows direct access via HTTP method GET | * **i:** subset of **r** that only allows direct access via HTTP method GET | ||||||
|   (CalDAV/CardDAV is susceptible to expensive search requests) |   (CalDAV/CardDAV is susceptible to expensive search requests) | ||||||
|   * **W:** write collections (excluding address books and calendars) | * **W:** write collections (excluding address books and calendars) | ||||||
|   * **w:** write address book and calendar collections | * **w:** write address book and calendar collections | ||||||
|  |  | ||||||
| ## Storage | ### Storage | ||||||
|  |  | ||||||
| This document describes the layout and format of the file system storage | This document describes the layout and format of the file system storage | ||||||
| (`multifilesystem` backend). | (`multifilesystem` backend). | ||||||
| @@ -1011,12 +1031,12 @@ Scripts can be invoked manually, periodically (e.g. with | |||||||
| change to the storage with the configuration option `hook` in the `storage` | change to the storage with the configuration option `hook` in the `storage` | ||||||
| section (e.g. [Versioning with Git](#tutorials/versioning-with-git)). | section (e.g. [Versioning with Git](#tutorials/versioning-with-git)). | ||||||
|  |  | ||||||
| ### Layout | #### Layout | ||||||
|  |  | ||||||
| The file system contains the following files and folders: | The file system contains the following files and folders: | ||||||
|  |  | ||||||
|   * `.Radicale.lock`: The lock file for locking the storage. | * `.Radicale.lock`: The lock file for locking the storage. | ||||||
|   * `collection-root`: This folder contains all collections and items. | * `collection-root`: This folder contains all collections and items. | ||||||
|  |  | ||||||
| A collection is represented by a folder. This folder may contain the file | A collection is represented by a folder. This folder may contain the file | ||||||
| `.Radicale.props` with all WebDAV properties of the collection encoded | `.Radicale.props` with all WebDAV properties of the collection encoded | ||||||
| @@ -1045,14 +1065,14 @@ They should be deleted after requests are finished but it's possible that | |||||||
| they are left behind when Radicale or the computer crashes. | they are left behind when Radicale or the computer crashes. | ||||||
| It's safe to delete them. | It's safe to delete them. | ||||||
|  |  | ||||||
| ### Locking | #### Locking | ||||||
|  |  | ||||||
| When the data is accessed by hand or by an externally invoked script, | When the data is accessed by hand or by an externally invoked script, | ||||||
| the storage must be locked. The storage can be locked for exclusive or | the storage must be locked. The storage can be locked for exclusive or | ||||||
| shared access. It prevents Radicale from reading or writing the file system. | shared access. It prevents Radicale from reading or writing the file system. | ||||||
| The storage is locked with exclusive access while the `hook` runs. | The storage is locked with exclusive access while the `hook` runs. | ||||||
|  |  | ||||||
| #### Linux shell scripts | ##### Linux shell scripts | ||||||
|  |  | ||||||
| Use the | Use the | ||||||
| [flock](https://manpages.debian.org/unstable/util-linux/flock.1.en.html) | [flock](https://manpages.debian.org/unstable/util-linux/flock.1.en.html) | ||||||
| @@ -1065,14 +1085,14 @@ $ flock --exclusive /path/to/storage/.Radicale.lock COMMAND | |||||||
| $ flock --shared /path/to/storage/.Radicale.lock COMMAND | $ flock --shared /path/to/storage/.Radicale.lock COMMAND | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| #### Linux and MacOS | ##### Linux and MacOS | ||||||
|  |  | ||||||
| Use the | Use the | ||||||
| [flock](https://manpages.debian.org/unstable/manpages-dev/flock.2.en.html) | [flock](https://manpages.debian.org/unstable/manpages-dev/flock.2.en.html) | ||||||
| syscall. Python provides it in the | syscall. Python provides it in the | ||||||
| [fcntl](https://docs.python.org/3/library/fcntl.html#fcntl.flock) module. | [fcntl](https://docs.python.org/3/library/fcntl.html#fcntl.flock) module. | ||||||
|  |  | ||||||
| #### Windows | ##### Windows | ||||||
|  |  | ||||||
| Use | Use | ||||||
| [LockFile](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365202%28v=vs.85%29.aspx) | [LockFile](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365202%28v=vs.85%29.aspx) | ||||||
| @@ -1081,7 +1101,7 @@ for exclusive access or | |||||||
| which also supports shared access. Setting `nNumberOfBytesToLockLow` to `1` | which also supports shared access. Setting `nNumberOfBytesToLockLow` to `1` | ||||||
| and `nNumberOfBytesToLockHigh` to `0` works. | and `nNumberOfBytesToLockHigh` to `0` works. | ||||||
|  |  | ||||||
| ### Manually creating collections | #### Manually creating collections | ||||||
|  |  | ||||||
| To create a new collection, you have to create the corresponding folder in the | To create a new collection, you have to create the corresponding folder in the | ||||||
| file system storage (e.g. `collection-root/user/calendar`). | file system storage (e.g. `collection-root/user/calendar`). | ||||||
| @@ -1105,65 +1125,38 @@ address books that are direct children of the path `/USERNAME/`. | |||||||
|  |  | ||||||
| Delete collections by deleting the corresponding folders. | Delete collections by deleting the corresponding folders. | ||||||
|  |  | ||||||
| ## Logging | ### Logging | ||||||
|  |  | ||||||
| Radicale logs to `stderr`. The verbosity of the log output can be controlled | Radicale logs to `stderr`. The verbosity of the log output can be controlled | ||||||
| with `--debug` command line argument or the `level` configuration option in | with `--debug` command line argument or the `level` configuration option in | ||||||
| the `logging` section. | the `logging` section. | ||||||
|  |  | ||||||
| ## Architecture | ### Architecture | ||||||
|  |  | ||||||
| Radicale is a small piece of software, but understanding it is not as | Radicale is a small piece of software, but understanding it is not as | ||||||
| easy as it seems. But don't worry, reading this short section is enough to | easy as it seems. But don't worry, reading this short section is enough to | ||||||
| understand what a CalDAV/CardDAV server is, and how Radicale's code is | understand what a CalDAV/CardDAV server is, and how Radicale's code is | ||||||
| organized. | organized. | ||||||
|  |  | ||||||
| ### Protocol overview | #### Protocol overview | ||||||
|  |  | ||||||
| Here is a simple overview of the global architecture for reaching a calendar or | Here is a simple overview of the global architecture for reaching a calendar or | ||||||
| an address book through network: | an address book through network: | ||||||
|  |  | ||||||
| <table> | | Part     | Layer                    | Protocol or Format                 | | ||||||
|   <thead> | |----------|--------------------------|------------------------------------| | ||||||
|     <tr> | | Server   | Calendar/Contact Storage | iCal/vCard                         | | ||||||
|       <th>Part</th> | | ''       | Calendar/Contact Server  | CalDAV/CardDAV Server              | | ||||||
|       <th>Layer</th> | | Transfer | Network                  | CalDAV/CardDAV (HTTP + TLS)        | | ||||||
|       <th>Protocol or Format</th> | | Client   | Calendar/Contact Client  | CalDAV/CardDAV Client              | | ||||||
|     </tr> | | ''       | GUI                      | Terminal, GTK, Web interface, etc. | | ||||||
|   </thead> |  | ||||||
|   <tbody> |  | ||||||
|     <tr> |  | ||||||
|       <td rowspan="2">Server</td> |  | ||||||
|       <td>Calendar/Contact Storage</td> |  | ||||||
|       <td>iCal/vCard</td> |  | ||||||
|     </tr> |  | ||||||
|     <tr> |  | ||||||
|       <td>Calendar/Contact Server</td> |  | ||||||
|       <td>CalDAV/CardDAV Server</td> |  | ||||||
|     </tr> |  | ||||||
|     <tr> |  | ||||||
|       <td>Transfer</td> |  | ||||||
|       <td>Network</td> |  | ||||||
|       <td>CalDAV/CardDAV (HTTP + TLS)</td> |  | ||||||
|     </tr> |  | ||||||
|     <tr> |  | ||||||
|       <td rowspan="2">Client</td> |  | ||||||
|       <td>Calendar/Contact Client</td> |  | ||||||
|       <td>CalDAV/CardDAV Client</td> |  | ||||||
|     </tr> |  | ||||||
|     <tr> |  | ||||||
|       <td>GUI</td> |  | ||||||
|       <td>Terminal, GTK, Web interface, etc.</td> |  | ||||||
|     </tr> |  | ||||||
|   </tbody> |  | ||||||
| </table> |  | ||||||
|  |  | ||||||
| Radicale is **only the server part** of this architecture. | Radicale is **only the server part** of this architecture. | ||||||
|  |  | ||||||
| Please note that: | Please note that: | ||||||
|  |  | ||||||
|   * CalDAV and CardDAV are superset protocols of WebDAV, | * CalDAV and CardDAV are superset protocols of WebDAV, | ||||||
|   * WebDAV is a superset protocol of HTTP. | * WebDAV is a superset protocol of HTTP. | ||||||
|  |  | ||||||
| Radicale being a CalDAV/CardDAV server, it also can be seen as a special WebDAV | Radicale being a CalDAV/CardDAV server, it also can be seen as a special WebDAV | ||||||
| and HTTP server. | and HTTP server. | ||||||
| @@ -1177,7 +1170,7 @@ If you want to see or edit your events and your contacts, you have to use | |||||||
| another software called a client, that can be a "normal" applications with | another software called a client, that can be a "normal" applications with | ||||||
| icons and buttons, a terminal or another web application. | icons and buttons, a terminal or another web application. | ||||||
|  |  | ||||||
| ### Code Architecture | #### Code Architecture | ||||||
|  |  | ||||||
| The ``radicale`` package offers the following modules. | The ``radicale`` package offers the following modules. | ||||||
|  |  | ||||||
| @@ -1236,12 +1229,12 @@ The ``radicale`` package offers the following modules. | |||||||
| : Helper functions for working with the XML part of CalDAV/CardDAV requests | : Helper functions for working with the XML part of CalDAV/CardDAV requests | ||||||
|   and responses. It's based on the ElementTree XML API. |   and responses. It's based on the ElementTree XML API. | ||||||
|  |  | ||||||
| ## Plugins | ### Plugins | ||||||
|  |  | ||||||
| Radicale can be extended by plugins for authentication, rights management and | Radicale can be extended by plugins for authentication, rights management and | ||||||
| storage. Plugins are **python** modules. | storage. Plugins are **python** modules. | ||||||
|  |  | ||||||
| ### Getting started | #### Getting started | ||||||
|  |  | ||||||
| To get started we walk through the creation of a simple authentication | To get started we walk through the creation of a simple authentication | ||||||
| plugin, that accepts login attempts with a static password. | plugin, that accepts login attempts with a static password. | ||||||
| @@ -1311,102 +1304,107 @@ You can uninstall the module with: | |||||||
| python3 -m pip uninstall radicale_static_password_auth | python3 -m pip uninstall radicale_static_password_auth | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### Authentication plugins | #### Authentication plugins | ||||||
|  |  | ||||||
| This plugin type is used to check login credentials. | This plugin type is used to check login credentials. | ||||||
| The module must contain a class `Auth` that extends | The module must contain a class `Auth` that extends | ||||||
| `radicale.auth.BaseAuth`. Take a look at the file `radicale/auth/__init__.py` | `radicale.auth.BaseAuth`. Take a look at the file `radicale/auth/__init__.py` | ||||||
| in Radicale's source code for more information. | in Radicale's source code for more information. | ||||||
|  |  | ||||||
| ### Rights management plugins | #### Rights management plugins | ||||||
|  |  | ||||||
| This plugin type is used to check if a user has access to a path. | This plugin type is used to check if a user has access to a path. | ||||||
| The module must contain a class `Rights` that extends | The module must contain a class `Rights` that extends | ||||||
| `radicale.rights.BaseRights`. Take a look at the file | `radicale.rights.BaseRights`. Take a look at the file | ||||||
| `radicale/rights/__init__.py` in Radicale's source code for more information. | `radicale/rights/__init__.py` in Radicale's source code for more information. | ||||||
|  |  | ||||||
| ### Web plugins | #### Web plugins | ||||||
|  |  | ||||||
| This plugin type is used to provide the web interface for Radicale. | This plugin type is used to provide the web interface for Radicale. | ||||||
| The module must contain a class `Web` that extends | The module must contain a class `Web` that extends | ||||||
| `radicale.web.BaseWeb`. Take a look at the file `radicale/web/__init__.py` in | `radicale.web.BaseWeb`. Take a look at the file `radicale/web/__init__.py` in | ||||||
| Radicale's source code for more information. | Radicale's source code for more information. | ||||||
|  |  | ||||||
| ### Storage plugins | #### Storage plugins | ||||||
|  |  | ||||||
| This plugin is used to store collections and items. | This plugin is used to store collections and items. | ||||||
| The module must contain a class `Storage` that extends | The module must contain a class `Storage` that extends | ||||||
| `radicale.storage.BaseStorage`. Take a look at the file | `radicale.storage.BaseStorage`. Take a look at the file | ||||||
| `radicale/storage/__init__.py` in Radicale's source code for more information. | `radicale/storage/__init__.py` in Radicale's source code for more information. | ||||||
|  |  | ||||||
| # Contribute | ## Contribute | ||||||
|  |  | ||||||
| ### Chat with Us on IRC | #### Chat with Us on IRC | ||||||
|  |  | ||||||
| Want to say something? Join our IRC room: `##kozea` on Freenode. | Want to say something? Join our IRC room: `##kozea` on Freenode. | ||||||
|  |  | ||||||
| ### Report Bugs | #### Report Bugs | ||||||
|  |  | ||||||
| Found a bug? Want a new feature? Report a new issue on the | Found a bug? Want a new feature? Report a new issue on the | ||||||
| [Radicale bug-tracker](https://github.com/Kozea/Radicale/issues). | [Radicale bug-tracker](https://github.com/Kozea/Radicale/issues). | ||||||
|  |  | ||||||
| ### Hack | #### Hack | ||||||
|  |  | ||||||
| Interested in hacking? Feel free to clone the | Interested in hacking? Feel free to clone the | ||||||
| [git repository on GitHub](https://github.com/Kozea/Radicale) if you want to | [git repository on GitHub](https://github.com/Kozea/Radicale) if you want to | ||||||
| add new features, fix bugs or update the documentation. | add new features, fix bugs or update the documentation. | ||||||
|  |  | ||||||
| ### Documentation | #### Documentation | ||||||
|  |  | ||||||
| To change or complement the documentation create a pull request to | To change or complement the documentation create a pull request to | ||||||
| [DOCUMENTATION.md](https://github.com/Kozea/Radicale/blob/master/DOCUMENTATION.md). | [DOCUMENTATION.md](https://github.com/Kozea/Radicale/blob/master/DOCUMENTATION.md). | ||||||
|  |  | ||||||
| # Download | ## Download | ||||||
|  |  | ||||||
| ### PyPI | #### PyPI | ||||||
|  |  | ||||||
| Radicale is [available on PyPI](https://pypi.python.org/pypi/Radicale/). To | Radicale is [available on PyPI](https://pypi.python.org/pypi/Radicale/). To | ||||||
| install, just type as superuser: | install, just type as superuser: | ||||||
|  |  | ||||||
|     $ python3 -m pip install --upgrade radicale | ```bash | ||||||
|  | python3 -m pip install --upgrade radicale | ||||||
|  | ``` | ||||||
|  |  | ||||||
| ### Git Repository | #### Git Repository | ||||||
|  |  | ||||||
| If you want the development version of Radicale, take a look at the | If you want the development version of Radicale, take a look at the | ||||||
| [git repository on GitHub](https://github.com/Kozea/Radicale/), or install it | [git repository on GitHub](https://github.com/Kozea/Radicale/), or install it | ||||||
| directly with: | directly with: | ||||||
|  |  | ||||||
|     $ python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz | ```bash | ||||||
|  | python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz | ||||||
|  | ``` | ||||||
|  |  | ||||||
| You can also download the content of the repository as an | You can also download the content of the repository as an | ||||||
| [archive](https://github.com/Kozea/Radicale/tarball/master). | [archive](https://github.com/Kozea/Radicale/tarball/master). | ||||||
|  |  | ||||||
| ### Source Packages | #### Source Packages | ||||||
|  |  | ||||||
| You can find the source packages of all releases on | You can find the source packages of all releases on | ||||||
| [GitHub](https://github.com/Kozea/Radicale/releases). | [GitHub](https://github.com/Kozea/Radicale/releases). | ||||||
|  |  | ||||||
| ### Linux Distribution Packages | #### Linux Distribution Packages | ||||||
|  |  | ||||||
| Radicale has been packaged for: | Radicale has been packaged for: | ||||||
|  |  | ||||||
|   * [ArchLinux](https://www.archlinux.org/packages/community/any/radicale/) by | * [ArchLinux](https://www.archlinux.org/packages/community/any/radicale/) by | ||||||
|   David Runge |   David Runge | ||||||
|   * [Debian](http://packages.debian.org/radicale) by Jonas Smedegaard | * [Debian](http://packages.debian.org/radicale) by Jonas Smedegaard | ||||||
|   * [Gentoo](https://packages.gentoo.org/packages/www-apps/radicale) | * [Gentoo](https://packages.gentoo.org/packages/www-apps/radicale) | ||||||
|   by René Neumann, Maxim Koltsov and Manuel Rüger |   by René Neumann, Maxim Koltsov and Manuel Rüger | ||||||
|   * [Fedora/RHEL/CentOS](https://src.fedoraproject.org/rpms/radicale) by Jorti and Peter Bieringer | * [Fedora/RHEL/CentOS](https://src.fedoraproject.org/rpms/radicale) by Jorti | ||||||
|   * [Mageia](http://madb.mageia.org/package/show/application/0/name/radicale) |   and Peter Bieringer | ||||||
|  | * [Mageia](http://madb.mageia.org/package/show/application/0/name/radicale) | ||||||
|   by Jani Välimaa |   by Jani Välimaa | ||||||
|   * [OpenBSD](http://openports.se/productivity/radicale) by Sergey Bronnikov, | * [OpenBSD](http://openports.se/productivity/radicale) by Sergey Bronnikov, | ||||||
|   Stuart Henderson and Ian Darwin |   Stuart Henderson and Ian Darwin | ||||||
|   * [openSUSE](http://software.opensuse.org/package/Radicale?search_term=radicale) | * [openSUSE](http://software.opensuse.org/package/Radicale?search_term=radicale) | ||||||
|   by Ákos Szőts and Rueckert |   by Ákos Szőts and Rueckert | ||||||
|   * [PyPM](http://code.activestate.com/pypm/radicale/) | * [PyPM](http://code.activestate.com/pypm/radicale/) | ||||||
|   * [Slackware](http://schoepfer.info/slackware.xhtml#packages-network) by | * [Slackware](http://schoepfer.info/slackware.xhtml#packages-network) by | ||||||
|   Johannes Schöpfer |   Johannes Schöpfer | ||||||
|   * [Trisquel](http://packages.trisquel.info/search?searchon=names&keywords=radicale) | * [Trisquel](http://packages.trisquel.info/search?searchon=names&keywords=radicale) | ||||||
|   * [Ubuntu](http://packages.ubuntu.com/radicale) by the MOTU and Jonas | * [Ubuntu](http://packages.ubuntu.com/radicale) by the MOTU and Jonas | ||||||
|   Smedegaard |   Smedegaard | ||||||
|  |  | ||||||
| Radicale is also | Radicale is also | ||||||
| @@ -1416,9 +1414,9 @@ and has a Dockerfile. | |||||||
| If you are interested in creating packages for other Linux distributions, read | If you are interested in creating packages for other Linux distributions, read | ||||||
| the ["Contribute" section](#contribute). | the ["Contribute" section](#contribute). | ||||||
|  |  | ||||||
| # About | ## About | ||||||
|  |  | ||||||
| ### Main Goals | #### Main Goals | ||||||
|  |  | ||||||
| Radicale is a complete calendar and contact storing and manipulating | Radicale is a complete calendar and contact storing and manipulating | ||||||
| solution. It can store multiple calendars and multiple address books. | solution. It can store multiple calendars and multiple address books. | ||||||
| @@ -1433,7 +1431,7 @@ preconfigured to work out-of-the-box. | |||||||
| Radicale is written in Python. It runs on most of the UNIX-like platforms | Radicale is written in Python. It runs on most of the UNIX-like platforms | ||||||
| (Linux, \*BSD, macOS) and Windows. It is free and open-source software. | (Linux, \*BSD, macOS) and Windows. It is free and open-source software. | ||||||
|  |  | ||||||
| ### What Radicale Will Never Be | #### What Radicale Will Never Be | ||||||
|  |  | ||||||
| Radicale is a server, not a client. No interfaces will be created to work with | Radicale is a server, not a client. No interfaces will be created to work with | ||||||
| the server. | the server. | ||||||
| @@ -1446,14 +1444,14 @@ CalDAV and CardDAV are the best open standards available, and they are quite | |||||||
| widely used by both clients and servers. We decided to use it, and we will not | widely used by both clients and servers. We decided to use it, and we will not | ||||||
| use another one. | use another one. | ||||||
|  |  | ||||||
| ### Technical Choices | #### Technical Choices | ||||||
|  |  | ||||||
| Important global development choices have been decided before writing | Important global development choices have been decided before writing | ||||||
| code. They are very useful to understand why the Radicale Project is different | code. They are very useful to understand why the Radicale Project is different | ||||||
| from other CalDAV and CardDAV servers, and why features are included or not in | from other CalDAV and CardDAV servers, and why features are included or not in | ||||||
| the code. | the code. | ||||||
|  |  | ||||||
| #### Oriented to Calendar and Contact User Agents | ##### Oriented to Calendar and Contact User Agents | ||||||
|  |  | ||||||
| Calendar and contact servers work with calendar and contact clients, using a | Calendar and contact servers work with calendar and contact clients, using a | ||||||
| defined protocol. CalDAV and CardDAV are good protocols, covering lots of | defined protocol. CalDAV and CardDAV are good protocols, covering lots of | ||||||
| @@ -1471,7 +1469,7 @@ Even if it tries it best to follow the RFCs, Radicale does not and **will not** | |||||||
| blindly implement the CalDAV and CardDAV standards. It is mainly designed to | blindly implement the CalDAV and CardDAV standards. It is mainly designed to | ||||||
| support the CalDAV and CardDAV implementations of different clients. | support the CalDAV and CardDAV implementations of different clients. | ||||||
|  |  | ||||||
| #### Simple | ##### Simple | ||||||
|  |  | ||||||
| Radicale is designed to be simple to install, simple to configure, simple to | Radicale is designed to be simple to install, simple to configure, simple to | ||||||
| use. | use. | ||||||
| @@ -1486,7 +1484,7 @@ or need a strong configuration, the Radicale Server can (sometimes, if not | |||||||
| often) be launched in a couple of minutes, if you follow the | often) be launched in a couple of minutes, if you follow the | ||||||
| [tutorial](#tutorials/simple-5-minute-setup). | [tutorial](#tutorials/simple-5-minute-setup). | ||||||
|  |  | ||||||
| #### Lazy | ##### Lazy | ||||||
|  |  | ||||||
| The CalDAV RFC defines what must be done, what can be done and what cannot be | The CalDAV RFC defines what must be done, what can be done and what cannot be | ||||||
| done. Many violations of the protocol are totally defined and behaviors are | done. Many violations of the protocol are totally defined and behaviors are | ||||||
| @@ -1497,7 +1495,7 @@ violations do not exist. That is why most of the errors in client requests have | |||||||
| undetermined consequences for the lazy server that can reply good answers, bad | undetermined consequences for the lazy server that can reply good answers, bad | ||||||
| answers, or even no answer. | answers, or even no answer. | ||||||
|  |  | ||||||
| ### History | #### History | ||||||
|  |  | ||||||
| Radicale has been started as a (free topic) stupid school project replacing | Radicale has been started as a (free topic) stupid school project replacing | ||||||
| another (assigned topic) even more stupid school project. | another (assigned topic) even more stupid school project. | ||||||
|   | |||||||
							
								
								
									
										525
									
								
								NEWS.md
									
									
									
									
									
								
							
							
						
						
									
										525
									
								
								NEWS.md
									
									
									
									
									
								
							| @@ -4,52 +4,53 @@ | |||||||
|  |  | ||||||
| ## 3.0.6 | ## 3.0.6 | ||||||
|  |  | ||||||
|   * Allow web plugins to handle POST requests | * Allow web plugins to handle POST requests | ||||||
|  |  | ||||||
| ## 3.0.5 | ## 3.0.5 | ||||||
|  |  | ||||||
|   * Start storage hook in own process group | * Start storage hook in own process group | ||||||
|   * Kill storage hook on error or exit | * Kill storage hook on error or exit | ||||||
|   * Try to kill child processes of storage hook | * 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) | * Internal Server: Exit immediately when signal is received | ||||||
|  |   (do not wait for clients or storage hook to finish) | ||||||
|  |  | ||||||
| ## 3.0.4 | ## 3.0.4 | ||||||
|  |  | ||||||
|   * Fix internal server on FreeBSD | * Fix internal server on FreeBSD | ||||||
|  |  | ||||||
| ## 3.0.3 | ## 3.0.3 | ||||||
|  |  | ||||||
|   * Fix internal server on OpenBSD | * Fix internal server on OpenBSD | ||||||
|  |  | ||||||
| ## 3.0.2 | ## 3.0.2 | ||||||
|  |  | ||||||
|   * Use 403 response for supported-report and valid-sync-token errors | * Use 403 response for supported-report and valid-sync-token errors | ||||||
|   * Internal server: Handle missing IPv6 support | * Internal server: Handle missing IPv6 support | ||||||
|  |  | ||||||
| ## 3.0.1 | ## 3.0.1 | ||||||
|  |  | ||||||
|   * Fix XML error messages | * Fix XML error messages | ||||||
|  |  | ||||||
| ## 3.0.0 | ## 3.0.0 | ||||||
|  |  | ||||||
| This release is incompatible with previous releases. | This release is incompatible with previous releases. | ||||||
| See the upgrade checklist below. | See the upgrade checklist below. | ||||||
|  |  | ||||||
|   * Parallel write requests | * Parallel write requests | ||||||
|   * Support PyPy | * Support PyPy | ||||||
|   * Protect against XML denial-of-service attacks | * Protect against XML denial-of-service attacks | ||||||
|   * Check for duplicated UIDs in calendars/address books | * Check for duplicated UIDs in calendars/address books | ||||||
|   * Only add missing UIDs for uploaded whole calendars/address books | * Only add missing UIDs for uploaded whole calendars/address books | ||||||
|   * Switch from md5 to sha256 for UIDs and tokens | * Switch from md5 to sha256 for UIDs and tokens | ||||||
|   * Code cleanup: | * Code cleanup: | ||||||
|   * All plugin interfaces were simplified and are incompatible with |   * All plugin interfaces were simplified and are incompatible with | ||||||
|     old plugins |     old plugins | ||||||
|   * Major refactor |   * Major refactor | ||||||
|   * Never sanitize paths multiple times (check if they are sanitized) |   * Never sanitize paths multiple times (check if they are sanitized) | ||||||
|   * Config | * Config | ||||||
|       * Multiple configuration files separated by ``:`` (resp. ``;`` |   * Multiple configuration files separated by `:` (resp. `;` | ||||||
|     on Windows) |     on Windows) | ||||||
|       * Optional configuration files by prepending file path with ``?`` |   * Optional configuration files by prepending file path with `?` | ||||||
|   * Check validity of every configuration file and command line |   * Check validity of every configuration file and command line | ||||||
|     arguments separately |     arguments separately | ||||||
|     * Report the source of invalid configuration parameters in |     * Report the source of invalid configuration parameters in | ||||||
| @@ -58,36 +59,36 @@ See the upgrade checklist below. | |||||||
|     * Store configuration as parsed values |     * Store configuration as parsed values | ||||||
|     * Use Schema that describes configuration and allow plugins to apply |     * Use Schema that describes configuration and allow plugins to apply | ||||||
|       their own schemas |       their own schemas | ||||||
|           * Mark internal settings with ``_`` |     * Mark internal settings with `_` | ||||||
|   * Internal server | * Internal server | ||||||
|   * Bind to IPv4 and IPv6 address, when both are available for hostname |   * Bind to IPv4 and IPv6 address, when both are available for hostname | ||||||
|       * Set default address to ``localhost:5232`` |   * Set default address to `localhost:5232` | ||||||
|   * Remove settings for SSL ciphers and protocol versions (enforce safe |   * Remove settings for SSL ciphers and protocol versions (enforce safe | ||||||
|     defaults instead) |     defaults instead) | ||||||
|   * Remove settings for file locking because they are of little use |   * Remove settings for file locking because they are of little use | ||||||
|   * Remove daemonization (should be handled by service managers) |   * Remove daemonization (should be handled by service managers) | ||||||
|   * Logging | * Logging | ||||||
|   * Replace complex Python logger configuration with simple |   * Replace complex Python logger configuration with simple | ||||||
|         ``logging.level`` setting |     `logging.level` setting | ||||||
|       * Write PID and ``threadName`` instead of cryptic id's in log messages |   * Write PID and `threadName` instead of cryptic id's in log messages | ||||||
|       * Use ``wsgi.errors`` for logging (as required by the WSGI spec) |   * Use `wsgi.errors` for logging (as required by the WSGI spec) | ||||||
|   * Code cleanup: |   * Code cleanup: | ||||||
|           * Don't pass logger object around (use ``logging.getLogger()`` |     * Don't pass logger object around (use `logging.getLogger()` | ||||||
|       instead) |       instead) | ||||||
|   * Auth | * Auth | ||||||
|       * Use ``md5`` as default for ``htpasswd_encryption`` setting |   * Use `md5` as default for `htpasswd_encryption` setting | ||||||
|       * Move setting ``realm`` from section ``server`` to ``auth`` |   * Move setting `realm` from section `server` to `auth` | ||||||
|   * Rights | * Rights | ||||||
|       * Use permissions ``RW`` for non-leaf collections and ``rw`` for |   * Use permissions `RW` for non-leaf collections and `rw` for | ||||||
|     address books/calendars |     address books/calendars | ||||||
|       * New permission ``i`` that only allows access with HTTP method GET |   * New permission `i` that only allows access with HTTP method GET | ||||||
|     (CalDAV/CardDAV is susceptible to expensive search requests) |     (CalDAV/CardDAV is susceptible to expensive search requests) | ||||||
|   * Web | * Web | ||||||
|   * Add upload dialog for calendars/address books from file |   * Add upload dialog for calendars/address books from file | ||||||
|   * Show startup loading message |   * Show startup loading message | ||||||
|   * Show warning if JavaScript is disabled |   * Show warning if JavaScript is disabled | ||||||
|   * Pass HTML Validator |   * Pass HTML Validator | ||||||
|   * Storage | * Storage | ||||||
|   * Check for missing UIDs in items |   * Check for missing UIDs in items | ||||||
|   * Check for child collections in address books and calendars |   * Check for child collections in address books and calendars | ||||||
|   * Code cleanup: |   * Code cleanup: | ||||||
| @@ -95,221 +96,214 @@ See the upgrade checklist below. | |||||||
|  |  | ||||||
| ## Upgrade checklist | ## Upgrade checklist | ||||||
|  |  | ||||||
|   * Config | * Config | ||||||
|   * Some settings were removed |   * Some settings were removed | ||||||
|       * The default of ``auth.htpasswd_encryption`` changed to ``md5`` |   * The default of `auth.htpasswd_encryption` changed to `md5` | ||||||
|       * The setting ``server.realm`` moved to ``auth.realm`` |   * The setting `server.realm` moved to `auth.realm` | ||||||
|       * The setting ``logging.debug`` was replaced by ``logging.level`` |   * The setting `logging.debug` was replaced by `logging.level` | ||||||
|       * The format of the ``rights.file`` configuration file changed: |   * The format of the `rights.file` configuration file changed: | ||||||
|           * Permission ``r`` replaced by ``Rr`` |     * Permission `r` replaced by `Rr` | ||||||
|           * Permission ``w`` replaced by ``Ww`` |     * Permission `w` replaced by `Ww` | ||||||
|           * New permission ``i`` added as subset of ``r`` |     * New permission `i` added as subset of `r` | ||||||
|           * Replaced variable ``%(login)s`` by ``{user}`` |     * Replaced variable `%(login)s` by `{user}` | ||||||
|           * Removed variable ``%(path)s`` |     * Removed variable `%(path)s` | ||||||
|           * ``{`` must be escaped as ``{{`` and ``}`` as ``}}`` in regexes |     * `{` must be escaped as `{{` and `}` as `}}` in regexes | ||||||
|   * File system storage | * File system storage | ||||||
|   * The storage format is compatible with Radicale 2.x.x |   * The storage format is compatible with Radicale 2.x.x | ||||||
|       * Run ``radicale --verify-storage`` to check for errors |   * Run `radicale --verify-storage` to check for errors | ||||||
|   * Custom plugins: | * Custom plugins: | ||||||
|       * ``auth`` and ``web`` plugins require minor adjustments |   * `auth` and `web` plugins require minor adjustments | ||||||
|       * ``rights`` plugins must be adapted to the new permission model |   * `rights` plugins must be adapted to the new permission model | ||||||
|       * ``storage`` plugins require major changes |   * `storage` plugins require major changes | ||||||
|  |  | ||||||
| ## 2.1.10 - Wild Radish | ## 2.1.10 - Wild Radish | ||||||
|  |  | ||||||
| This release is compatible with version 2.0.0. | This release is compatible with version 2.0.0. | ||||||
|  |  | ||||||
|   * Update required versions for dependencies | * Update required versions for dependencies | ||||||
|   * Get ``RADICALE_CONFIG`` from WSGI environ | * Get `RADICALE_CONFIG` from WSGI environ | ||||||
|   * Improve HTTP status codes | * Improve HTTP status codes | ||||||
|   * Fix race condition in storage lock creation | * Fix race condition in storage lock creation | ||||||
|   * Raise default limits for content length and timeout | * Raise default limits for content length and timeout | ||||||
|   * Log output from hook | * Log output from hook | ||||||
|  |  | ||||||
| ## 2.1.9 - Wild Radish | ## 2.1.9 - Wild Radish | ||||||
|  |  | ||||||
| This release is compatible with version 2.0.0. | This release is compatible with version 2.0.0. | ||||||
|  |  | ||||||
|   * Specify versions for dependencies | * Specify versions for dependencies | ||||||
|   * Move WSGI initialization into module | * Move WSGI initialization into module | ||||||
|   * Check if ``REPORT`` method is actually supported | * Check if `REPORT` method is actually supported | ||||||
|   * Include ``rights`` file in source distribution | * Include `rights` file in source distribution | ||||||
|   * Specify ``md5`` and ``bcrypt`` as extras | * Specify `md5` and `bcrypt` as extras | ||||||
|   * Improve logging messages | * Improve logging messages | ||||||
|   * Windows: Fix crash when item path is a directory | * Windows: Fix crash when item path is a directory | ||||||
|  |  | ||||||
| ## 2.1.8 - Wild Radish | ## 2.1.8 - Wild Radish | ||||||
|  |  | ||||||
| This release is compatible with version 2.0.0. | This release is compatible with version 2.0.0. | ||||||
|  |  | ||||||
|   * Flush files before fsync'ing | * Flush files before fsync'ing | ||||||
|  |  | ||||||
| ## 2.1.7 - Wild Radish | ## 2.1.7 - Wild Radish | ||||||
|  |  | ||||||
| This release is compatible with version 2.0.0. | This release is compatible with version 2.0.0. | ||||||
|  |  | ||||||
|   * Don't print warning when cache format changes | * Don't print warning when cache format changes | ||||||
|   * Add documentation for ``BaseAuth`` | * Add documentation for `BaseAuth` | ||||||
|   * Add ``is_authenticated2(login, user, password)`` to ``BaseAuth`` | * Add `is_authenticated2(login, user, password)` to `BaseAuth` | ||||||
|   * Fix names of custom properties in PROPFIND requests with | * Fix names of custom properties in PROPFIND requests with | ||||||
|     ``D:propname`` or ``D:allprop`` |   `D:propname` or `D:allprop` | ||||||
|   * Return all properties in PROPFIND requests with ``D:propname`` or | * Return all properties in PROPFIND requests with `D:propname` or | ||||||
|     ``D:allprop`` |   `D:allprop` | ||||||
|   * Allow ``D:displayname`` property on all collections | * Allow `D:displayname` property on all collections | ||||||
|   * Answer with ``D:unauthenticated`` for ``D:current-user-principal`` property | * Answer with `D:unauthenticated` for `D:current-user-principal` property | ||||||
|   when not logged in |   when not logged in | ||||||
|   * Remove non-existing ``ICAL:calendar-color`` and ``C:calendar-timezone`` | * Remove non-existing `ICAL:calendar-color` and `C:calendar-timezone` | ||||||
|     properties from PROPFIND requests with ``D:propname`` or ``D:allprop`` |   properties from PROPFIND requests with `D:propname` or `D:allprop` | ||||||
|   * Add ``D:owner`` property to calendar and address book objects | * Add `D:owner` property to calendar and address book objects | ||||||
|   * Remove ``D:getetag`` and ``D:getlastmodified`` properties from regular | * Remove `D:getetag` and `D:getlastmodified` properties from regular | ||||||
|   collections |   collections | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 2.1.6 - Wild Radish | ## 2.1.6 - Wild Radish | ||||||
|  |  | ||||||
| This release is compatible with version 2.0.0. | This release is compatible with version 2.0.0. | ||||||
|  |  | ||||||
|   * Fix content-type of VLIST | * Fix content-type of VLIST | ||||||
|   * Specify correct COMPONENT in content-type of VCALENDAR | * Specify correct COMPONENT in content-type of VCALENDAR | ||||||
|   * Cache COMPONENT of calendar objects (improves speed with some clients) | * Cache COMPONENT of calendar objects (improves speed with some clients) | ||||||
|   * Stricter parsing of filters | * Stricter parsing of filters | ||||||
|   * Improve support for CardDAV filter | * Improve support for CardDAV filter | ||||||
|   * Fix some smaller bugs in CalDAV filter | * Fix some smaller bugs in CalDAV filter | ||||||
|   * Add X-WR-CALNAME and X-WR-CALDESC to calendars downloaded via HTTP/WebDAV | * 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 | * Use X-WR-CALNAME and X-WR-CALDESC from calendars published via WebDAV | ||||||
|  |  | ||||||
| ## 2.1.5 - Wild Radish | ## 2.1.5 - Wild Radish | ||||||
|  |  | ||||||
| This release is compatible with version 2.0.0. | This release is compatible with version 2.0.0. | ||||||
|  |  | ||||||
|   * Add ``--verify-storage`` command-line argument | * Add `--verify-storage` command-line argument | ||||||
|   * Allow comments in the htpasswd file | * Allow comments in the htpasswd file | ||||||
|   * Don't strip whitespaces from user names and passwords in the htpasswd file | * Don't strip whitespaces from user names and passwords in the htpasswd file | ||||||
|   * Remove cookies from logging output | * Remove cookies from logging output | ||||||
|   * Allow uploads of whole collections with many components | * Allow uploads of whole collections with many components | ||||||
|   * Show warning message if server.timeout is used with Python < 3.5.2 | * Show warning message if server.timeout is used with Python < 3.5.2 | ||||||
|  |  | ||||||
| ## 2.1.4 - Wild Radish | ## 2.1.4 - Wild Radish | ||||||
|  |  | ||||||
| This release is compatible with version 2.0.0. | This release is compatible with version 2.0.0. | ||||||
|  |  | ||||||
|   * Fix incorrect time range matching and calculation for some edge-cases with | * Fix incorrect time range matching and calculation for some edge-cases with | ||||||
|   rescheduled recurrences |   rescheduled recurrences | ||||||
|   * Fix owner property | * Fix owner property | ||||||
|  |  | ||||||
| ## 2.1.3 - Wild Radish | ## 2.1.3 - Wild Radish | ||||||
|  |  | ||||||
| This release is compatible with version 2.0.0. | This release is compatible with version 2.0.0. | ||||||
|  |  | ||||||
|   * Enable timeout for SSL handshakes and move them out of the main thread | * Enable timeout for SSL handshakes and move them out of the main thread | ||||||
|   * Create cache entries during upload of items | * Create cache entries during upload of items | ||||||
|   * Stop built-in server on Windows when Ctrl+C is pressed | * Stop built-in server on Windows when Ctrl+C is pressed | ||||||
|   * Prevent slow down when multiple requests hit a collection during cache warm-up | * Prevent slow down when multiple requests hit a collection during cache warm-up | ||||||
|  |  | ||||||
| ## 2.1.2 - Wild Radish | ## 2.1.2 - Wild Radish | ||||||
|  |  | ||||||
| This release is compatible with version 2.0.0. | This release is compatible with version 2.0.0. | ||||||
|  |  | ||||||
|   * Remove workarounds for bugs in VObject < 0.9.5 | * Remove workarounds for bugs in VObject < 0.9.5 | ||||||
|   * Error checking of collection tags and associated components | * Error checking of collection tags and associated components | ||||||
|   * Improve error checking of uploaded collections and components | * Improve error checking of uploaded collections and components | ||||||
|   * Don't delete empty collection properties implicitly | * Don't delete empty collection properties implicitly | ||||||
|   * Improve logging of VObject serialization | * Improve logging of VObject serialization | ||||||
|  |  | ||||||
| ## 2.1.1 - Wild Radish Again | ## 2.1.1 - Wild Radish Again | ||||||
|  |  | ||||||
| This release is compatible with version 2.0.0. | This release is compatible with version 2.0.0. | ||||||
|  |  | ||||||
|   * Add missing UIDs instead of failing | * Add missing UIDs instead of failing | ||||||
|   * Improve error checking of calendar and address book objects | * Improve error checking of calendar and address book objects | ||||||
|   * Fix upload of whole address books | * Fix upload of whole address books | ||||||
|  |  | ||||||
| ## 2.1.0 - Wild Radish | ## 2.1.0 - Wild Radish | ||||||
|  |  | ||||||
| This release is compatible with version 2.0.0. | This release is compatible with version 2.0.0. | ||||||
|  |  | ||||||
|   * Built-in web interface for creating and managing address books and calendars | * Built-in web interface for creating and managing address books and calendars | ||||||
|   * can be extended with web plugins |   * can be extended with web plugins | ||||||
|   * Much faster storage backend | * Much faster storage backend | ||||||
|   * Significant reduction in memory usage | * Significant reduction in memory usage | ||||||
|   * Improved logging | * Improved logging | ||||||
|   * Include paths (of invalid items / requests) in log messages |   * Include paths (of invalid items / requests) in log messages | ||||||
|   * Include configuration values causing problems in log messages |   * Include configuration values causing problems in log messages | ||||||
|   * Log warning message for invalid requests by clients |   * Log warning message for invalid requests by clients | ||||||
|   * Log error message for invalid files in the storage backend |   * Log error message for invalid files in the storage backend | ||||||
|   * No stack traces unless debugging is enabled |   * No stack traces unless debugging is enabled | ||||||
|   * Time range filter also regards overwritten recurrences | * Time range filter also regards overwritten recurrences | ||||||
|   * Items that couldn't be filtered because of bugs in VObject are always | * Items that couldn't be filtered because of bugs in VObject are always | ||||||
|   returned (and a warning message is logged) |   returned (and a warning message is logged) | ||||||
|   * Basic error checking of configuration files | * Basic error checking of configuration files | ||||||
|   * File system locking isn't disabled implicitly anymore, instead a new | * File system locking isn't disabled implicitly anymore, instead a new | ||||||
|   configuration option gets introduced |   configuration option gets introduced | ||||||
|   * The permissions of the lock file are not changed anymore | * The permissions of the lock file are not changed anymore | ||||||
|   * Support for sync-token | * Support for sync-token | ||||||
|   * Support for client-side SSL certificates | * Support for client-side SSL certificates | ||||||
|   * Rights plugins can decide if access to an item is granted explicitly | * Rights plugins can decide if access to an item is granted explicitly | ||||||
|   * Respond with 403 instead of 404 for principal collections of non-existing |   * Respond with 403 instead of 404 for principal collections of non-existing | ||||||
|         users when ``owner_only`` plugin is used (information leakage) |     users when `owner_only` plugin is used (information leakage) | ||||||
|   * Authentication plugins can provide the login and password from the | * Authentication plugins can provide the login and password from the | ||||||
|   environment |   environment | ||||||
|       * new ``remote_user`` plugin, that gets the login from the ``REMOTE_USER`` |   * new `remote_user` plugin, that gets the login from the `REMOTE_USER` | ||||||
|     environment variable (for WSGI server) |     environment variable (for WSGI server) | ||||||
|       * new ``http_x_remote_user`` plugin, that gets the login from the |   * new `http_x_remote_user` plugin, that gets the login from the | ||||||
|         ``X-Remote-User`` HTTP header (for reverse proxies) |     `X-Remote-User` HTTP header (for reverse proxies) | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 2.0.0 - Little Big Radish | ## 2.0.0 - Little Big Radish | ||||||
|  |  | ||||||
| This feature is not compatible with the 1.x.x versions. Follow our | 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 | [migration guide](https://radicale.org/2.1.html#documentation/migration-from-1xx-to-2xx) | ||||||
| 2.0.0. | if you want to switch from 1.x.x to 2.0.0. | ||||||
|  |  | ||||||
|   * Support Python 3.3+ only, Python 2 is not supported anymore | * Support Python 3.3+ only, Python 2 is not supported anymore | ||||||
|   * Keep only one simple filesystem-based storage system | * Keep only one simple filesystem-based storage system | ||||||
|   * Remove built-in Git support | * Remove built-in Git support | ||||||
|   * Remove built-in authentication modules | * Remove built-in authentication modules | ||||||
|   * Keep the WSGI interface, use Python HTTP server by default | * Keep the WSGI interface, use Python HTTP server by default | ||||||
|   * Use a real iCal parser, rely on the "vobject" external module | * Use a real iCal parser, rely on the "vobject" external module | ||||||
|   * Add a solid calendar discovery | * Add a solid calendar discovery | ||||||
|   * Respect the difference between "files" and "folders", don't rely on slashes | * Respect the difference between "files" and "folders", don't rely on slashes | ||||||
|   * Remove the calendar creation with GET requests | * Remove the calendar creation with GET requests | ||||||
|   * Be stateless | * Be stateless | ||||||
|   * Use a file locker | * Use a file locker | ||||||
|   * Add threading | * Add threading | ||||||
|   * Get atomic writes | * Get atomic writes | ||||||
|   * Support new filters | * Support new filters | ||||||
|   * Support read-only permissions | * Support read-only permissions | ||||||
|   * Allow External plugins for authentication, rights management, storage and | * Allow External plugins for authentication, rights management, storage and | ||||||
|   version control |   version control | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 1.1.4 - Fifth Law of Nature | ## 1.1.4 - Fifth Law of Nature | ||||||
|  |  | ||||||
|   * Use ``shutil.move`` for ``--export-storage`` | * Use `shutil.move` for `--export-storage` | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 1.1.3 - Fourth Law of Nature | ## 1.1.3 - Fourth Law of Nature | ||||||
|  |  | ||||||
|   * Add a ``--export-storage=FOLDER`` command-line argument (by Unrud, see #606) | * Add a `--export-storage=FOLDER` command-line argument (by Unrud, see #606) | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 1.1.2 - Third Law of Nature | ## 1.1.2 - Third Law of Nature | ||||||
|  |  | ||||||
|   * **Security fix**: Add a random timer to avoid timing oracles and simple | * **Security fix**: Add a random timer to avoid timing oracles and simple | ||||||
|   bruteforce attacks when using the htpasswd authentication method. |   bruteforce attacks when using the htpasswd authentication method. | ||||||
|   * Various minor fixes. | * Various minor fixes. | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 1.1.1 - Second Law of Nature | ## 1.1.1 - Second Law of Nature | ||||||
|  |  | ||||||
|   * Fix the owner_write rights rule | * Fix the owner_write rights rule | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 1.1 - Law of Nature | ## 1.1 - Law of Nature | ||||||
|  |  | ||||||
| One feature in this release is **not backward compatible**: | One feature in this release is **not backward compatible**: | ||||||
|  |  | ||||||
|   * Use the first matching section for rights (inspired from daald) | * Use the first matching section for rights (inspired from daald) | ||||||
|  |  | ||||||
| Now, the first section matching the path and current user in your custom rights | 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 | file is used. In the previous versions, the most permissive rights of all the | ||||||
| @@ -319,175 +313,158 @@ specific rules at the top of the file independant from the generic ones. | |||||||
| Many **improvements in this release are related to security**, you should | Many **improvements in this release are related to security**, you should | ||||||
| upgrade Radicale as soon as possible: | upgrade Radicale as soon as possible: | ||||||
|  |  | ||||||
|   * Improve the regex used for well-known URIs (by Unrud) | * Improve the regex used for well-known URIs (by Unrud) | ||||||
|   * Prevent regex injection in rights management (by Unrud) | * Prevent regex injection in rights management (by Unrud) | ||||||
|   * Prevent crafted HTTP request from calling arbitrary functions (by Unrud) | * Prevent crafted HTTP request from calling arbitrary functions (by Unrud) | ||||||
|   * Improve URI sanitation and conversion to filesystem path (by Unrud) | * Improve URI sanitation and conversion to filesystem path (by Unrud) | ||||||
|   * Decouple the daemon from its parent environment (by Unrud) | * Decouple the daemon from its parent environment (by Unrud) | ||||||
|  |  | ||||||
| Some bugs have been fixed and little enhancements have been added: | Some bugs have been fixed and little enhancements have been added: | ||||||
|  |  | ||||||
|   * Assign new items to corret key (by Unrud) | * Assign new items to corret key (by Unrud) | ||||||
|   * Avoid race condition in PID file creation (by Unrud) | * Avoid race condition in PID file creation (by Unrud) | ||||||
|   * Improve the docker version (by cdpb) | * Improve the docker version (by cdpb) | ||||||
|   * Encode message and commiter for git commits | * Encode message and commiter for git commits | ||||||
|   * Test with Python 3.5 | * Test with Python 3.5 | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 1.0.1 - Sunflower Again | ## 1.0.1 - Sunflower Again | ||||||
|  |  | ||||||
|   * Update the version because of a **stupid** "feature"™ of PyPI | * Update the version because of a **stupid** "feature"™ of PyPI | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 1.0 - Sunflower | ## 1.0 - Sunflower | ||||||
|  |  | ||||||
|   * Enhanced performances (by Mathieu Dupuy) | * Enhanced performances (by Mathieu Dupuy) | ||||||
|   * Add MD5-APR1 and BCRYPT for htpasswd-based authentication (by Jan-Philip Gehrcke) | * Add MD5-APR1 and BCRYPT for htpasswd-based authentication (by Jan-Philip Gehrcke) | ||||||
|   * Use PAM service (by Stephen Paul Weber) | * Use PAM service (by Stephen Paul Weber) | ||||||
|   * Don't discard PROPPATCH on empty collections (by Markus Unterwaditzer) | * Don't discard PROPPATCH on empty collections (by Markus Unterwaditzer) | ||||||
|   * Write the path of the collection in the git message (by Matthew Monaco) | * Write the path of the collection in the git message (by Matthew Monaco) | ||||||
|   * Tests launched on Travis | * Tests launched on Travis | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 0.10 - Lovely Endless Grass | ## 0.10 - Lovely Endless Grass | ||||||
|  |  | ||||||
|   * Support well-known URLs (by Mathieu Dupuy) | * Support well-known URLs (by Mathieu Dupuy) | ||||||
|   * Fix collection discovery (by Markus Unterwaditzer) | * Fix collection discovery (by Markus Unterwaditzer) | ||||||
|   * Reload logger config on SIGHUP (by Élie Bouttier) | * Reload logger config on SIGHUP (by Élie Bouttier) | ||||||
|   * Remove props files when deleting a collection (by Vincent Untz) | * Remove props files when deleting a collection (by Vincent Untz) | ||||||
|   * Support salted SHA1 passwords (by Marc Kleine-Budde) | * Support salted SHA1 passwords (by Marc Kleine-Budde) | ||||||
|   * Don't spam the logs about non-SSL IMAP connections to localhost (by Giel van Schijndel) | * Don't spam the logs about non-SSL IMAP connections to localhost (by Giel van Schijndel) | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 0.9 - Rivers | ## 0.9 - Rivers | ||||||
|  |  | ||||||
|   * Custom handlers for auth, storage and rights (by Sergey Fursov) | * Custom handlers for auth, storage and rights (by Sergey Fursov) | ||||||
|   * 1-file-per-event storage (by Jean-Marc Martins) | * 1-file-per-event storage (by Jean-Marc Martins) | ||||||
|   * Git support for filesystem storages (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) | * DB storage working with PostgreSQL, MariaDB and SQLite (by Jean-Marc Martins) | ||||||
|   * Clean rights manager based on regular expressions (by Sweil) | * Clean rights manager based on regular expressions (by Sweil) | ||||||
|   * Support of contacts for Apple's clients | * Support of contacts for Apple's clients | ||||||
|   * Support colors (by Jochen Sprickerhof) | * Support colors (by Jochen Sprickerhof) | ||||||
|   * Decode URLs in XML (by Jean-Marc Martins) | * Decode URLs in XML (by Jean-Marc Martins) | ||||||
|   * Fix PAM authentication (by Stepan Henek) | * Fix PAM authentication (by Stepan Henek) | ||||||
|   * Use consistent etags (by 9m66p93w) | * Use consistent etags (by 9m66p93w) | ||||||
|   * Use consistent sorting order (by Daniel Danner) | * Use consistent sorting order (by Daniel Danner) | ||||||
|   * Return 401 on unauthorized DELETE requests (by Eduard Braun) | * Return 401 on unauthorized DELETE requests (by Eduard Braun) | ||||||
|   * Move pid file creation in child process (by Mathieu Dupuy) | * Move pid file creation in child process (by Mathieu Dupuy) | ||||||
|   * Allow requests without base_prefix (by jheidemann) | * Allow requests without base_prefix (by jheidemann) | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 0.8 - Rainbow | ## 0.8 - Rainbow | ||||||
|  |  | ||||||
|   * New authentication and rights management modules (by Matthias Jordan) | * New authentication and rights management modules (by Matthias Jordan) | ||||||
|   * Experimental database storage | * Experimental database storage | ||||||
|   * Command-line option for custom configuration file (by Mark Adams) | * 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) | * 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 | * Improved support for iCal, CalDAVSync, CardDAVSync, CalDavZAP and CardDavMATE | ||||||
|   * Empty PROPFIND requests handled (by Christoph Polcin) | * Empty PROPFIND requests handled (by Christoph Polcin) | ||||||
|   * Colon allowed in passwords | * Colon allowed in passwords | ||||||
|   * Configurable realm message | * Configurable realm message | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 0.7.1 - Waterfalls | ## 0.7.1 - Waterfalls | ||||||
|  |  | ||||||
|   * Many address books fixes | * Many address books fixes | ||||||
|   * New IMAP ACL (by Daniel Aleksandersen) | * New IMAP ACL (by Daniel Aleksandersen) | ||||||
|   * PAM ACL fixed (by Daniel Aleksandersen) | * PAM ACL fixed (by Daniel Aleksandersen) | ||||||
|   * Courier ACL fixed (by Benjamin Frank) | * Courier ACL fixed (by Benjamin Frank) | ||||||
|   * Always set display name to collections (by Oskari Timperi) | * Always set display name to collections (by Oskari Timperi) | ||||||
|   * Various DELETE responses fixed | * Various DELETE responses fixed | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 0.7 - Eternal Sunshine | ## 0.7 - Eternal Sunshine | ||||||
|  |  | ||||||
|   * Repeating events | * Repeating events | ||||||
|   * Collection deletion | * Collection deletion | ||||||
|   * Courier and PAM authentication methods | * Courier and PAM authentication methods | ||||||
|   * CardDAV support | * CardDAV support | ||||||
|   * Custom LDAP filters supported | * Custom LDAP filters supported | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 0.6.4 - Tulips | ## 0.6.4 - Tulips | ||||||
|  |  | ||||||
|   * Fix the installation with Python 3.1 | * Fix the installation with Python 3.1 | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 0.6.3 - Red Roses | ## 0.6.3 - Red Roses | ||||||
|  |  | ||||||
|   * MOVE requests fixed | * MOVE requests fixed | ||||||
|   * Faster REPORT answers | * Faster REPORT answers | ||||||
|   * Executable script moved into the package | * Executable script moved into the package | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 0.6.2 - Seeds | ## 0.6.2 - Seeds | ||||||
|  |  | ||||||
|   * iPhone and iPad support fixed | * iPhone and iPad support fixed | ||||||
|   * Backslashes replaced by slashes in PROPFIND answers on Windows | * Backslashes replaced by slashes in PROPFIND answers on Windows | ||||||
|   * PyPI archive set as default download URL | * PyPI archive set as default download URL | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 0.6.1 - Growing Up | ## 0.6.1 - Growing Up | ||||||
|  |  | ||||||
|   * Example files included in the tarball | * Example files included in the tarball | ||||||
|   * htpasswd support fixed | * htpasswd support fixed | ||||||
|   * Redirection loop bug fixed | * Redirection loop bug fixed | ||||||
|   * Testing message on GET requests | * Testing message on GET requests | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 0.6 - Sapling | ## 0.6 - Sapling | ||||||
|  |  | ||||||
|   * WSGI support | * WSGI support | ||||||
|   * IPv6 support | * IPv6 support | ||||||
|   * Smart, verbose and configurable logs | * Smart, verbose and configurable logs | ||||||
|   * Apple iCal 4 and iPhone support (by Łukasz Langa) | * Apple iCal 4 and iPhone support (by Łukasz Langa) | ||||||
|   * KDE KOrganizer support | * KDE KOrganizer support | ||||||
|   * LDAP auth backend (by Corentin Le Bail) | * LDAP auth backend (by Corentin Le Bail) | ||||||
|   * Public and private calendars (by René Neumann) | * Public and private calendars (by René Neumann) | ||||||
|   * PID file | * PID file | ||||||
|   * MOVE requests management | * MOVE requests management | ||||||
|   * Journal entries support | * Journal entries support | ||||||
|   * Drop Python 2.5 support | * Drop Python 2.5 support | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 0.5 - Historical Artifacts | ## 0.5 - Historical Artifacts | ||||||
|  |  | ||||||
|   * Calendar depth | * Calendar depth | ||||||
|   * MacOS and Windows support | * MacOS and Windows support | ||||||
|   * HEAD requests management | * HEAD requests management | ||||||
|   * htpasswd user from calendar path | * htpasswd user from calendar path | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 0.4 - Hot Days Back | ## 0.4 - Hot Days Back | ||||||
|  |  | ||||||
|   * Personal calendars | * Personal calendars | ||||||
|   * Last-Modified HTTP header | * Last-Modified HTTP header | ||||||
|   * ``no-ssl`` and ``foreground`` options | * `no-ssl` and `foreground` options | ||||||
|   * Default configuration file | * Default configuration file | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 0.3 - Dancing Flowers | ## 0.3 - Dancing Flowers | ||||||
|  |  | ||||||
|   * Evolution support | * Evolution support | ||||||
|   * Version management | * Version management | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 0.2 - Snowflakes | ## 0.2 - Snowflakes | ||||||
|  |  | ||||||
|   * Sunbird pre-1.0 support | * Sunbird pre-1.0 support | ||||||
|   * SSL connection | * SSL connection | ||||||
|   * Htpasswd authentication | * Htpasswd authentication | ||||||
|   * Daemon mode | * Daemon mode | ||||||
|   * User configuration | * User configuration | ||||||
|   * Twisted dependency removed | * Twisted dependency removed | ||||||
|   * Python 3 support | * Python 3 support | ||||||
|   * Real URLs for PUT and DELETE | * Real URLs for PUT and DELETE | ||||||
|   * Concurrent modification reported to users | * Concurrent modification reported to users | ||||||
|   * Many bugs fixed (by Roger Wenham) | * Many bugs fixed (by Roger Wenham) | ||||||
|  |  | ||||||
|  |  | ||||||
| ## 0.1 - Crazy Vegetables | ## 0.1 - Crazy Vegetables | ||||||
|  |  | ||||||
|   * First release | * First release | ||||||
|   * Lightning/Sunbird 0.9 compatibility | * Lightning/Sunbird 0.9 compatibility | ||||||
|   * Easy installer | * Easy installer | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Unrud
					Unrud