diff --git a/config.example.py b/config.example.py
index 6831062..1682dd4 100644
--- a/config.example.py
+++ b/config.example.py
@@ -10,11 +10,6 @@ class Config:
FLOWSPEC6_MAX_RULES = 9000
RTBH_MAX_RULES = 100000
- # Flask debugging
- DEBUG = True
- # Flask testing
- TESTING = False
-
# Choose your authentication method and set it to True here or
# the production / development config
# SSO auth enabled
@@ -104,6 +99,8 @@ class DevelopmentConfig(Config):
SQLALCHEMY_DATABASE_URI = "Your Local Database URI"
LOCAL_IP = "127.0.0.1"
LOCAL_IP6 = "::ffff:127.0.0.1"
+
+ # Debug and Devel mode enabled
DEBUG = True
DEVEL = True
diff --git a/flowapp/__about__.py b/flowapp/__about__.py
index 1ef1e64..da7547d 100755
--- a/flowapp/__about__.py
+++ b/flowapp/__about__.py
@@ -1,4 +1,4 @@
-__version__ = "1.1.9"
+__version__ = "1.2.0"
__title__ = "ExaFS"
__description__ = "Tool for creation, validation, and execution of ExaBGP messages."
__author__ = "CESNET / Jiri Vrany, Petr Adamec, Josef Verich, Jakub Man"
diff --git a/flowapp/__init__.py b/flowapp/__init__.py
index d1ea49d..5bed6f8 100644
--- a/flowapp/__init__.py
+++ b/flowapp/__init__.py
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
-import os
-from flask import Flask, redirect, render_template, session, url_for
+from flask import Flask, redirect, render_template, session, url_for, flash
from flask_sso import SSO
from flask_sqlalchemy import SQLAlchemy
@@ -128,11 +127,15 @@ def select_org(org_id=None):
user = db.session.query(models.User).filter_by(uuid=uuid).first()
if user is None:
- return render_template("errors/404.html"), 404 # Handle missing user gracefully
+ return render_template("errors/404.html"), 404
orgs = user.organization
if org_id:
- org = db.session.query(models.Organization).filter_by(id=org_id).first()
+ # Verify user belongs to this organization
+ org = user.organization.filter_by(id=org_id).first()
+ if not org:
+ flash("You don't have access to this organization", "alert-danger")
+ return redirect(url_for("index"))
session["user_org_id"] = org.id
session["user_org"] = org.name
return redirect("/")
diff --git a/flowapp/auth.py b/flowapp/auth.py
index a26628b..f484386 100644
--- a/flowapp/auth.py
+++ b/flowapp/auth.py
@@ -48,11 +48,13 @@ def decorated(*args, **kwargs):
def user_or_admin_required(f):
"""
decorator for admin/user endpoints
+ Allows access if the user has at least one role with ID > 1 (user or admin)
+ Role IDs: 1=view (read-only), 2=user (can create/edit), 3=admin
"""
@wraps(f)
def decorated(*args, **kwargs):
- if not all(i > 1 for i in session["user_role_ids"]):
+ if not any(i > 1 for i in session["user_role_ids"]):
return redirect(url_for("index"))
return f(*args, **kwargs)
diff --git a/flowapp/constants.py b/flowapp/constants.py
index 819f685..b37c8a0 100644
--- a/flowapp/constants.py
+++ b/flowapp/constants.py
@@ -35,9 +35,9 @@
MAX_PORT = 65535
MAX_PACKET = 9216
-IPV6_NEXT_HEADER = {"tcp": "tcp", "udp": "udp", "icmp": "58", "all": ""}
+IPV6_NEXT_HEADER = {"tcp": "tcp", "udp": "udp", "icmp": "58", "gre": "gre", "all": ""}
-IPV4_PROTOCOL = {"tcp": "tcp", "udp": "udp", "icmp": "icmp", "all": ""}
+IPV4_PROTOCOL = {"tcp": "tcp", "udp": "udp", "icmp": "icmp", "gre": "gre", "all": ""}
IPV4_FRAGMENT = {
"dont": "dont-fragment",
diff --git a/flowapp/instance_config.py b/flowapp/instance_config.py
index 4136530..bded1ca 100644
--- a/flowapp/instance_config.py
+++ b/flowapp/instance_config.py
@@ -102,8 +102,14 @@ class InstanceConfig:
"divide_before": True,
},
{"name": "Add action", "url": "admin.action"},
- {"name": "RTBH Communities", "url": "admin.communities"},
+ {
+ "name": "RTBH Communities",
+ "url": "admin.communities",
+ "divide_before": True,
+ },
{"name": "Add RTBH Comm.", "url": "admin.community"},
+ {"name": "AS Paths", "url": "admin.as_paths"},
+ {"name": "Add AS Path", "url": "admin.as_path"},
],
}
DASHBOARD = {
diff --git a/flowapp/templates/macros.html b/flowapp/templates/macros.html
index 661be2f..a8495e8 100644
--- a/flowapp/templates/macros.html
+++ b/flowapp/templates/macros.html
@@ -52,9 +52,12 @@
-
-
-
+
{% endif %}
{% if rule.comment %}