mirror of https://github.com/CIRCL/AIL-framework
chg: [user roles] rename coordinator as org_admin
parent
7b66ff6a8c
commit
7efc26bab9
|
@ -151,6 +151,13 @@ class Organisation:
|
|||
meta['creator'] = self._get_field('creator')
|
||||
if 'date_created' in options:
|
||||
meta['date_created'] = self._get_field('date_created')
|
||||
if 'users' in options:
|
||||
meta['users'] = self.get_users()
|
||||
if 'nb_users' in options:
|
||||
if 'users' in meta:
|
||||
meta['nb_users'] = len(meta['users'])
|
||||
else:
|
||||
meta['nb_users'] = self.get_nb_users()
|
||||
return meta
|
||||
|
||||
def is_user(self, user_id):
|
||||
|
@ -228,7 +235,7 @@ def check_access_acl(obj, user_org, is_admin=False):
|
|||
|
||||
# view
|
||||
# edit
|
||||
# delete -> coordinator or admin
|
||||
# delete -> org_admin or admin
|
||||
def check_obj_access_acl(obj, user_org, user_id, user_role, action):
|
||||
if user_role == 'admin':
|
||||
return True
|
||||
|
@ -243,7 +250,7 @@ def check_obj_access_acl(obj, user_org, user_id, user_role, action):
|
|||
return True
|
||||
# edit + delete
|
||||
else: # TODO allow user to edit same org global
|
||||
if user_role == 'coordinator':
|
||||
if user_role == 'org_admin':
|
||||
creator_org = obj.get_creator_org()
|
||||
if user_org == creator_org:
|
||||
return True
|
||||
|
@ -258,7 +265,7 @@ def check_obj_access_acl(obj, user_org, user_id, user_role, action):
|
|||
elif action == 'edit':
|
||||
return obj.get_org() == user_org
|
||||
elif action == 'delete':
|
||||
if user_role == 'coordinator':
|
||||
if user_role == 'org_admin':
|
||||
if user_org == obj.get_org():
|
||||
return True
|
||||
else:
|
||||
|
@ -285,14 +292,14 @@ def check_acl_edit_level(obj, user_org, user_id, user_role, new_level):
|
|||
elif new_level == 1:
|
||||
if level == 0 and obj.get_id() == user_id:
|
||||
return True
|
||||
elif level == 2 and user_role == 'coordinator':
|
||||
elif level == 2 and user_role == 'org_admin':
|
||||
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':
|
||||
elif level == 1 and user_role == 'org_admin':
|
||||
if obj.get_creator_org() == user_org:
|
||||
return True
|
||||
return False
|
||||
|
@ -308,6 +315,15 @@ def api_get_orgs_meta():
|
|||
meta['orgs'].append(org.get_meta(options=options))
|
||||
return meta
|
||||
|
||||
def api_get_org_meta(org_uuid):
|
||||
if not is_valid_uuid_v4(org_uuid):
|
||||
return {'status': 'error', 'reason': 'Invalid UUID'}, 400
|
||||
if not exists_org(org_uuid):
|
||||
return {'status': 'error', 'reason': 'Unknown org'}, 404
|
||||
org = Organisation(org_uuid)
|
||||
meta = org.get_meta(options={'date_created', 'description', 'name', 'users', 'nb_users'})
|
||||
return meta, 200
|
||||
|
||||
def api_create_org(creator, org_uuid, name, ip_address, user_agent, description=None):
|
||||
if not is_valid_uuid_v4(org_uuid):
|
||||
return {'status': 'error', 'reason': 'Invalid UUID'}, 400
|
||||
|
|
|
@ -270,6 +270,13 @@ def disable_user_2fa(user_id):
|
|||
def get_users():
|
||||
return r_serv_db.hkeys('ail:users:all')
|
||||
|
||||
def get_users_meta(users):
|
||||
meta = []
|
||||
for user_id in users:
|
||||
user = AILUser(user_id)
|
||||
meta.append(user.get_meta({'role'}))
|
||||
return meta
|
||||
|
||||
def get_user_role(user_id):
|
||||
return r_serv_db.hget(f'ail:user:metadata:{user_id}', 'role')
|
||||
|
||||
|
@ -733,15 +740,15 @@ def is_in_role(user_id, role):
|
|||
return r_serv_db.sismember(f'ail:users:role:{role}', user_id)
|
||||
|
||||
def _get_users_roles_list():
|
||||
return ['read_only', 'user_no_api', 'user', 'coordinator', 'admin']
|
||||
return ['read_only', 'user_no_api', 'user', 'org_admin', 'admin']
|
||||
|
||||
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'],
|
||||
'org_admin': ['read_only', 'user_no_api', 'user', 'org_admin'],
|
||||
'admin': ['read_only', 'user_no_api', 'user', 'org_admin', 'admin'],
|
||||
}
|
||||
|
||||
def set_user_role(user_id, role):
|
||||
|
|
|
@ -16,7 +16,7 @@ sys.path.append('modules')
|
|||
import Flask_config
|
||||
|
||||
# Import Role_Manager
|
||||
from Role_Manager import login_admin, login_coordinator, login_user, login_user_no_api, login_read_only
|
||||
from Role_Manager import login_admin, login_org_admin, login_user, login_user_no_api, login_read_only
|
||||
|
||||
sys.path.append(os.environ['AIL_BIN'])
|
||||
##################################
|
||||
|
@ -669,7 +669,7 @@ def retro_hunt_resume_task():
|
|||
|
||||
@hunters.route('/retro_hunt/task/delete', methods=['GET'])
|
||||
@login_required
|
||||
@login_coordinator
|
||||
@login_org_admin
|
||||
def retro_hunt_delete_task():
|
||||
user_org = current_user.get_org()
|
||||
user_id = current_user.get_id()
|
||||
|
|
|
@ -15,7 +15,7 @@ from flask_login import login_required, current_user
|
|||
sys.path.append('modules')
|
||||
|
||||
# Import Role_Manager
|
||||
from Role_Manager import login_admin, login_coordinator, login_read_only, login_user_no_api
|
||||
from Role_Manager import login_admin, login_org_admin, login_read_only, login_user_no_api
|
||||
|
||||
sys.path.append(os.environ['AIL_BIN'])
|
||||
##################################
|
||||
|
@ -216,7 +216,7 @@ def delete_object_id_to_export():
|
|||
|
||||
@import_export.route("/investigation/misp/export", methods=['GET'])
|
||||
@login_required
|
||||
@login_coordinator
|
||||
@login_org_admin
|
||||
def export_investigation():
|
||||
investigation_uuid = request.args.get("uuid")
|
||||
investigation = Investigation(investigation_uuid)
|
||||
|
|
|
@ -318,6 +318,18 @@ def organisations_list():
|
|||
meta = ail_orgs.api_get_orgs_meta()
|
||||
return render_template("orgs_list.html", meta=meta, acl_admin=True)
|
||||
|
||||
@settings_b.route("/settings/organisation", methods=['GET'])
|
||||
@login_required
|
||||
@login_admin
|
||||
def organisation():
|
||||
org_uuid = request.args.get('uuid')
|
||||
meta, r = ail_orgs.api_get_org_meta(org_uuid)
|
||||
if r != 200:
|
||||
return create_json_response(meta, r)
|
||||
if 'users' in meta:
|
||||
meta['users'] = ail_users.get_users_meta(meta['users'])
|
||||
return render_template("view_organisation.html", meta=meta, acl_admin=True)
|
||||
|
||||
@settings_b.route("/settings/create_organisation", methods=['GET'])
|
||||
@login_required
|
||||
@login_admin
|
||||
|
|
|
@ -41,12 +41,12 @@ def login_admin(func):
|
|||
return func(*args, **kwargs)
|
||||
return decorated_view
|
||||
|
||||
def login_coordinator(func):
|
||||
def login_org_admin(func):
|
||||
@wraps(func)
|
||||
def decorated_view(*args, **kwargs):
|
||||
if not current_user.is_authenticated:
|
||||
return login_manager.unauthorized()
|
||||
elif not current_user.is_in_role('coordinator'):
|
||||
elif not current_user.is_in_role('org_admin'):
|
||||
return login_manager.unauthorized()
|
||||
return func(*args, **kwargs)
|
||||
return decorated_view
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
{% for org in meta['orgs'] %}
|
||||
<tr>
|
||||
<td>{{org['name']}}</td>
|
||||
<td>{{org['uuid']}}</td>
|
||||
<td><a href="{{ url_for('settings_b.organisation', uuid=org['uuid']) }}">{{ org['uuid'] }}</a></td>
|
||||
<td>{{org['description']}}</td>
|
||||
<td>
|
||||
{% if org['date_created'] %}
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>AIL-Framework</title>
|
||||
<link rel="icon" href="{{ url_for('static', filename='image/ail-icon.png')}}">
|
||||
<!-- Core CSS -->
|
||||
<link href="{{ url_for('static', filename='css/bootstrap4.min.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/font-awesome.min.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/dataTables.bootstrap.min.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/ail-project.css') }}" rel="stylesheet">
|
||||
|
||||
<!-- JS -->
|
||||
<script src="{{ url_for('static', filename='js/jquery.js')}}"></script>
|
||||
<script src="{{ url_for('static', filename='js/bootstrap4.min.js')}}"></script>
|
||||
<script src="{{ url_for('static', filename='js/jquery.dataTables.min.js')}}"></script>
|
||||
<script src="{{ url_for('static', filename='js/dataTables.bootstrap.min.js')}}"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{% include 'nav_bar.html' %}
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
|
||||
{% include 'sidebars/sidebar_objects.html' %}
|
||||
|
||||
<div class="col-12 col-lg-10" id="core_content">
|
||||
|
||||
<div class="card my-1">
|
||||
<div class="card-header bg-dark text-white">
|
||||
<h4 class="card-title">{{meta['name']}}</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-6">
|
||||
|
||||
<table class="table table-hover">
|
||||
<tr>
|
||||
<th style="width:30%">UUID</th>
|
||||
<td>{{meta['uuid']}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Creator</th>
|
||||
<td>{{meta['creator']}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<td>{{meta['date_created']}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>NB Users</th>
|
||||
<td>
|
||||
{{ meta['nb_users'] }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Tags</th>
|
||||
<td>
|
||||
{% for tag in meta['tags'] %}
|
||||
<span class="badge badge-{{ bootstrap_label[loop.index0 % 5] }} pull-left">{{ tag }}</span>
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<td>{{meta['descriptions']}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="col-12 col-lg-6">
|
||||
|
||||
<div class="my-4">
|
||||
{# <a href="{{ url_for('investigations_b.delete_investigation') }}?uuid={{metadata['uuid']}}">#}
|
||||
{# <button type="button" class="btn btn-danger">#}
|
||||
{# <i class="fas fa-trash-alt"></i> <b>Delete</b>#}
|
||||
{# </button>#}
|
||||
{# </a>#}
|
||||
{# <a href="{{ url_for('investigations_b.edit_investigation') }}?uuid={{metadata['uuid']}}">#}
|
||||
{# <button type="button" class="btn btn-info">#}
|
||||
{# <i class="fas fa-pencil-alt"></i> <b>Edit</b>#}
|
||||
{# </button>#}
|
||||
{# </a>#}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Users</h3>
|
||||
|
||||
<table id="table_org_users" class="table table-striped border-primary">
|
||||
<thead class="bg-dark text-white">
|
||||
<tr>
|
||||
<th>User</th>
|
||||
<th>Role</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody style="font-size: 15px;">
|
||||
{% for user in meta['users'] %}
|
||||
<tr class="border-color: blue;">
|
||||
<td>
|
||||
{{ user['id'] }}
|
||||
</td>
|
||||
<td>
|
||||
{{ user['role'] }}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
{# <a href="{{ url_for('investigations_b.unregister_investigation') }}?uuid={{ metadata['uuid']}}&type={{ object['type'] }}&subtype={{ object['subtype']}}&id={{ object['id']}}">#}
|
||||
{# <button type="button" class="btn btn-danger"><i class="fas fa-trash-alt"></i></button>#}
|
||||
{# </a>#}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$('#nav_sync').removeClass("text-muted");
|
||||
|
||||
$('#table_org_users').DataTable({
|
||||
"aLengthMenu": [[5, 10, 15, -1], [5, 10, 15, "All"]],
|
||||
"iDisplayLength": 10,
|
||||
"order": [[ 0, "asc" ]]
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
</script>
|
Loading…
Reference in New Issue