#!/usr/bin/env bash
# policy: usr_block-binary — prevent IPA user group members from running named binaries.
# usr_block-binary-<name>: installs a PATH-priority wrapper that checks group membership
# at runtime via SSSD/id.  __ in the suffix decodes to . (Flatpak app ID support).
# Removing the IPA group causes the wrapper to be cleaned up on the next run.

BLOCK_STATE="$STATE_DIR/blocked-binaries"
[[ -f "$BLOCK_STATE" ]] || touch "$BLOCK_STATE"

_in_block_list() {
    local needle="$1"
    for b in "${ACTIVE_BLOCK_BINARIES[@]+"${ACTIVE_BLOCK_BINARIES[@]}"}"; do
        [[ "$b" == "$needle" ]] && return 0
    done
    return 1
}

for _idx in "${!ACTIVE_BLOCK_BINARIES[@]}"; do
    BIN="${ACTIVE_BLOCK_BINARIES[$_idx]}"
    IPA_GRP="${ACTIVE_BLOCK_IPA_GROUPS[$_idx]}"
    WRAPPER="$BLOCK_DIR/$BIN"
    if [[ ! -f "$WRAPPER" ]] \
        || ! grep -q "blocked by ansipa policy" "$WRAPPER" 2>/dev/null \
        || ! grep -qF "$IPA_GRP" "$WRAPPER" 2>/dev/null; then
        log "Installing user-aware block wrapper: $BIN (group: $IPA_GRP)"
        cat > "$WRAPPER" <<WRAPPER
#!/bin/bash
# blocked by ansipa policy (user-based)
if id -Gn 2>/dev/null | tr ' ' '\n' | grep -qxF "${IPA_GRP}"; then
    echo "[ansipa-policies] '${BIN}' is blocked by system policy for your account." >&2
    exit 1
fi
_real=\$(PATH="/usr/bin:/usr/sbin:/bin:/sbin:/usr/local/sbin:/opt/bin:/var/lib/flatpak/exports/bin:/usr/share/flatpak/exports/bin" command -v "${BIN}" 2>/dev/null)
[[ -n "\$_real" ]] && exec "\$_real" "\$@"
command -v flatpak &>/dev/null && exec flatpak run "${BIN}" "\$@" 2>/dev/null
echo "${BIN}: command not found" >&2
exit 127
WRAPPER
        chmod 755 "$WRAPPER"
    fi
done
unset _idx

# Remove wrappers whose IPA user group no longer exists.
while IFS= read -r OLD_BIN; do
    [[ -z "$OLD_BIN" ]] && continue
    if ! _in_block_list "$OLD_BIN"; then
        WRAPPER="$BLOCK_DIR/$OLD_BIN"
        if [[ -f "$WRAPPER" ]] && grep -q "blocked by ansipa policy" "$WRAPPER" 2>/dev/null; then
            rm -f "$WRAPPER"
            log "Removed binary block wrapper: $OLD_BIN"
        fi
    fi
done < "$BLOCK_STATE"

if [[ ${#ACTIVE_BLOCK_BINARIES[@]} -gt 0 ]]; then
    printf '%s\n' "${ACTIVE_BLOCK_BINARIES[@]}" | sort -u > "$BLOCK_STATE"
else
    > "$BLOCK_STATE"
fi
unset BIN IPA_GRP WRAPPER OLD_BIN
