# -*- encoding: utf-8 -*- # @author : vincent.benoit@benserv.fr # @brief : Params routes ######################################################### # Importation de modules externes # import sys, re, os import logging as log from datetime import datetime, timezone from flask import Flask, Blueprint, request, abort, jsonify, current_app from flask_api import status from flask_jwt_extended import create_access_token from flask_jwt_extended import get_jwt from flask_jwt_extended import set_access_cookies from flask_jwt_extended import unset_jwt_cookies from flask_jwt_extended import get_jwt_identity from flask_jwt_extended import jwt_required import json import shutil import hashlib from werkzeug.exceptions import HTTPException from ConfBack.manager import Sock ######################################################### # Class et Methods # params = Blueprint('params', __name__, url_prefix='/api/configurateur') @params.errorhandler(HTTPException) def handle_exception(e): ''' return JSON instead of HTML for HTTP errors ''' response = e.get_response() # replace the body with JSON response.data = json.dumps({ 'code': e.code, 'name': e.name, 'description': e.description, }) response.content_type = "application/json" return response @params.after_request def refresh_expiring_tokens(response): ''' Using an 'after_request' callback, we refresh any token that is within 30 minutes of expiring.''' try: exp_timestamp = get_jwt()['exp'] now = datetime.now(timezone.utc) target_timestamp = datetime.timestamp(now + current_app.config['DELTA']) if target_timestamp > exp_timestamp: current_app.logger.warning("On doit recréer un token JWT ....") access_token = create_access_token(identity=get_jwt_identity()) # refresh token in storage place if os.path.exists(os.path.join("/tmp", current_app.config['PROJECT'])): with open(os.path.join("/tmp", current_app.config['PROJECT'], get_jwt_identity()['id']), 'w') as f: f.write(access_token) # Modifiy a Flask Response to set a cookie containing the access JWT. set_access_cookies(response, access_token) return response except (RuntimeError, KeyError): return response @params.route('/params', methods=['GET']) @jwt_required() def retreive_params(): ''' Récupération des paramètres de l'intercom ''' current_app.logger.info("Récupération des paramètres de l'intercom") current_user = get_jwt_identity() # load data from JSON database try: with open(current_app.config['DB_PATH'], 'r') as f: data = json.load(f) if 'OPERATION' and 'PIN_ACTIF' and 'CODE_PIN' and 'NUM_AUTORISE' and 'TONE_DURATION' and 'DTMF_CODE' and 'DTMF_DURATION' in data: content = {'operation': data['OPERATION'], 'pin_actif': data['PIN_ACTIF'], 'code_pin': data['CODE_PIN'], 'num_autorized': data['NUM_AUTORISE'], 'tone_duration': data['TONE_DURATION'], 'dtmf_code': data['DTMF_CODE'], 'dtmf_duration': data['DTMF_DURATION']} else: abort(status.HTTP_406_NOT_ACCEPTABLE, description="paramètres manquant en base de données") except FileNotFoundError as e: current_app.logger.error("Fichier ({}) manquant".format(current_app.config['DB_PATH'])) abort(status.HTTP_406_NOT_ACCEPTABLE, description="Fichier manquant") return content, status.HTTP_200_OK @params.route('/update_params', methods=['POST']) @jwt_required() def update_params(): ''' Mise à jour des paramètres de l'intercom ''' current_app.logger.info("Mise à jour des paramètres de l'intercom") current_user = get_jwt_identity() # recuperation des attributs JSON de la requete data_req = request.get_json() current_app.logger.debug("request: {}".format(data_req)) # load data from JSON database try: with open(current_app.config['DB_PATH'], 'r') as f: data = json.load(f) except FileNotFoundError as e: current_app.logger.error("Fichier ({}) manquant".format(current_app.config['DB_PATH'])) abort(status.HTTP_406_NOT_ACCEPTABLE, description="Fichier manquant") if 'operation' in data_req: data['OPERATION'] = data_req['operation'] else: abort(status.HTTP_406_NOT_ACCEPTABLE, description="paramètre manquant") if 'pin_actif' in data_req: data['PIN_ACTIF'] = data_req['pin_actif'] else: abort(status.HTTP_406_NOT_ACCEPTABLE, description="paramètre manquant") if 'code_pin' in data_req: data['CODE_PIN'] = data_req['code_pin'] else: abort(status.HTTP_406_NOT_ACCEPTABLE, description="paramètre manquant") if 'num_autorized' in data_req: data['NUM_AUTORISE'] = data_req['num_autorized'] else: abort(status.HTTP_406_NOT_ACCEPTABLE, description="paramètre manquant") if 'tone_duration' in data_req: data['TONE_DURATION'] = int(data_req['tone_duration']) else: abort(status.HTTP_406_NOT_ACCEPTABLE, description="paramètre manquant") if 'dtmf_code' in data_req: data['DTMF_CODE'] = data_req['dtmf_code'] else: abort(status.HTTP_406_NOT_ACCEPTABLE, description="paramètre manquant") if 'dtmf_duration' in data_req: data['DTMF_DURATION'] = int(data_req['dtmf_duration']) else: abort(status.HTTP_406_NOT_ACCEPTABLE, description="paramètre manquant") with open(current_app.config['DB_PATH'], 'w') as f: json.dump(data, f) conn = Sock(addr=current_app.config['UNIX_ADDR'], logger=current_app.logger) if not conn.connect(): current_app.logger.error("impossible de se connecter au serveur") abort(status.HTTP_406_NOT_ACCEPTABLE, description="Impossible de se connecter au serveur") # send order to KineIntercom process if not conn.send(b"RELOAD_DB\n"): conn.disconnect() current_app.logger.error("impossible de communiquer avec le serveur") abort(status.HTTP_406_NOT_ACCEPTABLE, description="Impossible de communiquer avec le serveur") conn.disconnect() content = {'message':'maj parameters successful!'} return content, status.HTTP_200_OK