fixed permission implementation for ressources
This commit is contained in:
735
backend/main.go
735
backend/main.go
@@ -823,16 +823,35 @@ func getSpacesHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Verwende Prepared Statement für bessere Performance und Sicherheit
|
||||
stmt, err := db.Prepare("SELECT id, name, description, created_at FROM spaces ORDER BY created_at DESC")
|
||||
// Hole Benutzer-ID
|
||||
userID, _ := getUserFromRequest(r)
|
||||
|
||||
// Hole alle Spaces, auf die der Benutzer Zugriff hat
|
||||
accessibleSpaceIDs, err := getAccessibleSpaceIDs(userID)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Vorbereiten der Abfrage", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Vorbereiten der Abfrage: %v", err)
|
||||
http.Error(w, "Fehler beim Prüfen der Berechtigungen", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen der Berechtigungen: %v", err)
|
||||
return
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
rows, err := stmt.Query()
|
||||
// Wenn der Benutzer keinen Zugriff auf Spaces hat, gebe leeres Array zurück
|
||||
if len(accessibleSpaceIDs) == 0 {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode([]Space{})
|
||||
return
|
||||
}
|
||||
|
||||
// Baue Query mit IN-Klausel für die zugänglichen Spaces
|
||||
placeholders := make([]string, len(accessibleSpaceIDs))
|
||||
args := make([]interface{}, len(accessibleSpaceIDs))
|
||||
for i, spaceID := range accessibleSpaceIDs {
|
||||
placeholders[i] = "?"
|
||||
args[i] = spaceID
|
||||
}
|
||||
|
||||
query := fmt.Sprintf("SELECT id, name, description, created_at FROM spaces WHERE id IN (%s) ORDER BY created_at DESC", strings.Join(placeholders, ","))
|
||||
|
||||
rows, err := db.Query(query, args...)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Abrufen der Spaces", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Abrufen der Spaces: %v", err)
|
||||
@@ -888,6 +907,33 @@ func createSpaceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe Berechtigung: Nur FULL_ACCESS darf Spaces erstellen
|
||||
userID, username := getUserFromRequest(r)
|
||||
if userID == "" {
|
||||
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe, ob der Benutzer FULL_ACCESS hat (ohne Space-Beschränkung)
|
||||
permissions, err := getUserPermissions(userID)
|
||||
if err != nil || len(permissions.Groups) == 0 {
|
||||
http.Error(w, "Keine Berechtigung zum Erstellen von Spaces", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
hasFullAccess := false
|
||||
for _, group := range permissions.Groups {
|
||||
if group.Permission == PermissionFullAccess {
|
||||
hasFullAccess = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !hasFullAccess {
|
||||
http.Error(w, "Keine Berechtigung zum Erstellen von Spaces. Vollzugriff erforderlich.", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
var req CreateSpaceRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
http.Error(w, "Invalid request body", http.StatusBadRequest)
|
||||
@@ -904,7 +950,7 @@ func createSpaceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
createdAt := time.Now()
|
||||
|
||||
// Speichere in Datenbank
|
||||
_, err := db.Exec(
|
||||
_, err = db.Exec(
|
||||
"INSERT INTO spaces (id, name, description, created_at) VALUES (?, ?, ?, ?)",
|
||||
id, req.Name, req.Description, createdAt,
|
||||
)
|
||||
@@ -926,7 +972,6 @@ func createSpaceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Audit-Log: Space erstellt
|
||||
if auditService != nil {
|
||||
userID, username := getUserFromRequest(r)
|
||||
ipAddress, userAgent := getRequestInfo(r)
|
||||
auditService.Track(r.Context(), "CREATE", "space", id, userID, username, map[string]interface{}{
|
||||
"name": req.Name,
|
||||
@@ -955,9 +1000,28 @@ func deleteSpaceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe Berechtigung: Nur FULL_ACCESS darf Spaces löschen
|
||||
userID, username := getUserFromRequest(r)
|
||||
if userID == "" {
|
||||
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
hasPermission, err := hasPermission(userID, id, PermissionFullAccess)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen der Berechtigung", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen der Berechtigung: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !hasPermission {
|
||||
http.Error(w, "Keine Berechtigung zum Löschen von Spaces. Vollzugriff erforderlich.", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe ob der Space existiert
|
||||
var exists bool
|
||||
err := db.QueryRow("SELECT EXISTS(SELECT 1 FROM spaces WHERE id = ?)", id).Scan(&exists)
|
||||
err = db.QueryRow("SELECT EXISTS(SELECT 1 FROM spaces WHERE id = ?)", id).Scan(&exists)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen des Space", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen des Space: %v", err)
|
||||
@@ -1040,7 +1104,6 @@ func deleteSpaceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewEncoder(w).Encode(map[string]string{"message": "Space erfolgreich gelöscht"})
|
||||
|
||||
// Audit-Log: Space gelöscht
|
||||
userID, username := getUserFromRequest(r)
|
||||
ipAddress, userAgent := getRequestInfo(r)
|
||||
details := map[string]interface{}{
|
||||
"message": fmt.Sprintf("Space gelöscht: %s", id),
|
||||
@@ -1071,8 +1134,27 @@ func getSpaceFqdnCountHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe Berechtigung: Benutzer muss Zugriff auf den Space haben
|
||||
userID, _ := getUserFromRequest(r)
|
||||
if userID == "" {
|
||||
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
hasAccess, err := hasSpaceAccess(userID, spaceID)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen der Berechtigung", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen der Berechtigung: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !hasAccess {
|
||||
http.Error(w, "Keine Berechtigung für diesen Space", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
var count int
|
||||
err := db.QueryRow("SELECT COUNT(*) FROM fqdns WHERE space_id = ?", spaceID).Scan(&count)
|
||||
err = db.QueryRow("SELECT COUNT(*) FROM fqdns WHERE space_id = ?", spaceID).Scan(&count)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Abrufen der FQDN-Anzahl", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Abrufen der FQDN-Anzahl: %v", err)
|
||||
@@ -1101,9 +1183,28 @@ func getFqdnsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe Berechtigung: Benutzer muss Zugriff auf den Space haben
|
||||
userID, _ := getUserFromRequest(r)
|
||||
if userID == "" {
|
||||
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
hasAccess, err := hasSpaceAccess(userID, spaceID)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen der Berechtigung", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen der Berechtigung: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !hasAccess {
|
||||
http.Error(w, "Keine Berechtigung für diesen Space", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe ob der Space existiert
|
||||
var exists bool
|
||||
err := db.QueryRow("SELECT EXISTS(SELECT 1 FROM spaces WHERE id = ?)", spaceID).Scan(&exists)
|
||||
err = db.QueryRow("SELECT EXISTS(SELECT 1 FROM spaces WHERE id = ?)", spaceID).Scan(&exists)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen des Space", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen des Space: %v", err)
|
||||
@@ -1175,9 +1276,28 @@ func createFqdnHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe Berechtigung: READ_WRITE oder FULL_ACCESS erforderlich zum Erstellen von FQDNs
|
||||
userID, username := getUserFromRequest(r)
|
||||
if userID == "" {
|
||||
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
hasPermission, err := hasPermission(userID, spaceID, PermissionReadWrite)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen der Berechtigung", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen der Berechtigung: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !hasPermission {
|
||||
http.Error(w, "Keine Berechtigung zum Erstellen von FQDNs. Lesen/Schreiben oder Vollzugriff erforderlich.", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe ob der Space existiert
|
||||
var exists bool
|
||||
err := db.QueryRow("SELECT EXISTS(SELECT 1 FROM spaces WHERE id = ?)", spaceID).Scan(&exists)
|
||||
err = db.QueryRow("SELECT EXISTS(SELECT 1 FROM spaces WHERE id = ?)", spaceID).Scan(&exists)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen des Space", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen des Space: %v", err)
|
||||
@@ -1241,7 +1361,6 @@ func createFqdnHandler(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewEncoder(w).Encode(newFqdn)
|
||||
|
||||
// Audit-Log: FQDN erstellt
|
||||
userID, username := getUserFromRequest(r)
|
||||
ipAddress, userAgent := getRequestInfo(r)
|
||||
auditService.Track(r.Context(), "CREATE", "fqdn", id, userID, username, map[string]interface{}{
|
||||
"fqdn": req.FQDN,
|
||||
@@ -1271,9 +1390,28 @@ func deleteFqdnHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe Berechtigung: Nur FULL_ACCESS darf FQDNs löschen
|
||||
userID, username := getUserFromRequest(r)
|
||||
if userID == "" {
|
||||
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
hasPermission, err := hasPermission(userID, spaceID, PermissionFullAccess)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen der Berechtigung", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen der Berechtigung: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !hasPermission {
|
||||
http.Error(w, "Keine Berechtigung zum Löschen von FQDNs. Vollzugriff erforderlich.", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe ob der FQDN existiert und zum Space gehört
|
||||
var exists bool
|
||||
err := db.QueryRow("SELECT EXISTS(SELECT 1 FROM fqdns WHERE id = ? AND space_id = ?)", fqdnID, spaceID).Scan(&exists)
|
||||
err = db.QueryRow("SELECT EXISTS(SELECT 1 FROM fqdns WHERE id = ? AND space_id = ?)", fqdnID, spaceID).Scan(&exists)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen des FQDN", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen des FQDN: %v", err)
|
||||
@@ -1337,7 +1475,6 @@ func deleteFqdnHandler(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewEncoder(w).Encode(map[string]string{"message": "FQDN erfolgreich gelöscht"})
|
||||
|
||||
// Audit-Log: FQDN gelöscht
|
||||
userID, username := getUserFromRequest(r)
|
||||
ipAddress, userAgent := getRequestInfo(r)
|
||||
auditService.Track(r.Context(), "DELETE", "fqdn", fqdnID, userID, username, map[string]interface{}{
|
||||
"spaceId": spaceID,
|
||||
@@ -1364,9 +1501,28 @@ func deleteAllFqdnsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe Berechtigung: Nur FULL_ACCESS darf alle FQDNs eines Spaces löschen
|
||||
userID, _ := getUserFromRequest(r)
|
||||
if userID == "" {
|
||||
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
hasPermission, err := hasPermission(userID, spaceID, PermissionFullAccess)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen der Berechtigung", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen der Berechtigung: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !hasPermission {
|
||||
http.Error(w, "Keine Berechtigung zum Löschen aller FQDNs. Vollzugriff erforderlich.", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe ob der Space existiert
|
||||
var exists bool
|
||||
err := db.QueryRow("SELECT EXISTS(SELECT 1 FROM spaces WHERE id = ?)", spaceID).Scan(&exists)
|
||||
err = db.QueryRow("SELECT EXISTS(SELECT 1 FROM spaces WHERE id = ?)", spaceID).Scan(&exists)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen des Space", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen des Space: %v", err)
|
||||
@@ -1438,6 +1594,32 @@ func deleteAllFqdnsGlobalHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe Berechtigung: Nur FULL_ACCESS darf alle FQDNs global löschen
|
||||
userID, _ := getUserFromRequest(r)
|
||||
if userID == "" {
|
||||
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
permissions, err := getUserPermissions(userID)
|
||||
if err != nil || len(permissions.Groups) == 0 {
|
||||
http.Error(w, "Keine Berechtigung zum Löschen aller FQDNs. Vollzugriff erforderlich.", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
hasFullAccess := false
|
||||
for _, group := range permissions.Groups {
|
||||
if group.Permission == PermissionFullAccess {
|
||||
hasFullAccess = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !hasFullAccess {
|
||||
http.Error(w, "Keine Berechtigung zum Löschen aller FQDNs. Vollzugriff erforderlich.", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe Query-Parameter für Bestätigung (Sicherheitsmaßnahme)
|
||||
confirm := r.URL.Query().Get("confirm")
|
||||
if confirm != "true" {
|
||||
@@ -1447,7 +1629,7 @@ func deleteAllFqdnsGlobalHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Zähle zuerst die Anzahl der FQDNs
|
||||
var totalCount int
|
||||
err := db.QueryRow("SELECT COUNT(*) FROM fqdns").Scan(&totalCount)
|
||||
err = db.QueryRow("SELECT COUNT(*) FROM fqdns").Scan(&totalCount)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Zählen der FQDNs", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Zählen der FQDNs: %v", err)
|
||||
@@ -1523,6 +1705,32 @@ func deleteAllCSRsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe Berechtigung: Nur FULL_ACCESS darf alle CSRs löschen
|
||||
userID, _ := getUserFromRequest(r)
|
||||
if userID == "" {
|
||||
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
permissions, err := getUserPermissions(userID)
|
||||
if err != nil || len(permissions.Groups) == 0 {
|
||||
http.Error(w, "Keine Berechtigung zum Löschen aller CSRs. Vollzugriff erforderlich.", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
hasFullAccess := false
|
||||
for _, group := range permissions.Groups {
|
||||
if group.Permission == PermissionFullAccess {
|
||||
hasFullAccess = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !hasFullAccess {
|
||||
http.Error(w, "Keine Berechtigung zum Löschen aller CSRs. Vollzugriff erforderlich.", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe Query-Parameter für Bestätigung (Sicherheitsmaßnahme)
|
||||
confirm := r.URL.Query().Get("confirm")
|
||||
if confirm != "true" {
|
||||
@@ -1532,7 +1740,7 @@ func deleteAllCSRsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Zähle zuerst die Anzahl der CSRs
|
||||
var totalCount int
|
||||
err := db.QueryRow("SELECT COUNT(*) FROM csrs").Scan(&totalCount)
|
||||
err = db.QueryRow("SELECT COUNT(*) FROM csrs").Scan(&totalCount)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Zählen der CSRs", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Zählen der CSRs: %v", err)
|
||||
@@ -1615,6 +1823,25 @@ func uploadCSRHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe Berechtigung: READ_WRITE oder FULL_ACCESS erforderlich zum Hochladen von CSRs
|
||||
userID, username := getUserFromRequest(r)
|
||||
if userID == "" {
|
||||
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
hasPermission, err := hasPermission(userID, spaceID, PermissionReadWrite)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen der Berechtigung", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen der Berechtigung: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !hasPermission {
|
||||
http.Error(w, "Keine Berechtigung zum Hochladen von CSRs. Lesen/Schreiben oder Vollzugriff erforderlich.", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe ob Space existiert
|
||||
var spaceExists bool
|
||||
err = db.QueryRow("SELECT EXISTS(SELECT 1 FROM spaces WHERE id = ?)", spaceID).Scan(&spaceExists)
|
||||
@@ -1761,7 +1988,6 @@ func uploadCSRHandler(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewEncoder(w).Encode(newCSR)
|
||||
|
||||
// Audit-Log: CSR hochgeladen
|
||||
userID, username := getUserFromRequest(r)
|
||||
ipAddress, userAgent := getRequestInfo(r)
|
||||
auditService.Track(r.Context(), "UPLOAD", "csr", csrID, userID, username, map[string]interface{}{
|
||||
"fqdnId": fqdnID,
|
||||
@@ -1790,6 +2016,25 @@ func getCSRByFQDNHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe Berechtigung: Benutzer muss Zugriff auf den Space haben (READ, READ_WRITE oder FULL_ACCESS)
|
||||
userID, _ := getUserFromRequest(r)
|
||||
if userID == "" {
|
||||
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
hasAccess, err := hasSpaceAccess(userID, spaceID)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen der Berechtigung", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen der Berechtigung: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !hasAccess {
|
||||
http.Error(w, "Keine Berechtigung für diesen Space", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Prüfe ob nur der neueste CSR gewünscht ist
|
||||
latestOnly := r.URL.Query().Get("latest") == "true"
|
||||
|
||||
@@ -2502,6 +2747,113 @@ components:
|
||||
|
||||
// User Handler Functions
|
||||
|
||||
func getUserPermissionsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
|
||||
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
|
||||
|
||||
if r.Method == "OPTIONS" {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
|
||||
// Hole Benutzer-ID
|
||||
userID, _ := getUserFromRequest(r)
|
||||
if userID == "" {
|
||||
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
// Hole Berechtigungen
|
||||
permissions, err := getUserPermissions(userID)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Abrufen der Berechtigungen", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Abrufen der Berechtigungen: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Erstelle vereinfachte Antwort für Frontend
|
||||
canCreateFqdn := make(map[string]bool)
|
||||
canDeleteFqdn := make(map[string]bool)
|
||||
canUploadCSR := make(map[string]bool)
|
||||
canSignCSR := make(map[string]bool)
|
||||
|
||||
response := map[string]interface{}{
|
||||
"userId": userID,
|
||||
"hasFullAccess": permissions.HasFullAccess,
|
||||
"accessibleSpaces": []string{},
|
||||
"permissions": map[string]interface{}{
|
||||
"canCreateSpace": false,
|
||||
"canDeleteSpace": false,
|
||||
"canCreateFqdn": canCreateFqdn,
|
||||
"canDeleteFqdn": canDeleteFqdn,
|
||||
"canUploadCSR": canUploadCSR,
|
||||
"canSignCSR": canSignCSR,
|
||||
},
|
||||
}
|
||||
|
||||
// Hole alle Spaces
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
defer cancel()
|
||||
|
||||
spaceRows, err := db.QueryContext(ctx, "SELECT id FROM spaces")
|
||||
if err == nil {
|
||||
defer spaceRows.Close()
|
||||
var allSpaceIDs []string
|
||||
for spaceRows.Next() {
|
||||
var spaceID string
|
||||
if err := spaceRows.Scan(&spaceID); err == nil {
|
||||
allSpaceIDs = append(allSpaceIDs, spaceID)
|
||||
}
|
||||
}
|
||||
spaceRows.Close()
|
||||
|
||||
// Prüfe für jeden Space die Berechtigungen
|
||||
accessibleSpaces := []string{}
|
||||
|
||||
for _, spaceID := range allSpaceIDs {
|
||||
hasAccess, _ := hasSpaceAccess(userID, spaceID)
|
||||
if hasAccess {
|
||||
accessibleSpaces = append(accessibleSpaces, spaceID)
|
||||
|
||||
// Prüfe READ_WRITE für FQDN erstellen und CSR upload/sign
|
||||
hasReadWrite, _ := hasPermission(userID, spaceID, PermissionReadWrite)
|
||||
canCreateFqdn[spaceID] = hasReadWrite
|
||||
canUploadCSR[spaceID] = hasReadWrite
|
||||
canSignCSR[spaceID] = hasReadWrite
|
||||
|
||||
// Prüfe FULL_ACCESS für FQDN löschen
|
||||
hasFullAccess, _ := hasPermission(userID, spaceID, PermissionFullAccess)
|
||||
canDeleteFqdn[spaceID] = hasFullAccess
|
||||
}
|
||||
}
|
||||
|
||||
response["accessibleSpaces"] = accessibleSpaces
|
||||
perms := response["permissions"].(map[string]interface{})
|
||||
perms["canCreateFqdn"] = canCreateFqdn
|
||||
perms["canDeleteFqdn"] = canDeleteFqdn
|
||||
perms["canUploadCSR"] = canUploadCSR
|
||||
perms["canSignCSR"] = canSignCSR
|
||||
}
|
||||
|
||||
// Prüfe globale Berechtigungen (Space erstellen/löschen)
|
||||
hasFullAccessGlobal := false
|
||||
for _, group := range permissions.Groups {
|
||||
if group.Permission == PermissionFullAccess {
|
||||
hasFullAccessGlobal = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
perms := response["permissions"].(map[string]interface{})
|
||||
perms["canCreateSpace"] = hasFullAccessGlobal
|
||||
perms["canDeleteSpace"] = hasFullAccessGlobal
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
func getUsersHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
@@ -3612,6 +3964,262 @@ func getUserFromRequest(r *http.Request) (userID, username string) {
|
||||
return id, username
|
||||
}
|
||||
|
||||
// UserPermissionInfo enthält die Berechtigungsinformationen eines Benutzers
|
||||
type UserPermissionInfo struct {
|
||||
UserID string
|
||||
Groups []PermissionGroupInfo
|
||||
HasFullAccess bool // true wenn der Benutzer mindestens eine FULL_ACCESS Gruppe hat
|
||||
}
|
||||
|
||||
// PermissionGroupInfo enthält Informationen über eine Berechtigungsgruppe
|
||||
type PermissionGroupInfo struct {
|
||||
GroupID string
|
||||
Permission PermissionLevel
|
||||
SpaceIDs []string // Leer bedeutet Zugriff auf alle Spaces
|
||||
}
|
||||
|
||||
// getUserPermissions ruft die Berechtigungen eines Benutzers ab
|
||||
func getUserPermissions(userID string) (*UserPermissionInfo, error) {
|
||||
if userID == "" {
|
||||
return nil, fmt.Errorf("userID ist leer")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
defer cancel()
|
||||
|
||||
// Hole alle Gruppen des Benutzers mit ihren Berechtigungen
|
||||
query := `
|
||||
SELECT pg.id, pg.permission
|
||||
FROM permission_groups pg
|
||||
INNER JOIN user_groups ug ON pg.id = ug.group_id
|
||||
WHERE ug.user_id = ?
|
||||
`
|
||||
rows, err := db.QueryContext(ctx, query, userID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fehler beim Abrufen der Benutzergruppen: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
info := &UserPermissionInfo{
|
||||
UserID: userID,
|
||||
Groups: []PermissionGroupInfo{},
|
||||
}
|
||||
|
||||
var groupIDs []string
|
||||
for rows.Next() {
|
||||
var groupID string
|
||||
var permission string
|
||||
if err := rows.Scan(&groupID, &permission); err != nil {
|
||||
continue
|
||||
}
|
||||
groupIDs = append(groupIDs, groupID)
|
||||
|
||||
groupInfo := PermissionGroupInfo{
|
||||
GroupID: groupID,
|
||||
Permission: PermissionLevel(permission),
|
||||
SpaceIDs: []string{},
|
||||
}
|
||||
|
||||
if PermissionLevel(permission) == PermissionFullAccess {
|
||||
info.HasFullAccess = true
|
||||
}
|
||||
|
||||
info.Groups = append(info.Groups, groupInfo)
|
||||
}
|
||||
|
||||
// Hole Space-Zuweisungen für alle Gruppen
|
||||
if len(groupIDs) > 0 {
|
||||
placeholders := make([]string, len(groupIDs))
|
||||
args := make([]interface{}, len(groupIDs))
|
||||
for i, id := range groupIDs {
|
||||
placeholders[i] = "?"
|
||||
args[i] = id
|
||||
}
|
||||
|
||||
spaceQuery := fmt.Sprintf(`
|
||||
SELECT group_id, space_id
|
||||
FROM group_spaces
|
||||
WHERE group_id IN (%s)
|
||||
`, strings.Join(placeholders, ","))
|
||||
|
||||
spaceRows, err := db.QueryContext(ctx, spaceQuery, args...)
|
||||
if err == nil {
|
||||
spaceMap := make(map[string][]string)
|
||||
for spaceRows.Next() {
|
||||
var groupID, spaceID string
|
||||
if err := spaceRows.Scan(&groupID, &spaceID); err == nil {
|
||||
spaceMap[groupID] = append(spaceMap[groupID], spaceID)
|
||||
}
|
||||
}
|
||||
spaceRows.Close()
|
||||
|
||||
// Aktualisiere SpaceIDs für jede Gruppe
|
||||
for i := range info.Groups {
|
||||
if spaceIDs, exists := spaceMap[info.Groups[i].GroupID]; exists {
|
||||
info.Groups[i].SpaceIDs = spaceIDs
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return info, nil
|
||||
}
|
||||
|
||||
// hasSpaceAccess prüft, ob ein Benutzer Zugriff auf einen bestimmten Space hat
|
||||
func hasSpaceAccess(userID, spaceID string) (bool, error) {
|
||||
if userID == "" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
permissions, err := getUserPermissions(userID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Wenn der Benutzer keine Gruppen hat, hat er keinen Zugriff
|
||||
if len(permissions.Groups) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Prüfe für jede Gruppe, ob der Benutzer Zugriff auf den Space hat
|
||||
for _, group := range permissions.Groups {
|
||||
// Wenn die Gruppe keine Spaces zugewiesen hat, hat der Benutzer Zugriff auf alle Spaces
|
||||
if len(group.SpaceIDs) == 0 {
|
||||
return true, nil
|
||||
}
|
||||
// Prüfe, ob der Space in der Liste der zugewiesenen Spaces ist
|
||||
for _, assignedSpaceID := range group.SpaceIDs {
|
||||
if assignedSpaceID == spaceID {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// hasPermission prüft, ob ein Benutzer eine bestimmte Berechtigung für einen Space hat
|
||||
// requiredPermission kann READ, READ_WRITE oder FULL_ACCESS sein
|
||||
func hasPermission(userID, spaceID string, requiredPermission PermissionLevel) (bool, error) {
|
||||
if userID == "" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
permissions, err := getUserPermissions(userID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Wenn der Benutzer keine Gruppen hat, hat er keine Berechtigung
|
||||
if len(permissions.Groups) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Prüfe für jede Gruppe
|
||||
for _, group := range permissions.Groups {
|
||||
hasAccess := false
|
||||
|
||||
// Prüfe, ob der Benutzer Zugriff auf den Space hat
|
||||
if len(group.SpaceIDs) == 0 {
|
||||
// Keine Space-Zuweisungen = Zugriff auf alle Spaces
|
||||
hasAccess = true
|
||||
} else {
|
||||
// Prüfe, ob der Space in der Liste ist
|
||||
for _, assignedSpaceID := range group.SpaceIDs {
|
||||
if assignedSpaceID == spaceID {
|
||||
hasAccess = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !hasAccess {
|
||||
continue
|
||||
}
|
||||
|
||||
// Prüfe die Berechtigungsstufe
|
||||
switch requiredPermission {
|
||||
case PermissionRead:
|
||||
// READ, READ_WRITE und FULL_ACCESS haben alle READ-Berechtigung
|
||||
return true, nil
|
||||
case PermissionReadWrite:
|
||||
// READ_WRITE und FULL_ACCESS haben READ_WRITE-Berechtigung
|
||||
if group.Permission == PermissionReadWrite || group.Permission == PermissionFullAccess {
|
||||
return true, nil
|
||||
}
|
||||
case PermissionFullAccess:
|
||||
// Nur FULL_ACCESS hat FULL_ACCESS-Berechtigung
|
||||
if group.Permission == PermissionFullAccess {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// getAccessibleSpaceIDs gibt alle Space-IDs zurück, auf die der Benutzer Zugriff hat
|
||||
func getAccessibleSpaceIDs(userID string) ([]string, error) {
|
||||
if userID == "" {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
permissions, err := getUserPermissions(userID)
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
|
||||
// Wenn der Benutzer keine Gruppen hat, hat er keinen Zugriff
|
||||
if len(permissions.Groups) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
// Sammle alle zugewiesenen Spaces
|
||||
spaceIDMap := make(map[string]bool)
|
||||
hasUnrestrictedAccess := false
|
||||
|
||||
for _, group := range permissions.Groups {
|
||||
// Wenn eine Gruppe keine Spaces zugewiesen hat, hat der Benutzer Zugriff auf alle Spaces
|
||||
if len(group.SpaceIDs) == 0 {
|
||||
hasUnrestrictedAccess = true
|
||||
break
|
||||
}
|
||||
// Sammle alle zugewiesenen Spaces
|
||||
for _, spaceID := range group.SpaceIDs {
|
||||
spaceIDMap[spaceID] = true
|
||||
}
|
||||
}
|
||||
|
||||
// Wenn der Benutzer Zugriff auf alle Spaces hat, hole alle Spaces aus der DB
|
||||
if hasUnrestrictedAccess {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
defer cancel()
|
||||
|
||||
rows, err := db.QueryContext(ctx, "SELECT id FROM spaces")
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var spaceIDs []string
|
||||
for rows.Next() {
|
||||
var spaceID string
|
||||
if err := rows.Scan(&spaceID); err == nil {
|
||||
spaceIDs = append(spaceIDs, spaceID)
|
||||
}
|
||||
}
|
||||
return spaceIDs, nil
|
||||
}
|
||||
|
||||
// Konvertiere Map zu Slice
|
||||
spaceIDs := make([]string, 0, len(spaceIDMap))
|
||||
for spaceID := range spaceIDMap {
|
||||
spaceIDs = append(spaceIDs, spaceID)
|
||||
}
|
||||
|
||||
return spaceIDs, nil
|
||||
}
|
||||
|
||||
// Helper-Funktion zum Extrahieren von IP-Adresse und User-Agent aus Request
|
||||
func getRequestInfo(r *http.Request) (ipAddress, userAgent string) {
|
||||
// Hole IP-Adresse
|
||||
@@ -4159,18 +4767,18 @@ func main() {
|
||||
|
||||
// Protected Routes (Basic Auth erforderlich)
|
||||
api.HandleFunc("/stats", basicAuthMiddleware(getStatsHandler)).Methods("GET", "OPTIONS")
|
||||
api.HandleFunc("/spaces", getSpacesHandler).Methods("GET", "OPTIONS")
|
||||
api.HandleFunc("/spaces", createSpaceHandler).Methods("POST", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{id}", deleteSpaceHandler).Methods("DELETE", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{id}/fqdns/count", getSpaceFqdnCountHandler).Methods("GET", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{id}/fqdns", getFqdnsHandler).Methods("GET", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{id}/fqdns", createFqdnHandler).Methods("POST", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{id}/fqdns", deleteAllFqdnsHandler).Methods("DELETE", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{id}/fqdns/{fqdnId}", deleteFqdnHandler).Methods("DELETE", "OPTIONS")
|
||||
api.HandleFunc("/fqdns", deleteAllFqdnsGlobalHandler).Methods("DELETE", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{spaceId}/fqdns/{fqdnId}/csr", uploadCSRHandler).Methods("POST", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{spaceId}/fqdns/{fqdnId}/csr", getCSRByFQDNHandler).Methods("GET", "OPTIONS")
|
||||
api.HandleFunc("/csrs", deleteAllCSRsHandler).Methods("DELETE", "OPTIONS")
|
||||
api.HandleFunc("/spaces", basicAuthMiddleware(getSpacesHandler)).Methods("GET", "OPTIONS")
|
||||
api.HandleFunc("/spaces", basicAuthMiddleware(createSpaceHandler)).Methods("POST", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{id}", basicAuthMiddleware(deleteSpaceHandler)).Methods("DELETE", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{id}/fqdns/count", basicAuthMiddleware(getSpaceFqdnCountHandler)).Methods("GET", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{id}/fqdns", basicAuthMiddleware(getFqdnsHandler)).Methods("GET", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{id}/fqdns", basicAuthMiddleware(createFqdnHandler)).Methods("POST", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{id}/fqdns", basicAuthMiddleware(deleteAllFqdnsHandler)).Methods("DELETE", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{id}/fqdns/{fqdnId}", basicAuthMiddleware(deleteFqdnHandler)).Methods("DELETE", "OPTIONS")
|
||||
api.HandleFunc("/fqdns", basicAuthMiddleware(deleteAllFqdnsGlobalHandler)).Methods("DELETE", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{spaceId}/fqdns/{fqdnId}/csr", basicAuthMiddleware(uploadCSRHandler)).Methods("POST", "OPTIONS")
|
||||
api.HandleFunc("/spaces/{spaceId}/fqdns/{fqdnId}/csr", basicAuthMiddleware(getCSRByFQDNHandler)).Methods("GET", "OPTIONS")
|
||||
api.HandleFunc("/csrs", basicAuthMiddleware(deleteAllCSRsHandler)).Methods("DELETE", "OPTIONS")
|
||||
|
||||
// User Routes
|
||||
api.HandleFunc("/users", getUsersHandler).Methods("GET", "OPTIONS")
|
||||
@@ -4180,6 +4788,7 @@ func main() {
|
||||
api.HandleFunc("/users/{id}", deleteUserHandler).Methods("DELETE", "OPTIONS")
|
||||
api.HandleFunc("/users/{id}/avatar", basicAuthMiddleware(getAvatarHandler)).Methods("GET", "OPTIONS")
|
||||
api.HandleFunc("/users/{id}/avatar", basicAuthMiddleware(uploadAvatarHandler)).Methods("POST", "OPTIONS")
|
||||
api.HandleFunc("/user/permissions", basicAuthMiddleware(getUserPermissionsHandler)).Methods("GET", "OPTIONS")
|
||||
|
||||
// Permission Groups Routes (Protected)
|
||||
api.HandleFunc("/permission-groups", basicAuthMiddleware(getPermissionGroupsHandler)).Methods("GET", "OPTIONS")
|
||||
@@ -4477,6 +5086,25 @@ func signCSRHandler(w http.ResponseWriter, r *http.Request) {
|
||||
spaceID := vars["spaceId"]
|
||||
fqdnID := vars["fqdnId"]
|
||||
|
||||
// Prüfe Berechtigung: READ_WRITE oder FULL_ACCESS erforderlich zum Signieren von CSRs
|
||||
userID, username := getUserFromRequest(r)
|
||||
if userID == "" {
|
||||
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
hasPermission, err := hasPermission(userID, spaceID, PermissionReadWrite)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen der Berechtigung", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen der Berechtigung: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !hasPermission {
|
||||
http.Error(w, "Keine Berechtigung zum Signieren von CSRs. Lesen/Schreiben oder Vollzugriff erforderlich.", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
ProviderID string `json:"providerId"`
|
||||
CSRID string `json:"csrId,omitempty"` // Optional: spezifischer CSR, sonst neuester
|
||||
@@ -4495,7 +5123,7 @@ func signCSRHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// Hole neuesten CSR für den FQDN
|
||||
var csrPEM string
|
||||
var csrID string
|
||||
err := db.QueryRow(`
|
||||
err = db.QueryRow(`
|
||||
SELECT id, csr_pem
|
||||
FROM csrs
|
||||
WHERE fqdn_id = ? AND space_id = ?
|
||||
@@ -4579,7 +5207,6 @@ func signCSRHandler(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
|
||||
// Audit-Log: CSR signiert
|
||||
userID, username := getUserFromRequest(r)
|
||||
ipAddress, userAgent := getRequestInfo(r)
|
||||
auditService.Track(r.Context(), "SIGN", "csr", csrID, userID, username, map[string]interface{}{
|
||||
"providerId": req.ProviderID,
|
||||
@@ -4606,6 +5233,25 @@ func getCertificatesHandler(w http.ResponseWriter, r *http.Request) {
|
||||
spaceID := vars["spaceId"]
|
||||
fqdnID := vars["fqdnId"]
|
||||
|
||||
// Prüfe Berechtigung: Benutzer muss Zugriff auf den Space haben (READ, READ_WRITE oder FULL_ACCESS)
|
||||
userID, _ := getUserFromRequest(r)
|
||||
if userID == "" {
|
||||
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
hasAccess, err := hasSpaceAccess(userID, spaceID)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen der Berechtigung", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen der Berechtigung: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !hasAccess {
|
||||
http.Error(w, "Keine Berechtigung für diesen Space", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Hole alle Zertifikate für diesen FQDN
|
||||
rows, err := db.Query(`
|
||||
SELECT id, csr_id, certificate_id, provider_id, certificate_pem, status, created_at
|
||||
@@ -4661,9 +5307,28 @@ func refreshCertificateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
fqdnID := vars["fqdnId"]
|
||||
certID := vars["certId"]
|
||||
|
||||
// Prüfe Berechtigung: Benutzer muss Zugriff auf den Space haben (READ, READ_WRITE oder FULL_ACCESS)
|
||||
userID, _ := getUserFromRequest(r)
|
||||
if userID == "" {
|
||||
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
hasAccess, err := hasSpaceAccess(userID, spaceID)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Prüfen der Berechtigung", http.StatusInternalServerError)
|
||||
log.Printf("Fehler beim Prüfen der Berechtigung: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !hasAccess {
|
||||
http.Error(w, "Keine Berechtigung für diesen Space", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Hole Zertifikat aus DB
|
||||
var certificateID, providerID string
|
||||
err := db.QueryRow(`
|
||||
err = db.QueryRow(`
|
||||
SELECT certificate_id, provider_id
|
||||
FROM certificates
|
||||
WHERE id = ? AND fqdn_id = ? AND space_id = ?
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user