From 14628e537ddb856a57223a5aefdb9a927266976c Mon Sep 17 00:00:00 2001 From: Julien Terzibaschian Date: Sat, 5 Oct 2024 12:19:48 +0200 Subject: [PATCH] feat: initial commit --- justfile | 6 +++ settings.yml | 76 ++++++++++++++++++++++++++++++++++ src/bashly.yml | 34 +++++++++++++++ src/connect_command.sh | 14 +++++++ src/disconnect_command.sh | 1 + src/get_ip_command.sh | 1 + src/header.sh | 13 ++++++ src/lib/colors.sh | 42 +++++++++++++++++++ src/lib/country_codes.sh | 17 ++++++++ src/lib/filter_enforce_root.sh | 15 +++++++ 10 files changed, 219 insertions(+) create mode 100644 justfile create mode 100644 settings.yml create mode 100644 src/bashly.yml create mode 100644 src/connect_command.sh create mode 100644 src/disconnect_command.sh create mode 100644 src/get_ip_command.sh create mode 100644 src/header.sh create mode 100644 src/lib/colors.sh create mode 100644 src/lib/country_codes.sh create mode 100644 src/lib/filter_enforce_root.sh diff --git a/justfile b/justfile new file mode 100644 index 0000000..33232c9 --- /dev/null +++ b/justfile @@ -0,0 +1,6 @@ +default: + @just --list +generate: + @just bashly generate +bashly command="generate": + docker run --rm -it --user $(id -u):$(id -g) --volume "$PWD:/app" dannyben/bashly {{command}} diff --git a/settings.yml b/settings.yml new file mode 100644 index 0000000..55fe18b --- /dev/null +++ b/settings.yml @@ -0,0 +1,76 @@ +# All settings are optional (with their default values provided below), and +# can also be set with an environment variable with the same name, capitalized +# and prefixed by `BASHLY_` - for example: BASHLY_SOURCE_DIR +# +# When setting environment variables, you can use: +# - "0", "false" or "no" to represent false +# - "1", "true" or "yes" to represent true +# +# If you wish to change the path to this file, set the environment variable +# BASHLY_SETTINGS_PATH. + +# The path containing the bashly source files +source_dir: src + +# The path to bashly.yml +config_path: "%{source_dir}/bashly.yml" + +# The path to use for creating the bash script +target_dir: . + +# The path to use for common library files, relative to source_dir +lib_dir: lib + +# The path to use for command files, relative to source_dir +# When set to nil (~), command files will be placed directly under source_dir +# When set to any other string, command files will be placed under this +# directory, and each command will get its own subdirectory +commands_dir: ~ + +# Configure the bash options that will be added to the initialize function: +# strict: true Bash strict mode (set -euo pipefail) +# strict: false Only exit on errors (set -e) +# strict: '' Do not add any 'set' directive +# strict: Add any other custom 'set' directive +strict: false + +# When true, the generated script will use tab indentation instead of spaces +# (every 2 leading spaces will be converted to a tab character) +tab_indent: false + +# When true, the generated script will consider any argument in the form of +# `-abc` as if it is `-a -b -c`. +compact_short_flags: true + +# When true, the generated script will consider any argument in the form of +# `--flag=value` and `-f=value` as if it is `--flag value` and `-f value` +# respectively. +conjoined_flag_args: true + +# Set to 'production' or 'development': +env: production # Generate a smaller script, without file markers +# env: development # Generate with file markers + +# The extension to use when reading/writing partial script snippets +partials_extension: sh + +# Show command examples (if any) whenever the user does not provide the +# required arguments +show_examples_on_error: true + +# When using private commands, flags, or environment variables, you may set +# this option to a name of an environment variable that, if set, will reveal +# all the private elements in the usage texts, as if they were public. +private_reveal_key: ~ + +# Display various usage elements in color by providing the name of the color +# function. The value for each property is a name of a function that is +# available in your script, for example: `green` or `bold`. +# You can run `bashly add colors` to add a standard colors library. +# This option cannot be set via environment variables. +usage_colors: + caption: bold + command: green_underlined + arg: blue + flag: magenta + environment_variable: cyan_bold diff --git a/src/bashly.yml b/src/bashly.yml new file mode 100644 index 0000000..6587855 --- /dev/null +++ b/src/bashly.yml @@ -0,0 +1,34 @@ +name: cgw +help: CyberghostVPN Wrapper CLI +version: 0.1.0 +extensible: cyberghostvpn + +dependencies: + curl: install with $(green "apt install curl") + cyberghostvpn: + +commands: + - name: connect + alias: c + help: Connect to a VPN at specified location + + args: + - name: countrycode + required: false + help: "Country code to connect to (default: current country)" + + examples: + - cgw connect + - cgw connect US + - cgw connect DE + filters: + - enforce_root + + - name: disconnect + alias: d + help: Disconnect from VPN + filters: + - enforce_root + - name: get-ip + alias: gi + help: Get your public IP address diff --git a/src/connect_command.sh b/src/connect_command.sh new file mode 100644 index 0000000..24572a5 --- /dev/null +++ b/src/connect_command.sh @@ -0,0 +1,14 @@ +# echo "# this file is located in 'src/connect_command.sh'" +# echo "# code for 'cgw connect' goes here" +# echo "# you can edit it freely and regenerate (it will not be overwritten)" +# inspect_args + +cc=${args[countrycode]} + +if [[ -z "$cc" ]]; then + cc="$(get_current_country_code)" +fi + +check_country_code "$cc" + +"${deps[cyberghostvpn]}" --country-code "$cc" --connect diff --git a/src/disconnect_command.sh b/src/disconnect_command.sh new file mode 100644 index 0000000..877bf34 --- /dev/null +++ b/src/disconnect_command.sh @@ -0,0 +1 @@ +"${deps[cyberghostvpn]}" --disconnect diff --git a/src/get_ip_command.sh b/src/get_ip_command.sh new file mode 100644 index 0000000..bbbae4b --- /dev/null +++ b/src/get_ip_command.sh @@ -0,0 +1 @@ +"${deps[curl]}" -s ip-api.com diff --git a/src/header.sh b/src/header.sh new file mode 100644 index 0000000..ccb815f --- /dev/null +++ b/src/header.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# This wrapper is meant for an easier use of CyberghostVPN +# It is not meant to be used as a standalone script + +if [[ "${BASH_VERSINFO:-0}" -lt 4 ]]; then + printf "bash version 4 or higher is required\n" >&2 + exit 1 +fi + +# Enforce Root, because cyberghost-vpn requires root +if [[ $EUID -ne 0 ]]; then + exec sudo "$0" "$@" +fi diff --git a/src/lib/colors.sh b/src/lib/colors.sh new file mode 100644 index 0000000..cbdc015 --- /dev/null +++ b/src/lib/colors.sh @@ -0,0 +1,42 @@ +## Color functions [@bashly-upgrade colors] +## This file is a part of Bashly standard library +## +## Usage: +## Use any of the functions below to color or format a portion of a string. +## +## echo "before $(red this is red) after" +## echo "before $(green_bold this is green_bold) after" +## +## Color output will be disabled if `NO_COLOR` environment variable is set +## in compliance with https://no-color.org/ +## +print_in_color() { + local color="$1" + shift + if [[ -z ${NO_COLOR+x} ]]; then + printf "$color%b\e[0m\n" "$*" + else + printf "%b\n" "$*" + fi +} + +red() { print_in_color "\e[31m" "$*"; } +green() { print_in_color "\e[32m" "$*"; } +yellow() { print_in_color "\e[33m" "$*"; } +blue() { print_in_color "\e[34m" "$*"; } +magenta() { print_in_color "\e[35m" "$*"; } +cyan() { print_in_color "\e[36m" "$*"; } +bold() { print_in_color "\e[1m" "$*"; } +underlined() { print_in_color "\e[4m" "$*"; } +red_bold() { print_in_color "\e[1;31m" "$*"; } +green_bold() { print_in_color "\e[1;32m" "$*"; } +yellow_bold() { print_in_color "\e[1;33m" "$*"; } +blue_bold() { print_in_color "\e[1;34m" "$*"; } +magenta_bold() { print_in_color "\e[1;35m" "$*"; } +cyan_bold() { print_in_color "\e[1;36m" "$*"; } +red_underlined() { print_in_color "\e[4;31m" "$*"; } +green_underlined() { print_in_color "\e[4;32m" "$*"; } +yellow_underlined() { print_in_color "\e[4;33m" "$*"; } +blue_underlined() { print_in_color "\e[4;34m" "$*"; } +magenta_underlined() { print_in_color "\e[4;35m" "$*"; } +cyan_underlined() { print_in_color "\e[4;36m" "$*"; } diff --git a/src/lib/country_codes.sh b/src/lib/country_codes.sh new file mode 100644 index 0000000..84b3830 --- /dev/null +++ b/src/lib/country_codes.sh @@ -0,0 +1,17 @@ +get_current_country_code() { + local country_code + country_code="$(${deps[curl]} -s https://ipinfo.io/country)" + echo "${country_code}" +} + +check_country_code() { + COUNTRY_CODE="$1" + + # Check validity of country code + COUNTRY_CODE_LIST=$(${deps[cyberghostvpn]} --country-code | grep -c "$COUNTRY_CODE") + # This is a markdown list with three items per line where the last item is the country code + if [ ! "$COUNTRY_CODE_LIST" -eq 1 ]; then + echo "Invalid country code: $COUNTRY_CODE" 1>&2 + exit 1 + fi +} diff --git a/src/lib/filter_enforce_root.sh b/src/lib/filter_enforce_root.sh new file mode 100644 index 0000000..bea7c59 --- /dev/null +++ b/src/lib/filter_enforce_root.sh @@ -0,0 +1,15 @@ +## Add any function here that is needed in more than one parts of your +## application, or that you otherwise wish to extract from the main function +## scripts. +## +## Note that code here should be wrapped inside bash functions, and it is +## recommended to have a separate file for each function. +## +## Subdirectories will also be scanned for *.sh, so you have no reason not +## to organize your code neatly. +## +filter_enforce_root() { + if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root" + fi +}