summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/api
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-01 20:50:45 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-01 20:50:45 +0200
commit1e6db7d23c70b7bd7e1422f09911b3645f0fb2e2 (patch)
tree5ff1816f18625dfece9eb67fa06c7b25fdece4f8 /packages/meshbay-hub/src/meshbay_hub/api
parenta9eb121476eb8128e0cf1ae280ed0fea84d4b2aa (diff)
downloadmeshbay-1e6db7d23c70b7bd7e1422f09911b3645f0fb2e2.tar.gz
revert(hub): M6 — add_group_member must keep accepting node tokens
M6 in the third review was a misread. `add_group_member` accepting a node-scoped token is deliberate (commit 0443cf8): the node calls POST /v1/groups/{id}/members/{username} after a CLI `member invite` so the group shows up in the invitee's SPA, authenticating with a node-scoped token. `group.admin_id == caller` is the real guard. An older test (`test_node_scope_blocks_add_member`) asserted the opposite and had been left red on main; the M6 "fix" (commit 6b38704) satisfied that test by switching the dependency to `require_user_scope` — which made `ops.create_invite`'s hub-membership call 403. That exception is swallowed with a log.warning, so an invited user silently never lands in group_members and the group is invisible to them. Reported from live testing (CLI `member invite grenet`, grenet saw nothing). Dependency back to `get_current_user`. The stale test now asserts the intended behaviour: a node token may add a member to its own operator's group (201) but not to a group it does not own (403). Third-review M6 marked WITHDRAWN. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pG75yGK3NthNfyjH74omG
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/api')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/api/groups.py14
1 files changed, 8 insertions, 6 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/api/groups.py b/packages/meshbay-hub/src/meshbay_hub/api/groups.py
index 15c7a5d..07d3ec0 100644
--- a/packages/meshbay-hub/src/meshbay_hub/api/groups.py
+++ b/packages/meshbay-hub/src/meshbay_hub/api/groups.py
@@ -586,14 +586,16 @@ async def update_group(
async def add_group_member(
group_id: str,
username: str,
- current_user: User = Depends(require_user_scope),
+ current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
- # `require_user_scope`, like every other mutating group endpoint: a
- # node-scoped daemon token must not manage membership (NS7 — the operator
- # manages groups from the browser). This was the one membership endpoint
- # still on `get_current_user`, so a node token could add members to its
- # operator's own groups.
+ # `get_current_user`, not `require_user_scope`: the node calls this after a
+ # CLI `member invite` so the group becomes visible in the invitee's SPA
+ # (commit 0443cf8). The node authenticates with a node-scoped token, and the
+ # `group.admin_id == current_user.id` check below is the real guard — a node
+ # can only touch its own operator's groups, adding an already-registered
+ # account. (Third-review M6 proposed tightening this to `require_user_scope`;
+ # that broke the CLI invite flow and was reverted — see the review doc.)
group = await db.get(Group, group_id)
if not group:
raise HTTPException(status_code=404, detail="Group not found")