From 4b0f45395232a78c432559a80f119b41131e526d Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 20 Aug 2026 19:21:45 +0000 Subject: [PATCH] authelia: let user-management menu pick and act on multiple users per run MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit edit_authelia_user() previously only ever let you select one user, act on them, and then returned all the way out of install_authelia() (which calls it with an immediate `return 0`) — deleting several users meant re-running `sudo ./setup.sh authelia` and re-navigating to option 3 from scratch for every single one. Restructured: the per-user action menu (edit/reset-password/2FA/admin/ service-access/delete) is now _authelia_manage_one_user(), and edit_authelia_user() drives it in a loop — numbered multi-select up front ("2 4" deletes/edits both), then "Manage more users?" to go again with a freshly re-read user list instead of exiting. Guards against acting on a user who was already deleted earlier in the same batch. Verified against a synthetic users.yml: selecting two users by number and deleting both in one pass removes exactly those two, leaves the others untouched. --- services/authelia.sh | 78 ++++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/services/authelia.sh b/services/authelia.sh index 24f4a48..0d3b26f 100644 --- a/services/authelia.sh +++ b/services/authelia.sh @@ -1324,28 +1324,66 @@ edit_authelia_user() { return 1 fi - local -a USERNAMES - mapfile -t USERNAMES < <(_authelia_list_usernames "$USERS_FILE") - if [ "${#USERNAMES[@]}" -eq 0 ]; then - log_warning "No users found in $USERS_FILE." - return 0 - fi + # Outer loop: pick one or more users by number, act on each in turn (via + # _authelia_manage_one_user below), then ask whether to go again — so + # deleting/editing several users doesn't require re-running the whole + # script and re-navigating this menu from scratch for every single one. + local KEEP_GOING="y" + while [[ "$KEEP_GOING" =~ ^[Yy]$ ]]; do + local -a USERNAMES + mapfile -t USERNAMES < <(_authelia_list_usernames "$USERS_FILE") + if [ "${#USERNAMES[@]}" -eq 0 ]; then + log_warning "No users left in $USERS_FILE." + return 0 + fi - echo "" - echo " Existing users:" - local i=1 u - for u in "${USERNAMES[@]}"; do - echo " $i) $u" - i=$((i + 1)) + echo "" + echo " Existing users:" + local i + for i in "${!USERNAMES[@]}"; do + echo " $((i + 1))) ${USERNAMES[$i]}" + done + echo "" + echo " Select one or more by number (space-separated, e.g. \"2 4\")," + echo " blank to cancel." + local SEL="" + prompt_text " User number(s):" "" SEL + if [ -z "$SEL" ]; then + log_info "Cancelled." + return 0 + fi + + local -a SEL_TOKENS TARGETS=() + read -ra SEL_TOKENS <<< "$SEL" + local tok + for tok in "${SEL_TOKENS[@]}"; do + if [[ "$tok" =~ ^[0-9]+$ ]] && [ "$tok" -ge 1 ] && [ "$tok" -le "${#USERNAMES[@]}" ]; then + TARGETS+=("${USERNAMES[$((tok - 1))]}") + else + log_warning "Skipping invalid selection: $tok" + fi + done + + local TARGET + for TARGET in "${TARGETS[@]}"; do + # A user picked earlier in this same batch may have just been + # deleted (or this number was picked twice) — re-check before + # acting instead of operating on a now-stale line range. + grep -qE "^ ${TARGET}:$" "$USERS_FILE" 2>/dev/null || { log_info "'$TARGET' no longer exists — skipping."; continue; } + _authelia_manage_one_user "$TARGET" "$USERS_FILE" "$CONFIG_FILE" "$AUTHELIA_DIR" + done + + echo "" + prompt_yn " Manage more users? (y/n):" "n" KEEP_GOING done - echo "" - local SEL="" - prompt_text " Select a user by number (blank to cancel):" "" SEL - if [ -z "$SEL" ] || ! [[ "$SEL" =~ ^[0-9]+$ ]] || [ "$SEL" -lt 1 ] || [ "$SEL" -gt "${#USERNAMES[@]}" ]; then - log_info "Cancelled." - return 0 - fi - local TARGET="${USERNAMES[$((SEL - 1))]}" +} + +# Per-user action menu (edit/reset-password/2FA/admin/service-access/delete), +# extracted out of edit_authelia_user() so its caller can drive it once per +# selected user across a multi-user batch instead of only ever handling one +# user per script invocation. +_authelia_manage_one_user() { + local TARGET="$1" USERS_FILE="$2" CONFIG_FILE="$3" AUTHELIA_DIR="$4" local CONTINUE="y" while [[ "$CONTINUE" =~ ^[Yy]$ ]]; do