diff --git a/__pycache__/config.cpython-313.pyc b/__pycache__/config.cpython-313.pyc new file mode 100644 index 0000000..30bb4be Binary files /dev/null and b/__pycache__/config.cpython-313.pyc differ diff --git a/app/__pycache__/__init__.cpython-313.pyc b/app/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..38132e0 Binary files /dev/null and b/app/__pycache__/__init__.cpython-313.pyc differ diff --git a/app/core/__pycache__/auth.cpython-313.pyc b/app/core/__pycache__/auth.cpython-313.pyc new file mode 100644 index 0000000..baa0e7c Binary files /dev/null and b/app/core/__pycache__/auth.cpython-313.pyc differ diff --git a/app/core/__pycache__/extensions.cpython-313.pyc b/app/core/__pycache__/extensions.cpython-313.pyc new file mode 100644 index 0000000..f73c28f Binary files /dev/null and b/app/core/__pycache__/extensions.cpython-313.pyc differ diff --git a/app/core/__pycache__/models.cpython-313.pyc b/app/core/__pycache__/models.cpython-313.pyc new file mode 100644 index 0000000..905c29a Binary files /dev/null and b/app/core/__pycache__/models.cpython-313.pyc differ diff --git a/app/core/__pycache__/template_filters.cpython-313.pyc b/app/core/__pycache__/template_filters.cpython-313.pyc new file mode 100644 index 0000000..af6067a Binary files /dev/null and b/app/core/__pycache__/template_filters.cpython-313.pyc differ diff --git a/app/routes/__pycache__/api.cpython-313.pyc b/app/routes/__pycache__/api.cpython-313.pyc new file mode 100644 index 0000000..e859e0b Binary files /dev/null and b/app/routes/__pycache__/api.cpython-313.pyc differ diff --git a/app/routes/__pycache__/auth.cpython-313.pyc b/app/routes/__pycache__/auth.cpython-313.pyc new file mode 100644 index 0000000..e8382ee Binary files /dev/null and b/app/routes/__pycache__/auth.cpython-313.pyc differ diff --git a/app/routes/__pycache__/dashboard.cpython-313.pyc b/app/routes/__pycache__/dashboard.cpython-313.pyc new file mode 100644 index 0000000..2b89819 Binary files /dev/null and b/app/routes/__pycache__/dashboard.cpython-313.pyc differ diff --git a/app/routes/__pycache__/importexport.cpython-313.pyc b/app/routes/__pycache__/importexport.cpython-313.pyc new file mode 100644 index 0000000..3cfde01 Binary files /dev/null and b/app/routes/__pycache__/importexport.cpython-313.pyc differ diff --git a/app/routes/__pycache__/ipam.cpython-313.pyc b/app/routes/__pycache__/ipam.cpython-313.pyc new file mode 100644 index 0000000..7c694f5 Binary files /dev/null and b/app/routes/__pycache__/ipam.cpython-313.pyc differ diff --git a/app/routes/__pycache__/static.cpython-313.pyc b/app/routes/__pycache__/static.cpython-313.pyc new file mode 100644 index 0000000..c135bf5 Binary files /dev/null and b/app/routes/__pycache__/static.cpython-313.pyc differ 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 0000000..202d100 Binary files /dev/null and b/app/scripts/__pycache__/ip_scanner.cpython-313.pyc differ 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 @@
-