fix(PROJ-55): Tenant-Isolation für Rolle "auditor" + Audit-Log korrigieren

Kritischer Sicherheitsbug: Auditoren mit zugewiesenem Tenant sahen Mails
und Audit-Log-Einträge anderer Tenants (DSGVO-relevant). auditor wird
jetzt analog zu domain_auditor pro Tenant gescoped, sofern tenant_id
gesetzt ist (Abwärtskompatibilität: ohne tenant_id bleibt der bisherige
globale Zugriff erhalten). Betrifft Mail-Suche, Mail-Detailzugriff,
Export, eDiscovery, Threads, OCR sowie das Audit-Log (DB + tamper-evidentes
Flat-File), inkl. Befüllung von tenant_id an allen Audit-Log-Schreibstellen.
This commit is contained in:
sysops
2026-06-21 22:26:06 +02:00
parent 4a8b8964e5
commit 92e57431c3
28 changed files with 526 additions and 27 deletions
+14
View File
@@ -98,6 +98,7 @@ func (s *Server) handleSaveLDAP(w http.ResponseWriter, r *http.Request) {
s.audlog.Log(audit.Entry{
EventType: "ldap_config_saved",
Username: sess.Username,
TenantID: sess.TenantID,
IPAddress: s.remoteIP(r),
Success: true,
Detail: "LDAP-Konfiguration gespeichert",
@@ -126,6 +127,7 @@ func (s *Server) handleDeleteLDAP(w http.ResponseWriter, r *http.Request) {
s.audlog.Log(audit.Entry{
EventType: "ldap_config_deleted",
Username: sess.Username,
TenantID: sess.TenantID,
IPAddress: s.remoteIP(r),
Success: true,
Detail: "LDAP-Konfiguration gelöscht",
@@ -184,6 +186,7 @@ func (s *Server) handleTestLDAP(w http.ResponseWriter, r *http.Request) {
s.audlog.Log(audit.Entry{
EventType: "ldap_connection_test",
Username: sess.Username,
TenantID: sess.TenantID,
IPAddress: s.remoteIP(r),
Success: result.OK,
Detail: result.Message,
@@ -279,6 +282,7 @@ func (s *Server) handleCreateTenant(w http.ResponseWriter, r *http.Request) {
s.audlog.Log(audit.Entry{
EventType: "tenant_created",
Username: sess.Username,
TenantID: sess.TenantID,
IPAddress: s.remoteIP(r),
Success: true,
Detail: "Mandant erstellt: " + req.Name,
@@ -369,6 +373,7 @@ func (s *Server) handleDeleteTenant(w http.ResponseWriter, r *http.Request) {
s.audlog.Log(audit.Entry{
EventType: "tenant_deleted",
Username: sess.Username,
TenantID: sess.TenantID,
IPAddress: s.remoteIP(r),
Success: true,
Detail: "Mandant gelöscht: " + strconv.FormatInt(id, 10),
@@ -549,6 +554,7 @@ func (s *Server) handleSaveTenantLDAP(w http.ResponseWriter, r *http.Request) {
s.audlog.Log(audit.Entry{
EventType: "tenant_ldap_config_saved",
Username: sess.Username,
TenantID: sess.TenantID,
IPAddress: s.remoteIP(r),
Success: true,
Detail: "Mandant-LDAP-Konfiguration gespeichert",
@@ -580,6 +586,7 @@ func (s *Server) handleDeleteTenantLDAP(w http.ResponseWriter, r *http.Request)
s.audlog.Log(audit.Entry{
EventType: "tenant_ldap_config_deleted",
Username: sess.Username,
TenantID: sess.TenantID,
IPAddress: s.remoteIP(r),
Success: true,
Detail: "Mandant-LDAP-Konfiguration gelöscht",
@@ -619,6 +626,7 @@ func (s *Server) handleTestTenantLDAP(w http.ResponseWriter, r *http.Request) {
s.audlog.Log(audit.Entry{
EventType: "tenant_ldap_connection_test",
Username: sess.Username,
TenantID: sess.TenantID,
IPAddress: s.remoteIP(r),
Success: result.OK,
Detail: result.Message,
@@ -691,6 +699,7 @@ func (s *Server) handleAdminSaveTenantLDAP(w http.ResponseWriter, r *http.Reques
s.audlog.Log(audit.Entry{
EventType: "tenant_ldap_config_saved",
Username: sess.Username,
TenantID: sess.TenantID,
IPAddress: s.remoteIP(r),
Success: true,
Detail: "Mandant-LDAP-Konfiguration gespeichert (tenant " + strconv.FormatInt(id, 10) + ")",
@@ -723,6 +732,7 @@ func (s *Server) handleAdminDeleteTenantLDAP(w http.ResponseWriter, r *http.Requ
s.audlog.Log(audit.Entry{
EventType: "tenant_ldap_config_deleted",
Username: sess.Username,
TenantID: sess.TenantID,
IPAddress: s.remoteIP(r),
Success: true,
Detail: "Mandant-LDAP-Konfiguration gelöscht (tenant " + strconv.FormatInt(id, 10) + ")",
@@ -763,6 +773,7 @@ func (s *Server) handleAdminTestTenantLDAP(w http.ResponseWriter, r *http.Reques
s.audlog.Log(audit.Entry{
EventType: "tenant_ldap_connection_test",
Username: sess.Username,
TenantID: sess.TenantID,
IPAddress: s.remoteIP(r),
Success: result.OK,
Detail: result.Message + " (tenant " + strconv.FormatInt(id, 10) + ")",
@@ -847,6 +858,7 @@ func (s *Server) handleDeleteTenantLogo(w http.ResponseWriter, r *http.Request)
s.audlog.Log(audit.Entry{
EventType: "tenant_logo_deleted",
Username: sess.Username,
TenantID: sess.TenantID,
IPAddress: s.remoteIP(r),
Success: true,
Detail: "Mandant-Logo gelöscht (tenant " + strconv.FormatInt(id, 10) + ")",
@@ -914,6 +926,7 @@ func (s *Server) handleDeleteOwnTenantLogo(w http.ResponseWriter, r *http.Reques
s.audlog.Log(audit.Entry{
EventType: "tenant_logo_deleted",
Username: sess.Username,
TenantID: sess.TenantID,
IPAddress: s.remoteIP(r),
Success: true,
Detail: "Mandant-Logo gelöscht",
@@ -970,6 +983,7 @@ func (s *Server) saveTenantLogo(w http.ResponseWriter, r *http.Request, tenantID
s.audlog.Log(audit.Entry{
EventType: "tenant_logo_uploaded",
Username: sess.Username,
TenantID: sess.TenantID,
IPAddress: s.remoteIP(r),
Success: true,
Detail: fmt.Sprintf("Mandant-Logo hochgeladen (%d bytes, %s, tenant %d)", len(data), contentType, tenantID),