Skip to content

Commit d87ec76

Browse files
committed
gis-8825 added sentinel one power query render
1 parent 9231d12 commit d87ec76

File tree

6 files changed

+179
-1
lines changed

6 files changed

+179
-1
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
from app.translator.platforms.sentinel_one.renders.s1_cti import S1EventsCTI # noqa: F401
2+
from app.translator.platforms.sentinel_one.renders.sentinel_one_power_query import (
3+
SentinelOnePowerQueryRender, # noqa: F401
4+
)

uncoder-core/app/translator/platforms/sentinel_one/const.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from app.translator.core.models.platform_details import PlatformDetails
22

3-
43
PLATFORM_DETAILS = {"group_id": "sentinel-one", "group_name": "SentinelOne"}
54

65
SENTINEL_ONE_EVENTS_QUERY_DETAILS = {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from typing import ClassVar
2+
3+
from app.translator.core.custom_types.values import ValueType
4+
from app.translator.core.escape_manager import EscapeManager
5+
from app.translator.core.models.escape_details import EscapeDetails
6+
7+
8+
class SentinelOnePowerQueryEscapeManager(EscapeManager):
9+
escape_map: ClassVar[dict[str, list[EscapeDetails]]] = {
10+
ValueType.value: [EscapeDetails(pattern=r"\\", escape_symbols=r"\\\\")],
11+
ValueType.regex_value: [EscapeDetails(pattern=r"\\", escape_symbols=r"\\\\")],
12+
}
13+
14+
15+
sentinel_one_power_query_escape_manager = SentinelOnePowerQueryEscapeManager()
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from app.translator.core.mapping import BasePlatformMappings, LogSourceSignature
2+
from app.translator.platforms.sentinel_one.const import sentinel_one_power_query_details
3+
4+
5+
class SentinelOnePowerQueryLogSourceSignature(LogSourceSignature):
6+
def is_suitable(self) -> bool:
7+
return True
8+
9+
def __str__(self) -> str:
10+
return ""
11+
12+
13+
class SentinelOnePowerQueryMappings(BasePlatformMappings):
14+
def prepare_log_source_signature(self, mapping: dict) -> SentinelOnePowerQueryLogSourceSignature:
15+
...
16+
17+
18+
sentinel_one_power_query_query_mappings = SentinelOnePowerQueryMappings(
19+
platform_dir="sentinel_one", platform_details=sentinel_one_power_query_details
20+
)
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
from typing import Union, Optional
2+
3+
from app.translator.const import DEFAULT_VALUE_TYPE
4+
from app.translator.core.custom_types.values import ValueType
5+
from app.translator.core.mapping import LogSourceSignature
6+
from app.translator.core.models.platform_details import PlatformDetails
7+
from app.translator.core.render import BaseFieldValueRender, PlatformQueryRender
8+
from app.translator.core.str_value_manager import StrValueManager
9+
from app.translator.managers import render_manager
10+
from app.translator.platforms.sentinel_one.const import sentinel_one_power_query_details
11+
from app.translator.platforms.sentinel_one.mapping import (
12+
SentinelOnePowerQueryMappings,
13+
sentinel_one_power_query_query_mappings,
14+
)
15+
from app.translator.platforms.sentinel_one.str_value_manager import sentinel_one_power_query_str_value_manager
16+
17+
18+
class SentinelOnePowerQueryFieldValue(BaseFieldValueRender):
19+
details: PlatformDetails = sentinel_one_power_query_details
20+
str_value_manager: StrValueManager = sentinel_one_power_query_str_value_manager
21+
list_token = ", "
22+
23+
@staticmethod
24+
def _wrap_str_value(value: str) -> str:
25+
return f'"{value}"'
26+
27+
def equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
28+
if isinstance(value, list):
29+
values = self.list_token.join(
30+
self._pre_process_value(field, v, value_type=ValueType.value, wrap_str=True) for v in value
31+
)
32+
return f"{field} in ({values})"
33+
value = self._pre_process_value(field, value, value_type=ValueType.value, wrap_str=True)
34+
return f"{field} = {value}"
35+
36+
def less_modifier(self, field: str, value: Union[int, str]) -> str:
37+
value = self._pre_process_value(field, value, value_type=ValueType.value, wrap_str=True, wrap_int=True)
38+
return f"{field} < {value}"
39+
40+
def less_or_equal_modifier(self, field: str, value: Union[int, str]) -> str:
41+
value = self._pre_process_value(field, value, value_type=ValueType.value, wrap_str=True, wrap_int=True)
42+
return f"{field} <= {value}"
43+
44+
def greater_modifier(self, field: str, value: Union[int, str]) -> str:
45+
value = self._pre_process_value(field, value, value_type=ValueType.value, wrap_str=True, wrap_int=True)
46+
return f"{field} > {value}"
47+
48+
def greater_or_equal_modifier(self, field: str, value: Union[int, str]) -> str:
49+
value = self._pre_process_value(field, value, value_type=ValueType.value, wrap_str=True, wrap_int=True)
50+
return f"{field} >= {value}"
51+
52+
def not_equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
53+
if isinstance(value, list):
54+
values = self.list_token.join(
55+
self._pre_process_value(field, v, value_type=ValueType.value, wrap_str=True, wrap_int=True)
56+
for v in value
57+
)
58+
return f"{field} != ({values})"
59+
value = self._pre_process_value(field, value, value_type=ValueType.value, wrap_str=True, wrap_int=True)
60+
return f"{field} != {value}"
61+
62+
def contains_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
63+
if isinstance(value, list):
64+
values = self.list_token.join(
65+
self._pre_process_value(field, v, value_type=ValueType.value, wrap_str=True, wrap_int=True)
66+
for v in value
67+
)
68+
return f"{field} contains ({values})"
69+
value = self._pre_process_value(field, value, value_type=ValueType.value)
70+
return f"{field} contains {value}"
71+
72+
def endswith_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
73+
return self.contains_modifier(field, value)
74+
75+
def startswith_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
76+
return self.contains_modifier(field, value)
77+
78+
def regex_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
79+
if isinstance(value, list):
80+
values = self.list_token.join(
81+
self.str_value_manager.escape_manager.escape(
82+
self._pre_process_value(field, v, value_type=ValueType.regex_value, wrap_str=True, wrap_int=True),
83+
ValueType.regex_value,
84+
)
85+
for v in value
86+
)
87+
return f"{field} matches ({values})"
88+
value = self._pre_process_value(field, value, value_type=ValueType.regex_value, wrap_str=True, wrap_int=True)
89+
value = self.str_value_manager.escape_manager.escape(value, ValueType.regex_value)
90+
return f"{field} matches {value}"
91+
92+
def is_none(self, field: str, value: DEFAULT_VALUE_TYPE) -> str: # noqa: ARG002
93+
return f'not ({field} matches "\\.*")'
94+
95+
def is_not_none(self, field: str, value: DEFAULT_VALUE_TYPE) -> str: # noqa: ARG002
96+
return f'{field} matches "\\.*"'
97+
98+
99+
@render_manager.register
100+
class SentinelOnePowerQueryRender(PlatformQueryRender):
101+
details: PlatformDetails = sentinel_one_power_query_details
102+
mappings: SentinelOnePowerQueryMappings = sentinel_one_power_query_query_mappings
103+
or_token = "or"
104+
and_token = "and"
105+
not_token = "not"
106+
comment_symbol = "//"
107+
field_value_render = SentinelOnePowerQueryFieldValue(or_token=or_token)
108+
109+
def generate_prefix(self, log_source_signature: Optional[LogSourceSignature], functions_prefix: str = "") -> str:
110+
return "| columns "
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""
2+
Uncoder IO Community Edition License
3+
-----------------------------------------------------------------
4+
Copyright (c) 2024 SOC Prime, Inc.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
-----------------------------------------------------------------
18+
"""
19+
20+
from app.translator.core.str_value_manager import StrValueManager
21+
from app.translator.platforms.sentinel_one.escape_manager import (
22+
SentinelOnePowerQueryEscapeManager,
23+
sentinel_one_power_query_escape_manager,
24+
)
25+
26+
27+
class SentinelOnePowerQueryStrValueManager(StrValueManager):
28+
escape_manager: SentinelOnePowerQueryEscapeManager = sentinel_one_power_query_escape_manager
29+
30+
31+
sentinel_one_power_query_str_value_manager = SentinelOnePowerQueryStrValueManager()

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy