Skip to content

Commit fe2aa2f

Browse files
authored
Merge pull request #107 from UncoderIO/gis-7683
platforms init refactoring
2 parents b0a757f + 15bd579 commit fe2aa2f

File tree

95 files changed

+299
-159
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+299
-159
lines changed

uncoder-core/app/translator/cti_translator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111

1212
class CTITranslator:
13-
renders: RenderCTIManager = render_cti_manager
13+
render_manager: RenderCTIManager = render_cti_manager
1414

1515
def __init__(self):
1616
self.logger = logging.getLogger("cti_translator")
@@ -38,7 +38,7 @@ def __parse_iocs_from_string(
3838

3939
@handle_translation_exceptions
4040
def __render_translation(self, parsed_data: dict, platform_data: CTIPlatform, iocs_per_query: int) -> list[str]:
41-
render_cti = self.renders.get(platform_data.id)
41+
render_cti = self.render_manager.get(platform_data.id)
4242

4343
chunked_iocs = self.__get_iocs_chunk(
4444
chunks_size=iocs_per_query, data=parsed_data, mapping=render_cti.default_mapping
@@ -85,4 +85,4 @@ def __get_iocs_chunk(
8585

8686
@classmethod
8787
def get_renders(cls) -> list:
88-
return cls.renders.get_platforms_details
88+
return cls.render_manager.get_platforms_details

uncoder-core/app/translator/managers.py

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,26 @@
11
from abc import ABC
2+
from functools import cached_property
23

34
from app.models.translation import TranslatorPlatform
45
from app.translator.core.exceptions.core import UnsupportedRootAParser
5-
from app.translator.platforms import __ALL_PARSERS as PARSERS
6-
from app.translator.platforms import __ALL_RENDERS as RENDERS
7-
from app.translator.platforms import __ALL_RENDERS_CTI as RENDERS_CTI
86

97

108
class Manager(ABC):
11-
platforms_class = ()
9+
platforms = {}
1210

13-
@property
14-
def platforms(self) -> dict:
15-
return {platform.details.platform_id: platform for platform in self.platforms_class}
11+
def register(self, cls):
12+
self.platforms[cls.details.platform_id] = cls()
13+
return cls
1614

1715
def get(self, platform_id: str): # noqa: ANN201
1816
if platform := self.platforms.get(platform_id):
1917
return platform
2018
raise UnsupportedRootAParser(parser=platform_id)
2119

2220
def all_platforms(self) -> list:
23-
return list(self.platforms)
21+
return list(self.platforms.keys())
2422

25-
@property
23+
@cached_property
2624
def get_platforms_details(self) -> list[TranslatorPlatform]:
2725
platforms = [
2826
TranslatorPlatform(
@@ -37,21 +35,59 @@ def get_platforms_details(self) -> list[TranslatorPlatform]:
3735
alt_platform=platform.details.alt_platform,
3836
first_choice=platform.details.first_choice,
3937
)
40-
for platform in self.platforms_class
38+
for platform in self.platforms.values()
4139
]
4240
return sorted(platforms, key=lambda platform: platform.group_name)
4341

4442

45-
class RenderManager(Manager):
46-
platforms_class = RENDERS
43+
class ParserManager(Manager):
44+
platforms = {}
45+
supported_by_roota_platforms = {}
46+
main_platforms = {}
4747

48+
def get_supported_by_roota(self, platform_id: str): # noqa: ANN201
49+
if platform := self.supported_by_roota_platforms.get(platform_id):
50+
return platform
51+
raise UnsupportedRootAParser(parser=platform_id)
4852

49-
class ParserManager(Manager):
50-
platforms_class = PARSERS
53+
def register_supported_by_roota(self, cls):
54+
parser = cls()
55+
self.supported_by_roota_platforms[cls.details.platform_id] = parser
56+
self.platforms[cls.details.platform_id] = parser
57+
return cls
58+
59+
def register_main(self, cls):
60+
parser = cls()
61+
self.main_platforms[cls.details.platform_id] = parser
62+
self.platforms[cls.details.platform_id] = parser
63+
return cls
64+
65+
@cached_property
66+
def get_platforms_details(self) -> list[TranslatorPlatform]:
67+
platforms = [
68+
TranslatorPlatform(
69+
id=platform.details.platform_id,
70+
name=platform.details.name,
71+
code=platform.details.platform_id,
72+
group_name=platform.details.group_name,
73+
group_id=platform.details.group_id,
74+
platform_name=platform.details.platform_name,
75+
platform_id=platform.details.platform_id,
76+
alt_platform_name=platform.details.alt_platform_name,
77+
alt_platform=platform.details.alt_platform,
78+
first_choice=platform.details.first_choice,
79+
)
80+
for platform in self.platforms.values()
81+
]
82+
return sorted(platforms, key=lambda platform: platform.group_name)
83+
84+
85+
class RenderManager(Manager):
86+
platforms = {}
5187

5288

5389
class RenderCTIManager(Manager):
54-
platforms_class = RENDERS_CTI
90+
platforms = {}
5591

5692

5793
parser_manager = ParserManager()
Lines changed: 13 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -1,134 +1,17 @@
1-
from app.translator.platforms.athena.parsers.athena import AthenaQueryParser
2-
from app.translator.platforms.athena.renders.athena import AthenaQueryRender
3-
from app.translator.platforms.athena.renders.athena_cti import AthenaCTI
4-
from app.translator.platforms.carbonblack.renders.carbonblack_cti import CarbonBlackCTI
5-
from app.translator.platforms.chronicle.parsers.chronicle import ChronicleQueryParser
6-
from app.translator.platforms.chronicle.parsers.chronicle_rule import ChronicleRuleParser
7-
from app.translator.platforms.chronicle.renders.chronicle import ChronicleQueryRender
8-
from app.translator.platforms.chronicle.renders.chronicle_cti import ChronicleQueryCTI
9-
from app.translator.platforms.chronicle.renders.chronicle_rule import ChronicleSecurityRuleRender
10-
from app.translator.platforms.crowdstrike.parsers.crowdstrike import CrowdStrikeQueryParser
11-
from app.translator.platforms.crowdstrike.renders.crowdstrike import CrowdStrikeQueryRender
12-
from app.translator.platforms.crowdstrike.renders.crowdstrike_cti import CrowdStrikeCTI
13-
from app.translator.platforms.elasticsearch.parsers.detection_rule import ElasticSearchRuleParser
14-
from app.translator.platforms.elasticsearch.parsers.elasticsearch import ElasticSearchQueryParser
15-
from app.translator.platforms.elasticsearch.renders.detection_rule import ElasticSearchRuleRender
16-
from app.translator.platforms.elasticsearch.renders.elast_alert import ElastAlertRuleRender
17-
from app.translator.platforms.elasticsearch.renders.elasticsearch import ElasticSearchQueryRender
18-
from app.translator.platforms.elasticsearch.renders.elasticsearch_cti import ElasticsearchCTI
19-
from app.translator.platforms.elasticsearch.renders.kibana import KibanaRuleRender
20-
from app.translator.platforms.elasticsearch.renders.xpack_watcher import XPackWatcherRuleRender
21-
from app.translator.platforms.fireeye_helix.renders.fireeye_helix_cti import FireeyeHelixCTI
22-
from app.translator.platforms.forti_siem.renders.forti_siem_rule import FortiSiemRuleRender
23-
from app.translator.platforms.graylog.parsers.graylog import GraylogQueryParser
24-
from app.translator.platforms.graylog.renders.graylog import GraylogQueryRender
25-
from app.translator.platforms.graylog.renders.graylog_cti import GraylogCTI
26-
from app.translator.platforms.logpoint.renders.logpoint_cti import LogpointCTI
27-
from app.translator.platforms.logrhythm_axon.renders.logrhythm_axon_query import LogRhythmAxonQueryRender
28-
from app.translator.platforms.logrhythm_axon.renders.logrhythm_axon_rule import LogRhythmAxonRuleRender
29-
from app.translator.platforms.logscale.parsers.logscale import LogScaleQueryParser
30-
from app.translator.platforms.logscale.parsers.logscale_alert import LogScaleAlertParser
31-
from app.translator.platforms.logscale.renders.logscale import LogScaleQueryRender
32-
from app.translator.platforms.logscale.renders.logscale_alert import LogScaleAlertRender
33-
from app.translator.platforms.logscale.renders.logscale_cti import LogScaleCTI
34-
from app.translator.platforms.microsoft.parsers.microsoft_defender import MicrosoftDefenderQueryParser
35-
from app.translator.platforms.microsoft.parsers.microsoft_sentinel import MicrosoftSentinelQueryParser
36-
from app.translator.platforms.microsoft.parsers.microsoft_sentinel_rule import MicrosoftSentinelRuleParser
37-
from app.translator.platforms.microsoft.renders.microsoft_defender import MicrosoftDefenderQueryRender
38-
from app.translator.platforms.microsoft.renders.microsoft_defender_cti import MicrosoftDefenderCTI
39-
from app.translator.platforms.microsoft.renders.microsoft_sentinel import MicrosoftSentinelQueryRender
40-
from app.translator.platforms.microsoft.renders.microsoft_sentinel_cti import MicrosoftSentinelCTI
41-
from app.translator.platforms.microsoft.renders.microsoft_sentinel_rule import MicrosoftSentinelRuleRender
42-
from app.translator.platforms.opensearch.parsers.opensearch import OpenSearchQueryParser
43-
from app.translator.platforms.opensearch.renders.opensearch import OpenSearchQueryRender
44-
from app.translator.platforms.opensearch.renders.opensearch_cti import OpenSearchCTI
45-
from app.translator.platforms.opensearch.renders.opensearch_rule import OpenSearchRuleRender
46-
from app.translator.platforms.palo_alto.renders.cortex_xsiam import CortexXQLQueryRender
47-
from app.translator.platforms.qradar.parsers.qradar import QradarQueryParser
48-
from app.translator.platforms.qradar.renders.qradar import QradarQueryRender
49-
from app.translator.platforms.qradar.renders.qradar_cti import QRadarCTI
50-
from app.translator.platforms.qualys.renders.qualys_cti import QualysCTI
51-
from app.translator.platforms.rsa_netwitness.renders.rsa_netwitness_cti import RSANetwitnessCTI
52-
from app.translator.platforms.securonix.renders.securonix_cti import SecuronixCTI
53-
from app.translator.platforms.sentinel_one.renders.s1_cti import S1EventsCTI
54-
from app.translator.platforms.sigma.parsers.sigma import SigmaParser
55-
from app.translator.platforms.sigma.renders.sigma import SigmaRender
56-
from app.translator.platforms.snowflake.renders.snowflake_cti import SnowflakeCTI
57-
from app.translator.platforms.splunk.parsers.splunk import SplunkQueryParser
58-
from app.translator.platforms.splunk.parsers.splunk_alert import SplunkAlertParser
59-
from app.translator.platforms.splunk.renders.splunk import SplunkQueryRender
60-
from app.translator.platforms.splunk.renders.splunk_alert import SplunkAlertRender
61-
from app.translator.platforms.splunk.renders.splunk_cti import SplunkCTI
62-
from app.translator.platforms.sumo_logic.renders.sumologic_cti import SumologicCTI
1+
import importlib.util
2+
import os
633

64-
__ALL_RENDERS = (
65-
SigmaRender(),
66-
MicrosoftSentinelQueryRender(),
67-
MicrosoftSentinelRuleRender(),
68-
MicrosoftDefenderQueryRender(),
69-
QradarQueryRender(),
70-
CrowdStrikeQueryRender(),
71-
SplunkQueryRender(),
72-
SplunkAlertRender(),
73-
ChronicleQueryRender(),
74-
ChronicleSecurityRuleRender(),
75-
AthenaQueryRender(),
76-
ElasticSearchQueryRender(),
77-
LogRhythmAxonQueryRender(),
78-
LogRhythmAxonRuleRender(),
79-
LogScaleQueryRender(),
80-
LogScaleAlertRender(),
81-
ElasticSearchRuleRender(),
82-
ElastAlertRuleRender(),
83-
KibanaRuleRender(),
84-
XPackWatcherRuleRender(),
85-
OpenSearchQueryRender(),
86-
OpenSearchRuleRender(),
87-
GraylogQueryRender(),
88-
FortiSiemRuleRender(),
89-
CortexXQLQueryRender(),
90-
)
4+
from const import PLATFORMS_PATH
915

92-
__ALL_PARSERS = (
93-
AthenaQueryParser(),
94-
ChronicleQueryParser(),
95-
ChronicleRuleParser(),
96-
SplunkQueryParser(),
97-
SplunkAlertParser(),
98-
SigmaParser(),
99-
QradarQueryParser(),
100-
MicrosoftSentinelQueryParser(),
101-
MicrosoftSentinelRuleParser(),
102-
MicrosoftDefenderQueryParser(),
103-
CrowdStrikeQueryParser(),
104-
LogScaleQueryParser(),
105-
LogScaleAlertParser(),
106-
ElasticSearchQueryParser(),
107-
ElasticSearchRuleParser(),
108-
OpenSearchQueryParser(),
109-
GraylogQueryParser(),
110-
)
1116

7+
def init_platforms():
8+
for platform in [f for f in os.listdir(PLATFORMS_PATH) if os.path.isdir(os.path.join(PLATFORMS_PATH, f))]:
9+
if not platform.startswith("__") and not platform.endswith("__"):
10+
# Platforms __init__.py execution
11+
init_path = f"{PLATFORMS_PATH}/{platform}/__init__.py"
12+
spec = importlib.util.spec_from_file_location("__init__", init_path)
13+
init_module = importlib.util.module_from_spec(spec)
14+
spec.loader.exec_module(init_module)
11215

113-
__ALL_RENDERS_CTI = (
114-
MicrosoftSentinelCTI(),
115-
MicrosoftDefenderCTI(),
116-
QRadarCTI(),
117-
SplunkCTI(),
118-
ChronicleQueryCTI(),
119-
CrowdStrikeCTI(),
120-
SumologicCTI(),
121-
ElasticsearchCTI(),
122-
LogScaleCTI(),
123-
OpenSearchCTI(),
124-
FireeyeHelixCTI(),
125-
CarbonBlackCTI(),
126-
GraylogCTI(),
127-
LogpointCTI(),
128-
QualysCTI(),
129-
RSANetwitnessCTI(),
130-
S1EventsCTI(),
131-
SecuronixCTI(),
132-
SnowflakeCTI(),
133-
AthenaCTI(),
134-
)
16+
17+
init_platforms()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from app.translator.platforms.arcsight.renders.arcsight_cti import ArcsightKeyword
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from app.translator.core.models.platform_details import PlatformDetails
2+
from app.translator.core.render_cti import RenderCTI
3+
from app.translator.managers import render_cti_manager
4+
from app.translator.platforms.arcsight.const import ARCSIGHT_QUERY_DETAILS
5+
from app.translator.platforms.arcsight.mappings.arcsight_cti import DEFAULT_ARCSIGHT_MAPPING
6+
7+
8+
@render_cti_manager.register
9+
class ArcsightKeyword(RenderCTI):
10+
details: PlatformDetails = PlatformDetails(**ARCSIGHT_QUERY_DETAILS)
11+
12+
default_mapping = DEFAULT_ARCSIGHT_MAPPING
13+
field_value_template: str = "{key} = {value}"
14+
or_operator: str = " OR "
15+
group_or_operator: str = " OR "
16+
or_group: str = "{or_group}"
17+
result_join: str = ""
18+
final_result_for_many: str = '({result}) AND type != 2 | rex field = flexString1 mode=sed "s//Sigma: None/g"\n'
19+
final_result_for_one: str = '{result} AND type != 2 | rex field = flexString1 mode=sed "s//Sigma: None/g"\n'
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from app.translator.platforms.athena.parsers.athena import AthenaQueryParser
2+
from app.translator.platforms.athena.renders.athena import AthenaQueryRender
3+
from app.translator.platforms.athena.renders.athena_cti import AthenaCTI

uncoder-core/app/translator/platforms/athena/parsers/athena.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@
2222
from app.translator.core.models.platform_details import PlatformDetails
2323
from app.translator.core.models.query_container import RawQueryContainer, TokenizedQueryContainer
2424
from app.translator.core.parser import PlatformQueryParser
25+
from app.translator.managers import parser_manager
2526
from app.translator.platforms.athena.const import athena_details
2627
from app.translator.platforms.athena.mapping import AthenaMappings, athena_mappings
2728
from app.translator.platforms.athena.tokenizer import AthenaTokenizer
2829

2930

31+
@parser_manager.register_supported_by_roota
3032
class AthenaQueryParser(PlatformQueryParser):
3133
details: PlatformDetails = athena_details
3234
mappings: AthenaMappings = athena_mappings

uncoder-core/app/translator/platforms/athena/renders/athena.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from app.translator.core.mapping import LogSourceSignature
2424
from app.translator.core.models.platform_details import PlatformDetails
2525
from app.translator.core.render import BaseQueryFieldValue, PlatformQueryRender
26+
from app.translator.managers import render_manager
2627
from app.translator.platforms.athena.const import athena_details
2728
from app.translator.platforms.athena.mapping import AthenaMappings, athena_mappings
2829

@@ -76,6 +77,7 @@ def keywords(self, field: str, value: DEFAULT_VALUE_TYPE) -> str: # noqa: ARG00
7677
raise UnsupportedRenderMethod(platform_name=self.details.name, method="Keywords")
7778

7879

80+
@render_manager.register
7981
class AthenaQueryRender(PlatformQueryRender):
8082
details: PlatformDetails = athena_details
8183
mappings: AthenaMappings = athena_mappings

uncoder-core/app/translator/platforms/athena/renders/athena_cti.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919

2020
from app.translator.core.models.platform_details import PlatformDetails
2121
from app.translator.core.render_cti import RenderCTI
22+
from app.translator.managers import render_cti_manager
2223
from app.translator.platforms.athena.const import athena_details
2324
from app.translator.platforms.athena.mappings.athena_cti import DEFAULT_ATHENA_MAPPING
2425

2526

27+
@render_cti_manager.register
2628
class AthenaCTI(RenderCTI):
2729
details: PlatformDetails = athena_details
2830

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from app.translator.platforms.carbonblack.renders.carbonblack_cti import CarbonBlackCTI

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