Commit Graph

31 Commits

Author SHA1 Message Date
cproudlock
da91a29155 Admit kiosk callers by network position, not only by device token
The device token assumes a handful of fixed screens an administrator
provisions once. That is not how these kiosks are used: most people open the
page on their own PC, and there is no login, so per-browser provisioning would
mean touching every PC on the floor and losing it again on the next reimage or
cleared profile. A screen in that state did not look refused either - the USB
kiosk rendered a working page whose every call answered 404.

Both kiosks now admit a caller on either ground, the same shape the GE-Enforce
client endpoints already use: the per-device token, or a source address inside
an allowlist. Wall screens keep the token and are not confined to the
allowlist; everyone else is admitted by where they are on the network. Still
gated on the site's enable flag, so nothing opens by itself, and both
allowlists ship empty - token-only until a site enters its ranges.

- shopdb.api gains ip_in_cidrs and request_ip_allowlisted (contract 0.35.0).
  On the surface because both plugins need the identical gate, and a CIDR
  parser copied into two of them is where a fail-open creeps in later. They
  fail closed on an empty setting, an unparseable caller address and a
  malformed entry, and they read remote_addr rather than raw X-Forwarded-For -
  so the IIS rewrite rule is what makes them meaningful, which the module says
  at length.
- Separate settings per kiosk, usb_kiosk_allowed_cidrs and
  printedparts_kiosk_allowed_cidrs. One must not grant the other, for the same
  reason the tokens are separate.
- Both settings pages get a picker listing the network plugin's subnets with
  their VLANs. It stores resolved CIDR strings, not subnet ids: the setting has
  to work at a site that does not run that plugin and must not break when an
  inventory row is deleted. Entries matching no subnet are shown rather than
  hidden, since a stale one left by an inventory edit looks exactly like a
  hand-typed range.
- USBKiosk says it was not admitted instead of pretending to work, which
  PartsKiosk already did.
- The USB settings page keyed text-vs-boolean off the token alone. Adding a
  second text setting to the boolean path would have saved it as the word
  'true' - the bug that replaced the kiosk token and 404'd every provisioned
  screen. Both load and save now key off a list, with a spec on it.

The trade, stated plainly in the admin UI: anyone on an allowed network can
check a drive in or out against a badge number they guess, and the record
carries that person's name. Badges are attribution, not authorization. Keeping
the ranges narrow is what bounds it; login is the alternative and was ruled out
because these users do not sign in.
2026-09-16 14:33:22 -04:00
ff9ae693a6 Remediate the 2026-09-03 feature-test findings 2026-09-03 17:14:53 -04:00
4b21aa3887 Gate both kiosks behind a device token, and make an unreachable setting a test failure 2026-09-02 18:11:01 -04:00
2f90419ceb Shut the parts kiosk behind a device token, and stop the health probe leaking 2026-09-02 17:45:05 -04:00
6680c3c5de Merge the wilm delivery work into main
Ben Baker's installed-software collection, software delivery (run_script and
update_app), agentless adoption tool and command-queue hardening, with his
authorship preserved.

Reviewed before promotion. Fixed: the endpoints plugin tests were never collected
by pytest, the SBOM snapshot table's key would exhaust on MySQL, ingest did not
truncate two columns strict MySQL would reject, and update_app's version branch
pinned a digest for a file that route never serves. Agent packaging moved off
require_role('admin') onto a new endpoints.agentpackage permission.

