"feat: Implement Mercedes-Benz certificate generation"

This commit is contained in:
2025-05-26 11:24:36 +02:00
parent 7d4ec90d99
commit 8f416e441c
3 changed files with 283 additions and 95 deletions

View File

@@ -1,12 +1,27 @@
import os import os
import json import json
import secrets
from datetime import timedelta from datetime import timedelta
from pathlib import Path
# Hardcodierte Konfiguration # Basisverzeichnis der Anwendung für relative Pfade
SECRET_KEY = "7445630171969DFAC92C53CEC92E67A9CB2E00B3CB2F" BASE_DIR = Path(__file__).resolve().parent.parent
DATABASE_PATH = "../database/myp.db" PROJECT_ROOT = BASE_DIR.parent
TAPO_USERNAME = "till.tomczak@mercedes-benz.com"
TAPO_PASSWORD = "744563017196A" # Laden von Umgebungsvariablen, falls vorhanden
def get_env_variable(var_name, default=None):
"""Umgebungsvariablen abrufen mit Fallback auf Default-Werte"""
return os.environ.get(var_name, default)
# Sichere Konfiguration - Verwende Umgebungsvariablen oder generiere Secret Key
SECRET_KEY = get_env_variable("MYP_SECRET_KEY", secrets.token_hex(24))
# Datenbankpfad mit korrekter relativer Pfadauflösung
DATABASE_PATH = os.path.join(PROJECT_ROOT, "database", "myp.db")
# Tapo-Zugangsdaten aus Umgebungsvariablen laden
TAPO_USERNAME = get_env_variable("MYP_TAPO_USERNAME", "")
TAPO_PASSWORD = get_env_variable("MYP_TAPO_PASSWORD", "")
# Drucker-Konfiguration # Drucker-Konfiguration
PRINTERS = { PRINTERS = {
@@ -19,28 +34,28 @@ PRINTERS = {
} }
# Logging-Konfiguration # Logging-Konfiguration
LOG_DIR = "logs" LOG_DIR = os.path.join(PROJECT_ROOT, "logs")
LOG_SUBDIRS = ["app", "scheduler", "auth", "jobs", "printers", "errors"] LOG_SUBDIRS = ["app", "scheduler", "auth", "jobs", "printers", "errors"]
LOG_LEVEL = "INFO" LOG_LEVEL = get_env_variable("MYP_LOG_LEVEL", "INFO")
LOG_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" LOG_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S" LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
# Flask-Konfiguration # Flask-Konfiguration
FLASK_HOST = "0.0.0.0" FLASK_HOST = get_env_variable("MYP_FLASK_HOST", "0.0.0.0")
FLASK_PORT = 443 FLASK_PORT = int(get_env_variable("MYP_FLASK_PORT", 443))
FLASK_FALLBACK_PORT = 80 FLASK_FALLBACK_PORT = int(get_env_variable("MYP_FLASK_FALLBACK_PORT", 80))
FLASK_DEBUG = True FLASK_DEBUG = get_env_variable("MYP_FLASK_DEBUG", "True").lower() in ("true", "1", "yes")
SESSION_LIFETIME = timedelta(days=7) SESSION_LIFETIME = timedelta(days=int(get_env_variable("MYP_SESSION_DAYS", 7)))
# SSL-Konfiguration # SSL-Konfiguration
SSL_ENABLED = True SSL_ENABLED = get_env_variable("MYP_SSL_ENABLED", "True").lower() in ("true", "1", "yes")
SSL_CERT_PATH = "../certs/myp.crt" SSL_CERT_PATH = os.path.join(PROJECT_ROOT, "certs", "myp.crt")
SSL_KEY_PATH = "../certs/myp.key" SSL_KEY_PATH = os.path.join(PROJECT_ROOT, "certs", "myp.key")
SSL_HOSTNAME = "raspberrypi" SSL_HOSTNAME = get_env_variable("MYP_SSL_HOSTNAME", "raspberrypi")
# Scheduler-Konfiguration # Scheduler-Konfiguration
SCHEDULER_INTERVAL = 60 # Sekunden SCHEDULER_INTERVAL = int(get_env_variable("MYP_SCHEDULER_INTERVAL", 60)) # Sekunden
SCHEDULER_ENABLED = True SCHEDULER_ENABLED = get_env_variable("MYP_SCHEDULER_ENABLED", "True").lower() in ("true", "1", "yes")
# Datenbank-Konfiguration # Datenbank-Konfiguration
DB_ENGINE = f"sqlite:///{DATABASE_PATH}" DB_ENGINE = f"sqlite:///{DATABASE_PATH}"

View File

@@ -0,0 +1,172 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import datetime
import shutil
from pathlib import Path
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption
import ipaddress
def generate_mercedes_certificate():
"""
Generiert ein vollständiges Mercedes-Benz-Zertifikat
mit korrekten Metadaten und alternativen Namen.
"""
print("Generiere Mercedes-Benz SSL-Zertifikat...")
# Verzeichnispfade definieren und alte Zertifikate löschen
old_ssl_dir = "app/instance/ssl"
if os.path.exists(old_ssl_dir):
print(f"Lösche alten SSL-Ordner: {old_ssl_dir}")
try:
shutil.rmtree(old_ssl_dir)
except Exception as e:
print(f"Warnung: Konnte alten SSL-Ordner nicht löschen: {e}")
# Neues Zielverzeichnis
certs_dir = "app/certs"
os.makedirs(certs_dir, exist_ok=True)
# Pfade zu Zertifikat und Schlüssel
cert_path = os.path.join(certs_dir, "myp.crt")
key_path = os.path.join(certs_dir, "myp.key")
# Entferne alte Zertifikate, falls vorhanden
for path in [cert_path, key_path]:
if os.path.exists(path):
os.remove(path)
try:
# Privaten Schlüssel mit 4096 Bit generieren (sicherer)
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=4096,
)
# Aktuelles Datum und Ablaufdatum (1 Jahr gültig)
now = datetime.datetime.now()
valid_until = now + datetime.timedelta(days=365)
# Liste aller möglichen Hostnamen/IPs
hostnames = [
"localhost",
"raspberrypi",
"m040tbaraspi001",
"m040tbaraspi001.de040.corpintra.net",
"mbag.corpintra.net",
"mbag.mb.corpintra.net"
]
# IP-Adressen (als String, werden später konvertiert)
ip_addresses = [
"127.0.0.1",
"192.168.0.101",
"192.168.0.102",
"192.168.0.103",
"192.168.0.104",
"192.168.0.105",
"192.168.0.106"
]
# Erweiterte Zertifikatsattribute für Mercedes-Benz
subject = issuer = x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, "raspberrypi"),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Mercedes-Benz AG"),
x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "Werk 040 Berlin"),
x509.NameAttribute(NameOID.LOCALITY_NAME, "Berlin"),
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Berlin"),
x509.NameAttribute(NameOID.COUNTRY_NAME, "DE"),
x509.NameAttribute(NameOID.EMAIL_ADDRESS, "admin@mercedes-benz.com"),
])
# Subject Alternative Names (SAN) erstellen
san_list = []
for hostname in hostnames:
san_list.append(x509.DNSName(hostname))
# IP-Adressen hinzufügen
for ip in ip_addresses:
san_list.append(x509.IPAddress(ipaddress.IPv4Address(ip)))
# Zertifikat erstellen
cert = x509.CertificateBuilder().subject_name(
subject
).issuer_name(
issuer
).public_key(
private_key.public_key()
).serial_number(
x509.random_serial_number()
).not_valid_before(
now
).not_valid_after(
valid_until
).add_extension(
x509.SubjectAlternativeName(san_list),
critical=False,
).add_extension(
x509.BasicConstraints(ca=True, path_length=None), critical=True
).add_extension(
x509.KeyUsage(
digital_signature=True,
content_commitment=False,
key_encipherment=True,
data_encipherment=False,
key_agreement=False,
key_cert_sign=True,
crl_sign=True,
encipher_only=False,
decipher_only=False
), critical=True
).add_extension(
x509.ExtendedKeyUsage([
x509.oid.ExtendedKeyUsageOID.SERVER_AUTH,
x509.oid.ExtendedKeyUsageOID.CLIENT_AUTH,
x509.oid.ExtendedKeyUsageOID.CODE_SIGNING
]), critical=False
).sign(private_key, hashes.SHA256())
# Zertifikat und Schlüssel speichern
with open(key_path, "wb") as f:
f.write(private_key.private_bytes(
encoding=Encoding.PEM,
format=PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=NoEncryption()
))
with open(cert_path, "wb") as f:
f.write(cert.public_bytes(Encoding.PEM))
print(f"Mercedes-Benz SSL-Zertifikat wurde erfolgreich erstellt:")
print(f"- Zertifikat: {os.path.abspath(cert_path)}")
print(f"- Schlüssel: {os.path.abspath(key_path)}")
print(f"- Gültig bis: {valid_until.strftime('%d.%m.%Y')}")
print(f"- Hostnamen: {', '.join(hostnames)}")
print(f"- IP-Adressen: {', '.join(ip_addresses)}")
# Kopieren des Zertifikats in das Frontend-Verzeichnis
frontend_ssl_dir = "../frontend/ssl"
os.makedirs(frontend_ssl_dir, exist_ok=True)
import shutil
shutil.copy2(cert_path, os.path.join(frontend_ssl_dir, "myp.crt"))
shutil.copy2(key_path, os.path.join(frontend_ssl_dir, "myp.key"))
print(f"Zertifikate wurden in das Frontend-Verzeichnis kopiert: {os.path.abspath(frontend_ssl_dir)}")
return True
except Exception as e:
print(f"Fehler beim Erstellen des Mercedes-Benz SSL-Zertifikats: {e}")
return False
if __name__ == "__main__":
success = generate_mercedes_certificate()
if success:
print("Mercedes-Benz SSL-Zertifikatserstellung erfolgreich abgeschlossen.")
else:
print("Fehler bei der Zertifikatserstellung!")
exit(1)

