mirror of https://github.com/MISP/PyMISP
chg: [exportPDF] add basic handling of clusters
parent
a9c0ce4107
commit
9adff0b574
|
@ -10,6 +10,8 @@ from functools import partial
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from orca.cmdnames import TABLE_CELL_FIRST
|
||||||
|
|
||||||
if sys.version_info.major >= 3:
|
if sys.version_info.major >= 3:
|
||||||
from html import escape
|
from html import escape
|
||||||
# import PIL
|
# import PIL
|
||||||
|
@ -125,7 +127,8 @@ class Flowable_Tag(Flowable):
|
||||||
|
|
||||||
|
|
||||||
# Copy of pdfexport.py moduleconfig
|
# Copy of pdfexport.py moduleconfig
|
||||||
moduleconfig = ["MISP_base_url_for_dynamic_link", "MISP_name_for_metadata", "Activate_textual_description"]
|
moduleconfig = ["MISP_base_url_for_dynamic_link", "MISP_name_for_metadata", "Activate_textual_description",
|
||||||
|
"Activate_galaxy_description"]
|
||||||
|
|
||||||
# == Row colors of the table (alternating) ==
|
# == Row colors of the table (alternating) ==
|
||||||
EVEN_COLOR = colors.whitesmoke
|
EVEN_COLOR = colors.whitesmoke
|
||||||
|
@ -309,6 +312,71 @@ def get_table_styles():
|
||||||
return custom_body_style_col_1, custom_body_style_col_2
|
return custom_body_style_col_1, custom_body_style_col_2
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# Checks
|
||||||
|
|
||||||
|
def safe_string(bad_str):
|
||||||
|
return escape(str(bad_str))
|
||||||
|
|
||||||
|
def is_safe_attribute(curr_object, attribute_name):
|
||||||
|
return hasattr(curr_object, attribute_name) and getattr(curr_object, attribute_name) is not None and getattr(
|
||||||
|
curr_object, attribute_name) != ""
|
||||||
|
|
||||||
|
|
||||||
|
def is_safe_dict_attribute(curr_object, attribute_name):
|
||||||
|
return attribute_name in curr_object and curr_object[attribute_name] is not None and curr_object[
|
||||||
|
attribute_name] != ""
|
||||||
|
|
||||||
|
|
||||||
|
def is_safe_attribute_table(curr_object, attribute_name):
|
||||||
|
return hasattr(curr_object, attribute_name) and getattr(curr_object, attribute_name) is not None and getattr(
|
||||||
|
curr_object, attribute_name) != []
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# General attribut formater
|
||||||
|
|
||||||
|
def get_unoverflowable_paragraph(dirty_string, curr_style, do_escape_string=True):
|
||||||
|
'''
|
||||||
|
Create a paragraph that can fit on a cell of one page. Mostly hardcoded values.
|
||||||
|
This method can be improved (get the exact size of the current frame, and limit the paragraph to this size.)
|
||||||
|
This might be worst look at KeepInFrame (which hasn't went well so far)
|
||||||
|
:param do_escape_string: Activate the escaping (may be useful to add inline HTML, e.g. hyperlinks)
|
||||||
|
:param dirty_string: String to transform
|
||||||
|
:param curr_style: Style to apply to the returned paragraph
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
|
if do_escape_string:
|
||||||
|
sanitized_str = str(escape(str(dirty_string)))
|
||||||
|
else:
|
||||||
|
sanitized_str = dirty_string
|
||||||
|
|
||||||
|
# Get the space that the paragraph needs to be printed
|
||||||
|
w, h = Paragraph(sanitized_str, curr_style).wrap(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT)
|
||||||
|
|
||||||
|
# If there is enough space, directly send back the sanitized paragraph
|
||||||
|
if w <= FRAME_MAX_WIDTH and h <= FRAME_MAX_HEIGHT:
|
||||||
|
answer_paragraph = Paragraph(sanitized_str, curr_style)
|
||||||
|
else:
|
||||||
|
# Otherwise, cut the content to fit the paragraph (Dichotomy)
|
||||||
|
max_carac_amount = int((FRAME_MAX_HEIGHT / (h * 1.0)) * len(sanitized_str))
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
MAX_ITERATION = 10
|
||||||
|
limited_string = ""
|
||||||
|
while (w > FRAME_MAX_WIDTH or h > FRAME_MAX_HEIGHT) and i < MAX_ITERATION:
|
||||||
|
i += 1
|
||||||
|
limited_string = sanitized_str[:max_carac_amount] # .replace("\n", "").replace("\r", "")
|
||||||
|
w, h = Paragraph(limited_string + STR_TOO_LONG_WARNING, curr_style).wrap(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT)
|
||||||
|
max_carac_amount = int(max_carac_amount / 2)
|
||||||
|
|
||||||
|
if w <= FRAME_MAX_WIDTH and h <= FRAME_MAX_HEIGHT:
|
||||||
|
answer_paragraph = Paragraph(limited_string + STR_TOO_LONG_WARNING, curr_style)
|
||||||
|
else:
|
||||||
|
# We may still end with a not short enough string
|
||||||
|
answer_paragraph = Paragraph(STR_TOO_LONG_WARNING, curr_style)
|
||||||
|
|
||||||
|
return answer_paragraph
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Specific attribute formater
|
# Specific attribute formater
|
||||||
|
|
||||||
|
@ -368,6 +436,7 @@ def get_date_value(misp_event, item, col2_style):
|
||||||
return Paragraph(safe_string(getattr(misp_event, item[1])), col2_style)
|
return Paragraph(safe_string(getattr(misp_event, item[1])), col2_style)
|
||||||
return Paragraph(item[2], col2_style)
|
return Paragraph(item[2], col2_style)
|
||||||
|
|
||||||
|
|
||||||
def get_owner_value(misp_event, item, col2_style):
|
def get_owner_value(misp_event, item, col2_style):
|
||||||
'''
|
'''
|
||||||
Returns a flowable paragraph to add to the pdf given the misp_event owner
|
Returns a flowable paragraph to add to the pdf given the misp_event owner
|
||||||
|
@ -382,6 +451,7 @@ def get_owner_value(misp_event, item, col2_style):
|
||||||
return Paragraph(safe_string(getattr(misp_event, item[1])), col2_style)
|
return Paragraph(safe_string(getattr(misp_event, item[1])), col2_style)
|
||||||
return Paragraph(item[2], col2_style)
|
return Paragraph(item[2], col2_style)
|
||||||
|
|
||||||
|
|
||||||
def get_threat_value(misp_event, item, col2_style):
|
def get_threat_value(misp_event, item, col2_style):
|
||||||
'''
|
'''
|
||||||
Returns a flowable paragraph to add to the pdf given the misp_event threat
|
Returns a flowable paragraph to add to the pdf given the misp_event threat
|
||||||
|
@ -396,6 +466,7 @@ def get_threat_value(misp_event, item, col2_style):
|
||||||
return Paragraph(threat_map[safe_string(getattr(misp_event, item[1]))], col2_style)
|
return Paragraph(threat_map[safe_string(getattr(misp_event, item[1]))], col2_style)
|
||||||
return Paragraph(item[2], col2_style)
|
return Paragraph(item[2], col2_style)
|
||||||
|
|
||||||
|
|
||||||
def get_analysis_value(misp_event, item, col2_style):
|
def get_analysis_value(misp_event, item, col2_style):
|
||||||
'''
|
'''
|
||||||
Returns a flowable paragraph to add to the pdf given the misp_event analysis
|
Returns a flowable paragraph to add to the pdf given the misp_event analysis
|
||||||
|
@ -410,6 +481,7 @@ def get_analysis_value(misp_event, item, col2_style):
|
||||||
return Paragraph(analysis_map[safe_string(getattr(misp_event, item[1]))], col2_style)
|
return Paragraph(analysis_map[safe_string(getattr(misp_event, item[1]))], col2_style)
|
||||||
return Paragraph(item[2], col2_style)
|
return Paragraph(item[2], col2_style)
|
||||||
|
|
||||||
|
|
||||||
def get_timestamp_value(misp_event, item, col2_style):
|
def get_timestamp_value(misp_event, item, col2_style):
|
||||||
'''
|
'''
|
||||||
Returns a flowable paragraph to add to the pdf given the misp_event timestamp
|
Returns a flowable paragraph to add to the pdf given the misp_event timestamp
|
||||||
|
@ -471,6 +543,22 @@ def get_tag_value(misp_event, item, col2_style):
|
||||||
return Paragraph(item[2], col2_style)
|
return Paragraph(item[2], col2_style)
|
||||||
|
|
||||||
|
|
||||||
|
def get_galaxy_value(misp_event, item, col2_style):
|
||||||
|
'''
|
||||||
|
Returns a flowable paragraph to add to the pdf given the misp_event galaxies
|
||||||
|
:param misp_event: A misp event with or without "galaxies" attributes
|
||||||
|
:param item: a list of name, in order :
|
||||||
|
["Name to be print in the pdf", "json property access name",
|
||||||
|
" Name to be display if no values found in the misp_event"]
|
||||||
|
:param col2_style: style to be applied on the returned paragraph
|
||||||
|
:return: a Paragraph to add in the pdf, regarding the values of "galaxies"
|
||||||
|
'''
|
||||||
|
if is_safe_attribute_table(misp_event, item[1]):
|
||||||
|
table_event_tags = create_flowable_table_from_galaxies(misp_event)
|
||||||
|
return table_event_tags
|
||||||
|
return Paragraph(item[2], col2_style)
|
||||||
|
|
||||||
|
|
||||||
def get_published_value(misp_event, item, col2_style):
|
def get_published_value(misp_event, item, col2_style):
|
||||||
'''
|
'''
|
||||||
Returns a flowable paragraph to add to the pdf given the misp_event published/published_time
|
Returns a flowable paragraph to add to the pdf given the misp_event published/published_time
|
||||||
|
@ -510,23 +598,13 @@ def get_published_value(misp_event, item, col2_style):
|
||||||
|
|
||||||
return answer
|
return answer
|
||||||
|
|
||||||
|
def create_flowable_table_from_one_attribute(misp_attribute, config=None):
|
||||||
def is_safe_attribute(curr_object, attribute_name):
|
|
||||||
return hasattr(curr_object, attribute_name) and getattr(curr_object, attribute_name) is not None and getattr(
|
|
||||||
curr_object, attribute_name) != ""
|
|
||||||
|
|
||||||
|
|
||||||
def is_safe_attribute_table(curr_object, attribute_name):
|
|
||||||
return hasattr(curr_object, attribute_name) and getattr(curr_object, attribute_name) is not None and getattr(
|
|
||||||
curr_object, attribute_name) != []
|
|
||||||
|
|
||||||
|
|
||||||
def create_flowable_table_from_one_attribute(misp_attribute):
|
|
||||||
'''
|
'''
|
||||||
Returns a table (flowalbe) representing the attribute
|
Returns a table (flowalbe) representing the attribute
|
||||||
:param misp_attribute: A misp attribute
|
:param misp_attribute: A misp attribute
|
||||||
:return: a table representing this misp's attribute's attributes, to add to the pdf as a flowable
|
:return: a table representing this misp's attribute's attributes, to add to the pdf as a flowable
|
||||||
'''
|
'''
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
col1_style, col2_style = get_table_styles()
|
col1_style, col2_style = get_table_styles()
|
||||||
|
|
||||||
|
@ -570,16 +648,22 @@ def create_flowable_table_from_one_attribute(misp_attribute):
|
||||||
if is_safe_attribute_table(misp_attribute, item[1]):
|
if is_safe_attribute_table(misp_attribute, item[1]):
|
||||||
data.append([Paragraph(item[0], col1_style), get_tag_value(misp_attribute, item, col2_style)])
|
data.append([Paragraph(item[0], col1_style), get_tag_value(misp_attribute, item, col2_style)])
|
||||||
|
|
||||||
# Tags
|
# Sighting
|
||||||
item = ["Sighting", 'Sighting', "None"]
|
item = ["Sighting", 'Sighting', "None"]
|
||||||
if is_safe_attribute_table(misp_attribute, item[1]):
|
if is_safe_attribute_table(misp_attribute, item[1]):
|
||||||
data.append([Paragraph(item[0], col1_style),
|
data.append([Paragraph(item[0], col1_style),
|
||||||
create_flowable_paragraph_from_sightings(misp_attribute, item, col2_style)])
|
create_flowable_paragraph_from_sightings(misp_attribute, item, col2_style)])
|
||||||
|
|
||||||
|
if config is not None and moduleconfig[3] in config:
|
||||||
|
# Galaxies
|
||||||
|
item = ["Galaxies", 'Galaxy', "None"]
|
||||||
|
if is_safe_attribute_table(misp_attribute, item[1]):
|
||||||
|
data.append([Paragraph(item[0], col1_style), get_galaxy_value(misp_attribute, item, col2_style)])
|
||||||
|
|
||||||
return create_flowable_table_from_data(data)
|
return create_flowable_table_from_data(data)
|
||||||
|
|
||||||
|
|
||||||
def create_flowable_table_from_one_object(misp_object):
|
def create_flowable_table_from_one_object(misp_object, config=None):
|
||||||
'''
|
'''
|
||||||
Returns a table (flowable) representing the object
|
Returns a table (flowable) representing the object
|
||||||
:param misp_attribute: A misp object
|
:param misp_attribute: A misp object
|
||||||
|
@ -616,13 +700,145 @@ def create_flowable_table_from_one_object(misp_object):
|
||||||
|
|
||||||
# Handle all the attributes
|
# Handle all the attributes
|
||||||
if is_safe_attribute(misp_object, "Attribute"):
|
if is_safe_attribute(misp_object, "Attribute"):
|
||||||
data += create_flowable_table_from_attributes(misp_object)
|
data += create_flowable_table_from_attributes(misp_object, config)
|
||||||
|
|
||||||
# Add a page break at the end of an object
|
# Add a page break at the end of an object
|
||||||
data.append(PageBreak())
|
data.append(PageBreak())
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def create_flowable_table_from_one_galaxy(misp_galaxy):
|
||||||
|
'''
|
||||||
|
Returns a table (flowable) representing the galaxy
|
||||||
|
:param misp_attribute: A misp galaxy
|
||||||
|
:return: a table representing this misp's galaxy's attributes, to add to the pdf as a flowable
|
||||||
|
'''
|
||||||
|
data = []
|
||||||
|
col1_style, col2_style = get_table_styles()
|
||||||
|
|
||||||
|
# To reduce code size, and automate it a bit, triplet (Displayed Name, object_attribute_name,
|
||||||
|
# to_display_if_not_present) are store in the following list
|
||||||
|
list_attr_automated = [["Name", 'name', "None"],
|
||||||
|
["Type", 'type', "None"],
|
||||||
|
["Description", 'description', "None"],
|
||||||
|
["NameSpace", 'namespace', "None"]]
|
||||||
|
|
||||||
|
# Automated adding of standard (python) attributes of the misp object
|
||||||
|
for item in list_attr_automated:
|
||||||
|
if is_safe_dict_attribute(misp_galaxy, item[1]):
|
||||||
|
# The attribute exists, we fetch it and create the row
|
||||||
|
data.append([Paragraph(item[0], col1_style),
|
||||||
|
get_unoverflowable_paragraph(misp_galaxy[item[1]], col2_style)])
|
||||||
|
|
||||||
|
# Clusters
|
||||||
|
item = ["Clusters", 'GalaxyCluster', "None"]
|
||||||
|
data.append([Paragraph(item[0], col1_style), create_flowable_table_from_one_galaxy_cluster(misp_galaxy, item, col2_style)])
|
||||||
|
|
||||||
|
tmp_table = Table(data, ["25%","75%"])
|
||||||
|
# The attribute does not exist, you may want to print a default text on the row. Then use as a else case :
|
||||||
|
# data.append([Paragraph(item[0], col1_style), Paragraph(item[2], col2_style)])
|
||||||
|
return [tmp_table]
|
||||||
|
|
||||||
|
|
||||||
|
def create_flowable_table_from_one_galaxy_cluster(misp_galaxy):
|
||||||
|
'''
|
||||||
|
Returns a table (flowable) representing the galaxy
|
||||||
|
:param misp_attribute: A misp galaxy
|
||||||
|
:return: a table representing this misp's galaxy's attributes, to add to the pdf as a flowable
|
||||||
|
'''
|
||||||
|
data = []
|
||||||
|
col1_style, col2_style = get_table_styles()
|
||||||
|
|
||||||
|
# To reduce code size, and automate it a bit, triplet (Displayed Name, object_attribute_name,
|
||||||
|
# to_display_if_not_present) are store in the following list
|
||||||
|
list_attr_automated = [["Name", 'name', "None"],
|
||||||
|
["Type", 'type', "None"],
|
||||||
|
["Description", 'description', "None"],
|
||||||
|
["NameSpace", 'namespace', "None"]]
|
||||||
|
|
||||||
|
# Automated adding of standard (python) attributes of the misp object
|
||||||
|
for item in list_attr_automated:
|
||||||
|
if is_safe_dict_attribute(misp_galaxy, item[1]):
|
||||||
|
# The attribute exists, we fetch it and create the row
|
||||||
|
data.append([Paragraph(item[0], col1_style),
|
||||||
|
get_unoverflowable_paragraph(misp_galaxy[item[1]], col2_style)])
|
||||||
|
|
||||||
|
# Clusters
|
||||||
|
item = ["Object date", 'timestamp', "None"]
|
||||||
|
data.append([Paragraph(item[0], col1_style), get_timestamp_value(misp_object, item, col2_style)])
|
||||||
|
|
||||||
|
|
||||||
|
tmp_table = Table(data, ["25%","75%"])
|
||||||
|
# The attribute does not exist, you may want to print a default text on the row. Then use as a else case :
|
||||||
|
# data.append([Paragraph(item[0], col1_style), Paragraph(item[2], col2_style)])
|
||||||
|
return [tmp_table]
|
||||||
|
|
||||||
|
def get_image_value(misp_attribute, item, col2_style):
|
||||||
|
'''
|
||||||
|
Returns a flowable image to add to the pdf given the misp attribute type and data
|
||||||
|
:param misp_attribute: A misp attribute with type="attachement" and data
|
||||||
|
:param item: a list of name, in order :
|
||||||
|
["Name to be print in the pdf", "json property access name",
|
||||||
|
" Name to be display if no values found in the misp_event"]
|
||||||
|
:param col2_style: style to be applied on the returned paragraph
|
||||||
|
:return: a flowable image to add in the pdf, regarding the values of "data"
|
||||||
|
'''
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Get the image
|
||||||
|
buf = getattr(misp_attribute, item[1])
|
||||||
|
|
||||||
|
# Create image within a bounded box (to allow pdf creation)
|
||||||
|
img = Image(buf, width=FRAME_PICTURE_MAX_WIDTH, height=FRAME_PICTURE_MAX_HEIGHT, kind='bound')
|
||||||
|
answer = img
|
||||||
|
except OSError:
|
||||||
|
logger.error(
|
||||||
|
"Trying to add an attachment during PDF export generation. Attachement joining failed. Attachement may not be an image.")
|
||||||
|
answer = get_unoverflowable_paragraph(
|
||||||
|
"<font color=" + BAD_LINK_COLOR + ">" + NOT_A_PICTURE_MESSAGE + "</font>", col2_style, False)
|
||||||
|
|
||||||
|
return answer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# General Event's Attributes formater tools
|
||||||
|
|
||||||
|
def uuid_to_url(baseurl, uuid):
|
||||||
|
'''
|
||||||
|
Return an url constructed from the MISP baseurl and the uuid of the event, to go to this event on this MISP
|
||||||
|
:param baseurl: the baseurl of the MISP instnce e.g. http://localhost:8080 or http://localhost:8080/
|
||||||
|
:param uuid: the uuid of the event that we want to have a link to
|
||||||
|
:return: the complete URL to go to this event on this MISP instance
|
||||||
|
'''
|
||||||
|
if baseurl[len(baseurl) - 1] != "/":
|
||||||
|
baseurl += "/"
|
||||||
|
return baseurl + "events/view/" + uuid
|
||||||
|
|
||||||
|
|
||||||
|
def create_flowable_table_from_data(data, col_w = COL_WIDTHS):
|
||||||
|
'''
|
||||||
|
Given a list of flowables items (2D/list of list), creates a Table with styles.
|
||||||
|
:param data: list of list of items (flowables is better)
|
||||||
|
:return: a Table - with styles - to add to the pdf
|
||||||
|
'''
|
||||||
|
# Create the table
|
||||||
|
curr_table = Table(data, col_w)
|
||||||
|
|
||||||
|
# Aside notes :
|
||||||
|
# colWidths='*' does a 100% and share the space automatically
|
||||||
|
# rowHeights=ROW_HEIGHT if you want a fixed height. /!\ Problems with paragraphs that are spreading everywhere
|
||||||
|
|
||||||
|
# Create styles and set parameters
|
||||||
|
alternate_colors_style = alternate_colors_style_generator(data)
|
||||||
|
lines_style = lines_style_generator(data)
|
||||||
|
general_style = general_style_generator()
|
||||||
|
|
||||||
|
# Make the table nicer
|
||||||
|
curr_table.setStyle(TableStyle(general_style + alternate_colors_style + lines_style))
|
||||||
|
|
||||||
|
return curr_table
|
||||||
|
|
||||||
def create_tags_table_from_data(data):
|
def create_tags_table_from_data(data):
|
||||||
'''
|
'''
|
||||||
|
@ -695,122 +911,6 @@ def get_good_or_bad_link(misp_attribute, item, col2_style):
|
||||||
return answer
|
return answer
|
||||||
|
|
||||||
|
|
||||||
def get_image_value(misp_attribute, item, col2_style):
|
|
||||||
'''
|
|
||||||
Returns a flowable image to add to the pdf given the misp attribute type and data
|
|
||||||
:param misp_attribute: A misp attribute with type="attachement" and data
|
|
||||||
:param item: a list of name, in order :
|
|
||||||
["Name to be print in the pdf", "json property access name",
|
|
||||||
" Name to be display if no values found in the misp_event"]
|
|
||||||
:param col2_style: style to be applied on the returned paragraph
|
|
||||||
:return: a flowable image to add in the pdf, regarding the values of "data"
|
|
||||||
'''
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Get the image
|
|
||||||
buf = getattr(misp_attribute, item[1])
|
|
||||||
|
|
||||||
# Create image within a bounded box (to allow pdf creation)
|
|
||||||
img = Image(buf, width=FRAME_PICTURE_MAX_WIDTH, height=FRAME_PICTURE_MAX_HEIGHT, kind='bound')
|
|
||||||
answer = img
|
|
||||||
except OSError:
|
|
||||||
logger.error(
|
|
||||||
"Trying to add an attachment during PDF export generation. Attachement joining failed. Attachement may not be an image.")
|
|
||||||
answer = get_unoverflowable_paragraph(
|
|
||||||
"<font color=" + BAD_LINK_COLOR + ">" + NOT_A_PICTURE_MESSAGE + "</font>", col2_style, False)
|
|
||||||
|
|
||||||
return answer
|
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
|
||||||
# General attribut formater
|
|
||||||
|
|
||||||
def safe_string(bad_str):
|
|
||||||
return escape(str(bad_str))
|
|
||||||
|
|
||||||
|
|
||||||
def get_unoverflowable_paragraph(dirty_string, curr_style, do_escape_string=True):
|
|
||||||
'''
|
|
||||||
Create a paragraph that can fit on a cell of one page. Mostly hardcoded values.
|
|
||||||
This method can be improved (get the exact size of the current frame, and limit the paragraph to this size.)
|
|
||||||
This might be worst look at KeepInFrame (which hasn't went well so far)
|
|
||||||
:param do_escape_string: Activate the escaping (may be useful to add inline HTML, e.g. hyperlinks)
|
|
||||||
:param dirty_string: String to transform
|
|
||||||
:param curr_style: Style to apply to the returned paragraph
|
|
||||||
:return:
|
|
||||||
'''
|
|
||||||
if do_escape_string:
|
|
||||||
sanitized_str = str(escape(str(dirty_string)))
|
|
||||||
else:
|
|
||||||
sanitized_str = dirty_string
|
|
||||||
|
|
||||||
# Get the space that the paragraph needs to be printed
|
|
||||||
w, h = Paragraph(sanitized_str, curr_style).wrap(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT)
|
|
||||||
|
|
||||||
# If there is enough space, directly send back the sanitized paragraph
|
|
||||||
if w <= FRAME_MAX_WIDTH and h <= FRAME_MAX_HEIGHT:
|
|
||||||
answer_paragraph = Paragraph(sanitized_str, curr_style)
|
|
||||||
else:
|
|
||||||
# Otherwise, cut the content to fit the paragraph (Dichotomy)
|
|
||||||
max_carac_amount = int((FRAME_MAX_HEIGHT / (h * 1.0)) * len(sanitized_str))
|
|
||||||
|
|
||||||
i = 0
|
|
||||||
MAX_ITERATION = 10
|
|
||||||
limited_string = ""
|
|
||||||
while (w > FRAME_MAX_WIDTH or h > FRAME_MAX_HEIGHT) and i < MAX_ITERATION:
|
|
||||||
i += 1
|
|
||||||
limited_string = sanitized_str[:max_carac_amount] # .replace("\n", "").replace("\r", "")
|
|
||||||
w, h = Paragraph(limited_string + STR_TOO_LONG_WARNING, curr_style).wrap(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT)
|
|
||||||
max_carac_amount = int(max_carac_amount / 2)
|
|
||||||
|
|
||||||
if w <= FRAME_MAX_WIDTH and h <= FRAME_MAX_HEIGHT:
|
|
||||||
answer_paragraph = Paragraph(limited_string + STR_TOO_LONG_WARNING, curr_style)
|
|
||||||
else:
|
|
||||||
# We may still end with a not short enough string
|
|
||||||
answer_paragraph = Paragraph(STR_TOO_LONG_WARNING, curr_style)
|
|
||||||
|
|
||||||
return answer_paragraph
|
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
|
||||||
# General Event's Attributes formater tools
|
|
||||||
|
|
||||||
def uuid_to_url(baseurl, uuid):
|
|
||||||
'''
|
|
||||||
Return an url constructed from the MISP baseurl and the uuid of the event, to go to this event on this MISP
|
|
||||||
:param baseurl: the baseurl of the MISP instnce e.g. http://localhost:8080 or http://localhost:8080/
|
|
||||||
:param uuid: the uuid of the event that we want to have a link to
|
|
||||||
:return: the complete URL to go to this event on this MISP instance
|
|
||||||
'''
|
|
||||||
if baseurl[len(baseurl) - 1] != "/":
|
|
||||||
baseurl += "/"
|
|
||||||
return baseurl + "events/view/" + uuid
|
|
||||||
|
|
||||||
|
|
||||||
def create_flowable_table_from_data(data):
|
|
||||||
'''
|
|
||||||
Given a list of flowables items (2D/list of list), creates a Table with styles.
|
|
||||||
:param data: list of list of items (flowables is better)
|
|
||||||
:return: a Table - with styles - to add to the pdf
|
|
||||||
'''
|
|
||||||
# Create the table
|
|
||||||
curr_table = Table(data, COL_WIDTHS)
|
|
||||||
|
|
||||||
# Aside notes :
|
|
||||||
# colWidths='*' does a 100% and share the space automatically
|
|
||||||
# rowHeights=ROW_HEIGHT if you want a fixed height. /!\ Problems with paragraphs that are spreading everywhere
|
|
||||||
|
|
||||||
# Create styles and set parameters
|
|
||||||
alternate_colors_style = alternate_colors_style_generator(data)
|
|
||||||
lines_style = lines_style_generator(data)
|
|
||||||
general_style = general_style_generator()
|
|
||||||
|
|
||||||
# Make the table nicer
|
|
||||||
curr_table.setStyle(TableStyle(general_style + alternate_colors_style + lines_style))
|
|
||||||
|
|
||||||
return curr_table
|
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# General Event's Attributes formater
|
# General Event's Attributes formater
|
||||||
|
|
||||||
|
@ -977,14 +1077,13 @@ def create_flowable_description_from_event(misp_event, config=None):
|
||||||
return Paragraph(text, description_style)
|
return Paragraph(text, description_style)
|
||||||
|
|
||||||
|
|
||||||
def create_flowable_table_from_attributes(misp_event):
|
def create_flowable_table_from_attributes(misp_event, config=None):
|
||||||
'''
|
'''
|
||||||
Returns a list of flowables representing the list of attributes of a misp event.
|
Returns a list of flowables representing the list of attributes of a misp event.
|
||||||
The list is composed alternatively of headers and tables, to add to the pdf
|
The list is composed alternatively of headers and tables, to add to the pdf
|
||||||
:param misp_event: A misp event
|
:param misp_event: A misp event
|
||||||
:return: a table of flowables
|
:return: a table of flowables
|
||||||
'''
|
'''
|
||||||
|
|
||||||
flowable_table = []
|
flowable_table = []
|
||||||
sample_style_sheet = getSampleStyleSheet()
|
sample_style_sheet = getSampleStyleSheet()
|
||||||
i = 0
|
i = 0
|
||||||
|
@ -994,7 +1093,7 @@ def create_flowable_table_from_attributes(misp_event):
|
||||||
for item in getattr(misp_event, "Attribute"):
|
for item in getattr(misp_event, "Attribute"):
|
||||||
# you can use a spacer instead of title to separate paragraph: flowable_table.append(Spacer(1, 5 * mm))
|
# you can use a spacer instead of title to separate paragraph: flowable_table.append(Spacer(1, 5 * mm))
|
||||||
flowable_table.append(Paragraph("Attribute #" + str(i), sample_style_sheet['Heading4']))
|
flowable_table.append(Paragraph("Attribute #" + str(i), sample_style_sheet['Heading4']))
|
||||||
flowable_table.append(create_flowable_table_from_one_attribute(item))
|
flowable_table.append(create_flowable_table_from_one_attribute(item, config))
|
||||||
i += 1
|
i += 1
|
||||||
else:
|
else:
|
||||||
# No attributes for this object
|
# No attributes for this object
|
||||||
|
@ -1027,8 +1126,7 @@ def create_flowable_table_from_tags(misp_event):
|
||||||
|
|
||||||
return answer_tags
|
return answer_tags
|
||||||
|
|
||||||
|
def create_flowable_table_from_objects(misp_event, config=None):
|
||||||
def create_flowable_table_from_objects(misp_event):
|
|
||||||
'''
|
'''
|
||||||
Returns a list of flowables representing the list of objects of a misp event.
|
Returns a list of flowables representing the list of objects of a misp event.
|
||||||
The list is composed of a serie of
|
The list is composed of a serie of
|
||||||
|
@ -1047,7 +1145,7 @@ def create_flowable_table_from_objects(misp_event):
|
||||||
for item in getattr(misp_event, "Object"):
|
for item in getattr(misp_event, "Object"):
|
||||||
# you can use a spacer instead of title to separate paragraph: flowable_table.append(Spacer(1, 5 * mm))
|
# you can use a spacer instead of title to separate paragraph: flowable_table.append(Spacer(1, 5 * mm))
|
||||||
flowable_table.append(Paragraph("Object #" + str(i), sample_style_sheet['Heading3']))
|
flowable_table.append(Paragraph("Object #" + str(i), sample_style_sheet['Heading3']))
|
||||||
flowable_table += create_flowable_table_from_one_object(item)
|
flowable_table += create_flowable_table_from_one_object(item, config)
|
||||||
i += 1
|
i += 1
|
||||||
else:
|
else:
|
||||||
# No object found
|
# No object found
|
||||||
|
@ -1072,11 +1170,11 @@ def create_flowable_paragraph_from_sightings(misp_attribute, item, col2_style):
|
||||||
list_sighting = [0, 0, 0]
|
list_sighting = [0, 0, 0]
|
||||||
if is_safe_attribute_table(misp_attribute, "Sighting"):
|
if is_safe_attribute_table(misp_attribute, "Sighting"):
|
||||||
# There is some tags for this object
|
# There is some tags for this object
|
||||||
for item in getattr(misp_attribute, "Sighting"):
|
for curr_item in getattr(misp_attribute, "Sighting"):
|
||||||
# TODO : When Sightings will be object : if is_safe_attribute(item, "type"):
|
# TODO : When Sightings will be object : if is_safe_attribute(item, "type"):
|
||||||
if "type" in item:
|
if "type" in curr_item:
|
||||||
# Store the likes/dislikes depending on their types
|
# Store the likes/dislikes depending on their types
|
||||||
list_sighting[int(item["type"])] += 1
|
list_sighting[int(curr_item["type"])] += 1
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
# Create the sighting text
|
# Create the sighting text
|
||||||
|
@ -1093,6 +1191,30 @@ def create_flowable_paragraph_from_sightings(misp_attribute, item, col2_style):
|
||||||
return answer_sighting
|
return answer_sighting
|
||||||
|
|
||||||
|
|
||||||
|
def create_flowable_table_from_galaxies(misp_event):
|
||||||
|
'''
|
||||||
|
Returns a Table (flowable) to add to a pdf, representing the list of galaxies of an event or a misp event
|
||||||
|
:param misp_event: A misp event
|
||||||
|
:return: a table of flowables to add to the pdf
|
||||||
|
'''
|
||||||
|
|
||||||
|
flowable_table = []
|
||||||
|
col1_style, col2_style = get_table_styles()
|
||||||
|
i = 0
|
||||||
|
|
||||||
|
if is_safe_attribute_table(misp_event, "Galaxy"):
|
||||||
|
# There is some galaxies for this object
|
||||||
|
for item in getattr(misp_event, "Galaxy"):
|
||||||
|
# flowable_table.append([get_unoverflowable_paragraph(item["name"],col2_style)])
|
||||||
|
flowable_table.append(create_flowable_table_from_one_galaxy(item))
|
||||||
|
i += 1
|
||||||
|
answer_tags = create_flowable_table_from_data(flowable_table, ["99%"])
|
||||||
|
else:
|
||||||
|
# No galaxies for this object
|
||||||
|
answer_tags = [Paragraph("No galaxies", col2_style)]
|
||||||
|
|
||||||
|
return answer_tags
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Handling static parts drawn on the upper layer
|
# Handling static parts drawn on the upper layer
|
||||||
|
|
||||||
|
@ -1102,7 +1224,6 @@ def set_template(canvas, doc, misp_event, config=None):
|
||||||
# TODO : add_header()
|
# TODO : add_header()
|
||||||
# TODO : add_footer()
|
# TODO : add_footer()
|
||||||
|
|
||||||
|
|
||||||
def add_metadata(canvas, doc, misp_event, config=None):
|
def add_metadata(canvas, doc, misp_event, config=None):
|
||||||
'''
|
'''
|
||||||
Allow to add metadata to the pdf. Would need deeper digging to change other metadata.
|
Allow to add metadata to the pdf. Would need deeper digging to change other metadata.
|
||||||
|
@ -1187,14 +1308,14 @@ def collect_parts(misp_event, config=None):
|
||||||
flowables.append(PageBreak())
|
flowables.append(PageBreak())
|
||||||
|
|
||||||
event_attributes_title = Paragraph("Attributes", sample_style_sheet['Heading2'])
|
event_attributes_title = Paragraph("Attributes", sample_style_sheet['Heading2'])
|
||||||
table_direct_attributes = create_flowable_table_from_attributes(misp_event)
|
table_direct_attributes = create_flowable_table_from_attributes(misp_event, config)
|
||||||
flowables.append(event_attributes_title)
|
flowables.append(event_attributes_title)
|
||||||
flowables += table_direct_attributes
|
flowables += table_direct_attributes
|
||||||
|
|
||||||
flowables.append(PageBreak())
|
flowables.append(PageBreak())
|
||||||
|
|
||||||
event_objects_title = Paragraph("Objects", sample_style_sheet['Heading2'])
|
event_objects_title = Paragraph("Objects", sample_style_sheet['Heading2'])
|
||||||
table_objects = create_flowable_table_from_objects(misp_event)
|
table_objects = create_flowable_table_from_objects(misp_event, config)
|
||||||
flowables.append(event_objects_title)
|
flowables.append(event_objects_title)
|
||||||
flowables += table_objects
|
flowables += table_objects
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,33 +1,34 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
from pymisp import MISPEvent
|
|
||||||
|
|
||||||
|
from pymisp import MISPEvent
|
||||||
from pymisp.tools import reportlab_generator
|
from pymisp.tools import reportlab_generator
|
||||||
|
|
||||||
import sys
|
manual_testing = True
|
||||||
import os
|
|
||||||
import time
|
|
||||||
|
|
||||||
manual_testing = False
|
|
||||||
|
|
||||||
class TestMISPEvent(unittest.TestCase):
|
class TestMISPEvent(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.maxDiff = None
|
self.maxDiff = None
|
||||||
self.mispevent = MISPEvent()
|
self.mispevent = MISPEvent()
|
||||||
if not manual_testing :
|
if not manual_testing:
|
||||||
self.root = "tests/"
|
self.root = "tests/"
|
||||||
else :
|
else:
|
||||||
self.root = ""
|
self.root = ""
|
||||||
self.test_folder = self.root + "reportlab_testfiles/"
|
self.test_folder = self.root + "reportlab_testfiles/"
|
||||||
self.test_batch_folder = self.root + "OSINT_output/"
|
self.test_batch_folder = self.root + "OSINT_output/"
|
||||||
|
self.storage_folder_OSINT = self.root + "OSINT_PDF/"
|
||||||
self.test_image_folder = self.root + "image_json/"
|
self.test_image_folder = self.root + "image_json/"
|
||||||
self.storage_folder = self.root + "reportlab_testoutputs/"
|
self.storage_folder = self.root + "reportlab_testoutputs/"
|
||||||
self.storage_image_folder = self.root + "reportlab_test_image_outputs/"
|
self.storage_image_folder = self.root + "reportlab_test_image_outputs/"
|
||||||
self.moduleconfig = ["MISP_base_url_for_dynamic_link", "MISP_name_for_metadata", "Activate_textual_description"]
|
self.moduleconfig = ["MISP_base_url_for_dynamic_link", "MISP_name_for_metadata", "Activate_textual_description",
|
||||||
|
"Activate_galaxy_description"]
|
||||||
|
|
||||||
def init_event(self):
|
def init_event(self):
|
||||||
self.mispevent.info = 'This is a test'
|
self.mispevent.info = 'This is a test'
|
||||||
|
@ -94,12 +95,13 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
|
|
||||||
config = {}
|
config = {}
|
||||||
config[self.moduleconfig[0]] = "http://localhost:8080"
|
config[self.moduleconfig[0]] = "http://localhost:8080"
|
||||||
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
||||||
|
|
||||||
self.init_event()
|
self.init_event()
|
||||||
self.mispevent.load_file(self.test_folder + 'very_long_event.json')
|
self.mispevent.load_file(self.test_folder + 'very_long_event.json')
|
||||||
reportlab_generator.register_value_to_file(reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
reportlab_generator.register_value_to_file(
|
||||||
self.storage_folder + "config_complete_event.pdf")
|
reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
||||||
|
self.storage_folder + "config_complete_event.pdf")
|
||||||
|
|
||||||
def test_partial_0_config_json(self):
|
def test_partial_0_config_json(self):
|
||||||
if self.check_python_2():
|
if self.check_python_2():
|
||||||
|
@ -111,8 +113,9 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
|
|
||||||
self.init_event()
|
self.init_event()
|
||||||
self.mispevent.load_file(self.test_folder + 'very_long_event.json')
|
self.mispevent.load_file(self.test_folder + 'very_long_event.json')
|
||||||
reportlab_generator.register_value_to_file(reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
reportlab_generator.register_value_to_file(
|
||||||
self.storage_folder + "config_partial_0_event.pdf")
|
reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
||||||
|
self.storage_folder + "config_partial_0_event.pdf")
|
||||||
|
|
||||||
def test_partial_1_config_json(self):
|
def test_partial_1_config_json(self):
|
||||||
if self.check_python_2():
|
if self.check_python_2():
|
||||||
|
@ -120,12 +123,13 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
|
|
||||||
config = {}
|
config = {}
|
||||||
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
||||||
|
|
||||||
self.init_event()
|
self.init_event()
|
||||||
self.mispevent.load_file(self.test_folder + 'very_long_event.json')
|
self.mispevent.load_file(self.test_folder + 'very_long_event.json')
|
||||||
reportlab_generator.register_value_to_file(reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
reportlab_generator.register_value_to_file(
|
||||||
self.storage_folder + "config_partial_1_event.pdf")
|
reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
||||||
|
self.storage_folder + "config_partial_1_event.pdf")
|
||||||
|
|
||||||
def test_image_json(self):
|
def test_image_json(self):
|
||||||
if self.check_python_2():
|
if self.check_python_2():
|
||||||
|
@ -134,12 +138,13 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
|
|
||||||
config = {}
|
config = {}
|
||||||
config[self.moduleconfig[0]] = "http://localhost:8080"
|
config[self.moduleconfig[0]] = "http://localhost:8080"
|
||||||
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
||||||
|
|
||||||
self.init_event()
|
self.init_event()
|
||||||
self.mispevent.load_file(self.test_folder + 'image_event.json')
|
self.mispevent.load_file(self.test_folder + 'image_event.json')
|
||||||
reportlab_generator.register_value_to_file(reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
reportlab_generator.register_value_to_file(
|
||||||
self.storage_folder + "image_event.pdf")
|
reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
||||||
|
self.storage_folder + "image_event.pdf")
|
||||||
|
|
||||||
def test_objects_1_json(self):
|
def test_objects_1_json(self):
|
||||||
if self.check_python_2():
|
if self.check_python_2():
|
||||||
|
@ -148,12 +153,13 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
|
|
||||||
config = {}
|
config = {}
|
||||||
config[self.moduleconfig[0]] = "http://localhost:8080"
|
config[self.moduleconfig[0]] = "http://localhost:8080"
|
||||||
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
||||||
|
|
||||||
self.init_event()
|
self.init_event()
|
||||||
self.mispevent.load_file(self.test_folder + 'mainly_objects_1.json')
|
self.mispevent.load_file(self.test_folder + 'mainly_objects_1.json')
|
||||||
reportlab_generator.register_value_to_file(reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
reportlab_generator.register_value_to_file(
|
||||||
self.storage_folder + "mainly_objects_1.pdf")
|
reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
||||||
|
self.storage_folder + "mainly_objects_1.pdf")
|
||||||
|
|
||||||
def test_objects_2_json(self):
|
def test_objects_2_json(self):
|
||||||
if self.check_python_2():
|
if self.check_python_2():
|
||||||
|
@ -162,12 +168,13 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
|
|
||||||
config = {}
|
config = {}
|
||||||
config[self.moduleconfig[0]] = "http://localhost:8080"
|
config[self.moduleconfig[0]] = "http://localhost:8080"
|
||||||
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
||||||
|
|
||||||
self.init_event()
|
self.init_event()
|
||||||
self.mispevent.load_file(self.test_folder + 'mainly_objects_2.json')
|
self.mispevent.load_file(self.test_folder + 'mainly_objects_2.json')
|
||||||
reportlab_generator.register_value_to_file(reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
reportlab_generator.register_value_to_file(
|
||||||
self.storage_folder + "mainly_objects_2.pdf")
|
reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
||||||
|
self.storage_folder + "mainly_objects_2.pdf")
|
||||||
|
|
||||||
def test_sightings_1_json(self):
|
def test_sightings_1_json(self):
|
||||||
if self.check_python_2():
|
if self.check_python_2():
|
||||||
|
@ -176,12 +183,13 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
|
|
||||||
config = {}
|
config = {}
|
||||||
config[self.moduleconfig[0]] = "http://localhost:8080"
|
config[self.moduleconfig[0]] = "http://localhost:8080"
|
||||||
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
||||||
|
|
||||||
self.init_event()
|
self.init_event()
|
||||||
self.mispevent.load_file(self.test_folder + 'sighting_1.json')
|
self.mispevent.load_file(self.test_folder + 'sighting_1.json')
|
||||||
reportlab_generator.register_value_to_file(reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
reportlab_generator.register_value_to_file(
|
||||||
self.storage_folder + "sighting_1.pdf")
|
reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
||||||
|
self.storage_folder + "sighting_1.pdf")
|
||||||
|
|
||||||
def test_sightings_2_json(self):
|
def test_sightings_2_json(self):
|
||||||
if self.check_python_2():
|
if self.check_python_2():
|
||||||
|
@ -190,12 +198,13 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
|
|
||||||
config = {}
|
config = {}
|
||||||
config[self.moduleconfig[0]] = "http://localhost:8080"
|
config[self.moduleconfig[0]] = "http://localhost:8080"
|
||||||
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
||||||
|
|
||||||
self.init_event()
|
self.init_event()
|
||||||
self.mispevent.load_file(self.test_folder + 'sighting_2.json')
|
self.mispevent.load_file(self.test_folder + 'sighting_2.json')
|
||||||
reportlab_generator.register_value_to_file(reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
reportlab_generator.register_value_to_file(
|
||||||
self.storage_folder + "sighting_2.pdf")
|
reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
||||||
|
self.storage_folder + "sighting_2.pdf")
|
||||||
|
|
||||||
def test_textual_json(self):
|
def test_textual_json(self):
|
||||||
if self.check_python_2():
|
if self.check_python_2():
|
||||||
|
@ -204,21 +213,38 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
|
|
||||||
config = {}
|
config = {}
|
||||||
config[self.moduleconfig[0]] = "http://localhost:8080"
|
config[self.moduleconfig[0]] = "http://localhost:8080"
|
||||||
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
||||||
config[self.moduleconfig[2]] = True
|
config[self.moduleconfig[2]] = True
|
||||||
|
|
||||||
self.init_event()
|
self.init_event()
|
||||||
self.mispevent.load_file(self.test_folder + 'very_long_event.json')
|
self.mispevent.load_file(self.test_folder + 'very_long_event.json')
|
||||||
reportlab_generator.register_value_to_file(reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
reportlab_generator.register_value_to_file(
|
||||||
self.storage_folder + "textual.pdf")
|
reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
||||||
|
self.storage_folder + "textual.pdf")
|
||||||
|
|
||||||
|
def test_galaxy_1(self):
|
||||||
|
if self.check_python_2():
|
||||||
|
self.assertTrue(True)
|
||||||
|
else:
|
||||||
|
|
||||||
|
config = {}
|
||||||
|
config[self.moduleconfig[0]] = "http://localhost:8080"
|
||||||
|
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
||||||
|
config[self.moduleconfig[2]] = True
|
||||||
|
config[self.moduleconfig[3]] = True
|
||||||
|
|
||||||
|
self.init_event()
|
||||||
|
self.mispevent.load_file(self.test_folder + 'galaxy_1.json')
|
||||||
|
reportlab_generator.register_value_to_file(
|
||||||
|
reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
||||||
|
self.storage_folder + "galaxy_1.pdf")
|
||||||
|
|
||||||
def test_batch_image_events(self):
|
def test_batch_image_events(self):
|
||||||
# Test case ONLY for manual testing. Needs to download a full list of image events !
|
# Test case ONLY for manual testing. Needs to download a full list of image events !
|
||||||
|
|
||||||
if self.check_python_2():
|
if self.check_python_2():
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
elif not manual_testing :
|
elif not manual_testing:
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
else:
|
else:
|
||||||
self.init_event()
|
self.init_event()
|
||||||
|
@ -246,7 +272,7 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
|
|
||||||
if self.check_python_2():
|
if self.check_python_2():
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
elif not manual_testing :
|
elif not manual_testing:
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
else:
|
else:
|
||||||
self.init_event()
|
self.init_event()
|
||||||
|
@ -265,7 +291,7 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
|
|
||||||
reportlab_generator.register_value_to_file(
|
reportlab_generator.register_value_to_file(
|
||||||
reportlab_generator.convert_event_in_pdf_buffer(self.mispevent),
|
reportlab_generator.convert_event_in_pdf_buffer(self.mispevent),
|
||||||
self.storage_folder + curr_file + ".pdf")
|
self.storage_folder_OSINT + curr_file + ".pdf")
|
||||||
print("Elapsed time : " + str(time.time() - t))
|
print("Elapsed time : " + str(time.time() - t))
|
||||||
# Local run : 1958.930s for 1064 files
|
# Local run : 1958.930s for 1064 files
|
||||||
|
|
||||||
|
@ -274,15 +300,15 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
|
|
||||||
if self.check_python_2():
|
if self.check_python_2():
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
elif not manual_testing :
|
elif not manual_testing:
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
else:
|
else:
|
||||||
self.init_event()
|
self.init_event()
|
||||||
|
|
||||||
config = {}
|
config = {}
|
||||||
config[self.moduleconfig[0]] = "http://localhost:8080"
|
config[self.moduleconfig[0]] = "http://localhost:8080"
|
||||||
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
config[self.moduleconfig[1]] = "My Wonderful CERT"
|
||||||
config[self.moduleconfig[2]] = True
|
config[self.moduleconfig[2]] = True
|
||||||
|
|
||||||
file_nb = str(len(os.listdir(self.test_batch_folder)))
|
file_nb = str(len(os.listdir(self.test_batch_folder)))
|
||||||
i = 0
|
i = 0
|
||||||
|
@ -298,6 +324,6 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
|
|
||||||
reportlab_generator.register_value_to_file(
|
reportlab_generator.register_value_to_file(
|
||||||
reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
reportlab_generator.convert_event_in_pdf_buffer(self.mispevent, config),
|
||||||
self.storage_folder + curr_file + ".pdf")
|
self.storage_folder_OSINT + curr_file + ".pdf")
|
||||||
print("Elapsed time : " + str(time.time() - t))
|
print("Elapsed time : " + str(time.time() - t))
|
||||||
# Local run : 1958.930s for 1064 files
|
# Local run : 1513.283s for 1064 files
|
||||||
|
|
Loading…
Reference in New Issue