diff options
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/api/signaling.py')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/api/signaling.py | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/api/signaling.py b/packages/meshbay-hub/src/meshbay_hub/api/signaling.py index 84c1167..a8feae8 100644 --- a/packages/meshbay-hub/src/meshbay_hub/api/signaling.py +++ b/packages/meshbay-hub/src/meshbay_hub/api/signaling.py @@ -22,6 +22,7 @@ from pydantic import BaseModel from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession +from meshbay_hub import hub_settings from meshbay_hub.api.deps import get_current_user from meshbay_hub.api.middleware import limiter from meshbay_hub.db.engine import get_db @@ -93,6 +94,11 @@ async def webrtc_offer( # The caller must share at least one active group with the target node, # OR the node must host at least one open-join group (public groups admit # anyone — the node's MNP handshake handles authorization). + # + # That second path is exactly what "public groups" means, so it is gated by + # the instance switch: with public groups off, a non-member is not brokered a + # connection to a node just because it happens to host an open group. Members + # of that group are unaffected — they match `shared` below. node_group_ids = set(_node_groups.get(node_id, [])) if node_group_ids: result = await db.execute( @@ -102,19 +108,24 @@ async def webrtc_offer( )) shared = [gid for (gid,) in result.all()] if not shared: - has_open = await db.execute( - select(Group.id).where( - Group.id.in_(node_group_ids), - Group.join_policy == "open", - Group.status == "active", - )) - if not has_open.first(): + has_open = None + if await hub_settings.public_groups_allowed(db): + has_open = (await db.execute( + select(Group.id).where( + Group.id.in_(node_group_ids), + Group.join_policy == "open", + Group.status == "active", + ))).first() + if not has_open: raise HTTPException(status_code=403, detail="Not a member of any group on this node") else: - active = await db.execute( - select(Group.id).where(Group.id.in_(shared), Group.status == "active")) - if not active.first(): - raise HTTPException(status_code=403, detail="Group is not active") + statuses = set((await db.execute( + select(Group.status).where(Group.id.in_(shared)))).scalars().all()) + if "active" not in statuses: + # Report the strongest state present — "revoked" is the signed, + # node-enforced one; "suspended" is the reversible hub flag. + state = "revoked" if "revoked" in statuses else next(iter(statuses), "suspended") + raise HTTPException(status_code=403, detail=f"Group is {state}") if _pending_per_user.get(current_user.id, 0) >= MAX_PENDING_PER_USER: raise HTTPException(status_code=429, detail="Too many pending connections") |