import { useState, useEffect } from 'react' import { useAuth } from '../contexts/AuthContext' import { usePermissions } from '../contexts/PermissionsContext' const Permissions = () => { const { authFetch } = useAuth() const { refreshPermissions } = usePermissions() const [groups, setGroups] = useState([]) const [spaces, setSpaces] = useState([]) const [loading, setLoading] = useState(false) const [fetching, setFetching] = useState(true) const [error, setError] = useState('') const [showForm, setShowForm] = useState(false) const [editingGroup, setEditingGroup] = useState(null) const [showDeleteModal, setShowDeleteModal] = useState(false) const [groupToDelete, setGroupToDelete] = useState(null) const [confirmChecked, setConfirmChecked] = useState(false) const [formData, setFormData] = useState({ name: '', description: '', permission: 'READ', spaceIds: [] }) useEffect(() => { // Lade Daten parallel beim Mount und beim Zurückkehren zur Seite let isMounted = true const loadData = async () => { if (isMounted) { setFetching(true) } await Promise.all([fetchGroups(), fetchSpaces()]) } loadData() return () => { isMounted = false } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) const fetchGroups = async () => { try { setError('') const response = await authFetch('/api/permission-groups') if (response.ok) { const data = await response.json() setGroups(Array.isArray(data) ? data : []) } else { setError('Fehler beim Abrufen der Berechtigungsgruppen') } } catch (err) { setError('Fehler beim Abrufen der Berechtigungsgruppen') console.error('Error fetching permission groups:', err) } finally { setFetching(false) } } const fetchSpaces = async () => { try { const response = await authFetch('/api/spaces') if (response.ok) { const data = await response.json() setSpaces(Array.isArray(data) ? data : []) } } catch (err) { console.error('Error fetching spaces:', err) } } const handleSubmit = async (e) => { e.preventDefault() setError('') setLoading(true) if (!formData.name.trim()) { setError('Bitte geben Sie einen Namen ein') setLoading(false) return } if (!formData.permission) { setError('Bitte wählen Sie eine Berechtigungsstufe') setLoading(false) return } try { const url = editingGroup ? `/api/permission-groups/${editingGroup.id}` : '/api/permission-groups' const method = editingGroup ? 'PUT' : 'POST' const body = { name: formData.name, description: formData.description, permission: formData.permission, spaceIds: formData.spaceIds } const response = await authFetch(url, { method, headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(body), }) if (response.ok) { await fetchGroups() setFormData({ name: '', description: '', permission: 'READ', spaceIds: [] }) setShowForm(false) setEditingGroup(null) // Aktualisiere Berechtigungen nach Änderung an Berechtigungsgruppen refreshPermissions() } else { const errorData = await response.json() setError(errorData.error || 'Fehler beim Speichern der Berechtigungsgruppe') } } catch (err) { setError('Fehler beim Speichern der Berechtigungsgruppe') console.error('Error saving permission group:', err) } finally { setLoading(false) } } const handleEdit = (group) => { setEditingGroup(group) setFormData({ name: group.name, description: group.description || '', permission: group.permission, spaceIds: group.spaceIds || [] }) setShowForm(true) } const handleDelete = (group) => { setGroupToDelete(group) setShowDeleteModal(true) setConfirmChecked(false) } const confirmDelete = async () => { if (!confirmChecked || !groupToDelete) { return } try { const response = await authFetch(`/api/permission-groups/${groupToDelete.id}`, { method: 'DELETE', }) if (response.ok) { await fetchGroups() setShowDeleteModal(false) setGroupToDelete(null) setConfirmChecked(false) // Aktualisiere Berechtigungen nach Löschen einer Berechtigungsgruppe refreshPermissions() } else { const errorData = await response.json().catch(() => ({ error: 'Fehler beim Löschen' })) alert(errorData.error || 'Fehler beim Löschen der Berechtigungsgruppe') } } catch (err) { console.error('Error deleting permission group:', err) alert('Fehler beim Löschen der Berechtigungsgruppe') } } const cancelDelete = () => { setShowDeleteModal(false) setGroupToDelete(null) setConfirmChecked(false) } const handleChange = (e) => { setFormData({ ...formData, [e.target.name]: e.target.value }) } const handleSpaceToggle = (spaceId) => { setFormData(prev => { const spaceIds = prev.spaceIds || [] if (spaceIds.includes(spaceId)) { return { ...prev, spaceIds: spaceIds.filter(id => id !== spaceId) } } else { return { ...prev, spaceIds: [...spaceIds, spaceId] } } }) } const getPermissionLabel = (permission) => { switch (permission) { case 'READ': return 'Lesen' case 'READ_WRITE': return 'Lesen/Schreiben' case 'FULL_ACCESS': return 'Vollzugriff' default: return permission } } const getPermissionBadgeColor = (permission) => { switch (permission) { case 'READ': return 'bg-green-600/20 text-green-300 border-green-500/30' case 'READ_WRITE': return 'bg-yellow-600/20 text-yellow-300 border-yellow-500/30' case 'FULL_ACCESS': return 'bg-purple-600/20 text-purple-300 border-purple-500/30' default: return 'bg-blue-600/20 text-blue-300 border-blue-500/30' } } const getPermissionIcon = (permission) => { switch (permission) { case 'READ': return '👁️' case 'READ_WRITE': return '✏️' case 'FULL_ACCESS': return '🔓' default: return '🔐' } } const getPermissionDescription = (permission) => { switch (permission) { case 'READ': return 'Nur CSRs und Zertifikate ansehen. Keine Requests, keine Lösch-/Erstellrechte.' case 'READ_WRITE': return 'FQDNs innerhalb eines Spaces erstellen (nicht löschen), CSRs requesten und ansehen. Keine Spaces löschen/erstellen.' case 'FULL_ACCESS': return 'Vollzugriff: Alles darf gemacht werden. Löschen, Erstellen, CSR requesten und ansehen.' default: return '' } } return (

🔐 Berechtigungsgruppen

Verwalten Sie Berechtigungsgruppen und weisen Sie Spaces zu

{error && (
{error}
)} {showForm && (

{editingGroup ? '✏️' : '➕'} {editingGroup ? 'Berechtigungsgruppe bearbeiten' : 'Neue Berechtigungsgruppe'}