Skip to content

Commit 6aabe68

Browse files
authored
Merge pull request #21655 from nuwang/improve_oidc_username_tests
Add tests for oidc usernames
2 parents 87ec44c + 26f8693 commit 6aabe68

File tree

3 files changed

+78
-1
lines changed

3 files changed

+78
-1
lines changed

test/integration/oidc/galaxy-realm-export.json

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,40 @@
483483
"notBefore": 0,
484484
"groups": []
485485
},
486+
{
487+
"id": "f5e8b2c4-9a1d-4e3f-8c6a-7b2d5e4f3c1a",
488+
"createdTimestamp": 1694376671733,
489+
"username": "rincewind_test",
490+
"enabled": true,
491+
"totp": false,
492+
"emailVerified": true,
493+
"firstName": "Rincewind",
494+
"lastName": "Ankh-Morpork",
495+
"email": "[email protected]",
496+
"attributes": {
497+
"preferred_username": [
498+
"Rincewind (Ankh-Morpork)"
499+
]
500+
},
501+
"credentials": [
502+
{
503+
"id": "e5d4c3b2-a1f0-9e8d-7c6b-5a4f3e2d1c0b",
504+
"type": "password",
505+
"userLabel": "My password",
506+
"createdDate": 1694376754826,
507+
"secretData": "{\"value\":\"uNBI+UnpCLpXWHhm/tPSnnhuINiNw2MNt1XeDmImJaQ=\",\"salt\":\"fHS/FpnORylnSIco16UHwA==\",\"additionalParameters\":{}}",
508+
"credentialData": "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
509+
}
510+
],
511+
"disableableCredentialTypes": [],
512+
"requiredActions": [],
513+
"realmRoles": [
514+
"galaxy-access-role",
515+
"default-roles-gxyrealm"
516+
],
517+
"notBefore": 0,
518+
"groups": []
519+
},
486520
{
487521
"id": "24ffa3ff-d351-4d5e-b10b-8d615082ec9d",
488522
"createdTimestamp": 1694376671733,
@@ -2565,4 +2599,4 @@
25652599
"clientPolicies": {
25662600
"policies": []
25672601
}
2568-
}
2602+
}

test/integration/oidc/test_auth_oidc.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,24 @@ def test_oidc_login_new_user(self):
261261
self._assert_status_code_is(response, 200)
262262
assert response.json()["email"] == "[email protected]"
263263

264+
def test_oidc_login_username_sanitization(self):
265+
"""Test that OIDC usernames with special characters are properly sanitized."""
266+
_, response = self._login_via_keycloak("rincewind_test", KEYCLOAK_TEST_PASSWORD, save_cookies=True)
267+
268+
response = self._get("users/current")
269+
self._assert_status_code_is(response, 200)
270+
assert response.json()["email"] == "[email protected]"
271+
272+
username = response.json()["username"]
273+
from galaxy.security.validate_user_input import validate_publicname_str
274+
275+
error = validate_publicname_str(username)
276+
assert error == "", f"OIDC-created username '{username}' is invalid: {error}"
277+
assert "(" not in username, f"Username '{username}' should not contain parentheses"
278+
assert ")" not in username, f"Username '{username}' should not contain parentheses"
279+
assert " " not in username, f"Username '{username}' should not contain spaces"
280+
assert username == username.lower(), f"Username '{username}' should be lowercase"
281+
264282
def test_oidc_login_repeat_no_notification(self):
265283
"""
266284
Test that repeat logins do NOT show the 'identity has been linked' notification.

test/unit/util/test_utils.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,28 @@ def test_validate_doi_fail_too_long():
177177
doi = f"doi:10.1000/{long_suffix}"
178178
assert util.validate_doi(doi)
179179
assert not util.validate_doi(doi + "a") # Increase length by 1 past max limit
180+
181+
182+
@pytest.mark.parametrize(
183+
"input_name,expected_output",
184+
[
185+
# Existing documented behavior
186+
("My Cool Object", "My-Cool-Object"),
187+
("!My Cool Object!", "My-Cool-Object"),
188+
("Hello\u20a9\u25ce\u0491\u029f\u217e", "Hello"),
189+
# Additional edge cases
190+
("simple", "simple"),
191+
("UPPERCASE", "UPPERCASE"), # Note: lowercase applied separately
192+
("with-dash", "with-dash"),
193+
("with spaces", "with-spaces"),
194+
(" multiple spaces ", "-multiple-spaces"),
195+
("trailing!", "trailing"),
196+
("!leading", "leading"),
197+
("special@#$chars", "specialchars"),
198+
("parentheses(test)", "parenthesestest"),
199+
("Rincewind (Ankh-Morpork)", "Rincewind-Ankh-Morpork"),
200+
],
201+
)
202+
def test_ready_name_for_url(input_name, expected_output):
203+
"""Test that ready_name_for_url correctly sanitizes names for URL use."""
204+
assert util.ready_name_for_url(input_name) == expected_output

0 commit comments

Comments
 (0)