From f2ca241e4f4d9b19630b1b29093fe6e470ae3437 Mon Sep 17 00:00:00 2001 From: Terrtia Date: Wed, 8 May 2019 14:58:41 +0200 Subject: [PATCH] chg: [restapi] add rest api authentification + create default user --- OVERVIEW.md | 4 + var/www/create_default_user.py | 53 +++++ var/www/modules/Tags/Flask_Tags.py | 2 +- var/www/modules/restApi/Flask_restApi.py | 109 +++++++++ .../restApi/templates/api_default.html | 222 ++++++++++++++++++ .../modules/restApi/templates/header_api.html | 1 + 6 files changed, 390 insertions(+), 1 deletion(-) create mode 100755 var/www/create_default_user.py create mode 100644 var/www/modules/restApi/Flask_restApi.py create mode 100644 var/www/modules/restApi/templates/api_default.html create mode 100644 var/www/modules/restApi/templates/header_api.html diff --git a/OVERVIEW.md b/OVERVIEW.md index ecf16bf3..38488a74 100644 --- a/OVERVIEW.md +++ b/OVERVIEW.md @@ -56,6 +56,10 @@ Redis and ARDB overview | Key | Field | Value | | ------ | ------ | ------ | | user:all | **user id** | **password hash** | +| | | | +| user:tokens | **token** | **user id** | +| | | | +| user_metadata:**user id** | **user token** | **token** | | Key | Value | | ------ | ------ | diff --git a/var/www/create_default_user.py b/var/www/create_default_user.py new file mode 100755 index 00000000..c249ec0c --- /dev/null +++ b/var/www/create_default_user.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +# -*-coding:UTF-8 -* + +import os +import sys +import redis +import configparser + +import bcrypt +import secrets + +# Import config +sys.path.append('./modules/') + +def hashing_password(bytes_password): + hashed = bcrypt.hashpw(bytes_password, bcrypt.gensalt()) + return hashed + +def create_user_db(username_id , password, default=False): + 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) + + +if __name__ == "__main__": + 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) + + 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) + + username = 'admin@admin.test' + # # TODO: create random password + password = 'admin' + create_user_db(username, password, default=True) + + # create user token + token = secrets.token_urlsafe(41) + r_serv_db.hset('user:tokens', token, username) + + print('new user created: {}'.format(username)) + print('password: {}'.format(password)) diff --git a/var/www/modules/Tags/Flask_Tags.py b/var/www/modules/Tags/Flask_Tags.py index 307f6ed3..f68491e6 100644 --- a/var/www/modules/Tags/Flask_Tags.py +++ b/var/www/modules/Tags/Flask_Tags.py @@ -5,7 +5,7 @@ Flask functions and routes for the trending modules page ''' import redis -from flask import Flask, render_template, jsonify, request, Blueprint, current_app, redirect, url_for +from flask import Flask, render_template, jsonify, request, Blueprint, redirect, url_for from Role_Manager import login_admin, login_analyst from flask_login import login_required diff --git a/var/www/modules/restApi/Flask_restApi.py b/var/www/modules/restApi/Flask_restApi.py new file mode 100644 index 00000000..82c5ba45 --- /dev/null +++ b/var/www/modules/restApi/Flask_restApi.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +# -*-coding:UTF-8 -* + +''' + Flask functions and routes for the rest api +''' + +import os +import re +import sys +import json +import redis +import datetime + +from flask import Flask, render_template, jsonify, request, Blueprint, redirect, url_for, Response +from flask_login import login_required + +from functools import wraps + +# ============ VARIABLES ============ +import Flask_config + +app = Flask_config.app +cfg = Flask_config.cfg +baseUrl = Flask_config.baseUrl +r_cache = Flask_config.r_cache +r_serv_db = Flask_config.r_serv_db +r_serv_onion = Flask_config.r_serv_onion +r_serv_metadata = Flask_config.r_serv_metadata + +restApi = Blueprint('restApi', __name__, template_folder='templates') + +# ============ AUTH FUNCTIONS ============ + +def check_token_format(strg, search=re.compile(r'[^a-zA-Z0-9_-]').search): + return not bool(search(strg)) + +def verify_token(token): + if len(token) != 55: + return False + + if not check_token_format(token): + return False + + if r_serv_db.hexists('user:tokens', token): + return True + else: + return False + +# ============ DECORATOR ============ + +def token_required(funct): + @wraps(funct) + def api_token(*args, **kwargs): + data = authErrors() + if data: + return Response(json.dumps(data[0], indent=2, sort_keys=True), mimetype='application/json'), data[1] + else: + return funct(*args, **kwargs) + return api_token + +def get_auth_from_header(): + token = request.headers.get('Authorization').replace(' ', '') # remove space + return token + +def authErrors(): + # Check auth + if not request.headers.get('Authorization'): + return ({'status': 'error', 'reason': 'Authentication needed'}, 401) + token = get_auth_from_header() + data = None + # verify token format + + try: + authenticated = False + if verify_token(token): + authenticated = True + + if not authenticated: + data = ({'status': 'error', 'reason': 'Authentication failed'}, 401) + except Exception as e: + print(e) + data = ({'status': 'error', 'reason': 'Malformed Authentication String'}, 400) + if data: + return data + else: + return None + +# ============ FUNCTIONS ============ + +def one(): + return 1 + +# ============= ROUTES ============== + +@restApi.route("/api", methods=['GET']) +@login_required +def api(): + return 'api doc' + +@restApi.route("api/items", methods=['POST']) +@token_required +def items(): + item = request.args.get('id') + + return Response(json.dumps({'test': 2}), mimetype='application/json') + +# ========= REGISTRATION ========= +app.register_blueprint(restApi, url_prefix=baseUrl) diff --git a/var/www/modules/restApi/templates/api_default.html b/var/www/modules/restApi/templates/api_default.html new file mode 100644 index 00000000..91d300af --- /dev/null +++ b/var/www/modules/restApi/templates/api_default.html @@ -0,0 +1,222 @@ + + + + + AIL-Framework + + + + + + + + + + + + + + + {% include 'nav_bar.html' %} + +
+
+ + {% include 'crawler/menu_sidebar.html' %} + +
+ +
+
+ +
+
+
Onions Crawlers
+
+
+ {{ statDomains_onion['domains_up'] }} UP + {{ statDomains_onion['domains_down'] }} DOWN +
+
+ {{ statDomains_onion['total'] }} Crawled + {{ statDomains_onion['domains_queue'] }} Queue +
+
+
+
+ + + {% for crawler in crawler_metadata_onion %} + + + + + + {% endfor %} + +
+ {{crawler['crawler_info']}} + + {{crawler['crawling_domain']}} + + {{crawler['status_info']}} +
+
+
+ +
+
+
+
+
Regular Crawlers
+
+
+ {{ statDomains_regular['domains_up'] }} UP + {{ statDomains_regular['domains_down'] }} DOWN +
+
+ {{ statDomains_regular['total'] }} Crawled + {{ statDomains_regular['domains_queue'] }} Queue +
+
+
+
+ + + {% for crawler in crawler_metadata_regular %} + + + + + + {% endfor %} + +
+ {{crawler['crawler_info']}} + + {{crawler['crawling_domain']}} + + {{crawler['status_info']}} +
+
+
+
+
+ +
+
+
+ + + + + diff --git a/var/www/modules/restApi/templates/header_api.html b/var/www/modules/restApi/templates/header_api.html new file mode 100644 index 00000000..34e20319 --- /dev/null +++ b/var/www/modules/restApi/templates/header_api.html @@ -0,0 +1 @@ +
  • hidden Services