diff options
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/api/nodes.py')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/api/nodes.py | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/api/nodes.py b/packages/meshbay-hub/src/meshbay_hub/api/nodes.py index 7478173..6205180 100644 --- a/packages/meshbay-hub/src/meshbay_hub/api/nodes.py +++ b/packages/meshbay-hub/src/meshbay_hub/api/nodes.py @@ -11,15 +11,40 @@ from pydantic import BaseModel from sqlalchemy import func, select from sqlalchemy.ext.asyncio import AsyncSession -from meshbay_hub.api.deps import get_current_user +from meshbay_hub.api.deps import get_current_user, require_user_scope from meshbay_hub.api.middleware import limiter from meshbay_hub.api.netutil import client_ip -from meshbay_hub.auth import issue_access_token +from meshbay_hub.auth import issue_access_token, issue_mnp_token from meshbay_hub.db.engine import get_db from meshbay_hub.db.models import GroupMember, IPLog, Node, User router = APIRouter(prefix="/v1/nodes", tags=["nodes"]) + +@router.post("/mnp-token") +@limiter.limit("60/minute") +async def mnp_token( + request: Request, + current_user: User = Depends(require_user_scope), + db: AsyncSession = Depends(get_db), +): + """Mint the short-lived token a member presents to a node in the MNP handshake. + + Asked for with the member's own session token (require_user_scope, so a node + daemon token cannot mint one). The result carries the member's current group + membership and `aud=MNP_AUD`, so it authorises the member to a node and is + refused by the hub API. Short-lived on purpose; the client refetches it for a + new connection or a reconnect, and it is checked only at the handshake, so a + film already playing is never interrupted by its expiry. + """ + rows = await db.execute( + select(GroupMember.group_id).where(GroupMember.user_id == current_user.id)) + group_ids = [gid for (gid,) in rows.all()] + return { + "mnp_token": issue_mnp_token(current_user.id, groups=group_ids), + "expires_in": 900, + } + NODE_AUTH_TIMESTAMP_WINDOW = 60 # seconds |