- Vollständiges Rebranding "PoE Manager" -> TESM (TimEShepManager): neue Logos/Favicon (theme-aware), Sidebar/Login-Branding, Copyright-Zeile. - Infrastruktur-Umbenennung: srv/poe_manager -> srv/tesm, alle POE_*-Env-Vars -> TESM_* (POE_SCRIPT bewusst unverändert, echtes PoE-Skript), systemd Units poe_web/rpi-check* -> tesm/tesm-check*, nginx-Site, netplan/logrotate Configs, Gitea-Repo alientim/Aruba-PoE-Modern -> alientim/tesm. - LDAP/Active-Directory Same-Sign-On: Search+Bind, AD-Gruppen->App-Gruppen- Zuordnung (additiv), Konto-Sperren, AD-Vorab-Suche/-Anlage, eigene Einstellungsseite. - Selektives Import/Export (8 Kategorien, Zwei-Schritt-Vorschau) mit eigenem R/E/X-Rechtemodell (X = Export, getrennt von E = Import). - Papierkorb: Soft-Delete statt Hard-Delete für Geräte/Switche/Zugangsdaten/ Benutzer/Gruppen (AD-Nutzer ausgenommen), eigene Seite unterhalb Wartung, konfigurierbare Aufbewahrungsfrist. - rpi_ip -> ip Spalten-/Code-Umbenennung (Geräte sind längst nicht mehr auf Raspberry Pis beschränkt). - README auf aktuellen Stand gebracht.
115 lines
5.8 KiB
HTML
115 lines
5.8 KiB
HTML
{% extends "base.html" %}
|
|
{% set active_page = "settings_importexport" %}
|
|
{% block page_title %}Im-/Export{% endblock %}
|
|
{% block page_sub %}<div class="topbar-sub">Umzug auf eine neue Umgebung</div>{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="settings-grid">
|
|
|
|
<div class="card card-pad">
|
|
<div class="section-head" style="margin-bottom:16px;">
|
|
<div>
|
|
<h2 style="font-size:16px;">Import</h2>
|
|
<div class="hint">
|
|
{% if import_preview %}
|
|
Datei erfolgreich gelesen — wähle aus, welche Kategorien tatsächlich eingespielt werden sollen.
|
|
{% else %}
|
|
Exportiertes Bundle einlesen — nach dem Entschlüsseln wählst du aus, was übernommen wird.
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% if not current_user.has_permission('settings_importexport.edit') %}
|
|
<p class="text-faint" style="font-size:12.5px;">Für den Import fehlt das Recht „Im-/Export ändern“.</p>
|
|
{% elif import_preview %}
|
|
<form method="post" action="{{ url_for('import_apply') }}"
|
|
data-confirm="Ausgewählte Kategorien wirklich importieren? Bestehende Einträge mit gleichem Namen/Hostname/MAC/Benutzernamen werden überschrieben.">
|
|
<input type="hidden" name="import_token" value="{{ import_preview.token }}">
|
|
<div class="field">
|
|
<label>Was importieren?</label>
|
|
<div class="check-list">
|
|
{% for s in import_preview.sections %}
|
|
<label class="check-row">
|
|
<input type="checkbox" name="import_sections" value="{{ s.key }}"
|
|
{% if s.key not in admin_only_sections or current_user.is_admin %}checked{% endif %}
|
|
{% if s.admin_only and not current_user.is_admin %}disabled{% endif %}>
|
|
{{ s.label }} <span class="text-faint">({{ s.count }})</span>
|
|
{% if s.admin_only %}<span class="pill user" style="font-size:10px; padding:2px 7px;">Nur Admin</span>{% endif %}
|
|
</label>
|
|
{% endfor %}
|
|
</div>
|
|
<div class="field-hint">
|
|
AD/LDAP-Benutzerkonten sind hiervon unberührt — sie werden über Active Directory/Windows verwaltet,
|
|
nicht über diese App, und beim nächsten Login automatisch neu angelegt.
|
|
</div>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary btn-block">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg>
|
|
Ausgewählte Kategorien importieren
|
|
</button>
|
|
</form>
|
|
<a href="{{ url_for('settings_import_export') }}" class="text-faint" style="font-size:12px; display:inline-block; margin-top:10px;">Abbrechen / andere Datei wählen</a>
|
|
{% else %}
|
|
<form method="post" action="{{ url_for('import_data') }}" enctype="multipart/form-data">
|
|
<div class="field">
|
|
<label for="import_file">Export-Datei</label>
|
|
<input type="file" name="import_file" id="import_file" accept=".json" required>
|
|
</div>
|
|
<div class="field">
|
|
<label for="import_passphrase">Passphrase</label>
|
|
<input type="password" name="import_passphrase" id="import_passphrase" required>
|
|
</div>
|
|
<button type="submit" class="btn btn-secondary btn-block">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 9V5a2 2 0 00-2-2H5a2 2 0 00-2 2v4"/><path d="M7 14l5-5 5 5"/><path d="M12 9v12"/></svg>
|
|
Datei lesen & Vorschau anzeigen
|
|
</button>
|
|
</form>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="card card-pad">
|
|
<div class="section-head" style="margin-bottom:16px;">
|
|
<div>
|
|
<h2 style="font-size:16px;">Export</h2>
|
|
<div class="hint">Ausgewählte Kategorien verschlüsselt sichern.</div>
|
|
</div>
|
|
</div>
|
|
{% if current_user.has_permission('settings_importexport.export') %}
|
|
<form method="post" action="{{ url_for('export_data') }}">
|
|
<div class="field">
|
|
<label>Was exportieren?</label>
|
|
<div class="check-list">
|
|
{% for key, label in export_sections %}
|
|
<label class="check-row">
|
|
<input type="checkbox" name="export_sections" value="{{ key }}"
|
|
{% if key not in admin_only_sections or current_user.is_admin %}checked{% endif %}
|
|
{% if key in admin_only_sections and not current_user.is_admin %}disabled{% endif %}>
|
|
{{ label }}
|
|
{% if key in admin_only_sections %}<span class="pill user" style="font-size:10px; padding:2px 7px;">Nur Admin</span>{% endif %}
|
|
</label>
|
|
{% endfor %}
|
|
</div>
|
|
<div class="field-hint">
|
|
AD/LDAP-Benutzerkonten werden nie mitexportiert — sie werden über Active Directory/Windows verwaltet
|
|
(nicht über diese App) und legen sich beim nächsten Login automatisch wieder an. Beim LDAP-Export wird
|
|
lediglich das Bind-Konto (verschlüsselt) sowie die Gruppenzuordnungen gesichert.
|
|
</div>
|
|
</div>
|
|
<div class="field">
|
|
<label for="export_passphrase">Passphrase</label>
|
|
<input type="password" name="export_passphrase" id="export_passphrase" required>
|
|
<div class="field-hint">Wird zum Verschlüsseln der Export-Datei benötigt — für den späteren Import dieselbe Passphrase erneut eingeben.</div>
|
|
</div>
|
|
<button type="submit" class="btn btn-secondary btn-block">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><path d="M7 10l5 5 5-5"/><path d="M12 15V3"/></svg>
|
|
Export herunterladen
|
|
</button>
|
|
</form>
|
|
{% else %}
|
|
<p class="text-faint" style="font-size:12.5px;">Für den Export fehlt das Recht „Daten exportieren“.</p>
|
|
{% endif %}
|
|
</div>
|
|
|
|
</div>
|
|
{% endblock %}
|