1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/redirect_ynh.git synced 2024-09-03 20:16:10 +02:00

[enh] Add config panel

This commit is contained in:
ljf 2022-06-11 14:18:45 +02:00
parent 669e3b0e7a
commit 4a20a37ed7
14 changed files with 318 additions and 82 deletions

View file

@ -4,6 +4,7 @@
path="/path"
redirect_type="public_302"
redirect_path="http://127.0.0.1"
is_public=1
; Checks
pkg_linter=1
setup_sub_dir=1

View file

@ -1,5 +1,6 @@
location YNH_LOCATION {
proxy_pass YNH_REDIRECT_PATH;
#sub_path_only rewrite ^__PATH__$ __PATH__/ permanent;
location __PATH__/ {
proxy_pass __REDIRECT_PATH__;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;

View file

@ -0,0 +1,4 @@
#sub_path_only rewrite ^__PATH__$ __PATH__/ permanent;
location __PATH__/ {
return 301 __REDIRECT_PATH__;
}

View file

@ -0,0 +1,4 @@
#sub_path_only rewrite ^__PATH__$ __PATH__/ permanent;
location __PATH__/ {
return 301 __REDIRECT_PATH__$request_uri;
}

View file

@ -0,0 +1,4 @@
#sub_path_only rewrite ^__PATH__$ __PATH__/ permanent;
location __PATH__/ {
return 302 __REDIRECT_PATH__;
}

View file

@ -0,0 +1,4 @@
#sub_path_only rewrite ^__PATH__$ __PATH__/ permanent;
location __PATH__/ {
return 302 __REDIRECT_PATH__$request_uri;
}

View file

@ -1,3 +0,0 @@
location YNH_LOCATION {
return 301 YNH_REDIRECT_PATH$request_uri;
}

View file

@ -1,3 +0,0 @@
location YNH_LOCATION {
return 302 YNH_REDIRECT_PATH$request_uri;
}

56
config_panel.toml Normal file
View file

@ -0,0 +1,56 @@
version = "1.0"
[main]
name = "Auto-configuration"
[main.redirect]
name = ""
optional = false
[main.redirect.domain]
ask = "Domain"
type = "domain"
example = "domain.org"
[main.redirect.path_url]
ask = "Path"
type = "path"
bind = "path_url:/etc/yunohost/__APP__/settings.yml"
example = "/redirect"
[main.redirect.redirect_path]
ask = "Redirect destination path"
type = "url"
[main.redirect.redirect_type]
ask = "Redirect type"
type = "select"
choices.public_302 = "Visible temporary redirect (HTTP 302)"
choices.public_302_subpath = "Visible temporary redirect (HTTP 302) + subpaths are propagated"
choices.public_301 = "Visible permanent redirect (HTTP 301)"
choices.public_301_subpath = "Visible permanent redirect (HTTP 301) + subpaths are propagated"
choices.proxy = "Invisible redirect using proxy (NGINX proxy_pass)"
help = "Subpaths are propagated = transfer the subpath into the redirection. So if you redirect www.example.com to example.com, request https://www.example.com/foo/bar will redirect onto https://example.com/foo/bar instead of https://example.com"
[main.redirect.frame_allowed]
ask = "Frame allowed"
type = "boolean"
visible = "redirect_type == 'proxy'"
optional = true
[main.redirect.frame_ancestors]
ask = "Frame ancestors"
type = "tags"
visible = "redirect_type == 'proxy' and frame_allowed"
help = "Any valid host source like `https://example.com`, know more https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors"
optional = true
[main.redirect.client_max_body_size]
ask = "Maximum size of a requests"
type = "string"
help = "If you want to upload 100m video you should multiply by 1.4 ratio (140m) cause it will be mime-encoded. Note that temporary space is needed equal to the total size of all concurrent uploads."
pattern.regexp = "^[0-9]{1,15}(k|m|g|t)$"
pattern.error = "Provide a size like 20m or 100k"
visible = "redirect_type == 'proxy'"
optional = true

View file

@ -6,7 +6,7 @@
"en": "Create a redirection or a proxy to another path",
"fr": "Créer une redirection ou un proxy vers un autre emplacement"
},
"version": "1.0.1~ynh1",
"version": "1.0.2~ynh1",
"license": "AGPL-3.0-or-later",
"url": "https://github.com/YunoHost-Apps/redirect_ynh",
"upstream": {
@ -55,12 +55,20 @@
"fr": "Type de redirection"
},
"choices": {
"public_302": "Visible redirect (302, temporary). Everybody will be able to access it.",
"public_301": "Visible redirect (301, permanent). Everybody will be able to access it.",
"public_proxy": "Proxy, invisible (NGINX proxy_pass). Everybody will be able to access it.",
"private_proxy": "Proxy, invisible (NGINX proxy_pass). Only accessible for allowed users."
"public_302": "Visible redirect (302, temporary).",
"public_302_subpath": "Visible redirect (302, temporary) + subpaths are propagated.",
"public_301": "Visible redirect (301, permanent).",
"public_301_subpath": "Visible redirect (301, permanent) + subpaths are propagated.",
"proxy": "Proxy, invisible (NGINX proxy_pass)."
},
"default": "public_302"
"default": "public_302_subpath",
"help": "Subpaths are propagated = transfer the subpath into the redirection. So if you redirect www.example.com to example.com, request https://www.example.com/foo/bar will redirect onto https://example.com/foo/bar instead of https://example.com"
},
{
"name": "is_public",
"type": "boolean",
"default": true,
"visible": "redirect_type == 'proxy'"
}
]
}

