openvpn-endpoint-server/server/app/templates/gateways/profile_form.html

152 lines
7.7 KiB
HTML

{% extends "base.html" %}
{% block title %}
{% if profile %}Profil bearbeiten{% else %}Neues VPN-Profil{% endif %} - {{ gateway.name }} - mGuard VPN
{% endblock %}
{% block content %}
<nav aria-label="breadcrumb" class="mb-3">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/gateways">Gateways</a></li>
<li class="breadcrumb-item"><a href="/gateways/{{ gateway.id }}">{{ gateway.name }}</a></li>
<li class="breadcrumb-item"><a href="/gateways/{{ gateway.id }}/profiles">VPN-Profile</a></li>
<li class="breadcrumb-item active">{% if profile %}Bearbeiten{% else %}Neu{% endif %}</li>
</ol>
</nav>
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card">
<div class="card-header">
<h4 class="mb-0">
<i class="bi bi-shield-lock"></i>
{% if profile %}Profil bearbeiten{% else %}Neues VPN-Profil{% endif %}
</h4>
</div>
<div class="card-body">
{% if error %}
<div class="alert alert-danger">
<i class="bi bi-exclamation-triangle"></i> {{ error }}
</div>
{% endif %}
<form method="post">
<div class="mb-3">
<label for="name" class="form-label">Name *</label>
<input type="text" class="form-control" id="name" name="name"
value="{{ profile.name if profile else '' }}" required
placeholder="z.B. Produktion, Fallback, Migration">
<div class="form-text">Ein beschreibender Name für dieses Profil</div>
</div>
<div class="mb-3">
<label for="description" class="form-label">Beschreibung</label>
<textarea class="form-control" id="description" name="description" rows="2"
placeholder="Optionale Beschreibung">{{ profile.description if profile else '' }}</textarea>
</div>
<div class="mb-3">
<label for="vpn_server_id" class="form-label">VPN-Server *</label>
{% if profile %}
<input type="text" class="form-control" readonly disabled
value="{{ profile.vpn_server.name }} ({{ profile.vpn_server.hostname }}:{{ profile.vpn_server.port }})">
<div class="form-text text-muted">
Der VPN-Server kann nicht geändert werden (Zertifikat ist an den Server gebunden).
</div>
{% else %}
<select class="form-select" id="vpn_server_id" name="vpn_server_id" required>
<option value="">-- Server auswählen --</option>
{% for server in vpn_servers %}
<option value="{{ server.id }}">
{{ server.name }} ({{ server.hostname }}:{{ server.port }}/{{ server.protocol.value }})
</option>
{% endfor %}
</select>
<div class="form-text">
Der VPN-Server, mit dem sich das Gateway verbinden soll.
{% if not vpn_servers %}
<span class="text-warning">
<i class="bi bi-exclamation-triangle"></i>
Keine VPN-Server verfügbar. <a href="/vpn-servers/new">Erstellen Sie zuerst einen Server.</a>
</span>
{% endif %}
</div>
{% endif %}
</div>
<div class="mb-3">
<label for="priority" class="form-label">Priorität *</label>
<input type="number" class="form-control" id="priority" name="priority"
value="{{ profile.priority if profile else (existing_profiles|length + 1) }}"
min="1" max="99" required style="max-width: 120px;">
<div class="form-text">
1 = Höchste Priorität (Primärer Server). Bei Verbindungsproblemen wird das Profil
mit der nächsthöheren Priorität verwendet.
</div>
</div>
{% if not profile %}
<div class="mb-3">
<label for="cert_cn" class="form-label">Common Name (CN)</label>
<input type="text" class="form-control" id="cert_cn" name="cert_cn"
placeholder="Automatisch generiert wenn leer"
value="">
<div class="form-text">
Der Common Name für das Client-Zertifikat. Wenn leer, wird automatisch
"<code>{{ gateway.name|lower|replace(' ', '-') }}-[profilname]</code>" verwendet.
</div>
</div>
<div class="mb-3">
<label for="validity_days" class="form-label">Gültigkeit (Tage)</label>
<input type="number" class="form-control" id="validity_days" name="validity_days"
value="365" min="30" max="3650" style="max-width: 150px;">
<div class="form-text">Wie lange das Zertifikat gültig sein soll (Standard: 365 Tage)</div>
</div>
{% endif %}
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="is_active" name="is_active"
{% if not profile or profile.is_active %}checked{% endif %}>
<label class="form-check-label" for="is_active">
Profil ist aktiv
</label>
</div>
<div class="form-text">Inaktive Profile werden beim Provisioning nicht berücksichtigt</div>
</div>
<hr>
<div class="d-flex justify-content-between">
<a href="/gateways/{{ gateway.id }}/profiles" class="btn btn-outline-secondary">
<i class="bi bi-x-lg"></i> Abbrechen
</a>
<button type="submit" class="btn btn-primary" {% if not vpn_servers %}disabled{% endif %}>
<i class="bi bi-check-lg"></i>
{% if profile %}Speichern{% else %}Profil erstellen{% endif %}
</button>
</div>
</form>
</div>
</div>
{% if not profile %}
<div class="card mt-4">
<div class="card-header">
<i class="bi bi-info-circle"></i> Was passiert beim Erstellen?
</div>
<div class="card-body">
<ol class="mb-0">
<li>Ein Client-Zertifikat wird aus der CA des VPN-Servers generiert</li>
<li>Das Zertifikat wird mit dem Gateway verknüpft</li>
<li>Nach dem Erstellen können Sie die OpenVPN-Konfigurationsdatei (.ovpn) herunterladen</li>
<li>Die Konfiguration kann dann auf dem mGuard-Router importiert werden</li>
</ol>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock %}