feat(PROJ-21): Phase 2+3+5+8 Multi-Tenancy + PROJ-2 EML/MBOX Upload
Phase 2a: userstore domain_admin/superadmin Rollen, User.TenantID,
ListByTenant, UpsertLDAPUser mit tenantID
Phase 2b: storage.Save() mit tenantID *int64, email_refs Tabelle,
GetTenantForMail, GetAllIDsByTenant, StatsByTenant
Phase 2c: JWT-Claims tenant_id/tenant_slug, Session.TenantID,
Login Domain-Erkennung via E-Mail-Domain
Phase 3: tenantMiddleware, Handler-Filterung (Users, Mail, Stats)
Phase 5: SMTP Domain-Routing via DomainToTenantFunc Callback,
config smtp.tenant_routing + default_tenant_id
Phase 8: archivmail migrate-tenants Subkommando
PROJ-2: Upload-Seite /admin/upload mit DropZone + Progress-Polling
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -13,7 +13,7 @@
|
||||
| ID | Feature | Status | Spec | Created |
|
||||
|----|---------|--------|------|---------|
|
||||
| PROJ-1 | Nutzer-Authentifizierung & Rollen (User/Admin) | Deployed | [PROJ-1](PROJ-1-authentifizierung-und-rollen.md) | 2026-03-12 |
|
||||
| PROJ-2 | E-Mail-Import: EML/MBOX Upload | In Progress | [PROJ-2](PROJ-2-import-eml-mbox.md) | 2026-03-12 |
|
||||
| PROJ-2 | E-Mail-Import: EML/MBOX Upload | Deployed | [PROJ-2](PROJ-2-import-eml-mbox.md) | 2026-03-12 |
|
||||
| PROJ-3 | E-Mail-Import: IMAP-Verbindung | Deployed | [PROJ-3](PROJ-3-import-imap.md) | 2026-03-12 |
|
||||
| PROJ-4 | E-Mail-Import: SMTP-Eingang via BCC (primär) | Deployed | [PROJ-4](PROJ-4-import-smtp.md) | 2026-03-12 |
|
||||
| PROJ-5 | E-Mail-Speicherung & Volltext-Indexierung | Deployed | [PROJ-5](PROJ-5-speicherung-und-indexierung.md) | 2026-03-12 |
|
||||
|
||||
@@ -13,7 +13,33 @@ created: 2026-03-17
|
||||
- `src/lib/api.ts` — `Tenant`, `TenantDomain`, alle 7 API-Funktionen
|
||||
- `src/app/admin/page.tsx` — Mandanten-Tab mit Tabelle, Domain-Dialog, Löschen-Bestätigung
|
||||
|
||||
**Offene Phasen:** Phase 2 (userstore/storage tenant-aware), Phase 3 (Middleware), Phase 4 (Xapian-Index), Phase 5 (SMTP-Routing), Phase 8 (Migration)
|
||||
## Phase 2, 3, 5, 8 implementiert (2026-03-17)
|
||||
|
||||
**Phase 2a — Rollen & userstore:**
|
||||
- `internal/userstore/userstore.go` — Neue Rollen `domain_admin`, `superadmin`; `User.TenantID *int64`; `Create()` mit TenantID; `ListByTenant()`; `UpsertLDAPUser()` mit tenantID-Parameter; Scan-Helpers aktualisiert
|
||||
|
||||
**Phase 2b — storage.Save() + email_refs:**
|
||||
- `internal/storage/storage.go` — `Save()` neue Signatur `(ctx, raw, time, tenantID *int64)`; DB-Migrationen: `emails.tenant_id`, Tabelle `email_refs`; neue Methoden `GetTenantForMail()`, `GetAllIDsByTenant()`, `StatsByTenant()`; `insertMeta`/`insertMetaMinimal` mit tenantID
|
||||
|
||||
**Phase 2c — JWT tenant-aware:**
|
||||
- `internal/auth/auth.go` — `Session.TenantID *int64`; JWT-Claims `tenant_id`; `ValidateToken()` extrahiert tenant_id; `HasRole()` Hierarchie: superadmin > admin > domain_admin > auditor > user
|
||||
|
||||
**Phase 3 — Tenant-Middleware:**
|
||||
- `internal/api/server.go` — `tenantMiddleware()`, `tenantFromCtx()`; `auth()` + `authAdmin()` Helper; `handleListUsers` tenant-gefiltert; `handleStorageStats` via `StatsByTenant()`; `handleGetMail/Attachment/Raw` mit Tenant-Isolation
|
||||
|
||||
**Phase 5 — SMTP Domain-Routing:**
|
||||
- `internal/smtpd/smtpd.go` — `DomainToTenantFunc`; `Daemon.domainToTenant` + `defaultTenantID`; `SetDomainToTenant()`; `resolveTenantFromRcpts()`
|
||||
- `config/config.go` — `SMTPConfig.TenantRouting`, `SMTPConfig.DefaultTenantID`
|
||||
- `cmd/archivmail/main.go` — Tenant-Routing-Verdrahtung; `tenantSt` vor smtpDaemon initialisiert
|
||||
|
||||
**Phase 8 — Migrations-Script:**
|
||||
- `cmd/archivmail/cmd_migrate_tenants.go` — Subkommando `migrate-tenants`: default-Tenant anlegen, Users/Emails/Audit assignen, email_refs seeden, admins → domain_admin, superadmin erstellen
|
||||
|
||||
**Alle Save()-Aufrufer angepasst:**
|
||||
- `internal/imap/importer.go`, `internal/pop3/importer.go` — `TenantID *int64` Feld + `Save(ctx, ..., tenantID)`
|
||||
- `cmd/archivmail/cmd_import.go`, `cmd/archivmail-import/main.go` — `Save(ctx, ..., nil)`
|
||||
|
||||
**Offene Phasen:** Phase 4 (Xapian per-tenant Index-Filter)
|
||||
|
||||
## Ziel
|
||||
|
||||
|
||||
Reference in New Issue
Block a user