coder/enterprise/audit/audit.go

59 lines
1.4 KiB
Go

package audit
import (
"context"
"golang.org/x/xerrors"
"github.com/coder/coder/coderd/audit"
"github.com/coder/coder/coderd/database"
)
// Backends can store or send audit logs to arbitrary locations.
type Backend interface {
// Decision determines the FilterDecisions that the backend tolerates.
Decision() FilterDecision
// Export sends an audit log to the backend.
Export(ctx context.Context, alog database.AuditLog) error
}
func NewAuditor(filter Filter, backends ...Backend) audit.Auditor {
return &auditor{
filter: filter,
backends: backends,
Differ: audit.Differ{DiffFn: func(old, new any) audit.Map {
return diffValues(old, new, AuditableResources)
}},
}
}
// auditor is the enterprise implementation of the Auditor interface.
type auditor struct {
filter Filter
backends []Backend
audit.Differ
}
func (a *auditor) Export(ctx context.Context, alog database.AuditLog) error {
decision, err := a.filter.Check(ctx, alog)
if err != nil {
return xerrors.Errorf("filter check: %w", err)
}
for _, backend := range a.backends {
if decision&backend.Decision() != backend.Decision() {
continue
}
err = backend.Export(ctx, alog)
if err != nil {
// naively return the first error. should probably make this smarter
// by returning multiple errors.
return xerrors.Errorf("export audit log to backend: %w", err)
}
}
return nil
}