Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 29 additions & 8 deletions base/audit_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,16 @@ const (
AuditIDISGRAllRead AuditID = 54421

// Documents events
AuditIDDocumentCreate AuditID = 55000
AuditIDDocumentRead AuditID = 55001
AuditIDDocumentUpdate AuditID = 55002
AuditIDDocumentDelete AuditID = 55003
AuditIDDocumentMetadataRead AuditID = 55004
AuditIDDocumentImport AuditID = 55005
AuditIDDocumentResync AuditID = 55006
AuditIDDocumentRevoke AuditID = 55007
AuditIDDocumentCreate AuditID = 55000
AuditIDDocumentRead AuditID = 55001
AuditIDDocumentUpdate AuditID = 55002
AuditIDDocumentDelete AuditID = 55003
AuditIDDocumentMetadataRead AuditID = 55004
AuditIDDocumentImport AuditID = 55005
AuditIDDocumentResync AuditID = 55006
AuditIDDocumentRevoke AuditID = 55007
AuditIDDocumentChannelHistoryCompact AuditID = 55008

// Document attachments events
AuditIDAttachmentCreate AuditID = 55010
AuditIDAttachmentRead AuditID = 55011
Expand Down Expand Up @@ -1193,6 +1195,25 @@ var AuditEvents = events{
FilteringPermitted: true,
EventType: eventTypeData,
},
AuditIDDocumentChannelHistoryCompact: {
Name: "Document Channel history compact",
Description: "A document channel history was compacted by the Administrator",
MandatoryFields: AuditFields{
AuditFieldDocID: "document id",
AuditFieldChannels: []string{"list", "of", "channels"},
AuditFieldSequence: "sequence",
},
mandatoryFieldGroups: []fieldGroup{
fieldGroupAuthenticated,
fieldGroupKeyspace,
},
optionalFieldGroups: []fieldGroup{
fieldGroupRequest,
},
EnabledByDefault: false,
FilteringPermitted: true,
EventType: eventTypeData,
},
AuditIDAttachmentCreate: {
Name: "Create attachment",
Description: "A new attachment was created",
Expand Down
1 change: 1 addition & 0 deletions base/audit_events_fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ const (
AuditFieldDocIDs = "doc_ids"
AuditFieldFeedType = "feed_type"
AuditFieldIncludeDocs = "include_docs"
AuditFieldSequence = "seq"

// Cluster compat version freeze events 53352, 53353
AuditFieldClusterCompatVersion = "cluster_compat_version"
Expand Down
67 changes: 67 additions & 0 deletions rest/audit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1967,6 +1967,73 @@ func TestDatabaseAuditChanges(t *testing.T) {
}
}

func TestDocumentChannelHistoryCompactionAudit(t *testing.T) {
rt := createAuditLoggingRestTester(t)
defer rt.Close()

dbConfig := rt.NewDbConfig()
dbConfig.Logging = &DbLoggingConfig{
Audit: &DbAuditLoggingConfig{
Enabled: base.Ptr(true),
EnabledEvents: base.Ptr([]uint{
uint(base.AuditIDDocumentChannelHistoryCompact),
}),
},
}
RequireStatus(t, rt.CreateDatabase("db", dbConfig), http.StatusCreated)

testCases := []struct {
name string
docIDs []string
}{
{
name: "single doc",
docIDs: []string{"single_doc"},
},
{
name: "multiple docs",
docIDs: []string{"multi_doc_1", "multi_doc_2", "multi_doc_3"},
},
}

for _, tc := range testCases {
rt.Run(tc.name, func(t *testing.T) {
for _, docID := range tc.docIDs {
rt.CreateTestDoc(docID)
}

body := string(base.MustJSONMarshal(t, CompactDocChannelHistoryRequest{
Seq: 1,
}))
output := base.AuditLogContents(t, func(t testing.TB) {
for _, docID := range tc.docIDs {
RequireStatus(t, rt.SendAdminRequest(http.MethodPost, "/{{.keyspace}}/_channel_history/"+docID+"/compact", body), http.StatusOK)
}
})

for _, docID := range tc.docIDs {
requireDocChannelAuditEvent(t, output, base.AuditIDDocumentChannelHistoryCompact, docID)
}
})
}
}

func requireDocChannelAuditEvent(t testing.TB, output []byte, eventID base.AuditID, docID string) {
t.Helper()
events := jsonLines(t, output)
countFound := 0
for _, event := range events {
if base.AuditID(event[base.AuditFieldID].(float64)) != eventID {
continue
}
if event[base.AuditFieldDocID] == docID {
countFound++
}
}
require.Equal(t, 1, countFound, "expected exactly 1 %s event for doc %q, got %d",
base.AuditEvents[eventID].Name, docID, countFound)
}

// getAuditLoggingTestConfig returns a logging config with audit enabled and other loggers configured without collation to avoid CBG-4129
func getAuditLoggingTestConfig(tempdir string) base.LoggingConfig {
return base.LoggingConfig{
Expand Down
10 changes: 10 additions & 0 deletions rest/doc_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,10 @@ func (h *handler) handleGetDocChannelHistory() error {
return err
}

base.Audit(h.ctx(), base.AuditIDDocumentMetadataRead, base.AuditFields{
base.AuditFieldDocID: docid,
})

h.writeJSON(chanHistory)
return nil
}
Expand Down Expand Up @@ -977,6 +981,12 @@ func (h *handler) handleCompactDocChannelHistory() error {
"compacted_channels": channels,
}

base.Audit(h.ctx(), base.AuditIDDocumentChannelHistoryCompact, base.AuditFields{
base.AuditFieldDocID: docid,
base.AuditFieldChannels: channels,
base.AuditFieldSequence: strconv.FormatUint(req.Seq, 10),
})

h.writeJSON(res)
return nil
}
Loading