psengine 2.0.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- psengine/__init__.py +22 -0
- psengine/_sdk_id.py +16 -0
- psengine/_version.py +14 -0
- psengine/analyst_notes/__init__.py +32 -0
- psengine/analyst_notes/constants.py +15 -0
- psengine/analyst_notes/errors.py +42 -0
- psengine/analyst_notes/helpers.py +90 -0
- psengine/analyst_notes/models.py +219 -0
- psengine/analyst_notes/note.py +149 -0
- psengine/analyst_notes/note_mgr.py +400 -0
- psengine/base_http_client.py +285 -0
- psengine/classic_alerts/__init__.py +24 -0
- psengine/classic_alerts/classic_alert.py +275 -0
- psengine/classic_alerts/classic_alert_mgr.py +507 -0
- psengine/classic_alerts/constants.py +31 -0
- psengine/classic_alerts/errors.py +38 -0
- psengine/classic_alerts/helpers.py +87 -0
- psengine/classic_alerts/markdown/__init__.py +13 -0
- psengine/classic_alerts/markdown/markdown.py +359 -0
- psengine/classic_alerts/models.py +141 -0
- psengine/collective_insights/__init__.py +29 -0
- psengine/collective_insights/collective_insights.py +164 -0
- psengine/collective_insights/constants.py +44 -0
- psengine/collective_insights/errors.py +18 -0
- psengine/collective_insights/insight.py +89 -0
- psengine/collective_insights/models.py +81 -0
- psengine/common_models.py +89 -0
- psengine/config/__init__.py +15 -0
- psengine/config/config.py +284 -0
- psengine/config/errors.py +18 -0
- psengine/constants.py +63 -0
- psengine/detection/__init__.py +17 -0
- psengine/detection/detection_mgr.py +135 -0
- psengine/detection/detection_rule.py +85 -0
- psengine/detection/errors.py +26 -0
- psengine/detection/helpers.py +56 -0
- psengine/detection/models.py +47 -0
- psengine/endpoints.py +98 -0
- psengine/enrich/__init__.py +28 -0
- psengine/enrich/constants.py +73 -0
- psengine/enrich/errors.py +26 -0
- psengine/enrich/lookup.py +299 -0
- psengine/enrich/lookup_mgr.py +341 -0
- psengine/enrich/models/__init__.py +13 -0
- psengine/enrich/models/base_enriched_entity.py +43 -0
- psengine/enrich/models/lookup.py +271 -0
- psengine/enrich/models/soar.py +138 -0
- psengine/enrich/soar.py +89 -0
- psengine/enrich/soar_mgr.py +176 -0
- psengine/entity_lists/__init__.py +16 -0
- psengine/entity_lists/constants.py +19 -0
- psengine/entity_lists/entity_list.py +435 -0
- psengine/entity_lists/entity_list_mgr.py +185 -0
- psengine/entity_lists/errors.py +26 -0
- psengine/entity_lists/models.py +87 -0
- psengine/entity_match/__init__.py +16 -0
- psengine/entity_match/entity_match.py +90 -0
- psengine/entity_match/entity_match_mgr.py +235 -0
- psengine/entity_match/errors.py +18 -0
- psengine/entity_match/models.py +22 -0
- psengine/errors.py +41 -0
- psengine/helpers/__init__.py +23 -0
- psengine/helpers/helpers.py +471 -0
- psengine/logger/__init__.py +15 -0
- psengine/logger/constants.py +39 -0
- psengine/logger/errors.py +18 -0
- psengine/logger/rf_logger.py +148 -0
- psengine/markdown/__init__.py +21 -0
- psengine/markdown/markdown.py +169 -0
- psengine/markdown/models.py +22 -0
- psengine/playbook_alerts/__init__.py +34 -0
- psengine/playbook_alerts/constants.py +35 -0
- psengine/playbook_alerts/errors.py +35 -0
- psengine/playbook_alerts/helpers.py +80 -0
- psengine/playbook_alerts/mappings.py +44 -0
- psengine/playbook_alerts/markdown/__init__.py +13 -0
- psengine/playbook_alerts/markdown/markdown.py +98 -0
- psengine/playbook_alerts/markdown/markdown_code_repo.py +64 -0
- psengine/playbook_alerts/markdown/markdown_domain_abuse.py +118 -0
- psengine/playbook_alerts/markdown/markdown_identity_exposure.py +158 -0
- psengine/playbook_alerts/models/__init__.py +36 -0
- psengine/playbook_alerts/models/common_models.py +18 -0
- psengine/playbook_alerts/models/panel_log.py +329 -0
- psengine/playbook_alerts/models/panel_status.py +70 -0
- psengine/playbook_alerts/models/pba_code_repo_leak.py +52 -0
- psengine/playbook_alerts/models/pba_cyber_vulnerability.py +53 -0
- psengine/playbook_alerts/models/pba_domain_abuse.py +139 -0
- psengine/playbook_alerts/models/pba_identity_exposures.py +93 -0
- psengine/playbook_alerts/models/pba_third_party_risk.py +103 -0
- psengine/playbook_alerts/models/search_endpoint.py +68 -0
- psengine/playbook_alerts/pa_category.py +37 -0
- psengine/playbook_alerts/playbook_alert_mgr.py +593 -0
- psengine/playbook_alerts/playbook_alerts.py +393 -0
- psengine/rf_client.py +430 -0
- psengine/risklists/__init__.py +17 -0
- psengine/risklists/constants.py +15 -0
- psengine/risklists/errors.py +20 -0
- psengine/risklists/models.py +65 -0
- psengine/risklists/risklist_mgr.py +156 -0
- psengine/stix2/__init__.py +21 -0
- psengine/stix2/base_stix_entity.py +62 -0
- psengine/stix2/complex_entity.py +372 -0
- psengine/stix2/constants.py +81 -0
- psengine/stix2/enriched_indicator.py +261 -0
- psengine/stix2/errors.py +22 -0
- psengine/stix2/helpers.py +68 -0
- psengine/stix2/rf_bundle.py +240 -0
- psengine/stix2/simple_entity.py +145 -0
- psengine/stix2/util.py +53 -0
- psengine-2.0.4.dist-info/METADATA +189 -0
- psengine-2.0.4.dist-info/RECORD +115 -0
- psengine-2.0.4.dist-info/WHEEL +5 -0
- psengine-2.0.4.dist-info/entry_points.txt +2 -0
- psengine-2.0.4.dist-info/licenses/LICENSE +21 -0
- psengine-2.0.4.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
##################################### TERMS OF USE ###########################################
|
|
2
|
+
# The following code is provided for demonstration purpose only, and should not be used #
|
|
3
|
+
# without independent verification. Recorded Future makes no representations or warranties, #
|
|
4
|
+
# express, implied, statutory, or otherwise, regarding any aspect of this code or of the #
|
|
5
|
+
# information it may retrieve, and provides it both strictly “as-is” and without assuming #
|
|
6
|
+
# responsibility for any information it may retrieve. Recorded Future shall not be liable #
|
|
7
|
+
# for, and you assume all risk of using, the foregoing. By using this code, Customer #
|
|
8
|
+
# represents that it is solely responsible for having all necessary licenses, permissions, #
|
|
9
|
+
# rights, and/or consents to connect to third party APIs, and that it is solely responsible #
|
|
10
|
+
# for having all necessary licenses, permissions, rights, and/or consents to any data #
|
|
11
|
+
# accessed from any third party API. #
|
|
12
|
+
##############################################################################################
|
|
13
|
+
|
|
14
|
+
from functools import total_ordering
|
|
15
|
+
from typing import Optional
|
|
16
|
+
|
|
17
|
+
from pydantic import Field, NonNegativeInt, PositiveInt, model_validator
|
|
18
|
+
|
|
19
|
+
from ..common_models import RFBaseModel
|
|
20
|
+
from ..constants import DEFAULT_LIMIT, TIMESTAMP_STR
|
|
21
|
+
from ..playbook_alerts.markdown.markdown import _markdown_playbook_alert
|
|
22
|
+
from .models import (
|
|
23
|
+
CodeRepoEvidencePanel,
|
|
24
|
+
CodeRepoPanelStatus,
|
|
25
|
+
CyberVulnerabilityEvidencePanel,
|
|
26
|
+
CyberVulnerabilityPanelStatus,
|
|
27
|
+
DatetimeRange,
|
|
28
|
+
DomainAbuseEvidenceDns,
|
|
29
|
+
DomainAbuseEvidenceSummary,
|
|
30
|
+
DomainAbuseEvidenceWhois,
|
|
31
|
+
DomainAbusePanelStatus,
|
|
32
|
+
IdentityEvidencePanel,
|
|
33
|
+
IdentityPanelStatus,
|
|
34
|
+
TPREvidencePanel,
|
|
35
|
+
TPRPanelStatus,
|
|
36
|
+
)
|
|
37
|
+
from .models.panel_log import (
|
|
38
|
+
CodeRepoLeakageEvidenceChange,
|
|
39
|
+
DomainAbuseDnsChange,
|
|
40
|
+
DomainAbuseLogoTypeChange,
|
|
41
|
+
DomainAbuseMaliciousDnsChange,
|
|
42
|
+
DomainAbuseMaliciousUrlChange,
|
|
43
|
+
DomainAbuseReregistrationRecordChange,
|
|
44
|
+
DomainAbuseScreenshotMentions,
|
|
45
|
+
DomainAbuseWhoisChange,
|
|
46
|
+
PanelLogV2,
|
|
47
|
+
ThirdPartyAssessmentChange,
|
|
48
|
+
VulnerabilityLifecycleChange,
|
|
49
|
+
)
|
|
50
|
+
from .models.panel_status import PanelAction, PanelStatus
|
|
51
|
+
from .pa_category import PACategory
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@total_ordering
|
|
55
|
+
class PBA_Generic(RFBaseModel):
|
|
56
|
+
"""Base Model for Playbook Alerts. Removes the deprecated panel_log.
|
|
57
|
+
This model is intended to be inherited and should not be used on its own.
|
|
58
|
+
|
|
59
|
+
Methods:
|
|
60
|
+
__hash__:
|
|
61
|
+
Returns hash value based on ``playbook_alert_id`` and updated timestamp in panel status.
|
|
62
|
+
|
|
63
|
+
__eq__:
|
|
64
|
+
Checks equality between two BasePlaybookAlert instances based on ``playbook_alert_id``
|
|
65
|
+
and updated timestamp in panel status.
|
|
66
|
+
|
|
67
|
+
__gt__:
|
|
68
|
+
Defines a greater-than comparison between two ``BasePlaybookAlert`` instances based on
|
|
69
|
+
``playbook_alert_id`` and updated timestamp in panel status.
|
|
70
|
+
|
|
71
|
+
__str__:
|
|
72
|
+
Returns a string representation of the BasePlaybookAlert instance with:
|
|
73
|
+
``playbook_alert_id``, updated timestamp, case rule label, and status.
|
|
74
|
+
|
|
75
|
+
.. code-block:: python
|
|
76
|
+
|
|
77
|
+
>>> print(playbook_alert)
|
|
78
|
+
Playbook Alert ID: task:a1ccb1c8-5554-42af, Updated: 2024-05-21 10:42:30AM,
|
|
79
|
+
Category: Third Party Risk, Lookup Status: New
|
|
80
|
+
|
|
81
|
+
Total Ordering:
|
|
82
|
+
The ordering of BasePlaybookAlert instances is determined primarily by the updated timestamp
|
|
83
|
+
of the panel status. If two instances have the same updated timestamp, their
|
|
84
|
+
``playbook_alert_id`` is used as a secondary criterion for ordering.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
playbook_alert_id: str
|
|
88
|
+
panel_log_v2: Optional[list[PanelLogV2]] = []
|
|
89
|
+
panel_status: Optional[PanelStatus] = Field(default_factory=PanelStatus)
|
|
90
|
+
|
|
91
|
+
category: str = PACategory.UNMAPPED_ALERT.value
|
|
92
|
+
|
|
93
|
+
@model_validator(mode='before')
|
|
94
|
+
@classmethod
|
|
95
|
+
def remove_panel_log(cls, data):
|
|
96
|
+
"""Remove panel_log since it is deprecated."""
|
|
97
|
+
if 'panel_log' in data:
|
|
98
|
+
del data['panel_log']
|
|
99
|
+
return data
|
|
100
|
+
|
|
101
|
+
def __hash__(self):
|
|
102
|
+
return hash((self.playbook_alert_id, self.panel_status.updated))
|
|
103
|
+
|
|
104
|
+
def __eq__(self, other: 'PBA_Generic'):
|
|
105
|
+
return (self.playbook_alert_id, self.panel_status.updated) == (
|
|
106
|
+
other.playbook_alert_id,
|
|
107
|
+
other.panel_status.updated,
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
def __gt__(self, other: 'PBA_Generic'):
|
|
111
|
+
return (self.panel_status.updated, self.playbook_alert_id) > (
|
|
112
|
+
other.panel_status.updated,
|
|
113
|
+
other.playbook_alert_id,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def __str__(self):
|
|
117
|
+
return (
|
|
118
|
+
f'Playbook Alert ID: {self.playbook_alert_id}, '
|
|
119
|
+
f'Updated: {self.panel_status.updated.strftime(TIMESTAMP_STR)}, '
|
|
120
|
+
f'Category: {self.panel_status.case_rule_label}, '
|
|
121
|
+
f'Lookup Status: {self.panel_status.status}'
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
def markdown(
|
|
125
|
+
self,
|
|
126
|
+
html_tags: bool = True,
|
|
127
|
+
character_limit: Optional[int] = None,
|
|
128
|
+
defang_iocs: bool = False,
|
|
129
|
+
):
|
|
130
|
+
"""Markdown implementation for Playbook Alerts."""
|
|
131
|
+
return _markdown_playbook_alert(
|
|
132
|
+
self, html_tags=html_tags, character_limit=character_limit, defang_iocs=defang_iocs
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
def _get_changes(self, change_type):
|
|
136
|
+
"""Filter for a specific change type from the v2 panel log."""
|
|
137
|
+
changes = [obj.changes for obj in self.panel_log_v2]
|
|
138
|
+
changes = [x for y in changes for x in y]
|
|
139
|
+
return list(filter(lambda x: isinstance(x, change_type), changes))
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class PBA_CodeRepoLeakage(PBA_Generic):
|
|
143
|
+
"""Model for Code Repo Leakage. Inherit behaviours from BasePlaybookAlert."""
|
|
144
|
+
|
|
145
|
+
__doc__ = __doc__ + '\n\n' + PBA_Generic.__doc__ # noqa: A003
|
|
146
|
+
|
|
147
|
+
category: str = PACategory.CODE_REPO_LEAKAGE.value
|
|
148
|
+
|
|
149
|
+
panel_status: Optional[CodeRepoPanelStatus] = Field(default_factory=CodeRepoPanelStatus)
|
|
150
|
+
panel_evidence_summary: Optional[CodeRepoEvidencePanel] = Field(
|
|
151
|
+
default_factory=CodeRepoEvidencePanel
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
@property
|
|
155
|
+
def log_code_repo_leakage_evidence_changes(self) -> list:
|
|
156
|
+
"""Code Repo Leakage Evidence change."""
|
|
157
|
+
return self._get_changes(CodeRepoLeakageEvidenceChange)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class PBA_ThirdPartyRisk(PBA_Generic):
|
|
161
|
+
"""Model for Third Party Risk. Inherit behaviours from BasePlaybookAlert."""
|
|
162
|
+
|
|
163
|
+
__doc__ = __doc__ + '\n\n' + PBA_Generic.__doc__ # noqa: A003
|
|
164
|
+
|
|
165
|
+
category: str = PACategory.THIRD_PARTY_RISK.value
|
|
166
|
+
|
|
167
|
+
panel_status: Optional[TPRPanelStatus] = Field(default_factory=TPRPanelStatus)
|
|
168
|
+
panel_evidence_summary: Optional[TPREvidencePanel] = Field(default_factory=TPREvidencePanel)
|
|
169
|
+
|
|
170
|
+
@property
|
|
171
|
+
def log_third_party_assessment_changes(self) -> list:
|
|
172
|
+
"""Third Party Assessment change."""
|
|
173
|
+
return self._get_changes(ThirdPartyAssessmentChange)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class PBA_CyberVulnerability(PBA_Generic):
|
|
177
|
+
"""Model for Cyber Vulnerability. Inherit behaviours from BasePlaybookAlert."""
|
|
178
|
+
|
|
179
|
+
__doc__ = __doc__ + '\n\n' + PBA_Generic.__doc__ # noqa: A003
|
|
180
|
+
|
|
181
|
+
category: str = PACategory.CYBER_VULNERABILITY.value
|
|
182
|
+
|
|
183
|
+
panel_status: Optional[CyberVulnerabilityPanelStatus] = Field(
|
|
184
|
+
default_factory=CyberVulnerabilityPanelStatus
|
|
185
|
+
)
|
|
186
|
+
panel_evidence_summary: Optional[CyberVulnerabilityEvidencePanel] = Field(
|
|
187
|
+
default_factory=CyberVulnerabilityEvidencePanel
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
def lifecycle_stage(self) -> str:
|
|
192
|
+
"""Get playbook alert lifecycle_stage."""
|
|
193
|
+
if stage := self.panel_status.lifecycle_stage:
|
|
194
|
+
return stage
|
|
195
|
+
return self.panel_evidence_summary.summary.lifecycle_stage
|
|
196
|
+
|
|
197
|
+
@property
|
|
198
|
+
def log_vulnerability_lifecycle_changes(self) -> list:
|
|
199
|
+
"""Get ``VulnerabilityLifecycleChange`` log changes."""
|
|
200
|
+
return self._get_changes(VulnerabilityLifecycleChange)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
class PBA_IdentityNovelExposure(PBA_Generic):
|
|
204
|
+
"""Model for Identity Exposure. Inherit behaviours from BasePlaybookAlert."""
|
|
205
|
+
|
|
206
|
+
__doc__ = __doc__ + '\n\n' + PBA_Generic.__doc__ # noqa: A003
|
|
207
|
+
|
|
208
|
+
category: str = PACategory.IDENTITY_NOVEL_EXPOSURES.value
|
|
209
|
+
|
|
210
|
+
panel_status: Optional[IdentityPanelStatus] = Field(default_factory=IdentityPanelStatus)
|
|
211
|
+
panel_evidence_summary: Optional[IdentityEvidencePanel] = Field(
|
|
212
|
+
default_factory=IdentityEvidencePanel
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
@property
|
|
216
|
+
def assessment_names(self) -> list[str]:
|
|
217
|
+
"""Assessments contain name and criticality, this returns all assessment names.
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
List[str]: assessments names or [] if not found
|
|
221
|
+
"""
|
|
222
|
+
if not self.panel_evidence_summary or not self.panel_evidence_summary.assessments:
|
|
223
|
+
return []
|
|
224
|
+
return [assessment.name for assessment in self.panel_evidence_summary.assessments]
|
|
225
|
+
|
|
226
|
+
@property
|
|
227
|
+
def technology_names(self) -> list[str]:
|
|
228
|
+
"""Novel Identity Exposure: Return the technologies names list.
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
list[str]: List of technologies names
|
|
232
|
+
"""
|
|
233
|
+
if not self.panel_evidence_summary or not self.panel_evidence_summary.technologies:
|
|
234
|
+
return []
|
|
235
|
+
return [tech.name for tech in self.panel_evidence_summary.technologies]
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class PBA_DomainAbuse(PBA_Generic):
|
|
239
|
+
"""Model for Domain Abuse. Inherit behaviours from BasePlaybookAlert."""
|
|
240
|
+
|
|
241
|
+
__doc__ = __doc__ + '\n\n' + PBA_Generic.__doc__ # noqa: A003
|
|
242
|
+
|
|
243
|
+
_images: Optional[dict] = {}
|
|
244
|
+
|
|
245
|
+
category: str = PACategory.DOMAIN_ABUSE.value
|
|
246
|
+
|
|
247
|
+
panel_action: Optional[list[PanelAction]] = []
|
|
248
|
+
panel_status: Optional[DomainAbusePanelStatus] = Field(default_factory=DomainAbusePanelStatus)
|
|
249
|
+
panel_evidence_summary: Optional[DomainAbuseEvidenceSummary] = Field(
|
|
250
|
+
default_factory=DomainAbuseEvidenceSummary
|
|
251
|
+
)
|
|
252
|
+
panel_evidence_dns: Optional[DomainAbuseEvidenceDns] = Field(
|
|
253
|
+
default_factory=DomainAbuseEvidenceDns
|
|
254
|
+
)
|
|
255
|
+
panel_evidence_whois: Optional[DomainAbuseEvidenceWhois] = Field(
|
|
256
|
+
default_factory=DomainAbuseEvidenceWhois
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
def store_image(self, image_id: str, image_bytes: bytes) -> None:
|
|
260
|
+
"""Domain Abuse: store image bytes in ``self._images`` dictionary.
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
image_id (str): image id
|
|
264
|
+
image_bytes (bytes): image bytes
|
|
265
|
+
|
|
266
|
+
Raises:
|
|
267
|
+
ValueError: if the image_id is not present in alert screenshots list
|
|
268
|
+
"""
|
|
269
|
+
image_id_matches = list(
|
|
270
|
+
filter(
|
|
271
|
+
lambda x: x.image_id == image_id,
|
|
272
|
+
self.panel_evidence_summary.screenshots,
|
|
273
|
+
)
|
|
274
|
+
)
|
|
275
|
+
if len(image_id_matches) == 0:
|
|
276
|
+
raise ValueError(
|
|
277
|
+
f"Alert '{self.playbook_alert_id}' does not contain image id: '{image_id}'"
|
|
278
|
+
)
|
|
279
|
+
image_info = image_id_matches[0]
|
|
280
|
+
self._images[image_id] = {}
|
|
281
|
+
self._images[image_id]['description'] = image_info.description
|
|
282
|
+
self._images[image_id]['created'] = image_info.created
|
|
283
|
+
self._images[image_id]['image_bytes'] = image_bytes
|
|
284
|
+
|
|
285
|
+
@property
|
|
286
|
+
def image_ids(self) -> list:
|
|
287
|
+
"""Domain Abuse: get the playbook alert image ids.
|
|
288
|
+
|
|
289
|
+
Returns:
|
|
290
|
+
list: Alert image ids or empty list if not found
|
|
291
|
+
"""
|
|
292
|
+
ids = []
|
|
293
|
+
if self.panel_evidence_summary.screenshots:
|
|
294
|
+
ids = [screenshot.image_id for screenshot in self.panel_evidence_summary.screenshots]
|
|
295
|
+
return ids
|
|
296
|
+
|
|
297
|
+
@property
|
|
298
|
+
def images(self) -> dict:
|
|
299
|
+
"""Domain Abuse: get raw bytes of the screenshots.
|
|
300
|
+
|
|
301
|
+
This data is stored in the following format:
|
|
302
|
+
|
|
303
|
+
.. code-block::
|
|
304
|
+
|
|
305
|
+
{
|
|
306
|
+
image_id : {
|
|
307
|
+
'description': "awesome image description",
|
|
308
|
+
'created': "date",
|
|
309
|
+
'image_bytes': b'xyz'
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
Returns:
|
|
314
|
+
dict: Alert images raw bytes or {} if not found
|
|
315
|
+
"""
|
|
316
|
+
return self._images
|
|
317
|
+
|
|
318
|
+
@property
|
|
319
|
+
def log_dns_changes(self) -> list:
|
|
320
|
+
"""DNS change."""
|
|
321
|
+
return self._get_changes(DomainAbuseDnsChange)
|
|
322
|
+
|
|
323
|
+
@property
|
|
324
|
+
def log_whois_changes(self) -> list:
|
|
325
|
+
"""WHOIS change."""
|
|
326
|
+
return self._get_changes(DomainAbuseWhoisChange)
|
|
327
|
+
|
|
328
|
+
@property
|
|
329
|
+
def log_logotype_changes(self) -> list:
|
|
330
|
+
"""Logotype change."""
|
|
331
|
+
return self._get_changes(DomainAbuseLogoTypeChange)
|
|
332
|
+
|
|
333
|
+
@property
|
|
334
|
+
def log_malicious_dns_changes(self) -> list:
|
|
335
|
+
"""Malaicious DNS change."""
|
|
336
|
+
return self._get_changes(DomainAbuseMaliciousDnsChange)
|
|
337
|
+
|
|
338
|
+
@property
|
|
339
|
+
def log_reregistration_changes(self) -> list:
|
|
340
|
+
"""Reregistration change."""
|
|
341
|
+
return self._get_changes(DomainAbuseReregistrationRecordChange)
|
|
342
|
+
|
|
343
|
+
@property
|
|
344
|
+
def log_malicious_url_changes(self) -> list:
|
|
345
|
+
"""Malicious URL change."""
|
|
346
|
+
return self._get_changes(DomainAbuseMaliciousUrlChange)
|
|
347
|
+
|
|
348
|
+
@property
|
|
349
|
+
def log_screenshot_mentions_changes(self) -> list:
|
|
350
|
+
"""Screenshot mentions change."""
|
|
351
|
+
return self._get_changes(DomainAbuseScreenshotMentions)
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
class SearchIn(RFBaseModel):
|
|
355
|
+
"""Model for payload sent to ``/search`` endpoint."""
|
|
356
|
+
|
|
357
|
+
from_: Optional[NonNegativeInt] = Field(alias='from', default=None)
|
|
358
|
+
limit: Optional[PositiveInt] = DEFAULT_LIMIT
|
|
359
|
+
order_by: Optional[str] = None
|
|
360
|
+
direction: Optional[str] = None
|
|
361
|
+
entity: Optional[list] = None
|
|
362
|
+
statuses: Optional[list[str]] = None
|
|
363
|
+
priority: Optional[list[str]] = None
|
|
364
|
+
category: Optional[list[str]] = None
|
|
365
|
+
assignee: Optional[list[str]] = None
|
|
366
|
+
created_range: Optional[DatetimeRange] = None
|
|
367
|
+
updated_range: Optional[DatetimeRange] = None
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
class PreviewAlertOut(PanelStatus):
|
|
371
|
+
"""Model for payload received by GET ``/common/{alert_id}`` endpoint."""
|
|
372
|
+
|
|
373
|
+
playbook_alert_id: str
|
|
374
|
+
title: str
|
|
375
|
+
category: str
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
class UpdateAlertIn(RFBaseModel):
|
|
379
|
+
"""Model for payload sent to PUT ``/common/{playbook_alert_id}`` endpoint."""
|
|
380
|
+
|
|
381
|
+
priority: Optional[str] = None
|
|
382
|
+
status: Optional[str] = None
|
|
383
|
+
assignee: Optional[str] = None
|
|
384
|
+
log_entry: Optional[str] = None
|
|
385
|
+
reopen: Optional[str] = None
|
|
386
|
+
added_actions_taken: Optional[list[str]] = None
|
|
387
|
+
removed_actions_taken: Optional[list[str]] = None
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
class LookupAlertIn(RFBaseModel):
|
|
391
|
+
"""Model for playbook alert POST ``{playbook_alert_id}`` endpoints."""
|
|
392
|
+
|
|
393
|
+
panels: Optional[list] = None
|