chg: [user_management] create + check user password

pull/359/head
Terrtia 2019-05-03 16:52:05 +02:00
parent 1ab1a55a4f
commit 64ff94ce5f
No known key found for this signature in database
GPG Key ID: 1E1B1F50D84613D0
7 changed files with 151 additions and 20 deletions

View File

@ -52,6 +52,18 @@ Redis and ARDB overview
| ail:current_background_script | **name of the background script currently executed** | | ail:current_background_script | **name of the background script currently executed** |
| ail:current_background_script_stat | **progress in % of the background script** | | ail:current_background_script_stat | **progress in % of the background script** |
##### User Management:
| Key | Field | Value |
| ------ | ------ | ------ |
| user:all | **user id** | **password hash** |
| Key | Value |
| ------ | ------ |
| user:request_password_change | **user id** |
| user:admin | **user id** |
| | |
| user_role:**role** | **user id** |
## DB2 - TermFreq: ## DB2 - TermFreq:
##### Set: ##### Set:

View File

@ -1,36 +1,65 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*-coding:UTF-8 -* # -*-coding:UTF-8 -*
import os
import redis import redis
import bcrypt
import configparser
from flask_login import UserMixin from flask_login import UserMixin
class User(UserMixin): class User(UserMixin):
def __init__(self, id): def __init__(self, id):
self.id = 'abcdef'
configfile = os.path.join(os.environ['AIL_BIN'], 'packages/config.cfg')
if not os.path.exists(configfile):
raise Exception('Unable to find the configuration file. \
Did you set environment variables? \
Or activate the virtualenv.')
cfg = configparser.ConfigParser()
cfg.read(configfile)
self.r_serv_db = redis.StrictRedis(
host=cfg.get("ARDB_DB", "host"),
port=cfg.getint("ARDB_DB", "port"),
db=cfg.getint("ARDB_DB", "db"),
decode_responses=True)
if self.r_serv_db.hexists('user:all', id):
self.id = id
else:
self.id = "__anonymous__"
# return True or False # return True or False
#def is_authenticated(): #def is_authenticated():
# return True or False
#def is_active():
# return True or False # return True or False
#def is_anonymous(): #def is_anonymous():
@classmethod @classmethod
def get(self_class, id): def get(self_class, id):
print(id)
return self_class(id) return self_class(id)
def check_password(self, password): def check_password(self, password):
password = password.encode()
print(self.id) print(self.id)
if password=='admin': hashed_password = self.r_serv_db.hget('user:all', self.id).encode()
print('password ok') if bcrypt.checkpw(password, hashed_password):
print('password correct')
return True return True
else: else:
return False return False
def set_password(self): def request_password_change(self):
return True if self.r_serv_db.sismember('user:request_password_change', self.id):
return True
else:
return False
def is_in_role(self, role):
if self.r_serv_db.sismember('user_role:{}'.format(role), self.id):
return True
else:
return False

View File

@ -47,6 +47,7 @@ texttable
flask flask
flask-login flask-login
bcrypt
#DomainClassifier #DomainClassifier
DomainClassifier DomainClassifier

View File

