fix(web-app-keycloak): render the username cap instead of raising on it

7916c0177e wrote the cap as {{ IAM_USERNAME_MAX_LENGTH }} inside the {% set _base_attrs %} block. A set body is already a Jinja expression, so the nested delimiters are a syntax error rather than an interpolation, and jinja2 answers TemplateSyntaxError: expected token :, got }. realm.json.j2 includes the component unconditionally, so every realm render raised, not just the username path: that single typo is the whole of the 9 unit and 7 integration failures the gate reported.

The test context gains the value because render() builds its environment with StrictUndefined, which raises on an absent name instead of rendering empty, and a new case asserts the rendered validations.length.max equals it so the cap cannot fall back to the Keycloak default of 255 unnoticed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5 committed 2026-10-09 00:20:29 +02:00
1 parent da5bc17c7f
commit ae482e750b
2 files changed
+18 -1

No files matched your search

@@ -41,6 +41,7 @@ CONTEXT = {
"KEYCLOAK_LDAP_ENABLED": True,
"KEYCLOAK_MOODLE_ENABLED": True,
"KEYCLOAK_RESERVED_USERNAMES_REGEX": "^(root|admin)$",
"IAM_USERNAME_MAX_LENGTH": 20,
"KEYCLOAK_LDAP_USER_OBJECT_CLASSES": "inetOrgPerson, organizationalPerson",
"KEYCLOAK_LDAP_CMP_NAME": "ldap",
"KEYCLOAK_LDAP_URL": "ldap://openldap:389",
@@ -150,6 +151,22 @@ class TestRealmImportJson(unittest.TestCase):
declared = {attribute["name"] for attribute in profile["attributes"]}
self.assertIn("uidNumber", declared)
def test_the_username_length_follows_the_platform_limit(self) -> None:
"""Registration must refuse what the tightest consumer refuses, so the
profile carries IAM_USERNAME_MAX_LENGTH rather than Keycloak's own 255."""
realm = json.loads(render([]))
provider = realm["components"]["org.keycloak.userprofile.UserProfileProvider"]
profile = json.loads(provider[0]["config"]["kc.user.profile.config"][0])
username = next(
attribute
for attribute in profile["attributes"]
if attribute["name"] == "username"
)
self.assertEqual(
username["validations"]["length"]["max"],
CONTEXT["IAM_USERNAME_MAX_LENGTH"],
)
def test_realm_is_valid_json_with_one_saml_app(self) -> None:
realm = json.loads(render(["web-app-suitecrm"]))
clients = {c["clientId"]: c for c in realm["clients"]}