fix(SEC-29): Rollen-Trennung Admins/Auditoren, domain_auditor Rolle
- superadmin + domain_admin haben keinen Mail-Zugriff mehr (requireMailAccess) - Neue Rolle domain_auditor: alle Tenant-Mails, kein Admin-Zugriff - auditor + user: nur eigene Mails - ZIP-Export: kein separates Attachment-Entpacken mehr, nur EML - roleLevel() um domain_auditor (Level 3) erweitert Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+18
-10
@@ -34,14 +34,17 @@ func isValidMailID(id string) bool {
|
||||
}
|
||||
|
||||
// roleLevel returns the privilege level for a role string.
|
||||
// Hierarchy: superadmin=5 > admin=4 > domain_admin=3 > auditor=2 > user=1
|
||||
// Hierarchy: superadmin=5 > domain_admin=4 > domain_auditor=3 > auditor=2 > user=1
|
||||
// Separation of duties: admins (superadmin, domain_admin) have NO mail access.
|
||||
// Mail access: domain_auditor (all tenant mails), auditor (own mails), user (own mails).
|
||||
func roleLevel(role string) int {
|
||||
levels := map[string]int{
|
||||
userstore.RoleUser: 1,
|
||||
userstore.RoleAuditor: 2,
|
||||
userstore.RoleDomainAdmin: 3,
|
||||
userstore.RoleAdmin: 4,
|
||||
userstore.RoleSuperAdmin: 5,
|
||||
userstore.RoleUser: 1,
|
||||
userstore.RoleAuditor: 2,
|
||||
userstore.RoleDomainAuditor: 3,
|
||||
userstore.RoleDomainAdmin: 4,
|
||||
userstore.RoleAdmin: 4, // legacy alias for domain_admin
|
||||
userstore.RoleSuperAdmin: 5,
|
||||
}
|
||||
return levels[role]
|
||||
}
|
||||
@@ -261,10 +264,9 @@ func (s *Server) requireRole(role string, next http.HandlerFunc) http.HandlerFun
|
||||
// ── Mail access middleware ────────────────────────────────────────────────
|
||||
|
||||
// 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.
|
||||
// SEC-29: Strict separation of duties — admins manage, auditors review.
|
||||
// Mail access is granted ONLY to: user, auditor, domain_auditor.
|
||||
// superadmin and domain_admin are explicitly denied (manage system/tenant, not content).
|
||||
func (s *Server) requireMailAccess(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
sess := sessionFromCtx(r.Context())
|
||||
@@ -272,6 +274,12 @@ func (s *Server) requireMailAccess(next http.HandlerFunc) http.HandlerFunc {
|
||||
writeError(w, http.StatusUnauthorized, "not authenticated")
|
||||
return
|
||||
}
|
||||
// SEC-29: Admins must not access mail content.
|
||||
switch sess.Role {
|
||||
case userstore.RoleSuperAdmin, userstore.RoleDomainAdmin:
|
||||
writeError(w, http.StatusForbidden, "access denied")
|
||||
return
|
||||
}
|
||||
next(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user