Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

catname on the IDS seems to sometimes be an array of strings #113

Merged
merged 7 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module github.com/unpoller/unifi

go 1.19
go 1.21

toolchain go1.22.1

require (
github.com/brianvoe/gofakeit/v6 v6.28.0
Expand Down
84 changes: 42 additions & 42 deletions ids.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,48 +9,48 @@ import (

// IDS holds an Intrusion Prevention System Event.
type IDS struct {
AppProto string `json:"app_proto,omitempty"`
Archived FlexBool `json:"archived"`
Catname string `json:"catname"`
Datetime time.Time `fake:"{recent_time}" json:"datetime"`
DestIP string `fake:"{ipv4address}" json:"dest_ip"`
DestIPGeo IPGeo `json:"dstipGeo"`
DestPort int `fake:"{port}" json:"dest_port,omitempty"`
DstIPASN string `fake:"{address}" json:"dstipASN"`
DstIPCountry string `fake:"{country}" json:"dstipCountry"`
DstMAC string `fake:"{macaddress}" json:"dst_mac"`
EventType string `json:"event_type"`
FlowID int64 `json:"flow_id"`
Host string `json:"host"`
ID string `fake:"{uuid}" json:"_id"`
InIface string `json:"in_iface"`
InnerAlertAction string `json:"inner_alert_action"`
InnerAlertCategory string `json:"inner_alert_category"`
InnerAlertGID int64 `json:"inner_alert_gid"`
InnerAlertRev int64 `json:"inner_alert_rev"`
InnerAlertSeverity int64 `json:"inner_alert_severity"`
InnerAlertSignature string `json:"inner_alert_signature"`
InnerAlertSignatureID int64 `json:"inner_alert_signature_id"`
Key string `fake:"{uuid}" json:"key"`
Msg string `fake:"{buzzword}" json:"msg"`
Proto string `json:"proto"`
SiteID string `fake:"{uuid}" json:"site_id"`
SiteName string `json:"-"`
SourceIPGeo IPGeo `json:"srcipGeo"`
SourceName string `json:"-"`
SrcIP string `fake:"{ipv4address}" json:"src_ip"`
SrcIPASN string `fake:"{address}" json:"srcipASN"`
SrcIPCountry string `fake:"{country}" json:"srcipCountry"`
SrcMAC string `fake:"{macaddress}" json:"src_mac"`
SrcPort int `fake:"{port}" json:"src_port,omitempty"`
Subsystem string `json:"subsystem"`
Time int64 `fake:"{timestamp}" json:"time"`
Timestamp int64 `fake:"{timestamp}" json:"timestamp"`
USGIP string `fake:"{ipv4address}" json:"usgip"`
USGIPASN string `fake:"{address}" json:"usgipASN"`
USGIPCountry string `fake:"{country}" json:"usgipCountry"`
USGIPGeo IPGeo `json:"usgipGeo"`
UniqueAlertID string `json:"unique_alertid"`
AppProto string `json:"app_proto,omitempty"`
Archived FlexBool `json:"archived"`
Catname FlexString `json:"catname"`
Datetime time.Time `fake:"{recent_time}" json:"datetime"`
DestIP string `fake:"{ipv4address}" json:"dest_ip"`
DestIPGeo IPGeo `json:"dstipGeo"`
DestPort int `fake:"{port}" json:"dest_port,omitempty"`
DstIPASN string `fake:"{address}" json:"dstipASN"`
DstIPCountry string `fake:"{country}" json:"dstipCountry"`
DstMAC string `fake:"{macaddress}" json:"dst_mac"`
EventType string `json:"event_type"`
FlowID int64 `json:"flow_id"`
Host string `json:"host"`
ID string `fake:"{uuid}" json:"_id"`
InIface string `json:"in_iface"`
InnerAlertAction string `json:"inner_alert_action"`
InnerAlertCategory string `json:"inner_alert_category"`
InnerAlertGID int64 `json:"inner_alert_gid"`
InnerAlertRev int64 `json:"inner_alert_rev"`
InnerAlertSeverity int64 `json:"inner_alert_severity"`
InnerAlertSignature string `json:"inner_alert_signature"`
InnerAlertSignatureID int64 `json:"inner_alert_signature_id"`
Key string `fake:"{uuid}" json:"key"`
Msg string `fake:"{buzzword}" json:"msg"`
Proto string `json:"proto"`
SiteID string `fake:"{uuid}" json:"site_id"`
SiteName string `json:"-"`
SourceIPGeo IPGeo `json:"srcipGeo"`
SourceName string `json:"-"`
SrcIP string `fake:"{ipv4address}" json:"src_ip"`
SrcIPASN string `fake:"{address}" json:"srcipASN"`
SrcIPCountry string `fake:"{country}" json:"srcipCountry"`
SrcMAC string `fake:"{macaddress}" json:"src_mac"`
SrcPort int `fake:"{port}" json:"src_port,omitempty"`
Subsystem string `json:"subsystem"`
Time int64 `fake:"{timestamp}" json:"time"`
Timestamp int64 `fake:"{timestamp}" json:"timestamp"`
USGIP string `fake:"{ipv4address}" json:"usgip"`
USGIPASN string `fake:"{address}" json:"usgipASN"`
USGIPCountry string `fake:"{country}" json:"usgipCountry"`
USGIPGeo IPGeo `json:"usgipGeo"`
UniqueAlertID string `json:"unique_alertid"`
}

// GetIDS returns Intrusion Detection Systems events for a list of Sites.
Expand Down
83 changes: 83 additions & 0 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ func init() {
}

var ErrCannotUnmarshalFlexInt = fmt.Errorf("cannot unmarshal to FlexInt")
var ErrCannotUnmarshalFlexString = fmt.Errorf("cannot unmarshal to FlexString")

// This is a list of unifi API paths.
// The %s in each string must be replaced with a Site.Name.
Expand Down Expand Up @@ -289,6 +290,88 @@ type ServerStatus struct {
UUID string `fake:"{uuid}" json:"uuid"`
}

type FlexString struct {
Val string
Arr []string
}

func NewFlexString(v string) *FlexString {
return &FlexString{
Val: v,
Arr: []string{v},
}
}

// UnmarshalJSON converts a string or number to an integer.
// Generally, do call this directly, it's used in the json interface.
platinummonkey marked this conversation as resolved.
Show resolved Hide resolved
func (f *FlexString) UnmarshalJSON(b []byte) error {
var ust interface{}

if err := json.Unmarshal(b, &ust); err != nil {
return fmt.Errorf("json unmarshal: %w", err)
}

switch i := ust.(type) {
case []interface{}:
// try to cast to string
res := make([]string, 0)
platinummonkey marked this conversation as resolved.
Show resolved Hide resolved
for _, v := range i {
if s, err := v.(string); err == nil {
res = append(res, s)
}
}
f.Arr = res
f.Val = strings.Join(res, ", ")
case []string:
f.Val = strings.Join(i, ", ")
f.Arr = i
case string:
f.Val = i
f.Arr = []string{i}
case nil:
f.Val = ""
f.Arr = []string{}
default:
return fmt.Errorf("%v: %w", b, ErrCannotUnmarshalFlexString)
}
return nil
}

func (f FlexString) MarshalJSON() ([]byte, error) {
// array case
if f.Arr != nil && len(f.Arr) > 1 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will turn an array into a string if it only has 1 element. Seems fine for now, but something to keep in mind.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright added a hint here

return json.Marshal(f.Arr)
}

// plain string case
return json.Marshal(f.Val)
}

func (f FlexString) String() string {
return f.Val
}

func (f FlexString) Fake(faker *gofakeit.Faker) interface{} {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to read about what this does. hm

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

powers the gofakeit stuff for running the integration tests in unpoller/unpoller

randValue := math.Min(math.Max(0.1, math.Abs(faker.Rand.Float64())), 120)
s := fmt.Sprintf("fake-%0.2f", randValue)
if faker.Rand.Intn(2) == 0 {
// plain string value
return FlexString{
Val: s,
Arr: []string{s},
}
}

// array case
s2 := fmt.Sprintf("fake-%0.2f-2", randValue)
s3 := fmt.Sprintf("fake-%0.2f-3", randValue)
arr := []string{s, s2, s3}
return FlexString{
Val: strings.Join(arr, ", "),
Arr: arr,
}
}

// FlexInt provides a container and unmarshalling for fields that may be
// numbers or strings in the Unifi API.
type FlexInt struct {
Expand Down
Loading