ajout des fichiers pour la génération du paquet wheel et du paquet deb

This commit is contained in:
Vincent BENOIT
2022-11-17 10:31:33 +01:00
parent 832367d7eb
commit c694a89fe7
29 changed files with 175 additions and 15 deletions
+1
View File
@@ -0,0 +1 @@
1.0.0
View File
+6
View File
@@ -0,0 +1,6 @@
# -*- encoding: utf-8 -*-
# @author : vincent.benoit@benserv.fr
# @brief : account views and models
from .views import account
+93
View File
@@ -0,0 +1,93 @@
# -*- encoding: utf-8 -*-
# @author : vincent.benoit@benserv.fr
# @brief : Account 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, decode_token
import json
import shutil
import hashlib
from werkzeug.exceptions import HTTPException
#########################################################
# Class et Methods #
account = Blueprint('account', __name__, url_prefix='/api/configurateur')
@account.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
@account.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
@account.route('/update_passwd', methods=['POST'])
@jwt_required()
def update_password():
''' Mise à jour du mot de passe utilisateur
'''
current_app.logger.info("Mise à jour du mot de passe de l'utilisateur")
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
with open(current_app.config['DB_PATH'], 'r') as f:
data = json.load(f)
if 'old' in data_req:
if data_req['old'] != data['utilisateur']['password']:
abort(status.HTTP_406_NOT_ACCEPTABLE, description="Mauvais ancien mot de passe")
else:
abort(status.HTTP_406_NOT_ACCEPTABLE, description="Ancien mot de passe invalide")
if 'new' in data_req:
data['utilisateur']['password'] = data_req['new']
with open(current_app.config['DB_PATH'], 'w') as f:
json.dump(data, f)
else:
abort(status.HTTP_406_NOT_ACCEPTABLE, description="Nouveau mot de passe invalide")
content = {'message':'maj password successful!'}
return content, status.HTTP_200_OK
+157
View File
@@ -0,0 +1,157 @@
# -*- encoding: utf-8 -*-
# @author : vincent.benoit@benserv.fr
# @brief : Configurateur Backend Flask API
#########################################################
# Importation de modules externes #
import sys, re, os
import logging as log
from logging.config import dictConfig
from flask import Flask
from flask.logging import default_handler
from flask_cors import CORS, cross_origin
from flask_jwt_extended import JWTManager
import jwt
from ConfBack.config import DefaultConfig
from ConfBack.auth import auth
from ConfBack.account import account
from ConfBack.params import params
from ConfBack.schedule import schedule
from ConfBack.log import log as logs
from ConfBack.manager import sock
from ConfBack.infos import info
#########################################################
# Corps principal du programme #
def create_app(config=None, app_name=None):
''' Create and configure the app
:param config:
configuration object
:param app_name:
application name
'''
ret = True
if app_name is None:
app_name = DefaultConfig.PROJECT
# create the app
# tells the app that configuration files are relative to the instance folder.
app = Flask(app_name,
instance_path=os.path.join(os.getcwd(), app_name),
instance_relative_config=True)
if not configure_app(app, config):
return None
configure_log(app)
configure_blueprints(app)
ret = configure_connexion(app)
return ret, app
def configure_app(app=None, config=None):
''' configure the application with configuration file and/or object
:param app:
Application object
:param config:
Configuration object
:return bool:
True if OK, otherwise False
'''
# load default config
app.config.from_object(DefaultConfig)
try:
if config:
# load specific config
app.config.from_object(config)
except ModuleNotFoundError as e:
print("Module de configuration non trouvé: {}".format(e))
return False
# setup the Flask-JWT-Extended extension
jwt = JWTManager(app)
# setup the Flask-CORS extension for handling Cross Origin Resource Sharing
CORS(app, resources={r"/api/*": {
"origins": ["http://localhost:4200",
"http://localhost:6000",
"http://127.0.0.1:4200",
"http://127.0.0.1:6000"],
# "origins": "*",
"supports_credentials": True
}})
return True
def configure_log(app=None):
''' Configure log handler
:param app:
Application object
:return None:
'''
if not os.path.exists(app.config['LOG_FOLDER']):
try:
os.makedirs(app.config['LOG_FOLDER'])
except OSError:
pass
# On vire tous les handlers
for h in app.logger.handlers:
app.logger.removeHandler(h)
# Set info level on logger, which might be overwritten by handers.
# Suppress DEBUG messages.
app.logger.setLevel(log.DEBUG)
formatter = log.Formatter('%(asctime)s - %(name)s [%(module)s.%(funcName)s:%(lineno)d] - %(levelname)s - %(message)s')
info_log = os.path.join(app.config['LOG_FOLDER'], DefaultConfig.PROJECT + '.log')
info_file_handler = log.handlers.RotatingFileHandler(info_log, maxBytes=100000, backupCount=10)
info_file_handler.setLevel(log.DEBUG)
info_file_handler.setFormatter(formatter)
app.logger.addHandler(info_file_handler)
fl = log.StreamHandler()
fl.setLevel(log.DEBUG)
fl.setFormatter(formatter)
app.logger.addHandler(fl)
#logging.getLogger('apscheduler').setLevel(logging.DEBUG)
def configure_blueprints(app=None):
''' configure blueprints
:param app:
Application object
:return None:
'''
for bp in [auth, logs, account, params, schedule, info]:
app.register_blueprint(bp)
def configure_connexion(app=None):
''' Confgure AF_UNIX connexion with KineIntercom
process
'''
ret = False
try:
sock.connect(app.config['UNIX_ADDR'])
ret = True
except TimeoutError as e:
app.logger.error("Erreur de connexion avec le processus KineIntercom")
ret = False
except ConnectionRefusedError as e:
app.logger.error("Connexion refusée avec le processus KineIntercom")
ret = False
return ret
+6
View File
@@ -0,0 +1,6 @@
# -*- encoding: utf-8 -*-
# @author : vincent.benoit@benserv.fr
# @brief : auth views and models
from .views import auth
+152
View File
@@ -0,0 +1,152 @@
# -*- encoding: utf-8 -*-
# @author : vincent.benoit@benserv.fr
# @brief : Auth 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, decode_token
import json
import shutil
import hashlib
from werkzeug.exceptions import HTTPException
#########################################################
# Class et Methods #
auth = Blueprint('auth', __name__, url_prefix='/api/configurateur')
@auth.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
@auth.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
@auth.route('/login', methods=['POST'])
def login():
''' Authenticate User
'''
auth = request.authorization
current_app.logger.info("Connexion de l'utilisateur : {}".format(auth.username))
if not auth or not auth.username or not auth.password:
current_app.logger.error("Login and Password required !")
abort(401, description='Login and Password required')
try:
hashstr = hashlib.sha256(auth.password.encode('utf-8')).hexdigest()
with open(current_app.config['DB_PATH'], 'r') as f:
data = json.load(f)
# authenticate user with his username and password hash
if hashstr == data['utilisateur']['password']:
# create a new access token
current_app.logger.debug("create JWT Token with id: {}".format(auth.username))
token = create_access_token(identity={'id': auth.username})
if not os.path.exists(os.path.join("/tmp", current_app.config['PROJECT'])):
os.mkdir(os.path.join("/tmp", current_app.config['PROJECT']))
with open(os.path.join("/tmp", current_app.config['PROJECT'], auth.username), 'w') as f:
f.write(token)
content = jsonify({'message': 'login successful !'})
# set token as cookie
set_access_cookies(content, token)
return content, status.HTTP_200_OK
current_app.logger.error("Authorization failed !")
except Exception as e:
current_app.logger.error("Erreur : {}".format(e))
abort(500, description='Authentification impossible')
abort(401, description="Authorization failed !")
@auth.route('/logout', methods=['POST'])
@jwt_required()
def logout():
''' Handles HTTP requests to URL: /api/configurateur/logout
'''
current_app.logger.info("Deconnexion de l'utilisateur")
current_user = get_jwt_identity()
content = jsonify({'message': 'logout successful !'})
unset_jwt_cookies(content)
userpath = os.path.join("/tmp", current_app.config['PROJECT'])
if os.path.exists(userpath):
shutil.rmtree(userpath)
return content, status.HTTP_200_OK
@auth.route('/current', methods=['GET'])
@jwt_required()
def current_user():
''' retourne l'utilisateur courant connecté
'''
# Access the identity of the current user with get_jwt_identity
current_user = get_jwt_identity()
return jsonify(current_user)
@auth.route('/userConnected', methods=['GET'])
def user_connected():
''' retourne "oui" si un utilisateur est déjà connecté sinon "non"
'''
flag = False
resp = 'non'
uid = ''
path = os.path.join("/tmp", current_app.config['PROJECT'])
if os.path.exists(path):
# search unique file in path
for root, dirs, files in os.walk(path):
for f in files:
uid = str(f)
# retreive token in file
with open(os.path.join(path, f), 'r') as fp:
token = fp.read()
exp = decode_token(token, allow_expired = True)['exp']
now = datetime.now(timezone.utc)
target = datetime.timestamp(now)
if target > exp:
current_app.logger.warning("Le token de l'ancien utilisateur a expiré")
# remove tmp dir
shutil.rmtree(os.path.join("/tmp", current_app.config['PROJECT']))
flag = True
break
if not flag:
current_app.logger.warning("Un autre utilisateur est déjà connecté")
resp = 'oui'
content = ({'message':resp, 'uid':uid})
return jsonify(content), status.HTTP_200_OK
+70
View File
@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
#
# @author: vincent.benoit@benserv.fr
# @brief: Flask Config classes
import os
import datetime
class BaseConfig(object):
PROJECT = "configurateur"
# Get app root path, also can use flask.root_path.
PROJECT_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
DEBUG = False
TESTING = False
FLASK_ENV = 'production'
ADMINS = ['vincent.benoit@benserv.fr']
LOG_FOLDER = os.path.join(os.getcwd(), 'log')
APP_NAME = "KineIntercom"
SECRET_KEY = "d]omg;<*|uHfs}ogN=dk_$YW"
# Setup the Flask-JWT-Extended extension
JWT_SECRET_KEY = "xbNNvwHCY*cN,)Yq;A,e(]|P"
JWT_COOKIE_SECURE = False
JWT_TOKEN_LOCATION = ["cookies"]
JWT_ACCESS_TOKEN_EXPIRES = datetime.timedelta(minutes=30)
DELTA = datetime.timedelta(minutes=20) # in minutes
# Controls if Cross Site Request Forgery (CSRF) protection is enabled when using cookies
# This should always be True in production
JWT_COOKIE_CSRF_PROTECT = True
JWT_CSRF_IN_COOKIES = True
JWT_COOKIE_SAMESITE = "None"
STATIC_FOLDER = os.path.join(os.getcwd(), 'static')
UPLOAD_FOLDER = STATIC_FOLDER + '/upload'
DOWNLOAD_FOLDER = STATIC_FOLDER + '/download'
ALLOWED_EXTENSIONS = {'json', 'tar', 'txt'}
MAX_CONTENT_LENGTH = 200 * 1024 * 1024 # 100 megabytes
# Database path
DB_PATH = os.path.join(os.getcwd(), 'db.json')
UNIX_ADDR = "/tmp/uds_socket"
class DefaultConfig(BaseConfig):
DEBUG = True
TESTING = True
FLASK_ENV = 'development'
SECRET_KEY = "secretkey10"
# Setup the Flask-JWT-Extended extension
JWT_SECRET_KEY = "secretkeyjwt10"
JWT_ACCESS_TOKEN_EXPIRES = datetime.timedelta(minutes=10)
DELTA = datetime.timedelta(minutes=5) # in minutes
class ProdConfig(BaseConfig):
DEBUG = False
TESTING = False
FLASK_ENV = 'production'
ROOT_BASE_FOLDER = "/opt"
# Log Folder path
LOG_FOLDER = "/var/log/kineintercom"
# Database path
DB_PATH = os.path.join('/etc/kineintercom', 'db.json')
+6
View File
@@ -0,0 +1,6 @@
# -*- encoding: utf-8 -*-
# @author : vincent.benoit@benserv.fr
# @brief : info views and models
from .views import info
+81
View File
@@ -0,0 +1,81 @@
# -*- encoding: utf-8 -*-
# @author : vincent.benoit@benserv.fr
# @brief : info 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 get_jwt_identity
from flask_jwt_extended import jwt_required
import json
from werkzeug.exceptions import HTTPException
#########################################################
# Class et Methods #
info = Blueprint('info', __name__, url_prefix='/api/configurateur')
@info.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
@info.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 ....")
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
@info.route('/infos', methods=['GET'])
@jwt_required()
def get_infos():
''' Retreive informations '''
# Access the identity of the current user with get_jwt_identity
current_user = get_jwt_identity()
content = {}
# load data from JSON database
with open(current_app.config['DB_PATH'], 'r') as f:
data = json.load(f)
content['manufacturer'] = data['INFOS']['manufacturer']
content['operator'] = data['INFOS']['control']['operator']
content['provider'] = data['INFOS']['control']['service_provider']
content['signal_dbm'] = data['INFOS']['control']['signal_dbm']
content['signal_qos'] = data['INFOS']['control']['signal_qos']
content['sim_inserted'] = data['INFOS']['control']['sim_inserted']
content['call_ready'] = data['INFOS']['control']['call_ready']
return jsonify(content), status.HTTP_200_OK
+6
View File
@@ -0,0 +1,6 @@
# -*- encoding: utf-8 -*-
# @author : vincent.benoit@benserv.fr
# @brief : log views and models
from .views import log
+112
View File
@@ -0,0 +1,112 @@
# -*- encoding: utf-8 -*-
# @author : vincent.benoit@benserv.fr
# @brief : log 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 get_jwt_identity
from flask_jwt_extended import jwt_required
import json
from werkzeug.exceptions import HTTPException
#########################################################
# Class et Methods #
log = Blueprint('log', __name__, url_prefix='/api/configurateur')
@log.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
@log.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 ....")
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
@log.route('/conf_logs', methods=['GET'])
@jwt_required()
def get_conf_logs():
''' Retreive conf logs '''
# Access the identity of the current user with get_jwt_identity
current_user = get_jwt_identity()
lines = []
logfile = os.path.join(current_app.config['LOG_FOLDER'], current_app.config['PROJECT'] + '.log')
try:
with open(logfile) as f:
current_app.logger.debug("conf log file: {}".format(logfile))
for idx, line in enumerate(f.readlines()):
try:
date_time, head, gravity, msg = line.split(' - ', 3)
content = {'datetime': date_time, 'header': head, 'gravity': gravity, 'msg':msg}
lines.append(content)
except ValueError as e:
lines[-1]['msg'] = lines[-1]['msg'] + line
except FileNotFoundError as e:
current_app.logger.error("Fichier de log ({}) manquant".format(logfile))
abort(status.HTTP_406_NOT_ACCEPTABLE, description="Fichier log manquant")
return jsonify(lines), status.HTTP_200_OK
@log.route('/app_logs', methods=['GET'])
@jwt_required()
def get_app_logs():
''' Retreive app logs '''
# Access the identity of the current user with get_jwt_identity
current_user = get_jwt_identity()
lines = []
logfile = os.path.join(current_app.config['LOG_FOLDER'], current_app.config['APP_NAME'] + '.log')
try:
with open(logfile) as f:
current_app.logger.debug("app log file: {}".format(logfile))
for idx, line in enumerate(f.readlines()):
try:
date_time, head, gravity, msg = line.split(' - ', 3)
content = {'datetime': date_time, 'header': head, 'gravity': gravity, 'msg':msg}
lines.append(content)
except ValueError as e:
lines[-1]['msg'] = lines[-1]['msg'] + line
except FileNotFoundError as e:
current_app.logger.error("Fichier de log ({}) manquant".format(logfile))
abort(status.HTTP_406_NOT_ACCEPTABLE, description="Fichier log manquant")
return jsonify(lines), status.HTTP_200_OK
+21
View File
@@ -0,0 +1,21 @@
# -*- encoding: utf-8 -*-
# @author : vincent.benoit@scle.fr
# @brief : Client UNIX Socket Manager
#########################################################
# Importation de modules externes #
import sys, re, os
import socket
#########################################################
# Corps principal du programme #
#########################################################
# Decorators #
#########################################################
# Instantiation #
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+6
View File
@@ -0,0 +1,6 @@
# -*- encoding: utf-8 -*-
# @author : vincent.benoit@benserv.fr
# @brief : params views and models
from .views import params
+149
View File
@@ -0,0 +1,149 @@
# -*- 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)
try:
# send order to KineIntercom process
sock.send(b"RELOAD_DB\n")
except:
current_app.logger.error("Erreur d'envoi de l'ordre au processus KineIntercom")
abort(status.HTTP_406_NOT_ACCEPTABLE, description="Erreur d'envoi de l'ordre au processus")
content = {'message':'maj parameters successful!'}
return content, status.HTTP_200_OK
+6
View File
@@ -0,0 +1,6 @@
# -*- encoding: utf-8 -*-
# @author : vincent.benoit@benserv.fr
# @brief : schedule views and models
from .views import schedule
+121
View File
@@ -0,0 +1,121 @@
# -*- encoding: utf-8 -*-
# @author : vincent.benoit@benserv.fr
# @brief : Scheduler 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
#########################################################
# Class et Methods #
schedule = Blueprint('schedule', __name__, url_prefix='/api/configurateur')
@schedule.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
@schedule.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
@schedule.route('/scheduler', methods=['GET'])
@jwt_required()
def retreive_scheduler():
''' Récupération des horaires
'''
current_app.logger.info("Récupération des horaires")
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)
content = []
if 'HORAIRES' in data:
for day in data['HORAIRES']:
h = []
for hour in data['HORAIRES'][day]:
h.append(hour)
content.append({'name': day, 'horaires':h})
#current_app.logger.debug("{}".format(content))
else:
abort(status.HTTP_406_NOT_ACCEPTABLE, description="horaire 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
@schedule.route('/update_schedulers', methods=['POST'])
@jwt_required()
def update_scheduler():
''' Mise à jour des horaires
'''
current_app.logger.info("Mise à jour des horaires")
current_user = get_jwt_identity()
# recuperation des attributs JSON de la requete
data_req = request.get_json()
# load data from JSON database
try:
with open(current_app.config['DB_PATH'], 'r') as f:
data_db = 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")
for day in data_db['HORAIRES']:
for d in data_req:
if 'name' in d and d['name'] == day:
data_db['HORAIRES'][day] = d['horaires']
elif 'name' not in d:
abort(status.HTTP_406_NOT_ACCEPTABLE, description="erreur des données de la requete")
with open(current_app.config['DB_PATH'], 'w') as f:
json.dump(data_db, f)
content = {'message':'maj parameters successful!'}
return content, status.HTTP_200_OK