From 30e9c9328e65b38d5271bb3852894132801c3ab9 Mon Sep 17 00:00:00 2001 From: pika Date: Mon, 31 Mar 2025 00:19:49 +0200 Subject: [PATCH] wip --- __pycache__/config.cpython-313.pyc | Bin 0 -> 1762 bytes app/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 4041 bytes app/core/__pycache__/auth.cpython-313.pyc | Bin 0 -> 2626 bytes .../__pycache__/extensions.cpython-313.pyc | Bin 0 -> 927 bytes app/core/__pycache__/models.cpython-313.pyc | Bin 0 -> 6491 bytes .../template_filters.cpython-313.pyc | Bin 0 -> 3055 bytes app/routes/__pycache__/api.cpython-313.pyc | Bin 0 -> 16905 bytes app/routes/__pycache__/auth.cpython-313.pyc | Bin 0 -> 4721 bytes .../__pycache__/dashboard.cpython-313.pyc | Bin 0 -> 16109 bytes .../__pycache__/importexport.cpython-313.pyc | Bin 0 -> 4826 bytes app/routes/__pycache__/ipam.cpython-313.pyc | Bin 0 -> 12098 bytes app/routes/__pycache__/static.cpython-313.pyc | Bin 0 -> 5124 bytes app/routes/api.py | 60 ++-- .../__pycache__/ip_scanner.cpython-313.pyc | Bin 0 -> 7076 bytes app/templates/dashboard/app_form.html | 99 +++--- app/templates/dashboard/app_view.html | 302 ++++++++++++++---- .../__pycache__/app_utils.cpython-313.pyc | Bin 0 -> 4428 bytes instance/app.db | Bin 0 -> 36864 bytes 18 files changed, 320 insertions(+), 141 deletions(-) create mode 100644 __pycache__/config.cpython-313.pyc create mode 100644 app/__pycache__/__init__.cpython-313.pyc create mode 100644 app/core/__pycache__/auth.cpython-313.pyc create mode 100644 app/core/__pycache__/extensions.cpython-313.pyc create mode 100644 app/core/__pycache__/models.cpython-313.pyc create mode 100644 app/core/__pycache__/template_filters.cpython-313.pyc create mode 100644 app/routes/__pycache__/api.cpython-313.pyc create mode 100644 app/routes/__pycache__/auth.cpython-313.pyc create mode 100644 app/routes/__pycache__/dashboard.cpython-313.pyc create mode 100644 app/routes/__pycache__/importexport.cpython-313.pyc create mode 100644 app/routes/__pycache__/ipam.cpython-313.pyc create mode 100644 app/routes/__pycache__/static.cpython-313.pyc create mode 100644 app/scripts/__pycache__/ip_scanner.cpython-313.pyc create mode 100644 app/utils/__pycache__/app_utils.cpython-313.pyc create mode 100644 instance/app.db diff --git a/__pycache__/config.cpython-313.pyc b/__pycache__/config.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..30bb4be8bcf983808c826bbb02d701304c8faf63 GIT binary patch literal 1762 zcmZ{kOK;mo5P(UEq#l-RJ^ZL;S#^x2fQrOI3#135EuaULsJ5k)OQQ`SWGhRIqEsT4 zC2hbu87RQ_S;zw!{HzY z68!bD`Pj>Gf8fVNMAsM|f$@qX9O3sk#=XaFbHtP2i1(gnyn^wLPXM1-u8kPK}tJDh|=fBwYEF6MCp?j zGp%+@*K`A>eUvtgIv5_qw0)X>(qe{gdz+fYBq+sBk+1f%`}qg*!6T|F+58?os1!=Y zQa-DeDrI6vzE+DgPn05+%h}w%T(DP&ObE=;e5JBik||VwsL1vTrKVN0T6J2pEY>F8GGsnO9gjha=<6pZ?DN7F4c182@OT9##GTqNC7hMXLQhIt3n z58Q9U>P0mEI`J~`I`uO3Q>ed_KaUp9z8u{Cs4r{});9XW@*sKZTv%tzlkoW${tZn3 z|H6rviB(Bigvl9EqB9QoBmxoNU3vgwgK+5!O<&q?M+@4C);79$Jonzi5YdZI`6t(} z+Mz;L&E~R1riaS@zY+6!yJcy+nM|hE?d~*=9E9a`i1{G}3!uVh#THOugW6(2&K=%o zxCO)F8MdgsHg&U8JCy9DsR=p%pu*x9gBLZ%wu08$L}6C*HYnu3c@c`7$%E9^+h=c{ zz1837KR@n&UO7)a>!f{fdw<7V0|-k4ZZ^&;D_L~ zg`L+HdC1^>)UB4GyZrG`z1Wp|g1^YtVTL6@sV?co8%eVbSZ4cFnW&}mEO3^@L@`{k zs>lcOK~7e#zmd71-^VCaSfTkbC4YZS6ePMmD3EiF;L&qG~p!48B z8GZoj2IvBl;5X$1cz&mI!>VRlExqYd!<@Y(*Ed0?_F`8(y4%q@20Ps?y6^%w!@C8^ z#*pwe&4q!LGE}&+xe5wltY0j~ki#d~WoyZEVR?LFT$mQeeJ_ALZdwd=a?G@}?f-22 z)BJ*c2uqNT`6;MBy*$tV&ISIFB!2rZ4%8?n@*6)&BMyd9#K&*HI2my;jFv@y^F{G* J@NYU5{0F9{cVz$o literal 0 HcmV?d00001 diff --git a/app/__pycache__/__init__.cpython-313.pyc b/app/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..38132e00a180b2cf4407fcf3a708d32f82fbdc94 GIT binary patch literal 4041 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 YV(6I=DG8B3ML{@r;2>g`J+p872Mcg3mH+?% literal 0 HcmV?d00001 diff --git a/app/core/__pycache__/extensions.cpython-313.pyc b/app/core/__pycache__/extensions.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f73c28f053724323d5efbddd15c2103f2681f8a8 GIT binary patch literal 927 zcmYjOO>fgc5M4Woo!D`j1}K#Zt*I)i9Eb~250wxS1#xiNs^F`oXlrjAtNsY%O-mvn z1@%~QLi`ABoH_9mIB-Z;$^miejjDfuwVhU3$=>(g&g`3+z1B1Z@umE@^gfFS{Y}Zu zD$T$(_Z8-^ap^}QCd&K0KG1D@)PMD9CDLFmy$?5G8p9dcVTbf1Y zwBzts@nRS6T|f>jSbxI z8%_+wARj1+5&X>p1h1@v%I4<&> XiMICr;ZN$u-v>nE;#8v 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 WK%@7+yB{1F*x;l__mg(Z-oQWMlk3X> literal 0 HcmV?d00001 diff --git a/app/routes/__pycache__/api.cpython-313.pyc b/app/routes/__pycache__/api.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e859e0be5daa0c4df43c62c1fb76076a92aee8e7 GIT binary patch literal 16905 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 literal 0 HcmV?d00001 diff --git a/app/routes/__pycache__/auth.cpython-313.pyc b/app/routes/__pycache__/auth.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8382ee49fd37d5b24814c3f9d28cea27b9fc468 GIT binary patch literal 4721 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 OB1Ar2Pg$rMi~1*3QnNAu literal 0 HcmV?d00001 diff --git a/app/routes/__pycache__/dashboard.cpython-313.pyc b/app/routes/__pycache__/dashboard.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2b89819b281c09f5ac6add85eb1f92926508ea72 GIT binary patch literal 16109 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 literal 0 HcmV?d00001 diff --git a/app/routes/__pycache__/importexport.cpython-313.pyc b/app/routes/__pycache__/importexport.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3cfde01b0d4dfe193982aff8cbf84d1da6793cd9 GIT binary patch literal 4826 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 ND{}Cu86N3J`#*u$xl8~6 literal 0 HcmV?d00001 diff --git a/app/routes/__pycache__/static.cpython-313.pyc b/app/routes/__pycache__/static.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c135bf58cce74615575bd94170c7b5bc4a74c136 GIT binary patch literal 5124 zcmeHLT}&HS7QXZ2-*K?be^Lh~{3JL9&xRDtIzZBZ8wy#{;k7F5RG>x=dwJ&+2B2uOFW$&FIdk~;RTXv%GjOuu%kPLeg`Uw z(5K*TO*dymtk!{qIh(bm%XhH{?V59%QvDetV&o9^k1pYL-WlD_dXED$c6~;7x)oUc zc&ygC+y&~RSgY+D?kJAF81s7(h}T5qxHS_;*8B$mVsy+l;}FOW5VH$ZoSgF?U3r`` zM+$VDo@+d65pzU70w6hxV$fo0<3!A9u9pOYEpD4@Gj;VR^4DH(nUXml$`~8|GyR~r zy=B_OTy?8EXD$8iB$<|9&iElgW6j~*_R<%&I50$ z0=OG6$2vd~tzWQP=4aye!*g|_T?qDf?Xwa6nISSj_Z0M$uE%(|z_Zr$U?*ZR7H1kO zh-p5N7t_TYFR>zI)8e9#6O(B+n_=@=Ny-ZIDvi^tE%m;a%;vC_Sl^O$$v6TLw$u}a(6Vc^+e3bJtIvHZDM~6`NXidX z`eQLGK#T`9G|Gs%G!Iof|0pZTlIqMSAMyynkOcYP7t!`4m73>emBDCLloBZvbCnhg zyr9|^VOHi<2f{2Fp`2>dq0kk5l;R6=Rumw{{Gda1YvD?0OK>7AOJvaYAWjrCI4vZK zFo&m;3JCmomB^?BFFBBw)h{*7qJDW-~fG^50&`2{YWm1U7b5X(Wa zh+c?+tD(Xts`1(r+WhbWa*5qa&FH&b0x#{Lv3a#^rEN8^68P+4wIf{a2yeB1*-`O- zur!Udo`&V{)9~{6)A6;-Ri?Mh^gegGmzlpZf1BQMc7E^mFE2h_Tz>rY@!GV~H(v2x zUz$2Rs;|m)mznNwoNfEG+cmz|I{)O>UR&qtM@Pp0;~ZB=h~+1tG?RlJv< zx13$;Tc6x%32uD2*W9vtYvtD3R5j3F4)pId5Bx}h*2~}fT9o!1yS|&6Ft+ueIzCq( zpHs$SO6zZTeesu0;OSf|DQ~}9VQwn)%^&?}&~8icr^ z?n#_Qp&TkT=!kD7kwH&WZ$wWi5%MNGr4g=kN0Sn|P_9EPJM43z^zo5hNE>;ynIVSH-GdEN@+Q_98RiZ^`1C!%H?M4VD~-cdPq^#}YcM|Y z>Oh0>K`!b5&n^TehpA^{O-TOQ-;VFY?kMfp1`Z@|JKWJAwe4?+_E6hBHYAtYOc>AR z=ebOB0W)W)Ak6=Q;pltQuH%kVs6?(I%_$x}e!*~bD6B{Je~#f3I))o*po8HN08c?4 z9Rt`To8~jgVoqj7fwvw&D3nPh#*#_~l6RR%zPPv;nis|S93M)F`C8JU%(GzhTNBze z>Dnw7ho!(V;B4s8F`->YW^JALj8N0mFd3~-FU~!Nu3n(O88|zPaqw-FA`|E*`Az|u zn_5=GE8*4AmC<$Q#z3WMWa;+d`ntc$Tq-k{zQgr3;~M-|YvlF7+`mEZvhu$v_y|278t+dYU`feM*ym7w5gcUlBaXGZxGEgtC2Q^&o-}rE2 zLTUU})pMonxuW6n;463$MJC9owoEQ5J%ki$X(uG@KnC&uL{w)YAtdvBBB7G^3#v^! z&}iotjq|kdehv!yq8{qoZ*6`$y>&}WT zxJ2&T0ZIR*{ZH+RJ5nL8{Xm{0CWr$HkfZyWxF4zMFII?4Sbq(x`>^_&McZ8=dVU}S O#0b{*Y7)GHrv5iH+ya;Y literal 0 HcmV?d00001 diff --git a/app/routes/api.py b/app/routes/api.py index da88c8b..8cd2acb 100644 --- a/app/routes/api.py +++ b/app/routes/api.py @@ -1,4 +1,4 @@ -from flask import Blueprint, jsonify, request, abort, current_app, render_template +from flask import Blueprint, jsonify, request, abort, current_app, render_template, redirect, url_for from flask_login import login_required from app.core.models import Subnet, Server, App, Port from app.core.extensions import db @@ -197,15 +197,6 @@ def status(): return jsonify({"status": "OK"}) -@bp.route("/markdown-preview", methods=["POST"]) -@csrf.exempt # Remove this line in production! Temporary fix for demo purposes -def markdown_preview(): - data = request.json - md_content = data.get("markdown", "") - html = markdown.markdown(md_content) - return jsonify({"html": html}) - - @bp.route("/ports/suggest", methods=["GET"]) def suggest_ports(): app_type = request.args.get("type", "").lower() @@ -296,15 +287,15 @@ def add_app_port(app_id): valid, clean_port, error = validate_port_data(port_number, protocol, description) if not valid: - return jsonify({"success": False, "error": error}), 400 + flash(error, "danger") + return redirect(url_for("dashboard.app_view", app_id=app_id)) if not request.is_xhr else jsonify({"success": False, "error": error}), 400 # Check if port already exists existing_port = Port.query.filter_by(app_id=app_id, port_number=clean_port).first() if existing_port: - return jsonify({ - "success": False, - "error": f"Port {clean_port} already exists for this application" - }), 400 + error_msg = f"Port {clean_port} already exists for this application" + flash(error_msg, "warning") + return redirect(url_for("dashboard.app_view", app_id=app_id)) if not request.is_xhr else jsonify({"success": False, "error": error_msg}), 400 # Create new port new_port = Port( @@ -316,10 +307,17 @@ def add_app_port(app_id): db.session.add(new_port) db.session.commit() - flash(f"Port {clean_port}/{protocol} added successfully", "success") + success_msg = f"Port {clean_port}/{protocol} added successfully" + flash(success_msg, "success") + + # If it's a regular form submission (not AJAX), redirect + if not request.is_xhr and not request.is_json: + return redirect(url_for("dashboard.app_view", app_id=app_id)) + + # Otherwise return JSON for API/AJAX calls return jsonify({ "success": True, - "message": f"Port {clean_port}/{protocol} added successfully", + "message": success_msg, "port": { "id": new_port.id, "number": new_port.port_number, @@ -330,7 +328,8 @@ def add_app_port(app_id): except Exception as e: db.session.rollback() - return jsonify({"success": False, "error": str(e)}), 500 + flash(f"Error: {str(e)}", "danger") + return redirect(url_for("dashboard.app_view", app_id=app_id)) if not request.is_xhr else jsonify({"success": False, "error": str(e)}), 500 @bp.route("/app//ports", methods=["GET"]) @@ -357,25 +356,26 @@ def get_app_ports(app_id): return jsonify(result) -@bp.route("/port//delete", methods=["POST"]) +@bp.route("/app//port//delete", methods=["POST"]) @login_required -def delete_port(port_id): - """Delete a port""" - # Add CSRF validation - if request.is_json: # For AJAX requests - csrf_token = request.json.get("csrf_token") - if not csrf_token or not csrf.validate_csrf(csrf_token): - return jsonify({"success": False, "error": "CSRF validation failed"}), 403 - +def delete_app_port(app_id, port_id): + """Delete a port from an application""" + app = App.query.get_or_404(app_id) port = Port.query.get_or_404(port_id) - + + if port.app_id != app.id: + flash("Port does not belong to this application", "danger") + return redirect(url_for("dashboard.app_view", app_id=app_id)) + try: db.session.delete(port) db.session.commit() - return jsonify({"success": True, "message": f"Port {port.number} deleted"}) + flash(f"Port {port.port_number}/{port.protocol} deleted successfully", "success") except Exception as e: db.session.rollback() - return jsonify({"success": False, "error": str(e)}), 500 + flash(f"Error deleting port: {str(e)}", "danger") + + return redirect(url_for("dashboard.app_view", app_id=app_id)) @bp.route("/subnets//servers", methods=["GET"]) diff --git a/app/scripts/__pycache__/ip_scanner.cpython-313.pyc b/app/scripts/__pycache__/ip_scanner.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..202d10038042c7cc7eb8ce1f7a41d3e7e43891b2 GIT binary patch literal 7076 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 literal 0 HcmV?d00001 diff --git a/app/templates/dashboard/app_form.html b/app/templates/dashboard/app_form.html index 68f3e8b..bf1992b 100644 --- a/app/templates/dashboard/app_form.html +++ b/app/templates/dashboard/app_form.html @@ -66,34 +66,6 @@ Select the server where this application runs -
- - -
-
- - - Markdown formatting is supported. Include details about what this application does, contact info, etc. - -
-
-
-
Preview will be shown here...
-
-
-
-
- -
Port Configuration
-
@@ -112,16 +84,16 @@ - - - - + + + + {% if app and app.ports %} {% for port in app.ports %} - + {% endfor %} {% endif %} -
Port NumberProtocolDescriptionActionsPortProtocolDescription
@@ -146,13 +118,22 @@
Configure the network ports used by this application
+
+ + + + Use Markdown syntax + to format your documentation. The content will be rendered when viewing the application. + +
+ -
+
- +

Basic Information

@@ -35,44 +35,38 @@
Server
-
- - {{ server.hostname }} - - ({{ server.ip_address }}) -
+
{{ app.server.name }} ({{ + app.server.ip_address }})
Created
-
{{ app.created_at.strftime('%Y-%m-%d %H:%M') }}
+
{{ app.created_at }}
Last Updated
-
{{ app.updated_at.strftime('%Y-%m-%d %H:%M') }}
+
{{ app.updated_at }}
- +
-
+

Ports

-
- -
+
-
+
{% if app.ports %}
- +
- - - - + + + + @@ -80,12 +74,12 @@ - + {% endfor %} @@ -93,7 +87,7 @@
PortProtocolDescriptionPORTPROTOCOLDESCRIPTION
{{ port.port_number }} {{ port.protocol }}{{ port.description or 'No description' }}{{ port.description }} - +
{% else %} -
+
@@ -113,14 +107,14 @@
- -
+ +

Documentation

-
+
{% if app.documentation %} - {{ app.documentation|markdown }} + {{ app.documentation|markdown|safe }} {% else %}
@@ -144,23 +138,28 @@
-