mirror of
https://github.com/SecurityBrewery/catalyst.git
synced 2026-04-25 12:07:48 +02:00
Check input schema (#33)
This commit is contained in:
+6
-8
@@ -47,14 +47,12 @@ func (h *busService) handleJob(automationMsg *bus.JobMsg) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := h.db.JobUpdate(ctx, automationMsg.ID, &model.Job{
|
if _, err := h.db.JobUpdate(ctx, automationMsg.ID, &model.JobUpdate{
|
||||||
Automation: job.Automation,
|
Container: &containerID,
|
||||||
Container: &containerID,
|
Running: true,
|
||||||
Origin: job.Origin,
|
Output: job.Output,
|
||||||
Output: job.Output,
|
Log: &logs,
|
||||||
Log: &logs,
|
Status: job.Status,
|
||||||
Payload: job.Payload,
|
|
||||||
Status: job.Status,
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return
|
||||||
|
|||||||
+11
-44
@@ -5,11 +5,9 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/arangodb/go-driver"
|
"github.com/arangodb/go-driver"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/xeipuuv/gojsonschema"
|
|
||||||
|
|
||||||
"github.com/SecurityBrewery/catalyst/bus"
|
"github.com/SecurityBrewery/catalyst/bus"
|
||||||
"github.com/SecurityBrewery/catalyst/caql"
|
"github.com/SecurityBrewery/catalyst/caql"
|
||||||
@@ -39,15 +37,19 @@ func (db *Database) toJobResponse(ctx context.Context, key string, doc *model.Jo
|
|||||||
if doc.Running {
|
if doc.Running {
|
||||||
inspect, err := cli.ContainerInspect(ctx, key)
|
inspect, err := cli.ContainerInspect(ctx, key)
|
||||||
if err != nil || inspect.State == nil {
|
if err != nil || inspect.State == nil {
|
||||||
doc.Running = false
|
|
||||||
if update {
|
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 {
|
} else if doc.Status != inspect.State.Status {
|
||||||
status = inspect.State.Status
|
status = inspect.State.Status
|
||||||
doc.Status = inspect.State.Status
|
|
||||||
if update {
|
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
|
var doc model.Job
|
||||||
newctx := driver.WithReturnNew(ctx, &doc)
|
newctx := driver.WithReturnNew(ctx, &doc)
|
||||||
|
|
||||||
/* Start validation */
|
meta, err := db.jobCollection.CreateDocument(ctx, newctx, id, toJob(job))
|
||||||
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)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
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
|
var doc model.Job
|
||||||
ctx = driver.WithReturnNew(ctx, &doc)
|
ctx = driver.WithReturnNew(ctx, &doc)
|
||||||
|
|
||||||
/* Start validation */
|
meta, err := db.jobCollection.UpdateDocument(ctx, id, job)
|
||||||
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)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-5
@@ -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)
|
ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
task.Created = time.Now().UTC()
|
|
||||||
|
|
||||||
query := `LET d = DOCUMENT(@@collection, @ID)
|
query := `LET d = DOCUMENT(@@collection, @ID)
|
||||||
` + ticketFilterQuery + `
|
` + ticketFilterQuery + `
|
||||||
LET playbook = d.playbooks[@playbookID]
|
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 newplaybook = MERGE(playbook, {"tasks": newtasks})
|
||||||
LET newplaybooks = MERGE(d.playbooks, { @playbookID: newplaybook } )
|
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{}{
|
ticket, err := db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{
|
||||||
"playbookID": playbookID,
|
"playbookID": playbookID,
|
||||||
"taskID": taskID,
|
"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(),
|
"now": time.Now().UTC(),
|
||||||
}, ticketFilterVars), &busdb.Operation{
|
}, ticketFilterVars), &busdb.Operation{
|
||||||
Type: bus.DatabaseEntryUpdated,
|
Type: bus.DatabaseEntryUpdated,
|
||||||
|
|||||||
@@ -191,6 +191,8 @@ func (db *Database) UserUpdate(ctx context.Context, id string, user *model.UserF
|
|||||||
|
|
||||||
ctx = driver.WithReturnNew(ctx, &doc)
|
ctx = driver.WithReturnNew(ctx, &doc)
|
||||||
|
|
||||||
|
user.ID = id
|
||||||
|
|
||||||
meta, err := db.userCollection.ReplaceDocument(ctx, id, toUser(user, nil))
|
meta, err := db.userCollection.ReplaceDocument(ctx, id, toUser(user, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
+11
-1
@@ -48,7 +48,7 @@ paths:
|
|||||||
operationId: "updateJob"
|
operationId: "updateJob"
|
||||||
parameters:
|
parameters:
|
||||||
- { name: "id", in: "path", description: "Job ID", required: true, type: string, x-example: "99cd67131b48" }
|
- { 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:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: "successful operation"
|
description: "successful operation"
|
||||||
@@ -103,6 +103,16 @@ definitions:
|
|||||||
payload: { }
|
payload: { }
|
||||||
origin: { $ref: "#/definitions/Origin" }
|
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:
|
Job:
|
||||||
type: object
|
type: object
|
||||||
required: [ automation, running, status ]
|
required: [ automation, running, status ]
|
||||||
|
|||||||
@@ -16,31 +16,6 @@ paths:
|
|||||||
security: [ { roles: [ "ticket:read" ] } ]
|
security: [ { roles: [ "ticket:read" ] } ]
|
||||||
|
|
||||||
definitions:
|
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:
|
Task:
|
||||||
type: object
|
type: object
|
||||||
required: [ name, type, done, created ]
|
required: [ name, type, done, created ]
|
||||||
|
|||||||
+57
-5
@@ -80,7 +80,7 @@ paths:
|
|||||||
summary: "Create a new tickets in batch"
|
summary: "Create a new tickets in batch"
|
||||||
operationId: "createTicketBatch"
|
operationId: "createTicketBatch"
|
||||||
parameters:
|
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:
|
responses:
|
||||||
"204": { description: "successful operation" }
|
"204": { description: "successful operation" }
|
||||||
security: [ { roles: [ "ticket:write" ] } ]
|
security: [ { roles: [ "ticket:write" ] } ]
|
||||||
@@ -336,7 +336,7 @@ paths:
|
|||||||
operationId: "setReferences"
|
operationId: "setReferences"
|
||||||
parameters:
|
parameters:
|
||||||
- { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8125 }
|
- { 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:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: "successful operation"
|
description: "successful operation"
|
||||||
@@ -583,13 +583,13 @@ paths:
|
|||||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}:
|
/tickets/{id}/playbooks/{playbookID}/task/{taskID}:
|
||||||
put:
|
put:
|
||||||
tags: [ "tickets" ]
|
tags: [ "tickets" ]
|
||||||
summary: "Set a ticket playbook task"
|
summary: "Set a ticket playbook task data"
|
||||||
operationId: "setTask"
|
operationId: "setTaskData"
|
||||||
parameters:
|
parameters:
|
||||||
- { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8123 }
|
- { 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: "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: "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:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: "successful operation"
|
description: "successful operation"
|
||||||
@@ -625,6 +625,51 @@ paths:
|
|||||||
- { name: "leadreintermediate.io", status: "malicious" }
|
- { name: "leadreintermediate.io", status: "malicious" }
|
||||||
security: [ { roles: [ "ticket:write" ] } ]
|
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:
|
/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete:
|
||||||
put:
|
put:
|
||||||
tags: [ "tickets" ]
|
tags: [ "tickets" ]
|
||||||
@@ -883,6 +928,9 @@ paths:
|
|||||||
security: [ { roles: [ "ticket:write" ] } ]
|
security: [ { roles: [ "ticket:write" ] } ]
|
||||||
|
|
||||||
definitions:
|
definitions:
|
||||||
|
TicketFormArray:
|
||||||
|
type: array
|
||||||
|
items: { $ref: "#/definitions/TicketForm" }
|
||||||
|
|
||||||
TicketForm:
|
TicketForm:
|
||||||
type: object
|
type: object
|
||||||
@@ -1035,6 +1083,10 @@ definitions:
|
|||||||
created: { type: string, format: "date-time" }
|
created: { type: string, format: "date-time" }
|
||||||
message: { type: string }
|
message: { type: string }
|
||||||
|
|
||||||
|
ReferenceArray:
|
||||||
|
type: array
|
||||||
|
items: { $ref: '#/definitions/Reference' }
|
||||||
|
|
||||||
Reference:
|
Reference:
|
||||||
type: object
|
type: object
|
||||||
required: [ name, href ]
|
required: [ name, href ]
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ paths:
|
|||||||
summary: "Create user"
|
summary: "Create user"
|
||||||
operationId: "createUser"
|
operationId: "createUser"
|
||||||
parameters:
|
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:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: "successful operation"
|
description: "successful operation"
|
||||||
@@ -62,7 +62,7 @@ paths:
|
|||||||
operationId: "updateUser"
|
operationId: "updateUser"
|
||||||
parameters:
|
parameters:
|
||||||
- { name: "id", in: "path", description: "Template ID", required: true, type: string, x-example: "bob" }
|
- { 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:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: "successful operation"
|
description: "successful operation"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
version: '2.2'
|
version: '2.4'
|
||||||
services:
|
services:
|
||||||
nginx:
|
nginx:
|
||||||
image: nginx:1.21
|
image: nginx:1.21
|
||||||
@@ -38,6 +38,7 @@ services:
|
|||||||
|
|
||||||
keycloak:
|
keycloak:
|
||||||
image: quay.io/keycloak/keycloak:14.0.0
|
image: quay.io/keycloak/keycloak:14.0.0
|
||||||
|
platform: linux/amd64
|
||||||
environment:
|
environment:
|
||||||
DB_VENDOR: POSTGRES
|
DB_VENDOR: POSTGRES
|
||||||
DB_ADDR: postgres
|
DB_ADDR: postgres
|
||||||
|
|||||||
+2
-7
@@ -18,12 +18,8 @@ mv generated/openapi.json generated/community.json
|
|||||||
openapi-generator generate -i generated/catalyst.yml -o generated -g openapi
|
openapi-generator generate -i generated/catalyst.yml -o generated -g openapi
|
||||||
mv generated/openapi.json generated/catalyst.json
|
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
|
echo generate server and tests
|
||||||
# go run ./generator/. ./generator
|
swagger-go-chi generated/community.yml generated
|
||||||
swachigo generated/community.yml generated
|
|
||||||
|
|
||||||
echo generate typescript client
|
echo generate typescript client
|
||||||
openapi-generator generate -i generated/catalyst.yml -o ui/src/client -g typescript-axios --artifact-version 1.0.0-SNAPSHOT
|
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 gen
|
||||||
rm -rf generated/models/old
|
rm -rf generated/models/old
|
||||||
rm -rf generated/.openapi-generator generated/.openapi-generator-ignore generated/README.md
|
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
|
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
|
go mod tidy
|
||||||
gci -w -local "github.com/SecurityBrewery/catalyst" .
|
gci write --Section Standard --Section Default --Section "Prefix(github.com/SecurityBrewery/catalyst)" .
|
||||||
|
|||||||
+651
-99
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
|
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
|
package parser // CAQLParser
|
||||||
|
|
||||||
@@ -332,6 +332,9 @@ func (s *ParseContext) ExitRule(listener antlr.ParseTreeListener) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *CAQLParser) Parse() (localctx IParseContext) {
|
func (p *CAQLParser) Parse() (localctx IParseContext) {
|
||||||
|
this := p
|
||||||
|
_ = this
|
||||||
|
|
||||||
localctx = NewParseContext(p, p.GetParserRuleContext(), p.GetState())
|
localctx = NewParseContext(p, p.GetParserRuleContext(), p.GetState())
|
||||||
p.EnterRule(localctx, 0, CAQLParserRULE_parse)
|
p.EnterRule(localctx, 0, CAQLParserRULE_parse)
|
||||||
|
|
||||||
@@ -587,6 +590,9 @@ func (p *CAQLParser) Expression() (localctx IExpressionContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *CAQLParser) expression(_p int) (localctx IExpressionContext) {
|
func (p *CAQLParser) expression(_p int) (localctx IExpressionContext) {
|
||||||
|
this := p
|
||||||
|
_ = this
|
||||||
|
|
||||||
var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext()
|
var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext()
|
||||||
_parentState := p.GetState()
|
_parentState := p.GetState()
|
||||||
localctx = NewExpressionContext(p, p.GetParserRuleContext(), _parentState)
|
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) {
|
func (p *CAQLParser) Operator_unary() (localctx IOperator_unaryContext) {
|
||||||
|
this := p
|
||||||
|
_ = this
|
||||||
|
|
||||||
localctx = NewOperator_unaryContext(p, p.GetParserRuleContext(), p.GetState())
|
localctx = NewOperator_unaryContext(p, p.GetParserRuleContext(), p.GetState())
|
||||||
p.EnterRule(localctx, 4, CAQLParserRULE_operator_unary)
|
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) {
|
func (p *CAQLParser) reference(_p int) (localctx IReferenceContext) {
|
||||||
|
this := p
|
||||||
|
_ = this
|
||||||
|
|
||||||
var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext()
|
var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext()
|
||||||
_parentState := p.GetState()
|
_parentState := p.GetState()
|
||||||
localctx = NewReferenceContext(p, p.GetParserRuleContext(), _parentState)
|
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) {
|
func (p *CAQLParser) Compound_value() (localctx ICompound_valueContext) {
|
||||||
|
this := p
|
||||||
|
_ = this
|
||||||
|
|
||||||
localctx = NewCompound_valueContext(p, p.GetParserRuleContext(), p.GetState())
|
localctx = NewCompound_valueContext(p, p.GetParserRuleContext(), p.GetState())
|
||||||
p.EnterRule(localctx, 8, CAQLParserRULE_compound_value)
|
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) {
|
func (p *CAQLParser) Function_call() (localctx IFunction_callContext) {
|
||||||
|
this := p
|
||||||
|
_ = this
|
||||||
|
|
||||||
localctx = NewFunction_callContext(p, p.GetParserRuleContext(), p.GetState())
|
localctx = NewFunction_callContext(p, p.GetParserRuleContext(), p.GetState())
|
||||||
p.EnterRule(localctx, 10, CAQLParserRULE_function_call)
|
p.EnterRule(localctx, 10, CAQLParserRULE_function_call)
|
||||||
var _la int
|
var _la int
|
||||||
@@ -1778,6 +1796,9 @@ func (s *Value_literalContext) ExitRule(listener antlr.ParseTreeListener) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *CAQLParser) Value_literal() (localctx IValue_literalContext) {
|
func (p *CAQLParser) Value_literal() (localctx IValue_literalContext) {
|
||||||
|
this := p
|
||||||
|
_ = this
|
||||||
|
|
||||||
localctx = NewValue_literalContext(p, p.GetParserRuleContext(), p.GetState())
|
localctx = NewValue_literalContext(p, p.GetParserRuleContext(), p.GetState())
|
||||||
p.EnterRule(localctx, 12, CAQLParserRULE_value_literal)
|
p.EnterRule(localctx, 12, CAQLParserRULE_value_literal)
|
||||||
var _la int
|
var _la int
|
||||||
@@ -1912,6 +1933,9 @@ func (s *ArrayContext) ExitRule(listener antlr.ParseTreeListener) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *CAQLParser) Array() (localctx IArrayContext) {
|
func (p *CAQLParser) Array() (localctx IArrayContext) {
|
||||||
|
this := p
|
||||||
|
_ = this
|
||||||
|
|
||||||
localctx = NewArrayContext(p, p.GetParserRuleContext(), p.GetState())
|
localctx = NewArrayContext(p, p.GetParserRuleContext(), p.GetState())
|
||||||
p.EnterRule(localctx, 14, CAQLParserRULE_array)
|
p.EnterRule(localctx, 14, CAQLParserRULE_array)
|
||||||
var _la int
|
var _la int
|
||||||
@@ -2087,6 +2111,9 @@ func (s *ObjectContext) ExitRule(listener antlr.ParseTreeListener) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *CAQLParser) Object() (localctx IObjectContext) {
|
func (p *CAQLParser) Object() (localctx IObjectContext) {
|
||||||
|
this := p
|
||||||
|
_ = this
|
||||||
|
|
||||||
localctx = NewObjectContext(p, p.GetParserRuleContext(), p.GetState())
|
localctx = NewObjectContext(p, p.GetParserRuleContext(), p.GetState())
|
||||||
p.EnterRule(localctx, 16, CAQLParserRULE_object)
|
p.EnterRule(localctx, 16, CAQLParserRULE_object)
|
||||||
var _la int
|
var _la int
|
||||||
@@ -2272,6 +2299,9 @@ func (s *Object_elementContext) ExitRule(listener antlr.ParseTreeListener) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *CAQLParser) Object_element() (localctx IObject_elementContext) {
|
func (p *CAQLParser) Object_element() (localctx IObject_elementContext) {
|
||||||
|
this := p
|
||||||
|
_ = this
|
||||||
|
|
||||||
localctx = NewObject_elementContext(p, p.GetParserRuleContext(), p.GetState())
|
localctx = NewObject_elementContext(p, p.GetParserRuleContext(), p.GetState())
|
||||||
p.EnterRule(localctx, 18, CAQLParserRULE_object_element)
|
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) {
|
func (p *CAQLParser) Object_element_name() (localctx IObject_element_nameContext) {
|
||||||
|
this := p
|
||||||
|
_ = this
|
||||||
|
|
||||||
localctx = NewObject_element_nameContext(p, p.GetParserRuleContext(), p.GetState())
|
localctx = NewObject_element_nameContext(p, p.GetParserRuleContext(), p.GetState())
|
||||||
p.EnterRule(localctx, 20, CAQLParserRULE_object_element_name)
|
p.EnterRule(localctx, 20, CAQLParserRULE_object_element_name)
|
||||||
var _la int
|
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 {
|
func (p *CAQLParser) Expression_Sempred(localctx antlr.RuleContext, predIndex int) bool {
|
||||||
|
this := p
|
||||||
|
_ = this
|
||||||
|
|
||||||
switch predIndex {
|
switch predIndex {
|
||||||
case 0:
|
case 0:
|
||||||
return p.Precpred(p.GetParserRuleContext(), 13)
|
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 {
|
func (p *CAQLParser) Reference_Sempred(localctx antlr.RuleContext, predIndex int) bool {
|
||||||
|
this := p
|
||||||
|
_ = this
|
||||||
|
|
||||||
switch predIndex {
|
switch predIndex {
|
||||||
case 13:
|
case 13:
|
||||||
return p.Precpred(p.GetParserRuleContext(), 2)
|
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
|
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
|
package parser // CAQLParser
|
||||||
|
|
||||||
|
|||||||
+271
-70
@@ -659,7 +659,7 @@
|
|||||||
"content" : {
|
"content" : {
|
||||||
"application/json" : {
|
"application/json" : {
|
||||||
"schema" : {
|
"schema" : {
|
||||||
"$ref" : "#/components/schemas/Job"
|
"$ref" : "#/components/schemas/JobUpdate"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3404,7 +3404,7 @@
|
|||||||
},
|
},
|
||||||
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}" : {
|
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}" : {
|
||||||
"put" : {
|
"put" : {
|
||||||
"operationId" : "setTask",
|
"operationId" : "setTaskData",
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
"description" : "Ticket ID",
|
"description" : "Ticket ID",
|
||||||
"example" : 8123,
|
"example" : 8123,
|
||||||
@@ -3438,11 +3438,11 @@
|
|||||||
"content" : {
|
"content" : {
|
||||||
"application/json" : {
|
"application/json" : {
|
||||||
"schema" : {
|
"schema" : {
|
||||||
"$ref" : "#/components/schemas/Task"
|
"type" : "object"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"description" : "Task",
|
"description" : "Task data",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"responses" : {
|
"responses" : {
|
||||||
@@ -3628,9 +3628,9 @@
|
|||||||
"security" : [ {
|
"security" : [ {
|
||||||
"roles" : [ "ticket:write" ]
|
"roles" : [ "ticket:write" ]
|
||||||
} ],
|
} ],
|
||||||
"summary" : "Set a ticket playbook task",
|
"summary" : "Set a ticket playbook task data",
|
||||||
"tags" : [ "tickets" ],
|
"tags" : [ "tickets" ],
|
||||||
"x-codegen-request-body-name" : "task"
|
"x-codegen-request-body-name" : "data"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete" : {
|
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete" : {
|
||||||
@@ -3865,6 +3865,235 @@
|
|||||||
"x-codegen-request-body-name" : "data"
|
"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" : {
|
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}/run" : {
|
||||||
"post" : {
|
"post" : {
|
||||||
"operationId" : "runTask",
|
"operationId" : "runTask",
|
||||||
@@ -3928,10 +4157,7 @@
|
|||||||
"content" : {
|
"content" : {
|
||||||
"application/json" : {
|
"application/json" : {
|
||||||
"schema" : {
|
"schema" : {
|
||||||
"items" : {
|
"$ref" : "#/components/schemas/ReferenceArray"
|
||||||
"$ref" : "#/components/schemas/Reference"
|
|
||||||
},
|
|
||||||
"type" : "array"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -4390,10 +4616,7 @@
|
|||||||
"content" : {
|
"content" : {
|
||||||
"application/json" : {
|
"application/json" : {
|
||||||
"schema" : {
|
"schema" : {
|
||||||
"items" : {
|
"$ref" : "#/components/schemas/TicketFormArray"
|
||||||
"$ref" : "#/components/schemas/TicketForm"
|
|
||||||
},
|
|
||||||
"type" : "array"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -5295,6 +5518,28 @@
|
|||||||
"required" : [ "automation", "id", "status" ],
|
"required" : [ "automation", "id", "status" ],
|
||||||
"type" : "object"
|
"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" : {
|
"Link" : {
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"id" : {
|
"id" : {
|
||||||
@@ -5478,6 +5723,12 @@
|
|||||||
"required" : [ "href", "name" ],
|
"required" : [ "href", "name" ],
|
||||||
"type" : "object"
|
"type" : "object"
|
||||||
},
|
},
|
||||||
|
"ReferenceArray" : {
|
||||||
|
"items" : {
|
||||||
|
"$ref" : "#/components/schemas/Reference"
|
||||||
|
},
|
||||||
|
"type" : "array"
|
||||||
|
},
|
||||||
"Rule" : {
|
"Rule" : {
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"condition" : {
|
"condition" : {
|
||||||
@@ -5655,62 +5906,6 @@
|
|||||||
"required" : [ "created", "done", "name", "type" ],
|
"required" : [ "created", "done", "name", "type" ],
|
||||||
"type" : "object"
|
"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" : {
|
"TaskOrigin" : {
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"playbook_id" : {
|
"playbook_id" : {
|
||||||
@@ -5992,6 +6187,12 @@
|
|||||||
"required" : [ "name", "status", "type" ],
|
"required" : [ "name", "status", "type" ],
|
||||||
"type" : "object"
|
"type" : "object"
|
||||||
},
|
},
|
||||||
|
"TicketFormArray" : {
|
||||||
|
"items" : {
|
||||||
|
"$ref" : "#/components/schemas/TicketForm"
|
||||||
|
},
|
||||||
|
"type" : "array"
|
||||||
|
},
|
||||||
"TicketList" : {
|
"TicketList" : {
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"count" : {
|
"count" : {
|
||||||
|
|||||||
+300
-80
@@ -288,6 +288,22 @@ definitions:
|
|||||||
- automation
|
- automation
|
||||||
- status
|
- status
|
||||||
type: object
|
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:
|
Link:
|
||||||
properties:
|
properties:
|
||||||
id:
|
id:
|
||||||
@@ -435,6 +451,10 @@ definitions:
|
|||||||
- name
|
- name
|
||||||
- href
|
- href
|
||||||
type: object
|
type: object
|
||||||
|
ReferenceArray:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/Reference'
|
||||||
|
type: array
|
||||||
Rule:
|
Rule:
|
||||||
properties:
|
properties:
|
||||||
condition:
|
condition:
|
||||||
@@ -584,51 +604,6 @@ definitions:
|
|||||||
- done
|
- done
|
||||||
- created
|
- created
|
||||||
type: object
|
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:
|
TaskOrigin:
|
||||||
properties:
|
properties:
|
||||||
playbook_id:
|
playbook_id:
|
||||||
@@ -861,6 +836,10 @@ definitions:
|
|||||||
- type
|
- type
|
||||||
- status
|
- status
|
||||||
type: object
|
type: object
|
||||||
|
TicketFormArray:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/TicketForm'
|
||||||
|
type: array
|
||||||
TicketList:
|
TicketList:
|
||||||
properties:
|
properties:
|
||||||
count:
|
count:
|
||||||
@@ -1899,11 +1878,9 @@ paths:
|
|||||||
name: job
|
name: job
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Job'
|
$ref: '#/definitions/JobUpdate'
|
||||||
x-example:
|
x-example:
|
||||||
automation: hash.sha1
|
running: false
|
||||||
id: 99cd67131b48
|
|
||||||
payload: test
|
|
||||||
status: failed
|
status: failed
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
@@ -5465,7 +5442,7 @@ paths:
|
|||||||
- tickets
|
- tickets
|
||||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}:
|
/tickets/{id}/playbooks/{playbookID}/task/{taskID}:
|
||||||
put:
|
put:
|
||||||
operationId: setTask
|
operationId: setTaskData
|
||||||
parameters:
|
parameters:
|
||||||
- description: Ticket ID
|
- description: Ticket ID
|
||||||
format: int64
|
format: int64
|
||||||
@@ -5486,33 +5463,14 @@ paths:
|
|||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
x-example: board
|
x-example: board
|
||||||
- description: Task
|
- description: Task data
|
||||||
in: body
|
in: body
|
||||||
name: task
|
name: data
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Task'
|
type: object
|
||||||
x-example:
|
x-example:
|
||||||
active: true
|
boardInvolved: 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
|
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: successful operation
|
description: successful operation
|
||||||
@@ -5742,7 +5700,7 @@ paths:
|
|||||||
security:
|
security:
|
||||||
- roles:
|
- roles:
|
||||||
- ticket:write
|
- ticket:write
|
||||||
summary: Set a ticket playbook task
|
summary: Set a ticket playbook task data
|
||||||
tags:
|
tags:
|
||||||
- tickets
|
- tickets
|
||||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete:
|
/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete:
|
||||||
@@ -6009,6 +5967,267 @@ paths:
|
|||||||
summary: Complete ticket playbook task
|
summary: Complete ticket playbook task
|
||||||
tags:
|
tags:
|
||||||
- tickets
|
- 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:
|
/tickets/{id}/playbooks/{playbookID}/task/{taskID}/run:
|
||||||
post:
|
post:
|
||||||
operationId: runTask
|
operationId: runTask
|
||||||
@@ -6057,9 +6276,7 @@ paths:
|
|||||||
name: references
|
name: references
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
items:
|
$ref: '#/definitions/ReferenceArray'
|
||||||
$ref: '#/definitions/Reference'
|
|
||||||
type: array
|
|
||||||
x-example:
|
x-example:
|
||||||
- href: http://www.leadscalable.biz/envisioneer
|
- href: http://www.leadscalable.biz/envisioneer
|
||||||
name: fund
|
name: fund
|
||||||
@@ -6486,9 +6703,7 @@ paths:
|
|||||||
name: ticket
|
name: ticket
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
items:
|
$ref: '#/definitions/TicketFormArray'
|
||||||
$ref: '#/definitions/TicketForm'
|
|
||||||
type: array
|
|
||||||
x-example:
|
x-example:
|
||||||
- id: 123
|
- id: 123
|
||||||
name: Wannacry infection
|
name: Wannacry infection
|
||||||
@@ -6825,6 +7040,8 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/UserForm'
|
$ref: '#/definitions/UserForm'
|
||||||
x-example:
|
x-example:
|
||||||
|
apikey: true
|
||||||
|
blocked: false
|
||||||
id: syncscript
|
id: syncscript
|
||||||
roles:
|
roles:
|
||||||
- analyst
|
- analyst
|
||||||
@@ -6939,6 +7156,9 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/UserForm'
|
$ref: '#/definitions/UserForm'
|
||||||
x-example:
|
x-example:
|
||||||
|
apikey: false
|
||||||
|
blocked: false
|
||||||
|
id: syncscript
|
||||||
roles:
|
roles:
|
||||||
- analyst
|
- analyst
|
||||||
- admin
|
- admin
|
||||||
|
|||||||
+271
-70
@@ -427,7 +427,7 @@
|
|||||||
"content" : {
|
"content" : {
|
||||||
"application/json" : {
|
"application/json" : {
|
||||||
"schema" : {
|
"schema" : {
|
||||||
"$ref" : "#/components/schemas/Job"
|
"$ref" : "#/components/schemas/JobUpdate"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2974,7 +2974,7 @@
|
|||||||
},
|
},
|
||||||
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}" : {
|
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}" : {
|
||||||
"put" : {
|
"put" : {
|
||||||
"operationId" : "setTask",
|
"operationId" : "setTaskData",
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
"description" : "Ticket ID",
|
"description" : "Ticket ID",
|
||||||
"example" : 8123,
|
"example" : 8123,
|
||||||
@@ -3008,11 +3008,11 @@
|
|||||||
"content" : {
|
"content" : {
|
||||||
"application/json" : {
|
"application/json" : {
|
||||||
"schema" : {
|
"schema" : {
|
||||||
"$ref" : "#/components/schemas/Task"
|
"type" : "object"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"description" : "Task",
|
"description" : "Task data",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"responses" : {
|
"responses" : {
|
||||||
@@ -3198,9 +3198,9 @@
|
|||||||
"security" : [ {
|
"security" : [ {
|
||||||
"roles" : [ "ticket:write" ]
|
"roles" : [ "ticket:write" ]
|
||||||
} ],
|
} ],
|
||||||
"summary" : "Set a ticket playbook task",
|
"summary" : "Set a ticket playbook task data",
|
||||||
"tags" : [ "tickets" ],
|
"tags" : [ "tickets" ],
|
||||||
"x-codegen-request-body-name" : "task"
|
"x-codegen-request-body-name" : "data"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete" : {
|
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete" : {
|
||||||
@@ -3435,6 +3435,235 @@
|
|||||||
"x-codegen-request-body-name" : "data"
|
"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" : {
|
"/tickets/{id}/playbooks/{playbookID}/task/{taskID}/run" : {
|
||||||
"post" : {
|
"post" : {
|
||||||
"operationId" : "runTask",
|
"operationId" : "runTask",
|
||||||
@@ -3498,10 +3727,7 @@
|
|||||||
"content" : {
|
"content" : {
|
||||||
"application/json" : {
|
"application/json" : {
|
||||||
"schema" : {
|
"schema" : {
|
||||||
"items" : {
|
"$ref" : "#/components/schemas/ReferenceArray"
|
||||||
"$ref" : "#/components/schemas/Reference"
|
|
||||||
},
|
|
||||||
"type" : "array"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3960,10 +4186,7 @@
|
|||||||
"content" : {
|
"content" : {
|
||||||
"application/json" : {
|
"application/json" : {
|
||||||
"schema" : {
|
"schema" : {
|
||||||
"items" : {
|
"$ref" : "#/components/schemas/TicketFormArray"
|
||||||
"$ref" : "#/components/schemas/TicketForm"
|
|
||||||
},
|
|
||||||
"type" : "array"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -4797,6 +5020,28 @@
|
|||||||
"required" : [ "automation", "id", "status" ],
|
"required" : [ "automation", "id", "status" ],
|
||||||
"type" : "object"
|
"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" : {
|
"LogEntry" : {
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"created" : {
|
"created" : {
|
||||||
@@ -4953,6 +5198,12 @@
|
|||||||
"required" : [ "href", "name" ],
|
"required" : [ "href", "name" ],
|
||||||
"type" : "object"
|
"type" : "object"
|
||||||
},
|
},
|
||||||
|
"ReferenceArray" : {
|
||||||
|
"items" : {
|
||||||
|
"$ref" : "#/components/schemas/Reference"
|
||||||
|
},
|
||||||
|
"type" : "array"
|
||||||
|
},
|
||||||
"Settings" : {
|
"Settings" : {
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"artifactStates" : {
|
"artifactStates" : {
|
||||||
@@ -5076,62 +5327,6 @@
|
|||||||
"required" : [ "created", "done", "name", "type" ],
|
"required" : [ "created", "done", "name", "type" ],
|
||||||
"type" : "object"
|
"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" : {
|
"TaskOrigin" : {
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"playbook_id" : {
|
"playbook_id" : {
|
||||||
@@ -5413,6 +5608,12 @@
|
|||||||
"required" : [ "name", "status", "type" ],
|
"required" : [ "name", "status", "type" ],
|
||||||
"type" : "object"
|
"type" : "object"
|
||||||
},
|
},
|
||||||
|
"TicketFormArray" : {
|
||||||
|
"items" : {
|
||||||
|
"$ref" : "#/components/schemas/TicketForm"
|
||||||
|
},
|
||||||
|
"type" : "array"
|
||||||
|
},
|
||||||
"TicketList" : {
|
"TicketList" : {
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"count" : {
|
"count" : {
|
||||||
|
|||||||
+300
-80
@@ -236,6 +236,22 @@ definitions:
|
|||||||
- automation
|
- automation
|
||||||
- status
|
- status
|
||||||
type: object
|
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:
|
LogEntry:
|
||||||
properties:
|
properties:
|
||||||
created:
|
created:
|
||||||
@@ -360,6 +376,10 @@ definitions:
|
|||||||
- name
|
- name
|
||||||
- href
|
- href
|
||||||
type: object
|
type: object
|
||||||
|
ReferenceArray:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/Reference'
|
||||||
|
type: array
|
||||||
Settings:
|
Settings:
|
||||||
properties:
|
properties:
|
||||||
artifactStates:
|
artifactStates:
|
||||||
@@ -465,51 +485,6 @@ definitions:
|
|||||||
- done
|
- done
|
||||||
- created
|
- created
|
||||||
type: object
|
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:
|
TaskOrigin:
|
||||||
properties:
|
properties:
|
||||||
playbook_id:
|
playbook_id:
|
||||||
@@ -742,6 +717,10 @@ definitions:
|
|||||||
- type
|
- type
|
||||||
- status
|
- status
|
||||||
type: object
|
type: object
|
||||||
|
TicketFormArray:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/TicketForm'
|
||||||
|
type: array
|
||||||
TicketList:
|
TicketList:
|
||||||
properties:
|
properties:
|
||||||
count:
|
count:
|
||||||
@@ -1628,11 +1607,9 @@ paths:
|
|||||||
name: job
|
name: job
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Job'
|
$ref: '#/definitions/JobUpdate'
|
||||||
x-example:
|
x-example:
|
||||||
automation: hash.sha1
|
running: false
|
||||||
id: 99cd67131b48
|
|
||||||
payload: test
|
|
||||||
status: failed
|
status: failed
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
@@ -5053,7 +5030,7 @@ paths:
|
|||||||
- tickets
|
- tickets
|
||||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}:
|
/tickets/{id}/playbooks/{playbookID}/task/{taskID}:
|
||||||
put:
|
put:
|
||||||
operationId: setTask
|
operationId: setTaskData
|
||||||
parameters:
|
parameters:
|
||||||
- description: Ticket ID
|
- description: Ticket ID
|
||||||
format: int64
|
format: int64
|
||||||
@@ -5074,33 +5051,14 @@ paths:
|
|||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
x-example: board
|
x-example: board
|
||||||
- description: Task
|
- description: Task data
|
||||||
in: body
|
in: body
|
||||||
name: task
|
name: data
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Task'
|
type: object
|
||||||
x-example:
|
x-example:
|
||||||
active: true
|
boardInvolved: 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
|
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: successful operation
|
description: successful operation
|
||||||
@@ -5330,7 +5288,7 @@ paths:
|
|||||||
security:
|
security:
|
||||||
- roles:
|
- roles:
|
||||||
- ticket:write
|
- ticket:write
|
||||||
summary: Set a ticket playbook task
|
summary: Set a ticket playbook task data
|
||||||
tags:
|
tags:
|
||||||
- tickets
|
- tickets
|
||||||
/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete:
|
/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete:
|
||||||
@@ -5597,6 +5555,267 @@ paths:
|
|||||||
summary: Complete ticket playbook task
|
summary: Complete ticket playbook task
|
||||||
tags:
|
tags:
|
||||||
- tickets
|
- 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:
|
/tickets/{id}/playbooks/{playbookID}/task/{taskID}/run:
|
||||||
post:
|
post:
|
||||||
operationId: runTask
|
operationId: runTask
|
||||||
@@ -5645,9 +5864,7 @@ paths:
|
|||||||
name: references
|
name: references
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
items:
|
$ref: '#/definitions/ReferenceArray'
|
||||||
$ref: '#/definitions/Reference'
|
|
||||||
type: array
|
|
||||||
x-example:
|
x-example:
|
||||||
- href: http://www.leadscalable.biz/envisioneer
|
- href: http://www.leadscalable.biz/envisioneer
|
||||||
name: fund
|
name: fund
|
||||||
@@ -6074,9 +6291,7 @@ paths:
|
|||||||
name: ticket
|
name: ticket
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
items:
|
$ref: '#/definitions/TicketFormArray'
|
||||||
$ref: '#/definitions/TicketForm'
|
|
||||||
type: array
|
|
||||||
x-example:
|
x-example:
|
||||||
- id: 123
|
- id: 123
|
||||||
name: Wannacry infection
|
name: Wannacry infection
|
||||||
@@ -6413,6 +6628,8 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/UserForm'
|
$ref: '#/definitions/UserForm'
|
||||||
x-example:
|
x-example:
|
||||||
|
apikey: true
|
||||||
|
blocked: false
|
||||||
id: syncscript
|
id: syncscript
|
||||||
roles:
|
roles:
|
||||||
- analyst
|
- analyst
|
||||||
@@ -6527,6 +6744,9 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/UserForm'
|
$ref: '#/definitions/UserForm'
|
||||||
x-example:
|
x-example:
|
||||||
|
apikey: false
|
||||||
|
blocked: false
|
||||||
|
id: syncscript
|
||||||
roles:
|
roles:
|
||||||
- analyst
|
- analyst
|
||||||
- admin
|
- admin
|
||||||
|
|||||||
+69
-90
@@ -1,8 +1,6 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/xeipuuv/gojsonschema"
|
"github.com/xeipuuv/gojsonschema"
|
||||||
@@ -24,6 +22,7 @@ var (
|
|||||||
JobSchema = new(gojsonschema.Schema)
|
JobSchema = new(gojsonschema.Schema)
|
||||||
JobFormSchema = new(gojsonschema.Schema)
|
JobFormSchema = new(gojsonschema.Schema)
|
||||||
JobResponseSchema = new(gojsonschema.Schema)
|
JobResponseSchema = new(gojsonschema.Schema)
|
||||||
|
JobUpdateSchema = new(gojsonschema.Schema)
|
||||||
LogEntrySchema = new(gojsonschema.Schema)
|
LogEntrySchema = new(gojsonschema.Schema)
|
||||||
MessageSchema = new(gojsonschema.Schema)
|
MessageSchema = new(gojsonschema.Schema)
|
||||||
NewUserResponseSchema = new(gojsonschema.Schema)
|
NewUserResponseSchema = new(gojsonschema.Schema)
|
||||||
@@ -34,15 +33,16 @@ var (
|
|||||||
PlaybookTemplateFormSchema = new(gojsonschema.Schema)
|
PlaybookTemplateFormSchema = new(gojsonschema.Schema)
|
||||||
PlaybookTemplateResponseSchema = new(gojsonschema.Schema)
|
PlaybookTemplateResponseSchema = new(gojsonschema.Schema)
|
||||||
ReferenceSchema = new(gojsonschema.Schema)
|
ReferenceSchema = new(gojsonschema.Schema)
|
||||||
|
ReferenceArraySchema = new(gojsonschema.Schema)
|
||||||
SettingsSchema = new(gojsonschema.Schema)
|
SettingsSchema = new(gojsonschema.Schema)
|
||||||
StatisticsSchema = new(gojsonschema.Schema)
|
StatisticsSchema = new(gojsonschema.Schema)
|
||||||
TaskSchema = new(gojsonschema.Schema)
|
TaskSchema = new(gojsonschema.Schema)
|
||||||
TaskFormSchema = new(gojsonschema.Schema)
|
|
||||||
TaskOriginSchema = new(gojsonschema.Schema)
|
TaskOriginSchema = new(gojsonschema.Schema)
|
||||||
TaskResponseSchema = new(gojsonschema.Schema)
|
TaskResponseSchema = new(gojsonschema.Schema)
|
||||||
TaskWithContextSchema = new(gojsonschema.Schema)
|
TaskWithContextSchema = new(gojsonschema.Schema)
|
||||||
TicketSchema = new(gojsonschema.Schema)
|
TicketSchema = new(gojsonschema.Schema)
|
||||||
TicketFormSchema = new(gojsonschema.Schema)
|
TicketFormSchema = new(gojsonschema.Schema)
|
||||||
|
TicketFormArraySchema = new(gojsonschema.Schema)
|
||||||
TicketListSchema = new(gojsonschema.Schema)
|
TicketListSchema = new(gojsonschema.Schema)
|
||||||
TicketResponseSchema = new(gojsonschema.Schema)
|
TicketResponseSchema = new(gojsonschema.Schema)
|
||||||
TicketSimpleResponseSchema = new(gojsonschema.Schema)
|
TicketSimpleResponseSchema = new(gojsonschema.Schema)
|
||||||
@@ -63,55 +63,57 @@ var (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
err := schemaLoader.AddSchemas(
|
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","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","required":["ticket_id","artifact"],"x-embed":"","properties":{"artifact":{"type":"string"},"ticket_id":{"format":"int64","type":"integer"}},"$id":"#/definitions/ArtifactOrigin"}`),
|
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","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","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","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","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","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","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","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","properties":{"created":{"format":"date-time","type":"string"},"creator":{"type":"string"},"message":{"type":"string"}},"required":["creator","created","message"],"$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","properties":{"created":{"format":"date-time","type":"string"},"creator":{"type":"string"},"message":{"type":"string"}},"required":["message"],"$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","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","properties":{"created":{"format":"date-time","type":"string"},"data":{"type":"object"},"name":{"type":"string"}},"required":["name","data","created"],"$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","properties":{"data":{"type":"object"},"name":{"type":"string"}},"required":["name","data"],"$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","properties":{"key":{"type":"string"},"name":{"type":"string"}},"required":["key","name"],"$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","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","required":["automation"],"x-embed":"","properties":{"automation":{"type":"string"},"origin":{"$ref":"#/definitions/Origin"},"payload":{}},"$id":"#/definitions/JobForm"}`),
|
gojsonschema.NewStringLoader(`{"type":"object","properties":{"automation":{"type":"string"},"origin":{"$ref":"#/definitions/Origin"},"payload":{}},"required":["automation"],"$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","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","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","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","x-embed":"","properties":{"context":{"$ref":"#/definitions/Context"},"payload":{},"secrets":{"type":"object","additionalProperties":{"type":"string"}}},"$id":"#/definitions/Message"}`),
|
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","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","properties":{"context":{"$ref":"#/definitions/Context"},"payload":{},"secrets":{"type":"object","additionalProperties":{"type":"string"}}},"$id":"#/definitions/Message"}`),
|
||||||
gojsonschema.NewStringLoader(`{"type":"object","x-embed":"","properties":{"artifact_origin":{"$ref":"#/definitions/ArtifactOrigin"},"task_origin":{"$ref":"#/definitions/TaskOrigin"}},"$id":"#/definitions/Origin"}`),
|
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","required":["name","tasks"],"x-embed":"","properties":{"name":{"type":"string"},"tasks":{"type":"object","additionalProperties":{"$ref":"#/definitions/Task"}}},"$id":"#/definitions/Playbook"}`),
|
gojsonschema.NewStringLoader(`{"type":"object","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/TaskResponse"}}},"$id":"#/definitions/PlaybookResponse"}`),
|
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","required":["name","yaml"],"x-embed":"","properties":{"name":{"type":"string"},"yaml":{"type":"string"}},"$id":"#/definitions/PlaybookTemplate"}`),
|
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","required":["yaml"],"x-embed":"","properties":{"id":{"type":"string"},"yaml":{"type":"string"}},"$id":"#/definitions/PlaybookTemplateForm"}`),
|
gojsonschema.NewStringLoader(`{"type":"object","properties":{"name":{"type":"string"},"yaml":{"type":"string"}},"required":["name","yaml"],"$id":"#/definitions/PlaybookTemplate"}`),
|
||||||
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","properties":{"id":{"type":"string"},"yaml":{"type":"string"}},"required":["yaml"],"$id":"#/definitions/PlaybookTemplateForm"}`),
|
||||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","href"],"x-embed":"","properties":{"href":{"type":"string"},"name":{"type":"string"}},"$id":"#/definitions/Reference"}`),
|
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","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","properties":{"href":{"type":"string"},"name":{"type":"string"}},"required":["name","href"],"$id":"#/definitions/Reference"}`),
|
||||||
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(`{"items":{"$ref":"#/definitions/Reference"},"type":"array","$id":"#/definitions/ReferenceArray"}`),
|
||||||
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","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","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","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","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","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","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","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","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","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","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","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","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","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","required":["tickets","count"],"x-embed":"","properties":{"count":{"type":"number"},"tickets":{"items":{"$ref":"#/definitions/TicketSimpleResponse"},"type":"array"}},"$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":{"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(`{"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(`{"items":{"$ref":"#/definitions/TicketForm"},"type":"array","$id":"#/definitions/TicketFormArray"}`),
|
||||||
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","properties":{"count":{"type":"number"},"tickets":{"items":{"$ref":"#/definitions/TicketSimpleResponse"},"type":"array"}},"required":["tickets","count"],"$id":"#/definitions/TicketList"}`),
|
||||||
gojsonschema.NewStringLoader(`{"type":"object","required":["name","schema"],"x-embed":"","properties":{"name":{"type":"string"},"schema":{"type":"string"}},"$id":"#/definitions/TicketTemplate"}`),
|
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","required":["name","schema"],"x-embed":"","properties":{"id":{"type":"string"},"name":{"type":"string"},"schema":{"type":"string"}},"$id":"#/definitions/TicketTemplateForm"}`),
|
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","required":["id","name","schema"],"x-embed":"","properties":{"id":{"type":"string"},"name":{"type":"string"},"schema":{"type":"string"}},"$id":"#/definitions/TicketTemplateResponse"}`),
|
gojsonschema.NewStringLoader(`{"type":"object","properties":{"name":{"type":"string"},"schema":{"type":"string"}},"required":["name","schema"],"$id":"#/definitions/TicketTemplate"}`),
|
||||||
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","properties":{"id":{"type":"string"},"name":{"type":"string"},"schema":{"type":"string"}},"required":["name","schema"],"$id":"#/definitions/TicketTemplateForm"}`),
|
||||||
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","properties":{"id":{"type":"string"},"name":{"type":"string"},"schema":{"type":"string"}},"required":["id","name","schema"],"$id":"#/definitions/TicketTemplateResponse"}`),
|
||||||
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","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","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","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","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","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","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","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","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","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","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","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","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","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","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":{"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 {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -131,6 +133,7 @@ func init() {
|
|||||||
JobSchema = mustCompile(`#/definitions/Job`)
|
JobSchema = mustCompile(`#/definitions/Job`)
|
||||||
JobFormSchema = mustCompile(`#/definitions/JobForm`)
|
JobFormSchema = mustCompile(`#/definitions/JobForm`)
|
||||||
JobResponseSchema = mustCompile(`#/definitions/JobResponse`)
|
JobResponseSchema = mustCompile(`#/definitions/JobResponse`)
|
||||||
|
JobUpdateSchema = mustCompile(`#/definitions/JobUpdate`)
|
||||||
LogEntrySchema = mustCompile(`#/definitions/LogEntry`)
|
LogEntrySchema = mustCompile(`#/definitions/LogEntry`)
|
||||||
MessageSchema = mustCompile(`#/definitions/Message`)
|
MessageSchema = mustCompile(`#/definitions/Message`)
|
||||||
NewUserResponseSchema = mustCompile(`#/definitions/NewUserResponse`)
|
NewUserResponseSchema = mustCompile(`#/definitions/NewUserResponse`)
|
||||||
@@ -141,15 +144,16 @@ func init() {
|
|||||||
PlaybookTemplateFormSchema = mustCompile(`#/definitions/PlaybookTemplateForm`)
|
PlaybookTemplateFormSchema = mustCompile(`#/definitions/PlaybookTemplateForm`)
|
||||||
PlaybookTemplateResponseSchema = mustCompile(`#/definitions/PlaybookTemplateResponse`)
|
PlaybookTemplateResponseSchema = mustCompile(`#/definitions/PlaybookTemplateResponse`)
|
||||||
ReferenceSchema = mustCompile(`#/definitions/Reference`)
|
ReferenceSchema = mustCompile(`#/definitions/Reference`)
|
||||||
|
ReferenceArraySchema = mustCompile(`#/definitions/ReferenceArray`)
|
||||||
SettingsSchema = mustCompile(`#/definitions/Settings`)
|
SettingsSchema = mustCompile(`#/definitions/Settings`)
|
||||||
StatisticsSchema = mustCompile(`#/definitions/Statistics`)
|
StatisticsSchema = mustCompile(`#/definitions/Statistics`)
|
||||||
TaskSchema = mustCompile(`#/definitions/Task`)
|
TaskSchema = mustCompile(`#/definitions/Task`)
|
||||||
TaskFormSchema = mustCompile(`#/definitions/TaskForm`)
|
|
||||||
TaskOriginSchema = mustCompile(`#/definitions/TaskOrigin`)
|
TaskOriginSchema = mustCompile(`#/definitions/TaskOrigin`)
|
||||||
TaskResponseSchema = mustCompile(`#/definitions/TaskResponse`)
|
TaskResponseSchema = mustCompile(`#/definitions/TaskResponse`)
|
||||||
TaskWithContextSchema = mustCompile(`#/definitions/TaskWithContext`)
|
TaskWithContextSchema = mustCompile(`#/definitions/TaskWithContext`)
|
||||||
TicketSchema = mustCompile(`#/definitions/Ticket`)
|
TicketSchema = mustCompile(`#/definitions/Ticket`)
|
||||||
TicketFormSchema = mustCompile(`#/definitions/TicketForm`)
|
TicketFormSchema = mustCompile(`#/definitions/TicketForm`)
|
||||||
|
TicketFormArraySchema = mustCompile(`#/definitions/TicketFormArray`)
|
||||||
TicketListSchema = mustCompile(`#/definitions/TicketList`)
|
TicketListSchema = mustCompile(`#/definitions/TicketList`)
|
||||||
TicketResponseSchema = mustCompile(`#/definitions/TicketResponse`)
|
TicketResponseSchema = mustCompile(`#/definitions/TicketResponse`)
|
||||||
TicketSimpleResponseSchema = mustCompile(`#/definitions/TicketSimpleResponse`)
|
TicketSimpleResponseSchema = mustCompile(`#/definitions/TicketSimpleResponse`)
|
||||||
@@ -266,6 +270,14 @@ type JobResponse struct {
|
|||||||
Status string `json:"status"`
|
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 {
|
type LogEntry struct {
|
||||||
Created time.Time `json:"created"`
|
Created time.Time `json:"created"`
|
||||||
Creator string `json:"creator"`
|
Creator string `json:"creator"`
|
||||||
@@ -323,6 +335,8 @@ type Reference struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ReferenceArray []*Reference
|
||||||
|
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
ArtifactStates []*Type `json:"artifactStates"`
|
ArtifactStates []*Type `json:"artifactStates"`
|
||||||
Roles []string `json:"roles,omitempty"`
|
Roles []string `json:"roles,omitempty"`
|
||||||
@@ -354,21 +368,6 @@ type Task struct {
|
|||||||
Type string `json:"type"`
|
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 {
|
type TaskOrigin struct {
|
||||||
PlaybookId string `json:"playbook_id"`
|
PlaybookId string `json:"playbook_id"`
|
||||||
TaskId string `json:"task_id"`
|
TaskId string `json:"task_id"`
|
||||||
@@ -438,6 +437,8 @@ type TicketForm struct {
|
|||||||
Write []string `json:"write,omitempty"`
|
Write []string `json:"write,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TicketFormArray []*TicketForm
|
||||||
|
|
||||||
type TicketList struct {
|
type TicketList struct {
|
||||||
Count int `json:"count"`
|
Count int `json:"count"`
|
||||||
Tickets []*TicketSimpleResponse `json:"tickets"`
|
Tickets []*TicketSimpleResponse `json:"tickets"`
|
||||||
@@ -596,22 +597,6 @@ func mustCompile(uri string) *gojsonschema.Schema {
|
|||||||
return s
|
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 (
|
const (
|
||||||
SettingsTierCommunity = "community"
|
SettingsTierCommunity = "community"
|
||||||
|
|
||||||
@@ -623,12 +608,6 @@ const (
|
|||||||
|
|
||||||
TaskTypeAutomation = "automation"
|
TaskTypeAutomation = "automation"
|
||||||
|
|
||||||
TaskFormTypeTask = "task"
|
|
||||||
|
|
||||||
TaskFormTypeInput = "input"
|
|
||||||
|
|
||||||
TaskFormTypeAutomation = "automation"
|
|
||||||
|
|
||||||
TaskResponseTypeTask = "task"
|
TaskResponseTypeTask = "task"
|
||||||
|
|
||||||
TaskResponseTypeInput = "input"
|
TaskResponseTypeInput = "input"
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ func (s *Service) GetJob(ctx context.Context, id string) (*model.JobResponse, er
|
|||||||
return s.database.JobGet(ctx, id)
|
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))
|
defer s.publishRequest(ctx, err, "UpdateJob", jobResponseID(doc))
|
||||||
return s.database.JobUpdate(ctx, id, job)
|
return s.database.JobUpdate(ctx, id, job)
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-6
@@ -2,12 +2,15 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/arangodb/go-driver"
|
"github.com/arangodb/go-driver"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
|
||||||
"github.com/SecurityBrewery/catalyst/database"
|
"github.com/SecurityBrewery/catalyst/database"
|
||||||
|
"github.com/SecurityBrewery/catalyst/generated/api"
|
||||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -63,8 +66,11 @@ func (s *Service) CreateTicket(ctx context.Context, form *model.TicketForm) (doc
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) CreateTicketBatch(ctx context.Context, forms []*model.TicketForm) error {
|
func (s *Service) CreateTicketBatch(ctx context.Context, ticketFormArray *model.TicketFormArray) error {
|
||||||
createdTickets, err := s.database.TicketBatchCreate(ctx, forms)
|
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))
|
defer s.publishRequest(ctx, err, "CreateTicket", ticketIDs(createdTickets))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -140,9 +146,14 @@ func (s *Service) RemoveTicketPlaybook(ctx context.Context, i int64, s2 string)
|
|||||||
return s.database.RemoveTicketPlaybook(ctx, i, s2)
|
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))
|
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) {
|
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)
|
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))
|
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) {
|
func (s *Service) SetSchema(ctx context.Context, i int64, s2 string) (doc *model.TicketWithTickets, err error) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
-282
@@ -1,31 +1,20 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/zip"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"mime/multipart"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"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/stretchr/testify/assert"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
"github.com/tidwall/sjson"
|
"github.com/tidwall/sjson"
|
||||||
|
|
||||||
"github.com/SecurityBrewery/catalyst"
|
|
||||||
"github.com/SecurityBrewery/catalyst/generated/api"
|
"github.com/SecurityBrewery/catalyst/generated/api"
|
||||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
|
||||||
"github.com/SecurityBrewery/catalyst/pointer"
|
|
||||||
ctime "github.com/SecurityBrewery/catalyst/time"
|
ctime "github.com/SecurityBrewery/catalyst/time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -75,7 +64,7 @@ func TestServer(t *testing.T) {
|
|||||||
if result.StatusCode != tt.Want.Status {
|
if result.StatusCode != tt.Want.Status {
|
||||||
msg, _ := io.ReadAll(result.Body)
|
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 {
|
if tt.Want.Status != http.StatusNoContent {
|
||||||
jsonEqual(t, result.Body, tt.Want.Body)
|
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{}) {
|
func jsonEqual(t *testing.T, got io.Reader, want interface{}) {
|
||||||
var gotObject, wantObject interface{}
|
var gotObject, wantObject interface{}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
+778
-755
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,7 @@
|
|||||||
import { Configuration } from "./configuration";
|
import { Configuration } from "./configuration";
|
||||||
// Some imports not used depending on template conditions
|
// Some imports not used depending on template conditions
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import globalAxios, { AxiosPromise, AxiosInstance } from 'axios';
|
import globalAxios, { AxiosPromise, AxiosInstance, AxiosRequestConfig } from 'axios';
|
||||||
|
|
||||||
export const BASE_PATH = "http://./api".replace(/\/+$/, "");
|
export const BASE_PATH = "http://./api".replace(/\/+$/, "");
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ export const COLLECTION_FORMATS = {
|
|||||||
*/
|
*/
|
||||||
export interface RequestArgs {
|
export interface RequestArgs {
|
||||||
url: string;
|
url: string;
|
||||||
options: any;
|
options: AxiosRequestConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
|
|
||||||
import { Configuration } from "./configuration";
|
import { Configuration } from "./configuration";
|
||||||
import { RequiredError, RequestArgs } from "./base";
|
import { RequiredError, RequestArgs } from "./base";
|
||||||
import { AxiosInstance } from 'axios';
|
import { AxiosInstance, AxiosResponse } from 'axios';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -131,8 +131,8 @@ export const toPathString = function (url: URL) {
|
|||||||
* @export
|
* @export
|
||||||
*/
|
*/
|
||||||
export const createRequestFunction = function (axiosArgs: RequestArgs, globalAxios: AxiosInstance, BASE_PATH: string, configuration?: Configuration) {
|
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};
|
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;
|
return icon;
|
||||||
},
|
},
|
||||||
statusColor: function () {
|
statusColor: function () {
|
||||||
let color = TypeColorEnum.Info;
|
let color = TypeColorEnum.Info as TypeColorEnum;
|
||||||
this.lodash.forEach(this.$store.state.settings.artifactStates, (state: Type) => {
|
this.lodash.forEach(this.$store.state.settings.artifactStates, (state: Type) => {
|
||||||
if (this.artifact.status === state.id && state.color) {
|
if (this.artifact.status === state.id && state.color) {
|
||||||
color = state.color
|
color = state.color;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return 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
|
// jshint ignore: start
|
||||||
import antlr4 from 'antlr4';
|
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
|
// jshint ignore: start
|
||||||
import antlr4 from 'antlr4';
|
import antlr4 from 'antlr4';
|
||||||
import CAQLParserListener from './CAQLParserListener.js';
|
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
|
// jshint ignore: start
|
||||||
import antlr4 from 'antlr4';
|
import antlr4 from 'antlr4';
|
||||||
|
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ export default Vue.extend({
|
|||||||
return icon;
|
return icon;
|
||||||
},
|
},
|
||||||
statusColor: function (status: string) {
|
statusColor: function (status: string) {
|
||||||
let color = TypeColorEnum.Info;
|
let color = TypeColorEnum.Info as TypeColorEnum;
|
||||||
this.lodash.forEach(this.$store.state.settings.artifactStates, (state: Type) => {
|
this.lodash.forEach(this.$store.state.settings.artifactStates, (state: Type) => {
|
||||||
if (status === state.id && state.color) {
|
if (status === state.id && state.color) {
|
||||||
color = state.color
|
color = state.color
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
loadAutomations() {
|
loadAutomations() {
|
||||||
API.listAutomations(this.$route.params.id).then((response) => {
|
API.listAutomations().then((response) => {
|
||||||
this.automations = response.data;
|
this.automations = response.data;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
+3
-22
@@ -1145,30 +1145,13 @@ export default Vue.extend({
|
|||||||
this.selectedTask = undefined;
|
this.selectedTask = undefined;
|
||||||
this.selectedTaskPlaybook = 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) {
|
save(playbookID: string, taskID: string) {
|
||||||
if (!this.ticket || !this.ticket.id || !this.ticket.playbooks) {
|
if (!this.ticket || !this.ticket.id || !this.ticket.playbooks) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let task = this.ticket.playbooks[playbookID].tasks[taskID]
|
let data = this.tdata[playbookID.toString() + "-" + taskID];
|
||||||
task.data = this.tdata[playbookID.toString() + "-" + taskID];
|
API.setTaskData(this.ticket.id, playbookID, taskID, data).then((response) => {
|
||||||
API.setTask(this.ticket.id, playbookID, taskID, this.toTaskForm(task)).then((response) => {
|
|
||||||
this.$store.dispatch("alertSuccess", { name: "Task saved" });
|
this.$store.dispatch("alertSuccess", { name: "Task saved" });
|
||||||
this.setTicket(response.data);
|
this.setTicket(response.data);
|
||||||
});
|
});
|
||||||
@@ -1181,9 +1164,7 @@ export default Vue.extend({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let task = this.ticket.playbooks[playbookID].tasks[taskID]
|
API.setTaskOwner(this.ticket.id, playbookID, taskID, owner).then((response) => {
|
||||||
task.owner = owner
|
|
||||||
API.setTask(this.ticket.id, playbookID, taskID, this.toTaskForm(task)).then((response) => {
|
|
||||||
this.$store.dispatch("alertSuccess", { name: "Owner saved" });
|
this.$store.dispatch("alertSuccess", { name: "Owner saved" });
|
||||||
this.setTicket(response.data);
|
this.setTicket(response.data);
|
||||||
if (response.data.playbooks) {
|
if (response.data.playbooks) {
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from "vue";
|
import Vue from "vue";
|
||||||
|
|
||||||
import { NewUserResponse, UserResponse } from "../client";
|
import { NewUserResponse, UserResponse } from "@/client";
|
||||||
import {API} from "@/services/api";
|
import {API} from "@/services/api";
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
|||||||
Reference in New Issue
Block a user