This commit is contained in:
Weblate 2021-04-09 19:14:53 +00:00
commit 1c675cbb74
52 changed files with 260 additions and 312 deletions

View file

@ -295,6 +295,9 @@ user:
action_help: List permissions and corresponding accesses
api: GET /users/permissions
arguments:
apps:
help: Apps to list permission for (all by default)
nargs: "*"
-s:
full: --short
help: Only list permission names

View file

@ -1,6 +1,6 @@
#!/bin/bash
n_version=7.0.2
n_version=7.1.0
n_install_dir="/opt/node_n"
node_version_path="$n_install_dir/n/versions/node"
# N_PREFIX is the directory of n, it needs to be loaded as a environment variable.
@ -17,7 +17,7 @@ ynh_install_n () {
ynh_print_info --message="Installation of N - Node.js version management"
# Build an app.src for n
echo "SOURCE_URL=https://github.com/tj/n/archive/v${n_version}.tar.gz
SOURCE_SUM=fa80a8685f0fb1b4187fc0a1228b44f0ea2f244e063fe8f443b8913ea595af89" > "$YNH_APP_BASEDIR/conf/n.src"
SOURCE_SUM=20100f3bc56648cc414717fb7367fcf0e8229dc59a10b0530ccac90042ee0a74" > "$YNH_APP_BASEDIR/conf/n.src"
# Download and extract n
ynh_setup_source --dest_dir="$n_install_dir/git" --source_id=n
# Install n

View file

@ -182,7 +182,7 @@ ynh_permission_exists() {
local permission
ynh_handle_getopts_args "$@"
yunohost user permission list --output-as json --quiet \
yunohost user permission list "$app" --output-as json --quiet \
| jq -e --arg perm "$app.$permission" '.permissions[$perm]' >/dev/null
}

0
data/hooks/backup/05-conf_ldap Executable file → Normal file
View file

View file

@ -1,17 +0,0 @@
#!/bin/bash
# Exit hook on subcommand error or unset variable
set -eu
# Source YNH helpers
source /usr/share/yunohost/helpers
# Backup destination
backup_dir="${1}/conf/ssh"
# Backup the configuration
if [ -d /etc/ssh/ ]; then
ynh_backup "/etc/ssh" "$backup_dir"
else
echo "SSH is not installed"
fi

View file

@ -1,13 +0,0 @@
#!/bin/bash
# Exit hook on subcommand error or unset variable
set -eu
# Source YNH helpers
source /usr/share/yunohost/helpers
# Backup destination
backup_dir="${1}/conf/ssowat"
# Backup the configuration
ynh_backup "/etc/ssowat" "$backup_dir"

0
data/hooks/backup/17-data_home Executable file → Normal file
View file

View file

@ -1,13 +0,0 @@
#!/bin/bash
# Exit hook on subcommand error or unset variable
set -eu
# Source YNH helpers
source /usr/share/yunohost/helpers
# Backup destination
backup_dir="${1}/conf/ynh/firewall"
# Backup the configuration
ynh_backup "/etc/yunohost/firewall.yml" "${backup_dir}/firewall.yml"

View file

@ -0,0 +1,17 @@
#!/bin/bash
# Exit hook on subcommand error or unset variable
set -eu
# Source YNH helpers
source /usr/share/yunohost/helpers
# Backup destination
backup_dir="${1}/conf/ynh"
# Backup the configuration
ynh_backup "/etc/yunohost/firewall.yml" "${backup_dir}/firewall.yml"
ynh_backup "/etc/yunohost/current_host" "${backup_dir}/current_host"
[ ! -e "/etc/yunohost/settings.json" ] || ynh_backup "/etc/yunohost/settings.json" "${backup_dir}/settings.json"
[ ! -d "/etc/yunohost/dyndns" ] || ynh_backup "/etc/yunohost/dyndns" "${backup_dir}/dyndns"
[ ! -d "/etc/dkim" ] || ynh_backup "/etc/dkim" "${backup_dir}/dkim"

0
data/hooks/backup/21-conf_ynh_certs Executable file → Normal file
View file

View file

@ -1,9 +0,0 @@
#!/bin/bash
source /usr/share/yunohost/helpers
ynh_abort_if_errors
YNH_CWD="${YNH_BACKUP_DIR%/}/conf/dkim"
mkdir -p "$YNH_CWD"
cd "$YNH_CWD"
ynh_backup --src_path="/etc/dkim"

0
data/hooks/backup/23-data_mail Executable file → Normal file
View file

View file

@ -1,14 +0,0 @@
#!/bin/bash
# Exit hook on subcommand error or unset variable
set -eu
# Source YNH helpers
source /usr/share/yunohost/helpers
# Backup destination
backup_dir="${1}/conf/xmpp"
# Backup the configuration
ynh_backup /etc/metronome "${backup_dir}/etc"
ynh_backup /var/lib/metronome "${backup_dir}/var"

View file

@ -0,0 +1,13 @@
#!/bin/bash
# Exit hook on subcommand error or unset variable
set -eu
# Source YNH helpers
source /usr/share/yunohost/helpers
# Backup destination
backup_dir="${1}/data/xmpp"
ynh_backup /var/lib/metronome "${backup_dir}/var_lib_metronome"
ynh_backup /var/xmpp-upload/ "${backup_dir}/var_xmpp-upload"

View file

@ -1,13 +0,0 @@
#!/bin/bash
# Exit hook on subcommand error or unset variable
set -eu
# Source YNH helpers
source /usr/share/yunohost/helpers
# Backup destination
backup_dir="${1}/conf/nginx"
# Backup the configuration
ynh_backup "/etc/nginx/conf.d" "$backup_dir"

View file

@ -1,13 +0,0 @@
#!/bin/bash
# Exit hook on subcommand error or unset variable
set -eu
# Source YNH helpers
source /usr/share/yunohost/helpers
# Backup destination
backup_dir="${1}/conf/ynh"
# Backup the configuration
ynh_backup "/etc/yunohost/current_host" "${backup_dir}/current_host"

View file

@ -1,10 +0,0 @@
#!/bin/bash
source /usr/share/yunohost/helpers
ynh_abort_if_errors
YNH_CWD="${YNH_BACKUP_DIR%/}/conf/ynh/dyndns"
mkdir -p $YNH_CWD
cd "$YNH_CWD"
# Backup the configuration
ynh_exec_warn_less ynh_backup --src_path="/etc/yunohost/dyndns" --not_mandatory

View file

@ -0,0 +1,18 @@
#!/bin/bash
source /usr/share/yunohost/helpers
ynh_abort_if_errors
YNH_CWD="${YNH_BACKUP_DIR%/}/conf/manually_modified_files"
mkdir -p "$YNH_CWD"
cd "$YNH_CWD"
yunohost tools shell -c "from yunohost.regenconf import manually_modified_files; print('\n'.join(manually_modified_files()))" > ./manually_modified_files_list
ynh_backup --src_path="./manually_modified_files_list"
for file in $(cat ./manually_modified_files_list)
do
ynh_backup --src_path="$file"
done
ynh_backup --src_path="/etc/ssowat/conf.json.persistent"

View file

@ -1,15 +1,8 @@
#!/bin/bash
backup_dir="${1}/conf/ldap"
if [[ $EUID -ne 0 ]]; then
# We need to execute this script as root, since the ldap
# service will be shut down during the operation (and sudo
# won't be available)
/bin/bash $(readlink -f $0) $1
else
service slapd stop || true
systemctl stop slapd
# Create a directory for backup
TMPDIR="/tmp/$(date +%s)"
@ -28,7 +21,7 @@ else
mv "${TMPDIR}/ldap" /var/lib/ldap)
chown -R openldap: /etc/ldap/slapd.d /var/lib/ldap
service slapd start
systemctl start slapd
rm -rf "$TMPDIR"
# Print an error message and exit
@ -42,7 +35,8 @@ else
cp -a "${backup_dir}/ldap.conf" /etc/ldap/ldap.conf
cp -a "${backup_dir}/slapd.ldif" /etc/ldap/slapd.ldif
# Legacy thing but we need it to force the regen-conf in case of it exist
cp -a "${backup_dir}/slapd.conf" /etc/ldap/slapd.conf
[ ! -e "${backup_dir}/slapd.conf" ] \
|| cp -a "${backup_dir}/slapd.conf" /etc/ldap/slapd.conf
slapadd -F /etc/ldap/slapd.d -b cn=config \
-l "${backup_dir}/cn=config.master.ldif" \
|| die 1 "Unable to restore LDAP configuration"
@ -56,6 +50,5 @@ else
|| die 2 "Unable to restore LDAP database"
chown -R openldap: /var/lib/ldap
service slapd start
systemctl start slapd
rm -rf "$TMPDIR"
fi

