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 AgenDAV for YunoHost
------------------- --------------------
**This is a work-in-progress AgenDAV package upgrade.**
[AgenDAV](http://agendav.org/) is a CalDAV web client which features an [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. 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 ## TODO
backend, even if creating new ones work.
* Update the `upgrade`, `backup` and `restore` scripts
* Test the upgrade from the 1.x to the 2.x
## Links ## Links
**AgenDAV**: http://agendav.org/ * Report a bug: https://dev.yunohost.org/projects/apps/issues
* Nextcloud website: http://agendav.org/
**YunoHost**: https://yunohost.org/ * YunoHost website: https://yunohost.org/

View file

@ -1,13 +1,18 @@
location {LOCATION} { location {PATH}/ {
alias {DESTDIR}/web/public; alias {DESTDIR}/web/public/;
index index.php;
if ($scheme = http) { if ($scheme = http) {
rewrite ^ https://$server_name$request_uri? permanent; rewrite ^ https://$server_name$request_uri? permanent;
} }
index index.php;
try_files $uri $uri/ index.php; # The seemingly weird syntax is due to a long-standing bug in nginx,
location ~ [^/]\.php(/|$) { # 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_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; fastcgi_index index.php;
include fastcgi_params; include fastcgi_params;
fastcgi_param REMOTE_USER $remote_user; fastcgi_param REMOTE_USER $remote_user;
@ -15,6 +20,13 @@ location {LOCATION} {
fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_param SCRIPT_FILENAME $request_filename;
} }
location ~ \.php$ {
return 404;
}
# Include SSOWAT user panel. # Include SSOWAT user panel.
include conf.d/yunohost_panel.conf.inc; 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/", "url": "http://agendav.org/",
"license": "GPL-3", "license": "GPL-3",
"version": "1.2.6.2", "version": "2.0.0-beta2",
"maintainer": { "maintainer": {
"name": "julien", "name": "julien",
"email": "julien.malik@paraiso.me" "email": "julien.malik@paraiso.me"
@ -42,6 +42,17 @@
}, },
"example": "/agendav", "example": "/agendav",
"default": "/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 #!/bin/bash
set -e set -eu
# Retrieve arguments # Retrieve arguments
domain=$1 domain=$1
path=${2%/} path=${2%/}
language=$3
# Source app helpers # Source common variables and helpers
. /usr/share/yunohost/helpers source ./_common.sh
# Set app specific variables # Set app specific variables
app="agendav" app="agendav"
@ -18,6 +19,10 @@ dbuser=$app
sudo yunohost app checkurl "${domain}${path}" -a "$app" \ sudo yunohost app checkurl "${domain}${path}" -a "$app" \
|| exit 1 || exit 1
# Set and store language
language=${LANGUAGES[$3]}
ynh_app_setting_set "$app" language "$language"
# Check destination directory # Check destination directory
DESTDIR="/var/www/${app}" DESTDIR="/var/www/${app}"
[[ -d "$DESTDIR" ]] && ynh_die \ [[ -d "$DESTDIR" ]] && ynh_die \
@ -27,12 +32,10 @@ DESTDIR="/var/www/${app}"
# Check whether Baïkal or Radicale is installed # Check whether Baïkal or Radicale is installed
if sudo yunohost app list --installed -f baikal | grep -q id ; then if sudo yunohost app list --installed -f baikal | grep -q id ; then
caldav_app="baikal" caldav_app="baikal"
caldav_principal_path="/cal.php/%u/" caldav_baseurl="/cal.php/"
caldav_calendar_path="/cal.php/calendars/%s/"
elif sudo yunohost app list --installed -f radicale | grep -q id ; then elif sudo yunohost app list --installed -f radicale | grep -q id ; then
caldav_app="radicale" caldav_app="radicale"
caldav_principal_path="/%u/" caldav_baseurl="/"
caldav_calendar_path="/%s/"
else else
ynh_die "You must install Baïkal or Radicale before" ynh_die "You must install Baïkal or Radicale before"
fi fi
@ -41,64 +44,65 @@ fi
ynh_package_is_installed "php5-cli" \ ynh_package_is_installed "php5-cli" \
|| ynh_package_install "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 # Generate random password and encryption key
dbpass=$(ynh_string_random) dbpass=$(ynh_string_random)
encryptkey=$(ynh_string_random 24) encryptkey=$(ynh_string_random 24)
ynh_app_setting_set "$app" encryptkey "$encryptkey"
ynh_app_setting_set "$app" mysqlpwd "$dbpass"
# Initialize database # Create log directory
ynh_mysql_create_db "$dbname" "$dbuser" "$dbpass" LOGDIR=/var/log/agendav
ynh_mysql_connect_as "$dbuser" "$dbpass" "$dbname" \ sudo install -m 750 -o www-data -d "$LOGDIR"
< "../sources/sql/mysql.schema.sql"
# Copy files to the right place # Copy and set AgenDAV configuration
sudo cp -r ../sources "$DESTDIR" 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 config
caldav_domain=$(ynh_app_setting_get "$caldav_app" domain) caldav_domain=$(ynh_app_setting_get "$caldav_app" domain)
caldav_path=$(ynh_app_setting_get "$caldav_app" path) caldav_path=$(ynh_app_setting_get "$caldav_app" path)
caldav_url="https://${caldav_domain}${caldav_path%/}" caldav_url="https://${caldav_domain}${caldav_path%/}"
sed -i "s@{PRINCIPAL_URL}@${caldav_url}${caldav_principal_path}@g" \ sed -i "s@{CALDAV_BASEURL}@${caldav_url}${caldav_baseurl}@g" "$conf_path"
../conf/caldav.php sed -i "s@{CALDAV_DOMAIN}@${caldav_domain}@g" "$conf_path"
sed -i "s@{CALENDAR_URL}@${caldav_url}${caldav_calendar_path}@g" \
../conf/caldav.php
# Database config # Install files and set permissions
sed -i "s/{DBUSER}/${dbuser}/g" ../conf/database.php sudo mv "$TMPDIR" "$DESTDIR"
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)
sudo chown -hR root: "$DESTDIR" sudo chown -hR root: "$DESTDIR"
sudo chown -hR www-data: "${DESTDIR}/web"
sudo chmod -R 750 "${DESTDIR}/web/var"
# Create log directory # Initialize database
sudo install -m 750 -o www-data -d "$LOGDIR" ynh_mysql_create_db "$dbname" "$dbuser" "$dbpass"
(cd "$DESTDIR" && sudo sudo -u www-data \
# Execute database shema update php agendavcli migrations:migrate --no-interaction) \
sudo /var/www/agendav/bin/agendavcli dbupdate || ynh_die "Unable to create AgenDAV tables"
# Save app settings
ynh_app_setting_set "$app" encryptkey "$encryptkey"
ynh_app_setting_set "$app" mysqlpwd "$dbpass"
# Copy and set nginx configuration # Copy and set nginx configuration
nginx_conf="/etc/nginx/conf.d/${domain}.d/${app}.conf" 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@{LOCATION}@${path:-/}@g" ../conf/nginx.conf
sed -i "s@{DESTDIR}@${DESTDIR}@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" 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 # Reload services
sudo service php5-fpm restart
sudo service nginx reload sudo service nginx reload

View file

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