Contract 0.27.0. Full suite 2231, frontend 314.
2026-08-30 19:41:15 -04:00
0c1fbfcc1e read permissions on every GET 2026-08-27 14:26:17 -04:00
4da6c6aa36 guest role; guide section ticking 2026-08-27 13:02:35 -04:00
376298dc02 Navigation sections declared, guide editor drag + references, USB settings, permission refresh 2026-08-27 09:30:08 -04:00
0738d71525 Guides image + draft gating, audit retention, ADR-015 gate, backup credential redaction 2026-08-26 15:08:53 -04:00
4e38303326 Tab titles name the record; Guides reach a site and the contract surface 2026-08-26 13:31:13 -04:00
f109dd1349 Plugin baselines skip tables that already exist 2026-08-24 09:28:52 -04:00
ece0e15f03 Page past the 100-row cap in pickers and batch label sheets 2026-08-17 14:17:28 -04:00
265ca2eb01 Security hardening, multi-site portability, and a documentation and API-surface sweep 2026-08-14 16:28:34 -04:00
dd6ccd7a55 Centre the parts kiosk on the screen instead of hugging the top 2026-08-07 08:39:08 -04:00
c674000ccc Show the kiosk label prefix, and let a plugin declare the settings it owns 2026-08-06 18:17:56 -04:00
d3e7311376 Catalog seeding, blank-unique fix, slides rotation, console repair 2026-08-05 13:19:51 -04:00
9c530a70db Filter pagination reset; catalog model retype tool 2026-08-05 11:26:40 -04:00
c355eaae43 printers low-toner alerts; geenforce display readiness + token scope-binding; air-gap docker deploy kit 2026-07-23 14:37:00 -04:00
73b05e5b1c alerts: per-support-team webhook + printedparts routing 2026-07-22 13:32:01 -04:00
4a5b78dad2 alerts: Teams webhook fan-out + contract 0.14.0 2026-07-22 10:56:04 -04:00
e3d09bdd78 printedparts detail: revision column in transactions 2026-07-22 10:21:43 -04:00
bbd086f075 printedparts: kiosk revision display + gage-tag/link in low-stock email 2026-07-22 10:12:52 -04:00
d49f0cbb09 printedparts: QR label tag+rev, record taken revision 2026-07-22 07:52:17 -04:00
b5b68f2196 printedparts kiosk: gage lab tag on SSO prompt 2026-07-20 11:34:13 -04:00
ce6edb54bc printedparts kiosk prefix + gage lab tag labels 2026-07-20 11:18:16 -04:00
cb9ede497d Kiosk entry input, gage lab tag column, model image subpath fix 2026-07-20 11:14:20 -04:00
c2e1b9b367 printedparts: show gage lab tag in the catalog list 2026-07-20 11:03:42 -04:00
d0c31d1c97 ADR-013 Phase 4: frontend staging + printedparts relocation 2026-07-18 23:43:39 -04:00
365b0f2f69 printedparts: gage-lab asset tag + print-files redesign
The gage lab assigns real WJRP asset numbers: internal itemcode stays
auto-minted, a new optional unique gagelabtag carries the lab's number,
searchable and kiosk-resolved (scans and bare digits against either
identifier). Print files render as stacked revision cards instead of a
scrolling table.
2026-07-17 14:01:10 -04:00
503c0cfcf4 printedparts: badge resolution honors the employee directory mode
At sites running the external HR directory the self-hosted table is
empty, so every kiosk badge fell to the deny policy. The resolver now
branches on employee_directory_mode: selfhosted reads the directory
table by SSO; external queries the HR directory, resolving PayNo
badges by their real PayNo column.
2026-07-17 10:39:12 -04:00
11c8d79ba4 Add the printedparts plugin: 3D-printed parts storefront and kiosk
Catalog with photos and append-only print-file revisions, a stock
ledger attributing every take/restock/adjust to a badge-resolved
employee, a touch kiosk (scan bin, scan badge, keypad quantity) with a
deliberately open decrement-only take endpoint, 1x0.5in CODE128 bin
labels, low-stock email alerts to selected users, roles, or addresses,
and stock/consumption/by-person reports with a cache-vs-ledger
reconcile. Ships disabled; enable per site. Contract 0.13.0 adds the
mailer and the User/Role models to the plugin surface.
2026-07-17 09:29:01 -04:00