#!/bin/bash #================================================= # GENERIC STARTING #================================================= # IMPORT GENERIC HELPERS #================================================= source _common.sh source /usr/share/yunohost/helpers #================================================= # RETRIEVE ARGUMENTS #================================================= app=$YNH_APP_INSTANCE_NAME final_path=$(ynh_app_setting_get $app final_path) #================================================= # SPECIFIC CODE #================================================= # DECLARE GENERIC FUNCTION #================================================= lowerdot_to_uppersnake() { local lowerdot lowerdot=$(echo "$1" | cut -d= -f1 | sed "s/\./_/g") echo "${lowerdot^^}" } _ynh_panel_get() { # From settings local params_sources params_sources=`python << EOL import toml from collections import OrderedDict with open("/etc/yunohost/apps/vpnclient/config_panel.toml", "r") as f: file_content = f.read() loaded_toml = toml.loads(file_content, _dict=OrderedDict) for panel_name,panel in loaded_toml.items(): if isinstance(panel, dict): for section_name, section in panel.items(): if isinstance(section, dict): for name, param in section.items(): if isinstance(param, dict) and param.get('source', '') == 'settings': print("%s.%s.%s=%s" %(panel_name, section_name, name, param.get('source', 'settings'))) EOL ` for param_source in params_sources do local _dot_setting=$(echo "$param_source" | cut -d= -f1) local _snake_setting="YNH_CONFIG_$(lowerdot_to_uppersnake $dot_setting)" local short_setting=$(echo "$_dot_setting" | cut -d. -f3) local _getter="get__${short_setting}" local source="$(echo $param_source | cut -d= -f2)" # Get value from getter if exists if type $getter | grep -q '^function$' 2>/dev/null; then old[$short_setting]="$($getter)" # elif [[ "$source" != "settings" ]] then old[$short_setting]="$source" # By default, get value from settings.yml else old[$short_setting]="$(ynh_app_setting_get $app $short_setting)" fi done } _ynh_panel_apply() { for short_setting in "${!dot_settings[@]}" do local setter="set__${short_setting}" local source="$sources[$short_setting]" # Apply setter if exists if type $setter | grep -q '^function$' 2>/dev/null; then $setter # Copy file in right place elif [[ "$source" != "settings" ]] then cp "$new[$short_setting]" "$source" # By default, set value into settings.yml else ynh_app_setting_get $app $short_setting "$new[$short_setting]" fi done } _ynh_panel_show() { for short_setting in "${!old[@]}" do local key="YNH_CONFIG_$(lowerdot_to_uppersnake $dot_settings[$short_setting])" ynh_return "$key=${old[$short_setting]}" done } _ynh_panel_validate() { # Change detection local is_error=true #for changed_status in "${!changed[@]}" for short_setting in "${!dot_settings[@]}" do #TODO file hash file_hash[$setting]=$(sha256sum "$_source" | cut -d' ' -f1) file_hash[$form_setting]=$(sha256sum "${!form_setting}" | cut -d' ' -f1) if [[ "${file_hash[$setting]}" != "${file_hash[$form_setting]}" ]] then changed[$setting]=true fi if [[ "$new[$short_setting]" == "$old[$short_setting]" ]] then changed[$short_setting]=false else changed[$short_setting]=true is_error=false fi done # Run validation if something is changed if [[ "$is_error" == "false" ]] then for short_setting in "${!dot_settings[@]}" do local result="$(validate__$short_setting)" local key="YNH_ERROR_$(lowerdot_to_uppersnake $dot_settings[$short_setting])" if [ -n "$result" ] then ynh_return "$key=$result" is_error=true fi done fi if [[ "$is_error" == "true" ]] then ynh_die fi } ynh_panel_init() { declare -A old=() declare -A changed=() declare -A file_hash=() ynh_panel_get } ynh_panel_show() { _ynh_panel_show } ynh_panel_validate() { _ynh_panel_validate } ynh_panel_apply() { _ynh_panel_apply } #================================================= # SPECIFIC GETTERS FOR TOML SHORT KEY #================================================= get__status() { if [ -f "/sys/class/net/tun0/operstate" ] && [ "$(cat /sys/class/net/tun0/operstate)" == "up" ] then echo "running" else echo "not running" fi } get__login_user() { if [ -s /etc/openvpn/keys/credentials ] then sed -n 1p /etc/openvpn/keys/credentials fi } get__login_passphrase() { if [ -s /etc/openvpn/keys/credentials ] then sed -n 2p /etc/openvpn/keys/credentials fi } #================================================= # SPECIFIC VALIDATORS FOR TOML SHORT KEYS #================================================= validate__login_user() { [[ -n "$login_passphrase" && -z "$login_user" ]] && echo 'A Username is needed when you suggest a Password' } validate__login_passphrase() { [[ -n "$login_user" && -z "$login_passphrase" ]] && echo 'A Password is needed when you suggest a Username' } validate__crt() { [[ -n "$key" && -z "$crt" ]] && echo "A Client Certificate is needed when you suggest a Key" } validate__key() { [[ -n "$crt" && -z "$key" ]] && echo "A Key is needed when you suggest a Client Certificate" } # TODO validate__server_ip6() { $ipv6_expanded=$(ipv6_expanded "$server_ip6") if [[ -z "$ipv6_expanded" ]] then echo 'The IPv6 Delegated Prefix format looks bad' fi # $ip6_blocs = explode(':', $ip6_net); # $ip6_addr = "${ip6_blocs[0]}:${ip6_blocs[1]}:${ip6_blocs[2]}:${ip6_blocs[3]}:${ip6_blocs[4]}:${ip6_blocs[5]}:${ip6_blocs[6]}:42"; # $ip6_net = ipv6_compressed($ip6_net); # $ip6_addr = ipv6_compressed($ip6_addr); } #================================================= # SPECIFIC SETTERS FOR TOML SHORT KEYS #================================================= set__login_user() { if [ -z "$login_user" ] then echo "$login_user\n$login_passphrase" > /etc/openvpn/keys/credentials else echo "" > /etc/openvpn/keys/credentials fi } set__login_passphrase() { : } # TODO set__cube_file() { if [ -f "$cube_file" ] then cp -f $tmp_dir/client.conf.tpl /etc/openvpn/client.conf.tpl fi } #================================================= # OVERWRITING VALIDATE STEP #================================================= ynh_panel_validate() { # Overwrite form response with cube files data before validation process if [[ "$cube_file" ]] then # TODO declare -A settings settings[server_name]="" settings[server_port]="" settings[server_proto]="" settings[login_user]="" settings[login_passphrase]="" settings[dns0]="" settings[dns1]="" settings[crt_server_ca]="file" settings[crt_client]="file" settings[crt_client_key]="file" settings[crt_client_ta]="file" tmp_dir=$(dirname "$cube_file") for setting_name in "${!settings[@]}" do setting_value="$(jq --raw-output '.$setting_name' '$cube_file')" if [[ "$setting_value" == "null" ]] then setting_value='' # Save file in tmp dir elif [[ "${settings[$setting_name]}" == "file" ]] then echo "${settings[$setting_name]}" | sed s/|/\n/g > $tmp_dir/$setting_name setting_value="$tmp_dir/$setting_name" fi # Change settings value and changed status if needed if [[ "$setting_value" != "${!setting}" ]] then declare "$setting='$setting_value'" changed[$setting]=false if [[ "$setting_value" != "${old[$setting]}" ]] then changed[$setting]=true fi fi done # Build specific OVPN template cp -f /etc/openvpn/client.conf.tpl.restore $tmp_dir/client.conf.tpl # Remove some lines for rm_regex in "$(jq --raw-output '.openvpn_rm[]' '$cube_file')" do sed -i "/$rm_regex/di" $tmp_dir/client.conf.tpl done # Add some other lines echo "# Custom" >> $tmp_dir/client.conf.tpl jq --raw-output ".openvpn_add[]" "$cube_file" >> $tmp_dir/client.conf.tpl fi _ynh_panel_validate } #================================================= # OVERWRITING APPLY STEP #================================================= ynh_panel_apply() { # Stop vpn client touch /tmp/.ynh-vpnclient-stopped systemctl stop ynh-vpnclient _ynh_panel_apply # Start vpn client systemctl start ynh-vpnclient rm -f /tmp/.ynh-vpnclient-stopped } #================================================= # GENERIC FINALIZATION #================================================= # Please don't change that code. # You can overwrite these functions if you need it #================================================= ynh_panel_init case $1 in show) ynh_panel_show;; apply) ynh_panel_validate && ynh_panel_apply;; esac