From bb8d0f7751ad34ff602659474ca65371cd5433f8 Mon Sep 17 00:00:00 2001
From: SujanSanjula96 <sanjulasujan@gmail.com>
Date: Thu, 2 Jan 2025 14:34:46 +0530
Subject: [PATCH 1/2] Fix SAML name ID format inconsistency

---
 .../wso2/carbon/identity/sso/saml/SAMLSSOConstants.java    | 1 +
 .../carbon/identity/sso/saml/admin/SAMLSSOConfigAdmin.java | 7 ++++++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/SAMLSSOConstants.java b/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/SAMLSSOConstants.java
index 5657c8c5..e640e819 100644
--- a/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/SAMLSSOConstants.java
+++ b/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/SAMLSSOConstants.java
@@ -71,6 +71,7 @@ public class SAMLSSOConstants {
     public static final String SAML_IDP_INIT_LOGOUT_RESPONSE_SIGNING_ENABLED = "SSOService.SAMLIdpInitLogoutResponseSigningEnabled";
     public static final String SAML_ASSERTION_ENCRYPT_WITH_APP_CERT = "SSOService.SAMLAssertionEncyptWithAppCert";
     public static final String SEPARATE_MULTI_ATTRS_FROM_IDPS_USING_ATTRIBUTE_SEPARATOR = "SSOService.SeparateMultiAttributesFromIdP";
+    public static final String SAML_RETURN_VALID_NAME_ID_FORMAT = "SSOService.ReturnValidNameIDFormat";
     public static final String START_SOAP_BINDING = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
             "<SOAP-ENV:Body>";
     public static final String END_SOAP_BINDING = "</SOAP-ENV:Body>" +
diff --git a/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdmin.java b/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdmin.java
index 59d8f595..cf47ffd7 100644
--- a/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdmin.java
+++ b/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdmin.java
@@ -35,6 +35,7 @@
 import org.wso2.carbon.identity.sp.metadata.saml2.exception.InvalidMetadataException;
 import org.wso2.carbon.identity.sp.metadata.saml2.util.Parser;
 import org.wso2.carbon.identity.sso.saml.Error;
+import org.wso2.carbon.identity.sso.saml.SAMLSSOConstants;
 import org.wso2.carbon.identity.sso.saml.SSOServiceProviderConfigManager;
 import org.wso2.carbon.identity.sso.saml.dto.SAMLSSOServiceProviderDTO;
 import org.wso2.carbon.identity.sso.saml.dto.SAMLSSOServiceProviderInfoDTO;
@@ -695,7 +696,11 @@ public SAMLSSOServiceProviderInfoDTO getServiceProviders() throws IdentityExcept
                 if (providerDTO.getNameIDFormat() == null) {
                     providerDTO.setNameIDFormat(NameIdentifier.UNSPECIFIED);
                 }
-                providerDTO.setNameIDFormat(providerDTO.getNameIDFormat().replace(":", "/"));
+                boolean returnValidNameIDFormat = Boolean.parseBoolean(
+                        IdentityUtil.getProperty(SAMLSSOConstants.SAML_RETURN_VALID_NAME_ID_FORMAT));
+                if (!returnValidNameIDFormat) {
+                    providerDTO.setNameIDFormat(providerDTO.getNameIDFormat().replace(":", "/"));
+                }
 
                 providerDTO.setIdPInitSSOEnabled(providerDO.isIdPInitSSOEnabled());
                 providerDTO.setIdPInitSLOEnabled(providerDO.isIdPInitSLOEnabled());

From 4c5d03c366a679dfa88dc31da5893d56550bb581 Mon Sep 17 00:00:00 2001
From: SujanSanjula96 <sanjulasujan@gmail.com>
Date: Thu, 2 Jan 2025 16:00:25 +0530
Subject: [PATCH 2/2] Add unit tests for name ID format

---
 .../saml/admin/SAMLSSOConfigAdminTest.java    | 65 ++++++++++++++++++-
 1 file changed, 64 insertions(+), 1 deletion(-)

diff --git a/components/org.wso2.carbon.identity.sso.saml/src/test/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdminTest.java b/components/org.wso2.carbon.identity.sso.saml/src/test/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdminTest.java
index 19fa211f..b9c41dc1 100644
--- a/components/org.wso2.carbon.identity.sso.saml/src/test/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdminTest.java
+++ b/components/org.wso2.carbon.identity.sso.saml/src/test/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdminTest.java
@@ -30,7 +30,9 @@
 import org.wso2.carbon.identity.base.IdentityException;
 import org.wso2.carbon.identity.core.SAMLSSOServiceProviderManager;
 import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO;
+import org.wso2.carbon.identity.core.util.IdentityUtil;
 import org.wso2.carbon.identity.sp.metadata.saml2.util.Parser;
+import org.wso2.carbon.identity.sso.saml.SAMLSSOConstants;
 import org.wso2.carbon.identity.sso.saml.SSOServiceProviderConfigManager;
 import org.wso2.carbon.identity.sso.saml.TestUtils;
 import org.wso2.carbon.identity.sso.saml.dto.SAMLSSOServiceProviderDTO;
@@ -48,7 +50,8 @@
 import static org.powermock.api.mockito.PowerMockito.*;
 
 @PrepareForTest({IdentitySAMLSSOServiceComponentHolder.class, SSOServiceProviderConfigManager.class,
-        SAMLSSOServiceProviderDO.class, Parser.class, UserRegistry.class, SAMLSSOConfigAdmin.class, SAMLSSOUtil.class})
+        SAMLSSOServiceProviderDO.class, Parser.class, UserRegistry.class, SAMLSSOConfigAdmin.class, SAMLSSOUtil.class,
+        IdentityUtil.class})
 @PowerMockIgnore({"javax.xml.*", "org.xml.*", "org.apache.xerces.*", "org.w3c.dom.*"})
 public class SAMLSSOConfigAdminTest extends PowerMockTestCase {
 
@@ -57,6 +60,9 @@ public class SAMLSSOConfigAdminTest extends PowerMockTestCase {
     @Mock
     UserRegistry userRegistry;
 
+    @Mock
+    IdentityUtil identityUtil;
+
     @Mock
     private SAMLSSOServiceProviderManager samlSSOServiceProviderManager;
 
@@ -261,4 +267,61 @@ public void testGetServiceProviders() throws Exception {
         Assert.assertEquals(samlssoConfigAdmin.getServiceProviders().getServiceProviders().length, 3);
     }
 
+    @Test
+    public void testGetServiceProvidersForValidNameIDFormat() throws Exception {
+
+        mockStatic(UserRegistry.class);
+        mockStatic(IdentityUtil.class);
+        SAMLSSOServiceProviderDO[] serviceProvidersList = new SAMLSSOServiceProviderDO[2];
+        when(userRegistry.getTenantId()).thenReturn(0);
+        when(samlSSOServiceProviderManager.getServiceProviders(anyInt())).thenReturn(serviceProvidersList);
+
+        SAMLSSOServiceProviderDO samlssoServiceProviderDO = new SAMLSSOServiceProviderDO();
+        samlssoServiceProviderDO.setIssuer("issuer");
+        samlssoServiceProviderDO.setNameIDFormat(null);
+        SAMLSSOServiceProviderDO samlssoServiceProviderDO1 = new SAMLSSOServiceProviderDO();
+        samlssoServiceProviderDO1.setIssuer("issuer1");
+        samlssoServiceProviderDO1.setNameIDFormat("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress");
+        serviceProvidersList[0] = samlssoServiceProviderDO;
+        serviceProvidersList[1] = samlssoServiceProviderDO1;
+
+        when(IdentityUtil.getProperty(SAMLSSOConstants.SAML_RETURN_VALID_NAME_ID_FORMAT)).thenReturn("true");
+
+        when(userRegistry.getTenantId()).thenReturn(0);
+        SAMLSSOServiceProviderDTO[] serviceProviders = samlssoConfigAdmin.getServiceProviders().getServiceProviders();
+        Assert.assertEquals(serviceProviders.length, 2);
+        Assert.assertEquals(serviceProviders[0].getNameIDFormat(),
+                "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified");
+        Assert.assertEquals(serviceProviders[1].getNameIDFormat(),
+                "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress");
+    }
+
+    @Test
+    public void testGetServiceProvidersForLegacyNameIDFormat() throws Exception {
+
+        mockStatic(UserRegistry.class);
+        mockStatic(IdentityUtil.class);
+        SAMLSSOServiceProviderDO[] serviceProvidersList = new SAMLSSOServiceProviderDO[2];
+        when(userRegistry.getTenantId()).thenReturn(0);
+        when(samlSSOServiceProviderManager.getServiceProviders(anyInt())).thenReturn(serviceProvidersList);
+
+        SAMLSSOServiceProviderDO samlssoServiceProviderDO = new SAMLSSOServiceProviderDO();
+        samlssoServiceProviderDO.setIssuer("issuer");
+        samlssoServiceProviderDO.setNameIDFormat(null);
+        SAMLSSOServiceProviderDO samlssoServiceProviderDO1 = new SAMLSSOServiceProviderDO();
+        samlssoServiceProviderDO1.setIssuer("issuer1");
+        samlssoServiceProviderDO1.setNameIDFormat("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress");
+        serviceProvidersList[0] = samlssoServiceProviderDO;
+        serviceProvidersList[1] = samlssoServiceProviderDO1;
+
+        when(IdentityUtil.getProperty(SAMLSSOConstants.SAML_RETURN_VALID_NAME_ID_FORMAT)).thenReturn("false");
+
+        when(userRegistry.getTenantId()).thenReturn(0);
+        SAMLSSOServiceProviderDTO[] serviceProviders = samlssoConfigAdmin.getServiceProviders().getServiceProviders();
+        Assert.assertEquals(serviceProviders.length, 2);
+        Assert.assertEquals(serviceProviders[0].getNameIDFormat(),
+                "urn/oasis/names/tc/SAML/1.1/nameid-format/unspecified");
+        Assert.assertEquals(serviceProviders[1].getNameIDFormat(),
+                "urn/oasis/names/tc/SAML/1.1/nameid-format/emailAddress");
+    }
 }