From a05e1feed69f9e4995dbc69a4e0894f561223cb4 Mon Sep 17 00:00:00 2001 From: terrtia Date: Thu, 5 Sep 2024 14:41:13 +0200 Subject: [PATCH] chg: [acl] refactor acl cookiejars, trackers, retro_hunts, investigation + refactor users roles --- bin/lib/Investigations.py | 58 +++++---- bin/lib/Tracker.py | 159 +++++++++---------------- bin/lib/ail_api.py | 2 +- bin/lib/ail_orgs.py | 81 ++++++++++++- bin/lib/ail_users.py | 116 ++++++++---------- bin/lib/crawlers.py | 50 +++----- update/v5.0/DB_KVROCKS_MIGRATION.py | 6 +- update/v5.7/Update.py | 10 +- var/www/blueprints/api_rest.py | 4 +- var/www/blueprints/crawler_splash.py | 40 +++---- var/www/blueprints/hunters.py | 59 ++++++--- var/www/blueprints/investigations_b.py | 22 ++-- var/www/blueprints/settings_b.py | 4 +- var/www/create_default_user.py | 2 +- 14 files changed, 312 insertions(+), 301 deletions(-) diff --git a/bin/lib/Investigations.py b/bin/lib/Investigations.py index 15e222b8..e1164933 100755 --- a/bin/lib/Investigations.py +++ b/bin/lib/Investigations.py @@ -456,29 +456,21 @@ def get_investigations_selector(org_uuid): #### 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 - elif 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): +def api_check_investigation_acl(inv, user_org, user_id, user_role, action): + if not ail_orgs.check_obj_access_acl(inv, user_org, user_id, user_role, action): return {"status": "error", "reason": "Access Denied"}, 403 +def api_is_allowed_to_edit_investigation_level(inv, user_org, user_id, user_role, new_level): + if not ail_orgs.check_acl_edit_level(inv, user_org, user_id, user_role, new_level): + return {"status": "error", "reason": "Access Denied - Investigation level"}, 403 + #### API #### -def api_get_investigation(user_org, is_admin, investigation_uuid): # TODO check if is UUIDv4 +def api_get_investigation(user_org, user_id, user_role, 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) + res = api_check_investigation_acl(investigation, user_org, user_id, user_role, 'view') if res: return res @@ -528,7 +520,7 @@ def api_add_investigation(json_dict): return res, 200 # # TODO: edit threat level / status -def api_edit_investigation(user_org, user_id, is_admin, json_dict): +def api_edit_investigation(user_org, user_id, user_role, 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 @@ -536,7 +528,18 @@ def api_edit_investigation(user_org, user_id, is_admin, 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) + res = api_check_investigation_acl(investigation, user_org, user_id, user_role, 'edit') + if res: + return res + + level = json_dict.get('level', 1) + try: + level = int(level) + except TypeError: + level = 1 + if level not in range(1, 3): + level = 1 + res = api_is_allowed_to_edit_investigation_level(investigation, user_org, user_id, user_role, level) if res: return res @@ -561,13 +564,6 @@ def api_edit_investigation(user_org, user_id, is_admin, 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) @@ -581,7 +577,7 @@ def api_edit_investigation(user_org, user_id, is_admin, json_dict): return investigation_uuid, 200 -def api_delete_investigation(user_org, user_id, is_admin, json_dict): +def api_delete_investigation(user_org, user_id, user_role, 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 @@ -589,13 +585,13 @@ def api_delete_investigation(user_org, user_id, is_admin, 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) + res = api_check_investigation_acl(investigation, user_org, user_id, user_role, 'delete') if res: return res res = investigation.delete() return res, 200 -def api_register_object(user_org, user_id, is_admin, json_dict): +def api_register_object(user_org, user_id, user_role, 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 @@ -603,7 +599,7 @@ def api_register_object(user_org, user_id, is_admin, 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) + res = api_check_investigation_acl(investigation, user_org, user_id, user_role, 'edit') if res: return res @@ -622,7 +618,7 @@ def api_register_object(user_org, user_id, is_admin, json_dict): res = investigation.register_object(obj_id, obj_type, subtype, comment=comment) return res, 200 -def api_unregister_object(user_org, user_id, is_admin, json_dict): +def api_unregister_object(user_org, user_id, user_role, 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 @@ -630,7 +626,7 @@ def api_unregister_object(user_org, user_id, is_admin, 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) + res = api_check_investigation_acl(investigation, user_org, user_id, user_role, 'edit') if res: return res diff --git a/bin/lib/Tracker.py b/bin/lib/Tracker.py index e528bd54..e35ead1a 100755 --- a/bin/lib/Tracker.py +++ b/bin/lib/Tracker.py @@ -30,7 +30,6 @@ from lib import ail_orgs from lib import ConfigLoader from lib import item_basic from lib import Tag -from lib.ail_users import AILUser # LOGS logging.config.dictConfig(ail_logger.get_config(name='modules')) @@ -47,7 +46,7 @@ TOKENIZER = None def init_tokenizer(): global TOKENIZER TOKENIZER = RegexpTokenizer('[\&\~\:\;\,\.\(\)\{\}\|\[\]\\\\/\-/\=\'\"\%\$\?\@\+\#\_\^\<\>\!\*\n\r\t\s]+', - gaps=True, discard_empty=True) + gaps=True, discard_empty=True) def get_special_characters(): special_characters = set('[<>~!?@#$%^&*|()_-+={}":;,.\'\n\r\t]/\\') @@ -143,8 +142,8 @@ class Tracker: first_seen = self.get_first_seen() # if op == 'add': if not first_seen: - self._set_first_seen(date) - self._set_last_seen(date) + self._set_first_seen(date) + self._set_last_seen(date) else: first_seen = int(first_seen) last_seen = int(self.get_last_seen()) @@ -476,8 +475,6 @@ class Tracker: r_tracker.sadd('trackers:all', self.uuid) r_tracker.sadd(f'trackers:all:{tracker_type}', self.uuid) - - # TRACKER LEVEL self.set_level(level, org) @@ -506,7 +503,7 @@ class Tracker: trigger_trackers_refresh(tracker_type) return self.uuid - def edit(self, tracker_type, to_track, level, org, description=None, filters={}, tags=[], mails=[], webhook=None): # TODO ADMIN: EDIT ORG UUID + def edit(self, tracker_type, to_track, level, org, description=None, filters={}, tags=[], mails=[], webhook=None): # edit tracker old_type = self.get_type() @@ -868,55 +865,20 @@ def api_check_tracker_uuid(tracker_uuid): return {"status": "error", "reason": "Unknown uuid"}, 404 return None -def api_check_tracker_acl(tracker_uuid, user_org, user_id): +def api_check_tracker_acl(tracker_uuid, user_org, user_id, user_role, action): res = api_check_tracker_uuid(tracker_uuid) if res: return res tracker = Tracker(tracker_uuid) - if tracker.is_level_user(): - if tracker.get_user() != user_id or not AILUser(user_id).is_in_role('admin'): - 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 + if not ail_orgs.check_obj_access_acl(tracker, user_org, user_id, user_role, action): + return {"status": "error", "reason": "Access Denied"}, 403 -def api_is_allowed_to_edit_tracker(tracker_uuid, user_org, user_id): - res = api_check_tracker_uuid(tracker_uuid) - if res: - return res +def api_is_allowed_to_edit_tracker_level(tracker_uuid, user_org, user_id, user_role, new_level): tracker = Tracker(tracker_uuid) - if tracker.is_level_user(): - if tracker.get_user() != user_id or not AILUser(user_id).is_in_role('admin'): - 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 - 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 + if not ail_orgs.check_acl_edit_level(tracker, user_org, user_id, user_role, new_level): + return {"status": "error", "reason": "Access Denied - Tracker level"}, 403 -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-- ## #### FIX DB #### TODO ################################################################### def fix_tracker_stats_per_day(tracker_uuid): @@ -959,7 +921,7 @@ def fix_all_tracker_uuid_list(): r_tracker.sadd(f'trackers:all', tracker_uuid) r_tracker.sadd(f'trackers:all:{tracker_type}', tracker_uuid) -##-- FIX DB --## +## --FIX DB-- ## #### CREATE TRACKER #### def api_validate_tracker_to_add(to_track, tracker_type, nb_words=1): @@ -1083,9 +1045,9 @@ def api_add_tracker(dict_input, org, user_id): return {'tracked': to_track, 'type': tracker_type, 'uuid': tracker_uuid}, 200 -def api_edit_tracker(dict_input, user_org, user_id): +def api_edit_tracker(dict_input, user_org, user_id, user_role): tracker_uuid = dict_input.get('uuid') - res = api_check_tracker_acl(tracker_uuid, user_org, user_id) + res = api_check_tracker_acl(tracker_uuid, user_org, user_id, user_role, 'edit') if res: return res @@ -1105,7 +1067,7 @@ def api_edit_tracker(dict_input, user_org, user_id): 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) + res = api_is_allowed_to_edit_tracker_level(tracker_uuid, user_org, user_id, user_role, level) if res: return res @@ -1163,18 +1125,18 @@ def api_edit_tracker(dict_input, user_org, user_id): return {'tracked': to_track, 'type': tracker_type, 'uuid': tracker_uuid}, 200 -def api_delete_tracker(data, user_org, user_id): +def api_delete_tracker(data, user_org, user_id, user_role): tracker_uuid = data.get('uuid') - res = api_check_tracker_acl(tracker_uuid, user_org, user_id) + res = api_check_tracker_acl(tracker_uuid, user_org, user_id, user_role, 'delete') if res: return res tracker = Tracker(tracker_uuid) return tracker.delete(), 200 -def api_tracker_add_object(data, user_org, user_id): +def api_tracker_add_object(data, user_org, user_id, user_role): tracker_uuid = data.get('uuid') - res = api_check_tracker_acl(tracker_uuid, user_org, user_id) + res = api_check_tracker_acl(tracker_uuid, user_org, user_id, user_role, 'edit') if res: return res tracker = Tracker(tracker_uuid) @@ -1189,9 +1151,9 @@ def api_tracker_add_object(data, user_org, user_id): return {"status": "error", "reason": "Invalid Object"}, 400 return tracker.add(obj_type, subtype, obj_id, date=date), 200 -def api_tracker_remove_object(data, user_org, user_id): +def api_tracker_remove_object(data, user_org, user_id, user_role): tracker_uuid = data.get('uuid') - res = api_check_tracker_acl(tracker_uuid, user_org, user_id) + res = api_check_tracker_acl(tracker_uuid, user_org, user_id, user_role, 'edit') if res: return res @@ -1766,7 +1728,7 @@ def create_retro_hunt(user_org, user_id, level, name, rule_type, rule, descripti retro_hunt = RetroHunt(task_uuid) # rule_type: yara_default - yara custom rule = save_yara_rule(rule_type, rule, tracker_uuid=retro_hunt.uuid) - retro_hunt.create(user_org, user_id , level, name, rule, description=description, mails=mails, tags=tags, + retro_hunt.create(user_org, user_id, level, name, rule, description=description, mails=mails, tags=tags, timeout=timeout, filters=filters, state=state) return retro_hunt.uuid @@ -1841,22 +1803,15 @@ def delete_obj_retro_hunts(obj_type, subtype, obj_id): #### ACL #### -def check_retro_hunt_access_acl(retro_hunt, user_org, is_admin=False): - if is_admin: - return True - - level = retro_hunt.get_level() - if level == 1: - return True - elif level == 2: - return ail_orgs.check_access_acl(retro_hunt, user_org, is_admin=is_admin) - else: - return False - -def api_check_retro_hunt_access_acl(retro_hunt, user_org, is_admin=False): - if not check_retro_hunt_access_acl(retro_hunt, user_org, is_admin=is_admin): +def api_check_retro_hunt_acl(retro_hunt, user_org, user_id, user_role, action): + if not ail_orgs.check_obj_access_acl(retro_hunt, user_org, user_id, user_role, action): return {"status": "error", "reason": "Access Denied"}, 403 +# TODO +def api_is_allowed_to_edit_retro_hunt_level(retro_hunt, user_org, user_id, user_role, new_level): + if not ail_orgs.check_acl_edit_level(retro_hunt, user_org, user_id, user_role, new_level): + return {"status": "error", "reason": "Access Denied - Tracker level"}, 403 + #### API #### def api_check_retro_hunt_task_uuid(task_uuid): @@ -1867,12 +1822,12 @@ def api_check_retro_hunt_task_uuid(task_uuid): return {"status": "error", "reason": "Unknown uuid"}, 404 return None -def api_pause_retro_hunt_task(user_org, is_admin, task_uuid): +def api_pause_retro_hunt_task(user_org, user_id, user_role, task_uuid): res = api_check_retro_hunt_task_uuid(task_uuid) if res: return res retro_hunt = RetroHunt(task_uuid) - res = api_check_retro_hunt_access_acl(retro_hunt, user_org, is_admin=is_admin) + res = api_check_retro_hunt_acl(retro_hunt, user_org, user_id, user_role, 'edit') if res: return res task_state = retro_hunt.get_state() @@ -1881,12 +1836,12 @@ def api_pause_retro_hunt_task(user_org, is_admin, task_uuid): retro_hunt.pause() return task_uuid, 200 -def api_resume_retro_hunt_task(user_org, is_admin, task_uuid): +def api_resume_retro_hunt_task(user_org, user_id, user_role, task_uuid): res = api_check_retro_hunt_task_uuid(task_uuid) if res: return res retro_hunt = RetroHunt(task_uuid) - res = api_check_retro_hunt_access_acl(retro_hunt, user_org, is_admin=is_admin) + res = api_check_retro_hunt_acl(retro_hunt, user_org, user_id, user_role, 'edit') if res: return res if not retro_hunt.is_paused(): @@ -1988,12 +1943,12 @@ def api_create_retro_hunt_task(dict_input, user_org, user_id): mails=mails, tags=tags, timeout=30, filters=filters) return {'name': name, 'rule': rule, 'type': task_type, 'uuid': task_uuid}, 200 -def api_delete_retro_hunt_task(user_org, is_admin, task_uuid): +def api_delete_retro_hunt_task(user_org, user_id, user_role, task_uuid): res = api_check_retro_hunt_task_uuid(task_uuid) if res: return res retro_hunt = RetroHunt(task_uuid) - res = api_check_retro_hunt_access_acl(retro_hunt, user_org, is_admin=is_admin) + res = api_check_retro_hunt_acl(retro_hunt, user_org, user_id, user_role, 'delete') if res: return res if retro_hunt.is_running() and retro_hunt.get_state() not in ['completed', 'paused']: @@ -2006,12 +1961,12 @@ def api_delete_retro_hunt_task(user_org, is_admin, task_uuid): ################################################################################ ################################################################################ -#### DB FIX #### TODO +#### DB FIX #### -def _fix_db_custom_tags(): - for tag in get_trackers_tags(): - if not Tag.is_taxonomie_tag(tag) and not Tag.is_galaxy_tag(tag): - Tag.create_custom_tag(tag) +# def _fix_db_custom_tags(): +# for tag in get_trackers_tags(): +# if not Tag.is_taxonomie_tag(tag) and not Tag.is_galaxy_tag(tag): +# Tag.create_custom_tag(tag) #### -- #### @@ -2026,33 +1981,32 @@ def _fix_db_custom_tags(): # import Term # Term.delete_term('5262ab6c-8784-4a55-b0ff-a471018414b4') - #fix_tracker_stats_per_day('5262ab6c-8784-4a55-b0ff-a471018414b4') + # fix_tracker_stats_per_day('5262ab6c-8784-4a55-b0ff-a471018414b4') # tracker_uuid = '5262ab6c-8784-4a55-b0ff-a471018414b4' # fix_tracker_item_link(tracker_uuid) # res = get_item_all_trackers_uuid('archive/') # print(res) - #res = is_valid_yara_rule('rule dummy { }') + # res = is_valid_yara_rule('rule dummy { }') # res = create_tracker('test', 'word', 'admin@admin.test', 1, [], [], None, sources=['crawled', 'pastebin.com', 'rt/pastebin.com']) - #res = create_tracker('circl\.lu', 'regex', 'admin@admin.test', 1, [], [], None, sources=['crawled','pastebin.com']) - #print(res) + # res = create_tracker('circl\.lu', 'regex', 'admin@admin.test', 1, [], [], None, sources=['crawled','pastebin.com']) + # print(res) - #t_uuid = '1c2d35b0-9330-4feb-b454-da13007aa9f7' - #res = get_tracker_sources('ail-yara-rules/rules/crypto/certificate.yar', 'yara') + # t_uuid = '1c2d35b0-9330-4feb-b454-da13007aa9f7' + # res = get_tracker_sources('ail-yara-rules/rules/crypto/certificate.yar', 'yara') # sys.path.append(os.environ['AIL_BIN']) # from packages import Term # Term.delete_term('074ab4be-6049-45b5-a20e-8125a4e4f500') + # res = get_items_to_analyze('archive/pastebin.com_pro/2020/05/15', last='archive/pastebin.com_pro/2020/05/15/zkHEgqjQ.gz') + # get_retro_hunt_task_progress('0', nb_src_done=2) - #res = get_items_to_analyze('archive/pastebin.com_pro/2020/05/15', last='archive/pastebin.com_pro/2020/05/15/zkHEgqjQ.gz') - #get_retro_hunt_task_progress('0', nb_src_done=2) - - #res = set_cache_retro_hunt_task_progress('0', 100) - #res = get_retro_hunt_task_nb_src_done('0', sources=['pastebin.com_pro', 'alerts/pastebin.com_pro', 'crawled']) - #print(res) + # res = set_cache_retro_hunt_task_progress('0', 100) + # res = get_retro_hunt_task_nb_src_done('0', sources=['pastebin.com_pro', 'alerts/pastebin.com_pro', 'crawled']) + # print(res) # sources = ['pastebin.com_pro', 'alerts/pastebin.com_pro', 'crawled'] # rule = 'custom-rules/4a8a3d04-f0b6-43ce-8e00-bdf47a8df241.yar' @@ -2063,13 +2017,12 @@ def _fix_db_custom_tags(): # date_from = '20200610' # date_to = '20210630' - #res = create_retro_hunt_task(name, rule, date_from, date_to, creator, sources=sources, tags=tags, description=description) + # res = create_retro_hunt_task(name, rule, date_from, date_to, creator, sources=sources, tags=tags, description=description) + # get_retro_hunt_nb_item_by_day(['80b402ef-a8a9-4e97-adb6-e090edcfd571'], date_from=None, date_to=None, num_day=31) - #get_retro_hunt_nb_item_by_day(['80b402ef-a8a9-4e97-adb6-e090edcfd571'], date_from=None, date_to=None, num_day=31) + # res = get_retro_hunt_nb_item_by_day(['c625f971-16e6-4331-82a7-b1e1b9efdec1'], date_from='20200610', date_to='20210630') - #res = get_retro_hunt_nb_item_by_day(['c625f971-16e6-4331-82a7-b1e1b9efdec1'], date_from='20200610', date_to='20210630') + # res = delete_retro_hunt_task('598687b6-f765-4f8b-861a-09ad76d0ab34') - #res = delete_retro_hunt_task('598687b6-f765-4f8b-861a-09ad76d0ab34') - - #print(res) + # print(res) diff --git a/bin/lib/ail_api.py b/bin/lib/ail_api.py index d01de0fc..f62ac520 100755 --- a/bin/lib/ail_api.py +++ b/bin/lib/ail_api.py @@ -28,7 +28,7 @@ def get_user_from_token(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') + return ail_users.get_user_org(user_id), user_id, ail_users.get_user_role(user_id) def is_user_in_role(role, token): # verify_user_role # User without API diff --git a/bin/lib/ail_orgs.py b/bin/lib/ail_orgs.py index dcc068d5..cc1288a8 100755 --- a/bin/lib/ail_orgs.py +++ b/bin/lib/ail_orgs.py @@ -83,7 +83,8 @@ def create_default_org(): # org = Organisation(generate_uuid()) name = 'Default AIL Organisation' description = 'Default AIL Organisation' - return create_org(name, description) + creator = 'admin@admin.test' + return create_org(creator, name, description) #### ORGANISATION #### @@ -99,7 +100,7 @@ class Organisation: 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) + r_serv_db.hset(f'ail:org:{self.uuid}', field, value) def get_uuid(self): return self.uuid @@ -197,7 +198,7 @@ class Organisation: 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 ????? +def create_org(creator, name, description, uuid=None, nationality=None, sector=None, org_type=None, logo=None): if uuid is None: uuid = generate_uuid() else: @@ -205,7 +206,7 @@ def create_org(name, description, uuid=None, nationality=None, sector=None, org_ 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) + org.create(creator, name, description, nationality=nationality, sector=sector, org_type=org_type, logo=logo) return org def get_org_objs_by_type(org_uuid, obj_type): @@ -225,6 +226,78 @@ def check_access_acl(obj, user_org, is_admin=False): return True return obj.get_org() == user_org +# view +# edit +# delete -> coordinator or admin +def check_obj_access_acl(obj, user_org, user_id, user_role, action): + if user_role == 'admin': + return True + + level = obj.get_level() + # User + if level == 0: + return user_id == obj.get_user() + # Global + elif level == 1: + if action == 'view': + return True + # edit + delete + else: # TODO allow user to edit same org global + if user_role == 'coordinator': + creator_org = obj.get_creator_org() + if user_org == creator_org: + return True + else: + return False + else: + return False # TODO allow user (creator) to edit global tracker ???? + # Organization + elif level == 2: + if action == 'view': + return obj.get_org() == user_org + elif action == 'edit': + return obj.get_org() == user_org + elif action == 'delete': + if user_role == 'coordinator': + if user_org == obj.get_org(): + return True + else: + return False + else: + return False + + return False + +def check_acl_edit_level(obj, user_org, user_id, user_role, new_level): + if user_role == 'admin': + return True + + level = obj.get_level() + if new_level == level: + return True + + # User + if new_level == 0: # TODO + return False + # if obj.get_user() == user_id: + # return True + # Global + elif new_level == 1: + if level == 0 and obj.get_id() == user_id: + return True + elif level == 2 and user_role == 'coordinator': + if obj.get_creator_org() == user_org: + return True + # Organisation + elif new_level == 2: + if level == 0 and obj.get_id() == user_id: + return True + elif level == 1 and user_role == 'coordinator': + if obj.get_creator_org() == user_org: + return True + return False + + #### API #### def api_get_orgs_meta(): diff --git a/bin/lib/ail_users.py b/bin/lib/ail_users.py index b954adc6..514d778d 100755 --- a/bin/lib/ail_users.py +++ b/bin/lib/ail_users.py @@ -326,13 +326,9 @@ def create_user(user_id, password=None, admin_id=None, chg_passwd=True, org_uuid r_serv_db.hset(f'ail:user:metadata:{user_id}', 'last_edit', date) # Role - if not role: + if not role or role not in get_roles(): role = get_default_role() - - if role in get_all_roles(): - for role_to_add in get_all_user_role(role): - r_serv_db.sadd(f'ail:users:role:{role_to_add}', user_id) - r_serv_db.hset(f'ail:user:metadata:{user_id}', 'role', role) + set_user_role(user_id, role) # ORG org = ail_orgs.Organisation(org_uuid) @@ -569,7 +565,7 @@ class AILUser(UserMixin): def delete(self): kill_session_user(self.user_id) - for role_id in get_all_roles(): + for role_id in get_roles(): r_serv_db.srem(f'ail:users:role:{role_id}', self.user_id) user_token = self.get_api_key() if user_token: @@ -711,35 +707,15 @@ def api_delete_user(user_id, admin_id, ip_address): #### ROLES #### -def get_all_roles(): - return r_serv_db.zrange('ail:roles:all', 0, -1) +def get_roles(): + return r_serv_db.smembers('ail:roles') -# create role_list -def _create_roles_list(): - if not r_serv_db.exists('ail:roles:all'): - r_serv_db.zadd('ail:roles:all', {'admin': 1}) - r_serv_db.zadd('ail:roles:all', {'analyst': 2}) - r_serv_db.zadd('ail:roles:all', {'user': 3}) - r_serv_db.zadd('ail:roles:all', {'user_no_api': 4}) - r_serv_db.zadd('ail:roles:all', {'read_only': 5}) - -def get_role_level(role): - return int(r_serv_db.zscore('ail:roles:all', role)) - -def get_user_role_by_range(inf, sup): - return r_serv_db.zrange('ail:roles:all', inf, sup) - -def get_all_user_role(user_role): - current_role_val = get_role_level(user_role) - return r_serv_db.zrange('ail:roles:all', current_role_val - 1, -1) - -def get_all_user_upper_role(user_role): - current_role_val = get_role_level(user_role) - # remove one rank - if current_role_val > 1: - return r_serv_db.zrange('ail:roles:all', 0, current_role_val - 2) - else: - return [] +def _create_roles(): + r_serv_db.sadd('ail:roles', 'admin') + r_serv_db.sadd('ail:roles', 'read_only') + r_serv_db.sadd('ail:roles', 'user') + r_serv_db.sadd('ail:roles', 'user_no_api') + r_serv_db.sadd('ail:roles', 'contributor') def get_default_role(): return 'read_only' @@ -747,41 +723,45 @@ def get_default_role(): def is_in_role(user_id, role): return r_serv_db.sismember(f'ail:users:role:{role}', user_id) -def edit_user_role(user_id, role): - current_role = get_user_role(user_id) - if role != current_role: - request_level = get_role_level(role) - current_role = get_role_level(current_role) +def _get_users_roles_list(): + return ['read_only', 'user_no_api', 'user', 'coordinator', 'admin'] - if current_role < request_level: - role_to_remove = get_user_role_by_range(current_role - 1, request_level - 2) - for role_id in role_to_remove: - r_serv_db.srem(f'ail:users:role:{role_id}', user_id) - r_serv_db.hset(f'ail:user:metadata:{user_id}', 'role', role) - else: - role_to_add = get_user_role_by_range(request_level - 1, current_role) - for role_id in role_to_add: - r_serv_db.sadd(f'ail:users:role:{role_id}', user_id) - r_serv_db.hset(f'ail:user:metadata:{user_id}', 'role', role) +def _get_users_roles_dict(): + return { + 'read_only': ['read_only'], + 'user_no_api': ['read_only', 'user_no_api'], + 'user': ['read_only', 'user_no_api', 'user'], + 'coordinator': ['read_only', 'user_no_api', 'user', 'coordinator'], + 'admin': ['read_only', 'user_no_api', 'user', 'coordinator', 'admin'], + } + +def set_user_role(user_id, role): + roles = _get_users_roles_dict() + # set role + for role_to_add in roles[role]: + r_serv_db.sadd(f'ail:users:role:{role_to_add}', user_id) + r_serv_db.hset(f'ail:user:metadata:{user_id}', 'role', role) def check_user_role_integrity(user_id): + roles = _get_users_roles_dict() user_role = get_user_role(user_id) - all_user_role = get_all_user_role(user_role) - res = True - for role in all_user_role: - if not r_serv_db.sismember(f'ail:users:role:{role}', user_id): - res = False - upper_role = get_all_user_upper_role(user_role) - for role in upper_role: - if r_serv_db.sismember(f'ail:users:role:{role}', user_id): - res = False - return res + if user_role not in roles: + return False + # check if is in role + for r in roles[user_role]: + if not r_serv_db.sismember(f'ail:users:role:{r}', user_id): + print(r) + return False + for r in list(set(_get_users_roles_list()) - set(roles[user_role])): + if r_serv_db.sismember(f'ail:users:role:{r}', user_id): + print(r) + return False + return True -## --ROLES-- ## - -# 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) +# TODO +# ACL: +# - mass tag correlation graph +# +# +# +# diff --git a/bin/lib/crawlers.py b/bin/lib/crawlers.py index b7c2bc41..8d74579d 100755 --- a/bin/lib/crawlers.py +++ b/bin/lib/crawlers.py @@ -701,24 +701,24 @@ def api_get_cookiejars_selector(user_org, user_id): cookiejars.append(f'{description} : {cookiejar.uuid}') return sorted(cookiejars) -def api_edit_cookiejar_description(user_org, user_id, is_admin, cookiejar_uuid, description): - resp = api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, is_admin) +def api_edit_cookiejar_description(user_org, user_id, user_role, cookiejar_uuid, description): + resp = api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, user_role, 'edit') if resp: return resp cookiejar = Cookiejar(cookiejar_uuid) cookiejar.set_description(description) return {'cookiejar_uuid': cookiejar_uuid}, 200 -def api_delete_cookiejar(user_org, user_id, is_admin, cookiejar_uuid): - resp = api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, is_admin) +def api_delete_cookiejar(user_org, user_id, user_role, cookiejar_uuid): + resp = api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, user_role, 'delete') if resp: return resp cookiejar = Cookiejar(cookiejar_uuid) cookiejar.delete() return {'cookiejar_uuid': cookiejar_uuid}, 200 -def api_get_cookiejar(user_org, user_id, is_admin, cookiejar_uuid): - resp = api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, is_admin) +def api_get_cookiejar(user_org, user_id, user_role, cookiejar_uuid): + resp = api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, user_role, 'view') if resp: return resp cookiejar = Cookiejar(cookiejar_uuid) @@ -727,25 +727,11 @@ def api_get_cookiejar(user_org, user_id, is_admin, cookiejar_uuid): #### ACL #### -def check_cookiejar_access_acl(cookiejar, user_org, user_id, is_admin=False): - if is_admin: - return True - - level = cookiejar.get_level() - if level == 0: - return user_id == cookiejar.get_user() - elif level == 1: - return True - elif level == 2: - return ail_orgs.check_access_acl(cookiejar, user_org, is_admin=is_admin) - else: - return False - -def api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, is_admin=False): +def api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, user_role, action): cookiejar = Cookiejar(cookiejar_uuid) if not cookiejar.exists(): return {'error': 'unknown cookiejar uuid', 'cookiejar_uuid': cookiejar_uuid}, 404 - if not check_cookiejar_access_acl(cookiejar, user_org, user_id, is_admin=is_admin): + if not ail_orgs.check_obj_access_acl(cookiejar, user_org, user_id, user_role, action): return {"status": "error", "reason": "Access Denied"}, 403 #### API #### @@ -849,20 +835,20 @@ class Cookie: ## API ## -def api_get_cookie(user_org, user_id, is_admin, cookie_uuid): +def api_get_cookie(user_org, user_id, user_role, cookie_uuid): cookie = Cookie(cookie_uuid) if not cookie.exists(): return {'error': 'unknown cookie uuid', 'cookie_uuid': cookie_uuid}, 404 - resp = api_check_cookiejar_access_acl(cookie.get_cookiejar(), user_org, user_id, is_admin) + resp = api_check_cookiejar_access_acl(cookie.get_cookiejar(), user_org, user_id, user_role, 'view') if resp: return resp return cookie.get_meta() -def api_edit_cookie(user_org, user_id, is_admin, cookie_uuid, cookie_dict): +def api_edit_cookie(user_org, user_id, user_role, cookie_uuid, cookie_dict): cookie = Cookie(cookie_uuid) if not cookie.exists(): return {'error': 'unknown cookie uuid', 'cookie_uuid': cookie_uuid}, 404 - resp = api_check_cookiejar_access_acl(cookie.get_cookiejar(), user_org, user_id, is_admin) + resp = api_check_cookiejar_access_acl(cookie.get_cookiejar(), user_org, user_id, user_role, 'edit') if resp: return resp if 'name' not in cookie_dict or 'value' not in cookie_dict or not cookie_dict['name'] or not cookie_dict['value']: @@ -870,8 +856,8 @@ def api_edit_cookie(user_org, user_id, is_admin, cookie_uuid, cookie_dict): cookie.edit(cookie_dict) return cookie.get_meta(), 200 -def api_create_cookie(user_org, user_id, is_admin, cookiejar_uuid, cookie_dict): - resp = api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, is_admin) +def api_create_cookie(user_org, user_id, user_role, cookiejar_uuid, cookie_dict): + resp = api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, user_role, 'edit') if resp: return resp if 'name' not in cookie_dict or 'value' not in cookie_dict or not cookie_dict['name'] or not cookie_dict['value']: @@ -887,12 +873,12 @@ def api_create_cookie(user_org, user_id, is_admin, cookiejar_uuid, cookie_dict): cookiejar.add_cookie(name, value, domain=domain, httponly=httponly, path=path, secure=secure, text=text) return resp, 200 -def api_delete_cookie(user_org, user_id, is_admin, cookie_uuid): +def api_delete_cookie(user_org, user_id, user_role, cookie_uuid): cookie = Cookie(cookie_uuid) if not cookie.exists(): return {'error': 'unknown cookie uuid', 'cookie_uuid': cookie_uuid}, 404 cookiejar_uuid = cookie.get_cookiejar() - resp = api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, is_admin) + resp = api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, user_role, 'edit') if resp: return resp cookiejar = Cookiejar(cookiejar_uuid) @@ -938,8 +924,8 @@ def unpack_imported_json_cookie(json_cookie): ## - - ## #### COOKIEJAR API #### -def api_import_cookies_from_json(user_org, user_id, is_admin, cookiejar_uuid, json_cookies_str): # # TODO: add catch - resp = api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, is_admin) +def api_import_cookies_from_json(user_org, user_id, user_role, cookiejar_uuid, json_cookies_str): # # TODO: add catch + resp = api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, user_role, 'edit') if resp: return resp json_cookies = json.loads(json_cookies_str) diff --git a/update/v5.0/DB_KVROCKS_MIGRATION.py b/update/v5.0/DB_KVROCKS_MIGRATION.py index 2d2f0a88..02789d37 100755 --- a/update/v5.0/DB_KVROCKS_MIGRATION.py +++ b/update/v5.0/DB_KVROCKS_MIGRATION.py @@ -113,7 +113,7 @@ def user_migration(): print('USER MIGRATION...') # create role_list - ail_users._create_roles_list() + ail_users._create_roles() for user_id in r_serv_db.hkeys('user:all'): role = r_serv_db.hget(f'user_metadata:{user_id}', 'role') @@ -248,8 +248,6 @@ def trackers_migration(): for obj_id in old_Tracker.get_retro_hunt_items_by_daterange(task_uuid, meta['date_from'], meta['date_to']): retro_hunt.add('item', '', obj_id) - Tracker._fix_db_custom_tags() - ############################### # # @@ -452,7 +450,7 @@ def crawler_migration(): cookie_dict = get_cookie_dict(cookie_uuid) if cookie_dict: # print(cookie_dict) - crawlers.api_create_cookie(get_ail_uuid(), meta['user'], True, cookiejar_uuid, cookie_dict) + crawlers.api_create_cookie(get_ail_uuid(), meta['user'], 'admin', cookiejar_uuid, cookie_dict) auto_crawler_web = r_crawler.smembers('auto_crawler_url:regular') auto_crawler_onion = r_crawler.smembers('auto_crawler_url:onion') diff --git a/update/v5.7/Update.py b/update/v5.7/Update.py index 666abc55..98fb0f9f 100755 --- a/update/v5.7/Update.py +++ b/update/v5.7/Update.py @@ -31,20 +31,22 @@ if __name__ == '__main__': config_loader = None date = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') - # ORGS - # TODO CREATE DEFAULT ORG - # USERS print('Updating Users ...') # Create Default Org org = ail_orgs.create_default_org() org_uuid = org.get_uuid() - for user_id in ail_users.get_users(): # TODO ORG + for user_id in ail_users.get_users(): + if ail_users.get_user_role(user_id) == 'analyst': + ail_users.set_user_role(user_id, 'user') ail_users.edit_user('admin@admin.test', user_id, org_uuid=org_uuid) 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) + r_serv_db.srem(f'ail:users:role:analyst', user_id) + user_role = ail_users.get_user_role(user_id) + ail_users.set_user_role(user_id, user_role) # ADD User to ORG org.add_user(user_id) diff --git a/var/www/blueprints/api_rest.py b/var/www/blueprints/api_rest.py index b39c9ec5..aa2cf918 100644 --- a/var/www/blueprints/api_rest.py +++ b/var/www/blueprints/api_rest.py @@ -252,8 +252,8 @@ def objects_titles_download_unsafe(): @token_required('read_only') def v1_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) + user_org, user_id, user_role = ail_api.get_basic_user_meta(user_token) + r = Investigations.api_get_investigation(user_org, user_id, user_role, investigation_uuid) return create_json_response(r[0], r[1]) # TODO CATCH REDIRECT diff --git a/var/www/blueprints/crawler_splash.py b/var/www/blueprints/crawler_splash.py index c4011181..f18e246f 100644 --- a/var/www/blueprints/crawler_splash.py +++ b/var/www/blueprints/crawler_splash.py @@ -19,7 +19,7 @@ sys.path.append('modules') import Flask_config # Import Role_Manager -from Role_Manager import login_admin, login_analyst, login_read_only +from Role_Manager import login_admin, login_analyst, login_read_only, login_user_no_api sys.path.append(os.environ['AIL_BIN']) ################################## @@ -660,7 +660,7 @@ def crawler_cookiejar_add(): def crawler_cookiejar_add_post(): user_org = current_user.get_org() user_id = current_user.get_user_id() - is_admin = current_user.is_admin() + user_role = current_user.get_role() description = request.form.get('description') level = request.form.get('level') @@ -697,11 +697,11 @@ def crawler_cookiejar_add_post(): # Create Cookies if json_cookies: # TODO CHECK Import - res = crawlers.api_import_cookies_from_json(user_org, user_id, is_admin, cookiejar_uuid, json_cookies) + res = crawlers.api_import_cookies_from_json(user_org, user_id, user_role, cookiejar_uuid, json_cookies) if res: return create_json_response(res[0], res[1]) for cookie_dict in l_manual_cookie: - crawlers.api_create_cookie(user_org, user_id, is_admin, cookiejar_uuid, cookie_dict) + crawlers.api_create_cookie(user_org, user_id, user_role, cookiejar_uuid, cookie_dict) return redirect(url_for('crawler_splash.crawler_cookiejar_show', uuid=cookiejar_uuid)) @@ -725,10 +725,10 @@ def crawler_cookiejar_all(): def crawler_cookiejar_show(): user_org = current_user.get_org() user_id = current_user.get_user_id() - is_admin = current_user.is_admin() + user_role = current_user.get_role() cookiejar_uuid = request.args.get('uuid') - res = crawlers.api_get_cookiejar(user_org, user_id, is_admin, cookiejar_uuid) + res = crawlers.api_get_cookiejar(user_org, user_id, user_role, cookiejar_uuid) if res[1] != 200: return create_json_response(res[0], res[1]) else: @@ -739,14 +739,14 @@ def crawler_cookiejar_show(): @crawler_splash.route('/crawler/cookie/delete', methods=['GET']) @login_required -@login_analyst +@login_user_no_api def crawler_cookiejar_cookie_delete(): user_org = current_user.get_org() user_id = current_user.get_user_id() - is_admin = current_user.is_admin() + user_role = current_user.get_role() cookie_uuid = request.args.get('uuid') - res = crawlers.api_delete_cookie(user_org, user_id, is_admin, cookie_uuid) + res = crawlers.api_delete_cookie(user_org, user_id, user_role, cookie_uuid) if res[1] != 200: return create_json_response(res[0], res[1]) else: @@ -760,10 +760,10 @@ def crawler_cookiejar_cookie_delete(): def crawler_cookiejar_delete(): user_org = current_user.get_org() user_id = current_user.get_user_id() - is_admin = current_user.is_admin() + user_role = current_user.get_role() cookiejar_uuid = request.args.get('uuid') - res = crawlers.api_delete_cookiejar(user_org, user_id, is_admin, cookiejar_uuid) + res = crawlers.api_delete_cookiejar(user_org, user_id, user_role, cookiejar_uuid) if res[1] != 200: return create_json_response(res[0], res[1]) return redirect(url_for('crawler_splash.crawler_cookiejar_all')) @@ -775,11 +775,11 @@ def crawler_cookiejar_delete(): def crawler_cookiejar_edit(): user_org = current_user.get_org() user_id = current_user.get_user_id() - is_admin = current_user.is_admin() + user_role = current_user.get_role() cookiejar_uuid = request.args.get('uuid') description = request.args.get('description') - res = crawlers.api_edit_cookiejar_description(user_org, user_id, is_admin, cookiejar_uuid, description) + res = crawlers.api_edit_cookiejar_description(user_org, user_id, user_role, cookiejar_uuid, description) return create_json_response(res[0], res[1]) @@ -789,10 +789,10 @@ def crawler_cookiejar_edit(): def crawler_cookiejar_cookie_edit(): user_org = current_user.get_org() user_id = current_user.get_user_id() - is_admin = current_user.is_admin() + user_role = current_user.get_role() cookie_uuid = request.args.get('uuid') - cookie_dict = crawlers.api_get_cookie(user_org, user_id, is_admin, cookie_uuid) + cookie_dict = crawlers.api_get_cookie(user_org, user_id, user_role, cookie_uuid) return render_template("edit_cookie.html", cookie_uuid=cookie_uuid, cookie_dict=cookie_dict) @@ -802,7 +802,7 @@ def crawler_cookiejar_cookie_edit(): def crawler_cookiejar_cookie_edit_post(): user_org = current_user.get_org() user_id = current_user.get_user_id() - is_admin = current_user.is_admin() + user_role = current_user.get_role() cookie_uuid = request.form.get('cookie_uuid') name = request.form.get('name') value = request.form.get('value') @@ -821,7 +821,7 @@ def crawler_cookiejar_cookie_edit_post(): if secure: cookie_dict['secure'] = True - res = crawlers.api_edit_cookie(user_org, user_id, is_admin, cookie_uuid, cookie_dict) + res = crawlers.api_edit_cookie(user_org, user_id, user_role, cookie_uuid, cookie_dict) if res[1] != 200: return create_json_response(res[0], res[1]) cookie = crawlers.Cookie(cookie_uuid) @@ -835,10 +835,10 @@ def crawler_cookiejar_cookie_edit_post(): def crawler_cookiejar_cookie_add(): user_org = current_user.get_org() user_id = current_user.get_user_id() - is_admin = current_user.is_admin() + user_role = current_user.get_role() cookiejar_uuid = request.args.get('uuid') - res = crawlers.api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, is_admin) - if res[1] != 200: + res = crawlers.api_check_cookiejar_access_acl(cookiejar_uuid, user_org, user_id, user_role, action='edit') + if res: return create_json_response(res[0], res[1]) return render_template("add_cookie.html", cookiejar_uuid=cookiejar_uuid) diff --git a/var/www/blueprints/hunters.py b/var/www/blueprints/hunters.py index ae7ece31..c97eca89 100644 --- a/var/www/blueprints/hunters.py +++ b/var/www/blueprints/hunters.py @@ -16,7 +16,7 @@ sys.path.append('modules') import Flask_config # Import Role_Manager -from Role_Manager import login_admin, login_analyst, login_read_only +from Role_Manager import login_admin, login_analyst, login_user_no_api, login_read_only sys.path.append(os.environ['AIL_BIN']) ################################## @@ -151,8 +151,10 @@ def tracked_menu_admin(): @login_read_only def show_tracker(): user_id = current_user.get_user_id() + user_org = current_user.get_org() + user_role = current_user.get_role() tracker_uuid = request.args.get('uuid', None) - res = Tracker.api_check_tracker_acl(tracker_uuid, current_user.get_org(), user_id) + res = Tracker.api_check_tracker_acl(tracker_uuid, user_org, user_id, user_role, 'view') if res: # invalid access return Response(json.dumps(res[0], indent=2, sort_keys=True), mimetype='application/json'), res[1] @@ -312,20 +314,21 @@ def add_tracked_menu(): @hunters.route("/tracker/edit", methods=['GET', 'POST']) @login_required -@login_analyst +@login_user_no_api def tracker_edit(): user_id = current_user.get_user_id() user_org = current_user.get_org() + user_role = current_user.get_role() if request.method == 'POST': input_dict = parse_add_edit_request(request.form) - res = Tracker.api_edit_tracker(input_dict, user_org, user_id) + res = Tracker.api_edit_tracker(input_dict, user_org, user_id, user_role) if res[1] == 200: return redirect(url_for('hunters.show_tracker', uuid=res[0].get('uuid'))) else: return create_json_response(res[0], res[1]) else: tracker_uuid = request.args.get('uuid', None) - res = Tracker.api_is_allowed_to_edit_tracker(tracker_uuid, user_org, user_id) + res = Tracker.api_check_tracker_acl(tracker_uuid, user_org, user_id, user_role, 'edit') if res: # invalid access return Response(json.dumps(res[0], indent=2, sort_keys=True), mimetype='application/json'), res[1] @@ -356,8 +359,10 @@ def tracker_edit(): @login_analyst def tracker_delete(): user_id = current_user.get_user_id() + user_org = current_user.get_org() + user_role = current_user.get_role() tracker_uuid = request.args.get('uuid') - res = Tracker.api_delete_tracker({'uuid': tracker_uuid}, current_user.get_org(), user_id) + res = Tracker.api_delete_tracker({'uuid': tracker_uuid}, user_org, user_id, user_role) if res[1] != 200: return create_json_response(res[0], res[1]) else: @@ -369,8 +374,10 @@ def tracker_delete(): @login_read_only def get_json_tracker_graph(): user_id = current_user.get_user_id() + user_org = current_user.get_org() + user_role = current_user.get_role() tracker_uuid = request.args.get('uuid') - res = Tracker.api_check_tracker_acl(tracker_uuid, current_user.get_org(), user_id) + res = Tracker.api_check_tracker_acl(tracker_uuid, user_org, user_id, user_role, 'view') if res: return create_json_response(res[0], res[1]) @@ -392,6 +399,8 @@ def get_json_tracker_graph(): @login_admin def tracker_object_add(): user_id = current_user.get_user_id() + user_org = current_user.get_org() + user_role = current_user.get_role() tracker_uuid = request.args.get('uuid') object_global_id = request.args.get('gid') if object_global_id.startswith('messages::'): @@ -399,7 +408,7 @@ def tracker_object_add(): date = obj.get_date() else: date = request.args.get('date') # TODO check daterange - res = Tracker.api_tracker_add_object({'uuid': tracker_uuid, 'gid': object_global_id, 'date': date}, current_user.get_org(), user_id) + res = Tracker.api_tracker_add_object({'uuid': tracker_uuid, 'gid': object_global_id, 'date': date}, user_org, user_id, user_role) if res[1] != 200: return create_json_response(res[0], res[1]) else: @@ -410,12 +419,14 @@ def tracker_object_add(): @hunters.route('/tracker/object/remove', methods=['GET']) @login_required -@login_analyst +@login_user_no_api def tracker_object_remove(): user_id = current_user.get_user_id() + user_org = current_user.get_org() + user_role = current_user.get_role() tracker_uuid = request.args.get('uuid') object_global_id = request.args.get('gid') - res = Tracker.api_tracker_remove_object({'uuid': tracker_uuid, 'gid': object_global_id}, current_user.get_org(), user_id) + res = Tracker.api_tracker_remove_object({'uuid': tracker_uuid, 'gid': object_global_id}, user_org, user_id, user_role) if res[1] != 200: return create_json_response(res[0], res[1]) else: @@ -430,8 +441,10 @@ def tracker_object_remove(): @login_admin def tracker_objects(): user_id = current_user.get_user_id() + user_org = current_user.get_org() + user_role = current_user.get_role() tracker_uuid = request.args.get('uuid', None) - res = Tracker.api_is_allowed_to_edit_tracker(tracker_uuid, current_user.get_org(), user_id) + res = Tracker.api_check_tracker_acl(tracker_uuid, user_org, user_id, user_role, 'edit') if res: # invalid access return Response(json.dumps(res[0], indent=2, sort_keys=True), mimetype='application/json'), res[1] @@ -477,6 +490,10 @@ def retro_hunt_all_tasks(): @login_required @login_read_only def retro_hunt_show_task(): + user_org = current_user.get_org() + user_id = current_user.get_user_id() + user_role = current_user.get_role() + task_uuid = request.args.get('uuid', None) objs = request.args.get('objs', False) @@ -490,8 +507,11 @@ def retro_hunt_show_task(): res = Tracker.api_check_retro_hunt_task_uuid(task_uuid) if res: return create_json_response(res[0], res[1]) - retro_hunt = Tracker.RetroHunt(task_uuid) + res = Tracker.api_check_retro_hunt_acl(retro_hunt, user_org, user_id, user_role, 'view') + if res: + return res + dict_task = retro_hunt.get_meta(options={'creator', 'date', 'description', 'level', 'progress', 'filters', 'nb_objs', 'tags'}) rule_content = Tracker.get_yara_rule_content(dict_task['rule']) dict_task['filters'] = json.dumps(dict_task['filters'], indent=4) @@ -614,9 +634,10 @@ def retro_hunt_add_task(): @login_analyst def retro_hunt_pause_task(): user_org = current_user.get_org() - is_admin = current_user.is_admin() + user_id = current_user.get_user_id() + user_role = current_user.get_role() task_uuid = request.args.get('uuid', None) - res = Tracker.api_pause_retro_hunt_task(user_org, is_admin, task_uuid) + res = Tracker.api_pause_retro_hunt_task(user_org, user_id, user_role, task_uuid) if res[1] != 200: return create_json_response(res[0], res[1]) return redirect(url_for('hunters.retro_hunt_all_tasks')) @@ -626,9 +647,10 @@ def retro_hunt_pause_task(): @login_analyst def retro_hunt_resume_task(): user_org = current_user.get_org() - is_admin = current_user.is_admin() + user_id = current_user.get_user_id() + user_role = current_user.get_role() task_uuid = request.args.get('uuid', None) - res = Tracker.api_resume_retro_hunt_task(user_org, is_admin, task_uuid) + res = Tracker.api_resume_retro_hunt_task(user_org, user_id, user_role, task_uuid) if res[1] != 200: return create_json_response(res[0], res[1]) return redirect(url_for('hunters.retro_hunt_all_tasks')) @@ -638,9 +660,10 @@ def retro_hunt_resume_task(): @login_analyst def retro_hunt_delete_task(): user_org = current_user.get_org() - is_admin = current_user.is_admin() + user_id = current_user.get_id() + user_role = current_user.get_role() task_uuid = request.args.get('uuid', None) - res = Tracker.api_delete_retro_hunt_task(user_org, is_admin, task_uuid) + res = Tracker.api_delete_retro_hunt_task(user_org, user_id, user_role, task_uuid) if res[1] != 200: return create_json_response(res[0], res[1]) return redirect(url_for('hunters.retro_hunt_all_tasks')) diff --git a/var/www/blueprints/investigations_b.py b/var/www/blueprints/investigations_b.py index 6208d2a1..f715ee9f 100644 --- a/var/www/blueprints/investigations_b.py +++ b/var/www/blueprints/investigations_b.py @@ -53,13 +53,13 @@ def investigations_dashboard(): @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() + user_id = current_user.get_user_id() + user_role = current_user.get_role() 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) + res = Investigations.api_check_investigation_acl(investigation, user_org, user_id, user_role, 'view') if res: return create_json_response(res[0], res[1]) @@ -124,7 +124,7 @@ 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() + user_role = current_user.get_role() investigation_uuid = request.form.get("investigation_uuid") level = request.form.get("investigation_level") name = request.form.get("investigation_name") @@ -153,7 +153,7 @@ def edit_investigation(): # TODO CHECK ACL 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(user_org, user_id, is_admin, input_dict) + res = Investigations.api_edit_investigation(user_org, user_id, user_role, input_dict) if res[1] != 200: return create_json_response(res[0], res[1]) @@ -175,10 +175,10 @@ def edit_investigation(): # TODO CHECK ACL def delete_investigation(): user_org = current_user.get_org() user_id = current_user.get_user_id() - is_admin = current_user.is_admin() + user_role = current_user.get_role() investigation_uuid = request.args.get('uuid') input_dict = {"uuid": investigation_uuid} - res = Investigations.api_delete_investigation(user_org, user_id, is_admin, input_dict) + res = Investigations.api_delete_investigation(user_org, user_id, user_role, input_dict) if res[1] != 200: return create_json_response(res[0], res[1]) return redirect(url_for('investigations_b.investigations_dashboard')) @@ -189,7 +189,7 @@ def delete_investigation(): def register_investigation(): user_id = current_user.get_user_id() user_org = current_user.get_org() - is_admin = current_user.is_admin() + user_role = current_user.get_role() investigations_uuid = request.args.get('uuids') investigations_uuid = investigations_uuid.split(',') @@ -203,7 +203,7 @@ def register_investigation(): "type": object_type, "subtype": object_subtype} if comment: input_dict["comment"] = comment - res = Investigations.api_register_object(user_org, user_id, is_admin, input_dict) + res = Investigations.api_register_object(user_org, user_id, user_role, 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)) @@ -214,14 +214,14 @@ def register_investigation(): def unregister_investigation(): user_id = current_user.get_user_id() user_org = current_user.get_org() - is_admin = current_user.is_admin() + user_role = current_user.get_role() 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(user_org, user_id, is_admin, input_dict) + res = Investigations.api_unregister_object(user_org, user_id, user_role, 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)) diff --git a/var/www/blueprints/settings_b.py b/var/www/blueprints/settings_b.py index a9775ce4..c48604ee 100644 --- a/var/www/blueprints/settings_b.py +++ b/var/www/blueprints/settings_b.py @@ -219,7 +219,7 @@ def create_user(): if r[1] != 200: return create_json_response(r[0], r[1]) meta = r[0] - all_roles = ail_users.get_all_roles() + all_roles = ail_users.get_roles() orgs = ail_orgs.get_orgs_selector() return render_template("create_user.html", all_roles=all_roles, orgs=orgs, meta=meta, error=error, error_mail=error_mail, @@ -251,7 +251,7 @@ def create_user_post(): else: enable_2_fa = False - all_roles = ail_users.get_all_roles() + all_roles = ail_users.get_roles() if email and len(email) < 300 and ail_users.check_email(email) and role: if role in all_roles: diff --git a/var/www/create_default_user.py b/var/www/create_default_user.py index 81d0903b..92cb532a 100755 --- a/var/www/create_default_user.py +++ b/var/www/create_default_user.py @@ -17,7 +17,7 @@ if __name__ == "__main__": password = ail_users.gen_password() # create role_list - ail_users._create_roles_list() + ail_users._create_roles() if not ail_users.exists_user(user_id): # Create Default Org