mirror of
https://github.com/SecurityBrewery/catalyst.git
synced 2025-12-06 07:12:46 +01:00
388 lines
11 KiB
Go
388 lines
11 KiB
Go
package fakedata
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/brianvoe/gofakeit/v7"
|
|
"github.com/pocketbase/pocketbase/core"
|
|
"github.com/pocketbase/pocketbase/daos"
|
|
"github.com/pocketbase/pocketbase/models"
|
|
"github.com/pocketbase/pocketbase/tools/security"
|
|
|
|
"github.com/SecurityBrewery/catalyst/migrations"
|
|
)
|
|
|
|
const (
|
|
minimumUserCount = 1
|
|
minimumTicketCount = 1
|
|
)
|
|
|
|
func Generate(app core.App, userCount, ticketCount int) error {
|
|
if userCount < minimumUserCount {
|
|
userCount = minimumUserCount
|
|
}
|
|
|
|
if ticketCount < minimumTicketCount {
|
|
ticketCount = minimumTicketCount
|
|
}
|
|
|
|
records, err := Records(app, userCount, ticketCount)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, record := range records {
|
|
if err := app.Dao().SaveRecord(record); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func Records(app core.App, userCount int, ticketCount int) ([]*models.Record, error) {
|
|
types, err := app.Dao().FindRecordsByExpr(migrations.TypeCollectionName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
users := userRecords(app.Dao(), userCount)
|
|
tickets := ticketRecords(app.Dao(), users, types, ticketCount)
|
|
reactions := reactionRecords(app.Dao())
|
|
|
|
var records []*models.Record
|
|
records = append(records, users...)
|
|
records = append(records, types...)
|
|
records = append(records, tickets...)
|
|
records = append(records, reactions...)
|
|
|
|
return records, nil
|
|
}
|
|
|
|
func userRecords(dao *daos.Dao, count int) []*models.Record {
|
|
collection, err := dao.FindCollectionByNameOrId(migrations.UserCollectionName)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
records := make([]*models.Record, 0, count)
|
|
|
|
// create the test user
|
|
if _, err := dao.FindRecordById(migrations.UserCollectionName, "u_test"); err != nil {
|
|
record := models.NewRecord(collection)
|
|
record.SetId("u_test")
|
|
_ = record.SetUsername("u_test")
|
|
_ = record.SetPassword("1234567890")
|
|
record.Set("name", gofakeit.Name())
|
|
record.Set("email", "user@catalyst-soar.com")
|
|
_ = record.SetVerified(true)
|
|
|
|
records = append(records, record)
|
|
}
|
|
|
|
for range count - 1 {
|
|
record := models.NewRecord(collection)
|
|
record.SetId("u_" + security.PseudorandomString(10))
|
|
_ = record.SetUsername("u_" + security.RandomStringWithAlphabet(5, "123456789"))
|
|
_ = record.SetPassword("1234567890")
|
|
record.Set("name", gofakeit.Name())
|
|
record.Set("email", gofakeit.Username()+"@catalyst-soar.com")
|
|
_ = record.SetVerified(true)
|
|
|
|
records = append(records, record)
|
|
}
|
|
|
|
return records
|
|
}
|
|
|
|
func ticketRecords(dao *daos.Dao, users, types []*models.Record, count int) []*models.Record {
|
|
collection, err := dao.FindCollectionByNameOrId(migrations.TicketCollectionName)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
records := make([]*models.Record, 0, count)
|
|
|
|
created := time.Now()
|
|
number := gofakeit.Number(200*count, 300*count)
|
|
|
|
for range count {
|
|
number -= gofakeit.Number(100, 200)
|
|
created = created.Add(time.Duration(-gofakeit.Number(13, 37)) * time.Hour)
|
|
|
|
record := models.NewRecord(collection)
|
|
record.SetId("t_" + security.PseudorandomString(10))
|
|
|
|
updated := gofakeit.DateRange(created, time.Now())
|
|
|
|
ticketType := random(types)
|
|
|
|
record.Set("created", created.Format("2006-01-02T15:04:05Z"))
|
|
record.Set("updated", updated.Format("2006-01-02T15:04:05Z"))
|
|
|
|
record.Set("name", fmt.Sprintf("%s-%d", strings.ToUpper(ticketType.GetString("singular")), number))
|
|
record.Set("type", ticketType.GetId())
|
|
record.Set("description", fakeTicketDescription())
|
|
record.Set("open", gofakeit.Bool())
|
|
record.Set("schema", `{"type":"object","properties":{"tlp":{"title":"TLP","type":"string"}}}`)
|
|
record.Set("state", `{"severity":"Medium"}`)
|
|
record.Set("owner", random(users).GetId())
|
|
|
|
records = append(records, record)
|
|
|
|
// Add comments
|
|
records = append(records, commentRecords(dao, users, created, record)...)
|
|
records = append(records, timelineRecords(dao, created, record)...)
|
|
records = append(records, taskRecords(dao, users, created, record)...)
|
|
records = append(records, linkRecords(dao, created, record)...)
|
|
}
|
|
|
|
return records
|
|
}
|
|
|
|
func commentRecords(dao *daos.Dao, users []*models.Record, created time.Time, record *models.Record) []*models.Record {
|
|
commentCollection, err := dao.FindCollectionByNameOrId(migrations.CommentCollectionName)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
records := make([]*models.Record, 0, 5)
|
|
|
|
for range gofakeit.IntN(5) {
|
|
commentCreated := gofakeit.DateRange(created, time.Now())
|
|
commentUpdated := gofakeit.DateRange(commentCreated, time.Now())
|
|
|
|
commentRecord := models.NewRecord(commentCollection)
|
|
commentRecord.SetId("c_" + security.PseudorandomString(10))
|
|
commentRecord.Set("created", commentCreated.Format("2006-01-02T15:04:05Z"))
|
|
commentRecord.Set("updated", commentUpdated.Format("2006-01-02T15:04:05Z"))
|
|
commentRecord.Set("ticket", record.GetId())
|
|
commentRecord.Set("author", random(users).GetId())
|
|
commentRecord.Set("message", fakeTicketComment())
|
|
|
|
records = append(records, commentRecord)
|
|
}
|
|
|
|
return records
|
|
}
|
|
|
|
func timelineRecords(dao *daos.Dao, created time.Time, record *models.Record) []*models.Record {
|
|
timelineCollection, err := dao.FindCollectionByNameOrId(migrations.TimelineCollectionName)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
records := make([]*models.Record, 0, 5)
|
|
|
|
for range gofakeit.IntN(5) {
|
|
timelineCreated := gofakeit.DateRange(created, time.Now())
|
|
timelineUpdated := gofakeit.DateRange(timelineCreated, time.Now())
|
|
|
|
timelineRecord := models.NewRecord(timelineCollection)
|
|
timelineRecord.SetId("tl_" + security.PseudorandomString(10))
|
|
timelineRecord.Set("created", timelineCreated.Format("2006-01-02T15:04:05Z"))
|
|
timelineRecord.Set("updated", timelineUpdated.Format("2006-01-02T15:04:05Z"))
|
|
timelineRecord.Set("ticket", record.GetId())
|
|
timelineRecord.Set("time", gofakeit.DateRange(created, time.Now()).Format("2006-01-02T15:04:05Z"))
|
|
timelineRecord.Set("message", fakeTicketTimelineMessage())
|
|
|
|
records = append(records, timelineRecord)
|
|
}
|
|
|
|
return records
|
|
}
|
|
|
|
func taskRecords(dao *daos.Dao, users []*models.Record, created time.Time, record *models.Record) []*models.Record {
|
|
taskCollection, err := dao.FindCollectionByNameOrId(migrations.TaskCollectionName)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
records := make([]*models.Record, 0, 5)
|
|
|
|
for range gofakeit.IntN(5) {
|
|
taskCreated := gofakeit.DateRange(created, time.Now())
|
|
taskUpdated := gofakeit.DateRange(taskCreated, time.Now())
|
|
|
|
taskRecord := models.NewRecord(taskCollection)
|
|
taskRecord.SetId("ts_" + security.PseudorandomString(10))
|
|
taskRecord.Set("created", taskCreated.Format("2006-01-02T15:04:05Z"))
|
|
taskRecord.Set("updated", taskUpdated.Format("2006-01-02T15:04:05Z"))
|
|
taskRecord.Set("ticket", record.GetId())
|
|
taskRecord.Set("name", fakeTicketTask())
|
|
taskRecord.Set("open", gofakeit.Bool())
|
|
taskRecord.Set("owner", random(users).GetId())
|
|
|
|
records = append(records, taskRecord)
|
|
}
|
|
|
|
return records
|
|
}
|
|
|
|
func linkRecords(dao *daos.Dao, created time.Time, record *models.Record) []*models.Record {
|
|
linkCollection, err := dao.FindCollectionByNameOrId(migrations.LinkCollectionName)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
records := make([]*models.Record, 0, 5)
|
|
|
|
for range gofakeit.IntN(5) {
|
|
linkCreated := gofakeit.DateRange(created, time.Now())
|
|
linkUpdated := gofakeit.DateRange(linkCreated, time.Now())
|
|
|
|
linkRecord := models.NewRecord(linkCollection)
|
|
linkRecord.SetId("l_" + security.PseudorandomString(10))
|
|
linkRecord.Set("created", linkCreated.Format("2006-01-02T15:04:05Z"))
|
|
linkRecord.Set("updated", linkUpdated.Format("2006-01-02T15:04:05Z"))
|
|
linkRecord.Set("ticket", record.GetId())
|
|
linkRecord.Set("url", gofakeit.URL())
|
|
linkRecord.Set("name", random([]string{"Blog", "Forum", "Wiki", "Documentation"}))
|
|
|
|
records = append(records, linkRecord)
|
|
}
|
|
|
|
return records
|
|
}
|
|
|
|
const createTicketPy = `import sys
|
|
import json
|
|
import random
|
|
import os
|
|
|
|
from pocketbase import PocketBase
|
|
|
|
# Connect to the PocketBase server
|
|
client = PocketBase(os.environ["CATALYST_APP_URL"])
|
|
client.auth_store.save(token=os.environ["CATALYST_TOKEN"])
|
|
|
|
newtickets = client.collection("tickets").get_list(1, 200, {"filter": 'name = "New Ticket"'})
|
|
for ticket in newtickets.items:
|
|
client.collection("tickets").delete(ticket.id)
|
|
|
|
# Create a new ticket
|
|
client.collection("tickets").create({
|
|
"name": "New Ticket",
|
|
"type": "alert",
|
|
"open": True,
|
|
})`
|
|
|
|
const alertIngestPy = `import sys
|
|
import json
|
|
import random
|
|
import os
|
|
|
|
from pocketbase import PocketBase
|
|
|
|
# Parse the event from the webhook payload
|
|
event = json.loads(sys.argv[1])
|
|
body = json.loads(event["body"])
|
|
|
|
# Connect to the PocketBase server
|
|
client = PocketBase(os.environ["CATALYST_APP_URL"])
|
|
client.auth_store.save(token=os.environ["CATALYST_TOKEN"])
|
|
|
|
# Create a new ticket
|
|
client.collection("tickets").create({
|
|
"name": body["name"],
|
|
"type": "alert",
|
|
"open": True,
|
|
})`
|
|
|
|
const assignTicketsPy = `import sys
|
|
import json
|
|
import random
|
|
import os
|
|
|
|
from pocketbase import PocketBase
|
|
|
|
# Parse the ticket from the input
|
|
ticket = json.loads(sys.argv[1])
|
|
|
|
# Connect to the PocketBase server
|
|
client = PocketBase(os.environ["CATALYST_APP_URL"])
|
|
client.auth_store.save(token=os.environ["CATALYST_TOKEN"])
|
|
|
|
# Get a random user
|
|
users = client.collection("users").get_list(1, 200)
|
|
random_user = random.choice(users.items)
|
|
|
|
# Assign the ticket to the random user
|
|
client.collection("tickets").update(ticket["record"]["id"], {
|
|
"owner": random_user.id,
|
|
})`
|
|
|
|
const (
|
|
triggerSchedule = `{"expression":"12 * * * *"}`
|
|
triggerWebhook = `{"token":"1234567890","path":"webhook"}`
|
|
triggerHook = `{"collections":["tickets"],"events":["create"]}`
|
|
)
|
|
|
|
func reactionRecords(dao *daos.Dao) []*models.Record {
|
|
var records []*models.Record
|
|
|
|
collection, err := dao.FindCollectionByNameOrId(migrations.ReactionCollectionName)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
createTicketActionData, err := json.Marshal(map[string]interface{}{
|
|
"requirements": "pocketbase",
|
|
"script": createTicketPy,
|
|
})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
record := models.NewRecord(collection)
|
|
record.SetId("w_" + security.PseudorandomString(10))
|
|
record.Set("name", "Create New Ticket")
|
|
record.Set("trigger", "schedule")
|
|
record.Set("triggerdata", triggerSchedule)
|
|
record.Set("action", "python")
|
|
record.Set("actiondata", string(createTicketActionData))
|
|
|
|
records = append(records, record)
|
|
|
|
alertIngestActionData, err := json.Marshal(map[string]interface{}{
|
|
"requirements": "pocketbase",
|
|
"script": alertIngestPy,
|
|
})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
record = models.NewRecord(collection)
|
|
record.SetId("w_" + security.PseudorandomString(10))
|
|
record.Set("name", "Alert Ingest Webhook")
|
|
record.Set("trigger", "webhook")
|
|
record.Set("triggerdata", triggerWebhook)
|
|
record.Set("action", "python")
|
|
record.Set("actiondata", string(alertIngestActionData))
|
|
|
|
records = append(records, record)
|
|
|
|
assignTicketsActionData, err := json.Marshal(map[string]interface{}{
|
|
"requirements": "pocketbase",
|
|
"script": assignTicketsPy,
|
|
})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
record = models.NewRecord(collection)
|
|
record.SetId("w_" + security.PseudorandomString(10))
|
|
record.Set("name", "Assign new Tickets")
|
|
record.Set("trigger", "hook")
|
|
record.Set("triggerdata", triggerHook)
|
|
record.Set("action", "python")
|
|
record.Set("actiondata", string(assignTicketsActionData))
|
|
|
|
records = append(records, record)
|
|
|
|
return records
|
|
}
|