diff --git a/roles/web-app-keycloak/templates/import/components/org.keycloak.userprofile.UserProfileProvider.json.j2 b/roles/web-app-keycloak/templates/import/components/org.keycloak.userprofile.UserProfileProvider.json.j2 index 165eef7f8f..195a7f733d 100644 --- a/roles/web-app-keycloak/templates/import/components/org.keycloak.userprofile.UserProfileProvider.json.j2 +++ b/roles/web-app-keycloak/templates/import/components/org.keycloak.userprofile.UserProfileProvider.json.j2 @@ -26,7 +26,7 @@ "name": "username", "displayName": "${username}", "validations": { - "length": { "min": 3, "max": {{ IAM_USERNAME_MAX_LENGTH }} }, + "length": { "min": 3, "max": IAM_USERNAME_MAX_LENGTH }, "pattern": { "pattern": "^(?!(?:" ~ KEYCLOAK_RESERVED_USERNAMES_REGEX | replace('\\', '\\\\') ~ ")$)[a-z0-9]+$", "error-message": "Username is reserved or contains invalid characters. Only lowercase letters (a–z) and digits (0–9) are allowed." diff --git a/tests/unit/python/roles/web-app-keycloak/templates/test_realm_import_json.py b/tests/unit/python/roles/web-app-keycloak/templates/test_realm_import_json.py index 249189de47..bbfeff2dcf 100644 --- a/tests/unit/python/roles/web-app-keycloak/templates/test_realm_import_json.py +++ b/tests/unit/python/roles/web-app-keycloak/templates/test_realm_import_json.py @@ -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"]}