diff --git a/bin/lib/correlations_engine.py b/bin/lib/correlations_engine.py
index e1fbeb4e..27307ad4 100755
--- a/bin/lib/correlations_engine.py
+++ b/bin/lib/correlations_engine.py
@@ -118,6 +118,33 @@ def delete_obj_correlation(obj1_type, subtype1, obj1_id, obj2_type, subtype2, ob
r_metadata.srem(f'correlation:obj:{obj1_type}:{subtype1}:{obj2_type}:{obj1_id}', f'{subtype2}:{obj2_id}')
r_metadata.srem(f'correlation:obj:{obj2_type}:{subtype2}:{obj1_type}:{obj2_id}', f'{subtype1}:{obj1_id}')
+# # bypass max result/objects ???
+# def get_correlation_depht(obj_type, subtype, obj_id, filter_types=[], level=1, nb_max=300):
+# objs = set()
+# _get_correlation_depht(objs, obj_type, subtype, obj_id, filter_types, level, nb_max)
+# return objs
+#
+# def _get_correlation_depht(objs, obj_type, subtype, obj_id, filter_types, level, nb_max, previous_str_obj=''):
+# obj_str_id = get_obj_str_id(obj_type, subtype, obj_id)
+# objs.add(obj_str_id)
+#
+# obj_correlations = get_correlations(obj_type, subtype, obj_id, filter_types=filter_types)
+# for correl_type in obj_correlations:
+# for str_obj in obj_correlations[correl_type]:
+# subtype2, obj2_id = str_obj.split(':', 1)
+# obj2_str_id = get_obj_str_id(correl_type, subtype2, obj2_id)
+#
+# if obj2_str_id == previous_str_obj:
+# continue
+#
+# if len(nodes) > nb_max:
+# break
+# objs.add(obj2_str_id)
+#
+# if level > 0:
+# next_level = level - 1
+# _get_correlation_depht(objs, correl_type, subtype2, obj2_id, filter_types, next_level, nb_max,
+# previous_str_obj=obj_str_id)
def get_obj_str_id(obj_type, subtype, obj_id):
if subtype is None:
diff --git a/bin/lib/objects/abstract_object.py b/bin/lib/objects/abstract_object.py
index 7408ba67..0a52618f 100755
--- a/bin/lib/objects/abstract_object.py
+++ b/bin/lib/objects/abstract_object.py
@@ -213,11 +213,11 @@ class AbstractObject(ABC):
"""
return get_correlations(self.type, self.subtype, self.id, filter_types=[obj_type])
- def get_correlations(self):
+ def get_correlations(self, filter_types=[]):
"""
Get object correlations
"""
- return get_correlations(self.type, self.subtype, self.id)
+ return get_correlations(self.type, self.subtype, self.id, filter_types=filter_types)
def get_nb_correlation(self, correl_type):
return get_nb_correlation_by_correl_type(self.type, self.get_subtype(r_str=True), self.id, correl_type)
diff --git a/bin/lib/objects/ail_objects.py b/bin/lib/objects/ail_objects.py
index 4525d033..9cf87eaf 100755
--- a/bin/lib/objects/ail_objects.py
+++ b/bin/lib/objects/ail_objects.py
@@ -273,27 +273,31 @@ def get_obj_correlations(obj_type, subtype, obj_id):
obj = get_object(obj_type, subtype, obj_id)
return obj.get_correlations()
-def _get_obj_correlations_objs(objs, obj_type, subtype, obj_id, lvl=0):
- if lvl > 0 and (obj_type, subtype, obj_id) not in objs: # Avoid looking for the same correlation
- objs.add((obj_type, subtype, obj_id))
- lvl = lvl - 1
- obj = get_object(obj_type, subtype, obj_id)
- correlations = obj.get_correlations()
- # print('--------------------------')
- # print( obj_id, correlations)
- # print(lvl)
- # print('--------------------------')
- for obj2_type in correlations:
- for str_obj in correlations[obj2_type]:
- obj2_subtype, obj2_id = str_obj.split(':', 1)
- _get_obj_correlations_objs(objs, obj2_type, obj2_subtype, obj2_id, lvl=lvl)
- # print(len(objs))
- objs.add((obj_type, subtype, obj_id))
+def _get_obj_correlations_objs(objs, obj_type, subtype, obj_id, filter_types, lvl, nb_max):
+ if len(objs) < nb_max or nb_max == -1:
+ if lvl == 0:
+ objs.add((obj_type, subtype, obj_id))
+
+ elif lvl > 0 and (obj_type, subtype, obj_id) not in objs: # Avoid looking for the same correlation
+ objs.add((obj_type, subtype, obj_id))
+ obj = get_object(obj_type, subtype, obj_id)
+ correlations = obj.get_correlations(filter_types=filter_types)
+ lvl = lvl - 1
+ for obj2_type in correlations:
+ for str_obj in correlations[obj2_type]:
+ obj2_subtype, obj2_id = str_obj.split(':', 1)
+ _get_obj_correlations_objs(objs, obj2_type, obj2_subtype, obj2_id, filter_types, lvl, nb_max)
+
+def get_obj_correlations_objs(obj_type, subtype, obj_id, filter_types=[], lvl=0, nb_max=300):
+ objs = set()
+ _get_obj_correlations_objs(objs, obj_type, subtype, obj_id, filter_types, lvl, nb_max)
return objs
-def get_obj_correlations_objs(obj_type, subtype, obj_id, lvl=0):
- objs = set()
- _get_obj_correlations_objs(objs, obj_type, subtype, obj_id, lvl=lvl)
+def obj_correlations_objs_add_tags(obj_type, subtype, obj_id, tags, filter_types=[], lvl=0, nb_max=300):
+ objs = get_obj_correlations_objs(obj_type, subtype, obj_id, filter_types=filter_types, lvl=lvl, nb_max=nb_max)
+ for obj_tuple in objs:
+ obj1_type, subtype1, id1 = obj_tuple
+ add_obj_tags(obj1_type, subtype1, id1, tags)
return objs
################################################################################
diff --git a/var/www/blueprints/correlation.py b/var/www/blueprints/correlation.py
index ba9c1ba7..7e8a11a6 100644
--- a/var/www/blueprints/correlation.py
+++ b/var/www/blueprints/correlation.py
@@ -24,22 +24,17 @@ sys.path.append(os.environ['AIL_BIN'])
# Import Project packages
##################################
from lib.objects import ail_objects
+from lib import Tag
bootstrap_label = Flask_config.bootstrap_label
vt_enabled = Flask_config.vt_enabled
# ============ BLUEPRINT ============
-correlation = Blueprint('correlation', __name__, template_folder=os.path.join(os.environ['AIL_FLASK'], 'templates/correlation'))
+correlation = Blueprint('correlation', __name__,
+ template_folder=os.path.join(os.environ['AIL_FLASK'], 'templates/correlation'))
# ============ VARIABLES ============
-######
-### graph_line_json
-### 'hashDecoded.pgpdump_graph_line_json'
-### 'hashDecoded.cryptocurrency_graph_line_json'
-###
-######
-
# ============ FUNCTIONS ============
def sanitise_graph_mode(graph_mode):
@@ -53,12 +48,12 @@ def sanitise_nb_max_nodes(nb_max_nodes):
nb_max_nodes = int(nb_max_nodes)
if nb_max_nodes < 2:
nb_max_nodes = 300
- except:
+ except (TypeError, ValueError):
nb_max_nodes = 300
return nb_max_nodes
# ============= ROUTES ==============
-@correlation.route('/correlation/show', methods=['GET', 'POST']) # GET + POST
+@correlation.route('/correlation/show', methods=['GET', 'POST'])
@login_required
@login_read_only
def show_correlation():
@@ -106,7 +101,7 @@ def show_correlation():
# redirect to keep history and bookmark
return redirect(url_for('correlation.show_correlation', type=object_type, subtype=subtype, id=obj_id, mode=mode,
- max_nodes=max_nodes, filter=filter_types))
+ max_nodes=max_nodes, filter=filter_types))
# request.method == 'GET'
else:
@@ -120,13 +115,9 @@ def show_correlation():
filter_types = ail_objects.sanitize_objs_types(request.args.get('filter', '').split(','))
- # # TODO: remove me, rename screenshot to image
- if obj_type == 'image':
- obj_type = 'screenshot'
-
# check if obj_id exist
if not ail_objects.exists_obj(obj_type, subtype, obj_id):
- abort(404) # return 404
+ return abort(404)
# object exist
else:
dict_object = {"object_type": obj_type,
@@ -138,7 +129,8 @@ def show_correlation():
if subtype:
dict_object["metadata"]['type_id'] = subtype
dict_object["metadata_card"] = ail_objects.get_object_card_meta(obj_type, subtype, obj_id, related_btc=related_btc)
- return render_template("show_correlation.html", dict_object=dict_object, bootstrap_label=bootstrap_label)
+ return render_template("show_correlation.html", dict_object=dict_object, bootstrap_label=bootstrap_label,
+ tags_selector_data=Tag.get_tags_selector_data())
@correlation.route('/correlation/get/description')
@login_required
@@ -158,7 +150,6 @@ def get_description():
else:
return jsonify({})
-
# check if correlation_id exist
# # TODO: return error json
if not ail_objects.exists_obj(object_type, type_id, correlation_id):
@@ -179,11 +170,48 @@ def graph_node_json():
filter_types = ail_objects.sanitize_objs_types(request.args.get('filter', '').split(','))
- # # TODO: remove me, rename screenshot
- if obj_type == 'image':
- obj_type = 'screenshot'
-
json_graph = ail_objects.get_correlations_graph_node(obj_type, subtype, obj_id, filter_types=filter_types, max_nodes=max_nodes, level=2, flask_context=True)
#json_graph = Correlate_object.get_graph_node_object_correlation(obj_type, obj_id, 'union', correlation_names, correlation_objects, requested_correl_type=subtype, max_nodes=max_nodes)
return jsonify(json_graph)
+@correlation.route('/correlation/tags/add', methods=['POST'])
+@login_required
+@login_read_only
+def correlation_tags_add():
+ obj_id = request.form.get('tag_obj_id')
+ subtype = request.form.get('tag_subtype', '')
+ obj_type = request.form.get('tag_obj_type')
+ nb_max = sanitise_nb_max_nodes(request.form.get('tag_nb_max'))
+ filter_types = ail_objects.sanitize_objs_types(request.form.get('tag_filter', '').split(','))
+
+ if not ail_objects.exists_obj(obj_type, subtype, obj_id):
+ return abort(404)
+
+ # tags
+ taxonomies_tags = request.form.get('taxonomies_tags')
+ if taxonomies_tags:
+ try:
+ taxonomies_tags = json.loads(taxonomies_tags)
+ except Exception:
+ taxonomies_tags = []
+ else:
+ taxonomies_tags = []
+ galaxies_tags = request.form.get('galaxies_tags')
+ if galaxies_tags:
+ try:
+ galaxies_tags = json.loads(galaxies_tags)
+ except Exception:
+ galaxies_tags = []
+ if taxonomies_tags or galaxies_tags:
+ if not Tag.is_valid_tags_taxonomies_galaxy(taxonomies_tags, galaxies_tags):
+ return {'error': 'Invalid tag(s)'}, 400
+ tags = taxonomies_tags + galaxies_tags
+ else:
+ tags = []
+
+ if tags:
+ ail_objects.obj_correlations_objs_add_tags(obj_type, subtype, obj_id, tags, filter_types=filter_types, lvl=2, nb_max=nb_max)
+
+ return redirect(url_for('correlation.show_correlation',
+ type=obj_type, subtype=subtype, id=obj_id,
+ filter=",".join(filter_types)))
diff --git a/var/www/templates/correlation/show_correlation.html b/var/www/templates/correlation/show_correlation.html
index 24be9d8a..636b8848 100644
--- a/var/www/templates/correlation/show_correlation.html
+++ b/var/www/templates/correlation/show_correlation.html
@@ -16,7 +16,7 @@
-
+