@ -11,6 +11,8 @@ import calendar
from flask import Flask, render_template, jsonify, request, Request, session, redirect, url_for from flask import Flask, render_template, jsonify, request, Request, session, redirect, url_for
from flask_login import LoginManager, current_user, login_user, logout_user, login_required from flask_login import LoginManager, current_user, login_user, logout_user, login_required
import bcrypt
import flask import flask
import importlib import importlib
import os import os
@ -28,6 +30,41 @@ from pytaxonomies import Taxonomies
# Import config # Import config
import Flask_config import Flask_config
def flask_init():
int_user_management()
def int_user_management():
# # TODO: check for admin account
# check if an account exists
if not r_serv_db.hexists('user:all'):
password = 'admin@admin.test'
create_user_db('admin', password, default=True)
def hashing_password(bytes_password):
hashed = bcrypt.hashpw(bytes_password, bcrypt.gensalt())
return hashed
def verify_password(id, bytes_password):
hashed_password = r_serv_db.hget('user:all', id)
if bcrypt.checkpw(password, hashed):
return True
else:
return False
def create_user_db(username_id , password, default=False):
## TODO: validate username
## TODO: validate password
if username_id == '__anonymous__':
## TODO: return 500
return 'ERROR'
password = password.encode()
password_hash = hashing_password(password)
r_serv_db.hset('user:all', username_id, password_hash)
if default:
r_serv_db.set('user:request_password_change', username_id)
# CONFIG # # CONFIG #
cfg = Flask_config.cfg cfg = Flask_config.cfg
baseUrl = cfg.get("Flask", "baseurl") baseUrl = cfg.get("Flask", "baseurl")
@ -35,6 +72,20 @@ baseUrl = baseUrl.replace('/', '')
if baseUrl != '': if baseUrl != '':
baseUrl = '/'+baseUrl baseUrl = '/'+baseUrl
# ========= REDIS =========#
r_serv_db = redis.StrictRedis(
host=cfg.get("ARDB_DB", "host"),
port=cfg.getint("ARDB_DB", "port"),
db=cfg.getint("ARDB_DB", "db"),
decode_responses=True)
r_serv_tags = redis.StrictRedis(
host=cfg.get("ARDB_Tags", "host"),
port=cfg.getint("ARDB_Tags", "port"),
db=cfg.getint("ARDB_Tags", "db"),
decode_responses=True)
# ========= =========#
Flask_config.app = Flask(__name__, static_url_path=baseUrl+'/static/') Flask_config.app = Flask(__name__, static_url_path=baseUrl+'/static/')
app = Flask_config.app app = Flask_config.app
app.config['MAX_CONTENT_LENGTH'] = 900 * 1024 * 1024 app.config['MAX_CONTENT_LENGTH'] = 900 * 1024 * 1024
@ -152,6 +203,8 @@ def login():
#print(user.is_authenticated) #print(user.is_authenticated)
if user and user.check_password(password): if user and user.check_password(password):
login_user(user) ## TODO: use remember me ? login_user(user) ## TODO: use remember me ?
#print(user.request_password_change())
print(user.is_active)
return redirect(url_for('dashboard.index')) return redirect(url_for('dashboard.index'))
else: else:
return 'incorrect password' return 'incorrect password'
@ -167,7 +220,27 @@ def login():
@login_required @login_required
def logout(): def logout():
logout_user() logout_user()
return redirect(url_for('dashboard.index')) return redirect(url_for('login'))
@app.route('/create_user')
@login_required
def create_user():
username = request.form.get('username')
password = request.form.get('password')
#role = request.form.get('role') ## TODO: create role
## TODO: validate username
## TODO: validate password
username = 'admin@admin.test'
password = 'admin'
if r_serv_db.hexists('user:all', username):
return 'this id is not available'
create_user_db(username, password)
return 'True'
@app.route('/searchbox/') @app.route('/searchbox/')
@ -176,11 +249,6 @@ def searchbox():
# ========== INITIAL taxonomies ============ # ========== INITIAL taxonomies ============
r_serv_tags = redis.StrictRedis(
host=cfg.get("ARDB_Tags", "host"),
port=cfg.getint("ARDB_Tags", "port"),
db=cfg.getint("ARDB_Tags", "db"),
decode_responses=True)
# add default ail taxonomies # add default ail taxonomies
r_serv_tags.sadd('active_taxonomies', 'infoleak') r_serv_tags.sadd('active_taxonomies', 'infoleak')
r_serv_tags.sadd('active_taxonomies', 'gdpr') r_serv_tags.sadd('active_taxonomies', 'gdpr')
@ -195,11 +263,6 @@ for tag in taxonomies.get('fpf').machinetags():
r_serv_tags.sadd('active_tag_fpf', tag) r_serv_tags.sadd('active_tag_fpf', tag)
# ========== INITIAL tags auto export ============ # ========== INITIAL tags auto export ============
r_serv_db = redis.StrictRedis(
host=cfg.get("ARDB_DB", "host"),
port=cfg.getint("ARDB_DB", "port"),
db=cfg.getint("ARDB_DB", "db"),
decode_responses=True)
infoleak_tags = taxonomies.get('infoleak').machinetags() infoleak_tags = taxonomies.get('infoleak').machinetags()
infoleak_automatic_tags = [] infoleak_automatic_tags = []
for tag in taxonomies.get('infoleak').machinetags(): for tag in taxonomies.get('infoleak').machinetags():

