1- from collections .abc import Iterable
21import json
32import os
4-
5- from modules import util
3+ from collections . abc import Iterable
4+ from typing import List
65
76from loguru import logger
87
9- from . import groups_config
8+ from modules import util
9+
1010from .. import site_config
11+ from . import groups_config
1112
1213
1314def generate_groups ():
14- """Responsible for verifying group directory and starting off
15- group markdown generation
16- """
17-
15+ """Responsible for verifying group directory and starting off group markdown generation."""
1816 # Create content pages directory if does not already exist
1917 util .buildhelpers .create_content_pages_dir ()
2018
@@ -44,10 +42,7 @@ def generate_groups():
4442
4543
4644def generate_markdown_files ():
47- """Responsible for generating group index page and getting shared data for
48- all groups
49- """
50-
45+ """Responsible for generating group index page and getting shared data for all groups."""
5146 has_group = False
5247
5348 group_list = util .relationshipgetters .get_group_list ()
@@ -60,9 +55,6 @@ def generate_markdown_files():
6055 if has_group :
6156 data = {}
6257
63- # Amount of characters per category
64- group_by = 2
65-
6658 notes = util .relationshipgetters .get_objects_using_notes ()
6759 side_menu_data = util .buildhelpers .get_side_menu_data ("Groups" , "/groups/" , group_list_no_deprecated_revoked )
6860 data ["side_menu_data" ] = side_menu_data
@@ -84,8 +76,7 @@ def generate_markdown_files():
8476
8577
8678def generate_group_md (group , side_menu_data , notes ):
87- """Responsible for generating markdown of all groups"""
88-
79+ """Responsible for generating markdown of all groups."""
8980 attack_id = util .buildhelpers .get_attack_id (group )
9081
9182 if attack_id :
@@ -132,13 +123,13 @@ def generate_group_md(group, side_menu_data, notes):
132123
133124 # Get navigator layers for this group
134125 layers = util .buildhelpers .get_navigator_layers (
135- data ["name" ],
136- data ["attack_id" ],
137- "group" ,
138- "used by" ,
139- data ["version" ] if "version" in data else None ,
140- data ["technique_table_data" ],
141- inheritance , # extend legend to include color coding for inherited techniques, if applicable
126+ name = data ["name" ],
127+ attack_id = data ["attack_id" ],
128+ obj_type = "group" ,
129+ rel_type = "used by" ,
130+ version = data ["version" ] if "version" in data else None ,
131+ techniques_used = data ["technique_table_data" ],
132+ inheritance = inheritance , # extend legend to include color coding for inherited techniques, if applicable
142133 )
143134
144135 data ["layers" ] = []
@@ -166,13 +157,19 @@ def generate_group_md(group, side_menu_data, notes):
166157 )
167158
168159 # get campaign data for campaign table
169- data ["campaign_data" ], data ["add_campaign_ref" ] = get_campaign_table_data (group , reference_list )
160+ data ["campaign_data" ], data ["add_campaign_ref" ] = get_campaign_table_data (
161+ group = group , reference_list = reference_list
162+ )
170163
171164 # Grab software data for Software table
172- data ["software_data" ], data ["add_software_ref" ] = get_software_table_data (group , reference_list )
165+ data ["software_data" ], data ["add_software_ref" ] = get_software_table_data (
166+ group = group , reference_list = reference_list
167+ )
173168
174169 if group .get ("aliases" ):
175- data ["alias_descriptions" ] = util .buildhelpers .get_alias_data (group ["aliases" ][1 :], ext_ref )
170+ data ["alias_descriptions" ] = util .buildhelpers .get_alias_data (
171+ alias_list = group ["aliases" ][1 :], ext_refs = ext_ref
172+ )
176173
177174 data ["citations" ] = reference_list
178175
@@ -192,8 +189,7 @@ def generate_group_md(group, side_menu_data, notes):
192189
193190
194191def get_groups_table_data (group_list ):
195- """Responsible for generating group table data for the group index page"""
196-
192+ """Responsible for generating group table data for the group index page."""
197193 groups_table_data = []
198194
199195 # Now the table on the right, which is made up of group data
@@ -223,9 +219,9 @@ def get_groups_table_data(group_list):
223219
224220
225221def get_techniques_used_by_group_data (group , reference_list ):
226- """Given a group and its reference list, get the techniques used by the
227- group. Check the reference list for citations, if not found
228- in list, add it.
222+ """Given a group and its reference list, get the techniques used by the group.
223+
224+ Check the reference list for citations, if not found in list, add it.
229225 """
230226 technique_list = {}
231227
@@ -304,7 +300,7 @@ def get_campaign_table_data(group, reference_list):
304300 reference_list = util .buildhelpers .update_reference_list (reference_list , campaign ["object" ])
305301
306302 if campaign ["relationship" ].get ("description" ):
307- if reference == False :
303+ if reference is False :
308304 reference = True
309305
310306 campaign_list [campaign_id ]["desc" ] = campaign ["relationship" ]["description" ]
@@ -344,7 +340,7 @@ def get_campaign_table_data(group, reference_list):
344340
345341
346342def get_software_table_data (group , reference_list ):
347- """Given a group, get software table data"""
343+ """Given a group, get software table data. """
348344 software_list = {}
349345 reference = False
350346
@@ -361,7 +357,11 @@ def get_software_table_data(group, reference_list):
361357 ]
362358 # get malware or tools used by group
363359 software_list , reference = update_software_list (
364- tools_and_malware , software_list , reference_list , reference , group .get ("id" )
360+ pairings = tools_and_malware ,
361+ software_list = software_list ,
362+ reference_list = reference_list ,
363+ reference = reference ,
364+ id = group .get ("id" ),
365365 )
366366
367367 # campaigns attributed to groups
@@ -384,7 +384,11 @@ def get_software_table_data(group, reference_list):
384384 campaign_id = campaign ["object" ]["id" ]
385385 # get malware or tools used by campaigns
386386 software_list , reference = update_software_list (
387- software_used_by_campaigns , software_list , reference_list , reference , campaign_id
387+ pairings = software_used_by_campaigns ,
388+ software_list = software_list ,
389+ reference_list = reference_list ,
390+ reference = reference ,
391+ id = campaign_id ,
388392 )
389393
390394 # Moving it to an array because jinja does not like to loop through dictionaries
@@ -400,12 +404,36 @@ def get_software_table_data(group, reference_list):
400404 return data , reference
401405
402406
403- def update_software_list (pairings , software_list , reference_list , reference , id ):
407+ def update_software_list (pairings : List , software_list : List , reference_list : List , reference : bool , id : str ):
408+ """Update the software list with the given pairings.
409+
410+ This function iterates through the given pairings and updates the software list with
411+ the software that matches the given ID. It also updates the reference list with the
412+ corresponding reference.
413+
414+ Parameters
415+ ----------
416+ pairings : List
417+ A list of dictionaries that contain software and reference data.
418+ software_list : List
419+ The list of software to be updated.
420+ reference_list : List
421+ The list of references to be updated.
422+ reference : bool
423+ Whether the reference section should be included.
424+ id : str
425+ The ID of the software to be added to the software list.
426+
427+ Returns
428+ -------
429+ tuple
430+ A tuple containing the updated software list and whether the reference section should be included.
431+ """
404432 for pairing in pairings :
405433 if pairing ["software" ].get (id ):
406434 for software in pairing ["software" ][id ]:
407435 software_stix_id = software ["object" ]["id" ]
408- software_attack_id = util .buildhelpers .get_attack_id (software ["object" ])
436+ software_attack_id = util .buildhelpers .get_attack_id (object = software ["object" ])
409437 # check if software not in software_list dict
410438 if software_stix_id not in software_list and software_attack_id :
411439 software_list [software_stix_id ] = {"id" : software_attack_id , "name" : software ["object" ]["name" ]}
@@ -416,7 +444,7 @@ def update_software_list(pairings, software_list, reference_list, reference, id)
416444 software_list [software_stix_id ]["descr" ] = software ["relationship" ]["description" ]
417445 # Update reference list
418446 reference_list = util .buildhelpers .update_reference_list (
419- reference_list , software ["relationship" ]
447+ reference_list = reference_list , obj = software ["relationship" ]
420448 )
421449
422450 # Check if techniques exists, add techniques used by software
@@ -426,12 +454,12 @@ def update_software_list(pairings, software_list, reference_list, reference, id)
426454
427455 for technique in pairing ["techniques" ][software_stix_id ]:
428456 tech_data = {}
429- t_id = util .buildhelpers .get_attack_id (technique ["object" ])
457+ t_id = util .buildhelpers .get_attack_id (object = technique ["object" ])
430458 if t_id :
431- if util .buildhelpers .is_sub_tid (t_id ):
432- tech_data ["parent_id" ] = util .buildhelpers .get_parent_technique_id (t_id )
433- tech_data ["id" ] = util .buildhelpers .get_sub_technique_id (t_id )
434- tech_data ["name" ] = util .buildhelpers .get_technique_name (tech_data ["parent_id" ])
459+ if util .buildhelpers .is_sub_tid (sub_tid = t_id ):
460+ tech_data ["parent_id" ] = util .buildhelpers .get_parent_technique_id (sub_tid = t_id )
461+ tech_data ["id" ] = util .buildhelpers .get_sub_technique_id (sub_tid = t_id )
462+ tech_data ["name" ] = util .buildhelpers .get_technique_name (tid = tech_data ["parent_id" ])
435463 tech_data ["sub_name" ] = technique ["object" ]["name" ]
436464 else :
437465 tech_data ["id" ] = t_id
@@ -440,6 +468,7 @@ def update_software_list(pairings, software_list, reference_list, reference, id)
440468 software_list [software_stix_id ]["techniques" ].append (tech_data )
441469 return software_list , reference
442470
471+
443472def generate_sidebar_groups (side_menu_data ):
444473 """Responsible for generating the sidebar for the groups pages."""
445474 logger .info ("Generating groups sidebar" )
0 commit comments