mirror of
https://github.com/SecurityBrewery/catalyst.git
synced 2025-12-06 23:32:47 +01:00
Check input schema (#33)
This commit is contained in:
@@ -47,14 +47,12 @@ func (h *busService) handleJob(automationMsg *bus.JobMsg) {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := h.db.JobUpdate(ctx, automationMsg.ID, &model.Job{
|
||||
Automation: job.Automation,
|
||||
Container: &containerID,
|
||||
Origin: job.Origin,
|
||||
Output: job.Output,
|
||||
Log: &logs,
|
||||
Payload: job.Payload,
|
||||
Status: job.Status,
|
||||
if _, err := h.db.JobUpdate(ctx, automationMsg.ID, &model.JobUpdate{
|
||||
Container: &containerID,
|
||||
Running: true,
|
||||
Output: job.Output,
|
||||
Log: &logs,
|
||||
Status: job.Status,
|
||||
}); err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
|
||||
@@ -5,11 +5,9 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/xeipuuv/gojsonschema"
|
||||
|
||||
"github.com/SecurityBrewery/catalyst/bus"
|
||||
"github.com/SecurityBrewery/catalyst/caql"
|
||||
@@ -39,15 +37,19 @@ func (db *Database) toJobResponse(ctx context.Context, key string, doc *model.Jo
|
||||
if doc.Running {
|
||||
inspect, err := cli.ContainerInspect(ctx, key)
|
||||
if err != nil || inspect.State == nil {
|
||||
doc.Running = false
|
||||
if update {
|
||||
db.JobUpdate(ctx, key, doc)
|
||||
db.JobUpdate(ctx, key, &model.JobUpdate{
|
||||
Status: doc.Status,
|
||||
Running: false,
|
||||
})
|
||||
}
|
||||
} else if doc.Status != inspect.State.Status {
|
||||
status = inspect.State.Status
|
||||
doc.Status = inspect.State.Status
|
||||
if update {
|
||||
db.JobUpdate(ctx, key, doc)
|
||||
db.JobUpdate(ctx, key, &model.JobUpdate{
|
||||
Status: status,
|
||||
Running: doc.Running,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,25 +74,7 @@ func (db *Database) JobCreate(ctx context.Context, id string, job *model.JobForm
|
||||
var doc model.Job
|
||||
newctx := driver.WithReturnNew(ctx, &doc)
|
||||
|
||||
/* Start validation */
|
||||
j := toJob(job)
|
||||
b, _ := json.Marshal(j)
|
||||
|
||||
r, err := model.JobSchema.Validate(gojsonschema.NewBytesLoader(b))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !r.Valid() {
|
||||
var errs []string
|
||||
for _, e := range r.Errors() {
|
||||
errs = append(errs, e.String())
|
||||
}
|
||||
return nil, errors.New(strings.Join(errs, ", "))
|
||||
}
|
||||
/* End validation */
|
||||
|
||||
meta, err := db.jobCollection.CreateDocument(ctx, newctx, id, j)
|
||||
meta, err := db.jobCollection.CreateDocument(ctx, newctx, id, toJob(job))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -108,28 +92,11 @@ func (db *Database) JobGet(ctx context.Context, id string) (*model.JobResponse,
|
||||
return db.toJobResponse(ctx, meta.Key, &doc, true)
|
||||
}
|
||||
|
||||
func (db *Database) JobUpdate(ctx context.Context, id string, job *model.Job) (*model.JobResponse, error) {
|
||||
func (db *Database) JobUpdate(ctx context.Context, id string, job *model.JobUpdate) (*model.JobResponse, error) {
|
||||
var doc model.Job
|
||||
ctx = driver.WithReturnNew(ctx, &doc)
|
||||
|
||||
/* Start validation */
|
||||
b, _ := json.Marshal(job)
|
||||
|
||||
r, err := model.JobSchema.Validate(gojsonschema.NewBytesLoader(b))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !r.Valid() {
|
||||
var errs []string
|
||||
for _, e := range r.Errors() {
|
||||
errs = append(errs, e.String())
|
||||
}
|
||||
return nil, errors.New(strings.Join(errs, ", "))
|
||||
}
|
||||
/* End validation */
|
||||
|
||||
meta, err := db.jobCollection.ReplaceDocument(ctx, id, job)
|
||||
meta, err := db.jobCollection.UpdateDocument(ctx, id, job)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -113,18 +113,18 @@ func extractTicketResponse(ticket *model.TicketWithTickets) *model.TicketRespons
|
||||
}
|
||||
}
|
||||
|
||||
func (db *Database) TaskUpdate(ctx context.Context, id int64, playbookID string, taskID string, task *model.Task) (*model.TicketWithTickets, error) {
|
||||
func (db *Database) TaskUpdateOwner(ctx context.Context, id int64, playbookID string, taskID string, owner string) (*model.TicketWithTickets, error) {
|
||||
ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
task.Created = time.Now().UTC()
|
||||
|
||||
query := `LET d = DOCUMENT(@@collection, @ID)
|
||||
` + ticketFilterQuery + `
|
||||
LET playbook = d.playbooks[@playbookID]
|
||||
LET newtasks = MERGE(playbook.tasks, { @taskID: @task } )
|
||||
LET task = playbook.tasks[@taskID]
|
||||
LET newtask = MERGE(task, {"owner": @owner })
|
||||
LET newtasks = MERGE(playbook.tasks, { @taskID: newtask } )
|
||||
LET newplaybook = MERGE(playbook, {"tasks": newtasks})
|
||||
LET newplaybooks = MERGE(d.playbooks, { @playbookID: newplaybook } )
|
||||
|
||||
@@ -133,7 +133,42 @@ func (db *Database) TaskUpdate(ctx context.Context, id int64, playbookID string,
|
||||
ticket, err := db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{
|
||||
"playbookID": playbookID,
|
||||
"taskID": taskID,
|
||||
"task": task,
|
||||
"owner": owner,
|
||||
"now": time.Now().UTC(),
|
||||
}, ticketFilterVars), &busdb.Operation{
|
||||
Type: bus.DatabaseEntryUpdated,
|
||||
Ids: []driver.DocumentID{
|
||||
driver.NewDocumentID(TicketCollectionName, fmt.Sprintf("%d", id)),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ticket, nil
|
||||
}
|
||||
|
||||
func (db *Database) TaskUpdateData(ctx context.Context, id int64, playbookID string, taskID string, data map[string]interface{}) (*model.TicketWithTickets, error) {
|
||||
ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query := `LET d = DOCUMENT(@@collection, @ID)
|
||||
` + ticketFilterQuery + `
|
||||
LET playbook = d.playbooks[@playbookID]
|
||||
LET task = playbook.tasks[@taskID]
|
||||
LET newtask = MERGE(task, {"data": @data })
|
||||
LET newtasks = MERGE(playbook.tasks, { @taskID: newtask } )
|
||||
LET newplaybook = MERGE(playbook, {"tasks": newtasks})
|
||||
LET newplaybooks = MERGE(d.playbooks, { @playbookID: newplaybook } )
|
||||
|
||||
UPDATE d WITH { "modified": @now, "playbooks": newplaybooks } IN @@collection
|
||||
RETURN NEW`
|
||||
ticket, err := db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{
|
||||
"playbookID": playbookID,
|
||||
"taskID": taskID,
|
||||
"data": data,
|
||||
"now": time.Now().UTC(),
|
||||
}, ticketFilterVars), &busdb.Operation{
|
||||
Type: bus.DatabaseEntryUpdated,
|
||||
|
||||
@@ -191,6 +191,8 @@ func (db *Database) UserUpdate(ctx context.Context, id string, user *model.UserF
|
||||
|
||||
ctx = driver.WithReturnNew(ctx, &doc)
|
||||
|
||||
user.ID = id
|
||||
|
||||
meta, err := db.userCollection.ReplaceDocument(ctx, id, toUser(user, nil))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -48,7 +48,7 @@ paths:
|
||||
operationId: "updateJob"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Job ID", required: true, type: string, x-example: "99cd67131b48" }
|
||||
- { name: "job", in: "body", description: "Job object that needs to be added", required: true, schema: { $ref: "#/definitions/Job" }, x-example: { id: "99cd67131b48", automation: "hash.sha1", payload: "test", status: "failed" } }
|
||||
- { name: "job", in: "body", description: "Job object that needs to be added", required: true, schema: { $ref: "#/definitions/JobUpdate" }, x-example: { status: "failed", running: false } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
@@ -103,6 +103,16 @@ definitions:
|
||||
payload: { }
|
||||
origin: { $ref: "#/definitions/Origin" }
|
||||
|
||||
JobUpdate:
|
||||
type: object
|
||||
required: [ running, status ]
|
||||
properties:
|
||||
container: { type: string }
|
||||
running: { type: boolean }
|
||||
status: { type: string }
|
||||
log: { type: string }
|
||||
output: { type: object }
|
||||
|
||||
Job:
|
||||
type: object
|
||||
required: [ automation, running, status ]
|
||||
|
||||
@@ -16,31 +16,6 @@ paths:
|
||||
security: [ { roles: [ "ticket:read" ] } ]
|
||||
|
||||
definitions:
|
||||
TaskForm:
|
||||
type: object
|
||||
required: [ name, type ]
|
||||
properties:
|
||||
name: { type: string, example: "Inform user" }
|
||||
type: { type: string, enum: [ task, input, automation ], example: "task" }
|
||||
done: { type: boolean }
|
||||
|
||||
owner: { type: string }
|
||||
data: { type: object }
|
||||
|
||||
# automation
|
||||
automation: { type: string }
|
||||
payload: { type: object, additionalProperties: { type: string } }
|
||||
|
||||
# input
|
||||
schema: { type: object }
|
||||
|
||||
# workflow
|
||||
join: { type: boolean, example: false }
|
||||
next: { type: object, additionalProperties: { type: string } }
|
||||
|
||||
created: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" }
|
||||
closed: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" }
|
||||
|
||||
Task:
|
||||
type: object
|
||||
required: [ name, type, done, created ]
|
||||
|
||||
@@ -80,7 +80,7 @@ paths:
|
||||
summary: "Create a new tickets in batch"
|
||||
operationId: "createTicketBatch"
|
||||
parameters:
|
||||
- { name: "ticket", in: "body", description: "New ticket", required: true, schema: { type: array, items: { $ref: "#/definitions/TicketForm" } }, x-example: [ { id: 123, owner: bob, name: "Wannacry infection", status: "open", type: "incident" } ] }
|
||||
- { name: "ticket", in: "body", description: "New ticket", required: true, schema: { $ref: "#/definitions/TicketFormArray" }, x-example: [ { id: 123, owner: bob, name: "Wannacry infection", status: "open", type: "incident" } ] }
|
||||
responses:
|
||||
"204": { description: "successful operation" }
|
||||
security: [ { roles: [ "ticket:write" ] } ]
|
||||
@@ -336,7 +336,7 @@ paths:
|
||||
operationId: "setReferences"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8125 }
|
||||
- { name: "references", in: "body", description: "All ticket references", required: true, schema: { type: array, items: { $ref: "#/definitions/Reference" } }, x-example: [ { href: "http://www.leadscalable.biz/envisioneer", name: "fund" } ] }
|
||||
- { name: "references", in: "body", description: "All ticket references", required: true, schema: { $ref: "#/definitions/ReferenceArray" }, x-example: [ { href: "http://www.leadscalable.biz/envisioneer", name: "fund" } ] }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
@@ -583,13 +583,13 @@ paths:
|
||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}:
|
||||
put:
|
||||
tags: [ "tickets" ]
|
||||
summary: "Set a ticket playbook task"
|
||||
operationId: "setTask"
|
||||
summary: "Set a ticket playbook task data"
|
||||
operationId: "setTaskData"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8123 }
|
||||
- { name: "playbookID", in: "path", description: "Playbook ID", required: true, type: string, x-example: "phishing" }
|
||||
- { name: "taskID", in: "path", description: "Task ID", required: true, type: string, x-example: "board" }
|
||||
- { name: "task", in: "body", description: "Task", required: true, schema: { $ref: "#/definitions/Task" }, x-example: { done: false, "active": true, "order": 0, name: "Board Involvement?","next": { "escalate": "boardInvolved == true","mail-available": "boardInvolved == false" },"schema": { "properties": { "boardInvolved": { "default": false, "title": "A board member is involved.", type: "boolean" } }, "required": [ "boardInvolved" ], "title": "Board Involvement?", type: "object" }, type: "input", data: { boardInvolved: true } } }
|
||||
- { name: "data", in: "body", description: "Task data", required: true, schema: { type: object }, x-example: { boardInvolved: true } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
@@ -625,6 +625,51 @@ paths:
|
||||
- { name: "leadreintermediate.io", status: "malicious" }
|
||||
security: [ { roles: [ "ticket:write" ] } ]
|
||||
|
||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}/owner:
|
||||
put:
|
||||
tags: [ "tickets" ]
|
||||
summary: "Set a ticket playbook task owner"
|
||||
operationId: "setTaskOwner"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8123 }
|
||||
- { name: "playbookID", in: "path", description: "Playbook ID", required: true, type: string, x-example: "phishing" }
|
||||
- { name: "taskID", in: "path", description: "Task ID", required: true, type: string, x-example: "board" }
|
||||
- { name: "owner", in: "body", description: "Task owner", required: true, schema: { type: string }, x-example: "eve" }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/TicketWithTickets" }
|
||||
examples:
|
||||
test:
|
||||
id: 8123
|
||||
created: "2021-10-02T16:04:59.078206Z"
|
||||
modified: "2021-12-12T12:12:12.000000012Z"
|
||||
name: "live zebra"
|
||||
owner: "demo"
|
||||
playbooks:
|
||||
phishing:
|
||||
name: "Phishing"
|
||||
tasks:
|
||||
"block-iocs": { created: "2021-12-12T12:12:12.000000012Z", done: false, "active": false, "order": 6, name: "Block IOCs", type: "task" }
|
||||
"block-sender": { created: "2021-12-12T12:12:12.000000012Z", done: false, "active": false, "order": 3, name: "Block sender","next": { "extract-iocs": "" }, type: "task" }
|
||||
"board": { created: "2021-12-12T12:12:12.000000012Z", done: false, "active": true, "order": 0, name: "Board Involvement?","next": { "escalate": "boardInvolved == true","mail-available": "boardInvolved == false" },"schema": { "properties": { "boardInvolved": { "default": false, "title": "A board member is involved.", type: "boolean" } }, "required": [ "boardInvolved" ], "title": "Board Involvement?", type: "object" }, type: "input", owner: "eve" }
|
||||
"escalate": { created: "2021-12-12T12:12:12.000000012Z", done: false, "active": false, "order": 1, name: "Escalate to CISO", type: "task" }
|
||||
"extract-iocs": { created: "2021-12-12T12:12:12.000000012Z", done: false, "active": false, "order": 5, name: "Extract IOCs", "next": { "block-iocs": "" },"schema": { "properties": { "iocs": { "items": { type: "string" },"title": "IOCs", type: "array" } }, "title": "Extract IOCs", type: "object" }, type: "input" }
|
||||
"mail-available": { created: "2021-12-12T12:12:12.000000012Z", done: false, "active": false, "order": 2, name: "Mail available","next": { "block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'" },"schema": { "oneOf": [ { "properties": { "mail": { "title": "Mail", type: "string", "x-display": "textarea" }, "schemaKey": { "const": "yes", type: "string" } },"required": [ "mail" ], "title": "Yes" },{ "properties": { "schemaKey": { "const": "no", type: "string" } },"title": "No" } ],"title": "Mail available", type: "object" }, type: "input" }
|
||||
"search-email-gateway": { created: "2021-12-12T12:12:12.000000012Z", done: false, "active": false, "order": 4, name: "Search email gateway","next": { "extract-iocs": "" }, type: "task" }
|
||||
references:
|
||||
- { href: "https://www.leadmaximize.net/e-services/back-end", name: "performance" }
|
||||
- { href: "http://www.corporateinteractive.name/rich", name: "autumn" }
|
||||
- { href: "https://www.corporateintuitive.org/intuitive/platforms/integrate", name: "suggest" }
|
||||
"schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n"
|
||||
status: "closed"
|
||||
type: "incident"
|
||||
artifacts:
|
||||
- { name: "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", status: "unknown" }
|
||||
- { name: "http://www.customerviral.io/scalable/vertical/killer", status: "clean" }
|
||||
- { name: "leadreintermediate.io", status: "malicious" }
|
||||
security: [ { roles: [ "ticket:write" ] } ]
|
||||
|
||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete:
|
||||
put:
|
||||
tags: [ "tickets" ]
|
||||
@@ -883,6 +928,9 @@ paths:
|
||||
security: [ { roles: [ "ticket:write" ] } ]
|
||||
|
||||
definitions:
|
||||
TicketFormArray:
|
||||
type: array
|
||||
items: { $ref: "#/definitions/TicketForm" }
|
||||
|
||||
TicketForm:
|
||||
type: object
|
||||
@@ -1035,6 +1083,10 @@ definitions:
|
||||
created: { type: string, format: "date-time" }
|
||||
message: { type: string }
|
||||
|
||||
ReferenceArray:
|
||||
type: array
|
||||
items: { $ref: '#/definitions/Reference' }
|
||||
|
||||
Reference:
|
||||
type: object
|
||||
required: [ name, href ]
|
||||
|
||||
@@ -34,7 +34,7 @@ paths:
|
||||
summary: "Create user"
|
||||
operationId: "createUser"
|
||||
parameters:
|
||||
- { name: "user", in: "body", description: "user object that needs to be added", required: true, schema: { $ref: "#/definitions/UserForm" }, x-example: { id: "syncscript", roles: [ "analyst" ] } }
|
||||
- { name: "user", in: "body", description: "user object that needs to be added", required: true, schema: { $ref: "#/definitions/UserForm" }, x-example: { id: "syncscript", roles: [ "analyst" ], blocked: false, apikey: true } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
@@ -62,7 +62,7 @@ paths:
|
||||
operationId: "updateUser"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Template ID", required: true, type: string, x-example: "bob" }
|
||||
- { name: "user", in: "body", description: "user object that needs to be added", required: true, schema: { $ref: "#/definitions/UserForm" }, x-example: { roles: [ "analyst", "admin" ] } }
|
||||
- { name: "user", in: "body", description: "user object that needs to be added", required: true, schema: { $ref: "#/definitions/UserForm" }, x-example: { id: "syncscript", roles: [ "analyst", "admin" ], blocked: false, apikey: false } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
version: '2.2'
|
||||
version: '2.4'
|
||||
services:
|
||||
nginx:
|
||||
image: nginx:1.21
|
||||
@@ -38,6 +38,7 @@ services:
|
||||
|
||||
keycloak:
|
||||
image: quay.io/keycloak/keycloak:14.0.0
|
||||
platform: linux/amd64
|
||||
environment:
|
||||
DB_VENDOR: POSTGRES
|
||||
DB_ADDR: postgres
|
||||
|
||||
@@ -18,12 +18,8 @@ mv generated/openapi.json generated/community.json
|
||||
openapi-generator generate -i generated/catalyst.yml -o generated -g openapi
|
||||
mv generated/openapi.json generated/catalyst.json
|
||||
|
||||
# generate python client
|
||||
# openapi-generator generate -i generated/community.yml -o generated/python -g python --package-name catalystpy --ignore-file-override .openapi-generator-ignore
|
||||
|
||||
echo generate server and tests
|
||||
# go run ./generator/. ./generator
|
||||
swachigo generated/community.yml generated
|
||||
swagger-go-chi generated/community.yml generated
|
||||
|
||||
echo generate typescript client
|
||||
openapi-generator generate -i generated/catalyst.yml -o ui/src/client -g typescript-axios --artifact-version 1.0.0-SNAPSHOT
|
||||
@@ -31,8 +27,7 @@ openapi-generator generate -i generated/catalyst.yml -o ui/src/client -g typescr
|
||||
rm -rf gen
|
||||
rm -rf generated/models/old
|
||||
rm -rf generated/.openapi-generator generated/.openapi-generator-ignore generated/README.md
|
||||
# rm -rf generated/python/.openapi-generator generated/python/.gitlab-ci.yml generated/python/git_push.sh generated/python/.travis.yml generated/python/.gitignore generated/python/.openapi-generator-ignore
|
||||
rm -rf ui/src/client/.openapi-generator ui/src/client/git_push.sh ui/src/client/.gitignore ui/src/client/.openapi-generator-ignore
|
||||
|
||||
go mod tidy
|
||||
gci -w -local "github.com/SecurityBrewery/catalyst" .
|
||||
gci write --Section Standard --Section Default --Section "Prefix(github.com/SecurityBrewery/catalyst)" .
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
// Code generated from CAQLLexer.g4 by ANTLR 4.9.2. DO NOT EDIT.
|
||||
// Code generated from CAQLLexer.g4 by ANTLR 4.9.3. DO NOT EDIT.
|
||||
|
||||
package parser
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated from CAQLParser.g4 by ANTLR 4.9.2. DO NOT EDIT.
|
||||
// Code generated from CAQLParser.g4 by ANTLR 4.9.3. DO NOT EDIT.
|
||||
|
||||
package parser // CAQLParser
|
||||
|
||||
@@ -332,6 +332,9 @@ func (s *ParseContext) ExitRule(listener antlr.ParseTreeListener) {
|
||||
}
|
||||
|
||||
func (p *CAQLParser) Parse() (localctx IParseContext) {
|
||||
this := p
|
||||
_ = this
|
||||
|
||||
localctx = NewParseContext(p, p.GetParserRuleContext(), p.GetState())
|
||||
p.EnterRule(localctx, 0, CAQLParserRULE_parse)
|
||||
|
||||
@@ -587,6 +590,9 @@ func (p *CAQLParser) Expression() (localctx IExpressionContext) {
|
||||
}
|
||||
|
||||
func (p *CAQLParser) expression(_p int) (localctx IExpressionContext) {
|
||||
this := p
|
||||
_ = this
|
||||
|
||||
var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext()
|
||||
_parentState := p.GetState()
|
||||
localctx = NewExpressionContext(p, p.GetParserRuleContext(), _parentState)
|
||||
@@ -1076,6 +1082,9 @@ func (s *Operator_unaryContext) ExitRule(listener antlr.ParseTreeListener) {
|
||||
}
|
||||
|
||||
func (p *CAQLParser) Operator_unary() (localctx IOperator_unaryContext) {
|
||||
this := p
|
||||
_ = this
|
||||
|
||||
localctx = NewOperator_unaryContext(p, p.GetParserRuleContext(), p.GetState())
|
||||
p.EnterRule(localctx, 4, CAQLParserRULE_operator_unary)
|
||||
|
||||
@@ -1264,6 +1273,9 @@ func (p *CAQLParser) Reference() (localctx IReferenceContext) {
|
||||
}
|
||||
|
||||
func (p *CAQLParser) reference(_p int) (localctx IReferenceContext) {
|
||||
this := p
|
||||
_ = this
|
||||
|
||||
var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext()
|
||||
_parentState := p.GetState()
|
||||
localctx = NewReferenceContext(p, p.GetParserRuleContext(), _parentState)
|
||||
@@ -1469,6 +1481,9 @@ func (s *Compound_valueContext) ExitRule(listener antlr.ParseTreeListener) {
|
||||
}
|
||||
|
||||
func (p *CAQLParser) Compound_value() (localctx ICompound_valueContext) {
|
||||
this := p
|
||||
_ = this
|
||||
|
||||
localctx = NewCompound_valueContext(p, p.GetParserRuleContext(), p.GetState())
|
||||
p.EnterRule(localctx, 8, CAQLParserRULE_compound_value)
|
||||
|
||||
@@ -1614,6 +1629,9 @@ func (s *Function_callContext) ExitRule(listener antlr.ParseTreeListener) {
|
||||
}
|
||||
|
||||
func (p *CAQLParser) Function_call() (localctx IFunction_callContext) {
|
||||
this := p
|
||||
_ = this
|
||||
|
||||
localctx = NewFunction_callContext(p, p.GetParserRuleContext(), p.GetState())
|
||||
p.EnterRule(localctx, 10, CAQLParserRULE_function_call)
|
||||
var _la int
|
||||
@@ -1778,6 +1796,9 @@ func (s *Value_literalContext) ExitRule(listener antlr.ParseTreeListener) {
|
||||
}
|
||||
|
||||
func (p *CAQLParser) Value_literal() (localctx IValue_literalContext) {
|
||||
this := p
|
||||
_ = this
|
||||
|
||||
localctx = NewValue_literalContext(p, p.GetParserRuleContext(), p.GetState())
|
||||
p.EnterRule(localctx, 12, CAQLParserRULE_value_literal)
|
||||
var _la int
|
||||
@@ -1912,6 +1933,9 @@ func (s *ArrayContext) ExitRule(listener antlr.ParseTreeListener) {
|
||||
}
|
||||
|
||||
func (p *CAQLParser) Array() (localctx IArrayContext) {
|
||||
this := p
|
||||
_ = this
|
||||
|
||||
localctx = NewArrayContext(p, p.GetParserRuleContext(), p.GetState())
|
||||
p.EnterRule(localctx, 14, CAQLParserRULE_array)
|
||||
var _la int
|
||||
@@ -2087,6 +2111,9 @@ func (s *ObjectContext) ExitRule(listener antlr.ParseTreeListener) {
|
||||
}
|
||||
|
||||
func (p *CAQLParser) Object() (localctx IObjectContext) {
|
||||
this := p
|
||||
_ = this
|
||||
|
||||
localctx = NewObjectContext(p, p.GetParserRuleContext(), p.GetState())
|
||||
p.EnterRule(localctx, 16, CAQLParserRULE_object)
|
||||
var _la int
|
||||
@@ -2272,6 +2299,9 @@ func (s *Object_elementContext) ExitRule(listener antlr.ParseTreeListener) {
|
||||
}
|
||||
|
||||
func (p *CAQLParser) Object_element() (localctx IObject_elementContext) {
|
||||
this := p
|
||||
_ = this
|
||||
|
||||
localctx = NewObject_elementContext(p, p.GetParserRuleContext(), p.GetState())
|
||||
p.EnterRule(localctx, 18, CAQLParserRULE_object_element)
|
||||
|
||||
@@ -2409,6 +2439,9 @@ func (s *Object_element_nameContext) ExitRule(listener antlr.ParseTreeListener)
|
||||
}
|
||||
|
||||
func (p *CAQLParser) Object_element_name() (localctx IObject_element_nameContext) {
|
||||
this := p
|
||||
_ = this
|
||||
|
||||
localctx = NewObject_element_nameContext(p, p.GetParserRuleContext(), p.GetState())
|
||||
p.EnterRule(localctx, 20, CAQLParserRULE_object_element_name)
|
||||
var _la int
|
||||
@@ -2467,6 +2500,9 @@ func (p *CAQLParser) Sempred(localctx antlr.RuleContext, ruleIndex, predIndex in
|
||||
}
|
||||
|
||||
func (p *CAQLParser) Expression_Sempred(localctx antlr.RuleContext, predIndex int) bool {
|
||||
this := p
|
||||
_ = this
|
||||
|
||||
switch predIndex {
|
||||
case 0:
|
||||
return p.Precpred(p.GetParserRuleContext(), 13)
|
||||
@@ -2513,6 +2549,9 @@ func (p *CAQLParser) Expression_Sempred(localctx antlr.RuleContext, predIndex in
|
||||
}
|
||||
|
||||
func (p *CAQLParser) Reference_Sempred(localctx antlr.RuleContext, predIndex int) bool {
|
||||
this := p
|
||||
_ = this
|
||||
|
||||
switch predIndex {
|
||||
case 13:
|
||||
return p.Precpred(p.GetParserRuleContext(), 2)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated from CAQLParser.g4 by ANTLR 4.9.2. DO NOT EDIT.
|
||||
// Code generated from CAQLParser.g4 by ANTLR 4.9.3. DO NOT EDIT.
|
||||
|
||||
package parser // CAQLParser
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated from CAQLParser.g4 by ANTLR 4.9.2. DO NOT EDIT.
|
||||
// Code generated from CAQLParser.g4 by ANTLR 4.9.3. DO NOT EDIT.
|
||||
|
||||
package parser // CAQLParser
|
||||
|
||||
|
||||
@@ -659,7 +659,7 @@
|
||||
"content" : {
|
||||
"application/json" : {
|
||||
"schema" : {
|
||||
"$ref" : "#/components/schemas/Job"
|
||||
"$ref" : "#/components/schemas/JobUpdate"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3404,7 +3404,7 @@
|
||||
},
|
||||
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}" : {
|
||||
"put" : {
|
||||
"operationId" : "setTask",
|
||||
"operationId" : "setTaskData",
|
||||
"parameters" : [ {
|
||||
"description" : "Ticket ID",
|
||||
"example" : 8123,
|
||||
@@ -3438,11 +3438,11 @@
|
||||
"content" : {
|
||||
"application/json" : {
|
||||
"schema" : {
|
||||
"$ref" : "#/components/schemas/Task"
|
||||
"type" : "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description" : "Task",
|
||||
"description" : "Task data",
|
||||
"required" : true
|
||||
},
|
||||
"responses" : {
|
||||
@@ -3628,9 +3628,9 @@
|
||||
"security" : [ {
|
||||
"roles" : [ "ticket:write" ]
|
||||
} ],
|
||||
"summary" : "Set a ticket playbook task",
|
||||
"summary" : "Set a ticket playbook task data",
|
||||
"tags" : [ "tickets" ],
|
||||
"x-codegen-request-body-name" : "task"
|
||||
"x-codegen-request-body-name" : "data"
|
||||
}
|
||||
},
|
||||
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete" : {
|
||||
@@ -3865,6 +3865,235 @@
|
||||
"x-codegen-request-body-name" : "data"
|
||||
}
|
||||
},
|
||||
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}/owner" : {
|
||||
"put" : {
|
||||
"operationId" : "setTaskOwner",
|
||||
"parameters" : [ {
|
||||
"description" : "Ticket ID",
|
||||
"example" : 8123,
|
||||
"in" : "path",
|
||||
"name" : "id",
|
||||
"required" : true,
|
||||
"schema" : {
|
||||
"format" : "int64",
|
||||
"type" : "integer"
|
||||
}
|
||||
}, {
|
||||
"description" : "Playbook ID",
|
||||
"example" : "phishing",
|
||||
"in" : "path",
|
||||
"name" : "playbookID",
|
||||
"required" : true,
|
||||
"schema" : {
|
||||
"type" : "string"
|
||||
}
|
||||
}, {
|
||||
"description" : "Task ID",
|
||||
"example" : "board",
|
||||
"in" : "path",
|
||||
"name" : "taskID",
|
||||
"required" : true,
|
||||
"schema" : {
|
||||
"type" : "string"
|
||||
}
|
||||
} ],
|
||||
"requestBody" : {
|
||||
"content" : {
|
||||
"application/json" : {
|
||||
"schema" : {
|
||||
"type" : "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description" : "Task owner",
|
||||
"required" : true
|
||||
},
|
||||
"responses" : {
|
||||
"200" : {
|
||||
"content" : {
|
||||
"application/json" : {
|
||||
"schema" : {
|
||||
"$ref" : "#/components/schemas/TicketWithTickets"
|
||||
}
|
||||
},
|
||||
"test" : {
|
||||
"example" : {
|
||||
"artifacts" : [ {
|
||||
"name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a",
|
||||
"status" : "unknown"
|
||||
}, {
|
||||
"name" : "http://www.customerviral.io/scalable/vertical/killer",
|
||||
"status" : "clean"
|
||||
}, {
|
||||
"name" : "leadreintermediate.io",
|
||||
"status" : "malicious"
|
||||
} ],
|
||||
"created" : "2021-10-02T16:04:59.078+0000",
|
||||
"id" : 8123,
|
||||
"modified" : "2021-12-12T12:12:12.000+0000",
|
||||
"name" : "live zebra",
|
||||
"owner" : "demo",
|
||||
"playbooks" : {
|
||||
"phishing" : {
|
||||
"name" : "Phishing",
|
||||
"tasks" : {
|
||||
"block-iocs" : {
|
||||
"active" : false,
|
||||
"created" : "2021-12-12T12:12:12.000+0000",
|
||||
"done" : false,
|
||||
"name" : "Block IOCs",
|
||||
"order" : 6,
|
||||
"type" : "task"
|
||||
},
|
||||
"block-sender" : {
|
||||
"active" : false,
|
||||
"created" : "2021-12-12T12:12:12.000+0000",
|
||||
"done" : false,
|
||||
"name" : "Block sender",
|
||||
"next" : {
|
||||
"extract-iocs" : ""
|
||||
},
|
||||
"order" : 3,
|
||||
"type" : "task"
|
||||
},
|
||||
"board" : {
|
||||
"active" : true,
|
||||
"created" : "2021-12-12T12:12:12.000+0000",
|
||||
"done" : false,
|
||||
"name" : "Board Involvement?",
|
||||
"next" : {
|
||||
"escalate" : "boardInvolved == true",
|
||||
"mail-available" : "boardInvolved == false"
|
||||
},
|
||||
"order" : 0,
|
||||
"owner" : "eve",
|
||||
"schema" : {
|
||||
"properties" : {
|
||||
"boardInvolved" : {
|
||||
"default" : false,
|
||||
"title" : "A board member is involved.",
|
||||
"type" : "boolean"
|
||||
}
|
||||
},
|
||||
"required" : [ "boardInvolved" ],
|
||||
"title" : "Board Involvement?",
|
||||
"type" : "object"
|
||||
},
|
||||
"type" : "input"
|
||||
},
|
||||
"escalate" : {
|
||||
"active" : false,
|
||||
"created" : "2021-12-12T12:12:12.000+0000",
|
||||
"done" : false,
|
||||
"name" : "Escalate to CISO",
|
||||
"order" : 1,
|
||||
"type" : "task"
|
||||
},
|
||||
"extract-iocs" : {
|
||||
"active" : false,
|
||||
"created" : "2021-12-12T12:12:12.000+0000",
|
||||
"done" : false,
|
||||
"name" : "Extract IOCs",
|
||||
"next" : {
|
||||
"block-iocs" : ""
|
||||
},
|
||||
"order" : 5,
|
||||
"schema" : {
|
||||
"properties" : {
|
||||
"iocs" : {
|
||||
"items" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"title" : "IOCs",
|
||||
"type" : "array"
|
||||
}
|
||||
},
|
||||
"title" : "Extract IOCs",
|
||||
"type" : "object"
|
||||
},
|
||||
"type" : "input"
|
||||
},
|
||||
"mail-available" : {
|
||||
"active" : false,
|
||||
"created" : "2021-12-12T12:12:12.000+0000",
|
||||
"done" : false,
|
||||
"name" : "Mail available",
|
||||
"next" : {
|
||||
"block-sender" : "schemaKey == 'yes'",
|
||||
"extract-iocs" : "schemaKey == 'yes'",
|
||||
"search-email-gateway" : "schemaKey == 'no'"
|
||||
},
|
||||
"order" : 2,
|
||||
"schema" : {
|
||||
"oneOf" : [ {
|
||||
"properties" : {
|
||||
"mail" : {
|
||||
"title" : "Mail",
|
||||
"type" : "string",
|
||||
"x-display" : "textarea"
|
||||
},
|
||||
"schemaKey" : {
|
||||
"const" : "yes",
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
"required" : [ "mail" ],
|
||||
"title" : "Yes"
|
||||
}, {
|
||||
"properties" : {
|
||||
"schemaKey" : {
|
||||
"const" : "no",
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
"title" : "No"
|
||||
} ],
|
||||
"title" : "Mail available",
|
||||
"type" : "object"
|
||||
},
|
||||
"type" : "input"
|
||||
},
|
||||
"search-email-gateway" : {
|
||||
"active" : false,
|
||||
"created" : "2021-12-12T12:12:12.000+0000",
|
||||
"done" : false,
|
||||
"name" : "Search email gateway",
|
||||
"next" : {
|
||||
"extract-iocs" : ""
|
||||
},
|
||||
"order" : 4,
|
||||
"type" : "task"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"references" : [ {
|
||||
"href" : "https://www.leadmaximize.net/e-services/back-end",
|
||||
"name" : "performance"
|
||||
}, {
|
||||
"href" : "http://www.corporateinteractive.name/rich",
|
||||
"name" : "autumn"
|
||||
}, {
|
||||
"href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate",
|
||||
"name" : "suggest"
|
||||
} ],
|
||||
"schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n",
|
||||
"status" : "closed",
|
||||
"type" : "incident"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description" : "successful operation"
|
||||
}
|
||||
},
|
||||
"security" : [ {
|
||||
"roles" : [ "ticket:write" ]
|
||||
} ],
|
||||
"summary" : "Set a ticket playbook task owner",
|
||||
"tags" : [ "tickets" ],
|
||||
"x-codegen-request-body-name" : "owner"
|
||||
}
|
||||
},
|
||||
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}/run" : {
|
||||
"post" : {
|
||||
"operationId" : "runTask",
|
||||
@@ -3928,10 +4157,7 @@
|
||||
"content" : {
|
||||
"application/json" : {
|
||||
"schema" : {
|
||||
"items" : {
|
||||
"$ref" : "#/components/schemas/Reference"
|
||||
},
|
||||
"type" : "array"
|
||||
"$ref" : "#/components/schemas/ReferenceArray"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4390,10 +4616,7 @@
|
||||
"content" : {
|
||||
"application/json" : {
|
||||
"schema" : {
|
||||
"items" : {
|
||||
"$ref" : "#/components/schemas/TicketForm"
|
||||
},
|
||||
"type" : "array"
|
||||
"$ref" : "#/components/schemas/TicketFormArray"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -5295,6 +5518,28 @@
|
||||
"required" : [ "automation", "id", "status" ],
|
||||
"type" : "object"
|
||||
},
|
||||
"JobUpdate" : {
|
||||
"properties" : {
|
||||
"container" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"log" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"output" : {
|
||||
"properties" : { },
|
||||
"type" : "object"
|
||||
},
|
||||
"running" : {
|
||||
"type" : "boolean"
|
||||
},
|
||||
"status" : {
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
"required" : [ "running", "status" ],
|
||||
"type" : "object"
|
||||
},
|
||||
"Link" : {
|
||||
"properties" : {
|
||||
"id" : {
|
||||
@@ -5478,6 +5723,12 @@
|
||||
"required" : [ "href", "name" ],
|
||||
"type" : "object"
|
||||
},
|
||||
"ReferenceArray" : {
|
||||
"items" : {
|
||||
"$ref" : "#/components/schemas/Reference"
|
||||
},
|
||||
"type" : "array"
|
||||
},
|
||||
"Rule" : {
|
||||
"properties" : {
|
||||
"condition" : {
|
||||
@@ -5655,62 +5906,6 @@
|
||||
"required" : [ "created", "done", "name", "type" ],
|
||||
"type" : "object"
|
||||
},
|
||||
"TaskForm" : {
|
||||
"properties" : {
|
||||
"automation" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"closed" : {
|
||||
"format" : "date-time",
|
||||
"type" : "string"
|
||||
},
|
||||
"created" : {
|
||||
"format" : "date-time",
|
||||
"type" : "string"
|
||||
},
|
||||
"data" : {
|
||||
"properties" : { },
|
||||
"type" : "object"
|
||||
},
|
||||
"done" : {
|
||||
"type" : "boolean"
|
||||
},
|
||||
"join" : {
|
||||
"example" : false,
|
||||
"type" : "boolean"
|
||||
},
|
||||
"name" : {
|
||||
"example" : "Inform user",
|
||||
"type" : "string"
|
||||
},
|
||||
"next" : {
|
||||
"additionalProperties" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"type" : "object"
|
||||
},
|
||||
"owner" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"payload" : {
|
||||
"additionalProperties" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"type" : "object"
|
||||
},
|
||||
"schema" : {
|
||||
"properties" : { },
|
||||
"type" : "object"
|
||||
},
|
||||
"type" : {
|
||||
"enum" : [ "task", "input", "automation" ],
|
||||
"example" : "task",
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
"required" : [ "name", "type" ],
|
||||
"type" : "object"
|
||||
},
|
||||
"TaskOrigin" : {
|
||||
"properties" : {
|
||||
"playbook_id" : {
|
||||
@@ -5992,6 +6187,12 @@
|
||||
"required" : [ "name", "status", "type" ],
|
||||
"type" : "object"
|
||||
},
|
||||
"TicketFormArray" : {
|
||||
"items" : {
|
||||
"$ref" : "#/components/schemas/TicketForm"
|
||||
},
|
||||
"type" : "array"
|
||||
},
|
||||
"TicketList" : {
|
||||
"properties" : {
|
||||
"count" : {
|
||||
|
||||
@@ -288,6 +288,22 @@ definitions:
|
||||
- automation
|
||||
- status
|
||||
type: object
|
||||
JobUpdate:
|
||||
properties:
|
||||
container:
|
||||
type: string
|
||||
log:
|
||||
type: string
|
||||
output:
|
||||
type: object
|
||||
running:
|
||||
type: boolean
|
||||
status:
|
||||
type: string
|
||||
required:
|
||||
- running
|
||||
- status
|
||||
type: object
|
||||
Link:
|
||||
properties:
|
||||
id:
|
||||
@@ -435,6 +451,10 @@ definitions:
|
||||
- name
|
||||
- href
|
||||
type: object
|
||||
ReferenceArray:
|
||||
items:
|
||||
$ref: '#/definitions/Reference'
|
||||
type: array
|
||||
Rule:
|
||||
properties:
|
||||
condition:
|
||||
@@ -584,51 +604,6 @@ definitions:
|
||||
- done
|
||||
- created
|
||||
type: object
|
||||
TaskForm:
|
||||
properties:
|
||||
automation:
|
||||
type: string
|
||||
closed:
|
||||
example: 1985-04-12T23:20:50.52Z
|
||||
format: date-time
|
||||
type: string
|
||||
created:
|
||||
example: 1985-04-12T23:20:50.52Z
|
||||
format: date-time
|
||||
type: string
|
||||
data:
|
||||
type: object
|
||||
done:
|
||||
type: boolean
|
||||
join:
|
||||
example: false
|
||||
type: boolean
|
||||
name:
|
||||
example: Inform user
|
||||
type: string
|
||||
next:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
owner:
|
||||
type: string
|
||||
payload:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
schema:
|
||||
type: object
|
||||
type:
|
||||
enum:
|
||||
- task
|
||||
- input
|
||||
- automation
|
||||
example: task
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
TaskOrigin:
|
||||
properties:
|
||||
playbook_id:
|
||||
@@ -861,6 +836,10 @@ definitions:
|
||||
- type
|
||||
- status
|
||||
type: object
|
||||
TicketFormArray:
|
||||
items:
|
||||
$ref: '#/definitions/TicketForm'
|
||||
type: array
|
||||
TicketList:
|
||||
properties:
|
||||
count:
|
||||
@@ -1899,11 +1878,9 @@ paths:
|
||||
name: job
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/Job'
|
||||
$ref: '#/definitions/JobUpdate'
|
||||
x-example:
|
||||
automation: hash.sha1
|
||||
id: 99cd67131b48
|
||||
payload: test
|
||||
running: false
|
||||
status: failed
|
||||
responses:
|
||||
"200":
|
||||
@@ -5465,7 +5442,7 @@ paths:
|
||||
- tickets
|
||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}:
|
||||
put:
|
||||
operationId: setTask
|
||||
operationId: setTaskData
|
||||
parameters:
|
||||
- description: Ticket ID
|
||||
format: int64
|
||||
@@ -5486,33 +5463,14 @@ paths:
|
||||
required: true
|
||||
type: string
|
||||
x-example: board
|
||||
- description: Task
|
||||
- description: Task data
|
||||
in: body
|
||||
name: task
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/Task'
|
||||
type: object
|
||||
x-example:
|
||||
active: true
|
||||
data:
|
||||
boardInvolved: true
|
||||
done: false
|
||||
name: Board Involvement?
|
||||
next:
|
||||
escalate: boardInvolved == true
|
||||
mail-available: boardInvolved == false
|
||||
order: 0
|
||||
schema:
|
||||
properties:
|
||||
boardInvolved:
|
||||
default: false
|
||||
title: A board member is involved.
|
||||
type: boolean
|
||||
required:
|
||||
- boardInvolved
|
||||
title: Board Involvement?
|
||||
type: object
|
||||
type: input
|
||||
boardInvolved: true
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
@@ -5742,7 +5700,7 @@ paths:
|
||||
security:
|
||||
- roles:
|
||||
- ticket:write
|
||||
summary: Set a ticket playbook task
|
||||
summary: Set a ticket playbook task data
|
||||
tags:
|
||||
- tickets
|
||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete:
|
||||
@@ -6009,6 +5967,267 @@ paths:
|
||||
summary: Complete ticket playbook task
|
||||
tags:
|
||||
- tickets
|
||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}/owner:
|
||||
put:
|
||||
operationId: setTaskOwner
|
||||
parameters:
|
||||
- description: Ticket ID
|
||||
format: int64
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
x-example: 8123
|
||||
- description: Playbook ID
|
||||
in: path
|
||||
name: playbookID
|
||||
required: true
|
||||
type: string
|
||||
x-example: phishing
|
||||
- description: Task ID
|
||||
in: path
|
||||
name: taskID
|
||||
required: true
|
||||
type: string
|
||||
x-example: board
|
||||
- description: Task owner
|
||||
in: body
|
||||
name: owner
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
x-example: eve
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
examples:
|
||||
test:
|
||||
artifacts:
|
||||
- name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a
|
||||
status: unknown
|
||||
- name: http://www.customerviral.io/scalable/vertical/killer
|
||||
status: clean
|
||||
- name: leadreintermediate.io
|
||||
status: malicious
|
||||
created: 2021-10-02T16:04:59.078206Z
|
||||
id: 8123
|
||||
modified: 2021-12-12T12:12:12.000000012Z
|
||||
name: live zebra
|
||||
owner: demo
|
||||
playbooks:
|
||||
phishing:
|
||||
name: Phishing
|
||||
tasks:
|
||||
block-iocs:
|
||||
active: false
|
||||
created: 2021-12-12T12:12:12.000000012Z
|
||||
done: false
|
||||
name: Block IOCs
|
||||
order: 6
|
||||
type: task
|
||||
block-sender:
|
||||
active: false
|
||||
created: 2021-12-12T12:12:12.000000012Z
|
||||
done: false
|
||||
name: Block sender
|
||||
next:
|
||||
extract-iocs: ""
|
||||
order: 3
|
||||
type: task
|
||||
board:
|
||||
active: true
|
||||
created: 2021-12-12T12:12:12.000000012Z
|
||||
done: false
|
||||
name: Board Involvement?
|
||||
next:
|
||||
escalate: boardInvolved == true
|
||||
mail-available: boardInvolved == false
|
||||
order: 0
|
||||
owner: eve
|
||||
schema:
|
||||
properties:
|
||||
boardInvolved:
|
||||
default: false
|
||||
title: A board member is involved.
|
||||
type: boolean
|
||||
required:
|
||||
- boardInvolved
|
||||
title: Board Involvement?
|
||||
type: object
|
||||
type: input
|
||||
escalate:
|
||||
active: false
|
||||
created: 2021-12-12T12:12:12.000000012Z
|
||||
done: false
|
||||
name: Escalate to CISO
|
||||
order: 1
|
||||
type: task
|
||||
extract-iocs:
|
||||
active: false
|
||||
created: 2021-12-12T12:12:12.000000012Z
|
||||
done: false
|
||||
name: Extract IOCs
|
||||
next:
|
||||
block-iocs: ""
|
||||
order: 5
|
||||
schema:
|
||||
properties:
|
||||
iocs:
|
||||
items:
|
||||
type: string
|
||||
title: IOCs
|
||||
type: array
|
||||
title: Extract IOCs
|
||||
type: object
|
||||
type: input
|
||||
mail-available:
|
||||
active: false
|
||||
created: 2021-12-12T12:12:12.000000012Z
|
||||
done: false
|
||||
name: Mail available
|
||||
next:
|
||||
block-sender: schemaKey == 'yes'
|
||||
extract-iocs: schemaKey == 'yes'
|
||||
search-email-gateway: schemaKey == 'no'
|
||||
order: 2
|
||||
schema:
|
||||
oneOf:
|
||||
- properties:
|
||||
mail:
|
||||
title: Mail
|
||||
type: string
|
||||
x-display: textarea
|
||||
schemaKey:
|
||||
const: "yes"
|
||||
type: string
|
||||
required:
|
||||
- mail
|
||||
title: "Yes"
|
||||
- properties:
|
||||
schemaKey:
|
||||
const: "no"
|
||||
type: string
|
||||
title: "No"
|
||||
title: Mail available
|
||||
type: object
|
||||
type: input
|
||||
search-email-gateway:
|
||||
active: false
|
||||
created: 2021-12-12T12:12:12.000000012Z
|
||||
done: false
|
||||
name: Search email gateway
|
||||
next:
|
||||
extract-iocs: ""
|
||||
order: 4
|
||||
type: task
|
||||
references:
|
||||
- href: https://www.leadmaximize.net/e-services/back-end
|
||||
name: performance
|
||||
- href: http://www.corporateinteractive.name/rich
|
||||
name: autumn
|
||||
- href: https://www.corporateintuitive.org/intuitive/platforms/integrate
|
||||
name: suggest
|
||||
schema: |
|
||||
{
|
||||
"definitions": {},
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://example.com/object1618746510.json",
|
||||
"title": "Event",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"severity",
|
||||
"description",
|
||||
"tlp"
|
||||
],
|
||||
"properties": {
|
||||
"severity": {
|
||||
"$id": "#root/severity",
|
||||
"title": "Severity",
|
||||
"type": "string",
|
||||
"default": "Medium",
|
||||
"nx-enum": [
|
||||
"Low",
|
||||
"Medium",
|
||||
"High"
|
||||
],
|
||||
"x-cols": 6,
|
||||
"x-class": "pr-2",
|
||||
"x-display": "icon",
|
||||
"x-itemIcon": "icon",
|
||||
"oneOf": [
|
||||
{
|
||||
"const": "Low",
|
||||
"title": "Low",
|
||||
"icon": "mdi-chevron-up"
|
||||
},
|
||||
{
|
||||
"const": "Medium",
|
||||
"title": "Medium",
|
||||
"icon": "mdi-chevron-double-up"
|
||||
},
|
||||
{
|
||||
"const": "High",
|
||||
"title": "High",
|
||||
"icon": "mdi-chevron-triple-up"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tlp": {
|
||||
"$id": "#root/tlp",
|
||||
"title": "TLP",
|
||||
"type": "string",
|
||||
"nx-enum": [
|
||||
"White",
|
||||
"Green",
|
||||
"Amber",
|
||||
"Red"
|
||||
],
|
||||
"x-cols": 6,
|
||||
"x-class": "pr-2",
|
||||
"x-display": "icon",
|
||||
"x-itemIcon": "icon",
|
||||
"oneOf": [
|
||||
{
|
||||
"const": "White",
|
||||
"title": "White",
|
||||
"icon": "mdi-alpha-w"
|
||||
},
|
||||
{
|
||||
"const": "Green",
|
||||
"title": "Green",
|
||||
"icon": "mdi-alpha-g"
|
||||
},
|
||||
{
|
||||
"const": "Amber",
|
||||
"title": "Amber",
|
||||
"icon": "mdi-alpha-a"
|
||||
},
|
||||
{
|
||||
"const": "Red",
|
||||
"title": "Red",
|
||||
"icon": "mdi-alpha-r"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"$id": "#root/description",
|
||||
"title": "Description",
|
||||
"type": "string",
|
||||
"x-display": "textarea",
|
||||
"x-class": "pr-2"
|
||||
}
|
||||
}
|
||||
}
|
||||
status: closed
|
||||
type: incident
|
||||
schema:
|
||||
$ref: '#/definitions/TicketWithTickets'
|
||||
security:
|
||||
- roles:
|
||||
- ticket:write
|
||||
summary: Set a ticket playbook task owner
|
||||
tags:
|
||||
- tickets
|
||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}/run:
|
||||
post:
|
||||
operationId: runTask
|
||||
@@ -6057,9 +6276,7 @@ paths:
|
||||
name: references
|
||||
required: true
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/Reference'
|
||||
type: array
|
||||
$ref: '#/definitions/ReferenceArray'
|
||||
x-example:
|
||||
- href: http://www.leadscalable.biz/envisioneer
|
||||
name: fund
|
||||
@@ -6486,9 +6703,7 @@ paths:
|
||||
name: ticket
|
||||
required: true
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/TicketForm'
|
||||
type: array
|
||||
$ref: '#/definitions/TicketFormArray'
|
||||
x-example:
|
||||
- id: 123
|
||||
name: Wannacry infection
|
||||
@@ -6825,6 +7040,8 @@ paths:
|
||||
schema:
|
||||
$ref: '#/definitions/UserForm'
|
||||
x-example:
|
||||
apikey: true
|
||||
blocked: false
|
||||
id: syncscript
|
||||
roles:
|
||||
- analyst
|
||||
@@ -6939,6 +7156,9 @@ paths:
|
||||
schema:
|
||||
$ref: '#/definitions/UserForm'
|
||||
x-example:
|
||||
apikey: false
|
||||
blocked: false
|
||||
id: syncscript
|
||||
roles:
|
||||
- analyst
|
||||
- admin
|
||||
|
||||
@@ -427,7 +427,7 @@
|
||||
"content" : {
|
||||
"application/json" : {
|
||||
"schema" : {
|
||||
"$ref" : "#/components/schemas/Job"
|
||||
"$ref" : "#/components/schemas/JobUpdate"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2974,7 +2974,7 @@
|
||||
},
|
||||
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}" : {
|
||||
"put" : {
|
||||
"operationId" : "setTask",
|
||||
"operationId" : "setTaskData",
|
||||
"parameters" : [ {
|
||||
"description" : "Ticket ID",
|
||||
"example" : 8123,
|
||||
@@ -3008,11 +3008,11 @@
|
||||
"content" : {
|
||||
"application/json" : {
|
||||
"schema" : {
|
||||
"$ref" : "#/components/schemas/Task"
|
||||
"type" : "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description" : "Task",
|
||||
"description" : "Task data",
|
||||
"required" : true
|
||||
},
|
||||
"responses" : {
|
||||
@@ -3198,9 +3198,9 @@
|
||||
"security" : [ {
|
||||
"roles" : [ "ticket:write" ]
|
||||
} ],
|
||||
"summary" : "Set a ticket playbook task",
|
||||
"summary" : "Set a ticket playbook task data",
|
||||
"tags" : [ "tickets" ],
|
||||
"x-codegen-request-body-name" : "task"
|
||||
"x-codegen-request-body-name" : "data"
|
||||
}
|
||||
},
|
||||
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete" : {
|
||||
@@ -3435,6 +3435,235 @@
|
||||
"x-codegen-request-body-name" : "data"
|
||||
}
|
||||
},
|
||||
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}/owner" : {
|
||||
"put" : {
|
||||
"operationId" : "setTaskOwner",
|
||||
"parameters" : [ {
|
||||
"description" : "Ticket ID",
|
||||
"example" : 8123,
|
||||
"in" : "path",
|
||||
"name" : "id",
|
||||
"required" : true,
|
||||
"schema" : {
|
||||
"format" : "int64",
|
||||
"type" : "integer"
|
||||
}
|
||||
}, {
|
||||
"description" : "Playbook ID",
|
||||
"example" : "phishing",
|
||||
"in" : "path",
|
||||
"name" : "playbookID",
|
||||
"required" : true,
|
||||
"schema" : {
|
||||
"type" : "string"
|
||||
}
|
||||
}, {
|
||||
"description" : "Task ID",
|
||||
"example" : "board",
|
||||
"in" : "path",
|
||||
"name" : "taskID",
|
||||
"required" : true,
|
||||
"schema" : {
|
||||
"type" : "string"
|
||||
}
|
||||
} ],
|
||||
"requestBody" : {
|
||||
"content" : {
|
||||
"application/json" : {
|
||||
"schema" : {
|
||||
"type" : "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description" : "Task owner",
|
||||
"required" : true
|
||||
},
|
||||
"responses" : {
|
||||
"200" : {
|
||||
"content" : {
|
||||
"application/json" : {
|
||||
"schema" : {
|
||||
"$ref" : "#/components/schemas/TicketWithTickets"
|
||||
}
|
||||
},
|
||||
"test" : {
|
||||
"example" : {
|
||||
"artifacts" : [ {
|
||||
"name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a",
|
||||
"status" : "unknown"
|
||||
}, {
|
||||
"name" : "http://www.customerviral.io/scalable/vertical/killer",
|
||||
"status" : "clean"
|
||||
}, {
|
||||
"name" : "leadreintermediate.io",
|
||||
"status" : "malicious"
|
||||
} ],
|
||||
"created" : "2021-10-02T16:04:59.078+0000",
|
||||
"id" : 8123,
|
||||
"modified" : "2021-12-12T12:12:12.000+0000",
|
||||
"name" : "live zebra",
|
||||
"owner" : "demo",
|
||||
"playbooks" : {
|
||||
"phishing" : {
|
||||
"name" : "Phishing",
|
||||
"tasks" : {
|
||||
"block-iocs" : {
|
||||
"active" : false,
|
||||
"created" : "2021-12-12T12:12:12.000+0000",
|
||||
"done" : false,
|
||||
"name" : "Block IOCs",
|
||||
"order" : 6,
|
||||
"type" : "task"
|
||||
},
|
||||
"block-sender" : {
|
||||
"active" : false,
|
||||
"created" : "2021-12-12T12:12:12.000+0000",
|
||||
"done" : false,
|
||||
"name" : "Block sender",
|
||||
"next" : {
|
||||
"extract-iocs" : ""
|
||||
},
|
||||
"order" : 3,
|
||||
"type" : "task"
|
||||
},
|
||||
"board" : {
|
||||
"active" : true,
|
||||
"created" : "2021-12-12T12:12:12.000+0000",
|
||||
"done" : false,
|
||||
"name" : "Board Involvement?",
|
||||
"next" : {
|
||||
"escalate" : "boardInvolved == true",
|
||||
"mail-available" : "boardInvolved == false"
|
||||
},
|
||||
"order" : 0,
|
||||
"owner" : "eve",
|
||||
"schema" : {
|
||||
"properties" : {
|
||||
"boardInvolved" : {
|
||||
"default" : false,
|
||||
"title" : "A board member is involved.",
|
||||
"type" : "boolean"
|
||||
}
|
||||
},
|
||||
"required" : [ "boardInvolved" ],
|
||||
"title" : "Board Involvement?",
|
||||
"type" : "object"
|
||||
},
|
||||
"type" : "input"
|
||||
},
|
||||
"escalate" : {
|
||||
"active" : false,
|
||||
"created" : "2021-12-12T12:12:12.000+0000",
|
||||
"done" : false,
|
||||
"name" : "Escalate to CISO",
|
||||
"order" : 1,
|
||||
"type" : "task"
|
||||
},
|
||||
"extract-iocs" : {
|
||||
"active" : false,
|
||||
"created" : "2021-12-12T12:12:12.000+0000",
|
||||
"done" : false,
|
||||
"name" : "Extract IOCs",
|
||||
"next" : {
|
||||
"block-iocs" : ""
|
||||
},
|
||||
"order" : 5,
|
||||
"schema" : {
|
||||
"properties" : {
|
||||
"iocs" : {
|
||||
"items" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"title" : "IOCs",
|
||||
"type" : "array"
|
||||
}
|
||||
},
|
||||
"title" : "Extract IOCs",
|
||||
"type" : "object"
|
||||
},
|
||||
"type" : "input"
|
||||
},
|
||||
"mail-available" : {
|
||||
"active" : false,
|
||||
"created" : "2021-12-12T12:12:12.000+0000",
|
||||
"done" : false,
|
||||
"name" : "Mail available",
|
||||
"next" : {
|
||||
"block-sender" : "schemaKey == 'yes'",
|
||||
"extract-iocs" : "schemaKey == 'yes'",
|
||||
"search-email-gateway" : "schemaKey == 'no'"
|
||||
},
|
||||
"order" : 2,
|
||||
"schema" : {
|
||||
"oneOf" : [ {
|
||||
"properties" : {
|
||||
"mail" : {
|
||||
"title" : "Mail",
|
||||
"type" : "string",
|
||||
"x-display" : "textarea"
|
||||
},
|
||||
"schemaKey" : {
|
||||
"const" : "yes",
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
"required" : [ "mail" ],
|
||||
"title" : "Yes"
|
||||
}, {
|
||||
"properties" : {
|
||||
"schemaKey" : {
|
||||
"const" : "no",
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
"title" : "No"
|
||||
} ],
|
||||
"title" : "Mail available",
|
||||
"type" : "object"
|
||||
},
|
||||
"type" : "input"
|
||||
},
|
||||
"search-email-gateway" : {
|
||||
"active" : false,
|
||||
"created" : "2021-12-12T12:12:12.000+0000",
|
||||
"done" : false,
|
||||
"name" : "Search email gateway",
|
||||
"next" : {
|
||||
"extract-iocs" : ""
|
||||
},
|
||||
"order" : 4,
|
||||
"type" : "task"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"references" : [ {
|
||||
"href" : "https://www.leadmaximize.net/e-services/back-end",
|
||||
"name" : "performance"
|
||||
}, {
|
||||
"href" : "http://www.corporateinteractive.name/rich",
|
||||
"name" : "autumn"
|
||||
}, {
|
||||
"href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate",
|
||||
"name" : "suggest"
|
||||
} ],
|
||||
"schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n",
|
||||
"status" : "closed",
|
||||
"type" : "incident"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description" : "successful operation"
|
||||
}
|
||||
},
|
||||
"security" : [ {
|
||||
"roles" : [ "ticket:write" ]
|
||||
} ],
|
||||
"summary" : "Set a ticket playbook task owner",
|
||||
"tags" : [ "tickets" ],
|
||||
"x-codegen-request-body-name" : "owner"
|
||||
}
|
||||
},
|
||||
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}/run" : {
|
||||
"post" : {
|
||||
"operationId" : "runTask",
|
||||
@@ -3498,10 +3727,7 @@
|
||||
"content" : {
|
||||
"application/json" : {
|
||||
"schema" : {
|
||||
"items" : {
|
||||
"$ref" : "#/components/schemas/Reference"
|
||||
},
|
||||
"type" : "array"
|
||||
"$ref" : "#/components/schemas/ReferenceArray"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3960,10 +4186,7 @@
|
||||
"content" : {
|
||||
"application/json" : {
|
||||
"schema" : {
|
||||
"items" : {
|
||||
"$ref" : "#/components/schemas/TicketForm"
|
||||
},
|
||||
"type" : "array"
|
||||
"$ref" : "#/components/schemas/TicketFormArray"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4797,6 +5020,28 @@
|
||||
"required" : [ "automation", "id", "status" ],
|
||||
"type" : "object"
|
||||
},
|
||||
"JobUpdate" : {
|
||||
"properties" : {
|
||||
"container" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"log" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"output" : {
|
||||
"properties" : { },
|
||||
"type" : "object"
|
||||
},
|
||||
"running" : {
|
||||
"type" : "boolean"
|
||||
},
|
||||
"status" : {
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
"required" : [ "running", "status" ],
|
||||
"type" : "object"
|
||||
},
|
||||
"LogEntry" : {
|
||||
"properties" : {
|
||||
"created" : {
|
||||
@@ -4953,6 +5198,12 @@
|
||||
"required" : [ "href", "name" ],
|
||||
"type" : "object"
|
||||
},
|
||||
"ReferenceArray" : {
|
||||
"items" : {
|
||||
"$ref" : "#/components/schemas/Reference"
|
||||
},
|
||||
"type" : "array"
|
||||
},
|
||||
"Settings" : {
|
||||
"properties" : {
|
||||
"artifactStates" : {
|
||||
@@ -5076,62 +5327,6 @@
|
||||
"required" : [ "created", "done", "name", "type" ],
|
||||
"type" : "object"
|
||||
},
|
||||
"TaskForm" : {
|
||||
"properties" : {
|
||||
"automation" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"closed" : {
|
||||
"format" : "date-time",
|
||||
"type" : "string"
|
||||
},
|
||||
"created" : {
|
||||
"format" : "date-time",
|
||||
"type" : "string"
|
||||
},
|
||||
"data" : {
|
||||
"properties" : { },
|
||||
"type" : "object"
|
||||
},
|
||||
"done" : {
|
||||
"type" : "boolean"
|
||||
},
|
||||
"join" : {
|
||||
"example" : false,
|
||||
"type" : "boolean"
|
||||
},
|
||||
"name" : {
|
||||
"example" : "Inform user",
|
||||
"type" : "string"
|
||||
},
|
||||
"next" : {
|
||||
"additionalProperties" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"type" : "object"
|
||||
},
|
||||
"owner" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"payload" : {
|
||||
"additionalProperties" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"type" : "object"
|
||||
},
|
||||
"schema" : {
|
||||
"properties" : { },
|
||||
"type" : "object"
|
||||
},
|
||||
"type" : {
|
||||
"enum" : [ "task", "input", "automation" ],
|
||||
"example" : "task",
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
"required" : [ "name", "type" ],
|
||||
"type" : "object"
|
||||
},
|
||||
"TaskOrigin" : {
|
||||
"properties" : {
|
||||
"playbook_id" : {
|
||||
@@ -5413,6 +5608,12 @@
|
||||
"required" : [ "name", "status", "type" ],
|
||||
"type" : "object"
|
||||
},
|
||||
"TicketFormArray" : {
|
||||
"items" : {
|
||||
"$ref" : "#/components/schemas/TicketForm"
|
||||
},
|
||||
"type" : "array"
|
||||
},
|
||||
"TicketList" : {
|
||||
"properties" : {
|
||||
"count" : {
|
||||
|
||||
@@ -236,6 +236,22 @@ definitions:
|
||||
- automation
|
||||
- status
|
||||
type: object
|
||||
JobUpdate:
|
||||
properties:
|
||||
container:
|
||||
type: string
|
||||
log:
|
||||
type: string
|
||||
output:
|
||||
type: object
|
||||
running:
|
||||
type: boolean
|
||||
status:
|
||||
type: string
|
||||
required:
|
||||
- running
|
||||
- status
|
||||
type: object
|
||||
LogEntry:
|
||||
properties:
|
||||
created:
|
||||
@@ -360,6 +376,10 @@ definitions:
|
||||
- name
|
||||
- href
|
||||
type: object
|
||||
ReferenceArray:
|
||||
items:
|
||||
$ref: '#/definitions/Reference'
|
||||
type: array
|
||||
Settings:
|
||||
properties:
|
||||
artifactStates:
|
||||
@@ -465,51 +485,6 @@ definitions:
|
||||
- done
|
||||
- created
|
||||
type: object
|
||||
TaskForm:
|
||||
properties:
|
||||
automation:
|
||||
type: string
|
||||
closed:
|
||||
example: 1985-04-12T23:20:50.52Z
|
||||
format: date-time
|
||||
type: string
|
||||
created:
|
||||
example: 1985-04-12T23:20:50.52Z
|
||||
format: date-time
|
||||
type: string
|
||||
data:
|
||||
type: object
|
||||
done:
|
||||
type: boolean
|
||||
join:
|
||||
example: false
|
||||
type: boolean
|
||||
name:
|
||||
example: Inform user
|
||||
type: string
|
||||
next:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
owner:
|
||||
type: string
|
||||
payload:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
schema:
|
||||
type: object
|
||||
type:
|
||||
enum:
|
||||
- task
|
||||
- input
|
||||
- automation
|
||||
example: task
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
TaskOrigin:
|
||||
properties:
|
||||
playbook_id:
|
||||
@@ -742,6 +717,10 @@ definitions:
|
||||
- type
|
||||
- status
|
||||
type: object
|
||||
TicketFormArray:
|
||||
items:
|
||||
$ref: '#/definitions/TicketForm'
|
||||
type: array
|
||||
TicketList:
|
||||
properties:
|
||||
count:
|
||||
@@ -1628,11 +1607,9 @@ paths:
|
||||
name: job
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/Job'
|
||||
$ref: '#/definitions/JobUpdate'
|
||||
x-example:
|
||||
automation: hash.sha1
|
||||
id: 99cd67131b48
|
||||
payload: test
|
||||
running: false
|
||||
status: failed
|
||||
responses:
|
||||
"200":
|
||||
@@ -5053,7 +5030,7 @@ paths:
|
||||
- tickets
|
||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}:
|
||||
put:
|
||||
operationId: setTask
|
||||
operationId: setTaskData
|
||||
parameters:
|
||||
- description: Ticket ID
|
||||
format: int64
|
||||
@@ -5074,33 +5051,14 @@ paths:
|
||||
required: true
|
||||
type: string
|
||||
x-example: board
|
||||
- description: Task
|
||||
- description: Task data
|
||||
in: body
|
||||
name: task
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/Task'
|
||||
type: object
|
||||
x-example:
|
||||
active: true
|
||||
data:
|
||||
boardInvolved: true
|
||||
done: false
|
||||
name: Board Involvement?
|
||||
next:
|
||||
escalate: boardInvolved == true
|
||||
mail-available: boardInvolved == false
|
||||
order: 0
|
||||
schema:
|
||||
properties:
|
||||
boardInvolved:
|
||||
default: false
|
||||
title: A board member is involved.
|
||||
type: boolean
|
||||
required:
|
||||
- boardInvolved
|
||||
title: Board Involvement?
|
||||
type: object
|
||||
type: input
|
||||
boardInvolved: true
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
@@ -5330,7 +5288,7 @@ paths:
|
||||
security:
|
||||
- roles:
|
||||
- ticket:write
|
||||
summary: Set a ticket playbook task
|
||||
summary: Set a ticket playbook task data
|
||||
tags:
|
||||
- tickets
|
||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete:
|
||||
@@ -5597,6 +5555,267 @@ paths:
|
||||
summary: Complete ticket playbook task
|
||||
tags:
|
||||
- tickets
|
||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}/owner:
|
||||
put:
|
||||
operationId: setTaskOwner
|
||||
parameters:
|
||||
- description: Ticket ID
|
||||
format: int64
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
x-example: 8123
|
||||
- description: Playbook ID
|
||||
in: path
|
||||
name: playbookID
|
||||
required: true
|
||||
type: string
|
||||
x-example: phishing
|
||||
- description: Task ID
|
||||
in: path
|
||||
name: taskID
|
||||
required: true
|
||||
type: string
|
||||
x-example: board
|
||||
- description: Task owner
|
||||
in: body
|
||||
name: owner
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
x-example: eve
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
examples:
|
||||
test:
|
||||
artifacts:
|
||||
- name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a
|
||||
status: unknown
|
||||
- name: http://www.customerviral.io/scalable/vertical/killer
|
||||
status: clean
|
||||
- name: leadreintermediate.io
|
||||
status: malicious
|
||||
created: 2021-10-02T16:04:59.078206Z
|
||||
id: 8123
|
||||
modified: 2021-12-12T12:12:12.000000012Z
|
||||
name: live zebra
|
||||
owner: demo
|
||||
playbooks:
|
||||
phishing:
|
||||
name: Phishing
|
||||
tasks:
|
||||
block-iocs:
|
||||
active: false
|
||||
created: 2021-12-12T12:12:12.000000012Z
|
||||
done: false
|
||||
name: Block IOCs
|
||||
order: 6
|
||||
type: task
|
||||
block-sender:
|
||||
active: false
|
||||
created: 2021-12-12T12:12:12.000000012Z
|
||||
done: false
|
||||
name: Block sender
|
||||
next:
|
||||
extract-iocs: ""
|
||||
order: 3
|
||||
type: task
|
||||
board:
|
||||
active: true
|
||||
created: 2021-12-12T12:12:12.000000012Z
|
||||
done: false
|
||||
name: Board Involvement?
|
||||
next:
|
||||
escalate: boardInvolved == true
|
||||
mail-available: boardInvolved == false
|
||||
order: 0
|
||||
owner: eve
|
||||
schema:
|
||||
properties:
|
||||
boardInvolved:
|
||||
default: false
|
||||
title: A board member is involved.
|
||||
type: boolean
|
||||
required:
|
||||
- boardInvolved
|
||||
title: Board Involvement?
|
||||
type: object
|
||||
type: input
|
||||
escalate:
|
||||
active: false
|
||||
created: 2021-12-12T12:12:12.000000012Z
|
||||
done: false
|
||||
name: Escalate to CISO
|
||||
order: 1
|
||||
type: task
|
||||
extract-iocs:
|
||||
active: false
|
||||
created: 2021-12-12T12:12:12.000000012Z
|
||||
done: false
|
||||
name: Extract IOCs
|
||||
next:
|
||||
block-iocs: ""
|
||||
order: 5
|
||||
schema:
|
||||
properties:
|
||||
iocs:
|
||||
items:
|
||||
type: string
|
||||
title: IOCs
|
||||
type: array
|
||||
title: Extract IOCs
|
||||
type: object
|
||||
type: input
|
||||
mail-available:
|
||||
active: false
|
||||
created: 2021-12-12T12:12:12.000000012Z
|
||||
done: false
|
||||
name: Mail available
|
||||
next:
|
||||
block-sender: schemaKey == 'yes'
|
||||
extract-iocs: schemaKey == 'yes'
|
||||
search-email-gateway: schemaKey == 'no'
|
||||
order: 2
|
||||
schema:
|
||||
oneOf:
|
||||
- properties:
|
||||
mail:
|
||||
title: Mail
|
||||
type: string
|
||||
x-display: textarea
|
||||
schemaKey:
|
||||
const: "yes"
|
||||
type: string
|
||||
required:
|
||||
- mail
|
||||
title: "Yes"
|
||||
- properties:
|
||||
schemaKey:
|
||||
const: "no"
|
||||
type: string
|
||||
title: "No"
|
||||
title: Mail available
|
||||
type: object
|
||||
type: input
|
||||
search-email-gateway:
|
||||
active: false
|
||||
created: 2021-12-12T12:12:12.000000012Z
|
||||
done: false
|
||||
name: Search email gateway
|
||||
next:
|
||||
extract-iocs: ""
|
||||
order: 4
|
||||
type: task
|
||||
references:
|
||||
- href: https://www.leadmaximize.net/e-services/back-end
|
||||
name: performance
|
||||
- href: http://www.corporateinteractive.name/rich
|
||||
name: autumn
|
||||
- href: https://www.corporateintuitive.org/intuitive/platforms/integrate
|
||||
name: suggest
|
||||
schema: |
|
||||
{
|
||||
"definitions": {},
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://example.com/object1618746510.json",
|
||||
"title": "Event",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"severity",
|
||||
"description",
|
||||
"tlp"
|
||||
],
|
||||
"properties": {
|
||||
"severity": {
|
||||
"$id": "#root/severity",
|
||||
"title": "Severity",
|
||||
"type": "string",
|
||||
"default": "Medium",
|
||||
"nx-enum": [
|
||||
"Low",
|
||||
"Medium",
|
||||
"High"
|
||||
],
|
||||
"x-cols": 6,
|
||||
"x-class": "pr-2",
|
||||
"x-display": "icon",
|
||||
"x-itemIcon": "icon",
|
||||
"oneOf": [
|
||||
{
|
||||
"const": "Low",
|
||||
"title": "Low",
|
||||
"icon": "mdi-chevron-up"
|
||||
},
|
||||
{
|
||||
"const": "Medium",
|
||||
"title": "Medium",
|
||||
"icon": "mdi-chevron-double-up"
|
||||
},
|
||||
{
|
||||
"const": "High",
|
||||
"title": "High",
|
||||
"icon": "mdi-chevron-triple-up"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tlp": {
|
||||
"$id": "#root/tlp",
|
||||
"title": "TLP",
|
||||
"type": "string",
|
||||
"nx-enum": [
|
||||
"White",
|
||||
"Green",
|
||||
"Amber",
|
||||
"Red"
|
||||
],
|
||||
"x-cols": 6,
|
||||
"x-class": "pr-2",
|
||||
"x-display": "icon",
|
||||
"x-itemIcon": "icon",
|
||||
"oneOf": [
|
||||
{
|
||||
"const": "White",
|
||||
"title": "White",
|
||||
"icon": "mdi-alpha-w"
|
||||
},
|
||||
{
|
||||
"const": "Green",
|
||||
"title": "Green",
|
||||
"icon": "mdi-alpha-g"
|
||||
},
|
||||
{
|
||||
"const": "Amber",
|
||||
"title": "Amber",
|
||||
"icon": "mdi-alpha-a"
|
||||
},
|
||||
{
|
||||
"const": "Red",
|
||||
"title": "Red",
|
||||
"icon": "mdi-alpha-r"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"$id": "#root/description",
|
||||
"title": "Description",
|
||||
"type": "string",
|
||||
"x-display": "textarea",
|
||||
"x-class": "pr-2"
|
||||
}
|
||||
}
|
||||
}
|
||||
status: closed
|
||||
type: incident
|
||||
schema:
|
||||
$ref: '#/definitions/TicketWithTickets'
|
||||
security:
|
||||
- roles:
|
||||
- ticket:write
|
||||
summary: Set a ticket playbook task owner
|
||||
tags:
|
||||
- tickets
|
||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}/run:
|
||||
post:
|
||||
operationId: runTask
|
||||
@@ -5645,9 +5864,7 @@ paths:
|
||||
name: references
|
||||
required: true
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/Reference'
|
||||
type: array
|
||||
$ref: '#/definitions/ReferenceArray'
|
||||
x-example:
|
||||
- href: http://www.leadscalable.biz/envisioneer
|
||||
name: fund
|
||||
@@ -6074,9 +6291,7 @@ paths:
|
||||
name: ticket
|
||||
required: true
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/TicketForm'
|
||||
type: array
|
||||
$ref: '#/definitions/TicketFormArray'
|
||||
x-example:
|
||||
- id: 123
|
||||
name: Wannacry infection
|
||||
@@ -6413,6 +6628,8 @@ paths:
|
||||
schema:
|
||||
$ref: '#/definitions/UserForm'
|
||||
x-example:
|
||||
apikey: true
|
||||
blocked: false
|
||||
id: syncscript
|
||||
roles:
|
||||
- analyst
|
||||
@@ -6527,6 +6744,9 @@ paths:
|
||||
schema:
|
||||
$ref: '#/definitions/UserForm'
|
||||
x-example:
|
||||
apikey: false
|
||||
blocked: false
|
||||
id: syncscript
|
||||
roles:
|
||||
- analyst
|
||||
- admin
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/xeipuuv/gojsonschema"
|
||||
@@ -24,6 +22,7 @@ var (
|
||||
JobSchema = new(gojsonschema.Schema)
|
||||
JobFormSchema = new(gojsonschema.Schema)
|
||||
JobResponseSchema = new(gojsonschema.Schema)
|
||||
JobUpdateSchema = new(gojsonschema.Schema)
|
||||
LogEntrySchema = new(gojsonschema.Schema)
|
||||
MessageSchema = new(gojsonschema.Schema)
|
||||
NewUserResponseSchema = new(gojsonschema.Schema)
|
||||
@@ -34,15 +33,16 @@ var (
|
||||
PlaybookTemplateFormSchema = new(gojsonschema.Schema)
|
||||
PlaybookTemplateResponseSchema = new(gojsonschema.Schema)
|
||||
ReferenceSchema = new(gojsonschema.Schema)
|
||||
ReferenceArraySchema = new(gojsonschema.Schema)
|
||||
SettingsSchema = new(gojsonschema.Schema)
|
||||
StatisticsSchema = new(gojsonschema.Schema)
|
||||
TaskSchema = new(gojsonschema.Schema)
|
||||
TaskFormSchema = new(gojsonschema.Schema)
|
||||
TaskOriginSchema = new(gojsonschema.Schema)
|
||||
TaskResponseSchema = new(gojsonschema.Schema)
|
||||
TaskWithContextSchema = new(gojsonschema.Schema)
|
||||
TicketSchema = new(gojsonschema.Schema)
|
||||
TicketFormSchema = new(gojsonschema.Schema)
|
||||
TicketFormArraySchema = new(gojsonschema.Schema)
|
||||
TicketListSchema = new(gojsonschema.Schema)
|
||||
TicketResponseSchema = new(gojsonschema.Schema)
|
||||
TicketSimpleResponseSchema = new(gojsonschema.Schema)
|
||||
@@ -63,55 +63,57 @@ var (
|
||||
|
||||
func init() {
|
||||
err := schemaLoader.AddSchemas(
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name"],"x-embed":"","properties":{"enrichments":{"type":"object","additionalProperties":{"$ref":"#/definitions/Enrichment"}},"name":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"}},"$id":"#/definitions/Artifact"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["ticket_id","artifact"],"x-embed":"","properties":{"artifact":{"type":"string"},"ticket_id":{"format":"int64","type":"integer"}},"$id":"#/definitions/ArtifactOrigin"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["image","script","type"],"x-embed":"","properties":{"image":{"type":"string"},"schema":{"type":"string"},"script":{"type":"string"},"type":{"items":{"type":"string","enum":["artifact","playbook","global"]},"type":"array"}},"$id":"#/definitions/Automation"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["id","image","script","type"],"x-embed":"","properties":{"id":{"type":"string"},"image":{"type":"string"},"schema":{"type":"string"},"script":{"type":"string"},"type":{"items":{"type":"string","enum":["artifact","playbook","global"]},"type":"array"}},"$id":"#/definitions/AutomationForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["id","image","script","type"],"x-embed":"","properties":{"id":{"type":"string"},"image":{"type":"string"},"schema":{"type":"string"},"script":{"type":"string"},"type":{"items":{"type":"string","enum":["artifact","playbook","global"]},"type":"array"}},"$id":"#/definitions/AutomationResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["creator","created","message"],"x-embed":"","properties":{"created":{"format":"date-time","type":"string"},"creator":{"type":"string"},"message":{"type":"string"}},"$id":"#/definitions/Comment"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["message"],"x-embed":"","properties":{"created":{"format":"date-time","type":"string"},"creator":{"type":"string"},"message":{"type":"string"}},"$id":"#/definitions/CommentForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","x-embed":"","properties":{"artifact":{"$ref":"#/definitions/Artifact"},"playbook":{"$ref":"#/definitions/PlaybookResponse"},"task":{"$ref":"#/definitions/TaskResponse"},"ticket":{"$ref":"#/definitions/TicketResponse"}},"$id":"#/definitions/Context"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","data","created"],"x-embed":"","properties":{"created":{"format":"date-time","type":"string"},"data":{"type":"object"},"name":{"type":"string"}},"$id":"#/definitions/Enrichment"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","data"],"x-embed":"","properties":{"data":{"type":"object"},"name":{"type":"string"}},"$id":"#/definitions/EnrichmentForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["key","name"],"x-embed":"","properties":{"key":{"type":"string"},"name":{"type":"string"}},"$id":"#/definitions/File"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["automation","running","status"],"x-embed":"","properties":{"automation":{"type":"string"},"container":{"type":"string"},"log":{"type":"string"},"origin":{"$ref":"#/definitions/Origin"},"output":{"type":"object"},"payload":{},"running":{"type":"boolean"},"status":{"type":"string"}},"$id":"#/definitions/Job"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["automation"],"x-embed":"","properties":{"automation":{"type":"string"},"origin":{"$ref":"#/definitions/Origin"},"payload":{}},"$id":"#/definitions/JobForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["id","automation","status"],"x-embed":"","properties":{"automation":{"type":"string"},"container":{"type":"string"},"id":{"type":"string"},"log":{"type":"string"},"origin":{"$ref":"#/definitions/Origin"},"output":{"type":"object"},"payload":{},"status":{"type":"string"}},"$id":"#/definitions/JobResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["type","reference","creator","created","message"],"x-embed":"","properties":{"created":{"format":"date-time","type":"string"},"creator":{"type":"string"},"message":{"type":"string"},"reference":{"type":"string"},"type":{"type":"string"}},"$id":"#/definitions/LogEntry"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","x-embed":"","properties":{"context":{"$ref":"#/definitions/Context"},"payload":{},"secrets":{"type":"object","additionalProperties":{"type":"string"}}},"$id":"#/definitions/Message"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["id","blocked","roles"],"x-embed":"","properties":{"blocked":{"type":"boolean"},"id":{"type":"string"},"roles":{"items":{"type":"string"},"type":"array"},"secret":{"type":"string"}},"$id":"#/definitions/NewUserResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","x-embed":"","properties":{"artifact_origin":{"$ref":"#/definitions/ArtifactOrigin"},"task_origin":{"$ref":"#/definitions/TaskOrigin"}},"$id":"#/definitions/Origin"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","tasks"],"x-embed":"","properties":{"name":{"type":"string"},"tasks":{"type":"object","additionalProperties":{"$ref":"#/definitions/Task"}}},"$id":"#/definitions/Playbook"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","tasks"],"x-embed":"","properties":{"name":{"type":"string"},"tasks":{"type":"object","additionalProperties":{"$ref":"#/definitions/TaskResponse"}}},"$id":"#/definitions/PlaybookResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","yaml"],"x-embed":"","properties":{"name":{"type":"string"},"yaml":{"type":"string"}},"$id":"#/definitions/PlaybookTemplate"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["yaml"],"x-embed":"","properties":{"id":{"type":"string"},"yaml":{"type":"string"}},"$id":"#/definitions/PlaybookTemplateForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["id","name","yaml"],"x-embed":"","properties":{"id":{"type":"string"},"name":{"type":"string"},"yaml":{"type":"string"}},"$id":"#/definitions/PlaybookTemplateResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","href"],"x-embed":"","properties":{"href":{"type":"string"},"name":{"type":"string"}},"$id":"#/definitions/Reference"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["version","tier","timeformat","ticketTypes","artifactStates"],"x-embed":"","properties":{"artifactStates":{"title":"Artifact States","items":{"$ref":"#/definitions/Type"},"type":"array"},"roles":{"title":"Roles","items":{"type":"string"},"type":"array"},"ticketTypes":{"title":"Ticket Types","items":{"$ref":"#/definitions/TicketTypeResponse"},"type":"array"},"tier":{"title":"Tier","type":"string","enum":["community","enterprise"]},"timeformat":{"title":"Time Format","type":"string"},"version":{"title":"Version","type":"string"}},"$id":"#/definitions/Settings"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["unassigned","open_tickets_per_user","tickets_per_week","tickets_per_type"],"x-embed":"","properties":{"open_tickets_per_user":{"type":"object","additionalProperties":{"type":"integer"}},"tickets_per_type":{"type":"object","additionalProperties":{"type":"integer"}},"tickets_per_week":{"type":"object","additionalProperties":{"type":"integer"}},"unassigned":{"type":"integer"}},"$id":"#/definitions/Statistics"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","type","done","created"],"x-embed":"","properties":{"automation":{"type":"string"},"closed":{"format":"date-time","type":"string"},"created":{"format":"date-time","type":"string"},"data":{"type":"object"},"done":{"type":"boolean"},"join":{"type":"boolean"},"name":{"type":"string"},"next":{"type":"object","additionalProperties":{"type":"string"}},"owner":{"type":"string"},"payload":{"type":"object","additionalProperties":{"type":"string"}},"schema":{"type":"object"},"type":{"type":"string","enum":["task","input","automation"]}},"$id":"#/definitions/Task"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","type"],"x-embed":"","properties":{"automation":{"type":"string"},"closed":{"format":"date-time","type":"string"},"created":{"format":"date-time","type":"string"},"data":{"type":"object"},"done":{"type":"boolean"},"join":{"type":"boolean"},"name":{"type":"string"},"next":{"type":"object","additionalProperties":{"type":"string"}},"owner":{"type":"string"},"payload":{"type":"object","additionalProperties":{"type":"string"}},"schema":{"type":"object"},"type":{"type":"string","enum":["task","input","automation"]}},"$id":"#/definitions/TaskForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["ticket_id","playbook_id","task_id"],"x-embed":"","properties":{"playbook_id":{"type":"string"},"task_id":{"type":"string"},"ticket_id":{"format":"int64","type":"integer"}},"$id":"#/definitions/TaskOrigin"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","type","done","created","order","active"],"x-embed":"","properties":{"active":{"type":"boolean"},"automation":{"type":"string"},"closed":{"format":"date-time","type":"string"},"created":{"format":"date-time","type":"string"},"data":{"type":"object"},"done":{"type":"boolean"},"join":{"type":"boolean"},"name":{"type":"string"},"next":{"type":"object","additionalProperties":{"type":"string"}},"order":{"format":"int64","type":"number"},"owner":{"type":"string"},"payload":{"type":"object","additionalProperties":{"type":"string"}},"schema":{"type":"object"},"type":{"type":"string","enum":["task","input","automation"]}},"$id":"#/definitions/TaskResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["ticket_id","ticket_name","playbook_id","playbook_name","task_id","task"],"x-embed":"","properties":{"playbook_id":{"type":"string"},"playbook_name":{"type":"string"},"task":{"$ref":"#/definitions/TaskResponse"},"task_id":{"type":"string"},"ticket_id":{"format":"int64","type":"number"},"ticket_name":{"type":"string"}},"$id":"#/definitions/TaskWithContext"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","type","status","created","modified","schema"],"x-embed":"","properties":{"artifacts":{"items":{"$ref":"#/definitions/Artifact"},"type":"array"},"comments":{"items":{"$ref":"#/definitions/Comment"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"type":"object"},"files":{"items":{"$ref":"#/definitions/File"},"type":"array"},"modified":{"format":"date-time","type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"playbooks":{"type":"object","additionalProperties":{"$ref":"#/definitions/Playbook"}},"read":{"items":{"type":"string"},"type":"array"},"references":{"items":{"$ref":"#/definitions/Reference"},"type":"array"},"schema":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"write":{"items":{"type":"string"},"type":"array"}},"$id":"#/definitions/Ticket"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","type","status"],"x-embed":"","properties":{"artifacts":{"items":{"$ref":"#/definitions/Artifact"},"type":"array"},"comments":{"items":{"$ref":"#/definitions/Comment"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"type":"object"},"files":{"items":{"$ref":"#/definitions/File"},"type":"array"},"id":{"format":"int64","type":"integer"},"modified":{"format":"date-time","type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"playbooks":{"items":{"$ref":"#/definitions/PlaybookTemplateForm"},"type":"array"},"read":{"items":{"type":"string"},"type":"array"},"references":{"items":{"$ref":"#/definitions/Reference"},"type":"array"},"schema":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"write":{"items":{"type":"string"},"type":"array"}},"$id":"#/definitions/TicketForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["tickets","count"],"x-embed":"","properties":{"count":{"type":"number"},"tickets":{"items":{"$ref":"#/definitions/TicketSimpleResponse"},"type":"array"}},"$id":"#/definitions/TicketList"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["id","name","type","status","created","modified","schema"],"x-embed":"","properties":{"artifacts":{"items":{"$ref":"#/definitions/Artifact"},"type":"array"},"comments":{"items":{"$ref":"#/definitions/Comment"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"type":"object"},"files":{"items":{"$ref":"#/definitions/File"},"type":"array"},"id":{"format":"int64","type":"integer"},"modified":{"format":"date-time","type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"playbooks":{"type":"object","additionalProperties":{"$ref":"#/definitions/PlaybookResponse"}},"read":{"items":{"type":"string"},"type":"array"},"references":{"items":{"$ref":"#/definitions/Reference"},"type":"array"},"schema":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"write":{"items":{"type":"string"},"type":"array"}},"$id":"#/definitions/TicketResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["id","name","type","status","created","modified","schema"],"x-embed":"","properties":{"artifacts":{"items":{"$ref":"#/definitions/Artifact"},"type":"array"},"comments":{"items":{"$ref":"#/definitions/Comment"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"type":"object"},"files":{"items":{"$ref":"#/definitions/File"},"type":"array"},"id":{"format":"int64","type":"integer"},"modified":{"format":"date-time","type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"playbooks":{"type":"object","additionalProperties":{"$ref":"#/definitions/Playbook"}},"read":{"items":{"type":"string"},"type":"array"},"references":{"items":{"$ref":"#/definitions/Reference"},"type":"array"},"schema":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"write":{"items":{"type":"string"},"type":"array"}},"$id":"#/definitions/TicketSimpleResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","schema"],"x-embed":"","properties":{"name":{"type":"string"},"schema":{"type":"string"}},"$id":"#/definitions/TicketTemplate"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","schema"],"x-embed":"","properties":{"id":{"type":"string"},"name":{"type":"string"},"schema":{"type":"string"}},"$id":"#/definitions/TicketTemplateForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["id","name","schema"],"x-embed":"","properties":{"id":{"type":"string"},"name":{"type":"string"},"schema":{"type":"string"}},"$id":"#/definitions/TicketTemplateResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","icon","default_template","default_playbooks"],"x-embed":"","properties":{"default_groups":{"items":{"type":"string"},"type":"array"},"default_playbooks":{"items":{"type":"string"},"type":"array"},"default_template":{"type":"string"},"icon":{"type":"string"},"name":{"type":"string"}},"$id":"#/definitions/TicketType"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","icon","default_template","default_playbooks"],"x-embed":"","properties":{"default_groups":{"items":{"type":"string"},"type":"array"},"default_playbooks":{"items":{"type":"string"},"type":"array"},"default_template":{"type":"string"},"icon":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"}},"$id":"#/definitions/TicketTypeForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["id","name","icon","default_template","default_playbooks"],"x-embed":"","properties":{"default_groups":{"items":{"type":"string"},"type":"array"},"default_playbooks":{"items":{"type":"string"},"type":"array"},"default_template":{"type":"string"},"icon":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"}},"$id":"#/definitions/TicketTypeResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["id","name","type","status","created","modified","schema"],"x-embed":"","properties":{"artifacts":{"items":{"$ref":"#/definitions/Artifact"},"type":"array"},"comments":{"items":{"$ref":"#/definitions/Comment"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"type":"object"},"files":{"items":{"$ref":"#/definitions/File"},"type":"array"},"id":{"format":"int64","type":"integer"},"logs":{"items":{"$ref":"#/definitions/LogEntry"},"type":"array"},"modified":{"format":"date-time","type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"playbooks":{"type":"object","additionalProperties":{"$ref":"#/definitions/PlaybookResponse"}},"read":{"items":{"type":"string"},"type":"array"},"references":{"items":{"$ref":"#/definitions/Reference"},"type":"array"},"schema":{"type":"string"},"status":{"type":"string"},"tickets":{"items":{"$ref":"#/definitions/TicketSimpleResponse"},"type":"array"},"type":{"type":"string"},"write":{"items":{"type":"string"},"type":"array"}},"$id":"#/definitions/TicketWithTickets"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["id","name","icon"],"x-embed":"","properties":{"color":{"title":"Color","type":"string","enum":["error","info","success","warning"]},"icon":{"title":"Icon (https://materialdesignicons.com)","type":"string"},"id":{"title":"ID","type":"string"},"name":{"title":"Name","type":"string"}},"$id":"#/definitions/Type"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["blocked","apikey","roles"],"x-embed":"","properties":{"apikey":{"type":"boolean"},"blocked":{"type":"boolean"},"roles":{"items":{"type":"string"},"type":"array"},"sha256":{"type":"string"}},"$id":"#/definitions/User"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","x-embed":"","properties":{"email":{"type":"string"},"image":{"type":"string"},"name":{"type":"string"},"timeformat":{"title":"Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)","type":"string"}},"$id":"#/definitions/UserData"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["id"],"x-embed":"","properties":{"email":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"name":{"type":"string"},"timeformat":{"title":"Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)","type":"string"}},"$id":"#/definitions/UserDataResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["id","blocked","roles","apikey"],"x-embed":"","properties":{"apikey":{"type":"boolean"},"blocked":{"type":"boolean"},"id":{"type":"string"},"roles":{"items":{"type":"string"},"type":"array"}},"$id":"#/definitions/UserForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","required":["id","blocked","roles","apikey"],"x-embed":"","properties":{"apikey":{"type":"boolean"},"blocked":{"type":"boolean"},"id":{"type":"string"},"roles":{"items":{"type":"string"},"type":"array"}},"$id":"#/definitions/UserResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"enrichments":{"type":"object","additionalProperties":{"$ref":"#/definitions/Enrichment"}},"name":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"}},"required":["name"],"$id":"#/definitions/Artifact"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"artifact":{"type":"string"},"ticket_id":{"format":"int64","type":"integer"}},"required":["ticket_id","artifact"],"$id":"#/definitions/ArtifactOrigin"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"image":{"type":"string"},"schema":{"type":"string"},"script":{"type":"string"},"type":{"items":{"type":"string","enum":["artifact","playbook","global"]},"type":"array"}},"required":["image","script","type"],"$id":"#/definitions/Automation"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"id":{"type":"string"},"image":{"type":"string"},"schema":{"type":"string"},"script":{"type":"string"},"type":{"items":{"type":"string","enum":["artifact","playbook","global"]},"type":"array"}},"required":["id","image","script","type"],"$id":"#/definitions/AutomationForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"id":{"type":"string"},"image":{"type":"string"},"schema":{"type":"string"},"script":{"type":"string"},"type":{"items":{"type":"string","enum":["artifact","playbook","global"]},"type":"array"}},"required":["id","image","script","type"],"$id":"#/definitions/AutomationResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"created":{"format":"date-time","type":"string"},"creator":{"type":"string"},"message":{"type":"string"}},"required":["creator","created","message"],"$id":"#/definitions/Comment"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"created":{"format":"date-time","type":"string"},"creator":{"type":"string"},"message":{"type":"string"}},"required":["message"],"$id":"#/definitions/CommentForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"artifact":{"$ref":"#/definitions/Artifact"},"playbook":{"$ref":"#/definitions/PlaybookResponse"},"task":{"$ref":"#/definitions/TaskResponse"},"ticket":{"$ref":"#/definitions/TicketResponse"}},"$id":"#/definitions/Context"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"created":{"format":"date-time","type":"string"},"data":{"type":"object"},"name":{"type":"string"}},"required":["name","data","created"],"$id":"#/definitions/Enrichment"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"data":{"type":"object"},"name":{"type":"string"}},"required":["name","data"],"$id":"#/definitions/EnrichmentForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"}},"required":["key","name"],"$id":"#/definitions/File"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"automation":{"type":"string"},"container":{"type":"string"},"log":{"type":"string"},"origin":{"$ref":"#/definitions/Origin"},"output":{"type":"object"},"payload":{},"running":{"type":"boolean"},"status":{"type":"string"}},"required":["automation","running","status"],"$id":"#/definitions/Job"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"automation":{"type":"string"},"origin":{"$ref":"#/definitions/Origin"},"payload":{}},"required":["automation"],"$id":"#/definitions/JobForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"automation":{"type":"string"},"container":{"type":"string"},"id":{"type":"string"},"log":{"type":"string"},"origin":{"$ref":"#/definitions/Origin"},"output":{"type":"object"},"payload":{},"status":{"type":"string"}},"required":["id","automation","status"],"$id":"#/definitions/JobResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"container":{"type":"string"},"log":{"type":"string"},"output":{"type":"object"},"running":{"type":"boolean"},"status":{"type":"string"}},"required":["running","status"],"$id":"#/definitions/JobUpdate"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"created":{"format":"date-time","type":"string"},"creator":{"type":"string"},"message":{"type":"string"},"reference":{"type":"string"},"type":{"type":"string"}},"required":["type","reference","creator","created","message"],"$id":"#/definitions/LogEntry"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"context":{"$ref":"#/definitions/Context"},"payload":{},"secrets":{"type":"object","additionalProperties":{"type":"string"}}},"$id":"#/definitions/Message"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"blocked":{"type":"boolean"},"id":{"type":"string"},"roles":{"items":{"type":"string"},"type":"array"},"secret":{"type":"string"}},"required":["id","blocked","roles"],"$id":"#/definitions/NewUserResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"artifact_origin":{"$ref":"#/definitions/ArtifactOrigin"},"task_origin":{"$ref":"#/definitions/TaskOrigin"}},"$id":"#/definitions/Origin"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"name":{"type":"string"},"tasks":{"type":"object","additionalProperties":{"$ref":"#/definitions/Task"}}},"required":["name","tasks"],"$id":"#/definitions/Playbook"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"name":{"type":"string"},"tasks":{"type":"object","additionalProperties":{"$ref":"#/definitions/TaskResponse"}}},"required":["name","tasks"],"$id":"#/definitions/PlaybookResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"name":{"type":"string"},"yaml":{"type":"string"}},"required":["name","yaml"],"$id":"#/definitions/PlaybookTemplate"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"id":{"type":"string"},"yaml":{"type":"string"}},"required":["yaml"],"$id":"#/definitions/PlaybookTemplateForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"yaml":{"type":"string"}},"required":["id","name","yaml"],"$id":"#/definitions/PlaybookTemplateResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"href":{"type":"string"},"name":{"type":"string"}},"required":["name","href"],"$id":"#/definitions/Reference"}`),
|
||||
gojsonschema.NewStringLoader(`{"items":{"$ref":"#/definitions/Reference"},"type":"array","$id":"#/definitions/ReferenceArray"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"artifactStates":{"title":"Artifact States","items":{"$ref":"#/definitions/Type"},"type":"array"},"roles":{"title":"Roles","items":{"type":"string"},"type":"array"},"ticketTypes":{"title":"Ticket Types","items":{"$ref":"#/definitions/TicketTypeResponse"},"type":"array"},"tier":{"title":"Tier","type":"string","enum":["community","enterprise"]},"timeformat":{"title":"Time Format","type":"string"},"version":{"title":"Version","type":"string"}},"required":["version","tier","timeformat","ticketTypes","artifactStates"],"$id":"#/definitions/Settings"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"open_tickets_per_user":{"type":"object","additionalProperties":{"type":"integer"}},"tickets_per_type":{"type":"object","additionalProperties":{"type":"integer"}},"tickets_per_week":{"type":"object","additionalProperties":{"type":"integer"}},"unassigned":{"type":"integer"}},"required":["unassigned","open_tickets_per_user","tickets_per_week","tickets_per_type"],"$id":"#/definitions/Statistics"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"automation":{"type":"string"},"closed":{"format":"date-time","type":"string"},"created":{"format":"date-time","type":"string"},"data":{"type":"object"},"done":{"type":"boolean"},"join":{"type":"boolean"},"name":{"type":"string"},"next":{"type":"object","additionalProperties":{"type":"string"}},"owner":{"type":"string"},"payload":{"type":"object","additionalProperties":{"type":"string"}},"schema":{"type":"object"},"type":{"type":"string","enum":["task","input","automation"]}},"required":["name","type","done","created"],"$id":"#/definitions/Task"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"playbook_id":{"type":"string"},"task_id":{"type":"string"},"ticket_id":{"format":"int64","type":"integer"}},"required":["ticket_id","playbook_id","task_id"],"$id":"#/definitions/TaskOrigin"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"active":{"type":"boolean"},"automation":{"type":"string"},"closed":{"format":"date-time","type":"string"},"created":{"format":"date-time","type":"string"},"data":{"type":"object"},"done":{"type":"boolean"},"join":{"type":"boolean"},"name":{"type":"string"},"next":{"type":"object","additionalProperties":{"type":"string"}},"order":{"format":"int64","type":"number"},"owner":{"type":"string"},"payload":{"type":"object","additionalProperties":{"type":"string"}},"schema":{"type":"object"},"type":{"type":"string","enum":["task","input","automation"]}},"required":["name","type","done","created","order","active"],"$id":"#/definitions/TaskResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"playbook_id":{"type":"string"},"playbook_name":{"type":"string"},"task":{"$ref":"#/definitions/TaskResponse"},"task_id":{"type":"string"},"ticket_id":{"format":"int64","type":"number"},"ticket_name":{"type":"string"}},"required":["ticket_id","ticket_name","playbook_id","playbook_name","task_id","task"],"$id":"#/definitions/TaskWithContext"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"artifacts":{"items":{"$ref":"#/definitions/Artifact"},"type":"array"},"comments":{"items":{"$ref":"#/definitions/Comment"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"type":"object"},"files":{"items":{"$ref":"#/definitions/File"},"type":"array"},"modified":{"format":"date-time","type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"playbooks":{"type":"object","additionalProperties":{"$ref":"#/definitions/Playbook"}},"read":{"items":{"type":"string"},"type":"array"},"references":{"items":{"$ref":"#/definitions/Reference"},"type":"array"},"schema":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"write":{"items":{"type":"string"},"type":"array"}},"required":["name","type","status","created","modified","schema"],"$id":"#/definitions/Ticket"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"artifacts":{"items":{"$ref":"#/definitions/Artifact"},"type":"array"},"comments":{"items":{"$ref":"#/definitions/Comment"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"type":"object"},"files":{"items":{"$ref":"#/definitions/File"},"type":"array"},"id":{"format":"int64","type":"integer"},"modified":{"format":"date-time","type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"playbooks":{"items":{"$ref":"#/definitions/PlaybookTemplateForm"},"type":"array"},"read":{"items":{"type":"string"},"type":"array"},"references":{"items":{"$ref":"#/definitions/Reference"},"type":"array"},"schema":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"write":{"items":{"type":"string"},"type":"array"}},"required":["name","type","status"],"$id":"#/definitions/TicketForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"items":{"$ref":"#/definitions/TicketForm"},"type":"array","$id":"#/definitions/TicketFormArray"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"count":{"type":"number"},"tickets":{"items":{"$ref":"#/definitions/TicketSimpleResponse"},"type":"array"}},"required":["tickets","count"],"$id":"#/definitions/TicketList"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"artifacts":{"items":{"$ref":"#/definitions/Artifact"},"type":"array"},"comments":{"items":{"$ref":"#/definitions/Comment"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"type":"object"},"files":{"items":{"$ref":"#/definitions/File"},"type":"array"},"id":{"format":"int64","type":"integer"},"modified":{"format":"date-time","type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"playbooks":{"type":"object","additionalProperties":{"$ref":"#/definitions/PlaybookResponse"}},"read":{"items":{"type":"string"},"type":"array"},"references":{"items":{"$ref":"#/definitions/Reference"},"type":"array"},"schema":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"write":{"items":{"type":"string"},"type":"array"}},"required":["id","name","type","status","created","modified","schema"],"$id":"#/definitions/TicketResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"artifacts":{"items":{"$ref":"#/definitions/Artifact"},"type":"array"},"comments":{"items":{"$ref":"#/definitions/Comment"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"type":"object"},"files":{"items":{"$ref":"#/definitions/File"},"type":"array"},"id":{"format":"int64","type":"integer"},"modified":{"format":"date-time","type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"playbooks":{"type":"object","additionalProperties":{"$ref":"#/definitions/Playbook"}},"read":{"items":{"type":"string"},"type":"array"},"references":{"items":{"$ref":"#/definitions/Reference"},"type":"array"},"schema":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"write":{"items":{"type":"string"},"type":"array"}},"required":["id","name","type","status","created","modified","schema"],"$id":"#/definitions/TicketSimpleResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"name":{"type":"string"},"schema":{"type":"string"}},"required":["name","schema"],"$id":"#/definitions/TicketTemplate"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"schema":{"type":"string"}},"required":["name","schema"],"$id":"#/definitions/TicketTemplateForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"schema":{"type":"string"}},"required":["id","name","schema"],"$id":"#/definitions/TicketTemplateResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"default_groups":{"items":{"type":"string"},"type":"array"},"default_playbooks":{"items":{"type":"string"},"type":"array"},"default_template":{"type":"string"},"icon":{"type":"string"},"name":{"type":"string"}},"required":["name","icon","default_template","default_playbooks"],"$id":"#/definitions/TicketType"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"default_groups":{"items":{"type":"string"},"type":"array"},"default_playbooks":{"items":{"type":"string"},"type":"array"},"default_template":{"type":"string"},"icon":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"}},"required":["name","icon","default_template","default_playbooks"],"$id":"#/definitions/TicketTypeForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"default_groups":{"items":{"type":"string"},"type":"array"},"default_playbooks":{"items":{"type":"string"},"type":"array"},"default_template":{"type":"string"},"icon":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name","icon","default_template","default_playbooks"],"$id":"#/definitions/TicketTypeResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"artifacts":{"items":{"$ref":"#/definitions/Artifact"},"type":"array"},"comments":{"items":{"$ref":"#/definitions/Comment"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"type":"object"},"files":{"items":{"$ref":"#/definitions/File"},"type":"array"},"id":{"format":"int64","type":"integer"},"logs":{"items":{"$ref":"#/definitions/LogEntry"},"type":"array"},"modified":{"format":"date-time","type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"playbooks":{"type":"object","additionalProperties":{"$ref":"#/definitions/PlaybookResponse"}},"read":{"items":{"type":"string"},"type":"array"},"references":{"items":{"$ref":"#/definitions/Reference"},"type":"array"},"schema":{"type":"string"},"status":{"type":"string"},"tickets":{"items":{"$ref":"#/definitions/TicketSimpleResponse"},"type":"array"},"type":{"type":"string"},"write":{"items":{"type":"string"},"type":"array"}},"required":["id","name","type","status","created","modified","schema"],"$id":"#/definitions/TicketWithTickets"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"color":{"title":"Color","type":"string","enum":["error","info","success","warning"]},"icon":{"title":"Icon (https://materialdesignicons.com)","type":"string"},"id":{"title":"ID","type":"string"},"name":{"title":"Name","type":"string"}},"required":["id","name","icon"],"$id":"#/definitions/Type"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"apikey":{"type":"boolean"},"blocked":{"type":"boolean"},"roles":{"items":{"type":"string"},"type":"array"},"sha256":{"type":"string"}},"required":["blocked","apikey","roles"],"$id":"#/definitions/User"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"email":{"type":"string"},"image":{"type":"string"},"name":{"type":"string"},"timeformat":{"title":"Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)","type":"string"}},"$id":"#/definitions/UserData"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"email":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"name":{"type":"string"},"timeformat":{"title":"Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)","type":"string"}},"required":["id"],"$id":"#/definitions/UserDataResponse"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"apikey":{"type":"boolean"},"blocked":{"type":"boolean"},"id":{"type":"string"},"roles":{"items":{"type":"string"},"type":"array"}},"required":["id","blocked","roles","apikey"],"$id":"#/definitions/UserForm"}`),
|
||||
gojsonschema.NewStringLoader(`{"type":"object","properties":{"apikey":{"type":"boolean"},"blocked":{"type":"boolean"},"id":{"type":"string"},"roles":{"items":{"type":"string"},"type":"array"}},"required":["id","blocked","roles","apikey"],"$id":"#/definitions/UserResponse"}`),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -131,6 +133,7 @@ func init() {
|
||||
JobSchema = mustCompile(`#/definitions/Job`)
|
||||
JobFormSchema = mustCompile(`#/definitions/JobForm`)
|
||||
JobResponseSchema = mustCompile(`#/definitions/JobResponse`)
|
||||
JobUpdateSchema = mustCompile(`#/definitions/JobUpdate`)
|
||||
LogEntrySchema = mustCompile(`#/definitions/LogEntry`)
|
||||
MessageSchema = mustCompile(`#/definitions/Message`)
|
||||
NewUserResponseSchema = mustCompile(`#/definitions/NewUserResponse`)
|
||||
@@ -141,15 +144,16 @@ func init() {
|
||||
PlaybookTemplateFormSchema = mustCompile(`#/definitions/PlaybookTemplateForm`)
|
||||
PlaybookTemplateResponseSchema = mustCompile(`#/definitions/PlaybookTemplateResponse`)
|
||||
ReferenceSchema = mustCompile(`#/definitions/Reference`)
|
||||
ReferenceArraySchema = mustCompile(`#/definitions/ReferenceArray`)
|
||||
SettingsSchema = mustCompile(`#/definitions/Settings`)
|
||||
StatisticsSchema = mustCompile(`#/definitions/Statistics`)
|
||||
TaskSchema = mustCompile(`#/definitions/Task`)
|
||||
TaskFormSchema = mustCompile(`#/definitions/TaskForm`)
|
||||
TaskOriginSchema = mustCompile(`#/definitions/TaskOrigin`)
|
||||
TaskResponseSchema = mustCompile(`#/definitions/TaskResponse`)
|
||||
TaskWithContextSchema = mustCompile(`#/definitions/TaskWithContext`)
|
||||
TicketSchema = mustCompile(`#/definitions/Ticket`)
|
||||
TicketFormSchema = mustCompile(`#/definitions/TicketForm`)
|
||||
TicketFormArraySchema = mustCompile(`#/definitions/TicketFormArray`)
|
||||
TicketListSchema = mustCompile(`#/definitions/TicketList`)
|
||||
TicketResponseSchema = mustCompile(`#/definitions/TicketResponse`)
|
||||
TicketSimpleResponseSchema = mustCompile(`#/definitions/TicketSimpleResponse`)
|
||||
@@ -266,6 +270,14 @@ type JobResponse struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type JobUpdate struct {
|
||||
Container *string `json:"container,omitempty"`
|
||||
Log *string `json:"log,omitempty"`
|
||||
Output map[string]interface{} `json:"output,omitempty"`
|
||||
Running bool `json:"running"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type LogEntry struct {
|
||||
Created time.Time `json:"created"`
|
||||
Creator string `json:"creator"`
|
||||
@@ -323,6 +335,8 @@ type Reference struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type ReferenceArray []*Reference
|
||||
|
||||
type Settings struct {
|
||||
ArtifactStates []*Type `json:"artifactStates"`
|
||||
Roles []string `json:"roles,omitempty"`
|
||||
@@ -354,21 +368,6 @@ type Task struct {
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type TaskForm struct {
|
||||
Automation *string `json:"automation,omitempty"`
|
||||
Closed *time.Time `json:"closed,omitempty"`
|
||||
Created *time.Time `json:"created,omitempty"`
|
||||
Data map[string]interface{} `json:"data,omitempty"`
|
||||
Done *bool `json:"done,omitempty"`
|
||||
Join *bool `json:"join,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Next map[string]string `json:"next,omitempty"`
|
||||
Owner *string `json:"owner,omitempty"`
|
||||
Payload map[string]string `json:"payload,omitempty"`
|
||||
Schema map[string]interface{} `json:"schema,omitempty"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type TaskOrigin struct {
|
||||
PlaybookId string `json:"playbook_id"`
|
||||
TaskId string `json:"task_id"`
|
||||
@@ -438,6 +437,8 @@ type TicketForm struct {
|
||||
Write []string `json:"write,omitempty"`
|
||||
}
|
||||
|
||||
type TicketFormArray []*TicketForm
|
||||
|
||||
type TicketList struct {
|
||||
Count int `json:"count"`
|
||||
Tickets []*TicketSimpleResponse `json:"tickets"`
|
||||
@@ -596,22 +597,6 @@ func mustCompile(uri string) *gojsonschema.Schema {
|
||||
return s
|
||||
}
|
||||
|
||||
func validate(s *gojsonschema.Schema, b []byte) error {
|
||||
res, err := s.Validate(gojsonschema.NewStringLoader(string(b)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(res.Errors()) > 0 {
|
||||
var l []string
|
||||
for _, e := range res.Errors() {
|
||||
l = append(l, e.String())
|
||||
}
|
||||
return fmt.Errorf("validation failed: %v", strings.Join(l, ", "))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
SettingsTierCommunity = "community"
|
||||
|
||||
@@ -623,12 +608,6 @@ const (
|
||||
|
||||
TaskTypeAutomation = "automation"
|
||||
|
||||
TaskFormTypeTask = "task"
|
||||
|
||||
TaskFormTypeInput = "input"
|
||||
|
||||
TaskFormTypeAutomation = "automation"
|
||||
|
||||
TaskResponseTypeTask = "task"
|
||||
|
||||
TaskResponseTypeInput = "input"
|
||||
|
||||
@@ -38,7 +38,7 @@ func (s *Service) GetJob(ctx context.Context, id string) (*model.JobResponse, er
|
||||
return s.database.JobGet(ctx, id)
|
||||
}
|
||||
|
||||
func (s *Service) UpdateJob(ctx context.Context, id string, job *model.Job) (doc *model.JobResponse, err error) {
|
||||
func (s *Service) UpdateJob(ctx context.Context, id string, job *model.JobUpdate) (doc *model.JobResponse, err error) {
|
||||
defer s.publishRequest(ctx, err, "UpdateJob", jobResponseID(doc))
|
||||
return s.database.JobUpdate(ctx, id, job)
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@ package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/SecurityBrewery/catalyst/database"
|
||||
"github.com/SecurityBrewery/catalyst/generated/api"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
)
|
||||
|
||||
@@ -63,8 +66,11 @@ func (s *Service) CreateTicket(ctx context.Context, form *model.TicketForm) (doc
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (s *Service) CreateTicketBatch(ctx context.Context, forms []*model.TicketForm) error {
|
||||
createdTickets, err := s.database.TicketBatchCreate(ctx, forms)
|
||||
func (s *Service) CreateTicketBatch(ctx context.Context, ticketFormArray *model.TicketFormArray) error {
|
||||
if ticketFormArray == nil {
|
||||
return &api.HTTPError{Status: http.StatusUnprocessableEntity, Internal: errors.New("no tickets given")}
|
||||
}
|
||||
createdTickets, err := s.database.TicketBatchCreate(ctx, *ticketFormArray)
|
||||
defer s.publishRequest(ctx, err, "CreateTicket", ticketIDs(createdTickets))
|
||||
return err
|
||||
}
|
||||
@@ -140,9 +146,14 @@ func (s *Service) RemoveTicketPlaybook(ctx context.Context, i int64, s2 string)
|
||||
return s.database.RemoveTicketPlaybook(ctx, i, s2)
|
||||
}
|
||||
|
||||
func (s *Service) SetTask(ctx context.Context, i int64, s3 string, s2 string, task *model.Task) (doc *model.TicketWithTickets, err error) {
|
||||
func (s *Service) SetTaskData(ctx context.Context, i int64, s3 string, s2 string, data map[string]interface{}) (doc *model.TicketWithTickets, err error) {
|
||||
defer s.publishRequest(ctx, err, "SetTask", ticketWithTicketsID(doc))
|
||||
return s.database.TaskUpdate(ctx, i, s3, s2, task)
|
||||
return s.database.TaskUpdateData(ctx, i, s3, s2, data)
|
||||
}
|
||||
|
||||
func (s *Service) SetTaskOwner(ctx context.Context, i int64, s3 string, s2 string, owner string) (doc *model.TicketWithTickets, err error) {
|
||||
defer s.publishRequest(ctx, err, "SetTask", ticketWithTicketsID(doc))
|
||||
return s.database.TaskUpdateOwner(ctx, i, s3, s2, owner)
|
||||
}
|
||||
|
||||
func (s *Service) CompleteTask(ctx context.Context, i int64, s3 string, s2 string, m map[string]interface{}) (doc *model.TicketWithTickets, err error) {
|
||||
@@ -155,9 +166,12 @@ func (s *Service) RunTask(ctx context.Context, i int64, s3 string, s2 string) (e
|
||||
return s.database.TaskRun(ctx, i, s3, s2)
|
||||
}
|
||||
|
||||
func (s *Service) SetReferences(ctx context.Context, i int64, references []*model.Reference) (doc *model.TicketWithTickets, err error) {
|
||||
func (s *Service) SetReferences(ctx context.Context, i int64, references *model.ReferenceArray) (doc *model.TicketWithTickets, err error) {
|
||||
if references == nil {
|
||||
return nil, &api.HTTPError{Status: http.StatusUnprocessableEntity, Internal: errors.New("no references given")}
|
||||
}
|
||||
defer s.publishRequest(ctx, err, "SetReferences", ticketID(i))
|
||||
return s.database.SetReferences(ctx, i, references)
|
||||
return s.database.SetReferences(ctx, i, *references)
|
||||
}
|
||||
|
||||
func (s *Service) SetSchema(ctx context.Context, i int64, s2 string) (doc *model.TicketWithTickets, err error) {
|
||||
|
||||
235
test/backup_test.go
Normal file
235
test/backup_test.go
Normal file
@@ -0,0 +1,235 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/SecurityBrewery/catalyst"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/pointer"
|
||||
)
|
||||
|
||||
func TestBackupAndRestore(t *testing.T) {
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
|
||||
type want struct {
|
||||
status int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
want want
|
||||
}{
|
||||
{name: "Backup", want: want{status: http.StatusOK}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ctx, _, server, err := Catalyst(t)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := SetupTestData(ctx, server.DB); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
createFile(ctx, server)
|
||||
|
||||
zipB := assertBackup(t, server)
|
||||
|
||||
assertZipFile(t, readZipFile(t, zipB))
|
||||
|
||||
clearAllDatabases(server)
|
||||
_, err = server.DB.UserCreateSetupAPIKey(ctx, "test")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
deleteAllBuckets(t, server)
|
||||
|
||||
assertRestore(t, zipB, server)
|
||||
|
||||
assertTicketExists(t, server)
|
||||
|
||||
assertFileExists(t, server)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func assertBackup(t *testing.T, server *catalyst.Server) []byte {
|
||||
// setup request
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/backup/create", nil)
|
||||
req.Header.Set("PRIVATE-TOKEN", "test")
|
||||
|
||||
// run request
|
||||
backupRequestRecorder := httptest.NewRecorder()
|
||||
server.Server.ServeHTTP(backupRequestRecorder, req)
|
||||
backupResult := backupRequestRecorder.Result()
|
||||
|
||||
// assert results
|
||||
assert.Equal(t, http.StatusOK, backupResult.StatusCode)
|
||||
|
||||
zipBuf := &bytes.Buffer{}
|
||||
if _, err := io.Copy(zipBuf, backupResult.Body); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.NoError(t, backupResult.Body.Close())
|
||||
|
||||
return zipBuf.Bytes()
|
||||
}
|
||||
|
||||
func assertZipFile(t *testing.T, r *zip.Reader) {
|
||||
var names []string
|
||||
for _, f := range r.File {
|
||||
names = append(names, f.Name)
|
||||
}
|
||||
|
||||
if !includes(t, names, "minio/catalyst-8125/test.txt") {
|
||||
t.Error("Minio file missing")
|
||||
}
|
||||
|
||||
for _, p := range []string{
|
||||
"arango/ENCRYPTION", "arango/automations_.*.data.json.gz", "arango/automations_.*.structure.json", "arango/dump.json", "arango/jobs_.*.data.json.gz", "arango/jobs_.*.structure.json", "arango/logs_.*.data.json.gz", "arango/logs_.*.structure.json", "arango/migrations_.*.data.json.gz", "arango/migrations_.*.structure.json", "arango/playbooks_.*.data.json.gz", "arango/playbooks_.*.structure.json", "arango/related_.*.data.json.gz", "arango/related_.*.structure.json", "arango/templates_.*.data.json.gz", "arango/templates_.*.structure.json", "arango/tickets_.*.data.json.gz", "arango/tickets_.*.structure.json", "arango/tickettypes_.*.data.json.gz", "arango/tickettypes_.*.structure.json", "arango/userdata_.*.data.json.gz", "arango/userdata_.*.structure.json", "arango/users_.*.data.json.gz", "arango/users_.*.structure.json",
|
||||
} {
|
||||
if !includes(t, names, p) {
|
||||
t.Errorf("Arango file missing: %s", p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func clearAllDatabases(server *catalyst.Server) {
|
||||
server.DB.Truncate(context.Background())
|
||||
}
|
||||
|
||||
func deleteAllBuckets(t *testing.T, server *catalyst.Server) {
|
||||
buckets, err := server.Storage.S3().ListBuckets(&s3.ListBucketsInput{})
|
||||
for _, bucket := range buckets.Buckets {
|
||||
server.Storage.S3().DeleteBucket(&s3.DeleteBucketInput{
|
||||
Bucket: bucket.Name,
|
||||
})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func assertRestore(t *testing.T, zipB []byte, server *catalyst.Server) {
|
||||
bodyBuf := &bytes.Buffer{}
|
||||
bodyWriter := multipart.NewWriter(bodyBuf)
|
||||
fileWriter, err := bodyWriter.CreateFormFile("backup", "backup.zip")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = fileWriter.Write(zipB)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
assert.NoError(t, bodyWriter.Close())
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/backup/restore", bodyBuf)
|
||||
req.Header.Set("PRIVATE-TOKEN", "test")
|
||||
req.Header.Set("Content-Type", bodyWriter.FormDataContentType())
|
||||
|
||||
// run request
|
||||
restoreRequestRecorder := httptest.NewRecorder()
|
||||
server.Server.ServeHTTP(restoreRequestRecorder, req)
|
||||
restoreResult := restoreRequestRecorder.Result()
|
||||
|
||||
if !assert.Equal(t, http.StatusOK, restoreResult.StatusCode) {
|
||||
b, _ := io.ReadAll(restoreResult.Body)
|
||||
log.Println(string(b))
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func createFile(ctx context.Context, server *catalyst.Server) {
|
||||
buf := bytes.NewBufferString("test text")
|
||||
|
||||
server.Storage.S3().CreateBucket(&s3.CreateBucketInput{Bucket: pointer.String("catalyst-8125")})
|
||||
|
||||
if _, err := server.Storage.Uploader().Upload(&s3manager.UploadInput{Body: buf, Bucket: pointer.String("catalyst-8125"), Key: pointer.String("test.txt")}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := server.DB.AddFile(ctx, 8125, &model.File{Key: "test.txt", Name: "test.txt"}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func assertTicketExists(t *testing.T, server *catalyst.Server) {
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/tickets/8125", nil)
|
||||
req.Header.Set("PRIVATE-TOKEN", "test")
|
||||
|
||||
// run request
|
||||
backupRequestRecorder := httptest.NewRecorder()
|
||||
server.Server.ServeHTTP(backupRequestRecorder, req)
|
||||
backupResult := backupRequestRecorder.Result()
|
||||
|
||||
// assert results
|
||||
assert.Equal(t, http.StatusOK, backupResult.StatusCode)
|
||||
|
||||
zipBuf := &bytes.Buffer{}
|
||||
if _, err := io.Copy(zipBuf, backupResult.Body); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.NoError(t, backupResult.Body.Close())
|
||||
|
||||
var ticket model.Ticket
|
||||
assert.NoError(t, json.Unmarshal(zipBuf.Bytes(), &ticket))
|
||||
|
||||
assert.Equal(t, "phishing from selenafadel@von.com detected", ticket.Name)
|
||||
}
|
||||
|
||||
func assertFileExists(t *testing.T, server *catalyst.Server) {
|
||||
obj, err := server.Storage.S3().GetObject(&s3.GetObjectInput{
|
||||
Bucket: aws.String("catalyst-8125"),
|
||||
Key: aws.String("test.txt"),
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
b, err := io.ReadAll(obj.Body)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "test text", string(b))
|
||||
}
|
||||
|
||||
func includes(t *testing.T, names []string, s string) bool {
|
||||
for _, name := range names {
|
||||
match, err := regexp.MatchString(s, name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if match {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func readZipFile(t *testing.T, b []byte) *zip.Reader {
|
||||
buf := bytes.NewReader(b)
|
||||
|
||||
zr, err := zip.NewReader(buf, int64(buf.Len()))
|
||||
if err != nil {
|
||||
t.Fatal(string(b), err)
|
||||
}
|
||||
|
||||
return zr
|
||||
}
|
||||
49
test/job_test.go
Normal file
49
test/job_test.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
)
|
||||
|
||||
func TestJob(t *testing.T) {
|
||||
_, _, _, _, _, _, _, server, cleanup, err := Server(t)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
// server.ConfigureRoutes()
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
// setup request
|
||||
var req *http.Request
|
||||
b, err := json.Marshal(model.JobForm{
|
||||
Automation: "hash.sha1",
|
||||
Origin: nil,
|
||||
Payload: nil,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
req = httptest.NewRequest(http.MethodPost, "/jobs", bytes.NewBuffer(b))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
// run request
|
||||
server.ServeHTTP(w, req)
|
||||
|
||||
result := w.Result()
|
||||
|
||||
// assert results
|
||||
if result.StatusCode != http.StatusNoContent {
|
||||
t.Fatalf("Status got = %v, want %v", result.Status, http.StatusNoContent)
|
||||
}
|
||||
// if tt.want.status != http.StatusNoContent {
|
||||
// jsonEqual(t, result.Body, tt.want.body)
|
||||
// }
|
||||
}
|
||||
@@ -1,31 +1,20 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/tidwall/sjson"
|
||||
|
||||
"github.com/SecurityBrewery/catalyst"
|
||||
"github.com/SecurityBrewery/catalyst/generated/api"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/pointer"
|
||||
ctime "github.com/SecurityBrewery/catalyst/time"
|
||||
)
|
||||
|
||||
@@ -75,7 +64,7 @@ func TestServer(t *testing.T) {
|
||||
if result.StatusCode != tt.Want.Status {
|
||||
msg, _ := io.ReadAll(result.Body)
|
||||
|
||||
t.Fatalf("Status got = %v, want %v: %s", result.Status, tt.Want.Status, msg)
|
||||
t.Fatalf("Status got = %v (%s), want %v", result.Status, msg, tt.Want.Status)
|
||||
}
|
||||
if tt.Want.Status != http.StatusNoContent {
|
||||
jsonEqual(t, result.Body, tt.Want.Body)
|
||||
@@ -84,276 +73,6 @@ func TestServer(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
type args struct {
|
||||
method string
|
||||
url string
|
||||
data interface{}
|
||||
}
|
||||
type want struct {
|
||||
status int
|
||||
body interface{}
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want want
|
||||
}{
|
||||
{name: "GetUser not existing", args: args{method: http.MethodGet, url: "/users/123"}, want: want{status: http.StatusNotFound, body: map[string]string{"error": "document not found"}}},
|
||||
{name: "ListUsers", args: args{method: http.MethodGet, url: "/users"}, want: want{status: http.StatusOK}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, _, _, _, _, _, _, server, cleanup, err := Server(t)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
// server.ConfigureRoutes()
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
// setup request
|
||||
var req *http.Request
|
||||
if tt.args.data != nil {
|
||||
b, err := json.Marshal(tt.args.data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
req = httptest.NewRequest(tt.args.method, tt.args.url, bytes.NewBuffer(b))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
} else {
|
||||
req = httptest.NewRequest(tt.args.method, tt.args.url, nil)
|
||||
}
|
||||
|
||||
// run request
|
||||
server.ServeHTTP(w, req)
|
||||
|
||||
result := w.Result()
|
||||
|
||||
// assert results
|
||||
if result.StatusCode != tt.want.status {
|
||||
t.Fatalf("Status got = %v, want %v", result.Status, tt.want.status)
|
||||
}
|
||||
if tt.want.status != http.StatusNoContent {
|
||||
jsonEqual(t, result.Body, tt.want.body)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackupAndRestore(t *testing.T) {
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
|
||||
type want struct {
|
||||
status int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
want want
|
||||
}{
|
||||
{name: "Backup", want: want{status: http.StatusOK}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ctx, _, server, err := Catalyst(t)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := SetupTestData(ctx, server.DB); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
createFile(ctx, server)
|
||||
|
||||
zipB := assertBackup(t, server)
|
||||
|
||||
assertZipFile(t, readZipFile(t, zipB))
|
||||
|
||||
clearAllDatabases(server)
|
||||
_, err = server.DB.UserCreateSetupAPIKey(ctx, "test")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
deleteAllBuckets(t, server)
|
||||
|
||||
assertRestore(t, zipB, server)
|
||||
|
||||
assertTicketExists(t, server)
|
||||
|
||||
assertFileExists(t, server)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func assertBackup(t *testing.T, server *catalyst.Server) []byte {
|
||||
// setup request
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/backup/create", nil)
|
||||
req.Header.Set("PRIVATE-TOKEN", "test")
|
||||
|
||||
// run request
|
||||
backupRequestRecorder := httptest.NewRecorder()
|
||||
server.Server.ServeHTTP(backupRequestRecorder, req)
|
||||
backupResult := backupRequestRecorder.Result()
|
||||
|
||||
// assert results
|
||||
assert.Equal(t, http.StatusOK, backupResult.StatusCode)
|
||||
|
||||
zipBuf := &bytes.Buffer{}
|
||||
if _, err := io.Copy(zipBuf, backupResult.Body); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.NoError(t, backupResult.Body.Close())
|
||||
|
||||
return zipBuf.Bytes()
|
||||
}
|
||||
|
||||
func assertZipFile(t *testing.T, r *zip.Reader) {
|
||||
var names []string
|
||||
for _, f := range r.File {
|
||||
names = append(names, f.Name)
|
||||
}
|
||||
|
||||
if !includes(t, names, "minio/catalyst-8125/test.txt") {
|
||||
t.Error("Minio file missing")
|
||||
}
|
||||
|
||||
for _, p := range []string{
|
||||
"arango/ENCRYPTION", "arango/automations_.*.data.json.gz", "arango/automations_.*.structure.json", "arango/dump.json", "arango/jobs_.*.data.json.gz", "arango/jobs_.*.structure.json", "arango/logs_.*.data.json.gz", "arango/logs_.*.structure.json", "arango/migrations_.*.data.json.gz", "arango/migrations_.*.structure.json", "arango/playbooks_.*.data.json.gz", "arango/playbooks_.*.structure.json", "arango/related_.*.data.json.gz", "arango/related_.*.structure.json", "arango/templates_.*.data.json.gz", "arango/templates_.*.structure.json", "arango/tickets_.*.data.json.gz", "arango/tickets_.*.structure.json", "arango/tickettypes_.*.data.json.gz", "arango/tickettypes_.*.structure.json", "arango/userdata_.*.data.json.gz", "arango/userdata_.*.structure.json", "arango/users_.*.data.json.gz", "arango/users_.*.structure.json",
|
||||
} {
|
||||
if !includes(t, names, p) {
|
||||
t.Errorf("Arango file missing: %s", p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func clearAllDatabases(server *catalyst.Server) {
|
||||
server.DB.Truncate(context.Background())
|
||||
}
|
||||
|
||||
func deleteAllBuckets(t *testing.T, server *catalyst.Server) {
|
||||
buckets, err := server.Storage.S3().ListBuckets(&s3.ListBucketsInput{})
|
||||
for _, bucket := range buckets.Buckets {
|
||||
server.Storage.S3().DeleteBucket(&s3.DeleteBucketInput{
|
||||
Bucket: bucket.Name,
|
||||
})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func assertRestore(t *testing.T, zipB []byte, server *catalyst.Server) {
|
||||
bodyBuf := &bytes.Buffer{}
|
||||
bodyWriter := multipart.NewWriter(bodyBuf)
|
||||
fileWriter, err := bodyWriter.CreateFormFile("backup", "backup.zip")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = fileWriter.Write(zipB)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
assert.NoError(t, bodyWriter.Close())
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/backup/restore", bodyBuf)
|
||||
req.Header.Set("PRIVATE-TOKEN", "test")
|
||||
req.Header.Set("Content-Type", bodyWriter.FormDataContentType())
|
||||
|
||||
// run request
|
||||
restoreRequestRecorder := httptest.NewRecorder()
|
||||
server.Server.ServeHTTP(restoreRequestRecorder, req)
|
||||
restoreResult := restoreRequestRecorder.Result()
|
||||
|
||||
if !assert.Equal(t, http.StatusOK, restoreResult.StatusCode) {
|
||||
b, _ := io.ReadAll(restoreResult.Body)
|
||||
log.Println(string(b))
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func createFile(ctx context.Context, server *catalyst.Server) {
|
||||
buf := bytes.NewBufferString("test text")
|
||||
|
||||
server.Storage.S3().CreateBucket(&s3.CreateBucketInput{Bucket: pointer.String("catalyst-8125")})
|
||||
|
||||
if _, err := server.Storage.Uploader().Upload(&s3manager.UploadInput{Body: buf, Bucket: pointer.String("catalyst-8125"), Key: pointer.String("test.txt")}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := server.DB.AddFile(ctx, 8125, &model.File{Key: "test.txt", Name: "test.txt"}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func assertTicketExists(t *testing.T, server *catalyst.Server) {
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/tickets/8125", nil)
|
||||
req.Header.Set("PRIVATE-TOKEN", "test")
|
||||
|
||||
// run request
|
||||
backupRequestRecorder := httptest.NewRecorder()
|
||||
server.Server.ServeHTTP(backupRequestRecorder, req)
|
||||
backupResult := backupRequestRecorder.Result()
|
||||
|
||||
// assert results
|
||||
assert.Equal(t, http.StatusOK, backupResult.StatusCode)
|
||||
|
||||
zipBuf := &bytes.Buffer{}
|
||||
if _, err := io.Copy(zipBuf, backupResult.Body); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.NoError(t, backupResult.Body.Close())
|
||||
|
||||
var ticket model.Ticket
|
||||
assert.NoError(t, json.Unmarshal(zipBuf.Bytes(), &ticket))
|
||||
|
||||
assert.Equal(t, "phishing from selenafadel@von.com detected", ticket.Name)
|
||||
}
|
||||
|
||||
func assertFileExists(t *testing.T, server *catalyst.Server) {
|
||||
obj, err := server.Storage.S3().GetObject(&s3.GetObjectInput{
|
||||
Bucket: aws.String("catalyst-8125"),
|
||||
Key: aws.String("test.txt"),
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
b, err := io.ReadAll(obj.Body)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "test text", string(b))
|
||||
}
|
||||
|
||||
func includes(t *testing.T, names []string, s string) bool {
|
||||
for _, name := range names {
|
||||
match, err := regexp.MatchString(s, name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if match {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func readZipFile(t *testing.T, b []byte) *zip.Reader {
|
||||
buf := bytes.NewReader(b)
|
||||
|
||||
zr, err := zip.NewReader(buf, int64(buf.Len()))
|
||||
if err != nil {
|
||||
t.Fatal(string(b), err)
|
||||
}
|
||||
|
||||
return zr
|
||||
}
|
||||
|
||||
func jsonEqual(t *testing.T, got io.Reader, want interface{}) {
|
||||
var gotObject, wantObject interface{}
|
||||
|
||||
|
||||
68
test/user_test.go
Normal file
68
test/user_test.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUser(t *testing.T) {
|
||||
type args struct {
|
||||
method string
|
||||
url string
|
||||
data interface{}
|
||||
}
|
||||
type want struct {
|
||||
status int
|
||||
body interface{}
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want want
|
||||
}{
|
||||
{name: "GetUser not existing", args: args{method: http.MethodGet, url: "/users/123"}, want: want{status: http.StatusNotFound, body: map[string]string{"error": "document not found"}}},
|
||||
{name: "ListUsers", args: args{method: http.MethodGet, url: "/users"}, want: want{status: http.StatusOK}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, _, _, _, _, _, _, server, cleanup, err := Server(t)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
// server.ConfigureRoutes()
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
// setup request
|
||||
var req *http.Request
|
||||
if tt.args.data != nil {
|
||||
b, err := json.Marshal(tt.args.data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
req = httptest.NewRequest(tt.args.method, tt.args.url, bytes.NewBuffer(b))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
} else {
|
||||
req = httptest.NewRequest(tt.args.method, tt.args.url, nil)
|
||||
}
|
||||
|
||||
// run request
|
||||
server.ServeHTTP(w, req)
|
||||
|
||||
result := w.Result()
|
||||
|
||||
// assert results
|
||||
if result.StatusCode != tt.want.status {
|
||||
t.Fatalf("Status got = %v, want %v", result.Status, tt.want.status)
|
||||
}
|
||||
if tt.want.status != http.StatusNoContent {
|
||||
jsonEqual(t, result.Body, tt.want.body)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
1533
ui/src/client/api.ts
1533
ui/src/client/api.ts
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,7 @@
|
||||
import { Configuration } from "./configuration";
|
||||
// Some imports not used depending on template conditions
|
||||
// @ts-ignore
|
||||
import globalAxios, { AxiosPromise, AxiosInstance } from 'axios';
|
||||
import globalAxios, { AxiosPromise, AxiosInstance, AxiosRequestConfig } from 'axios';
|
||||
|
||||
export const BASE_PATH = "http://./api".replace(/\/+$/, "");
|
||||
|
||||
@@ -38,7 +38,7 @@ export const COLLECTION_FORMATS = {
|
||||
*/
|
||||
export interface RequestArgs {
|
||||
url: string;
|
||||
options: any;
|
||||
options: AxiosRequestConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
|
||||
import { Configuration } from "./configuration";
|
||||
import { RequiredError, RequestArgs } from "./base";
|
||||
import { AxiosInstance } from 'axios';
|
||||
import { RequiredError, RequestArgs } from "./base";
|
||||
import { AxiosInstance, AxiosResponse } from 'axios';
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -131,8 +131,8 @@ export const toPathString = function (url: URL) {
|
||||
* @export
|
||||
*/
|
||||
export const createRequestFunction = function (axiosArgs: RequestArgs, globalAxios: AxiosInstance, BASE_PATH: string, configuration?: Configuration) {
|
||||
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||
return <T = unknown, R = AxiosResponse<T>>(axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||
const axiosRequestArgs = {...axiosArgs.options, url: (configuration?.basePath || basePath) + axiosArgs.url};
|
||||
return axios.request(axiosRequestArgs);
|
||||
return axios.request<T, R>(axiosRequestArgs);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -40,10 +40,10 @@ export default Vue.extend({
|
||||
return icon;
|
||||
},
|
||||
statusColor: function () {
|
||||
let color = TypeColorEnum.Info;
|
||||
let color = TypeColorEnum.Info as TypeColorEnum;
|
||||
this.lodash.forEach(this.$store.state.settings.artifactStates, (state: Type) => {
|
||||
if (this.artifact.status === state.id && state.color) {
|
||||
color = state.color
|
||||
color = state.color;
|
||||
}
|
||||
})
|
||||
return color;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated from CAQLLexer.g4 by ANTLR 4.9.2
|
||||
// Generated from CAQLLexer.g4 by ANTLR 4.9.3
|
||||
// jshint ignore: start
|
||||
import antlr4 from 'antlr4';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated from CAQLParser.g4 by ANTLR 4.9.2
|
||||
// Generated from CAQLParser.g4 by ANTLR 4.9.3
|
||||
// jshint ignore: start
|
||||
import antlr4 from 'antlr4';
|
||||
import CAQLParserListener from './CAQLParserListener.js';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated from CAQLParser.g4 by ANTLR 4.9.2
|
||||
// Generated from CAQLParser.g4 by ANTLR 4.9.3
|
||||
// jshint ignore: start
|
||||
import antlr4 from 'antlr4';
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@ export default Vue.extend({
|
||||
return icon;
|
||||
},
|
||||
statusColor: function (status: string) {
|
||||
let color = TypeColorEnum.Info;
|
||||
let color = TypeColorEnum.Info as TypeColorEnum;
|
||||
this.lodash.forEach(this.$store.state.settings.artifactStates, (state: Type) => {
|
||||
if (status === state.id && state.color) {
|
||||
color = state.color
|
||||
|
||||
@@ -152,7 +152,7 @@ export default Vue.extend({
|
||||
}
|
||||
},
|
||||
loadAutomations() {
|
||||
API.listAutomations(this.$route.params.id).then((response) => {
|
||||
API.listAutomations().then((response) => {
|
||||
this.automations = response.data;
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1145,30 +1145,13 @@ export default Vue.extend({
|
||||
this.selectedTask = undefined;
|
||||
this.selectedTaskPlaybook = undefined;
|
||||
},
|
||||
toTaskForm(task: TaskResponse): Task {
|
||||
return {
|
||||
automation: task.automation,
|
||||
closed: task.closed,
|
||||
created: task.created,
|
||||
data: task.data,
|
||||
done: task.done,
|
||||
join: task.join,
|
||||
payload: task.payload,
|
||||
name: task.name,
|
||||
next: task.next,
|
||||
owner: task.owner,
|
||||
schema: task.schema,
|
||||
type: task.type.toString() as TaskTypeEnum,
|
||||
} as Task
|
||||
},
|
||||
save(playbookID: string, taskID: string) {
|
||||
if (!this.ticket || !this.ticket.id || !this.ticket.playbooks) {
|
||||
return;
|
||||
}
|
||||
|
||||
let task = this.ticket.playbooks[playbookID].tasks[taskID]
|
||||
task.data = this.tdata[playbookID.toString() + "-" + taskID];
|
||||
API.setTask(this.ticket.id, playbookID, taskID, this.toTaskForm(task)).then((response) => {
|
||||
let data = this.tdata[playbookID.toString() + "-" + taskID];
|
||||
API.setTaskData(this.ticket.id, playbookID, taskID, data).then((response) => {
|
||||
this.$store.dispatch("alertSuccess", { name: "Task saved" });
|
||||
this.setTicket(response.data);
|
||||
});
|
||||
@@ -1181,9 +1164,7 @@ export default Vue.extend({
|
||||
return;
|
||||
}
|
||||
|
||||
let task = this.ticket.playbooks[playbookID].tasks[taskID]
|
||||
task.owner = owner
|
||||
API.setTask(this.ticket.id, playbookID, taskID, this.toTaskForm(task)).then((response) => {
|
||||
API.setTaskOwner(this.ticket.id, playbookID, taskID, owner).then((response) => {
|
||||
this.$store.dispatch("alertSuccess", { name: "Owner saved" });
|
||||
this.setTicket(response.data);
|
||||
if (response.data.playbooks) {
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
|
||||
import { NewUserResponse, UserResponse } from "../client";
|
||||
import { NewUserResponse, UserResponse } from "@/client";
|
||||
import {API} from "@/services/api";
|
||||
|
||||
interface State {
|
||||
|
||||
Reference in New Issue
Block a user