View file

@ -1,9 +0,0 @@
backup_dir="$1/conf/ssh"
if [ -d /etc/ssh/ ]; then
cp -a $backup_dir/. /etc/ssh
service ssh restart
else
echo "SSH is not installed"
fi

View file

@ -1,3 +0,0 @@
backup_dir="$1/conf/ssowat"
cp -a $backup_dir/. /etc/ssowat

View file

@ -1,4 +0,0 @@
backup_dir="$1/conf/ynh/firewall"
cp -a $backup_dir/. /etc/yunohost
yunohost firewall reload

View file

@ -0,0 +1,7 @@
backup_dir="$1/conf/ynh"
cp -a "${backup_dir}/current_host" /etc/yunohost/current_host
cp -a "${backup_dir}/firewall.yml" /etc/yunohost/firewall.yml
[ ! -e "${backup_dir}/settings.json" ] || cp -a "${backup_dir}/settings.json" "/etc/yunohost/settings.json"
[ ! -d "${backup_dir}/dyndns" ] || cp -raT "${backup_dir}/dyndns" "/etc/yunohost/dyndns"
[ ! -d "${backup_dir}/dkim" ] || cp -raT "${backup_dir}/dkim" "/etc/dkim"

View file

@ -3,5 +3,3 @@ backup_dir="$1/conf/ynh/certs"
mkdir -p /etc/yunohost/certs/
cp -a $backup_dir/. /etc/yunohost/certs/
service nginx reload
service metronome reload

