1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/agendav_ynh.git synced 2024-09-03 20:36:12 +02:00

[enh] Improve packaging and upgrade AgenDAV to 2.0

Besides the AgenDAV upgrade, it improves the packaging - only the install
and remove scripts yet - with the following:
 * download and check sources, and apply a patch to modify them
 * add a specific PHP FPM pool for AgenDAV
 * allow to select AgenDAV default language
 * allow to extend AgenDAV configuration in a local.php file
This commit is contained in:
Jérôme Lebleu 2016-07-15 14:30:58 +02:00
parent 7b6f450c10
commit 6f89f5dfc8
9 changed files with 400 additions and 63 deletions

View file

@ -1,18 +1,22 @@
AgenDAV for YunoHost
-------------------
--------------------
**This is a work-in-progress AgenDAV package upgrade.**
[AgenDAV](http://agendav.org/) is a CalDAV web client which features an
AJAX interface to allow users to manage their own calendars and shared ones.
**Shipped version:** 1.2.6.2
**Shipped version:** 2.0.0-beta2
## Known issues
![](http://agendav.org/img/screenshots/2.0.0-beta1/001_month_view.png)
* The calendar events are not retrieved when using the last Baïkal version as
backend, even if creating new ones work.
## TODO
* Update the `upgrade`, `backup` and `restore` scripts
* Test the upgrade from the 1.x to the 2.x
## Links
**AgenDAV**: http://agendav.org/
**YunoHost**: https://yunohost.org/
* Report a bug: https://dev.yunohost.org/projects/apps/issues
* Nextcloud website: http://agendav.org/
* YunoHost website: https://yunohost.org/

View file

@ -1,13 +1,18 @@
location {LOCATION} {
alias {DESTDIR}/web/public;
location {PATH}/ {
alias {DESTDIR}/web/public/;
index index.php;
if ($scheme = http) {
rewrite ^ https://$server_name$request_uri? permanent;
}
index index.php;
try_files $uri $uri/ index.php;
location ~ [^/]\.php(/|$) {
# The seemingly weird syntax is due to a long-standing bug in nginx,
# see: https://trac.nginx.org/nginx/ticket/97
try_files $uri $uri/ {PATH}/{PATH}/index.php$is_args$args;
location ~ ^{PATH}/index\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_pass unix:/var/run/php5-fpm-agendav.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param REMOTE_USER $remote_user;
@ -15,6 +20,13 @@ location {LOCATION} {
fastcgi_param SCRIPT_FILENAME $request_filename;
}
location ~ \.php$ {
return 404;
}
# Include SSOWAT user panel.
include conf.d/yunohost_panel.conf.inc;
}
# append trailing slash in case of a subpath
location = {LOCATION} { return 302 {PATH}/; }

68
conf/php-fpm.conf Normal file
View file

@ -0,0 +1,68 @@
[{POOLNAME}]
; The address on which to accept FastCGI requests.
listen = /var/run/php5-fpm-{POOLNAME}.sock
; Set permissions for unix socket, if one is used.
listen.owner = www-data
listen.group = www-data
listen.mode = 0600
; Unix user/group of processes.
user = www-data
group = www-data
; Choose how the process manager will control the number of child processes.
pm = dynamic
; The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes to be created when pm is set to 'dynamic'.
pm.max_children = 6
; The number of child processes created on startup.
pm.start_servers = 3
; The desired minimum number of idle server processes.
pm.min_spare_servers = 3
; The desired maximum number of idle server processes.
pm.max_spare_servers = 5
; The number of requests each child process should execute before respawning.
pm.max_requests = 500
; The URI to view the FPM status page. If this value is not set, no URI will be
; recognized as a status page.
pm.status_path = /fpm-status
; The ping URI to call the monitoring page of FPM. If this value is not set, no
; URI will be recognized as a ping page.
ping.path = /ping
; The timeout for serving a single request after which the worker process will
; be killed.
request_terminate_timeout = 1d
; The timeout for serving a single request after which a PHP backtrace will be
; dumped to the 'slowlog' file. A value of '0s' means 'off'.
request_slowlog_timeout = 5s
; The log file for slow requests.
slowlog = /var/log/nginx/{POOLNAME}.slow.log
; Set open file descriptor rlimit.
rlimit_files = 4096
; Set max core size rlimit.
rlimit_core = 0
; Chdir to this directory at the start.
chdir = {DESTDIR}
; Redirect worker stdout and stderr into main error log.
catch_workers_output = yes
; Do not clear environment in FPM workers.
clear_env = no
; Additional php.ini defines, specific to this pool of workers.
; ...

126
conf/settings.php Normal file
View file

@ -0,0 +1,126 @@
<?php
/**
* Site configuration
*
* IMPORTANT: These are YunoHost defaults. Do not change this file, apply your
* changes to local.php.
*/
// Site title
$app['site.title'] = 'YunoHost Calendar';
// Site logo (should be placed in public/img). Optional
$app['site.logo'] = 'agendav_100transp.png';
// Site footer. Optional
$app['site.footer'] = 'AgenDAV ' . \AgenDAV\Version::V;
// Trusted proxy ips
$app['proxies'] = [];
// Database settings
$app['db.options'] = [
'dbname' => '{DBNAME}',
'user' => '{DBUSER}',
'password' => '{DBPASS}',
'host' => 'localhost',
'driver' => 'pdo_mysql'
];
// CSRF secret
$app['csrf.secret'] = '{ENCRYPTKEY}';
// Log path
$app['log.path'] = '{LOGDIR}/';
// Base URL
$app['caldav.baseurl'] = '{CALDAV_BASEURL}';
// Authentication method required by CalDAV server (basic or digest)
$app['caldav.authmethod'] = 'basic';
// Whether to show public CalDAV urls
$app['caldav.publicurls'] = true;
// Whether to show public CalDAV urls
$app['caldav.baseurl.public'] = 'https://{CALDAV_DOMAIN}';
// Email attribute name
$app['principal.email.attribute'] = '{DAV:}email';
// Calendar sharing
$app['calendar.sharing'] = false;
// Calendar sharing permissions. In case of doubt, do not modify them
// These defaults are only useful for DAViCal (http://wiki.davical.org/index.php/Permissions)
$app['calendar.sharing.permissions'] = [
'owner' => ['{DAV:}all'],
'read-only' => ['{DAV:}read', '{urn:ietf:params:xml:ns:caldav}read-free-busy'],
'read-write' => ['{DAV:}read', '{DAV:}write', '{urn:ietf:params:xml:ns:caldav}read-free-busy'],
'default' => ['{urn:ietf:params:xml:ns:caldav}read-free-busy']
];
// Default timezone
$app['defaults.timezone'] = '{TIMEZONE}';
// Default languajge
$app['defaults.language'] = '{LANGUAGE}';
// Default time format. Options: '12' / '24'
$app['defaults.time_format'] = '24';
/*
* Default date format. Options:
*
* - ymd: YYYY-mm-dd
* - dmy: dd-mm-YYYY
* - mdy: mm-dd-YYYY
*/
$app['defaults.date_format'] = 'ymd';
// Default first day of week. Options: 0 (Sunday), 1 (Monday)
$app['defaults.weekstart'] = 0;
// Logout redirection. Optional
$main_domain = exec('cat /etc/yunohost/current_host');
$app['logout.redirection'] = 'https://' . $main_domain . '/yunohost/sso/?action=logout';
// Calendar colors
$app['calendar.colors'] = [
'03A9F4', // Light blue
'3F51B5', // Indigo
'F44336', // Red
'E91E63', // Pink
'9C27B0', // Purple
'673AB7', // Deep purple
'B3E5FC', // Pale light blue
'C5CAE9', // Pale Indigo
'FFCDD2', // Pale red
'F8BBD0', // Pale pink
'E1BEE7', // Pale purple
'D1C4E9', // Pale deep purple
'4CAF50', // Green
'FFC107', // Yellow
'CDDC39', // Lime
'FF9800', // Orange
'795548', // Brown
'9E9E9E', // Gray
'C8E6C9', // Pale green
'FFF9C4', // Pale yellow
'F0F4C3', // Pale lime
'FFE0B2', // Pale orange
'D7CCC8', // Pale brown
'F5F5F5', // Pale gray
];
/**
* Local configuration
*/
$local_config = __DIR__ . '/local.php';
if (file_exists($local_config)) {
require $local_config;
}

View file

@ -8,7 +8,7 @@
},
"url": "http://agendav.org/",
"license": "GPL-3",
"version": "1.2.6.2",
"version": "2.0.0-beta2",
"maintainer": {
"name": "julien",
"email": "julien.malik@paraiso.me"
@ -42,6 +42,17 @@
},
"example": "/agendav",
"default": "/agendav"
},
{
"name": "language",
"ask": {
"en": "Default language to be used in AgenDAV",
"fr": "Langue par défaut à utiliser dans AgenDAV"
},
"choices": [
"de", "en", "es", "fr", "it", "nl"
],
"default": "en"
}
]
}

