fix: Tenant-Isolation in handleSearch + requireMailAccess
- handleSearch: Ergebnisse nach tenant_id filtern (via email_refs) - requireMailAccess: domain_admin darf Mails lesen, Tenant-Prüfung erfolgt bereits in handleGetMail via GetTenantForMail Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+27
-3
@@ -542,6 +542,26 @@ func (s *Server) handleSearch(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Tenant isolation: filter results to only this tenant's emails.
|
||||
tenantID := tenantFromCtx(r.Context())
|
||||
if tenantID != nil && len(result.Hits) > 0 {
|
||||
allowedIDs, idErr := s.store.GetAllIDsByTenant(r.Context(), tenantID)
|
||||
if idErr == nil {
|
||||
allowed := make(map[string]struct{}, len(allowedIDs))
|
||||
for _, id := range allowedIDs {
|
||||
allowed[id] = struct{}{}
|
||||
}
|
||||
filtered := result.Hits[:0]
|
||||
for _, h := range result.Hits {
|
||||
if _, ok := allowed[h.ID]; ok {
|
||||
filtered = append(filtered, h)
|
||||
}
|
||||
}
|
||||
result.Hits = filtered
|
||||
result.Total = len(filtered)
|
||||
}
|
||||
}
|
||||
|
||||
sess := sessionFromCtx(r.Context())
|
||||
s.audlog.Log(audit.Entry{
|
||||
EventType: audit.EventSearch,
|
||||
@@ -768,12 +788,16 @@ func remoteIP(r *http.Request) string {
|
||||
|
||||
// ── Mail access middleware ────────────────────────────────────────────────
|
||||
|
||||
// requireMailAccess blocks admin role (no mail access) and passes user/auditor through.
|
||||
// requireMailAccess checks that the caller may read mail content.
|
||||
// superadmin and domain_admin have read access (tenant-scoped via handleGetMail).
|
||||
// Auditor and user have access to their own mails.
|
||||
// The old "admin" role (now domain_admin) previously had no mail access — that
|
||||
// restriction is removed; domain_admin now needs to be able to read archived mails.
|
||||
func (s *Server) requireMailAccess(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
sess := sessionFromCtx(r.Context())
|
||||
if sess.Role == userstore.RoleAdmin {
|
||||
writeError(w, http.StatusForbidden, "admins have no access to mail content")
|
||||
if sess == nil {
|
||||
writeError(w, http.StatusUnauthorized, "not authenticated")
|
||||
return
|
||||
}
|
||||
next(w, r)
|
||||
|
||||
Reference in New Issue
Block a user