Browse Source

Added code to display errors

master
Youen 2 years ago
parent
commit
634149d9fe
  1. 3
      src/api/api_document.py
  2. 8
      src/app.py
  3. 13
      src/data/document.py
  4. 8
      src/templates/error.html
  5. 3
      src/web/admin/admin.py
  6. 10
      src/web_utils/business_exception.py
  7. 3
      src/web_utils/get_arg.py
  8. 3
      src/web_utils/run.py
  9. 3
      src/web_utils/task.py

3
src/api/api_document.py

@ -1,5 +1,6 @@
from flask import Blueprint, request from flask import Blueprint, request
from web_utils.get_arg import get_arg from web_utils.get_arg import get_arg
from web_utils.business_exception import BusinessException
import os import os
from data.document import Document from data.document import Document
@ -14,7 +15,7 @@ def build():
doc = Document(doc_name, branch) doc = Document(doc_name, branch)
if doc.get_api_key() != apikey: if doc.get_api_key() != apikey:
raise Exception("Invalid API key") raise BusinessException("Invalid API key")
build_task = doc.build() build_task = doc.build()
build_task.join() build_task.join()

8
src/app.py

@ -1,10 +1,14 @@
import os import os
import random import random
import string import string
from flask import Flask from web_utils.business_exception import BusinessException
from flask import Flask, render_template
import data.document import data.document
def handle_exceptions(e):
return render_template("error.html", message = str(e))
def create_app(): def create_app():
app = Flask(__name__) app = Flask(__name__)
@ -29,6 +33,8 @@ def create_app():
raise Exception("Internal error: insecure secret key") raise Exception("Internal error: insecure secret key")
app.secret_key = secret_key app.secret_key = secret_key
app.register_error_handler(BusinessException, handle_exceptions)
if app.config['BEHIND_REVERSE_PROXY']: if app.config['BEHIND_REVERSE_PROXY']:
from werkzeug.middleware.proxy_fix import ProxyFix from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1) app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1)

13
src/data/document.py

@ -2,6 +2,7 @@ import os
import uuid import uuid
from flask import current_app from flask import current_app
from web_utils.task import ProcessTask from web_utils.task import ProcessTask
from web_utils.business_exception import BusinessException
import shutil import shutil
from unicodedata import normalize from unicodedata import normalize
import string import string
@ -24,7 +25,7 @@ def sanitize_name(initial_name):
valid_chars = "-_.(){0}{1}".format(string.ascii_letters, string.digits) valid_chars = "-_.(){0}{1}".format(string.ascii_letters, string.digits)
name = "".join(ch for ch in name if ch in valid_chars) name = "".join(ch for ch in name if ch in valid_chars)
if len(name) == 0 or '..' in name: if len(name) == 0 or '..' in name:
raise Exception("Invalid name: " + initial_name) raise BusinessException("Invalid name: " + initial_name)
return name return name
class Document: class Document:
@ -38,7 +39,7 @@ class Document:
self.valid = False self.valid = False
return return
else: else:
raise Exception("This document does not exist: "+doc_name+"@"+branch) raise BusinessException("This document does not exist: "+doc_name+"@"+branch)
self.doc_path = doc_path self.doc_path = doc_path
self.valid = True self.valid = True
@ -73,7 +74,7 @@ class Document:
def make_doc_path(doc_name, branch): def make_doc_path(doc_name, branch):
doc_path = os.path.realpath(get_document_root()+'/'+sanitize_name(doc_name)+'/'+sanitize_name(branch)) doc_path = os.path.realpath(get_document_root()+'/'+sanitize_name(doc_name)+'/'+sanitize_name(branch))
if not doc_path.startswith(get_document_root()): if not doc_path.startswith(get_document_root()):
raise Exception("Invalid document path for "+doc_name+"@"+branch) raise BusinessException("Invalid document path for "+doc_name+"@"+branch)
return doc_path return doc_path
@staticmethod @staticmethod
@ -81,14 +82,14 @@ class Document:
# check the document does not already exist # check the document does not already exist
doc_path = Document.make_doc_path(doc_name, branch) doc_path = Document.make_doc_path(doc_name, branch)
if os.path.isdir(doc_path): if os.path.isdir(doc_path):
raise Exception("This document already exists: "+doc_name+"@"+branch) raise BusinessException("This document already exists: "+doc_name+"@"+branch)
if source_dir != sanitize_name(source_dir): if source_dir != sanitize_name(source_dir):
raise Exception("Invalid source directory name: " + source_dir) raise BusinessException("Invalid source directory name: " + source_dir)
# we have potentially serious security issues related to cloning anything. For example cloning from SSH may use a pre-configured server identity, etc. # we have potentially serious security issues related to cloning anything. For example cloning from SSH may use a pre-configured server identity, etc.
if not repo.startswith("https://"): if not repo.startswith("https://"):
raise Exception("Only HTTPS repositories are allowed in current implementation") raise BusinessException("Only HTTPS repositories are allowed in current implementation")
# Generate an API key # Generate an API key
apikey = str(uuid.uuid4()) apikey = str(uuid.uuid4())