View file

@ -1,9 +0,0 @@
#!/bin/bash
backup_dir="$1/conf/dkim"
cp -a $backup_dir/etc/dkim/. /etc/dkim
chown -R root:root /etc/dkim
chown _rspamd:root /etc/dkim
chown _rspamd:root /etc/dkim/*.mail.key

View file

@ -2,7 +2,3 @@ backup_dir="$1/data/mail"
cp -a $backup_dir/. /var/mail/ || echo 'No mail found'
chown -R vmail:mail /var/mail/
# Restart services to use migrated certs
service postfix restart
service dovecot restart

View file

@ -1,7 +0,0 @@
backup_dir="$1/conf/xmpp"
cp -a $backup_dir/etc/. /etc/metronome
cp -a $backup_dir/var/. /var/lib/metronome
# Restart to apply new conf and certs
service metronome restart

View file

@ -0,0 +1,4 @@
backup_dir="$1/data/xmpp"
cp -a $backup_dir/var_lib_metronome/. /var/lib/metronome
cp -a $backup_dir/var_xmpp-upload/. /var/xmpp-upload

View file

@ -1,7 +0,0 @@
backup_dir="$1/conf/nginx"
# Copy all conf except apps specific conf located in DOMAIN.d
find $backup_dir/ -mindepth 1 -maxdepth 1 -name '*.d' -or -exec cp -a {} /etc/nginx/conf.d/ \;
# Restart to use new conf and certs
service nginx restart

View file

@ -1,3 +0,0 @@
backup_dir="$1/conf/ynh"
cp -a "${backup_dir}/current_host" /etc/yunohost/current_host

View file

@ -1,9 +0,0 @@
#!/bin/bash
source /usr/share/yunohost/helpers
ynh_abort_if_errors
YNH_CWD="${YNH_BACKUP_DIR%/}/conf/ynh/dyndns"
cd "$YNH_CWD"
# Restore file if exists
ynh_restore_file --origin_path="/etc/yunohost/dyndns" --not_mandatory

View file

@ -0,0 +1,13 @@
#!/bin/bash
source /usr/share/yunohost/helpers
ynh_abort_if_errors
YNH_CWD="${YNH_BACKUP_DIR%/}/conf/manually_modified_files"
cd "$YNH_CWD"
for file in $(cat ./manually_modified_files_list)
do
ynh_restore_file --origin_path="$file" --not_mandatory
done
ynh_restore_file --origin_path="/etc/ssowat/conf.json.persistent" --not_mandatory

View file

@ -6,6 +6,6 @@ location /yunohost/admin/ {
default_type text/html;
index index.html;
more_set_headers "Content-Security-Policy: upgrade-insecure-requests; default-src 'self'; connect-src 'self' https://raw.githubusercontent.com https://paste.yunohost.org wss://$host; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-eval'; object-src 'none';";
more_set_headers "Content-Security-Policy: upgrade-insecure-requests; default-src 'self'; connect-src 'self' https://raw.githubusercontent.com https://paste.yunohost.org wss://$host; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-eval'; object-src 'none'; img-src 'self' data:;";
more_set_headers "Content-Security-Policy-Report-Only:";
}

View file

@ -54,7 +54,12 @@ smtpd_tls_loglevel=1
# -- TLS for outgoing connections
# Use TLS if this is supported by the remote SMTP server, otherwise use plaintext.
{% if relay_port == "465" %}
smtp_tls_wrappermode = yes
smtp_tls_security_level = encrypt
{% else %}
smtp_tls_security_level = may
{% endif %}
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_exclude_ciphers = aNULL, MD5, DES, ADH, RC4, 3DES
smtp_tls_mandatory_ciphers= high

View file

@ -327,7 +327,7 @@
"regenconf_failed": "No s'ha pogut regenerar la configuració per la/les categoria/es : {categories}",
"regenconf_pending_applying": "Aplicació de la configuració pendent per la categoria «{category}»...",
"restore_already_installed_app": "Una aplicació amb la ID «{app:s}» ja està instal·lada",
"restore_app_failed": "No s'ha pogut restaurar {app:s}",
"app_restore_failed": "No s'ha pogut restaurar {app:s}: {error:s}",
"restore_cleaning_failed": "No s'ha pogut netejar el directori temporal de restauració",
"restore_complete": "Restauració completada",
"restore_confirm_yunohost_installed": "Esteu segur de voler restaurar un sistema ja instal·lat? [{answers:s}]",

View file

@ -96,7 +96,7 @@
"port_already_closed": "Der Port {port:d} wurde bereits für {ip_version:s} Verbindungen geschlossen",
"port_already_opened": "Der Port {port:d} wird bereits von {ip_version:s} benutzt",
"restore_already_installed_app": "Es ist bereits eine App mit der ID '{app:s}' installiet",
"restore_app_failed": "'{app:s}' konnte nicht wiederhergestellt werden",
"restore_app_failed": "'{app:s}' konnte nicht wiederhergestellt werden: {error:s}",
"restore_cleaning_failed": "Das temporäre Dateiverzeichnis für Systemrestaurierung konnte nicht gelöscht werden",
"restore_complete": "Vollständig wiederhergestellt",
"restore_confirm_yunohost_installed": "Möchtest du die Wiederherstellung wirklich starten? [{answers:s}]",

View file

@ -44,6 +44,8 @@
"app_requirements_checking": "Checking required packages for {app}...",
"app_requirements_unmeet": "Requirements are not met for {app}, the package {pkgname} ({version}) must be {spec}",
"app_remove_after_failed_install": "Removing the app following the installation failure...",
"app_restore_failed": "Could not restore {app:s}: {error:s}",
"app_restore_script_failed": "An error occured inside the app restore script",
"app_sources_fetch_failed": "Could not fetch sources files, is the URL correct?",
"app_start_install": "Installing {app}...",
"app_start_remove": "Removing {app}...",
@ -524,7 +526,6 @@
"regex_with_only_domain": "You can't use a regex for domain, only for path",
"restore_already_installed_app": "An app with the ID '{app:s}' is already installed",
"restore_already_installed_apps": "The following apps can't be restored because they are already installed: {apps}",
"restore_app_failed": "Could not restore {app:s}",
"restore_backup_too_old": "This backup archive can not be restored because it comes from a too-old YunoHost version.",
"restore_cleaning_failed": "Could not clean up the temporary restoration directory",
"restore_complete": "Restoration completed",

View file

@ -479,7 +479,7 @@
"service_restarted": "Servo '{service:s}' rekomencis",
"pattern_username": "Devas esti minuskulaj literoj kaj minuskloj nur",
"extracting": "Eltirante…",
"restore_app_failed": "Ne povis restarigi la programon '{app:s}'",
"app_restore_failed": "Ne povis restarigi la programon '{app:s}': {error:s}",
"yunohost_configured": "YunoHost nun estas agordita",
"certmanager_self_ca_conf_file_not_found": "Ne povis trovi agorddosieron por mem-subskriba aŭtoritato (dosiero: {file:s})",
"log_app_remove": "Forigu la aplikon '{}'",

View file

@ -107,7 +107,7 @@
"port_already_closed": "El puerto {port:d} ya está cerrado para las conexiones {ip_version:s}",
"port_already_opened": "El puerto {port:d} ya está abierto para las conexiones {ip_version:s}",
"restore_already_installed_app": "Una aplicación con el ID «{app:s}» ya está instalada",
"restore_app_failed": "No se pudo restaurar la aplicación «{app:s}»",
"app_restore_failed": "No se pudo restaurar la aplicación «{app:s}»: {error:s}",
"restore_cleaning_failed": "No se pudo limpiar el directorio temporal de restauración",
"restore_complete": "Restaurada",
"restore_confirm_yunohost_installed": "¿Realmente desea restaurar un sistema ya instalado? [{answers:s}]",

View file

@ -107,7 +107,7 @@
"port_already_closed": "Le port {port:d} est déjà fermé pour les connexions {ip_version:s}",
"port_already_opened": "Le port {port:d} est déjà ouvert pour les connexions {ip_version:s}",
"restore_already_installed_app": "Une application est déjà installée avec lidentifiant '{app:s}'",
"restore_app_failed": "Impossible de restaurer '{app:s}'",
"app_restore_failed": "Impossible de restaurer '{app:s}': {error:s}",
"restore_cleaning_failed": "Impossible de nettoyer le dossier temporaire de restauration",
"restore_complete": "Restauration terminée",
"restore_confirm_yunohost_installed": "Voulez-vous vraiment restaurer un système déjà installé ? [{answers:s}]",

View file

@ -120,7 +120,7 @@
"pattern_username": "Caratteri minuscoli alfanumerici o trattini bassi soli",
"port_already_closed": "La porta {port:d} è già chiusa per le connessioni {ip_version:s}",
"restore_already_installed_app": "Un'applicazione con l'ID '{app:s}' è già installata",
"restore_app_failed": "Impossibile ripristinare l'applicazione '{app:s}'",
"app_restore_failed": "Impossibile ripristinare l'applicazione '{app:s}': {error:s}",
"restore_cleaning_failed": "Impossibile pulire la directory temporanea di ripristino",
"restore_complete": "Ripristino completo",
"restore_confirm_yunohost_installed": "Sei sicuro di volere ripristinare un sistema già installato? {answers:s}",

View file

@ -54,7 +54,7 @@
"pattern_password": "Wachtwoord moet tenminste 3 karakters lang zijn",
"port_already_closed": "Poort {port:d} is al gesloten voor {ip_version:s} verbindingen",
"port_already_opened": "Poort {port:d} is al open voor {ip_version:s} verbindingen",
"restore_app_failed": "De app '{app:s}' kon niet worden terug gezet",
"app_restore_failed": "De app '{app:s}' kon niet worden terug gezet: {error:s}",
"restore_hook_unavailable": "De herstel-hook '{part:s}' is niet beschikbaar op dit systeem",
"service_add_failed": "Kan service '{service:s}' niet toevoegen",
"service_already_started": "Service '{service:s}' draait al",

View file

@ -170,7 +170,7 @@
"port_already_closed": "Lo pòrt {port:d} es ja tampat per las connexions {ip_version:s}",
"port_already_opened": "Lo pòrt {port:d} es ja dubèrt per las connexions {ip_version:s}",
"restore_already_installed_app": "Una aplicacion es ja installada amb lid « {app:s} »",
"restore_app_failed": "Impossible de restaurar laplicacion « {app:s} »",
"app_restore_failed": "Impossible de restaurar laplicacion « {app:s} »: {error:s}",
"backup_ask_for_copying_if_needed": "Volètz far una salvagarda en utilizant {size:s} Mo temporàriament? (Aqueste biais de far es emplegat perque unes fichièrs an pas pogut èsser preparats amb un metòde mai eficaç.)",
"yunohost_not_installed": "YunoHost es pas installat o corrèctament installat. Mercés dexecutar «yunohost tools postinstall »",
"backup_output_directory_forbidden": "Causissètz un repertòri de destinacion deferent. Las salvagardas pòdon pas se realizar dins los repertòris bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var ou /home/yunohost.backup/archives",

View file

@ -194,7 +194,7 @@ def app_info(app, full=False):
)
local_manifest = _get_manifest_of_app(os.path.join(APPS_SETTING_PATH, app))
permissions = user_permission_list(full=True, absolute_urls=True)["permissions"]
permissions = user_permission_list(full=True, absolute_urls=True, apps=[app])["permissions"]
settings = _get_app_settings(app)
@ -229,9 +229,7 @@ def app_info(app, full=False):
local_manifest.get("multi_instance", False)
)
ret["permissions"] = {
p: i for p, i in permissions.items() if p.startswith(app + ".")
}
ret["permissions"] = permissions
ret["label"] = permissions.get(app + ".main", {}).get("label")
if not ret["label"]:
@ -1435,7 +1433,7 @@ def app_setting(app, key, value=None, delete=False):
permission_url,
)
permissions = user_permission_list(full=True)["permissions"]
permissions = user_permission_list(full=True, apps=[app])["permissions"]
permission_name = "%s.legacy_%s_uris" % (app, key.split("_")[0])
permission = permissions.get(permission_name)

View file

@ -1392,7 +1392,6 @@ class RestoreManager:
self.targets.set_result("apps", app_instance_name, "Warning")
return
logger.debug(m18n.n("restore_running_app_script", app=app_instance_name))
try:
# Restore app settings
app_settings_new_path = os.path.join(
@ -1401,7 +1400,7 @@ class RestoreManager:
app_scripts_new_path = os.path.join(app_settings_new_path, "scripts")
shutil.copytree(app_settings_in_archive, app_settings_new_path)
filesystem.chmod(app_settings_new_path, 0o400, 0o400, True)
filesystem.chown(app_scripts_new_path, "admin", None, True)
filesystem.chown(app_scripts_new_path, "root", None, True)
# Copy the app scripts to a writable temporary folder
# FIXME : use 'install -Dm555' or something similar to what's done
@ -1409,7 +1408,7 @@ class RestoreManager:
tmp_folder_for_app_restore = tempfile.mkdtemp(prefix="restore")
copytree(app_scripts_in_archive, tmp_folder_for_app_restore)
filesystem.chmod(tmp_folder_for_app_restore, 0o550, 0o550, True)
filesystem.chown(tmp_folder_for_app_restore, "admin", None, True)
filesystem.chown(tmp_folder_for_app_restore, "root", None, True)
restore_script = os.path.join(tmp_folder_for_app_restore, "restore")
# Restore permissions
@ -1454,6 +1453,22 @@ class RestoreManager:
os.remove("%s/permissions.yml" % app_settings_new_path)
_tools_migrations_run_before_app_restore(backup_version=self.info["from_yunohost_version"], app_id=app_instance_name)
except Exception:
import traceback
error = m18n.n("unexpected_error", error="\n" + traceback.format_exc())
msg = m18n.n("app_restore_failed", app=app_instance_name, error=error)
logger.error(msg)
operation_logger.error(msg)
self.targets.set_result("apps", app_instance_name, "Error")
# Cleanup
shutil.rmtree(app_settings_new_path, ignore_errors=True)
shutil.rmtree(tmp_folder_for_app_restore, ignore_errors=True)
return
logger.debug(m18n.n("restore_running_app_script", app=app_instance_name))
# Prepare env. var. to pass to script
env_dict = _make_environment_for_app_script(app_instance_name)
@ -1470,20 +1485,41 @@ class RestoreManager:
operation_logger.extra["env"] = env_dict
operation_logger.flush()
# Execute app restore script
hook_exec(
# Execute the app install script
restore_failed = True
try:
restore_retcode = hook_exec(
restore_script,
chdir=app_backup_in_archive,
raise_on_error=True,
env=env_dict,
)[0]
except Exception:
msg = m18n.n("restore_app_failed", app=app_instance_name)
logger.error(msg)
operation_logger.error(msg)
# "Common" app restore failure : the script failed and returned exit code != 0
restore_failed = True if restore_retcode != 0 else False
if restore_failed:
error = m18n.n("app_restore_script_failed")
logger.error(m18n.n("app_restore_failed", app=app_instance_name, error=error))
failure_message_with_debug_instructions = operation_logger.error(error)
if msettings.get("interface") != "api":
dump_app_log_extract_for_debugging(operation_logger)
# Script got manually interrupted ... N.B. : KeyboardInterrupt does not inherit from Exception
except (KeyboardInterrupt, EOFError):
error = m18n.n("operation_interrupted")
logger.error(m18n.n("app_restore_failed", app=app_instance_name, error=error))
failure_message_with_debug_instructions = operation_logger.error(error)
# Something wrong happened in Yunohost's code (most probably hook_exec)
except Exception:
import traceback
error = m18n.n("unexpected_error", error="\n" + traceback.format_exc())
logger.error(m18n.n("app_restore_failed", app=app_instance_name, error=error))
failure_message_with_debug_instructions = operation_logger.error(error)
finally:
# Cleaning temporary scripts directory
shutil.rmtree(tmp_folder_for_app_restore, ignore_errors=True)
if not restore_failed:
self.targets.set_result("apps", app_instance_name, "Success")
operation_logger.success()
else:
self.targets.set_result("apps", app_instance_name, "Error")
@ -1492,20 +1528,20 @@ class RestoreManager:
# Setup environment for remove script
env_dict_remove = _make_environment_for_app_script(app_instance_name)
operation_logger = OperationLogger(
remove_operation_logger = OperationLogger(
"remove_on_failed_restore",
[("app", app_instance_name)],
env=env_dict_remove,
)
operation_logger.start()
remove_operation_logger.start()
# Execute remove script
if hook_exec(remove_script, env=env_dict_remove)[0] != 0:
msg = m18n.n("app_not_properly_removed", app=app_instance_name)
logger.warning(msg)
operation_logger.error(msg)
remove_operation_logger.error(msg)
else:
operation_logger.success()
remove_operation_logger.success()
# Cleaning app directory
shutil.rmtree(app_settings_new_path, ignore_errors=True)
@ -1516,19 +1552,12 @@ class RestoreManager:
permission_delete(permission_name, force=True)
# TODO Cleaning app hooks
else:
self.targets.set_result("apps", app_instance_name, "Success")
operation_logger.success()
finally:
# Cleaning temporary scripts directory
shutil.rmtree(tmp_folder_for_app_restore, ignore_errors=True)
logger.error(failure_message_with_debug_instructions)
#
# Backup methods #
#
class BackupMethod(object):
"""

View file

@ -260,7 +260,7 @@ def dyndns_update(
ok, result = dig(dyn_host, "A")
dyn_host_ip = result[0] if ok == "ok" and len(result) else None
if not dyn_host_ip:
raise YunohostError("Failed to resolve %s" % dyn_host)
raise YunohostError("Failed to resolve %s" % dyn_host, raw_msg=True)
ok, result = dig(domain, rdtype, resolvers=[dyn_host_ip])
if ok == "ok":

View file

@ -188,18 +188,19 @@ def firewall_list(raw=False, by_ip_version=False, list_forwarded=False):
for i in ["ipv4", "ipv6"]:
f = firewall[i]
# Combine TCP and UDP ports
ports[i] = sorted(set(f["TCP"]) | set(f["UDP"]))
ports[i] = sorted(set(f["TCP"]) | set(f["UDP"]), key=lambda p: int(p.split(':')[0]) if isinstance(p, str) else p)
if not by_ip_version:
# Combine IPv4 and IPv6 ports
ports = sorted(set(ports["ipv4"]) | set(ports["ipv6"]))
ports = sorted(set(ports["ipv4"]) | set(ports["ipv6"]), key=lambda p: int(p.split(':')[0]) if isinstance(p, str) else p)
# Format returned dict
ret = {"opened_ports": ports}
if list_forwarded:
# Combine TCP and UDP forwarded ports
ret["forwarded_ports"] = sorted(
set(firewall["uPnP"]["TCP"]) | set(firewall["uPnP"]["UDP"])
set(firewall["uPnP"]["TCP"]) | set(firewall["uPnP"]["UDP"]),
key=lambda p: int(p.split(':')[0]) if isinstance(p, str) else p
)
return ret

View file

@ -414,7 +414,7 @@ class RedactingFormatter(Formatter):
# This matches stuff like db_pwd=the_secret or admin_password=other_secret
# (the secret part being at least 3 chars to avoid catching some lines like just "db_pwd=")
# Some names like "key" or "manifest_key" are ignored, used in helpers like ynh_app_setting_set or ynh_read_manifest
match = re.search(r'(pwd|pass|password|secret\w*|\w+key|token)=(\S{3,})$', record.strip())
match = re.search(r'(pwd|pass|password|passphrase|secret\w*|\w+key|token)=(\S{3,})$', record.strip())
if match and match.group(2) not in self.data_to_redact and match.group(1) not in ["key", "manifest_key"]:
self.data_to_redact.append(match.group(2))
except Exception as e:

View file

@ -46,7 +46,7 @@ SYSTEM_PERMS = ["mail", "xmpp", "sftp", "ssh"]
def user_permission_list(
short=False, full=False, ignore_system_perms=False, absolute_urls=False
short=False, full=False, ignore_system_perms=False, absolute_urls=False, apps=[]
):
"""
List permissions and corresponding accesses
@ -74,7 +74,9 @@ def user_permission_list(
)
# Parse / organize information to be outputed
apps = sorted(_installed_apps())
if apps:
ignore_system_perms = True
apps = apps if apps else sorted(_installed_apps())
apps_base_path = {
app: app_setting(app, "domain") + app_setting(app, "path")
for app in apps
@ -85,11 +87,14 @@ def user_permission_list(
for infos in permissions_infos:
name = infos["cn"][0]
if ignore_system_perms and name.split(".")[0] in SYSTEM_PERMS:
continue
app = name.split(".")[0]
if app in SYSTEM_PERMS:
if ignore_system_perms:
continue
elif app not in apps:
continue
perm = {}
perm["allowed"] = [
_ldap_path_extract(p, "cn") for p in infos.get("groupPermission", [])

View file

@ -413,7 +413,7 @@ def test_backup_with_different_output_directory(mocker):
# Create the backup
with message(mocker, "backup_created"):
backup_create(
system=["conf_ssh"],
system=["conf_ynh_settings"],
apps=None,
output_directory="/opt/test_backup_output_directory",
name="backup",
@ -427,7 +427,7 @@ def test_backup_with_different_output_directory(mocker):
archives_info = backup_info(archives[0], with_details=True)
assert archives_info["apps"] == {}
assert len(archives_info["system"].keys()) == 1
assert "conf_ssh" in archives_info["system"].keys()
assert "conf_ynh_settings" in archives_info["system"].keys()
@pytest.mark.clean_opt_dir
@ -436,7 +436,7 @@ def test_backup_using_copy_method(mocker):
# Create the backup
with message(mocker, "backup_created"):
backup_create(
system=["conf_nginx"],
system=["conf_ynh_settings"],
apps=None,
output_directory="/opt/test_backup_output_directory",
methods=["copy"],
@ -467,13 +467,13 @@ def test_restore_app_script_failure_handling(monkeypatch, mocker):
def custom_hook_exec(name, *args, **kwargs):
if os.path.basename(name).startswith("restore"):
monkeypatch.undo()
raise Exception
return (1, None)
monkeypatch.setattr("yunohost.backup.hook_exec", custom_hook_exec)
assert not _is_installed("wordpress")
with message(mocker, "restore_app_failed", app="wordpress"):
with message(mocker, "app_restore_script_failed"):
with raiseYunohostError(mocker, "restore_nothings_done"):
backup_restore(
system=None, name=backup_list()["archives"][0], apps=["wordpress"]
@ -675,9 +675,9 @@ def test_backup_binds_are_readonly(mocker, monkeypatch):
def custom_mount_and_backup(self):
self._organize_files()
confssh = os.path.join(self.work_dir, "conf/ssh")
conf = os.path.join(self.work_dir, "conf/ynh/dkim")
output = subprocess.check_output(
"touch %s/test 2>&1 || true" % confssh,
"touch %s/test 2>&1 || true" % conf,
shell=True,
env={"LANG": "en_US.UTF-8"},
)

View file

@ -862,10 +862,10 @@ def user_group_info(groupname):
#
def user_permission_list(short=False, full=False):
def user_permission_list(short=False, full=False, apps=[]):
import yunohost.permission
return yunohost.permission.user_permission_list(short, full, absolute_urls=True)
return yunohost.permission.user_permission_list(short, full, absolute_urls=True, apps=apps)
def user_permission_update(