mirror of
https://github.com/ail-project/ail-framework.git
synced 2024-11-22 22:27:17 +00:00
chg: [ail orgs] refactor organisations + add org level to investigations
This commit is contained in:
parent
69471e0d37
commit
ff59343bb7
12 changed files with 494 additions and 202 deletions
|
@ -23,6 +23,7 @@ sys.path.append(os.environ['AIL_BIN'])
|
||||||
# Import Project packages
|
# Import Project packages
|
||||||
##################################
|
##################################
|
||||||
from lib import ail_core
|
from lib import ail_core
|
||||||
|
from lib import ail_orgs
|
||||||
from lib import ConfigLoader
|
from lib import ConfigLoader
|
||||||
from lib import Tag
|
from lib import Tag
|
||||||
from lib.exceptions import UpdateInvestigationError
|
from lib.exceptions import UpdateInvestigationError
|
||||||
|
@ -47,9 +48,6 @@ def sanityze_uuid(UUID):
|
||||||
sanityzed_uuid = uuid.UUID(hex=UUID, version=4)
|
sanityzed_uuid = uuid.UUID(hex=UUID, version=4)
|
||||||
return str(sanityzed_uuid).replace('-', '')
|
return str(sanityzed_uuid).replace('-', '')
|
||||||
|
|
||||||
def exists_obj_type(obj_type):
|
|
||||||
return obj_type in ['domain', 'item', 'pgp', 'cryptocurrency', 'decoded', 'screenshot', 'username']
|
|
||||||
|
|
||||||
def generate_uuid():
|
def generate_uuid():
|
||||||
return str(uuid.uuid4()).replace('-', '')
|
return str(uuid.uuid4()).replace('-', '')
|
||||||
|
|
||||||
|
@ -105,6 +103,42 @@ class Investigation(object):
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
return r_tracking.hget(f'investigations:data:{self.uuid}', 'name')
|
return r_tracking.hget(f'investigations:data:{self.uuid}', 'name')
|
||||||
|
|
||||||
|
## LEVEL ##
|
||||||
|
|
||||||
|
def get_level(self):
|
||||||
|
return int(r_tracking.hget(f'investigations:data:{self.uuid}', 'level'))
|
||||||
|
|
||||||
|
def set_level(self, level, org_uuid):
|
||||||
|
r_tracking.hset(f'investigations:data:{self.uuid}', 'level', level)
|
||||||
|
# Global
|
||||||
|
if level == 1:
|
||||||
|
r_tracking.sadd('investigations', self.uuid)
|
||||||
|
# Org
|
||||||
|
elif level == 2:
|
||||||
|
self.add_to_org(org_uuid)
|
||||||
|
|
||||||
|
def reset_level(self, old_level, new_level, new_org_uuid):
|
||||||
|
if old_level == 1:
|
||||||
|
r_tracking.srem('investigations', self.uuid)
|
||||||
|
# Org
|
||||||
|
elif old_level == 2:
|
||||||
|
ail_orgs.remove_obj_to_org(self.get_org(), 'investigation', self.uuid)
|
||||||
|
self.set_level(new_level, new_org_uuid)
|
||||||
|
|
||||||
|
## ORG ##
|
||||||
|
|
||||||
|
def get_creator_org(self):
|
||||||
|
return r_tracking.hget(f'investigations:data:{self.uuid}', 'creator_org')
|
||||||
|
|
||||||
|
def get_org(self):
|
||||||
|
return r_tracking.hget(f'investigations:data:{self.uuid}', 'org')
|
||||||
|
|
||||||
|
def add_to_org(self, org_uuid):
|
||||||
|
r_tracking.hset(f'investigations:data:{self.uuid}', 'org', org_uuid)
|
||||||
|
ail_orgs.add_obj_to_org(org_uuid, 'investigation', self.uuid)
|
||||||
|
|
||||||
|
## -ORG- ##
|
||||||
|
|
||||||
def get_threat_level(self):
|
def get_threat_level(self):
|
||||||
try:
|
try:
|
||||||
return int(r_tracking.hget(f'investigations:data:{self.uuid}', 'threat_level'))
|
return int(r_tracking.hget(f'investigations:data:{self.uuid}', 'threat_level'))
|
||||||
|
@ -166,6 +200,8 @@ class Investigation(object):
|
||||||
'analysis': analysis,
|
'analysis': analysis,
|
||||||
'tags': list(self.get_tags()),
|
'tags': list(self.get_tags()),
|
||||||
'user_creator': self.get_creator_user(),
|
'user_creator': self.get_creator_user(),
|
||||||
|
'level': self.get_level(),
|
||||||
|
'org': self.get_org(),
|
||||||
'date': self.get_date(),
|
'date': self.get_date(),
|
||||||
'timestamp': self.get_timestamp(r_str=r_str),
|
'timestamp': self.get_timestamp(r_str=r_str),
|
||||||
'last_change': self.get_last_change(r_str=r_str),
|
'last_change': self.get_last_change(r_str=r_str),
|
||||||
|
@ -270,14 +306,22 @@ class Investigation(object):
|
||||||
self.unregister_object(obj_id, obj_type, subtype=subtype)
|
self.unregister_object(obj_id, obj_type, subtype=subtype)
|
||||||
|
|
||||||
r_tracking.srem('investigations:all', self.uuid)
|
r_tracking.srem('investigations:all', self.uuid)
|
||||||
|
# level
|
||||||
|
level = self.get_level()
|
||||||
|
if level == 1:
|
||||||
|
r_tracking.srem('investigations', self.uuid)
|
||||||
|
elif level == 2:
|
||||||
|
ail_orgs.remove_obj_to_org(self.get_org(), 'investigation', self.uuid)
|
||||||
|
|
||||||
# user map
|
# user map
|
||||||
r_tracking.srem(f'investigations:user:{self.get_creator_user()}', self.uuid)
|
r_tracking.srem(f'investigations:user:{self.get_creator_user()}', self.uuid)
|
||||||
# metadata
|
# metadata
|
||||||
r_tracking.delete(f'investigations:data:{self.uuid}')
|
r_tracking.delete(f'investigations:data:{self.uuid}')
|
||||||
r_tracking.delete(f'investigations:tags:{self.uuid}')
|
r_tracking.delete(f'investigations:tags:{self.uuid}')
|
||||||
r_tracking.delete(f'investigations:misp:{self.uuid}')
|
r_tracking.delete(f'investigations:misp:{self.uuid}')
|
||||||
|
return self.uuid
|
||||||
|
|
||||||
##-- Class --##
|
## -- -- ##
|
||||||
|
|
||||||
def get_all_investigations():
|
def get_all_investigations():
|
||||||
return r_tracking.smembers('investigations:all')
|
return r_tracking.smembers('investigations:all')
|
||||||
|
@ -285,6 +329,12 @@ def get_all_investigations():
|
||||||
def exists_investigation(investigation_uuid):
|
def exists_investigation(investigation_uuid):
|
||||||
return r_tracking.sismember('investigations:all', investigation_uuid)
|
return r_tracking.sismember('investigations:all', investigation_uuid)
|
||||||
|
|
||||||
|
def get_global_investigations():
|
||||||
|
return r_tracking.smembers('investigations')
|
||||||
|
|
||||||
|
def get_org_investigations(org_uuid):
|
||||||
|
return ail_orgs.get_org_objs_by_type(org_uuid, 'investigation')
|
||||||
|
|
||||||
# created by user
|
# created by user
|
||||||
def get_user_all_investigations(user_id):
|
def get_user_all_investigations(user_id):
|
||||||
return r_tracking.smembers(f'investigations:user:{user_id}')
|
return r_tracking.smembers(f'investigations:user:{user_id}')
|
||||||
|
@ -309,8 +359,8 @@ def _set_timestamp(investigation_uuid, timestamp):
|
||||||
|
|
||||||
# analysis - threat level - info - date - creator
|
# analysis - threat level - info - date - creator
|
||||||
|
|
||||||
def _re_create_investagation(investigation_uuid, user_id, date, name, threat_level, analysis, info, tags, last_change, timestamp, misp_events):
|
def _re_create_investigation(investigation_uuid, user_org, user_id, level, date, name, threat_level, analysis, info, tags, last_change, timestamp, misp_events):
|
||||||
create_investigation(user_id, date, name, threat_level, analysis, info, tags=tags, investigation_uuid=investigation_uuid)
|
create_investigation(user_org, user_id, level, date, name, threat_level, analysis, info, tags=tags, investigation_uuid=investigation_uuid)
|
||||||
if timestamp:
|
if timestamp:
|
||||||
_set_timestamp(investigation_uuid, timestamp)
|
_set_timestamp(investigation_uuid, timestamp)
|
||||||
investigation = Investigation(investigation_uuid)
|
investigation = Investigation(investigation_uuid)
|
||||||
|
@ -323,7 +373,7 @@ def _re_create_investagation(investigation_uuid, user_id, date, name, threat_lev
|
||||||
# # TODO: limit description + name
|
# # TODO: limit description + name
|
||||||
# # TODO: sanitize tags
|
# # TODO: sanitize tags
|
||||||
# # TODO: sanitize date
|
# # TODO: sanitize date
|
||||||
def create_investigation(user_id, date, name, threat_level, analysis, info, tags=[], investigation_uuid=None):
|
def create_investigation(user_org, user_id, level, date, name, threat_level, analysis, info, tags=[], investigation_uuid=None):
|
||||||
if investigation_uuid:
|
if investigation_uuid:
|
||||||
if not is_valid_uuid_v4(investigation_uuid):
|
if not is_valid_uuid_v4(investigation_uuid):
|
||||||
investigation_uuid = generate_uuid()
|
investigation_uuid = generate_uuid()
|
||||||
|
@ -331,12 +381,15 @@ def create_investigation(user_id, date, name, threat_level, analysis, info, tags
|
||||||
investigation_uuid = generate_uuid()
|
investigation_uuid = generate_uuid()
|
||||||
r_tracking.sadd('investigations:all', investigation_uuid)
|
r_tracking.sadd('investigations:all', investigation_uuid)
|
||||||
# user map
|
# user map
|
||||||
r_tracking.sadd(f'investigations:user:{user_id}', investigation_uuid)
|
r_tracking.sadd(f'investigations:user:{user_id}', investigation_uuid) # TODO REFACTOR ME
|
||||||
# metadata
|
# metadata
|
||||||
|
r_tracking.hset(f'investigations:data:{investigation_uuid}', 'creator_org', user_org)
|
||||||
r_tracking.hset(f'investigations:data:{investigation_uuid}', 'creator_user', user_id)
|
r_tracking.hset(f'investigations:data:{investigation_uuid}', 'creator_user', user_id)
|
||||||
|
|
||||||
# TODO: limit info + name
|
# TODO: limit info + name
|
||||||
investigation = Investigation(investigation_uuid)
|
investigation = Investigation(investigation_uuid)
|
||||||
|
investigation.set_level(level, user_org)
|
||||||
|
|
||||||
investigation.set_info(info)
|
investigation.set_info(info)
|
||||||
#investigation.set_name(name) ##############################################
|
#investigation.set_name(name) ##############################################
|
||||||
investigation.set_date(date)
|
investigation.set_date(date)
|
||||||
|
@ -360,23 +413,61 @@ def get_all_investigations_meta(r_str=False):
|
||||||
investigations_meta.append(investigation.get_metadata(r_str=r_str))
|
investigations_meta.append(investigation.get_metadata(r_str=r_str))
|
||||||
return investigations_meta
|
return investigations_meta
|
||||||
|
|
||||||
def get_investigations_selector():
|
def get_global_investigations_meta(r_str=False):
|
||||||
|
investigations_meta = []
|
||||||
|
for investigation_uuid in get_global_investigations():
|
||||||
|
investigation = Investigation(investigation_uuid)
|
||||||
|
investigations_meta.append(investigation.get_metadata(r_str=r_str))
|
||||||
|
return investigations_meta
|
||||||
|
|
||||||
|
|
||||||
|
def get_org_investigations_meta(org_uuid, r_str=False):
|
||||||
|
investigations_meta = []
|
||||||
|
for investigation_uuid in get_org_investigations(org_uuid):
|
||||||
|
investigation = Investigation(investigation_uuid)
|
||||||
|
investigations_meta.append(investigation.get_metadata(r_str=r_str))
|
||||||
|
return investigations_meta
|
||||||
|
|
||||||
|
|
||||||
|
def get_investigations_selector(org_uuid):
|
||||||
l_investigations = []
|
l_investigations = []
|
||||||
for investigation_uuid in get_all_investigations():
|
for investigation_uuid in get_global_investigations():
|
||||||
|
investigation = Investigation(investigation_uuid)
|
||||||
|
name = investigation.get_info()
|
||||||
|
l_investigations.append({"id": investigation_uuid, "name": name})
|
||||||
|
for investigation_uuid in get_org_investigations(org_uuid):
|
||||||
investigation = Investigation(investigation_uuid)
|
investigation = Investigation(investigation_uuid)
|
||||||
name = investigation.get_info()
|
name = investigation.get_info()
|
||||||
l_investigations.append({"id": investigation_uuid, "name": name})
|
l_investigations.append({"id": investigation_uuid, "name": name})
|
||||||
return l_investigations
|
return l_investigations
|
||||||
|
|
||||||
#{id:'8dc4b81aeff94a9799bd70ba556fa345',name:"Paris"}
|
#### ACL ####
|
||||||
|
|
||||||
|
def check_access_acl(inv, user_org, is_admin=False):
|
||||||
|
if is_admin:
|
||||||
|
return True
|
||||||
|
|
||||||
|
level = inv.get_level()
|
||||||
|
if level == 1:
|
||||||
|
return True
|
||||||
|
if level == 2:
|
||||||
|
return ail_orgs.check_access_acl(inv, user_org, is_admin=is_admin)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def api_check_access_acl(inv_uuid, user_org, is_admin=False):
|
||||||
|
if not check_access_acl(inv_uuid, user_org, is_admin=is_admin):
|
||||||
|
return {"status": "error", "reason": "Access Denied"}, 403
|
||||||
|
|
||||||
#### API ####
|
#### API ####
|
||||||
|
|
||||||
def api_get_investigation(investigation_uuid): # TODO check if is UUIDv4
|
def api_get_investigation(user_org, is_admin, investigation_uuid): # TODO check if is UUIDv4
|
||||||
investigation = Investigation(investigation_uuid)
|
investigation = Investigation(investigation_uuid)
|
||||||
if not investigation.exists():
|
if not investigation.exists():
|
||||||
return {'status': 'error', 'reason': 'Investigation Not Found'}, 404
|
return {'status': 'error', 'reason': 'Investigation Not Found'}, 404
|
||||||
|
res = api_check_access_acl(investigation, user_org, is_admin=is_admin)
|
||||||
|
if res:
|
||||||
|
return res
|
||||||
|
|
||||||
meta = investigation.get_metadata(options={'objects'}, r_str=False)
|
meta = investigation.get_metadata(options={'objects'}, r_str=False)
|
||||||
# objs = []
|
# objs = []
|
||||||
|
@ -392,6 +483,7 @@ def api_get_investigation(investigation_uuid): # TODO check if is UUIDv4
|
||||||
# # TODO: SANITYZE Fields
|
# # TODO: SANITYZE Fields
|
||||||
# # TODO: Name ?????
|
# # TODO: Name ?????
|
||||||
def api_add_investigation(json_dict):
|
def api_add_investigation(json_dict):
|
||||||
|
user_org = json_dict.get('user_org')
|
||||||
user_id = json_dict.get('user_id')
|
user_id = json_dict.get('user_id')
|
||||||
name = json_dict.get('name') ##### mandatory ?
|
name = json_dict.get('name') ##### mandatory ?
|
||||||
name = escape(name)
|
name = escape(name)
|
||||||
|
@ -401,6 +493,14 @@ def api_add_investigation(json_dict):
|
||||||
# # TODO: sanityze date
|
# # TODO: sanityze date
|
||||||
date = json_dict.get('date')
|
date = json_dict.get('date')
|
||||||
|
|
||||||
|
level = json_dict.get('level', 1)
|
||||||
|
try:
|
||||||
|
level = int(level)
|
||||||
|
except TypeError:
|
||||||
|
level = 1
|
||||||
|
if level not in range(1, 3):
|
||||||
|
level = 1
|
||||||
|
|
||||||
info = json_dict.get('info', '')
|
info = json_dict.get('info', '')
|
||||||
info = escape(info)
|
info = escape(info)
|
||||||
info = info[:1000]
|
info = info[:1000]
|
||||||
|
@ -409,13 +509,13 @@ def api_add_investigation(json_dict):
|
||||||
return {"status": "error", "reason": "Invalid/Disabled tags"}, 400
|
return {"status": "error", "reason": "Invalid/Disabled tags"}, 400
|
||||||
|
|
||||||
try:
|
try:
|
||||||
res = create_investigation(user_id, date, name, threat_level, analysis, info, tags=tags)
|
res = create_investigation(user_org, user_id, level, date, name, threat_level, analysis, info, tags=tags)
|
||||||
except UpdateInvestigationError as e:
|
except UpdateInvestigationError as e:
|
||||||
return e.message, 400
|
return e.message, 400
|
||||||
return res, 200
|
return res, 200
|
||||||
|
|
||||||
# # TODO: edit threat level / status
|
# # TODO: edit threat level / status
|
||||||
def api_edit_investigation(json_dict):
|
def api_edit_investigation(user_org, user_id, is_admin, json_dict):
|
||||||
investigation_uuid = json_dict.get('uuid', '').replace(' ', '')
|
investigation_uuid = json_dict.get('uuid', '').replace(' ', '')
|
||||||
if not is_valid_uuid_v4(investigation_uuid):
|
if not is_valid_uuid_v4(investigation_uuid):
|
||||||
return {"status": "error", "reason": "Invalid Investigation uuid"}, 400
|
return {"status": "error", "reason": "Invalid Investigation uuid"}, 400
|
||||||
|
@ -423,6 +523,9 @@ def api_edit_investigation(json_dict):
|
||||||
if not exists_investigation(investigation_uuid):
|
if not exists_investigation(investigation_uuid):
|
||||||
return {"status": "error", "reason": "Investigation not found"}, 404
|
return {"status": "error", "reason": "Investigation not found"}, 404
|
||||||
investigation = Investigation(investigation_uuid)
|
investigation = Investigation(investigation_uuid)
|
||||||
|
res = api_check_access_acl(investigation, user_org, is_admin=is_admin)
|
||||||
|
if res:
|
||||||
|
return res
|
||||||
|
|
||||||
name = json_dict.get('name') ##### mandatory ?
|
name = json_dict.get('name') ##### mandatory ?
|
||||||
name = escape(name)
|
name = escape(name)
|
||||||
|
@ -445,6 +548,17 @@ def api_edit_investigation(json_dict):
|
||||||
if not Tag.are_enabled_tags(tags):
|
if not Tag.are_enabled_tags(tags):
|
||||||
return {"status": "error", "reason": "Invalid/Disabled tags"}, 400
|
return {"status": "error", "reason": "Invalid/Disabled tags"}, 400
|
||||||
|
|
||||||
|
level = json_dict.get('level', 1)
|
||||||
|
try:
|
||||||
|
level = int(level)
|
||||||
|
except TypeError:
|
||||||
|
level = 1
|
||||||
|
if level not in range(1, 3):
|
||||||
|
level = 1
|
||||||
|
old_level = investigation.get_level()
|
||||||
|
if level != old_level:
|
||||||
|
investigation.reset_level(old_level, level, user_org)
|
||||||
|
|
||||||
investigation.set_info(info)
|
investigation.set_info(info)
|
||||||
investigation.set_name(name)
|
investigation.set_name(name)
|
||||||
investigation.set_tags(tags)
|
investigation.set_tags(tags)
|
||||||
|
@ -454,7 +568,7 @@ def api_edit_investigation(json_dict):
|
||||||
|
|
||||||
return investigation_uuid, 200
|
return investigation_uuid, 200
|
||||||
|
|
||||||
def api_delete_investigation(json_dict):
|
def api_delete_investigation(user_org, user_id, is_admin, json_dict):
|
||||||
investigation_uuid = json_dict.get('uuid', '').replace(' ', '')
|
investigation_uuid = json_dict.get('uuid', '').replace(' ', '')
|
||||||
if not is_valid_uuid_v4(investigation_uuid):
|
if not is_valid_uuid_v4(investigation_uuid):
|
||||||
return {"status": "error", "reason": "Invalid Investigation uuid"}, 400
|
return {"status": "error", "reason": "Invalid Investigation uuid"}, 400
|
||||||
|
@ -462,10 +576,13 @@ def api_delete_investigation(json_dict):
|
||||||
if not exists_investigation(investigation_uuid):
|
if not exists_investigation(investigation_uuid):
|
||||||
return {"status": "error", "reason": "Investigation not found"}, 404
|
return {"status": "error", "reason": "Investigation not found"}, 404
|
||||||
investigation = Investigation(investigation_uuid)
|
investigation = Investigation(investigation_uuid)
|
||||||
|
res = api_check_access_acl(investigation, user_org, is_admin=is_admin)
|
||||||
|
if res:
|
||||||
|
return res
|
||||||
res = investigation.delete()
|
res = investigation.delete()
|
||||||
return res, 200
|
return res, 200
|
||||||
|
|
||||||
def api_register_object(json_dict):
|
def api_register_object(user_org, user_id, is_admin, json_dict):
|
||||||
investigation_uuid = json_dict.get('uuid', '').replace(' ', '')
|
investigation_uuid = json_dict.get('uuid', '').replace(' ', '')
|
||||||
if not is_valid_uuid_v4(investigation_uuid):
|
if not is_valid_uuid_v4(investigation_uuid):
|
||||||
return {"status": "error", "reason": f"Invalid Investigation uuid: {investigation_uuid}"}, 400
|
return {"status": "error", "reason": f"Invalid Investigation uuid: {investigation_uuid}"}, 400
|
||||||
|
@ -473,6 +590,9 @@ def api_register_object(json_dict):
|
||||||
if not exists_investigation(investigation_uuid):
|
if not exists_investigation(investigation_uuid):
|
||||||
return {"status": "error", "reason": f"Investigation not found: {investigation_uuid}"}, 404
|
return {"status": "error", "reason": f"Investigation not found: {investigation_uuid}"}, 404
|
||||||
investigation = Investigation(investigation_uuid)
|
investigation = Investigation(investigation_uuid)
|
||||||
|
res = api_check_access_acl(investigation, user_org, is_admin=is_admin)
|
||||||
|
if res:
|
||||||
|
return res
|
||||||
|
|
||||||
obj_type = json_dict.get('type', '').replace(' ', '')
|
obj_type = json_dict.get('type', '').replace(' ', '')
|
||||||
if obj_type not in ail_core.get_all_objects():
|
if obj_type not in ail_core.get_all_objects():
|
||||||
|
@ -489,7 +609,7 @@ def api_register_object(json_dict):
|
||||||
res = investigation.register_object(obj_id, obj_type, subtype, comment=comment)
|
res = investigation.register_object(obj_id, obj_type, subtype, comment=comment)
|
||||||
return res, 200
|
return res, 200
|
||||||
|
|
||||||
def api_unregister_object(json_dict):
|
def api_unregister_object(user_org, user_id, is_admin, json_dict):
|
||||||
investigation_uuid = json_dict.get('uuid', '').replace(' ', '')
|
investigation_uuid = json_dict.get('uuid', '').replace(' ', '')
|
||||||
if not is_valid_uuid_v4(investigation_uuid):
|
if not is_valid_uuid_v4(investigation_uuid):
|
||||||
return {"status": "error", "reason": f"Invalid Investigation uuid: {investigation_uuid}"}, 400
|
return {"status": "error", "reason": f"Invalid Investigation uuid: {investigation_uuid}"}, 400
|
||||||
|
@ -497,6 +617,9 @@ def api_unregister_object(json_dict):
|
||||||
if not exists_investigation(investigation_uuid):
|
if not exists_investigation(investigation_uuid):
|
||||||
return {"status": "error", "reason": f"Investigation not found: {investigation_uuid}"}, 404
|
return {"status": "error", "reason": f"Investigation not found: {investigation_uuid}"}, 404
|
||||||
investigation = Investigation(investigation_uuid)
|
investigation = Investigation(investigation_uuid)
|
||||||
|
res = api_check_access_acl(investigation, user_org, is_admin=is_admin)
|
||||||
|
if res:
|
||||||
|
return res
|
||||||
|
|
||||||
obj_type = json_dict.get('type', '').replace(' ', '')
|
obj_type = json_dict.get('type', '').replace(' ', '')
|
||||||
subtype = json_dict.get('subtype', '')
|
subtype = json_dict.get('subtype', '')
|
||||||
|
|
|
@ -26,6 +26,10 @@ def is_valid_token(token):
|
||||||
def get_user_from_token(token):
|
def get_user_from_token(token):
|
||||||
return ail_users.get_token_user(token)
|
return ail_users.get_token_user(token)
|
||||||
|
|
||||||
|
def get_basic_user_meta(token):
|
||||||
|
user_id = get_user_from_token(token)
|
||||||
|
return ail_users.get_user_org(user_id), user_id, ail_users.is_in_role(user_id, 'admin')
|
||||||
|
|
||||||
def is_user_in_role(role, token): # verify_user_role
|
def is_user_in_role(role, token): # verify_user_role
|
||||||
# User without API
|
# User without API
|
||||||
if role == 'user_no_api':
|
if role == 'user_no_api':
|
||||||
|
|
222
bin/lib/ail_orgs.py
Executable file
222
bin/lib/ail_orgs.py
Executable file
|
@ -0,0 +1,222 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*-coding:UTF-8 -*
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
sys.path.append(os.environ['AIL_BIN'])
|
||||||
|
##################################
|
||||||
|
# Import Project packages
|
||||||
|
##################################
|
||||||
|
from lib import ail_logger
|
||||||
|
from lib.ail_core import is_valid_uuid_v4, generate_uuid
|
||||||
|
from lib.ConfigLoader import ConfigLoader
|
||||||
|
|
||||||
|
|
||||||
|
# LOGS
|
||||||
|
|
||||||
|
access_logger = ail_logger.get_access_config()
|
||||||
|
|
||||||
|
# Config
|
||||||
|
config_loader = ConfigLoader()
|
||||||
|
r_serv_db = config_loader.get_db_conn("Kvrocks_DB")
|
||||||
|
r_data = config_loader.get_db_conn("Kvrocks_DB") # TODO MOVE DEFAULT DB
|
||||||
|
# r_cache = config_loader.get_redis_conn("Redis_Cache")
|
||||||
|
|
||||||
|
config_loader = None
|
||||||
|
|
||||||
|
|
||||||
|
#### ORGANISATIONS ####
|
||||||
|
|
||||||
|
# TODO EDIT
|
||||||
|
|
||||||
|
# TODO DELETE CHECK
|
||||||
|
# TODO DELETE OBJS
|
||||||
|
|
||||||
|
# TODO ORG View
|
||||||
|
|
||||||
|
# TODO TAGS
|
||||||
|
# TODO TAGS USERS ????
|
||||||
|
|
||||||
|
# TODO Check if ORG name is UNIQUE
|
||||||
|
|
||||||
|
def get_orgs():
|
||||||
|
return r_serv_db.smembers(f'ail:orgs')
|
||||||
|
|
||||||
|
def is_user_in_org(org_uuid, user_id):
|
||||||
|
return r_serv_db.sadd(f'ail:org:{org_uuid}:users', user_id)
|
||||||
|
|
||||||
|
#### ORGANISATION ####
|
||||||
|
|
||||||
|
class Organisation:
|
||||||
|
|
||||||
|
def __init__(self, org_uuid):
|
||||||
|
self.uuid = org_uuid
|
||||||
|
|
||||||
|
def exists(self):
|
||||||
|
return r_serv_db.exists(f'ail:org:{self.uuid}')
|
||||||
|
|
||||||
|
def _get_field(self, field):
|
||||||
|
return r_serv_db.hget(f'ail:org:{self.uuid}', field)
|
||||||
|
|
||||||
|
def _set_fields(self, field, value):
|
||||||
|
return r_serv_db.hset(f'ail:org:{self.uuid}', field, value)
|
||||||
|
|
||||||
|
def get_uuid(self):
|
||||||
|
return self.uuid
|
||||||
|
|
||||||
|
def get_date_created(self):
|
||||||
|
return self._get_field('date_created')
|
||||||
|
|
||||||
|
def get_date_modified(self):
|
||||||
|
return self._get_field('date_modified')
|
||||||
|
|
||||||
|
def get_description(self):
|
||||||
|
return self._get_field('description')
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
return self._get_field('name')
|
||||||
|
|
||||||
|
def get_nationality(self):
|
||||||
|
return self._get_field('nationality')
|
||||||
|
|
||||||
|
def get_creator(self):
|
||||||
|
return self._get_field('creator')
|
||||||
|
|
||||||
|
def get_org_type(self):
|
||||||
|
return self._get_field('type')
|
||||||
|
|
||||||
|
def get_sector(self):
|
||||||
|
return self._get_field('sector')
|
||||||
|
|
||||||
|
def get_tags(self): # TODO
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_logo(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_users(self):
|
||||||
|
return r_serv_db.smembers(f'ail:org:{self.uuid}:users')
|
||||||
|
|
||||||
|
def get_nb_users(self):
|
||||||
|
return r_serv_db.scard(f'ail:org:{self.uuid}:users')
|
||||||
|
|
||||||
|
def get_meta(self, options=set()):
|
||||||
|
meta = {'uuid': self.uuid}
|
||||||
|
if 'name' in options:
|
||||||
|
meta['name'] = self._get_field('name')
|
||||||
|
if 'description' in options:
|
||||||
|
meta['description'] = self._get_field('description')
|
||||||
|
if 'creator' in options:
|
||||||
|
meta['creator'] = self._get_field('creator')
|
||||||
|
if 'date_created' in options:
|
||||||
|
meta['date_created'] = self._get_field('date_created')
|
||||||
|
return meta
|
||||||
|
|
||||||
|
def add_user(self, user_id):
|
||||||
|
r_serv_db.sadd(f'ail:org:{self.uuid}:users', user_id)
|
||||||
|
r_serv_db.hset(f'ail:user:metadata:{user_id}', 'org', self.uuid)
|
||||||
|
|
||||||
|
def remove_user(self, user_id):
|
||||||
|
r_serv_db.srem(f'ail:org:{self.uuid}:users', user_id)
|
||||||
|
r_serv_db.hdel(f'ail:user:metadata:{user_id}', 'org')
|
||||||
|
|
||||||
|
def remove_users(self):
|
||||||
|
for user_id in self.get_users():
|
||||||
|
self.remove_user(user_id)
|
||||||
|
|
||||||
|
def create(self, creator, name, description=None, nationality=None, sector=None, org_type=None, logo=None):
|
||||||
|
r_serv_db.sadd(f'ail:orgs', self.uuid)
|
||||||
|
|
||||||
|
self._set_fields('creator', creator)
|
||||||
|
self._set_fields('name', name)
|
||||||
|
self._set_fields('description', description)
|
||||||
|
if nationality:
|
||||||
|
self._set_fields('nationality', nationality)
|
||||||
|
if sector:
|
||||||
|
self._set_fields('sector', sector)
|
||||||
|
if org_type:
|
||||||
|
self._set_fields('type', org_type)
|
||||||
|
# if logo:
|
||||||
|
|
||||||
|
current = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
self._set_fields('date_created', current)
|
||||||
|
self._set_fields('date_modified', current)
|
||||||
|
|
||||||
|
def edit(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def delete(self): # TODO CHANGE ACL ASSOCIATED WITH ORGS -> Tracker, Investigation, objects, ...
|
||||||
|
self.remove_users()
|
||||||
|
r_serv_db.delete(f'ail:org:{self.uuid}')
|
||||||
|
r_serv_db.srem(f'ail:orgs', self.uuid)
|
||||||
|
|
||||||
|
|
||||||
|
def exists_org(org_uuid):
|
||||||
|
return r_serv_db.exists(f'ail:org:{org_uuid}')
|
||||||
|
|
||||||
|
def create_org(name, description, uuid=None, nationality=None, sector=None, org_type=None, logo=None): # contacts ?????
|
||||||
|
if uuid is None:
|
||||||
|
uuid = generate_uuid()
|
||||||
|
else:
|
||||||
|
if exists_org(uuid):
|
||||||
|
raise Exception('Organisation already exists') # TODO CUSTOM ERROR
|
||||||
|
|
||||||
|
org = Organisation(uuid)
|
||||||
|
org.create(name, description, nationality=nationality, sector=sector, org_type=org_type, logo=logo)
|
||||||
|
|
||||||
|
def get_org_objs_by_type(org_uuid, obj_type):
|
||||||
|
return r_serv_db.smembers(f'org:{org_uuid}:{obj_type}')
|
||||||
|
|
||||||
|
def add_obj_to_org(org_uuid, obj_type, obj_gid): # ADD set UUID -> object types ???
|
||||||
|
r_serv_db.sadd(f'org:{org_uuid}:{obj_type}', obj_gid)
|
||||||
|
|
||||||
|
def remove_obj_to_org(org_uuid, obj_type, obj_gid):
|
||||||
|
r_serv_db.srem(f'org:{org_uuid}:{obj_type}', obj_gid)
|
||||||
|
|
||||||
|
|
||||||
|
## --ORGANISATION-- ##
|
||||||
|
|
||||||
|
def check_access_acl(obj, user_org, is_admin=False):
|
||||||
|
if is_admin:
|
||||||
|
return True
|
||||||
|
return obj.get_org() == user_org
|
||||||
|
|
||||||
|
#### API ####
|
||||||
|
|
||||||
|
def api_get_orgs_meta():
|
||||||
|
meta = {'orgs': []}
|
||||||
|
options = {'date_created', 'description', 'name'}
|
||||||
|
for org_uuid in get_orgs():
|
||||||
|
org = Organisation(org_uuid)
|
||||||
|
meta['orgs'].append(org.get_meta(options=options))
|
||||||
|
return meta
|
||||||
|
|
||||||
|
def api_create_org(creator, org_uuid, name, ip_address, description=None):
|
||||||
|
if not is_valid_uuid_v4(org_uuid):
|
||||||
|
return {'status': 'error', 'reason': 'Invalid UUID'}, 400
|
||||||
|
if exists_org(org_uuid):
|
||||||
|
return {'status': 'error', 'reason': 'Org already exists'}, 400
|
||||||
|
|
||||||
|
org = Organisation(org_uuid)
|
||||||
|
org.create(creator, name, description=description)
|
||||||
|
access_logger.info(f'Created org {org_uuid}', extra={'user_id': creator, 'ip_address': ip_address})
|
||||||
|
return org.get_uuid(), 200
|
||||||
|
|
||||||
|
def api_delete_org(org_uuid, admin_id, ip_address): # TODO check if nothing is linked to this org
|
||||||
|
if not exists_org(org_uuid):
|
||||||
|
return {'status': 'error', 'reason': 'Org not found'}, 404
|
||||||
|
access_logger.warning(f'Deleted org {org_uuid}', extra={'user_id': admin_id, 'ip_address': ip_address})
|
||||||
|
org = Organisation(org_uuid)
|
||||||
|
org.delete()
|
||||||
|
return org_uuid, 200
|
||||||
|
|
||||||
|
|
||||||
|
# if __name__ == '__main__':
|
||||||
|
# user_id = 'admin@admin.test'
|
||||||
|
# instance_name = 'AIL TEST'
|
||||||
|
# delete_user_otp(user_id)
|
||||||
|
# # q = get_user_otp_qr_code(user_id, instance_name)
|
||||||
|
# # print(q)
|
|
@ -20,7 +20,7 @@ sys.path.append(os.environ['AIL_BIN'])
|
||||||
# Import Project packages
|
# Import Project packages
|
||||||
##################################
|
##################################
|
||||||
from lib import ail_logger
|
from lib import ail_logger
|
||||||
from lib.ail_core import is_valid_uuid_v4
|
from lib import ail_orgs
|
||||||
from lib.ConfigLoader import ConfigLoader
|
from lib.ConfigLoader import ConfigLoader
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,145 +42,6 @@ config_loader = None
|
||||||
regex_password = r'^(?=(.*\d){2})(?=.*[a-z])(?=.*[A-Z]).{10,100}$'
|
regex_password = r'^(?=(.*\d){2})(?=.*[a-z])(?=.*[A-Z]).{10,100}$'
|
||||||
regex_password = re.compile(regex_password)
|
regex_password = re.compile(regex_password)
|
||||||
|
|
||||||
#### ORGANISATIONS ####
|
|
||||||
|
|
||||||
# TODO EDIT
|
|
||||||
# TODO DELETE CHECK
|
|
||||||
|
|
||||||
# TODO ORG View
|
|
||||||
|
|
||||||
# TODO TAGS
|
|
||||||
# TODO TAGS USERS ????
|
|
||||||
|
|
||||||
# TODO Check if ORG name is UNIQUE
|
|
||||||
|
|
||||||
def get_orgs():
|
|
||||||
return r_serv_db.smembers(f'ail:orgs')
|
|
||||||
|
|
||||||
def is_user_in_org(org_uuid, user_id):
|
|
||||||
return r_serv_db.sadd(f'ail:org:{org_uuid}:users', user_id)
|
|
||||||
|
|
||||||
class Organisation:
|
|
||||||
|
|
||||||
def __init__(self, org_uuid):
|
|
||||||
self.uuid = org_uuid
|
|
||||||
|
|
||||||
def exists(self):
|
|
||||||
return r_serv_db.exists(f'ail:org:{self.uuid}')
|
|
||||||
|
|
||||||
def _get_field(self, field):
|
|
||||||
return r_serv_db.hget(f'ail:org:{self.uuid}', field)
|
|
||||||
|
|
||||||
def _set_fields(self, field, value):
|
|
||||||
return r_serv_db.hset(f'ail:org:{self.uuid}', field, value)
|
|
||||||
|
|
||||||
def get_uuid(self):
|
|
||||||
return self.uuid
|
|
||||||
|
|
||||||
def get_date_created(self):
|
|
||||||
date = self._get_field('date_created')
|
|
||||||
|
|
||||||
def get_date_modified(self):
|
|
||||||
date = self._get_field('date_modified')
|
|
||||||
|
|
||||||
def get_description(self):
|
|
||||||
return self._get_field('description')
|
|
||||||
|
|
||||||
def get_name(self):
|
|
||||||
return self._get_field('name')
|
|
||||||
|
|
||||||
def get_nationality(self):
|
|
||||||
return self._get_field('nationality')
|
|
||||||
|
|
||||||
def get_creator(self):
|
|
||||||
return self._get_field('creator')
|
|
||||||
|
|
||||||
def get_org_type(self):
|
|
||||||
return self._get_field('type')
|
|
||||||
|
|
||||||
def get_sector(self):
|
|
||||||
return self._get_field('sector')
|
|
||||||
|
|
||||||
def get_tags(self): # TODO
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_logo(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_users(self):
|
|
||||||
return r_serv_db.smembers(f'ail:org:{self.uuid}:users')
|
|
||||||
|
|
||||||
def get_nb_users(self):
|
|
||||||
return r_serv_db.scard(f'ail:org:{self.uuid}:users')
|
|
||||||
|
|
||||||
def get_meta(self, options=set()):
|
|
||||||
meta = {'uuid': self.uuid}
|
|
||||||
if 'name' in options:
|
|
||||||
meta['name'] = self._get_field('name')
|
|
||||||
if 'description' in options:
|
|
||||||
meta['description'] = self._get_field('description')
|
|
||||||
if 'creator' in options:
|
|
||||||
meta['creator'] = self._get_field('creator')
|
|
||||||
if 'date_created' in options:
|
|
||||||
meta['date_created'] = self._get_field('date_created')
|
|
||||||
return meta
|
|
||||||
|
|
||||||
def add_user(self, user_id):
|
|
||||||
if exists_user(user_id) and not get_user_org(user_id):
|
|
||||||
r_serv_db.sadd(f'ail:org:{self.uuid}:users', user_id)
|
|
||||||
r_serv_db.hset(f'ail:user:metadata:{user_id}', 'org', self.uuid)
|
|
||||||
|
|
||||||
def remove_user(self, user_id):
|
|
||||||
r_serv_db.srem(f'ail:org:{self.uuid}:users', user_id)
|
|
||||||
r_serv_db.hdel(f'ail:user:metadata:{user_id}', 'org')
|
|
||||||
|
|
||||||
def remove_users(self):
|
|
||||||
for user_id in self.get_users():
|
|
||||||
self.remove_user(user_id)
|
|
||||||
|
|
||||||
def create(self, creator, name, description=None, nationality=None, sector=None, org_type=None, logo=None):
|
|
||||||
r_serv_db.sadd(f'ail:orgs', self.uuid)
|
|
||||||
|
|
||||||
self._set_fields('creator', creator)
|
|
||||||
self._set_fields('name', name)
|
|
||||||
self._set_fields('description', description)
|
|
||||||
if nationality:
|
|
||||||
self._set_fields('nationality', nationality)
|
|
||||||
if sector:
|
|
||||||
self._set_fields('sector', sector)
|
|
||||||
if org_type:
|
|
||||||
self._set_fields('type', org_type)
|
|
||||||
#if logo:
|
|
||||||
|
|
||||||
current = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')
|
|
||||||
self._set_fields('date_created', current)
|
|
||||||
self._set_fields('date_modified', current)
|
|
||||||
|
|
||||||
def edit(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def delete(self): # TODO CHANGE ACL ASSOCIATED WITH ORGS -> Tracker, Investigation, objects, ...
|
|
||||||
self.remove_users()
|
|
||||||
r_serv_db.delete(f'ail:org:{self.uuid}')
|
|
||||||
r_serv_db.srem(f'ail:orgs', self.uuid)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def exists_org(org_uuid):
|
|
||||||
return r_serv_db.exists(f'ail:org:{org_uuid}')
|
|
||||||
|
|
||||||
def create_org(name, description, uuid=None, nationality=None, sector=None, org_type=None, logo=None): # contacts ?????
|
|
||||||
if uuid is None:
|
|
||||||
uuid = str(uuid4()) # TODO check if is uuidv4
|
|
||||||
else:
|
|
||||||
if exists_org(uuid):
|
|
||||||
raise Exception('Organisation already exists') # TODO CUSTOM ERROR
|
|
||||||
|
|
||||||
org = Organisation(uuid)
|
|
||||||
org.create( name, description, nationality=nationality, sector=sector, org_type=org_type, logo=logo)
|
|
||||||
|
|
||||||
## --ORGANISATIONS-- ##
|
|
||||||
|
|
||||||
#### SESSIONS ####
|
#### SESSIONS ####
|
||||||
|
|
||||||
def get_sessions():
|
def get_sessions():
|
||||||
|
@ -680,6 +541,9 @@ class AILUser(UserMixin):
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def is_admin(self):
|
||||||
|
return self.is_in_role('admin')
|
||||||
|
|
||||||
def get_role(self):
|
def get_role(self):
|
||||||
return r_serv_db.hget(f'ail:user:metadata:{self.user_id}', 'role')
|
return r_serv_db.hget(f'ail:user:metadata:{self.user_id}', 'role')
|
||||||
|
|
||||||
|
@ -698,33 +562,6 @@ class AILUser(UserMixin):
|
||||||
|
|
||||||
#### API ####
|
#### API ####
|
||||||
|
|
||||||
def api_get_orgs_meta():
|
|
||||||
meta = {'orgs': []}
|
|
||||||
options = {'date_created', 'description', 'name'}
|
|
||||||
for org_uuid in get_orgs():
|
|
||||||
org = Organisation(org_uuid)
|
|
||||||
meta['orgs'].append(org.get_meta(options=options))
|
|
||||||
return meta
|
|
||||||
|
|
||||||
def api_create_org(creator, org_uuid, name, ip_address, description=None):
|
|
||||||
if not is_valid_uuid_v4(org_uuid):
|
|
||||||
return {'status': 'error', 'reason': 'Invalid UUID'}, 400
|
|
||||||
if exists_org(org_uuid):
|
|
||||||
return {'status': 'error', 'reason': 'Org already exists'}, 400
|
|
||||||
|
|
||||||
org = Organisation(org_uuid)
|
|
||||||
org.create(creator, name, description=description)
|
|
||||||
access_logger.info(f'Created org {org_uuid}', extra={'user_id': creator, 'ip_address': ip_address})
|
|
||||||
return org.get_uuid(), 200
|
|
||||||
|
|
||||||
def api_delete_org(org_uuid, admin_id, ip_address): # TODO check if nothing is linked to this org
|
|
||||||
if not exists_org(org_uuid):
|
|
||||||
return {'status': 'error', 'reason': 'Org not found'}, 404
|
|
||||||
access_logger.warning(f'Deleted org {org_uuid}', extra={'user_id': admin_id, 'ip_address': ip_address})
|
|
||||||
org = Organisation(org_uuid)
|
|
||||||
org.delete()
|
|
||||||
return org_uuid, 200
|
|
||||||
|
|
||||||
def api_get_users_meta():
|
def api_get_users_meta():
|
||||||
meta = {'users': []}
|
meta = {'users': []}
|
||||||
options = {'api_key', 'creator', 'created_at', 'is_logged', 'last_edit', 'last_login', 'last_seen', 'last_seen_api', 'role', '2fa', 'otp_setup'}
|
options = {'api_key', 'creator', 'created_at', 'is_logged', 'last_edit', 'last_login', 'last_seen', 'last_seen_api', 'role', '2fa', 'otp_setup'}
|
||||||
|
|
|
@ -9,6 +9,8 @@ import sys
|
||||||
|
|
||||||
import importlib.util
|
import importlib.util
|
||||||
|
|
||||||
|
from lib.ail_core import get_ail_uuid
|
||||||
|
|
||||||
sys.path.append(os.environ['AIL_BIN'])
|
sys.path.append(os.environ['AIL_BIN'])
|
||||||
##################################
|
##################################
|
||||||
# Import Project packages
|
# Import Project packages
|
||||||
|
@ -260,7 +262,7 @@ def investigations_migration():
|
||||||
for investigation_uuid in old_Investigations.get_all_investigations():
|
for investigation_uuid in old_Investigations.get_all_investigations():
|
||||||
old_investigation = old_Investigations.Investigation(investigation_uuid)
|
old_investigation = old_Investigations.Investigation(investigation_uuid)
|
||||||
meta = old_investigation.get_metadata()
|
meta = old_investigation.get_metadata()
|
||||||
Investigations._re_create_investagation(meta['uuid'], meta['user_creator'], meta['date'], meta['name'], meta['threat_level'], meta['analysis'], meta['info'], meta['tags'], meta['last_change'], meta['timestamp'], meta['misp_events'])
|
Investigations._re_create_investigation(meta['uuid'], get_ail_uuid(), meta['user_creator'], 1, meta['date'], meta['name'], meta['threat_level'], meta['analysis'], meta['info'], meta['tags'], meta['last_change'], meta['timestamp'], meta['misp_events'])
|
||||||
new_investigation = Investigations.Investigation(meta['uuid'])
|
new_investigation = Investigations.Investigation(meta['uuid'])
|
||||||
for dict_obj in old_investigation.get_objects():
|
for dict_obj in old_investigation.get_objects():
|
||||||
new_investigation.register_object(dict_obj['id'], dict_obj['type'], dict_obj['subtype'])
|
new_investigation.register_object(dict_obj['id'], dict_obj['type'], dict_obj['subtype'])
|
||||||
|
|
|
@ -12,6 +12,7 @@ sys.path.append(os.environ['AIL_HOME'])
|
||||||
##################################
|
##################################
|
||||||
from update.bin.ail_updater import AIL_Updater
|
from update.bin.ail_updater import AIL_Updater
|
||||||
from lib import ail_users
|
from lib import ail_users
|
||||||
|
from lib import Investigations
|
||||||
from lib.ConfigLoader import ConfigLoader
|
from lib.ConfigLoader import ConfigLoader
|
||||||
from lib import chats_viewer
|
from lib import chats_viewer
|
||||||
|
|
||||||
|
@ -28,11 +29,22 @@ if __name__ == '__main__':
|
||||||
config_loader = None
|
config_loader = None
|
||||||
date = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')
|
date = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
for user_id in ail_users.get_users():
|
# ORGS
|
||||||
|
# TODO CREATE DEFAULT ORG
|
||||||
|
|
||||||
|
# USERS
|
||||||
|
print('Updating Users ...')
|
||||||
|
for user_id in ail_users.get_users(): # TODO ORG
|
||||||
r_serv_db.hset(f'ail:user:metadata:{user_id}', 'creator', 'admin@admin.test')
|
r_serv_db.hset(f'ail:user:metadata:{user_id}', 'creator', 'admin@admin.test')
|
||||||
r_serv_db.hset(f'ail:user:metadata:{user_id}', 'created_at', date)
|
r_serv_db.hset(f'ail:user:metadata:{user_id}', 'created_at', date)
|
||||||
r_serv_db.hset(f'ail:user:metadata:{user_id}', 'last_edit', date)
|
r_serv_db.hset(f'ail:user:metadata:{user_id}', 'last_edit', date)
|
||||||
|
|
||||||
|
# INVESTIGATIONS
|
||||||
|
print('Updating Investigations ...')
|
||||||
|
for inv_uuid in Investigations.get_all_investigations(): # TODO Creator ORG
|
||||||
|
inv = Investigations.Investigation(inv_uuid)
|
||||||
|
inv.set_level(1, None)
|
||||||
|
|
||||||
chats_viewer.fix_chats_with_messages()
|
chats_viewer.fix_chats_with_messages()
|
||||||
|
|
||||||
updater = Updater('v5.7')
|
updater = Updater('v5.7')
|
||||||
|
|
|
@ -19,6 +19,7 @@ sys.path.append(os.environ['AIL_BIN'])
|
||||||
from lib import ail_api
|
from lib import ail_api
|
||||||
from lib import ail_core
|
from lib import ail_core
|
||||||
from lib import ail_updates
|
from lib import ail_updates
|
||||||
|
from lib import ail_logger
|
||||||
from lib import crawlers
|
from lib import crawlers
|
||||||
from lib import chats_viewer
|
from lib import chats_viewer
|
||||||
|
|
||||||
|
@ -32,6 +33,10 @@ from lib.objects import Titles
|
||||||
from importer.FeederImporter import api_add_json_feeder_to_queue
|
from importer.FeederImporter import api_add_json_feeder_to_queue
|
||||||
|
|
||||||
|
|
||||||
|
# LOGS
|
||||||
|
# access_logger = ail_logger.get_access_config()
|
||||||
|
|
||||||
|
|
||||||
# ============ BLUEPRINT ============
|
# ============ BLUEPRINT ============
|
||||||
api_rest = Blueprint('api_rest', __name__, template_folder=os.path.join(os.environ['AIL_FLASK'], 'templates'))
|
api_rest = Blueprint('api_rest', __name__, template_folder=os.path.join(os.environ['AIL_FLASK'], 'templates'))
|
||||||
|
|
||||||
|
@ -66,6 +71,7 @@ def token_required(user_role):
|
||||||
return create_json_response({'status': 'error', 'reason': 'Access Forbidden'}, 403)
|
return create_json_response({'status': 'error', 'reason': 'Access Forbidden'}, 403)
|
||||||
else:
|
else:
|
||||||
# User Authenticated + In Role
|
# User Authenticated + In Role
|
||||||
|
# print(funct.__name__)
|
||||||
return funct(*args, **kwargs)
|
return funct(*args, **kwargs)
|
||||||
else:
|
else:
|
||||||
return create_json_response({'status': 'error', 'reason': 'Internal'}, 400)
|
return create_json_response({'status': 'error', 'reason': 'Internal'}, 400)
|
||||||
|
@ -245,7 +251,9 @@ def objects_titles_download_unsafe():
|
||||||
@api_rest.route("api/v1/investigation/<investigation_uuid>", methods=['GET']) # TODO options
|
@api_rest.route("api/v1/investigation/<investigation_uuid>", methods=['GET']) # TODO options
|
||||||
@token_required('read_only')
|
@token_required('read_only')
|
||||||
def v1_investigation(investigation_uuid):
|
def v1_investigation(investigation_uuid):
|
||||||
r = Investigations.api_get_investigation(investigation_uuid)
|
user_token = get_auth_from_header()
|
||||||
|
user_org, user_id, is_admin = ail_api.get_basic_user_meta(user_token)
|
||||||
|
r = Investigations.api_get_investigation(user_org, is_admin, investigation_uuid)
|
||||||
return create_json_response(r[0], r[1])
|
return create_json_response(r[0], r[1])
|
||||||
|
|
||||||
# TODO CATCH REDIRECT
|
# TODO CATCH REDIRECT
|
||||||
|
|
|
@ -42,17 +42,27 @@ def create_json_response(data, status_code):
|
||||||
@login_required
|
@login_required
|
||||||
@login_read_only
|
@login_read_only
|
||||||
def investigations_dashboard():
|
def investigations_dashboard():
|
||||||
investigations = Investigations.get_all_investigations_meta(r_str=True)
|
inv_global = Investigations.get_global_investigations_meta(r_str=True)
|
||||||
|
inv_org = Investigations.get_org_investigations_meta(current_user.get_org(), r_str=True)
|
||||||
return render_template("investigations.html", bootstrap_label=bootstrap_label,
|
return render_template("investigations.html", bootstrap_label=bootstrap_label,
|
||||||
investigations=investigations)
|
inv_global=inv_global, inv_org=inv_org)
|
||||||
|
|
||||||
|
|
||||||
@investigations_b.route("/investigation", methods=['GET']) ## FIXME: add /view ????
|
@investigations_b.route("/investigation", methods=['GET']) ## FIXME: add /view ????
|
||||||
@login_required
|
@login_required
|
||||||
@login_read_only
|
@login_read_only
|
||||||
def show_investigation():
|
def show_investigation():
|
||||||
|
user_org = current_user.get_org()
|
||||||
|
# user_id = current_user.get_user_id()
|
||||||
|
is_admin = current_user.is_admin()
|
||||||
investigation_uuid = request.args.get("uuid")
|
investigation_uuid = request.args.get("uuid")
|
||||||
investigation = Investigations.Investigation(investigation_uuid)
|
investigation = Investigations.Investigation(investigation_uuid)
|
||||||
|
if not investigation.exists():
|
||||||
|
create_json_response({'status': 'error', 'reason': 'Investigation Not Found'}, 404)
|
||||||
|
res = Investigations.api_check_access_acl(investigation, user_org, is_admin=is_admin)
|
||||||
|
if res:
|
||||||
|
return create_json_response(res[0], res[1])
|
||||||
|
|
||||||
metadata = investigation.get_metadata(r_str=True)
|
metadata = investigation.get_metadata(r_str=True)
|
||||||
objs = []
|
objs = []
|
||||||
for obj in investigation.get_objects():
|
for obj in investigation.get_objects():
|
||||||
|
@ -71,6 +81,8 @@ def show_investigation():
|
||||||
def add_investigation():
|
def add_investigation():
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
user_id = current_user.get_user_id()
|
user_id = current_user.get_user_id()
|
||||||
|
user_org = current_user.get_org()
|
||||||
|
level = request.form.get("investigation_level")
|
||||||
name = request.form.get("investigation_name")
|
name = request.form.get("investigation_name")
|
||||||
date = request.form.get("investigation_date")
|
date = request.form.get("investigation_date")
|
||||||
threat_level = request.form.get("threat_level")
|
threat_level = request.form.get("threat_level")
|
||||||
|
@ -93,7 +105,7 @@ def add_investigation():
|
||||||
galaxies_tags = []
|
galaxies_tags = []
|
||||||
tags = taxonomies_tags + galaxies_tags
|
tags = taxonomies_tags + galaxies_tags
|
||||||
|
|
||||||
input_dict = {"user_id": user_id, "name": name,
|
input_dict = {"user_org": user_org, "user_id": user_id, "level": level, "name": name,
|
||||||
"threat_level": threat_level, "date": date,
|
"threat_level": threat_level, "date": date,
|
||||||
"analysis": analysis, "info": info, "tags": tags}
|
"analysis": analysis, "info": info, "tags": tags}
|
||||||
res = Investigations.api_add_investigation(input_dict)
|
res = Investigations.api_add_investigation(input_dict)
|
||||||
|
@ -108,10 +120,13 @@ def add_investigation():
|
||||||
@investigations_b.route("/investigation/edit", methods=['GET', 'POST'])
|
@investigations_b.route("/investigation/edit", methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
@login_analyst
|
@login_analyst
|
||||||
def edit_investigation():
|
def edit_investigation(): # TODO CHECK ACL
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
user_org = current_user.get_org()
|
||||||
user_id = current_user.get_user_id()
|
user_id = current_user.get_user_id()
|
||||||
|
is_admin = current_user.is_admin()
|
||||||
investigation_uuid = request.form.get("investigation_uuid")
|
investigation_uuid = request.form.get("investigation_uuid")
|
||||||
|
level = request.form.get("investigation_level")
|
||||||
name = request.form.get("investigation_name")
|
name = request.form.get("investigation_name")
|
||||||
date = request.form.get("investigation_date")
|
date = request.form.get("investigation_date")
|
||||||
threat_level = request.form.get("threat_level")
|
threat_level = request.form.get("threat_level")
|
||||||
|
@ -135,10 +150,10 @@ def edit_investigation():
|
||||||
galaxies_tags = []
|
galaxies_tags = []
|
||||||
tags = taxonomies_tags + galaxies_tags
|
tags = taxonomies_tags + galaxies_tags
|
||||||
|
|
||||||
input_dict = {"user_id": user_id, "uuid": investigation_uuid,
|
input_dict = {"user_id": user_id, "uuid": investigation_uuid, "level": level,
|
||||||
"name": name, "threat_level": threat_level,
|
"name": name, "threat_level": threat_level,
|
||||||
"analysis": analysis, "info": info, "tags": tags}
|
"analysis": analysis, "info": info, "tags": tags}
|
||||||
res = Investigations.api_edit_investigation(input_dict)
|
res = Investigations.api_edit_investigation(user_org, user_id, is_admin, input_dict)
|
||||||
if res[1] != 200:
|
if res[1] != 200:
|
||||||
return create_json_response(res[0], res[1])
|
return create_json_response(res[0], res[1])
|
||||||
|
|
||||||
|
@ -158,9 +173,12 @@ def edit_investigation():
|
||||||
@login_required
|
@login_required
|
||||||
@login_analyst
|
@login_analyst
|
||||||
def delete_investigation():
|
def delete_investigation():
|
||||||
|
user_org = current_user.get_org()
|
||||||
|
user_id = current_user.get_user_id()
|
||||||
|
is_admin = current_user.is_admin()
|
||||||
investigation_uuid = request.args.get('uuid')
|
investigation_uuid = request.args.get('uuid')
|
||||||
input_dict = {"uuid": investigation_uuid}
|
input_dict = {"uuid": investigation_uuid}
|
||||||
res = Investigations.api_delete_investigation(input_dict)
|
res = Investigations.api_delete_investigation(user_org, user_id, is_admin, input_dict)
|
||||||
if res[1] != 200:
|
if res[1] != 200:
|
||||||
return create_json_response(res[0], res[1])
|
return create_json_response(res[0], res[1])
|
||||||
return redirect(url_for('investigations_b.investigations_dashboard'))
|
return redirect(url_for('investigations_b.investigations_dashboard'))
|
||||||
|
@ -169,6 +187,9 @@ def delete_investigation():
|
||||||
@login_required
|
@login_required
|
||||||
@login_read_only
|
@login_read_only
|
||||||
def register_investigation():
|
def register_investigation():
|
||||||
|
user_id = current_user.get_user_id()
|
||||||
|
user_org = current_user.get_org()
|
||||||
|
is_admin = current_user.is_admin()
|
||||||
investigations_uuid = request.args.get('uuids')
|
investigations_uuid = request.args.get('uuids')
|
||||||
investigations_uuid = investigations_uuid.split(',')
|
investigations_uuid = investigations_uuid.split(',')
|
||||||
|
|
||||||
|
@ -182,7 +203,7 @@ def register_investigation():
|
||||||
"type": object_type, "subtype": object_subtype}
|
"type": object_type, "subtype": object_subtype}
|
||||||
if comment:
|
if comment:
|
||||||
input_dict["comment"] = comment
|
input_dict["comment"] = comment
|
||||||
res = Investigations.api_register_object(input_dict)
|
res = Investigations.api_register_object(user_org, user_id, is_admin, input_dict)
|
||||||
if res[1] != 200:
|
if res[1] != 200:
|
||||||
return create_json_response(res[0], res[1])
|
return create_json_response(res[0], res[1])
|
||||||
return redirect(url_for('investigations_b.investigations_dashboard', uuid=investigation_uuid))
|
return redirect(url_for('investigations_b.investigations_dashboard', uuid=investigation_uuid))
|
||||||
|
@ -191,13 +212,16 @@ def register_investigation():
|
||||||
@login_required
|
@login_required
|
||||||
@login_read_only
|
@login_read_only
|
||||||
def unregister_investigation():
|
def unregister_investigation():
|
||||||
|
user_id = current_user.get_user_id()
|
||||||
|
user_org = current_user.get_org()
|
||||||
|
is_admin = current_user.is_admin()
|
||||||
investigation_uuid = request.args.get('uuid')
|
investigation_uuid = request.args.get('uuid')
|
||||||
object_type = request.args.get('type')
|
object_type = request.args.get('type')
|
||||||
object_subtype = request.args.get('subtype')
|
object_subtype = request.args.get('subtype')
|
||||||
object_id = request.args.get('id')
|
object_id = request.args.get('id')
|
||||||
input_dict = {"uuid": investigation_uuid, "id": object_id,
|
input_dict = {"uuid": investigation_uuid, "id": object_id,
|
||||||
"type": object_type, "subtype": object_subtype}
|
"type": object_type, "subtype": object_subtype}
|
||||||
res = Investigations.api_unregister_object(input_dict)
|
res = Investigations.api_unregister_object(user_org, user_id, is_admin, input_dict)
|
||||||
if res[1] != 200:
|
if res[1] != 200:
|
||||||
return create_json_response(res[0], res[1])
|
return create_json_response(res[0], res[1])
|
||||||
return redirect(url_for('investigations_b.show_investigation', uuid=investigation_uuid))
|
return redirect(url_for('investigations_b.show_investigation', uuid=investigation_uuid))
|
||||||
|
@ -207,7 +231,7 @@ def unregister_investigation():
|
||||||
@login_required
|
@login_required
|
||||||
@login_read_only
|
@login_read_only
|
||||||
def get_investigations_selector_json():
|
def get_investigations_selector_json():
|
||||||
return jsonify(Investigations.get_investigations_selector())
|
return jsonify(Investigations.get_investigations_selector(current_user.get_org()))
|
||||||
|
|
||||||
@investigations_b.route("/object/gid")
|
@investigations_b.route("/object/gid")
|
||||||
@login_required
|
@login_required
|
||||||
|
|
|
@ -20,6 +20,7 @@ sys.path.append(os.environ['AIL_BIN'])
|
||||||
# Import Project packages
|
# Import Project packages
|
||||||
##################################
|
##################################
|
||||||
from lib import ail_updates
|
from lib import ail_updates
|
||||||
|
from lib import ail_orgs
|
||||||
from lib import ail_users
|
from lib import ail_users
|
||||||
from lib import d4
|
from lib import d4
|
||||||
from packages import git_status
|
from packages import git_status
|
||||||
|
@ -307,7 +308,7 @@ def users_list():
|
||||||
@login_required
|
@login_required
|
||||||
@login_admin
|
@login_admin
|
||||||
def organisations_list():
|
def organisations_list():
|
||||||
meta = ail_users.api_get_orgs_meta()
|
meta = ail_orgs.api_get_orgs_meta()
|
||||||
return render_template("orgs_list.html", meta=meta, acl_admin=True)
|
return render_template("orgs_list.html", meta=meta, acl_admin=True)
|
||||||
|
|
||||||
@settings_b.route("/settings/create_organisation", methods=['GET'])
|
@settings_b.route("/settings/create_organisation", methods=['GET'])
|
||||||
|
@ -328,7 +329,7 @@ def create_org_post():
|
||||||
name = request.form.get('name')
|
name = request.form.get('name')
|
||||||
description = request.form.get('description')
|
description = request.form.get('description')
|
||||||
|
|
||||||
r = ail_users.api_create_org(admin_id, org_uuid, name, request.remote_addr, description=description)
|
r = ail_orgs.api_create_org(admin_id, org_uuid, name, request.remote_addr, description=description)
|
||||||
if r[1] != 200:
|
if r[1] != 200:
|
||||||
return create_json_response(r[0], r[1])
|
return create_json_response(r[0], r[1])
|
||||||
else:
|
else:
|
||||||
|
@ -344,7 +345,7 @@ def create_org_post():
|
||||||
def delete_org():
|
def delete_org():
|
||||||
admin_id = current_user.get_user_id()
|
admin_id = current_user.get_user_id()
|
||||||
org_uuid = request.args.get('uuid')
|
org_uuid = request.args.get('uuid')
|
||||||
r = ail_users.api_delete_org(org_uuid, admin_id, request.remote_addr)
|
r = ail_orgs.api_delete_org(org_uuid, admin_id, request.remote_addr)
|
||||||
if r[1] != 200:
|
if r[1] != 200:
|
||||||
return create_json_response(r[0], r[1])
|
return create_json_response(r[0], r[1])
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -144,6 +144,19 @@
|
||||||
{% else %}
|
{% else %}
|
||||||
Create a new Investigation
|
Create a new Investigation
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<label class="mt-3" for="level_selector">View Level</label>
|
||||||
|
<select class="custom-select" id="level_selector" name="investigation_level">
|
||||||
|
{% if edit %}
|
||||||
|
<option value="1" {% if metadata['level'] == 1 %}selected{% endif %}><i class="fas fa-users"></i> Global</option>
|
||||||
|
<option value="2" {% if metadata['level'] == 2 %}selected{% endif %}><i class="fas fa-landmark"></i> My Organisation</option>
|
||||||
|
{% else %}
|
||||||
|
<option value="1" selected><i class="fas fa-users"></i> Global</option>
|
||||||
|
<option value="2"><i class="fas fa-landmark"></i> My Organisation</option>
|
||||||
|
{% endif %}
|
||||||
|
</select>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
<div class="col-12 col-lg-10" id="core_content">
|
<div class="col-12 col-lg-10" id="core_content">
|
||||||
|
|
||||||
<h3 class="mt-2 text-secondary">
|
<h3 class="mt-2 text-secondary">
|
||||||
<i class="fas fa-microscope"></i> Investigations:
|
<i class="fas fa-microscope"></i> Organisation Investigations:
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<table id="table_investigation" class="table table-striped border-primary">
|
<table id="table_investigation" class="table table-striped border-primary">
|
||||||
|
@ -45,7 +45,43 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody style="font-size: 15px;">
|
<tbody style="font-size: 15px;">
|
||||||
{% for dict_investigation in investigations %}
|
{% for dict_investigation in inv_org %}
|
||||||
|
<tr class="border-color: blue;">
|
||||||
|
<td>
|
||||||
|
<a href="{{ url_for('investigations_b.show_investigation') }}?uuid={{ dict_investigation['uuid'] }}">
|
||||||
|
{{ dict_investigation['info']}}
|
||||||
|
<div>
|
||||||
|
{% for tag in dict_investigation['tags'] %}
|
||||||
|
<span class="badge badge-{{ bootstrap_label[loop.index0 % 5] }} pull-left">{{ tag }}</span>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>{{ dict_investigation['date']}}</td>
|
||||||
|
<td>{{ dict_investigation['last_change']}}</td>
|
||||||
|
<td>{{ dict_investigation['info']}}</td>
|
||||||
|
<td>{{ dict_investigation['nb_objects']}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h3 class="mt-2 text-secondary">
|
||||||
|
<i class="fas fa-microscope"></i> Global Investigations:
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<table id="table_investigation" class="table table-striped border-primary">
|
||||||
|
<thead class="bg-dark text-white">
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>last modified</th>
|
||||||
|
<td>Info</td>
|
||||||
|
<th>Nb Objects</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody style="font-size: 15px;">
|
||||||
|
{% for dict_investigation in inv_global %}
|
||||||
<tr class="border-color: blue;">
|
<tr class="border-color: blue;">
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for('investigations_b.show_investigation') }}?uuid={{ dict_investigation['uuid'] }}">
|
<a href="{{ url_for('investigations_b.show_investigation') }}?uuid={{ dict_investigation['uuid'] }}">
|
||||||
|
|
|
@ -47,6 +47,16 @@
|
||||||
<th>Creator</th>
|
<th>Creator</th>
|
||||||
<td>{{metadata['user_creator']}}</td>
|
<td>{{metadata['user_creator']}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Level</th>
|
||||||
|
<td>
|
||||||
|
{% if metadata['level'] == 1 %}
|
||||||
|
Global
|
||||||
|
{% elif metadata['level'] == 2 %}
|
||||||
|
My Organisation
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Tags</th>
|
<th>Tags</th>
|
||||||
<td>
|
<td>
|
||||||
|
|
Loading…
Reference in a new issue