diff --git a/master.html b/master.html index 76416819..b7e3db1d 100644 --- a/master.html +++ b/master.html @@ -146,7 +146,6 @@
Radicale is really easy to install and works out-of-the-box.
$ python3 -m pip install --upgrade radicale
-$ python3 -m radicale --config "" --storage-filesystem-folder=~/.var/lib/radicale/collections
When your server is launched, you can check that everything's OK by going to http://localhost:5232/ with your browser! You can login with any username and password.
Want more? Why don't you check our wonderful documentation?
@@ -284,7 +280,6 @@# 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
Victory! Open http://localhost:5232/ in your browser! You can login with any username and password.
The first step is to install Python. Go to 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\User> python -m pip install --upgrade radicale
-C:\Users\User> python -m radicale --config "" --storage-filesystem-folder=~/radicale/collections
If you are using PowerShell replace --config ""
with --config '""'
.
Victory! Open http://localhost:5232/ in your browser! You can login with any username and password.
Installation instructions can be found on the Tutorial page.
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 passed via command line arguments.)
All configuration options are described in detail on the Configuration page.
The users
file can be created and managed with htpasswd:
# 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:
-Authentication can be enabled with the following configuration:
- +Authentication can be enabled with the following configuration:
- +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:
- -More addresses can be added (separated by commas).
+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 (IPv4 and IPv6):
+Data is stored in the folder /var/lib/radicale/collections
. The path can be changed with the following configuration:
Security: The storage folder should not be readable by unauthorized users. Otherwise, they can read the calendar data and lock the storage. You can find OS dependent instructions in the Running as a service section.
Radicale enforces limits on the maximum number of parallel connections, 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.
- +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
[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
Radicale will load the configuration file from ~/.config/radicale/config
. You should set the configuration option filesystem_folder
in the storage
section to something like ~/.var/lib/radicale/collections
.
To enable and manage the service run:
- +Create the radicale user and group for the Radicale service. (Run useradd --system --home-dir / --shell /sbin/nologin radicale
as root.) The storage folder must be writable by radicale. (Run mkdir -p /var/lib/radicale/collections && chown -R radicale:radicale /var/lib/radicale/collections
as root.)
Security: The storage should not be readable by others. (Run chmod -R o= /var/lib/radicale/collections
as root.)
Create the file /etc/systemd/system/radicale.service
:
[Unit]
-Description=A simple CalDAV (calendar) and CardDAV (contact) server
-After=network.target
-Requires=network.target
-
-[Service]
-ExecStart=/usr/bin/env python3 -m radicale
-Restart=on-failure
-User=radicale
-# Deny other users access to the calendar data
-UMask=0027
-# Optional security settings
-PrivateTmp=true
-ProtectSystem=strict
-ProtectHome=true
-PrivateDevices=true
-ProtectKernelTunables=true
-ProtectKernelModules=true
-ProtectControlGroups=true
-NoNewPrivileges=true
-ReadWritePaths=/var/lib/radicale/collections
-
-[Install]
-WantedBy=multi-user.target
[Unit]
+Description=A simple CalDAV (calendar) and CardDAV (contact) server
+After=network.target
+Requires=network.target
+
+[Service]
+ExecStart=/usr/bin/env python3 -m radicale
+Restart=on-failure
+User=radicale
+# Deny other users access to the calendar data
+UMask=0027
+# Optional security settings
+PrivateTmp=true
+ProtectSystem=strict
+ProtectHome=true
+PrivateDevices=true
+ProtectKernelTunables=true
+ProtectKernelModules=true
+ProtectControlGroups=true
+NoNewPrivileges=true
+ReadWritePaths=/var/lib/radicale/collections
+
+[Install]
+WantedBy=multi-user.target
Radicale will load the configuration file from /etc/radicale/config
.
To enable and manage the service run:
- +To be written.
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.
-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!
First install NSSM and start nssm install
in a command prompt. Apply the following configuration:
Example Apache configuration:
-RewriteEngine On
-RewriteRule ^/radicale$ /radicale/ [R,L]
-
-<Location "/radicale/">
- ProxyPass http://localhost:5232/ retry=0
- ProxyPassReverse http://localhost:5232/
- RequestHeader set X-Script-Name /radicale/
-</Location>
RewriteEngine On
+RewriteRule ^/radicale$ /radicale/ [R,L]
+
+<Location "/radicale/">
+ ProxyPass http://localhost:5232/ retry=0
+ ProxyPassReverse http://localhost:5232/
+ RequestHeader set X-Script-Name /radicale/
+</Location>
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.
Example Apache configuration:
-RewriteEngine On
-RewriteRule ^/radicale$ /radicale/ [R,L]
-
-<Location "/radicale/">
- AuthType Basic
- AuthName "Radicale - Password Required"
- AuthUserFile "/etc/radicale/htpasswd"
- Require valid-user
-
- ProxyPass http://localhost:5232/ retry=0
- ProxyPassReverse http://localhost:5232/
- RequestHeader set X-Script-Name /radicale/
- RequestHeader set X-Remote-User expr=%{REMOTE_USER}
-</Location>
RewriteEngine On
+RewriteRule ^/radicale$ /radicale/ [R,L]
+
+<Location "/radicale/">
+ AuthType Basic
+ AuthName "Radicale - Password Required"
+ AuthUserFile "/etc/radicale/htpasswd"
+ Require valid-user
+
+ ProxyPass http://localhost:5232/ retry=0
+ ProxyPassReverse http://localhost:5232/
+ RequestHeader set X-Script-Name /radicale/
+ RequestHeader set X-Remote-User expr=%{REMOTE_USER}
+</Location>
Security: Untrusted clients should not be able to access the Radicale server directly. Otherwise, they can authenticate as any user.
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 a certificate for the reverse proxy. The following commands generate self-signed certificates. You will be asked to enter additional information about the certificate, the values don't matter and you can keep the defaults.
-$ openssl req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem -nodes -days 9999
-$ openssl req -x509 -newkey rsa:4096 -keyout client_key.pem -out client_cert.pem -nodes -days 9999
$ openssl req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem -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:
-[server]
-ssl = True
-certificate = /path/to/server_cert.pem
-key = /path/to/server_key.pem
-certificate_authority = /path/to/client_cert.pem
[server]
+ssl = True
+certificate = /path/to/server_cert.pem
+key = /path/to/server_key.pem
+certificate_authority = /path/to/client_cert.pem
Example nginx configuration:
location /radicale/ {
proxy_pass https://localhost:5232/;
@@ -579,14 +563,14 @@ user2:password2
Be reminded that Radicale's default configuration enforces limits on the maximum upload file size.
Security: The None
authentication type disables all rights checking. Don't use it with REMOTE_USER
. Use remote_user
instead.
Example uWSGI configuration:
-[uwsgi]
-http-socket = 127.0.0.1:5232
-processes = 8
-plugin = python3
-module = radicale
-env = RADICALE_CONFIG=/etc/radicale/config
+[uwsgi]
+http-socket = 127.0.0.1:5232
+processes = 8
+plugin = python3
+module = radicale
+env = RADICALE_CONFIG=/etc/radicale/config
Example Gunicorn configuration:
-
+
Manage user accounts with the WSGI server ¶
Set the configuration option type
in the auth
section to remote_user
. Radicale uses the user name provided by the WSGI server and disables authentication over HTTP.
@@ -601,7 +585,7 @@ user2:password2
.Radicale.tmp-*
The configuration option hook
in the storage
section must be set to the following command:
The command gets executed after every change to the storage and commits the changes into the git repository.
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) to create and manage collections.
+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) to create and manage 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 enter the URL of the collection directly (e.g. http://localhost:5232/user/calendar
).
To create a new collection, you have to create the corresponding folder in the file system storage (e.g. collection-root/user/calendar
). To tell Radicale and clients that the collection is a calendar, you have to create the file .Radicale.props
with the following content in the folder:
The calendar is now available at the URL path /user/calendar
. For address books the file must contain:
Calendar and address book collections must not have any child collections. Clients with automatic discovery of collections will only show calendars and addressbooks that are direct children of the path /USERNAME/
.
Delete collections by deleting the corresponding folders.
To create a new calendar run something like:
-$ curl -u user -X MKCOL 'http://localhost:5232/user/calendar' --data \
+$ curl -u user -X MKCOL 'http://localhost:5232/user/calendar' --data \
+'<?xml version="1.0" encoding="UTF-8" ?>
+<create xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:I="http://apple.com/ns/ical/">
+ <set>
+ <prop>
+ <resourcetype>
+ <collection />
+ <C:calendar />
+ </resourcetype>
+ <C:supported-calendar-component-set>
+ <C:comp name="VEVENT" />
+ <C:comp name="VJOURNAL" />
+ <C:comp name="VTODO" />
+ </C:supported-calendar-component-set>
+ <displayname>Calendar</displayname>
+ <C:calendar-description>Example calendar</C:calendar-description>
+ <I:calendar-color>#ff0000ff</I:calendar-color>
+ </prop>
+ </set>
+</create>'
+To create a new address book run something like:
+$ curl -u user -X MKCOL 'http://localhost:5232/user/addressbook' --data \
'<?xml version="1.0" encoding="UTF-8" ?>
-<create xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:I="http://apple.com/ns/ical/">
+<create xmlns="DAV:" xmlns:CR="urn:ietf:params:xml:ns:carddav">
<set>
<prop>
<resourcetype>
<collection />
- <C:calendar />
+ <CR:addressbook />
</resourcetype>
- <C:supported-calendar-component-set>
- <C:comp name="VEVENT" />
- <C:comp name="VJOURNAL" />
- <C:comp name="VTODO" />
- </C:supported-calendar-component-set>
- <displayname>Calendar</displayname>
- <C:calendar-description>Example calendar</C:calendar-description>
- <I:calendar-color>#ff0000ff</I:calendar-color>
- </prop>
- </set>
-</create>'
-To create a new address book run something like:
-$ curl -u user -X MKCOL 'http://localhost:5232/user/addressbook' --data \
-'<?xml version="1.0" encoding="UTF-8" ?>
-<create xmlns="DAV:" xmlns:CR="urn:ietf:params:xml:ns:carddav">
- <set>
- <prop>
- <resourcetype>
- <collection />
- <CR:addressbook />
- </resourcetype>
- <displayname>Address book</displayname>
- <CR:addressbook-description>Example address book</CR:addressbook-description>
- </prop>
- </set>
-</create>'
+ <displayname>Address book</displayname>
+ <CR:addressbook-description>Example address book</CR:addressbook-description>
+ </prop>
+ </set>
+</create>'
The collection /USERNAME
will be created automatically, when the user authenticates to Radicale for the first time. Clients with automatic discovery of collections will only show calendars and address books that are direct children of the path /USERNAME/
.
Delete the collections by running something like:
- +Radicale can be configured with a configuration file or with command line arguments.
An example configuration file looks like:
-[server]
-# Bind all addresses
-hosts = 0.0.0.0:5232
-
-[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.
[server]
+# Bind all addresses
+hosts = 0.0.0.0:5232, [::]:5232
+
+[auth]
+type = htpasswd
+htpasswd_filename = /path/to/users
+htpasswd_encryption = md5
+[storage]
+filesystem_folder = ~/.var/lib/radicale/collections
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:
-python3 -m radicale --config "" --server-hosts 0.0.0.0:5232 --auth-type htpasswd --htpasswd-filename /path/to/htpasswd --htpasswd-encryption bcrypt
The --config ""
argument is required to stop Radicale from trying to load configuration files. Run python3 -m radicale --help
for more information.
python3 -m radicale --server-hosts 0.0.0.0:5232,[::]:5232 --auth-type htpasswd --htpasswd-filename /path/to/htpasswd --htpasswd-encryption md5
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.
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.
A comma separated list of addresses that the server will bind to.
-Default: 127.0.0.1:5232
Daemonize the Radicale process. It does not reset the umask.
-Default: False
If daemon mode is enabled, Radicale will write its PID to this file.
-Default:
+Default: localhost:5232
The maximum number of parallel connections. Set to 0
to disable the limit.
Default: 20
Default: 8
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 authenticate users with client-side certificates, you also have to write an authentication plugin that extracts the user name from the certifcate.
Default:
SSL protocol used. See python's ssl module for available values.
-Default: PROTOCOL_TLSv1_2
Available ciphers for SSL. See python's ssl module for available ciphers.
-Default:
-Reverse DNS to resolve client address in logs.
-Default: True
Message displayed in the client when a password is needed.
-Default: Radicale - Password Required
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). It's insecure!
Default: bcrypt
bcrypt
: This uses a modified version of the Blowfish stream cipher. It's very secure. The installation of radicale[bcrypt] is required for this.
md5
: This uses an iterated md5 digest of the password with a salt.
Default: md5
Average delay after failed login attempts in seconds.
Default: 1
Message displayed in the client when a password is needed.
+Default: Radicale - Password Required
Folder for storing local collections, created if not present.
Default: /var/lib/radicale/collections
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
Delete sync-token that are older than the specified time. (seconds)
Default: 2592000
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
Command that is run after changes to storage. Take a look at the Versioning page for an example.
@@ -907,32 +853,23 @@ user2:password2Set the default logging level to debug.
-Default: False
Log all environment variables (including those set in the shell).
-Default: False
Set the logging level.
+Available levels: debug, info, warning, error, critical
+Default: warning
Don't include passwords in logs.
Default: True
Logging configuration file. See the Logging page.
-Default:
-In this section additional HTTP headers that are sent to clients can be specified.
An example to relax the same-origin policy:
- +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 method 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:
-# 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 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.
%(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 {1}
, {2}
, etc.
Use the flock utility.
- +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.
An example configuration to write the log output to the file /var/log/radicale/log
:
[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.
-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:
[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
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:
[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
Radicale logs to stderr
. The verbosity of the log output can be controlled with --debug
command line argument or the level
configuration option in the logging
section.
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.
__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.
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.
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.
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.
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.
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.
The radicale
package offers the following modules.
__init__
: Contains the entry point for WSGI.
__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.
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
: 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.
log
: The logger for Radicale based on the default Python logging module.
rights
: 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
: 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.
Radicale can be extended by plugins for authentication, rights management and storage. Plugins are python modules.
To get started we walk through the creation of a simple authentication plugin, that accepts login attempts if the username and password are equal.
+To get started we walk through the creation of a simple authentication plugin, that accepts login attempts with a static password.
The easiest way to develop and install python modules is Distutils. For a minimal setup create the file setup.py
with the following content in an empty folder:
#!/usr/bin/env python3
-
-from distutils.core import setup
-
-setup(name="radicale_silly_auth", packages=["radicale_silly_auth"])
In the same folder create the sub-folder radicale_silly_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:
from radicale.auth import BaseAuth
-
-
-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)
-
- # Check authentication
- self.logger.info("Login attempt by %r with password %r",
- user, password)
- return user == password
#!/usr/bin/env python3
+
+from distutils.core import setup
+
+setup(name="radicale_static_password_auth", packages=["radicale_static_password_auth"])
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_static_password_auth
folder with the following content:
from radicale.auth import BaseAuth
+from radicale.log import logger
+
+PLUGIN_CONFIG_SCHEMA = {"auth": {
+ "password": {"value": "", "type": str}}}
+
+
+class Auth(BaseAuth):
+ 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
+ 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 as setup.py
:
To make use this great creation in Radicale, set the configuration option type
in the auth
section to radicale_silly_auth
:
To make use this great creation in Radicale, set the configuration option type
in the auth
section to radicale_static_password_auth
:
You can uninstall the module with:
- +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.
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/__init__.py
in Radicale's source code for more information.
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.
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/__init__.py
in Radicale's source code for more information.
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's source code for more information.
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/__init__.py
in Radicale's source code for more information.
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.
This plugin is used to store collections and items. 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.
Interested in hacking? Feel free to clone the git repository on Github if you want to add new features, fix bugs or update the documentation.
+Interested in hacking? Feel free to clone the git repository on GitHub if you want to add new features, fix bugs or update the documentation.
You can download the Radicale package for each release:
-You can find the source packages of all releases on GitHub.