fix: [user_management] fix tokens duplicate + check user_acl_integrity + add login errors messages

This commit is contained in:
Terrtia 2019-06-20 15:49:40 +02:00
parent a9837c6e27
commit bb65179e50
No known key found for this signature in database
GPG key ID: 1E1B1F50D84613D0
6 changed files with 60 additions and 21 deletions

View file

@ -63,12 +63,10 @@ Redis and ARDB overview
| | | |
| user_metadata:**user id** | token | **token** |
| | change_passwd | **boolean** |
| | role | **role** |
| Set Key | Value |
| ------ | ------ |
| user:request_password_change | **user id** |
| user:admin | **user id** |
| | |
| user_role:**role** | **user id** |

View file

@ -42,7 +42,16 @@ class User(UserMixin):
def get(self_class, id):
return self_class(id)
def user_is_anonymous(self):
if self.id == "__anonymous__":
return True
else:
return False
def check_password(self, password):
if self.user_is_anonymous():
return False
password = password.encode()
hashed_password = self.r_serv_db.hget('user:all', self.id).encode()
if bcrypt.checkpw(password, hashed_password):

View file

@ -33,7 +33,7 @@ from pytaxonomies import Taxonomies
import Flask_config
# Import Role_Manager
from Role_Manager import create_user_db, check_password_strength
from Role_Manager import create_user_db, check_password_strength, check_user_role_integrity
from Role_Manager import login_admin, login_analyst
# CONFIG #
@ -162,19 +162,24 @@ def login():
if username is not None:
user = User.get(username)
if user and user.check_password(password):
if not check_user_role_integrity(user.get_id()):
error = 'Incorrect User ACL, Please contact your administrator'
return render_template("login.html", error=error)
login_user(user) ## TODO: use remember me ?
if user.request_password_change():
return redirect(url_for('change_password'))
else:
return redirect(url_for('dashboard.index'))
else:
return 'incorrect password'
error = 'Password Incorrect'
return render_template("login.html", error=error)
return 'none'
return 'please provide a valid username'
else:
#next_page = request.args.get('next')
return render_template("login.html")
error = request.args.get('error')
return render_template("login.html" , error=error)
@app.route('/change_password', methods=['POST', 'GET'])
@login_required

View file

@ -67,6 +67,14 @@ def login_analyst(func):
###############################################################
###############################################################
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_default_admin_token():
if r_serv_db.exists('user_metadata:admin@admin.test'):
return r_serv_db.hget('user_metadata:admin@admin.test', 'token')
@ -78,9 +86,7 @@ def create_user_db(username_id , password, default=False, role=None, update=Fals
password_hash = hashing_password(password)
# create user token
token = secrets.token_urlsafe(41)
r_serv_db.hset('user:tokens', token, username_id)
r_serv_db.hset('user_metadata:{}'.format(username_id), 'token', token)
generate_new_token(username_id)
if update:
r_serv_db.hdel('user_metadata:{}'.format(username_id), 'change_passwd')
@ -150,5 +156,29 @@ def get_all_user_role(user_role):
current_role_val = get_role_level(user_role)
return r_serv_db.zrange('ail:all_role', 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:all_role', 0, current_role_val -2)
else:
return []
def get_user_role_by_range(inf, sup):
return r_serv_db.zrange('ail:all_role', inf, sup)
def get_user_role(user_id):
return r_serv_db.hget('user_metadata:{}'.format(user_id), 'role')
def check_user_role_integrity(user_id):
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('user_role:{}'.format(role), user_id):
res = False
upper_role = get_all_user_upper_role(user_role)
for role in upper_role:
if r_serv_db.sismember('user_role:{}'.format(role), user_id):
res = False
return res

View file

@ -8,7 +8,7 @@ from flask import Flask, render_template, jsonify, request, Blueprint, redirect,
from flask_login import login_required, current_user
from Role_Manager import login_admin, login_analyst
from Role_Manager import create_user_db, edit_user_db, delete_user_db, check_password_strength
from Role_Manager import create_user_db, edit_user_db, delete_user_db, check_password_strength, generate_new_token
import json
import secrets
@ -44,14 +44,6 @@ def check_email(email):
else:
return False
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():
dict_git = {}
dict_git['current_branch'] = git_status.get_current_branch()

View file

@ -72,8 +72,13 @@
<label for="inputEmail" class="sr-only">Email address</label>
<input type="email" id="inputEmail" name="username" class="form-control" placeholder="Email address" required autofocus>
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" id="inputPassword" name="password" class="form-control" placeholder="Password" required>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
<input type="password" id="inputPassword" name="password" class="form-control {% if error %}is-invalid{% endif %}" placeholder="Password" required>
{% if error %}
<div class="invalid-feedback">
{{error}}
</div>
{% endif %}
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>