114
scripts/config Normal file
View file

@ -0,0 +1,114 @@
#!/bin/bash
#=================================================
# GENERIC STARTING
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
source /usr/share/yunohost/helpers
#=================================================
# MANAGE SCRIPT FAILURE
#=================================================
# Exit if an error occurs during the execution of the script
ynh_abort_if_errors
#=================================================
# SPECIFIC GETTERS FOR TOML SHORT KEY
#=================================================
get__client_max_body_size() {
grep -o -P "(?<=client_max_body_size )\d+[kmgt](?=;)" /etc/nginx/conf.d/$domain.d/$app.conf
}
get__frame_allowed() {
if grep -E -q "Content-Security-Policy: +frame-ancestors +'none' *;" /etc/nginx/conf.d/$domain.d/$app.conf
then
echo 0
else
echo 1
fi
}
get__frame_ancestors() {
if grep -E -q "Content-Security-Policy: +frame-ancestors +'none' *;" /etc/nginx/conf.d/$domain.d/$app.conf
then
grep -o -P "(?<=Content-security-Policy: frame-ancestors )[^;]+(?=;)" /etc/nginx/conf.d/$domain.d/$app.conf | sed "s/'none'//g" | xargs | sed -E "s/ /,/g"
fi
}
#=================================================
# SPECIFIC VALIDATORS FOR TOML SHORT KEYS
#=================================================
validate__redirect_path() {
url_regex='(https?|ftp|file)://[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=~_|]'
if [[ ! $redirect_path =~ $url_regex ]]
then
echo "Invalid destination: $redirect_path"
fi
# Avoid uncrypted remote destination with reverse proxy mode
# Indeed the SSO send the password in all requests in HTTP headers
url_regex='^(http://(127\.[0-9]+\.[0-9]+\.[0-9]+|localhost)|https://.*)(:[0-9]+)?(/.*)?$'
if [[ "$redirect_type" = "proxy" ]] && [[ ! $redirect_path =~ $url_regex ]]
then
echo
"For secure reason, you can't use an unencrypted http remote destination couple with ssowat for your reverse proxy: $redirect_path"
fi
}
#=================================================
# SPECIFIC SETTERS FOR TOML SHORT KEYS
#=================================================
set__domain() {
ynh_secure_remove /etc/nginx/conf.d/${old[domain]}.d/$app.conf
}
set__redirect_type() {
if [[ $redirect_type != "proxy" ]]
then
ynh_permission_update --permission="main" --add="visitors" --protected=1
ynh_app_setting_set --app=$app --key=is_public --value=1
else
ynh_permission_update --permission="main" --protected=0
fi
ynh_app_setting_set --app=$app --key=redirect_type --value="$redirect_type"
}
set__frame_allowed() {
if [[ $frame_allowed == "0" ]]
then
frame_ancestors="'none'"
fi
}
set__frame_ancestors() {
if [[ $frame_allowed == "0" ]]
then
frame_ancestors="'none'"
fi
frame_ancestors="${frame_ancestors//,/ }"
ynh_app_setting_set --app=$app --key=frame_ancestors --value="$frame_ancestors"
}
#=================================================
# OVERWRITING APPLY STEP
#=================================================
ynh_app_config_apply() {
ynh_print_info --message="Override NGINX configuration"
_ynh_app_config_apply
cp ../conf/nginx-$redirect_type.conf ../conf/nginx.conf
# Create a dedicated NGINX config
ynh_add_nginx_config
}
ynh_app_config_run $1

View file

@ -25,9 +25,15 @@ domain=$YNH_APP_ARG_DOMAIN
path_url=$YNH_APP_ARG_PATH
redirect_type=$YNH_APP_ARG_REDIRECT_TYPE
redirect_path=$YNH_APP_ARG_REDIRECT_PATH
is_public=$YNH_APP_ARG_IS_PUBLIC
propagate_subpath=$(echo $YNH_APP_ARG_REDIRECT_TYPE | grep -q subpath && echo 1 || echo 0)
frame_ancestors="'none'"
client_max_body_size="1m"
# Check domain/path availability
ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url
#=================================================
# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS
#=================================================
ynh_script_progression --message="Validating installation parameters..." --weight=1
# Validate redirect path
url_regex='(https?|ftp|file)://[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=~_|]'
@ -39,44 +45,60 @@ url_regex='^(http://(127\.[0-9]+\.[0-9]+\.[0-9]+|localhost)|https://.*)(:[0-9]+)
[[ "$redirect_type" = "proxy" ]] && [[ ! $redirect_path =~ $url_regex ]] && ynh_die \
"For secure reason, you can't use an unencrypted http remote destination couple with ssowat for your reverse proxy: $redirect_path" 1
if [ $is_public -eq 0 ] && [[ $redirect_type != "proxy" ]]
then
is_public=1
YNH_APP_ARG_IS_PUBLIC=1
ynh_warn "HTTP private redirection are not supported. Your redirection has been reflagged as public."
fi
# Register (book) web path
ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url
#=================================================
# STORE SETTINGS FROM MANIFEST
#=================================================
ynh_script_progression --message="Storing installation settings..." --weight=1
# Save extra settings
ynh_app_setting_set --app=$app --key=redirect_type --value=$redirect_type
ynh_app_setting_set --app=$app --key=redirect_path --value=$redirect_path
ynh_app_setting_set --app=$app --key=is_public --value=$is_public
ynh_app_setting_set --app=$app --key=frame_ancestors --value="'none'"
ynh_app_setting_set --app=$app --key=client_max_body_size --value="1m"
#=================================================
# CONFIGURE NGINX
# SPECIFIC SETUP
#=================================================
ynh_script_progression --message="Preparing NGINX web server configuration..." --weight=1
cp ../conf/nginx-$redirect_type.conf ../conf/nginx.conf
#=================================================
#=================================================
# NGINX CONFIGURATION
#=================================================
ynh_script_progression --message="Configuring NGINX web server..." --weight=1
# Nginx configuration
for FILE in $(ls ../conf/nginx-*.conf)
do
ynh_replace_string "YNH_LOCATION" "$path_url" $FILE
done
if [ "$redirect_type" = "public_302" ];
then
ynh_replace_string "YNH_REDIRECT_PATH" "$redirect_path" ../conf/nginx-visible-302.conf
cp ../conf/nginx-visible-302.conf /etc/nginx/conf.d/$domain.d/$app.conf
elif [ "$redirect_type" = "public_301" ];
then
ynh_replace_string "YNH_REDIRECT_PATH" "$redirect_path" ../conf/nginx-visible-301.conf
cp ../conf/nginx-visible-301.conf /etc/nginx/conf.d/$domain.d/$app.conf
elif [ "$redirect_type" = "public_proxy" ] || [ "$redirect_type" = "private_proxy" ];
then
ynh_replace_string "YNH_REDIRECT_PATH" "$redirect_path" ../conf/nginx-proxy.conf
cp ../conf/nginx-proxy.conf /etc/nginx/conf.d/$domain.d/$app.conf
fi
# Create a dedicated NGINX config
ynh_add_nginx_config
#=================================================
# CONFIGURE SSOWAT
# SETUP SSOWAT
#=================================================
ynh_script_progression --message="Configuring permissions..." --weight=2
ynh_script_progression --message="Configuring permissions..." --weight=1
# Make app public if necessary
if [ "$redirect_type" != "private_proxy" ]
if [ $is_public -eq 1 ]
then
# unprotected_uris allows SSO credentials to be passed anyway.
ynh_permission_update --permission="main" --add="visitors"
# Everyone can access the app.
# The "main" permission is automatically created before the install script.
if [[ $redirect_type != "proxy" ]]
then
ynh_permission_update --permission="main" --add="visitors" --protected=1
else
ynh_permission_update --permission="main" --add="visitors"
fi
fi
#=================================================

