diff --git a/CHANGELOG.md b/CHANGELOG.md
index 73cea4316..4d9cfca96 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,10 +16,13 @@ All notable changes to this project will be documented in this file.
- networks: Added configuration of wireless BSSID, band, and channel.
- networks: Added NetworkManager dispatcher script to configure
batman-adv mesh networking.
+- radicale: Added access rights control.
### Fixed
- Improved Dynamic DNS status message when no update needed.
- Improved Ikiwiki description.
+- Added check if a2query is installed before using it, since apache2
+ is not a dependency for Plinth.
### Changed
- Added suggested packages for ikiwiki. Removed recommends since they
diff --git a/actions/radicale b/actions/radicale
index a5f905a6b..bb9baf01b 100755
--- a/actions/radicale
+++ b/actions/radicale
@@ -22,7 +22,6 @@ Configuration helper for Radicale.
import argparse
import augeas
-import subprocess
from plinth import action_utils
@@ -38,8 +37,10 @@ def parse_arguments():
subparsers.add_parser('setup', help='Setup Radicale configuration')
subparsers.add_parser('enable', help='Enable Radicale service')
subparsers.add_parser('disable', help='Disable Radicale service')
- configure = subparsers.add_parser('configure', help='configure various options')
- configure.add_argument('--rights_type', help='Set the rights type for radicale')
+ configure = subparsers.add_parser('configure',
+ help='Configure various options')
+ configure.add_argument('--rights_type',
+ help='Set the rights type for radicale')
return parser.parse_args()
@@ -73,7 +74,6 @@ def subcommand_configure(arguments):
aug.save()
action_utils.service_restart('radicale')
- action_utils.webserver_enable('radicale-plinth')
def subcommand_enable(_):
diff --git a/plinth/modules/radicale/__init__.py b/plinth/modules/radicale/__init__.py
index 1b060b7a2..dbe495004 100644
--- a/plinth/modules/radicale/__init__.py
+++ b/plinth/modules/radicale/__init__.py
@@ -19,12 +19,14 @@
Plinth module for radicale.
"""
+import augeas
from django.utils.translation import ugettext_lazy as _
+
from plinth import actions
from plinth import action_utils
from plinth import cfg
from plinth import service as service_module
-
+from plinth.utils import format_lazy
version = 1
@@ -38,6 +40,18 @@ managed_packages = ['radicale']
title = _('Calendar and Addressbook (Radicale)')
+description = [
+ format_lazy(
+ _('Radicale is a CalDAV and CardDAV server. It allows synchronization '
+ 'and sharing of scheduling and contact data. To use Radicale, a '
+ ' supported client application '
+ 'is needed. Radicale can be accessed by any user with a {box_name} '
+ 'login.'), box_name=_(cfg.box_name)),
+]
+
+CONFIG_FILE = '/etc/radicale/config'
+
def init():
"""Initialize the radicale module."""
@@ -67,6 +81,26 @@ def disable():
actions.superuser_run('radicale', ['disable'])
+def load_augeas():
+ """Prepares the augeas."""
+ aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +
+ augeas.Augeas.NO_MODL_AUTOLOAD)
+
+ # INI file lens
+ aug.set('/augeas/load/Puppet/lens', 'Puppet.lns')
+ aug.set('/augeas/load/Puppet/incl[last() + 1]', CONFIG_FILE)
+
+ aug.load()
+ return aug
+
+
+def get_rights_value():
+ """Returns the current Rights value."""
+ aug = load_augeas()
+ value = aug.get('/files' + CONFIG_FILE + '/rights/type')
+ return value
+
+
def diagnose():
"""Run diagnostics and return the results."""
results = []
diff --git a/plinth/modules/radicale/forms.py b/plinth/modules/radicale/forms.py
index a88324bcf..404d3c632 100644
--- a/plinth/modules/radicale/forms.py
+++ b/plinth/modules/radicale/forms.py
@@ -1,10 +1,40 @@
-from plinth.forms import ServiceForm
+#
+# This file is part of Plinth.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+"""
+Forms for radicale module.
+"""
+
from django import forms
+from django.utils.translation import ugettext_lazy as _
+
+from plinth.forms import ServiceForm
+
+CHOICES = [
+ ('owner_only', _('Only the owner of a calendar/addressbook can view or '
+ 'make changes.')),
+ ('owner_write', _('Any user can view any calendar/addressbook, but only '
+ 'the owner can make changes.')),
+ ('authenticated', _('Any user can view or make changes to any '
+ 'calendar/addressbook.')),
+]
+
class RadicaleForm(ServiceForm):
"""Specialized configuration form for radicale service."""
- CHOICES = [('authenticated', 'Authenticated'),
- ('owner_only', 'Owner Only'),
- ('owner_write', 'Owner Write'), ]
- rights = forms.ChoiceField(choices=CHOICES, required=True,
- widget=forms.RadioSelect())
+ access_rights = forms.ChoiceField(choices=CHOICES, required=True,
+ widget=forms.RadioSelect())
diff --git a/plinth/modules/radicale/views.py b/plinth/modules/radicale/views.py
index a387246b8..da588689f 100644
--- a/plinth/modules/radicale/views.py
+++ b/plinth/modules/radicale/views.py
@@ -15,70 +15,40 @@
# along with this program. If not, see .
#
-import augeas
+"""
+Views for radicale module.
+"""
from django.contrib import messages
from django.utils.translation import ugettext_lazy as _
-from plinth.views import ServiceView
-from plinth import cfg
-from plinth.utils import format_lazy
from plinth import actions
+from plinth.views import ServiceView
+from . import description, get_rights_value, managed_services
from .forms import RadicaleForm
-CONFIG_FILE = '/etc/radicale/config'
-DEFAULT_FILE = '/etc/default/radicale'
-
-description = [
- format_lazy(
- _('Radicale is a CalDAV and CardDAV server. It allows synchronization '
- 'and sharing of scheduling and contact data. To use Radicale, a '
- ' supported client application '
- 'is needed. Radicale can be accessed by any user with a {box_name} '
- 'login.'), box_name=_(cfg.box_name)),
-]
-
-
-def load_augeas():
- """Prepares the augeas"""
- aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +
- augeas.Augeas.NO_MODL_AUTOLOAD)
- aug.set('/augeas/load/Shellvars/lens', 'Shellvars.lns')
- aug.set('/augeas/load/Shellvars/incl[last() + 1]', DEFAULT_FILE)
-
- # INI file lens
- aug.set('/augeas/load/Puppet/lens', 'Puppet.lns')
- aug.set('/augeas/load/Puppet/incl[last() + 1]', CONFIG_FILE)
- aug.load()
- return aug
-
-
-def get_rights_value():
- """Returns the current Rights value"""
- aug = load_augeas()
- value = aug.get('/files' + CONFIG_FILE + '/rights/type')
- return value
-
class RadicaleServiceView(ServiceView):
"""A specialized view for configuring radicale service."""
- service_id = 'radicale'
+ service_id = managed_services[0]
form_class = RadicaleForm
diagnostics_module_name = 'radicale'
description = description
def get_initial(self):
- """Return the values to fill in the form"""
+ """Return the values to fill in the form."""
initial = super().get_initial()
- initial['rights'] = get_rights_value()
+ initial['access_rights'] = get_rights_value()
return initial
def form_valid(self, form):
"""Change the access control of Radicale service."""
data = form.cleaned_data
- if get_rights_value() != data['rights']:
- actions.superuser_run('radicale', ['configure', '--rights_type', data['rights']])
- messages.success(self.request, _('Status Changed'))
+ if get_rights_value() != data['access_rights']:
+ actions.superuser_run(
+ 'radicale',
+ ['configure', '--rights_type', data['access_rights']])
+ messages.success(self.request,
+ _('Access rights configuration updated'))
return super().form_valid(form)