update
This commit is contained in:
@@ -11,7 +11,7 @@ func TestAuditFiltersFromRequest(t *testing.T) {
|
||||
t.Parallel()
|
||||
request := httptest.NewRequest(
|
||||
"GET",
|
||||
"/portal?audit_range=7d&audit_event=package_downloaded&audit_customer=Acme&audit_actor=taiadmin&audit_hostname=pve01&audit_package=sentinelone-linux&audit_ip=10.10.1.25&audit_details=install-rmm",
|
||||
"/portal?audit_range=7d&audit_event=package_downloaded&audit_customer=Acme&audit_user=taiadmin&audit_hostname=pve01&audit_package=sentinelone-linux&audit_ip=10.10.1.25&audit_details=install-rmm",
|
||||
nil,
|
||||
)
|
||||
filters := auditFiltersFromRequest(request)
|
||||
@@ -19,7 +19,7 @@ func TestAuditFiltersFromRequest(t *testing.T) {
|
||||
TimeRange: "7d",
|
||||
EventType: "package_downloaded",
|
||||
CustomerLabel: "Acme",
|
||||
Actor: "taiadmin",
|
||||
User: "taiadmin",
|
||||
Hostname: "pve01",
|
||||
PackageSlug: "sentinelone-linux",
|
||||
SourceIP: "10.10.1.25",
|
||||
@@ -38,6 +38,14 @@ func TestAuditFiltersDefaultToThirtyDays(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuditFiltersAcceptLegacyActorParameter(t *testing.T) {
|
||||
t.Parallel()
|
||||
request := httptest.NewRequest("GET", "/portal?audit_actor=legacy-user", nil)
|
||||
if filters := auditFiltersFromRequest(request); filters.User != "legacy-user" {
|
||||
t.Fatalf("user = %q, want legacy-user", filters.User)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasAuditQuery(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !hasAuditQuery(httptest.NewRequest("GET", "/portal?audit_hostname=pve01", nil)) {
|
||||
@@ -54,7 +62,7 @@ func TestAuditQueryUsesPlaceholders(t *testing.T) {
|
||||
TimeRange: "all",
|
||||
EventType: "package_downloaded",
|
||||
CustomerLabel: "Acme",
|
||||
Actor: "taiadmin",
|
||||
User: "taiadmin",
|
||||
Hostname: "pve01",
|
||||
PackageSlug: "sentinelone-linux",
|
||||
SourceIP: "10.10.1.25",
|
||||
@@ -62,7 +70,7 @@ func TestAuditQueryUsesPlaceholders(t *testing.T) {
|
||||
}
|
||||
query, arguments := auditQuery(filters, 250)
|
||||
if strings.Contains(query, filters.CustomerLabel) ||
|
||||
strings.Contains(query, filters.Actor) ||
|
||||
strings.Contains(query, filters.User) ||
|
||||
strings.Contains(query, filters.Hostname) {
|
||||
t.Fatal("filter values must not be interpolated into the SQL query")
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ func hasAuditQuery(r *http.Request) bool {
|
||||
"audit_range",
|
||||
"audit_event",
|
||||
"audit_customer",
|
||||
"audit_user",
|
||||
"audit_actor",
|
||||
"audit_hostname",
|
||||
"audit_package",
|
||||
@@ -155,11 +156,16 @@ func auditFiltersFromRequest(r *http.Request) auditFilters {
|
||||
default:
|
||||
timeRange = "30d"
|
||||
}
|
||||
userFilter := query.Get("audit_user")
|
||||
if strings.TrimSpace(userFilter) == "" {
|
||||
// Preserve audit links created before the portal used "user" terminology.
|
||||
userFilter = query.Get("audit_actor")
|
||||
}
|
||||
return auditFilters{
|
||||
TimeRange: timeRange,
|
||||
EventType: limitedFilter(query.Get("audit_event"), 100),
|
||||
CustomerLabel: limitedFilter(query.Get("audit_customer"), 255),
|
||||
Actor: limitedFilter(query.Get("audit_actor"), 255),
|
||||
User: limitedFilter(userFilter, 255),
|
||||
Hostname: limitedFilter(query.Get("audit_hostname"), 255),
|
||||
PackageSlug: limitedFilter(query.Get("audit_package"), 100),
|
||||
SourceIP: limitedFilter(query.Get("audit_ip"), 64),
|
||||
@@ -224,7 +230,7 @@ func auditQuery(filters auditFilters, limit int) (string, []any) {
|
||||
value string
|
||||
}{
|
||||
{"COALESCE(a.customer_label, '')", filters.CustomerLabel},
|
||||
{"ae.actor", filters.Actor},
|
||||
{"ae.actor", filters.User},
|
||||
{"ae.hostname", filters.Hostname},
|
||||
{"ae.package_slug", filters.PackageSlug},
|
||||
{"ae.source_ip", filters.SourceIP},
|
||||
@@ -260,7 +266,7 @@ func (s *Server) listAuditEvents(r *http.Request, filters auditFilters, limit in
|
||||
if err := rows.Scan(
|
||||
&record.EventType,
|
||||
&record.CustomerLabel,
|
||||
&record.Actor,
|
||||
&record.User,
|
||||
&record.Hostname,
|
||||
&record.PackageSlug,
|
||||
&record.SourceIP,
|
||||
@@ -606,7 +612,7 @@ func validSHA256(value string) bool {
|
||||
func (s *Server) audit(
|
||||
ctx context.Context,
|
||||
eventType string,
|
||||
actor string,
|
||||
user string,
|
||||
authorizationID *uint64,
|
||||
hostname string,
|
||||
packageSlug string,
|
||||
@@ -622,7 +628,7 @@ func (s *Server) audit(
|
||||
`INSERT INTO audit_events
|
||||
(event_type, actor, authorization_id, hostname, package_slug, source_ip, details)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
||||
eventType, actor, authID, hostname, packageSlug, sourceIP, details,
|
||||
eventType, user, authID, hostname, packageSlug, sourceIP, details,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ type authorizationRecord struct {
|
||||
type auditRecord struct {
|
||||
EventType string
|
||||
CustomerLabel string
|
||||
Actor string
|
||||
User string
|
||||
Hostname string
|
||||
PackageSlug string
|
||||
SourceIP string
|
||||
@@ -83,7 +83,7 @@ type auditFilters struct {
|
||||
TimeRange string
|
||||
EventType string
|
||||
CustomerLabel string
|
||||
Actor string
|
||||
User string
|
||||
Hostname string
|
||||
PackageSlug string
|
||||
SourceIP string
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
</select>
|
||||
</label>
|
||||
<label>Customer / deployment <input name="audit_customer" value="{{.AuditFilters.CustomerLabel}}" placeholder="Acme cluster refresh"></label>
|
||||
<label>Technician / actor <input name="audit_actor" value="{{.AuditFilters.Actor}}" placeholder="taiadmin"></label>
|
||||
<label>User <input name="audit_user" value="{{.AuditFilters.User}}" placeholder="taiadmin"></label>
|
||||
<label>Hostname <input name="audit_hostname" value="{{.AuditFilters.Hostname}}" placeholder="pve01"></label>
|
||||
<label>Package ID <input name="audit_package" value="{{.AuditFilters.PackageSlug}}" placeholder="sentinelone-linux"></label>
|
||||
<label>Source IP <input name="audit_ip" value="{{.AuditFilters.SourceIP}}" placeholder="10.10.1.25"></label>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<div class="audit-row audit-header" aria-hidden="true">
|
||||
<span>Event</span>
|
||||
<span>Customer / deployment</span>
|
||||
<span>Actor / host / package</span>
|
||||
<span>User / host / package</span>
|
||||
<span>Source / details</span>
|
||||
</div>
|
||||
{{range .AuditEvents}}
|
||||
@@ -41,7 +41,7 @@
|
||||
{{if .CustomerLabel}}<span>{{.CustomerLabel}}</span>{{else}}<span>—</span>{{end}}
|
||||
</div>
|
||||
<div>
|
||||
{{if .Actor}}<span>{{.Actor}}</span>{{end}}
|
||||
{{if .User}}<span>{{.User}}</span>{{end}}
|
||||
{{if .Hostname}}<span>{{.Hostname}}</span>{{end}}
|
||||
{{if .PackageSlug}}<span>{{.PackageSlug}}</span>{{end}}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user