diff --git a/.env b/.env new file mode 100644 index 0000000..b0428ea --- /dev/null +++ b/.env @@ -0,0 +1 @@ +GITEA_TOKEN= diff --git a/.gitignore b/.gitignore index 87df45d..123fb2e 100644 --- a/.gitignore +++ b/.gitignore @@ -173,3 +173,7 @@ Thumbs.db .idea/ copy + +incoming_dumps/ +upload-dump-* +counter \ No newline at end of file diff --git a/app/routes.py b/app/routes.py index ee7acb7..6cd392f 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,8 +1,11 @@ -import json, datetime, fcntl, glob, os, re, socket, subprocess, time +import json, datetime, fcntl, glob, os, re, socket, subprocess, time, requests from flask import jsonify, request, abort from flask import Blueprint from app import email +from dotenv import load_dotenv + +load_dotenv() bp = Blueprint("routes", __name__) @@ -22,6 +25,10 @@ DEBUG = False # if false, don't publish error messages DEBIAN_PACKAGES_EXP = "/srv/packages/pool/main/s/scodoc9/scodoc9_*.deb" RELEASE_LOG_FILE = "/home/viennet/scodoc-releases.log" +GITEA_URL = "https://scodoc.org/git" +GITEA_REPO = "ScoDoc/ScoDoc" +GITEA_LABEL_ID = None + @bp.route("/scodoc-installmgr/check_version/") def check_version(client_version: str): @@ -107,6 +114,150 @@ def last_stable_version(): ) +@bp.route("/scodoc-installmgr/report", methods=["POST"]) +def report(): + """Création d'un ticket Gitea depuis ScoDoc + => json + """ + log = open(LOG_FILENAME, "a") + log.write("report\n") + now = datetime.datetime.now() + fulltime = now.isoformat() + remote_addr = request.environ.get("HTTP_X_REAL_IP", request.remote_addr) + log.write(fulltime + " request from " + remote_addr + "\n") + log.flush() + + request_data = request.get_json(silent=True) + + if request_data is None: + log.write("json proccessing error\n") + log.close() + return ( + jsonify( + { + "message": "Une erreur est survenue lors du traitement de la requête. Veuillez réessayer." + } + ), + 400, + ) + + ticket = request_data.get("ticket", "") + user = request_data.get("user", "") + dump = request_data.get("dump", "") + scodoc = request_data.get("scodoc", "") + + if ( + not ticket + or not user + or not dump + or not scodoc + or not ticket.get("title") + or not ticket.get("message") + ): + log.write("missing json fields\n") + log.close() + return ( + jsonify( + { + "message": "Une erreur est survenue lors du traitement de la requête (données requises manquantes). Veuillez réessayer." + } + ), + 400, + ) + + meta = "Informations complémentaires :" + meta += "\n- Version de ScoDoc : " + scodoc.get("version", "inconnue") + meta += "\n- Dump : " + ( + ("inclus (id : " + dump.get("id", "inconnu") + ")") + if dump.get("included", False) + else "non inclus" + ) + meta += "\n- Établissement : " + ticket.get("etab") if ticket.get("etab") else "" + meta += "\n- Département : " + ticket.get("dept") if ticket.get("dept") else "" + + ticket_body = ticket.get("message") + "\n\n---\n\n" + meta + + response = requests.post( + GITEA_URL + "/api/v1/repos/" + GITEA_REPO + "/issues", + json={ + "title": ticket.get("title"), + "body": ticket_body, + "labels": [GITEA_LABEL_ID], + }, + headers={"Authorization": "token " + os.getenv("GITEA_TOKEN")}, + ) + + if response.status_code != 201: + log.write("gitea error\n") + try: + log.write("sending notification to {}\n".format(ALERT_MAIL_TO)) + email.send_email( + "[report] Gitea error !", + ALERT_MAIL_FROM, + [ALERT_MAIL_TO], + "Error " + + response.status_code + + " while creating the gitea ticket :\n" + + response.text + + "\n\nTicket info : " + + ticket.get("title") + + "\n" + + ticket_body + + "\n- Utilisateur : " + + user.get("name", "Nom inconnu") + + " <" + + user.get("email", "Adresse email inconnue") + + ">", + ) + except: + log.write("exception while sending email !\n") + log.close() + return ( + jsonify( + { + "message": "Une erreur est survenue lors de la création du ticket. Veuillez réessayer." + } + ), + 500, + ) + + try: + log.write("sending notification to {}\n".format(ALERT_MAIL_TO)) + email.send_email( + "[report] Ticket # " + + response.json()["id"] + + " créé avec succès ! : " + + ticket.get("title"), + ALERT_MAIL_FROM, + [ALERT_MAIL_TO], + "Nouveau ticket utilisateur :\n" + + meta + + "\n- Lien du ticket : " + + response.json()["url"] + + "\n- Utilisateur : " + + user.get("name", "Nom inconnu") + + " <" + + user.get("email", "Adresse email inconnue") + + ">", + ) + except: + log.write("exception while sending email !\n") + log.close() + + return ( + jsonify( + { + "message": "Votre demande a été enregistrée. Vous pouvez suivre son avancement sur " + + response.json()["html_url"] + + ". Vous êtes susceptible d'être contacté(e) par email à l'adresse liée à votre compte ScoDoc si des informations supplémentatires sont nécéssaires." + } + ), + 201, + ) + + @bp.route("/scodoc-installmgr/upload-dump", methods=["POST"]) def upload_scodoc9(): """Réception d'un fichier de dump""" @@ -121,7 +272,18 @@ def upload_scodoc9(): # Avec seulement alphanum et tiret: clean_deptname = re.sub(r"[^A-Za-z-]", "", request.form["dept_name"]) if not clean_deptname: - abort(400, "missing argument: dept_name") + return ( + jsonify( + { + "message": 'Erreur: champ dept_name manquant.\n Merci de contacter ' + + ALERT_MAIL_TO + + "

" + } + ), + 400, + ) try: remote_host = socket.gethostbyaddr(remote_addr)[0] except: @@ -171,7 +333,18 @@ def upload_scodoc9(): except: log.write("exception while sending email !\n") log.close() - abort(507, "Insufficient Storage") + return ( + jsonify( + { + "message": 'Erreur: espace de stockage insuffisant.\n Merci de contacter ' + + ALERT_MAIL_TO + + "

" + } + ), + 507, + ) else: log.write("writing dump to {}\n".format(D["dump_filename"])) # dump: @@ -196,7 +369,12 @@ def upload_scodoc9(): log.write("exception while sending email !\n") log.close() - return "Données envoyées." + return jsonify( + { + "message": "Données envoyées", + "dump_id": fulltime + "_" + clean_deptname, + } + ) @bp.route("/scodoc-installmgr/scodoc9") diff --git a/requirements.txt b/requirements.txt index a738062..3ce1064 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,12 +10,11 @@ Jinja2==3.0.1 MarkupSafe==2.0.1 mypy-extensions==0.4.3 pathspec==0.9.0 -pkg-resources==0.0.0 platformdirs==2.3.0 python-dotenv==0.19.0 regex==2021.8.28 tomli==1.2.1 -typed-ast==1.4.3 typing-extensions==3.10.0.2 Werkzeug==2.0.1 zipp==3.6.0 +requests==2.32.2 \ No newline at end of file