fix: let voice/mute/kick/detach take --party

A host of two or more parties was told 'pass a name' by commands that
accepted no name flag, making moderation impossible. Mirrors the
--party flag invite already had.
This commit is contained in:
veg 2026-07-04 09:14:19 +00:00
parent 9117f73423
commit fc366f48fa
2 changed files with 71 additions and 22 deletions

66
party
View file

@ -1034,19 +1034,43 @@ EOF
echo "Invited $user to '$RR_PARTY_NAME'."
}
# Toggle a user's read/write status. $1 = subcommand label (for usage
# and the success message), $2 = server-access flag (-w voice, -r mute),
# $3 = past-participle for the message, $4 = $user.
_set_user_access() {
label="$1" flag="$2" verb="$3" user="$4"
[ -n "$user" ] || { echo "Usage: party $label <user>" >&2; exit 2; }
resolve_authoritative_party "" || exit 1
"$PARTY_TMUX" -S "$RR_SOCKET" server-access "$flag" "$user"
echo "$verb $user."
# Parse the "<user> [--party <name>]" argv shared by voice/mute/kick/
# detach. Sets mod_user and mod_party in the calling shell (POSIX sh
# has no locals; the mod_ prefix keeps them out of callers' way).
# Exits 2 on usage errors.
_parse_user_party() {
label="$1"; shift
mod_user='' mod_party=''
while [ $# -gt 0 ]; do
case "$1" in
--party)
[ $# -ge 2 ] || { echo "party $label: --party needs an argument" >&2; exit 2; }
mod_party="$2"; shift 2 ;;
-h|--help)
echo "Usage: party $label <user> [--party <name>]"; exit 0 ;;
-*) echo "party $label: unknown flag '$1'" >&2; exit 2 ;;
*)
if [ -z "$mod_user" ]; then mod_user="$1"; shift
else echo "party $label: unexpected arg '$1'" >&2; exit 2; fi
;;
esac
done
[ -n "$mod_user" ] || { echo "Usage: party $label <user> [--party <name>]" >&2; exit 2; }
}
cmd_voice() { _set_user_access voice -w Voiced "${1:-}"; }
cmd_mute() { _set_user_access mute -r Muted "${1:-}"; }
# Toggle a user's read/write status. $1 = subcommand label (for usage
# and the success message), $2 = server-access flag (-w voice, -r mute),
# $3 = past-participle for the message; the rest is the user's argv.
_set_user_access() {
label="$1" flag="$2" verb="$3"; shift 3
_parse_user_party "$label" "$@"
resolve_authoritative_party "$mod_party" || exit 1
"$PARTY_TMUX" -S "$RR_SOCKET" server-access "$flag" "$mod_user"
echo "$verb $mod_user."
}
cmd_voice() { _set_user_access voice -w Voiced "$@"; }
cmd_mute() { _set_user_access mute -r Muted "$@"; }
# Disconnect every client of $user on the resolved party socket and kill
# their guest session if present. Used by both cmd_kick and cmd_detach.
@ -1061,20 +1085,18 @@ _disconnect_user() {
}
cmd_kick() {
user="${1:-}"
[ -n "$user" ] || { echo "Usage: party kick <user>" >&2; exit 2; }
resolve_authoritative_party "" || exit 1
"$PARTY_TMUX" -S "$RR_SOCKET" server-access -d "$user" 2>/dev/null || true
_disconnect_user "$user"
echo "Kicked $user."
_parse_user_party kick "$@"
resolve_authoritative_party "$mod_party" || exit 1
"$PARTY_TMUX" -S "$RR_SOCKET" server-access -d "$mod_user" 2>/dev/null || true
_disconnect_user "$mod_user"
echo "Kicked $mod_user."
}
cmd_detach() {
user="${1:-}"
[ -n "$user" ] || { echo "Usage: party detach <user>" >&2; exit 2; }
resolve_authoritative_party "" || exit 1
_disconnect_user "$user"
echo "Detached $user (still on allowlist)."
_parse_user_party detach "$@"
resolve_authoritative_party "$mod_party" || exit 1
_disconnect_user "$mod_user"
echo "Detached $mod_user (still on allowlist)."
}
cmd_list() {

View file

@ -810,3 +810,30 @@ STUB
! grep -q "server-access -aw $USER" "$TMUX_LOG" || \
fail "should not have attempted -aw before capability check"
}
@test "moderation accepts --party to disambiguate multiple hosted parties" {
"$PARTY_BIN" host alpha
"$PARTY_BIN" host bravo
# Without --party: ambiguous, must refuse and say so.
run "$PARTY_BIN" kick nobody
[ "$status" -ne 0 ]
[[ "$output" == *"multiple parties"* ]]
# With --party: resolves, and the server-access -d lands on bravo's
# socket specifically.
: > "$TMUX_LOG"
run "$PARTY_BIN" kick nobody --party bravo
[ "$status" -eq 0 ]
grep "server-access -d nobody" "$TMUX_LOG" | grep -q "party-$USER:bravo.d/sock"
: > "$TMUX_LOG"
run "$PARTY_BIN" voice nobody --party alpha
[ "$status" -eq 0 ]
grep "server-access -w nobody" "$TMUX_LOG" | grep -q "party-$USER:alpha.d/sock"
run "$PARTY_BIN" mute nobody --party alpha
[ "$status" -eq 0 ]
run "$PARTY_BIN" detach nobody --party alpha
[ "$status" -eq 0 ]
}