From c074278129a1dea0a1901bb5b90cf021a73123b0 Mon Sep 17 00:00:00 2001 From: Bryan Havenstein Date: Tue, 21 Oct 2025 19:35:48 -0600 Subject: [PATCH 1/2] AAP-56394 Fix SAML authentication uid selection --- ansible_base/authentication/utils/authentication.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ansible_base/authentication/utils/authentication.py b/ansible_base/authentication/utils/authentication.py index 8d87ad967..b7dadaba8 100644 --- a/ansible_base/authentication/utils/authentication.py +++ b/ansible_base/authentication/utils/authentication.py @@ -137,7 +137,10 @@ def determine_username_from_uid_social(**kwargs) -> dict: if authenticator.setting('USERNAME_IS_FULL_EMAIL', False): selected_username = kwargs.get('details', {}).get('email', None) else: - selected_username = kwargs.get('details', {}).get('username', None) + if authenticator.type == 'SAML': + selected_username = kwargs.get('uid', None) + else: + selected_username = kwargs.get('details', {}).get('username', None) if not selected_username: raise_auth_exception( _('Unable to get associated username from details, expected entry "username". Full user details: %(details)s') From 5808132d35bfc037ac4ab924c7fe517b40cc6e78 Mon Sep 17 00:00:00 2001 From: Bryan Havenstein Date: Tue, 21 Oct 2025 19:59:24 -0600 Subject: [PATCH 2/2] Add test coverage for username selection logic in authentication utils - Add parameterized test for determine_username_from_uid_social function - Cover both SAML (uses uid) and non-SAML (uses details.username) branches - Test multiple authenticator types: SAML, LDAP, OIDC, Keycloak - Ensures comprehensive coverage of lines 140-143 in authentication.py Co-authored-by: Claude --- .../utils/test_authentication.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test_app/tests/authentication/utils/test_authentication.py b/test_app/tests/authentication/utils/test_authentication.py index 4a0f0b017..0ed035fec 100644 --- a/test_app/tests/authentication/utils/test_authentication.py +++ b/test_app/tests/authentication/utils/test_authentication.py @@ -249,6 +249,27 @@ def test_determine_username_from_uid_social_happy_path(self, ldap_authenticator) ) assert response == {'username': 'Bob'} + @pytest.mark.parametrize( + "auth_fixture, expected_username, uid_param, details_username", + [ + # SAML authenticator uses uid parameter (line 141) + ("saml_authenticator", "SamlUser", "SamlUser", "should_not_be_used"), + # Non-SAML authenticators use details['username'] (line 143) + ("ldap_authenticator", "LdapUser", "should_not_be_used", "LdapUser"), + ("oidc_authenticator", "OidcUser", "should_not_be_used", "OidcUser"), + ("keycloak_authenticator", "KeycloakUser", "should_not_be_used", "KeycloakUser"), + ], + ) + def test_determine_username_from_uid_social_authenticator_types(self, request, auth_fixture, expected_username, uid_param, details_username): + """Test username selection logic for different authenticator types (lines 140-143)""" + authenticator = request.getfixturevalue(auth_fixture) + response = authentication.determine_username_from_uid_social( + details={'username': details_username}, + backend=get_authenticator_class(authenticator.type)(database_instance=authenticator), + uid=uid_param, + ) + assert response == {'username': expected_username} + def test_raise_auth_exception(self): try: authentication.raise_auth_exception('testing')