from array import array import threading from flask import session,Flask,request, jsonify import flask from utility.app_logging import logger_name import logging import persistence import Model.isp_model as isp_model import Model.model_manager as model_manager from werkzeug.security import check_password_hash,generate_password_hash import View.view_privilege as privileges import Modules.Inventory.inventory_view as inventory_view from datetime import timedelta import View.view_error_management as view_error_management from flask_limiter import Limiter from flask_limiter.util import get_remote_address logger = logging.getLogger(logger_name + ".VIEW") __app__ = Flask("OpenIsp") __app__.secret_key = "aseqzdwxc" __app__.permanent_session_lifetime = timedelta(minutes=2) __app__.logger = logger #CORS(__app__) __resource_array__ : array __id_counter__ : int = 1 limiter = Limiter(__app__,key_func=get_remote_address,default_limits=["500 per minute"]) limiter.logger = logger from werkzeug.serving import make_server class ServerThread(threading.Thread): def __init__(self, app,ip,port): threading.Thread.__init__(self) self.server = make_server(ip, port, app) self.ctx = app.app_context() self.ctx.push() def run(self): logger.info('starting server') self.server.serve_forever() def shutdown(self): self.server.shutdown() __server_process__ : ServerThread def get_user_privilege() : return privileges.get_privileges_from_user(session["user_account_id"]) def init() : privileges.init() view_error_management.define_error_management(__app__) @__app__.before_request def before_request_func(): global __id_counter__ logger.debug("before_request processing") logger.debug("request from " + request.remote_addr) logger.debug("request header" + str(request.headers.__dict__)) if request.json : logger.debug("request json body : " + str(request.json)) if not "client_id" in session : session["client_id"] = str(__id_counter__) logger.debug("client_id is " + session["client_id"]) __id_counter__ = __id_counter__ + 1 if not request.path == "/api/login" and not "username" in session : logger.warning("Unauthorized client with id " + session["client_id"] + " try to access application") resp = jsonify({'message' : 'Unauthorized'}) resp.status_code = 401 return resp if "username" in session : logger.debug("request from " + session["username"]) @__app__.after_request def after_request(response): header = response.headers # adding this to the header to allow cross origin # for exemple origin cross origin is when website with javascript has it's server (origin 1) # and the javascript call some request on another server (origin 2), typically our API. header['Access-Control-Allow-Origin'] = '*' header['Access-Control-Allow-Methods'] = 'GET,DELETE,UPDATE,HEAD,OPTIONS,POST,PUT' header['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization' return response @__app__.route('/api/login',methods = ['POST']) def login(): _json = request.json _username = _json['username'] _password = _json['password'] with persistence.get_Session_Instance() as sess : Item = sess.query(isp_model.user_account).filter(isp_model.user_account.nickname == _username).first() if not isinstance(Item,isp_model.user_account) : logger.warning("user tried to login with unknown account name : " + _username) resp = jsonify({'message' : 'Bad Request - user account not found'}) resp.status_code = 400 return resp if not check_password_hash(Item.password,_password) : logger.warning("user with account name '" + _username + "' tried to login with invalid password") resp = jsonify({'message' : 'Bad Request - invalid password for this account'}) resp.status_code = 400 return resp session["username"] = _username session["user_account_id"] = Item.id logger.info("account " + _username + " logged IN successfully with id : " + session["client_id"]) resp = jsonify({'message' : 'login successful'}) resp.status_code = 200 return resp @__app__.route('/api/logout',methods = ['DELETE']) def logout(): logger.info("account " + session["username"] + " logged OUT with id : " + session["client_id"]) session.clear() return jsonify('logout') @__app__.route('/api/password',methods = ['POST']) def change_password(): _json = request.json _old_password = _json['old_password'] _password = _json['new_password'] with persistence.get_Session_Instance() as sess : Item : isp_model.user_account = sess.query(isp_model.user_account).filter(isp_model.user_account.id == session["user_account_id"]).first() if not check_password_hash(Item.password,_password) : raise Exception("old password is incorrect") Item.password = generate_password_hash(_password) sess.commit() return jsonify('password changed') @__app__.route('/routes',methods = ['GET']) @privileges.manager.require_authorization(required_role=inventory_view.inventory_admin_role,get_privilege_func=get_user_privilege) def routes(): routes = [] for route in __app__.url_map.iter_rules(): routes.append('%s' % route) return jsonify(routes) def run() : global __server_process__ __server_process__ = ServerThread(__app__,"0.0.0.0",8000) __server_process__.start() logger.info('View server started') def stop() : global __server_process__ __server_process__.shutdown() logger.info('View server stopped') def register_blueprint(blueprint : flask.Blueprint) : logger.info("registering view (blueprint) : '" + blueprint.name + "' with prefix '" + blueprint.url_prefix +"'") __app__.register_blueprint(blueprint) @privileges.manager.require_authorization(required_role=inventory_view.inventory_read_only_role,get_privilege_func=get_user_privilege) def tab(): return jsonify([2,5,7]) __app__.add_url_rule("/tab","/tab",tab)