View file

@ -25,6 +25,9 @@ domain=$(ynh_app_setting_get --app=$app --key=domain)
path_url=$(ynh_app_setting_get --app=$app --key=path)
redirect_type=$(ynh_app_setting_get --app=$app --key=redirect_type)
redirect_path=$(ynh_app_setting_get --app=$app --key=redirect_path)
frame_ancestors=$(ynh_app_setting_get --app=$app --key=frame_ancestors)
client_max_body_size=$(ynh_app_setting_get --app=$app --key=client_max_body_size)
is_public=$(ynh_app_setting_get --app=$app --key=is_public)
# Validate redirect path
url_regex='(https?|ftp|file)://[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=~_|]'
@ -42,10 +45,16 @@ ynh_restore_file "$NGINX_CONF"
#=================================================
# Make app public if necessary
if [ "$redirect_type" != "private_proxy" ]
if [ $is_public -eq 1 ]
then
# unprotected_uris allows SSO credentials to be passed anyway.
ynh_permission_update --permission="main" --add="visitors"
# Everyone can access the app.
# The "main" permission is automatically created before the install script.
if [[ $redirect_type != "proxy" ]]
then
ynh_permission_update --permission="main" --add="visitors" --protected=1
else
ynh_permission_update --permission="main" --add="visitors"
fi
fi
#=================================================

View file

