radicale: [NEW] Python-based CalDAV/CardDAV Server
Inspired by OpenWrt Ticket System Ticket 9119 Python3 package currently marked as @BROKEN because no time for testing. Signed-off-by: Christian Schoenebeck <christian.schoenebeck@gmail.com>
This commit is contained in:
parent
3828a7096d
commit
f98dbf5aab
9 changed files with 728 additions and 0 deletions
138
net/radicale/Makefile
Normal file
138
net/radicale/Makefile
Normal file
|
@ -0,0 +1,138 @@
|
|||
#
|
||||
# Copyright (C) 2008-2015 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=radicale
|
||||
PKG_VERSION:=0.10
|
||||
PKG_RELEASE:=1
|
||||
PKG_MAINTAINER:=Christian Schoenebeck <chris5560@web.de>
|
||||
|
||||
PKG_LICENSE:=GPL-3.0
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
|
||||
PKG_SOURCE:=Radicale-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=http://pypi.python.org/packages/source/R/Radicale/
|
||||
PKG_MD5SUM:=32655d8893962956ead0ad690cca6044
|
||||
|
||||
# needed for "r"adicale <-> "R"adicale
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/Radicale-$(PKG_VERSION)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
# no default dependencies
|
||||
PKG_DEFAULT_DEPENDS=
|
||||
|
||||
define Package/$(PKG_NAME)/Default
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=Web Servers/Proxies
|
||||
URL:=http://radicale.org/
|
||||
PKGARCH:=all
|
||||
USERID:=radicale=5232:radicale=5232
|
||||
endef
|
||||
define Package/$(PKG_NAME)-py2
|
||||
$(call Package/$(PKG_NAME)/Default)
|
||||
PYTHON_VERSION:=2.7
|
||||
TITLE:=Radicale CalDAV/CardDAV server (Python 2)
|
||||
VARIANT:=python2
|
||||
DEPENDS:=+python-logging +python-openssl +python-xml +python-codecs
|
||||
endef
|
||||
define Package/$(PKG_NAME)-py3
|
||||
$(call Package/$(PKG_NAME)/Default)
|
||||
PYTHON_VERSION:=3.4
|
||||
TITLE:=Radicale CalDAV/CardDAV server (Python 3)
|
||||
VARIANT:=python3
|
||||
DEPENDS:=+python3-logging +python3-openssl +python3-xml +python3-codecs +python3-email @BROKEN
|
||||
endef
|
||||
|
||||
# shown in LuCI package description
|
||||
define Package/$(PKG_NAME)-py2/description
|
||||
Radicale CalDAV/CardDAV server (Python 2) - Homepage: http://radicale.org/
|
||||
endef
|
||||
define Package/$(PKG_NAME)-py3/description
|
||||
Radicale CalDAV/CardDAV server (Python 3) - Homepage: http://radicale.org/
|
||||
endef
|
||||
|
||||
# shown in make menuconfig <Help>
|
||||
define Package/$(PKG_NAME)-py2/config
|
||||
help
|
||||
The Radicale Project is a CalDAV (calendar) and CardDAV (contact) server.
|
||||
It aims to be a light solution, easy to use, easy to install, easy to configure.
|
||||
As a consequence, it requires few software dependances and is pre-configured to work out-of-the-box.
|
||||
!!! Will install and use Python $(PYTHON_VERSION) !!!
|
||||
.
|
||||
Version : $(PKG_VERSION)
|
||||
Homepage: http://radicale.org/
|
||||
.
|
||||
$(PKG_MAINTAINER)
|
||||
endef
|
||||
Package/$(PKG_NAME)-py3/config = $(Package/$(PKG_NAME)-py2/config)
|
||||
|
||||
define Package/$(PKG_NAME)-py2/conffiles
|
||||
/etc/config/radicale
|
||||
/etc/radicale/users
|
||||
/etc/radicale/rights
|
||||
endef
|
||||
Package/$(PKG_NAME)-py3/conffiles = $(Package/$(PKG_NAME)-py2/conffiles)
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)-py2/preinst
|
||||
#!/bin/sh
|
||||
[ -n "$${IPKG_INSTROOT}" ] && exit 0 # if run within buildroot exit
|
||||
|
||||
# stop service if PKG_UPGRADE
|
||||
[ "$${PKG_UPGRADE}" = "1" ] && /etc/init.d/$(PKG_NAME) stop >/dev/null 2>&1
|
||||
|
||||
exit 0 # supress errors from stop command
|
||||
endef
|
||||
define Package/$(PKG_NAME)-py3/preinst
|
||||
$(call Package/$(PKG_NAME)-py2/preinst)
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)-py2/install
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/radicale.init $(1)/etc/init.d/radicale
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
|
||||
$(INSTALL_BIN) ./files/radicale.hotplug $(1)/etc/hotplug.d/iface/80-radicale
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) ./files/radicale.config $(1)/etc/config/radicale
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/radicale/ssl
|
||||
$(INSTALL_DATA) ./files/config.template $(1)/etc/radicale/
|
||||
$(INSTALL_DATA) ./files/logging.template $(1)/etc/radicale/
|
||||
$(INSTALL_DATA) ./files/radicale.users $(1)/etc/radicale/users
|
||||
$(INSTALL_DATA) ./files/radicale.rights $(1)/etc/radicale/rights
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/lib/python$(PYTHON_VERSION)/site-packages/radicale
|
||||
$(CP) \
|
||||
$(PKG_BUILD_DIR)/radicale/* \
|
||||
$(1)/usr/lib/python$(PYTHON_VERSION)/site-packages/radicale
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/radicale $(1)/usr/bin/
|
||||
endef
|
||||
define Package/$(PKG_NAME)-py3/install
|
||||
$(call Package/$(PKG_NAME)-py2/install, $(1))
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)-py2/postinst
|
||||
#!/bin/sh
|
||||
# patch /usr/bin/radicale force run using python2
|
||||
/bin/sed -i 's/python/python2/' $${IPKG_INSTROOT}/usr/bin/radicale
|
||||
endef
|
||||
define Package/$(PKG_NAME)-py3/postinst
|
||||
#!/bin/sh
|
||||
# patch /usr/bin/radicale force run using python3
|
||||
/bin/sed -i 's/python/python3/' $${IPKG_INSTROOT}/usr/bin/radicale
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)-py2))
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)-py3))
|
30
net/radicale/files/config.template
Normal file
30
net/radicale/files/config.template
Normal file
|
@ -0,0 +1,30 @@
|
|||
# -*- mode: conf -*-
|
||||
# vim:ft=cfg
|
||||
|
||||
### AUTO-GENERATED CONFIGURATION
|
||||
### USED BY RADICALE
|
||||
### DO NOT EDIT
|
||||
### SEE /etc/config/radicale INSTEAD
|
||||
|
||||
[server]
|
||||
# daemon # handled by /etc/init.d/radicale
|
||||
# pid # handled by /etc/init.d/radicale
|
||||
|
||||
[encoding]
|
||||
|
||||
[well-known]
|
||||
|
||||
[auth]
|
||||
# htpasswd_filename # hard-coded /etc/radicale/users
|
||||
|
||||
[git]
|
||||
|
||||
[rights]
|
||||
# file # hard-coded /etc/radicale/rights
|
||||
|
||||
[storage]
|
||||
|
||||
[logging]
|
||||
# config # hard-coded /var/etc/radicale/logging
|
||||
|
||||
[headers]
|
47
net/radicale/files/logging.template
Normal file
47
net/radicale/files/logging.template
Normal file
|
@ -0,0 +1,47 @@
|
|||
# -*- mode: conf -*-
|
||||
# vim:ft=cfg
|
||||
|
||||
### AUTO-GENERATED CONFIGURATION
|
||||
### USED BY RADICALE
|
||||
### DO NOT EDIT
|
||||
### SEE /etc/config/radicale INSTEAD
|
||||
|
||||
[loggers]
|
||||
keys = root
|
||||
|
||||
[handlers]
|
||||
keys = console,file,syslog
|
||||
|
||||
[formatters]
|
||||
keys = simple,full,syslog
|
||||
|
||||
[logger_root]
|
||||
level = DEBUG
|
||||
handlers = console,file,syslog
|
||||
|
||||
[handler_console]
|
||||
class = StreamHandler
|
||||
args = (sys.stdout,)
|
||||
formatter = simple
|
||||
# level = WARNING # set via /etc/config/radicale
|
||||
|
||||
[handler_file]
|
||||
class = handlers.RotatingFileHandler
|
||||
formatter = full
|
||||
# level = INFO # set via /etc/config/radicale
|
||||
# args = ('[filename]','a',[maxbytes],[backupcount]) # set via /etc/config/radicale
|
||||
|
||||
[handler_syslog]
|
||||
class = handlers.SysLogHandler
|
||||
args = ('/dev/log', handlers.SysLogHandler.LOG_DAEMON)
|
||||
formatter = syslog
|
||||
# level = WARNING # set via /etc/config/radicale
|
||||
|
||||
[formatter_simple]
|
||||
format = %(message)s
|
||||
|
||||
[formatter_full]
|
||||
format = %(asctime)s - %(levelname)s: %(message)s
|
||||
|
||||
[formatter_syslog]
|
||||
format = radicale [%(process)d]: %(message)s
|
192
net/radicale/files/radicale.config
Normal file
192
net/radicale/files/radicale.config
Normal file
|
@ -0,0 +1,192 @@
|
|||
#
|
||||
# You find additional information on Radicale Homepage
|
||||
# http://radicale.org
|
||||
#
|
||||
# OpenWrt's wiki needs to be setup/updated ;-)
|
||||
#
|
||||
# if setting additional options please remember that UCI does not support
|
||||
# section names and option names with "-" (Dash) inside their name
|
||||
# to use them anyway replace "-" with "_" (Underscore)
|
||||
# Each Radicale's config [section] is setup as UCI config setting 'section'
|
||||
#
|
||||
|
||||
####################################################
|
||||
# Server options
|
||||
#
|
||||
config setting 'server'
|
||||
|
||||
# hostname:port
|
||||
# IPv4 syntax: address:port
|
||||
# IPv6 syntax: [address]:port
|
||||
# ATTENTION:
|
||||
# only use ports > 1024 (non-privileged Ports)
|
||||
# because this implementation is running as non-root user
|
||||
# Default: 0.0.0.0:5232
|
||||
# list hosts '0.0.0.0:5232'
|
||||
# list hosts 'localhost:5232'
|
||||
|
||||
# SSL flag, enable HTTPS protocol
|
||||
# Default: 0 (disabled)
|
||||
# option ssl '1'
|
||||
|
||||
# SSL Protocol used. See python's ssl module for available values
|
||||
# Default: PROTOCOL_SSLv23
|
||||
# option protocol 'PROTOCOL_SSLv23'
|
||||
|
||||
# Ciphers available. See python's ssl module for available ciphers
|
||||
# option ciphers ''
|
||||
|
||||
# SSL certificate path and file
|
||||
# option certificate '/etc/radicale/ssl/server.crt'
|
||||
|
||||
# SSL private key path and file
|
||||
# option key '/etc/radicale/ssl/server.key'
|
||||
|
||||
# Reverse DNS to resolve client address in logs
|
||||
# Default: 0 (disabled)
|
||||
# option dns_lookup '1'
|
||||
|
||||
# Message displayed in the client when a password is needed
|
||||
# option realm 'Radicale - Password Required'
|
||||
|
||||
|
||||
####################################################
|
||||
# Encoding options
|
||||
#
|
||||
config setting 'encoding'
|
||||
|
||||
# Encoding for responding requests
|
||||
# option request 'utf-8'
|
||||
|
||||
# Encoding for storing local collections
|
||||
# option stock 'utf-8'
|
||||
|
||||
|
||||
####################################################
|
||||
# Authentication options
|
||||
#
|
||||
config setting 'auth'
|
||||
|
||||
# Authentication method
|
||||
# Value: None | htpasswd | IMAP | LDAP | PAM | courier | http | remote_user | custom
|
||||
# Default: None
|
||||
# if setting 'htpasswd' the file /etc/radicale/users is used (hardcoded)
|
||||
# option type 'htpasswd'
|
||||
|
||||
# Htpasswd encryption method
|
||||
# Value: plain | sha1 | ssha | crypt
|
||||
# option htpasswd_encryption 'crypt'
|
||||
|
||||
# for other authenication methods consult Radicale documentation
|
||||
# and set options here
|
||||
|
||||
|
||||
####################################################
|
||||
# Git default options
|
||||
#
|
||||
config setting 'git'
|
||||
|
||||
# Git default options
|
||||
# option committer 'Radicale <radicale@example.com>'
|
||||
|
||||
|
||||
####################################################
|
||||
# Rights backend
|
||||
#
|
||||
config setting 'rights'
|
||||
|
||||
# Value: None | authenticated | owner_only | owner_write | from_file | custom
|
||||
# Default: None
|
||||
# if setting 'from_file' the file /etc/radicale/rights is used (hardcoded)
|
||||
# option type 'from_file'
|
||||
|
||||
# Custom rights handler
|
||||
# option custom_handler ''
|
||||
|
||||
|
||||
####################################################
|
||||
# Storage backend
|
||||
# -------
|
||||
# WARNING: ONLY "filesystem" IS DOCUMENTED AND TESTED,
|
||||
# OTHER BACKENDS ARE NOT READY FOR PRODUCTION.
|
||||
# -------
|
||||
#
|
||||
config setting 'storage'
|
||||
# Value: filesystem | multifilesystem | database | custom
|
||||
option type 'filesystem'
|
||||
option filesystem_folder '/srv/radicale'
|
||||
|
||||
|
||||
####################################################
|
||||
# Additional HTTP headers
|
||||
#
|
||||
config setting 'headers'
|
||||
# enable all if using CardDavMATE-, CalDavZAP- or InfCloud- WEBclient
|
||||
# list Access_Control_Allow_Origin '*'
|
||||
# list Access_Control_Allow_Methods 'GET'
|
||||
# list Access_Control_Allow_Methods 'POST'
|
||||
# list Access_Control_Allow_Methods 'OPTIONS'
|
||||
# list Access_Control_Allow_Methods 'PROPFIND'
|
||||
# list Access_Control_Allow_Methods 'PROPPATCH'
|
||||
# list Access_Control_Allow_Methods 'REPORT'
|
||||
# list Access_Control_Allow_Methods 'PUT'
|
||||
# list Access_Control_Allow_Methods 'MOVE'
|
||||
# list Access_Control_Allow_Methods 'DELETE'
|
||||
# list Access_Control_Allow_Methods 'LOCK'
|
||||
# list Access_Control_Allow_Methods 'UNLOCK'
|
||||
# list Access_Control_Allow_Headers 'User-Agent'
|
||||
# list Access_Control_Allow_Headers 'Authorization'
|
||||
# list Access_Control_Allow_Headers 'Content-type'
|
||||
# list Access_Control_Allow_Headers 'Depth'
|
||||
# list Access_Control_Allow_Headers 'If-match'
|
||||
# list Access_Control_Allow_Headers 'If-None-Match'
|
||||
# list Access_Control_Allow_Headers 'Lock-Token'
|
||||
# list Access_Control_Allow_Headers 'Timeout'
|
||||
# list Access_Control_Allow_Headers 'Destination'
|
||||
# list Access_Control_Allow_Headers 'Overwrite'
|
||||
# list Access_Control_Allow_Headers 'X-client'
|
||||
# list Access_Control_Allow_Headers 'X-Requested-With'
|
||||
# list Access_Control_Expose_Headers 'Etag'
|
||||
|
||||
|
||||
####################################################
|
||||
# Global logging options
|
||||
#
|
||||
config setting 'logging'
|
||||
|
||||
# Set the default logging level to debug for all outputs (ignore output level settings)
|
||||
# Default: 0 (disabled)
|
||||
# option debug '1'
|
||||
# Log all environment variables (including those set in the shell) when starting
|
||||
# Default: 0 (disabled)
|
||||
# option full_environment '1'
|
||||
|
||||
|
||||
####################################################
|
||||
# Spezial logging options
|
||||
# !!! not documented in Radicale documentation
|
||||
# !!! special settings for this implementation
|
||||
#
|
||||
config logging 'logger'
|
||||
|
||||
# Level: DEBUG | INFO | WARNING | ERROR | CRITICAL
|
||||
# To nearly disable logging set level to critical
|
||||
|
||||
# log level on console
|
||||
# option console_level 'ERROR'
|
||||
|
||||
# Here we use Rotating Logfiles in this implementation
|
||||
# !!! if maxbytes and/or backupcount is set to 0 !!!
|
||||
# !!! file rotation is disabled and logfile grows endless !!!
|
||||
# log level
|
||||
# option file_level 'INFO'
|
||||
# directory where log files are written
|
||||
# option file_path '/var/log/radicale'
|
||||
# max size of each logfile (see warning above)
|
||||
# option file_maxbytes '8196'
|
||||
# number of backup files to create (see warning above)
|
||||
# option file_backupcount '1'
|
||||
|
||||
# log level for syslog logging
|
||||
# option syslog_level 'WARNING'
|
||||
|
16
net/radicale/files/radicale.hotplug
Normal file
16
net/radicale/files/radicale.hotplug
Normal file
|
@ -0,0 +1,16 @@
|
|||
#!/bin/sh
|
||||
|
||||
# only (re-)start on ifup
|
||||
[ "$ACTION" = "ifup" ] || exit 0
|
||||
|
||||
_PID=$(ps | grep '[p]ython.*[r]adicale' 2>/dev/null | awk '{print \$1}')
|
||||
kill -1 $_PID 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# only restart if already running
|
||||
logger -p user.info -t "radicale[$_PID]" \
|
||||
"Restart request due to '$ACTION' of interface '$INTERFACE'"
|
||||
/etc/init.d/radicale restart
|
||||
else
|
||||
# only start if enabled
|
||||
/etc/init.d/radicale enabled && /etc/init.d/radicale start
|
||||
fi
|
220
net/radicale/files/radicale.init
Executable file
220
net/radicale/files/radicale.init
Executable file
|
@ -0,0 +1,220 @@
|
|||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2006-2015 OpenWrt.org
|
||||
|
||||
START=80
|
||||
STOP=10
|
||||
|
||||
CFGDIR=/var/etc/radicale
|
||||
SYSCFG=$CFGDIR/config
|
||||
LOGCFG=$CFGDIR/logging
|
||||
|
||||
DATADIR="/srv/radicale"
|
||||
LOGDIR=""
|
||||
|
||||
PGREP="ps | grep '[p]ython.*[r]adicale' 2>/dev/null | awk '{print \$1}' "
|
||||
|
||||
# we could start with empty configuration file using defaults
|
||||
[ -f /etc/config/radicale ] || touch /etc/config/radicale
|
||||
|
||||
_uci2radicale() {
|
||||
local _SYSTMP="$SYSCFG.tmp"
|
||||
local _LOGTMP="$LOGCFG.tmp"
|
||||
local _LOPT # list option name
|
||||
local _LVAL # list option value
|
||||
local _STYPE # section type
|
||||
local _SNAME # section name
|
||||
local _console_level="ERROR" # logging console level
|
||||
local _file_level="INFO" # logging file level
|
||||
local _file_path="/var/log/radicale" # logging file path
|
||||
local _file_maxbytes="8196" # logging file maxBytes
|
||||
local _file_backupcount="1" # logging file backupCount
|
||||
local _syslog_level="WARNING" # logging syslog level
|
||||
|
||||
# write list values to config
|
||||
_write_list() {
|
||||
_write_value "$_LOPT" "$_LVAL" # there might be spaces in _LVAL
|
||||
_LOPT=""
|
||||
_LVAL=""
|
||||
}
|
||||
|
||||
_write_value() {
|
||||
# $1 option
|
||||
# $2 value
|
||||
local __OPT=$1
|
||||
local __VAL=$2
|
||||
# section "server" ignore option "daemon" and "pid"
|
||||
[ "$_SNAME" = "server" -a "$__OPT" = "daemon" ] && return 0
|
||||
[ "$_SNAME" = "server" -a "$__OPT" = "pid" ] && return 0
|
||||
# section "logging" ignore option "config" (logging config file)
|
||||
[ "$_SNAME" = "logging" -a "$__OPT" = "config" ] && return 0
|
||||
# section "auth" ignore option "htpasswd_filename" (htpasswd file)
|
||||
[ "$_SNAME" = "auth" -a "$__OPT" = "htpasswd_filename" ] && return 0
|
||||
# section "rights" ignore option "file" (reg-based rights file)
|
||||
[ "$_SNAME" = "rights" -a "$__OPT" = "file" ] && return 0
|
||||
# section "headers" replace "_" with "-" in option (UCI problem)
|
||||
[ "$_SNAME" = "headers" ] && __OPT=$(echo "$__OPT" | sed -e "s#_#-#g")
|
||||
# save data driectory
|
||||
[ "$_SNAME" = "storage" -a "$__OPT" = "filesystem_folder" ] && DATADIR="$__VAL"
|
||||
# special handling for well-known, value needs single quotes
|
||||
[ "$_SNAME" = "well-known" -a "${__VAL#*\%\(}" != "$__VAL" ] && __VAL="'$__VAL'"
|
||||
# handling of log settings
|
||||
if [ "$_STYPE" = "logging" -a "$_SNAME" = "logger" ]; then
|
||||
eval "_$__OPT='$__VAL'" # set to environment for later use
|
||||
else
|
||||
# handle bool
|
||||
[ "$__VAL" = "0" ] && __VAL="False"
|
||||
[ "$__VAL" = "1" ] && __VAL="True"
|
||||
# append data to the corresponding section
|
||||
sed -i "/\[$_SNAME\]/a $__OPT = $__VAL" $_SYSTMP
|
||||
fi
|
||||
}
|
||||
|
||||
# redefined callback for sections when calling config_load
|
||||
config_cb() {
|
||||
# $1 "Type"
|
||||
# $2 "Name"
|
||||
# write out last list option
|
||||
[ -n "$_LOPT" ] && _write_list
|
||||
# mark invalid
|
||||
_STYPE=""
|
||||
_SNAME=""
|
||||
# check section type
|
||||
[ "$1" = "setting" -o "$1" = "logging" ] && {
|
||||
_STYPE="$1"
|
||||
_SNAME="$2"
|
||||
}
|
||||
# translate section name
|
||||
[ "$2" = "well_known" ] && _SNAME="well-known"
|
||||
return 0
|
||||
}
|
||||
|
||||
# redefined callback for lists when calling config_load
|
||||
list_cb() {
|
||||
# $1 name of variable
|
||||
# $2 value
|
||||
# invalid section type then ignore
|
||||
[ -z "$_STYPE" -o -z "$_SNAME" ] && return 0
|
||||
# write out last list option if new list starts
|
||||
[ -n "$_LOPT" -a "$_LOPT" != "$1" ] && _write_list
|
||||
# new list option
|
||||
if [ -z "$_LOPT" ]; then
|
||||
_LOPT="$1"
|
||||
_LVAL="$2"
|
||||
else
|
||||
_LVAL="$_LVAL, $2"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# redefined callback for options when calling config_load
|
||||
option_cb() {
|
||||
# $1 name of variable
|
||||
# $2 value
|
||||
local __OPT="$1"
|
||||
local __VAL="$2"
|
||||
# invalid section type then ignore
|
||||
[ -z "$_STYPE" -o -z "$_SNAME" ] && return 0
|
||||
# ignore list entrys will be handled by list_cb()
|
||||
[ "${__OPT#*_ITEM}" != "$__OPT" ] && return 0 # ignore lists *_ITEM*
|
||||
[ "${__OPT#*_LENGTH}" != "$__OPT" ] && return 0 # ignore lists *_LENGTH
|
||||
# write out last list option and clear
|
||||
[ -n "$_LOPT" ] && _write_list
|
||||
# write to file
|
||||
_write_value "$__OPT" "$__VAL" # there might be spaces in __VAL
|
||||
return 0
|
||||
}
|
||||
|
||||
# temporary config file
|
||||
# radicale need read access
|
||||
mkdir -m0755 -p $CFGDIR
|
||||
|
||||
cp /etc/radicale/config.template $_SYSTMP
|
||||
config_load radicale # calling above config_cb()/option_cb()/list_cb() and write into $_SYSTMP
|
||||
sed -i "/\[logging\]/a config = /var/etc/radicale/logging" $_SYSTMP # hard-code logging config
|
||||
sed -i "/\[auth\]/a htpasswd_filename = /etc/radicale/users" $_SYSTMP # hard-code htpasswd
|
||||
sed -i "/\[rights\]/a file = /etc/radicale/rights" $_SYSTMP # hard-code regexp-based rights
|
||||
|
||||
# temporary logging config file
|
||||
cp /etc/radicale/logging.template $_LOGTMP
|
||||
LOGDIR="$_file_path"
|
||||
sed -i "/\[handler_console\]/a level = $_console_level" $_LOGTMP
|
||||
sed -i "/\[handler_file\]/a level = $_file_level" $_LOGTMP
|
||||
sed -i "/\[handler_file\]/a args = ('$_file_path/radicale','a',$_file_maxbytes,$_file_backupcount)" $_LOGTMP
|
||||
sed -i "/\[handler_syslog\]/a level = $_syslog_level" $_LOGTMP
|
||||
|
||||
# move tmp to final
|
||||
mv -f $_SYSTMP $SYSCFG
|
||||
mv -f $_LOGTMP $LOGCFG
|
||||
}
|
||||
|
||||
_set_permission() {
|
||||
# config file permissions (read access for group)
|
||||
chmod 644 $SYSCFG $LOGCFG
|
||||
chgrp -R radicale $CFGDIR
|
||||
# log directory (full access and owner)
|
||||
[ -d $LOGDIR ] || mkdir -m0755 -p $LOGDIR
|
||||
chown -R radicale:radicale $LOGDIR
|
||||
# data directory does not exist
|
||||
[ -d $DATADIR ] || {
|
||||
logger -p user.error -t "radicale[----]" "Data directory '$DATADIR' does not exists. Startup failed !!!"
|
||||
exit 1
|
||||
}
|
||||
chgrp -R radicale $DATADIR
|
||||
}
|
||||
|
||||
boot() {
|
||||
return 0 # will be started by "iface" hotplug events
|
||||
}
|
||||
|
||||
start() {
|
||||
_running() {
|
||||
sleep 2 # give radicale time to completely come up
|
||||
local _PID=$(eval "$PGREP")
|
||||
kill -1 $_PID 2>/dev/null
|
||||
[ $? -eq 0 ] \
|
||||
&& logger -p user.notice -t "radicale[$_PID]" "Service started successfully"\
|
||||
|| logger -p user.warn -t "radicale[----]" "Service failed to start"
|
||||
}
|
||||
|
||||
# if already running do nothing
|
||||
local _PID=$(eval "$PGREP")
|
||||
kill -1 $_PID 2>/dev/null && return 0
|
||||
|
||||
_uci2radicale
|
||||
_set_permission
|
||||
|
||||
radicale --daemon --config=$SYSCFG
|
||||
|
||||
_running & # check if running and syslog
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
reload() {
|
||||
# reload is also used by luci
|
||||
local _PID=$(eval "$PGREP")
|
||||
kill -1 $_PID 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# only restart if already running
|
||||
restart
|
||||
else
|
||||
# only start if enabled
|
||||
enabled && start
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
stop() {
|
||||
local _PID=$(eval "$PGREP")
|
||||
[ -z "$_PID" ] && return 0 # not running
|
||||
kill -15 $_PID 2>/dev/null
|
||||
sleep 1 # give time to shutdown
|
||||
local _tmp=$(eval "$PGREP")
|
||||
if [ -z "$_tmp" ]; then
|
||||
logger -p user.notice -t "radicale[$_PID]" "Service shutdown successfully"
|
||||
else
|
||||
kill -9 $_tmp # Normally never come here
|
||||
logger -p user.warn -t "radicale[----]" "Service shutdown FORCED"
|
||||
fi
|
||||
return 0
|
||||
}
|
49
net/radicale/files/radicale.rights
Normal file
49
net/radicale/files/radicale.rights
Normal file
|
@ -0,0 +1,49 @@
|
|||
#
|
||||
# Authentication login is matched against the "user" key, and collection's path is matched against the "collection" key.
|
||||
# You can use Python's ConfigParser interpolation values %(login)s and %(path)s.
|
||||
# You can also get groups from the user regex in the collection with {0}, {1}, etc.
|
||||
#
|
||||
# For example, for the "user" key, ".+" means "authenticated user" and ".*" means "anybody" (including anonymous users).
|
||||
#
|
||||
# Section names are only used for naming the rule.
|
||||
# Leading or ending slashes are trimmed from collection's path.
|
||||
#
|
||||
|
||||
# This means all users starting with "admin" may read any collection
|
||||
[admin]
|
||||
user: ^admin.*$
|
||||
collection: .*
|
||||
permission: r
|
||||
|
||||
# This means all users may read and write any collection starting with public.
|
||||
# We do so by just not testing against the user string.
|
||||
[public]
|
||||
user: .*
|
||||
collection: ^public(/.+)?$
|
||||
permission: rw
|
||||
|
||||
# A little more complex: give read access to users from a domain for all
|
||||
# collections of all the users (ie. user@domain.tld can read domain/\*).
|
||||
[domain-wide-access]
|
||||
user: ^.+@(.+)\..+$
|
||||
collection: ^{0}/.+$
|
||||
permission: r
|
||||
|
||||
# Allow authenticated user to read all collections
|
||||
[allow-everyone-read]
|
||||
user: .+
|
||||
collection: .*
|
||||
permission: r
|
||||
|
||||
# Give write access to owners
|
||||
[owner-write]
|
||||
user: .+
|
||||
collection: ^%(login)s(/.+)?$
|
||||
permission: rw
|
||||
|
||||
# Allow CardDavMATE-, CalDavZAP- or InfCloud- WEBclient to work
|
||||
# anonymous users have read access to "/" but no files or subdir
|
||||
[infcloud]
|
||||
user: .*
|
||||
collection: /
|
||||
permission: r
|
6
net/radicale/files/radicale.users
Normal file
6
net/radicale/files/radicale.users
Normal file
|
@ -0,0 +1,6 @@
|
|||
#
|
||||
# Sample File
|
||||
#
|
||||
|
||||
user1:password1
|
||||
user2:password2
|
|
@ -0,0 +1,30 @@
|
|||
Subject: [PATCH] Run as user radicale and group radicale
|
||||
|
||||
Patch to run Radicale service as radicale:radicale non root user
|
||||
|
||||
Signed-off-by: Christian Schoenebeck <christian.schoenebeck@gmail.com>
|
||||
---
|
||||
bin/radicale | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/bin/radicale b/bin/radicale
|
||||
index 619aca5..7466020 100755
|
||||
--- a/bin/radicale
|
||||
+++ b/bin/radicale
|
||||
@@ -26,6 +26,13 @@ Launch the server according to configuration and command-line options.
|
||||
|
||||
"""
|
||||
|
||||
+# inserted to run as user radicale
|
||||
+import pwd, grp, os
|
||||
+uid = pwd.getpwnam('radicale').pw_uid
|
||||
+gid = grp.getgrnam('radicale').gr_gid
|
||||
+os.setegid(gid)
|
||||
+os.seteuid(uid)
|
||||
+
|
||||
import radicale.__main__
|
||||
|
||||
|
||||
--
|
||||
2.1.0
|
||||
|
Loading…
Reference in a new issue