mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-08 11:46:35 +00:00
fix(users): give the new admin accounts usernames Keycloak accepts
Run 37799529673 fails three jobs on the two accounts 3c72c2002a
introduced, because both were named with a hyphen:
failed: [localhost] (item=keycloak-bootstrap)
failed: [localhost] (item=platform-administrator)
stderr: Username is reserved or contains invalid characters.
Only lowercase letters (a-z) and digits (0-9) are allowed.
That message is this role's own policy: the Keycloak user profile pins
`^(?!reserved)[a-z0-9]+$` in
templates/import/components/org.keycloak.userprofile.UserProfileProvider.json.j2.
Mastodon refuses the same name independently, with
`bin/tootctl accounts create ... Failure/Error: account.username invalid`,
so loosening the Keycloak pattern would have fixed neither job. The
usernames become platformadministrator and keycloakbootstrap.
Every other hyphenated user in the repository is exempt by having no
`identity` account, so Keycloak never sees it; these two were the only
identity-registered names that violated the pattern, which is why nothing
caught them before a realm import ran.
The lint closes that gap: it resolves the real user set and fails when an
identity user's username is not lowercase alphanumeric, so the next such
name is rejected locally instead of fourteen hours later in a deploy job.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
7c63e02180
commit
526cb7e212
3 files changed
+52
-2
No files matched your search
@@ -3,7 +3,7 @@ platform_administrator:
|
||||
description: Application administrator for {{ ORGANIZATION }} on {{ DOMAIN_PRIMARY }}
|
||||
firstname: Platform
|
||||
lastname: Administrator
|
||||
username: platform-administrator
|
||||
username: platformadministrator
|
||||
authorized_keys: []
|
||||
accounts: [mailbox, identity]
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
keycloak_bootstrap:
|
||||
username: keycloak-bootstrap
|
||||
username: keycloakbootstrap
|
||||
roles:
|
||||
- bot
|
||||
platform_administrator: {}
|
||||
@@ -0,0 +1,50 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import unittest
|
||||
|
||||
from utils.cache.users import get_user_defaults
|
||||
|
||||
from . import PROJECT_ROOT
|
||||
|
||||
IDENTITY_USERNAME = re.compile(r"^[a-z0-9]+$")
|
||||
|
||||
|
||||
class TestIdentityUsernameCharset(unittest.TestCase):
|
||||
def test_every_identity_username_is_lowercase_alphanumeric(self):
|
||||
"""
|
||||
A user whose ``accounts`` contain ``identity`` MUST have a username of
|
||||
lowercase letters and digits only.
|
||||
|
||||
Two consumers reject anything else, and both reject it at deploy time
|
||||
rather than at render time. Keycloak's own user profile pins the
|
||||
pattern ``^(?!reserved)[a-z0-9]+$``
|
||||
(``roles/web-app-keycloak/templates/import/components/
|
||||
org.keycloak.userprofile.UserProfileProvider.json.j2``) and answers a
|
||||
violation with "Username is reserved or contains invalid characters".
|
||||
Mastodon's ``bin/tootctl accounts create`` answers with
|
||||
``Failure/Error: account.username invalid``.
|
||||
|
||||
A hyphen is the way this breaks, because it is the natural separator
|
||||
for a compound account name and every other hyphenated user in the
|
||||
repository is exempt by having no ``identity`` account, so nothing
|
||||
catches it until a realm import or a tootctl call runs.
|
||||
"""
|
||||
users = get_user_defaults(roles_dir=str(PROJECT_ROOT / "roles"))
|
||||
offenders = sorted(
|
||||
f"{key}: {entry['username']}"
|
||||
for key, entry in users.items()
|
||||
if "identity" in (entry.get("accounts") or [])
|
||||
and not IDENTITY_USERNAME.match(str(entry.get("username", "")))
|
||||
)
|
||||
|
||||
if offenders:
|
||||
self.fail(
|
||||
"These users are registered as an identity but carry a "
|
||||
"username Keycloak and Mastodon both refuse (lowercase "
|
||||
"letters and digits only):\n - " + "\n - ".join(offenders)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user