diff --git a/check_process b/check_process index d67ff3a..6bff7bc 100644 --- a/check_process +++ b/check_process @@ -14,11 +14,12 @@ setup_private=1 setup_public=1 upgrade=1 + upgrade=1 from_commit=cbb74263e33deb0ec36f99886a2f773e36d40fd9 backup_restore=1 multi_instance=1 incorrect_path=1 port_already_use=0 - change_url=0 + change_url=1 ;; Test avec multisite ; Manifest domain="domain.tld" (DOMAIN) @@ -45,8 +46,7 @@ Level 3=auto # Level 4: https://github.com/YunoHost-Apps/wordpress_ynh/blob/master/conf/sql/single.sql#L1 Level 4=1 -# Level 5: https://github.com/YunoHost-Apps/wordpress_ynh/issues/18 - Level 5=1 + Level 5=auto Level 6=auto Level 7=auto Level 8=0 @@ -55,3 +55,7 @@ ;;; Options Email= Notification=down +;;; Upgrade options + ; commit=cbb74263e33deb0ec36f99886a2f773e36d40fd9 + name=Upgrade 4.8 + manifest_arg=domain=DOMAIN&path=PATH&admin=USER&language=fr_FR&multisite=0&is_public=1& diff --git a/conf/app.src b/conf/app.src index 96acb1a..65d03a1 100644 --- a/conf/app.src +++ b/conf/app.src @@ -1,5 +1,5 @@ -SOURCE_URL=https://wordpress.org/wordpress-4.8.tar.gz -SOURCE_SUM=b91248a7220a7fb1ca293c3a0ec8db6c +SOURCE_URL=https://wordpress.org/wordpress-4.9.1.tar.gz +SOURCE_SUM=111ecbfc98633103e1fc1105c0c00c76 SOURCE_SUM_PRG=md5sum ARCH_FORMAT=tar.gz SOURCE_IN_SUBDIR=true diff --git a/conf/nginx.conf b/conf/nginx.conf index dadaea1..645b563 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -4,7 +4,8 @@ #--MULTISITE--rewrite ^__PATH__(/[^/]+)?(/.*\.php)$ __PATH__$2 last; #--MULTISITE--} -location __PATH__ { +#sub_path_only rewrite ^__PATH__$ __PATH__/ permanent; +location __PATH__/ { alias __FINALPATH__/; index index.php; if (!-e $request_filename) diff --git a/manifest.json b/manifest.json index 8b4408b..c9b55f2 100644 --- a/manifest.json +++ b/manifest.json @@ -6,9 +6,9 @@ "en": "Create a beautiful blog or website easily", "fr": "Logiciel de création de blog ou de site Web" }, - "version": "4.8", + "version": "4.9.1~ynh1", "url": "https://wordpress.org/", - "license": "GPLv2", + "license": "GPL-2.0", "maintainer": { "name": "Maniack Crudelis", "email": "maniackc_dev@crudelis.fr" diff --git a/scripts/_common.sh b/scripts/_common.sh index 37c4432..142d9e8 100755 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -33,3 +33,183 @@ CHECK_SIZE () { # Vérifie avant chaque backup que l'espace est suffisant ynh_die "Espace nécessaire: $(HUMAN_SIZE $backup_size)" fi } + + +#================================================= +#============= FUTURE YUNOHOST HELPER ============ +#================================================= + +# Delete a file checksum from the app settings +# +# $app should be defined when calling this helper +# +# usage: ynh_remove_file_checksum file +# | arg: file - The file for which the checksum will be deleted +ynh_delete_file_checksum () { + local checksum_setting_name=checksum_${1//[\/ ]/_} # Replace all '/' and ' ' by '_' + ynh_app_setting_delete $app $checksum_setting_name +} + + +#================================================= +# EXPERIMENTAL HELPERS +#================================================= + +# Create a dedicated fail2ban config (jail and filter conf files) +# +# usage: ynh_add_fail2ban_config log_file filter [max_retry [ports]] +# | arg: log_file - Log file to be checked by fail2ban +# | arg: failregex - Failregex to be looked for by fail2ban +# | arg: max_retry - Maximum number of retries allowed before banning IP address - default: 3 +# | arg: ports - Ports blocked for a banned IP address - default: http,https +ynh_add_fail2ban_config () { + # Process parameters + logpath=$1 + failregex=$2 + max_retry=${3:-3} + ports=${4:-http,https} + + test -n "$logpath" || ynh_die "ynh_add_fail2ban_config expects a logfile path as first argument and received nothing." + test -n "$failregex" || ynh_die "ynh_add_fail2ban_config expects a failure regex as second argument and received nothing." + + finalfail2banjailconf="/etc/fail2ban/jail.d/$app.conf" + finalfail2banfilterconf="/etc/fail2ban/filter.d/$app.conf" + ynh_backup_if_checksum_is_different "$finalfail2banjailconf" 1 + ynh_backup_if_checksum_is_different "$finalfail2banfilterconf" 1 + + sudo tee $finalfail2banjailconf <&2 + echo "WARNING${fail2ban_error#*WARNING}" >&2 + fi +} + +# Remove the dedicated fail2ban config (jail and filter conf files) +# +# usage: ynh_remove_fail2ban_config +ynh_remove_fail2ban_config () { + ynh_secure_remove "/etc/fail2ban/jail.d/$app.conf" + ynh_secure_remove "/etc/fail2ban/filter.d/$app.conf" + sudo systemctl restart fail2ban +} + +#================================================= + +# Read the value of a key in a ynh manifest file +# +# usage: ynh_read_manifest manifest key +# | arg: manifest - Path of the manifest to read +# | arg: key - Name of the key to find +ynh_read_manifest () { + manifest="$1" + key="$2" + python3 -c "import sys, json;print(json.load(open('$manifest'))['$key'])" +} + +# Exit without error if the package is up to date +# +# This helper should be used to avoid an upgrade of a package +# when it's not needed. +# +# To force an upgrade, even if the package is up to date, +# you have to set the variable YNH_FORCE_UPGRADE before. +# example: sudo YNH_FORCE_UPGRADE=1 yunohost app upgrade MyApp +# +# usage: ynh_abort_if_up_to_date +ynh_abort_if_up_to_date () { + local force_upgrade=${YNH_FORCE_UPGRADE:-0} + local package_check=${PACKAGE_CHECK_EXEC:-0} + + local version=$(ynh_read_manifest "/etc/yunohost/apps/$YNH_APP_INSTANCE_NAME/manifest.json" "version" || echo 1.0) + local last_version=$(ynh_read_manifest "../manifest.json" "version" || echo 1.0) + if [ "$version" = "$last_version" ] + then + if [ "$force_upgrade" != "0" ] + then + echo "Upgrade forced by YNH_FORCE_UPGRADE." >&2 + unset YNH_FORCE_UPGRADE + elif [ "$package_check" != "0" ] + then + echo "Upgrade forced for package check." >&2 + else + ynh_die "Up-to-date, nothing to do" 0 + fi + fi +} + +#================================================= + +# Send an email to inform the administrator +# +# usage: ynh_send_readme_to_admin app_message [recipients] +# | arg: app_message - The message to send to the administrator. +# | arg: recipients - The recipients of this email. Use spaces to separate multiples recipients. - default: root +# example: "root admin@domain" +# If you give the name of a YunoHost user, ynh_send_readme_to_admin will find its email adress for you +# example: "root admin@domain user1 user2" +ynh_send_readme_to_admin() { + local app_message="${1:-...No specific information...}" + local recipients="${2:-root}" + + # Retrieve the email of users + find_mails () { + local list_mails="$1" + local mail + local recipients=" " + # Read each mail in argument + for mail in $list_mails + do + # Keep root or a real email address as it is + if [ "$mail" = "root" ] || echo "$mail" | grep --quiet "@" + then + recipients="$recipients $mail" + else + # But replace an user name without a domain after by its email + if mail=$(ynh_user_get_info "$mail" "mail" 2> /dev/null) + then + recipients="$recipients $mail" + fi + fi + done + echo "$recipients" + } + recipients=$(find_mails "$recipients") + + local mail_subject="☁️🆈🅽🅷☁️: \`$app\` was just installed!" + + local mail_message="This is an automated message from your beloved YunoHost server. + +Specific information for the application $app. + +$app_message + +--- +Automatic diagnosis data from YunoHost + +$(yunohost tools diagnosis | grep -B 100 "services:" | sed '/services:/d')" + + # Send the email to the recipients + echo "$mail_message" | mail -a "Content-Type: text/plain; charset=UTF-8" -s "$mail_subject" "$recipients" +} diff --git a/scripts/_sed b/scripts/_sed new file mode 100644 index 0000000..cc76ab9 --- /dev/null +++ b/scripts/_sed @@ -0,0 +1,51 @@ +#!/bin/bash + +# https://github.com/YunoHost/yunohost/pull/394 + +# Substitute/replace a string (or expression) by another in a file +# +# usage: ynh_replace_string match_string replace_string target_file +# | arg: match_string - String to be searched and replaced in the file +# | arg: replace_string - String that will replace matches +# | arg: target_file - File in which the string will be replaced. +# +# As this helper is based on sed command, regular expressions and +# references to sub-expressions can be used +# (see sed manual page for more information) +ynh_replace_string () { + local delimit=@ + local match_string=$1 + local replace_string=$2 + local workfile=$3 + + # Escape the delimiter if it's in the string. + match_string=${match_string//${delimit}/"\\${delimit}"} + replace_string=${replace_string//${delimit}/"\\${delimit}"} + + sudo sed --in-place "s${delimit}${match_string}${delimit}${replace_string}${delimit}g" "$workfile" +} + +# Substitute/replace a password by another in a file +# +# usage: ynh_replace_password_string match_string replace_string target_file +# | arg: match_string - String to be searched and replaced in the file +# | arg: replace_string - String that will replace matches +# | arg: target_file - File in which the string will be replaced. +# +# This helper will use ynh_replace_string, but as you can use special +# characters, you can't use some regular expressions and sub-expressions. +ynh_replace_password_string () { + local match_string=$1 + local replace_string=$2 + local workfile=$3 + + # Escape any backslash to preserve them as simple backslash. + match_string=${match_string//\\/"\\\\"} + replace_string=${replace_string//\\/"\\\\"} + + # Escape the & character, who has a special function in sed. + match_string=${match_string//&/"\&"} + replace_string=${replace_string//&/"\&"} + + ynh_replace_string "$match_string" "$replace_string" "$workfile" +} diff --git a/scripts/backup b/scripts/backup index 7a22536..fc4ec98 100644 --- a/scripts/backup +++ b/scripts/backup @@ -60,3 +60,10 @@ ynh_backup "/etc/php5/fpm/conf.d/20-$app.ini" ynh_mysql_dump_db "$db_name" > db.sql CHECK_SIZE "db.sql" + +#================================================= +# BACKUP FAIL2BAN CONFIGURATION +#================================================= + +ynh_backup "/etc/fail2ban/jail.d/$app.conf" +ynh_backup "/etc/fail2ban/filter.d/$app.conf" diff --git a/scripts/change_url b/scripts/change_url new file mode 100644 index 0000000..440b9f3 --- /dev/null +++ b/scripts/change_url @@ -0,0 +1,135 @@ +#!/bin/bash + +#================================================= +# GENERIC STARTING +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers +source _sed + +#================================================= +# RETRIEVE ARGUMENTS +#================================================= + +old_domain=$YNH_APP_OLD_DOMAIN +old_path=$YNH_APP_OLD_PATH + +new_domain=$YNH_APP_NEW_DOMAIN +new_path=$YNH_APP_NEW_PATH + +app=$YNH_APP_INSTANCE_NAME + +#================================================= +# LOAD SETTINGS +#================================================= + +multisite=$(ynh_app_setting_get $app multisite) + +if [ $multisite -eq 1 ] +then + echo "A multisite installation of Wordpress can't be moved easily. Please have a look at the Wordpress codex to learn more about that." >&2 + ynh_die "https://codex.wordpress.org/Moving_WordPress#Moving_WordPress_Multisite" +fi + +#================================================= +# CHECK THE SYNTAX OF THE PATHS +#================================================= + +test -n "$old_path" || old_path="/" +test -n "$new_path" || new_path="/" +new_path=$(ynh_normalize_url_path $new_path) +old_path=$(ynh_normalize_url_path $old_path) + +#================================================= +# CHECK WHICH PARTS SHOULD BE CHANGED +#================================================= + +change_domain=0 +if [ "$old_domain" != "$new_domain" ] +then + change_domain=1 +fi + +change_path=0 +if [ "$old_path" != "$new_path" ] +then + change_path=1 +fi + +#================================================= +# MANAGE FAILURE OF THE SCRIPT +#================================================= + +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# STANDARD MODIFICATIONS +#================================================= +# MODIFY URL IN NGINX CONF +#================================================= + +nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf + +# Change the path in the nginx config file +if [ $change_path -eq 1 ] +then + # Make a backup of the original nginx config file if modified + ynh_backup_if_checksum_is_different "$nginx_conf_path" + + # Move from sub path to root + if [ "$new_path" == "/" ] + then + ynh_replace_string "\(^.*rewrite.*\^$old_path.* permanent;\)" "#sub_path_only\1" "$nginx_conf_path" + ynh_replace_string "\(rewrite *\^\)$old_path\$ $old_path/*" "\1$new_path$ $new_path" "$nginx_conf_path" + + # Move to a sub path + else + ynh_replace_string "^#sub_path_only" "" "$nginx_conf_path" + ynh_replace_string "\(rewrite *\^\)$old_path\$ $old_path/*" "\1$new_path$ $new_path/" "$nginx_conf_path" + fi + + ynh_replace_string "location ${old_path%/}/" "location ${new_path%/}/" "$nginx_conf_path" + + # Change the rewrite instructions for multisite + ynh_replace_string "rewrite \^$old_path\(.*last;\)" "rewrite ^$new_path\1" "$nginx_conf_path" + ynh_replace_string "$old_path\$2 last;" "$new_path\$2 last;" "$nginx_conf_path" + + # Change the rewrite instruction with $request_filename + ynh_replace_string "${old_path%/}/index.php?q=" "${new_path%/}/index.php?q=" "$nginx_conf_path" + + # Calculate and store the nginx config file checksum + ynh_store_file_checksum "$nginx_conf_path" +fi + +# Change the domain for nginx +if [ $change_domain -eq 1 ] +then + # Delete file checksum for the old conf file location + ynh_delete_file_checksum "$nginx_conf_path" + mv $nginx_conf_path /etc/nginx/conf.d/$new_domain.d/$app.conf + + nginx_conf_path=/etc/nginx/conf.d/$new_domain.d/$app.conf + # Calculate and store the nginx config file checksum + ynh_store_file_checksum "$nginx_conf_path" +fi + +#================================================= +# SPECIFIC MODIFICATIONS +#================================================= +# UPDATE THE DATABASE +#================================================= + +ynh_mysql_execute_as_root "UPDATE wp_options SET option_value='$new_domain$new_path' WHERE option_name='siteurl'" $app +ynh_mysql_execute_as_root "UPDATE wp_options SET option_value='$new_domain$new_path' WHERE option_name='home'" $app + +#================================================= +# GENERIC FINALISATION +#================================================= +# RELOAD NGINX +#================================================= + +systemctl reload nginx diff --git a/scripts/install b/scripts/install index 5cc709b..4ab1252 100644 --- a/scripts/install +++ b/scripts/install @@ -88,6 +88,10 @@ ynh_setup_source "$final_path" #================================================= # Create a dedicated nginx config +if [ "$path_url" != "/" ] +then + ynh_replace_string "^#sub_path_only" "" "../conf/nginx.conf" +fi ynh_add_nginx_config #================================================= @@ -114,8 +118,6 @@ cp ../conf/wp-config.php $final_path/wp-config.php # Change variables in Wordpress configuration ynh_replace_string "__DB_USER__" "$db_name" $final_path/wp-config.php ynh_replace_string "__DB_PWD__" "$db_pwd" $final_path/wp-config.php -ynh_replace_string "__DOMAIN__" "$domain" $final_path/wp-config.php -ynh_replace_string "__PATH__" "$path_url" $final_path/wp-config.php for i in 1 2 3 4 5 6 7 8 do @@ -167,14 +169,7 @@ wpcli_alias="php $final_path/wp-cli.phar --allow-root --path=$final_path" $wpcli_alias plugin install simple-ldap-login $wpcli_alias plugin install http-authentication $wpcli_alias plugin install companion-auto-update - -#================================================= -# LOAD SQL CONFIG -#================================================= - -# Replace variables in sql scripts -ynh_replace_string "__DOMAIN_PATH__" "$domain$path_url" ../conf/sql/*.sql -ynh_replace_string "__DATE__" "$(date +%s)" ../conf/sql/*.sql +$wpcli_alias plugin install wp-fail2ban #================================================= # SET LANGUAGE @@ -213,6 +208,7 @@ fi $wpcli_alias plugin activate simple-ldap-login $plugin_network # Do not activate http-authentication, this plugin is sometimes unstable $wpcli_alias plugin activate companion-auto-update $plugin_network +$wpcli_alias plugin activate wp-fail2ban $plugin_network #================================================= # STORE THE CHECKSUM OF THE CONFIG FILE @@ -232,6 +228,12 @@ chown -R $app: $final_path # Sauf le fichier de config wp-config.php qui appartient à root chown root: $final_path/wp-config.php +#================================================= +# SETUP FAIL2BAN +#================================================= + +ynh_add_fail2ban_config "/var/log/auth.log" "Authentication (attempt for unknown user|failure for) .* from " 5 + #================================================= # SETUP SSOWAT #================================================= @@ -253,3 +255,11 @@ systemctl reload nginx #================================================= ynh_secure_remove $final_path/wp-cli.phar + +#================================================= +# SEND A README FOR THE ADMIN +#================================================= + +message="If you facing an issue or want to improve this app, please open a new issue in this project: https://github.com/YunoHost-Apps/wordpress_ynh" + +ynh_send_readme_to_admin "$message" "$admin_wordpress" diff --git a/scripts/remove b/scripts/remove index 2126460..b4fdb89 100755 --- a/scripts/remove +++ b/scripts/remove @@ -55,6 +55,12 @@ ynh_remove_nginx_config # Remove the dedicated php-fpm config ynh_remove_fpm_config +#================================================= +# REMOVE FAIL2BAN CONFIGURATION +#================================================= + +ynh_remove_fail2ban_config + #================================================= # GENERIC FINALISATION #================================================= diff --git a/scripts/restore b/scripts/restore index 2d6cdea..a750d6d 100644 --- a/scripts/restore +++ b/scripts/restore @@ -86,6 +86,14 @@ chown root: $final_path/wp-config.php ynh_restore_file "/etc/php5/fpm/pool.d/$app.conf" ynh_restore_file "/etc/php5/fpm/conf.d/20-$app.ini" +#================================================= +# RESTORE FAIL2BAN CONFIGURATION +#================================================= + +ynh_restore_file "/etc/fail2ban/jail.d/$app.conf" +ynh_restore_file "/etc/fail2ban/filter.d/$app.conf" +systemctl restart fail2ban + #================================================= # GENERIC FINALISATION #================================================= diff --git a/scripts/upgrade b/scripts/upgrade index 7a02faa..afd5074 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -24,6 +24,12 @@ multisite=$(ynh_app_setting_get $app multisite) final_path=$(ynh_app_setting_get $app final_path) db_name=$(ynh_app_setting_get $app db_name) +#================================================= +# CHECK VERSION +#================================================= + +ynh_abort_if_up_to_date + #================================================= # ENSURE DOWNWARD COMPATIBILITY #================================================= @@ -45,18 +51,18 @@ if [ -z "$language" ]; then ynh_app_setting_set $app language $language fi -if [ "$is_public" = "Yes" ]; then +if [ "${is_public,,}" = "yes" ]; then ynh_app_setting_set $app is_public 1 # Fixe is_public en booléen is_public=1 -elif [ "$is_public" = "No" ]; then +elif [ "${is_public,,}" = "no" ]; then ynh_app_setting_set $app is_public 0 is_public=0 fi -if [ "$multisite" = "Yes" ]; then +if [ "${multisite,,}" = "yes" ]; then ynh_app_setting_set $app multisite 1 # Fixe multisite en booléen multisite=1 -elif [ "$multisite" = "No" ]; then +elif [ "${multisite,,}" = "no" ]; then ynh_app_setting_set $app multisite 0 multisite=0 fi @@ -97,6 +103,10 @@ path_url=$(ynh_normalize_url_path $path_url) #================================================= # Create a dedicated nginx config +if [ "$path_url" != "/" ] +then + ynh_replace_string "^#sub_path_only" "" "../conf/nginx.conf" +fi ynh_add_nginx_config #================================================= @@ -152,8 +162,11 @@ update_plugin () { ( $wpcli_alias plugin is-installed $1 && $wpcli_alias plugin update $1 ) || $wpcli_alias plugin install $1 } update_plugin simple-ldap-login +$wpcli_alias plugin activate simple-ldap-login $plugin_network update_plugin companion-auto-update $wpcli_alias plugin activate companion-auto-update $plugin_network +update_plugin wp-fail2ban +$wpcli_alias plugin activate wp-fail2ban $plugin_network # Disable broken plugin http-authentication $wpcli_alias plugin is-installed http-authentication && $wpcli_alias plugin deactivate http-authentication @@ -176,6 +189,12 @@ chown -R $app: $final_path # Sauf le fichier de config wp-config.php qui appartient à root chown root: $final_path/wp-config.php +#================================================= +# UPGRADE FAIL2BAN +#================================================= + +ynh_add_fail2ban_config "/var/log/auth.log" "Authentication (attempt for unknown user|failure for) .* from " 5 + #================================================= # SETUP SSOWAT #=================================================