View File

@@ -1,8 +1,8 @@
# MYP Installer Control Center # MYP Installer Control Center
# Zentrale Installationskonsole für die MYP-Plattform # Zentrale Installationskonsole fuer die MYP-Plattform
# Version 2.0 # Version 2.0
# Farbdefinitionen für bessere Lesbarkeit # Farbdefinitionen fuer bessere Lesbarkeit
$ColorTitle = "Cyan" $ColorTitle = "Cyan"
$ColorSuccess = "Green" $ColorSuccess = "Green"
$ColorError = "Red" $ColorError = "Red"
@@ -10,7 +10,7 @@ $ColorWarning = "Yellow"
$ColorInfo = "Blue" $ColorInfo = "Blue"
$ColorCommand = "White" $ColorCommand = "White"
# Überprüfen, ob das Skript als Administrator ausgeführt wird # Ueberpruefen, ob das Skript als Administrator ausgefuehrt wird
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
function Show-Header { function Show-Header {
@@ -24,8 +24,8 @@ function Show-Header {
Write-Host "=============================================================" -ForegroundColor $ColorTitle Write-Host "=============================================================" -ForegroundColor $ColorTitle
if (-not $isAdmin) { if (-not $isAdmin) {
Write-Host "HINWEIS: Dieses Skript läuft ohne Administrator-Rechte." -ForegroundColor $ColorWarning Write-Host "HINWEIS: Dieses Skript laeuft ohne Administrator-Rechte." -ForegroundColor $ColorWarning
Write-Host "Einige Funktionen sind möglicherweise eingeschränkt." -ForegroundColor $ColorWarning Write-Host "Einige Funktionen sind moeglicherweise eingeschraenkt." -ForegroundColor $ColorWarning
Write-Host "=============================================================" -ForegroundColor $ColorTitle Write-Host "=============================================================" -ForegroundColor $ColorTitle
} }
@@ -55,16 +55,16 @@ function Exec-Command {
try { try {
Invoke-Expression $Command | Out-Host Invoke-Expression $Command | Out-Host
if ($LASTEXITCODE -eq 0 -or $null -eq $LASTEXITCODE) { if ($LASTEXITCODE -eq 0 -or $null -eq $LASTEXITCODE) {
Write-Host "Erfolgreich abgeschlossen!" -ForegroundColor $ColorSuccess Write-Host "Erfolgreich abgeschlossen!" -ForegroundColor $ColorSuccess
return $true return $true
} else { } else {
Write-Host "Fehler beim Ausführen des Befehls. Exit-Code: $LASTEXITCODE" -ForegroundColor $ColorError Write-Host "Fehler beim Ausfuehren des Befehls. Exit-Code: $LASTEXITCODE" -ForegroundColor $ColorError
return $false return $false
} }
} }
catch { catch {
$errorMessage = $_.Exception.Message $errorMessage = $_.Exception.Message
Write-Host "Fehler: $errorMessage" -ForegroundColor $ColorError Write-Host "Fehler: $errorMessage" -ForegroundColor $ColorError
return $false return $false
} }
} }
@@ -78,54 +78,54 @@ function Get-LocalIPAddress {
} }
function Test-Dependencies { function Test-Dependencies {
Show-Header "Systemvoraussetzungen prüfen" Show-Header "Systemvoraussetzungen pruefen"
Write-Host "Prüfe Abhängigkeiten..." -ForegroundColor $ColorInfo Write-Host "Pruefe Abhaengigkeiten..." -ForegroundColor $ColorInfo
$pythonInstalled = Test-CommandExists "python" $pythonInstalled = Test-CommandExists "python"
if ($pythonInstalled) { if ($pythonInstalled) {
Write-Host "Python gefunden" -ForegroundColor $ColorSuccess Write-Host "Python gefunden" -ForegroundColor $ColorSuccess
} else { } else {
Write-Host "Python nicht gefunden" -ForegroundColor $ColorError Write-Host "Python nicht gefunden" -ForegroundColor $ColorError
} }
$pipInstalled = Test-CommandExists "pip" $pipInstalled = Test-CommandExists "pip"
if ($pipInstalled) { if ($pipInstalled) {
Write-Host "Pip gefunden" -ForegroundColor $ColorSuccess Write-Host "Pip gefunden" -ForegroundColor $ColorSuccess
} else { } else {
Write-Host "Pip nicht gefunden" -ForegroundColor $ColorError Write-Host "Pip nicht gefunden" -ForegroundColor $ColorError
} }
$dockerInstalled = Test-CommandExists "docker" $dockerInstalled = Test-CommandExists "docker"
if ($dockerInstalled) { if ($dockerInstalled) {
Write-Host "Docker gefunden" -ForegroundColor $ColorSuccess Write-Host "Docker gefunden" -ForegroundColor $ColorSuccess
} else { } else {
Write-Host "Docker nicht gefunden" -ForegroundColor $ColorError Write-Host "Docker nicht gefunden" -ForegroundColor $ColorError
} }
$dockerComposeInstalled = Test-CommandExists "docker-compose" $dockerComposeInstalled = Test-CommandExists "docker-compose"
if ($dockerComposeInstalled) { if ($dockerComposeInstalled) {
Write-Host "Docker Compose gefunden" -ForegroundColor $ColorSuccess Write-Host "Docker Compose gefunden" -ForegroundColor $ColorSuccess
} else { } else {
Write-Host "Docker Compose nicht gefunden" -ForegroundColor $ColorError Write-Host "Docker Compose nicht gefunden" -ForegroundColor $ColorError
} }
$nodeInstalled = Test-CommandExists "node" $nodeInstalled = Test-CommandExists "node"
if ($nodeInstalled) { if ($nodeInstalled) {
Write-Host "Node.js gefunden" -ForegroundColor $ColorSuccess Write-Host "Node.js gefunden" -ForegroundColor $ColorSuccess
} else { } else {
Write-Host "Node.js nicht gefunden" -ForegroundColor $ColorError Write-Host "Node.js nicht gefunden" -ForegroundColor $ColorError
} }
$npmInstalled = Test-CommandExists "npm" $npmInstalled = Test-CommandExists "npm"
if ($npmInstalled) { if ($npmInstalled) {
Write-Host "NPM gefunden" -ForegroundColor $ColorSuccess Write-Host "NPM gefunden" -ForegroundColor $ColorSuccess
} else { } else {
Write-Host "NPM nicht gefunden" -ForegroundColor $ColorError Write-Host "NPM nicht gefunden" -ForegroundColor $ColorError
} }
Write-Host "" Write-Host ""
Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." Write-Host "Druecken Sie eine beliebige Taste, um fortzufahren..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
} }
@@ -137,7 +137,7 @@ function Setup-Hosts {
Write-Host "Bitte starten Sie das Skript als Administrator neu." -ForegroundColor $ColorWarning Write-Host "Bitte starten Sie das Skript als Administrator neu." -ForegroundColor $ColorWarning
Write-Host "" Write-Host ""
Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." Write-Host "Druecken Sie eine beliebige Taste, um fortzufahren..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
return return
} }
@@ -148,11 +148,11 @@ function Setup-Hosts {
$hostsFile = "$env:windir\System32\drivers\etc\hosts" $hostsFile = "$env:windir\System32\drivers\etc\hosts"
Write-Host "Hosts-Datei: $hostsFile" -ForegroundColor $ColorInfo Write-Host "Hosts-Datei: $hostsFile" -ForegroundColor $ColorInfo
# Prüfen, ob die Einträge bereits existieren # Pruefen, ob die Eintraege bereits existieren
$frontendEntry = Select-String -Path $hostsFile -Pattern "m040tbaraspi001.de040.corpintra.net" -Quiet $frontendEntry = Select-String -Path $hostsFile -Pattern "m040tbaraspi001.de040.corpintra.net" -Quiet
$backendEntry = Select-String -Path $hostsFile -Pattern "raspberrypi" -Quiet $backendEntry = Select-String -Path $hostsFile -Pattern "raspberrypi" -Quiet
# Einträge in die Hosts-Datei schreiben # Eintraege in die Hosts-Datei schreiben
Write-Host "Aktualisiere Hosts-Datei..." -ForegroundColor $ColorInfo Write-Host "Aktualisiere Hosts-Datei..." -ForegroundColor $ColorInfo
$hostsContent = Get-Content -Path $hostsFile $hostsContent = Get-Content -Path $hostsFile
@@ -161,7 +161,7 @@ function Setup-Hosts {
$hostsContent += "" $hostsContent += ""
$hostsContent += "# MYP Frontend Host" $hostsContent += "# MYP Frontend Host"
$hostsContent += "$localIP m040tbaraspi001.de040.corpintra.net m040tbaraspi001" $hostsContent += "$localIP m040tbaraspi001.de040.corpintra.net m040tbaraspi001"
Write-Host "Frontend-Hostname hinzugefügt" -ForegroundColor $ColorSuccess Write-Host "Frontend-Hostname hinzugefuegt" -ForegroundColor $ColorSuccess
} else { } else {
Write-Host "Frontend-Hostname ist bereits konfiguriert" -ForegroundColor $ColorWarning Write-Host "Frontend-Hostname ist bereits konfiguriert" -ForegroundColor $ColorWarning
} }
@@ -170,7 +170,7 @@ function Setup-Hosts {
$hostsContent += "" $hostsContent += ""
$hostsContent += "# MYP Backend Host" $hostsContent += "# MYP Backend Host"
$hostsContent += "$localIP raspberrypi" $hostsContent += "$localIP raspberrypi"
Write-Host "Backend-Hostname hinzugefügt" -ForegroundColor $ColorSuccess Write-Host "Backend-Hostname hinzugefuegt" -ForegroundColor $ColorSuccess
} else { } else {
Write-Host "Backend-Hostname ist bereits konfiguriert" -ForegroundColor $ColorWarning Write-Host "Backend-Hostname ist bereits konfiguriert" -ForegroundColor $ColorWarning
} }
@@ -191,7 +191,7 @@ function Setup-Hosts {
Write-Host " - Backend: raspberrypi" -ForegroundColor $ColorCommand Write-Host " - Backend: raspberrypi" -ForegroundColor $ColorCommand
Write-Host "" Write-Host ""
Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." Write-Host "Druecken Sie eine beliebige Taste, um fortzufahren..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
} }
@@ -205,14 +205,15 @@ function Create-SSLCertificates {
$frontendCertFile = "$certDir/frontend.crt" $frontendCertFile = "$certDir/frontend.crt"
$frontendKeyFile = "$certDir/frontend.key" $frontendKeyFile = "$certDir/frontend.key"
Write-Host "Zertifikate werden für folgende Hostnamen erstellt:" -ForegroundColor $ColorInfo Write-Host "Zertifikate werden fuer folgende Hostnamen erstellt:" -ForegroundColor $ColorInfo
# Hostname-Auswahl # Hostname-Auswahl
Write-Host "1. Für lokale Entwicklung (localhost)" -ForegroundColor $ColorCommand Write-Host "1. Fuer lokale Entwicklung (localhost)" -ForegroundColor $ColorCommand
Write-Host "2. Für Raspberry Pi Deployment (raspberrypi)" -ForegroundColor $ColorCommand Write-Host "2. Fuer Raspberry Pi Deployment (raspberrypi)" -ForegroundColor $ColorCommand
Write-Host "3. Für Unternehmens-Setup (m040tbaraspi001.de040.corpintra.net)" -ForegroundColor $ColorCommand Write-Host "3. Fuer Unternehmens-Setup (m040tbaraspi001.de040.corpintra.net)" -ForegroundColor $ColorCommand
$choice = Read-Host "Wählen Sie eine Option (1-3, Standard: 1)" $inputText = "Waehlen Sie eine Option (1-3)"
$choice = Read-Host $inputText
$backendHostname = "localhost" $backendHostname = "localhost"
$frontendHostname = "localhost" $frontendHostname = "localhost"
@@ -241,11 +242,11 @@ function Create-SSLCertificates {
$pythonInstalled = Test-CommandExists "python" $pythonInstalled = Test-CommandExists "python"
if ($pythonInstalled) { if ($pythonInstalled) {
# Überprüfen, ob cryptography installiert ist # Ueberpruefen, ob cryptography installiert ist
$cryptographyInstalled = python -c "try: import cryptography; print('True'); except ImportError: print('False')" 2>$null $cryptographyInstalled = python -c "try: import cryptography; print('True'); except ImportError: print('False')" 2>$null
if ($cryptographyInstalled -ne "True") { if ($cryptographyInstalled -ne "True") {
Write-Host "Installiere Python-Abhängigkeit 'cryptography'..." -ForegroundColor $ColorWarning Write-Host "Installiere Python-Abhaengigkeit 'cryptography'..." -ForegroundColor $ColorWarning
Exec-Command "pip install cryptography" "Installiere cryptography-Paket" Exec-Command "pip install cryptography" "Installiere cryptography-Paket"
} }
@@ -266,13 +267,13 @@ def create_self_signed_cert(cert_path, key_path, hostname="localhost"):
if cert_dir and not os.path.exists(cert_dir): if cert_dir and not os.path.exists(cert_dir):
os.makedirs(cert_dir, exist_ok=True) os.makedirs(cert_dir, exist_ok=True)
# Privaten Schlüssel generieren # Privaten Schluessel generieren
private_key = rsa.generate_private_key( private_key = rsa.generate_private_key(
public_exponent=65537, public_exponent=65537,
key_size=4096, key_size=4096,
) )
# Schlüsseldatei schreiben # Schluesseldatei schreiben
with open(key_path, "wb") as key_file: with open(key_path, "wb") as key_file:
key_file.write(private_key.private_bytes( key_file.write(private_key.private_bytes(
encoding=Encoding.PEM, encoding=Encoding.PEM,
@@ -282,9 +283,9 @@ def create_self_signed_cert(cert_path, key_path, hostname="localhost"):
# Aktuelles Datum und Ablaufdatum berechnen # Aktuelles Datum und Ablaufdatum berechnen
now = datetime.datetime.now() now = datetime.datetime.now()
valid_until = now + datetime.timedelta(days=3650) # 10 Jahre gültig valid_until = now + datetime.timedelta(days=3650) # 10 Jahre gueltig
# Name für das Zertifikat erstellen # Name fuer das Zertifikat erstellen
subject = issuer = x509.Name([ subject = issuer = x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, hostname), x509.NameAttribute(NameOID.COMMON_NAME, hostname),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Mercedes-Benz AG"), x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Mercedes-Benz AG"),
@@ -338,10 +339,10 @@ def create_self_signed_cert(cert_path, key_path, hostname="localhost"):
with open(cert_path, "wb") as cert_file: with open(cert_path, "wb") as cert_file:
cert_file.write(cert.public_bytes(Encoding.PEM)) cert_file.write(cert.public_bytes(Encoding.PEM))
print(f"Selbstsigniertes SSL-Zertifikat für '{hostname}' erstellt:") print(f"Selbstsigniertes SSL-Zertifikat fuer '{hostname}' erstellt:")
print(f"Zertifikat: {cert_path}") print(f"Zertifikat: {cert_path}")
print(f"Schlüssel: {key_path}") print(f"Schluessel: {key_path}")
print(f"Gültig für 10 Jahre.") print(f"Gueltig fuer 10 Jahre.")
# Backend-Zertifikat erstellen # Backend-Zertifikat erstellen
create_self_signed_cert('$backendCertFile', '$backendKeyFile', '$backendHostname') create_self_signed_cert('$backendCertFile', '$backendKeyFile', '$backendHostname')
@@ -353,7 +354,7 @@ create_self_signed_cert('$frontendCertFile', '$frontendKeyFile', '$frontendHostn
$tempScriptPath = ".\temp_cert_script.py" $tempScriptPath = ".\temp_cert_script.py"
$certScript | Out-File -FilePath $tempScriptPath -Encoding utf8 $certScript | Out-File -FilePath $tempScriptPath -Encoding utf8
# Python-Skript ausführen # Python-Skript ausfuehren
try { try {
python $tempScriptPath python $tempScriptPath
Write-Host "SSL-Zertifikate erfolgreich erstellt!" -ForegroundColor $ColorSuccess Write-Host "SSL-Zertifikate erfolgreich erstellt!" -ForegroundColor $ColorSuccess
@@ -363,18 +364,18 @@ create_self_signed_cert('$frontendCertFile', '$frontendKeyFile', '$frontendHostn
Write-Host "Fehler beim Erstellen der SSL-Zertifikate: $errorMessage" -ForegroundColor $ColorError Write-Host "Fehler beim Erstellen der SSL-Zertifikate: $errorMessage" -ForegroundColor $ColorError
} }
finally { finally {
# Temporäres Skript löschen # Temporaeres Skript loeschen
if (Test-Path $tempScriptPath) { if (Test-Path $tempScriptPath) {
Remove-Item -Path $tempScriptPath -Force Remove-Item -Path $tempScriptPath -Force
} }
} }
} else { } else {
Write-Host "Python nicht gefunden. SSL-Zertifikate können nicht erstellt werden." -ForegroundColor $ColorError Write-Host "Python nicht gefunden. SSL-Zertifikate koennen nicht erstellt werden." -ForegroundColor $ColorError
} }
# Zertifikate im System installieren (optional) # Zertifikate im System installieren (optional)
if ($isAdmin) { if ($isAdmin) {
$installCerts = Read-Host "Möchten Sie die Zertifikate im System installieren? (j/n, Standard: n)" $installCerts = Read-Host "Moechten Sie die Zertifikate im System installieren? (j/n)"
if ($installCerts -eq "j") { if ($installCerts -eq "j") {
if (Test-Path $backendCertFile) { if (Test-Path $backendCertFile) {
@@ -391,13 +392,13 @@ create_self_signed_cert('$frontendCertFile', '$frontendKeyFile', '$frontendHostn
Write-Host "Hinweis: Um die Zertifikate im System zu installieren, starten Sie das Skript als Administrator." -ForegroundColor $ColorWarning Write-Host "Hinweis: Um die Zertifikate im System zu installieren, starten Sie das Skript als Administrator." -ForegroundColor $ColorWarning
} }
# Frontend für HTTPS konfigurieren # Frontend fuer HTTPS konfigurieren
Write-Host "" Write-Host ""
Write-Host "Möchten Sie das Frontend für HTTPS konfigurieren? (j/n, Standard: j)" -ForegroundColor $ColorInfo Write-Host "Moechten Sie das Frontend fuer HTTPS konfigurieren? (j/n)" -ForegroundColor $ColorInfo
$configureFrontend = Read-Host $configureFrontend = Read-Host
if ($configureFrontend -ne "n") { if ($configureFrontend -ne "n") {
Write-Host "Konfiguriere Frontend für HTTPS..." -ForegroundColor $ColorInfo Write-Host "Konfiguriere Frontend fuer HTTPS..." -ForegroundColor $ColorInfo
# Kopiere Zertifikate ins Frontend-Verzeichnis # Kopiere Zertifikate ins Frontend-Verzeichnis
$frontendSslDir = "./frontend/ssl" $frontendSslDir = "./frontend/ssl"
@@ -415,7 +416,7 @@ create_self_signed_cert('$frontendCertFile', '$frontendKeyFile', '$frontendHostn
Write-Host "Zertifikate ins Frontend-Verzeichnis kopiert." -ForegroundColor $ColorSuccess Write-Host "Zertifikate ins Frontend-Verzeichnis kopiert." -ForegroundColor $ColorSuccess
# Prüfen, ob .env.local existiert und aktualisieren # Pruefen, ob .env.local existiert und aktualisieren
$envLocalPath = "./frontend/.env.local" $envLocalPath = "./frontend/.env.local"
$envContent = "" $envContent = ""
@@ -445,7 +446,7 @@ create_self_signed_cert('$frontendCertFile', '$frontendKeyFile', '$frontendHostn
# Update existierende Konfiguration # Update existierende Konfiguration
$envContent = $envContent -replace $regex, $config $envContent = $envContent -replace $regex, $config
} else { } else {
# Neue Konfiguration hinzufügen # Neue Konfiguration hinzufuegen
$envContent += "`n$config" $envContent += "`n$config"
} }
} }
@@ -461,14 +462,14 @@ create_self_signed_cert('$frontendCertFile', '$frontendKeyFile', '$frontendHostn
Write-Host "Frontend: $frontendCertFile" -ForegroundColor $ColorCommand Write-Host "Frontend: $frontendCertFile" -ForegroundColor $ColorCommand
Write-Host "" Write-Host ""
Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." Write-Host "Druecken Sie eine beliebige Taste, um fortzufahren..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
} }
function Setup-Environment { function Setup-Environment {
Show-Header "Umgebungs-Setup" Show-Header "Umgebungs-Setup"
# Prüfen, ob Python und pip installiert sind # Pruefen, ob Python und pip installiert sind
$pythonInstalled = Test-CommandExists "python" $pythonInstalled = Test-CommandExists "python"
$pipInstalled = Test-CommandExists "pip" $pipInstalled = Test-CommandExists "pip"
@@ -476,25 +477,25 @@ function Setup-Environment {
Write-Host "Python oder pip ist nicht installiert. Bitte installieren Sie Python 3.6+ und versuchen Sie es erneut." -ForegroundColor $ColorError Write-Host "Python oder pip ist nicht installiert. Bitte installieren Sie Python 3.6+ und versuchen Sie es erneut." -ForegroundColor $ColorError
Write-Host "" Write-Host ""
Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." Write-Host "Druecken Sie eine beliebige Taste, um fortzufahren..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
return return
} }
# Python-Abhängigkeiten installieren # Python-Abhaengigkeiten installieren
Write-Host "Installiere Backend-Abhängigkeiten..." -ForegroundColor $ColorInfo Write-Host "Installiere Backend-Abhaengigkeiten..." -ForegroundColor $ColorInfo
Exec-Command "pip install -r backend/requirements.txt" "Installiere Python-Abhängigkeiten" Exec-Command "pip install -r backend/requirements.txt" "Installiere Python-Abhaengigkeiten"
# Prüfen, ob Node.js und npm installiert sind # Pruefen, ob Node.js und npm installiert sind
$nodeInstalled = Test-CommandExists "node" $nodeInstalled = Test-CommandExists "node"
$npmInstalled = Test-CommandExists "npm" $npmInstalled = Test-CommandExists "npm"
if ($nodeInstalled -and $npmInstalled) { if ($nodeInstalled -and $npmInstalled) {
# Frontend-Abhängigkeiten installieren # Frontend-Abhaengigkeiten installieren
Write-Host "Installiere Frontend-Abhängigkeiten..." -ForegroundColor $ColorInfo Write-Host "Installiere Frontend-Abhaengigkeiten..." -ForegroundColor $ColorInfo
Exec-Command "cd frontend && npm install" "Installiere Node.js-Abhängigkeiten" Exec-Command "cd frontend && npm install" "Installiere Node.js-Abhaengigkeiten"
} else { } else {
Write-Host "Node.js oder npm ist nicht installiert. Frontend-Abhängigkeiten werden übersprungen." -ForegroundColor $ColorWarning Write-Host "Node.js oder npm ist nicht installiert. Frontend-Abhaengigkeiten werden uebersprungen." -ForegroundColor $ColorWarning
} }
# Docker-Compose Datei aktualisieren # Docker-Compose Datei aktualisieren
@@ -516,31 +517,31 @@ function Setup-Environment {
Write-Host "Umgebungs-Setup abgeschlossen!" -ForegroundColor $ColorSuccess Write-Host "Umgebungs-Setup abgeschlossen!" -ForegroundColor $ColorSuccess
Write-Host "" Write-Host ""
Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." Write-Host "Druecken Sie eine beliebige Taste, um fortzufahren..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
} }
function Start-Application { function Start-Application {
Show-Header "Anwendung starten" Show-Header "Anwendung starten"
Write-Host "Wie möchten Sie die Anwendung starten?" -ForegroundColor $ColorInfo Write-Host "Wie moechten Sie die Anwendung starten?" -ForegroundColor $ColorInfo
Write-Host "1. Backend-Server starten (Python)" -ForegroundColor $ColorCommand Write-Host "1. Backend-Server starten (Python)" -ForegroundColor $ColorCommand
Write-Host "2. Frontend-Server starten (Node.js)" -ForegroundColor $ColorCommand Write-Host "2. Frontend-Server starten (Node.js)" -ForegroundColor $ColorCommand
Write-Host "3. Beide Server starten (in separaten Fenstern)" -ForegroundColor $ColorCommand Write-Host "3. Beide Server starten (in separaten Fenstern)" -ForegroundColor $ColorCommand
Write-Host "4. Mit Docker Compose starten" -ForegroundColor $ColorCommand Write-Host "4. Mit Docker Compose starten" -ForegroundColor $ColorCommand
Write-Host "5. Zurück zum Hauptmenü" -ForegroundColor $ColorCommand Write-Host "5. Zurueck zum Hauptmenue" -ForegroundColor $ColorCommand
$choice = Read-Host "Wählen Sie eine Option (1-5)" $choice = Read-Host "Waehlen Sie eine Option (1-5)"
if ($choice -eq "1") { if ($choice -eq "1") {
Write-Host "Starte Backend-Server..." -ForegroundColor $ColorInfo Write-Host "Starte Backend-Server..." -ForegroundColor $ColorInfo
Start-Process -FilePath "python" -ArgumentList "backend/app/app.py" -NoNewWindow Start-Process -FilePath "python" -ArgumentList "backend/app/app.py" -NoNewWindow
Write-Host "Backend-Server läuft jetzt im Hintergrund." -ForegroundColor $ColorSuccess Write-Host "Backend-Server laeuft jetzt im Hintergrund." -ForegroundColor $ColorSuccess
} }
elseif ($choice -eq "2") { elseif ($choice -eq "2") {
Write-Host "Starte Frontend-Server..." -ForegroundColor $ColorInfo Write-Host "Starte Frontend-Server..." -ForegroundColor $ColorInfo
Start-Process -FilePath "npm" -ArgumentList "run dev" -WorkingDirectory "frontend" -NoNewWindow Start-Process -FilePath "npm" -ArgumentList "run dev" -WorkingDirectory "frontend" -NoNewWindow
Write-Host "Frontend-Server läuft jetzt im Hintergrund." -ForegroundColor $ColorSuccess Write-Host "Frontend-Server laeuft jetzt im Hintergrund." -ForegroundColor $ColorSuccess
} }
elseif ($choice -eq "3") { elseif ($choice -eq "3") {
Write-Host "Starte Backend-Server..." -ForegroundColor $ColorInfo Write-Host "Starte Backend-Server..." -ForegroundColor $ColorInfo
@@ -567,27 +568,27 @@ function Start-Application {
return return
} }
else { else {
Write-Host "Ungültige Option." -ForegroundColor $ColorError Write-Host "Ungueltige Option." -ForegroundColor $ColorError
} }
Write-Host "" Write-Host ""
Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." Write-Host "Druecken Sie eine beliebige Taste, um fortzufahren..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
} }
# Hauptmenü anzeigen # Hauptmenue anzeigen
function Show-MainMenu { function Show-MainMenu {
Show-Header "Hauptmenü" Show-Header "Hauptmenue"
Write-Host "1. Systemvoraussetzungen prüfen" -ForegroundColor $ColorCommand Write-Host "1. Systemvoraussetzungen pruefen" -ForegroundColor $ColorCommand
Write-Host "2. Host-Konfiguration einrichten" -ForegroundColor $ColorCommand Write-Host "2. Host-Konfiguration einrichten" -ForegroundColor $ColorCommand
Write-Host "3. SSL-Zertifikate erstellen" -ForegroundColor $ColorCommand Write-Host "3. SSL-Zertifikate erstellen" -ForegroundColor $ColorCommand
Write-Host "4. Umgebung einrichten (Abhängigkeiten installieren)" -ForegroundColor $ColorCommand Write-Host "4. Umgebung einrichten (Abhaengigkeiten installieren)" -ForegroundColor $ColorCommand
Write-Host "5. Anwendung starten" -ForegroundColor $ColorCommand Write-Host "5. Anwendung starten" -ForegroundColor $ColorCommand
Write-Host "6. Beenden" -ForegroundColor $ColorCommand Write-Host "6. Beenden" -ForegroundColor $ColorCommand
Write-Host "" Write-Host ""
$choice = Read-Host "Wählen Sie eine Option (1-6)" $choice = Read-Host "Waehlen Sie eine Option (1-6)"
if ($choice -eq "1") { if ($choice -eq "1") {
Test-Dependencies Test-Dependencies
@@ -613,7 +614,7 @@ function Show-MainMenu {
exit exit
} }
else { else {
Write-Host "Ungültige Option. Bitte versuchen Sie es erneut." -ForegroundColor $ColorError Write-Host "Ungueltige Option. Bitte versuchen Sie es erneut." -ForegroundColor $ColorError
Start-Sleep -Seconds 2 Start-Sleep -Seconds 2
Show-MainMenu Show-MainMenu
} }