feat: auto-select the gating group; 'party' becomes the fallback
Bare 'party host' now walks staff, users, wheel, party and gates on the first group the caller belongs to, announcing the pick. Boxes where people already share a system group need no setup; the curated 'party' group remains the fallback and the explicit --group / TMUX_PARTY_GROUP paths are unchanged. Caller membership is the only probe (id -nG, portable everywhere); whether a guest is a member stays an invite-time warning, where it can actually be answered.
This commit is contained in:
parent
22606ea55d
commit
7770289d85
6 changed files with 165 additions and 22 deletions
66
party
66
party
|
|
@ -16,9 +16,25 @@ PARTY_VERSION=0.1.0
|
|||
# `env -i` invocations). Every cmd_* path references it, so guarantee it
|
||||
# now via id -un rather than crashing later under set -eu.
|
||||
: "${USER:=$(id -un)}"
|
||||
: "${TMUX_PARTY_GROUP:=party}"
|
||||
# Group default. Remember whether the caller supplied TMUX_PARTY_GROUP
|
||||
# explicitly: cmd_host auto-selects a candidate group only when it was
|
||||
# not (an empty value counts as unset; an empty group name gates
|
||||
# nothing).
|
||||
if [ -n "${TMUX_PARTY_GROUP:-}" ]; then
|
||||
TMUX_PARTY_GROUP_EXPLICIT=1
|
||||
else
|
||||
TMUX_PARTY_GROUP_EXPLICIT=0
|
||||
TMUX_PARTY_GROUP=party
|
||||
fi
|
||||
: "${PARTY_SOCKET_DIR:=/tmp}"
|
||||
: "${PARTY_TMUX:=tmux}"
|
||||
# Candidate groups for hosting when none was named: the admin
|
||||
# convention ('staff', also every macOS user's primary group), the
|
||||
# classic shared-users group, the BSD admin group, then the
|
||||
# recommended custom group as the fallback. Caller membership is the
|
||||
# only test; whether *guests* are members is checked where it can
|
||||
# actually be answered, at invite time (cmd_invite warns).
|
||||
: "${PARTY_GROUP_CANDIDATES:=staff users wheel party}"
|
||||
|
||||
# Usage
|
||||
# =====
|
||||
|
|
@ -110,10 +126,28 @@ user_exists() {
|
|||
id -u "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Boolean: is user $1 a member of group $2 (supplementary or primary)?
|
||||
# id -nG is the one portable membership probe: no getent on macOS, no
|
||||
# dscl anywhere else, and it answers primary-GID membership too.
|
||||
user_in_group() {
|
||||
id -nG "$1" 2>/dev/null | tr ' ' '\n' | grep -qx "$2"
|
||||
}
|
||||
|
||||
# Boolean: is the named user in TMUX_PARTY_GROUP?
|
||||
user_in_party_group() {
|
||||
user="$1"
|
||||
id -nG "$user" 2>/dev/null | tr ' ' '\n' | grep -qx "$TMUX_PARTY_GROUP"
|
||||
user_in_group "$1" "$TMUX_PARTY_GROUP"
|
||||
}
|
||||
|
||||
# Print the first PARTY_GROUP_CANDIDATES entry the caller belongs to;
|
||||
# print nothing and return 1 when the caller is in none of them.
|
||||
pick_host_group() {
|
||||
for _pg_g in $PARTY_GROUP_CANDIDATES; do
|
||||
if user_in_group "$USER" "$_pg_g"; then
|
||||
printf '%s\n' "$_pg_g"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Soft assertion: caller is in TMUX_PARTY_GROUP. Fails loudly with
|
||||
|
|
@ -132,6 +166,9 @@ One-time setup (as root), your OS may differ:
|
|||
OpenBSD: groupadd $TMUX_PARTY_GROUP && usermod -G $TMUX_PARTY_GROUP $USER
|
||||
illumos: groupadd $TMUX_PARTY_GROUP && usermod -G $TMUX_PARTY_GROUP $USER
|
||||
Then log out and back in.
|
||||
|
||||
Or gate on any existing group you are already in:
|
||||
party host --group <group>
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -612,9 +649,10 @@ Usage: party host [name] [--group <name>]
|
|||
name Party name (default: random).
|
||||
--group <g> Group used to gate this party. The host must be a
|
||||
member; only members can discover or join. Precedence:
|
||||
--group flag > $TMUX_PARTY_GROUP env > default 'party'.
|
||||
Pick any existing group (e.g. 'staff', 'users', 'wheel');
|
||||
no install-time setup needed.
|
||||
--group flag > $TMUX_PARTY_GROUP env > auto-selection:
|
||||
the first of staff, users, wheel, party the host
|
||||
belongs to (candidate list overridable via
|
||||
$PARTY_GROUP_CANDIDATES).
|
||||
EOF
|
||||
exit 0 ;;
|
||||
-*)
|
||||
|
|
@ -626,14 +664,24 @@ EOF
|
|||
esac
|
||||
done
|
||||
|
||||
# Group precedence: --group flag > $TMUX_PARTY_GROUP env > default
|
||||
# 'party' (set by the env-defaults block at the top of the file).
|
||||
# The chosen group becomes the per-party perimeter: chgrp on the
|
||||
# Group precedence: --group flag > $TMUX_PARTY_GROUP env >
|
||||
# auto-selection over PARTY_GROUP_CANDIDATES ('party' is the last
|
||||
# candidate, a fallback rather than a hardcoded default). The
|
||||
# chosen group becomes the per-party perimeter: chgrp on the
|
||||
# private dir, on the socket, and on the roster. No shared install
|
||||
# directory, pick any existing group the host is in.
|
||||
if [ -n "$group_arg" ]; then
|
||||
TMUX_PARTY_GROUP="$group_arg"
|
||||
export TMUX_PARTY_GROUP
|
||||
elif [ "$TMUX_PARTY_GROUP_EXPLICIT" = 0 ]; then
|
||||
auto_group=$(pick_host_group || true)
|
||||
if [ -n "$auto_group" ]; then
|
||||
TMUX_PARTY_GROUP="$auto_group"
|
||||
export TMUX_PARTY_GROUP
|
||||
echo "party host: gating on group '$TMUX_PARTY_GROUP' (auto-selected; --group overrides)."
|
||||
fi
|
||||
# In none of the candidates: keep the 'party' default so
|
||||
# require_caller_in_group prints its remediation message.
|
||||
fi
|
||||
|
||||
require_caller_in_group
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue