From 0cbdea014c914686b327931eb78206ce89dedce2 Mon Sep 17 00:00:00 2001 From: Unrud Date: Wed, 24 May 2017 19:13:47 +0200 Subject: [PATCH 1/7] WIP --- 1to2.md | 49 ++++------ about.md | 2 +- configuration.md | 240 +++++++++++++++++++++++++++++++++++++++++++++++ documentation.md | 11 ++- download.md | 5 +- edit.md | 3 + install.md | 5 - plugins.md | 64 +++++++++++++ production.md | 5 - proxy.md | 20 ++++ rights.md | 53 +++++++++++ setup.md | 183 ++++++++++++++++++++++++++++++++++++ tutorial.md | 60 +++++------- versioning.md | 21 +++++ wsgi.md | 8 ++ 15 files changed, 647 insertions(+), 82 deletions(-) delete mode 100644 install.md delete mode 100644 production.md create mode 100644 proxy.md create mode 100644 setup.md create mode 100644 wsgi.md diff --git a/1to2.md b/1to2.md index f621cafc..9bd7be85 100644 --- a/1to2.md +++ b/1to2.md @@ -36,44 +36,35 @@ work, Radicale won't be able to read your previous data.** There's now only one way to store data in Radicale: collections are stored as folders and events / contacts are stored in files. This new storage is close to the `multifilesystem`, but **it's now thread-safe, with atomic writes and file -locks**. +locks**. Other storage types can be used by creating +[plugins]({{ site.baseurl }}/plugins/). -Migrating your data can be done with tool called -[transplant](https://github.com/Kozea/transplant/blob/master/transplant.py) -that will copy your collections from one server to another using -CalDAV / CardDAV requests. Following these simple steps will help you migrate -your data: - -- Stop Radicale 1.x.x, -- edit your configuration to only listen to `http://localhost:5232`, -- remove authentication, -- restart the 1.x.x server, -- download Radicale 2.0.x and go into the downloaded folder, -- launch Radicale 2.0.x with - `python3 radicale.py --config=/dev/null --hosts=localhost:5233 --storage-filesystem-folder=~/.local/share/radicale/`, -- download transplant and go into the downloaded folder, -- launch transplant with `python3 transplant http://localhost:5232 http://localhost:5233`, -- you're done! - -This migration should work at least with simple configurations of Radicale 1.x.x -on Linux and macOS. Please adapt these steps carefully if you're on Windows or -if you're using a more complex configuration. - -Other storage types can be used by creating [plugins](/plugins/). These storage -types can reuse the current storage class to extend it (for example to add -versioning) or can be totally different from it (yes, don't worry, you can -write your own storage plugin using a DataBase®™ if you want). +To migrate data to Radicale 2.0.x the command line argument +``--export-storage`` was added to Radicale 1.1.3. +Start Radicale 1.x.x as you would normally do, but add the argument +``--export-storage path/to/empty/folder``. Radicale will export the storage +into the specified folder. This folder can be directly used with the +default storage backend of Radicale 2.0.x. ### Authentication **Radicale 2.0.x only provides htpasswd authentication out-of-the-box.** Other -authentication methods can be added by creating or using [plugins](/plugins/). +authentication methods can be added by creating or using +[plugins]({{ site.baseurl }}/plugins/). ### Rights In Radicale 2.0.x, rights are managed using regex-based rules based on the login of the authenticated user and the URL of the resource. Default configurations are built in for common cases, you'll find more about this on -the [Authentication & Rights](/rights/) page. +the [Authentication & Rights]({{ site.baseurl }}/rights/) page. -Other rights managers can be added by creating [plugins](/plugins/). +Other rights managers can be added by creating +[plugins]({{ site.baseurl }}/plugins/). + +### Versioning + +Support for versioning with **git** was removed from Radicale 2.0.x. +Instead, the configuration option ``hook`` in the ``storage`` section was added, +the [Collection Versioning]({{ site.baseurl }}/versioning/) page explains its +usage for version control. diff --git a/about.md b/about.md index 111e912d..03703111 100644 --- a/about.md +++ b/about.md @@ -17,7 +17,7 @@ configure. As a consequence, it requires few software dependencies and is pre-configured to work out-of-the-box. 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 diff --git a/configuration.md b/configuration.md index dc024e9a..80fd45b0 100644 --- a/configuration.md +++ b/configuration.md @@ -3,3 +3,243 @@ layout: page title: Configuration permalink: /configuration/ --- + +Radicale can be configured with a configuration file or with +command line arguments. + +An example configuration file looks like: +```ini +[server] +hosts = 0.0.0.0:5232 # Bind all addresses +[auth] +type = htpasswd +htpasswd_filename = /path/to/users +htpasswd_encryption = bcrypt +[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. + +The same example configuration via command line arguments looks like: +```sh +python3 -m radicale --config /dev/null --server-hosts 0.0.0.0:5232 --auth-type htpasswd --htpasswd-filename /path/to/htpasswd --htpasswd-encryption bcrypt +``` + +The ``--config /dev/null`` argument is required to stop Radicale from trying +to load 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. + +### hosts +A comma separated list of addresses that the server will bind to. + +Default: ``127.0.0.1:5555`` + +### daemon +Daemonize the Radicale process. It does not reset the umask or double fork. + +Default: ``False`` + +### pid +If daemon mode is enabled, Radicale will write its PID to this file. + +Default: + +### max_connections +The maximum number of parallel connections. Set to ``0`` to disable the limit. + +Default: ``20`` + +### max_content_length +The maximum size of the request body. (bytes) + +Default ``10000000`` + +### ssl +Enable transport layer encryption. + +Default: ``False`` + +### key +Path to the private key for SSL. Only effective if ``ssl`` is enabled. + +Default: ``/etc/ssl/radicale.key.pem`` + +### 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 +Encoding for responding requests. + +Default: ``utf-8`` + +### stock +Encoding for storing local collections + +Default: ``utf-8`` + +## auth +### type +The method to verify usernames and passwords. + +Available backends: + +`None` +: Just allows all usernames and passwords. + +`htpasswd` +: Use an [Apache htpasswd file](https://httpd.apache.org/docs/current/programs/htpasswd.html) to store + usernames and passwords. + +Default: ``None`` + +### htpasswd_filename +Path to the htpasswd file. + +Default: + +### htpasswd_encryption +The encryption method that is used in the htpasswd file. Use the +[htpasswd](https://httpd.apache.org/docs/current/programs/htpasswd.html) +or similar to generate this files. + +Available methods: + +`plain` +: Passwords are stored in plaintext. This is obviously not secure! + The htpasswd file for this can be created by hand and looks like: + ```htpasswd + user1:password1 + user2:password2 + ``` + +`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**. + +`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)](http://man7.org/linux/man-pages/man3/crypt.3.html). + It's insecure! + +Default: ``bcrypt`` + +## rights +### type +The backend that is used to check the access rights of collections. + +Available backends: + +`None` +: Everyone can read and write everything. + +`authenticated` +: Authenticated users can read and write everything. + +`owner_only` +: Authenticated users can read and write their own collections under the path + */USERNAME/*. + +`owner_write` +: Authenticated users can read everything and write their own collections under + the path */USERNAME/*. + +`from_file` +: Load the rules from a file. + +Default: ``owner_only`` + +### file +File for the rights backend ``from_file``. See the +[Rights]({{ site.baseurl }}/logging/) page. + +## storage +### type +The backend that is used to store data. + +Available backends: + +`multifilesystem` +: Stores the data in the filesystem. + +Default: ``multifilesystem`` + +### 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 +[Versioning]({{ site.baseurl }}/versioning/) page for an example. + +Default: + +## logging +## debug +Set the default logging level to debug. + +Default: ``False`` + +### full_environment +Log all environment variables (including those set in the shell). + +Default: ``False`` + +### mask_passwords +Don't include passwords in logs. + +Default: ``True`` + +### config +Logging configuration file. See the [Logging]({{ site.baseurl }}/logging/) page. + +Default: + +## headers +In this section additional HTTP headers that are sent to clients can be +specified. + +An example to relax the same-origin policy: +```ini +Access-Control-Allow-Origin = * +``` diff --git a/documentation.md b/documentation.md index 696def73..ae1abe5c 100644 --- a/documentation.md +++ b/documentation.md @@ -7,14 +7,16 @@ permalink: /documentation/ This documentation page is written for version 2.0.x. If you want to update Radicale from 1.x.x to 2.0.x, please follow our [migration guide]({{ site.baseurl }}/1to2/). -## Install +## Install and set up You're new to Radicale and you want to know how to use it? Welcome aboard! - [What is Radicale?]({{ site.baseurl }}/about/) - [A really simple 5-minute tutorial.]({{ site.baseurl }}/tutorial/) -- [A simple but solid installation for a personal use.]({{ site.baseurl }}/installation/) -- [A production-ready installation.]({{ site.baseurl }}/production/) +- [A simple but solid setup.]({{ site.baseurl }}/setup/) +- [Run behind a reverse proxy.]({{ site.baseurl }}/proxy/) +- [Run with a WSGI server.]({{ site.baseurl }}/wsgi/) +- [Track all changes to calendars and address books with Git.]({{ site.baseurl }}/versioning/) ## Use @@ -23,7 +25,7 @@ You're new to Radicale and you want to know how to use it? Welcome aboard! ## Configure Now that you have Radicale running, let's see what we can configure to make it -fit our needs. +fit your needs. - [What can I configure?]({{ site.baseurl }}/configuration/) - [Authentication & Rights.]({{ site.baseurl }}/rights/) @@ -38,5 +40,4 @@ and simple piece of code, it may be the perfect project to start hacking! - [How does Radicale work?]({{ site.baseurl }}/architecture/) - [Plugins.]({{ site.baseurl }}/plugins/) - [Debugging.]({{ site.baseurl }}/debugging/) -- [Collection versioning.]({{ site.baseurl }}/versioning/) - [Adding or fixing documentation.]({{ site.baseurl }}/edit/) diff --git a/download.md b/download.md index 59bd57fb..8ecb864a 100644 --- a/download.md +++ b/download.md @@ -9,13 +9,12 @@ permalink: /download/ Radicale is [available on PyPI](http://pypi.python.org/pypi/Radicale/). To install, just type as superuser: - pip install radicale + python3 -m pip install --upgrade radicale ## Git Repository If you want the development version of Radicale, take a look at the -[git repository on GitHub]({{ site.github.repository_url }}), or clone it -thanks to: +[git repository on GitHub]({{ site.github.repository_url }}), or clone it: git clone git://github.com/Kozea/Radicale.git diff --git a/edit.md b/edit.md index 5894f657..4217e7e3 100644 --- a/edit.md +++ b/edit.md @@ -3,3 +3,6 @@ layout: page title: Editing the Documentation permalink: /edit/ --- + +To change or complement the documentation create a pull requests to +https://github.com/Kozea/Radicale/tree/gh-pages. diff --git a/install.md b/install.md deleted file mode 100644 index e5c80e8c..00000000 --- a/install.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: page -title: Simple Installation -permalink: /installation/ ---- diff --git a/plugins.md b/plugins.md index 788f9b35..8a4b7332 100644 --- a/plugins.md +++ b/plugins.md @@ -3,3 +3,67 @@ layout: page title: Plugins permalink: /plugins/ --- + +Radicale can be extended by plugins for authentication, rights management and +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. + +The easiest way to develop and install **python** modules is +[Distutils](https://docs.python.org/3/distutils/setupscript.html). +For a minimal setup create the file **setup.py** with the following content +in an empty folder: + +```python +#!/usr/bin/env python3 + +from distutils.core import setup + +setup(packages=["silly_auth_plugin"]) +``` + +In the same folder create the sub-folder **silly_auth_plugin**. The folder +must have the same name as specified in ``packages`` above. + +Create the file **\_\_init\_\_.py** in the **silly_auth_plugin** folder with the +following content: + +```python +from radicale.auth import BaseAuth + +class Auth(BaseAuth): + def is_authenticated(self, user, password): + self.logger.info("Login attempt by '%s' with password '%s'", + user, password) + return user == password +``` + +Install the python module by running the following command in the same folder +as **setup.py**: +```sh +python3 -m pip install --upgrade . +``` + +To make use this great creation in Radicale, set the configuration option +``type`` in the ``auth`` section to ``silly_auth_plugin``. + +## 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. + +## 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.auth.BaseAuth``. Take a look at the file *radicale/rights.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 ``Storage`` that extends +``radicale.auth.BaseStorage``. Take a look at the file *radicale/storage.py* in +Radicale's source code for more information. diff --git a/production.md b/production.md deleted file mode 100644 index a01ce9f5..00000000 --- a/production.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: page -title: Installation for Production -permalink: /production/ ---- diff --git a/proxy.md b/proxy.md new file mode 100644 index 00000000..3d617b77 --- /dev/null +++ b/proxy.md @@ -0,0 +1,20 @@ +--- +layout: page +title: Reverse Proxy +permalink: /proxy/ +--- + +When a everse proxy is used, the path at which Radicale is available must +be provided via the ``X-Script-Name`` header. + + +Example **nginx** configuration: +``` +location /sub/folder/radicale { + proxy_pass localhost:5232/; # The / is important! + proxy_set_header X-Script-Name /radciale; +} +``` + +Radicale's default configuration limits the maximum number of parallel +connections! diff --git a/rights.md b/rights.md index bd4b2ce1..2ac09539 100644 --- a/rights.md +++ b/rights.md @@ -3,3 +3,56 @@ layout: page title: Authentication and Rights permalink: /rights/ --- + +This page describes the format of the rights file for the ``from_file`` +authentication backend. The configuration option ``file`` in the ``rights`` +section must point to the rights file. + +The recommended rights mehtod is ``owner_only``. If access to calendars +and address books outside of the home directory of users (that's */USERNAME/*) +is granted, clients won't detect these collections and will not show them to +the user. +This is only useful if you access calendars and address books directly via URL. + +An example rights file: +```ini +# The user "admin" can read and write any collection. +[admin] +user: admin +collection: .* +permission: rw + +# Block access for the user "user" to everything. +[block] +user: user +collection: .* +permission: + +# Authenticated users can read and write their own collections. +[owner-write] +user: .+ +collection: %(login)s/.* +permission: rw + +# Everyone can read the root collection +[read] +user: .* +collection: +permission: r +``` + +The titles of the sections are ignored (but must be unique). The keys ``user`` +and ``collection`` contain regular expressions, that are matched against the +user name and the path of the collection. Permissions from the first +matching section are used. If no section matches, access gets denied. + +The user name is empty for anonymous users. Therefore, the regex ``.+`` only +matches authenticated users and ``.*`` matches everyone (including anonymous +users). + +The path of the collection is separated by ``/`` and has no leading or trailing +``/``. Therefore, the path of the root collection is empty. + +``%(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. diff --git a/setup.md b/setup.md new file mode 100644 index 00000000..53c8398d --- /dev/null +++ b/setup.md @@ -0,0 +1,183 @@ +--- +layout: page +title: Basic Setup +permalink: /setup/ +--- + +Installation instructions can be found on the +[Tutorial]({{ site.baseurl }}/tutorial/) page. + +## 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. + +You should create a new configuration file at the desired location. +(If the use of a configuration file is inconvenient, all options can be +passed via command line arguments.) + +All configuration options are described in detail on the +[Configuration]({{ site.baseurl }}/configuration/) page. + +## Authentication + +In it's default configuration Radicale doesn't check user names or passwords. +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. +It can be stored in the same directory as the configuration file. + +The 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 +New password: +Re-type new password: +# Add another user +$ htpasswd -B /path/to/users user2 +New password: +Re-type new password: +``` +**bcrypt** is used to secure the passwords. Radicale required additional +dependencies for this encryption method: +```bash +$ python3 -m install passlib +$ python3 -m install bcrypt +``` + +Authentication can be enabled with the following configuration: +```ini +[auth] +type = htpasswd +htpasswd_filename = /path/to/users +htpasswd_encryption = bcrypt # encryption method used in the users file +``` + +## Addresses + +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: + +```ini +[server] +hosts = 0.0.0.0:5232 +``` + +More addresses can be added (separated by commas). + +## Storage + +Data is stored in the folder */var/lib/radicale/collections*. The path can +be changed with the foloowing configuration: + +```ini +[storage] +filesystem_folder = /path/to/storage +``` + +## Limits + +Radicale enforces limits on the maximum number of parallel connections, +the maximum file size (important for contacts with big photos) and limits +the rate of incorrect authentication attempts. The default values should be +fine for most scenarios. + +```ini +[server] +max_connections = 20 +max_content_length = 10000000 # 1 Megabyte +[auth] +delay = 1 # Average delay after failed login attempts in seconds +``` + +## Running as a service + +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 +requirements. + +### Linux with systemd as a user + +Create the file *~/.config/systemd/user/radicale.service*: +``` +[Unit] +Description=A simple CalDAV (calendar) and CardDAV (contact) server + +[Service] +ExecStart=/usr/bin/env python3 -m radicale +Restart=on-failure + +[Install] +WantedBy=default.target +``` +You may have to add addition command line arguments to Radicale for the +configuration file, etc. + +To enable and manage the service run: +```bash +# Enable the service +$ systemctl --user enable radicale +# Start the service +$ systemctl --user start radicale +# Check the status of the service +$ systemctl --user status radicale +# View all log messages +$ journalctl --user --unit radicale.service +``` + +### Linux with systemd system-wide + +Create the **radicale** user and group for the Radicale service. +The configuration files must be readable by this user and the storage folder +must be writable. + +Create the file */etc/systemd/system/radicale.service*: +``` +[Unit] +Description=A simple CalDAV (calendar) and CardDAV (contact) server + +[Service] +ExecStart=/usr/bin/env python3 -m radicale +Restart=on-failure +User=radicale + +[Install] +WantedBy=multi-user.target +``` +You may have to add addition command line arguments to Radicale for the +configuration file, etc. + +To enable and manage the service run: +```bash +# Enable the service +$ systemctl enable radicale +# Start the service +$ systemctl start radicale +# Check the status of the service +$ systemctl status radicale +# View all log messages +$ journalctl --unit radicale.service +``` + +## MacOS with launchd + +*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]({{ site.baseurl }}/tutorial/). + +If you start Radicale now, it will initialize and fork into the background. +The main process exits, after the PID file is written. + +## Windows + +*To be written.* diff --git a/tutorial.md b/tutorial.md index b8a8ddb0..56123b88 100644 --- a/tutorial.md +++ b/tutorial.md @@ -8,50 +8,42 @@ You want to try Radicale but only have 5 minutes free in your calendar? Let's go right now! You won't have the best installation ever, but it will be enough to play a little bit with Radicale. -Follow one of the chapters below depending on your operating system. - -When Radicale is launched, you can check that everything is OK by opening -[http://localhost:5232/](http://localhost:5232/) in your favourite browser: -you'll get a "Radicale works!" message. - When everything works, you can get a [client]({{ site.baseurl }}/clients/) and start creating calendars and address books. And if Radicale fits your needs, it -may be time to [install it "The Right Way"]({{ site.baseurl }}/install/). +may be time to for [some basic configuration](/setup/). -## Linux / *BSD +Follow one of the chapters below depending on your operating system. -Installing Radicale on Linux or *BSD is often really easy. +## Linux / \*BSD -First of all, check that you have Python 3.4 or superior installed, or install -it thanks to your package manager. Then open a console and type: +First of all, make sure that **python** 3.4 or later and **pip** are +installed. On most distributions it should be enough to install the package +``python3-pip``. - $ pip3 install radicale - $ python3 -m radicale --debug --storage-filesystem-folder=~/.local/radicale - ... - Radicale server ready +Then open a console and type: -## Windows - -First of all: please install all the Windows updates available for your version -of Windows! (But it's already done, isn't it?) - -The next step on Windows is to intall Python. Go to -[python.org](http://python.org) and download the latest version of Python. Run -the installer. - -On the first window of the installer, check the "Add Python to PATH" box and -click on "Install now". Wait a couple of minutes, it's done! - -Then launch a command prompt, and type: - - C:\Users\MyName> python -m pip install radicale - C:\Users\MyName> python -m radicale --debug --storage-filesystem-folder=~/radicale - ... - Radicale server ready + $ python3 -m pip install --upgrade radicale + $ python3 -m radicale --config /dev/null --storage-filesystem-folder=~/.var/lib/radicale/collections Victory! Open [http://localhost:5232/](http://localhost:5232/) in your browser and enjoy the "Radicale works!" message! -## macOS +## Windows + +This first step is to install Python. Go to +[python.org](http://python.org) and download the latest version of Python 3. +Then run the installer. +On the first window of the installer, check the "Add Python to PATH" box and +click on "Install now". Wait a couple of minutes, it's done! + +Launch a command prompt and type: + + C:\Users\MyName> python -m pip install --upgrade radicale + C:\Users\MyName> python -m radicale --storage-filesystem-folder=~/radicale + +Victory! Open [http://localhost:5232/](http://localhost:5232/) in your browser +and enjoy the "Radicale works!" message! + +## MacOS *To be written.* diff --git a/versioning.md b/versioning.md index c893763b..66b87c59 100644 --- a/versioning.md +++ b/versioning.md @@ -3,3 +3,24 @@ layout: page title: Versioning permalink: /versioning/ --- + +This page describes how to keep track of all changes to calendars and +address books with **git** (or any other version control system). + +The repository must be initialized by running ``git init`` in the file +system folder. Internal files of Radicale can be excluded by creating the +file **.gitignore** with the following content: +``` +.Radicale.cache +.Radicale.lock +.Radicale.tmp.* +``` + +The configuration option ``hook`` in the ``storage`` section must be set to +the following command: +```sh +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 changes into the **git** repository. diff --git a/wsgi.md b/wsgi.md new file mode 100644 index 00000000..76321a2d --- /dev/null +++ b/wsgi.md @@ -0,0 +1,8 @@ +--- +layout: page +title: WSGI +permalink: /wsgi/ +--- + +Radicale is compatible with the WSGI specification. No special configuration +is required. From 902f6e3211a08a93b52e7854da90850b43f2be5e Mon Sep 17 00:00:00 2001 From: Unrud Date: Wed, 24 May 2017 20:30:39 +0200 Subject: [PATCH 2/7] WIP (add logging.md) --- logging.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/logging.md b/logging.md index 15a08f50..0a1b62ed 100644 --- a/logging.md +++ b/logging.md @@ -3,3 +3,46 @@ layout: page title: Logging permalink: /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 +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). + +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] +level = WARNING # Change this to DEBUG or INFO for higher verbosity. +handlers = file + +[handler_file] +class = FileHandler +args = ('/var/log/radicale/log',) # Specify the output file here. +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. From 428138adb5deff5fa54db77cdf8be79fd989a579 Mon Sep 17 00:00:00 2001 From: Unrud Date: Wed, 24 May 2017 21:06:43 +0200 Subject: [PATCH 3/7] WIP (small fixes for setup.md) --- setup.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.md b/setup.md index 53c8398d..f32985ce 100644 --- a/setup.md +++ b/setup.md @@ -44,8 +44,8 @@ Re-type new password: **bcrypt** is used to secure the passwords. Radicale required additional dependencies for this encryption method: ```bash -$ python3 -m install passlib -$ python3 -m install bcrypt +$ python3 -m pip install --upgrade passlib +$ python3 -m pip install --upgrade bcrypt ``` Authentication can be enabled with the following configuration: @@ -53,7 +53,7 @@ Authentication can be enabled with the following configuration: [auth] type = htpasswd htpasswd_filename = /path/to/users -htpasswd_encryption = bcrypt # encryption method used in the users file +htpasswd_encryption = bcrypt # encryption method used in the htpasswd file ``` ## Addresses From a91e8fdb8b6c7ceb316741a4504edeb2a8bd9000 Mon Sep 17 00:00:00 2001 From: Unrud Date: Wed, 24 May 2017 21:12:18 +0200 Subject: [PATCH 4/7] WIP (use #608) --- configuration.md | 4 ++-- tutorial.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configuration.md b/configuration.md index 80fd45b0..3f18a365 100644 --- a/configuration.md +++ b/configuration.md @@ -26,10 +26,10 @@ This behaviour can be overwritten by specifying a path with the The same example configuration via command line arguments looks like: ```sh -python3 -m radicale --config /dev/null --server-hosts 0.0.0.0:5232 --auth-type htpasswd --htpasswd-filename /path/to/htpasswd --htpasswd-encryption bcrypt +python3 -m radicale --config "" --server-hosts 0.0.0.0:5232 --auth-type htpasswd --htpasswd-filename /path/to/htpasswd --htpasswd-encryption bcrypt ``` -The ``--config /dev/null`` argument is required to stop Radicale from trying +The ``--config ""`` argument is required to stop Radicale from trying to load configuration files. Run ``python3 -m radicale --help`` for more information. In the following, all configuration categories and options are described. diff --git a/tutorial.md b/tutorial.md index 56123b88..e945b409 100644 --- a/tutorial.md +++ b/tutorial.md @@ -23,7 +23,7 @@ installed. On most distributions it should be enough to install the package Then open a console and type: $ python3 -m pip install --upgrade radicale - $ python3 -m radicale --config /dev/null --storage-filesystem-folder=~/.var/lib/radicale/collections + $ python3 -m radicale --config "" --storage-filesystem-folder=~/.var/lib/radicale/collections Victory! Open [http://localhost:5232/](http://localhost:5232/) in your browser and enjoy the "Radicale works!" message! @@ -39,7 +39,7 @@ click on "Install now". Wait a couple of minutes, it's done! Launch a command prompt and type: C:\Users\MyName> python -m pip install --upgrade radicale - C:\Users\MyName> python -m radicale --storage-filesystem-folder=~/radicale + C:\Users\MyName> python -m radicale --config "" --storage-filesystem-folder=~/radicale Victory! Open [http://localhost:5232/](http://localhost:5232/) in your browser and enjoy the "Radicale works!" message! From 482ee333f1cb507f3e31e39d26015c44713770df Mon Sep 17 00:00:00 2001 From: Unrud Date: Thu, 25 May 2017 19:57:30 +0200 Subject: [PATCH 5/7] WIP (Fix spelling mistake) --- tutorial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorial.md b/tutorial.md index e945b409..a5dfb480 100644 --- a/tutorial.md +++ b/tutorial.md @@ -30,8 +30,8 @@ and enjoy the "Radicale works!" message! ## Windows -This first step is to install Python. Go to -[python.org](http://python.org) and download the latest version of Python 3. +The first step is to install Python. Go to +[python.org](https://python.org) and download the latest version of Python 3. Then run the installer. On the first window of the installer, check the "Add Python to PATH" box and click on "Install now". Wait a couple of minutes, it's done! From 016c4585fa71d8975a500755409e110f8e410597 Mon Sep 17 00:00:00 2001 From: Unrud Date: Thu, 25 May 2017 19:58:22 +0200 Subject: [PATCH 6/7] WIP (add missing configuration options) --- configuration.md | 12 +++++++++++- proxy.md | 5 +++-- setup.md | 7 ++++--- wsgi.md | 3 +++ 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/configuration.md b/configuration.md index 3f18a365..ac1f2180 100644 --- a/configuration.md +++ b/configuration.md @@ -62,13 +62,23 @@ Default: ``20`` ### max_content_length The maximum size of the request body. (bytes) -Default ``10000000`` +Default: ``10000000`` + +### timeout +Socket timeout. (seconds) + +Default: ``10`` ### ssl Enable transport layer encryption. Default: ``False`` +### certificate +Path of the SSL certifcate. + +Default: ``/etc/ssl/radicale.cert.pem`` + ### key Path to the private key for SSL. Only effective if ``ssl`` is enabled. diff --git a/proxy.md b/proxy.md index 3d617b77..82f74815 100644 --- a/proxy.md +++ b/proxy.md @@ -16,5 +16,6 @@ location /sub/folder/radicale { } ``` -Radicale's default configuration limits the maximum number of parallel -connections! +Be reminded that Radicale's default configuration enforces limits on the +maximum number of parallel connections, the maximum file size and the rate of +incorrect authentication attempts. Connections are terminated after a timeout. diff --git a/setup.md b/setup.md index f32985ce..7c61875e 100644 --- a/setup.md +++ b/setup.md @@ -82,14 +82,15 @@ filesystem_folder = /path/to/storage ## Limits Radicale enforces limits on the maximum number of parallel connections, -the maximum file size (important for contacts with big photos) and limits -the rate of incorrect authentication attempts. The default values should be -fine for most scenarios. +the maximum file size (important for contacts with big photos) and the rate of +incorrect authentication attempts. Connections are terminated after a timeout. +The default values should be fine for most scenarios. ```ini [server] max_connections = 20 max_content_length = 10000000 # 1 Megabyte +timeout = 10 # seconds [auth] delay = 1 # Average delay after failed login attempts in seconds ``` diff --git a/wsgi.md b/wsgi.md index 76321a2d..fb6a3078 100644 --- a/wsgi.md +++ b/wsgi.md @@ -6,3 +6,6 @@ permalink: /wsgi/ Radicale is compatible with the WSGI specification. No special configuration is required. + +Be reminded that Radicale's default configuration enforces limits on the +maximum file size and that connections are terminated after a timeout. From be54bd27298f76f96173a1660162ddc704c0fbb6 Mon Sep 17 00:00:00 2001 From: Unrud Date: Thu, 25 May 2017 19:58:36 +0200 Subject: [PATCH 7/7] WIP (Running as a service on Windows with NSSM) --- setup.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/setup.md b/setup.md index 7c61875e..767b6650 100644 --- a/setup.md +++ b/setup.md @@ -179,6 +179,23 @@ After daemonization the server will not log anything. You have to configure If you start Radicale now, it will initialize and fork into the background. The main process exits, after the PID file is written. -## Windows +## Windows with "NSSM - the Non-Sucking Service Manager" -*To be written.* +First install [NSSM](https://nssm.cc/) and start ``nssm install`` in a command +prompt. Apply the following configuration: + + * Service name: ``Radicale`` + * Application + * Path: ``C:\Path\To\Python\python.exe`` + * Arguments: ``-m radicale --config C:\Path\To\Config`` + * I/O redirection + * Error: ``C:\Path\To\Radicale.log`` + +Be aware that the service runs in the local system account, you might want to change this. Managing user accounts is beyond the scope of this manual. + +The log file might grow very big over time, you can configure file rotation +in **NSSM** to prevent this. + +The service is configured to start automatically when the computer starts. +To start the service manually open **Services** in **Computer Management** and +start the **Radicale** service.