WinPE now reports each machine's WMI model, manufacturer, Dell system
SKU and BIOS version to /hardware/seen (winpe-status-push.ps1, best
effort, wmic only). The webapp records every model seen and checks it
against what the server has:
- each image's Deploy/Control/HardwareDriver.json, matched exactly as
PESetup's GetDriverByModel does (as reimplemented in
lint-driver-catalogue.py), plus whether the pack's zip is on disk;
- the WinPE BIOS manifest (substring match like check-bios.cmd).
/hardware lists every model with per-image driver status and BIOS
status. A model missing a Win11 pack or a BIOS entry becomes item 5 on
the Technician To-Do (and the banner count) until the pack/BIOS is added
or it is dismissed. Virtual machines are ignored.
Also deploys the repo winpe-status-push.ps1 over the live copy, which
predated the -CurrentStage/-StageIndex parameters startnet.cmd passes
for the BIOS-flash stage, so that status post was failing.
40 lines
1.2 KiB
Python
40 lines
1.2 KiB
Python
"""Session-based CSRF token: generate per-session, double-submit on POST."""
|
|
|
|
import secrets
|
|
|
|
from flask import abort, request, session
|
|
|
|
# Endpoint paths exempt from CSRF (machine-to-machine POSTs from PXE clients
|
|
# that have no browser session to carry a token). Air-gapped LAN; treated as
|
|
# trust-by-network. Keep the list short and explicit.
|
|
CSRF_EXEMPT_PATHS = {
|
|
"/imaging/status",
|
|
"/reports/cloud-status",
|
|
"/hardware/seen",
|
|
}
|
|
|
|
|
|
def generate_csrf_token():
|
|
"""Return the CSRF token for the current session, creating one if needed."""
|
|
if "_csrf_token" not in session:
|
|
session["_csrf_token"] = secrets.token_hex(32)
|
|
return session["_csrf_token"]
|
|
|
|
|
|
def init_csrf(app):
|
|
"""Wire CSRF protection into a Flask app: validator + template helper."""
|
|
|
|
@app.before_request
|
|
def _validate_csrf():
|
|
if request.method != "POST":
|
|
return
|
|
if request.path in CSRF_EXEMPT_PATHS:
|
|
return
|
|
token = request.form.get("_csrf_token") or request.headers.get("X-CSRF-Token")
|
|
if not token or token != generate_csrf_token():
|
|
abort(403)
|
|
|
|
@app.context_processor
|
|
def _inject_csrf_token():
|
|
return {"csrf_token": generate_csrf_token}
|