Skip to content

Commit 487af37

Browse files
authored
Merge pull request #28 from NextronSystems/test/event-parsing
test: add tests for event parsing
2 parents 77ca5cb + 63338b1 commit 487af37

6 files changed

Lines changed: 226 additions & 12 deletions

File tree

thorlog/parser/parser_test.go

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
package parser
2+
3+
import (
4+
"testing"
5+
"time"
6+
7+
"github.com/NextronSystems/jsonlog"
8+
"github.com/NextronSystems/jsonlog/thorlog/common"
9+
thorlogv1 "github.com/NextronSystems/jsonlog/thorlog/v1"
10+
thorlogv2 "github.com/NextronSystems/jsonlog/thorlog/v2"
11+
"github.com/NextronSystems/jsonlog/thorlog/v3"
12+
"github.com/stretchr/testify/assert"
13+
"github.com/stretchr/testify/require"
14+
)
15+
16+
func mustTime(s string) time.Time {
17+
t, err := time.Parse(time.RFC3339, s)
18+
if err != nil {
19+
panic(err)
20+
}
21+
return t
22+
}
23+
24+
func TestParseEvent(t *testing.T) {
25+
for _, testcase := range []struct {
26+
name string
27+
rawEvent string
28+
expected thorlog.Event
29+
}{
30+
{
31+
"JsonV1Logline",
32+
`{"time":"2024-09-24T12:35:41Z","hostname":"host","level":"Info","module":"Startup","message":"Sigma Database: r2024-07-17-48-g5c4f599e3","scanid":"S-NtvqbRLWbf8","log_version":"v1.0.0"}`,
33+
&thorlogv1.Event{
34+
LogEventMetadata: thorlogv1.Metadata{
35+
Time: mustTime("2024-09-24T12:35:41Z"),
36+
Lvl: common.Info,
37+
Mod: "Startup",
38+
ScanID: "S-NtvqbRLWbf8",
39+
GenID: "",
40+
Source: "host",
41+
},
42+
Data: thorlogv1.Fields{
43+
{Key: "message", Value: "Sigma Database: r2024-07-17-48-g5c4f599e3"},
44+
},
45+
},
46+
},
47+
{
48+
"JsonV2",
49+
`{"time":"2024-09-24T12:37:04Z","hostname":"host","level":"Info","module":"Hosts","message":"Starting module","scanid":"S-kgKxYyJFQd0","log_version":"v2.0.0"}`,
50+
&thorlogv2.Event{
51+
LogEventMetadata: thorlogv2.Metadata{
52+
Time: mustTime("2024-09-24T12:37:04Z"),
53+
Lvl: common.Info,
54+
Mod: "Hosts",
55+
ScanID: "S-kgKxYyJFQd0",
56+
GenID: "",
57+
Source: "host",
58+
},
59+
Data: thorlogv2.Fields{
60+
{Key: "message", Value: "Starting module"},
61+
},
62+
EventVersion: "v2.0.0",
63+
},
64+
},
65+
{
66+
"JsonV2WithArray",
67+
`{"time":"2024-09-24T12:37:04Z","hostname":"host","level":"Info","module":"Hosts","message":"something","tags":["abc","def","ghi"],"scanid":"S-kgKxYyJFQd0","log_version":"v2.0.0"}`,
68+
&thorlogv2.Event{
69+
LogEventMetadata: thorlogv2.Metadata{
70+
Time: mustTime("2024-09-24T12:37:04Z"),
71+
Lvl: common.Info,
72+
Mod: "Hosts",
73+
ScanID: "S-kgKxYyJFQd0",
74+
GenID: "",
75+
Source: "host",
76+
},
77+
Data: thorlogv2.Fields{
78+
{Key: "message", Value: "something"},
79+
{Key: "tags", Value: []any{"abc", "def", "ghi"}},
80+
},
81+
EventVersion: "v2.0.0",
82+
},
83+
},
84+
{
85+
"JsonV2LoglineWithNested",
86+
`{"time":"2024-09-24T12:37:04Z","hostname":"host","level":"Info","module":"Hosts","message":"something","reasons":[{"reason":"r1","rulename":"rn1"},{"reason":"r2","rulename":"rn2"}],"scanid":"S-kgKxYyJFQd0","log_version":"v2.0.0"}`,
87+
&thorlogv2.Event{
88+
LogEventMetadata: thorlogv2.Metadata{
89+
Time: mustTime("2024-09-24T12:37:04Z"),
90+
Lvl: common.Info,
91+
Mod: "Hosts",
92+
ScanID: "S-kgKxYyJFQd0",
93+
GenID: "",
94+
Source: "host",
95+
},
96+
Data: thorlogv2.Fields{
97+
{Key: "message", Value: "something"},
98+
{Key: "reasons", Value: []any{
99+
thorlogv2.Fields{
100+
{Key: "reason", Value: "r1"},
101+
{Key: "rulename", Value: "rn1"},
102+
},
103+
thorlogv2.Fields{
104+
{Key: "reason", Value: "r2"},
105+
{Key: "rulename", Value: "rn2"},
106+
},
107+
}},
108+
},
109+
EventVersion: "v2.0.0",
110+
},
111+
},
112+
{
113+
"JsonV3Message",
114+
`{"message":"Starting module","type":"THOR message","meta":{"time":"2024-09-24T14:18:46.190394329+02:00","level":"Info","module":"Hosts","scan_id":"S-UBNfBD4xE8s","event_id":"","hostname":"host"},"fields":{},"log_version":"v3.0.0"}`,
115+
&thorlog.Message{
116+
ObjectHeader: jsonlog.ObjectHeader{
117+
Type: "THOR message",
118+
},
119+
Meta: thorlog.LogEventMetadata{
120+
Time: mustTime("2024-09-24T14:18:46.190394329+02:00"),
121+
Lvl: common.Info,
122+
Mod: "Hosts",
123+
ScanID: "S-UBNfBD4xE8s",
124+
GenID: "",
125+
Source: "host",
126+
},
127+
Text: "Starting module",
128+
LogVersion: "v3.0.0",
129+
},
130+
},
131+
{
132+
"JsonV3Finding",
133+
`{"type":"THOR finding","meta":{"time":"2024-09-24T14:18:46.190394329+02:00","level":"Alert","module":"Test","scan_id":"abdc","event_id":"abdas","hostname":"aserarsd"},"message":"This is a test finding","subject":{"type":"file","path":"path/to/file"},"score":70,"reasons":[{"type":"reason","summary":"Reason 1","signature":{"score":70,"ref":null,"origin":"internal","kind":""},"matched":null}],"reason_count":0,"context":[{"object":{"type":"At Job"},"relation":"","unique":false}],"log_version":"v3"}`,
134+
&thorlog.Finding{
135+
ObjectHeader: jsonlog.ObjectHeader{
136+
Type: "THOR finding",
137+
},
138+
Meta: thorlog.LogEventMetadata{
139+
Time: mustTime("2024-09-24T14:18:46.190394329+02:00"),
140+
Lvl: common.Alert,
141+
Mod: "Test",
142+
ScanID: "abdc",
143+
GenID: "abdas",
144+
Source: "aserarsd",
145+
},
146+
Text: "This is a test finding",
147+
Subject: &thorlog.File{
148+
ObjectHeader: jsonlog.ObjectHeader{
149+
Type: "file",
150+
},
151+
Path: "path/to/file",
152+
},
153+
Score: 70,
154+
Reasons: []thorlog.Reason{
155+
{
156+
ObjectHeader: jsonlog.ObjectHeader{
157+
Type: "reason",
158+
},
159+
Summary: "Reason 1",
160+
Signature: thorlog.Signature{
161+
Score: 70,
162+
Type: thorlog.Internal,
163+
},
164+
},
165+
},
166+
ReasonCount: 0,
167+
EventContext: thorlog.Context{
168+
{
169+
Object: &thorlog.AtJob{
170+
ObjectHeader: jsonlog.ObjectHeader{
171+
Type: "At Job",
172+
},
173+
},
174+
},
175+
},
176+
LogVersion: "v3.0.0",
177+
},
178+
},
179+
} {
180+
t.Run(testcase.name, func(t *testing.T) {
181+
event, err := ParseEvent([]byte(testcase.rawEvent))
182+
require.NoError(t, err)
183+
assert.Equal(t, testcase.expected, event)
184+
})
185+
}
186+
}

