Assign members to Cloudron 'members' group via PUT /users/:id/groups (verified endpoint)
This commit is contained in:
1 parent
7b84025e60
commit
c1efd39c5c
2 files changed
+23
-1
No files matched your search
@@ -42,6 +42,7 @@ LibreChat ──→ Member Portal ──→ LiteLLM ──→ backend
|
||||
|----------|---------|
|
||||
| `CLOUDRON_API` | Cloudron API origin (auto-set by Cloudron) |
|
||||
| `CLOUDRON_TOKEN` | Cloudron API token (Read+Write) |
|
||||
| `MEMBERS_GROUP_ID` | Cloudron group ID for members (grants chat access) |
|
||||
| `LITELLM_BASE` | LiteLLM gateway URL |
|
||||
| `LITELLM_MASTER_KEY` | LiteLLM master key |
|
||||
| `OPENCOLLECTIVE_WEBHOOK_SECRET` | Optional webhook signature secret |
|
||||
|
||||
+22
-1
@@ -41,6 +41,10 @@ TIER_BUDGETS = {
|
||||
}
|
||||
DEFAULT_TIER = "member"
|
||||
|
||||
# The "members" group in Cloudron (group-based access control).
|
||||
# Members are assigned to this group, which grants access to the chat app.
|
||||
MEMBERS_GROUP_ID = os.environ.get("MEMBERS_GROUP_ID", "")
|
||||
|
||||
# --- Helpers ---
|
||||
|
||||
def cloudron_headers() -> dict:
|
||||
@@ -48,11 +52,13 @@ def cloudron_headers() -> dict:
|
||||
|
||||
|
||||
async def cloudron_create_user(email: str, name: str) -> str:
|
||||
"""Create (or return existing) Cloudron user, assigned to the chat app.
|
||||
"""Create (or return existing) Cloudron user, assigned to the members group.
|
||||
|
||||
Verified user shape (from live API):
|
||||
{id, username, email, fallbackEmail, displayName, role, active, groupIds}
|
||||
Roles: "owner", "admin", "user".
|
||||
Group assignment is a SEPARATE call: PUT /api/v1/users/:userId/groups
|
||||
with body {"groupIds": [...]}.
|
||||
"""
|
||||
async with httpx.AsyncClient() as client:
|
||||
# Check if user exists
|
||||
@@ -81,6 +87,20 @@ async def cloudron_create_user(email: str, name: str) -> str:
|
||||
return r.json()["id"]
|
||||
|
||||
|
||||
async def cloudron_set_group(user_id: str) -> None:
|
||||
"""Assign a user to the members group (grants chat app access)."""
|
||||
if not MEMBERS_GROUP_ID:
|
||||
logger.warning("MEMBERS_GROUP_ID not set; skipping group assignment")
|
||||
return
|
||||
async with httpx.AsyncClient() as client:
|
||||
r = await client.put(
|
||||
f"{CLOUDRON_API}/api/v1/users/{user_id}/groups",
|
||||
headers=cloudron_headers(),
|
||||
json={"groupIds": [MEMBERS_GROUP_ID]},
|
||||
)
|
||||
r.raise_for_status()
|
||||
|
||||
|
||||
async def cloudron_set_active(user_id: str, active: bool) -> None:
|
||||
async with httpx.AsyncClient() as client:
|
||||
r = await client.post(
|
||||
@@ -163,6 +183,7 @@ async def opencollective_webhook(request: Request):
|
||||
tier = (data.get("tier") or {}).get("slug", DEFAULT_TIER)
|
||||
budget = TIER_BUDGETS.get(tier, TIER_BUDGETS[DEFAULT_TIER])
|
||||
user_id = await cloudron_create_user(email, name)
|
||||
await cloudron_set_group(user_id)
|
||||
await cloudron_set_active(user_id, True)
|
||||
await litellm_create_key(email, budget)
|
||||
return JSONResponse({"status": "activated", "user_id": user_id, "budget": budget})
|
||||
|
||||
Reference in new issue
Block a user