From c7ed9b3aef1dadca04326a533f02dcf5ae6a43b9 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Fri, 23 May 2025 13:01:22 +0330 Subject: [PATCH] feat: add reset webpanel admin credentials --- core/cli.py | 22 +++++++++ core/cli_api.py | 12 +++++ core/scripts/webpanel/webpanel_shell.sh | 65 +++++++++++++++++++++++++ 3 files changed, 99 insertions(+) diff --git a/core/cli.py b/core/cli.py index 6672e5b..ab0c9f7 100644 --- a/core/cli.py +++ b/core/cli.py @@ -523,6 +523,28 @@ def get_web_panel_api_token(): except Exception as e: click.echo(f'{e}', err=True) +@cli.command('reset-webpanel-creds') +@click.option('--new-username', '-u', required=False, help='New admin username for WebPanel', type=str) +@click.option('--new-password', '-p', required=False, help='New admin password for WebPanel', type=str) +def reset_webpanel_creds(new_username: str | None, new_password: str | None): + """Resets the WebPanel admin username and/or password.""" + try: + if not new_username and not new_password: + raise click.UsageError('Error: You must provide either --new-username or --new-password, or both.') + + cli_api.reset_webpanel_credentials(new_username, new_password) + + message_parts = [] + if new_username: + message_parts.append(f"username to '{new_username}'") + if new_password: + message_parts.append("password") + + click.echo(f'WebPanel admin {" and ".join(message_parts)} updated successfully.') + click.echo('WebPanel service has been restarted.') + except Exception as e: + click.echo(f'{e}', err=True) + @cli.command('get-webpanel-services-status') def get_web_panel_services_status(): diff --git a/core/cli_api.py b/core/cli_api.py index d491288..834da6c 100644 --- a/core/cli_api.py +++ b/core/cli_api.py @@ -588,6 +588,18 @@ def get_webpanel_api_token() -> str | None: '''Gets the API token of WebPanel.''' return run_cmd(['bash', Command.SHELL_WEBPANEL.value, 'api-token']) +def reset_webpanel_credentials(new_username: str | None = None, new_password: str | None = None): + '''Resets the WebPanel admin username and/or password.''' + if not new_username and not new_password: + raise InvalidInputError('Error: At least new username or new password must be provided.') + + cmd_args = ['bash', Command.SHELL_WEBPANEL.value, 'resetcreds'] + if new_username: + cmd_args.extend(['-u', new_username]) + if new_password: + cmd_args.extend(['-p', new_password]) + + run_cmd(cmd_args) def get_services_status() -> dict[str, bool] | None: '''Gets the status of all project services.''' diff --git a/core/scripts/webpanel/webpanel_shell.sh b/core/scripts/webpanel/webpanel_shell.sh index 629d127..05c8200 100644 --- a/core/scripts/webpanel/webpanel_shell.sh +++ b/core/scripts/webpanel/webpanel_shell.sh @@ -3,6 +3,7 @@ source /etc/hysteria/core/scripts/utils.sh define_colors CADDY_CONFIG_FILE="/etc/hysteria/core/scripts/webpanel/Caddyfile" +WEBPANEL_ENV_FILE="/etc/hysteria/core/scripts/webpanel/.env" install_dependencies() { # Update system @@ -365,6 +366,65 @@ EOL fi } +reset_credentials() { + local new_username_val="" + local new_password_val="" + local changes_made=false + + if [ ! -f "$WEBPANEL_ENV_FILE" ]; then + echo -e "${red}Error: Web panel .env file not found. Is the web panel configured?${NC}" + exit 1 + fi + + OPTIND=1 + while getopts ":u:p:" opt; do + case $opt in + u) new_username_val="$OPTARG" ;; + p) new_password_val="$OPTARG" ;; + \?) echo -e "${red}Invalid option: -$OPTARG${NC}" >&2; exit 1 ;; + :) echo -e "${red}Option -$OPTARG requires an argument.${NC}" >&2; exit 1 ;; + esac + done + + if [ -z "$new_username_val" ] && [ -z "$new_password_val" ]; then + echo -e "${red}Error: At least one option (-u or -p ) must be provided.${NC}" + echo -e "${yellow}Usage: $0 resetcreds [-u new_username] [-p new_password]${NC}" + exit 1 + fi + + if [ -n "$new_username_val" ]; then + echo "Updating username to: $new_username_val" + if sudo sed -i "s|^ADMIN_USERNAME=.*|ADMIN_USERNAME=$new_username_val|" "$WEBPANEL_ENV_FILE"; then + changes_made=true + else + echo -e "${red}Failed to update username in $WEBPANEL_ENV_FILE${NC}" + exit 1 + fi + fi + + if [ -n "$new_password_val" ]; then + echo "Updating password..." + local new_password_hash=$(echo -n "$new_password_val" | sha256sum | cut -d' ' -f1) + if sudo sed -i "s|^ADMIN_PASSWORD=.*|ADMIN_PASSWORD=$new_password_hash|" "$WEBPANEL_ENV_FILE"; then + changes_made=true + else + echo -e "${red}Failed to update password in $WEBPANEL_ENV_FILE${NC}" + exit 1 + fi + fi + + if [ "$changes_made" = true ]; then + echo "Restarting web panel service to apply changes..." + if systemctl restart hysteria-webpanel.service; then + echo -e "${green}Web panel credentials updated successfully.${NC}" + else + echo -e "${red}Failed to restart hysteria-webpanel service. Please restart it manually.${NC}" + fi + else + echo -e "${yellow}No changes were specified.${NC}" + fi +} + show_webpanel_url() { source /etc/hysteria/core/scripts/webpanel/.env local webpanel_url="https://$DOMAIN:$PORT/$ROOT_PATH/" @@ -413,6 +473,10 @@ case "$1" in stopdecoy) stop_decoy_site ;; + resetcreds) + shift + reset_credentials "$@" + ;; url) show_webpanel_url ;; @@ -425,6 +489,7 @@ case "$1" in echo -e "${yellow}stop${NC}" echo -e "${yellow}decoy ${NC}" echo -e "${yellow}stopdecoy${NC}" + echo -e "${yellow} resetcreds [-u new_username] [-p new_password]${NC}" echo -e "${yellow}url${NC}" echo -e "${yellow}api-token${NC}" exit 1