planka: default users to project owners

This commit is contained in:
Brad Stein 2026-01-12 23:24:09 -03:00
parent 35a19a2f7b
commit 4d6d0b89b2
2 changed files with 95 additions and 12 deletions

View File

@ -2,7 +2,7 @@
apiVersion: batch/v1
kind: Job
metadata:
name: keycloak-realm-settings-15
name: keycloak-realm-settings-16
namespace: sso
spec:
backoffLimit: 0
@ -227,21 +227,23 @@ spec:
if status not in (200, 204):
raise SystemExit(f"Unexpected user-profile update response: {status}")
# Ensure basic realm groups exist for provisioning.
for group_name in ("dev", "admin"):
def find_group(group_name: str):
status, groups = http_json(
"GET",
f"{base_url}/admin/realms/{realm}/groups?search={urllib.parse.quote(group_name)}",
access_token,
)
exists = False
if status == 200 and isinstance(groups, list):
for item in groups:
if isinstance(item, dict) and item.get("name") == group_name:
exists = True
break
if exists:
continue
if status != 200 or not isinstance(groups, list):
return None
for item in groups:
if isinstance(item, dict) and item.get("name") == group_name:
return item
return None
def ensure_group(group_name: str):
group = find_group(group_name)
if group:
return group
status, _ = http_json(
"POST",
f"{base_url}/admin/realms/{realm}/groups",
@ -250,6 +252,85 @@ spec:
)
if status not in (201, 204):
raise SystemExit(f"Unexpected group create response for {group_name}: {status}")
return find_group(group_name)
# Ensure basic realm groups exist for provisioning.
ensure_group("dev")
ensure_group("admin")
planka_group = ensure_group("planka-users")
if planka_group and planka_group.get("id"):
group_id = planka_group["id"]
status, default_groups = http_json(
"GET",
f"{base_url}/admin/realms/{realm}/default-groups",
access_token,
)
default_ids = set()
if status == 200 and isinstance(default_groups, list):
for item in default_groups:
if isinstance(item, dict) and item.get("id"):
default_ids.add(item["id"])
if group_id not in default_ids:
status, _ = http_json(
"PUT",
f"{base_url}/admin/realms/{realm}/default-groups/{group_id}",
access_token,
)
if status not in (200, 201, 204):
status, _ = http_json(
"POST",
f"{base_url}/admin/realms/{realm}/default-groups/{group_id}",
access_token,
)
if status not in (200, 201, 204):
raise SystemExit(
f"Unexpected default-group update response for planka-users: {status}"
)
# Ensure all existing users are in the planka-users group.
first = 0
page_size = 100
while True:
status, users = http_json(
"GET",
f"{base_url}/admin/realms/{realm}/users?first={first}&max={page_size}",
access_token,
)
if status != 200 or not isinstance(users, list) or not users:
break
for user in users:
user_id = user.get("id") if isinstance(user, dict) else None
if not user_id:
continue
status, groups = http_json(
"GET",
f"{base_url}/admin/realms/{realm}/users/{user_id}/groups",
access_token,
)
if status == 200 and isinstance(groups, list):
already = any(isinstance(g, dict) and g.get("id") == group_id for g in groups)
if already:
continue
status, _ = http_json(
"PUT",
f"{base_url}/admin/realms/{realm}/users/{user_id}/groups/{group_id}",
access_token,
)
if status not in (200, 201, 204):
status, _ = http_json(
"POST",
f"{base_url}/admin/realms/{realm}/users/{user_id}/groups/{group_id}",
access_token,
)
if status not in (200, 201, 204):
raise SystemExit(
f"Unexpected group membership update for user {user_id}: {status}"
)
if len(users) < page_size:
break
first += page_size
# Ensure Planka client exposes groups in userinfo for role mapping.
status, clients = http_json(

View File

@ -68,8 +68,10 @@ spec:
value: "true"
- name: OIDC_IGNORE_ROLES
value: "false"
- name: OIDC_ADMIN_ROLES
value: admin
- name: OIDC_PROJECT_OWNER_ROLES
value: "*"
value: planka-users
- name: OIDC_ROLES_ATTRIBUTE
value: groups
envFrom: