1
0
Fork 0
mirror of https://github.com/Kozea/Radicale.git synced 2025-06-26 16:45:52 +00:00

Generate documentation

This commit is contained in:
Github Actions 2021-12-01 21:58:57 +00:00
parent 50bf568521
commit 996636034f
4 changed files with 1682 additions and 1180 deletions

855
1.1.html
View file

@ -5,6 +5,137 @@
<meta content="pandoc" name="generator">
<meta content="width=device-width, initial-scale=1" name="viewport">
<style>
html {
line-height: 1.5;
font-family: Georgia, serif;
font-size: 20px;
color: #1a1a1a;
background-color: #fdfdfd;
}
body {
margin: 0 auto;
max-width: 36em;
padding-left: 50px;
padding-right: 50px;
padding-top: 50px;
padding-bottom: 50px;
hyphens: auto;
overflow-wrap: break-word;
text-rendering: optimizeLegibility;
font-kerning: normal;
}
@media (max-width: 600px) {
body {
font-size: 0.9em;
padding: 1em;
}
}
@media print {
body {
background-color: transparent;
color: black;
font-size: 12pt;
}
p, h2, h3 {
orphans: 3;
widows: 3;
}
h2, h3, h4 {
page-break-after: avoid;
}
}
p {
margin: 1em 0;
}
a {
color: #1a1a1a;
}
a:visited {
color: #1a1a1a;
}
img {
max-width: 100%;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 1.4em;
}
h5, h6 {
font-size: 1em;
font-style: italic;
}
h6 {
font-weight: normal;
}
ol, ul {
padding-left: 1.7em;
margin-top: 1em;
}
li > ol, li > ul {
margin-top: 0;
}
blockquote {
margin: 1em 0 1em 1.7em;
padding-left: 1em;
border-left: 2px solid #e6e6e6;
color: #606060;
}
code {
font-family: Menlo, Monaco, 'Lucida Console', Consolas, monospace;
font-size: 85%;
margin: 0;
}
pre {
margin: 1em 0;
overflow: auto;
}
pre code {
padding: 0;
overflow: visible;
overflow-wrap: normal;
}
.sourceCode {
background-color: transparent;
overflow: visible;
}
hr {
background-color: #1a1a1a;
border: none;
height: 1px;
margin: 1em 0;
}
table {
margin: 1em 0;
border-collapse: collapse;
width: 100%;
overflow-x: auto;
display: block;
font-variant-numeric: lining-nums tabular-nums;
}
table caption {
margin-bottom: 0.75em;
}
tbody {
margin-top: 0.5em;
border-top: 1px solid #1a1a1a;
border-bottom: 1px solid #1a1a1a;
}
th {
border-top: 1px solid #1a1a1a;
padding: 0.25em 0.5em 0.25em 0.5em;
}
td {
padding: 0.125em 0.5em 0.25em 0.5em;
}
header {
margin-bottom: 4em;
text-align: center;
}
#TOC li {
list-style: none;
}
#TOC a:not(:hover) {
text-decoration: none;
}
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
@ -14,6 +145,7 @@
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@ -73,6 +205,7 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
</style>
<link href="assets/default.css" media="all" rel="stylesheet">
<link href="assets/screen.css" media="screen" rel="stylesheet">
@ -422,7 +555,7 @@
<p class="heading">Calendars <a class="headerlink" href="#documentation/user-documentation/simple-usage/starting-the-client/korganizer/calendars">&para;</a></p>
<p><em>Tested with 4.8.3, you need one running on Akonadi for Cal/CarDav support.</em></p>
<p>The procedure below can also be done trough the sidebar "Calendar Manager". But to ensure it works for everyone this examples uses the menu-bar.</p>
<ol>
<ol type="1">
<li>Click <code>Settings &rarr; Configure KOrganizer</code>.</li>
<li>Click on <code>General &rarr; Calendars</code>.</li>
<li>Click on <code>Add</code>.</li>
@ -516,50 +649,50 @@ only <em>InfCloud</em> is used in description below.</p>
<section class="level7" id="documentation/user-documentation/simple-usage/starting-the-client/infcloud-caldavzap--carddavmate/radicale-configuration">
<p class="heading">Radicale configuration <a class="headerlink" href="#documentation/user-documentation/simple-usage/starting-the-client/infcloud-caldavzap--carddavmate/radicale-configuration">&para;</a></p>
<p>Add/Modify the following section in Radicale main configuration file:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb1-1"><a href="#cb1-1"></a><span class="co"># Additional HTTP headers</span></span>
<span id="cb1-2"><a href="#cb1-2"></a><span class="kw">[headers]</span></span>
<span id="cb1-3"><a href="#cb1-3"></a><span class="dt">Access-Control-Allow-Origin </span><span class="ot">=</span><span class="st"> *</span></span>
<span id="cb1-4"><a href="#cb1-4"></a><span class="dt">Access-Control-Allow-Methods </span><span class="ot">=</span><span class="st"> GET, POST, OPTIONS, PROPFIND, PROPPATCH, REPORT, PUT, MOVE, DELETE, LOCK, UNLOCK</span></span>
<span id="cb1-5"><a href="#cb1-5"></a><span class="dt">Access-Control-Allow-Headers </span><span class="ot">=</span><span class="st"> Authorization, Content-type, Depth, Destination, If-match, If-None-Match, Lock-Token, Overwrite, Prefer, Timeout, User-Agent, X-Client, X-Requested-With</span></span>
<span id="cb1-6"><a href="#cb1-6"></a><span class="dt">Access-Control-Expose-Headers </span><span class="ot">=</span><span class="st"> Etag</span></span></code></pre></div>
<div class="sourceCode" id="cb1"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb1-1"><a aria-hidden="true" href="#cb1-1" tabindex="-1"></a><span class="co"># Additional HTTP headers</span></span>
<span id="cb1-2"><a aria-hidden="true" href="#cb1-2" tabindex="-1"></a><span class="kw">[headers]</span></span>
<span id="cb1-3"><a aria-hidden="true" href="#cb1-3" tabindex="-1"></a><span class="dt">Access-Control-Allow-Origin </span><span class="ot">=</span><span class="st"> *</span></span>
<span id="cb1-4"><a aria-hidden="true" href="#cb1-4" tabindex="-1"></a><span class="dt">Access-Control-Allow-Methods </span><span class="ot">=</span><span class="st"> GET, POST, OPTIONS, PROPFIND, PROPPATCH, REPORT, PUT, MOVE, DELETE, LOCK, UNLOCK</span></span>
<span id="cb1-5"><a aria-hidden="true" href="#cb1-5" tabindex="-1"></a><span class="dt">Access-Control-Allow-Headers </span><span class="ot">=</span><span class="st"> Authorization, Content-type, Depth, Destination, If-match, If-None-Match, Lock-Token, Overwrite, Prefer, Timeout, User-Agent, X-Client, X-Requested-With</span></span>
<span id="cb1-6"><a aria-hidden="true" href="#cb1-6" tabindex="-1"></a><span class="dt">Access-Control-Expose-Headers </span><span class="ot">=</span><span class="st"> Etag</span></span></code></pre></div>
<p><code>InfCloud</code> needs read access for <code>everybody</code> (including anonymous users) on Radicale's root directory. If using Radicales rights management add the following section to rights file:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb2-1"><a href="#cb2-1"></a><span class="co"># Allow caldavzap, carddavmate and infcloud to work</span></span>
<span id="cb2-2"><a href="#cb2-2"></a><span class="kw">[infcloud]</span></span>
<span id="cb2-3"><a href="#cb2-3"></a><span class="dt">user: .*</span></span>
<span id="cb2-4"><a href="#cb2-4"></a><span class="dt">collection: /</span></span>
<span id="cb2-5"><a href="#cb2-5"></a><span class="dt">permission: r</span></span></code></pre></div>
<div class="sourceCode" id="cb2"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb2-1"><a aria-hidden="true" href="#cb2-1" tabindex="-1"></a><span class="co"># Allow caldavzap, carddavmate and infcloud to work</span></span>
<span id="cb2-2"><a aria-hidden="true" href="#cb2-2" tabindex="-1"></a><span class="kw">[infcloud]</span></span>
<span id="cb2-3"><a aria-hidden="true" href="#cb2-3" tabindex="-1"></a><span class="dt">user: .*</span></span>
<span id="cb2-4"><a aria-hidden="true" href="#cb2-4" tabindex="-1"></a><span class="dt">collection: /</span></span>
<span id="cb2-5"><a aria-hidden="true" href="#cb2-5" tabindex="-1"></a><span class="dt">permission: r</span></span></code></pre></div>
<p>Additional you need to change <code>[owner-write]</code> section to use the same syntax for collection as shown in <code>[public]</code> section.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb3-1"><a href="#cb3-1"></a><span class="co"># Give write access to owners</span></span>
<span id="cb3-2"><a href="#cb3-2"></a><span class="kw">[owner-write]</span></span>
<span id="cb3-3"><a href="#cb3-3"></a><span class="dt">user: .+</span></span>
<span id="cb3-4"><a href="#cb3-4"></a><span class="co"># collection: ^%(login)s/.+$ # DOES NOT WORK</span></span>
<span id="cb3-5"><a href="#cb3-5"></a><span class="dt">collection: ^%(login)s(/.+)?$</span></span>
<span id="cb3-6"><a href="#cb3-6"></a><span class="dt">permission: rw</span></span></code></pre></div>
<div class="sourceCode" id="cb3"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb3-1"><a aria-hidden="true" href="#cb3-1" tabindex="-1"></a><span class="co"># Give write access to owners</span></span>
<span id="cb3-2"><a aria-hidden="true" href="#cb3-2" tabindex="-1"></a><span class="kw">[owner-write]</span></span>
<span id="cb3-3"><a aria-hidden="true" href="#cb3-3" tabindex="-1"></a><span class="dt">user: .+</span></span>
<span id="cb3-4"><a aria-hidden="true" href="#cb3-4" tabindex="-1"></a><span class="co"># collection: ^%(login)s/.+$ # DOES NOT WORK</span></span>
<span id="cb3-5"><a aria-hidden="true" href="#cb3-5" tabindex="-1"></a><span class="dt">collection: ^%(login)s(/.+)?$</span></span>
<span id="cb3-6"><a aria-hidden="true" href="#cb3-6" tabindex="-1"></a><span class="dt">permission: rw</span></span></code></pre></div>
</section>
<section class="level7" id="documentation/user-documentation/simple-usage/starting-the-client/infcloud-caldavzap--carddavmate/infcloud-configuration">
<p class="heading">InfCloud configuration <a class="headerlink" href="#documentation/user-documentation/simple-usage/starting-the-client/infcloud-caldavzap--carddavmate/infcloud-configuration">&para;</a></p>
<p>Inside <code>InfCloud</code> configuration file <code>config.js</code> you need to set <code>globalNetworkCheckSettings</code> like following example:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode JavaScript"><code class="sourceCode javascript"><span id="cb4-1"><a href="#cb4-1"></a><span class="co">// href: </span></span>
<span id="cb4-2"><a href="#cb4-2"></a><span class="co">// put in here your protocol, host and port where Radicale is listening</span></span>
<span id="cb4-3"><a href="#cb4-3"></a><span class="co">// additionalResources:</span></span>
<span id="cb4-4"><a href="#cb4-4"></a><span class="co">// put in here a comma separated list of collections you want additionally look at.</span></span>
<span id="cb4-5"><a href="#cb4-5"></a><span class="co">// Don't forget '' around each collections name</span></span>
<span id="cb4-6"><a href="#cb4-6"></a><span class="kw">var</span> globalNetworkCheckSettings<span class="op">=</span>{</span>
<span id="cb4-7"><a href="#cb4-7"></a> <span class="dt">href</span><span class="op">:</span> <span class="st">'https://host.example.com:5232/'</span><span class="op">,</span></span>
<span id="cb4-8"><a href="#cb4-8"></a> <span class="dt">hrefLabel</span><span class="op">:</span> <span class="kw">null</span><span class="op">,</span></span>
<span id="cb4-9"><a href="#cb4-9"></a> <span class="dt">crossDomain</span><span class="op">:</span> <span class="kw">null</span><span class="op">,</span></span>
<span id="cb4-10"><a href="#cb4-10"></a> <span class="dt">additionalResources</span><span class="op">:</span> [<span class="st">'public'</span>]<span class="op">,</span></span>
<span id="cb4-11"><a href="#cb4-11"></a> <span class="dt">forceReadOnly</span><span class="op">:</span> <span class="kw">null</span><span class="op">,</span></span>
<span id="cb4-12"><a href="#cb4-12"></a> <span class="dt">withCredentials</span><span class="op">:</span> <span class="kw">false</span><span class="op">,</span></span>
<span id="cb4-13"><a href="#cb4-13"></a> <span class="dt">showHeader</span><span class="op">:</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb4-14"><a href="#cb4-14"></a> <span class="dt">settingsAccount</span><span class="op">:</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb4-15"><a href="#cb4-15"></a> <span class="dt">syncInterval</span><span class="op">:</span> <span class="dv">60000</span><span class="op">,</span></span>
<span id="cb4-16"><a href="#cb4-16"></a> <span class="dt">timeOut</span><span class="op">:</span> <span class="dv">30000</span><span class="op">,</span></span>
<span id="cb4-17"><a href="#cb4-17"></a> <span class="dt">lockTimeOut</span><span class="op">:</span> <span class="dv">10000</span><span class="op">,</span></span>
<span id="cb4-18"><a href="#cb4-18"></a> <span class="dt">delegation</span><span class="op">:</span> <span class="kw">false</span><span class="op">,</span></span>
<span id="cb4-19"><a href="#cb4-19"></a> <span class="dt">ignoreAlarms</span><span class="op">:</span> <span class="kw">false</span><span class="op">,</span></span>
<span id="cb4-20"><a href="#cb4-20"></a> <span class="dt">backgroundCalendars</span><span class="op">:</span> []</span>
<span id="cb4-21"><a href="#cb4-21"></a>}</span></code></pre></div>
<div class="sourceCode" id="cb4"><pre class="sourceCode JavaScript"><code class="sourceCode javascript"><span id="cb4-1"><a aria-hidden="true" href="#cb4-1" tabindex="-1"></a><span class="co">// href: </span></span>
<span id="cb4-2"><a aria-hidden="true" href="#cb4-2" tabindex="-1"></a><span class="co">// put in here your protocol, host and port where Radicale is listening</span></span>
<span id="cb4-3"><a aria-hidden="true" href="#cb4-3" tabindex="-1"></a><span class="co">// additionalResources:</span></span>
<span id="cb4-4"><a aria-hidden="true" href="#cb4-4" tabindex="-1"></a><span class="co">// put in here a comma separated list of collections you want additionally look at.</span></span>
<span id="cb4-5"><a aria-hidden="true" href="#cb4-5" tabindex="-1"></a><span class="co">// Don't forget '' around each collections name</span></span>
<span id="cb4-6"><a aria-hidden="true" href="#cb4-6" tabindex="-1"></a><span class="kw">var</span> globalNetworkCheckSettings<span class="op">=</span>{</span>
<span id="cb4-7"><a aria-hidden="true" href="#cb4-7" tabindex="-1"></a> <span class="dt">href</span><span class="op">:</span> <span class="st">'https://host.example.com:5232/'</span><span class="op">,</span></span>
<span id="cb4-8"><a aria-hidden="true" href="#cb4-8" tabindex="-1"></a> <span class="dt">hrefLabel</span><span class="op">:</span> <span class="kw">null</span><span class="op">,</span></span>
<span id="cb4-9"><a aria-hidden="true" href="#cb4-9" tabindex="-1"></a> <span class="dt">crossDomain</span><span class="op">:</span> <span class="kw">null</span><span class="op">,</span></span>
<span id="cb4-10"><a aria-hidden="true" href="#cb4-10" tabindex="-1"></a> <span class="dt">additionalResources</span><span class="op">:</span> [<span class="st">'public'</span>]<span class="op">,</span></span>
<span id="cb4-11"><a aria-hidden="true" href="#cb4-11" tabindex="-1"></a> <span class="dt">forceReadOnly</span><span class="op">:</span> <span class="kw">null</span><span class="op">,</span></span>
<span id="cb4-12"><a aria-hidden="true" href="#cb4-12" tabindex="-1"></a> <span class="dt">withCredentials</span><span class="op">:</span> <span class="kw">false</span><span class="op">,</span></span>
<span id="cb4-13"><a aria-hidden="true" href="#cb4-13" tabindex="-1"></a> <span class="dt">showHeader</span><span class="op">:</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb4-14"><a aria-hidden="true" href="#cb4-14" tabindex="-1"></a> <span class="dt">settingsAccount</span><span class="op">:</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb4-15"><a aria-hidden="true" href="#cb4-15" tabindex="-1"></a> <span class="dt">syncInterval</span><span class="op">:</span> <span class="dv">60000</span><span class="op">,</span></span>
<span id="cb4-16"><a aria-hidden="true" href="#cb4-16" tabindex="-1"></a> <span class="dt">timeOut</span><span class="op">:</span> <span class="dv">30000</span><span class="op">,</span></span>
<span id="cb4-17"><a aria-hidden="true" href="#cb4-17" tabindex="-1"></a> <span class="dt">lockTimeOut</span><span class="op">:</span> <span class="dv">10000</span><span class="op">,</span></span>
<span id="cb4-18"><a aria-hidden="true" href="#cb4-18" tabindex="-1"></a> <span class="dt">delegation</span><span class="op">:</span> <span class="kw">false</span><span class="op">,</span></span>
<span id="cb4-19"><a aria-hidden="true" href="#cb4-19" tabindex="-1"></a> <span class="dt">ignoreAlarms</span><span class="op">:</span> <span class="kw">false</span><span class="op">,</span></span>
<span id="cb4-20"><a aria-hidden="true" href="#cb4-20" tabindex="-1"></a> <span class="dt">backgroundCalendars</span><span class="op">:</span> []</span>
<span id="cb4-21"><a aria-hidden="true" href="#cb4-21" tabindex="-1"></a>}</span></code></pre></div>
<blockquote>
<p><strong>Note</strong></p>
<p><code>InfCloud</code>, <code>CardDavMATE</code> and <code>CalDavZAP</code> cannot create calendars and/or address books. <strong>They need to be created before first login.</strong> Each user needs to have minimum of one calendar and/or one adressbook even if only using shared addresses and/or calendars. Client will not login, if the user collections don't exists.</p>
@ -586,7 +719,7 @@ After installing and accepting it you should restart your browser.</p>
<section class="level7" id="documentation/user-documentation/simple-usage/starting-the-client/iphone--ipad/calendars">
<p class="heading">Calendars <a class="headerlink" href="#documentation/user-documentation/simple-usage/starting-the-client/iphone--ipad/calendars">&para;</a></p>
<p>For iOS devices, the setup is fairly straightforward but there are a few settings that are critical for proper operation.</p>
<ol>
<ol type="1">
<li>From the Home screen, open <code>Settings</code></li>
<li>Select <code>Mail, Contacts, Calendars</code></li>
<li>Select <code>Add Account&hellip;</code> &rarr; <code>Other</code> &rarr; <code>Add CalDAV Account</code></li>
@ -607,7 +740,7 @@ After installing and accepting it you should restart your browser.</p>
<section class="level7" id="documentation/user-documentation/simple-usage/starting-the-client/iphone--ipad/contacts">
<p class="heading">Contacts <a class="headerlink" href="#documentation/user-documentation/simple-usage/starting-the-client/iphone--ipad/contacts">&para;</a></p>
<p>In Contacts on iOS 6:</p>
<ol>
<ol type="1">
<li>From the Home screen, open <code>Settings</code></li>
<li>Select <code>Mail, Contacts, Calendars</code></li>
<li>Select <code>Add Account&hellip;</code> &rarr; <code>Other</code> &rarr; <code>Add CardDAV Account</code></li>
@ -635,7 +768,7 @@ After installing and accepting it you should restart your browser.</p>
<section class="level7" id="documentation/user-documentation/simple-usage/starting-the-client/os-x/calendars">
<p class="heading">Calendars <a class="headerlink" href="#documentation/user-documentation/simple-usage/starting-the-client/os-x/calendars">&para;</a></p>
<p>In iCal 4.0 or iCal 5.0:</p>
<ol>
<ol type="1">
<li>Open the <code>Preferences</code> dialog and select the <code>Accounts</code> tab</li>
<li>Click the <code>+</code> button at the lower left to open the account creation wizard</li>
<li>As <code>Account type</code> select <code>CalDAV</code></li>
@ -658,7 +791,7 @@ After installing and accepting it you should restart your browser.</p>
<section class="level7" id="documentation/user-documentation/simple-usage/starting-the-client/os-x/contacts">
<p class="heading">Contacts <a class="headerlink" href="#documentation/user-documentation/simple-usage/starting-the-client/os-x/contacts">&para;</a></p>
<p>In Contacts 7 (previously known as AddressBook):</p>
<ol>
<ol type="1">
<li>Open the <code>Preferences</code> dialog and select the <code>Accounts</code> tab.</li>
<li>Click the <code>+</code> button at the lower left to open the account creation wizard.</li>
<li>As <code>Account type</code> select <code>CardDAV</code>.</li>
@ -681,7 +814,7 @@ After installing and accepting it you should restart your browser.</p>
</section>
<section class="level6" id="documentation/user-documentation/simple-usage/starting-the-client/nokia--microsoft-windows-phones">
<h6>Nokia / Microsoft Windows Phones <a class="headerlink" href="#documentation/user-documentation/simple-usage/starting-the-client/nokia--microsoft-windows-phones">&para;</a></h6>
<ol>
<ol type="1">
<li>Go to "Settings" &gt; "email+accounts"</li>
<li>Click "add an account" &gt; "iCloud"</li>
<li>Enter random email address (e.g. "<a href="mailto:foo@bar">foo@bar</a>" and "qwerty") &gt; "sign in"</li>
@ -713,11 +846,9 @@ After installing and accepting it you should restart your browser.</p>
<section class="level5" id="documentation/user-documentation/complex-configuration/installing-the-server">
<h5>Installing the Server <a class="headerlink" href="#documentation/user-documentation/complex-configuration/installing-the-server">&para;</a></h5>
<p>You can install Radicale thanks to the following command, with superuser rights:</p>
<pre><code>python setup.py install
</code></pre>
<pre><code>python setup.py install</code></pre>
<p>Then, launching the server can be easily done by typing as a normal user:</p>
<pre><code>radicale
</code></pre>
<pre><code>radicale</code></pre>
</section>
<section class="level5" id="documentation/user-documentation/complex-configuration/configuring-the-server">
<h5>Configuring the Server <a class="headerlink" href="#documentation/user-documentation/complex-configuration/configuring-the-server">&para;</a></h5>
@ -728,248 +859,246 @@ After installing and accepting it you should restart your browser.</p>
<p>This section is following the latest stable version changes. Please look at the default configuration file included in your package if you have an older version of Radicale.</p>
</blockquote>
<p>The server configuration can be modified in <code>/etc/radicale/config</code> or in <code>~/.config/radicale/config</code>. You can use the <code>--config</code> parameter in the command line to choose a specific path. You can also set the <code>RADICALE_CONFIG</code> environment variable to a path of your choice. Here is the default configuration file, with the main parameters:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb7-1"><a href="#cb7-1"></a><span class="kw">[server]</span></span>
<span id="cb7-2"><a href="#cb7-2"></a></span>
<span id="cb7-3"><a href="#cb7-3"></a><span class="co"># CalDAV server hostnames separated by a comma</span></span>
<span id="cb7-4"><a href="#cb7-4"></a><span class="co"># IPv4 syntax: address:port</span></span>
<span id="cb7-5"><a href="#cb7-5"></a><span class="co"># IPv6 syntax: [address]:port</span></span>
<span id="cb7-6"><a href="#cb7-6"></a><span class="co"># For example: 0.0.0.0:9999, [::]:9999</span></span>
<span id="cb7-7"><a href="#cb7-7"></a><span class="co"># IPv6 adresses are configured to only allow IPv6 connections</span></span>
<span id="cb7-8"><a href="#cb7-8"></a><span class="co">#hosts = 0.0.0.0:5232</span></span>
<span id="cb7-9"><a href="#cb7-9"></a></span>
<span id="cb7-10"><a href="#cb7-10"></a><span class="co"># Daemon flag</span></span>
<span id="cb7-11"><a href="#cb7-11"></a><span class="co">#daemon = False</span></span>
<span id="cb7-12"><a href="#cb7-12"></a></span>
<span id="cb7-13"><a href="#cb7-13"></a><span class="co"># File storing the PID in daemon mode</span></span>
<span id="cb7-14"><a href="#cb7-14"></a><span class="co">#pid =</span></span>
<span id="cb7-15"><a href="#cb7-15"></a></span>
<span id="cb7-16"><a href="#cb7-16"></a><span class="co"># SSL flag, enable HTTPS protocol</span></span>
<span id="cb7-17"><a href="#cb7-17"></a><span class="co">#ssl = False</span></span>
<span id="cb7-18"><a href="#cb7-18"></a></span>
<span id="cb7-19"><a href="#cb7-19"></a><span class="co"># SSL certificate path</span></span>
<span id="cb7-20"><a href="#cb7-20"></a><span class="co">#certificate = /etc/apache2/ssl/server.crt</span></span>
<span id="cb7-21"><a href="#cb7-21"></a></span>
<span id="cb7-22"><a href="#cb7-22"></a><span class="co"># SSL private key</span></span>
<span id="cb7-23"><a href="#cb7-23"></a><span class="co">#key = /etc/apache2/ssl/server.key</span></span>
<span id="cb7-24"><a href="#cb7-24"></a></span>
<span id="cb7-25"><a href="#cb7-25"></a><span class="co"># SSL Protocol used. See python's ssl module for available values</span></span>
<span id="cb7-26"><a href="#cb7-26"></a><span class="co">#protocol = PROTOCOL_SSLv23</span></span>
<span id="cb7-27"><a href="#cb7-27"></a></span>
<span id="cb7-28"><a href="#cb7-28"></a><span class="co"># Ciphers available. See python's ssl module for available ciphers</span></span>
<span id="cb7-29"><a href="#cb7-29"></a><span class="co">#ciphers =</span></span>
<span id="cb7-30"><a href="#cb7-30"></a></span>
<span id="cb7-31"><a href="#cb7-31"></a><span class="co"># Reverse DNS to resolve client address in logs</span></span>
<span id="cb7-32"><a href="#cb7-32"></a><span class="co">#dns_lookup = True</span></span>
<span id="cb7-33"><a href="#cb7-33"></a></span>
<span id="cb7-34"><a href="#cb7-34"></a><span class="co"># Root URL of Radicale (starting and ending with a slash)</span></span>
<span id="cb7-35"><a href="#cb7-35"></a><span class="co">#base_prefix = /</span></span>
<span id="cb7-36"><a href="#cb7-36"></a></span>
<span id="cb7-37"><a href="#cb7-37"></a><span class="co"># Possibility to allow URLs cleaned by a HTTP server, without the base_prefix</span></span>
<span id="cb7-38"><a href="#cb7-38"></a><span class="co">#can_skip_base_prefix = False</span></span>
<span id="cb7-39"><a href="#cb7-39"></a></span>
<span id="cb7-40"><a href="#cb7-40"></a><span class="co"># Message displayed in the client when a password is needed</span></span>
<span id="cb7-41"><a href="#cb7-41"></a><span class="co">#realm = Radicale - Password Required</span></span>
<span id="cb7-42"><a href="#cb7-42"></a></span>
<span id="cb7-43"><a href="#cb7-43"></a></span>
<span id="cb7-44"><a href="#cb7-44"></a><span class="kw">[encoding]</span></span>
<span id="cb7-45"><a href="#cb7-45"></a></span>
<span id="cb7-46"><a href="#cb7-46"></a><span class="co"># Encoding for responding requests</span></span>
<span id="cb7-47"><a href="#cb7-47"></a><span class="co">#request = utf-8</span></span>
<span id="cb7-48"><a href="#cb7-48"></a></span>
<span id="cb7-49"><a href="#cb7-49"></a><span class="co"># Encoding for storing local collections</span></span>
<span id="cb7-50"><a href="#cb7-50"></a><span class="co">#stock = utf-8</span></span>
<span id="cb7-51"><a href="#cb7-51"></a></span>
<span id="cb7-52"><a href="#cb7-52"></a></span>
<span id="cb7-53"><a href="#cb7-53"></a><span class="kw">[well-known]</span></span>
<span id="cb7-54"><a href="#cb7-54"></a></span>
<span id="cb7-55"><a href="#cb7-55"></a><span class="co"># Path where /.well-known/caldav/ is redirected</span></span>
<span id="cb7-56"><a href="#cb7-56"></a><span class="co">#caldav = '/%(user)s/caldav/'</span></span>
<span id="cb7-57"><a href="#cb7-57"></a></span>
<span id="cb7-58"><a href="#cb7-58"></a><span class="co"># Path where /.well-known/carddav/ is redirected</span></span>
<span id="cb7-59"><a href="#cb7-59"></a><span class="co">#carddav = '/%(user)s/carddav/'</span></span>
<span id="cb7-60"><a href="#cb7-60"></a></span>
<span id="cb7-61"><a href="#cb7-61"></a></span>
<span id="cb7-62"><a href="#cb7-62"></a><span class="kw">[auth]</span></span>
<span id="cb7-63"><a href="#cb7-63"></a></span>
<span id="cb7-64"><a href="#cb7-64"></a><span class="co"># Authentication method</span></span>
<span id="cb7-65"><a href="#cb7-65"></a><span class="co"># Value: None | htpasswd | IMAP | LDAP | PAM | courier | http | remote_user | custom</span></span>
<span id="cb7-66"><a href="#cb7-66"></a><span class="co">#type = None</span></span>
<span id="cb7-67"><a href="#cb7-67"></a></span>
<span id="cb7-68"><a href="#cb7-68"></a><span class="co"># Custom authentication handler</span></span>
<span id="cb7-69"><a href="#cb7-69"></a><span class="co">#custom_handler =</span></span>
<span id="cb7-70"><a href="#cb7-70"></a></span>
<span id="cb7-71"><a href="#cb7-71"></a><span class="co"># Htpasswd filename</span></span>
<span id="cb7-72"><a href="#cb7-72"></a><span class="co">#htpasswd_filename = /etc/radicale/users</span></span>
<span id="cb7-73"><a href="#cb7-73"></a></span>
<span id="cb7-74"><a href="#cb7-74"></a><span class="co"># Htpasswd encryption method</span></span>
<span id="cb7-75"><a href="#cb7-75"></a><span class="co"># Value: plain | sha1 | ssha | crypt | bcrypt | md5</span></span>
<span id="cb7-76"><a href="#cb7-76"></a><span class="co">#htpasswd_encryption = crypt</span></span>
<span id="cb7-77"><a href="#cb7-77"></a></span>
<span id="cb7-78"><a href="#cb7-78"></a><span class="co"># LDAP server URL, with protocol and port</span></span>
<span id="cb7-79"><a href="#cb7-79"></a><span class="co">#ldap_url = ldap://localhost:389/</span></span>
<span id="cb7-80"><a href="#cb7-80"></a></span>
<span id="cb7-81"><a href="#cb7-81"></a><span class="co"># LDAP base path</span></span>
<span id="cb7-82"><a href="#cb7-82"></a><span class="co">#ldap_base = ou=users,dc=example,dc=com</span></span>
<span id="cb7-83"><a href="#cb7-83"></a></span>
<span id="cb7-84"><a href="#cb7-84"></a><span class="co"># LDAP login attribute</span></span>
<span id="cb7-85"><a href="#cb7-85"></a><span class="co">#ldap_attribute = uid</span></span>
<span id="cb7-86"><a href="#cb7-86"></a></span>
<span id="cb7-87"><a href="#cb7-87"></a><span class="co"># LDAP filter string</span></span>
<span id="cb7-88"><a href="#cb7-88"></a><span class="co"># placed as X in a query of the form (&amp;(...)X)</span></span>
<span id="cb7-89"><a href="#cb7-89"></a><span class="co"># example: (objectCategory=Person)(objectClass=User)(memberOf=cn=calenderusers,ou=users,dc=example,dc=org)</span></span>
<span id="cb7-90"><a href="#cb7-90"></a><span class="co"># leave empty if no additional filter is needed</span></span>
<span id="cb7-91"><a href="#cb7-91"></a><span class="co">#ldap_filter =</span></span>
<span id="cb7-92"><a href="#cb7-92"></a></span>
<span id="cb7-93"><a href="#cb7-93"></a><span class="co"># LDAP dn for initial login, used if LDAP server does not allow anonymous searches</span></span>
<span id="cb7-94"><a href="#cb7-94"></a><span class="co"># Leave empty if searches are anonymous</span></span>
<span id="cb7-95"><a href="#cb7-95"></a><span class="co">#ldap_binddn =</span></span>
<span id="cb7-96"><a href="#cb7-96"></a></span>
<span id="cb7-97"><a href="#cb7-97"></a><span class="co"># LDAP password for initial login, used with ldap_binddn</span></span>
<span id="cb7-98"><a href="#cb7-98"></a><span class="co">#ldap_password =</span></span>
<span id="cb7-99"><a href="#cb7-99"></a></span>
<span id="cb7-100"><a href="#cb7-100"></a><span class="co"># LDAP scope of the search</span></span>
<span id="cb7-101"><a href="#cb7-101"></a><span class="co">#ldap_scope = OneLevel</span></span>
<span id="cb7-102"><a href="#cb7-102"></a></span>
<span id="cb7-103"><a href="#cb7-103"></a><span class="co"># IMAP Configuration</span></span>
<span id="cb7-104"><a href="#cb7-104"></a><span class="co">#imap_hostname = localhost</span></span>
<span id="cb7-105"><a href="#cb7-105"></a><span class="co">#imap_port = 143</span></span>
<span id="cb7-106"><a href="#cb7-106"></a><span class="co">#imap_ssl = False</span></span>
<span id="cb7-107"><a href="#cb7-107"></a></span>
<span id="cb7-108"><a href="#cb7-108"></a><span class="co"># PAM group user should be member of</span></span>
<span id="cb7-109"><a href="#cb7-109"></a><span class="co">#pam_group_membership =</span></span>
<span id="cb7-110"><a href="#cb7-110"></a></span>
<span id="cb7-111"><a href="#cb7-111"></a><span class="co"># Path to the Courier Authdaemon socket</span></span>
<span id="cb7-112"><a href="#cb7-112"></a><span class="co">#courier_socket =</span></span>
<span id="cb7-113"><a href="#cb7-113"></a></span>
<span id="cb7-114"><a href="#cb7-114"></a><span class="co"># HTTP authentication request URL endpoint</span></span>
<span id="cb7-115"><a href="#cb7-115"></a><span class="co">#http_url =</span></span>
<span id="cb7-116"><a href="#cb7-116"></a><span class="co"># POST parameter to use for username</span></span>
<span id="cb7-117"><a href="#cb7-117"></a><span class="co">#http_user_parameter =</span></span>
<span id="cb7-118"><a href="#cb7-118"></a><span class="co"># POST parameter to use for password</span></span>
<span id="cb7-119"><a href="#cb7-119"></a><span class="co">#http_password_parameter =</span></span>
<span id="cb7-120"><a href="#cb7-120"></a></span>
<span id="cb7-121"><a href="#cb7-121"></a></span>
<span id="cb7-122"><a href="#cb7-122"></a><span class="kw">[git]</span></span>
<span id="cb7-123"><a href="#cb7-123"></a></span>
<span id="cb7-124"><a href="#cb7-124"></a><span class="co"># Git default options</span></span>
<span id="cb7-125"><a href="#cb7-125"></a><span class="co">#committer = Radicale &lt;radicale@example.com&gt;</span></span>
<span id="cb7-126"><a href="#cb7-126"></a></span>
<span id="cb7-127"><a href="#cb7-127"></a></span>
<span id="cb7-128"><a href="#cb7-128"></a><span class="kw">[rights]</span></span>
<span id="cb7-129"><a href="#cb7-129"></a></span>
<span id="cb7-130"><a href="#cb7-130"></a><span class="co"># Rights backend</span></span>
<span id="cb7-131"><a href="#cb7-131"></a><span class="co"># Value: None | authenticated | owner_only | owner_write | from_file | custom</span></span>
<span id="cb7-132"><a href="#cb7-132"></a><span class="co">#type = None</span></span>
<span id="cb7-133"><a href="#cb7-133"></a></span>
<span id="cb7-134"><a href="#cb7-134"></a><span class="co"># Custom rights handler</span></span>
<span id="cb7-135"><a href="#cb7-135"></a><span class="co">#custom_handler =</span></span>
<span id="cb7-136"><a href="#cb7-136"></a></span>
<span id="cb7-137"><a href="#cb7-137"></a><span class="co"># File for rights management from_file</span></span>
<span id="cb7-138"><a href="#cb7-138"></a><span class="co">#file = ~/.config/radicale/rights</span></span>
<span id="cb7-139"><a href="#cb7-139"></a></span>
<span id="cb7-140"><a href="#cb7-140"></a></span>
<span id="cb7-141"><a href="#cb7-141"></a><span class="kw">[storage]</span></span>
<span id="cb7-142"><a href="#cb7-142"></a></span>
<span id="cb7-143"><a href="#cb7-143"></a><span class="co"># Storage backend</span></span>
<span id="cb7-144"><a href="#cb7-144"></a><span class="co"># -------</span></span>
<span id="cb7-145"><a href="#cb7-145"></a><span class="co"># </span><span class="al">WARNING</span><span class="co">: ONLY "filesystem" IS DOCUMENTED AND TESTED,</span></span>
<span id="cb7-146"><a href="#cb7-146"></a><span class="co"># OTHER BACKENDS ARE NOT READY FOR PRODUCTION.</span></span>
<span id="cb7-147"><a href="#cb7-147"></a><span class="co"># -------</span></span>
<span id="cb7-148"><a href="#cb7-148"></a><span class="co"># Value: filesystem | multifilesystem | database | custom</span></span>
<span id="cb7-149"><a href="#cb7-149"></a><span class="co">#type = filesystem</span></span>
<span id="cb7-150"><a href="#cb7-150"></a></span>
<span id="cb7-151"><a href="#cb7-151"></a><span class="co"># Custom storage handler</span></span>
<span id="cb7-152"><a href="#cb7-152"></a><span class="co">#custom_handler =</span></span>
<span id="cb7-153"><a href="#cb7-153"></a></span>
<span id="cb7-154"><a href="#cb7-154"></a><span class="co"># Folder for storing local collections, created if not present</span></span>
<span id="cb7-155"><a href="#cb7-155"></a><span class="co">#filesystem_folder = ~/.config/radicale/collections</span></span>
<span id="cb7-156"><a href="#cb7-156"></a></span>
<span id="cb7-157"><a href="#cb7-157"></a><span class="co"># Database URL for SQLAlchemy</span></span>
<span id="cb7-158"><a href="#cb7-158"></a><span class="co"># dialect+driver://user:password@host/dbname[?key=value..]</span></span>
<span id="cb7-159"><a href="#cb7-159"></a><span class="co"># For example: sqlite:///var/db/radicale.db, postgresql://user:password@localhost/radicale</span></span>
<span id="cb7-160"><a href="#cb7-160"></a><span class="co"># See http://docs.sqlalchemy.org/en/rel_0_8/core/engines.html#sqlalchemy.create_engine</span></span>
<span id="cb7-161"><a href="#cb7-161"></a><span class="co">#database_url =</span></span>
<span id="cb7-162"><a href="#cb7-162"></a></span>
<span id="cb7-163"><a href="#cb7-163"></a></span>
<span id="cb7-164"><a href="#cb7-164"></a><span class="kw">[logging]</span></span>
<span id="cb7-165"><a href="#cb7-165"></a></span>
<span id="cb7-166"><a href="#cb7-166"></a><span class="co"># Logging configuration file</span></span>
<span id="cb7-167"><a href="#cb7-167"></a><span class="co"># If no config is given, simple information is printed on the standard output</span></span>
<span id="cb7-168"><a href="#cb7-168"></a><span class="co"># For more information about the syntax of the configuration file, see:</span></span>
<span id="cb7-169"><a href="#cb7-169"></a><span class="co"># http://docs.python.org/library/logging.config.html</span></span>
<span id="cb7-170"><a href="#cb7-170"></a><span class="co">#config = /etc/radicale/logging</span></span>
<span id="cb7-171"><a href="#cb7-171"></a><span class="co"># Set the default logging level to debug</span></span>
<span id="cb7-172"><a href="#cb7-172"></a><span class="co">#debug = False</span></span>
<span id="cb7-173"><a href="#cb7-173"></a><span class="co"># Store all environment variables (including those set in the shell)</span></span>
<span id="cb7-174"><a href="#cb7-174"></a><span class="co">#full_environment = False</span></span>
<span id="cb7-175"><a href="#cb7-175"></a></span>
<span id="cb7-176"><a href="#cb7-176"></a></span>
<span id="cb7-177"><a href="#cb7-177"></a><span class="kw">[headers]</span></span>
<span id="cb7-178"><a href="#cb7-178"></a></span>
<span id="cb7-179"><a href="#cb7-179"></a><span class="co"># Additional HTTP headers</span></span>
<span id="cb7-180"><a href="#cb7-180"></a><span class="co">#Access-Control-Allow-Origin = *</span></span></code></pre></div>
<div class="sourceCode" id="cb7"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb7-1"><a aria-hidden="true" href="#cb7-1" tabindex="-1"></a><span class="kw">[server]</span></span>
<span id="cb7-2"><a aria-hidden="true" href="#cb7-2" tabindex="-1"></a></span>
<span id="cb7-3"><a aria-hidden="true" href="#cb7-3" tabindex="-1"></a><span class="co"># CalDAV server hostnames separated by a comma</span></span>
<span id="cb7-4"><a aria-hidden="true" href="#cb7-4" tabindex="-1"></a><span class="co"># IPv4 syntax: address:port</span></span>
<span id="cb7-5"><a aria-hidden="true" href="#cb7-5" tabindex="-1"></a><span class="co"># IPv6 syntax: [address]:port</span></span>
<span id="cb7-6"><a aria-hidden="true" href="#cb7-6" tabindex="-1"></a><span class="co"># For example: 0.0.0.0:9999, [::]:9999</span></span>
<span id="cb7-7"><a aria-hidden="true" href="#cb7-7" tabindex="-1"></a><span class="co"># IPv6 adresses are configured to only allow IPv6 connections</span></span>
<span id="cb7-8"><a aria-hidden="true" href="#cb7-8" tabindex="-1"></a><span class="co">#hosts = 0.0.0.0:5232</span></span>
<span id="cb7-9"><a aria-hidden="true" href="#cb7-9" tabindex="-1"></a></span>
<span id="cb7-10"><a aria-hidden="true" href="#cb7-10" tabindex="-1"></a><span class="co"># Daemon flag</span></span>
<span id="cb7-11"><a aria-hidden="true" href="#cb7-11" tabindex="-1"></a><span class="co">#daemon = False</span></span>
<span id="cb7-12"><a aria-hidden="true" href="#cb7-12" tabindex="-1"></a></span>
<span id="cb7-13"><a aria-hidden="true" href="#cb7-13" tabindex="-1"></a><span class="co"># File storing the PID in daemon mode</span></span>
<span id="cb7-14"><a aria-hidden="true" href="#cb7-14" tabindex="-1"></a><span class="co">#pid =</span></span>
<span id="cb7-15"><a aria-hidden="true" href="#cb7-15" tabindex="-1"></a></span>
<span id="cb7-16"><a aria-hidden="true" href="#cb7-16" tabindex="-1"></a><span class="co"># SSL flag, enable HTTPS protocol</span></span>
<span id="cb7-17"><a aria-hidden="true" href="#cb7-17" tabindex="-1"></a><span class="co">#ssl = False</span></span>
<span id="cb7-18"><a aria-hidden="true" href="#cb7-18" tabindex="-1"></a></span>
<span id="cb7-19"><a aria-hidden="true" href="#cb7-19" tabindex="-1"></a><span class="co"># SSL certificate path</span></span>
<span id="cb7-20"><a aria-hidden="true" href="#cb7-20" tabindex="-1"></a><span class="co">#certificate = /etc/apache2/ssl/server.crt</span></span>
<span id="cb7-21"><a aria-hidden="true" href="#cb7-21" tabindex="-1"></a></span>
<span id="cb7-22"><a aria-hidden="true" href="#cb7-22" tabindex="-1"></a><span class="co"># SSL private key</span></span>
<span id="cb7-23"><a aria-hidden="true" href="#cb7-23" tabindex="-1"></a><span class="co">#key = /etc/apache2/ssl/server.key</span></span>
<span id="cb7-24"><a aria-hidden="true" href="#cb7-24" tabindex="-1"></a></span>
<span id="cb7-25"><a aria-hidden="true" href="#cb7-25" tabindex="-1"></a><span class="co"># SSL Protocol used. See python's ssl module for available values</span></span>
<span id="cb7-26"><a aria-hidden="true" href="#cb7-26" tabindex="-1"></a><span class="co">#protocol = PROTOCOL_SSLv23</span></span>
<span id="cb7-27"><a aria-hidden="true" href="#cb7-27" tabindex="-1"></a></span>
<span id="cb7-28"><a aria-hidden="true" href="#cb7-28" tabindex="-1"></a><span class="co"># Ciphers available. See python's ssl module for available ciphers</span></span>
<span id="cb7-29"><a aria-hidden="true" href="#cb7-29" tabindex="-1"></a><span class="co">#ciphers =</span></span>
<span id="cb7-30"><a aria-hidden="true" href="#cb7-30" tabindex="-1"></a></span>
<span id="cb7-31"><a aria-hidden="true" href="#cb7-31" tabindex="-1"></a><span class="co"># Reverse DNS to resolve client address in logs</span></span>
<span id="cb7-32"><a aria-hidden="true" href="#cb7-32" tabindex="-1"></a><span class="co">#dns_lookup = True</span></span>
<span id="cb7-33"><a aria-hidden="true" href="#cb7-33" tabindex="-1"></a></span>
<span id="cb7-34"><a aria-hidden="true" href="#cb7-34" tabindex="-1"></a><span class="co"># Root URL of Radicale (starting and ending with a slash)</span></span>
<span id="cb7-35"><a aria-hidden="true" href="#cb7-35" tabindex="-1"></a><span class="co">#base_prefix = /</span></span>
<span id="cb7-36"><a aria-hidden="true" href="#cb7-36" tabindex="-1"></a></span>
<span id="cb7-37"><a aria-hidden="true" href="#cb7-37" tabindex="-1"></a><span class="co"># Possibility to allow URLs cleaned by a HTTP server, without the base_prefix</span></span>
<span id="cb7-38"><a aria-hidden="true" href="#cb7-38" tabindex="-1"></a><span class="co">#can_skip_base_prefix = False</span></span>
<span id="cb7-39"><a aria-hidden="true" href="#cb7-39" tabindex="-1"></a></span>
<span id="cb7-40"><a aria-hidden="true" href="#cb7-40" tabindex="-1"></a><span class="co"># Message displayed in the client when a password is needed</span></span>
<span id="cb7-41"><a aria-hidden="true" href="#cb7-41" tabindex="-1"></a><span class="co">#realm = Radicale - Password Required</span></span>
<span id="cb7-42"><a aria-hidden="true" href="#cb7-42" tabindex="-1"></a></span>
<span id="cb7-43"><a aria-hidden="true" href="#cb7-43" tabindex="-1"></a></span>
<span id="cb7-44"><a aria-hidden="true" href="#cb7-44" tabindex="-1"></a><span class="kw">[encoding]</span></span>
<span id="cb7-45"><a aria-hidden="true" href="#cb7-45" tabindex="-1"></a></span>
<span id="cb7-46"><a aria-hidden="true" href="#cb7-46" tabindex="-1"></a><span class="co"># Encoding for responding requests</span></span>
<span id="cb7-47"><a aria-hidden="true" href="#cb7-47" tabindex="-1"></a><span class="co">#request = utf-8</span></span>
<span id="cb7-48"><a aria-hidden="true" href="#cb7-48" tabindex="-1"></a></span>
<span id="cb7-49"><a aria-hidden="true" href="#cb7-49" tabindex="-1"></a><span class="co"># Encoding for storing local collections</span></span>
<span id="cb7-50"><a aria-hidden="true" href="#cb7-50" tabindex="-1"></a><span class="co">#stock = utf-8</span></span>
<span id="cb7-51"><a aria-hidden="true" href="#cb7-51" tabindex="-1"></a></span>
<span id="cb7-52"><a aria-hidden="true" href="#cb7-52" tabindex="-1"></a></span>
<span id="cb7-53"><a aria-hidden="true" href="#cb7-53" tabindex="-1"></a><span class="kw">[well-known]</span></span>
<span id="cb7-54"><a aria-hidden="true" href="#cb7-54" tabindex="-1"></a></span>
<span id="cb7-55"><a aria-hidden="true" href="#cb7-55" tabindex="-1"></a><span class="co"># Path where /.well-known/caldav/ is redirected</span></span>
<span id="cb7-56"><a aria-hidden="true" href="#cb7-56" tabindex="-1"></a><span class="co">#caldav = '/%(user)s/caldav/'</span></span>
<span id="cb7-57"><a aria-hidden="true" href="#cb7-57" tabindex="-1"></a></span>
<span id="cb7-58"><a aria-hidden="true" href="#cb7-58" tabindex="-1"></a><span class="co"># Path where /.well-known/carddav/ is redirected</span></span>
<span id="cb7-59"><a aria-hidden="true" href="#cb7-59" tabindex="-1"></a><span class="co">#carddav = '/%(user)s/carddav/'</span></span>
<span id="cb7-60"><a aria-hidden="true" href="#cb7-60" tabindex="-1"></a></span>
<span id="cb7-61"><a aria-hidden="true" href="#cb7-61" tabindex="-1"></a></span>
<span id="cb7-62"><a aria-hidden="true" href="#cb7-62" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb7-63"><a aria-hidden="true" href="#cb7-63" tabindex="-1"></a></span>
<span id="cb7-64"><a aria-hidden="true" href="#cb7-64" tabindex="-1"></a><span class="co"># Authentication method</span></span>
<span id="cb7-65"><a aria-hidden="true" href="#cb7-65" tabindex="-1"></a><span class="co"># Value: None | htpasswd | IMAP | LDAP | PAM | courier | http | remote_user | custom</span></span>
<span id="cb7-66"><a aria-hidden="true" href="#cb7-66" tabindex="-1"></a><span class="co">#type = None</span></span>
<span id="cb7-67"><a aria-hidden="true" href="#cb7-67" tabindex="-1"></a></span>
<span id="cb7-68"><a aria-hidden="true" href="#cb7-68" tabindex="-1"></a><span class="co"># Custom authentication handler</span></span>
<span id="cb7-69"><a aria-hidden="true" href="#cb7-69" tabindex="-1"></a><span class="co">#custom_handler =</span></span>
<span id="cb7-70"><a aria-hidden="true" href="#cb7-70" tabindex="-1"></a></span>
<span id="cb7-71"><a aria-hidden="true" href="#cb7-71" tabindex="-1"></a><span class="co"># Htpasswd filename</span></span>
<span id="cb7-72"><a aria-hidden="true" href="#cb7-72" tabindex="-1"></a><span class="co">#htpasswd_filename = /etc/radicale/users</span></span>
<span id="cb7-73"><a aria-hidden="true" href="#cb7-73" tabindex="-1"></a></span>
<span id="cb7-74"><a aria-hidden="true" href="#cb7-74" tabindex="-1"></a><span class="co"># Htpasswd encryption method</span></span>
<span id="cb7-75"><a aria-hidden="true" href="#cb7-75" tabindex="-1"></a><span class="co"># Value: plain | sha1 | ssha | crypt | bcrypt | md5</span></span>
<span id="cb7-76"><a aria-hidden="true" href="#cb7-76" tabindex="-1"></a><span class="co">#htpasswd_encryption = crypt</span></span>
<span id="cb7-77"><a aria-hidden="true" href="#cb7-77" tabindex="-1"></a></span>
<span id="cb7-78"><a aria-hidden="true" href="#cb7-78" tabindex="-1"></a><span class="co"># LDAP server URL, with protocol and port</span></span>
<span id="cb7-79"><a aria-hidden="true" href="#cb7-79" tabindex="-1"></a><span class="co">#ldap_url = ldap://localhost:389/</span></span>
<span id="cb7-80"><a aria-hidden="true" href="#cb7-80" tabindex="-1"></a></span>
<span id="cb7-81"><a aria-hidden="true" href="#cb7-81" tabindex="-1"></a><span class="co"># LDAP base path</span></span>
<span id="cb7-82"><a aria-hidden="true" href="#cb7-82" tabindex="-1"></a><span class="co">#ldap_base = ou=users,dc=example,dc=com</span></span>
<span id="cb7-83"><a aria-hidden="true" href="#cb7-83" tabindex="-1"></a></span>
<span id="cb7-84"><a aria-hidden="true" href="#cb7-84" tabindex="-1"></a><span class="co"># LDAP login attribute</span></span>
<span id="cb7-85"><a aria-hidden="true" href="#cb7-85" tabindex="-1"></a><span class="co">#ldap_attribute = uid</span></span>
<span id="cb7-86"><a aria-hidden="true" href="#cb7-86" tabindex="-1"></a></span>
<span id="cb7-87"><a aria-hidden="true" href="#cb7-87" tabindex="-1"></a><span class="co"># LDAP filter string</span></span>
<span id="cb7-88"><a aria-hidden="true" href="#cb7-88" tabindex="-1"></a><span class="co"># placed as X in a query of the form (&amp;(...)X)</span></span>
<span id="cb7-89"><a aria-hidden="true" href="#cb7-89" tabindex="-1"></a><span class="co"># example: (objectCategory=Person)(objectClass=User)(memberOf=cn=calenderusers,ou=users,dc=example,dc=org)</span></span>
<span id="cb7-90"><a aria-hidden="true" href="#cb7-90" tabindex="-1"></a><span class="co"># leave empty if no additional filter is needed</span></span>
<span id="cb7-91"><a aria-hidden="true" href="#cb7-91" tabindex="-1"></a><span class="co">#ldap_filter =</span></span>
<span id="cb7-92"><a aria-hidden="true" href="#cb7-92" tabindex="-1"></a></span>
<span id="cb7-93"><a aria-hidden="true" href="#cb7-93" tabindex="-1"></a><span class="co"># LDAP dn for initial login, used if LDAP server does not allow anonymous searches</span></span>
<span id="cb7-94"><a aria-hidden="true" href="#cb7-94" tabindex="-1"></a><span class="co"># Leave empty if searches are anonymous</span></span>
<span id="cb7-95"><a aria-hidden="true" href="#cb7-95" tabindex="-1"></a><span class="co">#ldap_binddn =</span></span>
<span id="cb7-96"><a aria-hidden="true" href="#cb7-96" tabindex="-1"></a></span>
<span id="cb7-97"><a aria-hidden="true" href="#cb7-97" tabindex="-1"></a><span class="co"># LDAP password for initial login, used with ldap_binddn</span></span>
<span id="cb7-98"><a aria-hidden="true" href="#cb7-98" tabindex="-1"></a><span class="co">#ldap_password =</span></span>
<span id="cb7-99"><a aria-hidden="true" href="#cb7-99" tabindex="-1"></a></span>
<span id="cb7-100"><a aria-hidden="true" href="#cb7-100" tabindex="-1"></a><span class="co"># LDAP scope of the search</span></span>
<span id="cb7-101"><a aria-hidden="true" href="#cb7-101" tabindex="-1"></a><span class="co">#ldap_scope = OneLevel</span></span>
<span id="cb7-102"><a aria-hidden="true" href="#cb7-102" tabindex="-1"></a></span>
<span id="cb7-103"><a aria-hidden="true" href="#cb7-103" tabindex="-1"></a><span class="co"># IMAP Configuration</span></span>
<span id="cb7-104"><a aria-hidden="true" href="#cb7-104" tabindex="-1"></a><span class="co">#imap_hostname = localhost</span></span>
<span id="cb7-105"><a aria-hidden="true" href="#cb7-105" tabindex="-1"></a><span class="co">#imap_port = 143</span></span>
<span id="cb7-106"><a aria-hidden="true" href="#cb7-106" tabindex="-1"></a><span class="co">#imap_ssl = False</span></span>
<span id="cb7-107"><a aria-hidden="true" href="#cb7-107" tabindex="-1"></a></span>
<span id="cb7-108"><a aria-hidden="true" href="#cb7-108" tabindex="-1"></a><span class="co"># PAM group user should be member of</span></span>
<span id="cb7-109"><a aria-hidden="true" href="#cb7-109" tabindex="-1"></a><span class="co">#pam_group_membership =</span></span>
<span id="cb7-110"><a aria-hidden="true" href="#cb7-110" tabindex="-1"></a></span>
<span id="cb7-111"><a aria-hidden="true" href="#cb7-111" tabindex="-1"></a><span class="co"># Path to the Courier Authdaemon socket</span></span>
<span id="cb7-112"><a aria-hidden="true" href="#cb7-112" tabindex="-1"></a><span class="co">#courier_socket =</span></span>
<span id="cb7-113"><a aria-hidden="true" href="#cb7-113" tabindex="-1"></a></span>
<span id="cb7-114"><a aria-hidden="true" href="#cb7-114" tabindex="-1"></a><span class="co"># HTTP authentication request URL endpoint</span></span>
<span id="cb7-115"><a aria-hidden="true" href="#cb7-115" tabindex="-1"></a><span class="co">#http_url =</span></span>
<span id="cb7-116"><a aria-hidden="true" href="#cb7-116" tabindex="-1"></a><span class="co"># POST parameter to use for username</span></span>
<span id="cb7-117"><a aria-hidden="true" href="#cb7-117" tabindex="-1"></a><span class="co">#http_user_parameter =</span></span>
<span id="cb7-118"><a aria-hidden="true" href="#cb7-118" tabindex="-1"></a><span class="co"># POST parameter to use for password</span></span>
<span id="cb7-119"><a aria-hidden="true" href="#cb7-119" tabindex="-1"></a><span class="co">#http_password_parameter =</span></span>
<span id="cb7-120"><a aria-hidden="true" href="#cb7-120" tabindex="-1"></a></span>
<span id="cb7-121"><a aria-hidden="true" href="#cb7-121" tabindex="-1"></a></span>
<span id="cb7-122"><a aria-hidden="true" href="#cb7-122" tabindex="-1"></a><span class="kw">[git]</span></span>
<span id="cb7-123"><a aria-hidden="true" href="#cb7-123" tabindex="-1"></a></span>
<span id="cb7-124"><a aria-hidden="true" href="#cb7-124" tabindex="-1"></a><span class="co"># Git default options</span></span>
<span id="cb7-125"><a aria-hidden="true" href="#cb7-125" tabindex="-1"></a><span class="co">#committer = Radicale &lt;radicale@example.com&gt;</span></span>
<span id="cb7-126"><a aria-hidden="true" href="#cb7-126" tabindex="-1"></a></span>
<span id="cb7-127"><a aria-hidden="true" href="#cb7-127" tabindex="-1"></a></span>
<span id="cb7-128"><a aria-hidden="true" href="#cb7-128" tabindex="-1"></a><span class="kw">[rights]</span></span>
<span id="cb7-129"><a aria-hidden="true" href="#cb7-129" tabindex="-1"></a></span>
<span id="cb7-130"><a aria-hidden="true" href="#cb7-130" tabindex="-1"></a><span class="co"># Rights backend</span></span>
<span id="cb7-131"><a aria-hidden="true" href="#cb7-131" tabindex="-1"></a><span class="co"># Value: None | authenticated | owner_only | owner_write | from_file | custom</span></span>
<span id="cb7-132"><a aria-hidden="true" href="#cb7-132" tabindex="-1"></a><span class="co">#type = None</span></span>
<span id="cb7-133"><a aria-hidden="true" href="#cb7-133" tabindex="-1"></a></span>
<span id="cb7-134"><a aria-hidden="true" href="#cb7-134" tabindex="-1"></a><span class="co"># Custom rights handler</span></span>
<span id="cb7-135"><a aria-hidden="true" href="#cb7-135" tabindex="-1"></a><span class="co">#custom_handler =</span></span>
<span id="cb7-136"><a aria-hidden="true" href="#cb7-136" tabindex="-1"></a></span>
<span id="cb7-137"><a aria-hidden="true" href="#cb7-137" tabindex="-1"></a><span class="co"># File for rights management from_file</span></span>
<span id="cb7-138"><a aria-hidden="true" href="#cb7-138" tabindex="-1"></a><span class="co">#file = ~/.config/radicale/rights</span></span>
<span id="cb7-139"><a aria-hidden="true" href="#cb7-139" tabindex="-1"></a></span>
<span id="cb7-140"><a aria-hidden="true" href="#cb7-140" tabindex="-1"></a></span>
<span id="cb7-141"><a aria-hidden="true" href="#cb7-141" tabindex="-1"></a><span class="kw">[storage]</span></span>
<span id="cb7-142"><a aria-hidden="true" href="#cb7-142" tabindex="-1"></a></span>
<span id="cb7-143"><a aria-hidden="true" href="#cb7-143" tabindex="-1"></a><span class="co"># Storage backend</span></span>
<span id="cb7-144"><a aria-hidden="true" href="#cb7-144" tabindex="-1"></a><span class="co"># -------</span></span>
<span id="cb7-145"><a aria-hidden="true" href="#cb7-145" tabindex="-1"></a><span class="co"># </span><span class="al">WARNING</span><span class="co">: ONLY "filesystem" IS DOCUMENTED AND TESTED,</span></span>
<span id="cb7-146"><a aria-hidden="true" href="#cb7-146" tabindex="-1"></a><span class="co"># OTHER BACKENDS ARE NOT READY FOR PRODUCTION.</span></span>
<span id="cb7-147"><a aria-hidden="true" href="#cb7-147" tabindex="-1"></a><span class="co"># -------</span></span>
<span id="cb7-148"><a aria-hidden="true" href="#cb7-148" tabindex="-1"></a><span class="co"># Value: filesystem | multifilesystem | database | custom</span></span>
<span id="cb7-149"><a aria-hidden="true" href="#cb7-149" tabindex="-1"></a><span class="co">#type = filesystem</span></span>
<span id="cb7-150"><a aria-hidden="true" href="#cb7-150" tabindex="-1"></a></span>
<span id="cb7-151"><a aria-hidden="true" href="#cb7-151" tabindex="-1"></a><span class="co"># Custom storage handler</span></span>
<span id="cb7-152"><a aria-hidden="true" href="#cb7-152" tabindex="-1"></a><span class="co">#custom_handler =</span></span>
<span id="cb7-153"><a aria-hidden="true" href="#cb7-153" tabindex="-1"></a></span>
<span id="cb7-154"><a aria-hidden="true" href="#cb7-154" tabindex="-1"></a><span class="co"># Folder for storing local collections, created if not present</span></span>
<span id="cb7-155"><a aria-hidden="true" href="#cb7-155" tabindex="-1"></a><span class="co">#filesystem_folder = ~/.config/radicale/collections</span></span>
<span id="cb7-156"><a aria-hidden="true" href="#cb7-156" tabindex="-1"></a></span>
<span id="cb7-157"><a aria-hidden="true" href="#cb7-157" tabindex="-1"></a><span class="co"># Database URL for SQLAlchemy</span></span>
<span id="cb7-158"><a aria-hidden="true" href="#cb7-158" tabindex="-1"></a><span class="co"># dialect+driver://user:password@host/dbname[?key=value..]</span></span>
<span id="cb7-159"><a aria-hidden="true" href="#cb7-159" tabindex="-1"></a><span class="co"># For example: sqlite:///var/db/radicale.db, postgresql://user:password@localhost/radicale</span></span>
<span id="cb7-160"><a aria-hidden="true" href="#cb7-160" tabindex="-1"></a><span class="co"># See http://docs.sqlalchemy.org/en/rel_0_8/core/engines.html#sqlalchemy.create_engine</span></span>
<span id="cb7-161"><a aria-hidden="true" href="#cb7-161" tabindex="-1"></a><span class="co">#database_url =</span></span>
<span id="cb7-162"><a aria-hidden="true" href="#cb7-162" tabindex="-1"></a></span>
<span id="cb7-163"><a aria-hidden="true" href="#cb7-163" tabindex="-1"></a></span>
<span id="cb7-164"><a aria-hidden="true" href="#cb7-164" tabindex="-1"></a><span class="kw">[logging]</span></span>
<span id="cb7-165"><a aria-hidden="true" href="#cb7-165" tabindex="-1"></a></span>
<span id="cb7-166"><a aria-hidden="true" href="#cb7-166" tabindex="-1"></a><span class="co"># Logging configuration file</span></span>
<span id="cb7-167"><a aria-hidden="true" href="#cb7-167" tabindex="-1"></a><span class="co"># If no config is given, simple information is printed on the standard output</span></span>
<span id="cb7-168"><a aria-hidden="true" href="#cb7-168" tabindex="-1"></a><span class="co"># For more information about the syntax of the configuration file, see:</span></span>
<span id="cb7-169"><a aria-hidden="true" href="#cb7-169" tabindex="-1"></a><span class="co"># http://docs.python.org/library/logging.config.html</span></span>
<span id="cb7-170"><a aria-hidden="true" href="#cb7-170" tabindex="-1"></a><span class="co">#config = /etc/radicale/logging</span></span>
<span id="cb7-171"><a aria-hidden="true" href="#cb7-171" tabindex="-1"></a><span class="co"># Set the default logging level to debug</span></span>
<span id="cb7-172"><a aria-hidden="true" href="#cb7-172" tabindex="-1"></a><span class="co">#debug = False</span></span>
<span id="cb7-173"><a aria-hidden="true" href="#cb7-173" tabindex="-1"></a><span class="co"># Store all environment variables (including those set in the shell)</span></span>
<span id="cb7-174"><a aria-hidden="true" href="#cb7-174" tabindex="-1"></a><span class="co">#full_environment = False</span></span>
<span id="cb7-175"><a aria-hidden="true" href="#cb7-175" tabindex="-1"></a></span>
<span id="cb7-176"><a aria-hidden="true" href="#cb7-176" tabindex="-1"></a></span>
<span id="cb7-177"><a aria-hidden="true" href="#cb7-177" tabindex="-1"></a><span class="kw">[headers]</span></span>
<span id="cb7-178"><a aria-hidden="true" href="#cb7-178" tabindex="-1"></a></span>
<span id="cb7-179"><a aria-hidden="true" href="#cb7-179" tabindex="-1"></a><span class="co"># Additional HTTP headers</span></span>
<span id="cb7-180"><a aria-hidden="true" href="#cb7-180" tabindex="-1"></a><span class="co">#Access-Control-Allow-Origin = *</span></span></code></pre></div>
<p>This configuration file is read each time the server is launched. If some values are not given, the default ones are used. If no configuration file is available, all the default values are used.</p>
</section>
<section class="level6" id="documentation/user-documentation/complex-configuration/configuring-the-server/logging-configuration-file">
<h6>Logging Configuration File <a class="headerlink" href="#documentation/user-documentation/complex-configuration/configuring-the-server/logging-configuration-file">&para;</a></h6>
<p>Radicale uses the default logging facility for Python. The default configuration prints the information messages to the standard output. It is possible to print debug messages thanks to:</p>
<pre><code>radicale --debug
</code></pre>
<pre><code>radicale --debug</code></pre>
<p>Radicale can also be configured to send the messages to the console, logging files, syslog, etc. For more information about the syntax of the configuration file, see: <a href="http://docs.python.org/library/logging.config.html">http://docs.python.org/library/logging.config.html</a>. Here is an example of logging configuration file:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb9-1"><a href="#cb9-1"></a><span class="co"># Loggers, handlers and formatters keys</span></span>
<span id="cb9-2"><a href="#cb9-2"></a></span>
<span id="cb9-3"><a href="#cb9-3"></a><span class="kw">[loggers]</span></span>
<span id="cb9-4"><a href="#cb9-4"></a><span class="co"># Loggers names, main configuration slots</span></span>
<span id="cb9-5"><a href="#cb9-5"></a><span class="dt">keys </span><span class="ot">=</span><span class="st"> root</span></span>
<span id="cb9-6"><a href="#cb9-6"></a></span>
<span id="cb9-7"><a href="#cb9-7"></a><span class="kw">[handlers]</span></span>
<span id="cb9-8"><a href="#cb9-8"></a><span class="co"># Logging handlers, defining logging output methods</span></span>
<span id="cb9-9"><a href="#cb9-9"></a><span class="dt">keys </span><span class="ot">=</span><span class="st"> console,file</span></span>
<span id="cb9-10"><a href="#cb9-10"></a></span>
<span id="cb9-11"><a href="#cb9-11"></a><span class="kw">[formatters]</span></span>
<span id="cb9-12"><a href="#cb9-12"></a><span class="co"># Logging formatters</span></span>
<span id="cb9-13"><a href="#cb9-13"></a><span class="dt">keys </span><span class="ot">=</span><span class="st"> simple,full</span></span>
<span id="cb9-14"><a href="#cb9-14"></a></span>
<span id="cb9-15"><a href="#cb9-15"></a></span>
<span id="cb9-16"><a href="#cb9-16"></a><span class="co"># Loggers</span></span>
<span id="cb9-17"><a href="#cb9-17"></a></span>
<span id="cb9-18"><a href="#cb9-18"></a><span class="kw">[logger_root]</span></span>
<span id="cb9-19"><a href="#cb9-19"></a><span class="co"># Root logger</span></span>
<span id="cb9-20"><a href="#cb9-20"></a><span class="dt">level </span><span class="ot">=</span><span class="st"> DEBUG</span></span>
<span id="cb9-21"><a href="#cb9-21"></a><span class="dt">handlers </span><span class="ot">=</span><span class="st"> console,file</span></span>
<span id="cb9-22"><a href="#cb9-22"></a></span>
<span id="cb9-23"><a href="#cb9-23"></a></span>
<span id="cb9-24"><a href="#cb9-24"></a><span class="co"># Handlers</span></span>
<span id="cb9-25"><a href="#cb9-25"></a></span>
<span id="cb9-26"><a href="#cb9-26"></a><span class="kw">[handler_console]</span></span>
<span id="cb9-27"><a href="#cb9-27"></a><span class="co"># Console handler</span></span>
<span id="cb9-28"><a href="#cb9-28"></a><span class="dt">class </span><span class="ot">=</span><span class="st"> StreamHandler</span></span>
<span id="cb9-29"><a href="#cb9-29"></a><span class="dt">level </span><span class="ot">=</span><span class="st"> INFO</span></span>
<span id="cb9-30"><a href="#cb9-30"></a><span class="dt">args </span><span class="ot">=</span><span class="st"> (sys.stdout,)</span></span>
<span id="cb9-31"><a href="#cb9-31"></a><span class="dt">formatter </span><span class="ot">=</span><span class="st"> simple</span></span>
<span id="cb9-32"><a href="#cb9-32"></a></span>
<span id="cb9-33"><a href="#cb9-33"></a><span class="kw">[handler_file]</span></span>
<span id="cb9-34"><a href="#cb9-34"></a><span class="co"># File handler</span></span>
<span id="cb9-35"><a href="#cb9-35"></a><span class="dt">class </span><span class="ot">=</span><span class="st"> FileHandler</span></span>
<span id="cb9-36"><a href="#cb9-36"></a><span class="dt">args </span><span class="ot">=</span><span class="st"> ('/var/log/radicale',)</span></span>
<span id="cb9-37"><a href="#cb9-37"></a><span class="dt">formatter </span><span class="ot">=</span><span class="st"> full</span></span>
<span id="cb9-38"><a href="#cb9-38"></a></span>
<span id="cb9-39"><a href="#cb9-39"></a></span>
<span id="cb9-40"><a href="#cb9-40"></a><span class="co"># Formatters</span></span>
<span id="cb9-41"><a href="#cb9-41"></a></span>
<span id="cb9-42"><a href="#cb9-42"></a><span class="kw">[formatter_simple]</span></span>
<span id="cb9-43"><a href="#cb9-43"></a><span class="co"># Simple output format</span></span>
<span id="cb9-44"><a href="#cb9-44"></a><span class="dt">format </span><span class="ot">=</span><span class="st"> %(message)s</span></span>
<span id="cb9-45"><a href="#cb9-45"></a></span>
<span id="cb9-46"><a href="#cb9-46"></a><span class="kw">[formatter_full]</span></span>
<span id="cb9-47"><a href="#cb9-47"></a><span class="co"># Full output format</span></span>
<span id="cb9-48"><a href="#cb9-48"></a><span class="dt">format </span><span class="ot">=</span><span class="st"> %(asctime)s - %(levelname)s: %(message)s</span></span></code></pre></div>
<div class="sourceCode" id="cb9"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb9-1"><a aria-hidden="true" href="#cb9-1" tabindex="-1"></a><span class="co"># Loggers, handlers and formatters keys</span></span>
<span id="cb9-2"><a aria-hidden="true" href="#cb9-2" tabindex="-1"></a></span>
<span id="cb9-3"><a aria-hidden="true" href="#cb9-3" tabindex="-1"></a><span class="kw">[loggers]</span></span>
<span id="cb9-4"><a aria-hidden="true" href="#cb9-4" tabindex="-1"></a><span class="co"># Loggers names, main configuration slots</span></span>
<span id="cb9-5"><a aria-hidden="true" href="#cb9-5" tabindex="-1"></a><span class="dt">keys </span><span class="ot">=</span><span class="st"> root</span></span>
<span id="cb9-6"><a aria-hidden="true" href="#cb9-6" tabindex="-1"></a></span>
<span id="cb9-7"><a aria-hidden="true" href="#cb9-7" tabindex="-1"></a><span class="kw">[handlers]</span></span>
<span id="cb9-8"><a aria-hidden="true" href="#cb9-8" tabindex="-1"></a><span class="co"># Logging handlers, defining logging output methods</span></span>
<span id="cb9-9"><a aria-hidden="true" href="#cb9-9" tabindex="-1"></a><span class="dt">keys </span><span class="ot">=</span><span class="st"> console,file</span></span>
<span id="cb9-10"><a aria-hidden="true" href="#cb9-10" tabindex="-1"></a></span>
<span id="cb9-11"><a aria-hidden="true" href="#cb9-11" tabindex="-1"></a><span class="kw">[formatters]</span></span>
<span id="cb9-12"><a aria-hidden="true" href="#cb9-12" tabindex="-1"></a><span class="co"># Logging formatters</span></span>
<span id="cb9-13"><a aria-hidden="true" href="#cb9-13" tabindex="-1"></a><span class="dt">keys </span><span class="ot">=</span><span class="st"> simple,full</span></span>
<span id="cb9-14"><a aria-hidden="true" href="#cb9-14" tabindex="-1"></a></span>
<span id="cb9-15"><a aria-hidden="true" href="#cb9-15" tabindex="-1"></a></span>
<span id="cb9-16"><a aria-hidden="true" href="#cb9-16" tabindex="-1"></a><span class="co"># Loggers</span></span>
<span id="cb9-17"><a aria-hidden="true" href="#cb9-17" tabindex="-1"></a></span>
<span id="cb9-18"><a aria-hidden="true" href="#cb9-18" tabindex="-1"></a><span class="kw">[logger_root]</span></span>
<span id="cb9-19"><a aria-hidden="true" href="#cb9-19" tabindex="-1"></a><span class="co"># Root logger</span></span>
<span id="cb9-20"><a aria-hidden="true" href="#cb9-20" tabindex="-1"></a><span class="dt">level </span><span class="ot">=</span><span class="st"> DEBUG</span></span>
<span id="cb9-21"><a aria-hidden="true" href="#cb9-21" tabindex="-1"></a><span class="dt">handlers </span><span class="ot">=</span><span class="st"> console,file</span></span>
<span id="cb9-22"><a aria-hidden="true" href="#cb9-22" tabindex="-1"></a></span>
<span id="cb9-23"><a aria-hidden="true" href="#cb9-23" tabindex="-1"></a></span>
<span id="cb9-24"><a aria-hidden="true" href="#cb9-24" tabindex="-1"></a><span class="co"># Handlers</span></span>
<span id="cb9-25"><a aria-hidden="true" href="#cb9-25" tabindex="-1"></a></span>
<span id="cb9-26"><a aria-hidden="true" href="#cb9-26" tabindex="-1"></a><span class="kw">[handler_console]</span></span>
<span id="cb9-27"><a aria-hidden="true" href="#cb9-27" tabindex="-1"></a><span class="co"># Console handler</span></span>
<span id="cb9-28"><a aria-hidden="true" href="#cb9-28" tabindex="-1"></a><span class="dt">class </span><span class="ot">=</span><span class="st"> StreamHandler</span></span>
<span id="cb9-29"><a aria-hidden="true" href="#cb9-29" tabindex="-1"></a><span class="dt">level </span><span class="ot">=</span><span class="st"> INFO</span></span>
<span id="cb9-30"><a aria-hidden="true" href="#cb9-30" tabindex="-1"></a><span class="dt">args </span><span class="ot">=</span><span class="st"> (sys.stdout,)</span></span>
<span id="cb9-31"><a aria-hidden="true" href="#cb9-31" tabindex="-1"></a><span class="dt">formatter </span><span class="ot">=</span><span class="st"> simple</span></span>
<span id="cb9-32"><a aria-hidden="true" href="#cb9-32" tabindex="-1"></a></span>
<span id="cb9-33"><a aria-hidden="true" href="#cb9-33" tabindex="-1"></a><span class="kw">[handler_file]</span></span>
<span id="cb9-34"><a aria-hidden="true" href="#cb9-34" tabindex="-1"></a><span class="co"># File handler</span></span>
<span id="cb9-35"><a aria-hidden="true" href="#cb9-35" tabindex="-1"></a><span class="dt">class </span><span class="ot">=</span><span class="st"> FileHandler</span></span>
<span id="cb9-36"><a aria-hidden="true" href="#cb9-36" tabindex="-1"></a><span class="dt">args </span><span class="ot">=</span><span class="st"> ('/var/log/radicale',)</span></span>
<span id="cb9-37"><a aria-hidden="true" href="#cb9-37" tabindex="-1"></a><span class="dt">formatter </span><span class="ot">=</span><span class="st"> full</span></span>
<span id="cb9-38"><a aria-hidden="true" href="#cb9-38" tabindex="-1"></a></span>
<span id="cb9-39"><a aria-hidden="true" href="#cb9-39" tabindex="-1"></a></span>
<span id="cb9-40"><a aria-hidden="true" href="#cb9-40" tabindex="-1"></a><span class="co"># Formatters</span></span>
<span id="cb9-41"><a aria-hidden="true" href="#cb9-41" tabindex="-1"></a></span>
<span id="cb9-42"><a aria-hidden="true" href="#cb9-42" tabindex="-1"></a><span class="kw">[formatter_simple]</span></span>
<span id="cb9-43"><a aria-hidden="true" href="#cb9-43" tabindex="-1"></a><span class="co"># Simple output format</span></span>
<span id="cb9-44"><a aria-hidden="true" href="#cb9-44" tabindex="-1"></a><span class="dt">format </span><span class="ot">=</span><span class="st"> %(message)s</span></span>
<span id="cb9-45"><a aria-hidden="true" href="#cb9-45" tabindex="-1"></a></span>
<span id="cb9-46"><a aria-hidden="true" href="#cb9-46" tabindex="-1"></a><span class="kw">[formatter_full]</span></span>
<span id="cb9-47"><a aria-hidden="true" href="#cb9-47" tabindex="-1"></a><span class="co"># Full output format</span></span>
<span id="cb9-48"><a aria-hidden="true" href="#cb9-48" tabindex="-1"></a><span class="dt">format </span><span class="ot">=</span><span class="st"> %(asctime)s - %(levelname)s: %(message)s</span></span></code></pre></div>
</section>
<section class="level6" id="documentation/user-documentation/complex-configuration/configuring-the-server/command-line-options">
<h6>Command Line Options <a class="headerlink" href="#documentation/user-documentation/complex-configuration/configuring-the-server/command-line-options">&para;</a></h6>
<p>All the options of the <code>server</code> part can be changed with command line options. These options are available by typing:</p>
<pre><code>radicale --help
</code></pre>
<pre><code>radicale --help</code></pre>
</section>
</section>
<section class="level5" id="documentation/user-documentation/complex-configuration/wsgi-cgi-and-fastcgi">
@ -979,28 +1108,28 @@ After installing and accepting it you should restart your browser.</p>
<section class="level6" id="documentation/user-documentation/complex-configuration/wsgi-cgi-and-fastcgi/apache-and-mod_wsgi">
<h6>Apache and mod_wsgi <a class="headerlink" href="#documentation/user-documentation/complex-configuration/wsgi-cgi-and-fastcgi/apache-and-mod_wsgi">&para;</a></h6>
<p>To use Radicale with Apache's <code>mod_wsgi</code>, you first have to install the Radicale module in your Python path and write your <code>.wsgi</code> file (in <code>/var/www</code> for example):</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb11-1"><a href="#cb11-1"></a><span class="im">import</span> radicale</span>
<span id="cb11-2"><a href="#cb11-2"></a>radicale.log.start()</span>
<span id="cb11-3"><a href="#cb11-3"></a>application <span class="op">=</span> radicale.Application()</span></code></pre></div>
<div class="sourceCode" id="cb11"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb11-1"><a aria-hidden="true" href="#cb11-1" tabindex="-1"></a><span class="im">import</span> radicale</span>
<span id="cb11-2"><a aria-hidden="true" href="#cb11-2" tabindex="-1"></a>radicale.log.start()</span>
<span id="cb11-3"><a aria-hidden="true" href="#cb11-3" tabindex="-1"></a>application <span class="op">=</span> radicale.Application()</span></code></pre></div>
<blockquote>
<p><strong>Note</strong></p>
<p>The <code>hosts</code>, <code>daemon</code>, <code>pid</code>, <code>ssl</code>, <code>certificate</code>, <code>key</code>, <code>protocol</code> and <code>ciphers</code> keys of the <code>[server]</code> part of the configuration are ignored.</p>
</blockquote>
<p>Next you have to create the Apache virtual host (adapt the configuration to your environment):</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb12-1"><a href="#cb12-1"></a><span class="fu">&lt;VirtualHost</span><span class="at"> *:80</span><span class="fu">&gt;</span></span>
<span id="cb12-2"><a href="#cb12-2"></a> ServerName<span class="st"> cal.yourdomain.org</span></span>
<span id="cb12-3"><a href="#cb12-3"></a></span>
<span id="cb12-4"><a href="#cb12-4"></a> WSGIDaemonProcess radicale user<span class="st">=www-data group=www-data threads=1</span></span>
<span id="cb12-5"><a href="#cb12-5"></a> WSGIScriptAlias / /var/www/radicale.wsgi</span>
<span id="cb12-6"><a href="#cb12-6"></a></span>
<span id="cb12-7"><a href="#cb12-7"></a> <span class="fu">&lt;Directory</span><span class="at"> /var/www</span><span class="fu">&gt;</span></span>
<span id="cb12-8"><a href="#cb12-8"></a> WSGIProcessGroup radicale</span>
<span id="cb12-9"><a href="#cb12-9"></a> WSGIApplicationGroup %{GLOBAL}</span>
<span id="cb12-10"><a href="#cb12-10"></a> <span class="ex">AllowOverride</span><span class="ch"> </span><span class="kw">None</span></span>
<span id="cb12-11"><a href="#cb12-11"></a> <span class="ex">Order</span><span class="ch"> </span><span class="kw">allow,deny</span></span>
<span id="cb12-12"><a href="#cb12-12"></a> allow<span class="st"> from all</span></span>
<span id="cb12-13"><a href="#cb12-13"></a> <span class="fu">&lt;/Directory&gt;</span></span>
<span id="cb12-14"><a href="#cb12-14"></a><span class="fu">&lt;/VirtualHost&gt;</span></span></code></pre></div>
<div class="sourceCode" id="cb12"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb12-1"><a aria-hidden="true" href="#cb12-1" tabindex="-1"></a><span class="fu">&lt;VirtualHost</span><span class="at"> *:80</span><span class="fu">&gt;</span></span>
<span id="cb12-2"><a aria-hidden="true" href="#cb12-2" tabindex="-1"></a> ServerName<span class="st"> cal.yourdomain.org</span></span>
<span id="cb12-3"><a aria-hidden="true" href="#cb12-3" tabindex="-1"></a></span>
<span id="cb12-4"><a aria-hidden="true" href="#cb12-4" tabindex="-1"></a> WSGIDaemonProcess radicale user<span class="st">=www-data group=www-data threads=1</span></span>
<span id="cb12-5"><a aria-hidden="true" href="#cb12-5" tabindex="-1"></a> WSGIScriptAlias / /var/www/radicale.wsgi</span>
<span id="cb12-6"><a aria-hidden="true" href="#cb12-6" tabindex="-1"></a></span>
<span id="cb12-7"><a aria-hidden="true" href="#cb12-7" tabindex="-1"></a> <span class="fu">&lt;Directory</span><span class="at"> /var/www</span><span class="fu">&gt;</span></span>
<span id="cb12-8"><a aria-hidden="true" href="#cb12-8" tabindex="-1"></a> WSGIProcessGroup radicale</span>
<span id="cb12-9"><a aria-hidden="true" href="#cb12-9" tabindex="-1"></a> WSGIApplicationGroup %{GLOBAL}</span>
<span id="cb12-10"><a aria-hidden="true" href="#cb12-10" tabindex="-1"></a> <span class="ex">AllowOverride</span><span class="ch"> </span><span class="kw">None</span></span>
<span id="cb12-11"><a aria-hidden="true" href="#cb12-11" tabindex="-1"></a> <span class="ex">Order</span><span class="ch"> </span><span class="kw">allow,deny</span></span>
<span id="cb12-12"><a aria-hidden="true" href="#cb12-12" tabindex="-1"></a> allow<span class="st"> from all</span></span>
<span id="cb12-13"><a aria-hidden="true" href="#cb12-13" tabindex="-1"></a> <span class="fu">&lt;/Directory&gt;</span></span>
<span id="cb12-14"><a aria-hidden="true" href="#cb12-14" tabindex="-1"></a><span class="fu">&lt;/VirtualHost&gt;</span></span></code></pre></div>
<blockquote>
<p><strong>Warning</strong></p>
<p>You should use the root of the (sub)domain (<code>WSGIScriptAlias /</code>), else some CalDAV features may not work.</p>
@ -1008,29 +1137,29 @@ After installing and accepting it you should restart your browser.</p>
<p>If you want to use authentication with Apache, you <em>really</em> should use one of the Apache authentication modules, instead of the ones from Radicale: they're just better.</p>
<p>Deactivate any rights and module in Radicale and use your favourite Apache authentication backend. You can then restrict the access: allow the <code>alice</code> user to access <code>/alice/*</code> URLs, and everything should work as expected.</p>
<p>Here is one example of Apache configuration file:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb13-1"><a href="#cb13-1"></a><span class="fu">&lt;VirtualHost</span><span class="at"> *:80</span><span class="fu">&gt;</span></span>
<span id="cb13-2"><a href="#cb13-2"></a> ServerName<span class="st"> radicale.local</span></span>
<span id="cb13-3"><a href="#cb13-3"></a></span>
<span id="cb13-4"><a href="#cb13-4"></a> WSGIDaemonProcess radicale user<span class="st">=radicale group=radicale threads=1</span></span>
<span id="cb13-5"><a href="#cb13-5"></a> WSGIScriptAlias / /usr/share/radicale/radicale.wsgi</span>
<span id="cb13-6"><a href="#cb13-6"></a></span>
<span id="cb13-7"><a href="#cb13-7"></a> <span class="fu">&lt;Directory</span><span class="at"> /usr/share/radicale/</span><span class="fu">&gt;</span></span>
<span id="cb13-8"><a href="#cb13-8"></a> WSGIProcessGroup radicale</span>
<span id="cb13-9"><a href="#cb13-9"></a> WSGIApplicationGroup %{GLOBAL}</span>
<span id="cb13-10"><a href="#cb13-10"></a></span>
<span id="cb13-11"><a href="#cb13-11"></a> <span class="ex">AuthType</span><span class="ch"> </span><span class="kw">Basic</span></span>
<span id="cb13-12"><a href="#cb13-12"></a> AuthName<span class="st"> "Radicale Authentication"</span></span>
<span id="cb13-13"><a href="#cb13-13"></a> AuthBasicProvider<span class="st"> file</span></span>
<span id="cb13-14"><a href="#cb13-14"></a> AuthUserFile<span class="st"> /usr/share/radicale/radicale.passwd</span></span>
<span id="cb13-15"><a href="#cb13-15"></a></span>
<span id="cb13-16"><a href="#cb13-16"></a> <span class="ex">AllowOverride</span><span class="ch"> </span><span class="kw">None</span></span>
<span id="cb13-17"><a href="#cb13-17"></a> Require<span class="st"> valid-user</span></span>
<span id="cb13-18"><a href="#cb13-18"></a></span>
<span id="cb13-19"><a href="#cb13-19"></a> <span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb13-20"><a href="#cb13-20"></a> RewriteCond<span class="st"> %{REMOTE_USER}%{PATH_INFO} !^([^/]+/)\1</span></span>
<span id="cb13-21"><a href="#cb13-21"></a> RewriteRule<span class="st"> .* - [Forbidden]</span></span>
<span id="cb13-22"><a href="#cb13-22"></a> <span class="fu">&lt;/Directory&gt;</span></span>
<span id="cb13-23"><a href="#cb13-23"></a><span class="fu">&lt;/VirtualHost&gt;</span></span></code></pre></div>
<div class="sourceCode" id="cb13"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb13-1"><a aria-hidden="true" href="#cb13-1" tabindex="-1"></a><span class="fu">&lt;VirtualHost</span><span class="at"> *:80</span><span class="fu">&gt;</span></span>
<span id="cb13-2"><a aria-hidden="true" href="#cb13-2" tabindex="-1"></a> ServerName<span class="st"> radicale.local</span></span>
<span id="cb13-3"><a aria-hidden="true" href="#cb13-3" tabindex="-1"></a></span>
<span id="cb13-4"><a aria-hidden="true" href="#cb13-4" tabindex="-1"></a> WSGIDaemonProcess radicale user<span class="st">=radicale group=radicale threads=1</span></span>
<span id="cb13-5"><a aria-hidden="true" href="#cb13-5" tabindex="-1"></a> WSGIScriptAlias / /usr/share/radicale/radicale.wsgi</span>
<span id="cb13-6"><a aria-hidden="true" href="#cb13-6" tabindex="-1"></a></span>
<span id="cb13-7"><a aria-hidden="true" href="#cb13-7" tabindex="-1"></a> <span class="fu">&lt;Directory</span><span class="at"> /usr/share/radicale/</span><span class="fu">&gt;</span></span>
<span id="cb13-8"><a aria-hidden="true" href="#cb13-8" tabindex="-1"></a> WSGIProcessGroup radicale</span>
<span id="cb13-9"><a aria-hidden="true" href="#cb13-9" tabindex="-1"></a> WSGIApplicationGroup %{GLOBAL}</span>
<span id="cb13-10"><a aria-hidden="true" href="#cb13-10" tabindex="-1"></a></span>
<span id="cb13-11"><a aria-hidden="true" href="#cb13-11" tabindex="-1"></a> <span class="ex">AuthType</span><span class="ch"> </span><span class="kw">Basic</span></span>
<span id="cb13-12"><a aria-hidden="true" href="#cb13-12" tabindex="-1"></a> AuthName<span class="st"> "Radicale Authentication"</span></span>
<span id="cb13-13"><a aria-hidden="true" href="#cb13-13" tabindex="-1"></a> AuthBasicProvider<span class="st"> file</span></span>
<span id="cb13-14"><a aria-hidden="true" href="#cb13-14" tabindex="-1"></a> AuthUserFile<span class="st"> /usr/share/radicale/radicale.passwd</span></span>
<span id="cb13-15"><a aria-hidden="true" href="#cb13-15" tabindex="-1"></a></span>
<span id="cb13-16"><a aria-hidden="true" href="#cb13-16" tabindex="-1"></a> <span class="ex">AllowOverride</span><span class="ch"> </span><span class="kw">None</span></span>
<span id="cb13-17"><a aria-hidden="true" href="#cb13-17" tabindex="-1"></a> Require<span class="st"> valid-user</span></span>
<span id="cb13-18"><a aria-hidden="true" href="#cb13-18" tabindex="-1"></a></span>
<span id="cb13-19"><a aria-hidden="true" href="#cb13-19" tabindex="-1"></a> <span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb13-20"><a aria-hidden="true" href="#cb13-20" tabindex="-1"></a> RewriteCond<span class="st"> %{REMOTE_USER}%{PATH_INFO} !^([^/]+/)\1</span></span>
<span id="cb13-21"><a aria-hidden="true" href="#cb13-21" tabindex="-1"></a> RewriteRule<span class="st"> .* - [Forbidden]</span></span>
<span id="cb13-22"><a aria-hidden="true" href="#cb13-22" tabindex="-1"></a> <span class="fu">&lt;/Directory&gt;</span></span>
<span id="cb13-23"><a aria-hidden="true" href="#cb13-23" tabindex="-1"></a><span class="fu">&lt;/VirtualHost&gt;</span></span></code></pre></div>
<p>If you're still convinced that access control is better with Radicale, you have to add <code>WSGIPassAuthorization On</code> in your Apache configuration files, as explained in <a href="http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#User_Authentication">the mod_wsgi documentation</a>.</p>
<blockquote>
<p><strong>Note</strong></p>
@ -1085,46 +1214,46 @@ After installing and accepting it you should restart your browser.</p>
<p>Section names are only used for naming the rule.</p>
<p>Leading or ending slashes are trimmed from collection's path.</p>
<p>Example:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb14-1"><a href="#cb14-1"></a><span class="co"># The default path for this kind of files is ~/.config/radicale/rights</span></span>
<span id="cb14-2"><a href="#cb14-2"></a><span class="co"># This can be changed in the configuration file</span></span>
<span id="cb14-3"><a href="#cb14-3"></a><span class="co">#</span></span>
<span id="cb14-4"><a href="#cb14-4"></a><span class="co"># This file gives independant examples to help users write their own</span></span>
<span id="cb14-5"><a href="#cb14-5"></a><span class="co"># configuration files. Using these examples together in the same configuration</span></span>
<span id="cb14-6"><a href="#cb14-6"></a><span class="co"># file is meaningless.</span></span>
<span id="cb14-7"><a href="#cb14-7"></a><span class="co">#</span></span>
<span id="cb14-8"><a href="#cb14-8"></a><span class="co"># The first rule matching both user and collection patterns will be returned.</span></span>
<span id="cb14-9"><a href="#cb14-9"></a></span>
<span id="cb14-10"><a href="#cb14-10"></a><span class="co"># This means all users starting with "admin" may read any collection</span></span>
<span id="cb14-11"><a href="#cb14-11"></a><span class="kw">[admin]</span></span>
<span id="cb14-12"><a href="#cb14-12"></a><span class="dt">user: ^admin.*$</span></span>
<span id="cb14-13"><a href="#cb14-13"></a><span class="dt">collection: .*</span></span>
<span id="cb14-14"><a href="#cb14-14"></a><span class="dt">permission: r</span></span>
<span id="cb14-15"><a href="#cb14-15"></a></span>
<span id="cb14-16"><a href="#cb14-16"></a><span class="co"># This means all users may read and write any collection starting with public.</span></span>
<span id="cb14-17"><a href="#cb14-17"></a><span class="co"># We do so by just not testing against the user string.</span></span>
<span id="cb14-18"><a href="#cb14-18"></a><span class="kw">[public]</span></span>
<span id="cb14-19"><a href="#cb14-19"></a><span class="dt">user: .*</span></span>
<span id="cb14-20"><a href="#cb14-20"></a><span class="dt">collection: ^public(/.+)?$</span></span>
<span id="cb14-21"><a href="#cb14-21"></a><span class="dt">permission: rw</span></span>
<span id="cb14-22"><a href="#cb14-22"></a></span>
<span id="cb14-23"><a href="#cb14-23"></a><span class="co"># A little more complex: give read access to users from a domain for all</span></span>
<span id="cb14-24"><a href="#cb14-24"></a><span class="co"># collections of all the users (ie. user@domain.tld can read domain/*).</span></span>
<span id="cb14-25"><a href="#cb14-25"></a><span class="kw">[domain-wide-access]</span></span>
<span id="cb14-26"><a href="#cb14-26"></a><span class="dt">user: ^.+@(.+)\..+$</span></span>
<span id="cb14-27"><a href="#cb14-27"></a><span class="dt">collection: ^{0}/.+$</span></span>
<span id="cb14-28"><a href="#cb14-28"></a><span class="dt">permission: r</span></span>
<span id="cb14-29"><a href="#cb14-29"></a></span>
<span id="cb14-30"><a href="#cb14-30"></a><span class="co"># Allow authenticated user to read all collections</span></span>
<span id="cb14-31"><a href="#cb14-31"></a><span class="kw">[allow-everyone-read]</span></span>
<span id="cb14-32"><a href="#cb14-32"></a><span class="dt">user: .+</span></span>
<span id="cb14-33"><a href="#cb14-33"></a><span class="dt">collection: .*</span></span>
<span id="cb14-34"><a href="#cb14-34"></a><span class="dt">permission: r</span></span>
<span id="cb14-35"><a href="#cb14-35"></a></span>
<span id="cb14-36"><a href="#cb14-36"></a><span class="co"># Give write access to owners</span></span>
<span id="cb14-37"><a href="#cb14-37"></a><span class="kw">[owner-write]</span></span>
<span id="cb14-38"><a href="#cb14-38"></a><span class="dt">user: .+</span></span>
<span id="cb14-39"><a href="#cb14-39"></a><span class="dt">collection: ^%(login)s/.*$</span></span>
<span id="cb14-40"><a href="#cb14-40"></a><span class="dt">permission: w</span></span></code></pre></div>
<div class="sourceCode" id="cb14"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb14-1"><a aria-hidden="true" href="#cb14-1" tabindex="-1"></a><span class="co"># The default path for this kind of files is ~/.config/radicale/rights</span></span>
<span id="cb14-2"><a aria-hidden="true" href="#cb14-2" tabindex="-1"></a><span class="co"># This can be changed in the configuration file</span></span>
<span id="cb14-3"><a aria-hidden="true" href="#cb14-3" tabindex="-1"></a><span class="co">#</span></span>
<span id="cb14-4"><a aria-hidden="true" href="#cb14-4" tabindex="-1"></a><span class="co"># This file gives independant examples to help users write their own</span></span>
<span id="cb14-5"><a aria-hidden="true" href="#cb14-5" tabindex="-1"></a><span class="co"># configuration files. Using these examples together in the same configuration</span></span>
<span id="cb14-6"><a aria-hidden="true" href="#cb14-6" tabindex="-1"></a><span class="co"># file is meaningless.</span></span>
<span id="cb14-7"><a aria-hidden="true" href="#cb14-7" tabindex="-1"></a><span class="co">#</span></span>
<span id="cb14-8"><a aria-hidden="true" href="#cb14-8" tabindex="-1"></a><span class="co"># The first rule matching both user and collection patterns will be returned.</span></span>
<span id="cb14-9"><a aria-hidden="true" href="#cb14-9" tabindex="-1"></a></span>
<span id="cb14-10"><a aria-hidden="true" href="#cb14-10" tabindex="-1"></a><span class="co"># This means all users starting with "admin" may read any collection</span></span>
<span id="cb14-11"><a aria-hidden="true" href="#cb14-11" tabindex="-1"></a><span class="kw">[admin]</span></span>
<span id="cb14-12"><a aria-hidden="true" href="#cb14-12" tabindex="-1"></a><span class="dt">user: ^admin.*$</span></span>
<span id="cb14-13"><a aria-hidden="true" href="#cb14-13" tabindex="-1"></a><span class="dt">collection: .*</span></span>
<span id="cb14-14"><a aria-hidden="true" href="#cb14-14" tabindex="-1"></a><span class="dt">permission: r</span></span>
<span id="cb14-15"><a aria-hidden="true" href="#cb14-15" tabindex="-1"></a></span>
<span id="cb14-16"><a aria-hidden="true" href="#cb14-16" tabindex="-1"></a><span class="co"># This means all users may read and write any collection starting with public.</span></span>
<span id="cb14-17"><a aria-hidden="true" href="#cb14-17" tabindex="-1"></a><span class="co"># We do so by just not testing against the user string.</span></span>
<span id="cb14-18"><a aria-hidden="true" href="#cb14-18" tabindex="-1"></a><span class="kw">[public]</span></span>
<span id="cb14-19"><a aria-hidden="true" href="#cb14-19" tabindex="-1"></a><span class="dt">user: .*</span></span>
<span id="cb14-20"><a aria-hidden="true" href="#cb14-20" tabindex="-1"></a><span class="dt">collection: ^public(/.+)?$</span></span>
<span id="cb14-21"><a aria-hidden="true" href="#cb14-21" tabindex="-1"></a><span class="dt">permission: rw</span></span>
<span id="cb14-22"><a aria-hidden="true" href="#cb14-22" tabindex="-1"></a></span>
<span id="cb14-23"><a aria-hidden="true" href="#cb14-23" tabindex="-1"></a><span class="co"># A little more complex: give read access to users from a domain for all</span></span>
<span id="cb14-24"><a aria-hidden="true" href="#cb14-24" tabindex="-1"></a><span class="co"># collections of all the users (ie. user@domain.tld can read domain/*).</span></span>
<span id="cb14-25"><a aria-hidden="true" href="#cb14-25" tabindex="-1"></a><span class="kw">[domain-wide-access]</span></span>
<span id="cb14-26"><a aria-hidden="true" href="#cb14-26" tabindex="-1"></a><span class="dt">user: ^.+@(.+)\..+$</span></span>
<span id="cb14-27"><a aria-hidden="true" href="#cb14-27" tabindex="-1"></a><span class="dt">collection: ^{0}/.+$</span></span>
<span id="cb14-28"><a aria-hidden="true" href="#cb14-28" tabindex="-1"></a><span class="dt">permission: r</span></span>
<span id="cb14-29"><a aria-hidden="true" href="#cb14-29" tabindex="-1"></a></span>
<span id="cb14-30"><a aria-hidden="true" href="#cb14-30" tabindex="-1"></a><span class="co"># Allow authenticated user to read all collections</span></span>
<span id="cb14-31"><a aria-hidden="true" href="#cb14-31" tabindex="-1"></a><span class="kw">[allow-everyone-read]</span></span>
<span id="cb14-32"><a aria-hidden="true" href="#cb14-32" tabindex="-1"></a><span class="dt">user: .+</span></span>
<span id="cb14-33"><a aria-hidden="true" href="#cb14-33" tabindex="-1"></a><span class="dt">collection: .*</span></span>
<span id="cb14-34"><a aria-hidden="true" href="#cb14-34" tabindex="-1"></a><span class="dt">permission: r</span></span>
<span id="cb14-35"><a aria-hidden="true" href="#cb14-35" tabindex="-1"></a></span>
<span id="cb14-36"><a aria-hidden="true" href="#cb14-36" tabindex="-1"></a><span class="co"># Give write access to owners</span></span>
<span id="cb14-37"><a aria-hidden="true" href="#cb14-37" tabindex="-1"></a><span class="kw">[owner-write]</span></span>
<span id="cb14-38"><a aria-hidden="true" href="#cb14-38" tabindex="-1"></a><span class="dt">user: .+</span></span>
<span id="cb14-39"><a aria-hidden="true" href="#cb14-39" tabindex="-1"></a><span class="dt">collection: ^%(login)s/.*$</span></span>
<span id="cb14-40"><a aria-hidden="true" href="#cb14-40" tabindex="-1"></a><span class="dt">permission: w</span></span></code></pre></div>
</section>
</section>
<section class="level5" id="documentation/user-documentation/complex-configuration/git-support">
@ -1361,14 +1490,12 @@ This folder is a set of storage modules able to read and write collections. Curr
<section class="level4" id="download//pypi">
<h4>PyPI <a class="headerlink" href="#download//pypi">&para;</a></h4>
<p>Radicale is <a href="http://pypi.python.org/pypi/Radicale/">available on PyPI</a>. To install, just type as superuser:</p>
<pre><code>pip install radicale==1.1.*
</code></pre>
<pre><code>pip install radicale==1.1.*</code></pre>
</section>
<section class="level4" id="download//git-repository">
<h4>Git Repository <a class="headerlink" href="#download//git-repository">&para;</a></h4>
<p>If you want the development version of Radicale, take a look at the <code>git repository on GitHub</code>, or clone it thanks to:</p>
<pre><code>git clone git://github.com/Kozea/Radicale.git
</code></pre>
<pre><code>git clone git://github.com/Kozea/Radicale.git</code></pre>
<p>You can also download <a href="https://github.com/Kozea/Radicale/tarball/master">the Radicale package of the git repository</a>.</p>
</section>
<section class="level4" id="download//source-packages">

689
2.1.html
View file

@ -5,6 +5,137 @@
<meta content="pandoc" name="generator">
<meta content="width=device-width, initial-scale=1" name="viewport">
<style>
html {
line-height: 1.5;
font-family: Georgia, serif;
font-size: 20px;
color: #1a1a1a;
background-color: #fdfdfd;
}
body {
margin: 0 auto;
max-width: 36em;
padding-left: 50px;
padding-right: 50px;
padding-top: 50px;
padding-bottom: 50px;
hyphens: auto;
overflow-wrap: break-word;
text-rendering: optimizeLegibility;
font-kerning: normal;
}
@media (max-width: 600px) {
body {
font-size: 0.9em;
padding: 1em;
}
}
@media print {
body {
background-color: transparent;
color: black;
font-size: 12pt;
}
p, h2, h3 {
orphans: 3;
widows: 3;
}
h2, h3, h4 {
page-break-after: avoid;
}
}
p {
margin: 1em 0;
}
a {
color: #1a1a1a;
}
a:visited {
color: #1a1a1a;
}
img {
max-width: 100%;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 1.4em;
}
h5, h6 {
font-size: 1em;
font-style: italic;
}
h6 {
font-weight: normal;
}
ol, ul {
padding-left: 1.7em;
margin-top: 1em;
}
li > ol, li > ul {
margin-top: 0;
}
blockquote {
margin: 1em 0 1em 1.7em;
padding-left: 1em;
border-left: 2px solid #e6e6e6;
color: #606060;
}
code {
font-family: Menlo, Monaco, 'Lucida Console', Consolas, monospace;
font-size: 85%;
margin: 0;
}
pre {
margin: 1em 0;
overflow: auto;
}
pre code {
padding: 0;
overflow: visible;
overflow-wrap: normal;
}
.sourceCode {
background-color: transparent;
overflow: visible;
}
hr {
background-color: #1a1a1a;
border: none;
height: 1px;
margin: 1em 0;
}
table {
margin: 1em 0;
border-collapse: collapse;
width: 100%;
overflow-x: auto;
display: block;
font-variant-numeric: lining-nums tabular-nums;
}
table caption {
margin-bottom: 0.75em;
}
tbody {
margin-top: 0.5em;
border-top: 1px solid #1a1a1a;
border-bottom: 1px solid #1a1a1a;
}
th {
border-top: 1px solid #1a1a1a;
padding: 0.25em 0.5em 0.25em 0.5em;
}
td {
padding: 0.125em 0.5em 0.25em 0.5em;
}
header {
margin-bottom: 4em;
text-align: center;
}
#TOC li {
list-style: none;
}
#TOC a:not(:hover) {
text-decoration: none;
}
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
@ -14,6 +145,7 @@
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@ -73,6 +205,7 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
</style>
<link href="assets/default.css" media="all" rel="stylesheet">
<link href="assets/screen.css" media="screen" rel="stylesheet">
@ -417,9 +550,9 @@
<section class="level4" id="getting-started//installation">
<h4>Installation <a class="headerlink" href="#getting-started//installation">&para;</a></h4>
<p>Radicale is really easy to install and works out-of-the-box.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1"></a>$ <span class="ex">python3</span> -m pip install --upgrade radicale==2.1.*</span>
<span id="cb1-2"><a href="#cb1-2"></a>$ <span class="ex">python3</span> -m radicale --config <span class="st">""</span> --storage-filesystem-folder=~/.var/lib/radicale/collections</span></code></pre></div>
<p>When your server is launched, you can check that everything's OK by going to <a href="http://localhost:5232/">http://localhost:5232/</a> with your browser! You can login with any username and password.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a aria-hidden="true" href="#cb1-1" tabindex="-1"></a><span class="ex">$</span> python3 <span class="at">-m</span> pip install <span class="at">--upgrade</span> radicale==2.1.<span class="pp">*</span></span>
<span id="cb1-2"><a aria-hidden="true" href="#cb1-2" tabindex="-1"></a><span class="ex">$</span> python3 <span class="at">-m</span> radicale <span class="at">--config</span> <span class="st">""</span> <span class="at">--storage-filesystem-folder</span><span class="op">=</span>~/.var/lib/radicale/collections</span></code></pre></div>
<p>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.</p>
<p>Want more? Why don't you check our wonderful <a href="#documentation">documentation</a>?</p>
</section>
<section class="level4" id="getting-started//whats-new">
@ -477,18 +610,18 @@
<h4>Linux / *BSD <a class="headerlink" href="#documentation/tutorial/linux--bsd">&para;</a></h4>
<p>First of all, make sure that <strong>python</strong> 3.3 or later (<strong>python</strong> &ge; 3.6 is recommended) and <strong>pip</strong> are installed. On most distributions it should be enough to install the package <code>python3-pip</code>.</p>
<p>Then open a console and type:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1"></a><span class="co"># Run the following command as root or</span></span>
<span id="cb2-2"><a href="#cb2-2"></a><span class="co"># add the --user argument to only install for the current user</span></span>
<span id="cb2-3"><a href="#cb2-3"></a>$ <span class="ex">python3</span> -m pip install --upgrade radicale==2.1.*</span>
<span id="cb2-4"><a href="#cb2-4"></a>$ <span class="ex">python3</span> -m radicale --config <span class="st">""</span> --storage-filesystem-folder=~/.var/lib/radicale/collections</span></code></pre></div>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a aria-hidden="true" href="#cb2-1" tabindex="-1"></a><span class="co"># Run the following command as root or</span></span>
<span id="cb2-2"><a aria-hidden="true" href="#cb2-2" tabindex="-1"></a><span class="co"># add the --user argument to only install for the current user</span></span>
<span id="cb2-3"><a aria-hidden="true" href="#cb2-3" tabindex="-1"></a><span class="ex">$</span> python3 <span class="at">-m</span> pip install <span class="at">--upgrade</span> radicale==2.1.<span class="pp">*</span></span>
<span id="cb2-4"><a aria-hidden="true" href="#cb2-4" tabindex="-1"></a><span class="ex">$</span> python3 <span class="at">-m</span> radicale <span class="at">--config</span> <span class="st">""</span> <span class="at">--storage-filesystem-folder</span><span class="op">=</span>~/.var/lib/radicale/collections</span></code></pre></div>
<p>Victory! Open <a href="http://localhost:5232/">http://localhost:5232/</a> in your browser! You can login with any username and password.</p>
</section>
<section class="level4" id="documentation/tutorial/windows">
<h4>Windows <a class="headerlink" href="#documentation/tutorial/windows">&para;</a></h4>
<p>The first step is to install Python. Go to <a href="https://python.org">python.org</a> 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!</p>
<p>Launch a command prompt and type:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode powershell"><code class="sourceCode powershell"><span id="cb3-1"><a href="#cb3-1"></a>C:\Users\User&gt; python -m pip install --upgrade radicale==2.<span class="fu">1</span>.*</span>
<span id="cb3-2"><a href="#cb3-2"></a>C:\Users\User&gt; python -m radicale --config <span class="st">""</span> --storage-filesystem-folder=~/radicale/collections</span></code></pre></div>
<div class="sourceCode" id="cb3"><pre class="sourceCode powershell"><code class="sourceCode powershell"><span id="cb3-1"><a aria-hidden="true" href="#cb3-1" tabindex="-1"></a>C<span class="op">:</span>\Users\User<span class="op">&gt;</span> python <span class="op">-</span>m pip install <span class="op">--</span>upgrade radicale<span class="op">==</span>2<span class="op">.</span><span class="fu">1</span><span class="op">.*</span></span>
<span id="cb3-2"><a aria-hidden="true" href="#cb3-2" tabindex="-1"></a>C<span class="op">:</span>\Users\User<span class="op">&gt;</span> python <span class="op">-</span>m radicale <span class="op">--</span>config <span class="st">""</span> <span class="op">--</span>storage<span class="op">-</span>filesystem<span class="op">-</span>folder<span class="op">=~/</span>radicale<span class="op">/</span>collections</span></code></pre></div>
<p>If you are using PowerShell replace <code>--config ""</code> with <code>--config '""'</code>.</p>
<p>Victory! Open <a href="http://localhost:5232/">http://localhost:5232/</a> in your browser! You can login with any username and password.</p>
</section>
@ -513,64 +646,63 @@
<section class="level5" id="documentation/basic-setup/authentication/the-secure-way">
<h5>The secure way <a class="headerlink" href="#documentation/basic-setup/authentication/the-secure-way">&para;</a></h5>
<p>The <code>users</code> file can be created and managed with <a href="https://httpd.apache.org/docs/current/programs/htpasswd.html">htpasswd</a>:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1"></a><span class="co"># Create a new htpasswd file with the user "user1"</span></span>
<span id="cb4-2"><a href="#cb4-2"></a>$ <span class="ex">htpasswd</span> -B -c /path/to/users user1</span>
<span id="cb4-3"><a href="#cb4-3"></a><span class="ex">New</span> password:</span>
<span id="cb4-4"><a href="#cb4-4"></a><span class="ex">Re-type</span> new password:</span>
<span id="cb4-5"><a href="#cb4-5"></a><span class="co"># Add another user</span></span>
<span id="cb4-6"><a href="#cb4-6"></a>$ <span class="ex">htpasswd</span> -B /path/to/users user2</span>
<span id="cb4-7"><a href="#cb4-7"></a><span class="ex">New</span> password:</span>
<span id="cb4-8"><a href="#cb4-8"></a><span class="ex">Re-type</span> new password:</span></code></pre></div>
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a aria-hidden="true" href="#cb4-1" tabindex="-1"></a><span class="co"># Create a new htpasswd file with the user "user1"</span></span>
<span id="cb4-2"><a aria-hidden="true" href="#cb4-2" tabindex="-1"></a><span class="ex">$</span> htpasswd <span class="at">-B</span> <span class="at">-c</span> /path/to/users user1</span>
<span id="cb4-3"><a aria-hidden="true" href="#cb4-3" tabindex="-1"></a><span class="ex">New</span> password:</span>
<span id="cb4-4"><a aria-hidden="true" href="#cb4-4" tabindex="-1"></a><span class="ex">Re-type</span> new password:</span>
<span id="cb4-5"><a aria-hidden="true" href="#cb4-5" tabindex="-1"></a><span class="co"># Add another user</span></span>
<span id="cb4-6"><a aria-hidden="true" href="#cb4-6" tabindex="-1"></a><span class="ex">$</span> htpasswd <span class="at">-B</span> /path/to/users user2</span>
<span id="cb4-7"><a aria-hidden="true" href="#cb4-7" tabindex="-1"></a><span class="ex">New</span> password:</span>
<span id="cb4-8"><a aria-hidden="true" href="#cb4-8" tabindex="-1"></a><span class="ex">Re-type</span> new password:</span></code></pre></div>
<p><strong>bcrypt</strong> is used to secure the passwords. Radicale requires additional dependencies for this encryption method:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1"></a>$ <span class="ex">python3</span> -m pip install --upgrade radicale[bcrypt]==2.1.*</span></code></pre></div>
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a aria-hidden="true" href="#cb5-1" tabindex="-1"></a><span class="ex">$</span> python3 <span class="at">-m</span> pip install <span class="at">--upgrade</span> radicale[bcrypt]==2.1.<span class="pp">*</span></span></code></pre></div>
<p>Authentication can be enabled with the following configuration:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb6-1"><a href="#cb6-1"></a><span class="kw">[auth]</span></span>
<span id="cb6-2"><a href="#cb6-2"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb6-3"><a href="#cb6-3"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> /path/to/users</span></span>
<span id="cb6-4"><a href="#cb6-4"></a><span class="co"># encryption method used in the htpasswd file</span></span>
<span id="cb6-5"><a href="#cb6-5"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> bcrypt</span></span></code></pre></div>
<div class="sourceCode" id="cb6"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb6-1"><a aria-hidden="true" href="#cb6-1" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb6-2"><a aria-hidden="true" href="#cb6-2" tabindex="-1"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb6-3"><a aria-hidden="true" href="#cb6-3" tabindex="-1"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> /path/to/users</span></span>
<span id="cb6-4"><a aria-hidden="true" href="#cb6-4" tabindex="-1"></a><span class="co"># encryption method used in the htpasswd file</span></span>
<span id="cb6-5"><a aria-hidden="true" href="#cb6-5" tabindex="-1"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> bcrypt</span></span></code></pre></div>
</section>
<section class="level5" id="documentation/basic-setup/authentication/the-simple-but-insecure-way">
<h5>The simple but insecure way <a class="headerlink" href="#documentation/basic-setup/authentication/the-simple-but-insecure-way">&para;</a></h5>
<p>Create the <code>users</code> file by hand with lines containing the user name and password separated by <code>:</code>. Example:</p>
<pre class="htpasswd"><code>user1:password1
user2:password2
</code></pre>
user2:password2</code></pre>
<p>Authentication can be enabled with the following configuration:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb8-1"><a href="#cb8-1"></a><span class="kw">[auth]</span></span>
<span id="cb8-2"><a href="#cb8-2"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb8-3"><a href="#cb8-3"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> /path/to/users</span></span>
<span id="cb8-4"><a href="#cb8-4"></a><span class="co"># encryption method used in the htpasswd file</span></span>
<span id="cb8-5"><a href="#cb8-5"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> plain</span></span></code></pre></div>
<div class="sourceCode" id="cb8"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb8-1"><a aria-hidden="true" href="#cb8-1" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb8-2"><a aria-hidden="true" href="#cb8-2" tabindex="-1"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb8-3"><a aria-hidden="true" href="#cb8-3" tabindex="-1"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> /path/to/users</span></span>
<span id="cb8-4"><a aria-hidden="true" href="#cb8-4" tabindex="-1"></a><span class="co"># encryption method used in the htpasswd file</span></span>
<span id="cb8-5"><a aria-hidden="true" href="#cb8-5" tabindex="-1"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> plain</span></span></code></pre></div>
</section>
</section>
<section class="level4" id="documentation/basic-setup/addresses">
<h4>Addresses <a class="headerlink" href="#documentation/basic-setup/addresses">&para;</a></h4>
<p>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:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb9-1"><a href="#cb9-1"></a><span class="kw">[server]</span></span>
<span id="cb9-2"><a href="#cb9-2"></a><span class="dt">hosts </span><span class="ot">=</span><span class="st"> </span><span class="dv">0</span><span class="st">.</span><span class="dv">0</span><span class="st">.</span><span class="fl">0.0</span><span class="st">:</span><span class="dv">5232</span></span></code></pre></div>
<div class="sourceCode" id="cb9"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb9-1"><a aria-hidden="true" href="#cb9-1" tabindex="-1"></a><span class="kw">[server]</span></span>
<span id="cb9-2"><a aria-hidden="true" href="#cb9-2" tabindex="-1"></a><span class="dt">hosts </span><span class="ot">=</span><span class="st"> 0.0.0.0:5232</span></span></code></pre></div>
<p>More addresses can be added (separated by commas).</p>
</section>
<section class="level4" id="documentation/basic-setup/storage">
<h4>Storage <a class="headerlink" href="#documentation/basic-setup/storage">&para;</a></h4>
<p>Data is stored in the folder <code>/var/lib/radicale/collections</code>. The path can be changed with the following configuration:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb10-1"><a href="#cb10-1"></a><span class="kw">[storage]</span></span>
<span id="cb10-2"><a href="#cb10-2"></a><span class="dt">filesystem_folder </span><span class="ot">=</span><span class="st"> /path/to/storage</span></span></code></pre></div>
<div class="sourceCode" id="cb10"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb10-1"><a aria-hidden="true" href="#cb10-1" tabindex="-1"></a><span class="kw">[storage]</span></span>
<span id="cb10-2"><a aria-hidden="true" href="#cb10-2" tabindex="-1"></a><span class="dt">filesystem_folder </span><span class="ot">=</span><span class="st"> /path/to/storage</span></span></code></pre></div>
<p><strong>Security:</strong> 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 <strong>Running as a service</strong> section.</p>
</section>
<section class="level4" id="documentation/basic-setup/limits">
<h4>Limits <a class="headerlink" href="#documentation/basic-setup/limits">&para;</a></h4>
<p>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.</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb11-1"><a href="#cb11-1"></a><span class="kw">[server]</span></span>
<span id="cb11-2"><a href="#cb11-2"></a><span class="dt">max_connections </span><span class="ot">=</span><span class="st"> </span><span class="dv">20</span></span>
<span id="cb11-3"><a href="#cb11-3"></a><span class="co"># 100 Megabyte</span></span>
<span id="cb11-4"><a href="#cb11-4"></a><span class="dt">max_content_length </span><span class="ot">=</span><span class="st"> </span><span class="dv">100000000</span></span>
<span id="cb11-5"><a href="#cb11-5"></a><span class="co"># 30 seconds</span></span>
<span id="cb11-6"><a href="#cb11-6"></a><span class="dt">timeout </span><span class="ot">=</span><span class="st"> </span><span class="dv">30</span></span>
<span id="cb11-7"><a href="#cb11-7"></a></span>
<span id="cb11-8"><a href="#cb11-8"></a><span class="kw">[auth]</span></span>
<span id="cb11-9"><a href="#cb11-9"></a><span class="co"># Average delay after failed login attempts in seconds</span></span>
<span id="cb11-10"><a href="#cb11-10"></a><span class="dt">delay </span><span class="ot">=</span><span class="st"> </span><span class="dv">1</span></span></code></pre></div>
<div class="sourceCode" id="cb11"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb11-1"><a aria-hidden="true" href="#cb11-1" tabindex="-1"></a><span class="kw">[server]</span></span>
<span id="cb11-2"><a aria-hidden="true" href="#cb11-2" tabindex="-1"></a><span class="dt">max_connections </span><span class="ot">=</span><span class="st"> </span><span class="dv">20</span></span>
<span id="cb11-3"><a aria-hidden="true" href="#cb11-3" tabindex="-1"></a><span class="co"># 100 Megabyte</span></span>
<span id="cb11-4"><a aria-hidden="true" href="#cb11-4" tabindex="-1"></a><span class="dt">max_content_length </span><span class="ot">=</span><span class="st"> </span><span class="dv">100000000</span></span>
<span id="cb11-5"><a aria-hidden="true" href="#cb11-5" tabindex="-1"></a><span class="co"># 30 seconds</span></span>
<span id="cb11-6"><a aria-hidden="true" href="#cb11-6" tabindex="-1"></a><span class="dt">timeout </span><span class="ot">=</span><span class="st"> </span><span class="dv">30</span></span>
<span id="cb11-7"><a aria-hidden="true" href="#cb11-7" tabindex="-1"></a></span>
<span id="cb11-8"><a aria-hidden="true" href="#cb11-8" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb11-9"><a aria-hidden="true" href="#cb11-9" tabindex="-1"></a><span class="co"># Average delay after failed login attempts in seconds</span></span>
<span id="cb11-10"><a aria-hidden="true" href="#cb11-10" tabindex="-1"></a><span class="dt">delay </span><span class="ot">=</span><span class="st"> </span><span class="dv">1</span></span></code></pre></div>
</section>
<section class="level4" id="documentation/basic-setup/running-as-a-service">
<h4>Running as a service <a class="headerlink" href="#documentation/basic-setup/running-as-a-service">&para;</a></h4>
@ -578,65 +710,65 @@ user2:password2
<section class="level5" id="documentation/basic-setup/running-as-a-service/linux-with-systemd-as-a-user">
<h5>Linux with systemd as a user <a class="headerlink" href="#documentation/basic-setup/running-as-a-service/linux-with-systemd-as-a-user">&para;</a></h5>
<p>Create the file <code>~/.config/systemd/user/radicale.service</code>:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb12-1"><a href="#cb12-1"></a><span class="kw">[Unit]</span></span>
<span id="cb12-2"><a href="#cb12-2"></a><span class="dt">Description</span><span class="ot">=</span><span class="st">A simple CalDAV (calendar) and CardDAV (contact) server</span></span>
<span id="cb12-3"><a href="#cb12-3"></a></span>
<span id="cb12-4"><a href="#cb12-4"></a><span class="kw">[Service]</span></span>
<span id="cb12-5"><a href="#cb12-5"></a><span class="dt">ExecStart</span><span class="ot">=</span><span class="st">/usr/bin/env python3 -m radicale</span></span>
<span id="cb12-6"><a href="#cb12-6"></a><span class="dt">Restart</span><span class="ot">=</span><span class="kw">on</span><span class="st">-failure</span></span>
<span id="cb12-7"><a href="#cb12-7"></a></span>
<span id="cb12-8"><a href="#cb12-8"></a><span class="kw">[Install]</span></span>
<span id="cb12-9"><a href="#cb12-9"></a><span class="dt">WantedBy</span><span class="ot">=</span><span class="kw">default</span><span class="st">.target</span></span></code></pre></div>
<div class="sourceCode" id="cb12"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb12-1"><a aria-hidden="true" href="#cb12-1" tabindex="-1"></a><span class="kw">[Unit]</span></span>
<span id="cb12-2"><a aria-hidden="true" href="#cb12-2" tabindex="-1"></a><span class="dt">Description</span><span class="ot">=</span><span class="st">A simple CalDAV (calendar) and CardDAV (contact) server</span></span>
<span id="cb12-3"><a aria-hidden="true" href="#cb12-3" tabindex="-1"></a></span>
<span id="cb12-4"><a aria-hidden="true" href="#cb12-4" tabindex="-1"></a><span class="kw">[Service]</span></span>
<span id="cb12-5"><a aria-hidden="true" href="#cb12-5" tabindex="-1"></a><span class="dt">ExecStart</span><span class="ot">=</span><span class="st">/usr/bin/env python3 -m radicale</span></span>
<span id="cb12-6"><a aria-hidden="true" href="#cb12-6" tabindex="-1"></a><span class="dt">Restart</span><span class="ot">=</span><span class="st">on-failure</span></span>
<span id="cb12-7"><a aria-hidden="true" href="#cb12-7" tabindex="-1"></a></span>
<span id="cb12-8"><a aria-hidden="true" href="#cb12-8" tabindex="-1"></a><span class="kw">[Install]</span></span>
<span id="cb12-9"><a aria-hidden="true" href="#cb12-9" tabindex="-1"></a><span class="dt">WantedBy</span><span class="ot">=</span><span class="st">default.target</span></span></code></pre></div>
<p>Radicale will load the configuration file from <code>~/.config/radicale/config</code>. You should set the configuration option <code>filesystem_folder</code> in the <code>storage</code> section to something like <code>~/.var/lib/radicale/collections</code>.</p>
<p>To enable and manage the service run:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb13-1"><a href="#cb13-1"></a><span class="co"># Enable the service</span></span>
<span id="cb13-2"><a href="#cb13-2"></a>$ <span class="ex">systemctl</span> --user enable radicale</span>
<span id="cb13-3"><a href="#cb13-3"></a><span class="co"># Start the service</span></span>
<span id="cb13-4"><a href="#cb13-4"></a>$ <span class="ex">systemctl</span> --user start radicale</span>
<span id="cb13-5"><a href="#cb13-5"></a><span class="co"># Check the status of the service</span></span>
<span id="cb13-6"><a href="#cb13-6"></a>$ <span class="ex">systemctl</span> --user status radicale</span>
<span id="cb13-7"><a href="#cb13-7"></a><span class="co"># View all log messages</span></span>
<span id="cb13-8"><a href="#cb13-8"></a>$ <span class="ex">journalctl</span> --user --unit radicale.service</span></code></pre></div>
<div class="sourceCode" id="cb13"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb13-1"><a aria-hidden="true" href="#cb13-1" tabindex="-1"></a><span class="co"># Enable the service</span></span>
<span id="cb13-2"><a aria-hidden="true" href="#cb13-2" tabindex="-1"></a><span class="ex">$</span> systemctl <span class="at">--user</span> enable radicale</span>
<span id="cb13-3"><a aria-hidden="true" href="#cb13-3" tabindex="-1"></a><span class="co"># Start the service</span></span>
<span id="cb13-4"><a aria-hidden="true" href="#cb13-4" tabindex="-1"></a><span class="ex">$</span> systemctl <span class="at">--user</span> start radicale</span>
<span id="cb13-5"><a aria-hidden="true" href="#cb13-5" tabindex="-1"></a><span class="co"># Check the status of the service</span></span>
<span id="cb13-6"><a aria-hidden="true" href="#cb13-6" tabindex="-1"></a><span class="ex">$</span> systemctl <span class="at">--user</span> status radicale</span>
<span id="cb13-7"><a aria-hidden="true" href="#cb13-7" tabindex="-1"></a><span class="co"># View all log messages</span></span>
<span id="cb13-8"><a aria-hidden="true" href="#cb13-8" tabindex="-1"></a><span class="ex">$</span> journalctl <span class="at">--user</span> <span class="at">--unit</span> radicale.service</span></code></pre></div>
</section>
<section class="level5" id="documentation/basic-setup/running-as-a-service/linux-with-systemd-system-wide">
<h5>Linux with systemd system-wide <a class="headerlink" href="#documentation/basic-setup/running-as-a-service/linux-with-systemd-system-wide">&para;</a></h5>
<p>Create the <strong>radicale</strong> user and group for the Radicale service. (Run <code>useradd --system --home-dir / --shell /sbin/nologin radicale</code> as root.) The storage folder must be writable by <strong>radicale</strong>. (Run <code>mkdir -p /var/lib/radicale/collections &amp;&amp; chown -R radicale:radicale /var/lib/radicale/collections</code> as root.)</p>
<p><strong>Security:</strong> The storage should not be readable by others. (Run <code>chmod -R o= /var/lib/radicale/collections</code> as root.)</p>
<p>Create the file <code>/etc/systemd/system/radicale.service</code>:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb14-1"><a href="#cb14-1"></a><span class="kw">[Unit]</span></span>
<span id="cb14-2"><a href="#cb14-2"></a><span class="dt">Description</span><span class="ot">=</span><span class="st">A simple CalDAV (calendar) and CardDAV (contact) server</span></span>
<span id="cb14-3"><a href="#cb14-3"></a><span class="dt">After</span><span class="ot">=</span><span class="st">network.target</span></span>
<span id="cb14-4"><a href="#cb14-4"></a><span class="dt">Requires</span><span class="ot">=</span><span class="st">network.target</span></span>
<span id="cb14-5"><a href="#cb14-5"></a></span>
<span id="cb14-6"><a href="#cb14-6"></a><span class="kw">[Service]</span></span>
<span id="cb14-7"><a href="#cb14-7"></a><span class="dt">ExecStart</span><span class="ot">=</span><span class="st">/usr/bin/env python3 -m radicale</span></span>
<span id="cb14-8"><a href="#cb14-8"></a><span class="dt">Restart</span><span class="ot">=</span><span class="kw">on</span><span class="st">-failure</span></span>
<span id="cb14-9"><a href="#cb14-9"></a><span class="dt">User</span><span class="ot">=</span><span class="st">radicale</span></span>
<span id="cb14-10"><a href="#cb14-10"></a><span class="co"># Deny other users access to the calendar data</span></span>
<span id="cb14-11"><a href="#cb14-11"></a><span class="dt">UMask</span><span class="ot">=</span><span class="dv">0027</span></span>
<span id="cb14-12"><a href="#cb14-12"></a><span class="co"># Optional security settings</span></span>
<span id="cb14-13"><a href="#cb14-13"></a><span class="dt">PrivateTmp</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb14-14"><a href="#cb14-14"></a><span class="dt">ProtectSystem</span><span class="ot">=</span><span class="st">strict</span></span>
<span id="cb14-15"><a href="#cb14-15"></a><span class="dt">ProtectHome</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb14-16"><a href="#cb14-16"></a><span class="dt">PrivateDevices</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb14-17"><a href="#cb14-17"></a><span class="dt">ProtectKernelTunables</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb14-18"><a href="#cb14-18"></a><span class="dt">ProtectKernelModules</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb14-19"><a href="#cb14-19"></a><span class="dt">ProtectControlGroups</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb14-20"><a href="#cb14-20"></a><span class="dt">NoNewPrivileges</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb14-21"><a href="#cb14-21"></a><span class="dt">ReadWritePaths</span><span class="ot">=</span><span class="st">/var/lib/radicale/collections</span></span>
<span id="cb14-22"><a href="#cb14-22"></a></span>
<span id="cb14-23"><a href="#cb14-23"></a><span class="kw">[Install]</span></span>
<span id="cb14-24"><a href="#cb14-24"></a><span class="dt">WantedBy</span><span class="ot">=</span><span class="st">multi-user.target</span></span></code></pre></div>
<div class="sourceCode" id="cb14"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb14-1"><a aria-hidden="true" href="#cb14-1" tabindex="-1"></a><span class="kw">[Unit]</span></span>
<span id="cb14-2"><a aria-hidden="true" href="#cb14-2" tabindex="-1"></a><span class="dt">Description</span><span class="ot">=</span><span class="st">A simple CalDAV (calendar) and CardDAV (contact) server</span></span>
<span id="cb14-3"><a aria-hidden="true" href="#cb14-3" tabindex="-1"></a><span class="dt">After</span><span class="ot">=</span><span class="st">network.target</span></span>
<span id="cb14-4"><a aria-hidden="true" href="#cb14-4" tabindex="-1"></a><span class="dt">Requires</span><span class="ot">=</span><span class="st">network.target</span></span>
<span id="cb14-5"><a aria-hidden="true" href="#cb14-5" tabindex="-1"></a></span>
<span id="cb14-6"><a aria-hidden="true" href="#cb14-6" tabindex="-1"></a><span class="kw">[Service]</span></span>
<span id="cb14-7"><a aria-hidden="true" href="#cb14-7" tabindex="-1"></a><span class="dt">ExecStart</span><span class="ot">=</span><span class="st">/usr/bin/env python3 -m radicale</span></span>
<span id="cb14-8"><a aria-hidden="true" href="#cb14-8" tabindex="-1"></a><span class="dt">Restart</span><span class="ot">=</span><span class="st">on-failure</span></span>
<span id="cb14-9"><a aria-hidden="true" href="#cb14-9" tabindex="-1"></a><span class="dt">User</span><span class="ot">=</span><span class="st">radicale</span></span>
<span id="cb14-10"><a aria-hidden="true" href="#cb14-10" tabindex="-1"></a><span class="co"># Deny other users access to the calendar data</span></span>
<span id="cb14-11"><a aria-hidden="true" href="#cb14-11" tabindex="-1"></a><span class="dt">UMask</span><span class="ot">=</span><span class="dv">0027</span></span>
<span id="cb14-12"><a aria-hidden="true" href="#cb14-12" tabindex="-1"></a><span class="co"># Optional security settings</span></span>
<span id="cb14-13"><a aria-hidden="true" href="#cb14-13" tabindex="-1"></a><span class="dt">PrivateTmp</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb14-14"><a aria-hidden="true" href="#cb14-14" tabindex="-1"></a><span class="dt">ProtectSystem</span><span class="ot">=</span><span class="st">strict</span></span>
<span id="cb14-15"><a aria-hidden="true" href="#cb14-15" tabindex="-1"></a><span class="dt">ProtectHome</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb14-16"><a aria-hidden="true" href="#cb14-16" tabindex="-1"></a><span class="dt">PrivateDevices</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb14-17"><a aria-hidden="true" href="#cb14-17" tabindex="-1"></a><span class="dt">ProtectKernelTunables</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb14-18"><a aria-hidden="true" href="#cb14-18" tabindex="-1"></a><span class="dt">ProtectKernelModules</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb14-19"><a aria-hidden="true" href="#cb14-19" tabindex="-1"></a><span class="dt">ProtectControlGroups</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb14-20"><a aria-hidden="true" href="#cb14-20" tabindex="-1"></a><span class="dt">NoNewPrivileges</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb14-21"><a aria-hidden="true" href="#cb14-21" tabindex="-1"></a><span class="dt">ReadWritePaths</span><span class="ot">=</span><span class="st">/var/lib/radicale/collections</span></span>
<span id="cb14-22"><a aria-hidden="true" href="#cb14-22" tabindex="-1"></a></span>
<span id="cb14-23"><a aria-hidden="true" href="#cb14-23" tabindex="-1"></a><span class="kw">[Install]</span></span>
<span id="cb14-24"><a aria-hidden="true" href="#cb14-24" tabindex="-1"></a><span class="dt">WantedBy</span><span class="ot">=</span><span class="st">multi-user.target</span></span></code></pre></div>
<p>Radicale will load the configuration file from <code>/etc/radicale/config</code>.</p>
<p>To enable and manage the service run:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb15-1"><a href="#cb15-1"></a><span class="co"># Enable the service</span></span>
<span id="cb15-2"><a href="#cb15-2"></a>$ <span class="ex">systemctl</span> enable radicale</span>
<span id="cb15-3"><a href="#cb15-3"></a><span class="co"># Start the service</span></span>
<span id="cb15-4"><a href="#cb15-4"></a>$ <span class="ex">systemctl</span> start radicale</span>
<span id="cb15-5"><a href="#cb15-5"></a><span class="co"># Check the status of the service</span></span>
<span id="cb15-6"><a href="#cb15-6"></a>$ <span class="ex">systemctl</span> status radicale</span>
<span id="cb15-7"><a href="#cb15-7"></a><span class="co"># View all log messages</span></span>
<span id="cb15-8"><a href="#cb15-8"></a>$ <span class="ex">journalctl</span> --unit radicale.service</span></code></pre></div>
<div class="sourceCode" id="cb15"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb15-1"><a aria-hidden="true" href="#cb15-1" tabindex="-1"></a><span class="co"># Enable the service</span></span>
<span id="cb15-2"><a aria-hidden="true" href="#cb15-2" tabindex="-1"></a><span class="ex">$</span> systemctl enable radicale</span>
<span id="cb15-3"><a aria-hidden="true" href="#cb15-3" tabindex="-1"></a><span class="co"># Start the service</span></span>
<span id="cb15-4"><a aria-hidden="true" href="#cb15-4" tabindex="-1"></a><span class="ex">$</span> systemctl start radicale</span>
<span id="cb15-5"><a aria-hidden="true" href="#cb15-5" tabindex="-1"></a><span class="co"># Check the status of the service</span></span>
<span id="cb15-6"><a aria-hidden="true" href="#cb15-6" tabindex="-1"></a><span class="ex">$</span> systemctl status radicale</span>
<span id="cb15-7"><a aria-hidden="true" href="#cb15-7" tabindex="-1"></a><span class="co"># View all log messages</span></span>
<span id="cb15-8"><a aria-hidden="true" href="#cb15-8" tabindex="-1"></a><span class="ex">$</span> journalctl <span class="at">--unit</span> radicale.service</span></code></pre></div>
</section>
</section>
<section class="level4" id="documentation/basic-setup/macos-with-launchd">
@ -679,17 +811,16 @@ user2:password2
proxy_set_header X-Script-Name /radicale;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_header Authorization;
}
</code></pre>
}</code></pre>
<p>Example <strong>Apache</strong> configuration:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb17-1"><a href="#cb17-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb17-2"><a href="#cb17-2"></a>RewriteRule<span class="st"> ^/radicale$ /radicale/ [R,L]</span></span>
<span id="cb17-3"><a href="#cb17-3"></a></span>
<span id="cb17-4"><a href="#cb17-4"></a><span class="fu">&lt;Location</span><span class="at"> "/radicale/"</span><span class="fu">&gt;</span></span>
<span id="cb17-5"><a href="#cb17-5"></a> ProxyPass<span class="st"> http://localhost:5232/ retry=0</span></span>
<span id="cb17-6"><a href="#cb17-6"></a> ProxyPassReverse<span class="st"> http://localhost:5232/</span></span>
<span id="cb17-7"><a href="#cb17-7"></a> RequestHeader<span class="st"> set X-Script-Name /radicale/</span></span>
<span id="cb17-8"><a href="#cb17-8"></a><span class="fu">&lt;/Location&gt;</span></span></code></pre></div>
<div class="sourceCode" id="cb17"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb17-1"><a aria-hidden="true" href="#cb17-1" tabindex="-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb17-2"><a aria-hidden="true" href="#cb17-2" tabindex="-1"></a>RewriteRule<span class="st"> ^/radicale$ /radicale/ [R,L]</span></span>
<span id="cb17-3"><a aria-hidden="true" href="#cb17-3" tabindex="-1"></a></span>
<span id="cb17-4"><a aria-hidden="true" href="#cb17-4" tabindex="-1"></a><span class="fu">&lt;Location</span><span class="at"> "/radicale/"</span><span class="fu">&gt;</span></span>
<span id="cb17-5"><a aria-hidden="true" href="#cb17-5" tabindex="-1"></a> ProxyPass<span class="st"> http://localhost:5232/ retry=0</span></span>
<span id="cb17-6"><a aria-hidden="true" href="#cb17-6" tabindex="-1"></a> ProxyPassReverse<span class="st"> http://localhost:5232/</span></span>
<span id="cb17-7"><a aria-hidden="true" href="#cb17-7" tabindex="-1"></a> RequestHeader<span class="st"> set X-Script-Name /radicale/</span></span>
<span id="cb17-8"><a aria-hidden="true" href="#cb17-8" tabindex="-1"></a><span class="fu">&lt;/Location&gt;</span></span></code></pre></div>
<p>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.</p>
<section class="level4" id="documentation/reverse-proxy/manage-user-accounts-with-the-reverse-proxy">
<h4>Manage user accounts with the reverse proxy <a class="headerlink" href="#documentation/reverse-proxy/manage-user-accounts-with-the-reverse-proxy">&para;</a></h4>
@ -702,36 +833,35 @@ user2:password2
proxy_set_header X-Remote-User $remote_user;
auth_basic "Radicale - Password Required";
auth_basic_user_file /etc/nginx/htpasswd;
}
</code></pre>
}</code></pre>
<p>Example <strong>Apache</strong> configuration:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb19-1"><a href="#cb19-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb19-2"><a href="#cb19-2"></a>RewriteRule<span class="st"> ^/radicale$ /radicale/ [R,L]</span></span>
<span id="cb19-3"><a href="#cb19-3"></a></span>
<span id="cb19-4"><a href="#cb19-4"></a><span class="fu">&lt;Location</span><span class="at"> "/radicale/"</span><span class="fu">&gt;</span></span>
<span id="cb19-5"><a href="#cb19-5"></a> <span class="ex">AuthType</span><span class="ch"> </span><span class="kw">Basic</span></span>
<span id="cb19-6"><a href="#cb19-6"></a> AuthName<span class="st"> "Radicale - Password Required"</span></span>
<span id="cb19-7"><a href="#cb19-7"></a> AuthUserFile<span class="st"> "/etc/radicale/htpasswd"</span></span>
<span id="cb19-8"><a href="#cb19-8"></a> Require<span class="st"> valid-user</span></span>
<span id="cb19-9"><a href="#cb19-9"></a></span>
<span id="cb19-10"><a href="#cb19-10"></a> ProxyPass<span class="st"> http://localhost:5232/ retry=0</span></span>
<span id="cb19-11"><a href="#cb19-11"></a> ProxyPassReverse<span class="st"> http://localhost:5232/</span></span>
<span id="cb19-12"><a href="#cb19-12"></a> RequestHeader<span class="st"> set X-Script-Name /radicale/</span></span>
<span id="cb19-13"><a href="#cb19-13"></a> RequestHeader<span class="st"> set X-Remote-User expr=%{REMOTE_USER}</span></span>
<span id="cb19-14"><a href="#cb19-14"></a><span class="fu">&lt;/Location&gt;</span></span></code></pre></div>
<div class="sourceCode" id="cb19"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb19-1"><a aria-hidden="true" href="#cb19-1" tabindex="-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb19-2"><a aria-hidden="true" href="#cb19-2" tabindex="-1"></a>RewriteRule<span class="st"> ^/radicale$ /radicale/ [R,L]</span></span>
<span id="cb19-3"><a aria-hidden="true" href="#cb19-3" tabindex="-1"></a></span>
<span id="cb19-4"><a aria-hidden="true" href="#cb19-4" tabindex="-1"></a><span class="fu">&lt;Location</span><span class="at"> "/radicale/"</span><span class="fu">&gt;</span></span>
<span id="cb19-5"><a aria-hidden="true" href="#cb19-5" tabindex="-1"></a> <span class="ex">AuthType</span><span class="ch"> </span><span class="kw">Basic</span></span>
<span id="cb19-6"><a aria-hidden="true" href="#cb19-6" tabindex="-1"></a> AuthName<span class="st"> "Radicale - Password Required"</span></span>
<span id="cb19-7"><a aria-hidden="true" href="#cb19-7" tabindex="-1"></a> AuthUserFile<span class="st"> "/etc/radicale/htpasswd"</span></span>
<span id="cb19-8"><a aria-hidden="true" href="#cb19-8" tabindex="-1"></a> Require<span class="st"> valid-user</span></span>
<span id="cb19-9"><a aria-hidden="true" href="#cb19-9" tabindex="-1"></a></span>
<span id="cb19-10"><a aria-hidden="true" href="#cb19-10" tabindex="-1"></a> ProxyPass<span class="st"> http://localhost:5232/ retry=0</span></span>
<span id="cb19-11"><a aria-hidden="true" href="#cb19-11" tabindex="-1"></a> ProxyPassReverse<span class="st"> http://localhost:5232/</span></span>
<span id="cb19-12"><a aria-hidden="true" href="#cb19-12" tabindex="-1"></a> RequestHeader<span class="st"> set X-Script-Name /radicale/</span></span>
<span id="cb19-13"><a aria-hidden="true" href="#cb19-13" tabindex="-1"></a> RequestHeader<span class="st"> set X-Remote-User expr=%{REMOTE_USER}</span></span>
<span id="cb19-14"><a aria-hidden="true" href="#cb19-14" tabindex="-1"></a><span class="fu">&lt;/Location&gt;</span></span></code></pre></div>
<p><strong>Security:</strong> Untrusted clients should not be able to access the Radicale server directly. Otherwise, they can authenticate as any user.</p>
</section>
<section class="level4" id="documentation/reverse-proxy/secure-connection-between-radicale-and-the-reverse-proxy">
<h4>Secure connection between Radicale and the reverse proxy <a class="headerlink" href="#documentation/reverse-proxy/secure-connection-between-radicale-and-the-reverse-proxy">&para;</a></h4>
<p>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.</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb20-1"><a href="#cb20-1"></a>$ <span class="ex">openssl</span> req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem -nodes -days 9999</span>
<span id="cb20-2"><a href="#cb20-2"></a>$ <span class="ex">openssl</span> req -x509 -newkey rsa:4096 -keyout client_key.pem -out client_cert.pem -nodes -days 9999</span></code></pre></div>
<div class="sourceCode" id="cb20"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb20-1"><a aria-hidden="true" href="#cb20-1" tabindex="-1"></a><span class="ex">$</span> openssl req <span class="at">-x509</span> <span class="at">-newkey</span> rsa:4096 <span class="at">-keyout</span> server_key.pem <span class="at">-out</span> server_cert.pem <span class="at">-nodes</span> <span class="at">-days</span> 9999</span>
<span id="cb20-2"><a aria-hidden="true" href="#cb20-2" tabindex="-1"></a><span class="ex">$</span> openssl req <span class="at">-x509</span> <span class="at">-newkey</span> rsa:4096 <span class="at">-keyout</span> client_key.pem <span class="at">-out</span> client_cert.pem <span class="at">-nodes</span> <span class="at">-days</span> 9999</span></code></pre></div>
<p>Use the following configuration for Radicale:</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb21-1"><a href="#cb21-1"></a><span class="kw">[server]</span></span>
<span id="cb21-2"><a href="#cb21-2"></a><span class="dt">ssl </span><span class="ot">=</span><span class="st"> </span><span class="kw">True</span></span>
<span id="cb21-3"><a href="#cb21-3"></a><span class="dt">certificate </span><span class="ot">=</span><span class="st"> /path/to/server_cert.pem</span></span>
<span id="cb21-4"><a href="#cb21-4"></a><span class="dt">key </span><span class="ot">=</span><span class="st"> /path/to/server_key.pem</span></span>
<span id="cb21-5"><a href="#cb21-5"></a><span class="dt">certificate_authority </span><span class="ot">=</span><span class="st"> /path/to/client_cert.pem</span></span></code></pre></div>
<div class="sourceCode" id="cb21"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb21-1"><a aria-hidden="true" href="#cb21-1" tabindex="-1"></a><span class="kw">[server]</span></span>
<span id="cb21-2"><a aria-hidden="true" href="#cb21-2" tabindex="-1"></a><span class="dt">ssl </span><span class="ot">=</span><span class="st"> </span><span class="kw">True</span></span>
<span id="cb21-3"><a aria-hidden="true" href="#cb21-3" tabindex="-1"></a><span class="dt">certificate </span><span class="ot">=</span><span class="st"> /path/to/server_cert.pem</span></span>
<span id="cb21-4"><a aria-hidden="true" href="#cb21-4" tabindex="-1"></a><span class="dt">key </span><span class="ot">=</span><span class="st"> /path/to/server_key.pem</span></span>
<span id="cb21-5"><a aria-hidden="true" href="#cb21-5" tabindex="-1"></a><span class="dt">certificate_authority </span><span class="ot">=</span><span class="st"> /path/to/client_cert.pem</span></span></code></pre></div>
<p>Example <strong>nginx</strong> configuration:</p>
<pre class="nginx"><code>location /radicale/ {
proxy_pass https://localhost:5232/;
@ -740,8 +870,7 @@ user2:password2
proxy_ssl_certificate /path/to/client_cert.pem;
proxy_ssl_certificate_key /path/to/client_key.pem;
proxy_ssl_trusted_certificate /path/to/server_cert.pem;
}
</code></pre>
}</code></pre>
</section>
</section>
<section class="level3" id="documentation/wsgi">
@ -751,14 +880,14 @@ user2:password2
<p>Be reminded that Radicale's default configuration enforces limits on the maximum upload file size.</p>
<p><strong>Security:</strong> The <code>None</code> authentication type disables all rights checking. Don't use it with <code>REMOTE_USER</code>. Use <code>remote_user</code> instead.</p>
<p>Example <strong>uWSGI</strong> configuration:</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb23-1"><a href="#cb23-1"></a><span class="kw">[uwsgi]</span></span>
<span id="cb23-2"><a href="#cb23-2"></a><span class="dt">http-socket </span><span class="ot">=</span><span class="st"> </span><span class="dv">127</span><span class="st">.</span><span class="dv">0</span><span class="st">.</span><span class="fl">0.1</span><span class="st">:</span><span class="dv">5232</span></span>
<span id="cb23-3"><a href="#cb23-3"></a><span class="dt">processes </span><span class="ot">=</span><span class="st"> </span><span class="dv">8</span></span>
<span id="cb23-4"><a href="#cb23-4"></a><span class="dt">plugin </span><span class="ot">=</span><span class="st"> python3</span></span>
<span id="cb23-5"><a href="#cb23-5"></a><span class="dt">module </span><span class="ot">=</span><span class="st"> radicale</span></span>
<span id="cb23-6"><a href="#cb23-6"></a><span class="dt">env </span><span class="ot">=</span><span class="st"> RADICALE_CONFIG=/etc/radicale/config</span></span></code></pre></div>
<div class="sourceCode" id="cb23"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb23-1"><a aria-hidden="true" href="#cb23-1" tabindex="-1"></a><span class="kw">[uwsgi]</span></span>
<span id="cb23-2"><a aria-hidden="true" href="#cb23-2" tabindex="-1"></a><span class="dt">http-socket </span><span class="ot">=</span><span class="st"> 127.0.0.1:5232</span></span>
<span id="cb23-3"><a aria-hidden="true" href="#cb23-3" tabindex="-1"></a><span class="dt">processes </span><span class="ot">=</span><span class="st"> </span><span class="dv">8</span></span>
<span id="cb23-4"><a aria-hidden="true" href="#cb23-4" tabindex="-1"></a><span class="dt">plugin </span><span class="ot">=</span><span class="st"> python3</span></span>
<span id="cb23-5"><a aria-hidden="true" href="#cb23-5" tabindex="-1"></a><span class="dt">module </span><span class="ot">=</span><span class="st"> radicale</span></span>
<span id="cb23-6"><a aria-hidden="true" href="#cb23-6" tabindex="-1"></a><span class="dt">env </span><span class="ot">=</span><span class="st"> RADICALE_CONFIG=/etc/radicale/config</span></span></code></pre></div>
<p>Example <strong>Gunicorn</strong> configuration:</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb24-1"><a href="#cb24-1"></a><span class="ex">gunicorn</span> --bind <span class="st">'127.0.0.1:5232'</span> --workers 8 --env <span class="st">'RADICALE_CONFIG=/etc/radicale/config'</span> radicale</span></code></pre></div>
<div class="sourceCode" id="cb24"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb24-1"><a aria-hidden="true" href="#cb24-1" tabindex="-1"></a><span class="ex">gunicorn</span> <span class="at">--bind</span> <span class="st">'127.0.0.1:5232'</span> <span class="at">--workers</span> 8 <span class="at">--env</span> <span class="st">'RADICALE_CONFIG=/etc/radicale/config'</span> radicale</span></code></pre></div>
<section class="level4" id="documentation/wsgi/manage-user-accounts-with-the-wsgi-server">
<h4>Manage user accounts with the WSGI server <a class="headerlink" href="#documentation/wsgi/manage-user-accounts-with-the-wsgi-server">&para;</a></h4>
<p>Set the configuration option <code>type</code> in the <code>auth</code> section to <code>remote_user</code>. Radicale uses the user name provided by the WSGI server and disables authentication over HTTP.</p>
@ -770,10 +899,9 @@ user2:password2
<p>The repository must be initialized by running <code>git init</code> in the file system folder. Internal files of Radicale can be excluded by creating the file <code>.gitignore</code> with the following content:</p>
<pre><code>.Radicale.cache
.Radicale.lock
.Radicale.tmp-*
</code></pre>
.Radicale.tmp-*</code></pre>
<p>The configuration option <code>hook</code> in the <code>storage</code> section must be set to the following command:</p>
<div class="sourceCode" id="cb26"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb26-1"><a href="#cb26-1"></a><span class="fu">git</span> add -A <span class="kw">&amp;&amp;</span> <span class="kw">(</span><span class="fu">git</span> diff --cached --quiet <span class="kw">||</span> <span class="fu">git</span> commit -m <span class="st">"Changes by "</span>%(user<span class="kw">)</span><span class="ex">s</span>)</span></code></pre></div>
<div class="sourceCode" id="cb26"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb26-1"><a aria-hidden="true" href="#cb26-1" tabindex="-1"></a><span class="fu">git</span> add <span class="at">-A</span> <span class="kw">&amp;&amp;</span> <span class="kw">(</span><span class="fu">git</span> diff <span class="at">--cached</span> <span class="at">--quiet</span> <span class="kw">||</span> <span class="fu">git</span> commit <span class="at">-m</span> <span class="st">"Changes by "</span>%<span class="er">(</span><span class="ex">user</span><span class="kw">)</span><span class="ex">s</span><span class="kw">)</span></span></code></pre></div>
<p>The command gets executed after every change to the storage and commits the changes into the <strong>git</strong> repository.</p>
</section>
<section class="level3" id="documentation/clients">
@ -818,53 +946,53 @@ user2:password2
<section class="level5" id="documentation/clients/manual-creation-of-calendars-and-address-books/direct-editing-of-the-storage">
<h5>Direct editing of the storage <a class="headerlink" href="#documentation/clients/manual-creation-of-calendars-and-address-books/direct-editing-of-the-storage">&para;</a></h5>
<p>To create a new collection, you have to create the corresponding folder in the file system storage (e.g. <code>collection-root/user/calendar</code>). To tell Radicale and clients that the collection is a calendar, you have to create the file <code>.Radicale.props</code> with the following content in the folder:</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb27-1"><a href="#cb27-1"></a><span class="fu">{</span><span class="dt">"tag"</span><span class="fu">:</span> <span class="st">"VCALENDAR"</span><span class="fu">}</span></span></code></pre></div>
<div class="sourceCode" id="cb27"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb27-1"><a aria-hidden="true" href="#cb27-1" tabindex="-1"></a><span class="fu">{</span><span class="dt">"tag"</span><span class="fu">:</span> <span class="st">"VCALENDAR"</span><span class="fu">}</span></span></code></pre></div>
<p>The calendar is now available at the URL path <code>/user/calendar</code>. For address books the file must contain:</p>
<div class="sourceCode" id="cb28"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb28-1"><a href="#cb28-1"></a><span class="fu">{</span><span class="dt">"tag"</span><span class="fu">:</span> <span class="st">"VADDRESSBOOK"</span><span class="fu">}</span></span></code></pre></div>
<div class="sourceCode" id="cb28"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb28-1"><a aria-hidden="true" href="#cb28-1" tabindex="-1"></a><span class="fu">{</span><span class="dt">"tag"</span><span class="fu">:</span> <span class="st">"VADDRESSBOOK"</span><span class="fu">}</span></span></code></pre></div>
<p>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 <code>/USERNAME/</code>.</p>
<p>Delete collections by deleting the corresponding folders.</p>
</section>
<section class="level5" id="documentation/clients/manual-creation-of-calendars-and-address-books/http-requests-with-curl">
<h5>HTTP requests with curl <a class="headerlink" href="#documentation/clients/manual-creation-of-calendars-and-address-books/http-requests-with-curl">&para;</a></h5>
<p>To create a new calendar run something like:</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb29-1"><a href="#cb29-1"></a>$ <span class="ex">curl</span> -u user -X MKCOL <span class="st">'http://localhost:5232/user/calendar'</span> --data \</span>
<span id="cb29-2"><a href="#cb29-2"></a><span class="st">'&lt;?xml version="1.0" encoding="UTF-8" ?&gt;</span></span>
<span id="cb29-3"><a href="#cb29-3"></a><span class="st">&lt;create xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:I="http://apple.com/ns/ical/"&gt;</span></span>
<span id="cb29-4"><a href="#cb29-4"></a><span class="st"> &lt;set&gt;</span></span>
<span id="cb29-5"><a href="#cb29-5"></a><span class="st"> &lt;prop&gt;</span></span>
<span id="cb29-6"><a href="#cb29-6"></a><span class="st"> &lt;resourcetype&gt;</span></span>
<span id="cb29-7"><a href="#cb29-7"></a><span class="st"> &lt;collection /&gt;</span></span>
<span id="cb29-8"><a href="#cb29-8"></a><span class="st"> &lt;C:calendar /&gt;</span></span>
<span id="cb29-9"><a href="#cb29-9"></a><span class="st"> &lt;/resourcetype&gt;</span></span>
<span id="cb29-10"><a href="#cb29-10"></a><span class="st"> &lt;C:supported-calendar-component-set&gt;</span></span>
<span id="cb29-11"><a href="#cb29-11"></a><span class="st"> &lt;C:comp name="VEVENT" /&gt;</span></span>
<span id="cb29-12"><a href="#cb29-12"></a><span class="st"> &lt;C:comp name="VJOURNAL" /&gt;</span></span>
<span id="cb29-13"><a href="#cb29-13"></a><span class="st"> &lt;C:comp name="VTODO" /&gt;</span></span>
<span id="cb29-14"><a href="#cb29-14"></a><span class="st"> &lt;/C:supported-calendar-component-set&gt;</span></span>
<span id="cb29-15"><a href="#cb29-15"></a><span class="st"> &lt;displayname&gt;Calendar&lt;/displayname&gt;</span></span>
<span id="cb29-16"><a href="#cb29-16"></a><span class="st"> &lt;C:calendar-description&gt;Example calendar&lt;/C:calendar-description&gt;</span></span>
<span id="cb29-17"><a href="#cb29-17"></a><span class="st"> &lt;I:calendar-color&gt;#ff0000ff&lt;/I:calendar-color&gt;</span></span>
<span id="cb29-18"><a href="#cb29-18"></a><span class="st"> &lt;/prop&gt;</span></span>
<span id="cb29-19"><a href="#cb29-19"></a><span class="st"> &lt;/set&gt;</span></span>
<span id="cb29-20"><a href="#cb29-20"></a><span class="st">&lt;/create&gt;'</span></span></code></pre></div>
<div class="sourceCode" id="cb29"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb29-1"><a aria-hidden="true" href="#cb29-1" tabindex="-1"></a><span class="ex">$</span> curl <span class="at">-u</span> user <span class="at">-X</span> MKCOL <span class="st">'http://localhost:5232/user/calendar'</span> <span class="at">--data</span> <span class="dt">\</span></span>
<span id="cb29-2"><a aria-hidden="true" href="#cb29-2" tabindex="-1"></a><span class="st">'&lt;?xml version="1.0" encoding="UTF-8" ?&gt;</span></span>
<span id="cb29-3"><a aria-hidden="true" href="#cb29-3" tabindex="-1"></a><span class="st">&lt;create xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:I="http://apple.com/ns/ical/"&gt;</span></span>
<span id="cb29-4"><a aria-hidden="true" href="#cb29-4" tabindex="-1"></a><span class="st"> &lt;set&gt;</span></span>
<span id="cb29-5"><a aria-hidden="true" href="#cb29-5" tabindex="-1"></a><span class="st"> &lt;prop&gt;</span></span>
<span id="cb29-6"><a aria-hidden="true" href="#cb29-6" tabindex="-1"></a><span class="st"> &lt;resourcetype&gt;</span></span>
<span id="cb29-7"><a aria-hidden="true" href="#cb29-7" tabindex="-1"></a><span class="st"> &lt;collection /&gt;</span></span>
<span id="cb29-8"><a aria-hidden="true" href="#cb29-8" tabindex="-1"></a><span class="st"> &lt;C:calendar /&gt;</span></span>
<span id="cb29-9"><a aria-hidden="true" href="#cb29-9" tabindex="-1"></a><span class="st"> &lt;/resourcetype&gt;</span></span>
<span id="cb29-10"><a aria-hidden="true" href="#cb29-10" tabindex="-1"></a><span class="st"> &lt;C:supported-calendar-component-set&gt;</span></span>
<span id="cb29-11"><a aria-hidden="true" href="#cb29-11" tabindex="-1"></a><span class="st"> &lt;C:comp name="VEVENT" /&gt;</span></span>
<span id="cb29-12"><a aria-hidden="true" href="#cb29-12" tabindex="-1"></a><span class="st"> &lt;C:comp name="VJOURNAL" /&gt;</span></span>
<span id="cb29-13"><a aria-hidden="true" href="#cb29-13" tabindex="-1"></a><span class="st"> &lt;C:comp name="VTODO" /&gt;</span></span>
<span id="cb29-14"><a aria-hidden="true" href="#cb29-14" tabindex="-1"></a><span class="st"> &lt;/C:supported-calendar-component-set&gt;</span></span>
<span id="cb29-15"><a aria-hidden="true" href="#cb29-15" tabindex="-1"></a><span class="st"> &lt;displayname&gt;Calendar&lt;/displayname&gt;</span></span>
<span id="cb29-16"><a aria-hidden="true" href="#cb29-16" tabindex="-1"></a><span class="st"> &lt;C:calendar-description&gt;Example calendar&lt;/C:calendar-description&gt;</span></span>
<span id="cb29-17"><a aria-hidden="true" href="#cb29-17" tabindex="-1"></a><span class="st"> &lt;I:calendar-color&gt;#ff0000ff&lt;/I:calendar-color&gt;</span></span>
<span id="cb29-18"><a aria-hidden="true" href="#cb29-18" tabindex="-1"></a><span class="st"> &lt;/prop&gt;</span></span>
<span id="cb29-19"><a aria-hidden="true" href="#cb29-19" tabindex="-1"></a><span class="st"> &lt;/set&gt;</span></span>
<span id="cb29-20"><a aria-hidden="true" href="#cb29-20" tabindex="-1"></a><span class="st">&lt;/create&gt;'</span></span></code></pre></div>
<p>To create a new address book run something like:</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb30-1"><a href="#cb30-1"></a>$ <span class="ex">curl</span> -u user -X MKCOL <span class="st">'http://localhost:5232/user/addressbook'</span> --data \</span>
<span id="cb30-2"><a href="#cb30-2"></a><span class="st">'&lt;?xml version="1.0" encoding="UTF-8" ?&gt;</span></span>
<span id="cb30-3"><a href="#cb30-3"></a><span class="st">&lt;create xmlns="DAV:" xmlns:CR="urn:ietf:params:xml:ns:carddav"&gt;</span></span>
<span id="cb30-4"><a href="#cb30-4"></a><span class="st"> &lt;set&gt;</span></span>
<span id="cb30-5"><a href="#cb30-5"></a><span class="st"> &lt;prop&gt;</span></span>
<span id="cb30-6"><a href="#cb30-6"></a><span class="st"> &lt;resourcetype&gt;</span></span>
<span id="cb30-7"><a href="#cb30-7"></a><span class="st"> &lt;collection /&gt;</span></span>
<span id="cb30-8"><a href="#cb30-8"></a><span class="st"> &lt;CR:addressbook /&gt;</span></span>
<span id="cb30-9"><a href="#cb30-9"></a><span class="st"> &lt;/resourcetype&gt;</span></span>
<span id="cb30-10"><a href="#cb30-10"></a><span class="st"> &lt;displayname&gt;Address book&lt;/displayname&gt;</span></span>
<span id="cb30-11"><a href="#cb30-11"></a><span class="st"> &lt;CR:addressbook-description&gt;Example address book&lt;/CR:addressbook-description&gt;</span></span>
<span id="cb30-12"><a href="#cb30-12"></a><span class="st"> &lt;/prop&gt;</span></span>
<span id="cb30-13"><a href="#cb30-13"></a><span class="st"> &lt;/set&gt;</span></span>
<span id="cb30-14"><a href="#cb30-14"></a><span class="st">&lt;/create&gt;'</span></span></code></pre></div>
<div class="sourceCode" id="cb30"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb30-1"><a aria-hidden="true" href="#cb30-1" tabindex="-1"></a><span class="ex">$</span> curl <span class="at">-u</span> user <span class="at">-X</span> MKCOL <span class="st">'http://localhost:5232/user/addressbook'</span> <span class="at">--data</span> <span class="dt">\</span></span>
<span id="cb30-2"><a aria-hidden="true" href="#cb30-2" tabindex="-1"></a><span class="st">'&lt;?xml version="1.0" encoding="UTF-8" ?&gt;</span></span>
<span id="cb30-3"><a aria-hidden="true" href="#cb30-3" tabindex="-1"></a><span class="st">&lt;create xmlns="DAV:" xmlns:CR="urn:ietf:params:xml:ns:carddav"&gt;</span></span>
<span id="cb30-4"><a aria-hidden="true" href="#cb30-4" tabindex="-1"></a><span class="st"> &lt;set&gt;</span></span>
<span id="cb30-5"><a aria-hidden="true" href="#cb30-5" tabindex="-1"></a><span class="st"> &lt;prop&gt;</span></span>
<span id="cb30-6"><a aria-hidden="true" href="#cb30-6" tabindex="-1"></a><span class="st"> &lt;resourcetype&gt;</span></span>
<span id="cb30-7"><a aria-hidden="true" href="#cb30-7" tabindex="-1"></a><span class="st"> &lt;collection /&gt;</span></span>
<span id="cb30-8"><a aria-hidden="true" href="#cb30-8" tabindex="-1"></a><span class="st"> &lt;CR:addressbook /&gt;</span></span>
<span id="cb30-9"><a aria-hidden="true" href="#cb30-9" tabindex="-1"></a><span class="st"> &lt;/resourcetype&gt;</span></span>
<span id="cb30-10"><a aria-hidden="true" href="#cb30-10" tabindex="-1"></a><span class="st"> &lt;displayname&gt;Address book&lt;/displayname&gt;</span></span>
<span id="cb30-11"><a aria-hidden="true" href="#cb30-11" tabindex="-1"></a><span class="st"> &lt;CR:addressbook-description&gt;Example address book&lt;/CR:addressbook-description&gt;</span></span>
<span id="cb30-12"><a aria-hidden="true" href="#cb30-12" tabindex="-1"></a><span class="st"> &lt;/prop&gt;</span></span>
<span id="cb30-13"><a aria-hidden="true" href="#cb30-13" tabindex="-1"></a><span class="st"> &lt;/set&gt;</span></span>
<span id="cb30-14"><a aria-hidden="true" href="#cb30-14" tabindex="-1"></a><span class="st">&lt;/create&gt;'</span></span></code></pre></div>
<p>The collection <code>/USERNAME</code> 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 <code>/USERNAME/</code>.</p>
<p>Delete the collections by running something like:</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb31-1"><a href="#cb31-1"></a>$ <span class="ex">curl</span> -u user -X DELETE <span class="st">'http://localhost:5232/user/calendar'</span></span></code></pre></div>
<div class="sourceCode" id="cb31"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb31-1"><a aria-hidden="true" href="#cb31-1" tabindex="-1"></a><span class="ex">$</span> curl <span class="at">-u</span> user <span class="at">-X</span> DELETE <span class="st">'http://localhost:5232/user/calendar'</span></span></code></pre></div>
</section>
</section>
</section>
@ -872,19 +1000,19 @@ user2:password2
<h3>Configuration <a class="headerlink" href="#documentation/configuration">&para;</a></h3>
<p>Radicale can be configured with a configuration file or with command line arguments.</p>
<p>An example configuration file looks like:</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb32-1"><a href="#cb32-1"></a><span class="kw">[server]</span></span>
<span id="cb32-2"><a href="#cb32-2"></a><span class="co"># Bind all addresses</span></span>
<span id="cb32-3"><a href="#cb32-3"></a><span class="dt">hosts </span><span class="ot">=</span><span class="st"> </span><span class="dv">0</span><span class="st">.</span><span class="dv">0</span><span class="st">.</span><span class="fl">0.0</span><span class="st">:</span><span class="dv">5232</span></span>
<span id="cb32-4"><a href="#cb32-4"></a></span>
<span id="cb32-5"><a href="#cb32-5"></a><span class="kw">[auth]</span></span>
<span id="cb32-6"><a href="#cb32-6"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb32-7"><a href="#cb32-7"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> /path/to/users</span></span>
<span id="cb32-8"><a href="#cb32-8"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> bcrypt</span></span>
<span id="cb32-9"><a href="#cb32-9"></a><span class="kw">[storage]</span></span>
<span id="cb32-10"><a href="#cb32-10"></a><span class="dt">filesystem_folder </span><span class="ot">=</span><span class="st"> ~/.var/lib/radicale/collections</span></span></code></pre></div>
<div class="sourceCode" id="cb32"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb32-1"><a aria-hidden="true" href="#cb32-1" tabindex="-1"></a><span class="kw">[server]</span></span>
<span id="cb32-2"><a aria-hidden="true" href="#cb32-2" tabindex="-1"></a><span class="co"># Bind all addresses</span></span>
<span id="cb32-3"><a aria-hidden="true" href="#cb32-3" tabindex="-1"></a><span class="dt">hosts </span><span class="ot">=</span><span class="st"> 0.0.0.0:5232</span></span>
<span id="cb32-4"><a aria-hidden="true" href="#cb32-4" tabindex="-1"></a></span>
<span id="cb32-5"><a aria-hidden="true" href="#cb32-5" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb32-6"><a aria-hidden="true" href="#cb32-6" tabindex="-1"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb32-7"><a aria-hidden="true" href="#cb32-7" tabindex="-1"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> /path/to/users</span></span>
<span id="cb32-8"><a aria-hidden="true" href="#cb32-8" tabindex="-1"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> bcrypt</span></span>
<span id="cb32-9"><a aria-hidden="true" href="#cb32-9" tabindex="-1"></a><span class="kw">[storage]</span></span>
<span id="cb32-10"><a aria-hidden="true" href="#cb32-10" tabindex="-1"></a><span class="dt">filesystem_folder </span><span class="ot">=</span><span class="st"> ~/.var/lib/radicale/collections</span></span></code></pre></div>
<p>Radicale tries to load configuration files from <code>/etc/radicale/config</code>, <code>~/.config/radicale/config</code> and the <code>RADICALE_CONFIG</code> environment variable. This behaviour can be overwritten by specifying a path with the <code>--config /path/to/config</code> command line argument.</p>
<p>The same example configuration via command line arguments looks like:</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb33-1"><a href="#cb33-1"></a><span class="ex">python3</span> -m radicale --config <span class="st">""</span> --server-hosts 0.0.0.0:5232 --auth-type htpasswd --htpasswd-filename /path/to/htpasswd --htpasswd-encryption bcrypt</span></code></pre></div>
<div class="sourceCode" id="cb33"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb33-1"><a aria-hidden="true" href="#cb33-1" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> radicale <span class="at">--config</span> <span class="st">""</span> <span class="at">--server-hosts</span> 0.0.0.0:5232 <span class="at">--auth-type</span> htpasswd <span class="at">--htpasswd-filename</span> /path/to/htpasswd <span class="at">--htpasswd-encryption</span> bcrypt</span></code></pre></div>
<p>The <code>--config ""</code> argument is required to stop Radicale from trying to load configuration files. Run <code>python3 -m radicale --help</code> for more information.</p>
<p>In the following, all configuration categories and options are described.</p>
<section class="level4" id="documentation/configuration/server">
@ -997,8 +1125,7 @@ user2:password2
<p>Available methods:</p>
<p><code>plain</code> : Passwords are stored in plaintext. This is obviously not secure! The htpasswd file for this can be created by hand and looks like:</p>
<pre class="htpasswd"><code>user1:password1
user2:password2
</code></pre>
user2:password2</code></pre>
<p><code>bcrypt</code> : This uses a modified version of the Blowfish stream cipher. It's very secure. The <strong>passlib</strong> python module is required for this. Additionally you may need one of the following python modules: <strong>bcrypt</strong>, <strong>py-bcrypt</strong> or <strong>bcryptor</strong>.</p>
<p><code>md5</code> : This uses an iterated md5 digest of the password with a salt. The <strong>passlib</strong> python module is required for this.</p>
<p><code>sha1</code> : Passwords are stored as SHA1 hashes. It's insecure!</p>
@ -1104,7 +1231,7 @@ user2:password2
<h4>headers <a class="headerlink" href="#documentation/configuration/headers">&para;</a></h4>
<p>In this section additional HTTP headers that are sent to clients can be specified.</p>
<p>An example to relax the same-origin policy:</p>
<div class="sourceCode" id="cb35"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb35-1"><a href="#cb35-1"></a><span class="dt">Access-Control-Allow-Origin </span><span class="ot">=</span><span class="st"> *</span></span></code></pre></div>
<div class="sourceCode" id="cb35"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb35-1"><a aria-hidden="true" href="#cb35-1" tabindex="-1"></a><span class="dt">Access-Control-Allow-Origin </span><span class="ot">=</span><span class="st"> *</span></span></code></pre></div>
</section>
</section>
<section class="level3" id="documentation/authentication-and-rights">
@ -1112,29 +1239,29 @@ user2:password2
<p>This page describes the format of the rights file for the <code>from_file</code> authentication backend. The configuration option <code>file</code> in the <code>rights</code> section must point to the rights file.</p>
<p>The recommended rights method is <code>owner_only</code>. If access to calendars and address books outside of the home directory of users (that's <code>/USERNAME/</code>) 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.</p>
<p>An example rights file:</p>
<div class="sourceCode" id="cb36"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb36-1"><a href="#cb36-1"></a><span class="co"># The user "admin" can read and write any collection.</span></span>
<span id="cb36-2"><a href="#cb36-2"></a><span class="kw">[admin]</span></span>
<span id="cb36-3"><a href="#cb36-3"></a><span class="dt">user </span><span class="ot">=</span><span class="st"> admin</span></span>
<span id="cb36-4"><a href="#cb36-4"></a><span class="dt">collection </span><span class="ot">=</span><span class="st"> .*</span></span>
<span id="cb36-5"><a href="#cb36-5"></a><span class="dt">permission </span><span class="ot">=</span><span class="st"> rw</span></span>
<span id="cb36-6"><a href="#cb36-6"></a></span>
<span id="cb36-7"><a href="#cb36-7"></a><span class="co"># Block access for the user "user" to everything.</span></span>
<span id="cb36-8"><a href="#cb36-8"></a><span class="kw">[block]</span></span>
<span id="cb36-9"><a href="#cb36-9"></a><span class="dt">user </span><span class="ot">=</span><span class="st"> user</span></span>
<span id="cb36-10"><a href="#cb36-10"></a><span class="dt">collection </span><span class="ot">=</span><span class="st"> .*</span></span>
<span id="cb36-11"><a href="#cb36-11"></a><span class="dt">permission </span><span class="ot">=</span></span>
<span id="cb36-12"><a href="#cb36-12"></a></span>
<span id="cb36-13"><a href="#cb36-13"></a><span class="co"># Authenticated users can read and write their own collections.</span></span>
<span id="cb36-14"><a href="#cb36-14"></a><span class="kw">[owner-write]</span></span>
<span id="cb36-15"><a href="#cb36-15"></a><span class="dt">user </span><span class="ot">=</span><span class="st"> .+</span></span>
<span id="cb36-16"><a href="#cb36-16"></a><span class="dt">collection </span><span class="ot">=</span><span class="st"> %(login)s(/.*)?</span></span>
<span id="cb36-17"><a href="#cb36-17"></a><span class="dt">permission </span><span class="ot">=</span><span class="st"> rw</span></span>
<span id="cb36-18"><a href="#cb36-18"></a></span>
<span id="cb36-19"><a href="#cb36-19"></a><span class="co"># Everyone can read the root collection</span></span>
<span id="cb36-20"><a href="#cb36-20"></a><span class="kw">[read]</span></span>
<span id="cb36-21"><a href="#cb36-21"></a><span class="dt">user </span><span class="ot">=</span><span class="st"> .*</span></span>
<span id="cb36-22"><a href="#cb36-22"></a><span class="dt">collection </span><span class="ot">=</span></span>
<span id="cb36-23"><a href="#cb36-23"></a><span class="dt">permission </span><span class="ot">=</span><span class="st"> r</span></span></code></pre></div>
<div class="sourceCode" id="cb36"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb36-1"><a aria-hidden="true" href="#cb36-1" tabindex="-1"></a><span class="co"># The user "admin" can read and write any collection.</span></span>
<span id="cb36-2"><a aria-hidden="true" href="#cb36-2" tabindex="-1"></a><span class="kw">[admin]</span></span>
<span id="cb36-3"><a aria-hidden="true" href="#cb36-3" tabindex="-1"></a><span class="dt">user </span><span class="ot">=</span><span class="st"> admin</span></span>
<span id="cb36-4"><a aria-hidden="true" href="#cb36-4" tabindex="-1"></a><span class="dt">collection </span><span class="ot">=</span><span class="st"> .*</span></span>
<span id="cb36-5"><a aria-hidden="true" href="#cb36-5" tabindex="-1"></a><span class="dt">permission </span><span class="ot">=</span><span class="st"> rw</span></span>
<span id="cb36-6"><a aria-hidden="true" href="#cb36-6" tabindex="-1"></a></span>
<span id="cb36-7"><a aria-hidden="true" href="#cb36-7" tabindex="-1"></a><span class="co"># Block access for the user "user" to everything.</span></span>
<span id="cb36-8"><a aria-hidden="true" href="#cb36-8" tabindex="-1"></a><span class="kw">[block]</span></span>
<span id="cb36-9"><a aria-hidden="true" href="#cb36-9" tabindex="-1"></a><span class="dt">user </span><span class="ot">=</span><span class="st"> user</span></span>
<span id="cb36-10"><a aria-hidden="true" href="#cb36-10" tabindex="-1"></a><span class="dt">collection </span><span class="ot">=</span><span class="st"> .*</span></span>
<span id="cb36-11"><a aria-hidden="true" href="#cb36-11" tabindex="-1"></a><span class="dt">permission </span><span class="ot">=</span></span>
<span id="cb36-12"><a aria-hidden="true" href="#cb36-12" tabindex="-1"></a></span>
<span id="cb36-13"><a aria-hidden="true" href="#cb36-13" tabindex="-1"></a><span class="co"># Authenticated users can read and write their own collections.</span></span>
<span id="cb36-14"><a aria-hidden="true" href="#cb36-14" tabindex="-1"></a><span class="kw">[owner-write]</span></span>
<span id="cb36-15"><a aria-hidden="true" href="#cb36-15" tabindex="-1"></a><span class="dt">user </span><span class="ot">=</span><span class="st"> .+</span></span>
<span id="cb36-16"><a aria-hidden="true" href="#cb36-16" tabindex="-1"></a><span class="dt">collection </span><span class="ot">=</span><span class="st"> %(login)s(/.*)?</span></span>
<span id="cb36-17"><a aria-hidden="true" href="#cb36-17" tabindex="-1"></a><span class="dt">permission </span><span class="ot">=</span><span class="st"> rw</span></span>
<span id="cb36-18"><a aria-hidden="true" href="#cb36-18" tabindex="-1"></a></span>
<span id="cb36-19"><a aria-hidden="true" href="#cb36-19" tabindex="-1"></a><span class="co"># Everyone can read the root collection</span></span>
<span id="cb36-20"><a aria-hidden="true" href="#cb36-20" tabindex="-1"></a><span class="kw">[read]</span></span>
<span id="cb36-21"><a aria-hidden="true" href="#cb36-21" tabindex="-1"></a><span class="dt">user </span><span class="ot">=</span><span class="st"> .*</span></span>
<span id="cb36-22"><a aria-hidden="true" href="#cb36-22" tabindex="-1"></a><span class="dt">collection </span><span class="ot">=</span></span>
<span id="cb36-23"><a aria-hidden="true" href="#cb36-23" tabindex="-1"></a><span class="dt">permission </span><span class="ot">=</span><span class="st"> r</span></span></code></pre></div>
<p>The titles of the sections are ignored (but must be unique). The keys <code>user</code> and <code>collection</code> 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.</p>
<p>The user name is empty for anonymous users. Therefore, the regex <code>.+</code> only matches authenticated users and <code>.*</code> matches everyone (including anonymous users).</p>
<p>The path of the collection is separated by <code>/</code> and has no leading or trailing <code>/</code>. Therefore, the path of the root collection is empty.</p>
@ -1164,10 +1291,10 @@ user2:password2
<section class="level5" id="documentation/storage/locking/linux-shell-scripts">
<h5>Linux shell scripts <a class="headerlink" href="#documentation/storage/locking/linux-shell-scripts">&para;</a></h5>
<p>Use the <a href="https://manpages.debian.org/unstable/util-linux/flock.1.en.html">flock</a> utility.</p>
<div class="sourceCode" id="cb37"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb37-1"><a href="#cb37-1"></a><span class="co"># Exclusive</span></span>
<span id="cb37-2"><a href="#cb37-2"></a>$ <span class="ex">flock</span> --exclusive /path/to/storage/.Radicale.lock COMMAND</span>
<span id="cb37-3"><a href="#cb37-3"></a><span class="co"># Shared</span></span>
<span id="cb37-4"><a href="#cb37-4"></a>$ <span class="ex">flock</span> --shared /path/to/storage/.Radicale.lock COMMAND</span></code></pre></div>
<div class="sourceCode" id="cb37"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb37-1"><a aria-hidden="true" href="#cb37-1" tabindex="-1"></a><span class="co"># Exclusive</span></span>
<span id="cb37-2"><a aria-hidden="true" href="#cb37-2" tabindex="-1"></a><span class="ex">$</span> flock <span class="at">--exclusive</span> /path/to/storage/.Radicale.lock COMMAND</span>
<span id="cb37-3"><a aria-hidden="true" href="#cb37-3" tabindex="-1"></a><span class="co"># Shared</span></span>
<span id="cb37-4"><a aria-hidden="true" href="#cb37-4" tabindex="-1"></a><span class="ex">$</span> flock <span class="at">--shared</span> /path/to/storage/.Radicale.lock COMMAND</span></code></pre></div>
</section>
<section class="level5" id="documentation/storage/locking/linux-and-macos">
<h5>Linux and MacOS <a class="headerlink" href="#documentation/storage/locking/linux-and-macos">&para;</a></h5>
@ -1188,52 +1315,52 @@ user2:password2
<section class="level4" id="documentation/logging/logging-to-a-file">
<h4>Logging to a file <a class="headerlink" href="#documentation/logging/logging-to-a-file">&para;</a></h4>
<p>An example configuration to write the log output to the file <code>/var/log/radicale/log</code>:</p>
<div class="sourceCode" id="cb38"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb38-1"><a href="#cb38-1"></a><span class="kw">[loggers]</span></span>
<span id="cb38-2"><a href="#cb38-2"></a><span class="dt">keys </span><span class="ot">=</span><span class="st"> root</span></span>
<span id="cb38-3"><a href="#cb38-3"></a></span>
<span id="cb38-4"><a href="#cb38-4"></a><span class="kw">[handlers]</span></span>
<span id="cb38-5"><a href="#cb38-5"></a><span class="dt">keys </span><span class="ot">=</span><span class="st"> file</span></span>
<span id="cb38-6"><a href="#cb38-6"></a></span>
<span id="cb38-7"><a href="#cb38-7"></a><span class="kw">[formatters]</span></span>
<span id="cb38-8"><a href="#cb38-8"></a><span class="dt">keys </span><span class="ot">=</span><span class="st"> full</span></span>
<span id="cb38-9"><a href="#cb38-9"></a></span>
<span id="cb38-10"><a href="#cb38-10"></a><span class="kw">[logger_root]</span></span>
<span id="cb38-11"><a href="#cb38-11"></a><span class="co"># Change this to DEBUG or INFO for higher verbosity.</span></span>
<span id="cb38-12"><a href="#cb38-12"></a><span class="dt">level </span><span class="ot">=</span><span class="st"> WARNING</span></span>
<span id="cb38-13"><a href="#cb38-13"></a><span class="dt">handlers </span><span class="ot">=</span><span class="st"> file</span></span>
<span id="cb38-14"><a href="#cb38-14"></a></span>
<span id="cb38-15"><a href="#cb38-15"></a><span class="kw">[handler_file]</span></span>
<span id="cb38-16"><a href="#cb38-16"></a><span class="dt">class </span><span class="ot">=</span><span class="st"> FileHandler</span></span>
<span id="cb38-17"><a href="#cb38-17"></a><span class="co"># Specify the output file here.</span></span>
<span id="cb38-18"><a href="#cb38-18"></a><span class="dt">args </span><span class="ot">=</span><span class="st"> ('/var/log/radicale/log',)</span></span>
<span id="cb38-19"><a href="#cb38-19"></a><span class="dt">formatter </span><span class="ot">=</span><span class="st"> full</span></span>
<span id="cb38-20"><a href="#cb38-20"></a></span>
<span id="cb38-21"><a href="#cb38-21"></a><span class="kw">[formatter_full]</span></span>
<span id="cb38-22"><a href="#cb38-22"></a><span class="dt">format </span><span class="ot">=</span><span class="st"> %(asctime)s - [%(thread)x] %(levelname)s: %(message)s</span></span></code></pre></div>
<div class="sourceCode" id="cb38"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb38-1"><a aria-hidden="true" href="#cb38-1" tabindex="-1"></a><span class="kw">[loggers]</span></span>
<span id="cb38-2"><a aria-hidden="true" href="#cb38-2" tabindex="-1"></a><span class="dt">keys </span><span class="ot">=</span><span class="st"> root</span></span>
<span id="cb38-3"><a aria-hidden="true" href="#cb38-3" tabindex="-1"></a></span>
<span id="cb38-4"><a aria-hidden="true" href="#cb38-4" tabindex="-1"></a><span class="kw">[handlers]</span></span>
<span id="cb38-5"><a aria-hidden="true" href="#cb38-5" tabindex="-1"></a><span class="dt">keys </span><span class="ot">=</span><span class="st"> file</span></span>
<span id="cb38-6"><a aria-hidden="true" href="#cb38-6" tabindex="-1"></a></span>
<span id="cb38-7"><a aria-hidden="true" href="#cb38-7" tabindex="-1"></a><span class="kw">[formatters]</span></span>
<span id="cb38-8"><a aria-hidden="true" href="#cb38-8" tabindex="-1"></a><span class="dt">keys </span><span class="ot">=</span><span class="st"> full</span></span>
<span id="cb38-9"><a aria-hidden="true" href="#cb38-9" tabindex="-1"></a></span>
<span id="cb38-10"><a aria-hidden="true" href="#cb38-10" tabindex="-1"></a><span class="kw">[logger_root]</span></span>
<span id="cb38-11"><a aria-hidden="true" href="#cb38-11" tabindex="-1"></a><span class="co"># Change this to DEBUG or INFO for higher verbosity.</span></span>
<span id="cb38-12"><a aria-hidden="true" href="#cb38-12" tabindex="-1"></a><span class="dt">level </span><span class="ot">=</span><span class="st"> WARNING</span></span>
<span id="cb38-13"><a aria-hidden="true" href="#cb38-13" tabindex="-1"></a><span class="dt">handlers </span><span class="ot">=</span><span class="st"> file</span></span>
<span id="cb38-14"><a aria-hidden="true" href="#cb38-14" tabindex="-1"></a></span>
<span id="cb38-15"><a aria-hidden="true" href="#cb38-15" tabindex="-1"></a><span class="kw">[handler_file]</span></span>
<span id="cb38-16"><a aria-hidden="true" href="#cb38-16" tabindex="-1"></a><span class="dt">class </span><span class="ot">=</span><span class="st"> FileHandler</span></span>
<span id="cb38-17"><a aria-hidden="true" href="#cb38-17" tabindex="-1"></a><span class="co"># Specify the output file here.</span></span>
<span id="cb38-18"><a aria-hidden="true" href="#cb38-18" tabindex="-1"></a><span class="dt">args </span><span class="ot">=</span><span class="st"> ('/var/log/radicale/log',)</span></span>
<span id="cb38-19"><a aria-hidden="true" href="#cb38-19" tabindex="-1"></a><span class="dt">formatter </span><span class="ot">=</span><span class="st"> full</span></span>
<span id="cb38-20"><a aria-hidden="true" href="#cb38-20" tabindex="-1"></a></span>
<span id="cb38-21"><a aria-hidden="true" href="#cb38-21" tabindex="-1"></a><span class="kw">[formatter_full]</span></span>
<span id="cb38-22"><a aria-hidden="true" href="#cb38-22" tabindex="-1"></a><span class="dt">format </span><span class="ot">=</span><span class="st"> %(asctime)s - [%(thread)x] %(levelname)s: %(message)s</span></span></code></pre></div>
<p>You can specify multiple <strong>logger</strong>, <strong>handler</strong> and <strong>formatter</strong> if you want to have multiple simultaneous log outputs.</p>
<p>The parent folder of the log files must exist and must be writable by Radicale.</p>
<p><strong>Security:</strong> The log files should not be readable by unauthorized users. Set permissions accordingly.</p>
<section class="level5" id="documentation/logging/logging-to-a-file/timed-rotation-of-disk-log-files">
<h5>Timed rotation of disk log files <a class="headerlink" href="#documentation/logging/logging-to-a-file/timed-rotation-of-disk-log-files">&para;</a></h5>
<p>An example <strong>handler</strong> configuration to write the log output to the file <code>/var/log/radicale/log</code> and rotate it. Replace the section <code>handler_file</code> from the file logging example:</p>
<div class="sourceCode" id="cb39"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb39-1"><a href="#cb39-1"></a><span class="kw">[handler_file]</span></span>
<span id="cb39-2"><a href="#cb39-2"></a><span class="dt">class </span><span class="ot">=</span><span class="st"> handlers.TimedRotatingFileHandler</span></span>
<span id="cb39-3"><a href="#cb39-3"></a><span class="co"># Specify the output file and parameter for rotation here.</span></span>
<span id="cb39-4"><a href="#cb39-4"></a><span class="co"># See https://docs.python.org/3/library/logging.handlers.html#logging.handlers.TimedRotatingFileHandler</span></span>
<span id="cb39-5"><a href="#cb39-5"></a><span class="co"># Example: rollover at midnight and keep 7 files (means one week)</span></span>
<span id="cb39-6"><a href="#cb39-6"></a><span class="dt">args </span><span class="ot">=</span><span class="st"> ('/var/log/radicale/log', 'midnight', </span><span class="dv">1</span><span class="st">, </span><span class="dv">7</span><span class="st">)</span></span>
<span id="cb39-7"><a href="#cb39-7"></a><span class="dt">formatter </span><span class="ot">=</span><span class="st"> full</span></span></code></pre></div>
<div class="sourceCode" id="cb39"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb39-1"><a aria-hidden="true" href="#cb39-1" tabindex="-1"></a><span class="kw">[handler_file]</span></span>
<span id="cb39-2"><a aria-hidden="true" href="#cb39-2" tabindex="-1"></a><span class="dt">class </span><span class="ot">=</span><span class="st"> handlers.TimedRotatingFileHandler</span></span>
<span id="cb39-3"><a aria-hidden="true" href="#cb39-3" tabindex="-1"></a><span class="co"># Specify the output file and parameter for rotation here.</span></span>
<span id="cb39-4"><a aria-hidden="true" href="#cb39-4" tabindex="-1"></a><span class="co"># See https://docs.python.org/3/library/logging.handlers.html#logging.handlers.TimedRotatingFileHandler</span></span>
<span id="cb39-5"><a aria-hidden="true" href="#cb39-5" tabindex="-1"></a><span class="co"># Example: rollover at midnight and keep 7 files (means one week)</span></span>
<span id="cb39-6"><a aria-hidden="true" href="#cb39-6" tabindex="-1"></a><span class="dt">args </span><span class="ot">=</span><span class="st"> ('/var/log/radicale/log', 'midnight', 1, 7)</span></span>
<span id="cb39-7"><a aria-hidden="true" href="#cb39-7" tabindex="-1"></a><span class="dt">formatter </span><span class="ot">=</span><span class="st"> full</span></span></code></pre></div>
</section>
<section class="level5" id="documentation/logging/logging-to-a-file/rotation-of-disk-log-files-based-on-size">
<h5>Rotation of disk log files based on size <a class="headerlink" href="#documentation/logging/logging-to-a-file/rotation-of-disk-log-files-based-on-size">&para;</a></h5>
<p>An example <strong>handler</strong> configuration to write the log output to the file <code>/var/log/radicale/log</code> and rotate it . Replace the section <code>handle_file</code> from the file logging example:</p>
<div class="sourceCode" id="cb40"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb40-1"><a href="#cb40-1"></a><span class="kw">[handler_file]</span></span>
<span id="cb40-2"><a href="#cb40-2"></a><span class="dt">class </span><span class="ot">=</span><span class="st"> handlers.RotatingFileHandler</span></span>
<span id="cb40-3"><a href="#cb40-3"></a><span class="co"># Specify the output file and parameter for rotation here.</span></span>
<span id="cb40-4"><a href="#cb40-4"></a><span class="co"># See https://docs.python.org/3/library/logging.handlers.html#logging.handlers.RotatingFileHandler</span></span>
<span id="cb40-5"><a href="#cb40-5"></a><span class="co"># Example: rollover at 100000 kB and keep 10 files (means 1 MB)</span></span>
<span id="cb40-6"><a href="#cb40-6"></a><span class="dt">args </span><span class="ot">=</span><span class="st"> ('/var/log/radicale/log', 'a', </span><span class="dv">100000</span><span class="st">, </span><span class="dv">10</span><span class="st">)</span></span>
<span id="cb40-7"><a href="#cb40-7"></a><span class="dt">formatter </span><span class="ot">=</span><span class="st"> full</span></span></code></pre></div>
<div class="sourceCode" id="cb40"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb40-1"><a aria-hidden="true" href="#cb40-1" tabindex="-1"></a><span class="kw">[handler_file]</span></span>
<span id="cb40-2"><a aria-hidden="true" href="#cb40-2" tabindex="-1"></a><span class="dt">class </span><span class="ot">=</span><span class="st"> handlers.RotatingFileHandler</span></span>
<span id="cb40-3"><a aria-hidden="true" href="#cb40-3" tabindex="-1"></a><span class="co"># Specify the output file and parameter for rotation here.</span></span>
<span id="cb40-4"><a aria-hidden="true" href="#cb40-4" tabindex="-1"></a><span class="co"># See https://docs.python.org/3/library/logging.handlers.html#logging.handlers.RotatingFileHandler</span></span>
<span id="cb40-5"><a aria-hidden="true" href="#cb40-5" tabindex="-1"></a><span class="co"># Example: rollover at 100000 kB and keep 10 files (means 1 MB)</span></span>
<span id="cb40-6"><a aria-hidden="true" href="#cb40-6" tabindex="-1"></a><span class="dt">args </span><span class="ot">=</span><span class="st"> ('/var/log/radicale/log', 'a', 100000, 10)</span></span>
<span id="cb40-7"><a aria-hidden="true" href="#cb40-7" tabindex="-1"></a><span class="dt">formatter </span><span class="ot">=</span><span class="st"> full</span></span></code></pre></div>
</section>
</section>
</section>
@ -1308,36 +1435,36 @@ user2:password2
<h4>Getting started <a class="headerlink" href="#documentation/plugins/getting-started">&para;</a></h4>
<p>To get started we walk through the creation of a simple authentication plugin, that accepts login attempts if the username and password are equal.</p>
<p>The easiest way to develop and install <strong>python</strong> modules is <a href="https://docs.python.org/3/distutils/setupscript.html">Distutils</a>. For a minimal setup create the file <code>setup.py</code> with the following content in an empty folder:</p>
<div class="sourceCode" id="cb41"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb41-1"><a href="#cb41-1"></a><span class="co">#!/usr/bin/env python3</span></span>
<span id="cb41-2"><a href="#cb41-2"></a></span>
<span id="cb41-3"><a href="#cb41-3"></a><span class="im">from</span> distutils.core <span class="im">import</span> setup</span>
<span id="cb41-4"><a href="#cb41-4"></a></span>
<span id="cb41-5"><a href="#cb41-5"></a>setup(name<span class="op">=</span><span class="st">"radicale_silly_auth"</span>, packages<span class="op">=</span>[<span class="st">"radicale_silly_auth"</span>])</span></code></pre></div>
<div class="sourceCode" id="cb41"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb41-1"><a aria-hidden="true" href="#cb41-1" tabindex="-1"></a><span class="co">#!/usr/bin/env python3</span></span>
<span id="cb41-2"><a aria-hidden="true" href="#cb41-2" tabindex="-1"></a></span>
<span id="cb41-3"><a aria-hidden="true" href="#cb41-3" tabindex="-1"></a><span class="im">from</span> distutils.core <span class="im">import</span> setup</span>
<span id="cb41-4"><a aria-hidden="true" href="#cb41-4" tabindex="-1"></a></span>
<span id="cb41-5"><a aria-hidden="true" href="#cb41-5" tabindex="-1"></a>setup(name<span class="op">=</span><span class="st">"radicale_silly_auth"</span>, packages<span class="op">=</span>[<span class="st">"radicale_silly_auth"</span>])</span></code></pre></div>
<p>In the same folder create the sub-folder <code>radicale_silly_auth</code>. The folder must have the same name as specified in <code>packages</code> above.</p>
<p>Create the file <code>__init__.py</code> in the <code>radicale_silly_auth</code> folder with the following content:</p>
<div class="sourceCode" id="cb42"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb42-1"><a href="#cb42-1"></a><span class="im">from</span> radicale.auth <span class="im">import</span> BaseAuth</span>
<span id="cb42-2"><a href="#cb42-2"></a></span>
<span id="cb42-3"><a href="#cb42-3"></a></span>
<span id="cb42-4"><a href="#cb42-4"></a><span class="kw">class</span> Auth(BaseAuth):</span>
<span id="cb42-5"><a href="#cb42-5"></a> <span class="kw">def</span> is_authenticated(<span class="va">self</span>, user, password):</span>
<span id="cb42-6"><a href="#cb42-6"></a> <span class="co"># Example custom configuration option</span></span>
<span id="cb42-7"><a href="#cb42-7"></a> foo <span class="op">=</span> <span class="st">""</span></span>
<span id="cb42-8"><a href="#cb42-8"></a> <span class="cf">if</span> <span class="va">self</span>.configuration.has_option(<span class="st">"auth"</span>, <span class="st">"foo"</span>):</span>
<span id="cb42-9"><a href="#cb42-9"></a> foo <span class="op">=</span> <span class="va">self</span>.configuration.get(<span class="st">"auth"</span>, <span class="st">"foo"</span>)</span>
<span id="cb42-10"><a href="#cb42-10"></a> <span class="va">self</span>.logger.info(<span class="st">"Configuration option </span><span class="sc">%r</span><span class="st"> is </span><span class="sc">%r</span><span class="st">"</span>, <span class="st">"foo"</span>, foo)</span>
<span id="cb42-11"><a href="#cb42-11"></a></span>
<span id="cb42-12"><a href="#cb42-12"></a> <span class="co"># Check authentication</span></span>
<span id="cb42-13"><a href="#cb42-13"></a> <span class="va">self</span>.logger.info(<span class="st">"Login attempt by </span><span class="sc">%r</span><span class="st"> with password </span><span class="sc">%r</span><span class="st">"</span>,</span>
<span id="cb42-14"><a href="#cb42-14"></a> user, password)</span>
<span id="cb42-15"><a href="#cb42-15"></a> <span class="cf">return</span> user <span class="op">==</span> password</span></code></pre></div>
<div class="sourceCode" id="cb42"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb42-1"><a aria-hidden="true" href="#cb42-1" tabindex="-1"></a><span class="im">from</span> radicale.auth <span class="im">import</span> BaseAuth</span>
<span id="cb42-2"><a aria-hidden="true" href="#cb42-2" tabindex="-1"></a></span>
<span id="cb42-3"><a aria-hidden="true" href="#cb42-3" tabindex="-1"></a></span>
<span id="cb42-4"><a aria-hidden="true" href="#cb42-4" tabindex="-1"></a><span class="kw">class</span> Auth(BaseAuth):</span>
<span id="cb42-5"><a aria-hidden="true" href="#cb42-5" tabindex="-1"></a> <span class="kw">def</span> is_authenticated(<span class="va">self</span>, user, password):</span>
<span id="cb42-6"><a aria-hidden="true" href="#cb42-6" tabindex="-1"></a> <span class="co"># Example custom configuration option</span></span>
<span id="cb42-7"><a aria-hidden="true" href="#cb42-7" tabindex="-1"></a> foo <span class="op">=</span> <span class="st">""</span></span>
<span id="cb42-8"><a aria-hidden="true" href="#cb42-8" tabindex="-1"></a> <span class="cf">if</span> <span class="va">self</span>.configuration.has_option(<span class="st">"auth"</span>, <span class="st">"foo"</span>):</span>
<span id="cb42-9"><a aria-hidden="true" href="#cb42-9" tabindex="-1"></a> foo <span class="op">=</span> <span class="va">self</span>.configuration.get(<span class="st">"auth"</span>, <span class="st">"foo"</span>)</span>
<span id="cb42-10"><a aria-hidden="true" href="#cb42-10" tabindex="-1"></a> <span class="va">self</span>.logger.info(<span class="st">"Configuration option </span><span class="sc">%r</span><span class="st"> is </span><span class="sc">%r</span><span class="st">"</span>, <span class="st">"foo"</span>, foo)</span>
<span id="cb42-11"><a aria-hidden="true" href="#cb42-11" tabindex="-1"></a></span>
<span id="cb42-12"><a aria-hidden="true" href="#cb42-12" tabindex="-1"></a> <span class="co"># Check authentication</span></span>
<span id="cb42-13"><a aria-hidden="true" href="#cb42-13" tabindex="-1"></a> <span class="va">self</span>.logger.info(<span class="st">"Login attempt by </span><span class="sc">%r</span><span class="st"> with password </span><span class="sc">%r</span><span class="st">"</span>,</span>
<span id="cb42-14"><a aria-hidden="true" href="#cb42-14" tabindex="-1"></a> user, password)</span>
<span id="cb42-15"><a aria-hidden="true" href="#cb42-15" tabindex="-1"></a> <span class="cf">return</span> user <span class="op">==</span> password</span></code></pre></div>
<p>Install the python module by running the following command in the same folder as <code>setup.py</code>:</p>
<div class="sourceCode" id="cb43"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb43-1"><a href="#cb43-1"></a><span class="ex">python3</span> -m pip install --upgrade .</span></code></pre></div>
<div class="sourceCode" id="cb43"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb43-1"><a aria-hidden="true" href="#cb43-1" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> pip install <span class="at">--upgrade</span> .</span></code></pre></div>
<p>To make use this great creation in Radicale, set the configuration option <code>type</code> in the <code>auth</code> section to <code>radicale_silly_auth</code>:</p>
<div class="sourceCode" id="cb44"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb44-1"><a href="#cb44-1"></a><span class="kw">[auth]</span></span>
<span id="cb44-2"><a href="#cb44-2"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> radicale_silly_auth</span></span>
<span id="cb44-3"><a href="#cb44-3"></a><span class="dt">foo </span><span class="ot">=</span><span class="st"> bar</span></span></code></pre></div>
<div class="sourceCode" id="cb44"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb44-1"><a aria-hidden="true" href="#cb44-1" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb44-2"><a aria-hidden="true" href="#cb44-2" tabindex="-1"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> radicale_silly_auth</span></span>
<span id="cb44-3"><a aria-hidden="true" href="#cb44-3" tabindex="-1"></a><span class="dt">foo </span><span class="ot">=</span><span class="st"> bar</span></span></code></pre></div>
<p>You can uninstall the module with:</p>
<div class="sourceCode" id="cb45"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb45-1"><a href="#cb45-1"></a><span class="ex">python3</span> -m pip uninstall radicale_silly_auth</span></code></pre></div>
<div class="sourceCode" id="cb45"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb45-1"><a aria-hidden="true" href="#cb45-1" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> pip uninstall radicale_silly_auth</span></code></pre></div>
</section>
<section class="level4" id="documentation/plugins/authentication-plugins">
<h4>Authentication plugins <a class="headerlink" href="#documentation/plugins/authentication-plugins">&para;</a></h4>
@ -1380,7 +1507,7 @@ user2:password2
<p>If you import big calendars or address books into Radicale 2.x.x the first request might take a long time, because it has to initialize its internal caches. Clients can time out, subsequent requests will be much faster.</p>
<p>You can check the imported storage for errors by starting Radicale &gt;= 2.1.5 with the <code>--verify-storage</code> argument.</p>
<p>You can install version 1.1.x with:</p>
<div class="sourceCode" id="cb46"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb46-1"><a href="#cb46-1"></a>$ <span class="ex">python3</span> -m pip install --upgrade radicale==1.1.*</span></code></pre></div>
<div class="sourceCode" id="cb46"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb46-1"><a aria-hidden="true" href="#cb46-1" tabindex="-1"></a><span class="ex">$</span> python3 <span class="at">-m</span> pip install <span class="at">--upgrade</span> radicale==1.1.<span class="pp">*</span></span></code></pre></div>
</section>
<section class="level4" id="documentation/migration-from-1xx-to-2xx/authentication">
<h4>Authentication <a class="headerlink" href="#documentation/migration-from-1xx-to-2xx/authentication">&para;</a></h4>
@ -1421,14 +1548,12 @@ user2:password2
<section class="level4" id="download//pypi">
<h4>PyPI <a class="headerlink" href="#download//pypi">&para;</a></h4>
<p>Radicale is <a href="https://pypi.python.org/pypi/Radicale/">available on PyPI</a>. To install, just type as superuser:</p>
<pre><code>$ python3 -m pip install --upgrade radicale==2.1.*
</code></pre>
<pre><code>$ python3 -m pip install --upgrade radicale==2.1.*</code></pre>
</section>
<section class="level4" id="download//git-repository">
<h4>Git Repository <a class="headerlink" href="#download//git-repository">&para;</a></h4>
<p>If you want the development version of Radicale, take a look at the <a href="https://github.com/Kozea/Radicale/">git repository on GitHub</a>, or install it directly with:</p>
<pre><code>$ python3 -m pip install --upgrade git+https://github.com/Kozea/Radicale
</code></pre>
<pre><code>$ python3 -m pip install --upgrade git+https://github.com/Kozea/Radicale</code></pre>
<p>You can also download the content of the repository as an <a href="https://github.com/Kozea/Radicale/tarball/master">archive</a>.</p>
</section>
<section class="level4" id="download//source-packages">

659
3.0.html
View file

@ -5,6 +5,137 @@
<meta content="pandoc" name="generator">
<meta content="width=device-width, initial-scale=1" name="viewport">
<style>
html {
line-height: 1.5;
font-family: Georgia, serif;
font-size: 20px;
color: #1a1a1a;
background-color: #fdfdfd;
}
body {
margin: 0 auto;
max-width: 36em;
padding-left: 50px;
padding-right: 50px;
padding-top: 50px;
padding-bottom: 50px;
hyphens: auto;
overflow-wrap: break-word;
text-rendering: optimizeLegibility;
font-kerning: normal;
}
@media (max-width: 600px) {
body {
font-size: 0.9em;
padding: 1em;
}
}
@media print {
body {
background-color: transparent;
color: black;
font-size: 12pt;
}
p, h2, h3 {
orphans: 3;
widows: 3;
}
h2, h3, h4 {
page-break-after: avoid;
}
}
p {
margin: 1em 0;
}
a {
color: #1a1a1a;
}
a:visited {
color: #1a1a1a;
}
img {
max-width: 100%;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 1.4em;
}
h5, h6 {
font-size: 1em;
font-style: italic;
}
h6 {
font-weight: normal;
}
ol, ul {
padding-left: 1.7em;
margin-top: 1em;
}
li > ol, li > ul {
margin-top: 0;
}
blockquote {
margin: 1em 0 1em 1.7em;
padding-left: 1em;
border-left: 2px solid #e6e6e6;
color: #606060;
}
code {
font-family: Menlo, Monaco, 'Lucida Console', Consolas, monospace;
font-size: 85%;
margin: 0;
}
pre {
margin: 1em 0;
overflow: auto;
}
pre code {
padding: 0;
overflow: visible;
overflow-wrap: normal;
}
.sourceCode {
background-color: transparent;
overflow: visible;
}
hr {
background-color: #1a1a1a;
border: none;
height: 1px;
margin: 1em 0;
}
table {
margin: 1em 0;
border-collapse: collapse;
width: 100%;
overflow-x: auto;
display: block;
font-variant-numeric: lining-nums tabular-nums;
}
table caption {
margin-bottom: 0.75em;
}
tbody {
margin-top: 0.5em;
border-top: 1px solid #1a1a1a;
border-bottom: 1px solid #1a1a1a;
}
th {
border-top: 1px solid #1a1a1a;
padding: 0.25em 0.5em 0.25em 0.5em;
}
td {
padding: 0.125em 0.5em 0.25em 0.5em;
}
header {
margin-bottom: 4em;
text-align: center;
}
#TOC li {
list-style: none;
}
#TOC a:not(:hover) {
text-decoration: none;
}
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
@ -14,6 +145,7 @@
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@ -73,6 +205,7 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
</style>
<link href="assets/default.css" media="all" rel="stylesheet">
<link href="assets/screen.css" media="screen" rel="stylesheet">
@ -244,9 +377,9 @@
<section class="level4" id="getting-started//installation">
<h4>Installation <a class="headerlink" href="#getting-started//installation">&para;</a></h4>
<p>Radicale is really easy to install and works out-of-the-box.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1"></a>$ <span class="ex">python3</span> -m pip install --upgrade radicale</span>
<span id="cb1-2"><a href="#cb1-2"></a>$ <span class="ex">python3</span> -m radicale --storage-filesystem-folder=~/.var/lib/radicale/collections</span></code></pre></div>
<p>When the server is launched, open <a href="http://localhost:5232/">http://localhost:5232/</a> in your browser! You can login with any username and password.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a aria-hidden="true" href="#cb1-1" tabindex="-1"></a><span class="ex">$</span> python3 <span class="at">-m</span> pip install <span class="at">--upgrade</span> radicale</span>
<span id="cb1-2"><a aria-hidden="true" href="#cb1-2" tabindex="-1"></a><span class="ex">$</span> python3 <span class="at">-m</span> radicale <span class="at">--storage-filesystem-folder</span><span class="op">=</span>~/.var/lib/radicale/collections</span></code></pre></div>
<p>When the server is launched, open http://localhost:5232/ in your browser! You can login with any username and password.</p>
<p>Want more? Check the <a href="#tutorials">tutorials</a> and the <a href="#documentation">documentation</a>.</p>
</section>
<section class="level4" id="getting-started//whats-new">
@ -265,19 +398,19 @@
<h4>Linux / *BSD <a class="headerlink" href="#tutorials/simple-5-minute-setup/linux--bsd">&para;</a></h4>
<p>First, make sure that <strong>python</strong> 3.5 or later (<strong>python</strong> &ge; 3.6 is recommended) and <strong>pip</strong> are installed. On most distributions it should be enough to install the package <code>python3-pip</code>.</p>
<p>Then open a console and type:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1"></a><span class="co"># Run the following command as root or</span></span>
<span id="cb2-2"><a href="#cb2-2"></a><span class="co"># add the --user argument to only install for the current user</span></span>
<span id="cb2-3"><a href="#cb2-3"></a>$ <span class="ex">python3</span> -m pip install --upgrade radicale</span>
<span id="cb2-4"><a href="#cb2-4"></a>$ <span class="ex">python3</span> -m radicale --storage-filesystem-folder=~/.var/lib/radicale/collections</span></code></pre></div>
<p>Victory! Open <a href="http://localhost:5232/">http://localhost:5232/</a> in your browser! You can log in with any username and password.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a aria-hidden="true" href="#cb2-1" tabindex="-1"></a><span class="co"># Run the following command as root or</span></span>
<span id="cb2-2"><a aria-hidden="true" href="#cb2-2" tabindex="-1"></a><span class="co"># add the --user argument to only install for the current user</span></span>
<span id="cb2-3"><a aria-hidden="true" href="#cb2-3" tabindex="-1"></a><span class="ex">$</span> python3 <span class="at">-m</span> pip install <span class="at">--upgrade</span> radicale</span>
<span id="cb2-4"><a aria-hidden="true" href="#cb2-4" tabindex="-1"></a><span class="ex">$</span> python3 <span class="at">-m</span> radicale <span class="at">--storage-filesystem-folder</span><span class="op">=</span>~/.var/lib/radicale/collections</span></code></pre></div>
<p>Victory! Open http://localhost:5232/ in your browser! You can log in with any username and password.</p>
</section>
<section class="level4" id="tutorials/simple-5-minute-setup/windows">
<h4>Windows <a class="headerlink" href="#tutorials/simple-5-minute-setup/windows">&para;</a></h4>
<p>The first step is to install Python. Go to <a href="https://python.org">python.org</a> 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!</p>
<p>Launch a command prompt and type:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode powershell"><code class="sourceCode powershell"><span id="cb3-1"><a href="#cb3-1"></a>C:\Users\User&gt; python -m pip install --upgrade radicale</span>
<span id="cb3-2"><a href="#cb3-2"></a>C:\Users\User&gt; python -m radicale --storage-filesystem-folder=~/radicale/collections</span></code></pre></div>
<p>Victory! Open <a href="http://localhost:5232/">http://localhost:5232/</a> in your browser! You can log in with any username and password.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode powershell"><code class="sourceCode powershell"><span id="cb3-1"><a aria-hidden="true" href="#cb3-1" tabindex="-1"></a>C<span class="op">:</span>\Users\User<span class="op">&gt;</span> python <span class="op">-</span>m pip install <span class="op">--</span>upgrade radicale</span>
<span id="cb3-2"><a aria-hidden="true" href="#cb3-2" tabindex="-1"></a>C<span class="op">:</span>\Users\User<span class="op">&gt;</span> python <span class="op">-</span>m radicale <span class="op">--</span>storage<span class="op">-</span>filesystem<span class="op">-</span>folder<span class="op">=~/</span>radicale<span class="op">/</span>collections</span></code></pre></div>
<p>Victory! Open http://localhost:5232/ in your browser! You can log in with any username and password.</p>
</section>
</section>
<section class="level3" id="tutorials/basic-configuration">
@ -293,46 +426,45 @@
<section class="level5" id="tutorials/basic-configuration/authentication/the-secure-way">
<h5>The secure way <a class="headerlink" href="#tutorials/basic-configuration/authentication/the-secure-way">&para;</a></h5>
<p>The <code>users</code> file can be created and managed with <a href="https://httpd.apache.org/docs/current/programs/htpasswd.html">htpasswd</a>:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1"></a><span class="co"># Create a new htpasswd file with the user "user1"</span></span>
<span id="cb4-2"><a href="#cb4-2"></a>$ <span class="ex">htpasswd</span> -c /path/to/users user1</span>
<span id="cb4-3"><a href="#cb4-3"></a><span class="ex">New</span> password:</span>
<span id="cb4-4"><a href="#cb4-4"></a><span class="ex">Re-type</span> new password:</span>
<span id="cb4-5"><a href="#cb4-5"></a><span class="co"># Add another user</span></span>
<span id="cb4-6"><a href="#cb4-6"></a>$ <span class="ex">htpasswd</span> /path/to/users user2</span>
<span id="cb4-7"><a href="#cb4-7"></a><span class="ex">New</span> password:</span>
<span id="cb4-8"><a href="#cb4-8"></a><span class="ex">Re-type</span> new password:</span></code></pre></div>
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a aria-hidden="true" href="#cb4-1" tabindex="-1"></a><span class="co"># Create a new htpasswd file with the user "user1"</span></span>
<span id="cb4-2"><a aria-hidden="true" href="#cb4-2" tabindex="-1"></a><span class="ex">$</span> htpasswd <span class="at">-c</span> /path/to/users user1</span>
<span id="cb4-3"><a aria-hidden="true" href="#cb4-3" tabindex="-1"></a><span class="ex">New</span> password:</span>
<span id="cb4-4"><a aria-hidden="true" href="#cb4-4" tabindex="-1"></a><span class="ex">Re-type</span> new password:</span>
<span id="cb4-5"><a aria-hidden="true" href="#cb4-5" tabindex="-1"></a><span class="co"># Add another user</span></span>
<span id="cb4-6"><a aria-hidden="true" href="#cb4-6" tabindex="-1"></a><span class="ex">$</span> htpasswd /path/to/users user2</span>
<span id="cb4-7"><a aria-hidden="true" href="#cb4-7" tabindex="-1"></a><span class="ex">New</span> password:</span>
<span id="cb4-8"><a aria-hidden="true" href="#cb4-8" tabindex="-1"></a><span class="ex">Re-type</span> new password:</span></code></pre></div>
<p>Authentication can be enabled with the following configuration:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb5-1"><a href="#cb5-1"></a><span class="kw">[auth]</span></span>
<span id="cb5-2"><a href="#cb5-2"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb5-3"><a href="#cb5-3"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> /path/to/users</span></span>
<span id="cb5-4"><a href="#cb5-4"></a><span class="co"># encryption method used in the htpasswd file</span></span>
<span id="cb5-5"><a href="#cb5-5"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> md5</span></span></code></pre></div>
<div class="sourceCode" id="cb5"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb5-1"><a aria-hidden="true" href="#cb5-1" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb5-2"><a aria-hidden="true" href="#cb5-2" tabindex="-1"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb5-3"><a aria-hidden="true" href="#cb5-3" tabindex="-1"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> /path/to/users</span></span>
<span id="cb5-4"><a aria-hidden="true" href="#cb5-4" tabindex="-1"></a><span class="co"># encryption method used in the htpasswd file</span></span>
<span id="cb5-5"><a aria-hidden="true" href="#cb5-5" tabindex="-1"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> md5</span></span></code></pre></div>
</section>
<section class="level5" id="tutorials/basic-configuration/authentication/the-simple-but-insecure-way">
<h5>The simple but insecure way <a class="headerlink" href="#tutorials/basic-configuration/authentication/the-simple-but-insecure-way">&para;</a></h5>
<p>Create the <code>users</code> file by hand with lines containing the user name and password separated by <code>:</code>. Example:</p>
<pre class="htpasswd"><code>user1:password1
user2:password2
</code></pre>
user2:password2</code></pre>
<p>Authentication can be enabled with the following configuration:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb7-1"><a href="#cb7-1"></a><span class="kw">[auth]</span></span>
<span id="cb7-2"><a href="#cb7-2"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb7-3"><a href="#cb7-3"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> /path/to/users</span></span>
<span id="cb7-4"><a href="#cb7-4"></a><span class="co"># encryption method used in the htpasswd file</span></span>
<span id="cb7-5"><a href="#cb7-5"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> plain</span></span></code></pre></div>
<div class="sourceCode" id="cb7"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb7-1"><a aria-hidden="true" href="#cb7-1" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb7-2"><a aria-hidden="true" href="#cb7-2" tabindex="-1"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb7-3"><a aria-hidden="true" href="#cb7-3" tabindex="-1"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> /path/to/users</span></span>
<span id="cb7-4"><a aria-hidden="true" href="#cb7-4" tabindex="-1"></a><span class="co"># encryption method used in the htpasswd file</span></span>
<span id="cb7-5"><a aria-hidden="true" href="#cb7-5" tabindex="-1"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> plain</span></span></code></pre></div>
</section>
</section>
<section class="level4" id="tutorials/basic-configuration/addresses">
<h4>Addresses <a class="headerlink" href="#tutorials/basic-configuration/addresses">&para;</a></h4>
<p>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):</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb8-1"><a href="#cb8-1"></a><span class="kw">[server]</span></span>
<span id="cb8-2"><a href="#cb8-2"></a><span class="dt">hosts </span><span class="ot">=</span><span class="st"> </span><span class="dv">0</span><span class="st">.</span><span class="dv">0</span><span class="st">.</span><span class="fl">0.0</span><span class="st">:</span><span class="dv">5232</span><span class="st">, [::]:</span><span class="dv">5232</span></span></code></pre></div>
<div class="sourceCode" id="cb8"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb8-1"><a aria-hidden="true" href="#cb8-1" tabindex="-1"></a><span class="kw">[server]</span></span>
<span id="cb8-2"><a aria-hidden="true" href="#cb8-2" tabindex="-1"></a><span class="dt">hosts </span><span class="ot">=</span><span class="st"> 0.0.0.0:5232, [::]:5232</span></span></code></pre></div>
</section>
<section class="level4" id="tutorials/basic-configuration/storage">
<h4>Storage <a class="headerlink" href="#tutorials/basic-configuration/storage">&para;</a></h4>
<p>Data is stored in the folder <code>/var/lib/radicale/collections</code>. The path can be changed with the following configuration:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb9-1"><a href="#cb9-1"></a><span class="kw">[storage]</span></span>
<span id="cb9-2"><a href="#cb9-2"></a><span class="dt">filesystem_folder </span><span class="ot">=</span><span class="st"> /path/to/storage</span></span></code></pre></div>
<div class="sourceCode" id="cb9"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb9-1"><a aria-hidden="true" href="#cb9-1" tabindex="-1"></a><span class="kw">[storage]</span></span>
<span id="cb9-2"><a aria-hidden="true" href="#cb9-2" tabindex="-1"></a><span class="dt">filesystem_folder </span><span class="ot">=</span><span class="st"> /path/to/storage</span></span></code></pre></div>
<blockquote>
<p><strong>Security:</strong> 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 <a href="#tutorials/running-as-a-service">Running as a service</a> section.</p>
</blockquote>
@ -340,16 +472,16 @@ user2:password2
<section class="level4" id="tutorials/basic-configuration/limits">
<h4>Limits <a class="headerlink" href="#tutorials/basic-configuration/limits">&para;</a></h4>
<p>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.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb10-1"><a href="#cb10-1"></a><span class="kw">[server]</span></span>
<span id="cb10-2"><a href="#cb10-2"></a><span class="dt">max_connections </span><span class="ot">=</span><span class="st"> </span><span class="dv">20</span></span>
<span id="cb10-3"><a href="#cb10-3"></a><span class="co"># 100 Megabyte</span></span>
<span id="cb10-4"><a href="#cb10-4"></a><span class="dt">max_content_length </span><span class="ot">=</span><span class="st"> </span><span class="dv">100000000</span></span>
<span id="cb10-5"><a href="#cb10-5"></a><span class="co"># 30 seconds</span></span>
<span id="cb10-6"><a href="#cb10-6"></a><span class="dt">timeout </span><span class="ot">=</span><span class="st"> </span><span class="dv">30</span></span>
<span id="cb10-7"><a href="#cb10-7"></a></span>
<span id="cb10-8"><a href="#cb10-8"></a><span class="kw">[auth]</span></span>
<span id="cb10-9"><a href="#cb10-9"></a><span class="co"># Average delay after failed login attempts in seconds</span></span>
<span id="cb10-10"><a href="#cb10-10"></a><span class="dt">delay </span><span class="ot">=</span><span class="st"> </span><span class="dv">1</span></span></code></pre></div>
<div class="sourceCode" id="cb10"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb10-1"><a aria-hidden="true" href="#cb10-1" tabindex="-1"></a><span class="kw">[server]</span></span>
<span id="cb10-2"><a aria-hidden="true" href="#cb10-2" tabindex="-1"></a><span class="dt">max_connections </span><span class="ot">=</span><span class="st"> </span><span class="dv">20</span></span>
<span id="cb10-3"><a aria-hidden="true" href="#cb10-3" tabindex="-1"></a><span class="co"># 100 Megabyte</span></span>
<span id="cb10-4"><a aria-hidden="true" href="#cb10-4" tabindex="-1"></a><span class="dt">max_content_length </span><span class="ot">=</span><span class="st"> </span><span class="dv">100000000</span></span>
<span id="cb10-5"><a aria-hidden="true" href="#cb10-5" tabindex="-1"></a><span class="co"># 30 seconds</span></span>
<span id="cb10-6"><a aria-hidden="true" href="#cb10-6" tabindex="-1"></a><span class="dt">timeout </span><span class="ot">=</span><span class="st"> </span><span class="dv">30</span></span>
<span id="cb10-7"><a aria-hidden="true" href="#cb10-7" tabindex="-1"></a></span>
<span id="cb10-8"><a aria-hidden="true" href="#cb10-8" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb10-9"><a aria-hidden="true" href="#cb10-9" tabindex="-1"></a><span class="co"># Average delay after failed login attempts in seconds</span></span>
<span id="cb10-10"><a aria-hidden="true" href="#cb10-10" tabindex="-1"></a><span class="dt">delay </span><span class="ot">=</span><span class="st"> </span><span class="dv">1</span></span></code></pre></div>
</section>
</section>
<section class="level3" id="tutorials/running-as-a-service">
@ -362,63 +494,63 @@ user2:password2
<p><strong>Security:</strong> The storage should not be readable by others. (Run <code>chmod -R o= /var/lib/radicale/collections</code> as root.)</p>
</blockquote>
<p>Create the file <code>/etc/systemd/system/radicale.service</code>:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb11-1"><a href="#cb11-1"></a><span class="kw">[Unit]</span></span>
<span id="cb11-2"><a href="#cb11-2"></a><span class="dt">Description</span><span class="ot">=</span><span class="st">A simple CalDAV (calendar) and CardDAV (contact) server</span></span>
<span id="cb11-3"><a href="#cb11-3"></a><span class="dt">After</span><span class="ot">=</span><span class="st">network.target</span></span>
<span id="cb11-4"><a href="#cb11-4"></a><span class="dt">Requires</span><span class="ot">=</span><span class="st">network.target</span></span>
<span id="cb11-5"><a href="#cb11-5"></a></span>
<span id="cb11-6"><a href="#cb11-6"></a><span class="kw">[Service]</span></span>
<span id="cb11-7"><a href="#cb11-7"></a><span class="dt">ExecStart</span><span class="ot">=</span><span class="st">/usr/bin/env python3 -m radicale</span></span>
<span id="cb11-8"><a href="#cb11-8"></a><span class="dt">Restart</span><span class="ot">=</span><span class="kw">on</span><span class="st">-failure</span></span>
<span id="cb11-9"><a href="#cb11-9"></a><span class="dt">User</span><span class="ot">=</span><span class="st">radicale</span></span>
<span id="cb11-10"><a href="#cb11-10"></a><span class="co"># Deny other users access to the calendar data</span></span>
<span id="cb11-11"><a href="#cb11-11"></a><span class="dt">UMask</span><span class="ot">=</span><span class="dv">0027</span></span>
<span id="cb11-12"><a href="#cb11-12"></a><span class="co"># Optional security settings</span></span>
<span id="cb11-13"><a href="#cb11-13"></a><span class="dt">PrivateTmp</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-14"><a href="#cb11-14"></a><span class="dt">ProtectSystem</span><span class="ot">=</span><span class="st">strict</span></span>
<span id="cb11-15"><a href="#cb11-15"></a><span class="dt">ProtectHome</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-16"><a href="#cb11-16"></a><span class="dt">PrivateDevices</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-17"><a href="#cb11-17"></a><span class="dt">ProtectKernelTunables</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-18"><a href="#cb11-18"></a><span class="dt">ProtectKernelModules</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-19"><a href="#cb11-19"></a><span class="dt">ProtectControlGroups</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-20"><a href="#cb11-20"></a><span class="dt">NoNewPrivileges</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-21"><a href="#cb11-21"></a><span class="dt">ReadWritePaths</span><span class="ot">=</span><span class="st">/var/lib/radicale/collections</span></span>
<span id="cb11-22"><a href="#cb11-22"></a></span>
<span id="cb11-23"><a href="#cb11-23"></a><span class="kw">[Install]</span></span>
<span id="cb11-24"><a href="#cb11-24"></a><span class="dt">WantedBy</span><span class="ot">=</span><span class="st">multi-user.target</span></span></code></pre></div>
<div class="sourceCode" id="cb11"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb11-1"><a aria-hidden="true" href="#cb11-1" tabindex="-1"></a><span class="kw">[Unit]</span></span>
<span id="cb11-2"><a aria-hidden="true" href="#cb11-2" tabindex="-1"></a><span class="dt">Description</span><span class="ot">=</span><span class="st">A simple CalDAV (calendar) and CardDAV (contact) server</span></span>
<span id="cb11-3"><a aria-hidden="true" href="#cb11-3" tabindex="-1"></a><span class="dt">After</span><span class="ot">=</span><span class="st">network.target</span></span>
<span id="cb11-4"><a aria-hidden="true" href="#cb11-4" tabindex="-1"></a><span class="dt">Requires</span><span class="ot">=</span><span class="st">network.target</span></span>
<span id="cb11-5"><a aria-hidden="true" href="#cb11-5" tabindex="-1"></a></span>
<span id="cb11-6"><a aria-hidden="true" href="#cb11-6" tabindex="-1"></a><span class="kw">[Service]</span></span>
<span id="cb11-7"><a aria-hidden="true" href="#cb11-7" tabindex="-1"></a><span class="dt">ExecStart</span><span class="ot">=</span><span class="st">/usr/bin/env python3 -m radicale</span></span>
<span id="cb11-8"><a aria-hidden="true" href="#cb11-8" tabindex="-1"></a><span class="dt">Restart</span><span class="ot">=</span><span class="st">on-failure</span></span>
<span id="cb11-9"><a aria-hidden="true" href="#cb11-9" tabindex="-1"></a><span class="dt">User</span><span class="ot">=</span><span class="st">radicale</span></span>
<span id="cb11-10"><a aria-hidden="true" href="#cb11-10" tabindex="-1"></a><span class="co"># Deny other users access to the calendar data</span></span>
<span id="cb11-11"><a aria-hidden="true" href="#cb11-11" tabindex="-1"></a><span class="dt">UMask</span><span class="ot">=</span><span class="dv">0027</span></span>
<span id="cb11-12"><a aria-hidden="true" href="#cb11-12" tabindex="-1"></a><span class="co"># Optional security settings</span></span>
<span id="cb11-13"><a aria-hidden="true" href="#cb11-13" tabindex="-1"></a><span class="dt">PrivateTmp</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-14"><a aria-hidden="true" href="#cb11-14" tabindex="-1"></a><span class="dt">ProtectSystem</span><span class="ot">=</span><span class="st">strict</span></span>
<span id="cb11-15"><a aria-hidden="true" href="#cb11-15" tabindex="-1"></a><span class="dt">ProtectHome</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-16"><a aria-hidden="true" href="#cb11-16" tabindex="-1"></a><span class="dt">PrivateDevices</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-17"><a aria-hidden="true" href="#cb11-17" tabindex="-1"></a><span class="dt">ProtectKernelTunables</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-18"><a aria-hidden="true" href="#cb11-18" tabindex="-1"></a><span class="dt">ProtectKernelModules</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-19"><a aria-hidden="true" href="#cb11-19" tabindex="-1"></a><span class="dt">ProtectControlGroups</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-20"><a aria-hidden="true" href="#cb11-20" tabindex="-1"></a><span class="dt">NoNewPrivileges</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-21"><a aria-hidden="true" href="#cb11-21" tabindex="-1"></a><span class="dt">ReadWritePaths</span><span class="ot">=</span><span class="st">/var/lib/radicale/collections</span></span>
<span id="cb11-22"><a aria-hidden="true" href="#cb11-22" tabindex="-1"></a></span>
<span id="cb11-23"><a aria-hidden="true" href="#cb11-23" tabindex="-1"></a><span class="kw">[Install]</span></span>
<span id="cb11-24"><a aria-hidden="true" href="#cb11-24" tabindex="-1"></a><span class="dt">WantedBy</span><span class="ot">=</span><span class="st">multi-user.target</span></span></code></pre></div>
<p>Radicale will load the configuration file from <code>/etc/radicale/config</code>.</p>
<p>To enable and manage the service run:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1"></a><span class="co"># Enable the service</span></span>
<span id="cb12-2"><a href="#cb12-2"></a>$ <span class="ex">systemctl</span> enable radicale</span>
<span id="cb12-3"><a href="#cb12-3"></a><span class="co"># Start the service</span></span>
<span id="cb12-4"><a href="#cb12-4"></a>$ <span class="ex">systemctl</span> start radicale</span>
<span id="cb12-5"><a href="#cb12-5"></a><span class="co"># Check the status of the service</span></span>
<span id="cb12-6"><a href="#cb12-6"></a>$ <span class="ex">systemctl</span> status radicale</span>
<span id="cb12-7"><a href="#cb12-7"></a><span class="co"># View all log messages</span></span>
<span id="cb12-8"><a href="#cb12-8"></a>$ <span class="ex">journalctl</span> --unit radicale.service</span></code></pre></div>
<div class="sourceCode" id="cb12"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb12-1"><a aria-hidden="true" href="#cb12-1" tabindex="-1"></a><span class="co"># Enable the service</span></span>
<span id="cb12-2"><a aria-hidden="true" href="#cb12-2" tabindex="-1"></a><span class="ex">$</span> systemctl enable radicale</span>
<span id="cb12-3"><a aria-hidden="true" href="#cb12-3" tabindex="-1"></a><span class="co"># Start the service</span></span>
<span id="cb12-4"><a aria-hidden="true" href="#cb12-4" tabindex="-1"></a><span class="ex">$</span> systemctl start radicale</span>
<span id="cb12-5"><a aria-hidden="true" href="#cb12-5" tabindex="-1"></a><span class="co"># Check the status of the service</span></span>
<span id="cb12-6"><a aria-hidden="true" href="#cb12-6" tabindex="-1"></a><span class="ex">$</span> systemctl status radicale</span>
<span id="cb12-7"><a aria-hidden="true" href="#cb12-7" tabindex="-1"></a><span class="co"># View all log messages</span></span>
<span id="cb12-8"><a aria-hidden="true" href="#cb12-8" tabindex="-1"></a><span class="ex">$</span> journalctl <span class="at">--unit</span> radicale.service</span></code></pre></div>
</section>
<section class="level4" id="tutorials/running-as-a-service/linux-with-systemd-as-a-user">
<h4>Linux with systemd as a user <a class="headerlink" href="#tutorials/running-as-a-service/linux-with-systemd-as-a-user">&para;</a></h4>
<p>Create the file <code>~/.config/systemd/user/radicale.service</code>:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb13-1"><a href="#cb13-1"></a><span class="kw">[Unit]</span></span>
<span id="cb13-2"><a href="#cb13-2"></a><span class="dt">Description</span><span class="ot">=</span><span class="st">A simple CalDAV (calendar) and CardDAV (contact) server</span></span>
<span id="cb13-3"><a href="#cb13-3"></a></span>
<span id="cb13-4"><a href="#cb13-4"></a><span class="kw">[Service]</span></span>
<span id="cb13-5"><a href="#cb13-5"></a><span class="dt">ExecStart</span><span class="ot">=</span><span class="st">/usr/bin/env python3 -m radicale</span></span>
<span id="cb13-6"><a href="#cb13-6"></a><span class="dt">Restart</span><span class="ot">=</span><span class="kw">on</span><span class="st">-failure</span></span>
<span id="cb13-7"><a href="#cb13-7"></a></span>
<span id="cb13-8"><a href="#cb13-8"></a><span class="kw">[Install]</span></span>
<span id="cb13-9"><a href="#cb13-9"></a><span class="dt">WantedBy</span><span class="ot">=</span><span class="kw">default</span><span class="st">.target</span></span></code></pre></div>
<div class="sourceCode" id="cb13"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb13-1"><a aria-hidden="true" href="#cb13-1" tabindex="-1"></a><span class="kw">[Unit]</span></span>
<span id="cb13-2"><a aria-hidden="true" href="#cb13-2" tabindex="-1"></a><span class="dt">Description</span><span class="ot">=</span><span class="st">A simple CalDAV (calendar) and CardDAV (contact) server</span></span>
<span id="cb13-3"><a aria-hidden="true" href="#cb13-3" tabindex="-1"></a></span>
<span id="cb13-4"><a aria-hidden="true" href="#cb13-4" tabindex="-1"></a><span class="kw">[Service]</span></span>
<span id="cb13-5"><a aria-hidden="true" href="#cb13-5" tabindex="-1"></a><span class="dt">ExecStart</span><span class="ot">=</span><span class="st">/usr/bin/env python3 -m radicale</span></span>
<span id="cb13-6"><a aria-hidden="true" href="#cb13-6" tabindex="-1"></a><span class="dt">Restart</span><span class="ot">=</span><span class="st">on-failure</span></span>
<span id="cb13-7"><a aria-hidden="true" href="#cb13-7" tabindex="-1"></a></span>
<span id="cb13-8"><a aria-hidden="true" href="#cb13-8" tabindex="-1"></a><span class="kw">[Install]</span></span>
<span id="cb13-9"><a aria-hidden="true" href="#cb13-9" tabindex="-1"></a><span class="dt">WantedBy</span><span class="ot">=</span><span class="st">default.target</span></span></code></pre></div>
<p>Radicale will load the configuration file from <code>~/.config/radicale/config</code>. You should set the configuration option <code>filesystem_folder</code> in the <code>storage</code> section to something like <code>~/.var/lib/radicale/collections</code>.</p>
<p>To enable and manage the service run:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1"></a><span class="co"># Enable the service</span></span>
<span id="cb14-2"><a href="#cb14-2"></a>$ <span class="ex">systemctl</span> --user enable radicale</span>
<span id="cb14-3"><a href="#cb14-3"></a><span class="co"># Start the service</span></span>
<span id="cb14-4"><a href="#cb14-4"></a>$ <span class="ex">systemctl</span> --user start radicale</span>
<span id="cb14-5"><a href="#cb14-5"></a><span class="co"># Check the status of the service</span></span>
<span id="cb14-6"><a href="#cb14-6"></a>$ <span class="ex">systemctl</span> --user status radicale</span>
<span id="cb14-7"><a href="#cb14-7"></a><span class="co"># View all log messages</span></span>
<span id="cb14-8"><a href="#cb14-8"></a>$ <span class="ex">journalctl</span> --user --unit radicale.service</span></code></pre></div>
<div class="sourceCode" id="cb14"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb14-1"><a aria-hidden="true" href="#cb14-1" tabindex="-1"></a><span class="co"># Enable the service</span></span>
<span id="cb14-2"><a aria-hidden="true" href="#cb14-2" tabindex="-1"></a><span class="ex">$</span> systemctl <span class="at">--user</span> enable radicale</span>
<span id="cb14-3"><a aria-hidden="true" href="#cb14-3" tabindex="-1"></a><span class="co"># Start the service</span></span>
<span id="cb14-4"><a aria-hidden="true" href="#cb14-4" tabindex="-1"></a><span class="ex">$</span> systemctl <span class="at">--user</span> start radicale</span>
<span id="cb14-5"><a aria-hidden="true" href="#cb14-5" tabindex="-1"></a><span class="co"># Check the status of the service</span></span>
<span id="cb14-6"><a aria-hidden="true" href="#cb14-6" tabindex="-1"></a><span class="ex">$</span> systemctl <span class="at">--user</span> status radicale</span>
<span id="cb14-7"><a aria-hidden="true" href="#cb14-7" tabindex="-1"></a><span class="co"># View all log messages</span></span>
<span id="cb14-8"><a aria-hidden="true" href="#cb14-8" tabindex="-1"></a><span class="ex">$</span> journalctl <span class="at">--user</span> <span class="at">--unit</span> radicale.service</span></code></pre></div>
</section>
<section class="level4" id="tutorials/running-as-a-service/windows-with-nssm---the-non-sucking-service-manager">
<h4>Windows with "NSSM - the Non-Sucking Service Manager" <a class="headerlink" href="#tutorials/running-as-a-service/windows-with-nssm---the-non-sucking-service-manager">&para;</a></h4>
@ -452,24 +584,23 @@ user2:password2
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass_header Authorization;
}
</code></pre>
}</code></pre>
<p>Example <strong>Apache</strong> configuration:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb16-1"><a href="#cb16-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb16-2"><a href="#cb16-2"></a>RewriteRule<span class="st"> ^/radicale$ /radicale/ [R,L]</span></span>
<span id="cb16-3"><a href="#cb16-3"></a></span>
<span id="cb16-4"><a href="#cb16-4"></a><span class="fu">&lt;Location</span><span class="at"> "/radicale/"</span><span class="fu">&gt;</span></span>
<span id="cb16-5"><a href="#cb16-5"></a> ProxyPass<span class="st"> http://localhost:5232/ retry=0</span></span>
<span id="cb16-6"><a href="#cb16-6"></a> ProxyPassReverse<span class="st"> http://localhost:5232/</span></span>
<span id="cb16-7"><a href="#cb16-7"></a> RequestHeader<span class="st"> set X-Script-Name /radicale</span></span>
<span id="cb16-8"><a href="#cb16-8"></a><span class="fu">&lt;/Location&gt;</span></span></code></pre></div>
<div class="sourceCode" id="cb16"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb16-1"><a aria-hidden="true" href="#cb16-1" tabindex="-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb16-2"><a aria-hidden="true" href="#cb16-2" tabindex="-1"></a>RewriteRule<span class="st"> ^/radicale$ /radicale/ [R,L]</span></span>
<span id="cb16-3"><a aria-hidden="true" href="#cb16-3" tabindex="-1"></a></span>
<span id="cb16-4"><a aria-hidden="true" href="#cb16-4" tabindex="-1"></a><span class="fu">&lt;Location</span><span class="at"> "/radicale/"</span><span class="fu">&gt;</span></span>
<span id="cb16-5"><a aria-hidden="true" href="#cb16-5" tabindex="-1"></a> ProxyPass<span class="st"> http://localhost:5232/ retry=0</span></span>
<span id="cb16-6"><a aria-hidden="true" href="#cb16-6" tabindex="-1"></a> ProxyPassReverse<span class="st"> http://localhost:5232/</span></span>
<span id="cb16-7"><a aria-hidden="true" href="#cb16-7" tabindex="-1"></a> RequestHeader<span class="st"> set X-Script-Name /radicale</span></span>
<span id="cb16-8"><a aria-hidden="true" href="#cb16-8" tabindex="-1"></a><span class="fu">&lt;/Location&gt;</span></span></code></pre></div>
<p>Example <strong>Apache .htaccess</strong> configuration:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb17-1"><a href="#cb17-1"></a>DirectoryIndex<span class="st"> disabled</span></span>
<span id="cb17-2"><a href="#cb17-2"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb17-3"><a href="#cb17-3"></a>RewriteRule<span class="st"> ^(.*)$ http://localhost:5232/$1 [P,L]</span></span>
<span id="cb17-4"><a href="#cb17-4"></a></span>
<span id="cb17-5"><a href="#cb17-5"></a><span class="co"># Set to directory of .htaccess file:</span></span>
<span id="cb17-6"><a href="#cb17-6"></a>RequestHeader<span class="st"> set X-Script-Name /radicale</span></span></code></pre></div>
<div class="sourceCode" id="cb17"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb17-1"><a aria-hidden="true" href="#cb17-1" tabindex="-1"></a>DirectoryIndex<span class="st"> disabled</span></span>
<span id="cb17-2"><a aria-hidden="true" href="#cb17-2" tabindex="-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb17-3"><a aria-hidden="true" href="#cb17-3" tabindex="-1"></a>RewriteRule<span class="st"> ^(.*)$ http://localhost:5232/$1 [P,L]</span></span>
<span id="cb17-4"><a aria-hidden="true" href="#cb17-4" tabindex="-1"></a></span>
<span id="cb17-5"><a aria-hidden="true" href="#cb17-5" tabindex="-1"></a><span class="co"># Set to directory of .htaccess file:</span></span>
<span id="cb17-6"><a aria-hidden="true" href="#cb17-6" tabindex="-1"></a>RequestHeader<span class="st"> set X-Script-Name /radicale</span></span></code></pre></div>
<p>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.</p>
<section class="level4" id="tutorials/reverse-proxy/manage-user-accounts-with-the-reverse-proxy">
<h4>Manage user accounts with the reverse proxy <a class="headerlink" href="#tutorials/reverse-proxy/manage-user-accounts-with-the-reverse-proxy">&para;</a></h4>
@ -483,36 +614,35 @@ user2:password2
proxy_set_header Host $http_host;
auth_basic "Radicale - Password Required";
auth_basic_user_file /etc/nginx/htpasswd;
}
</code></pre>
}</code></pre>
<p>Example <strong>Apache</strong> configuration:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb19-1"><a href="#cb19-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb19-2"><a href="#cb19-2"></a>RewriteRule<span class="st"> ^/radicale$ /radicale/ [R,L]</span></span>
<span id="cb19-3"><a href="#cb19-3"></a></span>
<span id="cb19-4"><a href="#cb19-4"></a><span class="fu">&lt;Location</span><span class="at"> "/radicale/"</span><span class="fu">&gt;</span></span>
<span id="cb19-5"><a href="#cb19-5"></a> <span class="ex">AuthType</span><span class="ch"> </span><span class="kw">Basic</span></span>
<span id="cb19-6"><a href="#cb19-6"></a> AuthName<span class="st"> "Radicale - Password Required"</span></span>
<span id="cb19-7"><a href="#cb19-7"></a> AuthUserFile<span class="st"> "/etc/radicale/htpasswd"</span></span>
<span id="cb19-8"><a href="#cb19-8"></a> Require<span class="st"> valid-user</span></span>
<span id="cb19-9"><a href="#cb19-9"></a></span>
<span id="cb19-10"><a href="#cb19-10"></a> ProxyPass<span class="st"> http://localhost:5232/ retry=0</span></span>
<span id="cb19-11"><a href="#cb19-11"></a> ProxyPassReverse<span class="st"> http://localhost:5232/</span></span>
<span id="cb19-12"><a href="#cb19-12"></a> RequestHeader<span class="st"> set X-Script-Name /radicale</span></span>
<span id="cb19-13"><a href="#cb19-13"></a> RequestHeader<span class="st"> set X-Remote-User expr=%{REMOTE_USER}</span></span>
<span id="cb19-14"><a href="#cb19-14"></a><span class="fu">&lt;/Location&gt;</span></span></code></pre></div>
<div class="sourceCode" id="cb19"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb19-1"><a aria-hidden="true" href="#cb19-1" tabindex="-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb19-2"><a aria-hidden="true" href="#cb19-2" tabindex="-1"></a>RewriteRule<span class="st"> ^/radicale$ /radicale/ [R,L]</span></span>
<span id="cb19-3"><a aria-hidden="true" href="#cb19-3" tabindex="-1"></a></span>
<span id="cb19-4"><a aria-hidden="true" href="#cb19-4" tabindex="-1"></a><span class="fu">&lt;Location</span><span class="at"> "/radicale/"</span><span class="fu">&gt;</span></span>
<span id="cb19-5"><a aria-hidden="true" href="#cb19-5" tabindex="-1"></a> <span class="ex">AuthType</span><span class="ch"> </span><span class="kw">Basic</span></span>
<span id="cb19-6"><a aria-hidden="true" href="#cb19-6" tabindex="-1"></a> AuthName<span class="st"> "Radicale - Password Required"</span></span>
<span id="cb19-7"><a aria-hidden="true" href="#cb19-7" tabindex="-1"></a> AuthUserFile<span class="st"> "/etc/radicale/htpasswd"</span></span>
<span id="cb19-8"><a aria-hidden="true" href="#cb19-8" tabindex="-1"></a> Require<span class="st"> valid-user</span></span>
<span id="cb19-9"><a aria-hidden="true" href="#cb19-9" tabindex="-1"></a></span>
<span id="cb19-10"><a aria-hidden="true" href="#cb19-10" tabindex="-1"></a> ProxyPass<span class="st"> http://localhost:5232/ retry=0</span></span>
<span id="cb19-11"><a aria-hidden="true" href="#cb19-11" tabindex="-1"></a> ProxyPassReverse<span class="st"> http://localhost:5232/</span></span>
<span id="cb19-12"><a aria-hidden="true" href="#cb19-12" tabindex="-1"></a> RequestHeader<span class="st"> set X-Script-Name /radicale</span></span>
<span id="cb19-13"><a aria-hidden="true" href="#cb19-13" tabindex="-1"></a> RequestHeader<span class="st"> set X-Remote-User expr=%{REMOTE_USER}</span></span>
<span id="cb19-14"><a aria-hidden="true" href="#cb19-14" tabindex="-1"></a><span class="fu">&lt;/Location&gt;</span></span></code></pre></div>
<p>Example <strong>Apache .htaccess</strong> configuration:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb20-1"><a href="#cb20-1"></a>DirectoryIndex<span class="st"> disabled</span></span>
<span id="cb20-2"><a href="#cb20-2"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb20-3"><a href="#cb20-3"></a>RewriteRule<span class="st"> ^(.*)$ http://localhost:5232/$1 [P,L]</span></span>
<span id="cb20-4"><a href="#cb20-4"></a></span>
<span id="cb20-5"><a href="#cb20-5"></a><span class="ex">AuthType</span><span class="ch"> </span><span class="kw">Basic</span></span>
<span id="cb20-6"><a href="#cb20-6"></a>AuthName<span class="st"> "Radicale - Password Required"</span></span>
<span id="cb20-7"><a href="#cb20-7"></a>AuthUserFile<span class="st"> "/etc/radicale/htpasswd"</span></span>
<span id="cb20-8"><a href="#cb20-8"></a>Require<span class="st"> valid-user</span></span>
<span id="cb20-9"><a href="#cb20-9"></a></span>
<span id="cb20-10"><a href="#cb20-10"></a><span class="co"># Set to directory of .htaccess file:</span></span>
<span id="cb20-11"><a href="#cb20-11"></a>RequestHeader<span class="st"> set X-Script-Name /radicale</span></span>
<span id="cb20-12"><a href="#cb20-12"></a>RequestHeader<span class="st"> set X-Remote-User expr=%{REMOTE_USER}</span></span></code></pre></div>
<div class="sourceCode" id="cb20"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb20-1"><a aria-hidden="true" href="#cb20-1" tabindex="-1"></a>DirectoryIndex<span class="st"> disabled</span></span>
<span id="cb20-2"><a aria-hidden="true" href="#cb20-2" tabindex="-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb20-3"><a aria-hidden="true" href="#cb20-3" tabindex="-1"></a>RewriteRule<span class="st"> ^(.*)$ http://localhost:5232/$1 [P,L]</span></span>
<span id="cb20-4"><a aria-hidden="true" href="#cb20-4" tabindex="-1"></a></span>
<span id="cb20-5"><a aria-hidden="true" href="#cb20-5" tabindex="-1"></a><span class="ex">AuthType</span><span class="ch"> </span><span class="kw">Basic</span></span>
<span id="cb20-6"><a aria-hidden="true" href="#cb20-6" tabindex="-1"></a>AuthName<span class="st"> "Radicale - Password Required"</span></span>
<span id="cb20-7"><a aria-hidden="true" href="#cb20-7" tabindex="-1"></a>AuthUserFile<span class="st"> "/etc/radicale/htpasswd"</span></span>
<span id="cb20-8"><a aria-hidden="true" href="#cb20-8" tabindex="-1"></a>Require<span class="st"> valid-user</span></span>
<span id="cb20-9"><a aria-hidden="true" href="#cb20-9" tabindex="-1"></a></span>
<span id="cb20-10"><a aria-hidden="true" href="#cb20-10" tabindex="-1"></a><span class="co"># Set to directory of .htaccess file:</span></span>
<span id="cb20-11"><a aria-hidden="true" href="#cb20-11" tabindex="-1"></a>RequestHeader<span class="st"> set X-Script-Name /radicale</span></span>
<span id="cb20-12"><a aria-hidden="true" href="#cb20-12" tabindex="-1"></a>RequestHeader<span class="st"> set X-Remote-User expr=%{REMOTE_USER}</span></span></code></pre></div>
<blockquote>
<p><strong>Security:</strong> Untrusted clients should not be able to access the Radicale server directly. Otherwise, they can authenticate as any user.</p>
</blockquote>
@ -520,14 +650,14 @@ user2:password2
<section class="level4" id="tutorials/reverse-proxy/secure-connection-between-radicale-and-the-reverse-proxy">
<h4>Secure connection between Radicale and the reverse proxy <a class="headerlink" href="#tutorials/reverse-proxy/secure-connection-between-radicale-and-the-reverse-proxy">&para;</a></h4>
<p>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.</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb21-1"><a href="#cb21-1"></a>$ <span class="ex">openssl</span> req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem -nodes -days 9999</span>
<span id="cb21-2"><a href="#cb21-2"></a>$ <span class="ex">openssl</span> req -x509 -newkey rsa:4096 -keyout client_key.pem -out client_cert.pem -nodes -days 9999</span></code></pre></div>
<div class="sourceCode" id="cb21"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb21-1"><a aria-hidden="true" href="#cb21-1" tabindex="-1"></a><span class="ex">$</span> openssl req <span class="at">-x509</span> <span class="at">-newkey</span> rsa:4096 <span class="at">-keyout</span> server_key.pem <span class="at">-out</span> server_cert.pem <span class="at">-nodes</span> <span class="at">-days</span> 9999</span>
<span id="cb21-2"><a aria-hidden="true" href="#cb21-2" tabindex="-1"></a><span class="ex">$</span> openssl req <span class="at">-x509</span> <span class="at">-newkey</span> rsa:4096 <span class="at">-keyout</span> client_key.pem <span class="at">-out</span> client_cert.pem <span class="at">-nodes</span> <span class="at">-days</span> 9999</span></code></pre></div>
<p>Use the following configuration for Radicale:</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb22-1"><a href="#cb22-1"></a><span class="kw">[server]</span></span>
<span id="cb22-2"><a href="#cb22-2"></a><span class="dt">ssl </span><span class="ot">=</span><span class="st"> </span><span class="kw">True</span></span>
<span id="cb22-3"><a href="#cb22-3"></a><span class="dt">certificate </span><span class="ot">=</span><span class="st"> /path/to/server_cert.pem</span></span>
<span id="cb22-4"><a href="#cb22-4"></a><span class="dt">key </span><span class="ot">=</span><span class="st"> /path/to/server_key.pem</span></span>
<span id="cb22-5"><a href="#cb22-5"></a><span class="dt">certificate_authority </span><span class="ot">=</span><span class="st"> /path/to/client_cert.pem</span></span></code></pre></div>
<div class="sourceCode" id="cb22"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb22-1"><a aria-hidden="true" href="#cb22-1" tabindex="-1"></a><span class="kw">[server]</span></span>
<span id="cb22-2"><a aria-hidden="true" href="#cb22-2" tabindex="-1"></a><span class="dt">ssl </span><span class="ot">=</span><span class="st"> </span><span class="kw">True</span></span>
<span id="cb22-3"><a aria-hidden="true" href="#cb22-3" tabindex="-1"></a><span class="dt">certificate </span><span class="ot">=</span><span class="st"> /path/to/server_cert.pem</span></span>
<span id="cb22-4"><a aria-hidden="true" href="#cb22-4" tabindex="-1"></a><span class="dt">key </span><span class="ot">=</span><span class="st"> /path/to/server_key.pem</span></span>
<span id="cb22-5"><a aria-hidden="true" href="#cb22-5" tabindex="-1"></a><span class="dt">certificate_authority </span><span class="ot">=</span><span class="st"> /path/to/client_cert.pem</span></span></code></pre></div>
<p>Example <strong>nginx</strong> configuration:</p>
<pre class="nginx"><code>location /radicale/ {
proxy_pass https://localhost:5232/;
@ -536,8 +666,7 @@ user2:password2
proxy_ssl_certificate /path/to/client_cert.pem;
proxy_ssl_certificate_key /path/to/client_key.pem;
proxy_ssl_trusted_certificate /path/to/server_cert.pem;
}
</code></pre>
}</code></pre>
</section>
</section>
<section class="level3" id="tutorials/wsgi-server">
@ -545,14 +674,14 @@ user2:password2
<p>Radicale is compatible with the WSGI specification.</p>
<p>A configuration file can be set with the <code>RADICALE_CONFIG</code> environment variable, otherwise no configuration file is loaded and the default configuration is used.</p>
<p>Example <strong>uWSGI</strong> configuration:</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb24-1"><a href="#cb24-1"></a><span class="kw">[uwsgi]</span></span>
<span id="cb24-2"><a href="#cb24-2"></a><span class="dt">http-socket </span><span class="ot">=</span><span class="st"> </span><span class="dv">127</span><span class="st">.</span><span class="dv">0</span><span class="st">.</span><span class="fl">0.1</span><span class="st">:</span><span class="dv">5232</span></span>
<span id="cb24-3"><a href="#cb24-3"></a><span class="dt">processes </span><span class="ot">=</span><span class="st"> </span><span class="dv">8</span></span>
<span id="cb24-4"><a href="#cb24-4"></a><span class="dt">plugin </span><span class="ot">=</span><span class="st"> python3</span></span>
<span id="cb24-5"><a href="#cb24-5"></a><span class="dt">module </span><span class="ot">=</span><span class="st"> radicale</span></span>
<span id="cb24-6"><a href="#cb24-6"></a><span class="dt">env </span><span class="ot">=</span><span class="st"> RADICALE_CONFIG=/etc/radicale/config</span></span></code></pre></div>
<div class="sourceCode" id="cb24"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb24-1"><a aria-hidden="true" href="#cb24-1" tabindex="-1"></a><span class="kw">[uwsgi]</span></span>
<span id="cb24-2"><a aria-hidden="true" href="#cb24-2" tabindex="-1"></a><span class="dt">http-socket </span><span class="ot">=</span><span class="st"> 127.0.0.1:5232</span></span>
<span id="cb24-3"><a aria-hidden="true" href="#cb24-3" tabindex="-1"></a><span class="dt">processes </span><span class="ot">=</span><span class="st"> </span><span class="dv">8</span></span>
<span id="cb24-4"><a aria-hidden="true" href="#cb24-4" tabindex="-1"></a><span class="dt">plugin </span><span class="ot">=</span><span class="st"> python3</span></span>
<span id="cb24-5"><a aria-hidden="true" href="#cb24-5" tabindex="-1"></a><span class="dt">module </span><span class="ot">=</span><span class="st"> radicale</span></span>
<span id="cb24-6"><a aria-hidden="true" href="#cb24-6" tabindex="-1"></a><span class="dt">env </span><span class="ot">=</span><span class="st"> RADICALE_CONFIG=/etc/radicale/config</span></span></code></pre></div>
<p>Example <strong>Gunicorn</strong> configuration:</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb25-1"><a href="#cb25-1"></a><span class="ex">gunicorn</span> --bind <span class="st">'127.0.0.1:5232'</span> --workers 8 --env <span class="st">'RADICALE_CONFIG=/etc/radicale/config'</span> radicale</span></code></pre></div>
<div class="sourceCode" id="cb25"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb25-1"><a aria-hidden="true" href="#cb25-1" tabindex="-1"></a><span class="ex">gunicorn</span> <span class="at">--bind</span> <span class="st">'127.0.0.1:5232'</span> <span class="at">--workers</span> 8 <span class="at">--env</span> <span class="st">'RADICALE_CONFIG=/etc/radicale/config'</span> radicale</span></code></pre></div>
<section class="level4" id="tutorials/wsgi-server/manage-user-accounts-with-the-wsgi-server">
<h4>Manage user accounts with the WSGI server <a class="headerlink" href="#tutorials/wsgi-server/manage-user-accounts-with-the-wsgi-server">&para;</a></h4>
<p>Set the configuration option <code>type</code> in the <code>auth</code> section to <code>remote_user</code>. Radicale uses the user name provided by the WSGI server and disables authentication over HTTP.</p>
@ -564,10 +693,9 @@ user2:password2
<p>The repository must be initialized by running <code>git init</code> in the file system folder. Internal files of Radicale can be excluded by creating the file <code>.gitignore</code> with the following content:</p>
<pre><code>.Radicale.cache
.Radicale.lock
.Radicale.tmp-*
</code></pre>
.Radicale.tmp-*</code></pre>
<p>The configuration option <code>hook</code> in the <code>storage</code> section must be set to the following command:</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb27-1"><a href="#cb27-1"></a><span class="fu">git</span> add -A <span class="kw">&amp;&amp;</span> <span class="kw">(</span><span class="fu">git</span> diff --cached --quiet <span class="kw">||</span> <span class="fu">git</span> commit -m <span class="st">"Changes by "</span>%(user<span class="kw">)</span><span class="ex">s</span>)</span></code></pre></div>
<div class="sourceCode" id="cb27"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb27-1"><a aria-hidden="true" href="#cb27-1" tabindex="-1"></a><span class="fu">git</span> add <span class="at">-A</span> <span class="kw">&amp;&amp;</span> <span class="kw">(</span><span class="fu">git</span> diff <span class="at">--cached</span> <span class="at">--quiet</span> <span class="kw">||</span> <span class="fu">git</span> commit <span class="at">-m</span> <span class="st">"Changes by "</span>%<span class="er">(</span><span class="ex">user</span><span class="kw">)</span><span class="ex">s</span><span class="kw">)</span></span></code></pre></div>
<p>The command gets executed after every change to the storage and commits the changes into the <strong>git</strong> repository.</p>
</section>
</section>
@ -577,20 +705,20 @@ user2:password2
<h3>Configuration <a class="headerlink" href="#documentation/configuration">&para;</a></h3>
<p>Radicale can be configured with a configuration file or with command line arguments.</p>
<p>An example configuration file looks like:</p>
<div class="sourceCode" id="cb28"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb28-1"><a href="#cb28-1"></a><span class="kw">[server]</span></span>
<span id="cb28-2"><a href="#cb28-2"></a><span class="co"># Bind all addresses</span></span>
<span id="cb28-3"><a href="#cb28-3"></a><span class="dt">hosts </span><span class="ot">=</span><span class="st"> </span><span class="dv">0</span><span class="st">.</span><span class="dv">0</span><span class="st">.</span><span class="fl">0.0</span><span class="st">:</span><span class="dv">5232</span><span class="st">, [::]:</span><span class="dv">5232</span></span>
<span id="cb28-4"><a href="#cb28-4"></a></span>
<span id="cb28-5"><a href="#cb28-5"></a><span class="kw">[auth]</span></span>
<span id="cb28-6"><a href="#cb28-6"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb28-7"><a href="#cb28-7"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> ~/.config/radicale/users</span></span>
<span id="cb28-8"><a href="#cb28-8"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> md5</span></span>
<span id="cb28-9"><a href="#cb28-9"></a></span>
<span id="cb28-10"><a href="#cb28-10"></a><span class="kw">[storage]</span></span>
<span id="cb28-11"><a href="#cb28-11"></a><span class="dt">filesystem_folder </span><span class="ot">=</span><span class="st"> ~/.var/lib/radicale/collections</span></span></code></pre></div>
<div class="sourceCode" id="cb28"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb28-1"><a aria-hidden="true" href="#cb28-1" tabindex="-1"></a><span class="kw">[server]</span></span>
<span id="cb28-2"><a aria-hidden="true" href="#cb28-2" tabindex="-1"></a><span class="co"># Bind all addresses</span></span>
<span id="cb28-3"><a aria-hidden="true" href="#cb28-3" tabindex="-1"></a><span class="dt">hosts </span><span class="ot">=</span><span class="st"> 0.0.0.0:5232, [::]:5232</span></span>
<span id="cb28-4"><a aria-hidden="true" href="#cb28-4" tabindex="-1"></a></span>
<span id="cb28-5"><a aria-hidden="true" href="#cb28-5" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb28-6"><a aria-hidden="true" href="#cb28-6" tabindex="-1"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb28-7"><a aria-hidden="true" href="#cb28-7" tabindex="-1"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> ~/.config/radicale/users</span></span>
<span id="cb28-8"><a aria-hidden="true" href="#cb28-8" tabindex="-1"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> md5</span></span>
<span id="cb28-9"><a aria-hidden="true" href="#cb28-9" tabindex="-1"></a></span>
<span id="cb28-10"><a aria-hidden="true" href="#cb28-10" tabindex="-1"></a><span class="kw">[storage]</span></span>
<span id="cb28-11"><a aria-hidden="true" href="#cb28-11" tabindex="-1"></a><span class="dt">filesystem_folder </span><span class="ot">=</span><span class="st"> ~/.var/lib/radicale/collections</span></span></code></pre></div>
<p>Radicale tries to load configuration files from <code>/etc/radicale/config</code> and <code>~/.config/radicale/config</code>. Custom paths can be specified with the <code>--config /path/to/config</code> command line argument or the <code>RADICALE_CONFIG</code> environment variable. Multiple configuration files can be separated by <code>:</code> (resp. <code>;</code> on Windows). Paths that start with <code>?</code> are optional.</p>
<p>The same example configuration via command line arguments looks like:</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb29-1"><a href="#cb29-1"></a><span class="ex">python3</span> -m radicale --server-hosts 0.0.0.0:5232,[::]:5232 --auth-type htpasswd --htpasswd-filename ~/.config/radicale/users --htpasswd-encryption md5</span></code></pre></div>
<div class="sourceCode" id="cb29"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb29-1"><a aria-hidden="true" href="#cb29-1" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> radicale <span class="at">--server-hosts</span> 0.0.0.0:5232,[::]:5232 <span class="at">--auth-type</span> htpasswd <span class="at">--htpasswd-filename</span> ~/.config/radicale/users <span class="at">--htpasswd-encryption</span> md5</span></code></pre></div>
<p>Add the argument <code>--config ""</code> to stop Radicale from loading the default configuration files. Run <code>python3 -m radicale --help</code> for more information.</p>
<p>In the following, all configuration categories and options are described.</p>
<section class="level4" id="documentation/configuration/server">
@ -673,8 +801,7 @@ user2:password2
<p>Available methods:</p>
<p><code>plain</code> : Passwords are stored in plaintext. This is obviously not secure! The htpasswd file for this can be created by hand and looks like:</p>
<pre class="htpasswd"><code>user1:password1
user2:password2
</code></pre>
user2:password2</code></pre>
<p><code>bcrypt</code> : This uses a modified version of the Blowfish stream cipher. It's very secure. The installation of <strong>radicale[bcrypt]</strong> is required for this.</p>
<p><code>md5</code> : This uses an iterated md5 digest of the password with a salt.</p>
<p>Default: <code>md5</code></p>
@ -762,7 +889,7 @@ user2:password2
<h4>headers <a class="headerlink" href="#documentation/configuration/headers">&para;</a></h4>
<p>In this section additional HTTP headers that are sent to clients can be specified.</p>
<p>An example to relax the same-origin policy:</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb31-1"><a href="#cb31-1"></a><span class="dt">Access-Control-Allow-Origin </span><span class="ot">=</span><span class="st"> *</span></span></code></pre></div>
<div class="sourceCode" id="cb31"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb31-1"><a aria-hidden="true" href="#cb31-1" tabindex="-1"></a><span class="dt">Access-Control-Allow-Origin </span><span class="ot">=</span><span class="st"> *</span></span></code></pre></div>
</section>
</section>
<section class="level3" id="documentation/supported-clients">
@ -774,7 +901,7 @@ user2:password2
<li><a href="https://www.mozilla.org/thunderbird/">Mozilla Thunderbird</a> with <a href="https://addons.mozilla.org/thunderbird/addon/cardbook/">CardBook</a> and <a href="https://www.mozilla.org/projects/calendar/">Lightning</a></li>
<li><a href="https://www.inf-it.com/open-source/clients/infcloud/">InfCloud</a>, <a href="https://www.inf-it.com/open-source/clients/caldavzap/">CalDavZAP</a> and <a href="https://www.inf-it.com/open-source/clients/carddavmate/">CardDavMATE</a></li>
</ul>
<p>Many clients do not support the creation of new calendars and address books. You can use Radicale's web interface (e.g. <a href="http://localhost:5232">http://localhost:5232</a>) to create and manage address books and calendars.</p>
<p>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.</p>
<p>In some clients you can just enter the URL of the Radicale server (e.g. <code>http://localhost:5232</code>) and your user name. In others, you have to enter the URL of the collection directly (e.g. <code>http://localhost:5232/user/calendar</code>).</p>
<section class="level4" id="documentation/supported-clients/davx⁵">
<h4>DAVx⁵ <a class="headerlink" href="#documentation/supported-clients/davx⁵">&para;</a></h4>
@ -805,44 +932,44 @@ user2:password2
<h4>Command line <a class="headerlink" href="#documentation/supported-clients/command-line">&para;</a></h4>
<p>This is not the recommended way of creating and managing your calendars and address books. Use Radicale's web interface or a client with support for it (e.g. <strong>DAVx⁵</strong>).</p>
<p>To create a new calendar run something like:</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb32-1"><a href="#cb32-1"></a>$ <span class="ex">curl</span> -u user -X MKCOL <span class="st">'http://localhost:5232/user/calendar'</span> --data \</span>
<span id="cb32-2"><a href="#cb32-2"></a><span class="st">'&lt;?xml version="1.0" encoding="UTF-8" ?&gt;</span></span>
<span id="cb32-3"><a href="#cb32-3"></a><span class="st">&lt;create xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:I="http://apple.com/ns/ical/"&gt;</span></span>
<span id="cb32-4"><a href="#cb32-4"></a><span class="st"> &lt;set&gt;</span></span>
<span id="cb32-5"><a href="#cb32-5"></a><span class="st"> &lt;prop&gt;</span></span>
<span id="cb32-6"><a href="#cb32-6"></a><span class="st"> &lt;resourcetype&gt;</span></span>
<span id="cb32-7"><a href="#cb32-7"></a><span class="st"> &lt;collection /&gt;</span></span>
<span id="cb32-8"><a href="#cb32-8"></a><span class="st"> &lt;C:calendar /&gt;</span></span>
<span id="cb32-9"><a href="#cb32-9"></a><span class="st"> &lt;/resourcetype&gt;</span></span>
<span id="cb32-10"><a href="#cb32-10"></a><span class="st"> &lt;C:supported-calendar-component-set&gt;</span></span>
<span id="cb32-11"><a href="#cb32-11"></a><span class="st"> &lt;C:comp name="VEVENT" /&gt;</span></span>
<span id="cb32-12"><a href="#cb32-12"></a><span class="st"> &lt;C:comp name="VJOURNAL" /&gt;</span></span>
<span id="cb32-13"><a href="#cb32-13"></a><span class="st"> &lt;C:comp name="VTODO" /&gt;</span></span>
<span id="cb32-14"><a href="#cb32-14"></a><span class="st"> &lt;/C:supported-calendar-component-set&gt;</span></span>
<span id="cb32-15"><a href="#cb32-15"></a><span class="st"> &lt;displayname&gt;Calendar&lt;/displayname&gt;</span></span>
<span id="cb32-16"><a href="#cb32-16"></a><span class="st"> &lt;C:calendar-description&gt;Example calendar&lt;/C:calendar-description&gt;</span></span>
<span id="cb32-17"><a href="#cb32-17"></a><span class="st"> &lt;I:calendar-color&gt;#ff0000ff&lt;/I:calendar-color&gt;</span></span>
<span id="cb32-18"><a href="#cb32-18"></a><span class="st"> &lt;/prop&gt;</span></span>
<span id="cb32-19"><a href="#cb32-19"></a><span class="st"> &lt;/set&gt;</span></span>
<span id="cb32-20"><a href="#cb32-20"></a><span class="st">&lt;/create&gt;'</span></span></code></pre></div>
<div class="sourceCode" id="cb32"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb32-1"><a aria-hidden="true" href="#cb32-1" tabindex="-1"></a><span class="ex">$</span> curl <span class="at">-u</span> user <span class="at">-X</span> MKCOL <span class="st">'http://localhost:5232/user/calendar'</span> <span class="at">--data</span> <span class="dt">\</span></span>
<span id="cb32-2"><a aria-hidden="true" href="#cb32-2" tabindex="-1"></a><span class="st">'&lt;?xml version="1.0" encoding="UTF-8" ?&gt;</span></span>
<span id="cb32-3"><a aria-hidden="true" href="#cb32-3" tabindex="-1"></a><span class="st">&lt;create xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:I="http://apple.com/ns/ical/"&gt;</span></span>
<span id="cb32-4"><a aria-hidden="true" href="#cb32-4" tabindex="-1"></a><span class="st"> &lt;set&gt;</span></span>
<span id="cb32-5"><a aria-hidden="true" href="#cb32-5" tabindex="-1"></a><span class="st"> &lt;prop&gt;</span></span>
<span id="cb32-6"><a aria-hidden="true" href="#cb32-6" tabindex="-1"></a><span class="st"> &lt;resourcetype&gt;</span></span>
<span id="cb32-7"><a aria-hidden="true" href="#cb32-7" tabindex="-1"></a><span class="st"> &lt;collection /&gt;</span></span>
<span id="cb32-8"><a aria-hidden="true" href="#cb32-8" tabindex="-1"></a><span class="st"> &lt;C:calendar /&gt;</span></span>
<span id="cb32-9"><a aria-hidden="true" href="#cb32-9" tabindex="-1"></a><span class="st"> &lt;/resourcetype&gt;</span></span>
<span id="cb32-10"><a aria-hidden="true" href="#cb32-10" tabindex="-1"></a><span class="st"> &lt;C:supported-calendar-component-set&gt;</span></span>
<span id="cb32-11"><a aria-hidden="true" href="#cb32-11" tabindex="-1"></a><span class="st"> &lt;C:comp name="VEVENT" /&gt;</span></span>
<span id="cb32-12"><a aria-hidden="true" href="#cb32-12" tabindex="-1"></a><span class="st"> &lt;C:comp name="VJOURNAL" /&gt;</span></span>
<span id="cb32-13"><a aria-hidden="true" href="#cb32-13" tabindex="-1"></a><span class="st"> &lt;C:comp name="VTODO" /&gt;</span></span>
<span id="cb32-14"><a aria-hidden="true" href="#cb32-14" tabindex="-1"></a><span class="st"> &lt;/C:supported-calendar-component-set&gt;</span></span>
<span id="cb32-15"><a aria-hidden="true" href="#cb32-15" tabindex="-1"></a><span class="st"> &lt;displayname&gt;Calendar&lt;/displayname&gt;</span></span>
<span id="cb32-16"><a aria-hidden="true" href="#cb32-16" tabindex="-1"></a><span class="st"> &lt;C:calendar-description&gt;Example calendar&lt;/C:calendar-description&gt;</span></span>
<span id="cb32-17"><a aria-hidden="true" href="#cb32-17" tabindex="-1"></a><span class="st"> &lt;I:calendar-color&gt;#ff0000ff&lt;/I:calendar-color&gt;</span></span>
<span id="cb32-18"><a aria-hidden="true" href="#cb32-18" tabindex="-1"></a><span class="st"> &lt;/prop&gt;</span></span>
<span id="cb32-19"><a aria-hidden="true" href="#cb32-19" tabindex="-1"></a><span class="st"> &lt;/set&gt;</span></span>
<span id="cb32-20"><a aria-hidden="true" href="#cb32-20" tabindex="-1"></a><span class="st">&lt;/create&gt;'</span></span></code></pre></div>
<p>To create a new address book run something like:</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb33-1"><a href="#cb33-1"></a>$ <span class="ex">curl</span> -u user -X MKCOL <span class="st">'http://localhost:5232/user/addressbook'</span> --data \</span>
<span id="cb33-2"><a href="#cb33-2"></a><span class="st">'&lt;?xml version="1.0" encoding="UTF-8" ?&gt;</span></span>
<span id="cb33-3"><a href="#cb33-3"></a><span class="st">&lt;create xmlns="DAV:" xmlns:CR="urn:ietf:params:xml:ns:carddav"&gt;</span></span>
<span id="cb33-4"><a href="#cb33-4"></a><span class="st"> &lt;set&gt;</span></span>
<span id="cb33-5"><a href="#cb33-5"></a><span class="st"> &lt;prop&gt;</span></span>
<span id="cb33-6"><a href="#cb33-6"></a><span class="st"> &lt;resourcetype&gt;</span></span>
<span id="cb33-7"><a href="#cb33-7"></a><span class="st"> &lt;collection /&gt;</span></span>
<span id="cb33-8"><a href="#cb33-8"></a><span class="st"> &lt;CR:addressbook /&gt;</span></span>
<span id="cb33-9"><a href="#cb33-9"></a><span class="st"> &lt;/resourcetype&gt;</span></span>
<span id="cb33-10"><a href="#cb33-10"></a><span class="st"> &lt;displayname&gt;Address book&lt;/displayname&gt;</span></span>
<span id="cb33-11"><a href="#cb33-11"></a><span class="st"> &lt;CR:addressbook-description&gt;Example address book&lt;/CR:addressbook-description&gt;</span></span>
<span id="cb33-12"><a href="#cb33-12"></a><span class="st"> &lt;/prop&gt;</span></span>
<span id="cb33-13"><a href="#cb33-13"></a><span class="st"> &lt;/set&gt;</span></span>
<span id="cb33-14"><a href="#cb33-14"></a><span class="st">&lt;/create&gt;'</span></span></code></pre></div>
<div class="sourceCode" id="cb33"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb33-1"><a aria-hidden="true" href="#cb33-1" tabindex="-1"></a><span class="ex">$</span> curl <span class="at">-u</span> user <span class="at">-X</span> MKCOL <span class="st">'http://localhost:5232/user/addressbook'</span> <span class="at">--data</span> <span class="dt">\</span></span>
<span id="cb33-2"><a aria-hidden="true" href="#cb33-2" tabindex="-1"></a><span class="st">'&lt;?xml version="1.0" encoding="UTF-8" ?&gt;</span></span>
<span id="cb33-3"><a aria-hidden="true" href="#cb33-3" tabindex="-1"></a><span class="st">&lt;create xmlns="DAV:" xmlns:CR="urn:ietf:params:xml:ns:carddav"&gt;</span></span>
<span id="cb33-4"><a aria-hidden="true" href="#cb33-4" tabindex="-1"></a><span class="st"> &lt;set&gt;</span></span>
<span id="cb33-5"><a aria-hidden="true" href="#cb33-5" tabindex="-1"></a><span class="st"> &lt;prop&gt;</span></span>
<span id="cb33-6"><a aria-hidden="true" href="#cb33-6" tabindex="-1"></a><span class="st"> &lt;resourcetype&gt;</span></span>
<span id="cb33-7"><a aria-hidden="true" href="#cb33-7" tabindex="-1"></a><span class="st"> &lt;collection /&gt;</span></span>
<span id="cb33-8"><a aria-hidden="true" href="#cb33-8" tabindex="-1"></a><span class="st"> &lt;CR:addressbook /&gt;</span></span>
<span id="cb33-9"><a aria-hidden="true" href="#cb33-9" tabindex="-1"></a><span class="st"> &lt;/resourcetype&gt;</span></span>
<span id="cb33-10"><a aria-hidden="true" href="#cb33-10" tabindex="-1"></a><span class="st"> &lt;displayname&gt;Address book&lt;/displayname&gt;</span></span>
<span id="cb33-11"><a aria-hidden="true" href="#cb33-11" tabindex="-1"></a><span class="st"> &lt;CR:addressbook-description&gt;Example address book&lt;/CR:addressbook-description&gt;</span></span>
<span id="cb33-12"><a aria-hidden="true" href="#cb33-12" tabindex="-1"></a><span class="st"> &lt;/prop&gt;</span></span>
<span id="cb33-13"><a aria-hidden="true" href="#cb33-13" tabindex="-1"></a><span class="st"> &lt;/set&gt;</span></span>
<span id="cb33-14"><a aria-hidden="true" href="#cb33-14" tabindex="-1"></a><span class="st">&lt;/create&gt;'</span></span></code></pre></div>
<p>The collection <code>/USERNAME</code> 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 <code>/USERNAME/</code>.</p>
<p>Delete the collections by running something like:</p>
<div class="sourceCode" id="cb34"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb34-1"><a href="#cb34-1"></a>$ <span class="ex">curl</span> -u user -X DELETE <span class="st">'http://localhost:5232/user/calendar'</span></span></code></pre></div>
<div class="sourceCode" id="cb34"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb34-1"><a aria-hidden="true" href="#cb34-1" tabindex="-1"></a><span class="ex">$</span> curl <span class="at">-u</span> user <span class="at">-X</span> DELETE <span class="st">'http://localhost:5232/user/calendar'</span></span></code></pre></div>
</section>
</section>
<section class="level3" id="documentation/authentication-and-rights">
@ -850,24 +977,24 @@ user2:password2
<p>This section describes the format of the rights file for the <code>from_file</code> authentication backend. The configuration option <code>file</code> in the <code>rights</code> section must point to the rights file.</p>
<p>The recommended rights method is <code>owner_only</code>. If access to calendars and address books outside the home directory of users (that's <code>/USERNAME/</code>) 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.</p>
<p>An example rights file:</p>
<div class="sourceCode" id="cb35"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb35-1"><a href="#cb35-1"></a><span class="co"># Allow reading root collection for authenticated users</span></span>
<span id="cb35-2"><a href="#cb35-2"></a><span class="kw">[root]</span></span>
<span id="cb35-3"><a href="#cb35-3"></a><span class="dt">user: .+</span></span>
<span id="cb35-4"><a href="#cb35-4"></a><span class="dt">collection:</span></span>
<span id="cb35-5"><a href="#cb35-5"></a><span class="dt">permissions: R</span></span>
<span id="cb35-6"><a href="#cb35-6"></a></span>
<span id="cb35-7"><a href="#cb35-7"></a><span class="co"># Allow reading and writing principal collection (same as user name)</span></span>
<span id="cb35-8"><a href="#cb35-8"></a><span class="kw">[principal]</span></span>
<span id="cb35-9"><a href="#cb35-9"></a><span class="dt">user: .+</span></span>
<span id="cb35-10"><a href="#cb35-10"></a><span class="dt">collection: {user}</span></span>
<span id="cb35-11"><a href="#cb35-11"></a><span class="dt">permissions: RW</span></span>
<span id="cb35-12"><a href="#cb35-12"></a></span>
<span id="cb35-13"><a href="#cb35-13"></a><span class="co"># Allow reading and writing calendars and address books that are direct</span></span>
<span id="cb35-14"><a href="#cb35-14"></a><span class="co"># children of the principal collection</span></span>
<span id="cb35-15"><a href="#cb35-15"></a><span class="kw">[calendars]</span></span>
<span id="cb35-16"><a href="#cb35-16"></a><span class="dt">user: .+</span></span>
<span id="cb35-17"><a href="#cb35-17"></a><span class="dt">collection: {user}/</span><span class="kw">[^/]</span><span class="dt">+</span></span>
<span id="cb35-18"><a href="#cb35-18"></a><span class="dt">permissions: rw</span></span></code></pre></div>
<div class="sourceCode" id="cb35"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb35-1"><a aria-hidden="true" href="#cb35-1" tabindex="-1"></a><span class="co"># Allow reading root collection for authenticated users</span></span>
<span id="cb35-2"><a aria-hidden="true" href="#cb35-2" tabindex="-1"></a><span class="kw">[root]</span></span>
<span id="cb35-3"><a aria-hidden="true" href="#cb35-3" tabindex="-1"></a><span class="dt">user: .+</span></span>
<span id="cb35-4"><a aria-hidden="true" href="#cb35-4" tabindex="-1"></a><span class="dt">collection:</span></span>
<span id="cb35-5"><a aria-hidden="true" href="#cb35-5" tabindex="-1"></a><span class="dt">permissions: R</span></span>
<span id="cb35-6"><a aria-hidden="true" href="#cb35-6" tabindex="-1"></a></span>
<span id="cb35-7"><a aria-hidden="true" href="#cb35-7" tabindex="-1"></a><span class="co"># Allow reading and writing principal collection (same as user name)</span></span>
<span id="cb35-8"><a aria-hidden="true" href="#cb35-8" tabindex="-1"></a><span class="kw">[principal]</span></span>
<span id="cb35-9"><a aria-hidden="true" href="#cb35-9" tabindex="-1"></a><span class="dt">user: .+</span></span>
<span id="cb35-10"><a aria-hidden="true" href="#cb35-10" tabindex="-1"></a><span class="dt">collection: {user}</span></span>
<span id="cb35-11"><a aria-hidden="true" href="#cb35-11" tabindex="-1"></a><span class="dt">permissions: RW</span></span>
<span id="cb35-12"><a aria-hidden="true" href="#cb35-12" tabindex="-1"></a></span>
<span id="cb35-13"><a aria-hidden="true" href="#cb35-13" tabindex="-1"></a><span class="co"># Allow reading and writing calendars and address books that are direct</span></span>
<span id="cb35-14"><a aria-hidden="true" href="#cb35-14" tabindex="-1"></a><span class="co"># children of the principal collection</span></span>
<span id="cb35-15"><a aria-hidden="true" href="#cb35-15" tabindex="-1"></a><span class="kw">[calendars]</span></span>
<span id="cb35-16"><a aria-hidden="true" href="#cb35-16" tabindex="-1"></a><span class="dt">user: .+</span></span>
<span id="cb35-17"><a aria-hidden="true" href="#cb35-17" tabindex="-1"></a><span class="dt">collection: {user}/</span><span class="kw">[^/]</span><span class="dt">+</span></span>
<span id="cb35-18"><a aria-hidden="true" href="#cb35-18" tabindex="-1"></a><span class="dt">permissions: rw</span></span></code></pre></div>
<p>The titles of the sections are ignored (but must be unique). The keys <code>user</code> and <code>collection</code> 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.</p>
<p>The user name is empty for anonymous users. Therefore, the regex <code>.+</code> only matches authenticated users and <code>.*</code> matches everyone (including anonymous users).</p>
<p>The path of the collection is separated by <code>/</code> and has no leading or trailing <code>/</code>. Therefore, the path of the root collection is empty.</p>
@ -906,10 +1033,10 @@ user2:password2
<section class="level5" id="documentation/storage/locking/linux-shell-scripts">
<h5>Linux shell scripts <a class="headerlink" href="#documentation/storage/locking/linux-shell-scripts">&para;</a></h5>
<p>Use the <a href="https://manpages.debian.org/unstable/util-linux/flock.1.en.html">flock</a> utility.</p>
<div class="sourceCode" id="cb36"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb36-1"><a href="#cb36-1"></a><span class="co"># Exclusive</span></span>
<span id="cb36-2"><a href="#cb36-2"></a>$ <span class="ex">flock</span> --exclusive /path/to/storage/.Radicale.lock COMMAND</span>
<span id="cb36-3"><a href="#cb36-3"></a><span class="co"># Shared</span></span>
<span id="cb36-4"><a href="#cb36-4"></a>$ <span class="ex">flock</span> --shared /path/to/storage/.Radicale.lock COMMAND</span></code></pre></div>
<div class="sourceCode" id="cb36"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb36-1"><a aria-hidden="true" href="#cb36-1" tabindex="-1"></a><span class="co"># Exclusive</span></span>
<span id="cb36-2"><a aria-hidden="true" href="#cb36-2" tabindex="-1"></a><span class="ex">$</span> flock <span class="at">--exclusive</span> /path/to/storage/.Radicale.lock COMMAND</span>
<span id="cb36-3"><a aria-hidden="true" href="#cb36-3" tabindex="-1"></a><span class="co"># Shared</span></span>
<span id="cb36-4"><a aria-hidden="true" href="#cb36-4" tabindex="-1"></a><span class="ex">$</span> flock <span class="at">--shared</span> /path/to/storage/.Radicale.lock COMMAND</span></code></pre></div>
</section>
<section class="level5" id="documentation/storage/locking/linux-and-macos">
<h5>Linux and MacOS <a class="headerlink" href="#documentation/storage/locking/linux-and-macos">&para;</a></h5>
@ -923,9 +1050,9 @@ user2:password2
<section class="level4" id="documentation/storage/manually-creating-collections">
<h4>Manually creating collections <a class="headerlink" href="#documentation/storage/manually-creating-collections">&para;</a></h4>
<p>To create a new collection, you have to create the corresponding folder in the file system storage (e.g. <code>collection-root/user/calendar</code>). To tell Radicale and clients that the collection is a calendar, you have to create the file <code>.Radicale.props</code> with the following content in the folder:</p>
<div class="sourceCode" id="cb37"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb37-1"><a href="#cb37-1"></a><span class="fu">{</span><span class="dt">"tag"</span><span class="fu">:</span> <span class="st">"VCALENDAR"</span><span class="fu">}</span></span></code></pre></div>
<div class="sourceCode" id="cb37"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb37-1"><a aria-hidden="true" href="#cb37-1" tabindex="-1"></a><span class="fu">{</span><span class="dt">"tag"</span><span class="fu">:</span> <span class="st">"VCALENDAR"</span><span class="fu">}</span></span></code></pre></div>
<p>The calendar is now available at the URL path <code>/user/calendar</code>. For address books the file must contain:</p>
<div class="sourceCode" id="cb38"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb38-1"><a href="#cb38-1"></a><span class="fu">{</span><span class="dt">"tag"</span><span class="fu">:</span> <span class="st">"VADDRESSBOOK"</span><span class="fu">}</span></span></code></pre></div>
<div class="sourceCode" id="cb38"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb38-1"><a aria-hidden="true" href="#cb38-1" tabindex="-1"></a><span class="fu">{</span><span class="dt">"tag"</span><span class="fu">:</span> <span class="st">"VADDRESSBOOK"</span><span class="fu">}</span></span></code></pre></div>
<p>Calendar and address book collections must not have any child collections. Clients with automatic discovery of collections will only show calendars and address books that are direct children of the path <code>/USERNAME/</code>.</p>
<p>Delete collections by deleting the corresponding folders.</p>
</section>
@ -1011,42 +1138,42 @@ user2:password2
<h4>Getting started <a class="headerlink" href="#documentation/plugins/getting-started">&para;</a></h4>
<p>To get started we walk through the creation of a simple authentication plugin, that accepts login attempts with a static password.</p>
<p>The easiest way to develop and install <strong>python</strong> modules is <a href="https://docs.python.org/3/distutils/setupscript.html">Distutils</a>. For a minimal setup create the file <code>setup.py</code> with the following content in an empty folder:</p>
<div class="sourceCode" id="cb39"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb39-1"><a href="#cb39-1"></a><span class="co">#!/usr/bin/env python3</span></span>
<span id="cb39-2"><a href="#cb39-2"></a></span>
<span id="cb39-3"><a href="#cb39-3"></a><span class="im">from</span> distutils.core <span class="im">import</span> setup</span>
<span id="cb39-4"><a href="#cb39-4"></a></span>
<span id="cb39-5"><a href="#cb39-5"></a>setup(name<span class="op">=</span><span class="st">"radicale_static_password_auth"</span>,</span>
<span id="cb39-6"><a href="#cb39-6"></a> packages<span class="op">=</span>[<span class="st">"radicale_static_password_auth"</span>])</span></code></pre></div>
<div class="sourceCode" id="cb39"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb39-1"><a aria-hidden="true" href="#cb39-1" tabindex="-1"></a><span class="co">#!/usr/bin/env python3</span></span>
<span id="cb39-2"><a aria-hidden="true" href="#cb39-2" tabindex="-1"></a></span>
<span id="cb39-3"><a aria-hidden="true" href="#cb39-3" tabindex="-1"></a><span class="im">from</span> distutils.core <span class="im">import</span> setup</span>
<span id="cb39-4"><a aria-hidden="true" href="#cb39-4" tabindex="-1"></a></span>
<span id="cb39-5"><a aria-hidden="true" href="#cb39-5" tabindex="-1"></a>setup(name<span class="op">=</span><span class="st">"radicale_static_password_auth"</span>,</span>
<span id="cb39-6"><a aria-hidden="true" href="#cb39-6" tabindex="-1"></a> packages<span class="op">=</span>[<span class="st">"radicale_static_password_auth"</span>])</span></code></pre></div>
<p>In the same folder create the sub-folder <code>radicale_static_password_auth</code>. The folder must have the same name as specified in <code>packages</code> above.</p>
<p>Create the file <code>__init__.py</code> in the <code>radicale_static_password_auth</code> folder with the following content:</p>
<div class="sourceCode" id="cb40"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb40-1"><a href="#cb40-1"></a><span class="im">from</span> radicale.auth <span class="im">import</span> BaseAuth</span>
<span id="cb40-2"><a href="#cb40-2"></a><span class="im">from</span> radicale.log <span class="im">import</span> logger</span>
<span id="cb40-3"><a href="#cb40-3"></a></span>
<span id="cb40-4"><a href="#cb40-4"></a>PLUGIN_CONFIG_SCHEMA <span class="op">=</span> {<span class="st">"auth"</span>: {</span>
<span id="cb40-5"><a href="#cb40-5"></a> <span class="st">"password"</span>: {<span class="st">"value"</span>: <span class="st">""</span>, <span class="st">"type"</span>: <span class="bu">str</span>}}}</span>
<span id="cb40-6"><a href="#cb40-6"></a></span>
<span id="cb40-7"><a href="#cb40-7"></a></span>
<span id="cb40-8"><a href="#cb40-8"></a><span class="kw">class</span> Auth(BaseAuth):</span>
<span id="cb40-9"><a href="#cb40-9"></a> <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>, configuration):</span>
<span id="cb40-10"><a href="#cb40-10"></a> <span class="bu">super</span>().<span class="fu">__init__</span>(configuration.copy(PLUGIN_CONFIG_SCHEMA))</span>
<span id="cb40-11"><a href="#cb40-11"></a></span>
<span id="cb40-12"><a href="#cb40-12"></a> <span class="kw">def</span> login(<span class="va">self</span>, login, password):</span>
<span id="cb40-13"><a href="#cb40-13"></a> <span class="co"># Get password from configuration option</span></span>
<span id="cb40-14"><a href="#cb40-14"></a> static_password <span class="op">=</span> <span class="va">self</span>.configuration.get(<span class="st">"auth"</span>, <span class="st">"password"</span>)</span>
<span id="cb40-15"><a href="#cb40-15"></a> <span class="co"># Check authentication</span></span>
<span id="cb40-16"><a href="#cb40-16"></a> logger.info(<span class="st">"Login attempt by </span><span class="sc">%r</span><span class="st"> with password </span><span class="sc">%r</span><span class="st">"</span>,</span>
<span id="cb40-17"><a href="#cb40-17"></a> login, password)</span>
<span id="cb40-18"><a href="#cb40-18"></a> <span class="cf">if</span> password <span class="op">==</span> static_password:</span>
<span id="cb40-19"><a href="#cb40-19"></a> <span class="cf">return</span> login</span>
<span id="cb40-20"><a href="#cb40-20"></a> <span class="cf">return</span> <span class="st">""</span></span></code></pre></div>
<div class="sourceCode" id="cb40"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb40-1"><a aria-hidden="true" href="#cb40-1" tabindex="-1"></a><span class="im">from</span> radicale.auth <span class="im">import</span> BaseAuth</span>
<span id="cb40-2"><a aria-hidden="true" href="#cb40-2" tabindex="-1"></a><span class="im">from</span> radicale.log <span class="im">import</span> logger</span>
<span id="cb40-3"><a aria-hidden="true" href="#cb40-3" tabindex="-1"></a></span>
<span id="cb40-4"><a aria-hidden="true" href="#cb40-4" tabindex="-1"></a>PLUGIN_CONFIG_SCHEMA <span class="op">=</span> {<span class="st">"auth"</span>: {</span>
<span id="cb40-5"><a aria-hidden="true" href="#cb40-5" tabindex="-1"></a> <span class="st">"password"</span>: {<span class="st">"value"</span>: <span class="st">""</span>, <span class="st">"type"</span>: <span class="bu">str</span>}}}</span>
<span id="cb40-6"><a aria-hidden="true" href="#cb40-6" tabindex="-1"></a></span>
<span id="cb40-7"><a aria-hidden="true" href="#cb40-7" tabindex="-1"></a></span>
<span id="cb40-8"><a aria-hidden="true" href="#cb40-8" tabindex="-1"></a><span class="kw">class</span> Auth(BaseAuth):</span>
<span id="cb40-9"><a aria-hidden="true" href="#cb40-9" tabindex="-1"></a> <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>, configuration):</span>
<span id="cb40-10"><a aria-hidden="true" href="#cb40-10" tabindex="-1"></a> <span class="bu">super</span>().<span class="fu">__init__</span>(configuration.copy(PLUGIN_CONFIG_SCHEMA))</span>
<span id="cb40-11"><a aria-hidden="true" href="#cb40-11" tabindex="-1"></a></span>
<span id="cb40-12"><a aria-hidden="true" href="#cb40-12" tabindex="-1"></a> <span class="kw">def</span> login(<span class="va">self</span>, login, password):</span>
<span id="cb40-13"><a aria-hidden="true" href="#cb40-13" tabindex="-1"></a> <span class="co"># Get password from configuration option</span></span>
<span id="cb40-14"><a aria-hidden="true" href="#cb40-14" tabindex="-1"></a> static_password <span class="op">=</span> <span class="va">self</span>.configuration.get(<span class="st">"auth"</span>, <span class="st">"password"</span>)</span>
<span id="cb40-15"><a aria-hidden="true" href="#cb40-15" tabindex="-1"></a> <span class="co"># Check authentication</span></span>
<span id="cb40-16"><a aria-hidden="true" href="#cb40-16" tabindex="-1"></a> logger.info(<span class="st">"Login attempt by </span><span class="sc">%r</span><span class="st"> with password </span><span class="sc">%r</span><span class="st">"</span>,</span>
<span id="cb40-17"><a aria-hidden="true" href="#cb40-17" tabindex="-1"></a> login, password)</span>
<span id="cb40-18"><a aria-hidden="true" href="#cb40-18" tabindex="-1"></a> <span class="cf">if</span> password <span class="op">==</span> static_password:</span>
<span id="cb40-19"><a aria-hidden="true" href="#cb40-19" tabindex="-1"></a> <span class="cf">return</span> login</span>
<span id="cb40-20"><a aria-hidden="true" href="#cb40-20" tabindex="-1"></a> <span class="cf">return</span> <span class="st">""</span></span></code></pre></div>
<p>Install the python module by running the following command in the same folder as <code>setup.py</code>:</p>
<div class="sourceCode" id="cb41"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb41-1"><a href="#cb41-1"></a><span class="ex">python3</span> -m pip install .</span></code></pre></div>
<div class="sourceCode" id="cb41"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb41-1"><a aria-hidden="true" href="#cb41-1" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> pip install .</span></code></pre></div>
<p>To make use this great creation in Radicale, set the configuration option <code>type</code> in the <code>auth</code> section to <code>radicale_static_password_auth</code>:</p>
<div class="sourceCode" id="cb42"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb42-1"><a href="#cb42-1"></a><span class="kw">[auth]</span></span>
<span id="cb42-2"><a href="#cb42-2"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> radicale_static_password_auth</span></span>
<span id="cb42-3"><a href="#cb42-3"></a><span class="dt">password </span><span class="ot">=</span><span class="st"> secret</span></span></code></pre></div>
<div class="sourceCode" id="cb42"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb42-1"><a aria-hidden="true" href="#cb42-1" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb42-2"><a aria-hidden="true" href="#cb42-2" tabindex="-1"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> radicale_static_password_auth</span></span>
<span id="cb42-3"><a aria-hidden="true" href="#cb42-3" tabindex="-1"></a><span class="dt">password </span><span class="ot">=</span><span class="st"> secret</span></span></code></pre></div>
<p>You can uninstall the module with:</p>
<div class="sourceCode" id="cb43"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb43-1"><a href="#cb43-1"></a><span class="ex">python3</span> -m pip uninstall radicale_static_password_auth</span></code></pre></div>
<div class="sourceCode" id="cb43"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb43-1"><a aria-hidden="true" href="#cb43-1" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> pip uninstall radicale_static_password_auth</span></code></pre></div>
</section>
<section class="level4" id="documentation/plugins/authentication-plugins">
<h4>Authentication plugins <a class="headerlink" href="#documentation/plugins/authentication-plugins">&para;</a></h4>
@ -1090,14 +1217,12 @@ user2:password2
<section class="level4" id="download//pypi">
<h4>PyPI <a class="headerlink" href="#download//pypi">&para;</a></h4>
<p>Radicale is <a href="https://pypi.python.org/pypi/Radicale/">available on PyPI</a>. To install, just type as superuser:</p>
<pre><code>$ python3 -m pip install --upgrade radicale
</code></pre>
<pre><code>$ python3 -m pip install --upgrade radicale</code></pre>
</section>
<section class="level4" id="download//git-repository">
<h4>Git Repository <a class="headerlink" href="#download//git-repository">&para;</a></h4>
<p>If you want the development version of Radicale, take a look at the <a href="https://github.com/Kozea/Radicale/">git repository on GitHub</a>, or install it directly with:</p>
<pre><code>$ python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz
</code></pre>
<pre><code>$ python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz</code></pre>
<p>You can also download the content of the repository as an <a href="https://github.com/Kozea/Radicale/tarball/master">archive</a>.</p>
</section>
<section class="level4" id="download//source-packages">

View file

@ -5,6 +5,137 @@
<meta content="pandoc" name="generator">
<meta content="width=device-width, initial-scale=1" name="viewport">
<style>
html {
line-height: 1.5;
font-family: Georgia, serif;
font-size: 20px;
color: #1a1a1a;
background-color: #fdfdfd;
}
body {
margin: 0 auto;
max-width: 36em;
padding-left: 50px;
padding-right: 50px;
padding-top: 50px;
padding-bottom: 50px;
hyphens: auto;
overflow-wrap: break-word;
text-rendering: optimizeLegibility;
font-kerning: normal;
}
@media (max-width: 600px) {
body {
font-size: 0.9em;
padding: 1em;
}
}
@media print {
body {
background-color: transparent;
color: black;
font-size: 12pt;
}
p, h2, h3 {
orphans: 3;
widows: 3;
}
h2, h3, h4 {
page-break-after: avoid;
}
}
p {
margin: 1em 0;
}
a {
color: #1a1a1a;
}
a:visited {
color: #1a1a1a;
}
img {
max-width: 100%;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 1.4em;
}
h5, h6 {
font-size: 1em;
font-style: italic;
}
h6 {
font-weight: normal;
}
ol, ul {
padding-left: 1.7em;
margin-top: 1em;
}
li > ol, li > ul {
margin-top: 0;
}
blockquote {
margin: 1em 0 1em 1.7em;
padding-left: 1em;
border-left: 2px solid #e6e6e6;
color: #606060;
}
code {
font-family: Menlo, Monaco, 'Lucida Console', Consolas, monospace;
font-size: 85%;
margin: 0;
}
pre {
margin: 1em 0;
overflow: auto;
}
pre code {
padding: 0;
overflow: visible;
overflow-wrap: normal;
}
.sourceCode {
background-color: transparent;
overflow: visible;
}
hr {
background-color: #1a1a1a;
border: none;
height: 1px;
margin: 1em 0;
}
table {
margin: 1em 0;
border-collapse: collapse;
width: 100%;
overflow-x: auto;
display: block;
font-variant-numeric: lining-nums tabular-nums;
}
table caption {
margin-bottom: 0.75em;
}
tbody {
margin-top: 0.5em;
border-top: 1px solid #1a1a1a;
border-bottom: 1px solid #1a1a1a;
}
th {
border-top: 1px solid #1a1a1a;
padding: 0.25em 0.5em 0.25em 0.5em;
}
td {
padding: 0.125em 0.5em 0.25em 0.5em;
}
header {
margin-bottom: 4em;
text-align: center;
}
#TOC li {
list-style: none;
}
#TOC a:not(:hover) {
text-decoration: none;
}
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
@ -14,6 +145,7 @@
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@ -73,6 +205,7 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
</style>
<link href="assets/default.css" media="all" rel="stylesheet">
<link href="assets/screen.css" media="screen" rel="stylesheet">
@ -244,9 +377,9 @@
<section class="level4" id="getting-started//installation">
<h4>Installation <a class="headerlink" href="#getting-started//installation">&para;</a></h4>
<p>Radicale is really easy to install and works out-of-the-box.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1"></a>$ <span class="ex">python3</span> -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz</span>
<span id="cb1-2"><a href="#cb1-2"></a>$ <span class="ex">python3</span> -m radicale --storage-filesystem-folder=~/.var/lib/radicale/collections</span></code></pre></div>
<p>When the server is launched, open <a href="http://localhost:5232/">http://localhost:5232/</a> in your browser! You can login with any username and password.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a aria-hidden="true" href="#cb1-1" tabindex="-1"></a><span class="ex">$</span> python3 <span class="at">-m</span> pip install <span class="at">--upgrade</span> https://github.com/Kozea/Radicale/archive/master.tar.gz</span>
<span id="cb1-2"><a aria-hidden="true" href="#cb1-2" tabindex="-1"></a><span class="ex">$</span> python3 <span class="at">-m</span> radicale <span class="at">--storage-filesystem-folder</span><span class="op">=</span>~/.var/lib/radicale/collections</span></code></pre></div>
<p>When the server is launched, open http://localhost:5232/ in your browser! You can login with any username and password.</p>
<p>Want more? Check the <a href="#tutorials">tutorials</a> and the <a href="#documentation">documentation</a>.</p>
</section>
<section class="level4" id="getting-started//whats-new">
@ -265,19 +398,19 @@
<h4>Linux / *BSD <a class="headerlink" href="#tutorials/simple-5-minute-setup/linux--bsd">&para;</a></h4>
<p>First, make sure that <strong>python</strong> 3.5 or later (<strong>python</strong> &ge; 3.6 is recommended) and <strong>pip</strong> are installed. On most distributions it should be enough to install the package <code>python3-pip</code>.</p>
<p>Then open a console and type:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1"></a><span class="co"># Run the following command as root or</span></span>
<span id="cb2-2"><a href="#cb2-2"></a><span class="co"># add the --user argument to only install for the current user</span></span>
<span id="cb2-3"><a href="#cb2-3"></a>$ <span class="ex">python3</span> -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz</span>
<span id="cb2-4"><a href="#cb2-4"></a>$ <span class="ex">python3</span> -m radicale --storage-filesystem-folder=~/.var/lib/radicale/collections</span></code></pre></div>
<p>Victory! Open <a href="http://localhost:5232/">http://localhost:5232/</a> in your browser! You can log in with any username and password.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a aria-hidden="true" href="#cb2-1" tabindex="-1"></a><span class="co"># Run the following command as root or</span></span>
<span id="cb2-2"><a aria-hidden="true" href="#cb2-2" tabindex="-1"></a><span class="co"># add the --user argument to only install for the current user</span></span>
<span id="cb2-3"><a aria-hidden="true" href="#cb2-3" tabindex="-1"></a><span class="ex">$</span> python3 <span class="at">-m</span> pip install <span class="at">--upgrade</span> https://github.com/Kozea/Radicale/archive/master.tar.gz</span>
<span id="cb2-4"><a aria-hidden="true" href="#cb2-4" tabindex="-1"></a><span class="ex">$</span> python3 <span class="at">-m</span> radicale <span class="at">--storage-filesystem-folder</span><span class="op">=</span>~/.var/lib/radicale/collections</span></code></pre></div>
<p>Victory! Open http://localhost:5232/ in your browser! You can log in with any username and password.</p>
</section>
<section class="level4" id="tutorials/simple-5-minute-setup/windows">
<h4>Windows <a class="headerlink" href="#tutorials/simple-5-minute-setup/windows">&para;</a></h4>
<p>The first step is to install Python. Go to <a href="https://python.org">python.org</a> 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!</p>
<p>Launch a command prompt and type:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode powershell"><code class="sourceCode powershell"><span id="cb3-1"><a href="#cb3-1"></a>C:\Users\User&gt; python -m pip install --upgrade https://github.<span class="fu">com</span>/Kozea/Radicale/archive/master.<span class="fu">tar</span>.<span class="fu">gz</span></span>
<span id="cb3-2"><a href="#cb3-2"></a>C:\Users\User&gt; python -m radicale --storage-filesystem-folder=~/radicale/collections</span></code></pre></div>
<p>Victory! Open <a href="http://localhost:5232/">http://localhost:5232/</a> in your browser! You can log in with any username and password.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode powershell"><code class="sourceCode powershell"><span id="cb3-1"><a aria-hidden="true" href="#cb3-1" tabindex="-1"></a>C<span class="op">:</span>\Users\User<span class="op">&gt;</span> python <span class="op">-</span>m pip install <span class="op">--</span>upgrade https<span class="op">://</span>github<span class="op">.</span><span class="fu">com</span><span class="op">/</span>Kozea<span class="op">/</span>Radicale<span class="op">/</span>archive<span class="op">/</span>master<span class="op">.</span><span class="fu">tar</span><span class="op">.</span><span class="fu">gz</span></span>
<span id="cb3-2"><a aria-hidden="true" href="#cb3-2" tabindex="-1"></a>C<span class="op">:</span>\Users\User<span class="op">&gt;</span> python <span class="op">-</span>m radicale <span class="op">--</span>storage<span class="op">-</span>filesystem<span class="op">-</span>folder<span class="op">=~/</span>radicale<span class="op">/</span>collections</span></code></pre></div>
<p>Victory! Open http://localhost:5232/ in your browser! You can log in with any username and password.</p>
</section>
</section>
<section class="level3" id="tutorials/basic-configuration">
@ -293,46 +426,45 @@
<section class="level5" id="tutorials/basic-configuration/authentication/the-secure-way">
<h5>The secure way <a class="headerlink" href="#tutorials/basic-configuration/authentication/the-secure-way">&para;</a></h5>
<p>The <code>users</code> file can be created and managed with <a href="https://httpd.apache.org/docs/current/programs/htpasswd.html">htpasswd</a>:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1"></a><span class="co"># Create a new htpasswd file with the user "user1"</span></span>
<span id="cb4-2"><a href="#cb4-2"></a>$ <span class="ex">htpasswd</span> -c /path/to/users user1</span>
<span id="cb4-3"><a href="#cb4-3"></a><span class="ex">New</span> password:</span>
<span id="cb4-4"><a href="#cb4-4"></a><span class="ex">Re-type</span> new password:</span>
<span id="cb4-5"><a href="#cb4-5"></a><span class="co"># Add another user</span></span>
<span id="cb4-6"><a href="#cb4-6"></a>$ <span class="ex">htpasswd</span> /path/to/users user2</span>
<span id="cb4-7"><a href="#cb4-7"></a><span class="ex">New</span> password:</span>
<span id="cb4-8"><a href="#cb4-8"></a><span class="ex">Re-type</span> new password:</span></code></pre></div>
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a aria-hidden="true" href="#cb4-1" tabindex="-1"></a><span class="co"># Create a new htpasswd file with the user "user1"</span></span>
<span id="cb4-2"><a aria-hidden="true" href="#cb4-2" tabindex="-1"></a><span class="ex">$</span> htpasswd <span class="at">-c</span> /path/to/users user1</span>
<span id="cb4-3"><a aria-hidden="true" href="#cb4-3" tabindex="-1"></a><span class="ex">New</span> password:</span>
<span id="cb4-4"><a aria-hidden="true" href="#cb4-4" tabindex="-1"></a><span class="ex">Re-type</span> new password:</span>
<span id="cb4-5"><a aria-hidden="true" href="#cb4-5" tabindex="-1"></a><span class="co"># Add another user</span></span>
<span id="cb4-6"><a aria-hidden="true" href="#cb4-6" tabindex="-1"></a><span class="ex">$</span> htpasswd /path/to/users user2</span>
<span id="cb4-7"><a aria-hidden="true" href="#cb4-7" tabindex="-1"></a><span class="ex">New</span> password:</span>
<span id="cb4-8"><a aria-hidden="true" href="#cb4-8" tabindex="-1"></a><span class="ex">Re-type</span> new password:</span></code></pre></div>
<p>Authentication can be enabled with the following configuration:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb5-1"><a href="#cb5-1"></a><span class="kw">[auth]</span></span>
<span id="cb5-2"><a href="#cb5-2"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb5-3"><a href="#cb5-3"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> /path/to/users</span></span>
<span id="cb5-4"><a href="#cb5-4"></a><span class="co"># encryption method used in the htpasswd file</span></span>
<span id="cb5-5"><a href="#cb5-5"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> md5</span></span></code></pre></div>
<div class="sourceCode" id="cb5"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb5-1"><a aria-hidden="true" href="#cb5-1" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb5-2"><a aria-hidden="true" href="#cb5-2" tabindex="-1"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb5-3"><a aria-hidden="true" href="#cb5-3" tabindex="-1"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> /path/to/users</span></span>
<span id="cb5-4"><a aria-hidden="true" href="#cb5-4" tabindex="-1"></a><span class="co"># encryption method used in the htpasswd file</span></span>
<span id="cb5-5"><a aria-hidden="true" href="#cb5-5" tabindex="-1"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> md5</span></span></code></pre></div>
</section>
<section class="level5" id="tutorials/basic-configuration/authentication/the-simple-but-insecure-way">
<h5>The simple but insecure way <a class="headerlink" href="#tutorials/basic-configuration/authentication/the-simple-but-insecure-way">&para;</a></h5>
<p>Create the <code>users</code> file by hand with lines containing the user name and password separated by <code>:</code>. Example:</p>
<pre class="htpasswd"><code>user1:password1
user2:password2
</code></pre>
user2:password2</code></pre>
<p>Authentication can be enabled with the following configuration:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb7-1"><a href="#cb7-1"></a><span class="kw">[auth]</span></span>
<span id="cb7-2"><a href="#cb7-2"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb7-3"><a href="#cb7-3"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> /path/to/users</span></span>
<span id="cb7-4"><a href="#cb7-4"></a><span class="co"># encryption method used in the htpasswd file</span></span>
<span id="cb7-5"><a href="#cb7-5"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> plain</span></span></code></pre></div>
<div class="sourceCode" id="cb7"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb7-1"><a aria-hidden="true" href="#cb7-1" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb7-2"><a aria-hidden="true" href="#cb7-2" tabindex="-1"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb7-3"><a aria-hidden="true" href="#cb7-3" tabindex="-1"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> /path/to/users</span></span>
<span id="cb7-4"><a aria-hidden="true" href="#cb7-4" tabindex="-1"></a><span class="co"># encryption method used in the htpasswd file</span></span>
<span id="cb7-5"><a aria-hidden="true" href="#cb7-5" tabindex="-1"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> plain</span></span></code></pre></div>
</section>
</section>
<section class="level4" id="tutorials/basic-configuration/addresses">
<h4>Addresses <a class="headerlink" href="#tutorials/basic-configuration/addresses">&para;</a></h4>
<p>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):</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb8-1"><a href="#cb8-1"></a><span class="kw">[server]</span></span>
<span id="cb8-2"><a href="#cb8-2"></a><span class="dt">hosts </span><span class="ot">=</span><span class="st"> </span><span class="dv">0</span><span class="st">.</span><span class="dv">0</span><span class="st">.</span><span class="fl">0.0</span><span class="st">:</span><span class="dv">5232</span><span class="st">, [::]:</span><span class="dv">5232</span></span></code></pre></div>
<div class="sourceCode" id="cb8"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb8-1"><a aria-hidden="true" href="#cb8-1" tabindex="-1"></a><span class="kw">[server]</span></span>
<span id="cb8-2"><a aria-hidden="true" href="#cb8-2" tabindex="-1"></a><span class="dt">hosts </span><span class="ot">=</span><span class="st"> 0.0.0.0:5232, [::]:5232</span></span></code></pre></div>
</section>
<section class="level4" id="tutorials/basic-configuration/storage">
<h4>Storage <a class="headerlink" href="#tutorials/basic-configuration/storage">&para;</a></h4>
<p>Data is stored in the folder <code>/var/lib/radicale/collections</code>. The path can be changed with the following configuration:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb9-1"><a href="#cb9-1"></a><span class="kw">[storage]</span></span>
<span id="cb9-2"><a href="#cb9-2"></a><span class="dt">filesystem_folder </span><span class="ot">=</span><span class="st"> /path/to/storage</span></span></code></pre></div>
<div class="sourceCode" id="cb9"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb9-1"><a aria-hidden="true" href="#cb9-1" tabindex="-1"></a><span class="kw">[storage]</span></span>
<span id="cb9-2"><a aria-hidden="true" href="#cb9-2" tabindex="-1"></a><span class="dt">filesystem_folder </span><span class="ot">=</span><span class="st"> /path/to/storage</span></span></code></pre></div>
<blockquote>
<p><strong>Security:</strong> 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 <a href="#tutorials/running-as-a-service">Running as a service</a> section.</p>
</blockquote>
@ -340,16 +472,16 @@ user2:password2
<section class="level4" id="tutorials/basic-configuration/limits">
<h4>Limits <a class="headerlink" href="#tutorials/basic-configuration/limits">&para;</a></h4>
<p>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.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb10-1"><a href="#cb10-1"></a><span class="kw">[server]</span></span>
<span id="cb10-2"><a href="#cb10-2"></a><span class="dt">max_connections </span><span class="ot">=</span><span class="st"> </span><span class="dv">20</span></span>
<span id="cb10-3"><a href="#cb10-3"></a><span class="co"># 100 Megabyte</span></span>
<span id="cb10-4"><a href="#cb10-4"></a><span class="dt">max_content_length </span><span class="ot">=</span><span class="st"> </span><span class="dv">100000000</span></span>
<span id="cb10-5"><a href="#cb10-5"></a><span class="co"># 30 seconds</span></span>
<span id="cb10-6"><a href="#cb10-6"></a><span class="dt">timeout </span><span class="ot">=</span><span class="st"> </span><span class="dv">30</span></span>
<span id="cb10-7"><a href="#cb10-7"></a></span>
<span id="cb10-8"><a href="#cb10-8"></a><span class="kw">[auth]</span></span>
<span id="cb10-9"><a href="#cb10-9"></a><span class="co"># Average delay after failed login attempts in seconds</span></span>
<span id="cb10-10"><a href="#cb10-10"></a><span class="dt">delay </span><span class="ot">=</span><span class="st"> </span><span class="dv">1</span></span></code></pre></div>
<div class="sourceCode" id="cb10"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb10-1"><a aria-hidden="true" href="#cb10-1" tabindex="-1"></a><span class="kw">[server]</span></span>
<span id="cb10-2"><a aria-hidden="true" href="#cb10-2" tabindex="-1"></a><span class="dt">max_connections </span><span class="ot">=</span><span class="st"> </span><span class="dv">20</span></span>
<span id="cb10-3"><a aria-hidden="true" href="#cb10-3" tabindex="-1"></a><span class="co"># 100 Megabyte</span></span>
<span id="cb10-4"><a aria-hidden="true" href="#cb10-4" tabindex="-1"></a><span class="dt">max_content_length </span><span class="ot">=</span><span class="st"> </span><span class="dv">100000000</span></span>
<span id="cb10-5"><a aria-hidden="true" href="#cb10-5" tabindex="-1"></a><span class="co"># 30 seconds</span></span>
<span id="cb10-6"><a aria-hidden="true" href="#cb10-6" tabindex="-1"></a><span class="dt">timeout </span><span class="ot">=</span><span class="st"> </span><span class="dv">30</span></span>
<span id="cb10-7"><a aria-hidden="true" href="#cb10-7" tabindex="-1"></a></span>
<span id="cb10-8"><a aria-hidden="true" href="#cb10-8" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb10-9"><a aria-hidden="true" href="#cb10-9" tabindex="-1"></a><span class="co"># Average delay after failed login attempts in seconds</span></span>
<span id="cb10-10"><a aria-hidden="true" href="#cb10-10" tabindex="-1"></a><span class="dt">delay </span><span class="ot">=</span><span class="st"> </span><span class="dv">1</span></span></code></pre></div>
</section>
</section>
<section class="level3" id="tutorials/running-as-a-service">
@ -362,63 +494,63 @@ user2:password2
<p><strong>Security:</strong> The storage should not be readable by others. (Run <code>chmod -R o= /var/lib/radicale/collections</code> as root.)</p>
</blockquote>
<p>Create the file <code>/etc/systemd/system/radicale.service</code>:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb11-1"><a href="#cb11-1"></a><span class="kw">[Unit]</span></span>
<span id="cb11-2"><a href="#cb11-2"></a><span class="dt">Description</span><span class="ot">=</span><span class="st">A simple CalDAV (calendar) and CardDAV (contact) server</span></span>
<span id="cb11-3"><a href="#cb11-3"></a><span class="dt">After</span><span class="ot">=</span><span class="st">network.target</span></span>
<span id="cb11-4"><a href="#cb11-4"></a><span class="dt">Requires</span><span class="ot">=</span><span class="st">network.target</span></span>
<span id="cb11-5"><a href="#cb11-5"></a></span>
<span id="cb11-6"><a href="#cb11-6"></a><span class="kw">[Service]</span></span>
<span id="cb11-7"><a href="#cb11-7"></a><span class="dt">ExecStart</span><span class="ot">=</span><span class="st">/usr/bin/env python3 -m radicale</span></span>
<span id="cb11-8"><a href="#cb11-8"></a><span class="dt">Restart</span><span class="ot">=</span><span class="kw">on</span><span class="st">-failure</span></span>
<span id="cb11-9"><a href="#cb11-9"></a><span class="dt">User</span><span class="ot">=</span><span class="st">radicale</span></span>
<span id="cb11-10"><a href="#cb11-10"></a><span class="co"># Deny other users access to the calendar data</span></span>
<span id="cb11-11"><a href="#cb11-11"></a><span class="dt">UMask</span><span class="ot">=</span><span class="dv">0027</span></span>
<span id="cb11-12"><a href="#cb11-12"></a><span class="co"># Optional security settings</span></span>
<span id="cb11-13"><a href="#cb11-13"></a><span class="dt">PrivateTmp</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-14"><a href="#cb11-14"></a><span class="dt">ProtectSystem</span><span class="ot">=</span><span class="st">strict</span></span>
<span id="cb11-15"><a href="#cb11-15"></a><span class="dt">ProtectHome</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-16"><a href="#cb11-16"></a><span class="dt">PrivateDevices</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-17"><a href="#cb11-17"></a><span class="dt">ProtectKernelTunables</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-18"><a href="#cb11-18"></a><span class="dt">ProtectKernelModules</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-19"><a href="#cb11-19"></a><span class="dt">ProtectControlGroups</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-20"><a href="#cb11-20"></a><span class="dt">NoNewPrivileges</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-21"><a href="#cb11-21"></a><span class="dt">ReadWritePaths</span><span class="ot">=</span><span class="st">/var/lib/radicale/collections</span></span>
<span id="cb11-22"><a href="#cb11-22"></a></span>
<span id="cb11-23"><a href="#cb11-23"></a><span class="kw">[Install]</span></span>
<span id="cb11-24"><a href="#cb11-24"></a><span class="dt">WantedBy</span><span class="ot">=</span><span class="st">multi-user.target</span></span></code></pre></div>
<div class="sourceCode" id="cb11"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb11-1"><a aria-hidden="true" href="#cb11-1" tabindex="-1"></a><span class="kw">[Unit]</span></span>
<span id="cb11-2"><a aria-hidden="true" href="#cb11-2" tabindex="-1"></a><span class="dt">Description</span><span class="ot">=</span><span class="st">A simple CalDAV (calendar) and CardDAV (contact) server</span></span>
<span id="cb11-3"><a aria-hidden="true" href="#cb11-3" tabindex="-1"></a><span class="dt">After</span><span class="ot">=</span><span class="st">network.target</span></span>
<span id="cb11-4"><a aria-hidden="true" href="#cb11-4" tabindex="-1"></a><span class="dt">Requires</span><span class="ot">=</span><span class="st">network.target</span></span>
<span id="cb11-5"><a aria-hidden="true" href="#cb11-5" tabindex="-1"></a></span>
<span id="cb11-6"><a aria-hidden="true" href="#cb11-6" tabindex="-1"></a><span class="kw">[Service]</span></span>
<span id="cb11-7"><a aria-hidden="true" href="#cb11-7" tabindex="-1"></a><span class="dt">ExecStart</span><span class="ot">=</span><span class="st">/usr/bin/env python3 -m radicale</span></span>
<span id="cb11-8"><a aria-hidden="true" href="#cb11-8" tabindex="-1"></a><span class="dt">Restart</span><span class="ot">=</span><span class="st">on-failure</span></span>
<span id="cb11-9"><a aria-hidden="true" href="#cb11-9" tabindex="-1"></a><span class="dt">User</span><span class="ot">=</span><span class="st">radicale</span></span>
<span id="cb11-10"><a aria-hidden="true" href="#cb11-10" tabindex="-1"></a><span class="co"># Deny other users access to the calendar data</span></span>
<span id="cb11-11"><a aria-hidden="true" href="#cb11-11" tabindex="-1"></a><span class="dt">UMask</span><span class="ot">=</span><span class="dv">0027</span></span>
<span id="cb11-12"><a aria-hidden="true" href="#cb11-12" tabindex="-1"></a><span class="co"># Optional security settings</span></span>
<span id="cb11-13"><a aria-hidden="true" href="#cb11-13" tabindex="-1"></a><span class="dt">PrivateTmp</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-14"><a aria-hidden="true" href="#cb11-14" tabindex="-1"></a><span class="dt">ProtectSystem</span><span class="ot">=</span><span class="st">strict</span></span>
<span id="cb11-15"><a aria-hidden="true" href="#cb11-15" tabindex="-1"></a><span class="dt">ProtectHome</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-16"><a aria-hidden="true" href="#cb11-16" tabindex="-1"></a><span class="dt">PrivateDevices</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-17"><a aria-hidden="true" href="#cb11-17" tabindex="-1"></a><span class="dt">ProtectKernelTunables</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-18"><a aria-hidden="true" href="#cb11-18" tabindex="-1"></a><span class="dt">ProtectKernelModules</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-19"><a aria-hidden="true" href="#cb11-19" tabindex="-1"></a><span class="dt">ProtectControlGroups</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-20"><a aria-hidden="true" href="#cb11-20" tabindex="-1"></a><span class="dt">NoNewPrivileges</span><span class="ot">=</span><span class="kw">true</span></span>
<span id="cb11-21"><a aria-hidden="true" href="#cb11-21" tabindex="-1"></a><span class="dt">ReadWritePaths</span><span class="ot">=</span><span class="st">/var/lib/radicale/collections</span></span>
<span id="cb11-22"><a aria-hidden="true" href="#cb11-22" tabindex="-1"></a></span>
<span id="cb11-23"><a aria-hidden="true" href="#cb11-23" tabindex="-1"></a><span class="kw">[Install]</span></span>
<span id="cb11-24"><a aria-hidden="true" href="#cb11-24" tabindex="-1"></a><span class="dt">WantedBy</span><span class="ot">=</span><span class="st">multi-user.target</span></span></code></pre></div>
<p>Radicale will load the configuration file from <code>/etc/radicale/config</code>.</p>
<p>To enable and manage the service run:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1"></a><span class="co"># Enable the service</span></span>
<span id="cb12-2"><a href="#cb12-2"></a>$ <span class="ex">systemctl</span> enable radicale</span>
<span id="cb12-3"><a href="#cb12-3"></a><span class="co"># Start the service</span></span>
<span id="cb12-4"><a href="#cb12-4"></a>$ <span class="ex">systemctl</span> start radicale</span>
<span id="cb12-5"><a href="#cb12-5"></a><span class="co"># Check the status of the service</span></span>
<span id="cb12-6"><a href="#cb12-6"></a>$ <span class="ex">systemctl</span> status radicale</span>
<span id="cb12-7"><a href="#cb12-7"></a><span class="co"># View all log messages</span></span>
<span id="cb12-8"><a href="#cb12-8"></a>$ <span class="ex">journalctl</span> --unit radicale.service</span></code></pre></div>
<div class="sourceCode" id="cb12"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb12-1"><a aria-hidden="true" href="#cb12-1" tabindex="-1"></a><span class="co"># Enable the service</span></span>
<span id="cb12-2"><a aria-hidden="true" href="#cb12-2" tabindex="-1"></a><span class="ex">$</span> systemctl enable radicale</span>
<span id="cb12-3"><a aria-hidden="true" href="#cb12-3" tabindex="-1"></a><span class="co"># Start the service</span></span>
<span id="cb12-4"><a aria-hidden="true" href="#cb12-4" tabindex="-1"></a><span class="ex">$</span> systemctl start radicale</span>
<span id="cb12-5"><a aria-hidden="true" href="#cb12-5" tabindex="-1"></a><span class="co"># Check the status of the service</span></span>
<span id="cb12-6"><a aria-hidden="true" href="#cb12-6" tabindex="-1"></a><span class="ex">$</span> systemctl status radicale</span>
<span id="cb12-7"><a aria-hidden="true" href="#cb12-7" tabindex="-1"></a><span class="co"># View all log messages</span></span>
<span id="cb12-8"><a aria-hidden="true" href="#cb12-8" tabindex="-1"></a><span class="ex">$</span> journalctl <span class="at">--unit</span> radicale.service</span></code></pre></div>
</section>
<section class="level4" id="tutorials/running-as-a-service/linux-with-systemd-as-a-user">
<h4>Linux with systemd as a user <a class="headerlink" href="#tutorials/running-as-a-service/linux-with-systemd-as-a-user">&para;</a></h4>
<p>Create the file <code>~/.config/systemd/user/radicale.service</code>:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb13-1"><a href="#cb13-1"></a><span class="kw">[Unit]</span></span>
<span id="cb13-2"><a href="#cb13-2"></a><span class="dt">Description</span><span class="ot">=</span><span class="st">A simple CalDAV (calendar) and CardDAV (contact) server</span></span>
<span id="cb13-3"><a href="#cb13-3"></a></span>
<span id="cb13-4"><a href="#cb13-4"></a><span class="kw">[Service]</span></span>
<span id="cb13-5"><a href="#cb13-5"></a><span class="dt">ExecStart</span><span class="ot">=</span><span class="st">/usr/bin/env python3 -m radicale</span></span>
<span id="cb13-6"><a href="#cb13-6"></a><span class="dt">Restart</span><span class="ot">=</span><span class="kw">on</span><span class="st">-failure</span></span>
<span id="cb13-7"><a href="#cb13-7"></a></span>
<span id="cb13-8"><a href="#cb13-8"></a><span class="kw">[Install]</span></span>
<span id="cb13-9"><a href="#cb13-9"></a><span class="dt">WantedBy</span><span class="ot">=</span><span class="kw">default</span><span class="st">.target</span></span></code></pre></div>
<div class="sourceCode" id="cb13"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb13-1"><a aria-hidden="true" href="#cb13-1" tabindex="-1"></a><span class="kw">[Unit]</span></span>
<span id="cb13-2"><a aria-hidden="true" href="#cb13-2" tabindex="-1"></a><span class="dt">Description</span><span class="ot">=</span><span class="st">A simple CalDAV (calendar) and CardDAV (contact) server</span></span>
<span id="cb13-3"><a aria-hidden="true" href="#cb13-3" tabindex="-1"></a></span>
<span id="cb13-4"><a aria-hidden="true" href="#cb13-4" tabindex="-1"></a><span class="kw">[Service]</span></span>
<span id="cb13-5"><a aria-hidden="true" href="#cb13-5" tabindex="-1"></a><span class="dt">ExecStart</span><span class="ot">=</span><span class="st">/usr/bin/env python3 -m radicale</span></span>
<span id="cb13-6"><a aria-hidden="true" href="#cb13-6" tabindex="-1"></a><span class="dt">Restart</span><span class="ot">=</span><span class="st">on-failure</span></span>
<span id="cb13-7"><a aria-hidden="true" href="#cb13-7" tabindex="-1"></a></span>
<span id="cb13-8"><a aria-hidden="true" href="#cb13-8" tabindex="-1"></a><span class="kw">[Install]</span></span>
<span id="cb13-9"><a aria-hidden="true" href="#cb13-9" tabindex="-1"></a><span class="dt">WantedBy</span><span class="ot">=</span><span class="st">default.target</span></span></code></pre></div>
<p>Radicale will load the configuration file from <code>~/.config/radicale/config</code>. You should set the configuration option <code>filesystem_folder</code> in the <code>storage</code> section to something like <code>~/.var/lib/radicale/collections</code>.</p>
<p>To enable and manage the service run:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1"></a><span class="co"># Enable the service</span></span>
<span id="cb14-2"><a href="#cb14-2"></a>$ <span class="ex">systemctl</span> --user enable radicale</span>
<span id="cb14-3"><a href="#cb14-3"></a><span class="co"># Start the service</span></span>
<span id="cb14-4"><a href="#cb14-4"></a>$ <span class="ex">systemctl</span> --user start radicale</span>
<span id="cb14-5"><a href="#cb14-5"></a><span class="co"># Check the status of the service</span></span>
<span id="cb14-6"><a href="#cb14-6"></a>$ <span class="ex">systemctl</span> --user status radicale</span>
<span id="cb14-7"><a href="#cb14-7"></a><span class="co"># View all log messages</span></span>
<span id="cb14-8"><a href="#cb14-8"></a>$ <span class="ex">journalctl</span> --user --unit radicale.service</span></code></pre></div>
<div class="sourceCode" id="cb14"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb14-1"><a aria-hidden="true" href="#cb14-1" tabindex="-1"></a><span class="co"># Enable the service</span></span>
<span id="cb14-2"><a aria-hidden="true" href="#cb14-2" tabindex="-1"></a><span class="ex">$</span> systemctl <span class="at">--user</span> enable radicale</span>
<span id="cb14-3"><a aria-hidden="true" href="#cb14-3" tabindex="-1"></a><span class="co"># Start the service</span></span>
<span id="cb14-4"><a aria-hidden="true" href="#cb14-4" tabindex="-1"></a><span class="ex">$</span> systemctl <span class="at">--user</span> start radicale</span>
<span id="cb14-5"><a aria-hidden="true" href="#cb14-5" tabindex="-1"></a><span class="co"># Check the status of the service</span></span>
<span id="cb14-6"><a aria-hidden="true" href="#cb14-6" tabindex="-1"></a><span class="ex">$</span> systemctl <span class="at">--user</span> status radicale</span>
<span id="cb14-7"><a aria-hidden="true" href="#cb14-7" tabindex="-1"></a><span class="co"># View all log messages</span></span>
<span id="cb14-8"><a aria-hidden="true" href="#cb14-8" tabindex="-1"></a><span class="ex">$</span> journalctl <span class="at">--user</span> <span class="at">--unit</span> radicale.service</span></code></pre></div>
</section>
<section class="level4" id="tutorials/running-as-a-service/windows-with-nssm---the-non-sucking-service-manager">
<h4>Windows with "NSSM - the Non-Sucking Service Manager" <a class="headerlink" href="#tutorials/running-as-a-service/windows-with-nssm---the-non-sucking-service-manager">&para;</a></h4>
@ -452,24 +584,23 @@ user2:password2
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass_header Authorization;
}
</code></pre>
}</code></pre>
<p>Example <strong>Apache</strong> configuration:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb16-1"><a href="#cb16-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb16-2"><a href="#cb16-2"></a>RewriteRule<span class="st"> ^/radicale$ /radicale/ [R,L]</span></span>
<span id="cb16-3"><a href="#cb16-3"></a></span>
<span id="cb16-4"><a href="#cb16-4"></a><span class="fu">&lt;Location</span><span class="at"> "/radicale/"</span><span class="fu">&gt;</span></span>
<span id="cb16-5"><a href="#cb16-5"></a> ProxyPass<span class="st"> http://localhost:5232/ retry=0</span></span>
<span id="cb16-6"><a href="#cb16-6"></a> ProxyPassReverse<span class="st"> http://localhost:5232/</span></span>
<span id="cb16-7"><a href="#cb16-7"></a> RequestHeader<span class="st"> set X-Script-Name /radicale</span></span>
<span id="cb16-8"><a href="#cb16-8"></a><span class="fu">&lt;/Location&gt;</span></span></code></pre></div>
<div class="sourceCode" id="cb16"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb16-1"><a aria-hidden="true" href="#cb16-1" tabindex="-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb16-2"><a aria-hidden="true" href="#cb16-2" tabindex="-1"></a>RewriteRule<span class="st"> ^/radicale$ /radicale/ [R,L]</span></span>
<span id="cb16-3"><a aria-hidden="true" href="#cb16-3" tabindex="-1"></a></span>
<span id="cb16-4"><a aria-hidden="true" href="#cb16-4" tabindex="-1"></a><span class="fu">&lt;Location</span><span class="at"> "/radicale/"</span><span class="fu">&gt;</span></span>
<span id="cb16-5"><a aria-hidden="true" href="#cb16-5" tabindex="-1"></a> ProxyPass<span class="st"> http://localhost:5232/ retry=0</span></span>
<span id="cb16-6"><a aria-hidden="true" href="#cb16-6" tabindex="-1"></a> ProxyPassReverse<span class="st"> http://localhost:5232/</span></span>
<span id="cb16-7"><a aria-hidden="true" href="#cb16-7" tabindex="-1"></a> RequestHeader<span class="st"> set X-Script-Name /radicale</span></span>
<span id="cb16-8"><a aria-hidden="true" href="#cb16-8" tabindex="-1"></a><span class="fu">&lt;/Location&gt;</span></span></code></pre></div>
<p>Example <strong>Apache .htaccess</strong> configuration:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb17-1"><a href="#cb17-1"></a>DirectoryIndex<span class="st"> disabled</span></span>
<span id="cb17-2"><a href="#cb17-2"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb17-3"><a href="#cb17-3"></a>RewriteRule<span class="st"> ^(.*)$ http://localhost:5232/$1 [P,L]</span></span>
<span id="cb17-4"><a href="#cb17-4"></a></span>
<span id="cb17-5"><a href="#cb17-5"></a><span class="co"># Set to directory of .htaccess file:</span></span>
<span id="cb17-6"><a href="#cb17-6"></a>RequestHeader<span class="st"> set X-Script-Name /radicale</span></span></code></pre></div>
<div class="sourceCode" id="cb17"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb17-1"><a aria-hidden="true" href="#cb17-1" tabindex="-1"></a>DirectoryIndex<span class="st"> disabled</span></span>
<span id="cb17-2"><a aria-hidden="true" href="#cb17-2" tabindex="-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb17-3"><a aria-hidden="true" href="#cb17-3" tabindex="-1"></a>RewriteRule<span class="st"> ^(.*)$ http://localhost:5232/$1 [P,L]</span></span>
<span id="cb17-4"><a aria-hidden="true" href="#cb17-4" tabindex="-1"></a></span>
<span id="cb17-5"><a aria-hidden="true" href="#cb17-5" tabindex="-1"></a><span class="co"># Set to directory of .htaccess file:</span></span>
<span id="cb17-6"><a aria-hidden="true" href="#cb17-6" tabindex="-1"></a>RequestHeader<span class="st"> set X-Script-Name /radicale</span></span></code></pre></div>
<p>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.</p>
<section class="level4" id="tutorials/reverse-proxy/manage-user-accounts-with-the-reverse-proxy">
<h4>Manage user accounts with the reverse proxy <a class="headerlink" href="#tutorials/reverse-proxy/manage-user-accounts-with-the-reverse-proxy">&para;</a></h4>
@ -483,36 +614,35 @@ user2:password2
proxy_set_header Host $http_host;
auth_basic "Radicale - Password Required";
auth_basic_user_file /etc/nginx/htpasswd;
}
</code></pre>
}</code></pre>
<p>Example <strong>Apache</strong> configuration:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb19-1"><a href="#cb19-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb19-2"><a href="#cb19-2"></a>RewriteRule<span class="st"> ^/radicale$ /radicale/ [R,L]</span></span>
<span id="cb19-3"><a href="#cb19-3"></a></span>
<span id="cb19-4"><a href="#cb19-4"></a><span class="fu">&lt;Location</span><span class="at"> "/radicale/"</span><span class="fu">&gt;</span></span>
<span id="cb19-5"><a href="#cb19-5"></a> <span class="ex">AuthType</span><span class="ch"> </span><span class="kw">Basic</span></span>
<span id="cb19-6"><a href="#cb19-6"></a> AuthName<span class="st"> "Radicale - Password Required"</span></span>
<span id="cb19-7"><a href="#cb19-7"></a> AuthUserFile<span class="st"> "/etc/radicale/htpasswd"</span></span>
<span id="cb19-8"><a href="#cb19-8"></a> Require<span class="st"> valid-user</span></span>
<span id="cb19-9"><a href="#cb19-9"></a></span>
<span id="cb19-10"><a href="#cb19-10"></a> ProxyPass<span class="st"> http://localhost:5232/ retry=0</span></span>
<span id="cb19-11"><a href="#cb19-11"></a> ProxyPassReverse<span class="st"> http://localhost:5232/</span></span>
<span id="cb19-12"><a href="#cb19-12"></a> RequestHeader<span class="st"> set X-Script-Name /radicale</span></span>
<span id="cb19-13"><a href="#cb19-13"></a> RequestHeader<span class="st"> set X-Remote-User expr=%{REMOTE_USER}</span></span>
<span id="cb19-14"><a href="#cb19-14"></a><span class="fu">&lt;/Location&gt;</span></span></code></pre></div>
<div class="sourceCode" id="cb19"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb19-1"><a aria-hidden="true" href="#cb19-1" tabindex="-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb19-2"><a aria-hidden="true" href="#cb19-2" tabindex="-1"></a>RewriteRule<span class="st"> ^/radicale$ /radicale/ [R,L]</span></span>
<span id="cb19-3"><a aria-hidden="true" href="#cb19-3" tabindex="-1"></a></span>
<span id="cb19-4"><a aria-hidden="true" href="#cb19-4" tabindex="-1"></a><span class="fu">&lt;Location</span><span class="at"> "/radicale/"</span><span class="fu">&gt;</span></span>
<span id="cb19-5"><a aria-hidden="true" href="#cb19-5" tabindex="-1"></a> <span class="ex">AuthType</span><span class="ch"> </span><span class="kw">Basic</span></span>
<span id="cb19-6"><a aria-hidden="true" href="#cb19-6" tabindex="-1"></a> AuthName<span class="st"> "Radicale - Password Required"</span></span>
<span id="cb19-7"><a aria-hidden="true" href="#cb19-7" tabindex="-1"></a> AuthUserFile<span class="st"> "/etc/radicale/htpasswd"</span></span>
<span id="cb19-8"><a aria-hidden="true" href="#cb19-8" tabindex="-1"></a> Require<span class="st"> valid-user</span></span>
<span id="cb19-9"><a aria-hidden="true" href="#cb19-9" tabindex="-1"></a></span>
<span id="cb19-10"><a aria-hidden="true" href="#cb19-10" tabindex="-1"></a> ProxyPass<span class="st"> http://localhost:5232/ retry=0</span></span>
<span id="cb19-11"><a aria-hidden="true" href="#cb19-11" tabindex="-1"></a> ProxyPassReverse<span class="st"> http://localhost:5232/</span></span>
<span id="cb19-12"><a aria-hidden="true" href="#cb19-12" tabindex="-1"></a> RequestHeader<span class="st"> set X-Script-Name /radicale</span></span>
<span id="cb19-13"><a aria-hidden="true" href="#cb19-13" tabindex="-1"></a> RequestHeader<span class="st"> set X-Remote-User expr=%{REMOTE_USER}</span></span>
<span id="cb19-14"><a aria-hidden="true" href="#cb19-14" tabindex="-1"></a><span class="fu">&lt;/Location&gt;</span></span></code></pre></div>
<p>Example <strong>Apache .htaccess</strong> configuration:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb20-1"><a href="#cb20-1"></a>DirectoryIndex<span class="st"> disabled</span></span>
<span id="cb20-2"><a href="#cb20-2"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb20-3"><a href="#cb20-3"></a>RewriteRule<span class="st"> ^(.*)$ http://localhost:5232/$1 [P,L]</span></span>
<span id="cb20-4"><a href="#cb20-4"></a></span>
<span id="cb20-5"><a href="#cb20-5"></a><span class="ex">AuthType</span><span class="ch"> </span><span class="kw">Basic</span></span>
<span id="cb20-6"><a href="#cb20-6"></a>AuthName<span class="st"> "Radicale - Password Required"</span></span>
<span id="cb20-7"><a href="#cb20-7"></a>AuthUserFile<span class="st"> "/etc/radicale/htpasswd"</span></span>
<span id="cb20-8"><a href="#cb20-8"></a>Require<span class="st"> valid-user</span></span>
<span id="cb20-9"><a href="#cb20-9"></a></span>
<span id="cb20-10"><a href="#cb20-10"></a><span class="co"># Set to directory of .htaccess file:</span></span>
<span id="cb20-11"><a href="#cb20-11"></a>RequestHeader<span class="st"> set X-Script-Name /radicale</span></span>
<span id="cb20-12"><a href="#cb20-12"></a>RequestHeader<span class="st"> set X-Remote-User expr=%{REMOTE_USER}</span></span></code></pre></div>
<div class="sourceCode" id="cb20"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb20-1"><a aria-hidden="true" href="#cb20-1" tabindex="-1"></a>DirectoryIndex<span class="st"> disabled</span></span>
<span id="cb20-2"><a aria-hidden="true" href="#cb20-2" tabindex="-1"></a><span class="ex">RewriteEngine</span><span class="ch"> </span><span class="kw">On</span></span>
<span id="cb20-3"><a aria-hidden="true" href="#cb20-3" tabindex="-1"></a>RewriteRule<span class="st"> ^(.*)$ http://localhost:5232/$1 [P,L]</span></span>
<span id="cb20-4"><a aria-hidden="true" href="#cb20-4" tabindex="-1"></a></span>
<span id="cb20-5"><a aria-hidden="true" href="#cb20-5" tabindex="-1"></a><span class="ex">AuthType</span><span class="ch"> </span><span class="kw">Basic</span></span>
<span id="cb20-6"><a aria-hidden="true" href="#cb20-6" tabindex="-1"></a>AuthName<span class="st"> "Radicale - Password Required"</span></span>
<span id="cb20-7"><a aria-hidden="true" href="#cb20-7" tabindex="-1"></a>AuthUserFile<span class="st"> "/etc/radicale/htpasswd"</span></span>
<span id="cb20-8"><a aria-hidden="true" href="#cb20-8" tabindex="-1"></a>Require<span class="st"> valid-user</span></span>
<span id="cb20-9"><a aria-hidden="true" href="#cb20-9" tabindex="-1"></a></span>
<span id="cb20-10"><a aria-hidden="true" href="#cb20-10" tabindex="-1"></a><span class="co"># Set to directory of .htaccess file:</span></span>
<span id="cb20-11"><a aria-hidden="true" href="#cb20-11" tabindex="-1"></a>RequestHeader<span class="st"> set X-Script-Name /radicale</span></span>
<span id="cb20-12"><a aria-hidden="true" href="#cb20-12" tabindex="-1"></a>RequestHeader<span class="st"> set X-Remote-User expr=%{REMOTE_USER}</span></span></code></pre></div>
<blockquote>
<p><strong>Security:</strong> Untrusted clients should not be able to access the Radicale server directly. Otherwise, they can authenticate as any user.</p>
</blockquote>
@ -520,14 +650,14 @@ user2:password2
<section class="level4" id="tutorials/reverse-proxy/secure-connection-between-radicale-and-the-reverse-proxy">
<h4>Secure connection between Radicale and the reverse proxy <a class="headerlink" href="#tutorials/reverse-proxy/secure-connection-between-radicale-and-the-reverse-proxy">&para;</a></h4>
<p>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.</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb21-1"><a href="#cb21-1"></a>$ <span class="ex">openssl</span> req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem -nodes -days 9999</span>
<span id="cb21-2"><a href="#cb21-2"></a>$ <span class="ex">openssl</span> req -x509 -newkey rsa:4096 -keyout client_key.pem -out client_cert.pem -nodes -days 9999</span></code></pre></div>
<div class="sourceCode" id="cb21"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb21-1"><a aria-hidden="true" href="#cb21-1" tabindex="-1"></a><span class="ex">$</span> openssl req <span class="at">-x509</span> <span class="at">-newkey</span> rsa:4096 <span class="at">-keyout</span> server_key.pem <span class="at">-out</span> server_cert.pem <span class="at">-nodes</span> <span class="at">-days</span> 9999</span>
<span id="cb21-2"><a aria-hidden="true" href="#cb21-2" tabindex="-1"></a><span class="ex">$</span> openssl req <span class="at">-x509</span> <span class="at">-newkey</span> rsa:4096 <span class="at">-keyout</span> client_key.pem <span class="at">-out</span> client_cert.pem <span class="at">-nodes</span> <span class="at">-days</span> 9999</span></code></pre></div>
<p>Use the following configuration for Radicale:</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb22-1"><a href="#cb22-1"></a><span class="kw">[server]</span></span>
<span id="cb22-2"><a href="#cb22-2"></a><span class="dt">ssl </span><span class="ot">=</span><span class="st"> </span><span class="kw">True</span></span>
<span id="cb22-3"><a href="#cb22-3"></a><span class="dt">certificate </span><span class="ot">=</span><span class="st"> /path/to/server_cert.pem</span></span>
<span id="cb22-4"><a href="#cb22-4"></a><span class="dt">key </span><span class="ot">=</span><span class="st"> /path/to/server_key.pem</span></span>
<span id="cb22-5"><a href="#cb22-5"></a><span class="dt">certificate_authority </span><span class="ot">=</span><span class="st"> /path/to/client_cert.pem</span></span></code></pre></div>
<div class="sourceCode" id="cb22"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb22-1"><a aria-hidden="true" href="#cb22-1" tabindex="-1"></a><span class="kw">[server]</span></span>
<span id="cb22-2"><a aria-hidden="true" href="#cb22-2" tabindex="-1"></a><span class="dt">ssl </span><span class="ot">=</span><span class="st"> </span><span class="kw">True</span></span>
<span id="cb22-3"><a aria-hidden="true" href="#cb22-3" tabindex="-1"></a><span class="dt">certificate </span><span class="ot">=</span><span class="st"> /path/to/server_cert.pem</span></span>
<span id="cb22-4"><a aria-hidden="true" href="#cb22-4" tabindex="-1"></a><span class="dt">key </span><span class="ot">=</span><span class="st"> /path/to/server_key.pem</span></span>
<span id="cb22-5"><a aria-hidden="true" href="#cb22-5" tabindex="-1"></a><span class="dt">certificate_authority </span><span class="ot">=</span><span class="st"> /path/to/client_cert.pem</span></span></code></pre></div>
<p>Example <strong>nginx</strong> configuration:</p>
<pre class="nginx"><code>location /radicale/ {
proxy_pass https://localhost:5232/;
@ -536,8 +666,7 @@ user2:password2
proxy_ssl_certificate /path/to/client_cert.pem;
proxy_ssl_certificate_key /path/to/client_key.pem;
proxy_ssl_trusted_certificate /path/to/server_cert.pem;
}
</code></pre>
}</code></pre>
</section>
</section>
<section class="level3" id="tutorials/wsgi-server">
@ -545,14 +674,14 @@ user2:password2
<p>Radicale is compatible with the WSGI specification.</p>
<p>A configuration file can be set with the <code>RADICALE_CONFIG</code> environment variable, otherwise no configuration file is loaded and the default configuration is used.</p>
<p>Example <strong>uWSGI</strong> configuration:</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb24-1"><a href="#cb24-1"></a><span class="kw">[uwsgi]</span></span>
<span id="cb24-2"><a href="#cb24-2"></a><span class="dt">http-socket </span><span class="ot">=</span><span class="st"> </span><span class="dv">127</span><span class="st">.</span><span class="dv">0</span><span class="st">.</span><span class="fl">0.1</span><span class="st">:</span><span class="dv">5232</span></span>
<span id="cb24-3"><a href="#cb24-3"></a><span class="dt">processes </span><span class="ot">=</span><span class="st"> </span><span class="dv">8</span></span>
<span id="cb24-4"><a href="#cb24-4"></a><span class="dt">plugin </span><span class="ot">=</span><span class="st"> python3</span></span>
<span id="cb24-5"><a href="#cb24-5"></a><span class="dt">module </span><span class="ot">=</span><span class="st"> radicale</span></span>
<span id="cb24-6"><a href="#cb24-6"></a><span class="dt">env </span><span class="ot">=</span><span class="st"> RADICALE_CONFIG=/etc/radicale/config</span></span></code></pre></div>
<div class="sourceCode" id="cb24"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb24-1"><a aria-hidden="true" href="#cb24-1" tabindex="-1"></a><span class="kw">[uwsgi]</span></span>
<span id="cb24-2"><a aria-hidden="true" href="#cb24-2" tabindex="-1"></a><span class="dt">http-socket </span><span class="ot">=</span><span class="st"> 127.0.0.1:5232</span></span>
<span id="cb24-3"><a aria-hidden="true" href="#cb24-3" tabindex="-1"></a><span class="dt">processes </span><span class="ot">=</span><span class="st"> </span><span class="dv">8</span></span>
<span id="cb24-4"><a aria-hidden="true" href="#cb24-4" tabindex="-1"></a><span class="dt">plugin </span><span class="ot">=</span><span class="st"> python3</span></span>
<span id="cb24-5"><a aria-hidden="true" href="#cb24-5" tabindex="-1"></a><span class="dt">module </span><span class="ot">=</span><span class="st"> radicale</span></span>
<span id="cb24-6"><a aria-hidden="true" href="#cb24-6" tabindex="-1"></a><span class="dt">env </span><span class="ot">=</span><span class="st"> RADICALE_CONFIG=/etc/radicale/config</span></span></code></pre></div>
<p>Example <strong>Gunicorn</strong> configuration:</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb25-1"><a href="#cb25-1"></a><span class="ex">gunicorn</span> --bind <span class="st">'127.0.0.1:5232'</span> --workers 8 --env <span class="st">'RADICALE_CONFIG=/etc/radicale/config'</span> radicale</span></code></pre></div>
<div class="sourceCode" id="cb25"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb25-1"><a aria-hidden="true" href="#cb25-1" tabindex="-1"></a><span class="ex">gunicorn</span> <span class="at">--bind</span> <span class="st">'127.0.0.1:5232'</span> <span class="at">--workers</span> 8 <span class="at">--env</span> <span class="st">'RADICALE_CONFIG=/etc/radicale/config'</span> radicale</span></code></pre></div>
<section class="level4" id="tutorials/wsgi-server/manage-user-accounts-with-the-wsgi-server">
<h4>Manage user accounts with the WSGI server <a class="headerlink" href="#tutorials/wsgi-server/manage-user-accounts-with-the-wsgi-server">&para;</a></h4>
<p>Set the configuration option <code>type</code> in the <code>auth</code> section to <code>remote_user</code>. Radicale uses the user name provided by the WSGI server and disables authentication over HTTP.</p>
@ -564,10 +693,9 @@ user2:password2
<p>The repository must be initialized by running <code>git init</code> in the file system folder. Internal files of Radicale can be excluded by creating the file <code>.gitignore</code> with the following content:</p>
<pre><code>.Radicale.cache
.Radicale.lock
.Radicale.tmp-*
</code></pre>
.Radicale.tmp-*</code></pre>
<p>The configuration option <code>hook</code> in the <code>storage</code> section must be set to the following command:</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb27-1"><a href="#cb27-1"></a><span class="fu">git</span> add -A <span class="kw">&amp;&amp;</span> <span class="kw">(</span><span class="fu">git</span> diff --cached --quiet <span class="kw">||</span> <span class="fu">git</span> commit -m <span class="st">"Changes by "</span>%(user<span class="kw">)</span><span class="ex">s</span>)</span></code></pre></div>
<div class="sourceCode" id="cb27"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb27-1"><a aria-hidden="true" href="#cb27-1" tabindex="-1"></a><span class="fu">git</span> add <span class="at">-A</span> <span class="kw">&amp;&amp;</span> <span class="kw">(</span><span class="fu">git</span> diff <span class="at">--cached</span> <span class="at">--quiet</span> <span class="kw">||</span> <span class="fu">git</span> commit <span class="at">-m</span> <span class="st">"Changes by "</span>%<span class="er">(</span><span class="ex">user</span><span class="kw">)</span><span class="ex">s</span><span class="kw">)</span></span></code></pre></div>
<p>The command gets executed after every change to the storage and commits the changes into the <strong>git</strong> repository.</p>
</section>
</section>
@ -577,20 +705,20 @@ user2:password2
<h3>Configuration <a class="headerlink" href="#documentation/configuration">&para;</a></h3>
<p>Radicale can be configured with a configuration file or with command line arguments.</p>
<p>An example configuration file looks like:</p>
<div class="sourceCode" id="cb28"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb28-1"><a href="#cb28-1"></a><span class="kw">[server]</span></span>
<span id="cb28-2"><a href="#cb28-2"></a><span class="co"># Bind all addresses</span></span>
<span id="cb28-3"><a href="#cb28-3"></a><span class="dt">hosts </span><span class="ot">=</span><span class="st"> </span><span class="dv">0</span><span class="st">.</span><span class="dv">0</span><span class="st">.</span><span class="fl">0.0</span><span class="st">:</span><span class="dv">5232</span><span class="st">, [::]:</span><span class="dv">5232</span></span>
<span id="cb28-4"><a href="#cb28-4"></a></span>
<span id="cb28-5"><a href="#cb28-5"></a><span class="kw">[auth]</span></span>
<span id="cb28-6"><a href="#cb28-6"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb28-7"><a href="#cb28-7"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> ~/.config/radicale/users</span></span>
<span id="cb28-8"><a href="#cb28-8"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> md5</span></span>
<span id="cb28-9"><a href="#cb28-9"></a></span>
<span id="cb28-10"><a href="#cb28-10"></a><span class="kw">[storage]</span></span>
<span id="cb28-11"><a href="#cb28-11"></a><span class="dt">filesystem_folder </span><span class="ot">=</span><span class="st"> ~/.var/lib/radicale/collections</span></span></code></pre></div>
<div class="sourceCode" id="cb28"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb28-1"><a aria-hidden="true" href="#cb28-1" tabindex="-1"></a><span class="kw">[server]</span></span>
<span id="cb28-2"><a aria-hidden="true" href="#cb28-2" tabindex="-1"></a><span class="co"># Bind all addresses</span></span>
<span id="cb28-3"><a aria-hidden="true" href="#cb28-3" tabindex="-1"></a><span class="dt">hosts </span><span class="ot">=</span><span class="st"> 0.0.0.0:5232, [::]:5232</span></span>
<span id="cb28-4"><a aria-hidden="true" href="#cb28-4" tabindex="-1"></a></span>
<span id="cb28-5"><a aria-hidden="true" href="#cb28-5" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb28-6"><a aria-hidden="true" href="#cb28-6" tabindex="-1"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> htpasswd</span></span>
<span id="cb28-7"><a aria-hidden="true" href="#cb28-7" tabindex="-1"></a><span class="dt">htpasswd_filename </span><span class="ot">=</span><span class="st"> ~/.config/radicale/users</span></span>
<span id="cb28-8"><a aria-hidden="true" href="#cb28-8" tabindex="-1"></a><span class="dt">htpasswd_encryption </span><span class="ot">=</span><span class="st"> md5</span></span>
<span id="cb28-9"><a aria-hidden="true" href="#cb28-9" tabindex="-1"></a></span>
<span id="cb28-10"><a aria-hidden="true" href="#cb28-10" tabindex="-1"></a><span class="kw">[storage]</span></span>
<span id="cb28-11"><a aria-hidden="true" href="#cb28-11" tabindex="-1"></a><span class="dt">filesystem_folder </span><span class="ot">=</span><span class="st"> ~/.var/lib/radicale/collections</span></span></code></pre></div>
<p>Radicale tries to load configuration files from <code>/etc/radicale/config</code> and <code>~/.config/radicale/config</code>. Custom paths can be specified with the <code>--config /path/to/config</code> command line argument or the <code>RADICALE_CONFIG</code> environment variable. Multiple configuration files can be separated by <code>:</code> (resp. <code>;</code> on Windows). Paths that start with <code>?</code> are optional.</p>
<p>The same example configuration via command line arguments looks like:</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb29-1"><a href="#cb29-1"></a><span class="ex">python3</span> -m radicale --server-hosts 0.0.0.0:5232,[::]:5232 --auth-type htpasswd --auth-htpasswd-filename ~/.config/radicale/users --auth-htpasswd-encryption md5</span></code></pre></div>
<div class="sourceCode" id="cb29"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb29-1"><a aria-hidden="true" href="#cb29-1" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> radicale <span class="at">--server-hosts</span> 0.0.0.0:5232,[::]:5232 <span class="at">--auth-type</span> htpasswd <span class="at">--auth-htpasswd-filename</span> ~/.config/radicale/users <span class="at">--auth-htpasswd-encryption</span> md5</span></code></pre></div>
<p>Add the argument <code>--config ""</code> to stop Radicale from loading the default configuration files. Run <code>python3 -m radicale --help</code> for more information.</p>
<p>In the following, all configuration categories and options are described.</p>
<section class="level4" id="documentation/configuration/server">
@ -673,8 +801,7 @@ user2:password2
<p>Available methods:</p>
<p><code>plain</code> : Passwords are stored in plaintext. This is obviously not secure! The htpasswd file for this can be created by hand and looks like:</p>
<pre class="htpasswd"><code>user1:password1
user2:password2
</code></pre>
user2:password2</code></pre>
<p><code>bcrypt</code> : This uses a modified version of the Blowfish stream cipher. It's very secure. The installation of <strong>radicale[bcrypt]</strong> is required for this.</p>
<p><code>md5</code> : This uses an iterated md5 digest of the password with a salt.</p>
<p>Default: <code>md5</code></p>
@ -762,7 +889,7 @@ user2:password2
<h4>headers <a class="headerlink" href="#documentation/configuration/headers">&para;</a></h4>
<p>In this section additional HTTP headers that are sent to clients can be specified.</p>
<p>An example to relax the same-origin policy:</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb31-1"><a href="#cb31-1"></a><span class="dt">Access-Control-Allow-Origin </span><span class="ot">=</span><span class="st"> *</span></span></code></pre></div>
<div class="sourceCode" id="cb31"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb31-1"><a aria-hidden="true" href="#cb31-1" tabindex="-1"></a><span class="dt">Access-Control-Allow-Origin </span><span class="ot">=</span><span class="st"> *</span></span></code></pre></div>
</section>
</section>
<section class="level3" id="documentation/supported-clients">
@ -774,7 +901,7 @@ user2:password2
<li><a href="https://www.mozilla.org/thunderbird/">Mozilla Thunderbird</a> with <a href="https://addons.mozilla.org/thunderbird/addon/cardbook/">CardBook</a> and <a href="https://www.mozilla.org/projects/calendar/">Lightning</a></li>
<li><a href="https://www.inf-it.com/open-source/clients/infcloud/">InfCloud</a>, <a href="https://www.inf-it.com/open-source/clients/caldavzap/">CalDavZAP</a> and <a href="https://www.inf-it.com/open-source/clients/carddavmate/">CardDavMATE</a></li>
</ul>
<p>Many clients do not support the creation of new calendars and address books. You can use Radicale's web interface (e.g. <a href="http://localhost:5232">http://localhost:5232</a>) to create and manage address books and calendars.</p>
<p>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.</p>
<p>In some clients you can just enter the URL of the Radicale server (e.g. <code>http://localhost:5232</code>) and your user name. In others, you have to enter the URL of the collection directly (e.g. <code>http://localhost:5232/user/calendar</code>).</p>
<section class="level4" id="documentation/supported-clients/davx⁵">
<h4>DAVx⁵ <a class="headerlink" href="#documentation/supported-clients/davx⁵">&para;</a></h4>
@ -805,44 +932,44 @@ user2:password2
<h4>Command line <a class="headerlink" href="#documentation/supported-clients/command-line">&para;</a></h4>
<p>This is not the recommended way of creating and managing your calendars and address books. Use Radicale's web interface or a client with support for it (e.g. <strong>DAVx⁵</strong>).</p>
<p>To create a new calendar run something like:</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb32-1"><a href="#cb32-1"></a>$ <span class="ex">curl</span> -u user -X MKCOL <span class="st">'http://localhost:5232/user/calendar'</span> --data \</span>
<span id="cb32-2"><a href="#cb32-2"></a><span class="st">'&lt;?xml version="1.0" encoding="UTF-8" ?&gt;</span></span>
<span id="cb32-3"><a href="#cb32-3"></a><span class="st">&lt;create xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:I="http://apple.com/ns/ical/"&gt;</span></span>
<span id="cb32-4"><a href="#cb32-4"></a><span class="st"> &lt;set&gt;</span></span>
<span id="cb32-5"><a href="#cb32-5"></a><span class="st"> &lt;prop&gt;</span></span>
<span id="cb32-6"><a href="#cb32-6"></a><span class="st"> &lt;resourcetype&gt;</span></span>
<span id="cb32-7"><a href="#cb32-7"></a><span class="st"> &lt;collection /&gt;</span></span>
<span id="cb32-8"><a href="#cb32-8"></a><span class="st"> &lt;C:calendar /&gt;</span></span>
<span id="cb32-9"><a href="#cb32-9"></a><span class="st"> &lt;/resourcetype&gt;</span></span>
<span id="cb32-10"><a href="#cb32-10"></a><span class="st"> &lt;C:supported-calendar-component-set&gt;</span></span>
<span id="cb32-11"><a href="#cb32-11"></a><span class="st"> &lt;C:comp name="VEVENT" /&gt;</span></span>
<span id="cb32-12"><a href="#cb32-12"></a><span class="st"> &lt;C:comp name="VJOURNAL" /&gt;</span></span>
<span id="cb32-13"><a href="#cb32-13"></a><span class="st"> &lt;C:comp name="VTODO" /&gt;</span></span>
<span id="cb32-14"><a href="#cb32-14"></a><span class="st"> &lt;/C:supported-calendar-component-set&gt;</span></span>
<span id="cb32-15"><a href="#cb32-15"></a><span class="st"> &lt;displayname&gt;Calendar&lt;/displayname&gt;</span></span>
<span id="cb32-16"><a href="#cb32-16"></a><span class="st"> &lt;C:calendar-description&gt;Example calendar&lt;/C:calendar-description&gt;</span></span>
<span id="cb32-17"><a href="#cb32-17"></a><span class="st"> &lt;I:calendar-color&gt;#ff0000ff&lt;/I:calendar-color&gt;</span></span>
<span id="cb32-18"><a href="#cb32-18"></a><span class="st"> &lt;/prop&gt;</span></span>
<span id="cb32-19"><a href="#cb32-19"></a><span class="st"> &lt;/set&gt;</span></span>
<span id="cb32-20"><a href="#cb32-20"></a><span class="st">&lt;/create&gt;'</span></span></code></pre></div>
<div class="sourceCode" id="cb32"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb32-1"><a aria-hidden="true" href="#cb32-1" tabindex="-1"></a><span class="ex">$</span> curl <span class="at">-u</span> user <span class="at">-X</span> MKCOL <span class="st">'http://localhost:5232/user/calendar'</span> <span class="at">--data</span> <span class="dt">\</span></span>
<span id="cb32-2"><a aria-hidden="true" href="#cb32-2" tabindex="-1"></a><span class="st">'&lt;?xml version="1.0" encoding="UTF-8" ?&gt;</span></span>
<span id="cb32-3"><a aria-hidden="true" href="#cb32-3" tabindex="-1"></a><span class="st">&lt;create xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:I="http://apple.com/ns/ical/"&gt;</span></span>
<span id="cb32-4"><a aria-hidden="true" href="#cb32-4" tabindex="-1"></a><span class="st"> &lt;set&gt;</span></span>
<span id="cb32-5"><a aria-hidden="true" href="#cb32-5" tabindex="-1"></a><span class="st"> &lt;prop&gt;</span></span>
<span id="cb32-6"><a aria-hidden="true" href="#cb32-6" tabindex="-1"></a><span class="st"> &lt;resourcetype&gt;</span></span>
<span id="cb32-7"><a aria-hidden="true" href="#cb32-7" tabindex="-1"></a><span class="st"> &lt;collection /&gt;</span></span>
<span id="cb32-8"><a aria-hidden="true" href="#cb32-8" tabindex="-1"></a><span class="st"> &lt;C:calendar /&gt;</span></span>
<span id="cb32-9"><a aria-hidden="true" href="#cb32-9" tabindex="-1"></a><span class="st"> &lt;/resourcetype&gt;</span></span>
<span id="cb32-10"><a aria-hidden="true" href="#cb32-10" tabindex="-1"></a><span class="st"> &lt;C:supported-calendar-component-set&gt;</span></span>
<span id="cb32-11"><a aria-hidden="true" href="#cb32-11" tabindex="-1"></a><span class="st"> &lt;C:comp name="VEVENT" /&gt;</span></span>
<span id="cb32-12"><a aria-hidden="true" href="#cb32-12" tabindex="-1"></a><span class="st"> &lt;C:comp name="VJOURNAL" /&gt;</span></span>
<span id="cb32-13"><a aria-hidden="true" href="#cb32-13" tabindex="-1"></a><span class="st"> &lt;C:comp name="VTODO" /&gt;</span></span>
<span id="cb32-14"><a aria-hidden="true" href="#cb32-14" tabindex="-1"></a><span class="st"> &lt;/C:supported-calendar-component-set&gt;</span></span>
<span id="cb32-15"><a aria-hidden="true" href="#cb32-15" tabindex="-1"></a><span class="st"> &lt;displayname&gt;Calendar&lt;/displayname&gt;</span></span>
<span id="cb32-16"><a aria-hidden="true" href="#cb32-16" tabindex="-1"></a><span class="st"> &lt;C:calendar-description&gt;Example calendar&lt;/C:calendar-description&gt;</span></span>
<span id="cb32-17"><a aria-hidden="true" href="#cb32-17" tabindex="-1"></a><span class="st"> &lt;I:calendar-color&gt;#ff0000ff&lt;/I:calendar-color&gt;</span></span>
<span id="cb32-18"><a aria-hidden="true" href="#cb32-18" tabindex="-1"></a><span class="st"> &lt;/prop&gt;</span></span>
<span id="cb32-19"><a aria-hidden="true" href="#cb32-19" tabindex="-1"></a><span class="st"> &lt;/set&gt;</span></span>
<span id="cb32-20"><a aria-hidden="true" href="#cb32-20" tabindex="-1"></a><span class="st">&lt;/create&gt;'</span></span></code></pre></div>
<p>To create a new address book run something like:</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb33-1"><a href="#cb33-1"></a>$ <span class="ex">curl</span> -u user -X MKCOL <span class="st">'http://localhost:5232/user/addressbook'</span> --data \</span>
<span id="cb33-2"><a href="#cb33-2"></a><span class="st">'&lt;?xml version="1.0" encoding="UTF-8" ?&gt;</span></span>
<span id="cb33-3"><a href="#cb33-3"></a><span class="st">&lt;create xmlns="DAV:" xmlns:CR="urn:ietf:params:xml:ns:carddav"&gt;</span></span>
<span id="cb33-4"><a href="#cb33-4"></a><span class="st"> &lt;set&gt;</span></span>
<span id="cb33-5"><a href="#cb33-5"></a><span class="st"> &lt;prop&gt;</span></span>
<span id="cb33-6"><a href="#cb33-6"></a><span class="st"> &lt;resourcetype&gt;</span></span>
<span id="cb33-7"><a href="#cb33-7"></a><span class="st"> &lt;collection /&gt;</span></span>
<span id="cb33-8"><a href="#cb33-8"></a><span class="st"> &lt;CR:addressbook /&gt;</span></span>
<span id="cb33-9"><a href="#cb33-9"></a><span class="st"> &lt;/resourcetype&gt;</span></span>
<span id="cb33-10"><a href="#cb33-10"></a><span class="st"> &lt;displayname&gt;Address book&lt;/displayname&gt;</span></span>
<span id="cb33-11"><a href="#cb33-11"></a><span class="st"> &lt;CR:addressbook-description&gt;Example address book&lt;/CR:addressbook-description&gt;</span></span>
<span id="cb33-12"><a href="#cb33-12"></a><span class="st"> &lt;/prop&gt;</span></span>
<span id="cb33-13"><a href="#cb33-13"></a><span class="st"> &lt;/set&gt;</span></span>
<span id="cb33-14"><a href="#cb33-14"></a><span class="st">&lt;/create&gt;'</span></span></code></pre></div>
<div class="sourceCode" id="cb33"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb33-1"><a aria-hidden="true" href="#cb33-1" tabindex="-1"></a><span class="ex">$</span> curl <span class="at">-u</span> user <span class="at">-X</span> MKCOL <span class="st">'http://localhost:5232/user/addressbook'</span> <span class="at">--data</span> <span class="dt">\</span></span>
<span id="cb33-2"><a aria-hidden="true" href="#cb33-2" tabindex="-1"></a><span class="st">'&lt;?xml version="1.0" encoding="UTF-8" ?&gt;</span></span>
<span id="cb33-3"><a aria-hidden="true" href="#cb33-3" tabindex="-1"></a><span class="st">&lt;create xmlns="DAV:" xmlns:CR="urn:ietf:params:xml:ns:carddav"&gt;</span></span>
<span id="cb33-4"><a aria-hidden="true" href="#cb33-4" tabindex="-1"></a><span class="st"> &lt;set&gt;</span></span>
<span id="cb33-5"><a aria-hidden="true" href="#cb33-5" tabindex="-1"></a><span class="st"> &lt;prop&gt;</span></span>
<span id="cb33-6"><a aria-hidden="true" href="#cb33-6" tabindex="-1"></a><span class="st"> &lt;resourcetype&gt;</span></span>
<span id="cb33-7"><a aria-hidden="true" href="#cb33-7" tabindex="-1"></a><span class="st"> &lt;collection /&gt;</span></span>
<span id="cb33-8"><a aria-hidden="true" href="#cb33-8" tabindex="-1"></a><span class="st"> &lt;CR:addressbook /&gt;</span></span>
<span id="cb33-9"><a aria-hidden="true" href="#cb33-9" tabindex="-1"></a><span class="st"> &lt;/resourcetype&gt;</span></span>
<span id="cb33-10"><a aria-hidden="true" href="#cb33-10" tabindex="-1"></a><span class="st"> &lt;displayname&gt;Address book&lt;/displayname&gt;</span></span>
<span id="cb33-11"><a aria-hidden="true" href="#cb33-11" tabindex="-1"></a><span class="st"> &lt;CR:addressbook-description&gt;Example address book&lt;/CR:addressbook-description&gt;</span></span>
<span id="cb33-12"><a aria-hidden="true" href="#cb33-12" tabindex="-1"></a><span class="st"> &lt;/prop&gt;</span></span>
<span id="cb33-13"><a aria-hidden="true" href="#cb33-13" tabindex="-1"></a><span class="st"> &lt;/set&gt;</span></span>
<span id="cb33-14"><a aria-hidden="true" href="#cb33-14" tabindex="-1"></a><span class="st">&lt;/create&gt;'</span></span></code></pre></div>
<p>The collection <code>/USERNAME</code> 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 <code>/USERNAME/</code>.</p>
<p>Delete the collections by running something like:</p>
<div class="sourceCode" id="cb34"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb34-1"><a href="#cb34-1"></a>$ <span class="ex">curl</span> -u user -X DELETE <span class="st">'http://localhost:5232/user/calendar'</span></span></code></pre></div>
<div class="sourceCode" id="cb34"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb34-1"><a aria-hidden="true" href="#cb34-1" tabindex="-1"></a><span class="ex">$</span> curl <span class="at">-u</span> user <span class="at">-X</span> DELETE <span class="st">'http://localhost:5232/user/calendar'</span></span></code></pre></div>
</section>
</section>
<section class="level3" id="documentation/authentication-and-rights">
@ -850,24 +977,24 @@ user2:password2
<p>This section describes the format of the rights file for the <code>from_file</code> authentication backend. The configuration option <code>file</code> in the <code>rights</code> section must point to the rights file.</p>
<p>The recommended rights method is <code>owner_only</code>. If access to calendars and address books outside the home directory of users (that's <code>/USERNAME/</code>) 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.</p>
<p>An example rights file:</p>
<div class="sourceCode" id="cb35"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb35-1"><a href="#cb35-1"></a><span class="co"># Allow reading root collection for authenticated users</span></span>
<span id="cb35-2"><a href="#cb35-2"></a><span class="kw">[root]</span></span>
<span id="cb35-3"><a href="#cb35-3"></a><span class="dt">user: .+</span></span>
<span id="cb35-4"><a href="#cb35-4"></a><span class="dt">collection:</span></span>
<span id="cb35-5"><a href="#cb35-5"></a><span class="dt">permissions: R</span></span>
<span id="cb35-6"><a href="#cb35-6"></a></span>
<span id="cb35-7"><a href="#cb35-7"></a><span class="co"># Allow reading and writing principal collection (same as user name)</span></span>
<span id="cb35-8"><a href="#cb35-8"></a><span class="kw">[principal]</span></span>
<span id="cb35-9"><a href="#cb35-9"></a><span class="dt">user: .+</span></span>
<span id="cb35-10"><a href="#cb35-10"></a><span class="dt">collection: {user}</span></span>
<span id="cb35-11"><a href="#cb35-11"></a><span class="dt">permissions: RW</span></span>
<span id="cb35-12"><a href="#cb35-12"></a></span>
<span id="cb35-13"><a href="#cb35-13"></a><span class="co"># Allow reading and writing calendars and address books that are direct</span></span>
<span id="cb35-14"><a href="#cb35-14"></a><span class="co"># children of the principal collection</span></span>
<span id="cb35-15"><a href="#cb35-15"></a><span class="kw">[calendars]</span></span>
<span id="cb35-16"><a href="#cb35-16"></a><span class="dt">user: .+</span></span>
<span id="cb35-17"><a href="#cb35-17"></a><span class="dt">collection: {user}/</span><span class="kw">[^/]</span><span class="dt">+</span></span>
<span id="cb35-18"><a href="#cb35-18"></a><span class="dt">permissions: rw</span></span></code></pre></div>
<div class="sourceCode" id="cb35"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb35-1"><a aria-hidden="true" href="#cb35-1" tabindex="-1"></a><span class="co"># Allow reading root collection for authenticated users</span></span>
<span id="cb35-2"><a aria-hidden="true" href="#cb35-2" tabindex="-1"></a><span class="kw">[root]</span></span>
<span id="cb35-3"><a aria-hidden="true" href="#cb35-3" tabindex="-1"></a><span class="dt">user: .+</span></span>
<span id="cb35-4"><a aria-hidden="true" href="#cb35-4" tabindex="-1"></a><span class="dt">collection:</span></span>
<span id="cb35-5"><a aria-hidden="true" href="#cb35-5" tabindex="-1"></a><span class="dt">permissions: R</span></span>
<span id="cb35-6"><a aria-hidden="true" href="#cb35-6" tabindex="-1"></a></span>
<span id="cb35-7"><a aria-hidden="true" href="#cb35-7" tabindex="-1"></a><span class="co"># Allow reading and writing principal collection (same as user name)</span></span>
<span id="cb35-8"><a aria-hidden="true" href="#cb35-8" tabindex="-1"></a><span class="kw">[principal]</span></span>
<span id="cb35-9"><a aria-hidden="true" href="#cb35-9" tabindex="-1"></a><span class="dt">user: .+</span></span>
<span id="cb35-10"><a aria-hidden="true" href="#cb35-10" tabindex="-1"></a><span class="dt">collection: {user}</span></span>
<span id="cb35-11"><a aria-hidden="true" href="#cb35-11" tabindex="-1"></a><span class="dt">permissions: RW</span></span>
<span id="cb35-12"><a aria-hidden="true" href="#cb35-12" tabindex="-1"></a></span>
<span id="cb35-13"><a aria-hidden="true" href="#cb35-13" tabindex="-1"></a><span class="co"># Allow reading and writing calendars and address books that are direct</span></span>
<span id="cb35-14"><a aria-hidden="true" href="#cb35-14" tabindex="-1"></a><span class="co"># children of the principal collection</span></span>
<span id="cb35-15"><a aria-hidden="true" href="#cb35-15" tabindex="-1"></a><span class="kw">[calendars]</span></span>
<span id="cb35-16"><a aria-hidden="true" href="#cb35-16" tabindex="-1"></a><span class="dt">user: .+</span></span>
<span id="cb35-17"><a aria-hidden="true" href="#cb35-17" tabindex="-1"></a><span class="dt">collection: {user}/</span><span class="kw">[^/]</span><span class="dt">+</span></span>
<span id="cb35-18"><a aria-hidden="true" href="#cb35-18" tabindex="-1"></a><span class="dt">permissions: rw</span></span></code></pre></div>
<p>The titles of the sections are ignored (but must be unique). The keys <code>user</code> and <code>collection</code> 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.</p>
<p>The user name is empty for anonymous users. Therefore, the regex <code>.+</code> only matches authenticated users and <code>.*</code> matches everyone (including anonymous users).</p>
<p>The path of the collection is separated by <code>/</code> and has no leading or trailing <code>/</code>. Therefore, the path of the root collection is empty.</p>
@ -906,10 +1033,10 @@ user2:password2
<section class="level5" id="documentation/storage/locking/linux-shell-scripts">
<h5>Linux shell scripts <a class="headerlink" href="#documentation/storage/locking/linux-shell-scripts">&para;</a></h5>
<p>Use the <a href="https://manpages.debian.org/unstable/util-linux/flock.1.en.html">flock</a> utility.</p>
<div class="sourceCode" id="cb36"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb36-1"><a href="#cb36-1"></a><span class="co"># Exclusive</span></span>
<span id="cb36-2"><a href="#cb36-2"></a>$ <span class="ex">flock</span> --exclusive /path/to/storage/.Radicale.lock COMMAND</span>
<span id="cb36-3"><a href="#cb36-3"></a><span class="co"># Shared</span></span>
<span id="cb36-4"><a href="#cb36-4"></a>$ <span class="ex">flock</span> --shared /path/to/storage/.Radicale.lock COMMAND</span></code></pre></div>
<div class="sourceCode" id="cb36"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb36-1"><a aria-hidden="true" href="#cb36-1" tabindex="-1"></a><span class="co"># Exclusive</span></span>
<span id="cb36-2"><a aria-hidden="true" href="#cb36-2" tabindex="-1"></a><span class="ex">$</span> flock <span class="at">--exclusive</span> /path/to/storage/.Radicale.lock COMMAND</span>
<span id="cb36-3"><a aria-hidden="true" href="#cb36-3" tabindex="-1"></a><span class="co"># Shared</span></span>
<span id="cb36-4"><a aria-hidden="true" href="#cb36-4" tabindex="-1"></a><span class="ex">$</span> flock <span class="at">--shared</span> /path/to/storage/.Radicale.lock COMMAND</span></code></pre></div>
</section>
<section class="level5" id="documentation/storage/locking/linux-and-macos">
<h5>Linux and MacOS <a class="headerlink" href="#documentation/storage/locking/linux-and-macos">&para;</a></h5>
@ -923,9 +1050,9 @@ user2:password2
<section class="level4" id="documentation/storage/manually-creating-collections">
<h4>Manually creating collections <a class="headerlink" href="#documentation/storage/manually-creating-collections">&para;</a></h4>
<p>To create a new collection, you have to create the corresponding folder in the file system storage (e.g. <code>collection-root/user/calendar</code>). To tell Radicale and clients that the collection is a calendar, you have to create the file <code>.Radicale.props</code> with the following content in the folder:</p>
<div class="sourceCode" id="cb37"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb37-1"><a href="#cb37-1"></a><span class="fu">{</span><span class="dt">"tag"</span><span class="fu">:</span> <span class="st">"VCALENDAR"</span><span class="fu">}</span></span></code></pre></div>
<div class="sourceCode" id="cb37"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb37-1"><a aria-hidden="true" href="#cb37-1" tabindex="-1"></a><span class="fu">{</span><span class="dt">"tag"</span><span class="fu">:</span> <span class="st">"VCALENDAR"</span><span class="fu">}</span></span></code></pre></div>
<p>The calendar is now available at the URL path <code>/user/calendar</code>. For address books the file must contain:</p>
<div class="sourceCode" id="cb38"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb38-1"><a href="#cb38-1"></a><span class="fu">{</span><span class="dt">"tag"</span><span class="fu">:</span> <span class="st">"VADDRESSBOOK"</span><span class="fu">}</span></span></code></pre></div>
<div class="sourceCode" id="cb38"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb38-1"><a aria-hidden="true" href="#cb38-1" tabindex="-1"></a><span class="fu">{</span><span class="dt">"tag"</span><span class="fu">:</span> <span class="st">"VADDRESSBOOK"</span><span class="fu">}</span></span></code></pre></div>
<p>Calendar and address book collections must not have any child collections. Clients with automatic discovery of collections will only show calendars and address books that are direct children of the path <code>/USERNAME/</code>.</p>
<p>Delete collections by deleting the corresponding folders.</p>
</section>
@ -1011,42 +1138,42 @@ user2:password2
<h4>Getting started <a class="headerlink" href="#documentation/plugins/getting-started">&para;</a></h4>
<p>To get started we walk through the creation of a simple authentication plugin, that accepts login attempts with a static password.</p>
<p>The easiest way to develop and install <strong>python</strong> modules is <a href="https://docs.python.org/3/distutils/setupscript.html">Distutils</a>. For a minimal setup create the file <code>setup.py</code> with the following content in an empty folder:</p>
<div class="sourceCode" id="cb39"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb39-1"><a href="#cb39-1"></a><span class="co">#!/usr/bin/env python3</span></span>
<span id="cb39-2"><a href="#cb39-2"></a></span>
<span id="cb39-3"><a href="#cb39-3"></a><span class="im">from</span> distutils.core <span class="im">import</span> setup</span>
<span id="cb39-4"><a href="#cb39-4"></a></span>
<span id="cb39-5"><a href="#cb39-5"></a>setup(name<span class="op">=</span><span class="st">"radicale_static_password_auth"</span>,</span>
<span id="cb39-6"><a href="#cb39-6"></a> packages<span class="op">=</span>[<span class="st">"radicale_static_password_auth"</span>])</span></code></pre></div>
<div class="sourceCode" id="cb39"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb39-1"><a aria-hidden="true" href="#cb39-1" tabindex="-1"></a><span class="co">#!/usr/bin/env python3</span></span>
<span id="cb39-2"><a aria-hidden="true" href="#cb39-2" tabindex="-1"></a></span>
<span id="cb39-3"><a aria-hidden="true" href="#cb39-3" tabindex="-1"></a><span class="im">from</span> distutils.core <span class="im">import</span> setup</span>
<span id="cb39-4"><a aria-hidden="true" href="#cb39-4" tabindex="-1"></a></span>
<span id="cb39-5"><a aria-hidden="true" href="#cb39-5" tabindex="-1"></a>setup(name<span class="op">=</span><span class="st">"radicale_static_password_auth"</span>,</span>
<span id="cb39-6"><a aria-hidden="true" href="#cb39-6" tabindex="-1"></a> packages<span class="op">=</span>[<span class="st">"radicale_static_password_auth"</span>])</span></code></pre></div>
<p>In the same folder create the sub-folder <code>radicale_static_password_auth</code>. The folder must have the same name as specified in <code>packages</code> above.</p>
<p>Create the file <code>__init__.py</code> in the <code>radicale_static_password_auth</code> folder with the following content:</p>
<div class="sourceCode" id="cb40"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb40-1"><a href="#cb40-1"></a><span class="im">from</span> radicale.auth <span class="im">import</span> BaseAuth</span>
<span id="cb40-2"><a href="#cb40-2"></a><span class="im">from</span> radicale.log <span class="im">import</span> logger</span>
<span id="cb40-3"><a href="#cb40-3"></a></span>
<span id="cb40-4"><a href="#cb40-4"></a>PLUGIN_CONFIG_SCHEMA <span class="op">=</span> {<span class="st">"auth"</span>: {</span>
<span id="cb40-5"><a href="#cb40-5"></a> <span class="st">"password"</span>: {<span class="st">"value"</span>: <span class="st">""</span>, <span class="st">"type"</span>: <span class="bu">str</span>}}}</span>
<span id="cb40-6"><a href="#cb40-6"></a></span>
<span id="cb40-7"><a href="#cb40-7"></a></span>
<span id="cb40-8"><a href="#cb40-8"></a><span class="kw">class</span> Auth(BaseAuth):</span>
<span id="cb40-9"><a href="#cb40-9"></a> <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>, configuration):</span>
<span id="cb40-10"><a href="#cb40-10"></a> <span class="bu">super</span>().<span class="fu">__init__</span>(configuration.copy(PLUGIN_CONFIG_SCHEMA))</span>
<span id="cb40-11"><a href="#cb40-11"></a></span>
<span id="cb40-12"><a href="#cb40-12"></a> <span class="kw">def</span> login(<span class="va">self</span>, login, password):</span>
<span id="cb40-13"><a href="#cb40-13"></a> <span class="co"># Get password from configuration option</span></span>
<span id="cb40-14"><a href="#cb40-14"></a> static_password <span class="op">=</span> <span class="va">self</span>.configuration.get(<span class="st">"auth"</span>, <span class="st">"password"</span>)</span>
<span id="cb40-15"><a href="#cb40-15"></a> <span class="co"># Check authentication</span></span>
<span id="cb40-16"><a href="#cb40-16"></a> logger.info(<span class="st">"Login attempt by </span><span class="sc">%r</span><span class="st"> with password </span><span class="sc">%r</span><span class="st">"</span>,</span>
<span id="cb40-17"><a href="#cb40-17"></a> login, password)</span>
<span id="cb40-18"><a href="#cb40-18"></a> <span class="cf">if</span> password <span class="op">==</span> static_password:</span>
<span id="cb40-19"><a href="#cb40-19"></a> <span class="cf">return</span> login</span>
<span id="cb40-20"><a href="#cb40-20"></a> <span class="cf">return</span> <span class="st">""</span></span></code></pre></div>
<div class="sourceCode" id="cb40"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb40-1"><a aria-hidden="true" href="#cb40-1" tabindex="-1"></a><span class="im">from</span> radicale.auth <span class="im">import</span> BaseAuth</span>
<span id="cb40-2"><a aria-hidden="true" href="#cb40-2" tabindex="-1"></a><span class="im">from</span> radicale.log <span class="im">import</span> logger</span>
<span id="cb40-3"><a aria-hidden="true" href="#cb40-3" tabindex="-1"></a></span>
<span id="cb40-4"><a aria-hidden="true" href="#cb40-4" tabindex="-1"></a>PLUGIN_CONFIG_SCHEMA <span class="op">=</span> {<span class="st">"auth"</span>: {</span>
<span id="cb40-5"><a aria-hidden="true" href="#cb40-5" tabindex="-1"></a> <span class="st">"password"</span>: {<span class="st">"value"</span>: <span class="st">""</span>, <span class="st">"type"</span>: <span class="bu">str</span>}}}</span>
<span id="cb40-6"><a aria-hidden="true" href="#cb40-6" tabindex="-1"></a></span>
<span id="cb40-7"><a aria-hidden="true" href="#cb40-7" tabindex="-1"></a></span>
<span id="cb40-8"><a aria-hidden="true" href="#cb40-8" tabindex="-1"></a><span class="kw">class</span> Auth(BaseAuth):</span>
<span id="cb40-9"><a aria-hidden="true" href="#cb40-9" tabindex="-1"></a> <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>, configuration):</span>
<span id="cb40-10"><a aria-hidden="true" href="#cb40-10" tabindex="-1"></a> <span class="bu">super</span>().<span class="fu">__init__</span>(configuration.copy(PLUGIN_CONFIG_SCHEMA))</span>
<span id="cb40-11"><a aria-hidden="true" href="#cb40-11" tabindex="-1"></a></span>
<span id="cb40-12"><a aria-hidden="true" href="#cb40-12" tabindex="-1"></a> <span class="kw">def</span> login(<span class="va">self</span>, login, password):</span>
<span id="cb40-13"><a aria-hidden="true" href="#cb40-13" tabindex="-1"></a> <span class="co"># Get password from configuration option</span></span>
<span id="cb40-14"><a aria-hidden="true" href="#cb40-14" tabindex="-1"></a> static_password <span class="op">=</span> <span class="va">self</span>.configuration.get(<span class="st">"auth"</span>, <span class="st">"password"</span>)</span>
<span id="cb40-15"><a aria-hidden="true" href="#cb40-15" tabindex="-1"></a> <span class="co"># Check authentication</span></span>
<span id="cb40-16"><a aria-hidden="true" href="#cb40-16" tabindex="-1"></a> logger.info(<span class="st">"Login attempt by </span><span class="sc">%r</span><span class="st"> with password </span><span class="sc">%r</span><span class="st">"</span>,</span>
<span id="cb40-17"><a aria-hidden="true" href="#cb40-17" tabindex="-1"></a> login, password)</span>
<span id="cb40-18"><a aria-hidden="true" href="#cb40-18" tabindex="-1"></a> <span class="cf">if</span> password <span class="op">==</span> static_password:</span>
<span id="cb40-19"><a aria-hidden="true" href="#cb40-19" tabindex="-1"></a> <span class="cf">return</span> login</span>
<span id="cb40-20"><a aria-hidden="true" href="#cb40-20" tabindex="-1"></a> <span class="cf">return</span> <span class="st">""</span></span></code></pre></div>
<p>Install the python module by running the following command in the same folder as <code>setup.py</code>:</p>
<div class="sourceCode" id="cb41"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb41-1"><a href="#cb41-1"></a><span class="ex">python3</span> -m pip install .</span></code></pre></div>
<div class="sourceCode" id="cb41"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb41-1"><a aria-hidden="true" href="#cb41-1" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> pip install .</span></code></pre></div>
<p>To make use this great creation in Radicale, set the configuration option <code>type</code> in the <code>auth</code> section to <code>radicale_static_password_auth</code>:</p>
<div class="sourceCode" id="cb42"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb42-1"><a href="#cb42-1"></a><span class="kw">[auth]</span></span>
<span id="cb42-2"><a href="#cb42-2"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> radicale_static_password_auth</span></span>
<span id="cb42-3"><a href="#cb42-3"></a><span class="dt">password </span><span class="ot">=</span><span class="st"> secret</span></span></code></pre></div>
<div class="sourceCode" id="cb42"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb42-1"><a aria-hidden="true" href="#cb42-1" tabindex="-1"></a><span class="kw">[auth]</span></span>
<span id="cb42-2"><a aria-hidden="true" href="#cb42-2" tabindex="-1"></a><span class="dt">type </span><span class="ot">=</span><span class="st"> radicale_static_password_auth</span></span>
<span id="cb42-3"><a aria-hidden="true" href="#cb42-3" tabindex="-1"></a><span class="dt">password </span><span class="ot">=</span><span class="st"> secret</span></span></code></pre></div>
<p>You can uninstall the module with:</p>
<div class="sourceCode" id="cb43"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb43-1"><a href="#cb43-1"></a><span class="ex">python3</span> -m pip uninstall radicale_static_password_auth</span></code></pre></div>
<div class="sourceCode" id="cb43"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb43-1"><a aria-hidden="true" href="#cb43-1" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> pip uninstall radicale_static_password_auth</span></code></pre></div>
</section>
<section class="level4" id="documentation/plugins/authentication-plugins">
<h4>Authentication plugins <a class="headerlink" href="#documentation/plugins/authentication-plugins">&para;</a></h4>
@ -1090,14 +1217,12 @@ user2:password2
<section class="level4" id="download//pypi">
<h4>PyPI <a class="headerlink" href="#download//pypi">&para;</a></h4>
<p>Radicale is <a href="https://pypi.python.org/pypi/Radicale/">available on PyPI</a>. To install, just type as superuser:</p>
<pre><code>$ python3 -m pip install --upgrade radicale
</code></pre>
<pre><code>$ python3 -m pip install --upgrade radicale</code></pre>
</section>
<section class="level4" id="download//git-repository">
<h4>Git Repository <a class="headerlink" href="#download//git-repository">&para;</a></h4>
<p>If you want the development version of Radicale, take a look at the <a href="https://github.com/Kozea/Radicale/">git repository on GitHub</a>, or install it directly with:</p>
<pre><code>$ python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz
</code></pre>
<pre><code>$ python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz</code></pre>
<p>You can also download the content of the repository as an <a href="https://github.com/Kozea/Radicale/tarball/master">archive</a>.</p>
</section>
<section class="level4" id="download//source-packages">