diff --git a/README.md b/README.md
index 34868d9..740d862 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,9 @@ Côté ScoDoc, créer un rôle et un utilisateur dédiés:
flask create-role AutoSco
flask edit-role AutoSco -a ScoView
flask user-create autosco AutoSco @all
+flask user-edit autosco --allow-scodoc-login
flask user-password autosco
+
```
Configurer les paramètres d'accès dans AutoSco: éditer le fichier
diff --git a/app/__init__.py b/app/__init__.py
index fa80920..f8ccff6 100644
--- a/app/__init__.py
+++ b/app/__init__.py
@@ -1,6 +1,10 @@
-from flask import current_app, g, request
+import sys
+import time
+
+from flask import current_app, g, render_template, request
from flask import Flask
+from scodoc.api import APIError, ScoDocAuthError
from config import DevConfig
@@ -18,6 +22,30 @@ class ReverseProxied:
environ["wsgi.url_scheme"] = scheme # ou forcer à https ici ?
return self.app(environ, start_response)
+# --------- Logging
+def log(msg: str):
+ """log a message.
+ If Flask app, use configured logger, else stderr.
+ """
+ if current_app and not current_app.config["DEBUG"]:
+ current_app.logger.info(msg)
+ else:
+ sys.stdout.flush()
+ sys.stderr.write(
+ f"""[{time.strftime("%a %b %d %H:%M:%S %Y")}] scodoc: {msg}\n"""
+ )
+ sys.stderr.flush()
+
+def handle_sco_api_error(exc):
+ "page d'erreur avec message"
+ log("Error: handle_sco_api_error")
+ return render_template("errors/sco_api_error.j2", exc=exc), 404
+
+def handle_sco_auth_error(exc):
+ "page d'erreur avec message"
+ log("Error: handle_sco_auth_error")
+ return render_template("errors/sco_auth_error.j2", exc=exc), 404
+
def create_app(config_class=DevConfig):
app = Flask(__name__, static_url_path="/AutoSco/static", static_folder="static")
@@ -27,4 +55,8 @@ def create_app(config_class=DevConfig):
from app.views import bp
app.register_blueprint(bp)
+
+ app.register_error_handler(APIError, handle_sco_api_error)
+ app.register_error_handler(ScoDocAuthError, handle_sco_auth_error)
+
return app
diff --git a/app/templates/errors/sco_api_error.j2 b/app/templates/errors/sco_api_error.j2
new file mode 100644
index 0000000..8d665c0
--- /dev/null
+++ b/app/templates/errors/sco_api_error.j2
@@ -0,0 +1,13 @@
+{% extends 'base.j2' %}
+
+{% block content %}
+
+
+
Erreur API
+
ScoDoc a renvoyé une erreur {{exc.status_code}}
+
Message: {{exc.payload["message"]}}
+
Requête: {{exc.message}}
+
Si le problème persiste, veuillez contacter le support technique.
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/app/templates/errors/sco_auth_error.j2 b/app/templates/errors/sco_auth_error.j2
new file mode 100644
index 0000000..402bd2e
--- /dev/null
+++ b/app/templates/errors/sco_auth_error.j2
@@ -0,0 +1,11 @@
+{% extends 'base.j2' %}
+
+{% block content %}
+
+
+
Erreur d'authentification
+
AutoSco ne parvient pas à se connecter à ScoDoc
+
Si le problème persiste, veuillez contacter le support technique.
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/autosco.py b/autosco.py
index c938aba..97d3dba 100755
--- a/autosco.py
+++ b/autosco.py
@@ -45,7 +45,6 @@ def make_shell_context():
"scu": scu,
}
+# Start using:
+# flask run -p 5001 --host 0.0.0.0 --debug
-if __name__ == "__main__":
- port = os.environ.get("PORT", 5001)
- app.run(debug=True, port=port)
diff --git a/config.py b/config.py
index a718315..f8457c0 100644
--- a/config.py
+++ b/config.py
@@ -40,7 +40,7 @@ class Config:
SCODOC_CHECK_CERTIFICATE = os.environ.get("SCODOC_CHECK_CERTIFICATE", True)
API_TIMEOUT = 120 # 2 minutes
API_URL = SCODOC_URL + "/ScoDoc/api"
- SCODOC_DEPT_ACRONYM = "ESPL"
+ SCODOC_DEPT_ACRONYM = os.environ.get("SCODOC_DEPT_ACRONYM", "ESPL")
def __getitem__(self, k) -> str | int | None:
return getattr(self, k)
diff --git a/scodoc/api.py b/scodoc/api.py
index 23ae7b3..f835597 100644
--- a/scodoc/api.py
+++ b/scodoc/api.py
@@ -7,20 +7,8 @@ from flask import current_app
import config
-def get_auth_headers(user: str, password: str, conf: config.Config) -> dict:
- "Demande de jeton, dict à utiliser dans les en-têtes de requêtes http"
- ans = requests.post(
- conf["API_URL"] + "/tokens",
- auth=(user, password),
- timeout=conf["API_TIMEOUT"],
- )
- if ans.status_code != 200:
- raise APIError(f"Echec demande jeton par {user}", status_code=ans.status_code)
- token = ans.json()["token"]
- return {"Authorization": f"Bearer {token}"}
-
-
class APIError(Exception):
+ "Error using ScoDoc API"
def __init__(self, message: str = "", payload=None, status_code=None):
self.message = message
self.payload = payload or {}
@@ -29,6 +17,20 @@ class APIError(Exception):
def __str__(self):
return f"APIError: {self.message} payload={self.payload} status_code={self.status_code}"
+class ScoDocAuthError(APIError):
+ "Error getting ScoDoc token"
+
+def get_auth_headers(user: str, password: str, conf: config.Config) -> dict:
+ "Demande de jeton, dict à utiliser dans les en-têtes de requêtes http"
+ ans = requests.post(
+ conf["API_URL"] + "/tokens",
+ auth=(user, password),
+ timeout=conf["API_TIMEOUT"],
+ )
+ if ans.status_code != 200:
+ raise ScoDocAuthError(f"Echec demande jeton par {user}", status_code=ans.status_code)
+ token = ans.json()["token"]
+ return {"Authorization": f"Bearer {token}"}
class APIAccessor:
"Gestion bas niveau des accès à l'API ScoDoc"
@@ -64,9 +66,9 @@ class APIAccessor:
print("url", url)
print("reply", reply.text)
try:
- payload = r.json()
+ payload = reply.json()
except requests.exceptions.JSONDecodeError:
- payload = r.text
+ payload = reply.text
raise APIError(
errmsg or f"""erreur get {url} !""",
payload,