mirror of https://github.com/CIRCL/AIL-framework
chg: [user_management UI] edit my_profile + renew api tokens
parent
3fe9d14e9f
commit
9c2d290580
|
@ -59,7 +59,7 @@ Redis and ARDB overview
|
||||||
| | | |
|
| | | |
|
||||||
| user:tokens | **token** | **user id** |
|
| user:tokens | **token** | **user id** |
|
||||||
| | | |
|
| | | |
|
||||||
| user_metadata:**user id** | **user token** | **token** |
|
| user_metadata:**user id** | token | **token** |
|
||||||
| | change_passwd | **boolean** |
|
| | change_passwd | **boolean** |
|
||||||
|
|
||||||
| Set Key | Value |
|
| Set Key | Value |
|
||||||
|
|
|
@ -28,6 +28,7 @@ def create_user_db(username_id , password, default=False, role=None, update=Fals
|
||||||
else:
|
else:
|
||||||
if default:
|
if default:
|
||||||
r_serv_db.hset('user_metadata:{}'.format(username_id), 'change_passwd', True)
|
r_serv_db.hset('user_metadata:{}'.format(username_id), 'change_passwd', True)
|
||||||
|
r_serv_db.hset('user_metadata:{}'.format(username_id), 'role', role)
|
||||||
if role:
|
if role:
|
||||||
if role in get_all_role():
|
if role in get_all_role():
|
||||||
r_serv_db.sadd('user_role:{}'.format(role), username_id)
|
r_serv_db.sadd('user_role:{}'.format(role), username_id)
|
||||||
|
@ -55,6 +56,7 @@ if __name__ == "__main__":
|
||||||
# create user token
|
# create user token
|
||||||
token = secrets.token_urlsafe(41)
|
token = secrets.token_urlsafe(41)
|
||||||
r_serv_db.hset('user:tokens', token, username)
|
r_serv_db.hset('user:tokens', token, username)
|
||||||
|
r_serv_db.hset('user_metadata:{}'.format(username), 'token', token)
|
||||||
|
|
||||||
default_passwd_file = os.path.join(os.environ['AIL_HOME'], 'DEFAULT_PASSWORD')
|
default_passwd_file = os.path.join(os.environ['AIL_HOME'], 'DEFAULT_PASSWORD')
|
||||||
to_write_str = '# Password Generated by default\n# This file is deleted after the first login\n#\nemail=admin@admin.test\npassword='
|
to_write_str = '# Password Generated by default\n# This file is deleted after the first login\n#\nemail=admin@admin.test\npassword='
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
Flask functions and routes for the settings modules page
|
Flask functions and routes for the settings modules page
|
||||||
'''
|
'''
|
||||||
from flask import Flask, render_template, jsonify, request, Blueprint, redirect, url_for
|
from flask import Flask, render_template, jsonify, request, Blueprint, redirect, url_for
|
||||||
from flask_login import login_required
|
from flask_login import login_required, current_user
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import secrets
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
import git_status
|
import git_status
|
||||||
|
@ -35,6 +36,14 @@ def one():
|
||||||
#def get_v1.5_update_tags_backgroud_status():
|
#def get_v1.5_update_tags_backgroud_status():
|
||||||
# return '38%'
|
# return '38%'
|
||||||
|
|
||||||
|
def generate_new_token(user_id):
|
||||||
|
# create user token
|
||||||
|
current_token = r_serv_db.hget('user_metadata:{}'.format(user_id), 'token')
|
||||||
|
r_serv_db.hdel('user:tokens', current_token)
|
||||||
|
token = secrets.token_urlsafe(41)
|
||||||
|
r_serv_db.hset('user:tokens', token, user_id)
|
||||||
|
r_serv_db.hset('user_metadata:{}'.format(user_id), 'token', token)
|
||||||
|
|
||||||
def get_git_metadata():
|
def get_git_metadata():
|
||||||
dict_git = {}
|
dict_git = {}
|
||||||
dict_git['current_branch'] = git_status.get_current_branch()
|
dict_git['current_branch'] = git_status.get_current_branch()
|
||||||
|
@ -72,6 +81,14 @@ def get_update_metadata():
|
||||||
dict_update['current_background_script_stat'] = r_serv_db.get('ail:current_background_script_stat')
|
dict_update['current_background_script_stat'] = r_serv_db.get('ail:current_background_script_stat')
|
||||||
|
|
||||||
return dict_update
|
return dict_update
|
||||||
|
|
||||||
|
def get_user_metadata(user_id):
|
||||||
|
user_metadata = {}
|
||||||
|
user_metadata['email'] = user_id
|
||||||
|
user_metadata['role'] = r_serv_db.hget('user_metadata:{}'.format(user_id), 'role')
|
||||||
|
user_metadata['api_key'] = r_serv_db.hget('user_metadata:{}'.format(user_id), 'token')
|
||||||
|
return user_metadata
|
||||||
|
|
||||||
# ============= ROUTES ==============
|
# ============= ROUTES ==============
|
||||||
|
|
||||||
@settings.route("/settings/", methods=['GET'])
|
@settings.route("/settings/", methods=['GET'])
|
||||||
|
@ -81,10 +98,21 @@ def settings_page():
|
||||||
current_version = r_serv_db.get('ail:version')
|
current_version = r_serv_db.get('ail:version')
|
||||||
update_metadata = get_update_metadata()
|
update_metadata = get_update_metadata()
|
||||||
|
|
||||||
|
|
||||||
return render_template("settings_index.html", git_metadata=git_metadata,
|
return render_template("settings_index.html", git_metadata=git_metadata,
|
||||||
current_version=current_version)
|
current_version=current_version)
|
||||||
|
|
||||||
|
@settings.route("/settings/edit_profile", methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
def edit_profile():
|
||||||
|
user_metadata = get_user_metadata(current_user.get_id())
|
||||||
|
return render_template("edit_profile.html", user_metadata=user_metadata)
|
||||||
|
|
||||||
|
@settings.route("/settings/new_token", methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
def new_token():
|
||||||
|
generate_new_token(current_user.get_id())
|
||||||
|
return redirect(url_for('settings.edit_profile'))
|
||||||
|
|
||||||
|
|
||||||
@settings.route("/settings/get_background_update_stats_json", methods=['GET'])
|
@settings.route("/settings/get_background_update_stats_json", methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
<!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">
|
||||||
|
|
||||||
|
<div class="card mb-3 mt-1">
|
||||||
|
<div class="card-header text-white bg-dark pb-1">
|
||||||
|
<h5 class="card-title">AIL-framework Status :</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xl-6">
|
||||||
|
<div class="card text-center border-secondary">
|
||||||
|
<div class="card-body px-1 py-0">
|
||||||
|
<table class="table table-sm">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Email</td>
|
||||||
|
<td>{{user_metadata['email']}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Role</td>
|
||||||
|
<td>{{user_metadata['role']}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>API Key</td>
|
||||||
|
<td>
|
||||||
|
{{user_metadata['api_key']}}
|
||||||
|
<a class="ml-3" href="{{url_for('settings.new_token')}}"><i class="fa fa-random"></i></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
$("#nav_edit_profile").addClass("active");
|
||||||
|
$("#nav_my_profile").removeClass("text-muted");
|
||||||
|
} );
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</html>
|
|
@ -142,7 +142,8 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
$("#page-options").addClass("active");
|
$("#nav_server_status").addClass("active");
|
||||||
|
$("#nav_server").removeClass("text-muted");
|
||||||
} );
|
} );
|
||||||
|
|
||||||
function toggle_sidebar(){
|
function toggle_sidebar(){
|
||||||
|
|
|
@ -5,9 +5,55 @@
|
||||||
<span>Toggle Sidebar</span>
|
<span>Toggle Sidebar</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<nav class="navbar navbar-expand navbar-light bg-light flex-md-column flex-row align-items-start py-2" id="nav_menu">
|
<nav class="navbar navbar-expand navbar-light bg-light flex-md-column flex-row align-items-start py-2">
|
||||||
<h5 class="d-flex text-muted w-100">
|
<h5 class="d-flex text-muted w-100" id="nav_server">
|
||||||
<span>Diagnostic</span>
|
<span>Diagnostic</span>
|
||||||
</h5>
|
</h5>
|
||||||
|
<ul class="nav flex-md-column flex-row navbar-nav justify-content-between w-100"> <!--nav-pills-->
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{url_for('hashDecoded.hashDecoded_page')}}" id="nav_server_status">
|
||||||
|
<i class="fas fa-tools"></i>
|
||||||
|
<span>Server Status</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<nav class="navbar navbar-expand navbar-light bg-light flex-md-column flex-row align-items-start py-2" id="nav_profile">
|
||||||
|
<h5 class="d-flex text-muted w-100" id="nav_my_profile">
|
||||||
|
<span>My Profile</span>
|
||||||
|
</h5>
|
||||||
|
<ul class="nav flex-md-column flex-row navbar-nav justify-content-between w-100"> <!--nav-pills-->
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{url_for('settings.edit_profile')}}" id="nav_edit_profile">
|
||||||
|
<i class="fas fa-user-edit"></i>
|
||||||
|
<span>My Profile</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{url_for('change_password')}}" id="nav_dashboard">
|
||||||
|
<i class="fas fa-key"></i>
|
||||||
|
<span>Change Password</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<nav class="navbar navbar-expand navbar-light bg-light flex-md-column flex-row align-items-start py-2" id="nav_users">
|
||||||
|
<h5 class="d-flex text-muted w-100">
|
||||||
|
<span>User Management</span>
|
||||||
|
</h5>
|
||||||
|
<ul class="nav flex-md-column flex-row navbar-nav justify-content-between w-100"> <!--nav-pills-->
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{url_for('hashDecoded.hashDecoded_page')}}" id="nav_dashboard">
|
||||||
|
<i class="fas fa-user-plus"></i>
|
||||||
|
<span>Create User</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{url_for('hashDecoded.hashDecoded_page')}}" id="nav_dashboard">
|
||||||
|
<i class="fas fa-users"></i>
|
||||||
|
<span>Users List</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue