From f769d78a1451c6af812e7c3dd8f087bdec6f30e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=BCller?= Date: Tue, 7 Jul 2026 10:19:18 +0200 Subject: [PATCH] First version --- .gitignore | 2 + app.py | 79 ++++++ requirements.txt | 3 + templates/benutzer_template.html | 131 ++++++++++ templates/index.html | 416 +++++++++++++++++++++++++++++++ 5 files changed, 631 insertions(+) create mode 100644 .gitignore create mode 100644 app.py create mode 100644 requirements.txt create mode 100644 templates/benutzer_template.html create mode 100644 templates/index.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cae6e38 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.docx +*.pdf \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..0fc17f1 --- /dev/null +++ b/app.py @@ -0,0 +1,79 @@ +import secrets +import datetime +from flask import Flask, render_template, request, jsonify, send_file +from weasyprint import HTML +import io + +app = Flask(__name__) + +def generate_secure_password(): + # Length: randomly between 12 and 16 characters + length = secrets.choice(range(12, 17)) + + # Allowed Characters + upper = "ABCDEFGHJKMNPQRSTUVWXYZ" # without I, L, O + lower = "abcdefghjkmnpqrstuvwxyz" # without i, l, o + digits = "23456789" # without 0, 1 + special = "!§$%&/()=?\\+#*-_,;.:@€" + + while True: + password = ''.join(secrets.choice(upper + lower + digits + special) for _ in range(length)) + + # Minimum 2 characters from each category + if (sum(c in upper for c in password) >= 2 and + sum(c in lower for c in password) >= 2 and + sum(c in digits for c in password) >= 2 and + sum(c in special for c in password) >= 2): + + # Double check that no forbidden characters somehow made it in + forbidden = "ILOilo01ÄÖÜäöü<>|~´`'^°\"" + if not any(c in forbidden for c in password): + return password + +@app.route('/') +def index(): + return render_template('index.html') + +@app.route('/api/generate_password', methods=['GET']) +def api_generate_password(): + password = generate_secure_password() + return jsonify({"password": password}) + +@app.route('/download_pdf', methods=['POST']) +def download_pdf(): + vorname = request.form.get('vorname', '') + nachname = request.form.get('nachname', '') + benutzername = request.form.get('benutzername', '') + passwort = request.form.get('passwort', '') + + datum = datetime.datetime.now().strftime("%d.%m.%Y") + + # Render template + html_out = render_template( + 'benutzer_template.html', + VORNAME=vorname, + NACHNAME=nachname, + BENUTZERNAME=benutzername, + PASSWORT=passwort, + DATUM=datum + ) + + # Generate PDF + pdf_file = io.BytesIO() + HTML(string=html_out).write_pdf(pdf_file) + pdf_file.seek(0) + + # Format filename safely + safe_vorname = vorname.replace(' ', '_') + safe_nachname = nachname.replace(' ', '_') + filename = f"Benutzerantrag_{safe_vorname}_{safe_nachname}.pdf" + + return send_file( + pdf_file, + download_name=filename, + as_attachment=True, + mimetype='application/pdf' + ) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000, debug=True) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..58e11ca --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +Flask==3.0.3 +WeasyPrint==62.1 +gunicorn==22.0.0 diff --git a/templates/benutzer_template.html b/templates/benutzer_template.html new file mode 100644 index 0000000..57d4513 --- /dev/null +++ b/templates/benutzer_template.html @@ -0,0 +1,131 @@ + + + + + Benutzerantrag - {{VORNAME}} {{NACHNAME}} + + + +
+ +
+
+ Logo +
+
Windows- & Office-Anmeldung
+
Intranet- & Helpdesk-Anmeldung
+ +
+
+ Benutzername: + {{BENUTZERNAME}} +
+
+ Kennwort: + {{PASSWORT}} +
+
+ E-Mail-Adresse: + {{BENUTZERNAME}}@azintec.com +
+
+ +
+
SAGE
+
+ Windows NT-Anmeldedaten verwenden +
+
+
+ + +
+
+ + diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..0ca63ae --- /dev/null +++ b/templates/index.html @@ -0,0 +1,416 @@ + + + + + + AZess - Benutzerantrag + + + + + + + + +
+
+

AZess

+
IT Admin Benutzer-Einrichtung
+ +
+
+ + +
+
+ + +
+
+ + + +
+
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + + + +