mirror of
https://github.com/ail-project/ail-framework.git
synced 2024-11-26 15:57:16 +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
|
||||
##################################
|
||||
from lib import ail_core
|
||||
from lib import ail_orgs
|
||||
from lib import ConfigLoader
|
||||
from lib import Tag
|
||||
from lib.exceptions import UpdateInvestigationError
|
||||
|
@ -47,9 +48,6 @@ def sanityze_uuid(UUID):
|
|||
sanityzed_uuid = uuid.UUID(hex=UUID, version=4)
|
||||
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():
|
||||
return str(uuid.uuid4()).replace('-', '')
|
||||
|
||||
|
@ -105,6 +103,42 @@ class Investigation(object):
|
|||
def get_name(self):
|
||||
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):
|
||||
try:
|
||||
return int(r_tracking.hget(f'investigations:data:{self.uuid}', 'threat_level'))
|
||||
|
@ -166,6 +200,8 @@ class Investigation(object):
|
|||
'analysis': analysis,
|
||||
'tags': list(self.get_tags()),
|
||||
'user_creator': self.get_creator_user(),
|
||||
'level': self.get_level(),
|
||||
'org': self.get_org(),
|
||||
'date': self.get_date(),
|
||||
'timestamp': self.get_timestamp(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)
|
||||
|
||||
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
|
||||
r_tracking.srem(f'investigations:user:{self.get_creator_user()}', self.uuid)
|
||||
# metadata
|
||||
r_tracking.delete(f'investigations:data:{self.uuid}')
|
||||
r_tracking.delete(f'investigations:tags:{self.uuid}')
|
||||
r_tracking.delete(f'investigations:misp:{self.uuid}')
|
||||
return self.uuid
|
||||
|
||||
##-- Class --##
|
||||
## -- -- ##
|
||||
|
||||
def get_all_investigations():
|
||||
return r_tracking.smembers('investigations:all')
|
||||
|
@ -285,6 +329,12 @@ def get_all_investigations():
|
|||
def exists_investigation(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
|
||||
def get_user_all_investigations(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
|
||||
|
||||
def _re_create_investagation(investigation_uuid, user_id, 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)
|
||||
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_org, user_id, level, date, name, threat_level, analysis, info, tags=tags, investigation_uuid=investigation_uuid)
|
||||
if timestamp:
|
||||
_set_timestamp(investigation_uuid, timestamp)
|
||||
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: sanitize tags
|
||||
# # 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 not is_valid_uuid_v4(investigation_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()
|
||||
r_tracking.sadd('investigations:all', investigation_uuid)
|
||||
# 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
|
||||
r_tracking.hset(f'investigations:data:{investigation_uuid}', 'creator_org', user_org)
|
||||
r_tracking.hset(f'investigations:data:{investigation_uuid}', 'creator_user', user_id)
|
||||
|
||||
# TODO: limit info + name
|
||||
investigation = Investigation(investigation_uuid)
|
||||
investigation.set_level(level, user_org)
|
||||
|
||||
investigation.set_info(info)
|
||||
#investigation.set_name(name) ##############################################
|
||||
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))
|
||||
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 = []
|
||||
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)
|
||||
name = investigation.get_info()
|
||||
l_investigations.append({"id": investigation_uuid, "name": name})
|
||||
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 ####
|
||||
|
||||
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)
|
||||
if not investigation.exists():
|
||||
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)
|
||||
# objs = []
|
||||
|
@ -392,6 +483,7 @@ def api_get_investigation(investigation_uuid): # TODO check if is UUIDv4
|
|||
# # TODO: SANITYZE Fields
|
||||
# # TODO: Name ?????
|
||||
def api_add_investigation(json_dict):
|
||||
user_org = json_dict.get('user_org')
|
||||
user_id = json_dict.get('user_id')
|
||||
name = json_dict.get('name') ##### mandatory ?
|
||||
name = escape(name)
|
||||
|
@ -401,6 +493,14 @@ def api_add_investigation(json_dict):
|
|||
# # TODO: sanityze 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 = escape(info)
|
||||
info = info[:1000]
|
||||
|
@ -409,13 +509,13 @@ def api_add_investigation(json_dict):
|
|||
return {"status": "error", "reason": "Invalid/Disabled tags"}, 400
|
||||
|
||||
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:
|
||||
return e.message, 400
|
||||
return res, 200
|
||||
|
||||
# # 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(' ', '')
|
||||
if not is_valid_uuid_v4(investigation_uuid):
|
||||
return {"status": "error", "reason": "Invalid Investigation uuid"}, 400
|
||||
|
@ -423,6 +523,9 @@ def api_edit_investigation(json_dict):
|
|||
if not exists_investigation(investigation_uuid):
|
||||
return {"status": "error", "reason": "Investigation not found"}, 404
|
||||
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 = escape(name)
|
||||
|
@ -445,6 +548,17 @@ def api_edit_investigation(json_dict):
|
|||
if not Tag.are_enabled_tags(tags):
|
||||
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_name(name)
|
||||
investigation.set_tags(tags)
|
||||
|
@ -454,7 +568,7 @@ def api_edit_investigation(json_dict):
|
|||
|
||||
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(' ', '')
|
||||
if not is_valid_uuid_v4(investigation_uuid):
|
||||
return {"status": "error", "reason": "Invalid Investigation uuid"}, 400
|
||||
|
@ -462,10 +576,13 @@ def api_delete_investigation(json_dict):
|
|||
if not exists_investigation(investigation_uuid):
|
||||
return {"status": "error", "reason": "Investigation not found"}, 404
|
||||
investigation = Investigation(investigation_uuid)
|
||||
res = api_check_access_acl(investigation, user_org, is_admin=is_admin)
|
||||
if res:
|
||||
return res
|
||||
res = investigation.delete()
|
||||
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(' ', '')
|
||||
if not is_valid_uuid_v4(investigation_uuid):
|
||||
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):
|
||||
return {"status": "error", "reason": f"Investigation not found: {investigation_uuid}"}, 404
|
||||
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(' ', '')
|
||||
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)
|
||||
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(' ', '')
|
||||
if not is_valid_uuid_v4(investigation_uuid):
|
||||
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):
|
||||
return {"status": "error", "reason": f"Investigation not found: {investigation_uuid}"}, 404
|
||||
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(' ', '')
|
||||
subtype = json_dict.get('subtype', '')
|
||||
|
|
|
@ -26,6 +26,10 @@ def is_valid_token(token):
|
|||
def get_user_from_token(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
|
||||
# User without 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
|
||||
##################################
|
||||
from lib import ail_logger
|
||||
from lib.ail_core import is_valid_uuid_v4
|
||||
from lib import ail_orgs
|
||||
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 = 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 ####
|
||||
|
||||
def get_sessions():
|
||||
|
@ -680,6 +541,9 @@ class AILUser(UserMixin):
|
|||
else:
|
||||
return False
|
||||
|
||||
def is_admin(self):
|
||||
return self.is_in_role('admin')
|
||||
|
||||
def get_role(self):
|
||||
return r_serv_db.hget(f'ail:user:metadata:{self.user_id}', 'role')
|
||||
|
||||
|
@ -698,33 +562,6 @@ class AILUser(UserMixin):
|
|||
|
||||
#### 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():
|
||||
meta = {'users': []}
|
||||
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
|
||||
|
||||
from lib.ail_core import get_ail_uuid
|
||||
|
||||
sys.path.append(os.environ['AIL_BIN'])
|
||||
##################################
|
||||
# Import Project packages
|
||||
|
@ -260,7 +262,7 @@ def investigations_migration():
|
|||
for investigation_uuid in old_Investigations.get_all_investigations():
|
||||
old_investigation = old_Investigations.Investigation(investigation_uuid)
|
||||
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'])
|
||||
for dict_obj in old_investigation.get_objects():
|
||||
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 lib import ail_users
|
||||
from lib import Investigations
|
||||
from lib.ConfigLoader import ConfigLoader
|
||||
from lib import chats_viewer
|
||||
|
||||
|
@ -28,11 +29,22 @@ if __name__ == '__main__':
|
|||
config_loader = None
|
||||
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}', 'created_at', 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()
|
||||
|
||||
updater = Updater('v5.7')
|
||||
|
|
|
@ -19,6 +19,7 @@ sys.path.append(os.environ['AIL_BIN'])
|
|||
from lib import ail_api
|
||||
from lib import ail_core
|
||||
from lib import ail_updates
|
||||
from lib import ail_logger
|
||||
from lib import crawlers
|
||||
from lib import chats_viewer
|
||||
|
||||
|
@ -32,6 +33,10 @@ from lib.objects import Titles
|
|||
from importer.FeederImporter import api_add_json_feeder_to_queue
|
||||
|
||||
|
||||
# LOGS
|
||||
# access_logger = ail_logger.get_access_config()
|
||||
|
||||
|
||||
# ============ BLUEPRINT ============
|
||||
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)
|
||||
else:
|
||||
# User Authenticated + In Role
|
||||
# print(funct.__name__)
|
||||
return funct(*args, **kwargs)
|
||||
else:
|
||||
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
|
||||
@token_required('read_only')
|
||||
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])
|
||||
|
||||
# TODO CATCH REDIRECT
|
||||
|
|
|
@ -42,17 +42,27 @@ def create_json_response(data, status_code):
|
|||
@login_required
|
||||
@login_read_only
|
||||
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,
|
||||
investigations=investigations)
|
||||
inv_global=inv_global, inv_org=inv_org)
|
||||
|
||||
|
||||
@investigations_b.route("/investigation", methods=['GET']) ## FIXME: add /view ????
|
||||
@login_required
|
||||
@login_read_only
|
||||
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 = 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)
|
||||
objs = []
|
||||
for obj in investigation.get_objects():
|
||||
|
@ -71,6 +81,8 @@ def show_investigation():
|
|||
def add_investigation():
|
||||
if request.method == 'POST':
|
||||
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")
|
||||
date = request.form.get("investigation_date")
|
||||
threat_level = request.form.get("threat_level")
|
||||
|
@ -93,7 +105,7 @@ def add_investigation():
|
|||
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,
|
||||
"analysis": analysis, "info": info, "tags": tags}
|
||||
res = Investigations.api_add_investigation(input_dict)
|
||||
|
@ -108,10 +120,13 @@ def add_investigation():
|
|||
@investigations_b.route("/investigation/edit", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@login_analyst
|
||||
def edit_investigation():
|
||||
def edit_investigation(): # TODO CHECK ACL
|
||||
if request.method == 'POST':
|
||||
user_org = current_user.get_org()
|
||||
user_id = current_user.get_user_id()
|
||||
is_admin = current_user.is_admin()
|
||||
investigation_uuid = request.form.get("investigation_uuid")
|
||||
level = request.form.get("investigation_level")
|
||||
name = request.form.get("investigation_name")
|
||||
date = request.form.get("investigation_date")
|
||||
threat_level = request.form.get("threat_level")
|
||||
|
@ -135,10 +150,10 @@ def edit_investigation():
|
|||
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,
|
||||
"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:
|
||||
return create_json_response(res[0], res[1])
|
||||
|
||||
|
@ -158,9 +173,12 @@ def edit_investigation():
|
|||
@login_required
|
||||
@login_analyst
|
||||
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')
|
||||
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:
|
||||
return create_json_response(res[0], res[1])
|
||||
return redirect(url_for('investigations_b.investigations_dashboard'))
|
||||
|
@ -169,6 +187,9 @@ def delete_investigation():
|
|||
@login_required
|
||||
@login_read_only
|
||||
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 = investigations_uuid.split(',')
|
||||
|
||||
|
@ -182,7 +203,7 @@ def register_investigation():
|
|||
"type": object_type, "subtype": object_subtype}
|
||||
if 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:
|
||||
return create_json_response(res[0], res[1])
|
||||
return redirect(url_for('investigations_b.investigations_dashboard', uuid=investigation_uuid))
|
||||
|
@ -191,13 +212,16 @@ def register_investigation():
|
|||
@login_required
|
||||
@login_read_only
|
||||
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')
|
||||
object_type = request.args.get('type')
|
||||
object_subtype = request.args.get('subtype')
|
||||
object_id = request.args.get('id')
|
||||
input_dict = {"uuid": investigation_uuid, "id": object_id,
|
||||
"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:
|
||||
return create_json_response(res[0], res[1])
|
||||
return redirect(url_for('investigations_b.show_investigation', uuid=investigation_uuid))
|
||||
|
@ -207,7 +231,7 @@ def unregister_investigation():
|
|||
@login_required
|
||||
@login_read_only
|
||||
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")
|
||||
@login_required
|
||||
|
|
|
@ -20,6 +20,7 @@ sys.path.append(os.environ['AIL_BIN'])
|
|||
# Import Project packages
|
||||
##################################
|
||||
from lib import ail_updates
|
||||
from lib import ail_orgs
|
||||
from lib import ail_users
|
||||
from lib import d4
|
||||
from packages import git_status
|
||||
|
@ -307,7 +308,7 @@ def users_list():
|
|||
@login_required
|
||||
@login_admin
|
||||
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)
|
||||
|
||||
@settings_b.route("/settings/create_organisation", methods=['GET'])
|
||||
|
@ -328,7 +329,7 @@ def create_org_post():
|
|||
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)
|
||||
r = ail_orgs.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:
|
||||
|
@ -344,7 +345,7 @@ def create_org_post():
|
|||
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)
|
||||
r = ail_orgs.api_delete_org(org_uuid, admin_id, request.remote_addr)
|
||||
if r[1] != 200:
|
||||
return create_json_response(r[0], r[1])
|
||||
else:
|
||||
|
|
|
@ -144,6 +144,19 @@
|
|||
{% else %}
|
||||
Create a new Investigation
|
||||
{% 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>
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<div class="col-12 col-lg-10" id="core_content">
|
||||
|
||||
<h3 class="mt-2 text-secondary">
|
||||
<i class="fas fa-microscope"></i> Investigations:
|
||||
<i class="fas fa-microscope"></i> Organisation Investigations:
|
||||
</h3>
|
||||
|
||||
<table id="table_investigation" class="table table-striped border-primary">
|
||||
|
@ -45,7 +45,43 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<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;">
|
||||
<td>
|
||||
<a href="{{ url_for('investigations_b.show_investigation') }}?uuid={{ dict_investigation['uuid'] }}">
|
||||
|
|
|
@ -47,6 +47,16 @@
|
|||
<th>Creator</th>
|
||||
<td>{{metadata['user_creator']}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Level</th>
|
||||
<td>
|
||||
{% if metadata['level'] == 1 %}
|
||||
Global
|
||||
{% elif metadata['level'] == 2 %}
|
||||
My Organisation
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Tags</th>
|
||||
<td>
|
||||
|
|
Loading…
Reference in a new issue