Fix review findings: offline assets, security, audit logging
- Bundle Bootstrap CSS/JS/icons locally for air-gapped operation - Add path traversal validation on image import source - Disable Flask debug mode in production - Fix file handle leaks, remove unused import - Add python3-pip, python3-venv, p7zip-full to offline packages - Add pip wheel download/bundling for offline Flask install - Change UFW default policy from allow to deny - Fix wrong path displayed in unattend editor template - Dynamic sidebar image lists from all_image_types - Add audit logging for all write operations - Audit log viewer page with activity history Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
62
webapp/templates/audit.html
Normal file
62
webapp/templates/audit.html
Normal file
@@ -0,0 +1,62 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Audit Log - PXE Server Manager{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h2 class="mb-0"><i class="bi bi-journal-text me-2"></i>Audit Log</h2>
|
||||
<span class="badge bg-secondary fs-6">{{ entries|length }} entries</span>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header d-flex align-items-center">
|
||||
<i class="bi bi-clock-history me-2"></i> Activity History
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
{% if entries %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th style="width: 180px;">Timestamp</th>
|
||||
<th style="width: 130px;">Source</th>
|
||||
<th style="width: 180px;">Action</th>
|
||||
<th>Details</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for entry in entries %}
|
||||
<tr>
|
||||
{% set parts = entry.split(' ', 1) %}
|
||||
{% if parts|length == 2 %}
|
||||
{% set meta = parts[1].split('] ', 1) %}
|
||||
<td><small class="text-muted">{{ parts[0] }}</small></td>
|
||||
{% if meta|length == 2 %}
|
||||
<td><code>{{ meta[0].lstrip('[') }}</code></td>
|
||||
{% set action_detail = meta[1].split(': ', 1) %}
|
||||
{% if action_detail|length == 2 %}
|
||||
<td><span class="badge bg-primary">{{ action_detail[0] }}</span></td>
|
||||
<td>{{ action_detail[1] }}</td>
|
||||
{% else %}
|
||||
<td colspan="2">{{ meta[1] }}</td>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<td colspan="3">{{ parts[1] }}</td>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<td colspan="4">{{ entry }}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-center text-muted py-5">
|
||||
<i class="bi bi-journal-text" style="font-size: 3rem;"></i>
|
||||
<p class="mt-2">No audit log entries yet.</p>
|
||||
<p class="small">Actions like image imports, unattend edits, and backup operations will be logged here.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -5,12 +5,8 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}PXE Server Manager{% endblock %}</title>
|
||||
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
|
||||
rel="stylesheet"
|
||||
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YcnS49cn91B2HOwP4cMpe1bBMnos9GBsYl7a"
|
||||
crossorigin="anonymous">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"
|
||||
rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='bootstrap.min.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='bootstrap-icons.min.css') }}" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--sidebar-width: 280px;
|
||||
@@ -155,12 +151,18 @@
|
||||
<i class="bi bi-shield-check"></i> Blancco Reports
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if request.endpoint == 'audit_log' %}active{% endif %}"
|
||||
href="{{ url_for('audit_log') }}">
|
||||
<i class="bi bi-journal-text"></i> Audit Log
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="nav-section-divider"></div>
|
||||
<div class="sidebar-heading">GE Aerospace Images</div>
|
||||
<ul class="nav flex-column">
|
||||
{% for it in ['gea-standard', 'gea-engineer', 'gea-shopfloor'] %}
|
||||
{% for it in all_image_types if it.startswith('gea-') %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if request.endpoint == 'unattend_editor' and image_type is defined and image_type == it %}active{% endif %}"
|
||||
href="{{ url_for('unattend_editor', image_type=it) }}">
|
||||
@@ -173,7 +175,7 @@
|
||||
<div class="nav-section-divider"></div>
|
||||
<div class="sidebar-heading">GE Legacy Images</div>
|
||||
<ul class="nav flex-column">
|
||||
{% for it in ['ge-standard', 'ge-engineer', 'ge-shopfloor-lockdown', 'ge-shopfloor-mce'] %}
|
||||
{% for it in all_image_types if it.startswith('ge-') and not it.startswith('gea-') %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if request.endpoint == 'unattend_editor' and image_type is defined and image_type == it %}active{% endif %}"
|
||||
href="{{ url_for('unattend_editor', image_type=it) }}">
|
||||
@@ -200,9 +202,7 @@
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
|
||||
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="{{ url_for('static', filename='bootstrap.bundle.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='app.js') }}"></script>
|
||||
{% block extra_scripts %}{% endblock %}
|
||||
</body>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<h2 class="mb-1">{{ friendly_name }}</h2>
|
||||
<small class="text-muted">
|
||||
<i class="bi bi-file-earmark-code me-1"></i>
|
||||
<code>{{ image_type }}/Deploy/Control/unattend.xml</code>
|
||||
<code>{{ image_type }}/Deploy/FlatUnattendW10.xml</code>
|
||||
</small>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user