FDN-02/FDN-03/FDN-07/FDN-08: Migrations-Rollback, Objekt-Storage-Interface, go.sum-Fix, Observability
CI / Backend (go vet, go test -cover) (push) Has been cancelled
CI / Frontend (ESLint, tsc, next build) (push) Has been cancelled

- FDN-02: Rollback-fähige Down-Migrationen (024-026), archivdms seed dev CLI
- FDN-03: internal/objectstore Interface + lokaler WORM-Treiber, signierte Download-URLs
- FDN-07: go.mod/go.sum vervollständigt (fehlender go-ldap/v3-Eintrag), CI-Pipeline (.gitea/workflows/ci.yml, bereits in FDN-01 committet) damit lauffähig
- FDN-08: Request-ID-Middleware, /metrics-Endpoint, Panic-Recovery, Login/Logout/Me technisches Logging inkl. Access-Log je Anfrage
This commit is contained in:
2026-08-11 22:27:52 +02:00
parent 9a24ea29e1
commit 89de794356
30 changed files with 2688 additions and 113 deletions
+5 -6
View File
@@ -15,7 +15,6 @@ import (
"errors"
"io"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
@@ -107,7 +106,7 @@ func (s *Server) handlePublicShareDownload(w http.ResponseWriter, r *http.Reques
// Atomically claim one access slot (closes the max_accesses race).
ok, err := s.store.IncrementShareAccess(r.Context(), rs.ShareID())
if err != nil {
s.logger.Error("share access increment failed", "share_id", rs.ShareID(), "err", err)
s.reqLog(r.Context()).Error("share access increment failed", "share_id", rs.ShareID(), "err", err)
writeError(w, http.StatusInternalServerError, "download failed")
return
}
@@ -118,9 +117,9 @@ func (s *Server) handlePublicShareDownload(w http.ResponseWriter, r *http.Reques
return
}
f, err := os.Open(rs.StoragePath())
f, err := s.objects.Open(r.Context(), rs.TenantID(), rs.StoragePath())
if err != nil {
s.logger.Error("share file open failed", "share_id", rs.ShareID(), "err", err)
s.reqLog(r.Context()).Error("share file open failed", "share_id", rs.ShareID(), "err", err)
writeError(w, http.StatusInternalServerError, "download failed")
return
}
@@ -133,7 +132,7 @@ func (s *Server) handlePublicShareDownload(w http.ResponseWriter, r *http.Reques
w.Header().Set("Content-Disposition", "attachment; filename=\""+safeDownloadName(rs.DocumentTitle, ext)+"\"")
w.Header().Set("X-Content-Type-Options", "nosniff")
if _, err := io.Copy(w, f); err != nil {
s.logger.Warn("share file stream interrupted", "share_id", rs.ShareID(), "err", err)
s.reqLog(r.Context()).Warn("share file stream interrupted", "share_id", rs.ShareID(), "err", err)
}
}
@@ -141,7 +140,7 @@ func (s *Server) handlePublicShareDownload(w http.ResponseWriter, r *http.Reques
// into the audit log (EventShareAccessed). Never blocks the response path.
func (s *Server) recordShareAccess(r *http.Request, rs *storage.ResolvedShare, ip, result string) {
if err := s.store.LogShareAccess(r.Context(), rs.ShareID(), ip, r.UserAgent(), result); err != nil {
s.logger.Error("share access log failed", "share_id", rs.ShareID(), "err", err)
s.reqLog(r.Context()).Error("share access log failed", "share_id", rs.ShareID(), "err", err)
}
tenantID := rs.TenantID()
s.audlog.Log(audit.Entry{