update
This commit is contained in:
@@ -31,7 +31,13 @@ func (s *Server) handlePortal(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "unable to list installer actions", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
auditEvents, err := s.listAuditEvents(r)
|
||||
auditFilter := auditFiltersFromRequest(r)
|
||||
auditEventTypes, err := s.listAuditEventTypes(r)
|
||||
if err != nil {
|
||||
http.Error(w, "unable to list audit event types", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
auditEvents, err := s.listAuditEvents(r, auditFilter)
|
||||
if err != nil {
|
||||
http.Error(w, "unable to list audit events", http.StatusInternalServerError)
|
||||
return
|
||||
@@ -42,6 +48,8 @@ func (s *Server) handlePortal(w http.ResponseWriter, r *http.Request) {
|
||||
CSRFToken: tech.CSRFToken,
|
||||
Authorizations: authorizations,
|
||||
AuditEvents: auditEvents,
|
||||
AuditFilters: auditFilter,
|
||||
AuditEventTypes: auditEventTypes,
|
||||
Packages: packages,
|
||||
Actions: actions,
|
||||
NewCode: r.URL.Query().Get("code"),
|
||||
@@ -74,13 +82,102 @@ func (s *Server) listActions(r *http.Request) ([]actionRecord, error) {
|
||||
return records, rows.Err()
|
||||
}
|
||||
|
||||
func (s *Server) listAuditEvents(r *http.Request) ([]auditRecord, error) {
|
||||
func auditFiltersFromRequest(r *http.Request) auditFilters {
|
||||
query := r.URL.Query()
|
||||
timeRange := strings.TrimSpace(query.Get("audit_range"))
|
||||
switch timeRange {
|
||||
case "24h", "7d", "30d", "90d", "all":
|
||||
default:
|
||||
timeRange = "30d"
|
||||
}
|
||||
return auditFilters{
|
||||
TimeRange: timeRange,
|
||||
EventType: limitedFilter(query.Get("audit_event"), 100),
|
||||
Actor: limitedFilter(query.Get("audit_actor"), 255),
|
||||
Hostname: limitedFilter(query.Get("audit_hostname"), 255),
|
||||
PackageSlug: limitedFilter(query.Get("audit_package"), 100),
|
||||
SourceIP: limitedFilter(query.Get("audit_ip"), 64),
|
||||
Details: limitedFilter(query.Get("audit_details"), 255),
|
||||
}
|
||||
}
|
||||
|
||||
func limitedFilter(value string, maxLength int) string {
|
||||
value = strings.TrimSpace(value)
|
||||
characters := []rune(value)
|
||||
if len(characters) > maxLength {
|
||||
return string(characters[:maxLength])
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func (s *Server) listAuditEventTypes(r *http.Request) ([]string, error) {
|
||||
rows, err := s.db.QueryContext(
|
||||
r.Context(),
|
||||
`SELECT event_type, actor, hostname, package_slug, source_ip, details, created_at
|
||||
`SELECT DISTINCT event_type
|
||||
FROM audit_events
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 100`,
|
||||
ORDER BY event_type`,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var eventTypes []string
|
||||
for rows.Next() {
|
||||
var eventType string
|
||||
if err := rows.Scan(&eventType); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
eventTypes = append(eventTypes, eventType)
|
||||
}
|
||||
return eventTypes, rows.Err()
|
||||
}
|
||||
|
||||
func auditQuery(filters auditFilters) (string, []any) {
|
||||
query := `SELECT event_type, actor, hostname, package_slug, source_ip, details, created_at
|
||||
FROM audit_events
|
||||
WHERE 1 = 1`
|
||||
var arguments []any
|
||||
|
||||
timeClauses := map[string]string{
|
||||
"24h": " AND created_at >= UTC_TIMESTAMP(6) - INTERVAL 1 DAY",
|
||||
"7d": " AND created_at >= UTC_TIMESTAMP(6) - INTERVAL 7 DAY",
|
||||
"30d": " AND created_at >= UTC_TIMESTAMP(6) - INTERVAL 30 DAY",
|
||||
"90d": " AND created_at >= UTC_TIMESTAMP(6) - INTERVAL 90 DAY",
|
||||
}
|
||||
query += timeClauses[filters.TimeRange]
|
||||
|
||||
if filters.EventType != "" {
|
||||
query += " AND event_type = ?"
|
||||
arguments = append(arguments, filters.EventType)
|
||||
}
|
||||
containsFilters := []struct {
|
||||
column string
|
||||
value string
|
||||
}{
|
||||
{"actor", filters.Actor},
|
||||
{"hostname", filters.Hostname},
|
||||
{"package_slug", filters.PackageSlug},
|
||||
{"source_ip", filters.SourceIP},
|
||||
{"details", filters.Details},
|
||||
}
|
||||
for _, filter := range containsFilters {
|
||||
if filter.value == "" {
|
||||
continue
|
||||
}
|
||||
query += " AND LOCATE(?, " + filter.column + ") > 0"
|
||||
arguments = append(arguments, filter.value)
|
||||
}
|
||||
query += " ORDER BY created_at DESC LIMIT 250"
|
||||
return query, arguments
|
||||
}
|
||||
|
||||
func (s *Server) listAuditEvents(r *http.Request, filters auditFilters) ([]auditRecord, error) {
|
||||
query, arguments := auditQuery(filters)
|
||||
rows, err := s.db.QueryContext(
|
||||
r.Context(),
|
||||
query,
|
||||
arguments...,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -147,9 +244,10 @@ func (s *Server) listAuthorizations(r *http.Request) ([]authorizationRecord, err
|
||||
WHERE h.authorization_id = a.id),
|
||||
a.created_at, a.expires_at, a.revoked_at,
|
||||
COALESCE((
|
||||
SELECT GROUP_CONCAT(ap.display_name
|
||||
ORDER BY ap.display_name SEPARATOR ', ')
|
||||
SELECT GROUP_CONCAT(p.display_name
|
||||
ORDER BY p.display_name SEPARATOR ', ')
|
||||
FROM authorization_packages ap
|
||||
JOIN packages p ON p.id = ap.package_id
|
||||
WHERE ap.authorization_id = a.id
|
||||
), ''),
|
||||
COALESCE((
|
||||
|
||||
Reference in New Issue
Block a user