thorlog/v1/event.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@ package v1
22

33
import (
44
"encoding/json"
5+
"time"
56

67
"github.com/NextronSystems/jsonlog/thorlog/common"
78
"golang.org/x/mod/semver"
89
)
910

1011
type Event struct {
11-
common.LogEventMetadata
12+
LogEventMetadata Metadata
1213

1314
Data Fields `textlog:",expand"`
1415
}
1516

1617
func (e *Event) Metadata() *common.LogEventMetadata {
17-
return &e.LogEventMetadata
18+
return (*common.LogEventMetadata)(&e.LogEventMetadata)
1819
}
1920

2021
func (e *Event) Message() string {
@@ -75,3 +76,12 @@ func (e Event) MarshalJSON() ([]byte, error) {
7576
combinedData = append(combinedData, data2[1:]...)
7677
return combinedData, nil
7778
}
79+
80+
type Metadata struct {
81+
Time time.Time `json:"time" textlog:"-"`
82+
Lvl common.LogLevel `json:"level" textlog:"-"`
83+
Mod string `json:"module" textlog:"-"`
84+
ScanID string `json:"scanid" textlog:"scanid,omitempty"`
85+
GenID string `json:"uid" textlog:"uid,omitempty"`
86+
Source string `json:"hostname" textlog:"-"`
87+
}

thorlog/v2/event.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,22 @@ import (
55
"errors"
66
"fmt"
77
"strconv"
8+
"time"
89

910
"github.com/NextronSystems/jsonlog/thorlog/common"
1011
"golang.org/x/mod/semver"
1112
)
1213

1314
type Event struct {
14-
common.LogEventMetadata
15+
LogEventMetadata Metadata
1516

1617
Data Fields `textlog:",expand"`
1718

1819
EventVersion common.Version `json:"log_version"`
1920
}
2021

2122
func (e *Event) Metadata() *common.LogEventMetadata {
22-
return &e.LogEventMetadata
23+
return (*common.LogEventMetadata)(&e.LogEventMetadata)
2324
}
2425

2526
func (e *Event) Message() string {
@@ -100,3 +101,12 @@ func (e Event) MarshalJSON() ([]byte, error) {
100101
combinedData = append(combinedData, '}')
101102
return combinedData, nil
102103
}
104+
105+
type Metadata struct {
106+
Time time.Time `json:"time" textlog:"-"`
107+
Lvl common.LogLevel `json:"level" textlog:"-"`
108+
Mod string `json:"module" textlog:"-"`
109+
ScanID string `json:"scanid" textlog:"scanid,omitempty"`
110+
GenID string `json:"uid" textlog:"uid,omitempty"`
111+
Source string `json:"hostname" textlog:"-"`
112+
}

thorlog/v3/event_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ func TestFinding_UnmarshalJSON(t *testing.T) {
119119
if err != nil {
120120
t.Fatal(err)
121121
}
122+
t.Log(string(jsonform))
122123
var newFinding Finding
123124
if err := json.Unmarshal(jsonform, &newFinding); err != nil {
124125
t.Fatal(err)

thorlog/v3/file.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package thorlog
22

33
import (
44
"encoding/json"
5+
"fmt"
56
"time"
67

78
"github.com/NextronSystems/jsonlog"
@@ -73,17 +74,20 @@ func (f *File) UnmarshalJSON(data []byte) error {
7374
// Permissions are either unix or windows permissions, so we need to try both
7475
type plainFile File
7576

76-
var testFile plainFile
77-
testFile.Permissions = &UnixPermissions{}
77+
var testFile struct {
78+
plainFile
79+
Permissions EmbeddedObject `json:"permissions"`
80+
}
7881
err := json.Unmarshal(data, &testFile)
7982
if err != nil {
80-
testFile.Permissions = &WindowsPermissions{}
81-
err = json.Unmarshal(data, &testFile)
82-
if err != nil {
83-
return err
84-
}
83+
return err
84+
}
85+
perms, isPermissions := testFile.Permissions.Object.(Permissions)
86+
if !isPermissions && testFile.Permissions.Object != nil {
87+
return fmt.Errorf("invalid permissions type: %T", testFile.Permissions.Object)
8588
}
86-
*f = File(testFile)
89+
*f = File(testFile.plainFile)
90+
f.Permissions = perms
8791
return nil
8892
}
8993

thorlog/v3/unmarshal.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ func (e *EmbeddedObject) UnmarshalJSON(data []byte) error {
9292
if err != nil {
9393
return err
9494
}
95+
if details == nil {
96+
return nil
97+
}
9598
objectType, exists := details["type"]
9699
if !exists {
97100
return ErrNoLogObject

0 commit comments

Comments
 (0)