@ -19,6 +19,34 @@ domain=$(ynh_app_setting_get --app=$app --key=domain)
path_url=$(ynh_app_setting_get --app=$app --key=path)
redirect_type=$(ynh_app_setting_get --app=$app --key=redirect_type)
redirect_path=$(ynh_app_setting_get --app=$app --key=redirect_path)
frame_ancestors=$(ynh_app_setting_get --app=$app --key=frame_ancestors)
client_max_body_size=$(ynh_app_setting_get --app=$app --key=client_max_body_size)
is_public=$(ynh_app_setting_get --app=$app --key=is_public)
#=================================================
# CHECK VERSION
#=================================================
### This helper will compare the version of the currently installed app and the version of the upstream package.
### $upgrade_type can have 2 different values
### - UPGRADE_APP if the upstream app version has changed
### - UPGRADE_PACKAGE if only the YunoHost package has changed
### ynh_check_app_version_changed will stop the upgrade if the app is up to date.
### UPGRADE_APP should be used to upgrade the core app only if there's an upgrade to do.
upgrade_type=$(ynh_check_app_version_changed)
#=================================================
# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP
#=================================================
# Backup the current version of the app
ynh_backup_before_upgrade
ynh_clean_setup () {
# restore it if the upgrade fails
ynh_restore_upgradebackup
}
# Exit if an error occurs during the execution of the script
ynh_abort_if_errors
#=================================================
# ENSURE DOWNWARD COMPATIBILITY
@ -47,13 +75,7 @@ then
is_public=1
fi
if [ "$redirect_type" == "proxy" ] && [ "$is_public" = "1" ]
then
redirect_type="public_proxy"
elif [ "$redirect_type" == "proxy" ] && [ "$is_public" = "0" ]
then
redirect_type="private_proxy"
elif [ "$redirect_type" == "visible_302" ]
if [ "$redirect_type" == "visible_302" ]
then
redirect_type="public_302"
elif [ "$redirect_type" == "visible_301" ]
@ -62,7 +84,7 @@ then
fi
ynh_app_setting_set $app 'redirect_type' $redirect_type
ynh_app_setting_set $app 'is_public'
ynh_app_setting_set $app 'is_public' $is_public
fi
# Migrate legacy permissions to new system
@ -73,18 +95,20 @@ then
ynh_app_setting_delete --app=$app --key=is_public
fi
#=================================================
# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP
#=================================================
# Introduce frame_ancestors
if [ -z "$frame_ancestors" ];
then
frame_ancestors="'none'"
ynh_app_setting_set $app 'frame_ancestors' $frame_ancestors
fi
# Introduce client_max_body_size
if [ -z "$client_max_body_size" ];
then
client_max_body_size="1m"
ynh_app_setting_set $app 'client_max_body_size' $client_max_body_size
fi
# Backup the current version of the app
ynh_backup_before_upgrade
ynh_clean_setup () {
# restore it if the upgrade fails
ynh_restore_upgradebackup
}
# Exit if an error occurs during the execution of the script
ynh_abort_if_errors
# Validate redirect path
url_regex='(https?|ftp|file)://[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=~_|]'
@ -95,33 +119,24 @@ url_regex='(https?|ftp|file)://[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=
#=================================================
# Nginx configuration
for FILE in $(ls ../conf/nginx-*.conf)
do
ynh_replace_string "YNH_LOCATION" "$path_url" $FILE
done
if [ "$redirect_type" = "public_302" ];
then
ynh_replace_string "YNH_REDIRECT_PATH" "$redirect_path" ../conf/nginx-visible-302.conf
cp ../conf/nginx-visible-302.conf /etc/nginx/conf.d/$domain.d/$app.conf
elif [ "$redirect_type" = "public_301" ];
then
ynh_replace_string "YNH_REDIRECT_PATH" "$redirect_path" ../conf/nginx-visible-301.conf
cp ../conf/nginx-visible-301.conf /etc/nginx/conf.d/$domain.d/$app.conf
elif [ "$redirect_type" = "public_proxy" ] || [ "$redirect_type" = "private_proxy" ];
then
ynh_replace_string "YNH_REDIRECT_PATH" "$redirect_path" ../conf/nginx-proxy.conf
cp ../conf/nginx-proxy.conf /etc/nginx/conf.d/$domain.d/$app.conf
fi
cp ../conf/nginx-$redirect_type.conf ../conf/nginx.conf
ynh_add_nginx_config
#=================================================
# CONFIGURE SSOWAT
#=================================================
# Make app public if necessary
if [ "$redirect_type" != "private_proxy" ]
if [ $is_public -eq 1 ]
then
# unprotected_uris allows SSO credentials to be passed anyway.
ynh_permission_update --permission="main" --add="visitors"
# Everyone can access the app.
# The "main" permission is automatically created before the install script.
if [[ $redirect_type != "proxy" ]]
then
ynh_permission_update --permission="main" --add="visitors" --protected=1
else
ynh_permission_update --permission="main" --add="visitors" --protected=0
fi
fi
#=================================================