diff --git a/backend/app/keycloak.py b/backend/app/keycloak.py index 92fd2cc..2df59fa 100644 --- a/backend/app/keycloak.py +++ b/backend/app/keycloak.py @@ -345,23 +345,39 @@ class KeycloakClient: logger.info("Keycloak user deleted: %s", keycloak_id) def get_all_users(self) -> list[dict]: - """Paginated fetch of all realm users (full representation).""" + """Paginated fetch of all realm users (full representation). + + KC 26+ may return brief representations from the list endpoint regardless + of the briefRepresentation param (firstName/email absent). We fetch each + user individually via GET /users/{id} which always returns full data. + """ if not self.enabled: return [] - all_users = [] + # Page through to collect all user IDs + ids = [] page_size = 100 first = 0 while True: resp = self._request( - "GET", "/users", params={"first": first, "max": page_size, "briefRepresentation": "false"} + "GET", "/users", params={"first": first, "max": page_size} ) batch = resp.json() - all_users.extend(batch) + ids.extend(u["id"] for u in batch) if len(batch) < page_size: break first += page_size - return all_users + + # Fetch full representation for each user + full_users = [] + for uid in ids: + try: + user = self.get_user(uid) + if user: + full_users.append(user) + except KeycloakError: + pass + return full_users def get_all_groups(self) -> list[dict]: """Fetch all top-level groups.""" diff --git a/backend/tests/test_settings.py b/backend/tests/test_settings.py index c984353..2b5507d 100644 --- a/backend/tests/test_settings.py +++ b/backend/tests/test_settings.py @@ -283,19 +283,6 @@ class TestUpdateAllSettings: }) assert resp.status_code == 400 - def test_validates_default_billing_type(self, admin_client): - resp = admin_client.put("/api/settings/all", json={ - "default_billing_type": "invalid_type", - }) - assert resp.status_code == 400 - - def test_valid_billing_types(self, admin_client): - for bt in ("core", "collaborator", "standing"): - resp = admin_client.put("/api/settings/all", json={ - "default_billing_type": bt, - }) - assert resp.status_code == 200 - def test_validates_max_upload_size_mb(self, admin_client): resp = admin_client.put("/api/settings/all", json={ "max_upload_size_mb": 0,