summaryrefslogtreecommitdiff
path: root/internal/controlplane/audit.go
blob: 93a4f586a1033eba5b8ce2e449674392fdf38a79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package controlplane

import (
	"context"
	"fmt"
	"strings"
)

func (s *Store) WriteAudit(ctx context.Context, input AuditInput) error {
	actorType := "console_user"
	if input.Actor.Bootstrap {
		actorType = "bootstrap"
	}
	_, err := s.db.Exec(ctx, `INSERT INTO audit_logs
		(actor_id, actor_type, actor_role, tenant_id, request_id, method, path, action, status_code, remote_ip, user_agent)
		VALUES (NULLIF($1,'')::uuid,$2,$3,NULLIF($4,'')::uuid,$5,$6,$7,$8,$9,NULLIF($10,'')::inet,$11)`,
		input.Actor.ID, actorType, input.Actor.Role, input.Actor.TenantID, input.RequestID, input.Method,
		input.Path, input.Action, input.StatusCode, input.RemoteIP, input.UserAgent)
	if err != nil {
		return fmt.Errorf("write audit log: %w", err)
	}
	return nil
}

func (s *Store) ListAudit(ctx context.Context, tenantID string, limit int) ([]AuditLog, error) {
	if limit < 1 || limit > 1000 {
		limit = 200
	}
	query := `SELECT id, COALESCE(actor_id::text,''), actor_type, actor_role, COALESCE(tenant_id::text,''),
		request_id, method, path, action, status_code, COALESCE(host(remote_ip),''), user_agent, created_at FROM audit_logs`
	args := []any{}
	if strings.TrimSpace(tenantID) != "" {
		query += ` WHERE tenant_id=$1`
		args = append(args, tenantID)
	}
	args = append(args, limit)
	query += fmt.Sprintf(` ORDER BY created_at DESC LIMIT $%d`, len(args))
	rows, err := s.db.Query(ctx, query, args...)
	if err != nil {
		return nil, fmt.Errorf("query audit logs: %w", err)
	}
	defer rows.Close()
	result := make([]AuditLog, 0)
	for rows.Next() {
		var item AuditLog
		if err := rows.Scan(&item.ID, &item.ActorID, &item.ActorType, &item.ActorRole, &item.TenantID, &item.RequestID, &item.Method, &item.Path, &item.Action, &item.StatusCode, &item.RemoteIP, &item.UserAgent, &item.CreatedAt); err != nil {
			return nil, fmt.Errorf("scan audit log: %w", err)
		}
		result = append(result, item)
	}
	return result, rows.Err()
}