Initial overhaul of documentation

This commit is contained in:
Unrud 2020-04-11 16:14:41 +02:00
parent d6d5e512dc
commit 27ac0ed025

View File

@ -21,7 +21,7 @@ Radicale is really easy to install and works out-of-the-box.
```bash
$ python3 -m pip install --upgrade radicale
$ python3 -m radicale --config "" --storage-filesystem-folder=~/.var/lib/radicale/collections
$ python3 -m radicale --storage-filesystem-folder=~/.var/lib/radicale/collections
```
When your server is launched, you can check that everything's OK by going
@ -60,7 +60,6 @@ fit your needs.
- [What can I configure?](#documentation/configuration)
- [Authentication & Rights.](#documentation/authentication-and-rights)
- [Storage.](#documentation/storage)
- [Logging.](#documentation/logging)
### Hack
@ -97,7 +96,7 @@ Then open a console and type:
# Run the following command as root or
# add the --user argument to only install for the current user
$ python3 -m pip install --upgrade radicale
$ python3 -m radicale --config "" --storage-filesystem-folder=~/.var/lib/radicale/collections
$ python3 -m radicale --storage-filesystem-folder=~/.var/lib/radicale/collections
```
Victory! Open [http://localhost:5232/](http://localhost:5232/) in your browser!
@ -115,11 +114,9 @@ Launch a command prompt and type:
```powershell
C:\Users\User> python -m pip install --upgrade radicale
C:\Users\User> python -m radicale --config "" --storage-filesystem-folder=~/radicale/collections
C:\Users\User> python -m radicale --storage-filesystem-folder=~/radicale/collections
```
If you are using PowerShell replace ``--config ""`` with ``--config '""'``.
Victory! Open [http://localhost:5232/](http://localhost:5232/) in your browser!
You can login with any username and password.
@ -134,10 +131,12 @@ Installation instructions can be found on the
### Configuration
Radicale tries to load configuration files from `/etc/radicale/config`,
`~/.config/radicale/config` and the `RADICALE_CONFIG` environment variable.
A custom path can be specified with the `--config /path/to/config` command
line argument.
Radicale tries to load configuration files from `/etc/radicale/config` and
`~/.config/radicale/config`.
Custom paths can be specified with the `--config /path/to/config` command
line argument or the `RADICALE_CONFIG` environment variable.
Multiple configuration files can be separated by `:` (resp. `;` on Windows).
Paths that start with `?` are optional.
You should create a new configuration file at the desired location.
(If the use of a configuration file is inconvenient, all options can be
@ -160,19 +159,14 @@ The `users` file can be created and managed with
[htpasswd](https://httpd.apache.org/docs/current/programs/htpasswd.html):
```bash
# Create a new htpasswd file with the user "user1"
$ htpasswd -B -c /path/to/users user1
$ htpasswd -c /path/to/users user1
New password:
Re-type new password:
# Add another user
$ htpasswd -B /path/to/users user2
$ htpasswd /path/to/users user2
New password:
Re-type new password:
```
**bcrypt** is used to secure the passwords. Radicale requires additional
dependencies for this encryption method:
```bash
$ python3 -m pip install --upgrade radicale[bcrypt]
```
Authentication can be enabled with the following configuration:
```ini
@ -180,7 +174,7 @@ Authentication can be enabled with the following configuration:
type = htpasswd
htpasswd_filename = /path/to/users
# encryption method used in the htpasswd file
htpasswd_encryption = bcrypt
htpasswd_encryption = md5
```
#### The simple but insecure way
@ -206,15 +200,13 @@ htpasswd_encryption = plain
The default configuration binds the server to localhost. It can't be reached
from other computers. This can be changed with the following configuration
options:
options (IPv4 and IPv6):
```ini
[server]
hosts = 0.0.0.0:5232
hosts = 0.0.0.0:5232, [::]:5232
```
More addresses can be added (separated by commas).
### Storage
Data is stored in the folder `/var/lib/radicale/collections`. The path can
@ -342,21 +334,6 @@ $ journalctl --unit radicale.service
*To be written.*
### Classic daemonization
Set the configuration option `daemon` in the section `server` to `True`.
You may want to set the option `pid` to the path of a PID file.
After daemonization the server will not log anything. You have to configure
[Logging](#documentation/logging).
If you start Radicale now, it will initialize and fork into the background.
The main process exits, after the PID file is written.
**Security:** You can set the **umask** with `umask 0027` before you start the
daemon, to protect your calendar data and log files from other users.
Don't forget to set permissions of files that are already created!
### Windows with "NSSM - the Non-Sucking Service Manager"
First install [NSSM](https://nssm.cc/) and start `nssm install` in a command
@ -569,7 +546,7 @@ Radicale has been tested with:
Many clients do not support the creation of new calendars and address books.
You can use Radicale's web interface
(e.g. [http://localhost:5232](http://localhost:5232)) to create and manage
collections.
address books and calendars.
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
@ -716,60 +693,49 @@ An example configuration file looks like:
```ini
[server]
# Bind all addresses
hosts = 0.0.0.0:5232
hosts = 0.0.0.0:5232, [::]:5232
[auth]
type = htpasswd
htpasswd_filename = /path/to/users
htpasswd_encryption = bcrypt
htpasswd_encryption = md5
[storage]
filesystem_folder = ~/.var/lib/radicale/collections
```
Radicale tries to load configuration files from `/etc/radicale/config`,
`~/.config/radicale/config` and the `RADICALE_CONFIG` environment variable.
This behaviour can be overwritten by specifying a path with the
`--config /path/to/config` command line argument.
Radicale tries to load configuration files from `/etc/radicale/config` and
`~/.config/radicale/config`.
Custom paths can be specified with the `--config /path/to/config` command
line argument or the `RADICALE_CONFIG` environment variable.
Multiple configuration files can be separated by `:` (resp. `;` on Windows).
Paths that start with `?` are optional.
The same example configuration via command line arguments looks like:
```bash
python3 -m radicale --config "" --server-hosts 0.0.0.0:5232 --auth-type htpasswd --htpasswd-filename /path/to/htpasswd --htpasswd-encryption bcrypt
python3 -m radicale --server-hosts 0.0.0.0:5232,[::]:5232 --auth-type htpasswd --htpasswd-filename /path/to/htpasswd --htpasswd-encryption md5
```
The `--config ""` argument is required to stop Radicale from trying
to load configuration files. Run `python3 -m radicale --help` for more information.
Add the argument `--config ""` to stop Radicale from loading the default
configuration files. Run `python3 -m radicale --help` for more information.
In the following, all configuration categories and options are described.
### server
Most configuration options in this category are only relevant in standalone
mode. All options beside `max_content_length` and `realm` are ignored,
when Radicale runs via WSGI.
The configuration options in this category are only relevant in standalone
mode. All options are ignored, when Radicale runs via WSGI.
#### hosts
A comma separated list of addresses that the server will bind to.
Default: `127.0.0.1:5232`
#### daemon
Daemonize the Radicale process. It does not reset the umask.
Default: `False`
#### pid
If daemon mode is enabled, Radicale will write its PID to this file.
Default:
Default: `localhost:5232`
#### max_connections
The maximum number of parallel connections. Set to `0` to disable the limit.
Default: `20`
Default: `8`
#### max_content_length
@ -810,30 +776,6 @@ authentication plugin that extracts the user name from the certifcate.
Default:
#### protocol
SSL protocol used. See python's ssl module for available values.
Default: `PROTOCOL_TLSv1_2`
#### ciphers
Available ciphers for SSL. See python's ssl module for available ciphers.
Default:
#### dns_lookup
Reverse DNS to resolve client address in logs.
Default: `True`
#### realm
Message displayed in the client when a password is needed.
Default: `Radicale - Password Required`
### encoding
#### request
@ -897,25 +839,12 @@ Available methods:
`bcrypt`
: This uses a modified version of the Blowfish stream cipher. It's very secure.
The **passlib** python module is required for this. Additionally you may need
one of the following python modules: **bcrypt**, **py-bcrypt** or **bcryptor**.
The installation of **radicale[bcrypt]** is required for this.
`md5`
: This uses an iterated md5 digest of the password with a salt.
The **passlib** python module is required for this.
`sha1`
: Passwords are stored as SHA1 hashes. It's insecure!
`ssha`
: Passwords are stored as salted SHA1 hashes. It's insecure!
`crypt`
: This uses UNIX
[crypt(3)](https://manpages.debian.org/unstable/manpages-dev/crypt.3.en.html).
It's insecure!
Default: `bcrypt`
Default: `md5`
#### delay
@ -923,6 +852,12 @@ Average delay after failed login attempts in seconds.
Default: `1`
#### realm
Message displayed in the client when a password is needed.
Default: `Radicale - Password Required`
### rights
#### type
@ -978,28 +913,12 @@ Folder for storing local collections, created if not present.
Default: `/var/lib/radicale/collections`
#### filesystem_locking
Lock the storage. This must be disabled if locking is not supported by the
underlying file system. Never start multiple instances of Radicale or edit the
storage externally while Radicale is running if disabled.
Default: `True`
#### max_sync_token_age
Delete sync-token that are older than the specified time. (seconds)
Default: `2592000`
#### filesystem_fsync
Sync all changes to disk during requests. (This can impair performance.)
Disabling it increases the risk of data loss, when the system crashes or
power fails!
Default: `True`
#### hook
Command that is run after changes to storage. Take a look at the
@ -1023,17 +942,13 @@ Available backends:
Default: `internal`
### logging
#### debug
#### level
Set the default logging level to debug.
Set the logging level.
Default: `False`
Available levels: **debug**, **info**, **warning**, **error**, **critical**
#### full_environment
Log all environment variables (including those set in the shell).
Default: `False`
Default: `warning`
#### mask_passwords
@ -1041,12 +956,6 @@ Don't include passwords in logs.
Default: `True`
#### config
Logging configuration file. See the [Logging](#documentation/logging) page.
Default:
### headers
In this section additional HTTP headers that are sent to clients can be
@ -1110,7 +1019,7 @@ The path of the collection is separated by `/` and has no leading or trailing
`%(login)s` gets replaced by the user name and `%(path)s` by the path of
the collection. You can also get groups from the `user` regex in the
`collection` regex with `{0}`, `{1}`, etc.
`collection` regex with `{1}`, `{2}`, etc.
## Storage
@ -1196,85 +1105,9 @@ and `nNumberOfBytesToLockHigh` to `0` works.
## Logging
Radicale logs to `stderr`. The verbosity of the log output can be controlled
with `--debug` command line argument or the `debug` configuration option in
with `--debug` command line argument or the `level` configuration option in
the `logging` section.
This is the recommended configuration for use with modern init systems
(like **systemd**) or if you just test Radicale in a terminal.
You can configure Radicale to write its logging output to files (and even
rotate them).
This is useful if the process daemonizes or if your chosen method of running
Radicale doesn't handle logging output.
A logging configuration file can be specified in the `config` configuration
option in the `logging` section. The file format is explained in the
[Python Logging Module](https://docs.python.org/3/library/logging.config.html#configuration-file-format).
### Logging to a file
An example configuration to write the log output to the file `/var/log/radicale/log`:
```ini
[loggers]
keys = root
[handlers]
keys = file
[formatters]
keys = full
[logger_root]
# Change this to DEBUG or INFO for higher verbosity.
level = WARNING
handlers = file
[handler_file]
class = FileHandler
# Specify the output file here.
args = ('/var/log/radicale/log',)
formatter = full
[formatter_full]
format = %(asctime)s - [%(thread)x] %(levelname)s: %(message)s
```
You can specify multiple **logger**, **handler** and **formatter** if you want
to have multiple simultaneous log outputs.
The parent folder of the log files must exist and must be writable by Radicale.
**Security:** The log files should not be readable by unauthorized users. Set
permissions accordingly.
#### Timed rotation of disk log files
An example **handler** configuration to write the log output to the file `/var/log/radicale/log` and rotate it.
Replace the section `handler_file` from the file logging example:
```ini
[handler_file]
class = handlers.TimedRotatingFileHandler
# Specify the output file and parameter for rotation here.
# See https://docs.python.org/3/library/logging.handlers.html#logging.handlers.TimedRotatingFileHandler
# Example: rollover at midnight and keep 7 files (means one week)
args = ('/var/log/radicale/log', 'midnight', 1, 7)
formatter = full
```
#### Rotation of disk log files based on size
An example **handler** configuration to write the log output to the file `/var/log/radicale/log` and rotate it .
Replace the section `handle_file` from the file logging example:
```ini
[handler_file]
class = handlers.RotatingFileHandler
# Specify the output file and parameter for rotation here.
# See https://docs.python.org/3/library/logging.handlers.html#logging.handlers.RotatingFileHandler
# Example: rollover at 100000 kB and keep 10 files (means 1 MB)
args = ('/var/log/radicale/log', 'a', 100000, 10)
formatter = full
```
## Architecture
Radicale is a really small piece of software, but understanding it is not as
@ -1343,61 +1176,63 @@ icons and buttons, a terminal or another web application.
### Code Architecture
The ``radicale`` package offers 9 modules.
`__main__`
: The main module provides a simple function called run. Its main work is to
read the configuration from the configuration file and from the options given
in the command line; then it creates a server, according to the configuration.
The ``radicale`` package offers the following modules.
`__init__`
: This is the core part of the module, with the code for the CalDAV/CardDAV
server. The server inherits from a WSGIServer server class, which relies on
the default HTTP server class given by Python. The code managing the
different HTTP requests according to the CalDAV/CardDAV normalization is
written here.
: Contains the entry point for WSGI.
`config`
: This part gives a dict-like access to the server configuration, read from the
configuration file. The configuration can be altered when launching the
executable with some command line options.
`__main__`
: Provides the entry point for the ``radicale`` executable and
includes the command line parser. It loads configuration files from
the default (or specified) paths and starts the internal server.
`xmlutils`
: The functions defined in this module are mainly called by the CalDAV/CardDAV
server class to read the XML part of the request, read or alter the
calendars, and create the XML part of the response. The main part of this
code relies on ElementTree.
`log`
: The start function provided by this module starts a logging mechanism based
on the default Python logging module. Logging options can be stored in a
logging configuration file.
`app`
: This is the core part of Radicale, with the code for the CalDAV/CardDAV
server. The code managing the different HTTP requests according to the
CalDAV/CardDAV specification can be found here.
`auth`
: This module provides a default authentication manager equivalent to Apache's
htpasswd. Login + password couples are stored in a file and used to
authenticate users. Passwords can be encrypted using various methods. Other
authentication methods can inherit from the base class in this file and be
provided as plugins.
: Used for authenticating users based on username and password, mapping
usernames to internal users and optionally retrieving credentials from
the environment.
`config`
: Contains the code for managing configuration and loading settings from files.
`ìtem`
: Internal represenation of address book and calendar entries. Based on
[VObject](https://eventable.github.io/vobject/).
`log`
: The logger for Radicale based on the default Python logging module.
`rights`
: This module is a set of Access Control Lists, a set of methods used by
Radicale to manage rights to access the calendars. When the CalDAV/CardDAV
server is launched, an Access Control List is chosen in the set, according to
the configuration. The HTTP requests are then filtered to restrict the access
depending on who is authenticated. Other configurations can be written using
regex-based rules. Other rights managers can also inherit from the base class
in this file and be provided as plugins.
: This module is used by Radicale to manage access rights to collections,
address books and calendars.
`server`
: The integrated HTTP server for standalone use.
`storage`
: In this module are written the classes representing collections and items in
Radicale, and the class storing these collections and items in your
filesystem. Other storage classes can inherit from the base class in this
file and be provided as plugins.
: This module contains the classes representing collections in Radicale and
the code for storing and loading them in the filesystem.
`web`
: This module contains the web interface.
`utils`
: Contains general helper functions.
`httputils`
: Contains helper functions for working with HTTP.
`pathutils`
: Helper functions for working with paths and the filesystem.
`xmlutils`
: Helper functions for working with the XML part of CalDAV/CardDAV requests
and responses. It's based on the ElementTree XML API.
## Plugins
Radicale can be extended by plugins for authentication, rights management and
@ -1406,7 +1241,7 @@ storage. Plugins are **python** modules.
### Getting started
To get started we walk through the creation of a simple authentication
plugin, that accepts login attempts if the username and password are equal.
plugin, that accepts login attempts with a static password.
The easiest way to develop and install **python** modules is
[Distutils](https://docs.python.org/3/distutils/setupscript.html).
@ -1418,31 +1253,36 @@ in an empty folder:
from distutils.core import setup
setup(name="radicale_silly_auth", packages=["radicale_silly_auth"])
setup(name="radicale_static_password_auth", packages=["radicale_static_password_auth"])
```
In the same folder create the sub-folder `radicale_silly_auth`. The folder
must have the same name as specified in `packages` above.
In the same folder create the sub-folder `radicale_static_password_auth`.
The folder must have the same name as specified in `packages` above.
Create the file `__init__.py` in the `radicale_silly_auth` folder with the
following content:
Create the file `__init__.py` in the `radicale_static_password_auth` folder
with the following content:
```python
from radicale.auth import BaseAuth
from radicale.log import logger
PLUGIN_CONFIG_SCHEMA = {"auth": {
"password": {"value": "", "type": str}}}
class Auth(BaseAuth):
def is_authenticated(self, user, password):
# Example custom configuration option
foo = ""
if self.configuration.has_option("auth", "foo"):
foo = self.configuration.get("auth", "foo")
self.logger.info("Configuration option %r is %r", "foo", foo)
def __init__(self, configuration):
super().__init__(configuration.copy(PLUGIN_CONFIG_SCHEMA))
def login(self, user, password):
# Get password from configuration option
static_password = self.configuration.get("auth", "password")
# Check authentication
self.logger.info("Login attempt by %r with password %r",
user, password)
return user == password
logger.info("Login attempt by %r with password %r",
user, password)
if password == static_password:
return user
return ""
```
Install the python module by running the following command in the same folder
@ -1452,46 +1292,46 @@ python3 -m pip install --upgrade .
```
To make use this great creation in Radicale, set the configuration option
`type` in the `auth` section to `radicale_silly_auth`:
`type` in the `auth` section to `radicale_static_password_auth`:
```ini
[auth]
type = radicale_silly_auth
foo = bar
type = radicale_static_password_auth
password = secret
```
You can uninstall the module with:
```bash
python3 -m pip uninstall radicale_silly_auth
python3 -m pip uninstall radicale_static_password_auth
```
### Authentication plugins
This plugin type is used to check login credentials.
The module must contain a class `Auth` that extends
`radicale.auth.BaseAuth`. Take a look at the file `radicale/auth.py` in
Radicale's source code for more information.
`radicale.auth.BaseAuth`. Take a look at the file `radicale/auth/__init__.py`
in Radicale's source code for more information.
### Rights management plugins
This plugin type is used to check if a user has access to a path.
The module must contain a class `Rights` that extends
`radicale.rights.BaseRights`. Take a look at the file `radicale/rights.py` in
Radicale's source code for more information.
`radicale.rights.BaseRights`. Take a look at the file
`radicale/rights/__init__.py` in Radicale's source code for more information.
### Web plugins
This plugin type is used to provide the web interface for Radicale.
The module must contain a class `Web` that extends
`radicale.web.BaseWeb`. Take a look at the file `radicale/web.py` in
`radicale.web.BaseWeb`. Take a look at the file `radicale/web/__init__.py` in
Radicale's source code for more information.
### Storage plugins
This plugin is used to store collections and items.
The module must contain a class `Collection` that extends
`radicale.storage.BaseCollection`. Take a look at the file `radicale/storage.py`
in Radicale's source code for more information.
The module must contain a class `Storage` that extends
`radicale.storage.BaseStorage`. Take a look at the file
`radicale/storage/__init__.py` in Radicale's source code for more information.
# Contribute
@ -1507,7 +1347,7 @@ Found a bug? Want a new feature? Report a new issue on the
### Hack
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.
### Documentation
@ -1537,34 +1377,8 @@ You can also download the content of the repository as an
### Source Packages
You can download the Radicale package for each release:
- [**2.1.11 - Wild Radish**](https://api.github.com/repos/Kozea/Radicale/tarball/2.1.11)
- [**2.1.10 - Wild Radish**](https://api.github.com/repos/Kozea/Radicale/tarball/2.1.10)
- [**2.1.9 - Wild Radish**](https://api.github.com/repos/Kozea/Radicale/tarball/2.1.9)
- [**2.1.8 - Wild Radish**](https://api.github.com/repos/Kozea/Radicale/tarball/2.1.8)
- [**2.1.7 - Wild Radish**](https://api.github.com/repos/Kozea/Radicale/tarball/2.1.7)
- [**2.1.6 - Wild Radish**](https://api.github.com/repos/Kozea/Radicale/tarball/2.1.6)
- [**2.1.5 - Wild Radish**](https://api.github.com/repos/Kozea/Radicale/tarball/2.1.5)
- [**2.1.4 - Wild Radish**](https://api.github.com/repos/Kozea/Radicale/tarball/2.1.4)
- [**2.1.3 - Wild Radish**](https://api.github.com/repos/Kozea/Radicale/tarball/2.1.3)
- [**2.1.2 - Wild Radish**](https://api.github.com/repos/Kozea/Radicale/tarball/2.1.2)
- [**1.1.6 - Sixth Law of Nature**](https://api.github.com/repos/Kozea/Radicale/tarball/1.1.6)
- [**2.1.1 - Wild Radish Again**](https://api.github.com/repos/Kozea/Radicale/tarball/2.1.1)
- [**2.1.0 - Wild Radish**](https://api.github.com/repos/Kozea/Radicale/tarball/2.1.0)
- [**1.1.4 - Fifth Law of Nature**](https://api.github.com/repos/Kozea/Radicale/tarball/1.1.4)
- [2.1.0rc3](https://api.github.com/repos/Kozea/Radicale/tarball/2.1.0rc3)
- [2.1.0rc2](https://api.github.com/repos/Kozea/Radicale/tarball/2.1.0rc2)
- [2.1.0rc1](https://api.github.com/repos/Kozea/Radicale/tarball/2.1.0rc1)
- [**2.0.0 - Little Big Radish**](https://api.github.com/repos/Kozea/Radicale/tarball/2.0.0)
- [**1.1.3 - Fourth Law of Nature**](https://api.github.com/repos/Kozea/Radicale/tarball/1.1.3)
- [2.0.0rc2](https://api.github.com/repos/Kozea/Radicale/tarball/2.0.0rc2)
- [**1.1.2 - Third Law of Nature**](https://api.github.com/repos/Kozea/Radicale/tarball/1.1.2)
- [2.0.0rc1](https://api.github.com/repos/Kozea/Radicale/tarball/2.0.0rc1)
- [**1.1.1 - Second Law of Nature**](https://api.github.com/repos/Kozea/Radicale/tarball/1.1.1)
- [**1.1 - Law of Nature**](https://api.github.com/repos/Kozea/Radicale/tarball/1.1)
- [**1.0.1 - Sunflower Again**](https://api.github.com/repos/Kozea/Radicale/tarball/1.0.1)
- [**1.0 - Sunflower**](https://api.github.com/repos/Kozea/Radicale/tarball/1.0)
You can find the source packages of all releases on
[GitHub](https://github.com/Kozea/Radicale/releases).
### Linux Distribution Packages