mirror of https://github.com/CIRCL/AIL-framework
chg: [user_management] create + check user password
parent
1ab1a55a4f
commit
64ff94ce5f
12
OVERVIEW.md
12
OVERVIEW.md
|
@ -52,6 +52,18 @@ Redis and ARDB overview
|
|||
| ail:current_background_script | **name of the background script currently executed** |
|
||||
| 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:
|
||||
|
||||
##### Set:
|
||||
|
|
|
@ -1,36 +1,65 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*-coding:UTF-8 -*
|
||||
|
||||
import os
|
||||
import redis
|
||||
import bcrypt
|
||||
import configparser
|
||||
|
||||
from flask_login import UserMixin
|
||||
|
||||
class User(UserMixin):
|
||||
|
||||
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
|
||||
#def is_authenticated():
|
||||
|
||||
# return True or False
|
||||
#def is_active():
|
||||
|
||||
# return True or False
|
||||
#def is_anonymous():
|
||||
|
||||
@classmethod
|
||||
def get(self_class, id):
|
||||
print(id)
|
||||
return self_class(id)
|
||||
|
||||
def check_password(self, password):
|
||||
password = password.encode()
|
||||
print(self.id)
|
||||
if password=='admin':
|
||||
print('password ok')
|
||||
hashed_password = self.r_serv_db.hget('user:all', self.id).encode()
|
||||
if bcrypt.checkpw(password, hashed_password):
|
||||
print('password correct')
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def set_password(self):
|
||||
def request_password_change(self):
|
||||
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
|
||||
|
|
|
@ -47,6 +47,7 @@ texttable
|
|||
|
||||
flask
|
||||
flask-login
|
||||
bcrypt
|
||||
|
||||
#DomainClassifier
|
||||
DomainClassifier
|
||||
|
|
|
@ -11,6 +11,8 @@ import calendar
|
|||
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
|
||||
|
||||
import bcrypt
|
||||
|
||||
import flask
|
||||
import importlib
|
||||
import os
|
||||
|
@ -28,6 +30,41 @@ from pytaxonomies import Taxonomies
|
|||
# Import 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 #
|
||||
cfg = Flask_config.cfg
|
||||
baseUrl = cfg.get("Flask", "baseurl")
|
||||
|
@ -35,6 +72,20 @@ baseUrl = baseUrl.replace('/', '')
|
|||
if 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/')
|
||||
app = Flask_config.app
|
||||
app.config['MAX_CONTENT_LENGTH'] = 900 * 1024 * 1024
|
||||
|
@ -152,6 +203,8 @@ def login():
|
|||
#print(user.is_authenticated)
|
||||
if user and user.check_password(password):
|
||||
login_user(user) ## TODO: use remember me ?
|
||||
#print(user.request_password_change())
|
||||
print(user.is_active)
|
||||
return redirect(url_for('dashboard.index'))
|
||||
else:
|
||||
return 'incorrect password'
|
||||
|
@ -167,7 +220,27 @@ def login():
|
|||
@login_required
|
||||
def logout():
|
||||
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/')
|
||||
|
@ -176,11 +249,6 @@ def searchbox():
|
|||
|
||||
|
||||
# ========== 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
|
||||
r_serv_tags.sadd('active_taxonomies', 'infoleak')
|
||||
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)
|
||||
|
||||
# ========== 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_automatic_tags = []
|
||||
for tag in taxonomies.get('infoleak').machinetags():
|
||||
|
|
|
@ -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
|
|
@ -13,6 +13,7 @@ import flask
|
|||
from Date import Date
|
||||
|
||||
from flask import Flask, render_template, jsonify, request, Blueprint, url_for
|
||||
from flask_login import login_required
|
||||
|
||||
# ============ VARIABLES ============
|
||||
import Flask_config
|
||||
|
@ -109,10 +110,12 @@ def datetime_from_utc_to_local(utc_str):
|
|||
# ============ ROUTES ============
|
||||
|
||||
@dashboard.route("/_logs")
|
||||
@login_required
|
||||
def logs():
|
||||
return flask.Response(event_stream(), mimetype="text/event-stream")
|
||||
|
||||
@dashboard.route("/_get_last_logs_json")
|
||||
@login_required
|
||||
def get_last_logs_json():
|
||||
date = datetime.datetime.now().strftime("%Y%m%d")
|
||||
|
||||
|
@ -154,11 +157,13 @@ def get_last_logs_json():
|
|||
|
||||
|
||||
@dashboard.route("/_stuff", methods=['GET'])
|
||||
@login_required
|
||||
def stuff():
|
||||
return jsonify(row1=get_queues(r_serv))
|
||||
|
||||
|
||||
@dashboard.route("/")
|
||||
@login_required
|
||||
def index():
|
||||
default_minute = cfg.get("Flask", "minute_processed_paste")
|
||||
threshold_stucked_module = cfg.getint("Module_ModuleInformation", "threshold_stucked_module")
|
||||
|
|
|
@ -17,6 +17,8 @@ from flask_login import login_required
|
|||
from Date import Date
|
||||
from HiddenServices import HiddenServices
|
||||
|
||||
from Decorator import login_required
|
||||
|
||||
# ============ VARIABLES ============
|
||||
import Flask_config
|
||||
|
||||
|
@ -35,6 +37,7 @@ list_types=['onion', 'regular']
|
|||
dic_type_name={'onion':'Onion', 'regular':'Website'}
|
||||
|
||||
# ============ FUNCTIONS ============
|
||||
|
||||
def one():
|
||||
return 1
|
||||
|
||||
|
@ -233,6 +236,7 @@ def delete_auto_crawler(url):
|
|||
# ============= ROUTES ==============
|
||||
|
||||
@hiddenServices.route("/crawlers/", methods=['GET'])
|
||||
#@login_required(role="ADMIN")
|
||||
@login_required
|
||||
def dashboard():
|
||||
crawler_metadata_onion = get_crawler_splash_status('onion')
|
||||
|
|
Loading…
Reference in New Issue