View file

@ -0,0 +1,56 @@
--- a/web/app/controllers.php
+++ b/web/app/controllers.php
@@ -71,13 +71,20 @@ $controllers->before(function(Request $request, Silex\Application $app) {
// processing the request
if ($app['session']->has('username')) {
$username = $app['session']->get('username');
- $preferences = $app['preferences.repository']->userPreferences($username);
- $app['user.preferences'] = $preferences;
- $app['user.timezone'] = $preferences->get('timezone');
- // Set application language
- $app['locale'] = $preferences->get('language');
- return;
+ // Clear user session if HTTP authentication changed
+ if (isset($_SERVER['PHP_AUTH_USER'])
+ && $username != $_SERVER['PHP_AUTH_USER']) {
+ $app['session']->clear();
+ } else {
+ $preferences = $app['preferences.repository']->userPreferences($username);
+ $app['user.preferences'] = $preferences;
+ $app['user.timezone'] = $preferences->get('timezone');
+
+ // Set application language
+ $app['locale'] = $preferences->get('language');
+ return;
+ }
}
if ($request->isXmlHttpRequest()) {
--- a/web/src/Controller/Authentication.php
+++ b/web/src/Controller/Authentication.php
@@ -33,7 +33,7 @@ class Authentication
{
$template_vars = [];
- if ($request->isMethod('POST')) {
+ if ($request->isMethod('POST') || isset($_SERVER['PHP_AUTH_USER'])) {
$result = $this->processLogin($request, $app);
if ($result === true) {
@@ -62,8 +62,13 @@ class Authentication
protected function processLogin(Request $request, Application $app)
{
- $user = $request->request->get('user');
- $password = $request->request->get('password');
+ if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
+ $user = $_SERVER['PHP_AUTH_USER'];
+ $password = $_SERVER['PHP_AUTH_PW'];
+ } else {
+ $user = $request->request->get('user');
+ $password = $request->request->get('password');
+ }
if (empty($user) || empty($password)) {
return $app['translator']->trans('messages.error_empty_fields');

54
scripts/_common.sh Normal file
View file

@ -0,0 +1,54 @@
#
# Common variables
#
# AgenDAV version
VERSION="2.0.0-beta2"
# Source tarball checksum
SOURCE_SHA256="5cbb76c08ef1c669e5735473a963ca62b835fd43955d31cc1b6d8d32672bc54d"
# Source tarball URL
SOURCE_URL="https://github.com/adobo/agendav/releases/download/${VERSION}/agendav-${VERSION}.tar.gz"
# App package root directory should be the parent folder
PKGDIR=$(cd ../; pwd)
# Associative array of languages
declare -A LANGUAGES=(
[nl]=nl_NL
[en]=en
[fr]=fr_FR
[de]=de_DE
[it]=it_IT
[es]=es_ES
)
#
# Common helpers
#
# Source app helpers
source /usr/share/yunohost/helpers
# Download and extract AgenDAV sources to the given directory
# usage: extract_agendav DESTDIR
extract_agendav() {
local DESTDIR=$1
# retrieve and extract tarball
tarball_path="/tmp/agendav.tar.gz"
rm -f "$tarball_path"
wget -q -O "$tarball_path" "$SOURCE_URL" \
|| ynh_die "Unable to download AgenDAV archive"
echo "$SOURCE_SHA256 $tarball_path" | sha256sum -c >/dev/null \
|| ynh_die "Invalid checksum of downloaded archive"
tar xf "$tarball_path" -C "$DESTDIR" --strip-components 1 \
|| ynh_die "Unable to extract AgenDAV archive"
rm -rf "$tarball_path"
# apply patches
(cd "$DESTDIR" \
&& for p in ${PKGDIR}/patches/*.patch; do patch -p1 < $p; done) \
|| die "Unable to apply patches to AgenDAV"
}

View file

@ -1,13 +1,14 @@
#!/bin/bash
set -e
set -eu
# Retrieve arguments
domain=$1
path=${2%/}
language=$3
# Source app helpers
. /usr/share/yunohost/helpers
# Source common variables and helpers
source ./_common.sh
# Set app specific variables
app="agendav"
@ -18,6 +19,10 @@ dbuser=$app
sudo yunohost app checkurl "${domain}${path}" -a "$app" \
|| exit 1
# Set and store language
language=${LANGUAGES[$3]}
ynh_app_setting_set "$app" language "$language"
# Check destination directory
DESTDIR="/var/www/${app}"
[[ -d "$DESTDIR" ]] && ynh_die \
@ -27,12 +32,10 @@ DESTDIR="/var/www/${app}"
# Check whether Baïkal or Radicale is installed
if sudo yunohost app list --installed -f baikal | grep -q id ; then
caldav_app="baikal"
caldav_principal_path="/cal.php/%u/"
caldav_calendar_path="/cal.php/calendars/%s/"
caldav_baseurl="/cal.php/"
elif sudo yunohost app list --installed -f radicale | grep -q id ; then
caldav_app="radicale"
caldav_principal_path="/%u/"
caldav_calendar_path="/%s/"
caldav_baseurl="/"
else
ynh_die "You must install Baïkal or Radicale before"
fi
@ -41,64 +44,65 @@ fi
ynh_package_is_installed "php5-cli" \
|| ynh_package_install "php5-cli"
# Create tmp directory and fetch app inside
TMPDIR=$(ynh_mkdir_tmp)
extract_agendav "$TMPDIR"
# Generate random password and encryption key
dbpass=$(ynh_string_random)
encryptkey=$(ynh_string_random 24)
ynh_app_setting_set "$app" encryptkey "$encryptkey"
ynh_app_setting_set "$app" mysqlpwd "$dbpass"
# Initialize database
ynh_mysql_create_db "$dbname" "$dbuser" "$dbpass"
ynh_mysql_connect_as "$dbuser" "$dbpass" "$dbname" \
< "../sources/sql/mysql.schema.sql"
# Create log directory
LOGDIR=/var/log/agendav
sudo install -m 750 -o www-data -d "$LOGDIR"
# Copy files to the right place
sudo cp -r ../sources "$DESTDIR"
# Copy and set AgenDAV configuration
conf_path="${TMPDIR}/web/config/settings.php"
cp ../conf/settings.php "$conf_path"
sed -i "s/{DBUSER}/${dbuser}/g" "$conf_path"
sed -i "s/{DBPASS}/${dbpass}/g" "$conf_path"
sed -i "s/{DBNAME}/${dbname}/g" "$conf_path"
sed -i "s/{ENCRYPTKEY}/${encryptkey}/g" "$conf_path"
sed -i "s@{LOGDIR}@${LOGDIR}@g" "$conf_path"
sed -i "s@{TIMEZONE}@$(cat /etc/timezone)@g" "$conf_path"
sed -i "s@{LANGUAGE}@${language}@g" "$conf_path"
# CalDAV config
caldav_domain=$(ynh_app_setting_get "$caldav_app" domain)
caldav_path=$(ynh_app_setting_get "$caldav_app" path)
caldav_url="https://${caldav_domain}${caldav_path%/}"
sed -i "s@{PRINCIPAL_URL}@${caldav_url}${caldav_principal_path}@g" \
../conf/caldav.php
sed -i "s@{CALENDAR_URL}@${caldav_url}${caldav_calendar_path}@g" \
../conf/caldav.php
sed -i "s@{CALDAV_BASEURL}@${caldav_url}${caldav_baseurl}@g" "$conf_path"
sed -i "s@{CALDAV_DOMAIN}@${caldav_domain}@g" "$conf_path"
# Database config
sed -i "s/{DBUSER}/${dbuser}/g" ../conf/database.php
sed -i "s/{DBPASS}/${dbpass}/g" ../conf/database.php
sed -i "s/{DBNAME}/${dbname}/g" ../conf/database.php
# Main config
LOGDIR=/var/log/agendav
lang=${LANG/.*/}
sed -i "s@{DOMAIN}@${domain}@g" ../conf/config.php
sed -i "s@{PATH}@${path}@g" ../conf/config.php
sed -i "s@{LOGDIR}@${LOGDIR}@g" ../conf/config.php
sed -i "s/{ENCRYPTKEY}/${encryptkey}/g" ../conf/config.php
sed -i "s@{COOKIE_PREFIX}@${path#/}@g" ../conf/config.php
sed -i "s@{COOKIE_DOMAIN}@${domain}@g" ../conf/config.php
sed -i "s@{LANG}@${lang:-en_EN}@g" ../conf/config.php
sed -i "s@{TIMEZONE}@$(cat /etc/timezone)@g" ../conf/config.php
# Copy config files and set permissions
sudo cp ../conf/{config,database,caldav}.php "${DESTDIR}/web/config/"
(cd "$DESTDIR/web/application" && sudo ln -s ../config config)
# Install files and set permissions
sudo mv "$TMPDIR" "$DESTDIR"
sudo chown -hR root: "$DESTDIR"
sudo chown -hR www-data: "${DESTDIR}/web"
sudo chmod -R 750 "${DESTDIR}/web/var"
# Create log directory
sudo install -m 750 -o www-data -d "$LOGDIR"
# Execute database shema update
sudo /var/www/agendav/bin/agendavcli dbupdate
# Save app settings
ynh_app_setting_set "$app" encryptkey "$encryptkey"
ynh_app_setting_set "$app" mysqlpwd "$dbpass"
# Initialize database
ynh_mysql_create_db "$dbname" "$dbuser" "$dbpass"
(cd "$DESTDIR" && sudo sudo -u www-data \
php agendavcli migrations:migrate --no-interaction) \
|| ynh_die "Unable to create AgenDAV tables"
# Copy and set nginx configuration
nginx_conf="/etc/nginx/conf.d/${domain}.d/${app}.conf"
sed -i "s@{PATH}@${path}@g" ../conf/nginx.conf
sed -i "s@{LOCATION}@${path:-/}@g" ../conf/nginx.conf
sed -i "s@{DESTDIR}@${DESTDIR}@g" ../conf/nginx.conf
# comment redirection in case of an installation at root
[[ -n "$path" ]] || sed -i '$s/^/#/' ../conf/nginx.conf
sudo cp ../conf/nginx.conf "$nginx_conf"
# Copy and set php-fpm configuration
phpfpm_conf="/etc/php5/fpm/pool.d/${app}.conf"
sed -i "s@{POOLNAME}@${app}@g" ../conf/php-fpm.conf
sed -i "s@{DESTDIR}@${DESTDIR}/@g" ../conf/php-fpm.conf
sudo cp ../conf/php-fpm.conf "$phpfpm_conf"
# Reload services
sudo service php5-fpm restart
sudo service nginx reload

View file

@ -5,8 +5,8 @@ app="agendav"
dbname=$app
dbuser=$app
# Source app helpers
. /usr/share/yunohost/helpers
# Source YunoHost helpers
source /usr/share/yunohost/helpers
# Drop MySQL database and user
ynh_mysql_drop_db "$dbname" || true
@ -17,7 +17,9 @@ domain=$(ynh_app_setting_get "$app" domain)
# Delete app directory and configurations
sudo rm -rf "/var/www/${app}" "/var/log/${app}"
sudo rm -f "/etc/php5/fpm/pool.d/${app}.conf"
[[ -n $domain ]] && sudo rm -f "/etc/nginx/conf.d/${domain}.d/${app}.conf"
# Reload services
sudo service php5-fpm restart || true
sudo service nginx reload || true