mirror of
https://github.com/coder/coder.git
synced 2026-06-04 05:28:20 +00:00
17ddee05e5
- Update go.mod to use Go 1.24.1 - Update GitHub Actions setup-go action to use Go 1.24.1 - Fix linting issues with golangci-lint by: - Updating to golangci-lint v1.57.1 (more compatible with Go 1.24.1) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <claude@anthropic.com>
83 lines
2.0 KiB
Go
83 lines
2.0 KiB
Go
package audit
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
|
|
"github.com/google/uuid"
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/coder/coder/v2/coderd/audit"
|
|
"github.com/coder/coder/v2/coderd/database"
|
|
"github.com/coder/coder/v2/coderd/database/dbauthz"
|
|
)
|
|
|
|
type BackendDetails struct {
|
|
Actor *Actor
|
|
}
|
|
|
|
type Actor struct {
|
|
ID uuid.UUID `json:"id"`
|
|
Email string `json:"email"`
|
|
Username string `json:"username"`
|
|
}
|
|
|
|
// 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, details BackendDetails) error
|
|
}
|
|
|
|
func NewAuditor(db database.Store, filter Filter, backends ...Backend) audit.Auditor {
|
|
return &auditor{
|
|
db: db,
|
|
filter: filter,
|
|
backends: backends,
|
|
Differ: audit.Differ{DiffFn: func(old, newVal any) audit.Map {
|
|
return diffValues(old, newVal, AuditableResources)
|
|
}},
|
|
}
|
|
}
|
|
|
|
// auditor is the enterprise implementation of the Auditor interface.
|
|
type auditor struct {
|
|
db database.Store
|
|
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)
|
|
}
|
|
|
|
actor, err := a.db.GetUserByID(dbauthz.AsSystemRestricted(ctx), alog.UserID) //nolint
|
|
if err != nil && !xerrors.Is(err, sql.ErrNoRows) {
|
|
return err
|
|
}
|
|
|
|
for _, backend := range a.backends {
|
|
if decision&backend.Decision() != backend.Decision() {
|
|
continue
|
|
}
|
|
|
|
err = backend.Export(ctx, alog, BackendDetails{Actor: &Actor{
|
|
ID: actor.ID,
|
|
Email: actor.Email,
|
|
Username: actor.Username,
|
|
}})
|
|
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
|
|
}
|