Files
app-installer/templates/profile.html
SimolZimol 1eac702d7d modified: app.py
new file:   file_manager.py
	modified:   requirements.txt
	new file:   sessions_db.json
	modified:   templates/base.html
	new file:   templates/file_manager.html
	new file:   templates/file_manager_new.html
	new file:   templates/login.html
	new file:   templates/profile.html
	new file:   templates/users_management.html
	new file:   user_management.py
	new file:   users_db.json
2025-07-10 00:00:59 +02:00

263 lines
13 KiB
HTML

{% extends "base.html" %}
{% block title %}Benutzerprofil - App Installer{% endblock %}
{% block content %}
<div class="container-fluid py-4">
<div class="row">
<div class="col-12">
<!-- Breadcrumb -->
<nav aria-label="breadcrumb" class="mb-4">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ url_for('index') }}"><i class="fas fa-home"></i> Dashboard</a></li>
<li class="breadcrumb-item active">Profil</li>
</ol>
</nav>
<!-- Flash Messages -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ 'danger' if category == 'error' else category }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
{% endif %}
{% endwith %}
</div>
</div>
<div class="row">
<!-- Profil-Info -->
<div class="col-lg-4 col-md-6 mb-4">
<div class="card">
<div class="card-header bg-primary text-white">
<h5 class="card-title mb-0">
<i class="fas fa-user me-2"></i>
Benutzer-Informationen
</h5>
</div>
<div class="card-body">
<div class="text-center mb-3">
<div class="avatar-circle bg-primary text-white mb-3" style="width: 80px; height: 80px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto; font-size: 2rem;">
{{ user.first_name[0] if user.first_name else user.username[0] }}{{ user.last_name[0] if user.last_name else '' }}
</div>
<h4 class="mb-1">
{% if user.first_name or user.last_name %}
{{ user.first_name }} {{ user.last_name }}
{% else %}
{{ user.username }}
{% endif %}
</h4>
<span class="badge bg-{% if user.role == 'admin' %}danger{% elif user.role == 'moderator' %}warning{% elif user.role == 'user' %}primary{% else %}secondary{% endif %} fs-6">
{{ user.role.title() }}
</span>
</div>
<hr>
<div class="info-item mb-2">
<strong><i class="fas fa-user me-2"></i>Benutzername:</strong>
<span class="text-muted">{{ user.username }}</span>
</div>
<div class="info-item mb-2">
<strong><i class="fas fa-envelope me-2"></i>E-Mail:</strong>
<span class="text-muted">{{ user.email }}</span>
</div>
<div class="info-item mb-2">
<strong><i class="fas fa-calendar-plus me-2"></i>Erstellt:</strong>
<span class="text-muted">{{ user.created_at[:10] }}</span>
</div>
{% if user.last_login %}
<div class="info-item mb-2">
<strong><i class="fas fa-clock me-2"></i>Letzter Login:</strong>
<span class="text-muted">{{ user.last_login[:16] }}</span>
</div>
{% endif %}
<div class="info-item mb-0">
<strong><i class="fas fa-sign-in-alt me-2"></i>Login-Anzahl:</strong>
<span class="text-muted">{{ user.login_count or 0 }}x</span>
</div>
</div>
</div>
</div>
<!-- Passwort ändern -->
<div class="col-lg-8 col-md-6 mb-4">
<div class="card">
<div class="card-header bg-warning text-dark">
<h5 class="card-title mb-0">
<i class="fas fa-key me-2"></i>
Passwort ändern
</h5>
</div>
<div class="card-body">
<form method="POST" action="{{ url_for('change_password') }}">
<div class="row">
<div class="col-md-12 mb-3">
<label for="old_password" class="form-label">Aktuelles Passwort</label>
<input type="password"
class="form-control"
id="old_password"
name="old_password"
required>
</div>
<div class="col-md-6 mb-3">
<label for="new_password" class="form-label">Neues Passwort</label>
<input type="password"
class="form-control"
id="new_password"
name="new_password"
minlength="6"
required>
<div class="form-text">Mindestens 6 Zeichen</div>
</div>
<div class="col-md-6 mb-3">
<label for="confirm_password" class="form-label">Passwort bestätigen</label>
<input type="password"
class="form-control"
id="confirm_password"
name="confirm_password"
minlength="6"
required>
</div>
</div>
<button type="submit" class="btn btn-warning">
<i class="fas fa-save me-2"></i>
Passwort ändern
</button>
</form>
</div>
</div>
</div>
</div>
<!-- Berechtigungen anzeigen -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header bg-info text-white">
<h5 class="card-title mb-0">
<i class="fas fa-shield-alt me-2"></i>
Ihre Berechtigungen
</h5>
</div>
<div class="card-body">
<div class="row">
<!-- Projekt-Berechtigungen -->
<div class="col-md-6">
<h6 class="text-primary mb-3"><i class="fas fa-project-diagram me-2"></i>Projekt-Berechtigungen</h6>
<div class="permissions-list">
{% set project_permissions = [
('project.view', 'Projekte anzeigen', 'fas fa-eye'),
('project.create', 'Projekte erstellen', 'fas fa-plus'),
('project.update', 'Projekte aktualisieren', 'fas fa-edit'),
('project.delete', 'Projekte löschen', 'fas fa-trash'),
('project.start', 'Projekte starten', 'fas fa-play'),
('project.stop', 'Projekte stoppen', 'fas fa-stop'),
('project.restart', 'Projekte neustarten', 'fas fa-redo'),
('project.logs', 'Logs anzeigen', 'fas fa-file-alt'),
('project.console', 'Konsole nutzen', 'fas fa-terminal'),
('project.files', 'Dateien verwalten', 'fas fa-folder')
] %}
{% for perm, desc, icon in project_permissions %}
{% set has_perm = user.role in ['admin'] or (user.role == 'moderator' and perm != 'project.delete') or (user.role == 'user' and perm not in ['project.delete', 'project.console']) or (user.role == 'viewer' and perm in ['project.view', 'project.logs']) %}
<div class="permission-item d-flex align-items-center mb-2">
<i class="{{ icon }} me-2 {{ 'text-success' if has_perm else 'text-muted' }}"></i>
<span class="{{ 'text-dark' if has_perm else 'text-muted' }}">{{ desc }}</span>
{% if has_perm %}
<i class="fas fa-check text-success ms-auto"></i>
{% else %}
<i class="fas fa-times text-danger ms-auto"></i>
{% endif %}
</div>
{% endfor %}
</div>
</div>
<!-- System-Berechtigungen -->
<div class="col-md-6">
<h6 class="text-warning mb-3"><i class="fas fa-cogs me-2"></i>System-Berechtigungen</h6>
<div class="permissions-list">
{% set system_permissions = [
('system.config', 'Konfiguration', 'fas fa-cog'),
('system.users', 'Benutzerverwaltung', 'fas fa-users'),
('system.monitoring', 'System-Überwachung', 'fas fa-chart-line'),
('system.backups', 'Backup-Verwaltung', 'fas fa-download'),
('system.docker', 'Docker-Verwaltung', 'fab fa-docker')
] %}
{% for perm, desc, icon in system_permissions %}
{% set has_perm = user.role == 'admin' or (user.role == 'moderator' and perm in ['system.monitoring', 'system.docker']) %}
<div class="permission-item d-flex align-items-center mb-2">
<i class="{{ icon }} me-2 {{ 'text-success' if has_perm else 'text-muted' }}"></i>
<span class="{{ 'text-dark' if has_perm else 'text-muted' }}">{{ desc }}</span>
{% if has_perm %}
<i class="fas fa-check text-success ms-auto"></i>
{% else %}
<i class="fas fa-times text-danger ms-auto"></i>
{% endif %}
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<style>
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
}
.permission-item {
padding: 0.25rem 0;
border-bottom: 1px solid #f8f9fa;
}
.permission-item:last-child {
border-bottom: none;
}
.permissions-list {
max-height: 300px;
overflow-y: auto;
}
</style>
{% endblock %}
{% block scripts %}
<script>
// Passwort-Bestätigung prüfen
document.getElementById('confirm_password').addEventListener('input', function() {
const newPassword = document.getElementById('new_password').value;
const confirmPassword = this.value;
if (newPassword !== confirmPassword) {
this.setCustomValidity('Passwörter stimmen nicht überein');
} else {
this.setCustomValidity('');
}
});
document.getElementById('new_password').addEventListener('input', function() {
const confirmPassword = document.getElementById('confirm_password');
confirmPassword.dispatchEvent(new Event('input'));
});
</script>
{% endblock %}