diff --git a/app.py b/app.py index a1b3afe..23ba6d4 100644 --- a/app.py +++ b/app.py @@ -60,7 +60,6 @@ class Config: log_level = logging.DEBUG if os.getenv("DEBUG", "false").lower() == "true" else logging.INFO logging.basicConfig(level=log_level) -# 🔥 Flask / Werkzeug Access Logs reduzieren logging.getLogger("werkzeug").setLevel(logging.ERROR) logger = logging.getLogger("matrix-interceptor") @@ -122,6 +121,48 @@ def remember_user(user_id): def get_role(user_id): return "admin" if user_id in config.admin_users else "user" +# ============================================================ +# 🔥 NEW: LOCAL MEMBERSHIP CHECK +# ============================================================ + +def is_user_in_local_rooms(user_id: str) -> bool: + if not config.admin_token: + return False + + try: + headers = {"Authorization": f"Bearer {config.admin_token}"} + + rooms_res = requests.get( + f"{config.tuwunel_url}/_matrix/client/v3/joined_rooms", + headers=headers, + timeout=5 + ) + + if rooms_res.status_code != 200: + return False + + for room_id in rooms_res.json().get("joined_rooms", []): + if room_id.split(":")[1] != config.local_domain: + continue + + members_res = requests.get( + f"{config.tuwunel_url}/_matrix/client/v3/rooms/{room_id}/joined_members", + headers=headers, + timeout=5 + ) + + if members_res.status_code != 200: + continue + + members = members_res.json().get("joined", {}) + if user_id in members: + return True + + except Exception: + return False + + return False + # ============================================================ # DM DETECTION # ============================================================ @@ -234,7 +275,6 @@ def create_room(): payload ) - @app.route('/_matrix/federation/v2/invite//', methods=['PUT']) def invite(room_id, event_id): payload = request.get_json(force=True) @@ -248,11 +288,9 @@ def invite(room_id, event_id): domain = extract_domain(sender) is_dm = is_likely_dm_event(event) - # Rate limit if len(RATE_LIMIT[domain]) > config.rate_limit_per_minute: return Response(status=429) - # Whitelist if domain in config.domain_whitelist: remember_user(sender) return forward_request( @@ -262,8 +300,9 @@ def invite(room_id, event_id): payload ) + # 🔥 FIXED: combine cache + membership if config.block_external_dms and is_dm and is_external(sender): - if not is_known_user(sender): + if not (is_known_user(sender) or is_user_in_local_rooms(sender)): log_event( "invite_blocked",