-
Notifications
You must be signed in to change notification settings - Fork 0
refactor(airc-bash): extract cmd_kick #218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,82 @@ | ||||||||||||||||||||||
| # Sourced by airc. cmd_kick — host-only peer eviction. | ||||||||||||||||||||||
| # | ||||||||||||||||||||||
| # Function exported to airc's dispatch: | ||||||||||||||||||||||
| # cmd_kick — forcibly remove a paired peer (IRC /kick analog). | ||||||||||||||||||||||
| # Emits a system event, drops the peer's SSH pubkey from | ||||||||||||||||||||||
| # authorized_keys, deletes the peer file. The kicked | ||||||||||||||||||||||
| # peer's tail loop dies on the closed pipe; future SSH | ||||||||||||||||||||||
| # auth attempts fail because their key is gone. | ||||||||||||||||||||||
| # | ||||||||||||||||||||||
| # External cross-references (call-time): die, ensure_init, get_config_val, | ||||||||||||||||||||||
| # resolve_name, AIRC_HOME, AIRC_WRITE_DIR, MESSAGES. | ||||||||||||||||||||||
| # | ||||||||||||||||||||||
| # Extracted from airc as part of #152 Phase 3 file split. Standalone | ||||||||||||||||||||||
| # (not bundled with identity) because kick is host moderation, not | ||||||||||||||||||||||
| # identity — separating now also lets the identity bundle pull cleanly | ||||||||||||||||||||||
| # in the next PR. | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| cmd_kick() { | ||||||||||||||||||||||
| # Host-only: forcibly remove a paired peer. IRC analog: /kick <user>. | ||||||||||||||||||||||
| # Steps: emit a system event, drop their SSH pubkey from authorized_keys, | ||||||||||||||||||||||
| # remove the peer file. The kicked peer's tail loop dies on the closed | ||||||||||||||||||||||
| # pipe AND any future auth attempts fail because their key is gone from | ||||||||||||||||||||||
| # authorized_keys — they can't silently keep operating after a kick. | ||||||||||||||||||||||
| # They can re-pair via airc connect (no ban yet) — for that, see future | ||||||||||||||||||||||
| # `airc ban`. | ||||||||||||||||||||||
| ensure_init | ||||||||||||||||||||||
| local target="${1:-}" | ||||||||||||||||||||||
| [ -z "$target" ] && die "Usage: airc kick <peer> [reason]" | ||||||||||||||||||||||
| _validate_peer_name "$target" | ||||||||||||||||||||||
| shift || true | ||||||||||||||||||||||
| local reason="${*:-no reason given}" | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| # Joiner role check — kicking only makes sense as host. | ||||||||||||||||||||||
| local host_target; host_target=$(get_config_val host_target "") | ||||||||||||||||||||||
| if [ -n "$host_target" ]; then | ||||||||||||||||||||||
| die "kick: only the room host can kick. You are a joiner of $host_target — talk to the host." | ||||||||||||||||||||||
| fi | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| local peer_file="$PEERS_DIR/$target.json" | ||||||||||||||||||||||
| if [ ! -f "$peer_file" ]; then | ||||||||||||||||||||||
| die "kick: '$target' not in peers list (try: airc peers)" | ||||||||||||||||||||||
| fi | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| # Read the joiner's SSH pubkey from the peer JSON record (the host | ||||||||||||||||||||||
| # handshake stores it there — `<peer>.pub` holds the SIGNING pubkey, | ||||||||||||||||||||||
| # not the SSH auth key, so we can't use that file). Without this, | ||||||||||||||||||||||
| # kick would leave the joiner's SSH key in authorized_keys and the | ||||||||||||||||||||||
| # peer could keep authenticating despite the "kick" — caught by | ||||||||||||||||||||||
| # Copilot review on PR #73. | ||||||||||||||||||||||
| local peer_ssh_pub | ||||||||||||||||||||||
| peer_ssh_pub=$(PEER_FILE="$peer_file" "$AIRC_PYTHON" -c ' | ||||||||||||||||||||||
| import json, os | ||||||||||||||||||||||
| try: | ||||||||||||||||||||||
| p = json.load(open(os.environ["PEER_FILE"])) | ||||||||||||||||||||||
| print((p.get("ssh_pub") or "").strip()) | ||||||||||||||||||||||
| except Exception: | ||||||||||||||||||||||
| pass | ||||||||||||||||||||||
| ' 2>/dev/null || echo "") | ||||||||||||||||||||||
|
Comment on lines
+51
to
+58
|
||||||||||||||||||||||
| peer_ssh_pub=$(PEER_FILE="$peer_file" "$AIRC_PYTHON" -c ' | |
| import json, os | |
| try: | |
| p = json.load(open(os.environ["PEER_FILE"])) | |
| print((p.get("ssh_pub") or "").strip()) | |
| except Exception: | |
| pass | |
| ' 2>/dev/null || echo "") | |
| peer_ssh_pub=$(get_config_val_in "$peer_file" "ssh_pub" "") | |
| peer_ssh_pub=$(printf '%s' "$peer_ssh_pub" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "External cross-references" list appears stale/inaccurate for this extracted module: cmd_kick uses
_validate_peer_name,cmd_send,PEERS_DIR,AIRC_PYTHON, and$HOME/.ssh/authorized_keys, but does not referenceresolve_name,AIRC_HOME,AIRC_WRITE_DIR, orMESSAGES. Please update the list so future extraction/refactor work doesn’t rely on incorrect dependencies.