mirror of https://github.com/CIRCL/AIL-framework
chg: [core] add users organisation + tracker acl by organisation
parent
ee443ff313
commit
69471e0d37
|
@ -186,10 +186,13 @@ class Tracker:
|
||||||
def is_level_user(self):
|
def is_level_user(self):
|
||||||
return self.get_level() == 0
|
return self.get_level() == 0
|
||||||
|
|
||||||
|
def is_level_org(self):
|
||||||
|
return self.get_level() == 2
|
||||||
|
|
||||||
def is_level_global(self):
|
def is_level_global(self):
|
||||||
return self.get_level() == 1
|
return self.get_level() == 1
|
||||||
|
|
||||||
def _set_level(self, level, tracker_type=None, user=None):
|
def _set_level(self, level, tracker_type=None, org=None, user=None):
|
||||||
if not tracker_type:
|
if not tracker_type:
|
||||||
tracker_type = self.get_type()
|
tracker_type = self.get_type()
|
||||||
if level == 0: # user only
|
if level == 0: # user only
|
||||||
|
@ -200,6 +203,9 @@ class Tracker:
|
||||||
elif level == 1: # global
|
elif level == 1: # global
|
||||||
r_tracker.sadd('global:tracker', self.uuid)
|
r_tracker.sadd('global:tracker', self.uuid)
|
||||||
r_tracker.sadd(f'global:tracker:{tracker_type}', self.uuid)
|
r_tracker.sadd(f'global:tracker:{tracker_type}', self.uuid)
|
||||||
|
elif level == 2: # org only
|
||||||
|
r_tracker.sadd(f'org:tracker:{org}', self.uuid)
|
||||||
|
r_tracker.sadd(f'org:tracker:{org}:{tracker_type}', self.uuid)
|
||||||
self._set_field('level', level)
|
self._set_field('level', level)
|
||||||
|
|
||||||
def get_filters(self):
|
def get_filters(self):
|
||||||
|
@ -252,6 +258,9 @@ class Tracker:
|
||||||
def _del_mails(self):
|
def _del_mails(self):
|
||||||
r_tracker.delete(f'tracker:mail:{self.uuid}')
|
r_tracker.delete(f'tracker:mail:{self.uuid}')
|
||||||
|
|
||||||
|
def get_org(self):
|
||||||
|
return self._get_field('org')
|
||||||
|
|
||||||
def get_user(self):
|
def get_user(self):
|
||||||
return self._get_field('user_id')
|
return self._get_field('user_id')
|
||||||
|
|
||||||
|
@ -285,6 +294,8 @@ class Tracker:
|
||||||
'date': self.get_date(),
|
'date': self.get_date(),
|
||||||
'first_seen': self.get_first_seen(),
|
'first_seen': self.get_first_seen(),
|
||||||
'last_seen': self.get_last_seen()}
|
'last_seen': self.get_last_seen()}
|
||||||
|
if 'org' in options:
|
||||||
|
meta['org'] = self.get_org()
|
||||||
if 'user' in options:
|
if 'user' in options:
|
||||||
meta['user'] = self.get_user()
|
meta['user'] = self.get_user()
|
||||||
if 'level' in options:
|
if 'level' in options:
|
||||||
|
@ -391,7 +402,7 @@ class Tracker:
|
||||||
|
|
||||||
# TODO escape custom tags
|
# TODO escape custom tags
|
||||||
# TODO escape mails ????
|
# TODO escape mails ????
|
||||||
def create(self, tracker_type, to_track, user_id, level, description=None, filters={}, tags=[], mails=[], webhook=None):
|
def create(self, tracker_type, to_track, org, user_id, level, description=None, filters={}, tags=[], mails=[], webhook=None):
|
||||||
if self.exists():
|
if self.exists():
|
||||||
raise Exception('Error: Tracker already exists')
|
raise Exception('Error: Tracker already exists')
|
||||||
|
|
||||||
|
@ -413,6 +424,7 @@ class Tracker:
|
||||||
self._set_field('tracked', to_track)
|
self._set_field('tracked', to_track)
|
||||||
self._set_field('type', tracker_type)
|
self._set_field('type', tracker_type)
|
||||||
self._set_field('date', datetime.date.today().strftime("%Y%m%d"))
|
self._set_field('date', datetime.date.today().strftime("%Y%m%d"))
|
||||||
|
self._set_field('org', org)
|
||||||
self._set_field('user_id', user_id)
|
self._set_field('user_id', user_id)
|
||||||
if description:
|
if description:
|
||||||
self._set_field('description', escape(description))
|
self._set_field('description', escape(description))
|
||||||
|
@ -426,8 +438,10 @@ class Tracker:
|
||||||
r_tracker.sadd('trackers:all', self.uuid)
|
r_tracker.sadd('trackers:all', self.uuid)
|
||||||
r_tracker.sadd(f'trackers:all:{tracker_type}', self.uuid)
|
r_tracker.sadd(f'trackers:all:{tracker_type}', self.uuid)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# TRACKER LEVEL
|
# TRACKER LEVEL
|
||||||
self._set_level(level, tracker_type=tracker_type, user=user_id)
|
self._set_level(level, tracker_type=tracker_type, org=org, user=user_id)
|
||||||
|
|
||||||
# create tracker tags list
|
# create tracker tags list
|
||||||
if tags:
|
if tags:
|
||||||
|
@ -454,7 +468,7 @@ class Tracker:
|
||||||
trigger_trackers_refresh(tracker_type)
|
trigger_trackers_refresh(tracker_type)
|
||||||
return self.uuid
|
return self.uuid
|
||||||
|
|
||||||
def edit(self, tracker_type, to_track, level, description=None, filters={}, tags=[], mails=[], webhook=None):
|
def edit(self, tracker_type, to_track, level, org, description=None, filters={}, tags=[], mails=[], webhook=None): # TODO ADMIN: EDIT ORG UUID
|
||||||
|
|
||||||
# edit tracker
|
# edit tracker
|
||||||
old_type = self.get_type()
|
old_type = self.get_type()
|
||||||
|
@ -481,9 +495,14 @@ class Tracker:
|
||||||
# LEVEL
|
# LEVEL
|
||||||
if old_level == 0:
|
if old_level == 0:
|
||||||
r_tracker.srem(f'user:tracker:{user_id}:{old_type}', self.uuid)
|
r_tracker.srem(f'user:tracker:{user_id}:{old_type}', self.uuid)
|
||||||
|
r_tracker.srem(f'user:tracker:{user_id}', self.uuid)
|
||||||
elif old_level == 1:
|
elif old_level == 1:
|
||||||
r_tracker.srem(f'global:tracker:{old_type}', self.uuid)
|
r_tracker.srem(f'global:tracker:{old_type}', self.uuid)
|
||||||
self._set_level(level, tracker_type=tracker_type, user=user_id)
|
r_tracker.srem(f'global:tracker', self.uuid)
|
||||||
|
elif old_level == 2:
|
||||||
|
r_tracker.srem(f'org:tracker:{self.get_org()}:{old_type}', self.uuid)
|
||||||
|
r_tracker.srem(f'org:tracker:{self.get_org()}', self.uuid)
|
||||||
|
self._set_level(level, tracker_type=tracker_type, org=org, user=user_id)
|
||||||
# Delete OLD YARA Rule File
|
# Delete OLD YARA Rule File
|
||||||
if old_type == 'yara':
|
if old_type == 'yara':
|
||||||
if not is_default_yara_rule(old_to_track):
|
if not is_default_yara_rule(old_to_track):
|
||||||
|
@ -506,11 +525,16 @@ class Tracker:
|
||||||
|
|
||||||
# Same Type
|
# Same Type
|
||||||
elif level != old_level:
|
elif level != old_level:
|
||||||
if level == 0:
|
if old_level == 0:
|
||||||
r_tracker.srem('global:tracker', self.uuid)
|
|
||||||
elif level == 1:
|
|
||||||
r_tracker.srem(f'user:tracker:{user_id}', self.uuid)
|
r_tracker.srem(f'user:tracker:{user_id}', self.uuid)
|
||||||
self._set_level(level, tracker_type=tracker_type, user=user_id)
|
r_tracker.srem(f'user:tracker:{user_id}:{tracker_type}', self.uuid)
|
||||||
|
elif old_level == 1:
|
||||||
|
r_tracker.srem('global:tracker', self.uuid)
|
||||||
|
r_tracker.srem(f'global:tracker:{tracker_type}', self.uuid)
|
||||||
|
elif old_level == 2:
|
||||||
|
r_tracker.srem(f'org:tracker:{self.get_org()}', self.uuid)
|
||||||
|
r_tracker.srem(f'org:tracker:{self.get_org()}:{tracker_type}', self.uuid)
|
||||||
|
self._set_level(level, tracker_type=tracker_type, org=org, user=user_id)
|
||||||
|
|
||||||
# To Track Edited
|
# To Track Edited
|
||||||
if to_track != old_to_track:
|
if to_track != old_to_track:
|
||||||
|
@ -589,21 +613,25 @@ class Tracker:
|
||||||
elif level == 1: # global
|
elif level == 1: # global
|
||||||
r_tracker.srem('global:tracker', self.uuid)
|
r_tracker.srem('global:tracker', self.uuid)
|
||||||
r_tracker.srem(f'global:tracker:{tracker_type}', self.uuid)
|
r_tracker.srem(f'global:tracker:{tracker_type}', self.uuid)
|
||||||
|
elif level == 2: # TODO ORG check delete permission
|
||||||
|
org = self.get_org()
|
||||||
|
r_tracker.srem(f'org:tracker:{org}', self.uuid)
|
||||||
|
r_tracker.srem(f'org:tracker:{org}:{tracker_type}', self.uuid)
|
||||||
|
|
||||||
# meta
|
# meta
|
||||||
r_tracker.delete(f'tracker:{self.uuid}')
|
r_tracker.delete(f'tracker:{self.uuid}')
|
||||||
trigger_trackers_refresh(tracker_type)
|
trigger_trackers_refresh(tracker_type)
|
||||||
|
|
||||||
|
|
||||||
def create_tracker(tracker_type, to_track, user_id, level, description=None, filters={}, tags=[], mails=[], webhook=None, tracker_uuid=None):
|
def create_tracker(tracker_type, to_track, org, user_id, level, description=None, filters={}, tags=[], mails=[], webhook=None, tracker_uuid=None):
|
||||||
if not tracker_uuid:
|
if not tracker_uuid:
|
||||||
tracker_uuid = str(uuid.uuid4())
|
tracker_uuid = str(uuid.uuid4())
|
||||||
tracker = Tracker(tracker_uuid)
|
tracker = Tracker(tracker_uuid)
|
||||||
return tracker.create(tracker_type, to_track, user_id, level, description=description, filters=filters, tags=tags,
|
return tracker.create(tracker_type, to_track, org, user_id, level, description=description, filters=filters, tags=tags,
|
||||||
mails=mails, webhook=webhook)
|
mails=mails, webhook=webhook)
|
||||||
|
|
||||||
def _re_create_tracker(tracker_type, tracker_uuid, to_track, user_id, level, description=None, filters={}, tags=[], mails=[], webhook=None, first_seen=None, last_seen=None):
|
def _re_create_tracker(tracker_type, tracker_uuid, to_track, org, user_id, level, description=None, filters={}, tags=[], mails=[], webhook=None, first_seen=None, last_seen=None):
|
||||||
create_tracker(tracker_type, to_track, user_id, level, description=description, filters=filters,
|
create_tracker(tracker_type, to_track, org, user_id, level, description=description, filters=filters,
|
||||||
tags=tags, mails=mails, webhook=webhook, tracker_uuid=tracker_uuid)
|
tags=tags, mails=mails, webhook=webhook, tracker_uuid=tracker_uuid)
|
||||||
|
|
||||||
def get_trackers_types():
|
def get_trackers_types():
|
||||||
|
@ -649,6 +677,12 @@ def get_user_trackers(user_id, tracker_type=None):
|
||||||
else:
|
else:
|
||||||
return r_tracker.smembers(f'user:tracker:{user_id}')
|
return r_tracker.smembers(f'user:tracker:{user_id}')
|
||||||
|
|
||||||
|
def get_org_trackers(org, tracker_type=None):
|
||||||
|
if tracker_type:
|
||||||
|
return r_tracker.smembers(f'org:tracker:{org}:{tracker_type}')
|
||||||
|
else:
|
||||||
|
return r_tracker.smembers(f'org:tracker:{org}')
|
||||||
|
|
||||||
def get_nb_global_trackers(tracker_type=None):
|
def get_nb_global_trackers(tracker_type=None):
|
||||||
if tracker_type:
|
if tracker_type:
|
||||||
return r_tracker.scard(f'global:tracker:{tracker_type}')
|
return r_tracker.scard(f'global:tracker:{tracker_type}')
|
||||||
|
@ -661,6 +695,13 @@ def get_nb_user_trackers(user_id, tracker_type=None):
|
||||||
else:
|
else:
|
||||||
return r_tracker.scard(f'user:tracker:{user_id}')
|
return r_tracker.scard(f'user:tracker:{user_id}')
|
||||||
|
|
||||||
|
def get_nb_org_trackers(org, tracker_type=None):
|
||||||
|
if tracker_type:
|
||||||
|
return r_tracker.scard(f'org:tracker:{org}:{tracker_type}')
|
||||||
|
else:
|
||||||
|
return r_tracker.scard(f'org:tracker:{org}')
|
||||||
|
|
||||||
|
|
||||||
def get_user_trackers_meta(user_id, tracker_type=None):
|
def get_user_trackers_meta(user_id, tracker_type=None):
|
||||||
metas = []
|
metas = []
|
||||||
for tracker_uuid in get_user_trackers(user_id, tracker_type=tracker_type):
|
for tracker_uuid in get_user_trackers(user_id, tracker_type=tracker_type):
|
||||||
|
@ -675,6 +716,13 @@ def get_global_trackers_meta(tracker_type=None):
|
||||||
metas.append(tracker.get_meta(options={'description', 'mails', 'sparkline', 'tags'}))
|
metas.append(tracker.get_meta(options={'description', 'mails', 'sparkline', 'tags'}))
|
||||||
return metas
|
return metas
|
||||||
|
|
||||||
|
def get_org_trackers_meta(user_org, tracker_type=None):
|
||||||
|
metas = []
|
||||||
|
for tracker_uuid in get_org_trackers(user_org, tracker_type=tracker_type):
|
||||||
|
tracker = Tracker(tracker_uuid)
|
||||||
|
metas.append(tracker.get_meta(options={'description', 'mails', 'sparkline', 'tags'}))
|
||||||
|
return metas
|
||||||
|
|
||||||
def get_users_trackers_meta():
|
def get_users_trackers_meta():
|
||||||
trackers = []
|
trackers = []
|
||||||
for tracker_uuid in get_trackers():
|
for tracker_uuid in get_trackers():
|
||||||
|
@ -683,6 +731,14 @@ def get_users_trackers_meta():
|
||||||
trackers.append(tracker.get_meta(options={'mails', 'sparkline', 'tags'}))
|
trackers.append(tracker.get_meta(options={'mails', 'sparkline', 'tags'}))
|
||||||
return trackers
|
return trackers
|
||||||
|
|
||||||
|
def get_orgs_trackers_meta():
|
||||||
|
trackers = []
|
||||||
|
for tracker_uuid in get_trackers():
|
||||||
|
tracker = Tracker(tracker_uuid)
|
||||||
|
if tracker.is_level_org():
|
||||||
|
trackers.append(tracker.get_meta(options={'mails', 'sparkline', 'tags'}))
|
||||||
|
return trackers
|
||||||
|
|
||||||
def get_trackers_graph_by_day(l_trackers, num_day=31, date_from=None, date_to=None):
|
def get_trackers_graph_by_day(l_trackers, num_day=31, date_from=None, date_to=None):
|
||||||
if date_from and date_to:
|
if date_from and date_to:
|
||||||
date_range = Date.substract_date(date_from, date_to)
|
date_range = Date.substract_date(date_from, date_to)
|
||||||
|
@ -725,13 +781,14 @@ def get_user_dashboard(user_id): # TODO SORT + REMOVE OLDER ROWS (trim)
|
||||||
|
|
||||||
return trackers
|
return trackers
|
||||||
|
|
||||||
def get_trackers_stats(user_id):
|
def get_trackers_stats(user_org, user_id):
|
||||||
stats = {'all': 0}
|
stats = {'all': 0}
|
||||||
for tracker_type in get_trackers_types():
|
for tracker_type in get_trackers_types():
|
||||||
nb_global = get_nb_global_trackers(tracker_type=tracker_type)
|
nb_global = get_nb_global_trackers(tracker_type=tracker_type)
|
||||||
nb_user = get_nb_user_trackers(user_id, tracker_type=tracker_type)
|
nb_user = get_nb_user_trackers(user_id, tracker_type=tracker_type)
|
||||||
stats[tracker_type] = nb_global + nb_user
|
nb_org = get_nb_org_trackers(user_org, tracker_type=tracker_type)
|
||||||
stats['all'] += nb_global + nb_user
|
stats[tracker_type] = nb_global + nb_user + nb_org
|
||||||
|
stats['all'] += nb_global + nb_user + nb_org
|
||||||
return stats
|
return stats
|
||||||
|
|
||||||
|
|
||||||
|
@ -789,7 +846,7 @@ def api_check_tracker_uuid(tracker_uuid):
|
||||||
return {"status": "error", "reason": "Unknown uuid"}, 404
|
return {"status": "error", "reason": "Unknown uuid"}, 404
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def api_check_tracker_acl(tracker_uuid, user_id):
|
def api_check_tracker_acl(tracker_uuid, user_org, user_id):
|
||||||
res = api_check_tracker_uuid(tracker_uuid)
|
res = api_check_tracker_uuid(tracker_uuid)
|
||||||
if res:
|
if res:
|
||||||
return res
|
return res
|
||||||
|
@ -797,31 +854,45 @@ def api_check_tracker_acl(tracker_uuid, user_id):
|
||||||
if tracker.is_level_user():
|
if tracker.is_level_user():
|
||||||
if tracker.get_user() != user_id or not AILUser(user_id).is_in_role('admin'):
|
if tracker.get_user() != user_id or not AILUser(user_id).is_in_role('admin'):
|
||||||
return {"status": "error", "reason": "Access Denied"}, 403
|
return {"status": "error", "reason": "Access Denied"}, 403
|
||||||
|
elif tracker.is_level_org():
|
||||||
|
if tracker.get_org() != user_org or not AILUser(user_id).is_in_role('admin'):
|
||||||
|
return {"status": "error", "reason": "Access Denied"}, 403
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def api_is_allowed_to_edit_tracker(tracker_uuid, user_id):
|
def api_is_allowed_to_edit_tracker(tracker_uuid, user_org, user_id):
|
||||||
if not is_valid_uuid_v4(tracker_uuid):
|
res = api_check_tracker_uuid(tracker_uuid)
|
||||||
return {"status": "error", "reason": "Invalid uuid"}, 400
|
if res:
|
||||||
tracker_creator = r_tracker.hget('tracker:{}'.format(tracker_uuid), 'user_id')
|
return res
|
||||||
if not tracker_creator:
|
tracker = Tracker(tracker_uuid)
|
||||||
return {"status": "error", "reason": "Unknown uuid"}, 404
|
if tracker.is_level_user():
|
||||||
user = AILUser(user_id)
|
if tracker.get_user() != user_id or not AILUser(user_id).is_in_role('admin'):
|
||||||
if not user.is_in_role('admin') and user_id != tracker_creator:
|
|
||||||
return {"status": "error", "reason": "Access Denied"}, 403
|
|
||||||
return {"uuid": tracker_uuid}, 200
|
|
||||||
|
|
||||||
|
|
||||||
def api_is_allowed_to_access_tracker(tracker_uuid, user_id):
|
|
||||||
if not is_valid_uuid_v4(tracker_uuid):
|
|
||||||
return {"status": "error", "reason": "Invalid uuid"}, 400
|
|
||||||
tracker_creator = r_tracker.hget('tracker:{}'.format(tracker_uuid), 'user_id')
|
|
||||||
if not tracker_creator:
|
|
||||||
return {"status": "error", "reason": "Unknown uuid"}, 404
|
|
||||||
user = AILUser(user_id)
|
|
||||||
if not is_tracker_global_level(tracker_uuid):
|
|
||||||
if not user.is_in_role('admin') and user_id != tracker_creator:
|
|
||||||
return {"status": "error", "reason": "Access Denied"}, 403
|
return {"status": "error", "reason": "Access Denied"}, 403
|
||||||
return {"uuid": tracker_uuid}, 200
|
elif tracker.is_level_org():
|
||||||
|
if tracker.get_org() != user_org or not AILUser(user_id).is_in_role('admin'):
|
||||||
|
return {"status": "error", "reason": "Access Denied"}, 403
|
||||||
|
else: # global
|
||||||
|
if tracker.get_user() != user_id or not AILUser(user_id).is_in_role('admin'):
|
||||||
|
return {"status": "error", "reason": "Access Denied"}, 403
|
||||||
|
return None
|
||||||
|
|
||||||
|
def api_is_allowed_to_edit_tracker_level(tracker_uuid, user_org, user_id, new_level):
|
||||||
|
tracker = Tracker(tracker_uuid)
|
||||||
|
level = tracker.get_level()
|
||||||
|
if level == new_level:
|
||||||
|
return None
|
||||||
|
# Global Edit
|
||||||
|
if level == 1:
|
||||||
|
if new_level == 0:
|
||||||
|
if tracker.get_user() != user_id or not AILUser(user_id).is_in_role('admin'):
|
||||||
|
return {"status": "error", "reason": "Access Denied"}, 403
|
||||||
|
elif new_level == 2:
|
||||||
|
if tracker.get_org() != user_org or not AILUser(user_id).is_in_role('admin'):
|
||||||
|
return {"status": "error", "reason": "Access Denied"}, 403
|
||||||
|
# Community Edit
|
||||||
|
elif level == 2:
|
||||||
|
if new_level == 0:
|
||||||
|
if tracker.get_user() != user_id or not AILUser(user_id).is_in_role('admin'):
|
||||||
|
return {"status": "error", "reason": "Access Denied"}, 403
|
||||||
|
|
||||||
##-- ACL --##
|
##-- ACL --##
|
||||||
|
|
||||||
|
@ -922,7 +993,7 @@ def api_validate_tracker_to_add(to_track, tracker_type, nb_words=1):
|
||||||
return {"status": "error", "reason": "Incorrect type"}, 400
|
return {"status": "error", "reason": "Incorrect type"}, 400
|
||||||
return {"status": "success", "tracked": to_track, "type": tracker_type}, 200
|
return {"status": "success", "tracked": to_track, "type": tracker_type}, 200
|
||||||
|
|
||||||
def api_add_tracker(dict_input, user_id):
|
def api_add_tracker(dict_input, org, user_id):
|
||||||
to_track = dict_input.get('tracked', None)
|
to_track = dict_input.get('tracked', None)
|
||||||
if not to_track:
|
if not to_track:
|
||||||
return {"status": "error", "reason": "Tracker not provided"}, 400
|
return {"status": "error", "reason": "Tracker not provided"}, 400
|
||||||
|
@ -982,17 +1053,17 @@ def api_add_tracker(dict_input, user_id):
|
||||||
level = int(level)
|
level = int(level)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
level = 1
|
level = 1
|
||||||
if level not in range(0, 1):
|
if level not in range(0, 3):
|
||||||
level = 1
|
level = 1
|
||||||
|
|
||||||
tracker_uuid = create_tracker(tracker_type, to_track, user_id, level, description=description, filters=filters,
|
tracker_uuid = create_tracker(tracker_type, to_track, org, user_id, level, description=description, filters=filters,
|
||||||
tags=tags, mails=mails, webhook=webhook)
|
tags=tags, mails=mails, webhook=webhook)
|
||||||
|
|
||||||
return {'tracked': to_track, 'type': tracker_type, 'uuid': tracker_uuid}, 200
|
return {'tracked': to_track, 'type': tracker_type, 'uuid': tracker_uuid}, 200
|
||||||
|
|
||||||
def api_edit_tracker(dict_input, user_id):
|
def api_edit_tracker(dict_input, user_org, user_id):
|
||||||
tracker_uuid = dict_input.get('uuid')
|
tracker_uuid = dict_input.get('uuid')
|
||||||
res = api_check_tracker_acl(tracker_uuid, user_id)
|
res = api_check_tracker_acl(tracker_uuid, user_org, user_id)
|
||||||
if res:
|
if res:
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
@ -1004,6 +1075,18 @@ def api_edit_tracker(dict_input, user_id):
|
||||||
tracker_type = dict_input.get('type', None)
|
tracker_type = dict_input.get('type', None)
|
||||||
if not tracker_type:
|
if not tracker_type:
|
||||||
return {"status": "error", "reason": "Tracker type not provided"}, 400
|
return {"status": "error", "reason": "Tracker type not provided"}, 400
|
||||||
|
|
||||||
|
level = dict_input.get('level', 1)
|
||||||
|
try:
|
||||||
|
level = int(level)
|
||||||
|
except TypeError:
|
||||||
|
level = 1
|
||||||
|
if level not in range(0, 3):
|
||||||
|
level = 1
|
||||||
|
res = api_is_allowed_to_edit_tracker_level(tracker_uuid, user_org, user_id, level)
|
||||||
|
if res:
|
||||||
|
return res
|
||||||
|
|
||||||
nb_words = dict_input.get('nb_words', 1)
|
nb_words = dict_input.get('nb_words', 1)
|
||||||
description = dict_input.get('description', '')
|
description = dict_input.get('description', '')
|
||||||
description = escape(description)
|
description = escape(description)
|
||||||
|
@ -1053,31 +1136,23 @@ def api_edit_tracker(dict_input, user_id):
|
||||||
if subtype not in obj_subtypes:
|
if subtype not in obj_subtypes:
|
||||||
return {"status": "error", "reason": "Invalid Tracker Object subtype"}, 400
|
return {"status": "error", "reason": "Invalid Tracker Object subtype"}, 400
|
||||||
|
|
||||||
level = dict_input.get('level', 1)
|
tracker.edit(tracker_type, to_track, level, user_org, description=description, filters=filters,
|
||||||
try:
|
|
||||||
level = int(level)
|
|
||||||
except TypeError:
|
|
||||||
level = 1
|
|
||||||
if level not in range(0, 1):
|
|
||||||
level = 1
|
|
||||||
|
|
||||||
tracker.edit(tracker_type, to_track, level, description=description, filters=filters,
|
|
||||||
tags=tags, mails=mails, webhook=webhook)
|
tags=tags, mails=mails, webhook=webhook)
|
||||||
return {'tracked': to_track, 'type': tracker_type, 'uuid': tracker_uuid}, 200
|
return {'tracked': to_track, 'type': tracker_type, 'uuid': tracker_uuid}, 200
|
||||||
|
|
||||||
|
|
||||||
def api_delete_tracker(data, user_id):
|
def api_delete_tracker(data, user_org, user_id):
|
||||||
tracker_uuid = data.get('uuid')
|
tracker_uuid = data.get('uuid')
|
||||||
res = api_check_tracker_acl(tracker_uuid, user_id)
|
res = api_check_tracker_acl(tracker_uuid, user_org, user_id)
|
||||||
if res:
|
if res:
|
||||||
return res
|
return res
|
||||||
|
|
||||||
tracker = Tracker(tracker_uuid)
|
tracker = Tracker(tracker_uuid)
|
||||||
return tracker.delete(), 200
|
return tracker.delete(), 200
|
||||||
|
|
||||||
def api_tracker_add_object(data, user_id):
|
def api_tracker_add_object(data, user_org, user_id):
|
||||||
tracker_uuid = data.get('uuid')
|
tracker_uuid = data.get('uuid')
|
||||||
res = api_check_tracker_acl(tracker_uuid, user_id)
|
res = api_check_tracker_acl(tracker_uuid, user_org, user_id)
|
||||||
if res:
|
if res:
|
||||||
return res
|
return res
|
||||||
tracker = Tracker(tracker_uuid)
|
tracker = Tracker(tracker_uuid)
|
||||||
|
@ -1092,9 +1167,9 @@ def api_tracker_add_object(data, user_id):
|
||||||
return {"status": "error", "reason": "Invalid Object"}, 400
|
return {"status": "error", "reason": "Invalid Object"}, 400
|
||||||
return tracker.add(obj_type, subtype, obj_id, date=date), 200
|
return tracker.add(obj_type, subtype, obj_id, date=date), 200
|
||||||
|
|
||||||
def api_tracker_remove_object(data, user_id):
|
def api_tracker_remove_object(data, user_org, user_id):
|
||||||
tracker_uuid = data.get('uuid')
|
tracker_uuid = data.get('uuid')
|
||||||
res = api_check_tracker_acl(tracker_uuid, user_id)
|
res = api_check_tracker_acl(tracker_uuid, user_org, user_id)
|
||||||
if res:
|
if res:
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
@ -1216,7 +1291,6 @@ def get_tracked_yara_rules():
|
||||||
else:
|
else:
|
||||||
rules[tracked] = rule
|
rules[tracked] = rule
|
||||||
to_track[obj_type] = yara.compile(filepaths=rules)
|
to_track[obj_type] = yara.compile(filepaths=rules)
|
||||||
print(to_track)
|
|
||||||
return to_track
|
return to_track
|
||||||
|
|
||||||
def reload_yara_rules():
|
def reload_yara_rules():
|
||||||
|
|
|
@ -20,8 +20,10 @@ 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.ConfigLoader import ConfigLoader
|
from lib.ConfigLoader import ConfigLoader
|
||||||
|
|
||||||
|
|
||||||
# LOGS
|
# LOGS
|
||||||
|
|
||||||
access_logger = ail_logger.get_access_config()
|
access_logger = ail_logger.get_access_config()
|
||||||
|
@ -40,6 +42,145 @@ 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():
|
||||||
|
@ -266,6 +407,9 @@ def get_user_role(user_id):
|
||||||
def exists_user(user_id):
|
def exists_user(user_id):
|
||||||
return r_serv_db.exists(f'ail:user:metadata:{user_id}')
|
return r_serv_db.exists(f'ail:user:metadata:{user_id}')
|
||||||
|
|
||||||
|
def get_user_org(user_id):
|
||||||
|
return r_serv_db.hget(f'ail:user:metadata:{user_id}', 'org')
|
||||||
|
|
||||||
def get_user_creator(user_id):
|
def get_user_creator(user_id):
|
||||||
return r_serv_db.hget(f'ail:user:metadata:{user_id}', 'creator')
|
return r_serv_db.hget(f'ail:user:metadata:{user_id}', 'creator')
|
||||||
|
|
||||||
|
@ -409,6 +553,9 @@ class AILUser(UserMixin):
|
||||||
def update_last_login(self):
|
def update_last_login(self):
|
||||||
r_serv_db.hset(f'ail:user:metadata:{self.user_id}', 'last_login', datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S'))
|
r_serv_db.hset(f'ail:user:metadata:{self.user_id}', 'last_login', datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S'))
|
||||||
|
|
||||||
|
def get_org(self):
|
||||||
|
return get_user_org(self.user_id)
|
||||||
|
|
||||||
def get_meta(self, options=set()):
|
def get_meta(self, options=set()):
|
||||||
meta = {'id': self.user_id}
|
meta = {'id': self.user_id}
|
||||||
if 'creator' in options:
|
if 'creator' in options:
|
||||||
|
@ -435,6 +582,8 @@ class AILUser(UserMixin):
|
||||||
meta['is_disabled'] = self.is_disabled()
|
meta['is_disabled'] = self.is_disabled()
|
||||||
if 'is_logged' in options:
|
if 'is_logged' in options:
|
||||||
meta['is_logged'] = is_user_logged(self.user_id)
|
meta['is_logged'] = is_user_logged(self.user_id)
|
||||||
|
if 'org' in options:
|
||||||
|
meta['org'] = self.get_org()
|
||||||
return meta
|
return meta
|
||||||
|
|
||||||
## SESSION ##
|
## SESSION ##
|
||||||
|
@ -549,6 +698,33 @@ 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'}
|
||||||
|
|
|
@ -220,7 +220,7 @@ def trackers_migration():
|
||||||
print('TRACKERS MIGRATION...')
|
print('TRACKERS MIGRATION...')
|
||||||
for tracker_uuid in old_Tracker.get_all_tracker_uuid():
|
for tracker_uuid in old_Tracker.get_all_tracker_uuid():
|
||||||
meta = get_tracker_metadata(tracker_uuid)
|
meta = get_tracker_metadata(tracker_uuid)
|
||||||
Tracker._re_create_tracker(meta['type'], meta['uuid'], meta['tracked'], meta['user_id'], meta['level'],
|
Tracker._re_create_tracker(meta['type'], meta['uuid'], meta['tracked'], 'TEST_ORG', meta['user_id'], meta['level'],
|
||||||
tags=meta['tags'], mails=meta['mails'], description=meta['description'],
|
tags=meta['tags'], mails=meta['mails'], description=meta['description'],
|
||||||
webhook=meta['webhook'], sources=meta['sources'],
|
webhook=meta['webhook'], sources=meta['sources'],
|
||||||
first_seen=meta['first_seen'], last_seen=meta['last_seen'])
|
first_seen=meta['first_seen'], last_seen=meta['last_seen'])
|
||||||
|
|
|
@ -9,7 +9,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from flask import render_template, jsonify, request, Blueprint, redirect, url_for, Response, abort
|
from flask import render_template, jsonify, request, Blueprint, redirect, url_for, Response
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
|
|
||||||
sys.path.append('modules')
|
sys.path.append('modules')
|
||||||
|
@ -67,7 +67,7 @@ def get_default_yara_rule_content():
|
||||||
def trackers_dashboard():
|
def trackers_dashboard():
|
||||||
user_id = current_user.get_user_id()
|
user_id = current_user.get_user_id()
|
||||||
trackers = Tracker.get_trackers_dashboard()
|
trackers = Tracker.get_trackers_dashboard()
|
||||||
stats = Tracker.get_trackers_stats(user_id)
|
stats = Tracker.get_trackers_stats(current_user.get_org(), user_id)
|
||||||
return render_template("trackers_dashboard.html", trackers=trackers, stats=stats, bootstrap_label=bootstrap_label)
|
return render_template("trackers_dashboard.html", trackers=trackers, stats=stats, bootstrap_label=bootstrap_label)
|
||||||
|
|
||||||
@hunters.route("/trackers/all")
|
@hunters.route("/trackers/all")
|
||||||
|
@ -75,9 +75,10 @@ def trackers_dashboard():
|
||||||
@login_read_only
|
@login_read_only
|
||||||
def tracked_menu():
|
def tracked_menu():
|
||||||
user_id = current_user.get_user_id()
|
user_id = current_user.get_user_id()
|
||||||
|
org_trackers = Tracker.get_org_trackers_meta(current_user.get_org())
|
||||||
user_trackers = Tracker.get_user_trackers_meta(user_id)
|
user_trackers = Tracker.get_user_trackers_meta(user_id)
|
||||||
global_trackers = Tracker.get_global_trackers_meta()
|
global_trackers = Tracker.get_global_trackers_meta()
|
||||||
return render_template("trackersManagement.html", user_trackers=user_trackers, global_trackers=global_trackers, bootstrap_label=bootstrap_label)
|
return render_template("trackersManagement.html", user_trackers=user_trackers, org_trackers=org_trackers, global_trackers=global_trackers, bootstrap_label=bootstrap_label)
|
||||||
|
|
||||||
@hunters.route("/trackers/word")
|
@hunters.route("/trackers/word")
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -85,9 +86,10 @@ def tracked_menu():
|
||||||
def tracked_menu_word():
|
def tracked_menu_word():
|
||||||
tracker_type = 'word'
|
tracker_type = 'word'
|
||||||
user_id = current_user.get_user_id()
|
user_id = current_user.get_user_id()
|
||||||
|
org_trackers = Tracker.get_org_trackers_meta(current_user.get_org(), tracker_type='word')
|
||||||
user_trackers = Tracker.get_user_trackers_meta(user_id, tracker_type='word')
|
user_trackers = Tracker.get_user_trackers_meta(user_id, tracker_type='word')
|
||||||
global_trackers = Tracker.get_global_trackers_meta(tracker_type='word')
|
global_trackers = Tracker.get_global_trackers_meta(tracker_type='word')
|
||||||
return render_template("trackersManagement.html", user_trackers=user_trackers, global_trackers=global_trackers, bootstrap_label=bootstrap_label, tracker_type=tracker_type)
|
return render_template("trackersManagement.html", user_trackers=user_trackers, org_trackers=org_trackers, global_trackers=global_trackers, bootstrap_label=bootstrap_label, tracker_type=tracker_type)
|
||||||
|
|
||||||
@hunters.route("/trackers/set")
|
@hunters.route("/trackers/set")
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -95,9 +97,10 @@ def tracked_menu_word():
|
||||||
def tracked_menu_set():
|
def tracked_menu_set():
|
||||||
tracker_type = 'set'
|
tracker_type = 'set'
|
||||||
user_id = current_user.get_user_id()
|
user_id = current_user.get_user_id()
|
||||||
|
org_trackers = Tracker.get_org_trackers_meta(current_user.get_org(), tracker_type=tracker_type)
|
||||||
user_trackers = Tracker.get_user_trackers_meta(user_id, tracker_type=tracker_type)
|
user_trackers = Tracker.get_user_trackers_meta(user_id, tracker_type=tracker_type)
|
||||||
global_trackers = Tracker.get_global_trackers_meta(tracker_type=tracker_type)
|
global_trackers = Tracker.get_global_trackers_meta(tracker_type=tracker_type)
|
||||||
return render_template("trackersManagement.html", user_trackers=user_trackers, global_trackers=global_trackers, bootstrap_label=bootstrap_label, tracker_type=tracker_type)
|
return render_template("trackersManagement.html", user_trackers=user_trackers, org_trackers=org_trackers, global_trackers=global_trackers, bootstrap_label=bootstrap_label, tracker_type=tracker_type)
|
||||||
|
|
||||||
@hunters.route("/trackers/regex")
|
@hunters.route("/trackers/regex")
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -105,9 +108,10 @@ def tracked_menu_set():
|
||||||
def tracked_menu_regex():
|
def tracked_menu_regex():
|
||||||
tracker_type = 'regex'
|
tracker_type = 'regex'
|
||||||
user_id = current_user.get_user_id()
|
user_id = current_user.get_user_id()
|
||||||
|
org_trackers = Tracker.get_org_trackers_meta(current_user.get_org(), tracker_type=tracker_type)
|
||||||
user_trackers = Tracker.get_user_trackers_meta(user_id, tracker_type=tracker_type)
|
user_trackers = Tracker.get_user_trackers_meta(user_id, tracker_type=tracker_type)
|
||||||
global_trackers = Tracker.get_global_trackers_meta(tracker_type=tracker_type)
|
global_trackers = Tracker.get_global_trackers_meta(tracker_type=tracker_type)
|
||||||
return render_template("trackersManagement.html", user_trackers=user_trackers, global_trackers=global_trackers, bootstrap_label=bootstrap_label, tracker_type=tracker_type)
|
return render_template("trackersManagement.html", user_trackers=user_trackers, org_trackers=org_trackers, global_trackers=global_trackers, bootstrap_label=bootstrap_label, tracker_type=tracker_type)
|
||||||
|
|
||||||
@hunters.route("/trackers/yara")
|
@hunters.route("/trackers/yara")
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -115,9 +119,10 @@ def tracked_menu_regex():
|
||||||
def tracked_menu_yara():
|
def tracked_menu_yara():
|
||||||
tracker_type = 'yara'
|
tracker_type = 'yara'
|
||||||
user_id = current_user.get_user_id()
|
user_id = current_user.get_user_id()
|
||||||
|
org_trackers = Tracker.get_org_trackers_meta(current_user.get_org(), tracker_type=tracker_type)
|
||||||
user_trackers = Tracker.get_user_trackers_meta(user_id, tracker_type=tracker_type)
|
user_trackers = Tracker.get_user_trackers_meta(user_id, tracker_type=tracker_type)
|
||||||
global_trackers = Tracker.get_global_trackers_meta(tracker_type=tracker_type)
|
global_trackers = Tracker.get_global_trackers_meta(tracker_type=tracker_type)
|
||||||
return render_template("trackersManagement.html", user_trackers=user_trackers, global_trackers=global_trackers, bootstrap_label=bootstrap_label, tracker_type=tracker_type)
|
return render_template("trackersManagement.html", user_trackers=user_trackers, org_trackers=org_trackers, global_trackers=global_trackers, bootstrap_label=bootstrap_label, tracker_type=tracker_type)
|
||||||
|
|
||||||
@hunters.route("/trackers/typosquatting")
|
@hunters.route("/trackers/typosquatting")
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -125,17 +130,19 @@ def tracked_menu_yara():
|
||||||
def tracked_menu_typosquatting():
|
def tracked_menu_typosquatting():
|
||||||
tracker_type = 'typosquatting'
|
tracker_type = 'typosquatting'
|
||||||
user_id = current_user.get_user_id()
|
user_id = current_user.get_user_id()
|
||||||
|
org_trackers = Tracker.get_org_trackers_meta(current_user.get_org(), tracker_type=tracker_type)
|
||||||
user_trackers = Tracker.get_user_trackers_meta(user_id, tracker_type=tracker_type)
|
user_trackers = Tracker.get_user_trackers_meta(user_id, tracker_type=tracker_type)
|
||||||
global_trackers = Tracker.get_global_trackers_meta(tracker_type=tracker_type)
|
global_trackers = Tracker.get_global_trackers_meta(tracker_type=tracker_type)
|
||||||
return render_template("trackersManagement.html", user_trackers=user_trackers, global_trackers=global_trackers,
|
return render_template("trackersManagement.html", user_trackers=user_trackers, org_trackers=org_trackers, global_trackers=global_trackers,
|
||||||
bootstrap_label=bootstrap_label, tracker_type=tracker_type)
|
bootstrap_label=bootstrap_label, tracker_type=tracker_type)
|
||||||
|
|
||||||
@hunters.route("/trackers/admin")
|
@hunters.route("/trackers/admin")
|
||||||
@login_required
|
@login_required
|
||||||
@login_admin
|
@login_admin
|
||||||
def tracked_menu_admin():
|
def tracked_menu_admin():
|
||||||
|
org_trackers = Tracker.get_orgs_trackers_meta()
|
||||||
user_trackers = Tracker.get_users_trackers_meta()
|
user_trackers = Tracker.get_users_trackers_meta()
|
||||||
return render_template("trackersManagement.html", user_trackers=user_trackers, global_trackers=[],
|
return render_template("trackersManagement.html", user_trackers=user_trackers, org_trackers=org_trackers, global_trackers=[],
|
||||||
bootstrap_label=bootstrap_label)
|
bootstrap_label=bootstrap_label)
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,8 +152,8 @@ def tracked_menu_admin():
|
||||||
def show_tracker():
|
def show_tracker():
|
||||||
user_id = current_user.get_user_id()
|
user_id = current_user.get_user_id()
|
||||||
tracker_uuid = request.args.get('uuid', None)
|
tracker_uuid = request.args.get('uuid', None)
|
||||||
res = Tracker.api_is_allowed_to_access_tracker(tracker_uuid, user_id)
|
res = Tracker.api_check_tracker_acl(tracker_uuid, current_user.get_org(), user_id)
|
||||||
if res[1] != 200: # invalid access
|
if res: # invalid access
|
||||||
return Response(json.dumps(res[0], indent=2, sort_keys=True), mimetype='application/json'), res[1]
|
return Response(json.dumps(res[0], indent=2, sort_keys=True), mimetype='application/json'), res[1]
|
||||||
|
|
||||||
date_from = request.args.get('date_from')
|
date_from = request.args.get('date_from')
|
||||||
|
@ -241,10 +248,7 @@ def parse_add_edit_request(request_form):
|
||||||
to_track = yara_default_rule
|
to_track = yara_default_rule
|
||||||
tracker_type = 'yara_default'
|
tracker_type = 'yara_default'
|
||||||
|
|
||||||
if level == 'on':
|
level = int(level)
|
||||||
level = 1
|
|
||||||
else:
|
|
||||||
level = 0
|
|
||||||
if mails:
|
if mails:
|
||||||
mails = mails.split()
|
mails = mails.split()
|
||||||
else:
|
else:
|
||||||
|
@ -293,7 +297,8 @@ def add_tracked_menu():
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
input_dict = parse_add_edit_request(request.form)
|
input_dict = parse_add_edit_request(request.form)
|
||||||
user_id = current_user.get_user_id()
|
user_id = current_user.get_user_id()
|
||||||
res = Tracker.api_add_tracker(input_dict, user_id)
|
org = current_user.get_org()
|
||||||
|
res = Tracker.api_add_tracker(input_dict, org, user_id)
|
||||||
if res[1] == 200:
|
if res[1] == 200:
|
||||||
return redirect(url_for('hunters.trackers_dashboard'))
|
return redirect(url_for('hunters.trackers_dashboard'))
|
||||||
else:
|
else:
|
||||||
|
@ -309,19 +314,19 @@ def add_tracked_menu():
|
||||||
@login_required
|
@login_required
|
||||||
@login_analyst
|
@login_analyst
|
||||||
def tracker_edit():
|
def tracker_edit():
|
||||||
|
user_id = current_user.get_user_id()
|
||||||
|
user_org = current_user.get_org()
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
input_dict = parse_add_edit_request(request.form)
|
input_dict = parse_add_edit_request(request.form)
|
||||||
user_id = current_user.get_user_id()
|
res = Tracker.api_edit_tracker(input_dict, user_org, user_id)
|
||||||
res = Tracker.api_edit_tracker(input_dict, user_id)
|
|
||||||
if res[1] == 200:
|
if res[1] == 200:
|
||||||
return redirect(url_for('hunters.show_tracker', uuid=res[0].get('uuid')))
|
return redirect(url_for('hunters.show_tracker', uuid=res[0].get('uuid')))
|
||||||
else:
|
else:
|
||||||
return create_json_response(res[0], res[1])
|
return create_json_response(res[0], res[1])
|
||||||
else:
|
else:
|
||||||
user_id = current_user.get_user_id()
|
|
||||||
tracker_uuid = request.args.get('uuid', None)
|
tracker_uuid = request.args.get('uuid', None)
|
||||||
res = Tracker.api_is_allowed_to_edit_tracker(tracker_uuid, user_id)
|
res = Tracker.api_is_allowed_to_edit_tracker(tracker_uuid, user_org, user_id)
|
||||||
if res[1] != 200: # invalid access
|
if res: # invalid access
|
||||||
return Response(json.dumps(res[0], indent=2, sort_keys=True), mimetype='application/json'), res[1]
|
return Response(json.dumps(res[0], indent=2, sort_keys=True), mimetype='application/json'), res[1]
|
||||||
|
|
||||||
tracker = Tracker.Tracker(tracker_uuid)
|
tracker = Tracker.Tracker(tracker_uuid)
|
||||||
|
@ -352,7 +357,7 @@ def tracker_edit():
|
||||||
def tracker_delete():
|
def tracker_delete():
|
||||||
user_id = current_user.get_user_id()
|
user_id = current_user.get_user_id()
|
||||||
tracker_uuid = request.args.get('uuid')
|
tracker_uuid = request.args.get('uuid')
|
||||||
res = Tracker.api_delete_tracker({'uuid': tracker_uuid}, user_id)
|
res = Tracker.api_delete_tracker({'uuid': tracker_uuid}, current_user.get_org(), user_id)
|
||||||
if res[1] != 200:
|
if res[1] != 200:
|
||||||
return create_json_response(res[0], res[1])
|
return create_json_response(res[0], res[1])
|
||||||
else:
|
else:
|
||||||
|
@ -365,7 +370,7 @@ def tracker_delete():
|
||||||
def get_json_tracker_graph():
|
def get_json_tracker_graph():
|
||||||
user_id = current_user.get_user_id()
|
user_id = current_user.get_user_id()
|
||||||
tracker_uuid = request.args.get('uuid')
|
tracker_uuid = request.args.get('uuid')
|
||||||
res = Tracker.api_check_tracker_acl(tracker_uuid, user_id)
|
res = Tracker.api_check_tracker_acl(tracker_uuid, current_user.get_org(), user_id)
|
||||||
if res:
|
if res:
|
||||||
return create_json_response(res[0], res[1])
|
return create_json_response(res[0], res[1])
|
||||||
|
|
||||||
|
@ -394,7 +399,7 @@ def tracker_object_add():
|
||||||
date = obj.get_date()
|
date = obj.get_date()
|
||||||
else:
|
else:
|
||||||
date = request.args.get('date') # TODO check daterange
|
date = request.args.get('date') # TODO check daterange
|
||||||
res = Tracker.api_tracker_add_object({'uuid': tracker_uuid, 'gid': object_global_id, 'date': date}, user_id)
|
res = Tracker.api_tracker_add_object({'uuid': tracker_uuid, 'gid': object_global_id, 'date': date}, current_user.get_org(), user_id)
|
||||||
if res[1] != 200:
|
if res[1] != 200:
|
||||||
return create_json_response(res[0], res[1])
|
return create_json_response(res[0], res[1])
|
||||||
else:
|
else:
|
||||||
|
@ -410,7 +415,7 @@ def tracker_object_remove():
|
||||||
user_id = current_user.get_user_id()
|
user_id = current_user.get_user_id()
|
||||||
tracker_uuid = request.args.get('uuid')
|
tracker_uuid = request.args.get('uuid')
|
||||||
object_global_id = request.args.get('gid')
|
object_global_id = request.args.get('gid')
|
||||||
res = Tracker.api_tracker_remove_object({'uuid': tracker_uuid, 'gid': object_global_id}, user_id)
|
res = Tracker.api_tracker_remove_object({'uuid': tracker_uuid, 'gid': object_global_id}, current_user.get_org(), user_id)
|
||||||
if res[1] != 200:
|
if res[1] != 200:
|
||||||
return create_json_response(res[0], res[1])
|
return create_json_response(res[0], res[1])
|
||||||
else:
|
else:
|
||||||
|
@ -426,8 +431,8 @@ def tracker_object_remove():
|
||||||
def tracker_objects():
|
def tracker_objects():
|
||||||
user_id = current_user.get_user_id()
|
user_id = current_user.get_user_id()
|
||||||
tracker_uuid = request.args.get('uuid', None)
|
tracker_uuid = request.args.get('uuid', None)
|
||||||
res = Tracker.api_is_allowed_to_edit_tracker(tracker_uuid, user_id)
|
res = Tracker.api_is_allowed_to_edit_tracker(tracker_uuid, current_user.get_org(), user_id)
|
||||||
if res[1] != 200: # invalid access
|
if res: # invalid access
|
||||||
return Response(json.dumps(res[0], indent=2, sort_keys=True), mimetype='application/json'), res[1]
|
return Response(json.dumps(res[0], indent=2, sort_keys=True), mimetype='application/json'), res[1]
|
||||||
|
|
||||||
tracker = Tracker.Tracker(tracker_uuid)
|
tracker = Tracker.Tracker(tracker_uuid)
|
||||||
|
|
|
@ -303,6 +303,56 @@ def users_list():
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
|
|
||||||
|
@settings_b.route("/settings/organisations", methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
@login_admin
|
||||||
|
def organisations_list():
|
||||||
|
meta = ail_users.api_get_orgs_meta()
|
||||||
|
return render_template("orgs_list.html", meta=meta, acl_admin=True)
|
||||||
|
|
||||||
|
@settings_b.route("/settings/create_organisation", methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
@login_admin
|
||||||
|
def create_organisation():
|
||||||
|
meta = {}
|
||||||
|
return render_template("create_org.html", meta=meta, error_mail=False, acl_admin=True)
|
||||||
|
|
||||||
|
@settings_b.route("/settings/create_org_post", methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
@login_admin
|
||||||
|
def create_org_post():
|
||||||
|
# Admin ID
|
||||||
|
admin_id = current_user.get_user_id()
|
||||||
|
|
||||||
|
org_uuid = request.form.get('uuid')
|
||||||
|
name = request.form.get('name')
|
||||||
|
description = request.form.get('description')
|
||||||
|
|
||||||
|
r = ail_users.api_create_org(admin_id, org_uuid, name, request.remote_addr, description=description)
|
||||||
|
if r[1] != 200:
|
||||||
|
return create_json_response(r[0], r[1])
|
||||||
|
else:
|
||||||
|
return redirect(url_for('settings_b.organisations_list'))
|
||||||
|
|
||||||
|
|
||||||
|
# TODO check if uuid4
|
||||||
|
# TODO check name format + length
|
||||||
|
|
||||||
|
@settings_b.route("/settings/delete_org", methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
@login_admin
|
||||||
|
def delete_org():
|
||||||
|
admin_id = current_user.get_user_id()
|
||||||
|
org_uuid = request.args.get('uuid')
|
||||||
|
r = ail_users.api_delete_org(org_uuid, admin_id, request.remote_addr)
|
||||||
|
if r[1] != 200:
|
||||||
|
return create_json_response(r[0], r[1])
|
||||||
|
else:
|
||||||
|
return redirect(url_for('settings_b.organisations_list'))
|
||||||
|
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
|
||||||
@settings_b.route("/settings/passivedns", methods=['GET'])
|
@settings_b.route("/settings/passivedns", methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
@login_read_only
|
@login_read_only
|
||||||
|
|
|
@ -211,12 +211,20 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-xl-3">
|
<div class="col-12 col-xl-3">
|
||||||
<div class="custom-control custom-switch mt-1">
|
|
||||||
<input class="custom-control-input" type="checkbox" name="level" id="id_level" {%if dict_tracker%}{%if dict_tracker['level']==1%}checked{%endif%}{%else%}checked{%endif%}>
|
<label class="mt-3" for="level_selector">View Level</label>
|
||||||
<label class="custom-control-label" for="id_level">
|
<select class="custom-select" id="level_selector" name="level">
|
||||||
<i class="fas fa-users"></i> Show tracker to all Users
|
{% if dict_tracker %}
|
||||||
</label>
|
<option value="1" {% if dict_tracker['level'] == 1 %}selected{% endif %}><i class="fas fa-users"></i> Global</option>
|
||||||
</div>
|
<option value="2" {% if dict_tracker['level'] == 2 %}selected{% endif %}><i class="fas fa-landmark"></i> My Organisation</option>
|
||||||
|
<option value="0" {% if dict_tracker['level'] == 0 %}selected{% endif %}><i class="fas fa-user"></i> My User</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>
|
||||||
|
<option value="0"><i class="fas fa-user"></i> My User</option>
|
||||||
|
{% endif %}
|
||||||
|
</select>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -119,9 +119,11 @@
|
||||||
<td class="text-right"><b>Level</b></td>
|
<td class="text-right"><b>Level</b></td>
|
||||||
<td>
|
<td>
|
||||||
{% if meta['level'] == 0 %}
|
{% if meta['level'] == 0 %}
|
||||||
Private
|
My User
|
||||||
{% else %}
|
{% elif meta['level'] == 1 %}
|
||||||
Global
|
Global
|
||||||
|
{% elif meta['level'] == 2 %}
|
||||||
|
My Organisation
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -115,6 +115,78 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if org_trackers %}
|
||||||
|
|
||||||
|
<div class="card my-3">
|
||||||
|
<div class="card-header">
|
||||||
|
<h5 class="card-title">Organisation {{ tracker_type }} Trackers</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table id="table_org_trackers" class="table table-striped table-bordered">
|
||||||
|
<thead class="bg-dark text-white">
|
||||||
|
<tr>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Tracker</th>
|
||||||
|
<th>First seen</th>
|
||||||
|
<th>Last seen</th>
|
||||||
|
<th>Emails</th>
|
||||||
|
<th>sparkline</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody style="font-size: 15px;">
|
||||||
|
{% for dict_uuid in org_trackers %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ dict_uuid['type'] }}</td>
|
||||||
|
<td>
|
||||||
|
<span>
|
||||||
|
<a target="_blank" href="{{ url_for('hunters.show_tracker') }}?uuid={{ dict_uuid['uuid'] }}">
|
||||||
|
{% if dict_uuid['tracked'] %}
|
||||||
|
{% if dict_uuid['tracked']|length > 256 %}
|
||||||
|
{{ dict_uuid['tracked'][0:256] }}...
|
||||||
|
{% else %}
|
||||||
|
{{ dict_uuid['tracked'] }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
{% if dict_uuid['description'] %}
|
||||||
|
<div><i>{{ dict_uuid['description'] }}</i></div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{% for tag in dict_uuid['tags'] %}
|
||||||
|
<a href="{{ url_for('tags_ui.get_obj_by_tags') }}?object_type=item<ags={{ tag }}">
|
||||||
|
<span class="badge badge-{{ bootstrap_label[loop.index0 % 5] }} pull-left">{{ tag }}</span>
|
||||||
|
</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if dict_uuid['first_seen'] %}
|
||||||
|
{{ dict_uuid['first_seen'][0:4] }}/{{ dict_uuid['first_seen'][4:6] }}/{{ dict_uuid['first_seen'][6:8] }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if dict_uuid['last_seen'] %}
|
||||||
|
{{ dict_uuid['last_seen'][0:4] }}/{{ dict_uuid['last_seen'][4:6] }}/{{ dict_uuid['last_seen'][6:8] }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% for mail in dict_uuid['mails'] %}
|
||||||
|
{{ mail }}<br>
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
<td id="sparklines_{{ dict_uuid['uuid'] }}" style="text-align:center;"></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="card my-3">
|
<div class="card my-3">
|
||||||
|
@ -203,6 +275,9 @@
|
||||||
{% for dict_uuid in user_trackers %}
|
{% for dict_uuid in user_trackers %}
|
||||||
sparkline("sparklines_{{ dict_uuid['uuid'] }}", {{ dict_uuid['sparkline'] }}, {height: 40});
|
sparkline("sparklines_{{ dict_uuid['uuid'] }}", {{ dict_uuid['sparkline'] }}, {height: 40});
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% for dict_uuid in org_trackers %}
|
||||||
|
sparkline("sparklines_{{ dict_uuid['uuid'] }}", {{ dict_uuid['sparkline'] }}, {height: 40});
|
||||||
|
{% endfor %}
|
||||||
{% for dict_uuid in global_trackers %}
|
{% for dict_uuid in global_trackers %}
|
||||||
sparkline("sparklines_{{ dict_uuid['uuid'] }}", {{ dict_uuid['sparkline'] }}, {height: 40});
|
sparkline("sparklines_{{ dict_uuid['uuid'] }}", {{ dict_uuid['sparkline'] }}, {height: 40});
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -212,6 +287,11 @@
|
||||||
"iDisplayLength": 10,
|
"iDisplayLength": 10,
|
||||||
"order": [[0, "desc"]]
|
"order": [[0, "desc"]]
|
||||||
});
|
});
|
||||||
|
$('#table_org_trackers').DataTable({
|
||||||
|
"aLengthMenu": [[5, 10, 15, -1], [5, 10, 15, "All"]],
|
||||||
|
"iDisplayLength": 10,
|
||||||
|
"order": [[0, "desc"]]
|
||||||
|
});
|
||||||
$('#table_global_trackers').DataTable({
|
$('#table_global_trackers').DataTable({
|
||||||
"aLengthMenu": [[5, 10, 15, -1], [5, 10, 15, "All"]],
|
"aLengthMenu": [[5, 10, 15, -1], [5, 10, 15, "All"]],
|
||||||
"iDisplayLength": 10,
|
"iDisplayLength": 10,
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Create Org - AIL</title>
|
||||||
|
<link rel="icon" href="{{ url_for('static', filename='image/ail-icon.png') }}">
|
||||||
|
|
||||||
|
<!-- Core CSS -->
|
||||||
|
<link href="{{ url_for('static', filename='css/bootstrap4.min.css') }}" rel="stylesheet">
|
||||||
|
<link href="{{ url_for('static', filename='css/font-awesome.min.css') }}" rel="stylesheet">
|
||||||
|
<link href="{{ url_for('static', filename='css/dataTables.bootstrap.min.css') }}" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- JS -->
|
||||||
|
<script src="{{ url_for('static', filename='js/jquery.js')}}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/popper.min.js')}}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/bootstrap4.min.js')}}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/jquery.dataTables.min.js')}}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/dataTables.bootstrap.min.js')}}"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
{% include 'nav_bar.html' %}
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
{% include 'settings/menu_sidebar.html' %}
|
||||||
|
<div class="col-12 col-lg-10" id="core_content">
|
||||||
|
|
||||||
|
<form class="form-signin" action="{{ url_for('settings_b.create_org_post')}}" autocomplete="off" method="post">
|
||||||
|
|
||||||
|
<h1 class="h3 mt-1 mb-3 text-center text-secondary">{% if meta['uuid'] %}Edit{% else %}Create{% endif %} Org</h1>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="inputUUID">UUID:</label>
|
||||||
|
<input class="form-control" type="text" id="inputUUID" name="uuid" placeholder="UUID" autocomplete="off" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="inputName">Name:</label>
|
||||||
|
<input class="form-control" type="text" id="inputName" name="name" placeholder="Name" autocomplete="off" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="inputDescription">Description:</label>
|
||||||
|
<input class="form-control" type="text" id="inputDescription" name="description" placeholder="Description - (optional)" autocomplete="off">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="btn btn-lg btn-primary btn-block mt-3" type="submit">Submit</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
$("#nav_create_org").addClass("active");
|
||||||
|
$("#nav_orgs_management").removeClass("text-muted");
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
function toggle_sidebar(){
|
||||||
|
if($('#nav_menu').is(':visible')){
|
||||||
|
$('#nav_menu').hide();
|
||||||
|
$('#side_menu').removeClass('border-right')
|
||||||
|
$('#side_menu').removeClass('col-lg-2')
|
||||||
|
$('#core_content').removeClass('col-lg-10')
|
||||||
|
}else{
|
||||||
|
$('#nav_menu').show();
|
||||||
|
$('#side_menu').addClass('border-right')
|
||||||
|
$('#side_menu').addClass('col-lg-2')
|
||||||
|
$('#core_content').addClass('col-lg-10')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</html>
|
|
@ -101,6 +101,23 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<h5 class="d-flex text-muted w-100 py-2" id="nav_orgs_management">
|
||||||
|
<span>Organisations</span>
|
||||||
|
</h5>
|
||||||
|
<ul class="nav flex-md-column flex-row navbar-nav justify-content-between w-100">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{url_for('settings_b.organisations_list')}}" id="nav_orgs_list">
|
||||||
|
<i class="fas fa-landmark"></i>
|
||||||
|
<span>Organisations List</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{url_for('settings_b.create_organisation')}}" id="nav_create_org">
|
||||||
|
<i class="fas fa-plus"></i>
|
||||||
|
<span>Create Organisation</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<h5 class="d-flex text-muted w-100" id="nav_doc">
|
<h5 class="d-flex text-muted w-100" id="nav_doc">
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Organisations - AIL</title>
|
||||||
|
<link rel="icon" href="{{ url_for('static', filename='image/ail-icon.png') }}">
|
||||||
|
|
||||||
|
<!-- Core CSS -->
|
||||||
|
<link href="{{ url_for('static', filename='css/bootstrap4.min.css') }}" rel="stylesheet">
|
||||||
|
<link href="{{ url_for('static', filename='css/font-awesome.min.css') }}" rel="stylesheet">
|
||||||
|
<link href="{{ url_for('static', filename='css/dataTables.bootstrap.min.css') }}" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- JS -->
|
||||||
|
<script src="{{ url_for('static', filename='js/jquery.js')}}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/popper.min.js')}}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/bootstrap4.min.js')}}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/jquery.dataTables.min.js')}}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/dataTables.bootstrap.min.js')}}"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
{% include 'nav_bar.html' %}
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
{% include 'settings/menu_sidebar.html' %}
|
||||||
|
<div class="col-12 col-lg-10" id="core_content">
|
||||||
|
|
||||||
|
<h3>AIL Organisations:</h3>
|
||||||
|
<table id="tableorgs" class="table table-hover table-striped">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>uuid</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Created at</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="tbody_last_crawled">
|
||||||
|
{% for org in meta['orgs'] %}
|
||||||
|
<tr>
|
||||||
|
<td>{{org['name']}}</td>
|
||||||
|
<td>{{org['uuid']}}</td>
|
||||||
|
<td>{{org['description']}}</td>
|
||||||
|
<td>
|
||||||
|
{% if org['date_created'] %}
|
||||||
|
{{org['date_created']}}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="d-flex justify-content-start">
|
||||||
|
{# <a class="btn btn-outline-primary ml-3 px-1 py-0" href="{{ url_for('settings_b.edit_user', org_uuid=org['uuid']) }}">#}
|
||||||
|
{# <i class="fas fa-pencil-alt"></i>#}
|
||||||
|
{# </a>#}
|
||||||
|
<a class="btn btn-outline-danger ml-3 px-1 py-0" href="{{ url_for('settings_b.delete_org', uuid=org['uuid']) }}">
|
||||||
|
<i class="fas fa-trash-alt"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
$("#nav_orgs_list").addClass("active");
|
||||||
|
$("#nav_orgs_management").removeClass("text-muted");
|
||||||
|
$('#tableorgs').DataTable({
|
||||||
|
"aLengthMenu": [[5, 10, 15, -1], [5, 10, 15, "All"]],
|
||||||
|
"iDisplayLength": 10,
|
||||||
|
"order": [[ 0, "asc" ]]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function toggle_sidebar(){
|
||||||
|
if($('#nav_menu').is(':visible')){
|
||||||
|
$('#nav_menu').hide();
|
||||||
|
$('#side_menu').removeClass('border-right')
|
||||||
|
$('#side_menu').removeClass('col-lg-2')
|
||||||
|
$('#core_content').removeClass('col-lg-10')
|
||||||
|
}else{
|
||||||
|
$('#nav_menu').show();
|
||||||
|
$('#side_menu').addClass('border-right')
|
||||||
|
$('#side_menu').addClass('col-lg-2')
|
||||||
|
$('#core_content').addClass('col-lg-10')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in New Issue