myCRM/docs/USER-CRUD.md
olli fcfda9d9be feat: Implement user management functionality with CRUD operations
- Added UserManagement.vue component for managing users with PrimeVue DataTable.
- Integrated API endpoints for user CRUD operations in the backend.
- Implemented user password hashing using a custom state processor.
- Updated router to include user management route with admin access control.
- Enhanced Dashboard.vue and app.scss for improved styling and responsiveness.
- Documented user management features and API usage in USER-CRUD.md.
2025-11-08 10:50:00 +01:00

276 lines
7.2 KiB
Markdown

# Benutzerverwaltung (User CRUD)
## Übersicht
Das User-CRUD-System ermöglicht Administratoren die vollständige Verwaltung von Benutzern über eine moderne Vue.js-Oberfläche mit PrimeVue-Komponenten.
## Backend (API Platform)
### API-Endpunkte
- **GET /api/users** - Liste aller Benutzer (authentifiziert)
- **GET /api/users/{id}** - Einzelner Benutzer (authentifiziert)
- **POST /api/users** - Neuen Benutzer erstellen (nur ROLE_ADMIN)
- **PUT /api/users/{id}** - Benutzer bearbeiten (ROLE_ADMIN oder eigener Account)
- **DELETE /api/users/{id}** - Benutzer löschen (nur ROLE_ADMIN)
### Sicherheitsregeln
```php
#[ApiResource(
operations: [
new GetCollection(),
new Get(),
new Post(security: "is_granted('ROLE_ADMIN')"),
new Put(security: "is_granted('ROLE_ADMIN') or object == user"),
new Delete(security: "is_granted('ROLE_ADMIN')")
],
normalizationContext: ['groups' => ['user:read']],
denormalizationContext: ['groups' => ['user:write']]
)]
```
### Serialization Groups
**user:read** (Ausgabe):
- id, email, firstName, lastName
- roles (array)
- isActive (boolean)
- createdAt, lastLoginAt (DateTimeImmutable)
**user:write** (Eingabe):
- email, firstName, lastName
- plainPassword (wird automatisch gehasht)
- roles (array)
- isActive (boolean)
### Passwort-Hashing
Ein eigener State Processor (`App\State\UserPasswordHasher`) sorgt dafür, dass das `plainPassword`-Feld automatisch gehasht wird:
```php
// config/services.yaml
App\State\UserPasswordHasher:
decorates: 'api_platform.doctrine.orm.state.persist_processor'
arguments:
$processor: '@.inner'
```
Der Processor:
1. Prüft, ob ein `plainPassword` gesetzt wurde
2. Hasht das Passwort mit `UserPasswordHasherInterface`
3. Setzt das gehashte Passwort
4. Ruft `eraseCredentials()` auf (löscht plainPassword aus dem Speicher)
5. Delegiert an den Standard-Persist-Processor
## Frontend (Vue.js)
### Komponente: UserManagement.vue
**Features:**
- PrimeVue DataTable mit Sortierung, Pagination
- Erstellen/Bearbeiten via Dialog
- Löschen mit Bestätigungs-Dialog
- Formvalidierung
- Toast-Benachrichtigungen
- Eigenen Account kann nicht gelöscht werden
- Nur für Admins sichtbar
**Formularfelder:**
- Vorname* / Nachname*
- E-Mail*
- Passwort* (bei Erstellung) / Neues Passwort (bei Bearbeitung, optional)
- Symfony-Rollen (ROLE_USER, ROLE_ADMIN via Checkboxen)
- Status (Aktiv/Inaktiv Toggle)
### Integration
```javascript
// router.js
{ path: '/users', name: 'users', component: UserManagement, meta: { requiresAdmin: true } }
// App.vue Navigation (nur für Admins)
<RouterLink to="/users" v-if="authStore.isAdmin">
<i class="pi pi-user-edit"></i> Benutzerverwaltung
</RouterLink>
```
## Verwendung
### Neuen Benutzer erstellen
1. Navigiere zu `/users` (nur als Admin)
2. Klicke auf "Neuer Benutzer"
3. Fülle alle Pflichtfelder aus:
- Vorname, Nachname, E-Mail
- Passwort (mind. 6 Zeichen empfohlen)
- Rollen auswählen (ROLE_USER ist Standard)
- Status auf "Aktiv" setzen
4. Klicke "Speichern"
**API Request:**
```json
POST /api/users
{
"firstName": "Max",
"lastName": "Mustermann",
"email": "max@example.com",
"plainPassword": "sicheres123",
"roles": ["ROLE_USER"],
"isActive": true
}
```
### Benutzer bearbeiten
1. Klicke auf das Stift-Symbol in der Aktionsspalte
2. Ändere gewünschte Felder
3. Optional: Klicke "Passwort ändern" um ein neues Passwort zu setzen
4. Klicke "Speichern"
**Hinweis:** Admins können alle Benutzer bearbeiten, normale Benutzer nur ihren eigenen Account.
### Benutzer löschen
1. Klicke auf das Papierkorb-Symbol
2. Bestätige die Löschung im Dialog
**Einschränkungen:**
- Eigener Account kann nicht gelöscht werden (Button deaktiviert)
- Nur Admins können Benutzer löschen
## Sicherheit
### Authentifizierung
Alle API-Endpunkte erfordern Authentifizierung. Die Vue.js-App sendet automatisch die Session-Cookies mit.
### Autorisierung
- **POST /api/users**: Nur ROLE_ADMIN
- **PUT /api/users/{id}**: ROLE_ADMIN oder eigener Account (`object == user`)
- **DELETE /api/users/{id}**: Nur ROLE_ADMIN
- **GET**: Alle authentifizierten Benutzer
### CSRF-Schutz
Da wir Session-basierte Authentifizierung verwenden, ist CSRF-Schutz automatisch aktiv. Für API-Requests ist dies standardmäßig deaktiviert.
## Technische Details
### Dependencies
**Backend:**
- API Platform 4.x
- Symfony Security Component
- Doctrine ORM
- PasswordHasher
**Frontend:**
- Vue.js 3 Composition API
- PrimeVue (DataTable, Dialog, InputText, Password, Checkbox, Button, Tag, Toast)
- Pinia (Auth Store)
### Datenbankstruktur
```sql
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(180) NOT NULL UNIQUE,
roles JSON NOT NULL,
password VARCHAR(255) NOT NULL,
first_name VARCHAR(100),
last_name VARCHAR(100),
is_active TINYINT(1) DEFAULT 1,
created_at DATETIME NOT NULL,
last_login_at DATETIME DEFAULT NULL
);
```
## Testing
### Backend
```bash
# API-Endpunkte testen
curl -X GET http://localhost:8000/api/users \
-H "Cookie: PHPSESSID=..." \
-H "Accept: application/json"
# Neuen User erstellen (als Admin)
curl -X POST http://localhost:8000/api/users \
-H "Cookie: PHPSESSID=..." \
-H "Content-Type: application/json" \
-d '{
"firstName": "Test",
"lastName": "User",
"email": "test@example.com",
"plainPassword": "test123",
"roles": ["ROLE_USER"],
"isActive": true
}'
```
### Frontend
1. Melde dich als Admin an (admin@mycrm.local / admin123)
2. Navigiere zu `/users`
3. Teste alle CRUD-Operationen
4. Prüfe Browser-Konsole auf Fehler
5. Prüfe Toast-Benachrichtigungen
## Troubleshooting
### "Unauthorized" bei API-Calls
**Problem:** 401 Unauthorized bei allen API-Requests
**Lösung:**
- Stelle sicher, dass du eingeloggt bist
- Prüfe, ob Session-Cookie korrekt gesendet wird
- Cache leeren: `php bin/console cache:clear`
### Passwort-Hashing funktioniert nicht
**Problem:** Passwort wird nicht gehasht, Login nicht möglich
**Lösung:**
- Prüfe, ob `UserPasswordHasher` Service registriert ist
- Stelle sicher, dass `decorates: 'api_platform.doctrine.orm.state.persist_processor'` korrekt ist
- Cache leeren
### Vue-Komponente lädt nicht
**Problem:** Leere Seite oder JavaScript-Fehler
**Lösung:**
```bash
npm run build
php bin/console cache:clear
```
### "Cannot delete own account"
**Problem:** Löschen-Button funktioniert nicht
**Erklärung:** Das ist gewollt! Eigener Account kann nicht gelöscht werden (`:disabled="data.id === authStore.user?.id"`).
## Erweiterungen
### Mögliche zukünftige Features
1. **Rollen-Zuweisung:** Integration mit Role-Entity für komplexere Berechtigungen
2. **Bulk-Operationen:** Mehrere Benutzer gleichzeitig bearbeiten/löschen
3. **Export:** Benutzerliste als CSV/Excel exportieren
4. **Avatar-Upload:** Profilbilder für Benutzer
5. **E-Mail-Benachrichtigungen:** Bei Accounterstellung/Passwortänderung
6. **Passwort-Reset:** "Passwort vergessen"-Funktion
7. **2FA:** Zwei-Faktor-Authentifizierung
8. **Audit Log:** Historie von Änderungen an Benutzeraccounts
## Weitere Dokumentation
- [LOGIN.md](./LOGIN.md) - Authentifizierungssystem
- [PERMISSIONS.md](./PERMISSIONS.md) - Berechtigungssystem mit Rollen und Modulen
- [API Platform Docs](https://api-platform.com/)