View File

@ -0,0 +1,17 @@
#!/usr/bin/env python3
# -*-coding:UTF-8 -*
from functools import wraps
from flask_login import LoginManager, current_user, login_user, logout_user, login_required
from flask import request
def login_required(role="ANY"):
@wraps(role)
def decorated_view(*args, **kwargs):
if not current_user.is_authenticated:
return current_app.login_manager.unauthorized()
elif (not current_user.is_in_role(role)) and (role != "ANY"):
return login_manager.unauthorized()
return func(*args, **kwargs)
return decorated_view

View File

@ -13,6 +13,7 @@ import flask
from Date import Date from Date import Date
from flask import Flask, render_template, jsonify, request, Blueprint, url_for from flask import Flask, render_template, jsonify, request, Blueprint, url_for
from flask_login import login_required
# ============ VARIABLES ============ # ============ VARIABLES ============
import Flask_config import Flask_config
@ -109,10 +110,12 @@ def datetime_from_utc_to_local(utc_str):
# ============ ROUTES ============ # ============ ROUTES ============
@dashboard.route("/_logs") @dashboard.route("/_logs")
@login_required
def logs(): def logs():
return flask.Response(event_stream(), mimetype="text/event-stream") return flask.Response(event_stream(), mimetype="text/event-stream")
@dashboard.route("/_get_last_logs_json") @dashboard.route("/_get_last_logs_json")
@login_required
def get_last_logs_json(): def get_last_logs_json():
date = datetime.datetime.now().strftime("%Y%m%d") date = datetime.datetime.now().strftime("%Y%m%d")
@ -154,11 +157,13 @@ def get_last_logs_json():
@dashboard.route("/_stuff", methods=['GET']) @dashboard.route("/_stuff", methods=['GET'])
@login_required
def stuff(): def stuff():
return jsonify(row1=get_queues(r_serv)) return jsonify(row1=get_queues(r_serv))
@dashboard.route("/") @dashboard.route("/")
@login_required
def index(): def index():
default_minute = cfg.get("Flask", "minute_processed_paste") default_minute = cfg.get("Flask", "minute_processed_paste")
threshold_stucked_module = cfg.getint("Module_ModuleInformation", "threshold_stucked_module") threshold_stucked_module = cfg.getint("Module_ModuleInformation", "threshold_stucked_module")

View File

@ -17,6 +17,8 @@ from flask_login import login_required
from Date import Date from Date import Date
from HiddenServices import HiddenServices from HiddenServices import HiddenServices
from Decorator import login_required
# ============ VARIABLES ============ # ============ VARIABLES ============
import Flask_config import Flask_config
@ -35,6 +37,7 @@ list_types=['onion', 'regular']
dic_type_name={'onion':'Onion', 'regular':'Website'} dic_type_name={'onion':'Onion', 'regular':'Website'}
# ============ FUNCTIONS ============ # ============ FUNCTIONS ============
def one(): def one():
return 1 return 1
@ -233,6 +236,7 @@ def delete_auto_crawler(url):
# ============= ROUTES ============== # ============= ROUTES ==============
@hiddenServices.route("/crawlers/", methods=['GET']) @hiddenServices.route("/crawlers/", methods=['GET'])
#@login_required(role="ADMIN")
@login_required @login_required
def dashboard(): def dashboard():
crawler_metadata_onion = get_crawler_splash_status('onion') crawler_metadata_onion = get_crawler_splash_status('onion')