8
src/templates/error.html

@ -0,0 +1,8 @@
{% extends 'base.html' %}
{% block title %}Erreur{% endblock %}
{% block content %}
<h2>Une erreur s'est produite</h2>
<p>{{message}}</p>
{% endblock %}

3
src/web/admin/admin.py

@ -1,6 +1,7 @@
import os import os
import random import random
import string import string
from web_utils.business_exception import BusinessException
from flask import current_app, Blueprint, render_template, session, redirect, url_for, request from flask import current_app, Blueprint, render_template, session, redirect, url_for, request
from data.document import Document from data.document import Document
@ -31,6 +32,6 @@ def login():
session['authenticated'] = True session['authenticated'] = True
return redirect(url_for('admin.index'), code=302) return redirect(url_for('admin.index'), code=302)
else: else:
raise Exception("Incorrect password") raise BusinessException("Incorrect password")
else: else:
return render_template("admin/login.html") return render_template("admin/login.html")

10
src/web_utils/business_exception.py

@ -0,0 +1,10 @@
class BusinessException(Exception):
def __init__(self, *args):
super().__init__(args)
self.message = args[0]
def __str__(self):
if hasattr(self, 'message'):
return self.message
else:
return super().__str__()

3
src/web_utils/get_arg.py

@ -1,10 +1,11 @@
from web_utils.business_exception import BusinessException
from flask import request from flask import request
def get_arg(arg_name, default_value = None): def get_arg(arg_name, default_value = None):
result = request.args.get(arg_name) result = request.args.get(arg_name)
if result == None: if result == None:
if default_value == None: if default_value == None:
raise Exception("Missing query string parameter '"+arg_name+"'") raise BusinessException("Missing query string parameter '"+arg_name+"'")
else: else:
return default_value return default_value
return result return result

3
src/web_utils/run.py

@ -1,4 +1,5 @@
from subprocess import Popen, PIPE, STDOUT from subprocess import Popen, PIPE, STDOUT
from web_utils.business_exception import BusinessException
def run(cmd): def run(cmd):
p = Popen(cmd, stdout = PIPE, stderr = STDOUT, shell = True) p = Popen(cmd, stdout = PIPE, stderr = STDOUT, shell = True)
@ -9,6 +10,6 @@ def run(cmd):
p.wait() p.wait()
if p.returncode != 0: if p.returncode != 0:
raise Exception("Command failed ("+str(p.returncode)+")\n"+cmd+"\n"+outputStr) raise BusinessException("Command failed ("+str(p.returncode)+")\n"+cmd+"\n"+outputStr)
return outputStr return outputStr

3
src/web_utils/task.py

@ -2,6 +2,7 @@ from threading import Thread, Lock
from io import StringIO from io import StringIO
from subprocess import Popen, PIPE, STDOUT, DEVNULL from subprocess import Popen, PIPE, STDOUT, DEVNULL
import uuid import uuid
from web_utils.business_exception import BusinessException
tasks = {} tasks = {}
@ -61,4 +62,4 @@ class ProcessTask(Task):
if self.__process.returncode != 0: if self.__process.returncode != 0:
if self.__fail_callback: if self.__fail_callback:
self.__fail_callback() self.__fail_callback()
raise Exception("Command failed ("+str(self.__process.returncode)+")\n"+self.get_output_str()) raise BusinessException("Command failed ("+str(self.__process.returncode)+")\n"+self.get_output_str())
Loading…
Cancel
Save