Última atividade 1 month ago

nuno revisou este gist 1 month ago. Ir para a revisão

1 file changed, 399 insertions

gistfile1.txt(arquivo criado)

@@ -0,0 +1,399 @@
1 + #!/usr/bin/env bash
2 + # ui/rule.module.sh — rendering for rule data
3 + # Replaces rule::render_* functions from rule.module.sh.
4 + # All functions pure rendering — no writes, no state changes.
5 +
6 + # ======================================================
7 + # Entry Rendering (shared primitives)
8 + # ======================================================
9 +
10 + # ui::rule::entries <rule_name> [indent]
11 + # Renders the fully resolved entries for a rule (allow + block).
12 + function ui::rule::entries() {
13 + local rule_name="${1:-}" indent="${2:-4}"
14 +
15 + local allow_ports allow_ips block_ips block_ports dns
16 + allow_ports=$(rule::get "$rule_name" "allow_ports" 2>/dev/null || true)
17 + allow_ips=$(rule::get "$rule_name" "allow_ips" 2>/dev/null || true)
18 + block_ips=$(rule::get "$rule_name" "block_ips" 2>/dev/null || true)
19 + block_ports=$(rule::get "$rule_name" "block_ports" 2>/dev/null || true)
20 + dns=$(rule::get_own "$rule_name" "dns_redirect")
21 +
22 + while IFS= read -r e; do
23 + [[ -z "$e" ]] && continue
24 + net::print_entry "+" "$e" "$indent"
25 + done <<< "$allow_ports"$'\n'"$allow_ips"
26 +
27 + while IFS= read -r e; do
28 + [[ -z "$e" ]] && continue
29 + net::print_entry "-" "$e" "$indent"
30 + done <<< "$block_ips"$'\n'"$block_ports"
31 +
32 + [[ "${dns,,}" == "true" ]] && \
33 + net::print_dns_redirect "$(config::dns)" 6 "DNS"
34 + }
35 +
36 + # ui::rule::own_entries <rule_name> [indent]
37 + # Renders only the rule's own (non-inherited) entries.
38 + function ui::rule::own_entries() {
39 + local rule_name="${1:-}" indent="${2:-4}"
40 + local rule_file
41 + rule_file="$(rule::path "$rule_name")" || return 0
42 + [[ -z "$rule_file" ]] && return 0
43 +
44 + local allow_ports allow_ips block_ips block_ports dns
45 + allow_ports=$(json::get "$rule_file" "allow_ports" 2>/dev/null || true)
46 + allow_ips=$(json::get "$rule_file" "allow_ips" 2>/dev/null || true)
47 + block_ips=$(json::get "$rule_file" "block_ips" 2>/dev/null || true)
48 + block_ports=$(json::get "$rule_file" "block_ports" 2>/dev/null || true)
49 + dns=$(json::get "$rule_file" "dns_redirect" 2>/dev/null || true)
50 +
51 + local combined="${allow_ports}${allow_ips}${block_ips}${block_ports}"
52 + [[ -z "${combined//[$'\n']/}" ]] && return 0
53 +
54 + while IFS= read -r e; do
55 + [[ -z "$e" ]] && continue
56 + net::print_entry "+" "$e" "$indent"
57 + done <<< "$allow_ports"$'\n'"$allow_ips"
58 +
59 + while IFS= read -r e; do
60 + [[ -z "$e" ]] && continue
61 + net::print_entry "-" "$e" "$indent"
62 + done <<< "$block_ips"$'\n'"$block_ports"
63 +
64 + [[ "${dns,,}" == "true" ]] && \
65 + net::print_dns_redirect "$(config::dns)" 6 "DNS"
66 + }
67 +
68 + # ui::rule::flat <rule_name>
69 + # Renders the full resolved entries as a flat list.
70 + function ui::rule::flat() {
71 + local rule_name="${1:-}"
72 +
73 + local allow_ports allow_ips block_ips block_ports dns
74 + allow_ports=$(rule::get "$rule_name" "allow_ports")
75 + allow_ips=$(rule::get "$rule_name" "allow_ips")
76 + block_ips=$(rule::get "$rule_name" "block_ips")
77 + block_ports=$(rule::get "$rule_name" "block_ports")
78 + dns=$(rule::get_own "$rule_name" "dns_redirect")
79 +
80 + local has_content=false
81 + [[ -n "${allow_ports}${allow_ips}${block_ips}${block_ports}" ]] && has_content=true
82 +
83 + if ! $has_content; then
84 + printf "\n full access (no restrictions)\n"
85 + return 0
86 + fi
87 +
88 + if [[ -n "$allow_ports" || -n "$allow_ips" ]]; then
89 + printf "\n"
90 + while IFS= read -r e; do
91 + [[ -z "$e" ]] && continue
92 + net::print_entry "+" "$e" 2
93 + done <<< "$allow_ports"$'\n'"$allow_ips"
94 + fi
95 +
96 + if [[ -n "$block_ips" || -n "$block_ports" ]]; then
97 + printf "\n"
98 + while IFS= read -r e; do
99 + [[ -z "$e" ]] && continue
100 + net::print_entry "-" "$e" 2
101 + done <<< "$block_ips"$'\n'"$block_ports"
102 + fi
103 +
104 + [[ "${dns,,}" == "true" ]] && \
105 + net::print_dns_redirect "$(config::dns)" 6 "DNS"
106 + }
107 +
108 + # ======================================================
109 + # Shared Base Renderer
110 + # ======================================================
111 +
112 + # ui::rule::_render_bases <array_nameref> [entry_indent] [label_indent]
113 + # Renders a list of base rule names with newlines between them.
114 + # Used by both ui::rule::tree and ui::rule::_identity_rule_entry.
115 + function ui::rule::_render_bases() {
116 + local -n _bases="$1"
117 + local entry_indent="${2:-6}" label_indent="${3:-4}"
118 + local label_pad
119 + label_pad=$(printf '%*s' "$label_indent" '')
120 +
121 + local first=true
122 + for base_name in "${_bases[@]}"; do
123 + [[ -z "$base_name" ]] && continue
124 + $first || printf "\n"
125 + first=false
126 + printf "%s\033[0;37m↳ %s\033[0m\n" "$label_pad" "$base_name"
127 + ui::rule::entries "$base_name" "$entry_indent"
128 + done
129 + }
130 +
131 + # ======================================================
132 + # Tree Rendering
133 + # ======================================================
134 +
135 + # ui::rule::tree <rule_name>
136 + # Renders a rule's extends tree — one level deep with own entries.
137 + # Returns 1 if rule has no extends (caller can fall back to flat).
138 + function ui::rule::tree() {
139 + local rule_name="${1:-}"
140 + local rule_file
141 + rule_file="$(rule::path "$rule_name")" || return 1
142 + [[ -z "$rule_file" ]] && return 1
143 +
144 + local extends_raw=()
145 + mapfile -t extends_raw < <(json::get "$rule_file" "extends" 2>/dev/null || true) || true
146 +
147 + if [[ ${#extends_raw[@]} -eq 0 || -z "${extends_raw[0]:-}" ]]; then
148 + return 1
149 + fi
150 +
151 + ui::rule::_render_bases extends_raw 6 4
152 +
153 + local own_output
154 + own_output=$(ui::rule::own_entries "$rule_name" 6)
155 + if [[ -n "$own_output" ]]; then
156 + printf "\n \033[0;37mOwn:\033[0m\n"
157 + printf "%s\n" "$own_output"
158 + fi
159 +
160 + return 0
161 + }
162 +
163 + # ======================================================
164 + # Identity Rule Block
165 + # ======================================================
166 +
167 + # ui::rule::identity_block <identity_name> <strict_rule>
168 + # Renders the full identity rule block in inspect.
169 + function ui::rule::identity_block() {
170 + local identity_name="${1:-}" strict="${2:-false}" no_header=false
171 +
172 + # Parse optional flags
173 + shift 2 || true
174 + while [[ $# -gt 0 ]]; do
175 + case "$1" in
176 + --no-header) no_header=true; shift ;;
177 + *) shift ;;
178 + esac
179 + done
180 +
181 + local rules
182 + rules=$(identity::rules "$identity_name")
183 + [[ -z "$rules" ]] && return 0
184 +
185 + if ! $no_header; then
186 + printf "\n \033[0;37m· identity:%s\033[0m\n" "$identity_name"
187 + fi
188 +
189 + # Indentation levels:
190 + # normal: entry=6 label=6 own=10 own_label=8
191 + # no-header: entry=4 label=4 own=8 own_label=6
192 + local entry_indent label_indent own_indent own_label_indent
193 + if $no_header; then
194 + entry_indent=4
195 + label_indent=4
196 + own_indent=8
197 + own_label_indent=6
198 + else
199 + entry_indent=6
200 + label_indent=6
201 + own_indent=10
202 + own_label_indent=8
203 + fi
204 +
205 + local first=true
206 + while IFS= read -r rule_name; do
207 + [[ -z "$rule_name" ]] && continue
208 + $first || printf "\n"
209 + first=false
210 + ui::rule::_identity_rule_entry "$rule_name" \
211 + "$entry_indent" "$label_indent" "$own_indent" "$own_label_indent"
212 + done <<< "$rules"
213 +
214 + if [[ "$strict" == "true" ]]; then
215 + printf "\n \033[2m(strict — peer rule suppressed)\033[0m\n"
216 + fi
217 + }
218 +
219 + # ui::rule::_identity_rule_entry <rule_name>
220 + # Renders one rule within an identity block.
221 + function ui::rule::_identity_rule_entry() {
222 + local rule_name="${1:-}"
223 + local entry_indent="${2:-6}"
224 + local label_indent="${3:-6}"
225 + local own_indent="${4:-10}"
226 + local own_label_indent="${5:-8}"
227 +
228 + local rule_file
229 + rule_file="$(rule::path "$rule_name")" || return 0
230 +
231 + local label_pad
232 + label_pad=$(printf '%*s' "$label_indent" '')
233 + printf "%s\033[0;37m↳ %s\033[0m\n" "$label_pad" "$rule_name"
234 +
235 + local extends_raw=()
236 + mapfile -t extends_raw < <(json::get "$rule_file" "extends" 2>/dev/null || true) || true
237 +
238 + if [[ ${#extends_raw[@]} -gt 0 && -n "${extends_raw[0]:-}" ]]; then
239 + ui::rule::_render_bases extends_raw "$own_indent" "$(( entry_indent + 2 ))"
240 +
241 + local own_output
242 + own_output=$(ui::rule::own_entries "$rule_name" "$own_indent")
243 + if [[ -n "$own_output" ]]; then
244 + local own_pad
245 + own_pad=$(printf '%*s' "$(( entry_indent + 2 ))" '')
246 + printf "\n%s\033[0;37mOwn:\033[0m\n" "$own_pad"
247 + printf "%s\n" "$own_output"
248 + fi
249 + else
250 + local own_output
251 + own_output=$(ui::rule::own_entries "$rule_name" "$entry_indent")
252 + if [[ -n "$own_output" ]]; then
253 + printf "%s\n" "$own_output"
254 + else
255 + local full_pad
256 + full_pad=$(printf '%*s' "$(( entry_indent + 2 ))" '')
257 + printf "%s\033[2mfull access (no restrictions)\033[0m\n" "$full_pad"
258 + fi
259 + fi
260 + }
261 +
262 + # ======================================================
263 + # Peer Entry
264 + # ======================================================
265 +
266 + function ui::rule::_peer_rule_entry() {
267 + local rule_name="${1:-}"
268 + local rule_file
269 + rule_file="$(rule::path "$rule_name")" || return 0
270 +
271 + printf " \033[0;37m↳ %s\033[0m\n" "$rule_name"
272 +
273 + local extends_raw=()
274 + mapfile -t extends_raw < <(json::get "$rule_file" "extends" 2>/dev/null || true) || true
275 +
276 + if [[ ${#extends_raw[@]} -gt 0 && -n "${extends_raw[0]:-}" ]]; then
277 + ui::rule::_render_bases extends_raw 10 8
278 +
279 + local own_output
280 + own_output=$(ui::rule::own_entries "$rule_name" 10)
281 + if [[ -n "$own_output" ]]; then
282 + printf "\n \033[0;37mOwn:\033[0m\n"
283 + printf "%s\n" "$own_output"
284 + fi
285 + else
286 + local own_output
287 + own_output=$(ui::rule::own_entries "$rule_name" 8)
288 + if [[ -n "$own_output" ]]; then
289 + printf "%s\n" "$own_output"
290 + else
291 + printf " \033[2mfull access (no restrictions)\033[0m\n"
292 + fi
293 + fi
294 + }
295 +
296 + # ======================================================
297 + # List Rendering
298 + # ======================================================
299 +
300 + # ui::rule::list_group_header <group_name>
301 + function ui::rule::list_group_header() {
302 + local group="${1:-}"
303 + printf "\n \033[0;36m▸ %s\033[0m\n" "$group"
304 + }
305 +
306 + # ui::rule::list_base_header
307 + function ui::rule::list_base_header() {
308 + printf "\n \033[2m── Base Rules ──────────────────────\033[0m\n"
309 + }
310 +
311 +
312 + # ui::rule::list_row <name> <n_allows> <n_blocks> <peer_count> <w_name>
313 + function ui::rule::list_row() {
314 + local name="${1:-}" n_allows="${2:-0}" n_blocks="${3:-0}" \
315 + peer_count="${4:-0}" w_name="${5:-16}" extends_csv="${6:-}"
316 +
317 + local name_pad
318 + name_pad=$(printf "%-${w_name}s" "$name")
319 +
320 + local peer_word="peers"
321 + [[ "$peer_count" -eq 1 ]] && peer_word="peer"
322 +
323 + local peers_display
324 + peers_display=$(printf "%s %s" "$peer_count" "$peer_word")
325 + local peers_pad_n=$(( 10 - ${#peers_display} ))
326 + [[ $peers_pad_n -lt 0 ]] && peers_pad_n=0
327 +
328 + local extends_indicator=""
329 + if [[ -n "$extends_csv" ]]; then
330 + local extends_display="${extends_csv//,/, }"
331 + extends_indicator=" \033[2m↳ ${extends_display}\033[0m"
332 + fi
333 +
334 + # Allows column — green +N if >0, dim +0 if zero
335 + local allows_str
336 + if [[ "$n_allows" -gt 0 ]]; then
337 + allows_str=$(ui::pad_mb "\033[1;32m+${n_allows}\033[0m" 5)
338 + else
339 + allows_str=$(ui::pad_mb "\033[2m+0\033[0m" 5)
340 + fi
341 +
342 + # Blocks column — red -N if >0, dim -0 if zero
343 + local blocks_str
344 + if [[ "$n_blocks" -gt 0 ]]; then
345 + blocks_str=$(ui::pad_mb "\033[1;31m-${n_blocks}\033[0m" 5)
346 + else
347 + blocks_str=$(ui::pad_mb "\033[2m-0\033[0m" 5)
348 + fi
349 +
350 + # Peers — dim if zero
351 + local peers_colored
352 + if [[ "$peer_count" -eq 0 ]]; then
353 + peers_colored="\033[2m${peers_display}\033[0m"
354 + else
355 + peers_colored="$peers_display"
356 + fi
357 +
358 + printf " %s %b%b %b%*s%b\n" \
359 + "$name_pad" "$allows_str" "$blocks_str" \
360 + "$peers_colored" "$peers_pad_n" "" "$extends_indicator"
361 + }
362 +
363 + # ui::rule::list_extends <extends_csv>
364 + # Renders the extends tree for a rule in list view (compact, one level)
365 + function ui::rule::list_extends() {
366 + local extends_csv="${1:-}"
367 + [[ -z "$extends_csv" ]] && return 0
368 +
369 + local extend_list=()
370 + IFS=',' read -ra extend_list <<< "$extends_csv"
371 + for base in "${extend_list[@]}"; do
372 + [[ -z "$base" ]] && continue
373 + printf " \033[0;37m ↳ %s\033[0m\n" "$base"
374 + done
375 + }
376 +
377 + # ui::rule::list_extends_detailed <extends_csv> <rules_dir>
378 + # Renders the extends tree with entries expanded (--detailed mode)
379 + function ui::rule::list_extends_detailed() {
380 + local extends_csv="${1:-}" rules_dir="${2:-}"
381 + [[ -z "$extends_csv" ]] && return 0
382 +
383 + local extend_list=()
384 + IFS=',' read -ra extend_list <<< "$extends_csv"
385 + for base in "${extend_list[@]}"; do
386 + [[ -z "$base" ]] && continue
387 + printf " \033[0;37m ↳ %s\033[0m\n" "$base"
388 + ui::rule::entries "$base" 6
389 + done
390 + }
391 +
392 + # ======================================================
393 + # Show helpers
394 + # ======================================================
395 +
396 + function ui::rule::section_header() {
397 + local title="${1:-}"
398 + printf "\n \033[0;37m── %s ──────────────────────────────────\033[0m\n" "$title"
399 + }
Próximo Anterior