code wiki / _hdl_build / nx_portal_builder.nx

nx_portal_builder.nx source

↩ module page · 95 lines · 4753 B

1// nx_portal_builder.nx -- ADMIN-001 (CALLOUT-013): the admin-portal SHELL authoring tool. Reads the 2// module registry (knowledge/registry/modules.tsv) + a ROLE (argv[1]) and EMITS the role-filtered 3// portal page via the PROVEN nx_web_builder -- a WordPress-like portal showing ONLY the modules the 4// role may access (RBAC, same levels as roleaccess_gate). One tool authors the client /portal AND the 5// lawyer /admin from the SAME registry (data-driven, growable). Writes to knowledge/staging/media/ 6// (PRIVATE behind login -- not public). Prints PORTALGATE role= modules= for the gate. license_tier: ORIGINAL 7import "nx_syscalls.nx" 8import "nx_web_builder.nx" 9const PB_MAGIC_40000: i64 = 40000 10 11const PB_REG: *u8 = "knowledge/registry/modules.tsv" 12 13func pb_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 14func pb_putn(v: i64) -> i64 { let bb: *u8 = sys_mmap(28); var m: i64=v; if m<0 {m=0-m}; let t: *u8 = sys_mmap(28); var k: i64=0; if m==0 {t[0]=48;k=1}; while m>0 {t[k]=48+(m%10); m=m/10; k=k+1}; var i: i64=0; while i<k {bb[i]=t[k-1-i]; i=i+1}; sys_write(1, bb, k); return 0 } 15func pb_read(path: *u8, buf: *u8, cap: i64) -> i64 { 16 let fd: i64 = sys_openat_rd(path) 17 if fd < 0 { return 0 - 1 } 18 var tot: i64 = 0 19 var r: i64 = 1 20 while r > 0 { let dst: *u8 = ((buf as i64) + tot) as *u8; r = sys_read(fd, dst, cap - tot); if r > 0 { tot = tot + r } } 21 sys_close(fd) 22 return tot 23} 24func pb_scan(buf: *u8, n: i64, start: i64, delim: i64) -> i64 { var i: i64 = start; var s: i64 = 1; while s == 1 { if i >= n { s = 0 } else { if buf[i] == (delim as u8) { s = 0 } else { i = i + 1 } } } return i } 25// role level from a word: pub->0 cli->1 law->2 (compare first 3 bytes) 26func pb_lvl(w: *u8) -> i64 { 27 if w[0] == (112 as u8) { return 0 } // p ublic 28 if w[0] == (99 as u8) { return 1 } // c lient 29 if w[0] == (108 as u8) { return 2 } // l awyer 30 return 0 31} 32 33func main(argc: i64, argv: *i64) -> i64 { 34 if argc < 2 { pb_puts("PORTALGATE verdict=REFUSED reason=usage:nx_portal_builder <role>\n" as *u8); return 2 } 35 let role: *u8 = argv[1] as *u8 36 let rl: i64 = pb_lvl(role) 37 38 let rb: *u8 = sys_mmap(PB_MAGIC_40000) 39 let rn: i64 = pb_read(PB_REG, rb, PB_MAGIC_40000) 40 if rn <= 0 { pb_puts("PORTALGATE verdict=REFUSED reason=registry-unreadable\n" as *u8); return 2 } 41 42 // output path knowledge/staging/media/portal_<role>.html 43 let outp: *u8 = sys_mmap(256) 44 var o: i64 = 0 45 let pre: *u8 = "knowledge/staging/media/portal_" 46 var j: i64 = 0; while pre[j] != (0 as u8) { outp[o] = pre[j]; o = o + 1; j = j + 1 } 47 j = 0; while role[j] != (0 as u8) { outp[o] = role[j]; o = o + 1; j = j + 1 } 48 let suf: *u8 = ".html" 49 j = 0; while suf[j] != (0 as u8) { outp[o] = suf[j]; o = o + 1; j = j + 1 } 50 outp[o] = 0 as u8 51 52 let fd: i64 = sys_openat_wr(outp, 420) 53 if fd < 0 { pb_puts("PORTALGATE verdict=REFUSED reason=out-unwritable\n" as *u8); return 2 } 54 55 wb_doc_open(fd, "Nishi Admin Portal" as *u8) 56 wb_header(fd, "Nishi Portal" as *u8, "Sign out" as *u8, "/wiki/logout" as *u8) 57 wb_cards_open(fd, "Your modules (behind login)" as *u8) 58 59 // walk modules.tsv; emit a card per module the role may access 60 var count: i64 = 0 61 var p: i64 = 0 62 while p < rn { 63 let a: i64 = p 64 let e: i64 = pb_scan(rb, rn, a, 10) 65 if rb[a] == (35 as u8) { p = e + 1 } 66 else { if a >= e { p = e + 1 } 67 else { 68 let t1: i64 = pb_scan(rb, rn, a, 9); rb[t1] = 0 as u8 // module 69 let r2: i64 = t1 + 1 70 let t2: i64 = pb_scan(rb, rn, r2, 9); rb[t2] = 0 as u8 // route 71 let r3: i64 = t2 + 1 72 let t3: i64 = pb_scan(rb, rn, r3, 9); rb[t3] = 0 as u8 // role_required 73 let r4: i64 = t3 + 1 74 let t4: i64 = pb_scan(rb, rn, r4, 9); rb[t4] = 0 as u8 // capability 75 let r5: i64 = t4 + 1 76 let t5: i64 = pb_scan(rb, rn, r5, 10); rb[t5] = 0 as u8 // desc 77 let modp: *u8 = ((rb as i64) + a) as *u8 78 let routep: *u8 = ((rb as i64) + r2) as *u8 79 let reqp: *u8 = ((rb as i64) + r3) as *u8 80 let descp: *u8 = ((rb as i64) + r5) as *u8 81 if rl >= pb_lvl(reqp) { wb_card(fd, modp, descp); count = count + 1 } 82 p = t5 + 1 83 } } 84 } 85 wb_cards_close(fd) 86 wb_footer(fd, "Nishi unified admin portal -- one portal across the family of sites, behind your login." as *u8) 87 wb_doc_close(fd) 88 sys_close(fd) 89 90 pb_puts("PORTALGATE role=" as *u8); pb_puts(role) 91 pb_puts(" modules=" as *u8); pb_putn(count) 92 pb_puts(" -> " as *u8); pb_puts(outp) 93 pb_puts(" verdict=GREEN\n" as *u8) 94 return 0 95}