257 lines
No EOL
8.1 KiB
Bash
257 lines
No EOL
8.1 KiB
Bash
#!/usr/bin/env bash
|
|
# ui/rule.module.sh — rendering for rule data
|
|
# Replaces rule::render_* functions from rule.module.sh.
|
|
# All functions pure rendering — no writes, no state changes.
|
|
|
|
# ======================================================
|
|
# Entry Rendering (shared primitives)
|
|
# ======================================================
|
|
|
|
# ui::rule::entries <rule_name> [indent]
|
|
# Renders the fully resolved entries for a rule (allow + block).
|
|
function ui::rule::entries() {
|
|
local rule_name="${1:-}" indent="${2:-4}"
|
|
|
|
local allow_ports allow_ips block_ips block_ports dns
|
|
allow_ports=$(rule::get "$rule_name" "allow_ports" 2>/dev/null || true)
|
|
allow_ips=$(rule::get "$rule_name" "allow_ips" 2>/dev/null || true)
|
|
block_ips=$(rule::get "$rule_name" "block_ips" 2>/dev/null || true)
|
|
block_ports=$(rule::get "$rule_name" "block_ports" 2>/dev/null || true)
|
|
dns=$(rule::get_own "$rule_name" "dns_redirect")
|
|
|
|
while IFS= read -r e; do
|
|
[[ -z "$e" ]] && continue
|
|
net::print_entry "+" "$e" "$indent"
|
|
done <<< "$allow_ports"$'\n'"$allow_ips"
|
|
|
|
while IFS= read -r e; do
|
|
[[ -z "$e" ]] && continue
|
|
net::print_entry "-" "$e" "$indent"
|
|
done <<< "$block_ips"$'\n'"$block_ports"
|
|
|
|
[[ "${dns,,}" == "true" ]] && \
|
|
net::print_dns_redirect "$(config::dns)" 6 "DNS"
|
|
}
|
|
|
|
# ui::rule::own_entries <rule_name> [indent]
|
|
# Renders only the rule's own (non-inherited) entries.
|
|
function ui::rule::own_entries() {
|
|
local rule_name="${1:-}" indent="${2:-4}"
|
|
local rule_file
|
|
rule_file="$(rule::path "$rule_name")" || return 0
|
|
[[ -z "$rule_file" ]] && return 0
|
|
|
|
local allow_ports allow_ips block_ips block_ports dns
|
|
allow_ports=$(json::get "$rule_file" "allow_ports" 2>/dev/null || true)
|
|
allow_ips=$(json::get "$rule_file" "allow_ips" 2>/dev/null || true)
|
|
block_ips=$(json::get "$rule_file" "block_ips" 2>/dev/null || true)
|
|
block_ports=$(json::get "$rule_file" "block_ports" 2>/dev/null || true)
|
|
dns=$(json::get "$rule_file" "dns_redirect" 2>/dev/null || true)
|
|
|
|
local combined="${allow_ports}${allow_ips}${block_ips}${block_ports}"
|
|
[[ -z "${combined//[$'\n']/}" ]] && return 0
|
|
|
|
while IFS= read -r e; do
|
|
[[ -z "$e" ]] && continue
|
|
net::print_entry "+" "$e" "$indent"
|
|
done <<< "$allow_ports"$'\n'"$allow_ips"
|
|
|
|
while IFS= read -r e; do
|
|
[[ -z "$e" ]] && continue
|
|
net::print_entry "-" "$e" "$indent"
|
|
done <<< "$block_ips"$'\n'"$block_ports"
|
|
|
|
[[ "${dns,,}" == "true" ]] && \
|
|
net::print_dns_redirect "$(config::dns)" 6 "DNS"
|
|
}
|
|
|
|
# ui::rule::flat <rule_name>
|
|
# Renders the full resolved entries as a flat list.
|
|
function ui::rule::flat() {
|
|
local rule_name="${1:-}"
|
|
|
|
local allow_ports allow_ips block_ips block_ports dns
|
|
allow_ports=$(rule::get "$rule_name" "allow_ports")
|
|
allow_ips=$(rule::get "$rule_name" "allow_ips")
|
|
block_ips=$(rule::get "$rule_name" "block_ips")
|
|
block_ports=$(rule::get "$rule_name" "block_ports")
|
|
dns=$(rule::get_own "$rule_name" "dns_redirect")
|
|
|
|
local has_content=false
|
|
[[ -n "${allow_ports}${allow_ips}${block_ips}${block_ports}" ]] && has_content=true
|
|
|
|
if ! $has_content; then
|
|
printf "\n full access (no restrictions)\n"
|
|
return 0
|
|
fi
|
|
|
|
if [[ -n "$allow_ports" || -n "$allow_ips" ]]; then
|
|
printf "\n"
|
|
while IFS= read -r e; do
|
|
[[ -z "$e" ]] && continue
|
|
net::print_entry "+" "$e" 2
|
|
done <<< "$allow_ports"$'\n'"$allow_ips"
|
|
fi
|
|
|
|
if [[ -n "$block_ips" || -n "$block_ports" ]]; then
|
|
printf "\n"
|
|
while IFS= read -r e; do
|
|
[[ -z "$e" ]] && continue
|
|
net::print_entry "-" "$e" 2
|
|
done <<< "$block_ips"$'\n'"$block_ports"
|
|
fi
|
|
|
|
[[ "${dns,,}" == "true" ]] && \
|
|
net::print_dns_redirect "$(config::dns)" 6 "DNS"
|
|
}
|
|
|
|
# ======================================================
|
|
# Shared Base Renderer
|
|
# ======================================================
|
|
|
|
# ui::rule::_render_bases <array_nameref> [entry_indent] [label_indent]
|
|
# Renders a list of base rule names with newlines between them.
|
|
# Used by both ui::rule::tree and ui::rule::_identity_rule_entry.
|
|
function ui::rule::_render_bases() {
|
|
local -n _bases="$1"
|
|
local entry_indent="${2:-6}" label_indent="${3:-4}"
|
|
local label_pad
|
|
label_pad=$(printf '%*s' "$label_indent" '')
|
|
|
|
local first=true
|
|
for base_name in "${_bases[@]}"; do
|
|
[[ -z "$base_name" ]] && continue
|
|
$first || printf "\n"
|
|
first=false
|
|
printf "%s\033[0;37m↳ %s\033[0m\n" "$label_pad" "$base_name"
|
|
ui::rule::entries "$base_name" "$entry_indent"
|
|
done
|
|
}
|
|
|
|
# ======================================================
|
|
# Tree Rendering
|
|
# ======================================================
|
|
|
|
# ui::rule::tree <rule_name>
|
|
# Renders a rule's extends tree — one level deep with own entries.
|
|
# Returns 1 if rule has no extends (caller can fall back to flat).
|
|
function ui::rule::tree() {
|
|
local rule_name="${1:-}"
|
|
local rule_file
|
|
rule_file="$(rule::path "$rule_name")" || return 1
|
|
[[ -z "$rule_file" ]] && return 1
|
|
|
|
local extends_raw=()
|
|
mapfile -t extends_raw < <(json::get "$rule_file" "extends" 2>/dev/null || true) || true
|
|
|
|
if [[ ${#extends_raw[@]} -eq 0 || -z "${extends_raw[0]:-}" ]]; then
|
|
return 1
|
|
fi
|
|
|
|
ui::rule::_render_bases extends_raw 6 4
|
|
|
|
local own_output
|
|
own_output=$(ui::rule::own_entries "$rule_name" 6)
|
|
if [[ -n "$own_output" ]]; then
|
|
printf "\n \033[0;37mOwn:\033[0m\n"
|
|
printf "%s\n" "$own_output"
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# ======================================================
|
|
# Identity Rule Block
|
|
# ======================================================
|
|
|
|
# ui::rule::identity_block <identity_name> <strict_rule>
|
|
# Renders the full identity rule block in inspect.
|
|
function ui::rule::identity_block() {
|
|
local identity_name="${1:-}" strict="${2:-false}"
|
|
|
|
local rules
|
|
rules=$(identity::rules "$identity_name")
|
|
[[ -z "$rules" ]] && return 0
|
|
|
|
printf "\n \033[0;37m· identity:%s\033[0m\n" "$identity_name"
|
|
|
|
local first=true
|
|
while IFS= read -r rule_name; do
|
|
[[ -z "$rule_name" ]] && continue
|
|
$first || printf "\n"
|
|
first=false
|
|
ui::rule::_identity_rule_entry "$rule_name"
|
|
done <<< "$rules"
|
|
|
|
if [[ "$strict" == "true" ]]; then
|
|
printf "\n \033[2m(strict — peer rule suppressed)\033[0m\n"
|
|
fi
|
|
}
|
|
|
|
# ui::rule::_identity_rule_entry <rule_name>
|
|
# Renders one rule within an identity block.
|
|
function ui::rule::_identity_rule_entry() {
|
|
local rule_name="${1:-}"
|
|
local rule_file
|
|
rule_file="$(rule::path "$rule_name")" || return 0
|
|
|
|
printf " \033[0;37m↳ %s\033[0m\n" "$rule_name"
|
|
|
|
local extends_raw=()
|
|
mapfile -t extends_raw < <(json::get "$rule_file" "extends" 2>/dev/null || true) || true
|
|
|
|
if [[ ${#extends_raw[@]} -gt 0 && -n "${extends_raw[0]:-}" ]]; then
|
|
# Rule has extends — render one level deep using shared helper
|
|
ui::rule::_render_bases extends_raw 10 8
|
|
|
|
local own_output
|
|
own_output=$(ui::rule::own_entries "$rule_name" 10)
|
|
if [[ -n "$own_output" ]]; then
|
|
printf "\n \033[0;37mOwn:\033[0m\n"
|
|
printf "%s\n" "$own_output"
|
|
fi
|
|
else
|
|
# Leaf rule — show own entries or note full access
|
|
local own_output
|
|
own_output=$(ui::rule::own_entries "$rule_name" 8)
|
|
if [[ -n "$own_output" ]]; then
|
|
printf "%s\n" "$own_output"
|
|
else
|
|
printf " \033[2mfull access (no restrictions)\033[0m\n"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# ======================================================
|
|
# Peer Entry
|
|
# ======================================================
|
|
|
|
function ui::rule::_peer_rule_entry() {
|
|
local rule_name="${1:-}"
|
|
local rule_file
|
|
rule_file="$(rule::path "$rule_name")" || return 0
|
|
|
|
printf " \033[0;37m↳ %s\033[0m\n" "$rule_name"
|
|
|
|
local extends_raw=()
|
|
mapfile -t extends_raw < <(json::get "$rule_file" "extends" 2>/dev/null || true) || true
|
|
|
|
if [[ ${#extends_raw[@]} -gt 0 && -n "${extends_raw[0]:-}" ]]; then
|
|
ui::rule::_render_bases extends_raw 10 8
|
|
|
|
local own_output
|
|
own_output=$(ui::rule::own_entries "$rule_name" 10)
|
|
if [[ -n "$own_output" ]]; then
|
|
printf "\n \033[0;37mOwn:\033[0m\n"
|
|
printf "%s\n" "$own_output"
|
|
fi
|
|
else
|
|
local own_output
|
|
own_output=$(ui::rule::own_entries "$rule_name" 8)
|
|
if [[ -n "$own_output" ]]; then
|
|
printf "%s\n" "$own_output"
|
|
else
|
|
printf " \033[2mfull access (no restrictions)\033[0m\n"
|
|
fi
|
|
fi
|
|
} |