#!/usr/bin/bash
# access-matrix.sh — definitive access verification across all Linux Tailscale nodes.
# Uses the correct SSH user(s) per system type, checks sudo where applicable.
# Routes through remote.sh (the only allowed ssh path).
set -u
cd /home/reachableceo/projects/PFVCluster || exit 1

# Policy-excluded systems (never attempt access)
EXCLUDE=':tsys-cloudron:pfv-bms:tsys-umbrel:tsys-ucs-01:tsys-ucs-02:stlpc-bizoffice:ultix-highside:'

# Determine the SSH user(s) for a given hostname and whether sudo is expected.
# Returns "user1:user2:...:sudoflag" where sudoflag is "yes" or "no".
users_for() {
  local name="$1"
  case "$name" in
    pfv-tsys[0-9])                   echo "root:no" ;;
    *-proxmox-datacenter)            echo "root:no" ;;
    *-proxmox-pve)                   echo "root:no" ;;
    *-proxmox-pbs)                   echo "root:no" ;;
    *-proxmox-mailgw*)               echo "root:no" ;;
    *-proxmox-backup*)               echo "root:no" ;;
    tsys-ucs-*)                      echo "root:no" ;;
    ultix-streaming)                 echo "root:no" ;;
    stlpc-*)                         echo "root:labuser:no" ;;
    ultix-field)                     echo "ultixfield:yes" ;;
    subopi*)                         echo "subodev:yes" ;;
    *)                               echo "localuser:yes" ;;
  esac
}

check_user() {
  local ip="$1" user="$2" expect_sudo="$3"
  local out sudo
  out=$(VM_IP="$ip" VM_USER="$user" bash tests/remote.sh vm 'echo SSHOK; id -un' </dev/null 2>&1 | grep -oE 'SSHOK|keyboard-interactive|Connection refused' | head -1)
  case "$out" in
    SSHOK)
      if [ "$expect_sudo" = "yes" ]; then
        sudo=$(VM_IP="$ip" VM_USER="$user" bash tests/remote.sh vm 'sudo -n true 2>/dev/null && echo SUDOOK || echo SUDONO' </dev/null 2>&1 | grep -oE 'SUDOOK|SUDONO' | head -1)
        printf '%s(%s)' "$user" "${sudo:-?}"
      else
        printf '%s(ok)' "$user"
      fi
      ;;
    keyboard-interactive) printf '%s(2FA)' "$user" ;;
    'Connection refused')  printf '%s(NOSSH)' "$user" ;;
    *)                      printf '%s(NOKEY)' "$user" ;;
  esac
}

printf '%-32s %-16s %s\n' "NAME" "TS-IP" "ACCESS"
printf '%-32s %-16s %s\n' "----" "-----" "------"

tailscale status 2>/dev/null | awk '$4=="linux" {print $2, $1}' | sort | while read -r name ip; do
  [ -n "$name" ] || continue
  case "$EXCLUDE" in *":$name:"*) printf '%-32s %-16s %s\n' "$name" "$ip" "EXCLUDED"; continue;; esac

  map=$(users_for "$name")
  expect_sudo="${map##*:}"
  users="${map%:*}"
  result=""
  IFS=':' read -ra user_list <<< "$users"
  for u in "${user_list[@]}"; do
    r=$(check_user "$ip" "$u" "$expect_sudo")
    [ -z "$result" ] && result="$r" || result="$result $r"
  done
  printf '%-32s %-16s %s\n' "$name" "$ip" "$result"
done
