main
py 223 lines 6.94 KB
Raw
1 from enum import Enum
2 from typing import Any
3 from typing import Dict
4 from typing import List
5 from typing import Optional
6
7 from pydantic import BaseModel
8 from pydantic import ConfigDict
9 from pydantic import Field
10
11
12 class CustomerCodeKeys(Enum):
13 AGENT_LABELS_CUSTOMER = "agent_labels_customer"
14 DATA_OFFICE365_ORGANIZATION_ID = "data_office365_OrganizationId"
15 SYSLOG_CUSTOMER = "syslog_customer"
16 CUSTOMER_CODE = "customer_code"
17 CLUSTER_NODE = "cluster_node"
18
19 @staticmethod
20 def get_processed_value(key, value):
21 if key == CustomerCodeKeys.CLUSTER_NODE:
22 if value.startswith("wazuh.worker."):
23 parts = value.split(".")
24 if len(parts) >= 3:
25 return parts[2].lower()
26 return value
27
28
29 class SyslogLevelMapping(Enum):
30 INFO = 1
31 NOTICE = 2
32 WARNING = 3
33 ALERT = 4
34
35
36 class SourceFieldsToRemove(Enum):
37 GL2 = "gl2"
38 # Add more fields as needed
39
40
41 class ValidIocFields(Enum):
42 MISP_VALUE = "misp_value"
43 OPENCTI_VALUE = "opencti_value"
44 THREAT_INTEL_VALUE = "threat_intel_value"
45
46
47 class CreateAlertRequest(BaseModel):
48 index_name: str = Field(
49 ...,
50 description="The name of the index to search alerts for.",
51 )
52 alert_id: str = Field(..., description="The alert id.")
53
54
55 class CreateAlertResponse(BaseModel):
56 success: bool
57 message: str
58 alert_id: int = Field(..., description="The alert id as created in IRIS.")
59 alert_url: Optional[str] = Field(None, description="The alert url as created in IRIS.")
60
61
62 class GenericSourceModel(BaseModel):
63 timestamp: str = Field(..., description="The timestamp of the alert.")
64 timestamp_utc: Optional[str] = Field(
65 ...,
66 description="The UTC timestamp of the alert.",
67 )
68 rule_description: Optional[str] = Field(
69 "No autogenerated rule_description found",
70 description="The timefield of the alert to be used when creating the IRIS alert.",
71 )
72 syslog_level: Optional[str] = Field(
73 "No autogenerated syslog_level found",
74 description="The timefield of the alert to be used when creating the IRIS alert.",
75 )
76 model_config = ConfigDict(extra="allow")
77
78 def to_dict(self):
79 return self.model_dump(exclude_none=True)
80
81
82 class GenericAlertModel(BaseModel):
83 # NOTE: Pydantic 2 treats names with a leading underscore as PrivateAttr
84 # and silently drops them from input parsing. Aliased to keep accepting
85 # the Elasticsearch-shaped keys while exposing usable Python attributes.
86 index: str = Field(alias="_index")
87 id: str = Field(alias="_id")
88 version: int = Field(alias="_version")
89 source: GenericSourceModel = Field(alias="_source")
90 asset_type_id: Optional[int] = Field(
91 None,
92 description="The asset type id of the alert which is needed for when we add the asset to IRIS.",
93 )
94 ioc_value: Optional[str] = Field(
95 None,
96 description="The IoC value of the alert which is needed for when we add the IoC to IRIS.",
97 )
98 ioc_type: Optional[str] = Field(
99 None,
100 description="The IoC type of the alert which is needed for when we add the IoC to IRIS.",
101 )
102 time_field: Optional[str] = Field(
103 "timestamp",
104 description="The timefield of the alert to be used when creating the IRIS alert.",
105 )
106 rule_description: Optional[str] = Field(
107 "No autogenerated rule_description found",
108 description="The timefield of the alert to be used when creating the IRIS alert.",
109 )
110 syslog_level: Optional[str] = Field(
111 "No autogenerated syslog_level found",
112 description="The timefield of the alert to be used when creating the IRIS alert.",
113 )
114 model_config = ConfigDict(extra="allow", populate_by_name=True)
115
116
117 # Sample data from `get_single_alert_details`
118 sample_data = {
119 "_index": "some_index",
120 "_id": "some_id",
121 "_version": 1,
122 "_source": {
123 "agent_name": "some_agent_name",
124 "agent_id": "some_agent_id",
125 # ... other fields
126 },
127 # ... other fields
128 }
129
130
131 ########### Create Alerts Schemas ###########
132 class IrisAsset(BaseModel):
133 asset_name: str = Field(..., description="Name of the asset", examples=["Server01"])
134 asset_ip: str = Field(
135 ...,
136 description="IP address of the asset",
137 examples=["192.168.1.1"],
138 )
139 asset_description: str = Field(
140 ...,
141 description="Description of the asset",
142 examples=["Windows Server"],
143 )
144 asset_type_id: int = Field(..., description="Type ID of the asset", examples=[1])
145 asset_tags: Optional[str] = Field(
146 "Agent ID not found. Ensure the agent has been registered with Wazuh Manager and synced to the Agents table.",
147 description="Tags of the asset",
148 examples=["001"],
149 )
150
151 def to_dict(self):
152 return self.model_dump(exclude_none=True)
153
154
155 class IrisIoc(BaseModel):
156 ioc_value: str = Field(
157 ...,
158 description="Value of the IoC",
159 examples=["www.google.com"],
160 )
161 ioc_description: str = Field(
162 ...,
163 description="Description of the IoC",
164 examples=["Google"],
165 )
166 ioc_tlp_id: int = Field(1, description="TLP ID of the IoC", examples=[1])
167 ioc_type_id: int = Field(20, description="Type ID of the IoC", examples=[20])
168
169 def to_dict(self):
170 return self.model_dump(exclude_none=True)
171
172
173 class IrisAlertContext(BaseModel):
174 alert_id: str = Field(..., description="ID of the alert", examples=["123"])
175 alert_name: str = Field(
176 ...,
177 description="Name of the alert",
178 examples=["Intrusion Detected"],
179 )
180 alert_level: int = Field(..., description="Severity level of the alert", examples=[3])
181 process_name: Optional[List[str]] = Field(
182 None,
183 examples=[["No process name found"]],
184 description="Name of the process",
185 )
186 model_config = ConfigDict(extra="allow")
187
188
189 class IrisAlertPayload(BaseModel):
190 alert_title: str = Field(
191 ...,
192 description="Title of the alert",
193 examples=["Intrusion Detected"],
194 )
195 alert_description: str = Field(
196 ...,
197 description="Description of the alert",
198 examples=["Intrusion Detected by Firewall"],
199 )
200 alert_source: str = Field(..., description="Source of the alert", examples=["Wazuh"])
201 alert_status_id: int = Field(..., description="Status ID of the alert", examples=[3])
202 alert_severity_id: int = Field(
203 ...,
204 description="Severity ID of the alert",
205 examples=[5],
206 )
207 alert_customer_id: int = Field(
208 ...,
209 description="Customer ID related to the alert",
210 examples=[1],
211 )
212 alert_source_content: Dict[str, Any] = Field(
213 ...,
214 description="Original content from the alert source",
215 )
216 alert_context: IrisAlertContext = Field(
217 ...,
218 description="Contextual information about the alert",
219 )
220 model_config = ConfigDict(extra="allow")
221
222 def to_dict(self):
223 return self.model_dump(exclude_none=True)