mirror of https://github.com/CIRCL/AIL-framework
chg: [settings] refactor UI settings
parent
0b8ff17c5b
commit
8a0c18c575
|
@ -174,6 +174,14 @@ def exists_token(token):
|
||||||
|
|
||||||
# TODO USER LAST LOGIN TIME
|
# TODO USER LAST LOGIN TIME
|
||||||
# TODO Check if logged
|
# TODO Check if logged
|
||||||
|
|
||||||
|
# TODO USER: - Creation Date
|
||||||
|
# - Last Login
|
||||||
|
# - Last Request
|
||||||
|
# - Last API Usage
|
||||||
|
# - Organisation ???
|
||||||
|
# - Disabled / Lock
|
||||||
|
|
||||||
class AILUser(UserMixin):
|
class AILUser(UserMixin):
|
||||||
def __init__(self, user_id):
|
def __init__(self, user_id):
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
|
@ -200,8 +208,13 @@ class AILUser(UserMixin):
|
||||||
def exists(self): # TODO CHECK USAGE
|
def exists(self): # TODO CHECK USAGE
|
||||||
return r_serv_db.exists(f'ail:user:metadata:{self.user_id}')
|
return r_serv_db.exists(f'ail:user:metadata:{self.user_id}')
|
||||||
|
|
||||||
def get_meta(self):
|
def get_meta(self, options=set()): # TODO user creation date
|
||||||
return {'email': self.user_id,}
|
meta = {'id': self.user_id}
|
||||||
|
if 'api_key' in options: # TODO add option to censor key
|
||||||
|
meta['api_key'] = self.get_api_key()
|
||||||
|
if 'role' in options:
|
||||||
|
meta['role'] = get_user_role(self.user_id)
|
||||||
|
return meta
|
||||||
|
|
||||||
## SESSION ##
|
## SESSION ##
|
||||||
|
|
||||||
|
@ -253,6 +266,17 @@ class AILUser(UserMixin):
|
||||||
# create new token
|
# create new token
|
||||||
generate_new_token(self.user_id)
|
generate_new_token(self.user_id)
|
||||||
|
|
||||||
|
## TOKEN ##
|
||||||
|
|
||||||
|
def get_api_key(self):
|
||||||
|
return get_user_token(self.user_id)
|
||||||
|
|
||||||
|
def new_api_key(self):
|
||||||
|
_delete_user_token(self.user_id)
|
||||||
|
new_api_key = gen_token()
|
||||||
|
_set_user_token(self.user_id, new_api_key)
|
||||||
|
return new_api_key
|
||||||
|
|
||||||
## ROLE ##
|
## ROLE ##
|
||||||
|
|
||||||
def is_in_role(self, role): # TODO Get role via user alternative ID
|
def is_in_role(self, role): # TODO Get role via user alternative ID
|
||||||
|
@ -266,14 +290,45 @@ class AILUser(UserMixin):
|
||||||
def get_role(self):
|
def get_role(self):
|
||||||
return r_serv_db.hget(f'ail:user:metadata:{self.user_id}', 'role')
|
return r_serv_db.hget(f'ail:user:metadata:{self.user_id}', 'role')
|
||||||
|
|
||||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
## ##
|
||||||
|
|
||||||
def delete(self): # TODO DESTROY SESSION
|
def delete(self):
|
||||||
kill_session_user(self.user_id)
|
kill_session_user(self.user_id)
|
||||||
|
for role_id in get_all_roles():
|
||||||
|
r_serv_db.srem(f'ail:users:role:{role_id}', self.user_id)
|
||||||
|
user_token = self.get_api_key()
|
||||||
|
if user_token:
|
||||||
|
r_serv_db.hdel('ail:users:tokens', user_token)
|
||||||
|
r_serv_db.delete(f'ail:user:metadata:{self.user_id}')
|
||||||
|
r_serv_db.hdel('ail:users:all', self.user_id)
|
||||||
|
|
||||||
|
|
||||||
# def create_user(user_id):
|
# def create_user(user_id):
|
||||||
|
|
||||||
|
#### API ####
|
||||||
|
|
||||||
|
def api_get_users_meta():
|
||||||
|
meta = {'users': []}
|
||||||
|
options = {'api_key', 'role'}
|
||||||
|
for user_id in get_users():
|
||||||
|
user = AILUser(user_id)
|
||||||
|
meta['users'].append(user.get_meta(options=options))
|
||||||
|
return meta
|
||||||
|
|
||||||
|
def api_create_user_api_key(user_id, admin_id): # TODO LOG ADMIN ID
|
||||||
|
user = AILUser(user_id)
|
||||||
|
if not user.exists():
|
||||||
|
return {'status': 'error', 'reason': 'User not found'}, 404
|
||||||
|
print(admin_id)
|
||||||
|
return user.new_api_key(), 200
|
||||||
|
|
||||||
|
def api_delete_user(user_id, admin_id): # TODO LOG ADMIN ID
|
||||||
|
user = AILUser(user_id)
|
||||||
|
if not user.exists():
|
||||||
|
return {'status': 'error', 'reason': 'User not found'}, 404
|
||||||
|
print(admin_id)
|
||||||
|
return user.delete(), 200
|
||||||
|
|
||||||
########################################################################################################################
|
########################################################################################################################
|
||||||
########################################################################################################################
|
########################################################################################################################
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ sys.path.append(os.environ['AIL_BIN'])
|
||||||
# Import Project packages
|
# Import Project packages
|
||||||
##################################
|
##################################
|
||||||
from lib import ail_updates
|
from lib import ail_updates
|
||||||
|
from lib import ail_users
|
||||||
from packages import git_status
|
from packages import git_status
|
||||||
|
|
||||||
# ============ BLUEPRINT ============
|
# ============ BLUEPRINT ============
|
||||||
|
@ -40,9 +41,9 @@ def create_json_response(data, status_code):
|
||||||
def settings_page():
|
def settings_page():
|
||||||
git_metadata = git_status.get_git_metadata()
|
git_metadata = git_status.get_git_metadata()
|
||||||
ail_version = ail_updates.get_ail_version()
|
ail_version = ail_updates.get_ail_version()
|
||||||
admin_level = current_user.is_in_role('admin')
|
acl_admin = current_user.is_in_role('admin')
|
||||||
return render_template("settings_index.html", git_metadata=git_metadata,
|
return render_template("settings_index.html", git_metadata=git_metadata,
|
||||||
ail_version=ail_version, admin_level=admin_level)
|
ail_version=ail_version, acl_admin=acl_admin)
|
||||||
|
|
||||||
@settings_b.route("/settings/background_update/json", methods=['GET'])
|
@settings_b.route("/settings/background_update/json", methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -54,12 +55,46 @@ def get_background_update_metadata_json():
|
||||||
@login_required
|
@login_required
|
||||||
@login_read_only
|
@login_read_only
|
||||||
def settings_modules():
|
def settings_modules():
|
||||||
admin_level = current_user.is_in_role('admin')
|
acl_admin = current_user.is_in_role('admin')
|
||||||
return render_template("settings/modules.html", admin_level=admin_level)
|
return render_template("settings/modules.html", acl_admin=acl_admin)
|
||||||
|
|
||||||
|
@settings_b.route("/settings/user/profile", methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
@login_read_only
|
||||||
|
def user_profile():
|
||||||
|
acl_admin = current_user.is_in_role('admin')
|
||||||
|
|
||||||
|
@settings_b.route("/settings/new_user_api_key", methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
@login_admin
|
||||||
|
def new_token_user():
|
||||||
|
user_id = request.args.get('user_id')
|
||||||
|
admin_id = current_user.get_user_id()
|
||||||
|
r = ail_users.api_create_user_api_key(user_id, admin_id)
|
||||||
|
if r[1] != 200:
|
||||||
|
return create_json_response(r[0], r[1])
|
||||||
|
else:
|
||||||
|
return redirect(url_for('settings_b.users_list'))
|
||||||
|
|
||||||
|
@settings_b.route("/settings/delete_user", methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
@login_admin
|
||||||
|
def delete_user():
|
||||||
|
user_id = request.args.get('user_id')
|
||||||
|
admin_id = current_user.get_user_id()
|
||||||
|
r = ail_users.api_delete_user(user_id, admin_id)
|
||||||
|
if r[1] != 200:
|
||||||
|
return create_json_response(r[0], r[1])
|
||||||
|
else:
|
||||||
|
return redirect(url_for('settings_b.users_list'))
|
||||||
|
|
||||||
|
@settings_b.route("/settings/users", methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
@login_admin
|
||||||
|
def users_list():
|
||||||
|
meta = ail_users.api_get_users_meta()
|
||||||
|
new_user = {}
|
||||||
|
return render_template("users_list.html", meta=meta, new_user=new_user, acl_admin=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -61,17 +61,6 @@ def new_token():
|
||||||
Users.generate_new_token(current_user.get_id())
|
Users.generate_new_token(current_user.get_id())
|
||||||
return redirect(url_for('settings.edit_profile'))
|
return redirect(url_for('settings.edit_profile'))
|
||||||
|
|
||||||
|
|
||||||
@settings.route("/settings/new_token_user", methods=['POST'])
|
|
||||||
@login_required
|
|
||||||
@login_admin
|
|
||||||
def new_token_user():
|
|
||||||
user_id = request.form.get('user_id')
|
|
||||||
if Users.exists_user(user_id):
|
|
||||||
Users.generate_new_token(user_id)
|
|
||||||
return redirect(url_for('settings.users_list'))
|
|
||||||
|
|
||||||
|
|
||||||
@settings.route("/settings/create_user", methods=['GET'])
|
@settings.route("/settings/create_user", methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
@login_admin
|
@login_admin
|
||||||
|
@ -133,18 +122,18 @@ def create_user_post():
|
||||||
return render_template("create_user.html", all_roles=all_roles, error_mail=True, admin_level=True)
|
return render_template("create_user.html", all_roles=all_roles, error_mail=True, admin_level=True)
|
||||||
|
|
||||||
|
|
||||||
@settings.route("/settings/users_list", methods=['GET'])
|
# @settings.route("/settings/users_list", methods=['GET'])
|
||||||
@login_required
|
# @login_required
|
||||||
@login_admin
|
# @login_admin
|
||||||
def users_list():
|
# def users_list():
|
||||||
all_users = Users.get_users_metadata(Users.get_all_users())
|
# all_users = Users.get_users_metadata(Users.get_all_users())
|
||||||
new_user = request.args.get('new_user')
|
# new_user = request.args.get('new_user')
|
||||||
new_user_dict = {}
|
# new_user_dict = {}
|
||||||
if new_user:
|
# if new_user:
|
||||||
new_user_dict['email'] = new_user
|
# new_user_dict['email'] = new_user
|
||||||
new_user_dict['edited'] = request.args.get('new_user_edited')
|
# new_user_dict['edited'] = request.args.get('new_user_edited')
|
||||||
new_user_dict['password'] = request.args.get('new_user_password')
|
# new_user_dict['password'] = request.args.get('new_user_password')
|
||||||
return render_template("users_list.html", all_users=all_users, new_user=new_user_dict, admin_level=True)
|
# return render_template("users_list.html", all_users=all_users, new_user=new_user_dict, admin_level=True)
|
||||||
|
|
||||||
|
|
||||||
@settings.route("/settings/edit_user", methods=['POST'])
|
@settings.route("/settings/edit_user", methods=['POST'])
|
||||||
|
@ -155,15 +144,6 @@ def edit_user():
|
||||||
return redirect(url_for('settings.create_user', user_id=user_id))
|
return redirect(url_for('settings.create_user', user_id=user_id))
|
||||||
|
|
||||||
|
|
||||||
@settings.route("/settings/delete_user", methods=['POST'])
|
|
||||||
@login_required
|
|
||||||
@login_admin
|
|
||||||
def delete_user():
|
|
||||||
user_id = request.form.get('user_id')
|
|
||||||
Users.delete_user(user_id)
|
|
||||||
return redirect(url_for('settings.users_list'))
|
|
||||||
|
|
||||||
|
|
||||||
@settings.route("/settings/passivedns", methods=['GET'])
|
@settings.route("/settings/passivedns", methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
@login_read_only
|
@login_read_only
|
||||||
|
|
|
@ -1,139 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Server Management - AIL</title>
|
|
||||||
<link rel="icon" href="{{ url_for('static', filename='image/ail-icon.png') }}">
|
|
||||||
|
|
||||||
<!-- Core CSS -->
|
|
||||||
<link href="{{ url_for('static', filename='css/bootstrap4.min.css') }}" rel="stylesheet">
|
|
||||||
<link href="{{ url_for('static', filename='css/font-awesome.min.css') }}" rel="stylesheet">
|
|
||||||
<link href="{{ url_for('static', filename='css/dataTables.bootstrap4.min.css') }}" rel="stylesheet">
|
|
||||||
|
|
||||||
<!-- JS -->
|
|
||||||
<script src="{{ url_for('static', filename='js/jquery.js')}}"></script>
|
|
||||||
<script src="{{ url_for('static', filename='js/popper.min.js')}}"></script>
|
|
||||||
<script src="{{ url_for('static', filename='js/bootstrap4.min.js')}}"></script>
|
|
||||||
<script src="{{ url_for('static', filename='js/jquery.dataTables.min.js')}}"></script>
|
|
||||||
<script src="{{ url_for('static', filename='js/dataTables.bootstrap.min.js')}}"></script>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
{% include 'nav_bar.html' %}
|
|
||||||
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
{% include 'settings/menu_sidebar.html' %}
|
|
||||||
|
|
||||||
<div class="col-12 col-lg-10" id="core_content">
|
|
||||||
|
|
||||||
{% if new_user %}
|
|
||||||
<div class="text-center my-3 ">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
{% if new_user['edited']=='True' %}
|
|
||||||
<h5 class="card-title">User Edited</h5>
|
|
||||||
{% else %}
|
|
||||||
<h5 class="card-title">User Created</h5>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<p>User: {{new_user['email']}}</p>
|
|
||||||
<p>Password: {{new_user['password']}}</p>
|
|
||||||
<a href="{{url_for('settings.users_list')}}" class="btn btn-primary"><i class="fas fa-eye-slash"></i> Hide</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="table-responsive mt-1 table-hover table-borderless table-striped">
|
|
||||||
<table class="table">
|
|
||||||
<thead class="thead-dark">
|
|
||||||
<tr>
|
|
||||||
<th>Email</th>
|
|
||||||
<th>Role</th>
|
|
||||||
<th>Api Key</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="tbody_last_crawled">
|
|
||||||
{% for user in all_users %}
|
|
||||||
<tr>
|
|
||||||
<td>{{user['email']}}</td>
|
|
||||||
<td>{{user['role']}}</td>
|
|
||||||
<td>
|
|
||||||
<form action="{{ url_for('settings.new_token_user') }}" id="post_new_token" method=POST>
|
|
||||||
<span id="censored_key_{{loop.index0}}">
|
|
||||||
{{user['api_key'][:4]}}*********************************{{user['api_key'][-4:]}}
|
|
||||||
</span>
|
|
||||||
<span id="uncensored_key_{{loop.index0}}" style="display: none;">
|
|
||||||
{{user['api_key']}}
|
|
||||||
</span>
|
|
||||||
<input type="hidden" name="user_id" value="{{user['email']}}">
|
|
||||||
<button class="btn btn-outline-info ml-3 px-1 py-0" type="submit">
|
|
||||||
<i class="fas fa-random"></i>
|
|
||||||
</button>
|
|
||||||
<span class="btn btn-outline-secondary ml-1 px-1 py-0" id="btn_key_{{loop.index0}}" onclick="show_api_key({{loop.index0}})">
|
|
||||||
<i class="fas fa-eye"></i>
|
|
||||||
</span>
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="d-flex justify-content-start">
|
|
||||||
<form action="{{ url_for('settings.edit_user') }}" id="post_edit_user" method=POST>
|
|
||||||
<input type="hidden" name="user_id" value="{{user['email']}}">
|
|
||||||
<button class="btn btn-outline-primary ml-3 px-1 py-0" type="submit">
|
|
||||||
<i class="fas fa-pencil-alt"></i>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
<form action="{{ url_for('settings.delete_user') }}" id="post_delete_user" method=POST>
|
|
||||||
<input type="hidden" name="user_id" value="{{user['email']}}">
|
|
||||||
<button class="btn btn-outline-danger ml-3 px-1 py-0" type="submit">
|
|
||||||
<i class="fas fa-trash-alt"></i>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(document).ready(function(){
|
|
||||||
$("#nav_users_list").addClass("active");
|
|
||||||
$("#nav_user_management").removeClass("text-muted");
|
|
||||||
} );
|
|
||||||
|
|
||||||
function toggle_sidebar(){
|
|
||||||
if($('#nav_menu').is(':visible')){
|
|
||||||
$('#nav_menu').hide();
|
|
||||||
$('#side_menu').removeClass('border-right')
|
|
||||||
$('#side_menu').removeClass('col-lg-2')
|
|
||||||
$('#core_content').removeClass('col-lg-10')
|
|
||||||
}else{
|
|
||||||
$('#nav_menu').show();
|
|
||||||
$('#side_menu').addClass('border-right')
|
|
||||||
$('#side_menu').addClass('col-lg-2')
|
|
||||||
$('#core_content').addClass('col-lg-10')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function show_api_key(key_id) {
|
|
||||||
$('#censored_key_' + key_id).hide();
|
|
||||||
$('#btn_key_' + key_id).hide();
|
|
||||||
$('#uncensored_key_' + key_id).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -83,7 +83,7 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{% if admin_level %}
|
{% if acl_admin %}
|
||||||
<h5 class="d-flex text-muted w-100 py-2" id="nav_user_management">
|
<h5 class="d-flex text-muted w-100 py-2" id="nav_user_management">
|
||||||
<span>User Management</span>
|
<span>User Management</span>
|
||||||
</h5>
|
</h5>
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="{{url_for('settings.users_list')}}" id="nav_users_list">
|
<a class="nav-link" href="{{url_for('settings_b.users_list')}}" id="nav_users_list">
|
||||||
<i class="fas fa-users"></i>
|
<i class="fas fa-users"></i>
|
||||||
<span>Users List</span>
|
<span>Users List</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Users Settings - AIL</title>
|
||||||
|
<link rel="icon" href="{{ url_for('static', filename='image/ail-icon.png') }}">
|
||||||
|
|
||||||
|
<!-- Core CSS -->
|
||||||
|
<link href="{{ url_for('static', filename='css/bootstrap4.min.css') }}" rel="stylesheet">
|
||||||
|
<link href="{{ url_for('static', filename='css/font-awesome.min.css') }}" rel="stylesheet">
|
||||||
|
<link href="{{ url_for('static', filename='css/dataTables.bootstrap.min.css') }}" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- JS -->
|
||||||
|
<script src="{{ url_for('static', filename='js/jquery.js')}}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/popper.min.js')}}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/bootstrap4.min.js')}}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/jquery.dataTables.min.js')}}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/dataTables.bootstrap.min.js')}}"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
{% include 'nav_bar.html' %}
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
{% include 'settings/menu_sidebar.html' %}
|
||||||
|
<div class="col-12 col-lg-10" id="core_content">
|
||||||
|
|
||||||
|
{% if new_user %}
|
||||||
|
<div class="text-center my-3 ">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
{% if new_user['edited']=='True' %}
|
||||||
|
<h5 class="card-title">User Edited</h5>
|
||||||
|
{% else %}
|
||||||
|
<h5 class="card-title">User Created</h5>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p>User: {{new_user['email']}}</p>
|
||||||
|
<p>Password: {{new_user['password']}}</p>
|
||||||
|
<a href="{{url_for('settings.users_list')}}" class="btn btn-primary"><i class="fas fa-eye-slash"></i> Hide</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h3>AIL Users:</h3>
|
||||||
|
<table id="tableusers" class="table table-hover table-striped">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th>User</th>
|
||||||
|
<th>Role</th>
|
||||||
|
<th>Api Key</th>
|
||||||
|
<th></th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="tbody_last_crawled">
|
||||||
|
{% for user in meta['users'] %}
|
||||||
|
<tr>
|
||||||
|
<td>{{user['id']}}</td>
|
||||||
|
<td>{{user['role']}}</td>
|
||||||
|
<td>
|
||||||
|
<span id="censored_key_{{loop.index0}}">
|
||||||
|
{{user['api_key'][:4]}}*********************************{{user['api_key'][-4:]}}
|
||||||
|
</span>
|
||||||
|
<span id="uncensored_key_{{loop.index0}}" style="display: none;">
|
||||||
|
{{user['api_key']}}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a class="btn btn-outline-info ml-3 px-1 py-0" href="{{ url_for('settings_b.new_token_user', user_id=user['id']) }}">
|
||||||
|
<i class="fas fa-random"></i>
|
||||||
|
</a>
|
||||||
|
<span class="btn btn-outline-secondary ml-1 px-1 py-0" id="btn_key_{{loop.index0}}" onclick="show_api_key({{loop.index0}})">
|
||||||
|
<i class="fas fa-eye"></i>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="d-flex justify-content-start">
|
||||||
|
<form action="{{ url_for('settings.edit_user') }}" id="post_edit_user" method=POST>
|
||||||
|
<input type="hidden" name="user_id" value="{{user['id']}}">
|
||||||
|
<button class="btn btn-outline-primary ml-3 px-1 py-0" type="submit">
|
||||||
|
<i class="fas fa-pencil-alt"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<a class="btn btn-outline-danger ml-3 px-1 py-0" href="{{ url_for('settings_b.delete_user', user_id=user['id']) }}">
|
||||||
|
<i class="fas fa-trash-alt"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
$("#nav_users_list").addClass("active");
|
||||||
|
$("#nav_user_management").removeClass("text-muted");
|
||||||
|
$('#tableusers').DataTable({
|
||||||
|
"aLengthMenu": [[5, 10, 15, -1], [5, 10, 15, "All"]],
|
||||||
|
"iDisplayLength": 10,
|
||||||
|
"order": [[ 0, "asc" ]]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function toggle_sidebar(){
|
||||||
|
if($('#nav_menu').is(':visible')){
|
||||||
|
$('#nav_menu').hide();
|
||||||
|
$('#side_menu').removeClass('border-right')
|
||||||
|
$('#side_menu').removeClass('col-lg-2')
|
||||||
|
$('#core_content').removeClass('col-lg-10')
|
||||||
|
}else{
|
||||||
|
$('#nav_menu').show();
|
||||||
|
$('#side_menu').addClass('border-right')
|
||||||
|
$('#side_menu').addClass('col-lg-2')
|
||||||
|
$('#core_content').addClass('col-lg-10')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function show_api_key(key_id) {
|
||||||
|
$('#censored_key_' + key_id).hide();
|
||||||
|
$('#btn_key_' + key_id).hide();
|
||||||
|
$('#uncensored_key_' + key_id).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in New Issue