From 9051c4081bac30466aab289ef4f7b8b22f9bd5a3 Mon Sep 17 00:00:00 2001 From: Terrtia Date: Wed, 25 Sep 2019 08:58:18 +0200 Subject: [PATCH] fix: [url_prefix] add root blueprint, fix:#403 --- var/www/Flask_server.py | 139 +++--------------- var/www/blueprints/root.py | 140 +++++++++++++++++++ var/www/templates/change_password.html | 2 +- var/www/templates/login.html | 2 +- var/www/templates/nav_bar.html | 2 +- var/www/templates/settings/menu_sidebar.html | 2 +- 6 files changed, 166 insertions(+), 121 deletions(-) create mode 100644 var/www/blueprints/root.py diff --git a/var/www/Flask_server.py b/var/www/Flask_server.py index 4575ddb9..0b6b7fa6 100755 --- a/var/www/Flask_server.py +++ b/var/www/Flask_server.py @@ -2,7 +2,6 @@ # -*-coding:UTF-8 -* import os -import re import sys import ssl import json @@ -17,15 +16,11 @@ import configparser from flask import Flask, render_template, jsonify, request, Request, Response, session, redirect, url_for from flask_login import LoginManager, current_user, login_user, logout_user, login_required -import bcrypt - import flask import importlib from os.path import join sys.path.append(os.path.join(os.environ['AIL_BIN'], 'packages/')) sys.path.append('./modules/') -import Paste -from Date import Date from User import User @@ -34,9 +29,8 @@ from pytaxonomies import Taxonomies # Import config import Flask_config -# Import Role_Manager -from Role_Manager import create_user_db, check_password_strength, check_user_role_integrity -from Role_Manager import login_admin, login_analyst +# Import Blueprint +from blueprints.root import root Flask_dir = os.environ['AIL_FLASK'] @@ -92,19 +86,25 @@ Flask_config.app = Flask(__name__, static_url_path=baseUrl+'/static/') app = Flask_config.app app.config['MAX_CONTENT_LENGTH'] = 900 * 1024 * 1024 +# ========= BLUEPRINT =========# +app.register_blueprint(root, url_prefix=baseUrl) +# ========= =========# + # ========= session ======== app.secret_key = str(random.getrandbits(256)) login_manager = LoginManager() -login_manager.login_view = 'login' +login_manager.login_view = 'root.login' login_manager.init_app(app) +print() + # ========= LOGIN MANAGER ======== @login_manager.user_loader def load_user(user_id): return User.get(user_id) -# ========= HEADER GENERATION ======== +# ========= HEADER GENERATION ======== DEPRECATED # Get headers items that should be ignored (not displayed) toIgnoreModule = set() @@ -182,119 +182,24 @@ def add_header(response): response.headers['Cache-Control'] = 'private, max-age=0' return response -# @app.route('/test', methods=['GET']) -# def test(): -# for rule in app.url_map.iter_rules(): -# print(rule) -# return 'o' - # ========== ROUTES ============ -@app.route('/login', methods=['POST', 'GET']) -def login(): - current_ip = request.remote_addr - login_failed_ip = r_cache.get('failed_login_ip:{}'.format(current_ip)) - - # brute force by ip - if login_failed_ip: - login_failed_ip = int(login_failed_ip) - if login_failed_ip >= 5: - error = 'Max Connection Attempts reached, Please wait {}s'.format(r_cache.ttl('failed_login_ip:{}'.format(current_ip))) - return render_template("login.html", error=error) - - if request.method == 'POST': - username = request.form.get('username') - password = request.form.get('password') - #next_page = request.form.get('next_page') - - if username is not None: - user = User.get(username) - login_failed_user_id = r_cache.get('failed_login_user_id:{}'.format(username)) - # brute force by user_id - if login_failed_user_id: - login_failed_user_id = int(login_failed_user_id) - if login_failed_user_id >= 5: - error = 'Max Connection Attempts reached, Please wait {}s'.format(r_cache.ttl('failed_login_user_id:{}'.format(username))) - return render_template("login.html", error=error) - - 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')) - # login failed - else: - # set brute force protection - #logger.warning("Login failed, ip={}, username={}".format(current_ip, username)) - r_cache.incr('failed_login_ip:{}'.format(current_ip)) - r_cache.expire('failed_login_ip:{}'.format(current_ip), 300) - r_cache.incr('failed_login_user_id:{}'.format(username)) - r_cache.expire('failed_login_user_id:{}'.format(username), 300) - # - - error = 'Password Incorrect' - return render_template("login.html", error=error) - - return 'please provide a valid username' - - else: - #next_page = request.args.get('next') - error = request.args.get('error') - return render_template("login.html" , error=error) - -@app.route('/change_password', methods=['POST', 'GET']) -@login_required -def change_password(): - password1 = request.form.get('password1') - password2 = request.form.get('password2') - error = request.args.get('error') - - if error: - return render_template("change_password.html", error=error) - - if current_user.is_authenticated and password1!=None: - if password1==password2: - if check_password_strength(password1): - user_id = current_user.get_id() - create_user_db(user_id , password1, update=True) - return redirect(url_for('dashboard.index')) - else: - error = 'Incorrect password' - return render_template("change_password.html", error=error) - else: - error = "Passwords don't match" - return render_template("change_password.html", error=error) - else: - error = 'Please choose a new password' - return render_template("change_password.html", error=error) - -@app.route('/logout') -@login_required -def logout(): - logout_user() - return redirect(url_for('login')) - -# role error template -@app.route('/role', methods=['POST', 'GET']) -@login_required -def role(): - return render_template("error/403.html"), 403 - -@app.route('/searchbox/') -@login_required -@login_analyst -def searchbox(): - return render_template("searchbox.html") +#@app.route('/endpoints') +#def endpoints(): +# for rule in app.url_map.iter_rules(): +# str_endpoint = str(rule) +# if len(str_endpoint)>5: +# if str_endpoint[0:5]=='/api/': ## add baseUrl ??? +# print(str_endpoint) +# #print(rule.endpoint) #internal endpoint name +# #print(rule.methods) +# return 'ok' # ========== ERROR HANDLER ============ @app.errorhandler(405) def _handle_client_error(e): - if request.path.startswith('/api/'): + if request.path.startswith('/api/'): ## # TODO: add baseUrl res_dict = {"status": "error", "reason": "Method Not Allowed: The method is not allowed for the requested URL"} anchor_id = request.path[8:] anchor_id = anchor_id.replace('/', '_') @@ -306,7 +211,7 @@ def _handle_client_error(e): @app.errorhandler(404) def error_page_not_found(e): - if request.path.startswith('/api/'): + if request.path.startswith('/api/'): ## # TODO: add baseUrl return Response(json.dumps({"status": "error", "reason": "404 Not Found"}, indent=2, sort_keys=True), mimetype='application/json'), 404 else: # avoid endpoint enumeration diff --git a/var/www/blueprints/root.py b/var/www/blueprints/root.py new file mode 100644 index 00000000..83446dc6 --- /dev/null +++ b/var/www/blueprints/root.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python3 +# -*-coding:UTF-8 -* + +''' + Blueprint Flask: root endpoints: login, ... +''' + +import os +import sys + +from flask import Flask, render_template, jsonify, request, Blueprint, redirect, url_for, Response +from flask_login import login_required, current_user, login_user, logout_user + +sys.path.append('modules') +import Flask_config + +# Import Role_Manager +from Role_Manager import create_user_db, check_password_strength, check_user_role_integrity +from Role_Manager import login_admin, login_analyst + +sys.path.append(os.path.join(os.environ['AIL_BIN'], 'packages')) +from User import User + +r_cache = Flask_config.r_cache +r_serv_db = Flask_config.r_serv_db +r_serv_tags = Flask_config.r_serv_tags + +# ============ BLUEPRINT ============ + +root = Blueprint('root', __name__, template_folder='templates') + +# ============ VARIABLES ============ + + + +# ============ FUNCTIONS ============ + + + +# ============= ROUTES ============== +@root.route('/login', methods=['POST', 'GET']) +def login(): + + current_ip = request.remote_addr + login_failed_ip = r_cache.get('failed_login_ip:{}'.format(current_ip)) + + # brute force by ip + if login_failed_ip: + login_failed_ip = int(login_failed_ip) + if login_failed_ip >= 5: + error = 'Max Connection Attempts reached, Please wait {}s'.format(r_cache.ttl('failed_login_ip:{}'.format(current_ip))) + return render_template("login.html", error=error) + + if request.method == 'POST': + username = request.form.get('username') + password = request.form.get('password') + #next_page = request.form.get('next_page') + + if username is not None: + user = User.get(username) + login_failed_user_id = r_cache.get('failed_login_user_id:{}'.format(username)) + # brute force by user_id + if login_failed_user_id: + login_failed_user_id = int(login_failed_user_id) + if login_failed_user_id >= 5: + error = 'Max Connection Attempts reached, Please wait {}s'.format(r_cache.ttl('failed_login_user_id:{}'.format(username))) + return render_template("login.html", error=error) + + 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('root.change_password')) + else: + return redirect(url_for('dashboard.index')) + # login failed + else: + # set brute force protection + #logger.warning("Login failed, ip={}, username={}".format(current_ip, username)) + r_cache.incr('failed_login_ip:{}'.format(current_ip)) + r_cache.expire('failed_login_ip:{}'.format(current_ip), 300) + r_cache.incr('failed_login_user_id:{}'.format(username)) + r_cache.expire('failed_login_user_id:{}'.format(username), 300) + # + + error = 'Password Incorrect' + return render_template("login.html", error=error) + + return 'please provide a valid username' + + else: + #next_page = request.args.get('next') + error = request.args.get('error') + return render_template("login.html" , error=error) + +@root.route('/change_password', methods=['POST', 'GET']) +@login_required +def change_password(): + password1 = request.form.get('password1') + password2 = request.form.get('password2') + error = request.args.get('error') + + if error: + return render_template("change_password.html", error=error) + + if current_user.is_authenticated and password1!=None: + if password1==password2: + if check_password_strength(password1): + user_id = current_user.get_id() + create_user_db(user_id , password1, update=True) + return redirect(url_for('dashboard.index')) + else: + error = 'Incorrect password' + return render_template("change_password.html", error=error) + else: + error = "Passwords don't match" + return render_template("change_password.html", error=error) + else: + error = 'Please choose a new password' + return render_template("change_password.html", error=error) + +@root.route('/logout') +@login_required +def logout(): + logout_user() + return redirect(url_for('root.login')) + +# role error template +@root.route('/role', methods=['POST', 'GET']) +@login_required +def role(): + return render_template("error/403.html"), 403 + +@root.route('/searchbox/') +@login_required +@login_analyst +def searchbox(): + return render_template("searchbox.html") diff --git a/var/www/templates/change_password.html b/var/www/templates/change_password.html index 7560d8df..695db7c8 100644 --- a/var/www/templates/change_password.html +++ b/var/www/templates/change_password.html @@ -61,7 +61,7 @@ -
+

Change Password

diff --git a/var/www/templates/login.html b/var/www/templates/login.html index 43a3ee36..f4ee664b 100644 --- a/var/www/templates/login.html +++ b/var/www/templates/login.html @@ -66,7 +66,7 @@ - +

Please sign in

diff --git a/var/www/templates/nav_bar.html b/var/www/templates/nav_bar.html index f4ef06eb..7621f10a 100644 --- a/var/www/templates/nav_bar.html +++ b/var/www/templates/nav_bar.html @@ -34,7 +34,7 @@ Server Management diff --git a/var/www/templates/settings/menu_sidebar.html b/var/www/templates/settings/menu_sidebar.html index 7732bee5..ce63965f 100644 --- a/var/www/templates/settings/menu_sidebar.html +++ b/var/www/templates/settings/menu_sidebar.html @@ -28,7 +28,7 @@