diff --git a/Sekoia.io/CHANGELOG.md b/Sekoia.io/CHANGELOG.md index dd89188e..ea93cce6 100644 --- a/Sekoia.io/CHANGELOG.md +++ b/Sekoia.io/CHANGELOG.md @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## Unreleased + +## 2024-12-18 - 2.67.0 + +### Added + +- Add an action to create a case +- Add an action to modify a case +- Add an action to get the details of a case +- Add an action to add a comment to a case + ## 2024-12-09 - 2.66.2 ### Changed diff --git a/Sekoia.io/action_create_case.json b/Sekoia.io/action_create_case.json new file mode 100644 index 00000000..41c45aad --- /dev/null +++ b/Sekoia.io/action_create_case.json @@ -0,0 +1,556 @@ +{ + "arguments": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "title": { + "description": "title of the case", + "type": "string", + "in": "body" + }, + "description": { + "description": "description of the case", + "type": "string", + "in": "body" + }, + "status_uuid": { + "description": "identifier of case’s status", + "type": "string", + "in": "body" + }, + "priority": { + "description": "priority of the case", + "type": "string", + "in": "body", + "enum": [ + "low", + "medium", + "high" + ] + }, + "tags": { + "description": "tags to associate to the case", + "type": "array", + "in": "body", + "items": { + "type": "string" + } + }, + "subscribers": { + "description": "avatars to associate to the case", + "type": "array", + "in": "body", + "items": { + "type": "object", + "properties": { + "avatar_uuid": { + "type": "string" + }, + "type": { + "type": "string" + } + } + } + }, + "community_uuid": { + "description": "the identifier of the community to which the case is associated", + "type": "string", + "in": "body" + }, + "verdict_uuid": { + "description": "Verdict of the case", + "type": "string", + "in": "body" + }, + "custom_status_uuid": { + "description": "Custom status of the case", + "type": "string", + "in": "body" + }, + "custom_priority_uuid": { + "description": "Custom priority of the case", + "type": "string", + "in": "body" + } + }, + "required": [ + "title" + ], + "title": "Arguments", + "type": "object" + }, + "description": "Creates a new case", + "docker_parameters": "create_case", + "name": "Create case", + "results": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "short_id": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "created_by_type": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "updated_by_type": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "priority": { + "default": "medium", + "description": "low|medium|high" + }, + "status": { + "type": "string" + }, + "status_uuid": { + "type": "string", + "format": "uuid" + }, + "community_uuid": { + "type": "string", + "format": "uuid" + }, + "subscribers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "avatar_uuid": { + "type": "string", + "format": "uuid" + }, + "type": { + "type": "string" + } + }, + "required": [ + "avatar_uuid", + "type" + ] + } + }, + "tags": { + "type": "array", + "description": "List of tags associated to the case", + "items": { + "type": "string" + } + }, + "number_of_comments": { + "type": "integer" + }, + "first_seen_at": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "description": "Date and time of the first case event" + }, + "last_seen_at": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "description": "Date and time of the last case event" + }, + "manual": { + "type": "boolean", + "x-nullable": true, + "description": "if True, indicates that the case was created manually" + }, + "is_supplied": { + "type": "boolean", + "x-nullable": true, + "description": "if True, indicates that alerts can be automatically added to the case" + }, + "verdict_uuid": { + "type": "string", + "format": "uuid", + "x-nullable": true, + "description": "UUID of the verdict associated to the case" + }, + "verdict": { + "x-nullable": true, + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "level": { + "type": "integer" + }, + "stage": { + "type": "string" + } + }, + "required": [ + "description", + "label", + "level", + "stage" + ] + }, + "custom_status_uuid": { + "type": "string", + "format": "uuid", + "x-nullable": true, + "description": "UUID of the custom status associated to the case" + }, + "custom_status": { + "x-nullable": true, + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "level": { + "type": "integer" + }, + "stage": { + "type": "string" + } + }, + "required": [ + "description", + "label", + "level", + "stage" + ] + }, + "custom_priority_uuid": { + "type": "string", + "format": "uuid", + "x-nullable": true, + "description": "UUID of the priority associated to the case" + }, + "custom_priority": { + "x-nullable": true, + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "level": { + "type": "integer" + }, + "color": { + "type": "string" + } + }, + "required": [ + "color", + "description", + "label", + "level" + ] + }, + "number_of_alerts": { + "type": "integer" + }, + "alerts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "title": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "created_by": { + "type": "string" + }, + "created_by_type": { + "type": "string" + }, + "updated_at": { + "type": "integer" + }, + "updated_by": { + "type": "string" + }, + "updated_by_type": { + "type": "string" + }, + "community_uuid": { + "type": "string", + "format": "uuid" + }, + "short_id": { + "type": "string" + }, + "entity": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "uuid" + ] + }, + "urgency": { + "description": " The alert urgency can have two different representations in the api: a numerical and a textual representation. | Urgency | Value | | Low | [0-20[ | | Moderate | [20-40[ | | High | [40-60[ | | Major | [60-80[ | | Urgent | [80-100] |", + "type": "object", + "properties": { + "current_value": { + "type": "integer" + }, + "value": { + "type": "integer" + }, + "severity": { + "type": "integer" + }, + "criticity": { + "type": "integer" + }, + "display": { + "type": "string" + } + } + }, + "alert_type": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "category": { + "type": "string" + } + } + }, + "status": { + "type": "object", + "properties": { + "uuid": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + } + }, + "rule": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "severity": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "pattern": { + "type": "string" + } + }, + "required": [ + "name", + "pattern", + "uuid" + ] + }, + "detection_type": { + "type": "string" + }, + "source": { + "type": "string" + }, + "target": { + "type": "string" + }, + "similar": { + "type": "integer" + }, + "details": { + "type": "string" + }, + "ttps": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "type" + ] + } + }, + "adversaries": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "type" + ] + } + }, + "stix": { + "type": "object" + }, + "kill_chain_short_id": { + "type": "string" + }, + "number_of_unseen_comments": { + "type": "integer" + }, + "number_of_total_comments": { + "type": "integer" + }, + "first_seen_at": { + "type": "string", + "format": "date-time" + }, + "last_seen_at": { + "type": "string", + "format": "date-time" + }, + "assets": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "time_to_ingest": { + "type": "integer" + }, + "time_to_detect": { + "type": "integer" + }, + "time_to_acknowledge": { + "type": "integer" + }, + "time_to_respond": { + "type": "integer" + }, + "time_to_resolve": { + "type": "integer" + }, + "intake_uuids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "cases": { + "type": "array", + "items": { + "type": "object", + "properties": { + "short_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "is_supplied": { + "type": "boolean" + }, + "manual": { + "type": "boolean" + }, + "status": { + "type": "string" + } + } + } + } + } + } + } + }, + "required": [ + "community_uuid", + "created_at", + "created_by", + "created_by_type", + "short_id", + "status", + "status_uuid", + "title", + "uuid" + ] + }, + "uuid": "0ccabc04-43b4-4564-b9b2-08b80e0e1ecf" +} \ No newline at end of file diff --git a/Sekoia.io/action_get_case.json b/Sekoia.io/action_get_case.json new file mode 100644 index 00000000..4a340654 --- /dev/null +++ b/Sekoia.io/action_get_case.json @@ -0,0 +1,497 @@ +{ + "arguments": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "uuid": { + "description": "UUID of the case", + "type": "string", + "in": "path" + }, + "community_uuid": { + "description": "(Optional) Identifier of the community", + "type": "string", + "in": "query" + } + }, + "required": [ + "uuid" + ], + "title": "Arguments", + "type": "object" + }, + "description": "Retrieve the properties of a case", + "docker_parameters": "get_case", + "name": "Get case", + "results": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "short_id": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "created_by_type": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "updated_by_type": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "priority": { + "default": "medium", + "description": "low|medium|high" + }, + "status": { + "type": "string" + }, + "status_uuid": { + "type": "string", + "format": "uuid" + }, + "community_uuid": { + "type": "string", + "format": "uuid" + }, + "subscribers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "avatar_uuid": { + "type": "string", + "format": "uuid" + }, + "type": { + "type": "string" + } + }, + "required": [ + "avatar_uuid", + "type" + ] + } + }, + "tags": { + "type": "array", + "description": "List of tags associated to the case", + "items": { + "type": "string" + } + }, + "number_of_comments": { + "type": "integer" + }, + "first_seen_at": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "description": "Date and time of the first case event" + }, + "last_seen_at": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "description": "Date and time of the last case event" + }, + "manual": { + "type": "boolean", + "x-nullable": true, + "description": "if True, indicates that the case was created manually" + }, + "is_supplied": { + "type": "boolean", + "x-nullable": true, + "description": "if True, indicates that alerts can be automatically added to the case" + }, + "verdict_uuid": { + "type": "string", + "format": "uuid", + "x-nullable": true, + "description": "UUID of the verdict associated to the case" + }, + "verdict": { + "x-nullable": true, + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "level": { + "type": "integer" + }, + "stage": { + "type": "string" + } + }, + "required": [ + "description", + "label", + "level", + "stage" + ] + }, + "custom_status_uuid": { + "type": "string", + "format": "uuid", + "x-nullable": true, + "description": "UUID of the custom status associated to the case" + }, + "custom_status": { + "x-nullable": true, + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "level": { + "type": "integer" + }, + "stage": { + "type": "string" + } + }, + "required": [ + "description", + "label", + "level", + "stage" + ] + }, + "custom_priority_uuid": { + "type": "string", + "format": "uuid", + "x-nullable": true, + "description": "UUID of the priority associated to the case" + }, + "custom_priority": { + "x-nullable": true, + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "level": { + "type": "integer" + }, + "color": { + "type": "string" + } + }, + "required": [ + "color", + "description", + "label", + "level" + ] + }, + "number_of_alerts": { + "type": "integer" + }, + "alerts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "title": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "created_by": { + "type": "string" + }, + "created_by_type": { + "type": "string" + }, + "updated_at": { + "type": "integer" + }, + "updated_by": { + "type": "string" + }, + "updated_by_type": { + "type": "string" + }, + "community_uuid": { + "type": "string", + "format": "uuid" + }, + "short_id": { + "type": "string" + }, + "entity": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "uuid" + ] + }, + "urgency": { + "description": " The alert urgency can have two different representations in the api: a numerical and a textual representation. | Urgency | Value | | Low | [0-20[ | | Moderate | [20-40[ | | High | [40-60[ | | Major | [60-80[ | | Urgent | [80-100] |", + "type": "object", + "properties": { + "current_value": { + "type": "integer" + }, + "value": { + "type": "integer" + }, + "severity": { + "type": "integer" + }, + "criticity": { + "type": "integer" + }, + "display": { + "type": "string" + } + } + }, + "alert_type": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "category": { + "type": "string" + } + } + }, + "status": { + "type": "object", + "properties": { + "uuid": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + } + }, + "rule": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "severity": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "pattern": { + "type": "string" + } + }, + "required": [ + "name", + "pattern", + "uuid" + ] + }, + "detection_type": { + "type": "string" + }, + "source": { + "type": "string" + }, + "target": { + "type": "string" + }, + "similar": { + "type": "integer" + }, + "details": { + "type": "string" + }, + "ttps": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "type" + ] + } + }, + "adversaries": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "type" + ] + } + }, + "stix": { + "type": "object" + }, + "kill_chain_short_id": { + "type": "string" + }, + "number_of_unseen_comments": { + "type": "integer" + }, + "number_of_total_comments": { + "type": "integer" + }, + "first_seen_at": { + "type": "string", + "format": "date-time" + }, + "last_seen_at": { + "type": "string", + "format": "date-time" + }, + "assets": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "time_to_ingest": { + "type": "integer" + }, + "time_to_detect": { + "type": "integer" + }, + "time_to_acknowledge": { + "type": "integer" + }, + "time_to_respond": { + "type": "integer" + }, + "time_to_resolve": { + "type": "integer" + }, + "intake_uuids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "cases": { + "type": "array", + "items": { + "type": "object", + "properties": { + "short_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "is_supplied": { + "type": "boolean" + }, + "manual": { + "type": "boolean" + }, + "status": { + "type": "string" + } + } + } + } + } + } + } + }, + "required": [ + "community_uuid", + "created_at", + "created_by", + "created_by_type", + "short_id", + "status", + "status_uuid", + "title", + "uuid" + ] + }, + "uuid": "0ecabc04-43b4-4564-b9b2-08b80e0e1ecf" +} \ No newline at end of file diff --git a/Sekoia.io/action_post_a_comment_on_a_case.json b/Sekoia.io/action_post_a_comment_on_a_case.json new file mode 100644 index 00000000..388f500e --- /dev/null +++ b/Sekoia.io/action_post_a_comment_on_a_case.json @@ -0,0 +1,58 @@ +{ + "arguments": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "uuid": { + "description": "UUID of the case", + "type": "string", + "in": "path" + }, + "content": { + "type": "string", + "description": "Content of the comment", + "in": "body" + } + }, + "required": [ + "uuid", + "content" + ], + "title": "Arguments", + "type": "object" + }, + "description": "Add a new comment to a case", + "docker_parameters": "post_comment_to_a_case", + "name": "Comment case", + "results": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "content": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "created_by_type": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + }, + "required": [ + "content", + "created_at", + "created_by", + "created_by_type", + "uuid" + ] + }, + "uuid": "0fcabc04-43b4-4564-b9b2-08b80e0e1ecf" +} \ No newline at end of file diff --git a/Sekoia.io/action_update_case.json b/Sekoia.io/action_update_case.json new file mode 100644 index 00000000..a81d2c7e --- /dev/null +++ b/Sekoia.io/action_update_case.json @@ -0,0 +1,556 @@ +{ + "arguments": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "uuid": { + "description": "UUID of the case", + "type": "string", + "in": "path" + }, + "title": { + "description": "title of the case", + "type": "string", + "in": "body" + }, + "description": { + "description": "description of the case", + "type": "string", + "in": "body" + }, + "status_uuid": { + "description": "identifier of case’s status", + "type": "string", + "in": "body" + }, + "priority": { + "description": "priority of the case", + "type": "string", + "in": "body", + "enum": [ + "low", + "medium", + "high" + ] + }, + "tags": { + "description": "tags to associate to the case", + "type": "array", + "in": "body", + "items": { + "type": "string" + } + }, + "subscribers": { + "description": "avatars to associate to the case", + "type": "array", + "in": "body", + "items": { + "type": "object", + "properties": { + "avatar_uuid": { + "type": "string" + }, + "type": { + "type": "string" + } + } + } + }, + "verdict_uuid": { + "description": "Verdict of the case", + "type": "string", + "in": "body" + }, + "custom_status_uuid": { + "description": "Custom status of the case", + "type": "string", + "in": "body" + }, + "custom_priority_uuid": { + "description": "Custom priority of the case", + "type": "string", + "in": "body" + } + }, + "required": [ + "uuid" + ], + "title": "Arguments", + "type": "object" + }, + "description": "Edit the properties of a case", + "docker_parameters": "update_case", + "name": "Edit case", + "results": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "short_id": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "created_by_type": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "updated_by_type": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "priority": { + "default": "medium", + "description": "low|medium|high" + }, + "status": { + "type": "string" + }, + "status_uuid": { + "type": "string", + "format": "uuid" + }, + "community_uuid": { + "type": "string", + "format": "uuid" + }, + "subscribers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "avatar_uuid": { + "type": "string", + "format": "uuid" + }, + "type": { + "type": "string" + } + }, + "required": [ + "avatar_uuid", + "type" + ] + } + }, + "tags": { + "type": "array", + "description": "List of tags associated to the case", + "items": { + "type": "string" + } + }, + "number_of_comments": { + "type": "integer" + }, + "first_seen_at": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "description": "Date and time of the first case event" + }, + "last_seen_at": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "description": "Date and time of the last case event" + }, + "manual": { + "type": "boolean", + "x-nullable": true, + "description": "if True, indicates that the case was created manually" + }, + "is_supplied": { + "type": "boolean", + "x-nullable": true, + "description": "if True, indicates that alerts can be automatically added to the case" + }, + "verdict_uuid": { + "type": "string", + "format": "uuid", + "x-nullable": true, + "description": "UUID of the verdict associated to the case" + }, + "verdict": { + "x-nullable": true, + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "level": { + "type": "integer" + }, + "stage": { + "type": "string" + } + }, + "required": [ + "description", + "label", + "level", + "stage" + ] + }, + "custom_status_uuid": { + "type": "string", + "format": "uuid", + "x-nullable": true, + "description": "UUID of the custom status associated to the case" + }, + "custom_status": { + "x-nullable": true, + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "level": { + "type": "integer" + }, + "stage": { + "type": "string" + } + }, + "required": [ + "description", + "label", + "level", + "stage" + ] + }, + "custom_priority_uuid": { + "type": "string", + "format": "uuid", + "x-nullable": true, + "description": "UUID of the priority associated to the case" + }, + "custom_priority": { + "x-nullable": true, + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "level": { + "type": "integer" + }, + "color": { + "type": "string" + } + }, + "required": [ + "color", + "description", + "label", + "level" + ] + }, + "number_of_alerts": { + "type": "integer" + }, + "alerts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "title": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "created_by": { + "type": "string" + }, + "created_by_type": { + "type": "string" + }, + "updated_at": { + "type": "integer" + }, + "updated_by": { + "type": "string" + }, + "updated_by_type": { + "type": "string" + }, + "community_uuid": { + "type": "string", + "format": "uuid" + }, + "short_id": { + "type": "string" + }, + "entity": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "uuid" + ] + }, + "urgency": { + "description": " The alert urgency can have two different representations in the api: a numerical and a textual representation. | Urgency | Value | | Low | [0-20[ | | Moderate | [20-40[ | | High | [40-60[ | | Major | [60-80[ | | Urgent | [80-100] |", + "type": "object", + "properties": { + "current_value": { + "type": "integer" + }, + "value": { + "type": "integer" + }, + "severity": { + "type": "integer" + }, + "criticity": { + "type": "integer" + }, + "display": { + "type": "string" + } + } + }, + "alert_type": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "category": { + "type": "string" + } + } + }, + "status": { + "type": "object", + "properties": { + "uuid": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + } + }, + "rule": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "severity": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "pattern": { + "type": "string" + } + }, + "required": [ + "name", + "pattern", + "uuid" + ] + }, + "detection_type": { + "type": "string" + }, + "source": { + "type": "string" + }, + "target": { + "type": "string" + }, + "similar": { + "type": "integer" + }, + "details": { + "type": "string" + }, + "ttps": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "type" + ] + } + }, + "adversaries": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "type" + ] + } + }, + "stix": { + "type": "object" + }, + "kill_chain_short_id": { + "type": "string" + }, + "number_of_unseen_comments": { + "type": "integer" + }, + "number_of_total_comments": { + "type": "integer" + }, + "first_seen_at": { + "type": "string", + "format": "date-time" + }, + "last_seen_at": { + "type": "string", + "format": "date-time" + }, + "assets": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "time_to_ingest": { + "type": "integer" + }, + "time_to_detect": { + "type": "integer" + }, + "time_to_acknowledge": { + "type": "integer" + }, + "time_to_respond": { + "type": "integer" + }, + "time_to_resolve": { + "type": "integer" + }, + "intake_uuids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "cases": { + "type": "array", + "items": { + "type": "object", + "properties": { + "short_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "is_supplied": { + "type": "boolean" + }, + "manual": { + "type": "boolean" + }, + "status": { + "type": "string" + } + } + } + } + } + } + } + }, + "required": [ + "community_uuid", + "created_at", + "created_by", + "created_by_type", + "short_id", + "status", + "status_uuid", + "title", + "uuid" + ] + }, + "uuid": "0dcabc04-43b4-4564-b9b2-08b80e0e1ecf" +} \ No newline at end of file diff --git a/Sekoia.io/main.py b/Sekoia.io/main.py index 594a03a4..8207bde5 100644 --- a/Sekoia.io/main.py +++ b/Sekoia.io/main.py @@ -40,6 +40,10 @@ GetIntake, GetEntity, AddEventsToACase, + CreateCase, + UpdateCase, + GetCase, + PostCommentOnCase, ) from sekoiaio.operation_center.get_asset import GetAsset from sekoiaio.operation_center.get_aggregation_query import GetAggregationQuery @@ -104,6 +108,10 @@ module.register(GetEntity, "get-entities/{uuid}") module.register(GetCommunity, "get-communities/{uuid}") module.register(AddEventsToACase, "add_events_to_a_case") + module.register(CreateCase, "create_case") + module.register(UpdateCase, "update_case") + module.register(GetCase, "get_case") + module.register(PostCommentOnCase, "post_comment_to_a_case") # Operation Center Triggers module.register(SecurityAlertsTrigger, "security_alerts_trigger") diff --git a/Sekoia.io/manifest.json b/Sekoia.io/manifest.json index d94e7017..8ce1bf8e 100644 --- a/Sekoia.io/manifest.json +++ b/Sekoia.io/manifest.json @@ -12,7 +12,7 @@ "name": "Sekoia.io", "uuid": "92d8bb47-7c51-445d-81de-ae04edbb6f0a", "slug": "sekoia.io", - "version": "2.66.2", + "version": "2.67.0", "categories": [ "Generic" ] diff --git a/Sekoia.io/sekoiaio/operation_center/__init__.py b/Sekoia.io/sekoiaio/operation_center/__init__.py index 8d6b7da8..985695d9 100644 --- a/Sekoia.io/sekoiaio/operation_center/__init__.py +++ b/Sekoia.io/sekoiaio/operation_center/__init__.py @@ -147,13 +147,13 @@ }, ) -CreatesNewCase = type( - "CreatesNewCase", +CreateCase = type( + "CreateCase", (GenericAPIAction,), { "verb": "post", "endpoint": base_url + "cases", - "query_parameters": ["tags", "subscribers"], + "query_parameters": [], }, ) @@ -194,18 +194,18 @@ (GenericAPIAction,), { "verb": "get", - "endpoint": base_url + "cases/{case_uuid}", + "endpoint": base_url + "cases/{uuid}", "query_parameters": ["community_uuid"], }, ) -UpdatesCase = type( - "UpdatesCase", +UpdateCase = type( + "UpdateCase", (GenericAPIAction,), { "verb": "patch", - "endpoint": base_url + "cases/{case_uuid}", - "query_parameters": ["tags", "subscribers"], + "endpoint": base_url + "cases/{uuid}", + "query_parameters": [], }, ) @@ -240,12 +240,12 @@ }, ) -CreateNewCommentOnCase = type( - "CreateNewCommentOnCase", +PostCommentOnCase = type( + "PostCommentOnCase", (GenericAPIAction,), { "verb": "post", - "endpoint": base_url + "cases/{case_uuid}/comments", + "endpoint": base_url + "cases/{uuid}/comments", "query_parameters": [], }, ) diff --git a/Sekoia.io/tests/test_operation_center.py b/Sekoia.io/tests/test_operation_center.py index 36197a0d..3c4eaa92 100644 --- a/Sekoia.io/tests/test_operation_center.py +++ b/Sekoia.io/tests/test_operation_center.py @@ -3,11 +3,97 @@ import pytest import requests_mock -from sekoiaio.operation_center import GetAlert, ListAlerts, AddEventsToACase +from sekoiaio.operation_center import ( + GetAlert, + ListAlerts, + AddEventsToACase, + CreateCase, + UpdateCase, + GetCase, + PostCommentOnCase, +) module_base_url = "http://fake.url/" base_url = module_base_url + "api/v1/sic/" apikey = "fake_api_key" +case_expected_response = { + "uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f", + "short_id": "string", + "created_at": "string", + "created_by": "string", + "created_by_type": "string", + "updated_at": "string", + "updated_by": "string", + "updated_by_type": "string", + "title": "string", + "description": "string", + "priority": "medium", + "status": "string", + "status_uuid": "5ca52387-a6f7-45c3-a713-856468ffbdd7", + "community_uuid": "e391588b-4c35-45eb-a5af-211fba0cde08", + "subscribers": [{"avatar_uuid": "bed24c33-9044-41b5-96c5-024eb9b0c439", "type": "string"}], + "tags": ["string"], + "number_of_comments": 0, + "first_seen_at": "2019-08-24T14:15:22Z", + "last_seen_at": "2019-08-24T14:15:22Z", + "manual": True, + "is_supplied": True, + "verdict_uuid": "6108af3c-010d-4cae-915e-70c748f0e58e", + "verdict": {"description": "string", "label": "string", "level": 0, "stage": "string"}, + "custom_status_uuid": "c1ccc455-a896-4e7c-8f4d-b99df293a381", + "custom_status": {"description": "string", "label": "string", "level": 0, "stage": "string"}, + "custom_priority_uuid": "f47455f5-1211-4723-9c4e-63d8752ec65f", + "custom_priority": {"description": "string", "label": "string", "level": 0, "color": "string"}, + "number_of_alerts": 0, + "alerts": [ + { + "uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f", + "title": "string", + "created_at": 0, + "created_by": "string", + "created_by_type": "string", + "updated_at": 0, + "updated_by": "string", + "updated_by_type": "string", + "community_uuid": "e391588b-4c35-45eb-a5af-211fba0cde08", + "short_id": "string", + "entity": {"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f", "name": "string"}, + "urgency": {"current_value": 0, "value": 0, "severity": 0, "criticity": 0, "display": "string"}, + "alert_type": {"value": "string", "category": "string"}, + "status": {"uuid": "string", "name": "string", "description": "string"}, + "rule": { + "uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f", + "name": "string", + "severity": 0, + "type": "string", + "pattern": "string", + }, + "detection_type": "string", + "source": "string", + "target": "string", + "similar": 0, + "details": "string", + "ttps": [{"id": "string", "type": "string", "name": "string", "description": "string"}], + "adversaries": [{"id": "string", "type": "string", "name": "string", "description": "string"}], + "stix": {}, + "kill_chain_short_id": "string", + "number_of_unseen_comments": 0, + "number_of_total_comments": 0, + "first_seen_at": "2019-08-24T14:15:22Z", + "last_seen_at": "2019-08-24T14:15:22Z", + "assets": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "time_to_ingest": 0, + "time_to_detect": 0, + "time_to_acknowledge": 0, + "time_to_respond": 0, + "time_to_resolve": 0, + "intake_uuids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "cases": [ + {"short_id": "string", "name": "string", "is_supplied": True, "manual": True, "status": "string"} + ], + } + ], +} def test_list_alerts_success(): @@ -118,3 +204,82 @@ def test_add_events_to_case(): history = mock.request_history assert history[0].method == "POST" assert url_decoder(history[0].url) == f"{base_url}{ressource}" + + +def test_create_case(): + action: CreateCase = CreateCase() + action.module.configuration = {"base_url": module_base_url, "api_key": apikey} + + ressource = "cases" + + arguments = {"title": "title"} + + with requests_mock.Mocker() as mock: + mock.post(f"{base_url}{ressource}", json=case_expected_response) + + action.run(arguments) + assert mock.call_count == 1 + history = mock.request_history + assert history[0].method == "POST" + assert url_decoder(history[0].url) == f"{base_url}{ressource}" + + +def test_get_case(): + action: GetCase = GetCase() + action.module.configuration = {"base_url": module_base_url, "api_key": apikey} + + ressource = "cases/fake_uuid" + + arguments = {"uuid": "fake_uuid"} + + with requests_mock.Mocker() as mock: + mock.get(f"{base_url}{ressource}", json=case_expected_response) + + action.run(arguments) + assert mock.call_count == 1 + history = mock.request_history + assert history[0].method == "GET" + assert url_decoder(history[0].url) == f"{base_url}{ressource}" + + +def test_update_case(): + action: UpdateCase = UpdateCase() + action.module.configuration = {"base_url": module_base_url, "api_key": apikey} + + ressource = "cases/fake_uuid" + + arguments = {"uuid": "fake_uuid", "title": "title"} + + with requests_mock.Mocker() as mock: + mock.patch(f"{base_url}{ressource}", json=case_expected_response) + + action.run(arguments) + assert mock.call_count == 1 + history = mock.request_history + assert history[0].method == "PATCH" + assert url_decoder(history[0].url) == f"{base_url}{ressource}" + + +def test_post_comment_on_case(): + action: PostCommentOnCase = PostCommentOnCase() + action.module.configuration = {"base_url": module_base_url, "api_key": apikey} + + ressource = "cases/fake_uuid/comments" + expected_response = { + "uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f", + "content": "string", + "created_at": "string", + "created_by": "string", + "created_by_type": "string", + "updated_at": "string", + } + arguments = {"uuid": "fake_uuid", "content": "content"} + + with requests_mock.Mocker() as mock: + mock.post(f"{base_url}{ressource}", json=expected_response) + + action.run(arguments) + assert mock.call_count == 1 + history = mock.request_history + assert history[0].method == "POST" + assert url_decoder(history[0].url) == f"{base_url}{ressource}"