]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-18679 update its sonar auth
authorLéo Geoffroy <leo.geoffroy@sonarsource.com>
Wed, 15 Mar 2023 12:28:02 +0000 (13:28 +0100)
committerPhilippe Perrin <philippe.perrin@sonarsource.com>
Fri, 17 Mar 2023 09:08:02 +0000 (10:08 +0100)
50 files changed:
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/DefaultLdapAuthenticatorIT.java [new file with mode: 0644]
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/DefaultLdapGroupsProviderIT.java [new file with mode: 0644]
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/DefaultLdapUsersProviderIT.java [new file with mode: 0644]
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/KerberosIT.java [new file with mode: 0644]
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/LdapRealmIT.java [new file with mode: 0644]
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/LdapReferralsIT.java [new file with mode: 0644]
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/LdapSearchIT.java [new file with mode: 0644]
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/LdapSettingsFactory.java [new file with mode: 0644]
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/server/LdapServer.java [new file with mode: 0644]
server/sonar-auth-ldap/src/it/resources/conf/krb5.conf [new file with mode: 0644]
server/sonar-auth-ldap/src/it/resources/conf/sasl_mech.properties [new file with mode: 0644]
server/sonar-auth-ldap/src/it/resources/krb.ldif [new file with mode: 0644]
server/sonar-auth-ldap/src/it/resources/static-groups.example.org.ldif [new file with mode: 0644]
server/sonar-auth-ldap/src/it/resources/users-apacheds.ldif [new file with mode: 0644]
server/sonar-auth-ldap/src/it/resources/users.example.org.ldif [new file with mode: 0644]
server/sonar-auth-ldap/src/it/resources/users.infosupport.com.ldif [new file with mode: 0644]
server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/DefaultLdapAuthenticatorTest.java [deleted file]
server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/DefaultLdapGroupsProviderTest.java [deleted file]
server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/DefaultLdapUsersProviderTest.java [deleted file]
server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/KerberosTest.java [deleted file]
server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapRealmTest.java [deleted file]
server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapReferralsTest.java [deleted file]
server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapSearchTest.java [deleted file]
server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapSettingsFactory.java [deleted file]
server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/server/LdapServer.java [deleted file]
server/sonar-auth-ldap/src/test/resources/conf/krb5.conf [deleted file]
server/sonar-auth-ldap/src/test/resources/conf/sasl_mech.properties [deleted file]
server/sonar-auth-ldap/src/test/resources/krb.ldif [deleted file]
server/sonar-auth-ldap/src/test/resources/static-groups.example.org.ldif [deleted file]
server/sonar-auth-ldap/src/test/resources/users-apacheds.ldif [deleted file]
server/sonar-auth-ldap/src/test/resources/users.example.org.ldif [deleted file]
server/sonar-auth-ldap/src/test/resources/users.infosupport.com.ldif [deleted file]
server/sonar-auth-saml/src/it/java/org/sonar/auth/saml/SamlIdentityProviderIT.java [new file with mode: 0644]
server/sonar-auth-saml/src/it/java/org/sonar/auth/saml/SamlMessageIdCheckerIT.java [new file with mode: 0644]
server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_encrypted_response.txt [new file with mode: 0644]
server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_full_response.txt [new file with mode: 0644]
server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_full_response_with_reverse_proxy.txt [new file with mode: 0644]
server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_minimal_response.txt [new file with mode: 0644]
server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_response_without_login.txt [new file with mode: 0644]
server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_response_without_name.txt [new file with mode: 0644]
server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/how_to_generate_test_response.txt [new file with mode: 0644]
server/sonar-auth-saml/src/test/java/org/sonar/auth/saml/SamlIdentityProviderTest.java [deleted file]
server/sonar-auth-saml/src/test/java/org/sonar/auth/saml/SamlMessageIdCheckerTest.java [deleted file]
server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_encrypted_response.txt [deleted file]
server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_full_response.txt [deleted file]
server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_full_response_with_reverse_proxy.txt [deleted file]
server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_minimal_response.txt [deleted file]
server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_response_without_login.txt [deleted file]
server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_response_without_name.txt [deleted file]
server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/how_to_generate_test_response.txt [deleted file]

diff --git a/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/DefaultLdapAuthenticatorIT.java b/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/DefaultLdapAuthenticatorIT.java
new file mode 100644 (file)
index 0000000..1f3ee94
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.auth.ldap;
+
+import javax.servlet.http.HttpServletRequest;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.auth.ldap.server.LdapServer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class DefaultLdapAuthenticatorIT {
+
+  /**
+   * A reference to the original ldif file
+   */
+  public static final String USERS_EXAMPLE_ORG_LDIF = "/users.example.org.ldif";
+  /**
+   * A reference to an additional ldif file.
+   */
+  public static final String USERS_INFOSUPPORT_COM_LDIF = "/users.infosupport.com.ldif";
+  @ClassRule
+  public static LdapServer exampleServer = new LdapServer(USERS_EXAMPLE_ORG_LDIF);
+  @ClassRule
+  public static LdapServer infosupportServer = new LdapServer(USERS_INFOSUPPORT_COM_LDIF, "infosupport.com", "dc=infosupport,dc=com");
+
+  @Test
+  public void testNoConnection() {
+    exampleServer.disableAnonymousAccess();
+    try {
+      LdapSettingsManager settingsManager = new LdapSettingsManager(
+        LdapSettingsFactory.generateAuthenticationSettings(exampleServer, null, LdapContextFactory.AUTH_METHOD_SIMPLE).asConfig());
+      DefaultLdapAuthenticator authenticator = new DefaultLdapAuthenticator(settingsManager.getContextFactories(), settingsManager.getUserMappings());
+      boolean isAuthenticationSuccessful = authenticator.doAuthenticate(createContext("godin", "secret1")).isSuccess();
+      assertThat(isAuthenticationSuccessful).isTrue();
+    } finally {
+      exampleServer.enableAnonymousAccess();
+    }
+  }
+
+  @Test
+  public void testSimple() {
+    LdapSettingsManager settingsManager = new LdapSettingsManager(
+      LdapSettingsFactory.generateAuthenticationSettings(exampleServer, null, LdapContextFactory.AUTH_METHOD_SIMPLE).asConfig());
+    DefaultLdapAuthenticator authenticator = new DefaultLdapAuthenticator(settingsManager.getContextFactories(), settingsManager.getUserMappings());
+
+    LdapAuthenticationResult user1Success = authenticator.doAuthenticate(createContext("godin", "secret1"));
+    assertThat(user1Success.isSuccess()).isTrue();
+    assertThat(user1Success.getServerKey()).isEqualTo("default");
+
+    assertThat(authenticator.doAuthenticate(createContext("godin", "wrong")).isSuccess()).isFalse();
+
+    LdapAuthenticationResult user2Success = authenticator.doAuthenticate(createContext("tester", "secret2"));
+    assertThat(user2Success.isSuccess()).isTrue();
+    assertThat(user2Success.getServerKey()).isEqualTo("default");
+
+    assertThat(authenticator.doAuthenticate(createContext("tester", "wrong")).isSuccess()).isFalse();
+
+    assertThat(authenticator.doAuthenticate(createContext("notfound", "wrong")).isSuccess()).isFalse();
+    // SONARPLUGINS-2493
+    assertThat(authenticator.doAuthenticate(createContext("godin", "")).isSuccess()).isFalse();
+    assertThat(authenticator.doAuthenticate(createContext("godin", null)).isSuccess()).isFalse();
+  }
+
+  @Test
+  public void testSimpleMultiLdap() {
+    LdapSettingsManager settingsManager = new LdapSettingsManager(
+      LdapSettingsFactory.generateAuthenticationSettings(exampleServer, infosupportServer, LdapContextFactory.AUTH_METHOD_SIMPLE).asConfig());
+    DefaultLdapAuthenticator authenticator = new DefaultLdapAuthenticator(settingsManager.getContextFactories(), settingsManager.getUserMappings());
+
+    LdapAuthenticationResult user1Success = authenticator.doAuthenticate(createContext("godin", "secret1"));
+    assertThat(user1Success.isSuccess()).isTrue();
+    assertThat(user1Success.getServerKey()).isEqualTo("example");
+    assertThat(authenticator.doAuthenticate(createContext("godin", "wrong")).isSuccess()).isFalse();
+
+    LdapAuthenticationResult user2Server1Success = authenticator.doAuthenticate(createContext("tester", "secret2"));
+    assertThat(user2Server1Success.isSuccess()).isTrue();
+    assertThat(user2Server1Success.getServerKey()).isEqualTo("example");
+
+    LdapAuthenticationResult user2Server2Success = authenticator.doAuthenticate(createContext("tester", "secret3"));
+    assertThat(user2Server2Success.isSuccess()).isTrue();
+    assertThat(user2Server2Success.getServerKey()).isEqualTo("infosupport");
+
+    assertThat(authenticator.doAuthenticate(createContext("tester", "wrong")).isSuccess()).isFalse();
+
+    assertThat(authenticator.doAuthenticate(createContext("notfound", "wrong")).isSuccess()).isFalse();
+    // SONARPLUGINS-2493
+    assertThat(authenticator.doAuthenticate(createContext("godin", "")).isSuccess()).isFalse();
+    assertThat(authenticator.doAuthenticate(createContext("godin", null)).isSuccess()).isFalse();
+
+    // SONARPLUGINS-2793
+    LdapAuthenticationResult user3Success = authenticator.doAuthenticate(createContext("robby", "secret1"));
+    assertThat(user3Success.isSuccess()).isTrue();
+    assertThat(user3Success.getServerKey()).isEqualTo("infosupport");
+    assertThat(authenticator.doAuthenticate(createContext("robby", "wrong")).isSuccess()).isFalse();
+  }
+
+  @Test
+  public void testSasl() {
+    LdapSettingsManager settingsManager = new LdapSettingsManager(
+      LdapSettingsFactory.generateAuthenticationSettings(exampleServer, null, LdapContextFactory.AUTH_METHOD_CRAM_MD5).asConfig());
+    DefaultLdapAuthenticator authenticator = new DefaultLdapAuthenticator(settingsManager.getContextFactories(), settingsManager.getUserMappings());
+
+    LdapAuthenticationResult user1Success = authenticator.doAuthenticate(createContext("godin", "secret1"));
+    assertThat(user1Success.isSuccess()).isTrue();
+    assertThat(user1Success.getServerKey()).isEqualTo("default");
+
+    assertThat(authenticator.doAuthenticate(createContext("godin", "wrong")).isSuccess()).isFalse();
+
+    LdapAuthenticationResult user2Success = authenticator.doAuthenticate(createContext("tester", "secret2"));
+    assertThat(user2Success.isSuccess()).isTrue();
+    assertThat(user2Success.getServerKey()).isEqualTo("default");
+
+    assertThat(authenticator.doAuthenticate(createContext("tester", "wrong")).isSuccess()).isFalse();
+
+    assertThat(authenticator.doAuthenticate(createContext("notfound", "wrong")).isSuccess()).isFalse();
+  }
+
+  @Test
+  public void testSaslMultipleLdap() {
+    LdapSettingsManager settingsManager = new LdapSettingsManager(
+      LdapSettingsFactory.generateAuthenticationSettings(exampleServer, infosupportServer, LdapContextFactory.AUTH_METHOD_CRAM_MD5).asConfig());
+    DefaultLdapAuthenticator authenticator = new DefaultLdapAuthenticator(settingsManager.getContextFactories(), settingsManager.getUserMappings());
+
+    LdapAuthenticationResult user1Success = authenticator.doAuthenticate(createContext("godin", "secret1"));
+    assertThat(user1Success.isSuccess()).isTrue();
+    assertThat(authenticator.doAuthenticate(createContext("godin", "wrong")).isSuccess()).isFalse();
+
+    LdapAuthenticationResult user2Server1Success = authenticator.doAuthenticate(createContext("tester", "secret2"));
+    assertThat(user2Server1Success.isSuccess()).isTrue();
+    assertThat(user2Server1Success.getServerKey()).isEqualTo("example");
+
+    LdapAuthenticationResult user2Server2Success = authenticator.doAuthenticate(createContext("tester", "secret3"));
+    assertThat(user2Server2Success.isSuccess()).isTrue();
+    assertThat(user2Server2Success.getServerKey()).isEqualTo("infosupport");
+
+    assertThat(authenticator.doAuthenticate(createContext("tester", "wrong")).isSuccess()).isFalse();
+
+    assertThat(authenticator.doAuthenticate(createContext("notfound", "wrong")).isSuccess()).isFalse();
+
+    LdapAuthenticationResult user3Success = authenticator.doAuthenticate(createContext("robby", "secret1"));
+    assertThat(user3Success.isSuccess()).isTrue();
+
+    assertThat(authenticator.doAuthenticate(createContext("robby", "wrong")).isSuccess()).isFalse();
+  }
+
+  private static LdapAuthenticator.Context createContext(String username, String password) {
+    return new LdapAuthenticator.Context(username, password, mock(HttpServletRequest.class));
+  }
+
+}
diff --git a/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/DefaultLdapGroupsProviderIT.java b/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/DefaultLdapGroupsProviderIT.java
new file mode 100644 (file)
index 0000000..0534682
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.auth.ldap;
+
+import java.util.Collection;
+import javax.servlet.http.HttpServletRequest;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.config.internal.MapSettings;
+import org.sonar.auth.ldap.server.LdapServer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class DefaultLdapGroupsProviderIT {
+
+  /**
+   * A reference to the original ldif file
+   */
+  public static final String USERS_EXAMPLE_ORG_LDIF = "/users.example.org.ldif";
+  /**
+   * A reference to an aditional ldif file.
+   */
+  public static final String USERS_INFOSUPPORT_COM_LDIF = "/users.infosupport.com.ldif";
+
+  @ClassRule
+  public static LdapServer exampleServer = new LdapServer(USERS_EXAMPLE_ORG_LDIF);
+  @ClassRule
+  public static LdapServer infosupportServer = new LdapServer(USERS_INFOSUPPORT_COM_LDIF, "infosupport.com", "dc=infosupport,dc=com");
+
+  @Test
+  public void doGetGroups_when_single_server_without_key() {
+    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, null);
+
+    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
+    DefaultLdapGroupsProvider groupsProvider = new DefaultLdapGroupsProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings(),
+      settingsManager.getGroupMappings());
+
+    Collection<String> groups = getGroupsForContext(createContextForDefaultServer("tester"), groupsProvider);
+    assertThat(groups).containsOnly("sonar-users");
+
+    groups = getGroupsForContext(createContextForDefaultServer("godin"), groupsProvider);
+    assertThat(groups).containsOnly("sonar-users", "sonar-developers");
+
+    groups = getGroupsForContext(createContextForDefaultServer("unknown_user"), groupsProvider);
+    assertThat(groups).isEmpty();
+  }
+
+  @Test
+  public void doGetGroups_when_two_ldap_servers() {
+    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
+
+    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
+    DefaultLdapGroupsProvider groupsProvider = new DefaultLdapGroupsProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings(),
+      settingsManager.getGroupMappings());
+
+    Collection<String> groups = getGroupsForContext(createContextForExampleServer("tester"), groupsProvider);
+    assertThat(groups).containsOnly("sonar-users");
+
+    groups = getGroupsForContext(createContextForExampleServer("godin"), groupsProvider);
+    assertThat(groups).containsOnly("sonar-users", "sonar-developers");
+
+    groups = getGroupsForContext(createContextForExampleServer("unknown_user"), groupsProvider);
+    assertThat(groups).isEmpty();
+
+    groups = getGroupsForContext(createContextForInfoSupportServer("testerInfo"), groupsProvider);
+    assertThat(groups).containsOnly("sonar-users");
+
+    groups = getGroupsForContext(createContextForInfoSupportServer("robby"), groupsProvider);
+    assertThat(groups).containsOnly("sonar-users", "sonar-developers");
+  }
+
+  @Test
+  public void doGetGroups_when_two_ldap_servers_with_same_username_resolves_groups_from_right_server() {
+    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
+
+    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
+    DefaultLdapGroupsProvider groupsProvider = new DefaultLdapGroupsProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings(),
+      settingsManager.getGroupMappings());
+
+    Collection<String> groups = getGroupsForContext(createContextForExampleServer("duplicated"), groupsProvider);
+    assertThat(groups).containsOnly("sonar-users");
+
+    groups = getGroupsForContext(createContextForInfoSupportServer("duplicated"), groupsProvider);
+    assertThat(groups).containsOnly("sonar-developers");
+  }
+
+  @Test
+  public void posix() {
+    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, null);
+    settings.setProperty("ldap.group.request", "(&(objectClass=posixGroup)(memberUid={uid}))");
+    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
+    DefaultLdapGroupsProvider groupsProvider = new DefaultLdapGroupsProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings(),
+      settingsManager.getGroupMappings());
+
+    Collection<String> groups = getGroupsForContext(createContextForDefaultServer("godin"), groupsProvider);
+    assertThat(groups).containsOnly("linux-users");
+  }
+
+  @Test
+  public void posixMultipleLdap() {
+    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
+    settings.setProperty("ldap.example.group.request", "(&(objectClass=posixGroup)(memberUid={uid}))");
+    settings.setProperty("ldap.infosupport.group.request", "(&(objectClass=posixGroup)(memberUid={uid}))");
+    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
+    DefaultLdapGroupsProvider groupsProvider = new DefaultLdapGroupsProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings(),
+      settingsManager.getGroupMappings());
+
+    Collection<String> groups = getGroupsForContext(createContextForExampleServer("godin"), groupsProvider);
+    assertThat(groups).containsOnly("linux-users");
+
+    groups = getGroupsForContext(createContextForInfoSupportServer("robby"), groupsProvider);
+    assertThat(groups).containsOnly("linux-users");
+  }
+
+  private static Collection<String> getGroupsForContext(LdapGroupsProvider.Context context, DefaultLdapGroupsProvider groupsProvider) {
+    return groupsProvider.doGetGroups(context);
+  }
+
+  @Test
+  public void mixed() {
+    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
+    settings.setProperty("ldap.example.group.request", "(&(|(objectClass=groupOfUniqueNames)(objectClass=posixGroup))(|(uniqueMember={dn})(memberUid={uid})))");
+    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
+    DefaultLdapGroupsProvider groupsProvider = new DefaultLdapGroupsProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings(),
+      settingsManager.getGroupMappings());
+
+    Collection<String> groups = getGroupsForContext(createContextForExampleServer("godin"), groupsProvider);
+    assertThat(groups).containsOnly("sonar-users", "sonar-developers", "linux-users");
+  }
+
+  @Test
+  public void mixedMultipleLdap() {
+    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
+    settings.setProperty("ldap.example.group.request", "(&(|(objectClass=groupOfUniqueNames)(objectClass=posixGroup))(|(uniqueMember={dn})(memberUid={uid})))");
+    settings.setProperty("ldap.infosupport.group.request", "(&(|(objectClass=groupOfUniqueNames)(objectClass=posixGroup))(|(uniqueMember={dn})(memberUid={uid})))");
+    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
+    DefaultLdapGroupsProvider groupsProvider = new DefaultLdapGroupsProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings(),
+      settingsManager.getGroupMappings());
+
+    Collection<String> groups = getGroupsForContext(createContextForExampleServer("godin"), groupsProvider);
+    assertThat(groups).containsOnly("sonar-users", "sonar-developers", "linux-users");
+
+    groups = getGroupsForContext(createContextForInfoSupportServer("robby"), groupsProvider);
+    assertThat(groups).containsOnly("sonar-users", "sonar-developers", "linux-users");
+  }
+
+  private static LdapGroupsProvider.Context createContextForDefaultServer(String userName) {
+    return createContext("default", userName);
+  }
+
+  private static LdapGroupsProvider.Context createContextForExampleServer(String userName) {
+    return createContext("example", userName);
+  }
+
+  private static LdapGroupsProvider.Context createContextForInfoSupportServer(String userName) {
+    return createContext("infosupport", userName);
+  }
+
+  private static LdapGroupsProvider.Context createContext(String serverName, String userName) {
+    return new LdapGroupsProvider.Context(serverName, userName, mock(HttpServletRequest.class));
+  }
+
+}
diff --git a/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/DefaultLdapUsersProviderIT.java b/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/DefaultLdapUsersProviderIT.java
new file mode 100644 (file)
index 0000000..ea6894e
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.auth.ldap;
+
+import javax.servlet.http.HttpServletRequest;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.config.internal.MapSettings;
+import org.sonar.auth.ldap.server.LdapServer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class DefaultLdapUsersProviderIT {
+  /**
+   * A reference to the original ldif file
+   */
+  public static final String USERS_EXAMPLE_ORG_LDIF = "/users.example.org.ldif";
+  /**
+   * A reference to an additional ldif file.
+   */
+  public static final String USERS_INFOSUPPORT_COM_LDIF = "/users.infosupport.com.ldif";
+
+  @ClassRule
+  public static LdapServer exampleServer = new LdapServer(USERS_EXAMPLE_ORG_LDIF);
+  @ClassRule
+  public static LdapServer infosupportServer = new LdapServer(USERS_INFOSUPPORT_COM_LDIF, "infosupport.com", "dc=infosupport,dc=com");
+
+  @Test
+  public void test_user_from_first_server() {
+    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
+    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
+    DefaultLdapUsersProvider usersProvider = new DefaultLdapUsersProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings());
+
+    LdapUserDetails details = usersProvider.doGetUserDetails(createContext("example", "godin"));
+    assertThat(details.getName()).isEqualTo("Evgeny Mandrikov");
+    assertThat(details.getEmail()).isEqualTo("godin@example.org");
+  }
+
+  @Test
+  public void test_user_from_second_server() {
+    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
+    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
+    DefaultLdapUsersProvider usersProvider = new DefaultLdapUsersProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings());
+
+    LdapUserDetails details = usersProvider.doGetUserDetails(createContext("infosupport", "robby"));
+    assertThat(details.getName()).isEqualTo("Robby Developer");
+    assertThat(details.getEmail()).isEqualTo("rd@infosupport.com");
+
+  }
+
+  @Test
+  public void test_user_on_multiple_servers() {
+    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
+    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
+    DefaultLdapUsersProvider usersProvider = new DefaultLdapUsersProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings());
+
+    LdapUserDetails detailsExample = usersProvider.doGetUserDetails(createContext("example", "tester"));
+    assertThat(detailsExample.getName()).isEqualTo("Tester Testerovich");
+    assertThat(detailsExample.getEmail()).isEqualTo("tester@example.org");
+
+    LdapUserDetails detailsInfoSupport = usersProvider.doGetUserDetails(createContext("infosupport", "tester"));
+    assertThat(detailsInfoSupport.getName()).isEqualTo("Tester Testerovich Testerov");
+    assertThat(detailsInfoSupport.getEmail()).isEqualTo("tester@example2.org");
+  }
+
+  @Test
+  public void test_user_doesnt_exist() {
+    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
+    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
+    DefaultLdapUsersProvider usersProvider = new DefaultLdapUsersProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings());
+
+    LdapUserDetails details = usersProvider.doGetUserDetails(createContext("example", "notfound"));
+    assertThat(details).isNull();
+  }
+
+  private static LdapUsersProvider.Context createContext(String serverKey, String username) {
+    return new LdapUsersProvider.Context(serverKey, username, mock(HttpServletRequest.class));
+  }
+}
diff --git a/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/KerberosIT.java b/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/KerberosIT.java
new file mode 100644 (file)
index 0000000..08f1dfc
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.auth.ldap;
+
+import java.io.File;
+import javax.servlet.http.HttpServletRequest;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.sonar.api.config.Configuration;
+import org.sonar.api.config.internal.MapSettings;
+import org.sonar.auth.ldap.server.LdapServer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.sonar.process.ProcessProperties.Property.SONAR_SECURITY_REALM;
+
+public class KerberosIT {
+
+  static {
+    System.setProperty("java.security.krb5.conf", new File("target/krb5.conf").getAbsolutePath());
+  }
+
+  @ClassRule
+  public static LdapServer server = new LdapServer("/krb.ldif");
+
+  LdapAuthenticator authenticator;
+  LdapRealm ldapRealm;
+
+  @Before
+  public void before() {
+    MapSettings settings = configure();
+    ldapRealm = new LdapRealm(new LdapSettingsManager(settings.asConfig()), settings.asConfig());
+    authenticator = ldapRealm.getAuthenticator();
+  }
+
+  @Test
+  public void test_wrong_password() {
+    LdapAuthenticator.Context wrongPasswordContext = new LdapAuthenticator.Context("Godin@EXAMPLE.ORG", "wrong_user_password", Mockito.mock(HttpServletRequest.class));
+    assertThat(authenticator.doAuthenticate(wrongPasswordContext).isSuccess()).isFalse();
+  }
+
+  @Test
+  public void test_correct_password() {
+
+    LdapAuthenticator.Context correctPasswordContext = new LdapAuthenticator.Context("Godin@EXAMPLE.ORG", "user_password", Mockito.mock(HttpServletRequest.class));
+    assertThat(authenticator.doAuthenticate(correctPasswordContext).isSuccess()).isTrue();
+
+  }
+
+  @Test
+  public void test_default_realm() {
+
+    // Using default realm from krb5.conf:
+    LdapAuthenticator.Context defaultRealmContext = new LdapAuthenticator.Context("Godin", "user_password", Mockito.mock(HttpServletRequest.class));
+    assertThat(authenticator.doAuthenticate(defaultRealmContext).isSuccess()).isTrue();
+  }
+
+  @Test
+  public void test_groups() {
+    LdapGroupsProvider groupsProvider = ldapRealm.getGroupsProvider();
+    LdapGroupsProvider.Context groupsContext = new LdapGroupsProvider.Context("default", "godin", Mockito.mock(HttpServletRequest.class));
+    assertThat(groupsProvider.doGetGroups(groupsContext))
+      .containsOnly("sonar-users");
+  }
+
+  @Test
+  public void wrong_bind_password() {
+    MapSettings settings = configure()
+      .setProperty("ldap.bindPassword", "wrong_bind_password");
+
+    Configuration config = settings.asConfig();
+    LdapSettingsManager settingsManager = new LdapSettingsManager(config);
+    assertThatThrownBy(() -> new LdapRealm(settingsManager, config))
+      .isInstanceOf(LdapException.class)
+      .hasMessage("LDAP realm failed to start: Unable to open LDAP connection");
+
+  }
+
+  private static MapSettings configure() {
+    return new MapSettings()
+      .setProperty("ldap.url", server.getUrl())
+      .setProperty("ldap.authentication", LdapContextFactory.AUTH_METHOD_GSSAPI)
+      .setProperty("ldap.bindDn", "SonarQube@EXAMPLE.ORG")
+      .setProperty("ldap.bindPassword", "bind_password")
+      .setProperty("ldap.user.baseDn", "ou=users,dc=example,dc=org")
+      .setProperty("ldap.group.baseDn", "ou=groups,dc=example,dc=org")
+      .setProperty("ldap.group.request", "(&(objectClass=groupOfUniqueNames)(uniqueMember={dn}))")
+      .setProperty(SONAR_SECURITY_REALM.getKey(), LdapRealm.LDAP_SECURITY_REALM);
+  }
+
+}
diff --git a/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/LdapRealmIT.java b/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/LdapRealmIT.java
new file mode 100644 (file)
index 0000000..4075ca0
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.auth.ldap;
+
+import javax.servlet.http.HttpServletRequest;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.sonar.api.config.Configuration;
+import org.sonar.api.config.internal.MapSettings;
+import org.sonar.auth.ldap.server.LdapServer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.sonar.process.ProcessProperties.Property.SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE;
+import static org.sonar.process.ProcessProperties.Property.SONAR_SECURITY_REALM;
+
+public class LdapRealmIT {
+
+  @ClassRule
+  public static LdapServer server = new LdapServer("/users.example.org.ldif");
+
+  @Test
+  public void normal() {
+    MapSettings settings = new MapSettings()
+      .setProperty("ldap.url", server.getUrl())
+      .setProperty("ldap.user.baseDn", "cn=users")
+      .setProperty(SONAR_SECURITY_REALM.getKey(), LdapRealm.LDAP_SECURITY_REALM);
+
+    LdapRealm realm = new LdapRealm(new LdapSettingsManager(settings.asConfig()), settings.asConfig());
+    assertThat(realm.getAuthenticator()).isInstanceOf(DefaultLdapAuthenticator.class);
+    assertThat(realm.getUsersProvider()).isInstanceOf(LdapUsersProvider.class).isInstanceOf(DefaultLdapUsersProvider.class);
+    assertThat(realm.getGroupsProvider()).isNull();
+  }
+
+  @Test
+  public void noConnection() {
+    MapSettings settings = new MapSettings()
+      .setProperty("ldap.url", "ldap://no-such-host")
+      .setProperty("ldap.group.baseDn", "cn=groups,dc=example,dc=org")
+      .setProperty("ldap.user.baseDn", "cn=users,dc=example,dc=org")
+      .setProperty(SONAR_SECURITY_REALM.getKey(), LdapRealm.LDAP_SECURITY_REALM);
+    Configuration config = settings.asConfig();
+    LdapSettingsManager settingsManager = new LdapSettingsManager(config);
+    assertThatThrownBy(() -> new LdapRealm(settingsManager, config)).isInstanceOf(LdapException.class)
+      .hasMessage("LDAP realm failed to start: Unable to open LDAP connection");
+  }
+
+  @Test
+  public void noConnection_ignore_ignoreStartupFailure_is_false() {
+    MapSettings settings = new MapSettings()
+      .setProperty("ldap.url", "ldap://no-such-host")
+      .setProperty("ldap.group.baseDn", "cn=groups,dc=example,dc=org")
+      .setProperty("ldap.user.baseDn", "cn=users,dc=example,dc=org")
+      .setProperty(SONAR_SECURITY_REALM.getKey(), LdapRealm.LDAP_SECURITY_REALM)
+      .setProperty(SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE.getKey(), false);
+    ;
+    Configuration config = settings.asConfig();
+    LdapSettingsManager settingsManager = new LdapSettingsManager(config);
+    assertThatThrownBy(() -> new LdapRealm(settingsManager, config)).isInstanceOf(LdapException.class)
+      .hasMessage("LDAP realm failed to start: Unable to open LDAP connection");
+  }
+
+  @Test
+  public void noConnection_ignore_ignoreStartupFailure_is_true() {
+    MapSettings settings = new MapSettings()
+      .setProperty("ldap.url", "ldap://no-such-host")
+      .setProperty("ldap.group.baseDn", "cn=groups,dc=example,dc=org")
+      .setProperty("ldap.user.baseDn", "cn=users,dc=example,dc=org")
+      .setProperty(SONAR_SECURITY_REALM.getKey(), LdapRealm.LDAP_SECURITY_REALM)
+      .setProperty(SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE.getKey(), true);
+
+    LdapRealm realm = new LdapRealm(new LdapSettingsManager(settings.asConfig()), settings.asConfig());
+    verifyRealm(realm);
+  }
+
+  @Test
+  public void should_not_activate_ldap_if_realm_is_not_set() {
+    MapSettings settings = new MapSettings();
+
+    LdapRealm realm = new LdapRealm(new LdapSettingsManager(settings.asConfig()), settings.asConfig());
+    verifyDeactivatedRealm(realm);
+  }
+
+  @Test
+  public void should_not_activate_ldap_if_realm_is_not_ldap() {
+    MapSettings settings = new MapSettings()
+      .setProperty(SONAR_SECURITY_REALM.getKey(), "not_ldap");
+
+    LdapRealm realm = new LdapRealm(new LdapSettingsManager(settings.asConfig()), settings.asConfig());
+    verifyDeactivatedRealm(realm);
+  }
+
+  private static void verifyRealm(LdapRealm realm) {
+    assertThat(realm.getAuthenticator()).isInstanceOf(DefaultLdapAuthenticator.class);
+
+    LdapUsersProvider usersProvider = realm.getUsersProvider();
+    assertThat(usersProvider).isInstanceOf(LdapUsersProvider.class).isInstanceOf(DefaultLdapUsersProvider.class);
+
+    LdapGroupsProvider groupsProvider = realm.getGroupsProvider();
+    assertThat(groupsProvider).isInstanceOf(LdapGroupsProvider.class).isInstanceOf(DefaultLdapGroupsProvider.class);
+
+    LdapUsersProvider.Context userContext = new DefaultLdapUsersProvider.Context("<default>", "tester", Mockito.mock(HttpServletRequest.class));
+    assertThatThrownBy(() -> usersProvider.doGetUserDetails(userContext))
+      .isInstanceOf(LdapException.class)
+      .hasMessage("Unable to retrieve details for user tester and server key <default>: No user mapping found.");
+
+    LdapGroupsProvider.Context groupsContext = new DefaultLdapGroupsProvider.Context("default", "tester", Mockito.mock(HttpServletRequest.class));
+    assertThatThrownBy(() -> groupsProvider.doGetGroups(groupsContext))
+      .isInstanceOf(LdapException.class)
+      .hasMessage("Unable to retrieve groups for user tester in server with key <default>");
+
+    assertThat(realm.isLdapAuthActivated()).isTrue();
+  }
+
+  private static void verifyDeactivatedRealm(LdapRealm realm) {
+    assertThat(realm.getAuthenticator()).isNull();
+    assertThat(realm.getUsersProvider()).isNull();
+    assertThat(realm.getGroupsProvider()).isNull();
+    assertThat(realm.isLdapAuthActivated()).isFalse();
+
+  }
+
+}
diff --git a/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/LdapReferralsIT.java b/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/LdapReferralsIT.java
new file mode 100644 (file)
index 0000000..39afbda
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.auth.ldap;
+
+import java.util.Map;
+import javax.annotation.Nullable;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.config.internal.MapSettings;
+import org.sonar.auth.ldap.server.LdapServer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class LdapReferralsIT {
+
+  @ClassRule
+  public static LdapServer server = new LdapServer("/users.example.org.ldif");
+
+  Map<String, LdapContextFactory> underTest;
+
+  @Test
+  public void referral_is_set_to_follow_when_followReferrals_setting_is_set_to_true() {
+    underTest = createFactories("ldap.followReferrals", "true");
+
+    LdapContextFactory contextFactory = underTest.values().iterator().next();
+    assertThat(contextFactory.getReferral()).isEqualTo("follow");
+  }
+
+  @Test
+  public void referral_is_set_to_ignore_when_followReferrals_setting_is_set_to_false() {
+    underTest = createFactories("ldap.followReferrals", "false");
+
+    LdapContextFactory contextFactory = underTest.values().iterator().next();
+    assertThat(contextFactory.getReferral()).isEqualTo("ignore");
+  }
+
+  @Test
+  public void referral_is_set_to_follow_when_no_followReferrals_setting() {
+    underTest = createFactories(null, null);
+
+    LdapContextFactory contextFactory = underTest.values().iterator().next();
+    assertThat(contextFactory.getReferral()).isEqualTo("follow");
+  }
+
+  private static Map<String, LdapContextFactory> createFactories(@Nullable String propertyKey, @Nullable String propertyValue) {
+    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(server, null);
+    if (propertyKey != null) {
+      settings.setProperty(propertyKey, propertyValue);
+    }
+    return new LdapSettingsManager(settings.asConfig()).getContextFactories();
+  }
+}
diff --git a/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/LdapSearchIT.java b/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/LdapSearchIT.java
new file mode 100644 (file)
index 0000000..44d3d2f
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.auth.ldap;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Map;
+import javax.naming.NamingException;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.auth.ldap.server.LdapServer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class LdapSearchIT {
+
+  @ClassRule
+  public static LdapServer server = new LdapServer("/users.example.org.ldif");
+  private static Map<String, LdapContextFactory> contextFactories;
+
+  @BeforeClass
+  public static void init() {
+    contextFactories = new LdapSettingsManager(LdapSettingsFactory.generateSimpleAnonymousAccessSettings(server, null).asConfig()).getContextFactories();
+  }
+
+  @Test
+  public void subtreeSearch() throws Exception {
+    LdapSearch search = new LdapSearch(contextFactories.values().iterator().next())
+      .setBaseDn("dc=example,dc=org")
+      .setRequest("(objectClass={0})")
+      .setParameters("inetOrgPerson")
+      .returns("objectClass");
+
+    assertThat(search.getBaseDn()).isEqualTo("dc=example,dc=org");
+    assertThat(search.getScope()).isEqualTo(SearchControls.SUBTREE_SCOPE);
+    assertThat(search.getRequest()).isEqualTo("(objectClass={0})");
+    assertThat(search.getParameters()).isEqualTo(new String[] {"inetOrgPerson"});
+    assertThat(search.getReturningAttributes()).isEqualTo(new String[] {"objectClass"});
+    assertThat(search).hasToString("LdapSearch{baseDn=dc=example,dc=org, scope=subtree, request=(objectClass={0}), parameters=[inetOrgPerson], attributes=[objectClass]}");
+    assertThat(enumerationToArrayList(search.find()))
+      .extracting(SearchResult::getName)
+      .containsExactlyInAnyOrder(
+        "cn=Without Email,ou=users",
+        "cn=Evgeny Mandrikov,ou=users",
+        "cn=Tester Testerovich,ou=users",
+        "cn=duplicated,ou=users"
+      );
+
+
+    assertThatThrownBy(search::findUnique)
+      .isInstanceOf(NamingException.class)
+      .hasMessage("Non unique result for " + search);
+  }
+
+  @Test
+  public void oneLevelSearch() throws Exception {
+    LdapSearch search = new LdapSearch(contextFactories.values().iterator().next())
+      .setBaseDn("dc=example,dc=org")
+      .setScope(SearchControls.ONELEVEL_SCOPE)
+      .setRequest("(objectClass={0})")
+      .setParameters("inetOrgPerson")
+      .returns("cn");
+
+    assertThat(search.getBaseDn()).isEqualTo("dc=example,dc=org");
+    assertThat(search.getScope()).isEqualTo(SearchControls.ONELEVEL_SCOPE);
+    assertThat(search.getRequest()).isEqualTo("(objectClass={0})");
+    assertThat(search.getParameters()).isEqualTo(new String[] {"inetOrgPerson"});
+    assertThat(search.getReturningAttributes()).isEqualTo(new String[] {"cn"});
+    assertThat(search).hasToString("LdapSearch{baseDn=dc=example,dc=org, scope=onelevel, request=(objectClass={0}), parameters=[inetOrgPerson], attributes=[cn]}");
+    assertThat(enumerationToArrayList(search.find())).isEmpty();
+    assertThat(search.findUnique()).isNull();
+  }
+
+  @Test
+  public void objectSearch() throws Exception {
+    LdapSearch search = new LdapSearch(contextFactories.values().iterator().next())
+      .setBaseDn("cn=bind,ou=users,dc=example,dc=org")
+      .setScope(SearchControls.OBJECT_SCOPE)
+      .setRequest("(objectClass={0})")
+      .setParameters("uidObject")
+      .returns("uid");
+
+    assertThat(search.getBaseDn()).isEqualTo("cn=bind,ou=users,dc=example,dc=org");
+    assertThat(search.getScope()).isEqualTo(SearchControls.OBJECT_SCOPE);
+    assertThat(search.getRequest()).isEqualTo("(objectClass={0})");
+    assertThat(search.getParameters()).isEqualTo(new String[] {"uidObject"});
+    assertThat(search.getReturningAttributes()).isEqualTo(new String[] {"uid"});
+    assertThat(search).hasToString(
+      "LdapSearch{baseDn=cn=bind,ou=users,dc=example,dc=org, scope=object, request=(objectClass={0}), parameters=[uidObject], attributes=[uid]}");
+    assertThat(enumerationToArrayList(search.find())).hasSize(1);
+    assertThat(search.findUnique()).isNotNull();
+  }
+
+  private static <E> ArrayList<E> enumerationToArrayList(Enumeration<E> enumeration) {
+    ArrayList<E> result = new ArrayList<>();
+    while (enumeration.hasMoreElements()) {
+      result.add(enumeration.nextElement());
+    }
+    return result;
+  }
+
+}
diff --git a/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/LdapSettingsFactory.java b/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/LdapSettingsFactory.java
new file mode 100644 (file)
index 0000000..f6718eb
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.auth.ldap;
+
+import javax.annotation.Nullable;
+import org.sonar.api.config.internal.MapSettings;
+import org.sonar.auth.ldap.server.LdapServer;
+
+/**
+ * Create Settings for most used test cases.
+ */
+public class LdapSettingsFactory {
+
+  /**
+   * Generate simple settings for 2 ldap servers that allows anonymous access.
+   *
+   * @return The specific settings.
+   */
+  public static MapSettings generateSimpleAnonymousAccessSettings(LdapServer exampleServer, @Nullable LdapServer infosupportServer) {
+    MapSettings settings = new MapSettings();
+
+    if (infosupportServer != null) {
+      settings.setProperty("ldap.servers", "example,infosupport");
+
+      settings.setProperty("ldap.example.url", exampleServer.getUrl())
+        .setProperty("ldap.example.user.baseDn", "ou=users,dc=example,dc=org")
+        .setProperty("ldap.example.group.baseDn", "ou=groups,dc=example,dc=org");
+      settings.setProperty("ldap.infosupport.url", infosupportServer.getUrl())
+        .setProperty("ldap.infosupport.user.baseDn", "ou=users,dc=infosupport,dc=com")
+        .setProperty("ldap.infosupport.group.baseDn", "ou=groups,dc=infosupport,dc=com");
+    } else {
+      settings.setProperty("ldap.url", exampleServer.getUrl())
+        .setProperty("ldap.user.baseDn", "ou=users,dc=example,dc=org")
+        .setProperty("ldap.group.baseDn", "ou=groups,dc=example,dc=org");
+    }
+    return settings;
+  }
+
+  /**
+   * Generate settings for 2 ldap servers.
+   *
+   * @param exampleServer     The first ldap server.
+   * @param infosupportServer The second ldap server.
+   * @return The specific settings.
+   */
+  public static MapSettings generateAuthenticationSettings(LdapServer exampleServer, @Nullable LdapServer infosupportServer, String authMethod) {
+    MapSettings settings = new MapSettings();
+
+    if (infosupportServer != null) {
+      settings.setProperty("ldap.servers", "example,infosupport");
+
+      settings.setProperty("ldap.example.url", exampleServer.getUrl())
+        .setProperty("ldap.example.bindDn", LdapContextFactory.AUTH_METHOD_SIMPLE.equals(authMethod) ? "cn=bind,ou=users,dc=example,dc=org" : "bind")
+        .setProperty("ldap.example.bindPassword", "bindpassword")
+        .setProperty("ldap.example.authentication", authMethod)
+        .setProperty("ldap.example.realm", "example.org")
+        .setProperty("ldap.example.user.baseDn", "ou=users,dc=example,dc=org")
+        .setProperty("ldap.example.group.baseDn", "ou=groups,dc=example,dc=org");
+
+      settings.setProperty("ldap.infosupport.url", infosupportServer.getUrl())
+        .setProperty("ldap.infosupport.bindDn", LdapContextFactory.AUTH_METHOD_SIMPLE.equals(authMethod) ? "cn=bind,ou=users,dc=infosupport,dc=com" : "bind")
+        .setProperty("ldap.infosupport.bindPassword", "bindpassword")
+        .setProperty("ldap.infosupport.authentication", authMethod)
+        .setProperty("ldap.infosupport.realm", "infosupport.com")
+        .setProperty("ldap.infosupport.user.baseDn", "ou=users,dc=infosupport,dc=com")
+        .setProperty("ldap.infosupport.group.baseDn", "ou=groups,dc=infosupport,dc=com");
+    } else {
+      settings.setProperty("ldap.url", exampleServer.getUrl())
+        .setProperty("ldap.bindDn", LdapContextFactory.AUTH_METHOD_SIMPLE.equals(authMethod) ? "cn=bind,ou=users,dc=example,dc=org" : "bind")
+        .setProperty("ldap.bindPassword", "bindpassword")
+        .setProperty("ldap.authentication", authMethod)
+        .setProperty("ldap.realm", "example.org")
+        .setProperty("ldap.user.baseDn", "ou=users,dc=example,dc=org")
+        .setProperty("ldap.group.baseDn", "ou=groups,dc=example,dc=org");
+    }
+    return settings;
+  }
+}
diff --git a/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/server/LdapServer.java b/server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/server/LdapServer.java
new file mode 100644 (file)
index 0000000..0f628db
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.auth.ldap.server;
+
+import org.junit.rules.ExternalResource;
+import org.sonar.ldap.ApacheDS;
+
+public class LdapServer extends ExternalResource {
+
+  private ApacheDS server;
+  private String ldif;
+  private final String realm;
+  private final String baseDn;
+
+  public LdapServer(String ldifResourceName) {
+    this(ldifResourceName, "example.org", "dc=example,dc=org");
+  }
+
+  public LdapServer(String ldifResourceName, String realm, String baseDn) {
+    this.ldif = ldifResourceName;
+    this.realm = realm;
+    this.baseDn = baseDn;
+  }
+
+  @Override
+  protected void before() throws Throwable {
+    server = ApacheDS.start(realm, baseDn);
+    server.importLdif(LdapServer.class.getResourceAsStream(ldif));
+  }
+
+  @Override
+  protected void after() {
+    try {
+      server.stop();
+    } catch (Exception e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  public String getUrl() {
+    return server.getUrl();
+  }
+
+  public void disableAnonymousAccess() {
+    server.disableAnonymousAccess();
+  }
+
+  public void enableAnonymousAccess() {
+    server.enableAnonymousAccess();
+  }
+
+}
diff --git a/server/sonar-auth-ldap/src/it/resources/conf/krb5.conf b/server/sonar-auth-ldap/src/it/resources/conf/krb5.conf
new file mode 100644 (file)
index 0000000..04fd9f9
--- /dev/null
@@ -0,0 +1,20 @@
+[libdefaults]
+       default_realm = EXAMPLE.ORG
+
+[realms]
+       EXAMPLE.ORG = {
+               kdc = localhost:6088
+       }
+       INFOSUPPORT.COM = {
+       kdc = localhost:6089
+     }
+
+[domain_realm]
+       .example.org = EXAMPLE.ORG
+       example.org = EXAMPLE.ORG
+       .infosupport.com = INFOSUPPORT.COM
+       infosupport.com = INFOSUPPORT.COM
+
+[login]
+       krb4_convert = true
+       krb4_get_tickets = false
diff --git a/server/sonar-auth-ldap/src/it/resources/conf/sasl_mech.properties b/server/sonar-auth-ldap/src/it/resources/conf/sasl_mech.properties
new file mode 100644 (file)
index 0000000..f3d209e
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# SonarQube
+# Copyright (C) 2009-2019 SonarSource SA
+# mailto:info AT sonarsource DOT com
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 3 of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+#
+ldap.url:ldap://localhost:1024
+# TODO don't work as expected
+ldap.authentication:DIGEST-MD5 CRAM-MD5
+#ldap.realm: example.org
diff --git a/server/sonar-auth-ldap/src/it/resources/krb.ldif b/server/sonar-auth-ldap/src/it/resources/krb.ldif
new file mode 100644 (file)
index 0000000..6c8235d
--- /dev/null
@@ -0,0 +1,55 @@
+dn: dc=example,dc=org
+dc: example
+objectClass: domain
+objectClass: top
+
+dn: ou=Users,dc=example,dc=org
+objectClass: organizationalUnit
+objectClass: top
+ou: Users
+
+dn: uid=krbtgt,ou=Users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: KDC Service
+sn: Service
+uid: krbtgt
+userPassword: secret
+krb5PrincipalName: krbtgt/EXAMPLE.ORG@EXAMPLE.ORG
+krb5KeyVersionNumber: 0
+
+dn: cn=SonarQube,ou=Users,dc=example,dc=org
+objectClass: top
+objectClass: organizationalRole
+objectClass: simpleSecurityObject
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: SonarQube
+userPassword: bind_password
+krb5PrincipalName: SonarQube@EXAMPLE.ORG
+krb5KeyVersionNumber: 0
+
+dn: uid=godin,ou=Users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: Evgeny Mandrikov
+sn: Mandrikov
+uid: godin
+userPassword: user_password
+krb5PrincipalName: Godin@EXAMPLE.ORG
+krb5KeyVersionNumber: 0
+
+dn: ou=Groups,dc=example,dc=org
+objectclass:organizationalunit
+ou: groups
+
+dn: cn=sonar-users,ou=Groups,dc=example,dc=org
+objectclass: groupOfUniqueNames
+cn: sonar-users
+uniqueMember: uid=godin,ou=Users,dc=example,dc=org
diff --git a/server/sonar-auth-ldap/src/it/resources/static-groups.example.org.ldif b/server/sonar-auth-ldap/src/it/resources/static-groups.example.org.ldif
new file mode 100644 (file)
index 0000000..857efc7
--- /dev/null
@@ -0,0 +1,81 @@
+dn: dc=example,dc=org
+objectClass: domain
+objectClass: extensibleObject
+objectClass: top
+dc: example
+
+#
+# USERS
+#
+
+dn: ou=users,dc=example,dc=org
+objectClass: organizationalUnit
+objectClass: top
+ou: users
+
+# Bind user
+dn: cn=bind,ou=users,dc=example,dc=org
+objectClass: organizationalRole
+objectClass: simpleSecurityObject
+objectClass: top
+cn: bind
+userpassword: bindpassword
+
+# Typical user
+dn: cn=Evgeny Mandrikov,ou=users,dc=example,dc=org
+objectClass: organizationalPerson
+objectClass: person
+objectClass: extensibleObject
+objectClass: uidObject
+objectClass: inetOrgPerson
+objectClass: top
+cn: Evgeny Mandrikov
+sn: Mandrikov
+givenname: Evgeny
+mail: godin@example.org
+uid: godin
+userpassword: secret1
+
+# Just one more user
+dn: cn=Tester Testerovich,ou=users,dc=example,dc=org
+objectClass: organizationalPerson
+objectClass: person
+objectClass: extensibleObject
+objectClass: uidObject
+objectClass: inetOrgPerson
+objectClass: top
+cn: Tester Testerovich
+givenname: Tester
+sn: Testerovich
+mail: tester@example.org
+uid: tester
+userpassword: secret2
+
+#
+# GROUPS
+#
+
+dn: ou=groups,dc=example,dc=org
+objectclass:organizationalunit
+ou: groups
+
+# sonar-users
+dn: cn=sonar-users,ou=groups,dc=example,dc=org
+objectclass: groupOfUniqueNames
+cn: sonar-users
+uniqueMember: cn=Tester Testerovich,ou=users,dc=example,dc=org
+uniqueMember: cn=Evgeny Mandrikov,ou=users,dc=example,dc=org
+
+# sonar-developers
+dn: cn=sonar-developers,ou=groups,dc=example,dc=org
+objectclass: groupOfUniqueNames
+cn: sonar-developers
+uniqueMember: cn=Evgeny Mandrikov,ou=users,dc=example,dc=org
+
+# linux-users
+dn: cn=linux-users,ou=groups,dc=example,dc=org
+objectclass: posixGroup
+objectclass: top
+cn: linux-users
+gidNumber: 10000
+memberUid: godin
diff --git a/server/sonar-auth-ldap/src/it/resources/users-apacheds.ldif b/server/sonar-auth-ldap/src/it/resources/users-apacheds.ldif
new file mode 100644 (file)
index 0000000..d023151
--- /dev/null
@@ -0,0 +1,88 @@
+dn: dc=example,dc=org
+objectClass: domain
+objectClass: extensibleObject
+objectClass: top
+dc: example
+
+#
+# USERS
+#
+
+dn: ou=users,dc=example,dc=org
+objectClass: organizationalUnit
+objectClass: top
+ou: users
+
+dn: cn=bind,ou=users,dc=example,dc=org
+objectClass: organizationalRole
+objectClass: uidObject
+objectClass: simpleSecurityObject
+objectClass: top
+cn: bind
+uid: sonar
+userpassword: bindpassword
+
+dn: cn=Evgeny Mandrikov,ou=users,dc=example,dc=org
+objectClass: organizationalPerson
+objectClass: person
+objectClass: extensibleObject
+objectClass: uidObject
+objectClass: inetOrgPerson
+objectClass: top
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: Evgeny Mandrikov
+givenname: Evgeny
+mail: godin@example.org
+sn: Mandrikov
+uid: godin
+userpassword: secret1
+krb5PrincipalName: godin@EXAMPLE.ORG
+krb5KeyVersionNumber: 0
+
+dn: cn=Tester Testerovich,ou=users,dc=example,dc=org
+objectClass: organizationalPerson
+objectClass: person
+objectClass: extensibleObject
+objectClass: uidObject
+objectClass: inetOrgPerson
+objectClass: top
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: Tester Testerovich
+givenname: Tester
+mail: tester@example.org
+sn: Testerovich
+uid: tester
+userpassword: secret2
+krb5PrincipalName: tester@EXAMPLE.ORG
+krb5KeyVersionNumber: 0
+
+####
+# For Krb5
+####
+dn: uid=krbtgt,ou=users,dc=example,dc=org
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: top
+objectClass: krb5principal
+objectClass: krb5kdcentry
+sn: Service
+cn: KDC Service
+uid: krbtgt
+userPassword: secret
+krb5PrincipalName: krbtgt/EXAMPLE.ORG@EXAMPLE.ORG
+krb5KeyVersionNumber: 0
+
+dn: uid=ldap,ou=users,dc=example,dc=org
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: top
+objectClass: krb5principal
+objectClass: krb5kdcentry
+sn: Service
+cn: LDAP Service
+uid: ldap
+userPassword: randall
+krb5PrincipalName: ldap/localhost@EXAMPLE.COM
+krb5KeyVersionNumber: 0
diff --git a/server/sonar-auth-ldap/src/it/resources/users.example.org.ldif b/server/sonar-auth-ldap/src/it/resources/users.example.org.ldif
new file mode 100644 (file)
index 0000000..fe3341c
--- /dev/null
@@ -0,0 +1,113 @@
+dn: dc=example,dc=org
+objectClass: domain
+objectClass: extensibleObject
+objectClass: top
+dc: example
+
+#
+# USERS
+#
+
+dn: ou=users,dc=example,dc=org
+objectClass: organizationalUnit
+objectClass: top
+ou: users
+
+# Bind user
+dn: cn=bind,ou=users,dc=example,dc=org
+objectClass: organizationalRole
+objectClass: uidObject
+objectClass: simpleSecurityObject
+objectClass: top
+cn: bind
+uid: sonar
+userpassword: bindpassword
+
+# Duplicated user on infosupport ldap
+dn: cn=duplicated,ou=users,dc=example,dc=org
+objectClass: organizationalPerson
+objectClass: person
+objectClass: extensibleObject
+objectClass: uidObject
+objectClass: inetOrgPerson
+objectClass: top
+cn: duplicated
+uid: duplicated
+sn: Duplicated
+mail: duplicated@example.org
+userpassword: duplicated
+
+# Typical user
+dn: cn=Evgeny Mandrikov,ou=users,dc=example,dc=org
+objectClass: organizationalPerson
+objectClass: person
+objectClass: extensibleObject
+objectClass: uidObject
+objectClass: inetOrgPerson
+objectClass: top
+cn: Evgeny Mandrikov
+givenname: Evgeny
+sn: Mandrikov
+mail: godin@example.org
+uid: godin
+userpassword: secret1
+
+# Just one more user
+dn: cn=Tester Testerovich,ou=users,dc=example,dc=org
+objectClass: organizationalPerson
+objectClass: person
+objectClass: extensibleObject
+objectClass: uidObject
+objectClass: inetOrgPerson
+objectClass: top
+cn: Tester Testerovich
+givenname: Tester
+sn: Testerovich
+mail: tester@example.org
+uid: tester
+userpassword: secret2
+
+# Special case which can cause NPE
+dn: cn=Without Email,ou=users,dc=example,dc=org
+objectClass: organizationalPerson
+objectClass: person
+objectClass: extensibleObject
+objectClass: uidObject
+objectClass: inetOrgPerson
+objectClass: top
+cn: Without Email
+givenname: Without
+sn: Email
+uid: without_email
+userpassword: secret3
+
+
+#
+# GROUPS
+#
+
+dn: ou=groups,dc=example,dc=org
+objectclass:organizationalunit
+ou: groups
+
+# sonar-users
+dn: cn=sonar-users,ou=groups,dc=example,dc=org
+objectclass: groupOfUniqueNames
+cn: sonar-users
+uniqueMember: cn=Tester Testerovich,ou=users,dc=example,dc=org
+uniqueMember: cn=Evgeny Mandrikov,ou=users,dc=example,dc=org
+uniqueMember: cn=duplicated,ou=users,dc=example,dc=org
+
+# sonar-developers
+dn: cn=sonar-developers,ou=groups,dc=example,dc=org
+objectclass: groupOfUniqueNames
+cn: sonar-developers
+uniqueMember: cn=Evgeny Mandrikov,ou=users,dc=example,dc=org
+
+# linux-users
+dn: cn=linux-users,ou=groups,dc=example,dc=org
+objectclass: posixGroup
+objectclass: top
+cn: linux-users
+gidNumber: 10000
+memberUid: godin
diff --git a/server/sonar-auth-ldap/src/it/resources/users.infosupport.com.ldif b/server/sonar-auth-ldap/src/it/resources/users.infosupport.com.ldif
new file mode 100644 (file)
index 0000000..d57addd
--- /dev/null
@@ -0,0 +1,129 @@
+dn: dc=infosupport,dc=com
+objectClass: domain
+objectClass: extensibleObject
+objectClass: top
+dc: infosupport
+
+#
+# USERS
+#
+
+dn: ou=users,dc=infosupport,dc=com
+objectClass: organizationalUnit
+objectClass: top
+ou: users
+
+# Bind user
+dn: cn=bind,ou=users,dc=infosupport,dc=com
+objectClass: organizationalRole
+objectClass: uidObject
+objectClass: simpleSecurityObject
+objectClass: top
+cn: bind
+uid: sonar
+userpassword: bindpassword
+
+# Duplicated user on example ldap
+dn: cn=duplicated,ou=users,dc=infosupport,dc=com
+objectClass: organizationalPerson
+objectClass: person
+objectClass: extensibleObject
+objectClass: uidObject
+objectClass: inetOrgPerson
+objectClass: top
+cn: duplicated
+uid: duplicated
+sn: Duplicated
+mail: duplicated@infosupport.com
+userpassword: duplicated
+
+# Typical user
+dn: cn=Robby Developer,ou=users,dc=infosupport,dc=com
+objectClass: organizationalPerson
+objectClass: person
+objectClass: extensibleObject
+objectClass: uidObject
+objectClass: inetOrgPerson
+objectClass: top
+cn: Robby Developer
+givenname: Robby
+sn: Developer
+mail: rd@infosupport.com
+uid: robby
+userpassword: secret1
+
+# Just one more user
+dn: cn=Tester Testerovich,ou=users,dc=infosupport,dc=com
+objectClass: organizationalPerson
+objectClass: person
+objectClass: extensibleObject
+objectClass: uidObject
+objectClass: inetOrgPerson
+objectClass: top
+cn: Tester Testerovich
+givenname: Tester
+sn: Testerovich
+mail: tester@infosupport.com
+uid: testerInfo
+userpassword: secret2
+
+# User repeated on multiple servers
+dn: cn=Tester Testerovich Testerov,ou=users,dc=infosupport,dc=com
+objectClass: organizationalPerson
+objectClass: person
+objectClass: extensibleObject
+objectClass: uidObject
+objectClass: inetOrgPerson
+objectClass: top
+cn: Tester Testerovich Testerov
+givenname: Tester
+sn: Testerovich
+mail: tester@example2.org
+uid: tester
+userpassword: secret3
+
+
+# Special case which can cause NPE
+dn: cn=Without Email,ou=users,dc=infosupport,dc=com
+objectClass: organizationalPerson
+objectClass: person
+objectClass: extensibleObject
+objectClass: uidObject
+objectClass: inetOrgPerson
+objectClass: top
+cn: Without Email
+givenname: Without
+sn: Email
+uid: without_email
+userpassword: secret3
+
+
+#
+# GROUPS
+#
+
+dn: ou=groups,dc=infosupport,dc=com
+objectclass:organizationalunit
+ou: groups
+
+# sonar-users
+dn: cn=sonar-users,ou=groups,dc=infosupport,dc=com
+objectclass: groupOfUniqueNames
+cn: sonar-users
+uniqueMember: cn=Robby Developer,ou=users,dc=infosupport,dc=com
+uniqueMember: cn=Tester Testerovich,ou=users,dc=infosupport,dc=com
+
+# sonar-developers
+dn: cn=sonar-developers,ou=groups,dc=infosupport,dc=com
+objectclass: groupOfUniqueNames
+cn: sonar-developers
+uniqueMember: cn=Robby Developer,ou=users,dc=infosupport,dc=com
+uniqueMember: cn=duplicated,ou=users,dc=infosupport,dc=com
+
+# linux-users
+dn: cn=linux-users,ou=groups,dc=infosupport,dc=com
+objectclass: posixGroup
+objectclass: top
+cn: linux-users
+gidNumber: 10000
+memberUid: robby
diff --git a/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/DefaultLdapAuthenticatorTest.java b/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/DefaultLdapAuthenticatorTest.java
deleted file mode 100644 (file)
index d053ec5..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.auth.ldap;
-
-import javax.servlet.http.HttpServletRequest;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.sonar.auth.ldap.server.LdapServer;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-public class DefaultLdapAuthenticatorTest {
-
-  /**
-   * A reference to the original ldif file
-   */
-  public static final String USERS_EXAMPLE_ORG_LDIF = "/users.example.org.ldif";
-  /**
-   * A reference to an additional ldif file.
-   */
-  public static final String USERS_INFOSUPPORT_COM_LDIF = "/users.infosupport.com.ldif";
-  @ClassRule
-  public static LdapServer exampleServer = new LdapServer(USERS_EXAMPLE_ORG_LDIF);
-  @ClassRule
-  public static LdapServer infosupportServer = new LdapServer(USERS_INFOSUPPORT_COM_LDIF, "infosupport.com", "dc=infosupport,dc=com");
-
-  @Test
-  public void testNoConnection() {
-    exampleServer.disableAnonymousAccess();
-    try {
-      LdapSettingsManager settingsManager = new LdapSettingsManager(
-        LdapSettingsFactory.generateAuthenticationSettings(exampleServer, null, LdapContextFactory.AUTH_METHOD_SIMPLE).asConfig());
-      DefaultLdapAuthenticator authenticator = new DefaultLdapAuthenticator(settingsManager.getContextFactories(), settingsManager.getUserMappings());
-      boolean isAuthenticationSuccessful = authenticator.doAuthenticate(createContext("godin", "secret1")).isSuccess();
-      assertThat(isAuthenticationSuccessful).isTrue();
-    } finally {
-      exampleServer.enableAnonymousAccess();
-    }
-  }
-
-  @Test
-  public void testSimple() {
-    LdapSettingsManager settingsManager = new LdapSettingsManager(
-      LdapSettingsFactory.generateAuthenticationSettings(exampleServer, null, LdapContextFactory.AUTH_METHOD_SIMPLE).asConfig());
-    DefaultLdapAuthenticator authenticator = new DefaultLdapAuthenticator(settingsManager.getContextFactories(), settingsManager.getUserMappings());
-
-    LdapAuthenticationResult user1Success = authenticator.doAuthenticate(createContext("godin", "secret1"));
-    assertThat(user1Success.isSuccess()).isTrue();
-    assertThat(user1Success.getServerKey()).isEqualTo("default");
-
-    assertThat(authenticator.doAuthenticate(createContext("godin", "wrong")).isSuccess()).isFalse();
-
-    LdapAuthenticationResult user2Success = authenticator.doAuthenticate(createContext("tester", "secret2"));
-    assertThat(user2Success.isSuccess()).isTrue();
-    assertThat(user2Success.getServerKey()).isEqualTo("default");
-
-    assertThat(authenticator.doAuthenticate(createContext("tester", "wrong")).isSuccess()).isFalse();
-
-    assertThat(authenticator.doAuthenticate(createContext("notfound", "wrong")).isSuccess()).isFalse();
-    // SONARPLUGINS-2493
-    assertThat(authenticator.doAuthenticate(createContext("godin", "")).isSuccess()).isFalse();
-    assertThat(authenticator.doAuthenticate(createContext("godin", null)).isSuccess()).isFalse();
-  }
-
-  @Test
-  public void testSimpleMultiLdap() {
-    LdapSettingsManager settingsManager = new LdapSettingsManager(
-      LdapSettingsFactory.generateAuthenticationSettings(exampleServer, infosupportServer, LdapContextFactory.AUTH_METHOD_SIMPLE).asConfig());
-    DefaultLdapAuthenticator authenticator = new DefaultLdapAuthenticator(settingsManager.getContextFactories(), settingsManager.getUserMappings());
-
-    LdapAuthenticationResult user1Success = authenticator.doAuthenticate(createContext("godin", "secret1"));
-    assertThat(user1Success.isSuccess()).isTrue();
-    assertThat(user1Success.getServerKey()).isEqualTo("example");
-    assertThat(authenticator.doAuthenticate(createContext("godin", "wrong")).isSuccess()).isFalse();
-
-    LdapAuthenticationResult user2Server1Success = authenticator.doAuthenticate(createContext("tester", "secret2"));
-    assertThat(user2Server1Success.isSuccess()).isTrue();
-    assertThat(user2Server1Success.getServerKey()).isEqualTo("example");
-
-    LdapAuthenticationResult user2Server2Success = authenticator.doAuthenticate(createContext("tester", "secret3"));
-    assertThat(user2Server2Success.isSuccess()).isTrue();
-    assertThat(user2Server2Success.getServerKey()).isEqualTo("infosupport");
-
-    assertThat(authenticator.doAuthenticate(createContext("tester", "wrong")).isSuccess()).isFalse();
-
-    assertThat(authenticator.doAuthenticate(createContext("notfound", "wrong")).isSuccess()).isFalse();
-    // SONARPLUGINS-2493
-    assertThat(authenticator.doAuthenticate(createContext("godin", "")).isSuccess()).isFalse();
-    assertThat(authenticator.doAuthenticate(createContext("godin", null)).isSuccess()).isFalse();
-
-    // SONARPLUGINS-2793
-    LdapAuthenticationResult user3Success = authenticator.doAuthenticate(createContext("robby", "secret1"));
-    assertThat(user3Success.isSuccess()).isTrue();
-    assertThat(user3Success.getServerKey()).isEqualTo("infosupport");
-    assertThat(authenticator.doAuthenticate(createContext("robby", "wrong")).isSuccess()).isFalse();
-  }
-
-  @Test
-  public void testSasl() {
-    LdapSettingsManager settingsManager = new LdapSettingsManager(
-      LdapSettingsFactory.generateAuthenticationSettings(exampleServer, null, LdapContextFactory.AUTH_METHOD_CRAM_MD5).asConfig());
-    DefaultLdapAuthenticator authenticator = new DefaultLdapAuthenticator(settingsManager.getContextFactories(), settingsManager.getUserMappings());
-
-    LdapAuthenticationResult user1Success = authenticator.doAuthenticate(createContext("godin", "secret1"));
-    assertThat(user1Success.isSuccess()).isTrue();
-    assertThat(user1Success.getServerKey()).isEqualTo("default");
-
-    assertThat(authenticator.doAuthenticate(createContext("godin", "wrong")).isSuccess()).isFalse();
-
-    LdapAuthenticationResult user2Success = authenticator.doAuthenticate(createContext("tester", "secret2"));
-    assertThat(user2Success.isSuccess()).isTrue();
-    assertThat(user2Success.getServerKey()).isEqualTo("default");
-
-    assertThat(authenticator.doAuthenticate(createContext("tester", "wrong")).isSuccess()).isFalse();
-
-    assertThat(authenticator.doAuthenticate(createContext("notfound", "wrong")).isSuccess()).isFalse();
-  }
-
-  @Test
-  public void testSaslMultipleLdap() {
-    LdapSettingsManager settingsManager = new LdapSettingsManager(
-      LdapSettingsFactory.generateAuthenticationSettings(exampleServer, infosupportServer, LdapContextFactory.AUTH_METHOD_CRAM_MD5).asConfig());
-    DefaultLdapAuthenticator authenticator = new DefaultLdapAuthenticator(settingsManager.getContextFactories(), settingsManager.getUserMappings());
-
-    LdapAuthenticationResult user1Success = authenticator.doAuthenticate(createContext("godin", "secret1"));
-    assertThat(user1Success.isSuccess()).isTrue();
-    assertThat(authenticator.doAuthenticate(createContext("godin", "wrong")).isSuccess()).isFalse();
-
-    LdapAuthenticationResult user2Server1Success = authenticator.doAuthenticate(createContext("tester", "secret2"));
-    assertThat(user2Server1Success.isSuccess()).isTrue();
-    assertThat(user2Server1Success.getServerKey()).isEqualTo("example");
-
-    LdapAuthenticationResult user2Server2Success = authenticator.doAuthenticate(createContext("tester", "secret3"));
-    assertThat(user2Server2Success.isSuccess()).isTrue();
-    assertThat(user2Server2Success.getServerKey()).isEqualTo("infosupport");
-
-    assertThat(authenticator.doAuthenticate(createContext("tester", "wrong")).isSuccess()).isFalse();
-
-    assertThat(authenticator.doAuthenticate(createContext("notfound", "wrong")).isSuccess()).isFalse();
-
-    LdapAuthenticationResult user3Success = authenticator.doAuthenticate(createContext("robby", "secret1"));
-    assertThat(user3Success.isSuccess()).isTrue();
-
-    assertThat(authenticator.doAuthenticate(createContext("robby", "wrong")).isSuccess()).isFalse();
-  }
-
-  private static LdapAuthenticator.Context createContext(String username, String password) {
-    return new LdapAuthenticator.Context(username, password, mock(HttpServletRequest.class));
-  }
-
-}
diff --git a/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/DefaultLdapGroupsProviderTest.java b/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/DefaultLdapGroupsProviderTest.java
deleted file mode 100644 (file)
index 162ca5b..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.auth.ldap;
-
-import java.util.Collection;
-import javax.servlet.http.HttpServletRequest;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.sonar.api.config.internal.MapSettings;
-import org.sonar.auth.ldap.server.LdapServer;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-public class DefaultLdapGroupsProviderTest {
-
-  /**
-   * A reference to the original ldif file
-   */
-  public static final String USERS_EXAMPLE_ORG_LDIF = "/users.example.org.ldif";
-  /**
-   * A reference to an aditional ldif file.
-   */
-  public static final String USERS_INFOSUPPORT_COM_LDIF = "/users.infosupport.com.ldif";
-
-  @ClassRule
-  public static LdapServer exampleServer = new LdapServer(USERS_EXAMPLE_ORG_LDIF);
-  @ClassRule
-  public static LdapServer infosupportServer = new LdapServer(USERS_INFOSUPPORT_COM_LDIF, "infosupport.com", "dc=infosupport,dc=com");
-
-  @Test
-  public void doGetGroups_when_single_server_without_key() {
-    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, null);
-
-    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
-    DefaultLdapGroupsProvider groupsProvider = new DefaultLdapGroupsProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings(),
-      settingsManager.getGroupMappings());
-
-    Collection<String> groups = getGroupsForContext(createContextForDefaultServer("tester"), groupsProvider);
-    assertThat(groups).containsOnly("sonar-users");
-
-    groups = getGroupsForContext(createContextForDefaultServer("godin"), groupsProvider);
-    assertThat(groups).containsOnly("sonar-users", "sonar-developers");
-
-    groups = getGroupsForContext(createContextForDefaultServer("unknown_user"), groupsProvider);
-    assertThat(groups).isEmpty();
-  }
-
-  @Test
-  public void doGetGroups_when_two_ldap_servers() {
-    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
-
-    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
-    DefaultLdapGroupsProvider groupsProvider = new DefaultLdapGroupsProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings(),
-      settingsManager.getGroupMappings());
-
-    Collection<String> groups = getGroupsForContext(createContextForExampleServer("tester"), groupsProvider);
-    assertThat(groups).containsOnly("sonar-users");
-
-    groups = getGroupsForContext(createContextForExampleServer("godin"), groupsProvider);
-    assertThat(groups).containsOnly("sonar-users", "sonar-developers");
-
-    groups = getGroupsForContext(createContextForExampleServer("unknown_user"), groupsProvider);
-    assertThat(groups).isEmpty();
-
-    groups = getGroupsForContext(createContextForInfoSupportServer("testerInfo"), groupsProvider);
-    assertThat(groups).containsOnly("sonar-users");
-
-    groups = getGroupsForContext(createContextForInfoSupportServer("robby"), groupsProvider);
-    assertThat(groups).containsOnly("sonar-users", "sonar-developers");
-  }
-
-  @Test
-  public void doGetGroups_when_two_ldap_servers_with_same_username_resolves_groups_from_right_server() {
-    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
-
-    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
-    DefaultLdapGroupsProvider groupsProvider = new DefaultLdapGroupsProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings(),
-      settingsManager.getGroupMappings());
-
-    Collection<String> groups = getGroupsForContext(createContextForExampleServer("duplicated"), groupsProvider);
-    assertThat(groups).containsOnly("sonar-users");
-
-    groups = getGroupsForContext(createContextForInfoSupportServer("duplicated"), groupsProvider);
-    assertThat(groups).containsOnly("sonar-developers");
-  }
-
-  @Test
-  public void posix() {
-    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, null);
-    settings.setProperty("ldap.group.request", "(&(objectClass=posixGroup)(memberUid={uid}))");
-    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
-    DefaultLdapGroupsProvider groupsProvider = new DefaultLdapGroupsProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings(),
-      settingsManager.getGroupMappings());
-
-    Collection<String> groups = getGroupsForContext(createContextForDefaultServer("godin"), groupsProvider);
-    assertThat(groups).containsOnly("linux-users");
-  }
-
-  @Test
-  public void posixMultipleLdap() {
-    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
-    settings.setProperty("ldap.example.group.request", "(&(objectClass=posixGroup)(memberUid={uid}))");
-    settings.setProperty("ldap.infosupport.group.request", "(&(objectClass=posixGroup)(memberUid={uid}))");
-    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
-    DefaultLdapGroupsProvider groupsProvider = new DefaultLdapGroupsProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings(),
-      settingsManager.getGroupMappings());
-
-    Collection<String> groups = getGroupsForContext(createContextForExampleServer("godin"), groupsProvider);
-    assertThat(groups).containsOnly("linux-users");
-
-    groups = getGroupsForContext(createContextForInfoSupportServer("robby"), groupsProvider);
-    assertThat(groups).containsOnly("linux-users");
-  }
-
-  private static Collection<String> getGroupsForContext(LdapGroupsProvider.Context context, DefaultLdapGroupsProvider groupsProvider) {
-    return groupsProvider.doGetGroups(context);
-  }
-
-  @Test
-  public void mixed() {
-    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
-    settings.setProperty("ldap.example.group.request", "(&(|(objectClass=groupOfUniqueNames)(objectClass=posixGroup))(|(uniqueMember={dn})(memberUid={uid})))");
-    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
-    DefaultLdapGroupsProvider groupsProvider = new DefaultLdapGroupsProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings(),
-      settingsManager.getGroupMappings());
-
-    Collection<String> groups = getGroupsForContext(createContextForExampleServer("godin"), groupsProvider);
-    assertThat(groups).containsOnly("sonar-users", "sonar-developers", "linux-users");
-  }
-
-  @Test
-  public void mixedMultipleLdap() {
-    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
-    settings.setProperty("ldap.example.group.request", "(&(|(objectClass=groupOfUniqueNames)(objectClass=posixGroup))(|(uniqueMember={dn})(memberUid={uid})))");
-    settings.setProperty("ldap.infosupport.group.request", "(&(|(objectClass=groupOfUniqueNames)(objectClass=posixGroup))(|(uniqueMember={dn})(memberUid={uid})))");
-    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
-    DefaultLdapGroupsProvider groupsProvider = new DefaultLdapGroupsProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings(),
-      settingsManager.getGroupMappings());
-
-    Collection<String> groups = getGroupsForContext(createContextForExampleServer("godin"), groupsProvider);
-    assertThat(groups).containsOnly("sonar-users", "sonar-developers", "linux-users");
-
-    groups = getGroupsForContext(createContextForInfoSupportServer("robby"), groupsProvider);
-    assertThat(groups).containsOnly("sonar-users", "sonar-developers", "linux-users");
-  }
-
-  private static LdapGroupsProvider.Context createContextForDefaultServer(String userName) {
-    return createContext("default", userName);
-  }
-
-  private static LdapGroupsProvider.Context createContextForExampleServer(String userName) {
-    return createContext("example", userName);
-  }
-
-  private static LdapGroupsProvider.Context createContextForInfoSupportServer(String userName) {
-    return createContext("infosupport", userName);
-  }
-
-  private static LdapGroupsProvider.Context createContext(String serverName, String userName) {
-    return new LdapGroupsProvider.Context(serverName, userName, mock(HttpServletRequest.class));
-  }
-
-}
diff --git a/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/DefaultLdapUsersProviderTest.java b/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/DefaultLdapUsersProviderTest.java
deleted file mode 100644 (file)
index 1218cee..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.auth.ldap;
-
-import javax.servlet.http.HttpServletRequest;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.sonar.api.config.internal.MapSettings;
-import org.sonar.auth.ldap.server.LdapServer;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-public class DefaultLdapUsersProviderTest {
-  /**
-   * A reference to the original ldif file
-   */
-  public static final String USERS_EXAMPLE_ORG_LDIF = "/users.example.org.ldif";
-  /**
-   * A reference to an additional ldif file.
-   */
-  public static final String USERS_INFOSUPPORT_COM_LDIF = "/users.infosupport.com.ldif";
-
-  @ClassRule
-  public static LdapServer exampleServer = new LdapServer(USERS_EXAMPLE_ORG_LDIF);
-  @ClassRule
-  public static LdapServer infosupportServer = new LdapServer(USERS_INFOSUPPORT_COM_LDIF, "infosupport.com", "dc=infosupport,dc=com");
-
-  @Test
-  public void test_user_from_first_server() {
-    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
-    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
-    DefaultLdapUsersProvider usersProvider = new DefaultLdapUsersProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings());
-
-    LdapUserDetails details = usersProvider.doGetUserDetails(createContext("example", "godin"));
-    assertThat(details.getName()).isEqualTo("Evgeny Mandrikov");
-    assertThat(details.getEmail()).isEqualTo("godin@example.org");
-  }
-
-  @Test
-  public void test_user_from_second_server() {
-    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
-    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
-    DefaultLdapUsersProvider usersProvider = new DefaultLdapUsersProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings());
-
-    LdapUserDetails details = usersProvider.doGetUserDetails(createContext("infosupport", "robby"));
-    assertThat(details.getName()).isEqualTo("Robby Developer");
-    assertThat(details.getEmail()).isEqualTo("rd@infosupport.com");
-
-  }
-
-  @Test
-  public void test_user_on_multiple_servers() {
-    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
-    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
-    DefaultLdapUsersProvider usersProvider = new DefaultLdapUsersProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings());
-
-    LdapUserDetails detailsExample = usersProvider.doGetUserDetails(createContext("example", "tester"));
-    assertThat(detailsExample.getName()).isEqualTo("Tester Testerovich");
-    assertThat(detailsExample.getEmail()).isEqualTo("tester@example.org");
-
-    LdapUserDetails detailsInfoSupport = usersProvider.doGetUserDetails(createContext("infosupport", "tester"));
-    assertThat(detailsInfoSupport.getName()).isEqualTo("Tester Testerovich Testerov");
-    assertThat(detailsInfoSupport.getEmail()).isEqualTo("tester@example2.org");
-  }
-
-  @Test
-  public void test_user_doesnt_exist() {
-    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(exampleServer, infosupportServer);
-    LdapSettingsManager settingsManager = new LdapSettingsManager(settings.asConfig());
-    DefaultLdapUsersProvider usersProvider = new DefaultLdapUsersProvider(settingsManager.getContextFactories(), settingsManager.getUserMappings());
-
-    LdapUserDetails details = usersProvider.doGetUserDetails(createContext("example", "notfound"));
-    assertThat(details).isNull();
-  }
-
-  private static LdapUsersProvider.Context createContext(String serverKey, String username) {
-    return new LdapUsersProvider.Context(serverKey, username, mock(HttpServletRequest.class));
-  }
-}
diff --git a/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/KerberosTest.java b/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/KerberosTest.java
deleted file mode 100644 (file)
index 73f9f73..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.auth.ldap;
-
-import java.io.File;
-import javax.servlet.http.HttpServletRequest;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.sonar.api.config.Configuration;
-import org.sonar.api.config.internal.MapSettings;
-import org.sonar.auth.ldap.server.LdapServer;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.sonar.process.ProcessProperties.Property.SONAR_SECURITY_REALM;
-
-public class KerberosTest {
-
-  static {
-    System.setProperty("java.security.krb5.conf", new File("target/krb5.conf").getAbsolutePath());
-  }
-
-  @ClassRule
-  public static LdapServer server = new LdapServer("/krb.ldif");
-
-  LdapAuthenticator authenticator;
-  LdapRealm ldapRealm;
-
-  @Before
-  public void before() {
-    MapSettings settings = configure();
-    ldapRealm = new LdapRealm(new LdapSettingsManager(settings.asConfig()), settings.asConfig());
-    authenticator = ldapRealm.getAuthenticator();
-  }
-
-  @Test
-  public void test_wrong_password() {
-    LdapAuthenticator.Context wrongPasswordContext = new LdapAuthenticator.Context("Godin@EXAMPLE.ORG", "wrong_user_password", Mockito.mock(HttpServletRequest.class));
-    assertThat(authenticator.doAuthenticate(wrongPasswordContext).isSuccess()).isFalse();
-  }
-
-  @Test
-  public void test_correct_password() {
-
-    LdapAuthenticator.Context correctPasswordContext = new LdapAuthenticator.Context("Godin@EXAMPLE.ORG", "user_password", Mockito.mock(HttpServletRequest.class));
-    assertThat(authenticator.doAuthenticate(correctPasswordContext).isSuccess()).isTrue();
-
-  }
-
-  @Test
-  public void test_default_realm() {
-
-    // Using default realm from krb5.conf:
-    LdapAuthenticator.Context defaultRealmContext = new LdapAuthenticator.Context("Godin", "user_password", Mockito.mock(HttpServletRequest.class));
-    assertThat(authenticator.doAuthenticate(defaultRealmContext).isSuccess()).isTrue();
-  }
-
-  @Test
-  public void test_groups() {
-    LdapGroupsProvider groupsProvider = ldapRealm.getGroupsProvider();
-    LdapGroupsProvider.Context groupsContext = new LdapGroupsProvider.Context("default", "godin", Mockito.mock(HttpServletRequest.class));
-    assertThat(groupsProvider.doGetGroups(groupsContext))
-      .containsOnly("sonar-users");
-  }
-
-  @Test
-  public void wrong_bind_password() {
-    MapSettings settings = configure()
-      .setProperty("ldap.bindPassword", "wrong_bind_password");
-
-    Configuration config = settings.asConfig();
-    LdapSettingsManager settingsManager = new LdapSettingsManager(config);
-    assertThatThrownBy(() -> new LdapRealm(settingsManager, config))
-      .isInstanceOf(LdapException.class)
-      .hasMessage("LDAP realm failed to start: Unable to open LDAP connection");
-
-  }
-
-  private static MapSettings configure() {
-    return new MapSettings()
-      .setProperty("ldap.url", server.getUrl())
-      .setProperty("ldap.authentication", LdapContextFactory.AUTH_METHOD_GSSAPI)
-      .setProperty("ldap.bindDn", "SonarQube@EXAMPLE.ORG")
-      .setProperty("ldap.bindPassword", "bind_password")
-      .setProperty("ldap.user.baseDn", "ou=users,dc=example,dc=org")
-      .setProperty("ldap.group.baseDn", "ou=groups,dc=example,dc=org")
-      .setProperty("ldap.group.request", "(&(objectClass=groupOfUniqueNames)(uniqueMember={dn}))")
-      .setProperty(SONAR_SECURITY_REALM.getKey(), LdapRealm.LDAP_SECURITY_REALM);
-  }
-
-}
diff --git a/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapRealmTest.java b/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapRealmTest.java
deleted file mode 100644 (file)
index 6996f61..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.auth.ldap;
-
-import javax.servlet.http.HttpServletRequest;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.sonar.api.config.Configuration;
-import org.sonar.api.config.internal.MapSettings;
-import org.sonar.auth.ldap.server.LdapServer;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.sonar.process.ProcessProperties.Property.SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE;
-import static org.sonar.process.ProcessProperties.Property.SONAR_SECURITY_REALM;
-
-public class LdapRealmTest {
-
-  @ClassRule
-  public static LdapServer server = new LdapServer("/users.example.org.ldif");
-
-  @Test
-  public void normal() {
-    MapSettings settings = new MapSettings()
-      .setProperty("ldap.url", server.getUrl())
-      .setProperty("ldap.user.baseDn", "cn=users")
-      .setProperty(SONAR_SECURITY_REALM.getKey(), LdapRealm.LDAP_SECURITY_REALM);
-
-    LdapRealm realm = new LdapRealm(new LdapSettingsManager(settings.asConfig()), settings.asConfig());
-    assertThat(realm.getAuthenticator()).isInstanceOf(DefaultLdapAuthenticator.class);
-    assertThat(realm.getUsersProvider()).isInstanceOf(LdapUsersProvider.class).isInstanceOf(DefaultLdapUsersProvider.class);
-    assertThat(realm.getGroupsProvider()).isNull();
-  }
-
-  @Test
-  public void noConnection() {
-    MapSettings settings = new MapSettings()
-      .setProperty("ldap.url", "ldap://no-such-host")
-      .setProperty("ldap.group.baseDn", "cn=groups,dc=example,dc=org")
-      .setProperty("ldap.user.baseDn", "cn=users,dc=example,dc=org")
-      .setProperty(SONAR_SECURITY_REALM.getKey(), LdapRealm.LDAP_SECURITY_REALM);
-    Configuration config = settings.asConfig();
-    LdapSettingsManager settingsManager = new LdapSettingsManager(config);
-    assertThatThrownBy(() -> new LdapRealm(settingsManager, config)).isInstanceOf(LdapException.class)
-      .hasMessage("LDAP realm failed to start: Unable to open LDAP connection");
-  }
-
-  @Test
-  public void noConnection_ignore_ignoreStartupFailure_is_false() {
-    MapSettings settings = new MapSettings()
-      .setProperty("ldap.url", "ldap://no-such-host")
-      .setProperty("ldap.group.baseDn", "cn=groups,dc=example,dc=org")
-      .setProperty("ldap.user.baseDn", "cn=users,dc=example,dc=org")
-      .setProperty(SONAR_SECURITY_REALM.getKey(), LdapRealm.LDAP_SECURITY_REALM)
-      .setProperty(SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE.getKey(), false);
-    ;
-    Configuration config = settings.asConfig();
-    LdapSettingsManager settingsManager = new LdapSettingsManager(config);
-    assertThatThrownBy(() -> new LdapRealm(settingsManager, config)).isInstanceOf(LdapException.class)
-      .hasMessage("LDAP realm failed to start: Unable to open LDAP connection");
-  }
-
-  @Test
-  public void noConnection_ignore_ignoreStartupFailure_is_true() {
-    MapSettings settings = new MapSettings()
-      .setProperty("ldap.url", "ldap://no-such-host")
-      .setProperty("ldap.group.baseDn", "cn=groups,dc=example,dc=org")
-      .setProperty("ldap.user.baseDn", "cn=users,dc=example,dc=org")
-      .setProperty(SONAR_SECURITY_REALM.getKey(), LdapRealm.LDAP_SECURITY_REALM)
-      .setProperty(SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE.getKey(), true);
-
-    LdapRealm realm = new LdapRealm(new LdapSettingsManager(settings.asConfig()), settings.asConfig());
-    verifyRealm(realm);
-  }
-
-  @Test
-  public void should_not_activate_ldap_if_realm_is_not_set() {
-    MapSettings settings = new MapSettings();
-
-    LdapRealm realm = new LdapRealm(new LdapSettingsManager(settings.asConfig()), settings.asConfig());
-    verifyDeactivatedRealm(realm);
-  }
-
-  @Test
-  public void should_not_activate_ldap_if_realm_is_not_ldap() {
-    MapSettings settings = new MapSettings()
-      .setProperty(SONAR_SECURITY_REALM.getKey(), "not_ldap");
-
-    LdapRealm realm = new LdapRealm(new LdapSettingsManager(settings.asConfig()), settings.asConfig());
-    verifyDeactivatedRealm(realm);
-  }
-
-  private static void verifyRealm(LdapRealm realm) {
-    assertThat(realm.getAuthenticator()).isInstanceOf(DefaultLdapAuthenticator.class);
-
-    LdapUsersProvider usersProvider = realm.getUsersProvider();
-    assertThat(usersProvider).isInstanceOf(LdapUsersProvider.class).isInstanceOf(DefaultLdapUsersProvider.class);
-
-    LdapGroupsProvider groupsProvider = realm.getGroupsProvider();
-    assertThat(groupsProvider).isInstanceOf(LdapGroupsProvider.class).isInstanceOf(DefaultLdapGroupsProvider.class);
-
-    LdapUsersProvider.Context userContext = new DefaultLdapUsersProvider.Context("<default>", "tester", Mockito.mock(HttpServletRequest.class));
-    assertThatThrownBy(() -> usersProvider.doGetUserDetails(userContext))
-      .isInstanceOf(LdapException.class)
-      .hasMessage("Unable to retrieve details for user tester and server key <default>: No user mapping found.");
-
-    LdapGroupsProvider.Context groupsContext = new DefaultLdapGroupsProvider.Context("default", "tester", Mockito.mock(HttpServletRequest.class));
-    assertThatThrownBy(() -> groupsProvider.doGetGroups(groupsContext))
-      .isInstanceOf(LdapException.class)
-      .hasMessage("Unable to retrieve groups for user tester in server with key <default>");
-
-    assertThat(realm.isLdapAuthActivated()).isTrue();
-  }
-
-  private static void verifyDeactivatedRealm(LdapRealm realm) {
-    assertThat(realm.getAuthenticator()).isNull();
-    assertThat(realm.getUsersProvider()).isNull();
-    assertThat(realm.getGroupsProvider()).isNull();
-    assertThat(realm.isLdapAuthActivated()).isFalse();
-
-  }
-
-}
diff --git a/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapReferralsTest.java b/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapReferralsTest.java
deleted file mode 100644 (file)
index b836279..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.auth.ldap;
-
-import java.util.Map;
-import javax.annotation.Nullable;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.sonar.api.config.internal.MapSettings;
-import org.sonar.auth.ldap.server.LdapServer;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class LdapReferralsTest {
-
-  @ClassRule
-  public static LdapServer server = new LdapServer("/users.example.org.ldif");
-
-  Map<String, LdapContextFactory> underTest;
-
-  @Test
-  public void referral_is_set_to_follow_when_followReferrals_setting_is_set_to_true() {
-    underTest = createFactories("ldap.followReferrals", "true");
-
-    LdapContextFactory contextFactory = underTest.values().iterator().next();
-    assertThat(contextFactory.getReferral()).isEqualTo("follow");
-  }
-
-  @Test
-  public void referral_is_set_to_ignore_when_followReferrals_setting_is_set_to_false() {
-    underTest = createFactories("ldap.followReferrals", "false");
-
-    LdapContextFactory contextFactory = underTest.values().iterator().next();
-    assertThat(contextFactory.getReferral()).isEqualTo("ignore");
-  }
-
-  @Test
-  public void referral_is_set_to_follow_when_no_followReferrals_setting() {
-    underTest = createFactories(null, null);
-
-    LdapContextFactory contextFactory = underTest.values().iterator().next();
-    assertThat(contextFactory.getReferral()).isEqualTo("follow");
-  }
-
-  private static Map<String, LdapContextFactory> createFactories(@Nullable String propertyKey, @Nullable String propertyValue) {
-    MapSettings settings = LdapSettingsFactory.generateSimpleAnonymousAccessSettings(server, null);
-    if (propertyKey != null) {
-      settings.setProperty(propertyKey, propertyValue);
-    }
-    return new LdapSettingsManager(settings.asConfig()).getContextFactories();
-  }
-}
diff --git a/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapSearchTest.java b/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapSearchTest.java
deleted file mode 100644 (file)
index 87f76af..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.auth.ldap;
-
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Map;
-import javax.naming.NamingException;
-import javax.naming.directory.SearchControls;
-import javax.naming.directory.SearchResult;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.sonar.auth.ldap.server.LdapServer;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-public class LdapSearchTest {
-
-  @ClassRule
-  public static LdapServer server = new LdapServer("/users.example.org.ldif");
-  private static Map<String, LdapContextFactory> contextFactories;
-
-  @BeforeClass
-  public static void init() {
-    contextFactories = new LdapSettingsManager(LdapSettingsFactory.generateSimpleAnonymousAccessSettings(server, null).asConfig()).getContextFactories();
-  }
-
-  @Test
-  public void subtreeSearch() throws Exception {
-    LdapSearch search = new LdapSearch(contextFactories.values().iterator().next())
-      .setBaseDn("dc=example,dc=org")
-      .setRequest("(objectClass={0})")
-      .setParameters("inetOrgPerson")
-      .returns("objectClass");
-
-    assertThat(search.getBaseDn()).isEqualTo("dc=example,dc=org");
-    assertThat(search.getScope()).isEqualTo(SearchControls.SUBTREE_SCOPE);
-    assertThat(search.getRequest()).isEqualTo("(objectClass={0})");
-    assertThat(search.getParameters()).isEqualTo(new String[] {"inetOrgPerson"});
-    assertThat(search.getReturningAttributes()).isEqualTo(new String[] {"objectClass"});
-    assertThat(search).hasToString("LdapSearch{baseDn=dc=example,dc=org, scope=subtree, request=(objectClass={0}), parameters=[inetOrgPerson], attributes=[objectClass]}");
-    assertThat(enumerationToArrayList(search.find()))
-      .extracting(SearchResult::getName)
-      .containsExactlyInAnyOrder(
-        "cn=Without Email,ou=users",
-        "cn=Evgeny Mandrikov,ou=users",
-        "cn=Tester Testerovich,ou=users",
-        "cn=duplicated,ou=users"
-      );
-
-
-    assertThatThrownBy(search::findUnique)
-      .isInstanceOf(NamingException.class)
-      .hasMessage("Non unique result for " + search);
-  }
-
-  @Test
-  public void oneLevelSearch() throws Exception {
-    LdapSearch search = new LdapSearch(contextFactories.values().iterator().next())
-      .setBaseDn("dc=example,dc=org")
-      .setScope(SearchControls.ONELEVEL_SCOPE)
-      .setRequest("(objectClass={0})")
-      .setParameters("inetOrgPerson")
-      .returns("cn");
-
-    assertThat(search.getBaseDn()).isEqualTo("dc=example,dc=org");
-    assertThat(search.getScope()).isEqualTo(SearchControls.ONELEVEL_SCOPE);
-    assertThat(search.getRequest()).isEqualTo("(objectClass={0})");
-    assertThat(search.getParameters()).isEqualTo(new String[] {"inetOrgPerson"});
-    assertThat(search.getReturningAttributes()).isEqualTo(new String[] {"cn"});
-    assertThat(search).hasToString("LdapSearch{baseDn=dc=example,dc=org, scope=onelevel, request=(objectClass={0}), parameters=[inetOrgPerson], attributes=[cn]}");
-    assertThat(enumerationToArrayList(search.find())).isEmpty();
-    assertThat(search.findUnique()).isNull();
-  }
-
-  @Test
-  public void objectSearch() throws Exception {
-    LdapSearch search = new LdapSearch(contextFactories.values().iterator().next())
-      .setBaseDn("cn=bind,ou=users,dc=example,dc=org")
-      .setScope(SearchControls.OBJECT_SCOPE)
-      .setRequest("(objectClass={0})")
-      .setParameters("uidObject")
-      .returns("uid");
-
-    assertThat(search.getBaseDn()).isEqualTo("cn=bind,ou=users,dc=example,dc=org");
-    assertThat(search.getScope()).isEqualTo(SearchControls.OBJECT_SCOPE);
-    assertThat(search.getRequest()).isEqualTo("(objectClass={0})");
-    assertThat(search.getParameters()).isEqualTo(new String[] {"uidObject"});
-    assertThat(search.getReturningAttributes()).isEqualTo(new String[] {"uid"});
-    assertThat(search).hasToString(
-      "LdapSearch{baseDn=cn=bind,ou=users,dc=example,dc=org, scope=object, request=(objectClass={0}), parameters=[uidObject], attributes=[uid]}");
-    assertThat(enumerationToArrayList(search.find())).hasSize(1);
-    assertThat(search.findUnique()).isNotNull();
-  }
-
-  private static <E> ArrayList<E> enumerationToArrayList(Enumeration<E> enumeration) {
-    ArrayList<E> result = new ArrayList<>();
-    while (enumeration.hasMoreElements()) {
-      result.add(enumeration.nextElement());
-    }
-    return result;
-  }
-
-}
diff --git a/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapSettingsFactory.java b/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapSettingsFactory.java
deleted file mode 100644 (file)
index f6718eb..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.auth.ldap;
-
-import javax.annotation.Nullable;
-import org.sonar.api.config.internal.MapSettings;
-import org.sonar.auth.ldap.server.LdapServer;
-
-/**
- * Create Settings for most used test cases.
- */
-public class LdapSettingsFactory {
-
-  /**
-   * Generate simple settings for 2 ldap servers that allows anonymous access.
-   *
-   * @return The specific settings.
-   */
-  public static MapSettings generateSimpleAnonymousAccessSettings(LdapServer exampleServer, @Nullable LdapServer infosupportServer) {
-    MapSettings settings = new MapSettings();
-
-    if (infosupportServer != null) {
-      settings.setProperty("ldap.servers", "example,infosupport");
-
-      settings.setProperty("ldap.example.url", exampleServer.getUrl())
-        .setProperty("ldap.example.user.baseDn", "ou=users,dc=example,dc=org")
-        .setProperty("ldap.example.group.baseDn", "ou=groups,dc=example,dc=org");
-      settings.setProperty("ldap.infosupport.url", infosupportServer.getUrl())
-        .setProperty("ldap.infosupport.user.baseDn", "ou=users,dc=infosupport,dc=com")
-        .setProperty("ldap.infosupport.group.baseDn", "ou=groups,dc=infosupport,dc=com");
-    } else {
-      settings.setProperty("ldap.url", exampleServer.getUrl())
-        .setProperty("ldap.user.baseDn", "ou=users,dc=example,dc=org")
-        .setProperty("ldap.group.baseDn", "ou=groups,dc=example,dc=org");
-    }
-    return settings;
-  }
-
-  /**
-   * Generate settings for 2 ldap servers.
-   *
-   * @param exampleServer     The first ldap server.
-   * @param infosupportServer The second ldap server.
-   * @return The specific settings.
-   */
-  public static MapSettings generateAuthenticationSettings(LdapServer exampleServer, @Nullable LdapServer infosupportServer, String authMethod) {
-    MapSettings settings = new MapSettings();
-
-    if (infosupportServer != null) {
-      settings.setProperty("ldap.servers", "example,infosupport");
-
-      settings.setProperty("ldap.example.url", exampleServer.getUrl())
-        .setProperty("ldap.example.bindDn", LdapContextFactory.AUTH_METHOD_SIMPLE.equals(authMethod) ? "cn=bind,ou=users,dc=example,dc=org" : "bind")
-        .setProperty("ldap.example.bindPassword", "bindpassword")
-        .setProperty("ldap.example.authentication", authMethod)
-        .setProperty("ldap.example.realm", "example.org")
-        .setProperty("ldap.example.user.baseDn", "ou=users,dc=example,dc=org")
-        .setProperty("ldap.example.group.baseDn", "ou=groups,dc=example,dc=org");
-
-      settings.setProperty("ldap.infosupport.url", infosupportServer.getUrl())
-        .setProperty("ldap.infosupport.bindDn", LdapContextFactory.AUTH_METHOD_SIMPLE.equals(authMethod) ? "cn=bind,ou=users,dc=infosupport,dc=com" : "bind")
-        .setProperty("ldap.infosupport.bindPassword", "bindpassword")
-        .setProperty("ldap.infosupport.authentication", authMethod)
-        .setProperty("ldap.infosupport.realm", "infosupport.com")
-        .setProperty("ldap.infosupport.user.baseDn", "ou=users,dc=infosupport,dc=com")
-        .setProperty("ldap.infosupport.group.baseDn", "ou=groups,dc=infosupport,dc=com");
-    } else {
-      settings.setProperty("ldap.url", exampleServer.getUrl())
-        .setProperty("ldap.bindDn", LdapContextFactory.AUTH_METHOD_SIMPLE.equals(authMethod) ? "cn=bind,ou=users,dc=example,dc=org" : "bind")
-        .setProperty("ldap.bindPassword", "bindpassword")
-        .setProperty("ldap.authentication", authMethod)
-        .setProperty("ldap.realm", "example.org")
-        .setProperty("ldap.user.baseDn", "ou=users,dc=example,dc=org")
-        .setProperty("ldap.group.baseDn", "ou=groups,dc=example,dc=org");
-    }
-    return settings;
-  }
-}
diff --git a/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/server/LdapServer.java b/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/server/LdapServer.java
deleted file mode 100644 (file)
index 0f628db..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.auth.ldap.server;
-
-import org.junit.rules.ExternalResource;
-import org.sonar.ldap.ApacheDS;
-
-public class LdapServer extends ExternalResource {
-
-  private ApacheDS server;
-  private String ldif;
-  private final String realm;
-  private final String baseDn;
-
-  public LdapServer(String ldifResourceName) {
-    this(ldifResourceName, "example.org", "dc=example,dc=org");
-  }
-
-  public LdapServer(String ldifResourceName, String realm, String baseDn) {
-    this.ldif = ldifResourceName;
-    this.realm = realm;
-    this.baseDn = baseDn;
-  }
-
-  @Override
-  protected void before() throws Throwable {
-    server = ApacheDS.start(realm, baseDn);
-    server.importLdif(LdapServer.class.getResourceAsStream(ldif));
-  }
-
-  @Override
-  protected void after() {
-    try {
-      server.stop();
-    } catch (Exception e) {
-      throw new IllegalStateException(e);
-    }
-  }
-
-  public String getUrl() {
-    return server.getUrl();
-  }
-
-  public void disableAnonymousAccess() {
-    server.disableAnonymousAccess();
-  }
-
-  public void enableAnonymousAccess() {
-    server.enableAnonymousAccess();
-  }
-
-}
diff --git a/server/sonar-auth-ldap/src/test/resources/conf/krb5.conf b/server/sonar-auth-ldap/src/test/resources/conf/krb5.conf
deleted file mode 100644 (file)
index 04fd9f9..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-[libdefaults]
-       default_realm = EXAMPLE.ORG
-
-[realms]
-       EXAMPLE.ORG = {
-               kdc = localhost:6088
-       }
-       INFOSUPPORT.COM = {
-       kdc = localhost:6089
-     }
-
-[domain_realm]
-       .example.org = EXAMPLE.ORG
-       example.org = EXAMPLE.ORG
-       .infosupport.com = INFOSUPPORT.COM
-       infosupport.com = INFOSUPPORT.COM
-
-[login]
-       krb4_convert = true
-       krb4_get_tickets = false
diff --git a/server/sonar-auth-ldap/src/test/resources/conf/sasl_mech.properties b/server/sonar-auth-ldap/src/test/resources/conf/sasl_mech.properties
deleted file mode 100644 (file)
index f3d209e..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# SonarQube
-# Copyright (C) 2009-2019 SonarSource SA
-# mailto:info AT sonarsource DOT com
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 3 of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-#
-ldap.url:ldap://localhost:1024
-# TODO don't work as expected
-ldap.authentication:DIGEST-MD5 CRAM-MD5
-#ldap.realm: example.org
diff --git a/server/sonar-auth-ldap/src/test/resources/krb.ldif b/server/sonar-auth-ldap/src/test/resources/krb.ldif
deleted file mode 100644 (file)
index 6c8235d..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-dn: dc=example,dc=org
-dc: example
-objectClass: domain
-objectClass: top
-
-dn: ou=Users,dc=example,dc=org
-objectClass: organizationalUnit
-objectClass: top
-ou: Users
-
-dn: uid=krbtgt,ou=Users,dc=example,dc=org
-objectClass: top
-objectClass: person
-objectClass: inetOrgPerson
-objectClass: krb5principal
-objectClass: krb5kdcentry
-cn: KDC Service
-sn: Service
-uid: krbtgt
-userPassword: secret
-krb5PrincipalName: krbtgt/EXAMPLE.ORG@EXAMPLE.ORG
-krb5KeyVersionNumber: 0
-
-dn: cn=SonarQube,ou=Users,dc=example,dc=org
-objectClass: top
-objectClass: organizationalRole
-objectClass: simpleSecurityObject
-objectClass: krb5principal
-objectClass: krb5kdcentry
-cn: SonarQube
-userPassword: bind_password
-krb5PrincipalName: SonarQube@EXAMPLE.ORG
-krb5KeyVersionNumber: 0
-
-dn: uid=godin,ou=Users,dc=example,dc=org
-objectClass: top
-objectClass: person
-objectClass: inetOrgPerson
-objectClass: krb5principal
-objectClass: krb5kdcentry
-cn: Evgeny Mandrikov
-sn: Mandrikov
-uid: godin
-userPassword: user_password
-krb5PrincipalName: Godin@EXAMPLE.ORG
-krb5KeyVersionNumber: 0
-
-dn: ou=Groups,dc=example,dc=org
-objectclass:organizationalunit
-ou: groups
-
-dn: cn=sonar-users,ou=Groups,dc=example,dc=org
-objectclass: groupOfUniqueNames
-cn: sonar-users
-uniqueMember: uid=godin,ou=Users,dc=example,dc=org
diff --git a/server/sonar-auth-ldap/src/test/resources/static-groups.example.org.ldif b/server/sonar-auth-ldap/src/test/resources/static-groups.example.org.ldif
deleted file mode 100644 (file)
index 857efc7..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-dn: dc=example,dc=org
-objectClass: domain
-objectClass: extensibleObject
-objectClass: top
-dc: example
-
-#
-# USERS
-#
-
-dn: ou=users,dc=example,dc=org
-objectClass: organizationalUnit
-objectClass: top
-ou: users
-
-# Bind user
-dn: cn=bind,ou=users,dc=example,dc=org
-objectClass: organizationalRole
-objectClass: simpleSecurityObject
-objectClass: top
-cn: bind
-userpassword: bindpassword
-
-# Typical user
-dn: cn=Evgeny Mandrikov,ou=users,dc=example,dc=org
-objectClass: organizationalPerson
-objectClass: person
-objectClass: extensibleObject
-objectClass: uidObject
-objectClass: inetOrgPerson
-objectClass: top
-cn: Evgeny Mandrikov
-sn: Mandrikov
-givenname: Evgeny
-mail: godin@example.org
-uid: godin
-userpassword: secret1
-
-# Just one more user
-dn: cn=Tester Testerovich,ou=users,dc=example,dc=org
-objectClass: organizationalPerson
-objectClass: person
-objectClass: extensibleObject
-objectClass: uidObject
-objectClass: inetOrgPerson
-objectClass: top
-cn: Tester Testerovich
-givenname: Tester
-sn: Testerovich
-mail: tester@example.org
-uid: tester
-userpassword: secret2
-
-#
-# GROUPS
-#
-
-dn: ou=groups,dc=example,dc=org
-objectclass:organizationalunit
-ou: groups
-
-# sonar-users
-dn: cn=sonar-users,ou=groups,dc=example,dc=org
-objectclass: groupOfUniqueNames
-cn: sonar-users
-uniqueMember: cn=Tester Testerovich,ou=users,dc=example,dc=org
-uniqueMember: cn=Evgeny Mandrikov,ou=users,dc=example,dc=org
-
-# sonar-developers
-dn: cn=sonar-developers,ou=groups,dc=example,dc=org
-objectclass: groupOfUniqueNames
-cn: sonar-developers
-uniqueMember: cn=Evgeny Mandrikov,ou=users,dc=example,dc=org
-
-# linux-users
-dn: cn=linux-users,ou=groups,dc=example,dc=org
-objectclass: posixGroup
-objectclass: top
-cn: linux-users
-gidNumber: 10000
-memberUid: godin
diff --git a/server/sonar-auth-ldap/src/test/resources/users-apacheds.ldif b/server/sonar-auth-ldap/src/test/resources/users-apacheds.ldif
deleted file mode 100644 (file)
index d023151..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-dn: dc=example,dc=org
-objectClass: domain
-objectClass: extensibleObject
-objectClass: top
-dc: example
-
-#
-# USERS
-#
-
-dn: ou=users,dc=example,dc=org
-objectClass: organizationalUnit
-objectClass: top
-ou: users
-
-dn: cn=bind,ou=users,dc=example,dc=org
-objectClass: organizationalRole
-objectClass: uidObject
-objectClass: simpleSecurityObject
-objectClass: top
-cn: bind
-uid: sonar
-userpassword: bindpassword
-
-dn: cn=Evgeny Mandrikov,ou=users,dc=example,dc=org
-objectClass: organizationalPerson
-objectClass: person
-objectClass: extensibleObject
-objectClass: uidObject
-objectClass: inetOrgPerson
-objectClass: top
-objectClass: krb5principal
-objectClass: krb5kdcentry
-cn: Evgeny Mandrikov
-givenname: Evgeny
-mail: godin@example.org
-sn: Mandrikov
-uid: godin
-userpassword: secret1
-krb5PrincipalName: godin@EXAMPLE.ORG
-krb5KeyVersionNumber: 0
-
-dn: cn=Tester Testerovich,ou=users,dc=example,dc=org
-objectClass: organizationalPerson
-objectClass: person
-objectClass: extensibleObject
-objectClass: uidObject
-objectClass: inetOrgPerson
-objectClass: top
-objectClass: krb5principal
-objectClass: krb5kdcentry
-cn: Tester Testerovich
-givenname: Tester
-mail: tester@example.org
-sn: Testerovich
-uid: tester
-userpassword: secret2
-krb5PrincipalName: tester@EXAMPLE.ORG
-krb5KeyVersionNumber: 0
-
-####
-# For Krb5
-####
-dn: uid=krbtgt,ou=users,dc=example,dc=org
-objectClass: person
-objectClass: inetOrgPerson
-objectClass: top
-objectClass: krb5principal
-objectClass: krb5kdcentry
-sn: Service
-cn: KDC Service
-uid: krbtgt
-userPassword: secret
-krb5PrincipalName: krbtgt/EXAMPLE.ORG@EXAMPLE.ORG
-krb5KeyVersionNumber: 0
-
-dn: uid=ldap,ou=users,dc=example,dc=org
-objectClass: person
-objectClass: inetOrgPerson
-objectClass: top
-objectClass: krb5principal
-objectClass: krb5kdcentry
-sn: Service
-cn: LDAP Service
-uid: ldap
-userPassword: randall
-krb5PrincipalName: ldap/localhost@EXAMPLE.COM
-krb5KeyVersionNumber: 0
diff --git a/server/sonar-auth-ldap/src/test/resources/users.example.org.ldif b/server/sonar-auth-ldap/src/test/resources/users.example.org.ldif
deleted file mode 100644 (file)
index fe3341c..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-dn: dc=example,dc=org
-objectClass: domain
-objectClass: extensibleObject
-objectClass: top
-dc: example
-
-#
-# USERS
-#
-
-dn: ou=users,dc=example,dc=org
-objectClass: organizationalUnit
-objectClass: top
-ou: users
-
-# Bind user
-dn: cn=bind,ou=users,dc=example,dc=org
-objectClass: organizationalRole
-objectClass: uidObject
-objectClass: simpleSecurityObject
-objectClass: top
-cn: bind
-uid: sonar
-userpassword: bindpassword
-
-# Duplicated user on infosupport ldap
-dn: cn=duplicated,ou=users,dc=example,dc=org
-objectClass: organizationalPerson
-objectClass: person
-objectClass: extensibleObject
-objectClass: uidObject
-objectClass: inetOrgPerson
-objectClass: top
-cn: duplicated
-uid: duplicated
-sn: Duplicated
-mail: duplicated@example.org
-userpassword: duplicated
-
-# Typical user
-dn: cn=Evgeny Mandrikov,ou=users,dc=example,dc=org
-objectClass: organizationalPerson
-objectClass: person
-objectClass: extensibleObject
-objectClass: uidObject
-objectClass: inetOrgPerson
-objectClass: top
-cn: Evgeny Mandrikov
-givenname: Evgeny
-sn: Mandrikov
-mail: godin@example.org
-uid: godin
-userpassword: secret1
-
-# Just one more user
-dn: cn=Tester Testerovich,ou=users,dc=example,dc=org
-objectClass: organizationalPerson
-objectClass: person
-objectClass: extensibleObject
-objectClass: uidObject
-objectClass: inetOrgPerson
-objectClass: top
-cn: Tester Testerovich
-givenname: Tester
-sn: Testerovich
-mail: tester@example.org
-uid: tester
-userpassword: secret2
-
-# Special case which can cause NPE
-dn: cn=Without Email,ou=users,dc=example,dc=org
-objectClass: organizationalPerson
-objectClass: person
-objectClass: extensibleObject
-objectClass: uidObject
-objectClass: inetOrgPerson
-objectClass: top
-cn: Without Email
-givenname: Without
-sn: Email
-uid: without_email
-userpassword: secret3
-
-
-#
-# GROUPS
-#
-
-dn: ou=groups,dc=example,dc=org
-objectclass:organizationalunit
-ou: groups
-
-# sonar-users
-dn: cn=sonar-users,ou=groups,dc=example,dc=org
-objectclass: groupOfUniqueNames
-cn: sonar-users
-uniqueMember: cn=Tester Testerovich,ou=users,dc=example,dc=org
-uniqueMember: cn=Evgeny Mandrikov,ou=users,dc=example,dc=org
-uniqueMember: cn=duplicated,ou=users,dc=example,dc=org
-
-# sonar-developers
-dn: cn=sonar-developers,ou=groups,dc=example,dc=org
-objectclass: groupOfUniqueNames
-cn: sonar-developers
-uniqueMember: cn=Evgeny Mandrikov,ou=users,dc=example,dc=org
-
-# linux-users
-dn: cn=linux-users,ou=groups,dc=example,dc=org
-objectclass: posixGroup
-objectclass: top
-cn: linux-users
-gidNumber: 10000
-memberUid: godin
diff --git a/server/sonar-auth-ldap/src/test/resources/users.infosupport.com.ldif b/server/sonar-auth-ldap/src/test/resources/users.infosupport.com.ldif
deleted file mode 100644 (file)
index d57addd..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-dn: dc=infosupport,dc=com
-objectClass: domain
-objectClass: extensibleObject
-objectClass: top
-dc: infosupport
-
-#
-# USERS
-#
-
-dn: ou=users,dc=infosupport,dc=com
-objectClass: organizationalUnit
-objectClass: top
-ou: users
-
-# Bind user
-dn: cn=bind,ou=users,dc=infosupport,dc=com
-objectClass: organizationalRole
-objectClass: uidObject
-objectClass: simpleSecurityObject
-objectClass: top
-cn: bind
-uid: sonar
-userpassword: bindpassword
-
-# Duplicated user on example ldap
-dn: cn=duplicated,ou=users,dc=infosupport,dc=com
-objectClass: organizationalPerson
-objectClass: person
-objectClass: extensibleObject
-objectClass: uidObject
-objectClass: inetOrgPerson
-objectClass: top
-cn: duplicated
-uid: duplicated
-sn: Duplicated
-mail: duplicated@infosupport.com
-userpassword: duplicated
-
-# Typical user
-dn: cn=Robby Developer,ou=users,dc=infosupport,dc=com
-objectClass: organizationalPerson
-objectClass: person
-objectClass: extensibleObject
-objectClass: uidObject
-objectClass: inetOrgPerson
-objectClass: top
-cn: Robby Developer
-givenname: Robby
-sn: Developer
-mail: rd@infosupport.com
-uid: robby
-userpassword: secret1
-
-# Just one more user
-dn: cn=Tester Testerovich,ou=users,dc=infosupport,dc=com
-objectClass: organizationalPerson
-objectClass: person
-objectClass: extensibleObject
-objectClass: uidObject
-objectClass: inetOrgPerson
-objectClass: top
-cn: Tester Testerovich
-givenname: Tester
-sn: Testerovich
-mail: tester@infosupport.com
-uid: testerInfo
-userpassword: secret2
-
-# User repeated on multiple servers
-dn: cn=Tester Testerovich Testerov,ou=users,dc=infosupport,dc=com
-objectClass: organizationalPerson
-objectClass: person
-objectClass: extensibleObject
-objectClass: uidObject
-objectClass: inetOrgPerson
-objectClass: top
-cn: Tester Testerovich Testerov
-givenname: Tester
-sn: Testerovich
-mail: tester@example2.org
-uid: tester
-userpassword: secret3
-
-
-# Special case which can cause NPE
-dn: cn=Without Email,ou=users,dc=infosupport,dc=com
-objectClass: organizationalPerson
-objectClass: person
-objectClass: extensibleObject
-objectClass: uidObject
-objectClass: inetOrgPerson
-objectClass: top
-cn: Without Email
-givenname: Without
-sn: Email
-uid: without_email
-userpassword: secret3
-
-
-#
-# GROUPS
-#
-
-dn: ou=groups,dc=infosupport,dc=com
-objectclass:organizationalunit
-ou: groups
-
-# sonar-users
-dn: cn=sonar-users,ou=groups,dc=infosupport,dc=com
-objectclass: groupOfUniqueNames
-cn: sonar-users
-uniqueMember: cn=Robby Developer,ou=users,dc=infosupport,dc=com
-uniqueMember: cn=Tester Testerovich,ou=users,dc=infosupport,dc=com
-
-# sonar-developers
-dn: cn=sonar-developers,ou=groups,dc=infosupport,dc=com
-objectclass: groupOfUniqueNames
-cn: sonar-developers
-uniqueMember: cn=Robby Developer,ou=users,dc=infosupport,dc=com
-uniqueMember: cn=duplicated,ou=users,dc=infosupport,dc=com
-
-# linux-users
-dn: cn=linux-users,ou=groups,dc=infosupport,dc=com
-objectclass: posixGroup
-objectclass: top
-cn: linux-users
-gidNumber: 10000
-memberUid: robby
diff --git a/server/sonar-auth-saml/src/it/java/org/sonar/auth/saml/SamlIdentityProviderIT.java b/server/sonar-auth-saml/src/it/java/org/sonar/auth/saml/SamlIdentityProviderIT.java
new file mode 100644 (file)
index 0000000..f598d9c
--- /dev/null
@@ -0,0 +1,443 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.auth.saml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.io.IOUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.server.authentication.OAuth2IdentityProvider;
+import org.sonar.api.server.authentication.UnauthorizedException;
+import org.sonar.api.server.authentication.UserIdentity;
+import org.sonar.api.utils.System2;
+import org.sonar.api.utils.log.LogAndArguments;
+import org.sonar.api.utils.log.LogTester;
+import org.sonar.db.DbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.sonar.api.utils.log.LoggerLevel.ERROR;
+
+public class SamlIdentityProviderIT {
+  private static final String SQ_CALLBACK_URL = "http://localhost:9000/oauth2/callback/saml";
+
+  /* IDP private key (keep here for future tests with signature)
+-----BEGIN PRIVATE KEY-----MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQC7ecVdi8hh52lHzhpmR2j/fIHlccz5gIUlwOxU7XTMRuUuSd9CyIw9rVd31Sy2enHDo/9LLMgmY72OIw514J5j3xrviM/t3gk9o7qHeX0htYBxh6KNCD3nqeWxUVjcUcMav7s9vxBw4DJXe/z2OIX0MUHzBdL7lR9ivY5+hFFviWLf17MPIN2Xk4uUzXWcSyzbPWYS/6xRSWhNzKuCPfs+yB7CS/LKbq0UZKCRX1lrhJVGEcXJOFjVUWthlIkVOdqlRhpFzuQzHPBf8AAdQMmuZhxpVzkHw4OnjDYDEMmF5DIJV9eM8VpSoEwbZT+th9Ve7Rlrs+f+9SjhRpJOHAIEoN6ELDP7rlMt0D43HIYPGe9j9KSw7IssYKa7y0qRd27SnOeciEFcQa+NQhVLt3pr/yB6D3U2hNZq7eLREX4PD/k30NLOmV3Xls+1vkJ7cGJ7X269++4f16D4PzH+F8Xp/eKXiw+Ugp0785V0zbwtF+YOqapA0+529urPvHLgBG7GToBFrh35pP3Oi+nC/E0ZOvuHWZ2A5S1QJ0hcvdIc2N3B0ADPS4JbO8TFsW741D5Xn5eeTHvWHI8W/34MtUYi7smF1izzTrAqyE7Xc2BrfyKDqC7fuWlWF+lleErLBSKKAbotcB7JZaQyT6+V/0xxl0wEPXp1k/iROy8/6s9WdQIDAQABAoICAC34UAL+MaaAHfqzeRm3TPHIz/k5DG/pqbx2L/0rNMaaY7wT9SDlGC5PgPErXoloQNkeL415b6KqNmLSCcuxxmTq4in2PDYxicaJjUWG7r4DSXmNLriyWquhp2bxcX6ktdirRvh/D0L+VpnJF2Awv/f+1BMJTJDQIiAOJxCy1V0qLQqCU6/T+UIftcxJDRvD+z3PMmZaNyC/hUn+c9e95wuf+preEKy+ssYbXpwG62BH5GqIFR2gKXg1PMVyrKJ9yzVXmT2g26gE4pRDv2Ns7YdMFo9mCd/zeybsZJof1ap1KCfOWFaBIAq+r6rQCus8MX/TV7ZnKO4Fo36J1Xo9t+iKGpvw2nwrN7I71MT3c8wglfg2zmgFqjNYdeUDFOrl0GXRboBcDSX4dd5iB9fkqZ9dOqTtTzPQNwEhbDqLyYQ6I+00nihW8xzEUaiqd4tey7WXoqae3u0Bo7ep5jbE7dzKWxiBKaqlfI+S4aWDkhUiwkUKvkSC3SXWWehJbaVQZb5+DvSjWU5nLQxcVZdMl9Lp7kE0+nEeS1hO8C1r482jlXKppl9k0GjkoIRzU9RARxHNt1UvHURa43CQ/4nIGNsK9WeYVxk2vR/qozCE6dKIRv+5gZrD32YM2UrPf8kAAQOSpW4iumtWuqkrysr3/04f40mCtLV1uNF6EQcV+WfJAoIBAQC+A4JoY7gMrEf0EmRVhNbAuRkt67ENz8PBr8NvDlgIVM9ZdjeVFYSKWeL+TbkwihBoSqhn5wgAs5RhiNGjwqgL+odHVY/9KirQDvcdsy8/NaheYd+JJLAyCOLJKAc/C7VaZ5fFpHWOKRkUPVOliK955+3cxLp37q1+10p4406i6JIWphzqNt8rCpEQgXydIfEgDY8IDoEs65+9JcutFkH2MtQR1ypH0uLPvNCVZu8SNitmcvERq2/mJ4U1+8rIhAJhbq9uvaSXBSKFSzK62hdxvOLvMIlKFcEia8xTBCO9MbLxIbSH2Ht69HSCmZSytaHBodOb7qBcLjOQD5ZXMPGjAoIBAQD8lKBHrYUT8Cd39B5IkdeU6tVbiJ80Lb2E2ePLbg3/Dx9NsmzXrvLeHI60+gpxP+GlI/h2IzUvLsOuEf5ICjmu9NrnK2lJJmS/pCZlKxEV0k1T0fyITMyjk0iy9Vb70+PF3CDextnEY3zzhkHj7iaXqXIf1zs2ypm3zTGsGLdLXT+5Fm2sxdhLUKGIwfflaUruyLTyE/OiArDrezqgX7CVlF4Q2zgQZqRHDODxt09fJbz0FU422y02Hv/sG5cYFB5C24upwe3dIXrFyM9xuZnTUpM8z8DLPeLShKUUqsiL/qyhxLbXgdGkXsDaPrX31eTX99gG3AX9WoxENLQzvgkHAoIBABkSzXqI7hh+A2CprKO8S7pSsofkuhBggixkzR0yf1taFaJwfxUlKcA37EQybWWCUnfwohhT3DJ7f/D+5Or/HL236XH4UG/PyKZ70xAQPQPSSM1rjNvEA5wWoBZ7ObmQCfZMBTMHaJvBwJVzIj6NstobSMABFboNvMcoEaOyGwZUOjLS6K3fX8OGOW48J/10JSVdpKojf9g1n3aOLjpA3aNnQaS5B9NCeLuA5uVQF+wHSeLS+Ayk2rc8L8/X0gJzqPzCZlPuonFrNAryyVbuwHk5u5hkhzlHdZzdLLEnsq+ch0hackAayPCIoXc6XOzYGug6OnoxGugPEK7J38TRqJECggEAdXZxK6RotSMEV+axhrI8fcbQPmdFErEK6BOkumCOJcXUmv+VWqDD1cOWIlf+Lzi0KWaXD+nDvBOVcQhxJvOKa/D3NHad2iT+yZj/OiFTKsDIsWiAdqqwqInAT2mFcEvUK5n5t2DmuUxDOcWAMw336KQmrOQdZ5fE8RN+PDiqVWQiVGM30heYRT5UQRNjw865yF6St9nLfdaejISceSTHLGj5bgFlC0uQrnIw0nibcvZL739RBnXbisXT4uvZ0prYj+MmCmZjxmjhfcWro4nbHcnTK366fEplh92kH/5kkaZ4hirDlWmMI1LlgRmU6pMQf9eFIXuFVZOck8Om4kFIVQKCAQARCxrge8m+hOTJ7EkNtxor+o+4XioZSQ+Ht9lNOL+Ry1J08fldWwM8P4cpVE7WHi+73UM7NlJDLRaCCgS13C7FoW1klK1Rt3VtJRUF4Ic6B8RcLZQrOAp4sfbCLeT/PomexJ6KURdXof3GaTdij3F149NsNoje1VPEBLq5GE9j8vbPI/pyhJxfXzWtKXUGkNG9fC0oH7NjWqTDVoBiyUbZurCY8KN5oIh40UwJnUqvgu6gaUItfStmJn78VgsFZLTJvPcfnir+q9mOVp8WBYE3jrPYEhWtEP2MaG+nAGBi7AuRZ0tCsOL+s8ADNyzOx9WtFQcXryn6b7+BjIEbSrjg-----END PRIVATE KEY-----
+   */
+
+  private static final String IDP_CERTIFICATE = "-----BEGIN CERTIFICATE-----MIIF5zCCA8+gAwIBAgIUIXv9OVs/XUicgR1bsV9uccYhHfowDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYTAkFVMQ8wDQYDVQQIDAZHRU5FVkExEDAOBgNVBAcMB1ZFUk5JRVIxDjAMBgNVBAoMBVNPTkFSMQ0wCwYDVQQLDARRVUJFMQ8wDQYDVQQDDAZaaXBlbmcxIDAeBgkqhkiG9w0BCQEWEW5vcmVwbHlAZ21haWwuY29tMB4XDTIyMDYxMzEzMTQyN1oXDTMyMDYxMDEzMTQyN1owgYIxCzAJBgNVBAYTAkFVMQ8wDQYDVQQIDAZHRU5FVkExEDAOBgNVBAcMB1ZFUk5JRVIxDjAMBgNVBAoMBVNPTkFSMQ0wCwYDVQQLDARRVUJFMQ8wDQYDVQQDDAZaaXBlbmcxIDAeBgkqhkiG9w0BCQEWEW5vcmVwbHlAZ21haWwuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAu3nFXYvIYedpR84aZkdo/3yB5XHM+YCFJcDsVO10zEblLknfQsiMPa1Xd9Ustnpxw6P/SyzIJmO9jiMOdeCeY98a74jP7d4JPaO6h3l9IbWAcYeijQg956nlsVFY3FHDGr+7Pb8QcOAyV3v89jiF9DFB8wXS+5UfYr2OfoRRb4li39ezDyDdl5OLlM11nEss2z1mEv+sUUloTcyrgj37Psgewkvyym6tFGSgkV9Za4SVRhHFyThY1VFrYZSJFTnapUYaRc7kMxzwX/AAHUDJrmYcaVc5B8ODp4w2AxDJheQyCVfXjPFaUqBMG2U/rYfVXu0Za7Pn/vUo4UaSThwCBKDehCwz+65TLdA+NxyGDxnvY/SksOyLLGCmu8tKkXdu0pznnIhBXEGvjUIVS7d6a/8geg91NoTWau3i0RF+Dw/5N9DSzpld15bPtb5Ce3Bie19uvfvuH9eg+D8x/hfF6f3il4sPlIKdO/OVdM28LRfmDqmqQNPudvbqz7xy4ARuxk6ARa4d+aT9zovpwvxNGTr7h1mdgOUtUCdIXL3SHNjdwdAAz0uCWzvExbFu+NQ+V5+Xnkx71hyPFv9+DLVGIu7JhdYs806wKshO13Nga38ig6gu37lpVhfpZXhKywUiigG6LXAeyWWkMk+vlf9McZdMBD16dZP4kTsvP+rPVnUCAwEAAaNTMFEwHQYDVR0OBBYEFI5UVLtTySvbGqH7UP8xTL4wxZq3MB8GA1UdIwQYMBaAFI5UVLtTySvbGqH7UP8xTL4wxZq3MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBABAtXsKNWx0sDDFA53qZ1zRyWKWAMoh95pawFCrKgTEW4ZrA73pa790eE1Y+vT6qUXKI4li9skIDa+6psCdxhZIrHPRAnVZVeB2373Bxr5bw/XQ8elRCjWeMULbYJ9tgsLV0I9CiEP0a6Tm8t0yDVXNUfx36E5fkgLSrxoRo8XJzxHbJCnLVXHdaNBxOT7jVcom6Wo4PB2bsjVzhHm6amn5hZp4dMHm0Mv0ln1wH8jVnizHQBLsGMzvvl58+9s1pP17ceRDkpNDz+EQyA+ZArqkW1MqtwVhbzz8QgMprhflKkArrsC7v06Jv8fqUbn9LvtYK9IwHTX7J8dFcsO/gUC5PevYT3nriN3Azb20ggSQ1yOEMozvj5T96S6itfHPit7vyEQ84JPrEqfuQDZQ/LKZQqfvuXX1aAG3TU3TMWB9VMMFsTuMFS8bfrhMX77g0Ud4qJcBOYOH3hR59agSdd2QZNLP3zZsYQHLLQkq94jdTXKTqm/w7mlPFKV59HjTbHBhTtxBHMft/mvvLEuC9KKFfAOXYQ6V+s9Nk0BW4ggEfewaX58OBuy7ISqRtRFPGia18YRzzHqkhjubJYMPkIfYpFVd+C0II3F0kdy8TtpccjyKo9bcHMLxO4n8PDAl195CPthMi8gUvT008LGEotr+3kXsouTEZTT0glXKLdO2W-----END CERTIFICATE-----";
+
+  private static final String SP_CERTIFICATE = "MIICoTCCAYkCBgGBXPscaDANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAlzb25hcnF1YmUwHhcNMjIwNjEzMTIxMTA5WhcNMzIwNjEzMTIxMjQ5WjAUMRIwEAYDVQQDDAlzb25hcnF1YmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDSFoT371C0/klZuPgvKbGItkmTaf5CweNXL8u389d98aOXRpDQ7maTXdV/W+VcL8vUWg8yG6nn8CRwweYnGTNdn9UAdhgknvxQe3pq3EwOJyls4Fpiq6YTh+DQfiZUQizjFjDOr/GG5O2lNvTRkI4XZj/XnWjRqVZwttiA5tm1sKkvGdyOQljwn4Jja/VbITdV8GASumx66Bil/wamSsqIzm2RjsOOGSsf5VjYUPwDobpuSf+j4DLtWjem/9vIzI2wcE30uC8LBAgO3JAlIS9NQrchjS9xhMJRohOoitaSPmqsOy7D2BH0h7XX6TNgv/WYTkBY4eZPao3PsL2A6AmhAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAMBmTHUK4w+DX21tmhqdwq0WqLH5ZAkwtiocDxFXiJ4GRrUWUh3BaXsgOHB8YYnNTDfScjaU0sZMEyfC0su1zsN8B7NFckg7RcZCHuBYdgIEAmvK4YM6s6zNsiKKwt66p2MNeL+o0acrT2rYjQ1L5QDj0gpfJQAT4N7xTZfuSc2iwjotaQfvcgsO8EZlcDVrL4UuyWLbuRUlSQjxHWGYaxCW+I3enK1+8fGpF3O+k9ZQ8xt5nJsalpsZvHcPLA4IBOmjsSHqSkhg4EIAWL/sJZ1KNct4hHh5kToUTu+Q6e949VeBkWgj4O+rcGDgiN2frGiEEc0EMv8KCSENRRRrO2k=";
+  private static final String SP_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDSFoT371C0/klZuPgvKbGItkmTaf5CweNXL8u389d98aOXRpDQ7maTXdV/W+VcL8vUWg8yG6nn8CRwweYnGTNdn9UAdhgknvxQe3pq3EwOJyls4Fpiq6YTh+DQfiZUQizjFjDOr/GG5O2lNvTRkI4XZj/XnWjRqVZwttiA5tm1sKkvGdyOQljwn4Jja/VbITdV8GASumx66Bil/wamSsqIzm2RjsOOGSsf5VjYUPwDobpuSf+j4DLtWjem/9vIzI2wcE30uC8LBAgO3JAlIS9NQrchjS9xhMJRohOoitaSPmqsOy7D2BH0h7XX6TNgv/WYTkBY4eZPao3PsL2A6AmhAgMBAAECggEBAJj11HJAR96/leBBkFGmZaBIOGGgNoOcb023evfADhGgsZ8evamhKgX5t8w2uFPaaOl/eLje82Hvslh2lH+7FW8BRDBFy2Y+ay6d+I99PdLAKKUg5C4bE5v8vm6OqpGGbPAZ5AdYit3QKEa2MKG0QgA/bhQqg3rDdDA0sIWJjtF9MLv7LI7Tm0qgiHOKsI0MEBFk+ZoibgKWYh/dnfGDRWyC3Puqe13rdSheNJYUDR/0QMkd/EJNpLWv06uk+w8w2lU4RgN6TiV76ZZUIGZAAHFgMELJysgtBTCkOQY5roPu17OmMZjKfxngeIfNyd42q3/T6DmUbbwNYfP2HRMoiMECgYEA6SVc1mZ4ykytC9M61rZwT+2zXtJKudQVa0qpTtkf0aznRmnDOuc1bL7ewKIIIp9r5HKVteO6SKgpHmrP+qmvbwZ0Pz51Zg0MetoSmT9m0599/tOU2k6OI09dvQ4Xa3ccN5Czl61Q/HkMeAIDny8MrhGVBwhallE4J4fm/OjuVK0CgYEA5q6IVgqZtfcV1azIF6uOFt6blfn142zrwq0fF39jog2f+4jXaBKw6L4aP0HvIL83UArGppYY31894bLb6YL4EjS2JNbABM2VnJpJd4oGopOE42GCZlZRpf751zOptYAN23NFSujLlfaUfMbyrqIbRFC2DCdzNTU50GT5SAXX80UCgYEAlyvQvHwJCjMZaTd3SU1WGZ1o1qzIIyHvGXh5u1Rxm0TfWPquyfys2WwRhxoI6FoyXRgnFp8oZIAU2VIstL1dsUGgEnnvKVKAqw/HS3Keu80IpziNpdeVtjN59mGysc2zkBvVNx38Cxh6Cz5TFt4s/JkN5ld2VU0oeglWrtph3qkCgYALszZ/BrKdJBcba1QKv0zJpCjIBpGOI2whx54YFwH6qi4/F8W1JZ2LcHjsVG/IfWpUyPciY+KHEdGVrPiyc04Zvkquu6WpmLPJ6ZloUrvbaxgGYF+4yRADF1ecrqYg6onJY6NUFVKeHI+TdJPCf75aTK2vGCEjxbtU8ooiOQmm8QKBgEGe9ZdrwTP9rMQ35jYtzU+dT06k1r9BE9Q8CmrXl0HwK717ZWboX4J0YoFjxZC8PDsMl3p46MJ83rKbLU728uKig1AkZo7/OedxTWvezjZ1+lDyjC2EguXbgY1ecSC2HbJh9g+v8RUuhWxuA7RYoW92xVtKj+6l4vMadVP4Myp8-----END PRIVATE KEY-----";
+
+  @Rule
+  public DbTester db = DbTester.create();
+  @Rule
+  public LogTester log = new LogTester();
+
+  private final MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, SamlSettings.definitions()));
+  private final SamlIdentityProvider underTest = new SamlIdentityProvider(new SamlSettings(settings.asConfig()), new SamlMessageIdChecker(db.getDbClient()));
+  private HttpServletResponse response = mock(HttpServletResponse.class);
+  private HttpServletRequest request = mock(HttpServletRequest.class);
+
+  @Before
+  public void setup() {
+    this.request = mock(HttpServletRequest.class);
+    this.response = mock(HttpServletResponse.class);
+    when(this.request.getRequestURL()).thenReturn(new StringBuffer(SQ_CALLBACK_URL));
+  }
+
+  @Test
+  public void check_fields() {
+    setSettings(true);
+    assertThat(underTest.getKey()).isEqualTo("saml");
+    assertThat(underTest.getName()).isEqualTo("SAML");
+    assertThat(underTest.getDisplay().getIconPath()).isEqualTo("/images/saml.png");
+    assertThat(underTest.getDisplay().getBackgroundColor()).isEqualTo("#444444");
+    assertThat(underTest.allowsUsersToSignUp()).isTrue();
+  }
+
+  @Test
+  public void provider_name_is_provided_by_setting() {
+    // Default value
+    assertThat(underTest.getName()).isEqualTo("SAML");
+
+    settings.setProperty("sonar.auth.saml.providerName", "My Provider");
+    assertThat(underTest.getName()).isEqualTo("My Provider");
+  }
+
+  @Test
+  public void is_enabled() {
+    setSettings(true);
+    assertThat(underTest.isEnabled()).isTrue();
+
+    setSettings(false);
+    assertThat(underTest.isEnabled()).isFalse();
+  }
+
+  @Test
+  public void init() throws IOException {
+    setSettings(true);
+    DumbInitContext context = new DumbInitContext();
+
+    underTest.init(context);
+
+    verify(context.response).sendRedirect(anyString());
+    assertThat(context.generateCsrfState.get()).isTrue();
+  }
+
+  @Test
+  public void fail_to_init_when_login_url_is_invalid() {
+    setSettings(true);
+    settings.setProperty("sonar.auth.saml.loginUrl", "invalid");
+    DumbInitContext context = new DumbInitContext();
+
+    assertThatThrownBy(() -> underTest.init(context))
+      .isInstanceOf(IllegalStateException.class)
+      .hasMessage("Failed to create a SAML Auth");
+  }
+
+  @Test
+  public void callback() {
+    setSettings(true);
+    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_full_response.txt", SQ_CALLBACK_URL);
+
+    underTest.callback(callbackContext);
+
+    assertThat(callbackContext.redirectedToRequestedPage.get()).isTrue();
+    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
+    assertThat(callbackContext.verifyState.get()).isTrue();
+  }
+
+  @Test
+  public void failed_callback_when_behind_a_reverse_proxy_without_needed_header() {
+    setSettings(true);
+    // simulate reverse proxy stripping SSL and not adding X-Forwarded-Proto header
+    when(this.request.getRequestURL()).thenReturn(new StringBuffer("http://localhost/oauth2/callback/saml"));
+    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_full_response_with_reverse_proxy.txt",
+      "https://localhost/oauth2/callback/saml");
+
+    assertThatThrownBy(() -> underTest.callback(callbackContext))
+      .isInstanceOf(UnauthorizedException.class)
+      .hasMessageContaining("The response was received at http://localhost/oauth2/callback/saml instead of https://localhost/oauth2/callback/saml");
+  }
+
+  @Test
+  public void successful_callback_when_behind_a_reverse_proxy_with_needed_header() {
+    setSettings(true);
+    // simulate reverse proxy stripping SSL and adding X-Forwarded-Proto header
+    when(this.request.getRequestURL()).thenReturn(new StringBuffer("http://localhost/oauth2/callback/saml"));
+    when(this.request.getHeader("X-Forwarded-Proto")).thenReturn("https");
+    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_full_response_with_reverse_proxy.txt",
+      "https://localhost/oauth2/callback/saml");
+
+    underTest.callback(callbackContext);
+
+    assertThat(callbackContext.redirectedToRequestedPage.get()).isTrue();
+    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
+    assertThat(callbackContext.verifyState.get()).isTrue();
+  }
+
+  @Test
+  public void callback_on_full_response() {
+    setSettings(true);
+    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_full_response.txt", SQ_CALLBACK_URL);
+
+    underTest.callback(callbackContext);
+
+    assertThat(callbackContext.userIdentity.getName()).isEqualTo("John Doe");
+    assertThat(callbackContext.userIdentity.getEmail()).isEqualTo("johndoe@email.com");
+    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
+    assertThat(callbackContext.userIdentity.getGroups()).containsExactlyInAnyOrder("developer", "product-manager");
+  }
+
+  @Test
+  public void callback_on_encrypted_response() {
+    setSettings(true);
+    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_encrypted_response.txt", SQ_CALLBACK_URL);
+
+    underTest.callback(callbackContext);
+
+    assertThat(callbackContext.userIdentity.getName()).isEqualTo("John Doe");
+    assertThat(callbackContext.userIdentity.getEmail()).isEqualTo("johndoe@email.com");
+    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
+    assertThat(callbackContext.userIdentity.getGroups()).containsExactlyInAnyOrder("developer", "product-manager");
+  }
+
+  @Test
+  public void callback_on_signed_request() throws IOException {
+    setSettings(true);
+    settings.setProperty("sonar.auth.saml.signature.enabled", true);
+    DumbInitContext context = new DumbInitContext();
+
+    underTest.init(context);
+
+    String[] samlRequestParams = {"http://localhost:8080/auth/realms/sonarqube/protocol/saml",
+      "?SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256", "&SAMLRequest=", "&Signature="};
+    verify(context.response).sendRedirect(argThat(x -> Arrays.stream(samlRequestParams).allMatch(x::contains)));
+  }
+
+  @Test
+  public void callback_on_minimal_response() {
+    setSettings(true);
+    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_minimal_response.txt", SQ_CALLBACK_URL);
+
+    underTest.callback(callbackContext);
+
+    assertThat(callbackContext.userIdentity.getName()).isEqualTo("John Doe");
+    assertThat(callbackContext.userIdentity.getEmail()).isNull();
+    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
+    assertThat(callbackContext.userIdentity.getGroups()).isEmpty();
+  }
+
+  @Test
+  public void log_clear_error_when_private_key_is_not_pkcs8() {
+    var WRONG_FORMAT_PRIVATE_KEY = "MIIEpAIBAAKCAQEA0haE9+9QtP5JWbj4LymxiLZJk2n+QsHjVy/Lt/PXffGjl0aQ0O5mk13Vf1vlXC/L1FoPMhup5/AkcMHmJxkzXZ/VAHYYJJ78UHt6atxMDicpbOBaYqumE4fg0H4mVEIs4xYwzq/xhuTtpTb00ZCOF2Y/151o0alWcLbYgObZtbCpLxncjkJY8J+CY2v1WyE3VfBgErpseugYpf8GpkrKiM5tkY7DjhkrH+VY2FD8A6G6bkn/o+Ay7Vo3pv/byMyNsHBN9LgvCwQIDtyQJSEvTUK3IY0vcYTCUaITqIrWkj5qrDsuw9gR9Ie11+kzYL/1mE5AWOHmT2qNz7C9gOgJoQIDAQABAoIBAQCY9dRyQEfev5XgQZBRpmWgSDhhoDaDnG9Nt3r3wA4RoLGfHr2poSoF+bfMNrhT2mjpf3i43vNh77JYdpR/uxVvAUQwRctmPmsunfiPfT3SwCilIOQuGxOb/L5ujqqRhmzwGeQHWIrd0ChGtjChtEIAP24UKoN6w3QwNLCFiY7RfTC7+yyO05tKoIhzirCNDBARZPmaIm4ClmIf3Z3xg0Vsgtz7qntd63UoXjSWFA0f9EDJHfxCTaS1r9OrpPsPMNpVOEYDek4le+mWVCBmQABxYDBCycrILQUwpDkGOa6D7tezpjGYyn8Z4HiHzcneNqt/0+g5lG28DWHz9h0TKIjBAoGBAOklXNZmeMpMrQvTOta2cE/ts17SSrnUFWtKqU7ZH9Gs50ZpwzrnNWy+3sCiCCKfa+RylbXjukioKR5qz/qpr28GdD8+dWYNDHraEpk/ZtOfff7TlNpOjiNPXb0OF2t3HDeQs5etUPx5DHgCA58vDK4RlQcIWpZROCeH5vzo7lStAoGBAOauiFYKmbX3FdWsyBerjhbem5X59eNs68KtHxd/Y6INn/uI12gSsOi+Gj9B7yC/N1AKxqaWGN9fPeGy2+mC+BI0tiTWwATNlZyaSXeKBqKThONhgmZWUaX++dczqbWADdtzRUroy5X2lHzG8q6iG0RQtgwnczU1OdBk+UgF1/NFAoGBAJcr0Lx8CQozGWk3d0lNVhmdaNasyCMh7xl4ebtUcZtE31j6rsn8rNlsEYcaCOhaMl0YJxafKGSAFNlSLLS9XbFBoBJ57ylSgKsPx0tynrvNCKc4jaXXlbYzefZhsrHNs5Ab1Tcd/AsYegs+UxbeLPyZDeZXdlVNKHoJVq7aYd6pAoGAC7M2fwaynSQXG2tUCr9MyaQoyAaRjiNsIceeGBcB+qouPxfFtSWdi3B47FRvyH1qVMj3ImPihxHRlaz4snNOGb5KrrulqZizyemZaFK722sYBmBfuMkQAxdXnK6mIOqJyWOjVBVSnhyPk3STwn++WkytrxghI8W7VPKKIjkJpvECgYBBnvWXa8Ez/azEN+Y2Lc1PnU9OpNa/QRPUPApq15dB8Cu9e2Vm6F+CdGKBY8WQvDw7DJd6eOjCfN6ymy1O9vLiooNQJGaO/znncU1r3s42dfpQ8owthILl24GNXnEgth2yYfYPr/EVLoVsbgO0WKFvdsVbSo/upeLzGnVT+DMqfA==";
+    setSettings(true);
+    settings.setProperty("sonar.auth.saml.sp.privateKey.secured", WRONG_FORMAT_PRIVATE_KEY);
+    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_minimal_response.txt", SQ_CALLBACK_URL);
+
+    underTest.callback(callbackContext);
+
+    assertThat(log.getLogs(ERROR))
+      .extracting(LogAndArguments::getFormattedMsg)
+      .contains("Error in parsing service provider private key, please make sure that it is in PKCS 8 format.");
+  }
+
+  @Test
+  public void callback_does_not_sync_group_when_group_setting_is_not_set() {
+    setSettings(true);
+    settings.setProperty("sonar.auth.saml.group.name", (String) null);
+    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_full_response.txt", SQ_CALLBACK_URL);
+
+    underTest.callback(callbackContext);
+
+    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
+    assertThat(callbackContext.userIdentity.getGroups()).isEmpty();
+    assertThat(callbackContext.userIdentity.shouldSyncGroups()).isFalse();
+  }
+
+  @Test
+  public void fail_to_callback_when_login_is_missing() {
+    setSettings(true);
+    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_response_without_login.txt", SQ_CALLBACK_URL);
+
+    assertThatThrownBy(() -> underTest.callback(callbackContext))
+      .isInstanceOf(NullPointerException.class)
+      .hasMessage("login is missing");
+
+  }
+
+  @Test
+  public void fail_to_callback_when_name_is_missing() {
+    setSettings(true);
+    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_response_without_name.txt", SQ_CALLBACK_URL);
+
+    assertThatThrownBy(() -> underTest.callback(callbackContext))
+      .isInstanceOf(NullPointerException.class)
+      .hasMessage("name is missing");
+  }
+
+  @Test
+  public void fail_to_callback_when_certificate_is_invalid() {
+    setSettings(true);
+    settings.setProperty("sonar.auth.saml.certificate.secured", "invalid");
+    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_full_response.txt", SQ_CALLBACK_URL);
+
+    assertThatThrownBy(() -> underTest.callback(callbackContext))
+      .isInstanceOf(IllegalStateException.class)
+      .hasMessage("Failed to create a SAML Auth");
+  }
+
+  @Test
+  public void fail_to_callback_when_using_wrong_certificate() {
+    setSettings(true);
+    settings.setProperty("sonar.auth.saml.certificate.secured", "-----BEGIN CERTIFICATE-----\n" +
+      "MIIEIzCCAwugAwIBAgIUHUzPjy5E2TmnsmTRT2sIUBRXFF8wDQYJKoZIhvcNAQEF\n" +
+      "BQAwXDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC1NvbmFyU291cmNlMRUwEwYDVQQL\n" +
+      "DAxPbmVMb2dpbiBJZFAxIDAeBgNVBAMMF09uZUxvZ2luIEFjY291bnQgMTMxMTkx\n" +
+      "MB4XDTE4MDcxOTA4NDUwNVoXDTIzMDcxOTA4NDUwNVowXDELMAkGA1UEBhMCVVMx\n" +
+      "FDASBgNVBAoMC1NvbmFyU291cmNlMRUwEwYDVQQLDAxPbmVMb2dpbiBJZFAxIDAe\n" +
+      "BgNVBAMMF09uZUxvZ2luIEFjY291bnQgMTMxMTkxMIIBIjANBgkqhkiG9w0BAQEF\n" +
+      "AAOCAQ8AMIIBCgKCAQEArlpKHm4EkJiQyy+4GtZBixcy7fWnreB96T7cOoWLmWkK\n" +
+      "05FM5M/boWHZsvaNAuHsoCAMzIY3/l+55WbORzAxsloH7rvDaDrdPYQN+sU9bzsD\n" +
+      "ZkmDGDmA3QBSm/h/p5SiMkWU5Jg34toDdM0rmzUStIOMq6Gh/Ykx3fRRSjswy48x\n" +
+      "wfZLy+0wU7lasHqdfk54dVbb7mCm9J3iHZizvOt2lbtzGbP6vrrjpzvZm43ZRgP8\n" +
+      "FapYA8G3lczdIaG4IaLW6kYIRORd0UwI7IAwkao3uIo12rh1T6DLVyzjOs9PdIkb\n" +
+      "HbICN2EehB/ut3wohuPwmwp2UmqopIMVVaBSsmSlYwIDAQABo4HcMIHZMAwGA1Ud\n" +
+      "EwEB/wQCMAAwHQYDVR0OBBYEFAXGFMKYgtpzCpfpBUPQ1H/9AeDrMIGZBgNVHSME\n" +
+      "gZEwgY6AFAXGFMKYgtpzCpfpBUPQ1H/9AeDroWCkXjBcMQswCQYDVQQGEwJVUzEU\n" +
+      "MBIGA1UECgwLU29uYXJTb3VyY2UxFTATBgNVBAsMDE9uZUxvZ2luIElkUDEgMB4G\n" +
+      "A1UEAwwXT25lTG9naW4gQWNjb3VudCAxMzExOTGCFB1Mz48uRNk5p7Jk0U9rCFAU\n" +
+      "VxRfMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQUFAAOCAQEAPHgi9IdDaTxD\n" +
+      "R5R8KHMdt385Uq8XC5pd0Li6y5RR2k6SKjThCt+eQU7D0Y2CyYU27vfCa2DQV4hJ\n" +
+      "4v4UfQv3NR/fYfkVSsNpxjBXBI3YWouxt2yg7uwdZBdgGYd37Yv3g9PdIZenjOhr\n" +
+      "Ck6WjdleMAWHRgJpocmB4IOESSyTfUul3jFupWnkbnn8c0ue6zwXd7LA1/yjVT2l\n" +
+      "Yh45+lz25aIOlyyo7OUw2TD15LIl8OOIuWRS4+UWy5+VdhXMbmpSEQH+Byod90g6\n" +
+      "A1bKpOFhRBzcxaZ6B2hB4SqjTBzS9zdmJyyFs/WNJxHri3aorcdqG9oUakjJJqqX\n" +
+      "E13skIMV2g==\n" +
+      "-----END CERTIFICATE-----\n");
+    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_full_response.txt", SQ_CALLBACK_URL);
+
+    assertThatThrownBy(() -> underTest.callback(callbackContext))
+      .isInstanceOf(UnauthorizedException.class)
+      .hasMessage("Signature validation failed. SAML Response rejected");
+  }
+
+  @Test
+  public void fail_callback_when_message_was_already_sent() {
+    setSettings(true);
+    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_minimal_response.txt", SQ_CALLBACK_URL);
+
+    underTest.callback(callbackContext);
+
+    assertThatThrownBy(() -> underTest.callback(callbackContext))
+      .isInstanceOf(IllegalArgumentException.class)
+      .hasMessage("This message has already been processed");
+  }
+
+  private void setSettings(boolean enabled) {
+    if (enabled) {
+      settings.setProperty("sonar.auth.saml.applicationId", "MyApp");
+      settings.setProperty("sonar.auth.saml.providerId", "http://localhost:8080/auth/realms/sonarqube");
+      settings.setProperty("sonar.auth.saml.loginUrl", "http://localhost:8080/auth/realms/sonarqube/protocol/saml");
+      settings.setProperty("sonar.auth.saml.certificate.secured", IDP_CERTIFICATE);
+      settings.setProperty("sonar.auth.saml.sp.privateKey.secured", SP_PRIVATE_KEY);
+      settings.setProperty("sonar.auth.saml.sp.certificate.secured", SP_CERTIFICATE);
+      settings.setProperty("sonar.auth.saml.user.login", "login");
+      settings.setProperty("sonar.auth.saml.user.name", "name");
+      settings.setProperty("sonar.auth.saml.user.email", "email");
+      settings.setProperty("sonar.auth.saml.group.name", "groups");
+      settings.setProperty("sonar.auth.saml.enabled", true);
+    } else {
+      settings.setProperty("sonar.auth.saml.enabled", false);
+    }
+  }
+
+  private static class DumbInitContext implements OAuth2IdentityProvider.InitContext {
+    private final HttpServletResponse response = mock(HttpServletResponse.class);
+    private final AtomicBoolean generateCsrfState = new AtomicBoolean(false);
+
+    @Override
+    public String generateCsrfState() {
+      generateCsrfState.set(true);
+      return null;
+    }
+
+    @Override
+    public void redirectTo(String url) {
+    }
+
+    @Override
+    public String getCallbackUrl() {
+      return SQ_CALLBACK_URL;
+    }
+
+    @Override
+    public HttpServletRequest getRequest() {
+      return mock(HttpServletRequest.class);
+    }
+
+    @Override
+    public HttpServletResponse getResponse() {
+      return response;
+    }
+  }
+
+  private static class DumbCallbackContext implements OAuth2IdentityProvider.CallbackContext {
+    private final HttpServletResponse response;
+    private final HttpServletRequest request;
+    private final String expectedCallbackUrl;
+    private final AtomicBoolean redirectedToRequestedPage = new AtomicBoolean(false);
+    private final AtomicBoolean verifyState = new AtomicBoolean(false);
+
+    private UserIdentity userIdentity = null;
+
+    public DumbCallbackContext(HttpServletRequest request, HttpServletResponse response, String encodedResponseFile, String expectedCallbackUrl) {
+      this.request = request;
+      this.response = response;
+      this.expectedCallbackUrl = expectedCallbackUrl;
+      Map<String, String[]> parameterMap = new HashMap<>();
+      parameterMap.put("SAMLResponse", new String[]{loadResponse(encodedResponseFile)});
+      when(getRequest().getParameterMap()).thenReturn(parameterMap);
+    }
+
+
+    private String loadResponse(String file) {
+      try (InputStream json = getClass().getResourceAsStream(SamlIdentityProviderIT.class.getSimpleName() + "/" + file)) {
+        return IOUtils.toString(json, StandardCharsets.UTF_8);
+      } catch (IOException e) {
+        throw new IllegalStateException(e);
+      }
+    }
+
+    @Override
+    public void verifyCsrfState() {
+      throw new IllegalStateException("This method should not be called !");
+    }
+
+    @Override
+    public void verifyCsrfState(String parameterName) {
+      assertThat(parameterName).isEqualTo("RelayState");
+      verifyState.set(true);
+    }
+
+    @Override
+    public void redirectToRequestedPage() {
+      redirectedToRequestedPage.set(true);
+    }
+
+    @Override
+    public void authenticate(UserIdentity userIdentity) {
+      this.userIdentity = userIdentity;
+    }
+
+    @Override
+    public String getCallbackUrl() {
+      return this.expectedCallbackUrl;
+    }
+
+    @Override
+    public HttpServletRequest getRequest() {
+      return this.request;
+    }
+
+    @Override
+    public HttpServletResponse getResponse() {
+      return this.response;
+    }
+  }
+}
diff --git a/server/sonar-auth-saml/src/it/java/org/sonar/auth/saml/SamlMessageIdCheckerIT.java b/server/sonar-auth-saml/src/it/java/org/sonar/auth/saml/SamlMessageIdCheckerIT.java
new file mode 100644 (file)
index 0000000..517269f
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.auth.saml;
+
+import com.google.common.collect.ImmutableList;
+import com.onelogin.saml2.Auth;
+import java.util.Arrays;
+import org.joda.time.Instant;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.user.SamlMessageIdDto;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class SamlMessageIdCheckerIT {
+
+  @Rule
+  public DbTester db = DbTester.create();
+
+  private DbSession dbSession = db.getSession();
+
+  private Auth auth = mock(Auth.class);
+
+  private SamlMessageIdChecker underTest = new SamlMessageIdChecker(db.getDbClient());
+
+  @Test
+  public void check_do_not_fail_when_message_id_is_new_and_insert_saml_message_in_db() {
+    db.getDbClient().samlMessageIdDao().insert(dbSession, new SamlMessageIdDto().setMessageId("MESSAGE_1").setExpirationDate(1_000_000_000L));
+    db.commit();
+    when(auth.getLastMessageId()).thenReturn("MESSAGE_2");
+    when(auth.getLastAssertionNotOnOrAfter()).thenReturn(ImmutableList.of(Instant.ofEpochMilli(10_000_000_000L)));
+
+    assertThatCode(() -> underTest.check(auth)).doesNotThrowAnyException();
+
+    SamlMessageIdDto result = db.getDbClient().samlMessageIdDao().selectByMessageId(dbSession, "MESSAGE_2").get();
+    assertThat(result.getMessageId()).isEqualTo("MESSAGE_2");
+    assertThat(result.getExpirationDate()).isEqualTo(10_000_000_000L);
+  }
+
+  @Test
+  public void check_fails_when_message_id_already_exist() {
+    db.getDbClient().samlMessageIdDao().insert(dbSession, new SamlMessageIdDto().setMessageId("MESSAGE_1").setExpirationDate(1_000_000_000L));
+    db.commit();
+    when(auth.getLastMessageId()).thenReturn("MESSAGE_1");
+    when(auth.getLastAssertionNotOnOrAfter()).thenReturn(ImmutableList.of(Instant.ofEpochMilli(10_000_000_000L)));
+
+    assertThatThrownBy(() -> underTest.check(auth))
+      .isInstanceOf(IllegalArgumentException.class)
+      .hasMessageContaining("This message has already been processed");
+  }
+
+  @Test
+  public void check_insert_message_id_using_oldest_NotOnOrAfter_value() {
+    db.getDbClient().samlMessageIdDao().insert(dbSession, new SamlMessageIdDto().setMessageId("MESSAGE_1").setExpirationDate(1_000_000_000L));
+    db.commit();
+    when(auth.getLastMessageId()).thenReturn("MESSAGE_2");
+    when(auth.getLastAssertionNotOnOrAfter())
+      .thenReturn(Arrays.asList(Instant.ofEpochMilli(10_000_000_000L), Instant.ofEpochMilli(30_000_000_000L), Instant.ofEpochMilli(20_000_000_000L)));
+
+    assertThatCode(() -> underTest.check(auth)).doesNotThrowAnyException();
+
+    SamlMessageIdDto result = db.getDbClient().samlMessageIdDao().selectByMessageId(dbSession, "MESSAGE_2").get();
+    assertThat(result.getMessageId()).isEqualTo("MESSAGE_2");
+    assertThat(result.getExpirationDate()).isEqualTo(10_000_000_000L);
+  }
+}
diff --git a/server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_encrypted_response.txt b/server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_encrypted_response.txt
new file mode 100644 (file)
index 0000000..dca5abf
--- /dev/null
@@ -0,0 +1 @@
+PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c2FtbHA6UmVzcG9uc2UgeG1sbnM6c2FtbHA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCIgeG1sbnM6c2FtbD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgRGVzdGluYXRpb249Imh0dHA6Ly9sb2NhbGhvc3Q6OTAwMC9vYXV0aDIvY2FsbGJhY2svc2FtbCIgSUQ9InBmeDcxZGMxZjgxLTdmMmItNzVjMS0wYzlkLWM1ODIxMzA1Yzg1ZCIgSW5SZXNwb25zZVRvPSJPTkVMT0dJTl9iMjNkM2NhZi03YTVjLTQzNzAtYjg0OS0wZGI0ZDNjMzRlNzUiIElzc3VlSW5zdGFudD0iMjAyMC0wNi0wNVQyMzowMjoyOC40MzhaIiBWZXJzaW9uPSIyLjAiPg0KICAgIDxzYW1sOklzc3Vlcj5odHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvc29uYXJxdWJlPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4NCiAgPGRzOlNpZ25lZEluZm8+PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4NCiAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIi8+DQogIDxkczpSZWZlcmVuY2UgVVJJPSIjcGZ4NzFkYzFmODEtN2YyYi03NWMxLTBjOWQtYzU4MjEzMDVjODVkIj48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT55L2lsZHIvdTFNRTB3MU9Ia2VLT3RYc2dOQXM9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPkxraVhzMnEzeThZcG9YSHgrOEszY2V5aUkxZEQzaDIyNUVlQWtIK05GaHZLUmNsRlVDdzBVQmc1RmtUQzUvRjd0dCsvTDljU3drYXFpY0VaVGp3TGVzSCtnQzdJVUhOZ2NKTlFWUHBSRGQwckMweG94TzZkLzk4d3NDTDZmN2dIcWNLR3VJN0dGc1U5akprSHpmU2hvakpIWFYrVTRkK1FrUFRLWTQ1Z2F4dlN0T2EyYzNLNnQwSU5xc204aktBWHNvVHNZUStFMjZRTi8wZSs3SjY4WUdUSGFPayt2M2NiQ1ZHakVkcE5ZVWlTN0dMcTYxekpwVTI0SCtzY0xIUVVZRjAxeWdIZGk0SjdDQzhocUNOeFhnVUJhMlVTZWlpUXFMbGVZQU1iYUlIQ0dnLzdVOE9yZGlQWmN3Y1BTRVhpbUhQQWFIR2VKQldsQ1RhWjYxQnVqVHZmV1JQaXRVUSsrWEYyM0wwNDlJbDRVeHFaTlJ4T2h4eFdCYUZBM2RsL0I4U1VIV05aSEJ3NEVjcjNsQ1hPVXZGYjRtWitWYjA1VXNIQzJIdjQ3elNHS2d2bnV5djlwS0hGQzlBSXFrSEtFTG5OcHl6OTgvaUQvamtkczhjT0RRbk4wa05kWU5EVVZZOE5NbTRvTjVOM1pVRWVmaXc3ZThydjZuZTFLckZhcE1OMmlramgzclExcHJXaTZyVzJtcVZlWldHMlVkcVcwRUhsV3lyUGdpR2ZyRklYTS8ycTFJUlFwUEg2UUpzSjUwU05KaG9NOHEzSWZldWNMQkh6RU1FVlVINlpQQ2lBTmNUekxjdjJmdnFUS0ZFUmJmdkNZaWhwZnBnek5JZzVucXR6TXNQbGRWNEpma0NlaFROZGpZQXpXTEFrYjNUT2thNGJIS3dhd3lvPTwvZHM6U2lnbmF0dXJlVmFsdWU+DQo8ZHM6S2V5SW5mbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlGNXpDQ0E4K2dBd0lCQWdJVUlYdjlPVnMvWFVpY2dSMWJzVjl1Y2NZaEhmb3dEUVlKS29aSWh2Y05BUUVMQlFBd2dZSXhDekFKQmdOVkJBWVRBa0ZWTVE4d0RRWURWUVFJREFaSFJVNUZWa0V4RURBT0JnTlZCQWNNQjFaRlVrNUpSVkl4RGpBTUJnTlZCQW9NQlZOUFRrRlNNUTB3Q3dZRFZRUUxEQVJSVlVKRk1ROHdEUVlEVlFRRERBWmFhWEJsYm1jeElEQWVCZ2txaGtpRzl3MEJDUUVXRVc1dmNtVndiSGxBWjIxaGFXd3VZMjl0TUI0WERUSXlNRFl4TXpFek1UUXlOMW9YRFRNeU1EWXhNREV6TVRReU4xb3dnWUl4Q3pBSkJnTlZCQVlUQWtGVk1ROHdEUVlEVlFRSURBWkhSVTVGVmtFeEVEQU9CZ05WQkFjTUIxWkZVazVKUlZJeERqQU1CZ05WQkFvTUJWTlBUa0ZTTVEwd0N3WURWUVFMREFSUlZVSkZNUTh3RFFZRFZRUUREQVphYVhCbGJtY3hJREFlQmdrcWhraUc5dzBCQ1FFV0VXNXZjbVZ3YkhsQVoyMWhhV3d1WTI5dE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBdTNuRlhZdklZZWRwUjg0YVprZG8vM3lCNVhITStZQ0ZKY0RzVk8xMHpFYmxMa25mUXNpTVBhMVhkOVVzdG5weHc2UC9TeXpJSm1POWppTU9kZUNlWTk4YTc0alA3ZDRKUGFPNmgzbDlJYldBY1llaWpRZzk1Nm5sc1ZGWTNGSERHcis3UGI4UWNPQXlWM3Y4OWppRjlERkI4d1hTKzVVZllyMk9mb1JSYjRsaTM5ZXpEeURkbDVPTGxNMTFuRXNzMnoxbUV2K3NVVWxvVGN5cmdqMzdQc2dld2t2eXltNnRGR1Nna1Y5WmE0U1ZSaEhGeVRoWTFWRnJZWlNKRlRuYXBVWWFSYzdrTXh6d1gvQUFIVURKcm1ZY2FWYzVCOE9EcDR3MkF4REpoZVF5Q1ZmWGpQRmFVcUJNRzJVL3JZZlZYdTBaYTdQbi92VW80VWFTVGh3Q0JLRGVoQ3d6KzY1VExkQStOeHlHRHhudlkvU2tzT3lMTEdDbXU4dEtrWGR1MHB6bm5JaEJYRUd2alVJVlM3ZDZhLzhnZWc5MU5vVFdhdTNpMFJGK0R3LzVOOURTenBsZDE1YlB0YjVDZTNCaWUxOXV2ZnZ1SDllZytEOHgvaGZGNmYzaWw0c1BsSUtkTy9PVmRNMjhMUmZtRHFtcVFOUHVkdmJxejd4eTRBUnV4azZBUmE0ZCthVDl6b3Zwd3Z4TkdUcjdoMW1kZ09VdFVDZElYTDNTSE5qZHdkQUF6MHVDV3p2RXhiRnUrTlErVjUrWG5reDcxaHlQRnY5K0RMVkdJdTdKaGRZczgwNndLc2hPMTNOZ2EzOGlnNmd1MzdscFZoZnBaWGhLeXdVaWlnRzZMWEFleVdXa01rK3ZsZjlNY1pkTUJEMTZkWlA0a1RzdlArclBWblVDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRkk1VVZMdFR5U3ZiR3FIN1VQOHhUTDR3eFpxM01COEdBMVVkSXdRWU1CYUFGSTVVVkx0VHlTdmJHcUg3VVA4eFRMNHd4WnEzTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCQUJBdFhzS05XeDBzRERGQTUzcVoxelJ5V0tXQU1vaDk1cGF3RkNyS2dURVc0WnJBNzNwYTc5MGVFMVkrdlQ2cVVYS0k0bGk5c2tJRGErNnBzQ2R4aFpJckhQUkFuVlpWZUIyMzczQnhyNWJ3L1hROGVsUkNqV2VNVUxiWUo5dGdzTFYwSTlDaUVQMGE2VG04dDB5RFZYTlVmeDM2RTVma2dMU3J4b1JvOFhKenhIYkpDbkxWWEhkYU5CeE9UN2pWY29tNldvNFBCMmJzalZ6aEhtNmFtbjVoWnA0ZE1IbTBNdjBsbjF3SDhqVm5pekhRQkxzR016dnZsNTgrOXMxcFAxN2NlUkRrcE5EeitFUXlBK1pBcnFrVzFNcXR3Vmhieno4UWdNcHJoZmxLa0FycnNDN3YwNkp2OGZxVWJuOUx2dFlLOUl3SFRYN0o4ZEZjc08vZ1VDNVBldllUM25yaU4zQXpiMjBnZ1NRMXlPRU1venZqNVQ5NlM2aXRmSFBpdDd2eUVRODRKUHJFcWZ1UURaUS9MS1pRcWZ2dVhYMWFBRzNUVTNUTVdCOVZNTUZzVHVNRlM4YmZyaE1YNzdnMFVkNHFKY0JPWU9IM2hSNTlhZ1NkZDJRWk5MUDN6WnNZUUhMTFFrcTk0amRUWEtUcW0vdzdtbFBGS1Y1OUhqVGJIQmhUdHhCSE1mdC9tdnZMRXVDOUtLRmZBT1hZUTZWK3M5TmswQlc0Z2dFZmV3YVg1OE9CdXk3SVNxUnRSRlBHaWExOFlSenpIcWtoanViSllNUGtJZllwRlZkK0MwSUkzRjBrZHk4VHRwY2NqeUtvOWJjSE1MeE80bjhQREFsMTk1Q1B0aE1pOGdVdlQwMDhMR0VvdHIrM2tYc291VEVaVFQwZ2xYS0xkTzJXPC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+DQogICAgPHNhbWxwOlN0YXR1cz4NCiAgICAgICAgPHNhbWxwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPg0KICAgIDwvc2FtbHA6U3RhdHVzPg0KDQogICAgPHNhbWw6RW5jcnlwdGVkQXNzZXJ0aW9uPg0KICAgICAgICA8eGVuYzpFbmNyeXB0ZWREYXRhIHhtbG5zOnhlbmM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jIyIgeG1sbnM6ZHNpZz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyIgVHlwZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjRWxlbWVudCI+DQogICAgICAgICAgICA8eGVuYzpFbmNyeXB0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjYWVzMjU2LWNiYyIvPg0KICAgICAgICAgICAgPGRzaWc6S2V5SW5mbyB4bWxuczpkc2lnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4NCiAgICAgICAgICAgICAgICA8eGVuYzpFbmNyeXB0ZWRLZXk+DQogICAgICAgICAgICAgICAgICAgIDx4ZW5jOkVuY3J5cHRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGVuYyNyc2EtMV81Ii8+DQogICAgICAgICAgICAgICAgICAgIDx4ZW5jOkNpcGhlckRhdGE+DQogICAgICAgICAgICAgICAgICAgICAgICA8eGVuYzpDaXBoZXJWYWx1ZT5RRlduQ1oyZDhaS1J5ZGdXenBNazBVbmJBek55Q2kvUnUvd2RjZFUrTzR4Tkg0V1AreVh2WkZ0MXkrY2lmZHhIK3VYajlwcEtheE96T2JIL1pEaE1RSVIxSXVmS2xNUmVDSFJ3clZWV3FFRkZNS2Q5eXIrWFU5U29YdjEvQUdsSXBSQjlvbkhubTVidDljOFMrZ1ZlRFluRCtLblptelBlMU5KY1AzUmcvdGEwZUxIMng5WkQ5V3QzSUFYOFY2aXVXY0l0d21kakFvRmJrc1ZoUC9md0dpK0FRYmEvYksxNE5WVGtKS0lyS0s5NlV1dlBqTllpbitQK0JoSVlxdFhWSnA0Qm1pT1lKS3J5dVlnRU5vRzh4aUoyZy83Sk5RR0VjV0xOZVBkbGVvUU1BRjYvMTFDRndZYXVkOFcwQzlBSElBMWtFOWRmd01zN3pWZkZsREgzM2c9PTwveGVuYzpDaXBoZXJWYWx1ZT4NCiAgICAgICAgICAgICAgICAgICAgPC94ZW5jOkNpcGhlckRhdGE+DQogICAgICAgICAgICAgICAgPC94ZW5jOkVuY3J5cHRlZEtleT4NCiAgICAgICAgICAgIDwvZHNpZzpLZXlJbmZvPg0KICAgICAgICAgICAgPHhlbmM6Q2lwaGVyRGF0YT4NCiAgICAgICAgICAgICAgICA8eGVuYzpDaXBoZXJWYWx1ZT5oeGdPTnFnaXA5Wmd6Y2dMUitxc0poWFJPTWhrQ3J4R2dkUTN3UHhQMGVGMFk1UXpYRmQzRUJTRHVUYTl4YnBhb1RCdGFOQ3FnditLbWFKeTJxU2NVL1EzYXBWUmI0WEM5bmU3L1VFcDVrR0hiV2xyVkxZZUNTNnp1VHJSKzNmMzhzd0ordlg2cWZFbC9GbTBEV0VHaEFIWnhtMm80Wk1QR2xXRm4wMnp5c3QvdHdRL3Foa1RodnQ3akp6RVlTRFc2ZjBEdlpkNXVoTDRIOU9XaGZoNTlIRnloZzRncUp5a05Ha1pUQytEckc1dDh2OWs5ZDVHV0ptam9nVEdzVjVCTnJaclhBMmtjQkM4Q1VlL2w3Z20xSXF2Ymp0OW1CN2g5alVVVU5LWGVBeVR6MUxRRFN2aS9hbmZVZW40UDZsQ1dmanlsVnFmdnFnS3EzamVWdzBhUHVrZlllMFg2UFAzbDBZR25CU2h3UytJeERpNUFMREp4ZlBiM2M1cm9sR1F2V3Z4T3VYeVFxMHRIUThQWXNPajVKc2t4Q2FoY3NWYjgwNHlLeFlKcWdGRDJKdG14b1BIK005Y3F1VmRTVlVqUk5nU09XWjByVU5WU2ljRjlrOTVMYkJLaFB3WUpXbVdwWnBJb3FaeE9WcUdtcUNrdG9WcmhaeUY5TnNWN2JMQk5ubGt5LzZIMy94SExDamx5dkNyczNQd3VnOERkTzhLUTcyTmV0WEtYN2kxS1RiNi9lcVErZGUzeGljUWEvcEYvNDVQZ2EySkVKc3FvVWpRUEJvSFY2ZzhpM1RxSWtTWk15c3FmWE1Va1FRelVveU96VEtjTmFrVEx1VU4wUEdLQTR6OGNYbUM1ZmlTdTJNMVdVT3hxYjZ5bFBVRnl6RGtzUzEwU0dib3BWQ1NqMk1iUnIyLyt4ZGNFUXlhTlFPVCtMTGN0MXRaczN3NzNVRGtIQVlMS0NvNFROOVdPVkhRSFYwWnh4YnRsOUh4R1hvdXJSeDN6dDFXbjBBc0kwTWZBbVpJUVZmek0zMTE5eXgrL2VaTzhudnVXWWhKSVdjOUtwQi9XSzdBL2k5blRobzhOaGFKWU5jYWlLMlM2TzNWR1laNFUzRUNxZzlmQVI1d0FUMk5tTHpZMmI3K3lUTWdJWTRDTXl0Smp6NFA5MDhOay9DVDF6cEs1dkhQcWNhK3dHVEpnOEcycnlnL05MVXJKM3pEbkhhQTZDazRjRXFHSFQ4dUtnSWM0NHo5bERCemtJaXhXYW5FMVVvbkpNTnlnNDNvQXQyWnJTN3k1TkdsOWhKbythVEtTWjN5bVFNTTUyMWR2MmFGWmplTEhISncvYThvS2JQOUt5UDlpL2d5SWdGaXF4UDNKd3VwdFRIQnVqZlhMVnRyT0FIcWlZODhqU2svbzJmUzQ0di90aXhOcUI1a2FoU2dsNUhLVXJjQjJCVlVoRjY2aDhyWjQ4YnFEWElRN0NET0szZ3JoNkxrcmpFcmNsRityRWZqdWZ3LzRkRjZ1ZXkya2ViNjY3RlNYRTNEaE90TXRPV0txaVl1b3FiWm5OMm13bGdTTjBwRkprODZaWEVQUUtkMTlOWkloVWdMYWw3OGZadWJicHFYOXhqd3pTY2c3VUE0Y2JGUTdGWFV0eDg3dGVyNS9wcHByOGk3RVE1Q1RId0xzWEV6cWVQTEIrZVBCRzB6UDBsbVdNSkxxVHJJMC9KYXErK0l6RzBBNXNVZ1lxMUFsT05WZ3hsMGVPQ1pDVmVrby8rTHg4RkdDdzJWcGwzWkNqRGN5c1FCYkZlWWpUWDJSVG1Xa3ZrRmRSSDQzK2RsY3ovQmlDZWZQMGtISzk1by9iYWoyeHl1bGgrV1g0VUNkWWlNdUcvR25wQVU3NTc5UjNEWFlxMUhaRDRibEg0a0phZDlVZ2hFOEoxaXdacU9zVWtTM0RBMnRpWEZmbW1VSjFIbWpYU1ZHckhSUXExMFRncnBycW5DR2ZrUTUwbGxlMkhIUkRmLzNpQ2ltYUQxSkRnc1duYytyd2QyWlVtVkNFQU1pUG9xQng0cGdqUmtQOHZsa25QNm1NTEcvZkNEb0Rid3I0U1o1RDRiMkFPcjFWTVBoRDBGQlpBTC8wUFE5aWFETi9acHkydVBTRWd5ck5kU25GKytrakdMMnJQTUNHdFNJMUIwWFZudmE0NkhucmQ4ZGVVcUV1QmRhWWMwZW1JWkxuRVZ5OW8xTGhoeFNMamNEbnhlWk41ZW0zclNHdUVUN2MyMzAwOWdwR0hSOUlSU1RHZ2RVTTQrdmRycStBbHJtODlwNG1na09QUjNpdFU5UkVoMGQ5N3p3cGF2NkZRZ0liQXI0bEZDNTI0Y1hQTkdxeC85U0dodUt2enBoV0RqM05hK1phek90aUFIeTF4dklPZXk4eTBzMXJoWC9MRVRJRzZEREhaaU13eFlMbHF0c1piM3JlNEowOHBPUW9SdmVLSVF4amNwZVJRZWxuWUlsTkUvRlUyaktaeGNkakNjSDVxNlMrZmUwQW1iVng1ZDRaWi91akhnNWtycWlWWHpoMW9uTzF2WTh3emdORm9Ha2d4RDVFV3luSGFWN0ZKeWhwdUYrdVRvRG9nSjROcHo5eFQwVWNPVkJnMDl3T2VYak9vSTVsOWwyOWRZSlQ3TTVmcTlXd3B4QXRZaTI0Q1JZMkFCMEo1U3BuY2VKOVBFUlhGak1zaFpUM25LaTlxUy9aRVBIb1hwVmdpWUI2dHRSOU1NNUpqR1JJeXlKcnQrN1FtVHBXSzBSSitNcitqbWZ0V25vbThwN0xiL000YmY3dHFQZUFocXVOaWN0QmQ5eTEzL0p3MVVVSjdWR00yK2srRlpQN0tuc1Z6M0hWcERya3VXOVJJNVRDb2xmNUwwMXRiMzRjRjVDeERXb21CcjBkTHpBMkJBYlpBT1E2VEFUK0dvYXNNbC9mOWlMWi9FUks5NFJQbXkvdUtrUlN4bnJBRGorUkpZN1kyUi80UzJIV3A0WHZramJ1MnR5ZWVlTndabWR1SFJLZTVhNmY4SHJUZDlVdGljWTd6cDlJUnJlc2lBTjJoU0ZJaHAxZ05WaysvaXZBY1Rtb3k5b1dER3l2bzFwdEdpeHV6bGc1eGJ5SFRKa1VJWjFJVFZ5STNjZGozN3IxOVZPaThzaUtNZE5vOWtNY1Zsd3RCVkF3V2hDVi9wUlV1YjUzZHBSRFF0VDVCd2k5R3RPSE9YZ2FNYUc2REkyd0F3bHVBcWRYemlRQi9ZdHE1RStJYUIzaG1XRmxQTkN0WExQZ2JpSVBlM1lwNk5YeGY0VjRaV0VwWG9IVmZiYTZmK2k2Zm1tVkYxZThQeWgzVFFNamJSUFFtYWxLNnB2T1VSeTdha21URHEra21BamFHUnBpQnEwSi9yUkgxVUZyOFUxRmg2Q2NPN1B4ZU1QWHdOVGhVMSs4alMrZnJ0TXp1UVAybWJIT21telJzUWRNcE8wZU9YQU5VdVFza1pXZ0g0SFVqSXlVOGVESFcvL25zYnN0L2xxSWhUcjMzRnhtT3p4NkkyRXR6TEw1OWhzVlpIckZIclRhTDVoMWdud00xMmJBdHpyTTBEMzExZFpjaWdMWWRFUkh6WWhWOEkrZWFoOUtybGVZRGs2S0xBVWQwcm1FRnl3MzlVa3JpUW4wU0dwYTZ5N1BnY2V4ZklMZ1hVeE1wWXdJQnZmd0NVaTU3ckRqQWU1ZndyNTN4RkJxQWdSN1RjUHQ0TkF1cDRoYmtiWHNIUDNrVm5tWm1vSHRsSDZ6eW1qdUROaUpYYnFCWTFrVzNicER4Q2FvVmU4YmVSampHWXl0TisyREp3b09scmpSUi9FWjE4Z01vN1lJUk1FMmhoVW9Wa3kyWU04cVpUR0Jxcjk3L2pFRk1nWGlwam13ZTF0Ny9XWFpIMXJVRXI2QmdKeEt6RDBSdFczSXIzeFdmWk1xN1N6SzRyS0huQldOQ3J0VE5LT3FiRnY0UWxJR05sUEdNZHNXMHBWYmRyTkJTdGlhRjRQMWkrUEVraHNWc0h1UWcxQ28zWmlQZmREblVzVWtOOVJoWDhoQmkzT3JsT08yMkJrRDVGT1o1U0xjYjFwbFRsMjlFT0ZvRENWbDRMcXA5SDdPRjFQNG4wczNhankzZTVMUlVJbW9FdE1DR1pVQnpUNStiL1J4eFlneHp4SmJ1WU5DUjM3WGRLK2ZUMHZaSGo3YVB5WEJZUURIUWpHOFVOWVprNnRqMjRyZkxUM0dERzR1aUJBcXYxa3pyd3ZFVVNuMW9JaStLa0lxNUFTdzFPQ1FWMDBCTTk3VXpFMTZLOUtzNTEvcldhdU1BSzJOSHBvcmkzUEFYbTg1MzhkSEtRbmpFWFBGM1o5dDJzKzU3VmxPODFiazJ6NVZ4WDJGenRmNXZybUJORG5vQ1V4eTh1UXVuTHh0S2FrZHpmaDN6ckxRZVRpMjdMVnRMeGtEemJDWVRoWG52YU0zVEl1V3BGeTBTeStGRXNZaXNyTDh3L1F4WGgzRG9RQ0kwMTIvSTVoeXd2Q2VHUHR0VjNicld6MmhhM0drbVgzY3Z5QlpBeWM2T3dhOUhQMnRuTkhPV1VQTEp6TDlWR1IvUXRhM1R5Vm9TMUcwZjg3NGlnd2hBVlkxYUhFbzNncEtrRkpRTFc5eWlGSG9oRzg4aGlxa3ZWTnduc2kyVHZaVlBVbVU4b0xEOEl5VW5WaXd5NzZlMWh4UkRqc1B3VWxsOWdyWU94aGkrUUpQN2xHWjhSc2lPT0lWQm5WSjczdDdQYjVDOXlzbXJuMlNOdUdIUTFTYUxFaGZQN0UyU0FsQ0FETDRDV2cxYXZCK2FPQk9OdEx6Y1ZtV1lRaVk0T1B5dS9iR0pDTmhQcVRheXJLZzMrUTVaU2xGd055UkpZcDcrOUZxU1ljRk15ellPQlYvVUZjU3ovL3E3NU9uTHBzallOaGlwWVplNjgxLzhIR29QV1h4SktPMHd2U0RyNmpYcmJrUHlBSm16ZGtRWEFmYTlNMmNadS9aSTVRVnB2MW5qeVU1bDgxbjhOeDhVVkNrVlY4OFNsS3BlVzZ4QmNpa3JxWlp2NEFsakhKRXVVSzFYZUNSU0o0VU1MU1RqeXg0eWw4cTFmODgxV3RlWE1kK1FOUUtORkJ3b2o4VkNQZHp3Rmtub0h4S3ZmVHJ0TnJVYWlyN0h5L2VsbVNxZExqdUhpeStBRGRET2dLQ0F3cWZ1TGFWb2laWVhENENmVUozTHg3cUJYMDdZVysyZXk5NUdFcEdYVXJyM1lNRTVlT2NyZnZacDNVeTYrSkpRRFZqQ3YyZGRKUHVuWEI2OEFkVzNkTGJSR0lhQVJSV1A5MnlSMFFJTlg8L3hlbmM6Q2lwaGVyVmFsdWU+DQogICAgICAgICAgICA8L3hlbmM6Q2lwaGVyRGF0YT4NCiAgICAgICAgPC94ZW5jOkVuY3J5cHRlZERhdGE+DQogICAgPC9zYW1sOkVuY3J5cHRlZEFzc2VydGlvbj4NCjwvc2FtbHA6UmVzcG9uc2U+
diff --git a/server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_full_response.txt b/server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_full_response.txt
new file mode 100644 (file)
index 0000000..03e518d
--- /dev/null
@@ -0,0 +1 @@
+PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIERlc3RpbmF0aW9uPSJodHRwOi8vbG9jYWxob3N0OjkwMDAvb2F1dGgyL2NhbGxiYWNrL3NhbWwiIElEPSJJRF8yOGM0YzMzZi0yZDNhLTQ5NjEtYjcwZC0yYzMwZmNkYWVkNDAiIEluUmVzcG9uc2VUbz0iT05FTE9HSU5fYjIzZDNjYWYtN2E1Yy00MzcwLWI4NDktMGRiNGQzYzM0ZTc1IiBJc3N1ZUluc3RhbnQ9IjIwMjAtMDYtMDVUMjM6MDI6MjguNDM4WiIgVmVyc2lvbj0iMi4wIj4NCiAgICA8c2FtbDpJc3N1ZXI+aHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL3NvbmFycXViZTwvc2FtbDpJc3N1ZXI+DQogICAgPHNhbWxwOlN0YXR1cz4NCiAgICAgICAgPHNhbWxwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPg0KICAgIDwvc2FtbHA6U3RhdHVzPg0KICAgIDxzYW1sOkFzc2VydGlvbiB4bWxucz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9InBmeDI2YTQzNTgxLTg1OWUtNzZhMC0xN2ZmLTYwMDk0YjEwZDRmZCIgSXNzdWVJbnN0YW50PSIyMDIwLTA2LTA1VDIzOjAyOjI4LjQzOFoiIFZlcnNpb249IjIuMCI+DQogICAgICAgIDxzYW1sOklzc3Vlcj5odHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvc29uYXJxdWJlPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4NCiAgPGRzOlNpZ25lZEluZm8+PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4NCiAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIi8+DQogIDxkczpSZWZlcmVuY2UgVVJJPSIjcGZ4MjZhNDM1ODEtODU5ZS03NmEwLTE3ZmYtNjAwOTRiMTBkNGZkIj48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT5PNFdTcGpQbFVPWWkwdTFtemlQM0NYTzY1eWs9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPlpBTGN6Q2l1U3NvaGxwMVIvbExDK29qZFAyWGNHTytuY2RxRlJ6NXJERlc2T2F1TjlTRTJWSkNIS1BJUE53RVYzSytTdkpkR0hPTDRKTUdZa1kyTHYranRuYWNmOTd5VTZwLzNFam5ZejlTUXZWUEdkSXVCSG5DaHp3SWpVc1V3OXRGYjExa01MR0cyK0ZXeE1TQzZGUzJWT2Zxa3RoSzNnTTI1aUtwNVR0TTN1d0NFQWh0UGNwYXpoWld6cDBvQVovNWp5RnVpaVZPVzBvVnN3WjNnd1k2OTZaenBRbFlYbHlFYURNNUZPWXBXREsvQ3hOa2JxWExwdnZ2My9Qb2JTVktIU2VWRkdvdzE1NzN3a01iSDBSMTJLejdWREtoRGM2THBmZThobmV0Rmgxa2tRU21iRDFzdjVRQUJsbStnS2ZVRTNJU0MxdUtUdFI4c2hML0gxVFNWSEZKSGRWd0hKU0VHQmVBRkhlbFh3NFAxS1hncGxpeTJ2cGN1NWRQMEZKSW13NkpLZEg3V0xUclVpSjJPVmlWaGRTdHdJUFF4U2V6Z21zYVFxb2c1Ri9FaithaVJ5cFR1K2xYVXJMVEFJUHVPdFY5WHJnMGxWYXRQVmJ6U0oxZjVnUE45WFhKbFd5QVErRW95OW00eGVWYmhaOUpuc1VlSWRRUzZMQ0ducHVKMktYb3I1SHVuSGY2RUdmUVZUYmZFVWFxRmFZOHVxZE5aL2JrYkNKYU51TnNDYzVzcWV3Rkx5Z3Q5cjI5Sk1CK2ZjeGhpRUxqZEQzbzA5Wk9wSGtQTnZXTXVLbFFZdWF2ZVF6Z3M5bk5lMVFRcm5RWjRaeFFPVEpJUWdzM1M1a0NoMmdWSDN6MXdBWUdQVUNNOTVFM1hNb1Q0TkpVSWQzMEJlUUh4czJzPTwvZHM6U2lnbmF0dXJlVmFsdWU+DQo8ZHM6S2V5SW5mbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlGNXpDQ0E4K2dBd0lCQWdJVUlYdjlPVnMvWFVpY2dSMWJzVjl1Y2NZaEhmb3dEUVlKS29aSWh2Y05BUUVMQlFBd2dZSXhDekFKQmdOVkJBWVRBa0ZWTVE4d0RRWURWUVFJREFaSFJVNUZWa0V4RURBT0JnTlZCQWNNQjFaRlVrNUpSVkl4RGpBTUJnTlZCQW9NQlZOUFRrRlNNUTB3Q3dZRFZRUUxEQVJSVlVKRk1ROHdEUVlEVlFRRERBWmFhWEJsYm1jeElEQWVCZ2txaGtpRzl3MEJDUUVXRVc1dmNtVndiSGxBWjIxaGFXd3VZMjl0TUI0WERUSXlNRFl4TXpFek1UUXlOMW9YRFRNeU1EWXhNREV6TVRReU4xb3dnWUl4Q3pBSkJnTlZCQVlUQWtGVk1ROHdEUVlEVlFRSURBWkhSVTVGVmtFeEVEQU9CZ05WQkFjTUIxWkZVazVKUlZJeERqQU1CZ05WQkFvTUJWTlBUa0ZTTVEwd0N3WURWUVFMREFSUlZVSkZNUTh3RFFZRFZRUUREQVphYVhCbGJtY3hJREFlQmdrcWhraUc5dzBCQ1FFV0VXNXZjbVZ3YkhsQVoyMWhhV3d1WTI5dE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBdTNuRlhZdklZZWRwUjg0YVprZG8vM3lCNVhITStZQ0ZKY0RzVk8xMHpFYmxMa25mUXNpTVBhMVhkOVVzdG5weHc2UC9TeXpJSm1POWppTU9kZUNlWTk4YTc0alA3ZDRKUGFPNmgzbDlJYldBY1llaWpRZzk1Nm5sc1ZGWTNGSERHcis3UGI4UWNPQXlWM3Y4OWppRjlERkI4d1hTKzVVZllyMk9mb1JSYjRsaTM5ZXpEeURkbDVPTGxNMTFuRXNzMnoxbUV2K3NVVWxvVGN5cmdqMzdQc2dld2t2eXltNnRGR1Nna1Y5WmE0U1ZSaEhGeVRoWTFWRnJZWlNKRlRuYXBVWWFSYzdrTXh6d1gvQUFIVURKcm1ZY2FWYzVCOE9EcDR3MkF4REpoZVF5Q1ZmWGpQRmFVcUJNRzJVL3JZZlZYdTBaYTdQbi92VW80VWFTVGh3Q0JLRGVoQ3d6KzY1VExkQStOeHlHRHhudlkvU2tzT3lMTEdDbXU4dEtrWGR1MHB6bm5JaEJYRUd2alVJVlM3ZDZhLzhnZWc5MU5vVFdhdTNpMFJGK0R3LzVOOURTenBsZDE1YlB0YjVDZTNCaWUxOXV2ZnZ1SDllZytEOHgvaGZGNmYzaWw0c1BsSUtkTy9PVmRNMjhMUmZtRHFtcVFOUHVkdmJxejd4eTRBUnV4azZBUmE0ZCthVDl6b3Zwd3Z4TkdUcjdoMW1kZ09VdFVDZElYTDNTSE5qZHdkQUF6MHVDV3p2RXhiRnUrTlErVjUrWG5reDcxaHlQRnY5K0RMVkdJdTdKaGRZczgwNndLc2hPMTNOZ2EzOGlnNmd1MzdscFZoZnBaWGhLeXdVaWlnRzZMWEFleVdXa01rK3ZsZjlNY1pkTUJEMTZkWlA0a1RzdlArclBWblVDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRkk1VVZMdFR5U3ZiR3FIN1VQOHhUTDR3eFpxM01COEdBMVVkSXdRWU1CYUFGSTVVVkx0VHlTdmJHcUg3VVA4eFRMNHd4WnEzTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCQUJBdFhzS05XeDBzRERGQTUzcVoxelJ5V0tXQU1vaDk1cGF3RkNyS2dURVc0WnJBNzNwYTc5MGVFMVkrdlQ2cVVYS0k0bGk5c2tJRGErNnBzQ2R4aFpJckhQUkFuVlpWZUIyMzczQnhyNWJ3L1hROGVsUkNqV2VNVUxiWUo5dGdzTFYwSTlDaUVQMGE2VG04dDB5RFZYTlVmeDM2RTVma2dMU3J4b1JvOFhKenhIYkpDbkxWWEhkYU5CeE9UN2pWY29tNldvNFBCMmJzalZ6aEhtNmFtbjVoWnA0ZE1IbTBNdjBsbjF3SDhqVm5pekhRQkxzR016dnZsNTgrOXMxcFAxN2NlUkRrcE5EeitFUXlBK1pBcnFrVzFNcXR3Vmhieno4UWdNcHJoZmxLa0FycnNDN3YwNkp2OGZxVWJuOUx2dFlLOUl3SFRYN0o4ZEZjc08vZ1VDNVBldllUM25yaU4zQXpiMjBnZ1NRMXlPRU1venZqNVQ5NlM2aXRmSFBpdDd2eUVRODRKUHJFcWZ1UURaUS9MS1pRcWZ2dVhYMWFBRzNUVTNUTVdCOVZNTUZzVHVNRlM4YmZyaE1YNzdnMFVkNHFKY0JPWU9IM2hSNTlhZ1NkZDJRWk5MUDN6WnNZUUhMTFFrcTk0amRUWEtUcW0vdzdtbFBGS1Y1OUhqVGJIQmhUdHhCSE1mdC9tdnZMRXVDOUtLRmZBT1hZUTZWK3M5TmswQlc0Z2dFZmV3YVg1OE9CdXk3SVNxUnRSRlBHaWExOFlSenpIcWtoanViSllNUGtJZllwRlZkK0MwSUkzRjBrZHk4VHRwY2NqeUtvOWJjSE1MeE80bjhQREFsMTk1Q1B0aE1pOGdVdlQwMDhMR0VvdHIrM2tYc291VEVaVFQwZ2xYS0xkTzJXPC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+DQogICAgICAgIDxzYW1sOlN1YmplY3Q+DQogICAgICAgICAgICA8c2FtbDpOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDp1bnNwZWNpZmllZCI+am9obmRvZTwvc2FtbDpOYW1lSUQ+DQogICAgICAgICAgICA8c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uIE1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlciI+DQogICAgICAgICAgICAgICAgPHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgSW5SZXNwb25zZVRvPSJPTkVMT0dJTl9iMjNkM2NhZi03YTVjLTQzNzAtYjg0OS0wZGI0ZDNjMzRlNzUiIE5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTo0MToyNi40MzhaIiBSZWNpcGllbnQ9Imh0dHA6Ly9sb2NhbGhvc3Q6OTAwMC9vYXV0aDIvY2FsbGJhY2svc2FtbCIvPg0KICAgICAgICAgICAgPC9zYW1sOlN1YmplY3RDb25maXJtYXRpb24+DQogICAgICAgIDwvc2FtbDpTdWJqZWN0Pg0KICAgICAgICA8c2FtbDpDb25kaXRpb25zIE5vdEJlZm9yZT0iMjAyMC0wNi0wNVQyMzowMjoyNi40MzhaIiBOb3RPbk9yQWZ0ZXI9IjIwMzktMDYtMTFUMDk6NDE6MjYuNDM4WiI+DQogICAgICAgICAgICA8c2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF1ZGllbmNlPk15QXBwPC9zYW1sOkF1ZGllbmNlPg0KICAgICAgICAgICAgPC9zYW1sOkF1ZGllbmNlUmVzdHJpY3Rpb24+DQogICAgICAgIDwvc2FtbDpDb25kaXRpb25zPg0KICAgICAgICA8c2FtbDpBdXRoblN0YXRlbWVudCBBdXRobkluc3RhbnQ9IjIwMjAtMDYtMDVUMjM6MDI6MjguNDM5WiIgU2Vzc2lvbkluZGV4PSIyMzc2ZjlhMy0zYjJhLTRlOWEtYmE5Yi04NDc5Y2ViYjQyNTc6OjAyODE1Y2Q1LTllYzktNDY0OS1hOWYwLWQ1ZmRiOTU1NTFkYyIgU2Vzc2lvbk5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTo0MToyOC40MzlaIj4NCiAgICAgICAgICAgIDxzYW1sOkF1dGhuQ29udGV4dD4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3Nlczp1bnNwZWNpZmllZDwvc2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj4NCiAgICAgICAgICAgIDwvc2FtbDpBdXRobkNvbnRleHQ+DQogICAgICAgIDwvc2FtbDpBdXRoblN0YXRlbWVudD4NCiAgICAgICAgPHNhbWw6QXR0cmlidXRlU3RhdGVtZW50Pg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9Im5hbWUiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI+Sm9obiBEb2U8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9ImxvZ2luIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmpvaG5kb2U8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9Imdyb3VwcyIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+DQogICAgICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5kZXZlbG9wZXI8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5wcm9kdWN0LW1hbmFnZXI8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9ImVtYWlsIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmpvaG5kb2VAZW1haWwuY29tPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPg0KICAgICAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZT4NCiAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD4NCiAgICA8L3NhbWw6QXNzZXJ0aW9uPg0KPC9zYW1scDpSZXNwb25zZT4=
diff --git a/server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_full_response_with_reverse_proxy.txt b/server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_full_response_with_reverse_proxy.txt
new file mode 100644 (file)
index 0000000..19fced7
--- /dev/null
@@ -0,0 +1 @@
+PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIERlc3RpbmF0aW9uPSJodHRwczovL2xvY2FsaG9zdC9vYXV0aDIvY2FsbGJhY2svc2FtbCIgSUQ9IklEX2M0NWVjNTk1LTUwNDUtNDkzOS1iYTViLTE4MDRiNTBhZDQwMiIgSW5SZXNwb25zZVRvPSJPTkVMT0dJTl81ZTAzNzM3My0wYjE4LTQ1M2UtOTdhMC0wNWI1NjA2OTkzNzEiIElzc3VlSW5zdGFudD0iMjAyMC0wNi0wOFQxNjowMDo0MC4zOTJaIiBWZXJzaW9uPSIyLjAiPg0KICAgIDxzYW1sOklzc3Vlcj5odHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvc29uYXJxdWJlPC9zYW1sOklzc3Vlcj4NCiAgICA8c2FtbHA6U3RhdHVzPg0KICAgICAgICA8c2FtbHA6U3RhdHVzQ29kZSBWYWx1ZT0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnN0YXR1czpTdWNjZXNzIi8+DQogICAgPC9zYW1scDpTdGF0dXM+DQogICAgPHNhbWw6QXNzZXJ0aW9uIHhtbG5zPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiBJRD0icGZ4OTg0YmQ1ZTQtNTI5ZS1lMjQ1LTU4YjQtYzljMDI1NTc4YjJjIiBJc3N1ZUluc3RhbnQ9IjIwMjAtMDYtMDhUMTY6MDA6NDAuMzkyWiIgVmVyc2lvbj0iMi4wIj4NCiAgICAgICAgPHNhbWw6SXNzdWVyPmh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9hdXRoL3JlYWxtcy9zb25hcnF1YmU8L3NhbWw6SXNzdWVyPjxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPg0KICA8ZHM6U2lnbmVkSW5mbz48ZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPg0KICAgIDxkczpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjcnNhLXNoYTEiLz4NCiAgPGRzOlJlZmVyZW5jZSBVUkk9IiNwZng5ODRiZDVlNC01MjllLWUyNDUtNThiNC1jOWMwMjU1NzhiMmMiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNzaGExIi8+PGRzOkRpZ2VzdFZhbHVlPnZYQllhaHlZajhzL2hEZzhBVDlqMFQyMjV5ST08L2RzOkRpZ2VzdFZhbHVlPjwvZHM6UmVmZXJlbmNlPjwvZHM6U2lnbmVkSW5mbz48ZHM6U2lnbmF0dXJlVmFsdWU+RDB0SFRVWXRXNXkrUHoyNXprNnh2ZnExeXhCSzI1Y3VLWDNwTzhWZG5LUlpQWm43Kzhsa20vZEZNYjVlYXVyRmxrMWJ6alY4N056WktaUk5YZjQyWW9uM0VEQW5oZWxjRUp2d2JDTERSVU80Y1VOdjlSNlRHYVIzMWFYYkNOU1l2c243OUFwaUdtOWZOUkkyYm8xNDI5S2crNllqYmo5MzBzRUtVd0sycjV5Z2FqZmZaVDFWS0lSbnFlTjhOUVN4RVNlMm9XYkpQSjJrSjM4TlV3WGRnN3M4L1dTamFSZ1JPeHVaeUZkelN2VXF2emwxZjNHUG5XeW9DMGpMOWZsMm1ZRDZ2ZGxSUThLWFN1VDJhYzVwRUZ3b3FRVjl3MmNmYUhHRXNmd1hic0MwSWI4T1VHNkUya1hvYTg1WlBEWVIwbXNEUVZIdVlFY1o1bmVCV0tRcGQvQ0wvVzNWaTl5eFZQUE9DN2UrVlFac29MdjB4ZmZ5Z2lEMkoySTJEeTN1TUhIb0VHaFRxUS9UdnpueUVSWThPa2FJMXh2WGpWNE02K0xXV2ZyQmhpTG5TeS9XeW9PNG12aXNLK212MVlPeGhOTTF0M1FUbVAzTWwxQzMwL2ZCSUhEZm1TaEhia0NFQnMrVE10Rk9RdVZ3Q01hc3g4TDJpVVc2ckh1Z0dUYyt3TXM5QWJkVnlDRGdSWG5lQkpjYm1ROXZRNXNGZFRLdHBZZk1BS0U2c1M3ZjJ2Z1VPVGhOQy9lSUJCQ2h0T3pXV3lmdnN1MEVoQnc5Y2NqL3RsTGtFY2haMFZJNHI2enhnajdaTG9xTWpJQlBUSDdteEZRanp0bUZ6K1ZwcExuUDY1KzR5VlZBdTZ0Sm10RmVZR0JjWXlaQ0ZQRHV5a3hpNkRMeTVtYmpIaTQ9PC9kczpTaWduYXR1cmVWYWx1ZT4NCjxkczpLZXlJbmZvPjxkczpYNTA5RGF0YT48ZHM6WDUwOUNlcnRpZmljYXRlPk1JSUY1ekNDQTgrZ0F3SUJBZ0lVSVh2OU9Wcy9YVWljZ1IxYnNWOXVjY1loSGZvd0RRWUpLb1pJaHZjTkFRRUxCUUF3Z1lJeEN6QUpCZ05WQkFZVEFrRlZNUTh3RFFZRFZRUUlEQVpIUlU1RlZrRXhFREFPQmdOVkJBY01CMVpGVWs1SlJWSXhEakFNQmdOVkJBb01CVk5QVGtGU01RMHdDd1lEVlFRTERBUlJWVUpGTVE4d0RRWURWUVFEREFaYWFYQmxibWN4SURBZUJna3Foa2lHOXcwQkNRRVdFVzV2Y21Wd2JIbEFaMjFoYVd3dVkyOXRNQjRYRFRJeU1EWXhNekV6TVRReU4xb1hEVE15TURZeE1ERXpNVFF5TjFvd2dZSXhDekFKQmdOVkJBWVRBa0ZWTVE4d0RRWURWUVFJREFaSFJVNUZWa0V4RURBT0JnTlZCQWNNQjFaRlVrNUpSVkl4RGpBTUJnTlZCQW9NQlZOUFRrRlNNUTB3Q3dZRFZRUUxEQVJSVlVKRk1ROHdEUVlEVlFRRERBWmFhWEJsYm1jeElEQWVCZ2txaGtpRzl3MEJDUUVXRVc1dmNtVndiSGxBWjIxaGFXd3VZMjl0TUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF1M25GWFl2SVllZHBSODRhWmtkby8zeUI1WEhNK1lDRkpjRHNWTzEwekVibExrbmZRc2lNUGExWGQ5VXN0bnB4dzZQL1N5eklKbU85amlNT2RlQ2VZOThhNzRqUDdkNEpQYU82aDNsOUliV0FjWWVpalFnOTU2bmxzVkZZM0ZIREdyKzdQYjhRY09BeVYzdjg5amlGOURGQjh3WFMrNVVmWXIyT2ZvUlJiNGxpMzllekR5RGRsNU9MbE0xMW5Fc3MyejFtRXYrc1VVbG9UY3lyZ2ozN1BzZ2V3a3Z5eW02dEZHU2drVjlaYTRTVlJoSEZ5VGhZMVZGcllaU0pGVG5hcFVZYVJjN2tNeHp3WC9BQUhVREpybVljYVZjNUI4T0RwNHcyQXhESmhlUXlDVmZYalBGYVVxQk1HMlUvcllmVlh1MFphN1BuL3ZVbzRVYVNUaHdDQktEZWhDd3orNjVUTGRBK054eUdEeG52WS9Ta3NPeUxMR0NtdTh0S2tYZHUwcHpubkloQlhFR3ZqVUlWUzdkNmEvOGdlZzkxTm9UV2F1M2kwUkYrRHcvNU45RFN6cGxkMTViUHRiNUNlM0JpZTE5dXZmdnVIOWVnK0Q4eC9oZkY2ZjNpbDRzUGxJS2RPL09WZE0yOExSZm1EcW1xUU5QdWR2YnF6N3h5NEFSdXhrNkFSYTRkK2FUOXpvdnB3dnhOR1RyN2gxbWRnT1V0VUNkSVhMM1NITmpkd2RBQXowdUNXenZFeGJGdStOUStWNStYbmt4NzFoeVBGdjkrRExWR0l1N0poZFlzODA2d0tzaE8xM05nYTM4aWc2Z3UzN2xwVmhmcFpYaEt5d1VpaWdHNkxYQWV5V1drTWsrdmxmOU1jWmRNQkQxNmRaUDRrVHN2UCtyUFZuVUNBd0VBQWFOVE1GRXdIUVlEVlIwT0JCWUVGSTVVVkx0VHlTdmJHcUg3VVA4eFRMNHd4WnEzTUI4R0ExVWRJd1FZTUJhQUZJNVVWTHRUeVN2YkdxSDdVUDh4VEw0d3hacTNNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnSUJBQkF0WHNLTld4MHNEREZBNTNxWjF6UnlXS1dBTW9oOTVwYXdGQ3JLZ1RFVzRackE3M3BhNzkwZUUxWSt2VDZxVVhLSTRsaTlza0lEYSs2cHNDZHhoWklySFBSQW5WWlZlQjIzNzNCeHI1YncvWFE4ZWxSQ2pXZU1VTGJZSjl0Z3NMVjBJOUNpRVAwYTZUbTh0MHlEVlhOVWZ4MzZFNWZrZ0xTcnhvUm84WEp6eEhiSkNuTFZYSGRhTkJ4T1Q3alZjb202V280UEIyYnNqVnpoSG02YW1uNWhacDRkTUhtME12MGxuMXdIOGpWbml6SFFCTHNHTXp2dmw1OCs5czFwUDE3Y2VSRGtwTkR6K0VReUErWkFycWtXMU1xdHdWaGJ6ejhRZ01wcmhmbEtrQXJyc0M3djA2SnY4ZnFVYm45THZ0WUs5SXdIVFg3SjhkRmNzTy9nVUM1UGV2WVQzbnJpTjNBemIyMGdnU1ExeU9FTW96dmo1VDk2UzZpdGZIUGl0N3Z5RVE4NEpQckVxZnVRRFpRL0xLWlFxZnZ1WFgxYUFHM1RVM1RNV0I5Vk1NRnNUdU1GUzhiZnJoTVg3N2cwVWQ0cUpjQk9ZT0gzaFI1OWFnU2RkMlFaTkxQM3pac1lRSExMUWtxOTRqZFRYS1RxbS93N21sUEZLVjU5SGpUYkhCaFR0eEJITWZ0L212dkxFdUM5S0tGZkFPWFlRNlYrczlOazBCVzRnZ0VmZXdhWDU4T0J1eTdJU3FSdFJGUEdpYTE4WVJ6ekhxa2hqdWJKWU1Qa0lmWXBGVmQrQzBJSTNGMGtkeThUdHBjY2p5S285YmNITUx4TzRuOFBEQWwxOTVDUHRoTWk4Z1V2VDAwOExHRW90cisza1hzb3VURVpUVDBnbFhLTGRPMlc8L2RzOlg1MDlDZXJ0aWZpY2F0ZT48L2RzOlg1MDlEYXRhPjwvZHM6S2V5SW5mbz48L2RzOlNpZ25hdHVyZT4NCiAgICAgICAgPHNhbWw6U3ViamVjdD4NCiAgICAgICAgICAgIDxzYW1sOk5hbWVJRCBGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OnVuc3BlY2lmaWVkIj5qb2huZG9lPC9zYW1sOk5hbWVJRD4NCiAgICAgICAgICAgIDxzYW1sOlN1YmplY3RDb25maXJtYXRpb24gTWV0aG9kPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6Y206YmVhcmVyIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uRGF0YSBJblJlc3BvbnNlVG89Ik9ORUxPR0lOXzVlMDM3MzczLTBiMTgtNDUzZS05N2EwLTA1YjU2MDY5OTM3MSIgTm90T25PckFmdGVyPSIyMDM5LTA2LTE0VDAyOjM5OjM4LjM5MloiIFJlY2lwaWVudD0iaHR0cHM6Ly9sb2NhbGhvc3Qvb2F1dGgyL2NhbGxiYWNrL3NhbWwiLz4NCiAgICAgICAgICAgIDwvc2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uPg0KICAgICAgICA8L3NhbWw6U3ViamVjdD4NCiAgICAgICAgPHNhbWw6Q29uZGl0aW9ucyBOb3RCZWZvcmU9IjIwMjAtMDYtMDhUMTY6MDA6MzguMzkyWiIgTm90T25PckFmdGVyPSIyMDM5LTA2LTE0VDAyOjM5OjM4LjM5MloiPg0KICAgICAgICAgICAgPHNhbWw6QXVkaWVuY2VSZXN0cmljdGlvbj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdWRpZW5jZT5NeUFwcDwvc2FtbDpBdWRpZW5jZT4NCiAgICAgICAgICAgIDwvc2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPg0KICAgICAgICA8L3NhbWw6Q29uZGl0aW9ucz4NCiAgICAgICAgPHNhbWw6QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50PSIyMDIwLTA2LTA4VDE2OjAwOjQwLjM5M1oiIFNlc3Npb25JbmRleD0iYWYyN2JiMTMtNmQxYy00MTMzLWFkNTMtMDVkN2MyNGZmZDM2OjowMjgxNWNkNS05ZWM5LTQ2NDktYTlmMC1kNWZkYjk1NTUxZGMiIFNlc3Npb25Ob3RPbk9yQWZ0ZXI9IjIwMzktMDYtMTRUMDI6Mzk6NDAuMzkzWiI+DQogICAgICAgICAgICA8c2FtbDpBdXRobkNvbnRleHQ+DQogICAgICAgICAgICAgICAgPHNhbWw6QXV0aG5Db250ZXh0Q2xhc3NSZWY+dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFjOmNsYXNzZXM6dW5zcGVjaWZpZWQ8L3NhbWw6QXV0aG5Db250ZXh0Q2xhc3NSZWY+DQogICAgICAgICAgICA8L3NhbWw6QXV0aG5Db250ZXh0Pg0KICAgICAgICA8L3NhbWw6QXV0aG5TdGF0ZW1lbnQ+DQogICAgICAgIDxzYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD4NCiAgICAgICAgICAgIDxzYW1sOkF0dHJpYnV0ZSBOYW1lPSJlbWFpbCIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+DQogICAgICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5qb2huZG9lQGVtYWlsLmNvbTwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT4NCiAgICAgICAgICAgIDwvc2FtbDpBdHRyaWJ1dGU+DQogICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGUgTmFtZT0ibG9naW4iIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI+am9obmRvZTwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT4NCiAgICAgICAgICAgIDwvc2FtbDpBdHRyaWJ1dGU+DQogICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGUgTmFtZT0iZ3JvdXBzIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmRldmVsb3Blcjwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPnByb2R1Y3QtbWFuYWdlcjwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPnNvbmFyLWFkbWluaXN0cmF0b3JzPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPg0KICAgICAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZT4NCiAgICAgICAgICAgIDxzYW1sOkF0dHJpYnV0ZSBOYW1lPSJuYW1lIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPkpvaG4gRG9lPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPg0KICAgICAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZT4NCiAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD4NCiAgICA8L3NhbWw6QXNzZXJ0aW9uPg0KPC9zYW1scDpSZXNwb25zZT4=
diff --git a/server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_minimal_response.txt b/server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_minimal_response.txt
new file mode 100644 (file)
index 0000000..37de1e3
--- /dev/null
@@ -0,0 +1 @@
+PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIERlc3RpbmF0aW9uPSJodHRwOi8vbG9jYWxob3N0OjkwMDAvb2F1dGgyL2NhbGxiYWNrL3NhbWwiIElEPSJJRF85ZjFjOTUyYy0zZDA0LTQyN2ItYTE3NS05NDk3ZmQ5NGM4MmYiIEluUmVzcG9uc2VUbz0iT05FTE9HSU5fYzhmNzUxYzgtZWQ4OS00MmNlLTlhMTgtZTQyMjk0NTI0NzQ4IiBJc3N1ZUluc3RhbnQ9IjIwMjAtMDYtMDVUMjI6NTg6NDUuMTg1WiIgVmVyc2lvbj0iMi4wIj4NCiAgICA8c2FtbDpJc3N1ZXI+aHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL3NvbmFycXViZTwvc2FtbDpJc3N1ZXI+DQogICAgPHNhbWxwOlN0YXR1cz4NCiAgICAgICAgPHNhbWxwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPg0KICAgIDwvc2FtbHA6U3RhdHVzPg0KICAgIDxzYW1sOkFzc2VydGlvbiB4bWxucz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9InBmeGI2YTcwOGQzLWI0ODctN2Y4ZS0xNjhjLWVjN2JmZjljYWVkOSIgSXNzdWVJbnN0YW50PSIyMDIwLTA2LTA1VDIyOjU4OjQ1LjE4NFoiIFZlcnNpb249IjIuMCI+DQogICAgICAgIDxzYW1sOklzc3Vlcj5odHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvc29uYXJxdWJlPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4NCiAgPGRzOlNpZ25lZEluZm8+PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4NCiAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIi8+DQogIDxkczpSZWZlcmVuY2UgVVJJPSIjcGZ4YjZhNzA4ZDMtYjQ4Ny03ZjhlLTE2OGMtZWM3YmZmOWNhZWQ5Ij48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT51RFVNb3VsVXQrdjNUZ29VZEN0Y2hHSHp3Mk09PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPmJsdnhTZFhuVWdpaGhSK3UzbzV5NC9yZUVvNHdzL2JnRERCMFRUaXlxSDJQOTQvUHR4Qkg4TXZEdjQyTStYZEd0WWtWQUdPRlpJMHN1U2ZIRURKY1A3SUFSeEc0MnBGaDZqQjVKbVMxWGlNa2NSYVR6amE5QkVmZ3cySUFhYWRyUkQxNGdUb1RaSVpVV3JyVnlGM1U0L0JHbEphRHRTTlI4ajRQaHNPaDR4Qk5jWUh0ZXY2YTVBYm5naVkzZjZXWERoQnVMZEhJSnhUL0RQRUxJZGFESFRtZzRRVEtYemVzbEFQZGxMQy9EUkdJbUh2MWZNTVp0Z0VQNEZqQWtxVFkzUDZvdmg1M09nVHp6dUJkOEp0SlhudFZsbXVyc0ZhbUpidERyZk0rS1lyemNrUXpRbEFlVGlBdFVzeDN6akJKYUUwRS9hdytHRzAyd2FFUmIxc25maVpSL3Q5M050KzlLNFhsYWhrcEsrUyt3QmFtc2pJQmNBZEIzVERLZ3U3MlA5NXpZRkkvRzRCQko1U3liLy9xVFRhY0JsUFhMMkFWNllrK1lMU1BDbzE1eEFnYzFTWVBxZ3ZaZ09hbVcwcTYrMHpJWFVHTk9HdGdaUStINGkwdDNmMG1jQ0tRcFNaeHBqdytOTUE4TDlDSS9uQkdEOWI4MTVsOUNQZmNNMDFlYzV3Qm1XRWRDcW9xMy9lN2hkTW5KM3V0M1hVZTRsSTBLcW05M0kyT3JpeVA5bWlsU0JiOWhjZ2I0bTVITjJRamQ3dzI3S3AyMVI2YmNXYTdhQWptazlLajJldkZGWEVlcXRvZGptRW1kb1ZJOXR2YkpQcWswcUh1SndJaFF2STIvNEtZckR2U2J0a2xodmJxQnBHQU5tTFpYTm8yeHBaS3R3WGtoOVVXNkNBPTwvZHM6U2lnbmF0dXJlVmFsdWU+DQo8ZHM6S2V5SW5mbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlGNXpDQ0E4K2dBd0lCQWdJVUlYdjlPVnMvWFVpY2dSMWJzVjl1Y2NZaEhmb3dEUVlKS29aSWh2Y05BUUVMQlFBd2dZSXhDekFKQmdOVkJBWVRBa0ZWTVE4d0RRWURWUVFJREFaSFJVNUZWa0V4RURBT0JnTlZCQWNNQjFaRlVrNUpSVkl4RGpBTUJnTlZCQW9NQlZOUFRrRlNNUTB3Q3dZRFZRUUxEQVJSVlVKRk1ROHdEUVlEVlFRRERBWmFhWEJsYm1jeElEQWVCZ2txaGtpRzl3MEJDUUVXRVc1dmNtVndiSGxBWjIxaGFXd3VZMjl0TUI0WERUSXlNRFl4TXpFek1UUXlOMW9YRFRNeU1EWXhNREV6TVRReU4xb3dnWUl4Q3pBSkJnTlZCQVlUQWtGVk1ROHdEUVlEVlFRSURBWkhSVTVGVmtFeEVEQU9CZ05WQkFjTUIxWkZVazVKUlZJeERqQU1CZ05WQkFvTUJWTlBUa0ZTTVEwd0N3WURWUVFMREFSUlZVSkZNUTh3RFFZRFZRUUREQVphYVhCbGJtY3hJREFlQmdrcWhraUc5dzBCQ1FFV0VXNXZjbVZ3YkhsQVoyMWhhV3d1WTI5dE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBdTNuRlhZdklZZWRwUjg0YVprZG8vM3lCNVhITStZQ0ZKY0RzVk8xMHpFYmxMa25mUXNpTVBhMVhkOVVzdG5weHc2UC9TeXpJSm1POWppTU9kZUNlWTk4YTc0alA3ZDRKUGFPNmgzbDlJYldBY1llaWpRZzk1Nm5sc1ZGWTNGSERHcis3UGI4UWNPQXlWM3Y4OWppRjlERkI4d1hTKzVVZllyMk9mb1JSYjRsaTM5ZXpEeURkbDVPTGxNMTFuRXNzMnoxbUV2K3NVVWxvVGN5cmdqMzdQc2dld2t2eXltNnRGR1Nna1Y5WmE0U1ZSaEhGeVRoWTFWRnJZWlNKRlRuYXBVWWFSYzdrTXh6d1gvQUFIVURKcm1ZY2FWYzVCOE9EcDR3MkF4REpoZVF5Q1ZmWGpQRmFVcUJNRzJVL3JZZlZYdTBaYTdQbi92VW80VWFTVGh3Q0JLRGVoQ3d6KzY1VExkQStOeHlHRHhudlkvU2tzT3lMTEdDbXU4dEtrWGR1MHB6bm5JaEJYRUd2alVJVlM3ZDZhLzhnZWc5MU5vVFdhdTNpMFJGK0R3LzVOOURTenBsZDE1YlB0YjVDZTNCaWUxOXV2ZnZ1SDllZytEOHgvaGZGNmYzaWw0c1BsSUtkTy9PVmRNMjhMUmZtRHFtcVFOUHVkdmJxejd4eTRBUnV4azZBUmE0ZCthVDl6b3Zwd3Z4TkdUcjdoMW1kZ09VdFVDZElYTDNTSE5qZHdkQUF6MHVDV3p2RXhiRnUrTlErVjUrWG5reDcxaHlQRnY5K0RMVkdJdTdKaGRZczgwNndLc2hPMTNOZ2EzOGlnNmd1MzdscFZoZnBaWGhLeXdVaWlnRzZMWEFleVdXa01rK3ZsZjlNY1pkTUJEMTZkWlA0a1RzdlArclBWblVDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRkk1VVZMdFR5U3ZiR3FIN1VQOHhUTDR3eFpxM01COEdBMVVkSXdRWU1CYUFGSTVVVkx0VHlTdmJHcUg3VVA4eFRMNHd4WnEzTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCQUJBdFhzS05XeDBzRERGQTUzcVoxelJ5V0tXQU1vaDk1cGF3RkNyS2dURVc0WnJBNzNwYTc5MGVFMVkrdlQ2cVVYS0k0bGk5c2tJRGErNnBzQ2R4aFpJckhQUkFuVlpWZUIyMzczQnhyNWJ3L1hROGVsUkNqV2VNVUxiWUo5dGdzTFYwSTlDaUVQMGE2VG04dDB5RFZYTlVmeDM2RTVma2dMU3J4b1JvOFhKenhIYkpDbkxWWEhkYU5CeE9UN2pWY29tNldvNFBCMmJzalZ6aEhtNmFtbjVoWnA0ZE1IbTBNdjBsbjF3SDhqVm5pekhRQkxzR016dnZsNTgrOXMxcFAxN2NlUkRrcE5EeitFUXlBK1pBcnFrVzFNcXR3Vmhieno4UWdNcHJoZmxLa0FycnNDN3YwNkp2OGZxVWJuOUx2dFlLOUl3SFRYN0o4ZEZjc08vZ1VDNVBldllUM25yaU4zQXpiMjBnZ1NRMXlPRU1venZqNVQ5NlM2aXRmSFBpdDd2eUVRODRKUHJFcWZ1UURaUS9MS1pRcWZ2dVhYMWFBRzNUVTNUTVdCOVZNTUZzVHVNRlM4YmZyaE1YNzdnMFVkNHFKY0JPWU9IM2hSNTlhZ1NkZDJRWk5MUDN6WnNZUUhMTFFrcTk0amRUWEtUcW0vdzdtbFBGS1Y1OUhqVGJIQmhUdHhCSE1mdC9tdnZMRXVDOUtLRmZBT1hZUTZWK3M5TmswQlc0Z2dFZmV3YVg1OE9CdXk3SVNxUnRSRlBHaWExOFlSenpIcWtoanViSllNUGtJZllwRlZkK0MwSUkzRjBrZHk4VHRwY2NqeUtvOWJjSE1MeE80bjhQREFsMTk1Q1B0aE1pOGdVdlQwMDhMR0VvdHIrM2tYc291VEVaVFQwZ2xYS0xkTzJXPC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+DQogICAgICAgIDxzYW1sOlN1YmplY3Q+DQogICAgICAgICAgICA8c2FtbDpOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDp1bnNwZWNpZmllZCI+am9obmRvZTwvc2FtbDpOYW1lSUQ+DQogICAgICAgICAgICA8c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uIE1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlciI+DQogICAgICAgICAgICAgICAgPHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgSW5SZXNwb25zZVRvPSJPTkVMT0dJTl9jOGY3NTFjOC1lZDg5LTQyY2UtOWExOC1lNDIyOTQ1MjQ3NDgiIE5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTozNzo0My4xODRaIiBSZWNpcGllbnQ9Imh0dHA6Ly9sb2NhbGhvc3Q6OTAwMC9vYXV0aDIvY2FsbGJhY2svc2FtbCIvPg0KICAgICAgICAgICAgPC9zYW1sOlN1YmplY3RDb25maXJtYXRpb24+DQogICAgICAgIDwvc2FtbDpTdWJqZWN0Pg0KICAgICAgICA8c2FtbDpDb25kaXRpb25zIE5vdEJlZm9yZT0iMjAyMC0wNi0wNVQyMjo1ODo0My4xODRaIiBOb3RPbk9yQWZ0ZXI9IjIwMzktMDYtMTFUMDk6Mzc6NDMuMTg0WiI+DQogICAgICAgICAgICA8c2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF1ZGllbmNlPk15QXBwPC9zYW1sOkF1ZGllbmNlPg0KICAgICAgICAgICAgPC9zYW1sOkF1ZGllbmNlUmVzdHJpY3Rpb24+DQogICAgICAgIDwvc2FtbDpDb25kaXRpb25zPg0KICAgICAgICA8c2FtbDpBdXRoblN0YXRlbWVudCBBdXRobkluc3RhbnQ9IjIwMjAtMDYtMDVUMjI6NTg6NDUuMTg1WiIgU2Vzc2lvbkluZGV4PSI4MjJhZWYyYS0wZDJlLTQyY2EtYTdiMS0wMjgzZDhhZjZjZmI6OjAyODE1Y2Q1LTllYzktNDY0OS1hOWYwLWQ1ZmRiOTU1NTFkYyIgU2Vzc2lvbk5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTozNzo0NS4xODVaIj4NCiAgICAgICAgICAgIDxzYW1sOkF1dGhuQ29udGV4dD4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3Nlczp1bnNwZWNpZmllZDwvc2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj4NCiAgICAgICAgICAgIDwvc2FtbDpBdXRobkNvbnRleHQ+DQogICAgICAgIDwvc2FtbDpBdXRoblN0YXRlbWVudD4NCiAgICAgICAgPHNhbWw6QXR0cmlidXRlU3RhdGVtZW50Pg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9Im5hbWUiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI+Sm9obiBEb2U8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9ImxvZ2luIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmpvaG5kb2U8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICA8L3NhbWw6QXR0cmlidXRlU3RhdGVtZW50Pg0KICAgIDwvc2FtbDpBc3NlcnRpb24+DQo8L3NhbWxwOlJlc3BvbnNlPg==
diff --git a/server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_response_without_login.txt b/server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_response_without_login.txt
new file mode 100644 (file)
index 0000000..5826b4f
--- /dev/null
@@ -0,0 +1 @@
+PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIERlc3RpbmF0aW9uPSJodHRwOi8vbG9jYWxob3N0OjkwMDAvb2F1dGgyL2NhbGxiYWNrL3NhbWwiIElEPSJJRF9lZTFlNzNkZi1iMWQ4LTQzODUtOGMxNC01YmJlYTZhYTJlMTkiIEluUmVzcG9uc2VUbz0iT05FTE9HSU5fMjY3ZTFiMDUtZTIzNy00YWIwLWFiYmItODZiNTBjNDJiMGQ5IiBJc3N1ZUluc3RhbnQ9IjIwMjAtMDYtMDVUMjM6MDU6MTAuNjQ2WiIgVmVyc2lvbj0iMi4wIj4NCiAgICA8c2FtbDpJc3N1ZXI+aHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL3NvbmFycXViZTwvc2FtbDpJc3N1ZXI+DQogICAgPHNhbWxwOlN0YXR1cz4NCiAgICAgICAgPHNhbWxwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPg0KICAgIDwvc2FtbHA6U3RhdHVzPg0KICAgIDxzYW1sOkFzc2VydGlvbiB4bWxucz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9InBmeDUzOTljNDIxLTcxZTYtYTIwYy00MmFhLTg3ZGZmOWY4OTA5YyIgSXNzdWVJbnN0YW50PSIyMDIwLTA2LTA1VDIzOjA1OjEwLjY0NVoiIFZlcnNpb249IjIuMCI+DQogICAgICAgIDxzYW1sOklzc3Vlcj5odHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvc29uYXJxdWJlPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4NCiAgPGRzOlNpZ25lZEluZm8+PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4NCiAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIi8+DQogIDxkczpSZWZlcmVuY2UgVVJJPSIjcGZ4NTM5OWM0MjEtNzFlNi1hMjBjLTQyYWEtODdkZmY5Zjg5MDljIj48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT40eERlSHhWWFArWElnK0VBNHlHdmxTQkx5YmM9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPkROQzhzSDJLMjFlSXNaTGYxREdzbS9hTHhqMC9BOVRpbEhqUjNJZlNMRDZSTHYzWlRCcnNaT1A3UFdDVnNjVklhQVRnT0d1TStCWVlYRGFaVVlNTDQvS1p5cVVDRFNkbWRqa0hSZUxYSXVnU1RoaHJDRTI0VElJbnFuaXpsdVV4dWtLQUJEUkp4RVZaZ01ocVZpcHVjSHdWdjBjQWlRd0xRWmphSjl5TGJ6b0lNL09RZjJ2NE8ySTJ5azJYZVBpKytXeUJwVGNPN2NIWVZBSHRlYURqUFFnYklMcUtWOHdTSW12NkQzL2kxSisrMk41L2IrRlp0Sk1RTEUwbUdzU0hiQUc2ZmNXekplSWlUK0tqNTdzVUd2RldQSGNqSVRPQU50WCtYd0VCaDZpWVFYb3FhOFZqMzhZOU9mbm9FcThwTHBCTjBHODdzY1dta29jRE12RVJuQ2NoTGY0VVJsQmJwRTZaaWJzNnNiUmdzcVRPR3pGNjhhNXVhZlBPNzFCRHh3Qy9wK1c2azlRYWVISXBFNTduYzN0cUNCV2ZuczR6dHJQUDVDRWRJS2VNbVpZRStQOURibnV2bE9lU1U4NmlhZVZ5SjB0NnIxYlo1QkNkQVNNUk9WaFRUZFc4MEtFTmVGdlltcUk1OCtXQWpja3VFeUViR3NhajJyNkpCUmlxc1JOaDlJa21vbkhGaEpOU3c4VjRIY3dubjVjd1p1Sk1WNWpiWlBGY3ByUE5vWUp3L3VuaGpFelVlWUdKOG1ldlVaQkpYWktCRDhXLzMzZHdaeUl4WFlIZDJuUXlPMlVTM2hudXhJZnA4bUZyYjduWVM4Zk9KL1UvY2pleDU2MDFKM3VmQ1FwQTZmM0lGeVVwOXZKS2IvWFIzK3hmdFlyMUhMNTBnY1h4cFp3PTwvZHM6U2lnbmF0dXJlVmFsdWU+DQo8ZHM6S2V5SW5mbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlGNXpDQ0E4K2dBd0lCQWdJVUlYdjlPVnMvWFVpY2dSMWJzVjl1Y2NZaEhmb3dEUVlKS29aSWh2Y05BUUVMQlFBd2dZSXhDekFKQmdOVkJBWVRBa0ZWTVE4d0RRWURWUVFJREFaSFJVNUZWa0V4RURBT0JnTlZCQWNNQjFaRlVrNUpSVkl4RGpBTUJnTlZCQW9NQlZOUFRrRlNNUTB3Q3dZRFZRUUxEQVJSVlVKRk1ROHdEUVlEVlFRRERBWmFhWEJsYm1jeElEQWVCZ2txaGtpRzl3MEJDUUVXRVc1dmNtVndiSGxBWjIxaGFXd3VZMjl0TUI0WERUSXlNRFl4TXpFek1UUXlOMW9YRFRNeU1EWXhNREV6TVRReU4xb3dnWUl4Q3pBSkJnTlZCQVlUQWtGVk1ROHdEUVlEVlFRSURBWkhSVTVGVmtFeEVEQU9CZ05WQkFjTUIxWkZVazVKUlZJeERqQU1CZ05WQkFvTUJWTlBUa0ZTTVEwd0N3WURWUVFMREFSUlZVSkZNUTh3RFFZRFZRUUREQVphYVhCbGJtY3hJREFlQmdrcWhraUc5dzBCQ1FFV0VXNXZjbVZ3YkhsQVoyMWhhV3d1WTI5dE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBdTNuRlhZdklZZWRwUjg0YVprZG8vM3lCNVhITStZQ0ZKY0RzVk8xMHpFYmxMa25mUXNpTVBhMVhkOVVzdG5weHc2UC9TeXpJSm1POWppTU9kZUNlWTk4YTc0alA3ZDRKUGFPNmgzbDlJYldBY1llaWpRZzk1Nm5sc1ZGWTNGSERHcis3UGI4UWNPQXlWM3Y4OWppRjlERkI4d1hTKzVVZllyMk9mb1JSYjRsaTM5ZXpEeURkbDVPTGxNMTFuRXNzMnoxbUV2K3NVVWxvVGN5cmdqMzdQc2dld2t2eXltNnRGR1Nna1Y5WmE0U1ZSaEhGeVRoWTFWRnJZWlNKRlRuYXBVWWFSYzdrTXh6d1gvQUFIVURKcm1ZY2FWYzVCOE9EcDR3MkF4REpoZVF5Q1ZmWGpQRmFVcUJNRzJVL3JZZlZYdTBaYTdQbi92VW80VWFTVGh3Q0JLRGVoQ3d6KzY1VExkQStOeHlHRHhudlkvU2tzT3lMTEdDbXU4dEtrWGR1MHB6bm5JaEJYRUd2alVJVlM3ZDZhLzhnZWc5MU5vVFdhdTNpMFJGK0R3LzVOOURTenBsZDE1YlB0YjVDZTNCaWUxOXV2ZnZ1SDllZytEOHgvaGZGNmYzaWw0c1BsSUtkTy9PVmRNMjhMUmZtRHFtcVFOUHVkdmJxejd4eTRBUnV4azZBUmE0ZCthVDl6b3Zwd3Z4TkdUcjdoMW1kZ09VdFVDZElYTDNTSE5qZHdkQUF6MHVDV3p2RXhiRnUrTlErVjUrWG5reDcxaHlQRnY5K0RMVkdJdTdKaGRZczgwNndLc2hPMTNOZ2EzOGlnNmd1MzdscFZoZnBaWGhLeXdVaWlnRzZMWEFleVdXa01rK3ZsZjlNY1pkTUJEMTZkWlA0a1RzdlArclBWblVDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRkk1VVZMdFR5U3ZiR3FIN1VQOHhUTDR3eFpxM01COEdBMVVkSXdRWU1CYUFGSTVVVkx0VHlTdmJHcUg3VVA4eFRMNHd4WnEzTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCQUJBdFhzS05XeDBzRERGQTUzcVoxelJ5V0tXQU1vaDk1cGF3RkNyS2dURVc0WnJBNzNwYTc5MGVFMVkrdlQ2cVVYS0k0bGk5c2tJRGErNnBzQ2R4aFpJckhQUkFuVlpWZUIyMzczQnhyNWJ3L1hROGVsUkNqV2VNVUxiWUo5dGdzTFYwSTlDaUVQMGE2VG04dDB5RFZYTlVmeDM2RTVma2dMU3J4b1JvOFhKenhIYkpDbkxWWEhkYU5CeE9UN2pWY29tNldvNFBCMmJzalZ6aEhtNmFtbjVoWnA0ZE1IbTBNdjBsbjF3SDhqVm5pekhRQkxzR016dnZsNTgrOXMxcFAxN2NlUkRrcE5EeitFUXlBK1pBcnFrVzFNcXR3Vmhieno4UWdNcHJoZmxLa0FycnNDN3YwNkp2OGZxVWJuOUx2dFlLOUl3SFRYN0o4ZEZjc08vZ1VDNVBldllUM25yaU4zQXpiMjBnZ1NRMXlPRU1venZqNVQ5NlM2aXRmSFBpdDd2eUVRODRKUHJFcWZ1UURaUS9MS1pRcWZ2dVhYMWFBRzNUVTNUTVdCOVZNTUZzVHVNRlM4YmZyaE1YNzdnMFVkNHFKY0JPWU9IM2hSNTlhZ1NkZDJRWk5MUDN6WnNZUUhMTFFrcTk0amRUWEtUcW0vdzdtbFBGS1Y1OUhqVGJIQmhUdHhCSE1mdC9tdnZMRXVDOUtLRmZBT1hZUTZWK3M5TmswQlc0Z2dFZmV3YVg1OE9CdXk3SVNxUnRSRlBHaWExOFlSenpIcWtoanViSllNUGtJZllwRlZkK0MwSUkzRjBrZHk4VHRwY2NqeUtvOWJjSE1MeE80bjhQREFsMTk1Q1B0aE1pOGdVdlQwMDhMR0VvdHIrM2tYc291VEVaVFQwZ2xYS0xkTzJXPC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+DQogICAgICAgIDxzYW1sOlN1YmplY3Q+DQogICAgICAgICAgICA8c2FtbDpOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDp1bnNwZWNpZmllZCI+am9obmRvZTwvc2FtbDpOYW1lSUQ+DQogICAgICAgICAgICA8c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uIE1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlciI+DQogICAgICAgICAgICAgICAgPHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgSW5SZXNwb25zZVRvPSJPTkVMT0dJTl8yNjdlMWIwNS1lMjM3LTRhYjAtYWJiYi04NmI1MGM0MmIwZDkiIE5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTo0NDowOC42NDVaIiBSZWNpcGllbnQ9Imh0dHA6Ly9sb2NhbGhvc3Q6OTAwMC9vYXV0aDIvY2FsbGJhY2svc2FtbCIvPg0KICAgICAgICAgICAgPC9zYW1sOlN1YmplY3RDb25maXJtYXRpb24+DQogICAgICAgIDwvc2FtbDpTdWJqZWN0Pg0KICAgICAgICA8c2FtbDpDb25kaXRpb25zIE5vdEJlZm9yZT0iMjAyMC0wNi0wNVQyMzowNTowOC42NDVaIiBOb3RPbk9yQWZ0ZXI9IjIwMzktMDYtMTFUMDk6NDQ6MDguNjQ1WiI+DQogICAgICAgICAgICA8c2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF1ZGllbmNlPk15QXBwPC9zYW1sOkF1ZGllbmNlPg0KICAgICAgICAgICAgPC9zYW1sOkF1ZGllbmNlUmVzdHJpY3Rpb24+DQogICAgICAgIDwvc2FtbDpDb25kaXRpb25zPg0KICAgICAgICA8c2FtbDpBdXRoblN0YXRlbWVudCBBdXRobkluc3RhbnQ9IjIwMjAtMDYtMDVUMjM6MDU6MTAuNjQ3WiIgU2Vzc2lvbkluZGV4PSJhODUzNWM1My1iZjdkLTRhZTctYWY4ZC0wNTZjYzgwZTEzOTk6OjAyODE1Y2Q1LTllYzktNDY0OS1hOWYwLWQ1ZmRiOTU1NTFkYyIgU2Vzc2lvbk5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTo0NDoxMC42NDdaIj4NCiAgICAgICAgICAgIDxzYW1sOkF1dGhuQ29udGV4dD4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3Nlczp1bnNwZWNpZmllZDwvc2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj4NCiAgICAgICAgICAgIDwvc2FtbDpBdXRobkNvbnRleHQ+DQogICAgICAgIDwvc2FtbDpBdXRoblN0YXRlbWVudD4NCiAgICAgICAgPHNhbWw6QXR0cmlidXRlU3RhdGVtZW50Pg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9Im5hbWUiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI+Sm9obiBEb2U8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9Imdyb3VwcyIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+DQogICAgICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5kZXZlbG9wZXI8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5wcm9kdWN0LW1hbmFnZXI8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9ImVtYWlsIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmpvaG5kb2VAZW1haWwuY29tPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPg0KICAgICAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZT4NCiAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD4NCiAgICA8L3NhbWw6QXNzZXJ0aW9uPg0KPC9zYW1scDpSZXNwb25zZT4=
diff --git a/server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_response_without_name.txt b/server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/encoded_response_without_name.txt
new file mode 100644 (file)
index 0000000..4dc183e
--- /dev/null
@@ -0,0 +1 @@
+PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIERlc3RpbmF0aW9uPSJodHRwOi8vbG9jYWxob3N0OjkwMDAvb2F1dGgyL2NhbGxiYWNrL3NhbWwiIElEPSJJRF8wOGI3NzQxZS1lNjkwLTRiY2UtYjY4OS00YWY5NmEzMTZkYmYiIEluUmVzcG9uc2VUbz0iT05FTE9HSU5fZGE0ODgyODYtMDM3Yy00MWZjLWEwZGEtZmI5Njg1ZWU3NWMxIiBJc3N1ZUluc3RhbnQ9IjIwMjAtMDYtMDVUMjM6MDc6MjUuNjc1WiIgVmVyc2lvbj0iMi4wIj4NCiAgICA8c2FtbDpJc3N1ZXI+aHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL3NvbmFycXViZTwvc2FtbDpJc3N1ZXI+DQogICAgPHNhbWxwOlN0YXR1cz4NCiAgICAgICAgPHNhbWxwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPg0KICAgIDwvc2FtbHA6U3RhdHVzPg0KICAgIDxzYW1sOkFzc2VydGlvbiB4bWxucz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9InBmeDE4YzYyMzM2LTI1NmItN2YwZS03MGY0LTI5ZWRjMjFlNGM1MSIgSXNzdWVJbnN0YW50PSIyMDIwLTA2LTA1VDIzOjA3OjI1LjY3NVoiIFZlcnNpb249IjIuMCI+DQogICAgICAgIDxzYW1sOklzc3Vlcj5odHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvc29uYXJxdWJlPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4NCiAgPGRzOlNpZ25lZEluZm8+PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4NCiAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIi8+DQogIDxkczpSZWZlcmVuY2UgVVJJPSIjcGZ4MThjNjIzMzYtMjU2Yi03ZjBlLTcwZjQtMjllZGMyMWU0YzUxIj48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT4zdHlYQjA1MXlTMHNQSDd5TWxwWmJUQXVOKzA9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPkFSLzUvNmcwWXR6MWl5L3VrMWovbmNwU3JCK1UycHI2NUk5TU02TGxTdHpGZzgzRlJyMXFnQ3FMZDBPQkJHN2V1dndJNkVwUVowRmNldDZaZWU4WmtkS0xDQWozK2taSXBMRjdtQnlJdzdnOGdKODJXMVV4Rm00UGZzQ2hERTdOQVlQdzRuNEdsNENyU0g0MUN0RGliYlJLeTZ4Tlg1Vmo1bE5ORWp0R2pEZ0VNTkxLalB4QWdCVnhnWjBZdE9lS0RuYXFwdm5NcnI1eHdhZkpqMVdXTWRnUklHVStjdGZCWkVxRHJNN29MN245eWR0NXZieXNjcjh1TGFZQVJCeVBGckJsa1QyMi85VVdkM0Z4eEp3cXQ1ZnZaQ3E3UkVJMWNXLzBRWnYyNEhVbnozMzRHWU05S3pjelJjL3pGbDlITlBpUHNNUEthWUtnTXJKcEtQVDdnYWlTRXg4MXp5eHlNbUNyV3FIWVNrZHErN1dFcEpzY21qYWtUNUZsb1o0QVVyVVBSVEZXTmVhd056bkt3cEtVa0t0OWRIZVp2SENyaXUySEd2d2tnVy9kK1NSS25xSmdrWTZaWXl6RDBoMzQzMDl6TUY5Z3FvSU9DQXZiUEZ2em80cHRoOEYrM2VjTHJvM0c0QWdzWHNvejlyWlpJV0FMYXhqNjdiZVdFTzZPUkJ1NWpKMVh5S29MdWJKMGhSZjgvRGVCa1k4VDZGSklLc09MMU5BdkVlcFp0dWc0LzVGVXNUbmpDc29wNjNQei9DcU5QeXNBT1A1cHdBS0tVeWdFOW5zNTU3R1ZZUHc4NldNbEN2NS84STRjV0JvRlEySEl6OVJZcXphVDJtSlhmbDczWEhuNkJxRkpBNEpwaW5hWGh2akFzaDU3R1dtbWovTit4SWpPRjYwPTwvZHM6U2lnbmF0dXJlVmFsdWU+DQo8ZHM6S2V5SW5mbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlGNXpDQ0E4K2dBd0lCQWdJVUlYdjlPVnMvWFVpY2dSMWJzVjl1Y2NZaEhmb3dEUVlKS29aSWh2Y05BUUVMQlFBd2dZSXhDekFKQmdOVkJBWVRBa0ZWTVE4d0RRWURWUVFJREFaSFJVNUZWa0V4RURBT0JnTlZCQWNNQjFaRlVrNUpSVkl4RGpBTUJnTlZCQW9NQlZOUFRrRlNNUTB3Q3dZRFZRUUxEQVJSVlVKRk1ROHdEUVlEVlFRRERBWmFhWEJsYm1jeElEQWVCZ2txaGtpRzl3MEJDUUVXRVc1dmNtVndiSGxBWjIxaGFXd3VZMjl0TUI0WERUSXlNRFl4TXpFek1UUXlOMW9YRFRNeU1EWXhNREV6TVRReU4xb3dnWUl4Q3pBSkJnTlZCQVlUQWtGVk1ROHdEUVlEVlFRSURBWkhSVTVGVmtFeEVEQU9CZ05WQkFjTUIxWkZVazVKUlZJeERqQU1CZ05WQkFvTUJWTlBUa0ZTTVEwd0N3WURWUVFMREFSUlZVSkZNUTh3RFFZRFZRUUREQVphYVhCbGJtY3hJREFlQmdrcWhraUc5dzBCQ1FFV0VXNXZjbVZ3YkhsQVoyMWhhV3d1WTI5dE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBdTNuRlhZdklZZWRwUjg0YVprZG8vM3lCNVhITStZQ0ZKY0RzVk8xMHpFYmxMa25mUXNpTVBhMVhkOVVzdG5weHc2UC9TeXpJSm1POWppTU9kZUNlWTk4YTc0alA3ZDRKUGFPNmgzbDlJYldBY1llaWpRZzk1Nm5sc1ZGWTNGSERHcis3UGI4UWNPQXlWM3Y4OWppRjlERkI4d1hTKzVVZllyMk9mb1JSYjRsaTM5ZXpEeURkbDVPTGxNMTFuRXNzMnoxbUV2K3NVVWxvVGN5cmdqMzdQc2dld2t2eXltNnRGR1Nna1Y5WmE0U1ZSaEhGeVRoWTFWRnJZWlNKRlRuYXBVWWFSYzdrTXh6d1gvQUFIVURKcm1ZY2FWYzVCOE9EcDR3MkF4REpoZVF5Q1ZmWGpQRmFVcUJNRzJVL3JZZlZYdTBaYTdQbi92VW80VWFTVGh3Q0JLRGVoQ3d6KzY1VExkQStOeHlHRHhudlkvU2tzT3lMTEdDbXU4dEtrWGR1MHB6bm5JaEJYRUd2alVJVlM3ZDZhLzhnZWc5MU5vVFdhdTNpMFJGK0R3LzVOOURTenBsZDE1YlB0YjVDZTNCaWUxOXV2ZnZ1SDllZytEOHgvaGZGNmYzaWw0c1BsSUtkTy9PVmRNMjhMUmZtRHFtcVFOUHVkdmJxejd4eTRBUnV4azZBUmE0ZCthVDl6b3Zwd3Z4TkdUcjdoMW1kZ09VdFVDZElYTDNTSE5qZHdkQUF6MHVDV3p2RXhiRnUrTlErVjUrWG5reDcxaHlQRnY5K0RMVkdJdTdKaGRZczgwNndLc2hPMTNOZ2EzOGlnNmd1MzdscFZoZnBaWGhLeXdVaWlnRzZMWEFleVdXa01rK3ZsZjlNY1pkTUJEMTZkWlA0a1RzdlArclBWblVDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRkk1VVZMdFR5U3ZiR3FIN1VQOHhUTDR3eFpxM01COEdBMVVkSXdRWU1CYUFGSTVVVkx0VHlTdmJHcUg3VVA4eFRMNHd4WnEzTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCQUJBdFhzS05XeDBzRERGQTUzcVoxelJ5V0tXQU1vaDk1cGF3RkNyS2dURVc0WnJBNzNwYTc5MGVFMVkrdlQ2cVVYS0k0bGk5c2tJRGErNnBzQ2R4aFpJckhQUkFuVlpWZUIyMzczQnhyNWJ3L1hROGVsUkNqV2VNVUxiWUo5dGdzTFYwSTlDaUVQMGE2VG04dDB5RFZYTlVmeDM2RTVma2dMU3J4b1JvOFhKenhIYkpDbkxWWEhkYU5CeE9UN2pWY29tNldvNFBCMmJzalZ6aEhtNmFtbjVoWnA0ZE1IbTBNdjBsbjF3SDhqVm5pekhRQkxzR016dnZsNTgrOXMxcFAxN2NlUkRrcE5EeitFUXlBK1pBcnFrVzFNcXR3Vmhieno4UWdNcHJoZmxLa0FycnNDN3YwNkp2OGZxVWJuOUx2dFlLOUl3SFRYN0o4ZEZjc08vZ1VDNVBldllUM25yaU4zQXpiMjBnZ1NRMXlPRU1venZqNVQ5NlM2aXRmSFBpdDd2eUVRODRKUHJFcWZ1UURaUS9MS1pRcWZ2dVhYMWFBRzNUVTNUTVdCOVZNTUZzVHVNRlM4YmZyaE1YNzdnMFVkNHFKY0JPWU9IM2hSNTlhZ1NkZDJRWk5MUDN6WnNZUUhMTFFrcTk0amRUWEtUcW0vdzdtbFBGS1Y1OUhqVGJIQmhUdHhCSE1mdC9tdnZMRXVDOUtLRmZBT1hZUTZWK3M5TmswQlc0Z2dFZmV3YVg1OE9CdXk3SVNxUnRSRlBHaWExOFlSenpIcWtoanViSllNUGtJZllwRlZkK0MwSUkzRjBrZHk4VHRwY2NqeUtvOWJjSE1MeE80bjhQREFsMTk1Q1B0aE1pOGdVdlQwMDhMR0VvdHIrM2tYc291VEVaVFQwZ2xYS0xkTzJXPC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+DQogICAgICAgIDxzYW1sOlN1YmplY3Q+DQogICAgICAgICAgICA8c2FtbDpOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDp1bnNwZWNpZmllZCI+am9obmRvZTwvc2FtbDpOYW1lSUQ+DQogICAgICAgICAgICA8c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uIE1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlciI+DQogICAgICAgICAgICAgICAgPHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgSW5SZXNwb25zZVRvPSJPTkVMT0dJTl9kYTQ4ODI4Ni0wMzdjLTQxZmMtYTBkYS1mYjk2ODVlZTc1YzEiIE5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTo0NjoyMy42NzVaIiBSZWNpcGllbnQ9Imh0dHA6Ly9sb2NhbGhvc3Q6OTAwMC9vYXV0aDIvY2FsbGJhY2svc2FtbCIvPg0KICAgICAgICAgICAgPC9zYW1sOlN1YmplY3RDb25maXJtYXRpb24+DQogICAgICAgIDwvc2FtbDpTdWJqZWN0Pg0KICAgICAgICA8c2FtbDpDb25kaXRpb25zIE5vdEJlZm9yZT0iMjAyMC0wNi0wNVQyMzowNzoyMy42NzVaIiBOb3RPbk9yQWZ0ZXI9IjIwMzktMDYtMTFUMDk6NDY6MjMuNjc1WiI+DQogICAgICAgICAgICA8c2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF1ZGllbmNlPk15QXBwPC9zYW1sOkF1ZGllbmNlPg0KICAgICAgICAgICAgPC9zYW1sOkF1ZGllbmNlUmVzdHJpY3Rpb24+DQogICAgICAgIDwvc2FtbDpDb25kaXRpb25zPg0KICAgICAgICA8c2FtbDpBdXRoblN0YXRlbWVudCBBdXRobkluc3RhbnQ9IjIwMjAtMDYtMDVUMjM6MDc6MjUuNjc2WiIgU2Vzc2lvbkluZGV4PSIwODljNjA2Yi0zMjVmLTQ0NDktODM1NS1hNTQ5NWNiZTRjNGM6OjAyODE1Y2Q1LTllYzktNDY0OS1hOWYwLWQ1ZmRiOTU1NTFkYyIgU2Vzc2lvbk5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTo0NjoyNS42NzZaIj4NCiAgICAgICAgICAgIDxzYW1sOkF1dGhuQ29udGV4dD4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3Nlczp1bnNwZWNpZmllZDwvc2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj4NCiAgICAgICAgICAgIDwvc2FtbDpBdXRobkNvbnRleHQ+DQogICAgICAgIDwvc2FtbDpBdXRoblN0YXRlbWVudD4NCiAgICAgICAgPHNhbWw6QXR0cmlidXRlU3RhdGVtZW50Pg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9ImxvZ2luIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmpvaG5kb2U8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9Imdyb3VwcyIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+DQogICAgICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5kZXZlbG9wZXI8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5wcm9kdWN0LW1hbmFnZXI8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9ImVtYWlsIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmpvaG5kb2VAZW1haWwuY29tPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPg0KICAgICAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZT4NCiAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD4NCiAgICA8L3NhbWw6QXNzZXJ0aW9uPg0KPC9zYW1scDpSZXNwb25zZT4=
diff --git a/server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/how_to_generate_test_response.txt b/server/sonar-auth-saml/src/it/resources/org/sonar/auth/saml/SamlIdentityProviderIT/how_to_generate_test_response.txt
new file mode 100644 (file)
index 0000000..bd832ee
--- /dev/null
@@ -0,0 +1,6 @@
+# How to generate test responses for unit tests requiring encoded user response
+
+1. Set the server log in TRACE
+2. Login with a user
+3. Search in the logs for "[c.o.saml2.Auth] processResponse success -->"
+4. The value after the "-->" is the encoded response that can be used in test
\ No newline at end of file
diff --git a/server/sonar-auth-saml/src/test/java/org/sonar/auth/saml/SamlIdentityProviderTest.java b/server/sonar-auth-saml/src/test/java/org/sonar/auth/saml/SamlIdentityProviderTest.java
deleted file mode 100644 (file)
index 00add6e..0000000
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.auth.saml;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicBoolean;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.apache.commons.io.IOUtils;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.api.config.internal.MapSettings;
-import org.sonar.api.server.authentication.OAuth2IdentityProvider;
-import org.sonar.api.server.authentication.UnauthorizedException;
-import org.sonar.api.server.authentication.UserIdentity;
-import org.sonar.api.utils.System2;
-import org.sonar.api.utils.log.LogAndArguments;
-import org.sonar.api.utils.log.LogTester;
-import org.sonar.db.DbTester;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.sonar.api.utils.log.LoggerLevel.ERROR;
-
-public class SamlIdentityProviderTest {
-  private static final String SQ_CALLBACK_URL = "http://localhost:9000/oauth2/callback/saml";
-
-  /* IDP private key (keep here for future tests with signature)
------BEGIN PRIVATE KEY-----MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQC7ecVdi8hh52lHzhpmR2j/fIHlccz5gIUlwOxU7XTMRuUuSd9CyIw9rVd31Sy2enHDo/9LLMgmY72OIw514J5j3xrviM/t3gk9o7qHeX0htYBxh6KNCD3nqeWxUVjcUcMav7s9vxBw4DJXe/z2OIX0MUHzBdL7lR9ivY5+hFFviWLf17MPIN2Xk4uUzXWcSyzbPWYS/6xRSWhNzKuCPfs+yB7CS/LKbq0UZKCRX1lrhJVGEcXJOFjVUWthlIkVOdqlRhpFzuQzHPBf8AAdQMmuZhxpVzkHw4OnjDYDEMmF5DIJV9eM8VpSoEwbZT+th9Ve7Rlrs+f+9SjhRpJOHAIEoN6ELDP7rlMt0D43HIYPGe9j9KSw7IssYKa7y0qRd27SnOeciEFcQa+NQhVLt3pr/yB6D3U2hNZq7eLREX4PD/k30NLOmV3Xls+1vkJ7cGJ7X269++4f16D4PzH+F8Xp/eKXiw+Ugp0785V0zbwtF+YOqapA0+529urPvHLgBG7GToBFrh35pP3Oi+nC/E0ZOvuHWZ2A5S1QJ0hcvdIc2N3B0ADPS4JbO8TFsW741D5Xn5eeTHvWHI8W/34MtUYi7smF1izzTrAqyE7Xc2BrfyKDqC7fuWlWF+lleErLBSKKAbotcB7JZaQyT6+V/0xxl0wEPXp1k/iROy8/6s9WdQIDAQABAoICAC34UAL+MaaAHfqzeRm3TPHIz/k5DG/pqbx2L/0rNMaaY7wT9SDlGC5PgPErXoloQNkeL415b6KqNmLSCcuxxmTq4in2PDYxicaJjUWG7r4DSXmNLriyWquhp2bxcX6ktdirRvh/D0L+VpnJF2Awv/f+1BMJTJDQIiAOJxCy1V0qLQqCU6/T+UIftcxJDRvD+z3PMmZaNyC/hUn+c9e95wuf+preEKy+ssYbXpwG62BH5GqIFR2gKXg1PMVyrKJ9yzVXmT2g26gE4pRDv2Ns7YdMFo9mCd/zeybsZJof1ap1KCfOWFaBIAq+r6rQCus8MX/TV7ZnKO4Fo36J1Xo9t+iKGpvw2nwrN7I71MT3c8wglfg2zmgFqjNYdeUDFOrl0GXRboBcDSX4dd5iB9fkqZ9dOqTtTzPQNwEhbDqLyYQ6I+00nihW8xzEUaiqd4tey7WXoqae3u0Bo7ep5jbE7dzKWxiBKaqlfI+S4aWDkhUiwkUKvkSC3SXWWehJbaVQZb5+DvSjWU5nLQxcVZdMl9Lp7kE0+nEeS1hO8C1r482jlXKppl9k0GjkoIRzU9RARxHNt1UvHURa43CQ/4nIGNsK9WeYVxk2vR/qozCE6dKIRv+5gZrD32YM2UrPf8kAAQOSpW4iumtWuqkrysr3/04f40mCtLV1uNF6EQcV+WfJAoIBAQC+A4JoY7gMrEf0EmRVhNbAuRkt67ENz8PBr8NvDlgIVM9ZdjeVFYSKWeL+TbkwihBoSqhn5wgAs5RhiNGjwqgL+odHVY/9KirQDvcdsy8/NaheYd+JJLAyCOLJKAc/C7VaZ5fFpHWOKRkUPVOliK955+3cxLp37q1+10p4406i6JIWphzqNt8rCpEQgXydIfEgDY8IDoEs65+9JcutFkH2MtQR1ypH0uLPvNCVZu8SNitmcvERq2/mJ4U1+8rIhAJhbq9uvaSXBSKFSzK62hdxvOLvMIlKFcEia8xTBCO9MbLxIbSH2Ht69HSCmZSytaHBodOb7qBcLjOQD5ZXMPGjAoIBAQD8lKBHrYUT8Cd39B5IkdeU6tVbiJ80Lb2E2ePLbg3/Dx9NsmzXrvLeHI60+gpxP+GlI/h2IzUvLsOuEf5ICjmu9NrnK2lJJmS/pCZlKxEV0k1T0fyITMyjk0iy9Vb70+PF3CDextnEY3zzhkHj7iaXqXIf1zs2ypm3zTGsGLdLXT+5Fm2sxdhLUKGIwfflaUruyLTyE/OiArDrezqgX7CVlF4Q2zgQZqRHDODxt09fJbz0FU422y02Hv/sG5cYFB5C24upwe3dIXrFyM9xuZnTUpM8z8DLPeLShKUUqsiL/qyhxLbXgdGkXsDaPrX31eTX99gG3AX9WoxENLQzvgkHAoIBABkSzXqI7hh+A2CprKO8S7pSsofkuhBggixkzR0yf1taFaJwfxUlKcA37EQybWWCUnfwohhT3DJ7f/D+5Or/HL236XH4UG/PyKZ70xAQPQPSSM1rjNvEA5wWoBZ7ObmQCfZMBTMHaJvBwJVzIj6NstobSMABFboNvMcoEaOyGwZUOjLS6K3fX8OGOW48J/10JSVdpKojf9g1n3aOLjpA3aNnQaS5B9NCeLuA5uVQF+wHSeLS+Ayk2rc8L8/X0gJzqPzCZlPuonFrNAryyVbuwHk5u5hkhzlHdZzdLLEnsq+ch0hackAayPCIoXc6XOzYGug6OnoxGugPEK7J38TRqJECggEAdXZxK6RotSMEV+axhrI8fcbQPmdFErEK6BOkumCOJcXUmv+VWqDD1cOWIlf+Lzi0KWaXD+nDvBOVcQhxJvOKa/D3NHad2iT+yZj/OiFTKsDIsWiAdqqwqInAT2mFcEvUK5n5t2DmuUxDOcWAMw336KQmrOQdZ5fE8RN+PDiqVWQiVGM30heYRT5UQRNjw865yF6St9nLfdaejISceSTHLGj5bgFlC0uQrnIw0nibcvZL739RBnXbisXT4uvZ0prYj+MmCmZjxmjhfcWro4nbHcnTK366fEplh92kH/5kkaZ4hirDlWmMI1LlgRmU6pMQf9eFIXuFVZOck8Om4kFIVQKCAQARCxrge8m+hOTJ7EkNtxor+o+4XioZSQ+Ht9lNOL+Ry1J08fldWwM8P4cpVE7WHi+73UM7NlJDLRaCCgS13C7FoW1klK1Rt3VtJRUF4Ic6B8RcLZQrOAp4sfbCLeT/PomexJ6KURdXof3GaTdij3F149NsNoje1VPEBLq5GE9j8vbPI/pyhJxfXzWtKXUGkNG9fC0oH7NjWqTDVoBiyUbZurCY8KN5oIh40UwJnUqvgu6gaUItfStmJn78VgsFZLTJvPcfnir+q9mOVp8WBYE3jrPYEhWtEP2MaG+nAGBi7AuRZ0tCsOL+s8ADNyzOx9WtFQcXryn6b7+BjIEbSrjg-----END PRIVATE KEY-----
-   */
-
-  private static final String IDP_CERTIFICATE = "-----BEGIN CERTIFICATE-----MIIF5zCCA8+gAwIBAgIUIXv9OVs/XUicgR1bsV9uccYhHfowDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYTAkFVMQ8wDQYDVQQIDAZHRU5FVkExEDAOBgNVBAcMB1ZFUk5JRVIxDjAMBgNVBAoMBVNPTkFSMQ0wCwYDVQQLDARRVUJFMQ8wDQYDVQQDDAZaaXBlbmcxIDAeBgkqhkiG9w0BCQEWEW5vcmVwbHlAZ21haWwuY29tMB4XDTIyMDYxMzEzMTQyN1oXDTMyMDYxMDEzMTQyN1owgYIxCzAJBgNVBAYTAkFVMQ8wDQYDVQQIDAZHRU5FVkExEDAOBgNVBAcMB1ZFUk5JRVIxDjAMBgNVBAoMBVNPTkFSMQ0wCwYDVQQLDARRVUJFMQ8wDQYDVQQDDAZaaXBlbmcxIDAeBgkqhkiG9w0BCQEWEW5vcmVwbHlAZ21haWwuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAu3nFXYvIYedpR84aZkdo/3yB5XHM+YCFJcDsVO10zEblLknfQsiMPa1Xd9Ustnpxw6P/SyzIJmO9jiMOdeCeY98a74jP7d4JPaO6h3l9IbWAcYeijQg956nlsVFY3FHDGr+7Pb8QcOAyV3v89jiF9DFB8wXS+5UfYr2OfoRRb4li39ezDyDdl5OLlM11nEss2z1mEv+sUUloTcyrgj37Psgewkvyym6tFGSgkV9Za4SVRhHFyThY1VFrYZSJFTnapUYaRc7kMxzwX/AAHUDJrmYcaVc5B8ODp4w2AxDJheQyCVfXjPFaUqBMG2U/rYfVXu0Za7Pn/vUo4UaSThwCBKDehCwz+65TLdA+NxyGDxnvY/SksOyLLGCmu8tKkXdu0pznnIhBXEGvjUIVS7d6a/8geg91NoTWau3i0RF+Dw/5N9DSzpld15bPtb5Ce3Bie19uvfvuH9eg+D8x/hfF6f3il4sPlIKdO/OVdM28LRfmDqmqQNPudvbqz7xy4ARuxk6ARa4d+aT9zovpwvxNGTr7h1mdgOUtUCdIXL3SHNjdwdAAz0uCWzvExbFu+NQ+V5+Xnkx71hyPFv9+DLVGIu7JhdYs806wKshO13Nga38ig6gu37lpVhfpZXhKywUiigG6LXAeyWWkMk+vlf9McZdMBD16dZP4kTsvP+rPVnUCAwEAAaNTMFEwHQYDVR0OBBYEFI5UVLtTySvbGqH7UP8xTL4wxZq3MB8GA1UdIwQYMBaAFI5UVLtTySvbGqH7UP8xTL4wxZq3MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBABAtXsKNWx0sDDFA53qZ1zRyWKWAMoh95pawFCrKgTEW4ZrA73pa790eE1Y+vT6qUXKI4li9skIDa+6psCdxhZIrHPRAnVZVeB2373Bxr5bw/XQ8elRCjWeMULbYJ9tgsLV0I9CiEP0a6Tm8t0yDVXNUfx36E5fkgLSrxoRo8XJzxHbJCnLVXHdaNBxOT7jVcom6Wo4PB2bsjVzhHm6amn5hZp4dMHm0Mv0ln1wH8jVnizHQBLsGMzvvl58+9s1pP17ceRDkpNDz+EQyA+ZArqkW1MqtwVhbzz8QgMprhflKkArrsC7v06Jv8fqUbn9LvtYK9IwHTX7J8dFcsO/gUC5PevYT3nriN3Azb20ggSQ1yOEMozvj5T96S6itfHPit7vyEQ84JPrEqfuQDZQ/LKZQqfvuXX1aAG3TU3TMWB9VMMFsTuMFS8bfrhMX77g0Ud4qJcBOYOH3hR59agSdd2QZNLP3zZsYQHLLQkq94jdTXKTqm/w7mlPFKV59HjTbHBhTtxBHMft/mvvLEuC9KKFfAOXYQ6V+s9Nk0BW4ggEfewaX58OBuy7ISqRtRFPGia18YRzzHqkhjubJYMPkIfYpFVd+C0II3F0kdy8TtpccjyKo9bcHMLxO4n8PDAl195CPthMi8gUvT008LGEotr+3kXsouTEZTT0glXKLdO2W-----END CERTIFICATE-----";
-
-  private static final String SP_CERTIFICATE = "MIICoTCCAYkCBgGBXPscaDANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAlzb25hcnF1YmUwHhcNMjIwNjEzMTIxMTA5WhcNMzIwNjEzMTIxMjQ5WjAUMRIwEAYDVQQDDAlzb25hcnF1YmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDSFoT371C0/klZuPgvKbGItkmTaf5CweNXL8u389d98aOXRpDQ7maTXdV/W+VcL8vUWg8yG6nn8CRwweYnGTNdn9UAdhgknvxQe3pq3EwOJyls4Fpiq6YTh+DQfiZUQizjFjDOr/GG5O2lNvTRkI4XZj/XnWjRqVZwttiA5tm1sKkvGdyOQljwn4Jja/VbITdV8GASumx66Bil/wamSsqIzm2RjsOOGSsf5VjYUPwDobpuSf+j4DLtWjem/9vIzI2wcE30uC8LBAgO3JAlIS9NQrchjS9xhMJRohOoitaSPmqsOy7D2BH0h7XX6TNgv/WYTkBY4eZPao3PsL2A6AmhAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAMBmTHUK4w+DX21tmhqdwq0WqLH5ZAkwtiocDxFXiJ4GRrUWUh3BaXsgOHB8YYnNTDfScjaU0sZMEyfC0su1zsN8B7NFckg7RcZCHuBYdgIEAmvK4YM6s6zNsiKKwt66p2MNeL+o0acrT2rYjQ1L5QDj0gpfJQAT4N7xTZfuSc2iwjotaQfvcgsO8EZlcDVrL4UuyWLbuRUlSQjxHWGYaxCW+I3enK1+8fGpF3O+k9ZQ8xt5nJsalpsZvHcPLA4IBOmjsSHqSkhg4EIAWL/sJZ1KNct4hHh5kToUTu+Q6e949VeBkWgj4O+rcGDgiN2frGiEEc0EMv8KCSENRRRrO2k=";
-  private static final String SP_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDSFoT371C0/klZuPgvKbGItkmTaf5CweNXL8u389d98aOXRpDQ7maTXdV/W+VcL8vUWg8yG6nn8CRwweYnGTNdn9UAdhgknvxQe3pq3EwOJyls4Fpiq6YTh+DQfiZUQizjFjDOr/GG5O2lNvTRkI4XZj/XnWjRqVZwttiA5tm1sKkvGdyOQljwn4Jja/VbITdV8GASumx66Bil/wamSsqIzm2RjsOOGSsf5VjYUPwDobpuSf+j4DLtWjem/9vIzI2wcE30uC8LBAgO3JAlIS9NQrchjS9xhMJRohOoitaSPmqsOy7D2BH0h7XX6TNgv/WYTkBY4eZPao3PsL2A6AmhAgMBAAECggEBAJj11HJAR96/leBBkFGmZaBIOGGgNoOcb023evfADhGgsZ8evamhKgX5t8w2uFPaaOl/eLje82Hvslh2lH+7FW8BRDBFy2Y+ay6d+I99PdLAKKUg5C4bE5v8vm6OqpGGbPAZ5AdYit3QKEa2MKG0QgA/bhQqg3rDdDA0sIWJjtF9MLv7LI7Tm0qgiHOKsI0MEBFk+ZoibgKWYh/dnfGDRWyC3Puqe13rdSheNJYUDR/0QMkd/EJNpLWv06uk+w8w2lU4RgN6TiV76ZZUIGZAAHFgMELJysgtBTCkOQY5roPu17OmMZjKfxngeIfNyd42q3/T6DmUbbwNYfP2HRMoiMECgYEA6SVc1mZ4ykytC9M61rZwT+2zXtJKudQVa0qpTtkf0aznRmnDOuc1bL7ewKIIIp9r5HKVteO6SKgpHmrP+qmvbwZ0Pz51Zg0MetoSmT9m0599/tOU2k6OI09dvQ4Xa3ccN5Czl61Q/HkMeAIDny8MrhGVBwhallE4J4fm/OjuVK0CgYEA5q6IVgqZtfcV1azIF6uOFt6blfn142zrwq0fF39jog2f+4jXaBKw6L4aP0HvIL83UArGppYY31894bLb6YL4EjS2JNbABM2VnJpJd4oGopOE42GCZlZRpf751zOptYAN23NFSujLlfaUfMbyrqIbRFC2DCdzNTU50GT5SAXX80UCgYEAlyvQvHwJCjMZaTd3SU1WGZ1o1qzIIyHvGXh5u1Rxm0TfWPquyfys2WwRhxoI6FoyXRgnFp8oZIAU2VIstL1dsUGgEnnvKVKAqw/HS3Keu80IpziNpdeVtjN59mGysc2zkBvVNx38Cxh6Cz5TFt4s/JkN5ld2VU0oeglWrtph3qkCgYALszZ/BrKdJBcba1QKv0zJpCjIBpGOI2whx54YFwH6qi4/F8W1JZ2LcHjsVG/IfWpUyPciY+KHEdGVrPiyc04Zvkquu6WpmLPJ6ZloUrvbaxgGYF+4yRADF1ecrqYg6onJY6NUFVKeHI+TdJPCf75aTK2vGCEjxbtU8ooiOQmm8QKBgEGe9ZdrwTP9rMQ35jYtzU+dT06k1r9BE9Q8CmrXl0HwK717ZWboX4J0YoFjxZC8PDsMl3p46MJ83rKbLU728uKig1AkZo7/OedxTWvezjZ1+lDyjC2EguXbgY1ecSC2HbJh9g+v8RUuhWxuA7RYoW92xVtKj+6l4vMadVP4Myp8-----END PRIVATE KEY-----";
-
-  @Rule
-  public DbTester db = DbTester.create();
-  @Rule
-  public LogTester log = new LogTester();
-
-  private final MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, SamlSettings.definitions()));
-  private final SamlIdentityProvider underTest = new SamlIdentityProvider(new SamlSettings(settings.asConfig()), new SamlMessageIdChecker(db.getDbClient()));
-  private HttpServletResponse response = mock(HttpServletResponse.class);
-  private HttpServletRequest request = mock(HttpServletRequest.class);
-
-  @Before
-  public void setup() {
-    this.request = mock(HttpServletRequest.class);
-    this.response = mock(HttpServletResponse.class);
-    when(this.request.getRequestURL()).thenReturn(new StringBuffer(SQ_CALLBACK_URL));
-  }
-
-  @Test
-  public void check_fields() {
-    setSettings(true);
-    assertThat(underTest.getKey()).isEqualTo("saml");
-    assertThat(underTest.getName()).isEqualTo("SAML");
-    assertThat(underTest.getDisplay().getIconPath()).isEqualTo("/images/saml.png");
-    assertThat(underTest.getDisplay().getBackgroundColor()).isEqualTo("#444444");
-    assertThat(underTest.allowsUsersToSignUp()).isTrue();
-  }
-
-  @Test
-  public void provider_name_is_provided_by_setting() {
-    // Default value
-    assertThat(underTest.getName()).isEqualTo("SAML");
-
-    settings.setProperty("sonar.auth.saml.providerName", "My Provider");
-    assertThat(underTest.getName()).isEqualTo("My Provider");
-  }
-
-  @Test
-  public void is_enabled() {
-    setSettings(true);
-    assertThat(underTest.isEnabled()).isTrue();
-
-    setSettings(false);
-    assertThat(underTest.isEnabled()).isFalse();
-  }
-
-  @Test
-  public void init() throws IOException {
-    setSettings(true);
-    DumbInitContext context = new DumbInitContext();
-
-    underTest.init(context);
-
-    verify(context.response).sendRedirect(anyString());
-    assertThat(context.generateCsrfState.get()).isTrue();
-  }
-
-  @Test
-  public void fail_to_init_when_login_url_is_invalid() {
-    setSettings(true);
-    settings.setProperty("sonar.auth.saml.loginUrl", "invalid");
-    DumbInitContext context = new DumbInitContext();
-
-    assertThatThrownBy(() -> underTest.init(context))
-      .isInstanceOf(IllegalStateException.class)
-      .hasMessage("Failed to create a SAML Auth");
-  }
-
-  @Test
-  public void callback() {
-    setSettings(true);
-    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_full_response.txt", SQ_CALLBACK_URL);
-
-    underTest.callback(callbackContext);
-
-    assertThat(callbackContext.redirectedToRequestedPage.get()).isTrue();
-    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
-    assertThat(callbackContext.verifyState.get()).isTrue();
-  }
-
-  @Test
-  public void failed_callback_when_behind_a_reverse_proxy_without_needed_header() {
-    setSettings(true);
-    // simulate reverse proxy stripping SSL and not adding X-Forwarded-Proto header
-    when(this.request.getRequestURL()).thenReturn(new StringBuffer("http://localhost/oauth2/callback/saml"));
-    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_full_response_with_reverse_proxy.txt",
-      "https://localhost/oauth2/callback/saml");
-
-    assertThatThrownBy(() -> underTest.callback(callbackContext))
-      .isInstanceOf(UnauthorizedException.class)
-      .hasMessageContaining("The response was received at http://localhost/oauth2/callback/saml instead of https://localhost/oauth2/callback/saml");
-  }
-
-  @Test
-  public void successful_callback_when_behind_a_reverse_proxy_with_needed_header() {
-    setSettings(true);
-    // simulate reverse proxy stripping SSL and adding X-Forwarded-Proto header
-    when(this.request.getRequestURL()).thenReturn(new StringBuffer("http://localhost/oauth2/callback/saml"));
-    when(this.request.getHeader("X-Forwarded-Proto")).thenReturn("https");
-    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_full_response_with_reverse_proxy.txt",
-      "https://localhost/oauth2/callback/saml");
-
-    underTest.callback(callbackContext);
-
-    assertThat(callbackContext.redirectedToRequestedPage.get()).isTrue();
-    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
-    assertThat(callbackContext.verifyState.get()).isTrue();
-  }
-
-  @Test
-  public void callback_on_full_response() {
-    setSettings(true);
-    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_full_response.txt", SQ_CALLBACK_URL);
-
-    underTest.callback(callbackContext);
-
-    assertThat(callbackContext.userIdentity.getName()).isEqualTo("John Doe");
-    assertThat(callbackContext.userIdentity.getEmail()).isEqualTo("johndoe@email.com");
-    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
-    assertThat(callbackContext.userIdentity.getGroups()).containsExactlyInAnyOrder("developer", "product-manager");
-  }
-
-  @Test
-  public void callback_on_encrypted_response() {
-    setSettings(true);
-    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_encrypted_response.txt", SQ_CALLBACK_URL);
-
-    underTest.callback(callbackContext);
-
-    assertThat(callbackContext.userIdentity.getName()).isEqualTo("John Doe");
-    assertThat(callbackContext.userIdentity.getEmail()).isEqualTo("johndoe@email.com");
-    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
-    assertThat(callbackContext.userIdentity.getGroups()).containsExactlyInAnyOrder("developer", "product-manager");
-  }
-
-  @Test
-  public void callback_on_signed_request() throws IOException {
-    setSettings(true);
-    settings.setProperty("sonar.auth.saml.signature.enabled", true);
-    DumbInitContext context = new DumbInitContext();
-
-    underTest.init(context);
-
-    String[] samlRequestParams = {"http://localhost:8080/auth/realms/sonarqube/protocol/saml",
-      "?SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256", "&SAMLRequest=", "&Signature="};
-    verify(context.response).sendRedirect(argThat(x -> Arrays.stream(samlRequestParams).allMatch(x::contains)));
-  }
-
-  @Test
-  public void callback_on_minimal_response() {
-    setSettings(true);
-    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_minimal_response.txt", SQ_CALLBACK_URL);
-
-    underTest.callback(callbackContext);
-
-    assertThat(callbackContext.userIdentity.getName()).isEqualTo("John Doe");
-    assertThat(callbackContext.userIdentity.getEmail()).isNull();
-    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
-    assertThat(callbackContext.userIdentity.getGroups()).isEmpty();
-  }
-
-  @Test
-  public void log_clear_error_when_private_key_is_not_pkcs8() {
-    var WRONG_FORMAT_PRIVATE_KEY = "MIIEpAIBAAKCAQEA0haE9+9QtP5JWbj4LymxiLZJk2n+QsHjVy/Lt/PXffGjl0aQ0O5mk13Vf1vlXC/L1FoPMhup5/AkcMHmJxkzXZ/VAHYYJJ78UHt6atxMDicpbOBaYqumE4fg0H4mVEIs4xYwzq/xhuTtpTb00ZCOF2Y/151o0alWcLbYgObZtbCpLxncjkJY8J+CY2v1WyE3VfBgErpseugYpf8GpkrKiM5tkY7DjhkrH+VY2FD8A6G6bkn/o+Ay7Vo3pv/byMyNsHBN9LgvCwQIDtyQJSEvTUK3IY0vcYTCUaITqIrWkj5qrDsuw9gR9Ie11+kzYL/1mE5AWOHmT2qNz7C9gOgJoQIDAQABAoIBAQCY9dRyQEfev5XgQZBRpmWgSDhhoDaDnG9Nt3r3wA4RoLGfHr2poSoF+bfMNrhT2mjpf3i43vNh77JYdpR/uxVvAUQwRctmPmsunfiPfT3SwCilIOQuGxOb/L5ujqqRhmzwGeQHWIrd0ChGtjChtEIAP24UKoN6w3QwNLCFiY7RfTC7+yyO05tKoIhzirCNDBARZPmaIm4ClmIf3Z3xg0Vsgtz7qntd63UoXjSWFA0f9EDJHfxCTaS1r9OrpPsPMNpVOEYDek4le+mWVCBmQABxYDBCycrILQUwpDkGOa6D7tezpjGYyn8Z4HiHzcneNqt/0+g5lG28DWHz9h0TKIjBAoGBAOklXNZmeMpMrQvTOta2cE/ts17SSrnUFWtKqU7ZH9Gs50ZpwzrnNWy+3sCiCCKfa+RylbXjukioKR5qz/qpr28GdD8+dWYNDHraEpk/ZtOfff7TlNpOjiNPXb0OF2t3HDeQs5etUPx5DHgCA58vDK4RlQcIWpZROCeH5vzo7lStAoGBAOauiFYKmbX3FdWsyBerjhbem5X59eNs68KtHxd/Y6INn/uI12gSsOi+Gj9B7yC/N1AKxqaWGN9fPeGy2+mC+BI0tiTWwATNlZyaSXeKBqKThONhgmZWUaX++dczqbWADdtzRUroy5X2lHzG8q6iG0RQtgwnczU1OdBk+UgF1/NFAoGBAJcr0Lx8CQozGWk3d0lNVhmdaNasyCMh7xl4ebtUcZtE31j6rsn8rNlsEYcaCOhaMl0YJxafKGSAFNlSLLS9XbFBoBJ57ylSgKsPx0tynrvNCKc4jaXXlbYzefZhsrHNs5Ab1Tcd/AsYegs+UxbeLPyZDeZXdlVNKHoJVq7aYd6pAoGAC7M2fwaynSQXG2tUCr9MyaQoyAaRjiNsIceeGBcB+qouPxfFtSWdi3B47FRvyH1qVMj3ImPihxHRlaz4snNOGb5KrrulqZizyemZaFK722sYBmBfuMkQAxdXnK6mIOqJyWOjVBVSnhyPk3STwn++WkytrxghI8W7VPKKIjkJpvECgYBBnvWXa8Ez/azEN+Y2Lc1PnU9OpNa/QRPUPApq15dB8Cu9e2Vm6F+CdGKBY8WQvDw7DJd6eOjCfN6ymy1O9vLiooNQJGaO/znncU1r3s42dfpQ8owthILl24GNXnEgth2yYfYPr/EVLoVsbgO0WKFvdsVbSo/upeLzGnVT+DMqfA==";
-    setSettings(true);
-    settings.setProperty("sonar.auth.saml.sp.privateKey.secured", WRONG_FORMAT_PRIVATE_KEY);
-    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_minimal_response.txt", SQ_CALLBACK_URL);
-
-    underTest.callback(callbackContext);
-
-    assertThat(log.getLogs(ERROR))
-      .extracting(LogAndArguments::getFormattedMsg)
-      .contains("Error in parsing service provider private key, please make sure that it is in PKCS 8 format.");
-  }
-
-  @Test
-  public void callback_does_not_sync_group_when_group_setting_is_not_set() {
-    setSettings(true);
-    settings.setProperty("sonar.auth.saml.group.name", (String) null);
-    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_full_response.txt", SQ_CALLBACK_URL);
-
-    underTest.callback(callbackContext);
-
-    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
-    assertThat(callbackContext.userIdentity.getGroups()).isEmpty();
-    assertThat(callbackContext.userIdentity.shouldSyncGroups()).isFalse();
-  }
-
-  @Test
-  public void fail_to_callback_when_login_is_missing() {
-    setSettings(true);
-    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_response_without_login.txt", SQ_CALLBACK_URL);
-
-    assertThatThrownBy(() -> underTest.callback(callbackContext))
-      .isInstanceOf(NullPointerException.class)
-      .hasMessage("login is missing");
-
-  }
-
-  @Test
-  public void fail_to_callback_when_name_is_missing() {
-    setSettings(true);
-    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_response_without_name.txt", SQ_CALLBACK_URL);
-
-    assertThatThrownBy(() -> underTest.callback(callbackContext))
-      .isInstanceOf(NullPointerException.class)
-      .hasMessage("name is missing");
-  }
-
-  @Test
-  public void fail_to_callback_when_certificate_is_invalid() {
-    setSettings(true);
-    settings.setProperty("sonar.auth.saml.certificate.secured", "invalid");
-    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_full_response.txt", SQ_CALLBACK_URL);
-
-    assertThatThrownBy(() -> underTest.callback(callbackContext))
-      .isInstanceOf(IllegalStateException.class)
-      .hasMessage("Failed to create a SAML Auth");
-  }
-
-  @Test
-  public void fail_to_callback_when_using_wrong_certificate() {
-    setSettings(true);
-    settings.setProperty("sonar.auth.saml.certificate.secured", "-----BEGIN CERTIFICATE-----\n" +
-      "MIIEIzCCAwugAwIBAgIUHUzPjy5E2TmnsmTRT2sIUBRXFF8wDQYJKoZIhvcNAQEF\n" +
-      "BQAwXDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC1NvbmFyU291cmNlMRUwEwYDVQQL\n" +
-      "DAxPbmVMb2dpbiBJZFAxIDAeBgNVBAMMF09uZUxvZ2luIEFjY291bnQgMTMxMTkx\n" +
-      "MB4XDTE4MDcxOTA4NDUwNVoXDTIzMDcxOTA4NDUwNVowXDELMAkGA1UEBhMCVVMx\n" +
-      "FDASBgNVBAoMC1NvbmFyU291cmNlMRUwEwYDVQQLDAxPbmVMb2dpbiBJZFAxIDAe\n" +
-      "BgNVBAMMF09uZUxvZ2luIEFjY291bnQgMTMxMTkxMIIBIjANBgkqhkiG9w0BAQEF\n" +
-      "AAOCAQ8AMIIBCgKCAQEArlpKHm4EkJiQyy+4GtZBixcy7fWnreB96T7cOoWLmWkK\n" +
-      "05FM5M/boWHZsvaNAuHsoCAMzIY3/l+55WbORzAxsloH7rvDaDrdPYQN+sU9bzsD\n" +
-      "ZkmDGDmA3QBSm/h/p5SiMkWU5Jg34toDdM0rmzUStIOMq6Gh/Ykx3fRRSjswy48x\n" +
-      "wfZLy+0wU7lasHqdfk54dVbb7mCm9J3iHZizvOt2lbtzGbP6vrrjpzvZm43ZRgP8\n" +
-      "FapYA8G3lczdIaG4IaLW6kYIRORd0UwI7IAwkao3uIo12rh1T6DLVyzjOs9PdIkb\n" +
-      "HbICN2EehB/ut3wohuPwmwp2UmqopIMVVaBSsmSlYwIDAQABo4HcMIHZMAwGA1Ud\n" +
-      "EwEB/wQCMAAwHQYDVR0OBBYEFAXGFMKYgtpzCpfpBUPQ1H/9AeDrMIGZBgNVHSME\n" +
-      "gZEwgY6AFAXGFMKYgtpzCpfpBUPQ1H/9AeDroWCkXjBcMQswCQYDVQQGEwJVUzEU\n" +
-      "MBIGA1UECgwLU29uYXJTb3VyY2UxFTATBgNVBAsMDE9uZUxvZ2luIElkUDEgMB4G\n" +
-      "A1UEAwwXT25lTG9naW4gQWNjb3VudCAxMzExOTGCFB1Mz48uRNk5p7Jk0U9rCFAU\n" +
-      "VxRfMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQUFAAOCAQEAPHgi9IdDaTxD\n" +
-      "R5R8KHMdt385Uq8XC5pd0Li6y5RR2k6SKjThCt+eQU7D0Y2CyYU27vfCa2DQV4hJ\n" +
-      "4v4UfQv3NR/fYfkVSsNpxjBXBI3YWouxt2yg7uwdZBdgGYd37Yv3g9PdIZenjOhr\n" +
-      "Ck6WjdleMAWHRgJpocmB4IOESSyTfUul3jFupWnkbnn8c0ue6zwXd7LA1/yjVT2l\n" +
-      "Yh45+lz25aIOlyyo7OUw2TD15LIl8OOIuWRS4+UWy5+VdhXMbmpSEQH+Byod90g6\n" +
-      "A1bKpOFhRBzcxaZ6B2hB4SqjTBzS9zdmJyyFs/WNJxHri3aorcdqG9oUakjJJqqX\n" +
-      "E13skIMV2g==\n" +
-      "-----END CERTIFICATE-----\n");
-    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_full_response.txt", SQ_CALLBACK_URL);
-
-    assertThatThrownBy(() -> underTest.callback(callbackContext))
-      .isInstanceOf(UnauthorizedException.class)
-      .hasMessage("Signature validation failed. SAML Response rejected");
-  }
-
-  @Test
-  public void fail_callback_when_message_was_already_sent() {
-    setSettings(true);
-    DumbCallbackContext callbackContext = new DumbCallbackContext(request, response, "encoded_minimal_response.txt", SQ_CALLBACK_URL);
-
-    underTest.callback(callbackContext);
-
-    assertThatThrownBy(() -> underTest.callback(callbackContext))
-      .isInstanceOf(IllegalArgumentException.class)
-      .hasMessage("This message has already been processed");
-  }
-
-  private void setSettings(boolean enabled) {
-    if (enabled) {
-      settings.setProperty("sonar.auth.saml.applicationId", "MyApp");
-      settings.setProperty("sonar.auth.saml.providerId", "http://localhost:8080/auth/realms/sonarqube");
-      settings.setProperty("sonar.auth.saml.loginUrl", "http://localhost:8080/auth/realms/sonarqube/protocol/saml");
-      settings.setProperty("sonar.auth.saml.certificate.secured", IDP_CERTIFICATE);
-      settings.setProperty("sonar.auth.saml.sp.privateKey.secured", SP_PRIVATE_KEY);
-      settings.setProperty("sonar.auth.saml.sp.certificate.secured", SP_CERTIFICATE);
-      settings.setProperty("sonar.auth.saml.user.login", "login");
-      settings.setProperty("sonar.auth.saml.user.name", "name");
-      settings.setProperty("sonar.auth.saml.user.email", "email");
-      settings.setProperty("sonar.auth.saml.group.name", "groups");
-      settings.setProperty("sonar.auth.saml.enabled", true);
-    } else {
-      settings.setProperty("sonar.auth.saml.enabled", false);
-    }
-  }
-
-  private static class DumbInitContext implements OAuth2IdentityProvider.InitContext {
-    private final HttpServletResponse response = mock(HttpServletResponse.class);
-    private final AtomicBoolean generateCsrfState = new AtomicBoolean(false);
-
-    @Override
-    public String generateCsrfState() {
-      generateCsrfState.set(true);
-      return null;
-    }
-
-    @Override
-    public void redirectTo(String url) {
-    }
-
-    @Override
-    public String getCallbackUrl() {
-      return SQ_CALLBACK_URL;
-    }
-
-    @Override
-    public HttpServletRequest getRequest() {
-      return mock(HttpServletRequest.class);
-    }
-
-    @Override
-    public HttpServletResponse getResponse() {
-      return response;
-    }
-  }
-
-  private static class DumbCallbackContext implements OAuth2IdentityProvider.CallbackContext {
-    private final HttpServletResponse response;
-    private final HttpServletRequest request;
-    private final String expectedCallbackUrl;
-    private final AtomicBoolean redirectedToRequestedPage = new AtomicBoolean(false);
-    private final AtomicBoolean verifyState = new AtomicBoolean(false);
-
-    private UserIdentity userIdentity = null;
-
-    public DumbCallbackContext(HttpServletRequest request, HttpServletResponse response, String encodedResponseFile, String expectedCallbackUrl) {
-      this.request = request;
-      this.response = response;
-      this.expectedCallbackUrl = expectedCallbackUrl;
-      Map<String, String[]> parameterMap = new HashMap<>();
-      parameterMap.put("SAMLResponse", new String[] {loadResponse(encodedResponseFile)});
-      when(getRequest().getParameterMap()).thenReturn(parameterMap);
-    }
-
-    private String loadResponse(String file) {
-      try (InputStream json = getClass().getResourceAsStream("SamlIdentityProviderTest/" + file)) {
-        return IOUtils.toString(json, StandardCharsets.UTF_8);
-      } catch (IOException e) {
-        throw new IllegalStateException(e);
-      }
-    }
-
-    @Override
-    public void verifyCsrfState() {
-      throw new IllegalStateException("This method should not be called !");
-    }
-
-    @Override
-    public void verifyCsrfState(String parameterName) {
-      assertThat(parameterName).isEqualTo("RelayState");
-      verifyState.set(true);
-    }
-
-    @Override
-    public void redirectToRequestedPage() {
-      redirectedToRequestedPage.set(true);
-    }
-
-    @Override
-    public void authenticate(UserIdentity userIdentity) {
-      this.userIdentity = userIdentity;
-    }
-
-    @Override
-    public String getCallbackUrl() {
-      return this.expectedCallbackUrl;
-    }
-
-    @Override
-    public HttpServletRequest getRequest() {
-      return this.request;
-    }
-
-    @Override
-    public HttpServletResponse getResponse() {
-      return this.response;
-    }
-  }
-}
diff --git a/server/sonar-auth-saml/src/test/java/org/sonar/auth/saml/SamlMessageIdCheckerTest.java b/server/sonar-auth-saml/src/test/java/org/sonar/auth/saml/SamlMessageIdCheckerTest.java
deleted file mode 100644 (file)
index 613715e..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.auth.saml;
-
-import com.google.common.collect.ImmutableList;
-import com.onelogin.saml2.Auth;
-import java.util.Arrays;
-import org.joda.time.Instant;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.db.DbSession;
-import org.sonar.db.DbTester;
-import org.sonar.db.user.SamlMessageIdDto;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class SamlMessageIdCheckerTest {
-
-  @Rule
-  public DbTester db = DbTester.create();
-
-  private DbSession dbSession = db.getSession();
-
-  private Auth auth = mock(Auth.class);
-
-  private SamlMessageIdChecker underTest = new SamlMessageIdChecker(db.getDbClient());
-
-  @Test
-  public void check_do_not_fail_when_message_id_is_new_and_insert_saml_message_in_db() {
-    db.getDbClient().samlMessageIdDao().insert(dbSession, new SamlMessageIdDto().setMessageId("MESSAGE_1").setExpirationDate(1_000_000_000L));
-    db.commit();
-    when(auth.getLastMessageId()).thenReturn("MESSAGE_2");
-    when(auth.getLastAssertionNotOnOrAfter()).thenReturn(ImmutableList.of(Instant.ofEpochMilli(10_000_000_000L)));
-
-    assertThatCode(() -> underTest.check(auth)).doesNotThrowAnyException();
-
-    SamlMessageIdDto result = db.getDbClient().samlMessageIdDao().selectByMessageId(dbSession, "MESSAGE_2").get();
-    assertThat(result.getMessageId()).isEqualTo("MESSAGE_2");
-    assertThat(result.getExpirationDate()).isEqualTo(10_000_000_000L);
-  }
-
-  @Test
-  public void check_fails_when_message_id_already_exist() {
-    db.getDbClient().samlMessageIdDao().insert(dbSession, new SamlMessageIdDto().setMessageId("MESSAGE_1").setExpirationDate(1_000_000_000L));
-    db.commit();
-    when(auth.getLastMessageId()).thenReturn("MESSAGE_1");
-    when(auth.getLastAssertionNotOnOrAfter()).thenReturn(ImmutableList.of(Instant.ofEpochMilli(10_000_000_000L)));
-
-    assertThatThrownBy(() -> underTest.check(auth))
-      .isInstanceOf(IllegalArgumentException.class)
-      .hasMessageContaining("This message has already been processed");
-  }
-
-  @Test
-  public void check_insert_message_id_using_oldest_NotOnOrAfter_value() {
-    db.getDbClient().samlMessageIdDao().insert(dbSession, new SamlMessageIdDto().setMessageId("MESSAGE_1").setExpirationDate(1_000_000_000L));
-    db.commit();
-    when(auth.getLastMessageId()).thenReturn("MESSAGE_2");
-    when(auth.getLastAssertionNotOnOrAfter())
-      .thenReturn(Arrays.asList(Instant.ofEpochMilli(10_000_000_000L), Instant.ofEpochMilli(30_000_000_000L), Instant.ofEpochMilli(20_000_000_000L)));
-
-    assertThatCode(() -> underTest.check(auth)).doesNotThrowAnyException();
-
-    SamlMessageIdDto result = db.getDbClient().samlMessageIdDao().selectByMessageId(dbSession, "MESSAGE_2").get();
-    assertThat(result.getMessageId()).isEqualTo("MESSAGE_2");
-    assertThat(result.getExpirationDate()).isEqualTo(10_000_000_000L);
-  }
-}
diff --git a/server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_encrypted_response.txt b/server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_encrypted_response.txt
deleted file mode 100644 (file)
index dca5abf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c2FtbHA6UmVzcG9uc2UgeG1sbnM6c2FtbHA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCIgeG1sbnM6c2FtbD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgRGVzdGluYXRpb249Imh0dHA6Ly9sb2NhbGhvc3Q6OTAwMC9vYXV0aDIvY2FsbGJhY2svc2FtbCIgSUQ9InBmeDcxZGMxZjgxLTdmMmItNzVjMS0wYzlkLWM1ODIxMzA1Yzg1ZCIgSW5SZXNwb25zZVRvPSJPTkVMT0dJTl9iMjNkM2NhZi03YTVjLTQzNzAtYjg0OS0wZGI0ZDNjMzRlNzUiIElzc3VlSW5zdGFudD0iMjAyMC0wNi0wNVQyMzowMjoyOC40MzhaIiBWZXJzaW9uPSIyLjAiPg0KICAgIDxzYW1sOklzc3Vlcj5odHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvc29uYXJxdWJlPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4NCiAgPGRzOlNpZ25lZEluZm8+PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4NCiAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIi8+DQogIDxkczpSZWZlcmVuY2UgVVJJPSIjcGZ4NzFkYzFmODEtN2YyYi03NWMxLTBjOWQtYzU4MjEzMDVjODVkIj48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT55L2lsZHIvdTFNRTB3MU9Ia2VLT3RYc2dOQXM9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPkxraVhzMnEzeThZcG9YSHgrOEszY2V5aUkxZEQzaDIyNUVlQWtIK05GaHZLUmNsRlVDdzBVQmc1RmtUQzUvRjd0dCsvTDljU3drYXFpY0VaVGp3TGVzSCtnQzdJVUhOZ2NKTlFWUHBSRGQwckMweG94TzZkLzk4d3NDTDZmN2dIcWNLR3VJN0dGc1U5akprSHpmU2hvakpIWFYrVTRkK1FrUFRLWTQ1Z2F4dlN0T2EyYzNLNnQwSU5xc204aktBWHNvVHNZUStFMjZRTi8wZSs3SjY4WUdUSGFPayt2M2NiQ1ZHakVkcE5ZVWlTN0dMcTYxekpwVTI0SCtzY0xIUVVZRjAxeWdIZGk0SjdDQzhocUNOeFhnVUJhMlVTZWlpUXFMbGVZQU1iYUlIQ0dnLzdVOE9yZGlQWmN3Y1BTRVhpbUhQQWFIR2VKQldsQ1RhWjYxQnVqVHZmV1JQaXRVUSsrWEYyM0wwNDlJbDRVeHFaTlJ4T2h4eFdCYUZBM2RsL0I4U1VIV05aSEJ3NEVjcjNsQ1hPVXZGYjRtWitWYjA1VXNIQzJIdjQ3elNHS2d2bnV5djlwS0hGQzlBSXFrSEtFTG5OcHl6OTgvaUQvamtkczhjT0RRbk4wa05kWU5EVVZZOE5NbTRvTjVOM1pVRWVmaXc3ZThydjZuZTFLckZhcE1OMmlramgzclExcHJXaTZyVzJtcVZlWldHMlVkcVcwRUhsV3lyUGdpR2ZyRklYTS8ycTFJUlFwUEg2UUpzSjUwU05KaG9NOHEzSWZldWNMQkh6RU1FVlVINlpQQ2lBTmNUekxjdjJmdnFUS0ZFUmJmdkNZaWhwZnBnek5JZzVucXR6TXNQbGRWNEpma0NlaFROZGpZQXpXTEFrYjNUT2thNGJIS3dhd3lvPTwvZHM6U2lnbmF0dXJlVmFsdWU+DQo8ZHM6S2V5SW5mbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlGNXpDQ0E4K2dBd0lCQWdJVUlYdjlPVnMvWFVpY2dSMWJzVjl1Y2NZaEhmb3dEUVlKS29aSWh2Y05BUUVMQlFBd2dZSXhDekFKQmdOVkJBWVRBa0ZWTVE4d0RRWURWUVFJREFaSFJVNUZWa0V4RURBT0JnTlZCQWNNQjFaRlVrNUpSVkl4RGpBTUJnTlZCQW9NQlZOUFRrRlNNUTB3Q3dZRFZRUUxEQVJSVlVKRk1ROHdEUVlEVlFRRERBWmFhWEJsYm1jeElEQWVCZ2txaGtpRzl3MEJDUUVXRVc1dmNtVndiSGxBWjIxaGFXd3VZMjl0TUI0WERUSXlNRFl4TXpFek1UUXlOMW9YRFRNeU1EWXhNREV6TVRReU4xb3dnWUl4Q3pBSkJnTlZCQVlUQWtGVk1ROHdEUVlEVlFRSURBWkhSVTVGVmtFeEVEQU9CZ05WQkFjTUIxWkZVazVKUlZJeERqQU1CZ05WQkFvTUJWTlBUa0ZTTVEwd0N3WURWUVFMREFSUlZVSkZNUTh3RFFZRFZRUUREQVphYVhCbGJtY3hJREFlQmdrcWhraUc5dzBCQ1FFV0VXNXZjbVZ3YkhsQVoyMWhhV3d1WTI5dE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBdTNuRlhZdklZZWRwUjg0YVprZG8vM3lCNVhITStZQ0ZKY0RzVk8xMHpFYmxMa25mUXNpTVBhMVhkOVVzdG5weHc2UC9TeXpJSm1POWppTU9kZUNlWTk4YTc0alA3ZDRKUGFPNmgzbDlJYldBY1llaWpRZzk1Nm5sc1ZGWTNGSERHcis3UGI4UWNPQXlWM3Y4OWppRjlERkI4d1hTKzVVZllyMk9mb1JSYjRsaTM5ZXpEeURkbDVPTGxNMTFuRXNzMnoxbUV2K3NVVWxvVGN5cmdqMzdQc2dld2t2eXltNnRGR1Nna1Y5WmE0U1ZSaEhGeVRoWTFWRnJZWlNKRlRuYXBVWWFSYzdrTXh6d1gvQUFIVURKcm1ZY2FWYzVCOE9EcDR3MkF4REpoZVF5Q1ZmWGpQRmFVcUJNRzJVL3JZZlZYdTBaYTdQbi92VW80VWFTVGh3Q0JLRGVoQ3d6KzY1VExkQStOeHlHRHhudlkvU2tzT3lMTEdDbXU4dEtrWGR1MHB6bm5JaEJYRUd2alVJVlM3ZDZhLzhnZWc5MU5vVFdhdTNpMFJGK0R3LzVOOURTenBsZDE1YlB0YjVDZTNCaWUxOXV2ZnZ1SDllZytEOHgvaGZGNmYzaWw0c1BsSUtkTy9PVmRNMjhMUmZtRHFtcVFOUHVkdmJxejd4eTRBUnV4azZBUmE0ZCthVDl6b3Zwd3Z4TkdUcjdoMW1kZ09VdFVDZElYTDNTSE5qZHdkQUF6MHVDV3p2RXhiRnUrTlErVjUrWG5reDcxaHlQRnY5K0RMVkdJdTdKaGRZczgwNndLc2hPMTNOZ2EzOGlnNmd1MzdscFZoZnBaWGhLeXdVaWlnRzZMWEFleVdXa01rK3ZsZjlNY1pkTUJEMTZkWlA0a1RzdlArclBWblVDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRkk1VVZMdFR5U3ZiR3FIN1VQOHhUTDR3eFpxM01COEdBMVVkSXdRWU1CYUFGSTVVVkx0VHlTdmJHcUg3VVA4eFRMNHd4WnEzTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCQUJBdFhzS05XeDBzRERGQTUzcVoxelJ5V0tXQU1vaDk1cGF3RkNyS2dURVc0WnJBNzNwYTc5MGVFMVkrdlQ2cVVYS0k0bGk5c2tJRGErNnBzQ2R4aFpJckhQUkFuVlpWZUIyMzczQnhyNWJ3L1hROGVsUkNqV2VNVUxiWUo5dGdzTFYwSTlDaUVQMGE2VG04dDB5RFZYTlVmeDM2RTVma2dMU3J4b1JvOFhKenhIYkpDbkxWWEhkYU5CeE9UN2pWY29tNldvNFBCMmJzalZ6aEhtNmFtbjVoWnA0ZE1IbTBNdjBsbjF3SDhqVm5pekhRQkxzR016dnZsNTgrOXMxcFAxN2NlUkRrcE5EeitFUXlBK1pBcnFrVzFNcXR3Vmhieno4UWdNcHJoZmxLa0FycnNDN3YwNkp2OGZxVWJuOUx2dFlLOUl3SFRYN0o4ZEZjc08vZ1VDNVBldllUM25yaU4zQXpiMjBnZ1NRMXlPRU1venZqNVQ5NlM2aXRmSFBpdDd2eUVRODRKUHJFcWZ1UURaUS9MS1pRcWZ2dVhYMWFBRzNUVTNUTVdCOVZNTUZzVHVNRlM4YmZyaE1YNzdnMFVkNHFKY0JPWU9IM2hSNTlhZ1NkZDJRWk5MUDN6WnNZUUhMTFFrcTk0amRUWEtUcW0vdzdtbFBGS1Y1OUhqVGJIQmhUdHhCSE1mdC9tdnZMRXVDOUtLRmZBT1hZUTZWK3M5TmswQlc0Z2dFZmV3YVg1OE9CdXk3SVNxUnRSRlBHaWExOFlSenpIcWtoanViSllNUGtJZllwRlZkK0MwSUkzRjBrZHk4VHRwY2NqeUtvOWJjSE1MeE80bjhQREFsMTk1Q1B0aE1pOGdVdlQwMDhMR0VvdHIrM2tYc291VEVaVFQwZ2xYS0xkTzJXPC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+DQogICAgPHNhbWxwOlN0YXR1cz4NCiAgICAgICAgPHNhbWxwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPg0KICAgIDwvc2FtbHA6U3RhdHVzPg0KDQogICAgPHNhbWw6RW5jcnlwdGVkQXNzZXJ0aW9uPg0KICAgICAgICA8eGVuYzpFbmNyeXB0ZWREYXRhIHhtbG5zOnhlbmM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jIyIgeG1sbnM6ZHNpZz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyIgVHlwZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjRWxlbWVudCI+DQogICAgICAgICAgICA8eGVuYzpFbmNyeXB0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjYWVzMjU2LWNiYyIvPg0KICAgICAgICAgICAgPGRzaWc6S2V5SW5mbyB4bWxuczpkc2lnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4NCiAgICAgICAgICAgICAgICA8eGVuYzpFbmNyeXB0ZWRLZXk+DQogICAgICAgICAgICAgICAgICAgIDx4ZW5jOkVuY3J5cHRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGVuYyNyc2EtMV81Ii8+DQogICAgICAgICAgICAgICAgICAgIDx4ZW5jOkNpcGhlckRhdGE+DQogICAgICAgICAgICAgICAgICAgICAgICA8eGVuYzpDaXBoZXJWYWx1ZT5RRlduQ1oyZDhaS1J5ZGdXenBNazBVbmJBek55Q2kvUnUvd2RjZFUrTzR4Tkg0V1AreVh2WkZ0MXkrY2lmZHhIK3VYajlwcEtheE96T2JIL1pEaE1RSVIxSXVmS2xNUmVDSFJ3clZWV3FFRkZNS2Q5eXIrWFU5U29YdjEvQUdsSXBSQjlvbkhubTVidDljOFMrZ1ZlRFluRCtLblptelBlMU5KY1AzUmcvdGEwZUxIMng5WkQ5V3QzSUFYOFY2aXVXY0l0d21kakFvRmJrc1ZoUC9md0dpK0FRYmEvYksxNE5WVGtKS0lyS0s5NlV1dlBqTllpbitQK0JoSVlxdFhWSnA0Qm1pT1lKS3J5dVlnRU5vRzh4aUoyZy83Sk5RR0VjV0xOZVBkbGVvUU1BRjYvMTFDRndZYXVkOFcwQzlBSElBMWtFOWRmd01zN3pWZkZsREgzM2c9PTwveGVuYzpDaXBoZXJWYWx1ZT4NCiAgICAgICAgICAgICAgICAgICAgPC94ZW5jOkNpcGhlckRhdGE+DQogICAgICAgICAgICAgICAgPC94ZW5jOkVuY3J5cHRlZEtleT4NCiAgICAgICAgICAgIDwvZHNpZzpLZXlJbmZvPg0KICAgICAgICAgICAgPHhlbmM6Q2lwaGVyRGF0YT4NCiAgICAgICAgICAgICAgICA8eGVuYzpDaXBoZXJWYWx1ZT5oeGdPTnFnaXA5Wmd6Y2dMUitxc0poWFJPTWhrQ3J4R2dkUTN3UHhQMGVGMFk1UXpYRmQzRUJTRHVUYTl4YnBhb1RCdGFOQ3FnditLbWFKeTJxU2NVL1EzYXBWUmI0WEM5bmU3L1VFcDVrR0hiV2xyVkxZZUNTNnp1VHJSKzNmMzhzd0ordlg2cWZFbC9GbTBEV0VHaEFIWnhtMm80Wk1QR2xXRm4wMnp5c3QvdHdRL3Foa1RodnQ3akp6RVlTRFc2ZjBEdlpkNXVoTDRIOU9XaGZoNTlIRnloZzRncUp5a05Ha1pUQytEckc1dDh2OWs5ZDVHV0ptam9nVEdzVjVCTnJaclhBMmtjQkM4Q1VlL2w3Z20xSXF2Ymp0OW1CN2g5alVVVU5LWGVBeVR6MUxRRFN2aS9hbmZVZW40UDZsQ1dmanlsVnFmdnFnS3EzamVWdzBhUHVrZlllMFg2UFAzbDBZR25CU2h3UytJeERpNUFMREp4ZlBiM2M1cm9sR1F2V3Z4T3VYeVFxMHRIUThQWXNPajVKc2t4Q2FoY3NWYjgwNHlLeFlKcWdGRDJKdG14b1BIK005Y3F1VmRTVlVqUk5nU09XWjByVU5WU2ljRjlrOTVMYkJLaFB3WUpXbVdwWnBJb3FaeE9WcUdtcUNrdG9WcmhaeUY5TnNWN2JMQk5ubGt5LzZIMy94SExDamx5dkNyczNQd3VnOERkTzhLUTcyTmV0WEtYN2kxS1RiNi9lcVErZGUzeGljUWEvcEYvNDVQZ2EySkVKc3FvVWpRUEJvSFY2ZzhpM1RxSWtTWk15c3FmWE1Va1FRelVveU96VEtjTmFrVEx1VU4wUEdLQTR6OGNYbUM1ZmlTdTJNMVdVT3hxYjZ5bFBVRnl6RGtzUzEwU0dib3BWQ1NqMk1iUnIyLyt4ZGNFUXlhTlFPVCtMTGN0MXRaczN3NzNVRGtIQVlMS0NvNFROOVdPVkhRSFYwWnh4YnRsOUh4R1hvdXJSeDN6dDFXbjBBc0kwTWZBbVpJUVZmek0zMTE5eXgrL2VaTzhudnVXWWhKSVdjOUtwQi9XSzdBL2k5blRobzhOaGFKWU5jYWlLMlM2TzNWR1laNFUzRUNxZzlmQVI1d0FUMk5tTHpZMmI3K3lUTWdJWTRDTXl0Smp6NFA5MDhOay9DVDF6cEs1dkhQcWNhK3dHVEpnOEcycnlnL05MVXJKM3pEbkhhQTZDazRjRXFHSFQ4dUtnSWM0NHo5bERCemtJaXhXYW5FMVVvbkpNTnlnNDNvQXQyWnJTN3k1TkdsOWhKbythVEtTWjN5bVFNTTUyMWR2MmFGWmplTEhISncvYThvS2JQOUt5UDlpL2d5SWdGaXF4UDNKd3VwdFRIQnVqZlhMVnRyT0FIcWlZODhqU2svbzJmUzQ0di90aXhOcUI1a2FoU2dsNUhLVXJjQjJCVlVoRjY2aDhyWjQ4YnFEWElRN0NET0szZ3JoNkxrcmpFcmNsRityRWZqdWZ3LzRkRjZ1ZXkya2ViNjY3RlNYRTNEaE90TXRPV0txaVl1b3FiWm5OMm13bGdTTjBwRkprODZaWEVQUUtkMTlOWkloVWdMYWw3OGZadWJicHFYOXhqd3pTY2c3VUE0Y2JGUTdGWFV0eDg3dGVyNS9wcHByOGk3RVE1Q1RId0xzWEV6cWVQTEIrZVBCRzB6UDBsbVdNSkxxVHJJMC9KYXErK0l6RzBBNXNVZ1lxMUFsT05WZ3hsMGVPQ1pDVmVrby8rTHg4RkdDdzJWcGwzWkNqRGN5c1FCYkZlWWpUWDJSVG1Xa3ZrRmRSSDQzK2RsY3ovQmlDZWZQMGtISzk1by9iYWoyeHl1bGgrV1g0VUNkWWlNdUcvR25wQVU3NTc5UjNEWFlxMUhaRDRibEg0a0phZDlVZ2hFOEoxaXdacU9zVWtTM0RBMnRpWEZmbW1VSjFIbWpYU1ZHckhSUXExMFRncnBycW5DR2ZrUTUwbGxlMkhIUkRmLzNpQ2ltYUQxSkRnc1duYytyd2QyWlVtVkNFQU1pUG9xQng0cGdqUmtQOHZsa25QNm1NTEcvZkNEb0Rid3I0U1o1RDRiMkFPcjFWTVBoRDBGQlpBTC8wUFE5aWFETi9acHkydVBTRWd5ck5kU25GKytrakdMMnJQTUNHdFNJMUIwWFZudmE0NkhucmQ4ZGVVcUV1QmRhWWMwZW1JWkxuRVZ5OW8xTGhoeFNMamNEbnhlWk41ZW0zclNHdUVUN2MyMzAwOWdwR0hSOUlSU1RHZ2RVTTQrdmRycStBbHJtODlwNG1na09QUjNpdFU5UkVoMGQ5N3p3cGF2NkZRZ0liQXI0bEZDNTI0Y1hQTkdxeC85U0dodUt2enBoV0RqM05hK1phek90aUFIeTF4dklPZXk4eTBzMXJoWC9MRVRJRzZEREhaaU13eFlMbHF0c1piM3JlNEowOHBPUW9SdmVLSVF4amNwZVJRZWxuWUlsTkUvRlUyaktaeGNkakNjSDVxNlMrZmUwQW1iVng1ZDRaWi91akhnNWtycWlWWHpoMW9uTzF2WTh3emdORm9Ha2d4RDVFV3luSGFWN0ZKeWhwdUYrdVRvRG9nSjROcHo5eFQwVWNPVkJnMDl3T2VYak9vSTVsOWwyOWRZSlQ3TTVmcTlXd3B4QXRZaTI0Q1JZMkFCMEo1U3BuY2VKOVBFUlhGak1zaFpUM25LaTlxUy9aRVBIb1hwVmdpWUI2dHRSOU1NNUpqR1JJeXlKcnQrN1FtVHBXSzBSSitNcitqbWZ0V25vbThwN0xiL000YmY3dHFQZUFocXVOaWN0QmQ5eTEzL0p3MVVVSjdWR00yK2srRlpQN0tuc1Z6M0hWcERya3VXOVJJNVRDb2xmNUwwMXRiMzRjRjVDeERXb21CcjBkTHpBMkJBYlpBT1E2VEFUK0dvYXNNbC9mOWlMWi9FUks5NFJQbXkvdUtrUlN4bnJBRGorUkpZN1kyUi80UzJIV3A0WHZramJ1MnR5ZWVlTndabWR1SFJLZTVhNmY4SHJUZDlVdGljWTd6cDlJUnJlc2lBTjJoU0ZJaHAxZ05WaysvaXZBY1Rtb3k5b1dER3l2bzFwdEdpeHV6bGc1eGJ5SFRKa1VJWjFJVFZ5STNjZGozN3IxOVZPaThzaUtNZE5vOWtNY1Zsd3RCVkF3V2hDVi9wUlV1YjUzZHBSRFF0VDVCd2k5R3RPSE9YZ2FNYUc2REkyd0F3bHVBcWRYemlRQi9ZdHE1RStJYUIzaG1XRmxQTkN0WExQZ2JpSVBlM1lwNk5YeGY0VjRaV0VwWG9IVmZiYTZmK2k2Zm1tVkYxZThQeWgzVFFNamJSUFFtYWxLNnB2T1VSeTdha21URHEra21BamFHUnBpQnEwSi9yUkgxVUZyOFUxRmg2Q2NPN1B4ZU1QWHdOVGhVMSs4alMrZnJ0TXp1UVAybWJIT21telJzUWRNcE8wZU9YQU5VdVFza1pXZ0g0SFVqSXlVOGVESFcvL25zYnN0L2xxSWhUcjMzRnhtT3p4NkkyRXR6TEw1OWhzVlpIckZIclRhTDVoMWdud00xMmJBdHpyTTBEMzExZFpjaWdMWWRFUkh6WWhWOEkrZWFoOUtybGVZRGs2S0xBVWQwcm1FRnl3MzlVa3JpUW4wU0dwYTZ5N1BnY2V4ZklMZ1hVeE1wWXdJQnZmd0NVaTU3ckRqQWU1ZndyNTN4RkJxQWdSN1RjUHQ0TkF1cDRoYmtiWHNIUDNrVm5tWm1vSHRsSDZ6eW1qdUROaUpYYnFCWTFrVzNicER4Q2FvVmU4YmVSampHWXl0TisyREp3b09scmpSUi9FWjE4Z01vN1lJUk1FMmhoVW9Wa3kyWU04cVpUR0Jxcjk3L2pFRk1nWGlwam13ZTF0Ny9XWFpIMXJVRXI2QmdKeEt6RDBSdFczSXIzeFdmWk1xN1N6SzRyS0huQldOQ3J0VE5LT3FiRnY0UWxJR05sUEdNZHNXMHBWYmRyTkJTdGlhRjRQMWkrUEVraHNWc0h1UWcxQ28zWmlQZmREblVzVWtOOVJoWDhoQmkzT3JsT08yMkJrRDVGT1o1U0xjYjFwbFRsMjlFT0ZvRENWbDRMcXA5SDdPRjFQNG4wczNhankzZTVMUlVJbW9FdE1DR1pVQnpUNStiL1J4eFlneHp4SmJ1WU5DUjM3WGRLK2ZUMHZaSGo3YVB5WEJZUURIUWpHOFVOWVprNnRqMjRyZkxUM0dERzR1aUJBcXYxa3pyd3ZFVVNuMW9JaStLa0lxNUFTdzFPQ1FWMDBCTTk3VXpFMTZLOUtzNTEvcldhdU1BSzJOSHBvcmkzUEFYbTg1MzhkSEtRbmpFWFBGM1o5dDJzKzU3VmxPODFiazJ6NVZ4WDJGenRmNXZybUJORG5vQ1V4eTh1UXVuTHh0S2FrZHpmaDN6ckxRZVRpMjdMVnRMeGtEemJDWVRoWG52YU0zVEl1V3BGeTBTeStGRXNZaXNyTDh3L1F4WGgzRG9RQ0kwMTIvSTVoeXd2Q2VHUHR0VjNicld6MmhhM0drbVgzY3Z5QlpBeWM2T3dhOUhQMnRuTkhPV1VQTEp6TDlWR1IvUXRhM1R5Vm9TMUcwZjg3NGlnd2hBVlkxYUhFbzNncEtrRkpRTFc5eWlGSG9oRzg4aGlxa3ZWTnduc2kyVHZaVlBVbVU4b0xEOEl5VW5WaXd5NzZlMWh4UkRqc1B3VWxsOWdyWU94aGkrUUpQN2xHWjhSc2lPT0lWQm5WSjczdDdQYjVDOXlzbXJuMlNOdUdIUTFTYUxFaGZQN0UyU0FsQ0FETDRDV2cxYXZCK2FPQk9OdEx6Y1ZtV1lRaVk0T1B5dS9iR0pDTmhQcVRheXJLZzMrUTVaU2xGd055UkpZcDcrOUZxU1ljRk15ellPQlYvVUZjU3ovL3E3NU9uTHBzallOaGlwWVplNjgxLzhIR29QV1h4SktPMHd2U0RyNmpYcmJrUHlBSm16ZGtRWEFmYTlNMmNadS9aSTVRVnB2MW5qeVU1bDgxbjhOeDhVVkNrVlY4OFNsS3BlVzZ4QmNpa3JxWlp2NEFsakhKRXVVSzFYZUNSU0o0VU1MU1RqeXg0eWw4cTFmODgxV3RlWE1kK1FOUUtORkJ3b2o4VkNQZHp3Rmtub0h4S3ZmVHJ0TnJVYWlyN0h5L2VsbVNxZExqdUhpeStBRGRET2dLQ0F3cWZ1TGFWb2laWVhENENmVUozTHg3cUJYMDdZVysyZXk5NUdFcEdYVXJyM1lNRTVlT2NyZnZacDNVeTYrSkpRRFZqQ3YyZGRKUHVuWEI2OEFkVzNkTGJSR0lhQVJSV1A5MnlSMFFJTlg8L3hlbmM6Q2lwaGVyVmFsdWU+DQogICAgICAgICAgICA8L3hlbmM6Q2lwaGVyRGF0YT4NCiAgICAgICAgPC94ZW5jOkVuY3J5cHRlZERhdGE+DQogICAgPC9zYW1sOkVuY3J5cHRlZEFzc2VydGlvbj4NCjwvc2FtbHA6UmVzcG9uc2U+
diff --git a/server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_full_response.txt b/server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_full_response.txt
deleted file mode 100644 (file)
index 03e518d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIERlc3RpbmF0aW9uPSJodHRwOi8vbG9jYWxob3N0OjkwMDAvb2F1dGgyL2NhbGxiYWNrL3NhbWwiIElEPSJJRF8yOGM0YzMzZi0yZDNhLTQ5NjEtYjcwZC0yYzMwZmNkYWVkNDAiIEluUmVzcG9uc2VUbz0iT05FTE9HSU5fYjIzZDNjYWYtN2E1Yy00MzcwLWI4NDktMGRiNGQzYzM0ZTc1IiBJc3N1ZUluc3RhbnQ9IjIwMjAtMDYtMDVUMjM6MDI6MjguNDM4WiIgVmVyc2lvbj0iMi4wIj4NCiAgICA8c2FtbDpJc3N1ZXI+aHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL3NvbmFycXViZTwvc2FtbDpJc3N1ZXI+DQogICAgPHNhbWxwOlN0YXR1cz4NCiAgICAgICAgPHNhbWxwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPg0KICAgIDwvc2FtbHA6U3RhdHVzPg0KICAgIDxzYW1sOkFzc2VydGlvbiB4bWxucz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9InBmeDI2YTQzNTgxLTg1OWUtNzZhMC0xN2ZmLTYwMDk0YjEwZDRmZCIgSXNzdWVJbnN0YW50PSIyMDIwLTA2LTA1VDIzOjAyOjI4LjQzOFoiIFZlcnNpb249IjIuMCI+DQogICAgICAgIDxzYW1sOklzc3Vlcj5odHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvc29uYXJxdWJlPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4NCiAgPGRzOlNpZ25lZEluZm8+PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4NCiAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIi8+DQogIDxkczpSZWZlcmVuY2UgVVJJPSIjcGZ4MjZhNDM1ODEtODU5ZS03NmEwLTE3ZmYtNjAwOTRiMTBkNGZkIj48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT5PNFdTcGpQbFVPWWkwdTFtemlQM0NYTzY1eWs9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPlpBTGN6Q2l1U3NvaGxwMVIvbExDK29qZFAyWGNHTytuY2RxRlJ6NXJERlc2T2F1TjlTRTJWSkNIS1BJUE53RVYzSytTdkpkR0hPTDRKTUdZa1kyTHYranRuYWNmOTd5VTZwLzNFam5ZejlTUXZWUEdkSXVCSG5DaHp3SWpVc1V3OXRGYjExa01MR0cyK0ZXeE1TQzZGUzJWT2Zxa3RoSzNnTTI1aUtwNVR0TTN1d0NFQWh0UGNwYXpoWld6cDBvQVovNWp5RnVpaVZPVzBvVnN3WjNnd1k2OTZaenBRbFlYbHlFYURNNUZPWXBXREsvQ3hOa2JxWExwdnZ2My9Qb2JTVktIU2VWRkdvdzE1NzN3a01iSDBSMTJLejdWREtoRGM2THBmZThobmV0Rmgxa2tRU21iRDFzdjVRQUJsbStnS2ZVRTNJU0MxdUtUdFI4c2hML0gxVFNWSEZKSGRWd0hKU0VHQmVBRkhlbFh3NFAxS1hncGxpeTJ2cGN1NWRQMEZKSW13NkpLZEg3V0xUclVpSjJPVmlWaGRTdHdJUFF4U2V6Z21zYVFxb2c1Ri9FaithaVJ5cFR1K2xYVXJMVEFJUHVPdFY5WHJnMGxWYXRQVmJ6U0oxZjVnUE45WFhKbFd5QVErRW95OW00eGVWYmhaOUpuc1VlSWRRUzZMQ0ducHVKMktYb3I1SHVuSGY2RUdmUVZUYmZFVWFxRmFZOHVxZE5aL2JrYkNKYU51TnNDYzVzcWV3Rkx5Z3Q5cjI5Sk1CK2ZjeGhpRUxqZEQzbzA5Wk9wSGtQTnZXTXVLbFFZdWF2ZVF6Z3M5bk5lMVFRcm5RWjRaeFFPVEpJUWdzM1M1a0NoMmdWSDN6MXdBWUdQVUNNOTVFM1hNb1Q0TkpVSWQzMEJlUUh4czJzPTwvZHM6U2lnbmF0dXJlVmFsdWU+DQo8ZHM6S2V5SW5mbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlGNXpDQ0E4K2dBd0lCQWdJVUlYdjlPVnMvWFVpY2dSMWJzVjl1Y2NZaEhmb3dEUVlKS29aSWh2Y05BUUVMQlFBd2dZSXhDekFKQmdOVkJBWVRBa0ZWTVE4d0RRWURWUVFJREFaSFJVNUZWa0V4RURBT0JnTlZCQWNNQjFaRlVrNUpSVkl4RGpBTUJnTlZCQW9NQlZOUFRrRlNNUTB3Q3dZRFZRUUxEQVJSVlVKRk1ROHdEUVlEVlFRRERBWmFhWEJsYm1jeElEQWVCZ2txaGtpRzl3MEJDUUVXRVc1dmNtVndiSGxBWjIxaGFXd3VZMjl0TUI0WERUSXlNRFl4TXpFek1UUXlOMW9YRFRNeU1EWXhNREV6TVRReU4xb3dnWUl4Q3pBSkJnTlZCQVlUQWtGVk1ROHdEUVlEVlFRSURBWkhSVTVGVmtFeEVEQU9CZ05WQkFjTUIxWkZVazVKUlZJeERqQU1CZ05WQkFvTUJWTlBUa0ZTTVEwd0N3WURWUVFMREFSUlZVSkZNUTh3RFFZRFZRUUREQVphYVhCbGJtY3hJREFlQmdrcWhraUc5dzBCQ1FFV0VXNXZjbVZ3YkhsQVoyMWhhV3d1WTI5dE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBdTNuRlhZdklZZWRwUjg0YVprZG8vM3lCNVhITStZQ0ZKY0RzVk8xMHpFYmxMa25mUXNpTVBhMVhkOVVzdG5weHc2UC9TeXpJSm1POWppTU9kZUNlWTk4YTc0alA3ZDRKUGFPNmgzbDlJYldBY1llaWpRZzk1Nm5sc1ZGWTNGSERHcis3UGI4UWNPQXlWM3Y4OWppRjlERkI4d1hTKzVVZllyMk9mb1JSYjRsaTM5ZXpEeURkbDVPTGxNMTFuRXNzMnoxbUV2K3NVVWxvVGN5cmdqMzdQc2dld2t2eXltNnRGR1Nna1Y5WmE0U1ZSaEhGeVRoWTFWRnJZWlNKRlRuYXBVWWFSYzdrTXh6d1gvQUFIVURKcm1ZY2FWYzVCOE9EcDR3MkF4REpoZVF5Q1ZmWGpQRmFVcUJNRzJVL3JZZlZYdTBaYTdQbi92VW80VWFTVGh3Q0JLRGVoQ3d6KzY1VExkQStOeHlHRHhudlkvU2tzT3lMTEdDbXU4dEtrWGR1MHB6bm5JaEJYRUd2alVJVlM3ZDZhLzhnZWc5MU5vVFdhdTNpMFJGK0R3LzVOOURTenBsZDE1YlB0YjVDZTNCaWUxOXV2ZnZ1SDllZytEOHgvaGZGNmYzaWw0c1BsSUtkTy9PVmRNMjhMUmZtRHFtcVFOUHVkdmJxejd4eTRBUnV4azZBUmE0ZCthVDl6b3Zwd3Z4TkdUcjdoMW1kZ09VdFVDZElYTDNTSE5qZHdkQUF6MHVDV3p2RXhiRnUrTlErVjUrWG5reDcxaHlQRnY5K0RMVkdJdTdKaGRZczgwNndLc2hPMTNOZ2EzOGlnNmd1MzdscFZoZnBaWGhLeXdVaWlnRzZMWEFleVdXa01rK3ZsZjlNY1pkTUJEMTZkWlA0a1RzdlArclBWblVDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRkk1VVZMdFR5U3ZiR3FIN1VQOHhUTDR3eFpxM01COEdBMVVkSXdRWU1CYUFGSTVVVkx0VHlTdmJHcUg3VVA4eFRMNHd4WnEzTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCQUJBdFhzS05XeDBzRERGQTUzcVoxelJ5V0tXQU1vaDk1cGF3RkNyS2dURVc0WnJBNzNwYTc5MGVFMVkrdlQ2cVVYS0k0bGk5c2tJRGErNnBzQ2R4aFpJckhQUkFuVlpWZUIyMzczQnhyNWJ3L1hROGVsUkNqV2VNVUxiWUo5dGdzTFYwSTlDaUVQMGE2VG04dDB5RFZYTlVmeDM2RTVma2dMU3J4b1JvOFhKenhIYkpDbkxWWEhkYU5CeE9UN2pWY29tNldvNFBCMmJzalZ6aEhtNmFtbjVoWnA0ZE1IbTBNdjBsbjF3SDhqVm5pekhRQkxzR016dnZsNTgrOXMxcFAxN2NlUkRrcE5EeitFUXlBK1pBcnFrVzFNcXR3Vmhieno4UWdNcHJoZmxLa0FycnNDN3YwNkp2OGZxVWJuOUx2dFlLOUl3SFRYN0o4ZEZjc08vZ1VDNVBldllUM25yaU4zQXpiMjBnZ1NRMXlPRU1venZqNVQ5NlM2aXRmSFBpdDd2eUVRODRKUHJFcWZ1UURaUS9MS1pRcWZ2dVhYMWFBRzNUVTNUTVdCOVZNTUZzVHVNRlM4YmZyaE1YNzdnMFVkNHFKY0JPWU9IM2hSNTlhZ1NkZDJRWk5MUDN6WnNZUUhMTFFrcTk0amRUWEtUcW0vdzdtbFBGS1Y1OUhqVGJIQmhUdHhCSE1mdC9tdnZMRXVDOUtLRmZBT1hZUTZWK3M5TmswQlc0Z2dFZmV3YVg1OE9CdXk3SVNxUnRSRlBHaWExOFlSenpIcWtoanViSllNUGtJZllwRlZkK0MwSUkzRjBrZHk4VHRwY2NqeUtvOWJjSE1MeE80bjhQREFsMTk1Q1B0aE1pOGdVdlQwMDhMR0VvdHIrM2tYc291VEVaVFQwZ2xYS0xkTzJXPC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+DQogICAgICAgIDxzYW1sOlN1YmplY3Q+DQogICAgICAgICAgICA8c2FtbDpOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDp1bnNwZWNpZmllZCI+am9obmRvZTwvc2FtbDpOYW1lSUQ+DQogICAgICAgICAgICA8c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uIE1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlciI+DQogICAgICAgICAgICAgICAgPHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgSW5SZXNwb25zZVRvPSJPTkVMT0dJTl9iMjNkM2NhZi03YTVjLTQzNzAtYjg0OS0wZGI0ZDNjMzRlNzUiIE5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTo0MToyNi40MzhaIiBSZWNpcGllbnQ9Imh0dHA6Ly9sb2NhbGhvc3Q6OTAwMC9vYXV0aDIvY2FsbGJhY2svc2FtbCIvPg0KICAgICAgICAgICAgPC9zYW1sOlN1YmplY3RDb25maXJtYXRpb24+DQogICAgICAgIDwvc2FtbDpTdWJqZWN0Pg0KICAgICAgICA8c2FtbDpDb25kaXRpb25zIE5vdEJlZm9yZT0iMjAyMC0wNi0wNVQyMzowMjoyNi40MzhaIiBOb3RPbk9yQWZ0ZXI9IjIwMzktMDYtMTFUMDk6NDE6MjYuNDM4WiI+DQogICAgICAgICAgICA8c2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF1ZGllbmNlPk15QXBwPC9zYW1sOkF1ZGllbmNlPg0KICAgICAgICAgICAgPC9zYW1sOkF1ZGllbmNlUmVzdHJpY3Rpb24+DQogICAgICAgIDwvc2FtbDpDb25kaXRpb25zPg0KICAgICAgICA8c2FtbDpBdXRoblN0YXRlbWVudCBBdXRobkluc3RhbnQ9IjIwMjAtMDYtMDVUMjM6MDI6MjguNDM5WiIgU2Vzc2lvbkluZGV4PSIyMzc2ZjlhMy0zYjJhLTRlOWEtYmE5Yi04NDc5Y2ViYjQyNTc6OjAyODE1Y2Q1LTllYzktNDY0OS1hOWYwLWQ1ZmRiOTU1NTFkYyIgU2Vzc2lvbk5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTo0MToyOC40MzlaIj4NCiAgICAgICAgICAgIDxzYW1sOkF1dGhuQ29udGV4dD4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3Nlczp1bnNwZWNpZmllZDwvc2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj4NCiAgICAgICAgICAgIDwvc2FtbDpBdXRobkNvbnRleHQ+DQogICAgICAgIDwvc2FtbDpBdXRoblN0YXRlbWVudD4NCiAgICAgICAgPHNhbWw6QXR0cmlidXRlU3RhdGVtZW50Pg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9Im5hbWUiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI+Sm9obiBEb2U8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9ImxvZ2luIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmpvaG5kb2U8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9Imdyb3VwcyIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+DQogICAgICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5kZXZlbG9wZXI8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5wcm9kdWN0LW1hbmFnZXI8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9ImVtYWlsIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmpvaG5kb2VAZW1haWwuY29tPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPg0KICAgICAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZT4NCiAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD4NCiAgICA8L3NhbWw6QXNzZXJ0aW9uPg0KPC9zYW1scDpSZXNwb25zZT4=
diff --git a/server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_full_response_with_reverse_proxy.txt b/server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_full_response_with_reverse_proxy.txt
deleted file mode 100644 (file)
index 19fced7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIERlc3RpbmF0aW9uPSJodHRwczovL2xvY2FsaG9zdC9vYXV0aDIvY2FsbGJhY2svc2FtbCIgSUQ9IklEX2M0NWVjNTk1LTUwNDUtNDkzOS1iYTViLTE4MDRiNTBhZDQwMiIgSW5SZXNwb25zZVRvPSJPTkVMT0dJTl81ZTAzNzM3My0wYjE4LTQ1M2UtOTdhMC0wNWI1NjA2OTkzNzEiIElzc3VlSW5zdGFudD0iMjAyMC0wNi0wOFQxNjowMDo0MC4zOTJaIiBWZXJzaW9uPSIyLjAiPg0KICAgIDxzYW1sOklzc3Vlcj5odHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvc29uYXJxdWJlPC9zYW1sOklzc3Vlcj4NCiAgICA8c2FtbHA6U3RhdHVzPg0KICAgICAgICA8c2FtbHA6U3RhdHVzQ29kZSBWYWx1ZT0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnN0YXR1czpTdWNjZXNzIi8+DQogICAgPC9zYW1scDpTdGF0dXM+DQogICAgPHNhbWw6QXNzZXJ0aW9uIHhtbG5zPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiBJRD0icGZ4OTg0YmQ1ZTQtNTI5ZS1lMjQ1LTU4YjQtYzljMDI1NTc4YjJjIiBJc3N1ZUluc3RhbnQ9IjIwMjAtMDYtMDhUMTY6MDA6NDAuMzkyWiIgVmVyc2lvbj0iMi4wIj4NCiAgICAgICAgPHNhbWw6SXNzdWVyPmh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9hdXRoL3JlYWxtcy9zb25hcnF1YmU8L3NhbWw6SXNzdWVyPjxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPg0KICA8ZHM6U2lnbmVkSW5mbz48ZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPg0KICAgIDxkczpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjcnNhLXNoYTEiLz4NCiAgPGRzOlJlZmVyZW5jZSBVUkk9IiNwZng5ODRiZDVlNC01MjllLWUyNDUtNThiNC1jOWMwMjU1NzhiMmMiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNzaGExIi8+PGRzOkRpZ2VzdFZhbHVlPnZYQllhaHlZajhzL2hEZzhBVDlqMFQyMjV5ST08L2RzOkRpZ2VzdFZhbHVlPjwvZHM6UmVmZXJlbmNlPjwvZHM6U2lnbmVkSW5mbz48ZHM6U2lnbmF0dXJlVmFsdWU+RDB0SFRVWXRXNXkrUHoyNXprNnh2ZnExeXhCSzI1Y3VLWDNwTzhWZG5LUlpQWm43Kzhsa20vZEZNYjVlYXVyRmxrMWJ6alY4N056WktaUk5YZjQyWW9uM0VEQW5oZWxjRUp2d2JDTERSVU80Y1VOdjlSNlRHYVIzMWFYYkNOU1l2c243OUFwaUdtOWZOUkkyYm8xNDI5S2crNllqYmo5MzBzRUtVd0sycjV5Z2FqZmZaVDFWS0lSbnFlTjhOUVN4RVNlMm9XYkpQSjJrSjM4TlV3WGRnN3M4L1dTamFSZ1JPeHVaeUZkelN2VXF2emwxZjNHUG5XeW9DMGpMOWZsMm1ZRDZ2ZGxSUThLWFN1VDJhYzVwRUZ3b3FRVjl3MmNmYUhHRXNmd1hic0MwSWI4T1VHNkUya1hvYTg1WlBEWVIwbXNEUVZIdVlFY1o1bmVCV0tRcGQvQ0wvVzNWaTl5eFZQUE9DN2UrVlFac29MdjB4ZmZ5Z2lEMkoySTJEeTN1TUhIb0VHaFRxUS9UdnpueUVSWThPa2FJMXh2WGpWNE02K0xXV2ZyQmhpTG5TeS9XeW9PNG12aXNLK212MVlPeGhOTTF0M1FUbVAzTWwxQzMwL2ZCSUhEZm1TaEhia0NFQnMrVE10Rk9RdVZ3Q01hc3g4TDJpVVc2ckh1Z0dUYyt3TXM5QWJkVnlDRGdSWG5lQkpjYm1ROXZRNXNGZFRLdHBZZk1BS0U2c1M3ZjJ2Z1VPVGhOQy9lSUJCQ2h0T3pXV3lmdnN1MEVoQnc5Y2NqL3RsTGtFY2haMFZJNHI2enhnajdaTG9xTWpJQlBUSDdteEZRanp0bUZ6K1ZwcExuUDY1KzR5VlZBdTZ0Sm10RmVZR0JjWXlaQ0ZQRHV5a3hpNkRMeTVtYmpIaTQ9PC9kczpTaWduYXR1cmVWYWx1ZT4NCjxkczpLZXlJbmZvPjxkczpYNTA5RGF0YT48ZHM6WDUwOUNlcnRpZmljYXRlPk1JSUY1ekNDQTgrZ0F3SUJBZ0lVSVh2OU9Wcy9YVWljZ1IxYnNWOXVjY1loSGZvd0RRWUpLb1pJaHZjTkFRRUxCUUF3Z1lJeEN6QUpCZ05WQkFZVEFrRlZNUTh3RFFZRFZRUUlEQVpIUlU1RlZrRXhFREFPQmdOVkJBY01CMVpGVWs1SlJWSXhEakFNQmdOVkJBb01CVk5QVGtGU01RMHdDd1lEVlFRTERBUlJWVUpGTVE4d0RRWURWUVFEREFaYWFYQmxibWN4SURBZUJna3Foa2lHOXcwQkNRRVdFVzV2Y21Wd2JIbEFaMjFoYVd3dVkyOXRNQjRYRFRJeU1EWXhNekV6TVRReU4xb1hEVE15TURZeE1ERXpNVFF5TjFvd2dZSXhDekFKQmdOVkJBWVRBa0ZWTVE4d0RRWURWUVFJREFaSFJVNUZWa0V4RURBT0JnTlZCQWNNQjFaRlVrNUpSVkl4RGpBTUJnTlZCQW9NQlZOUFRrRlNNUTB3Q3dZRFZRUUxEQVJSVlVKRk1ROHdEUVlEVlFRRERBWmFhWEJsYm1jeElEQWVCZ2txaGtpRzl3MEJDUUVXRVc1dmNtVndiSGxBWjIxaGFXd3VZMjl0TUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF1M25GWFl2SVllZHBSODRhWmtkby8zeUI1WEhNK1lDRkpjRHNWTzEwekVibExrbmZRc2lNUGExWGQ5VXN0bnB4dzZQL1N5eklKbU85amlNT2RlQ2VZOThhNzRqUDdkNEpQYU82aDNsOUliV0FjWWVpalFnOTU2bmxzVkZZM0ZIREdyKzdQYjhRY09BeVYzdjg5amlGOURGQjh3WFMrNVVmWXIyT2ZvUlJiNGxpMzllekR5RGRsNU9MbE0xMW5Fc3MyejFtRXYrc1VVbG9UY3lyZ2ozN1BzZ2V3a3Z5eW02dEZHU2drVjlaYTRTVlJoSEZ5VGhZMVZGcllaU0pGVG5hcFVZYVJjN2tNeHp3WC9BQUhVREpybVljYVZjNUI4T0RwNHcyQXhESmhlUXlDVmZYalBGYVVxQk1HMlUvcllmVlh1MFphN1BuL3ZVbzRVYVNUaHdDQktEZWhDd3orNjVUTGRBK054eUdEeG52WS9Ta3NPeUxMR0NtdTh0S2tYZHUwcHpubkloQlhFR3ZqVUlWUzdkNmEvOGdlZzkxTm9UV2F1M2kwUkYrRHcvNU45RFN6cGxkMTViUHRiNUNlM0JpZTE5dXZmdnVIOWVnK0Q4eC9oZkY2ZjNpbDRzUGxJS2RPL09WZE0yOExSZm1EcW1xUU5QdWR2YnF6N3h5NEFSdXhrNkFSYTRkK2FUOXpvdnB3dnhOR1RyN2gxbWRnT1V0VUNkSVhMM1NITmpkd2RBQXowdUNXenZFeGJGdStOUStWNStYbmt4NzFoeVBGdjkrRExWR0l1N0poZFlzODA2d0tzaE8xM05nYTM4aWc2Z3UzN2xwVmhmcFpYaEt5d1VpaWdHNkxYQWV5V1drTWsrdmxmOU1jWmRNQkQxNmRaUDRrVHN2UCtyUFZuVUNBd0VBQWFOVE1GRXdIUVlEVlIwT0JCWUVGSTVVVkx0VHlTdmJHcUg3VVA4eFRMNHd4WnEzTUI4R0ExVWRJd1FZTUJhQUZJNVVWTHRUeVN2YkdxSDdVUDh4VEw0d3hacTNNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnSUJBQkF0WHNLTld4MHNEREZBNTNxWjF6UnlXS1dBTW9oOTVwYXdGQ3JLZ1RFVzRackE3M3BhNzkwZUUxWSt2VDZxVVhLSTRsaTlza0lEYSs2cHNDZHhoWklySFBSQW5WWlZlQjIzNzNCeHI1YncvWFE4ZWxSQ2pXZU1VTGJZSjl0Z3NMVjBJOUNpRVAwYTZUbTh0MHlEVlhOVWZ4MzZFNWZrZ0xTcnhvUm84WEp6eEhiSkNuTFZYSGRhTkJ4T1Q3alZjb202V280UEIyYnNqVnpoSG02YW1uNWhacDRkTUhtME12MGxuMXdIOGpWbml6SFFCTHNHTXp2dmw1OCs5czFwUDE3Y2VSRGtwTkR6K0VReUErWkFycWtXMU1xdHdWaGJ6ejhRZ01wcmhmbEtrQXJyc0M3djA2SnY4ZnFVYm45THZ0WUs5SXdIVFg3SjhkRmNzTy9nVUM1UGV2WVQzbnJpTjNBemIyMGdnU1ExeU9FTW96dmo1VDk2UzZpdGZIUGl0N3Z5RVE4NEpQckVxZnVRRFpRL0xLWlFxZnZ1WFgxYUFHM1RVM1RNV0I5Vk1NRnNUdU1GUzhiZnJoTVg3N2cwVWQ0cUpjQk9ZT0gzaFI1OWFnU2RkMlFaTkxQM3pac1lRSExMUWtxOTRqZFRYS1RxbS93N21sUEZLVjU5SGpUYkhCaFR0eEJITWZ0L212dkxFdUM5S0tGZkFPWFlRNlYrczlOazBCVzRnZ0VmZXdhWDU4T0J1eTdJU3FSdFJGUEdpYTE4WVJ6ekhxa2hqdWJKWU1Qa0lmWXBGVmQrQzBJSTNGMGtkeThUdHBjY2p5S285YmNITUx4TzRuOFBEQWwxOTVDUHRoTWk4Z1V2VDAwOExHRW90cisza1hzb3VURVpUVDBnbFhLTGRPMlc8L2RzOlg1MDlDZXJ0aWZpY2F0ZT48L2RzOlg1MDlEYXRhPjwvZHM6S2V5SW5mbz48L2RzOlNpZ25hdHVyZT4NCiAgICAgICAgPHNhbWw6U3ViamVjdD4NCiAgICAgICAgICAgIDxzYW1sOk5hbWVJRCBGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OnVuc3BlY2lmaWVkIj5qb2huZG9lPC9zYW1sOk5hbWVJRD4NCiAgICAgICAgICAgIDxzYW1sOlN1YmplY3RDb25maXJtYXRpb24gTWV0aG9kPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6Y206YmVhcmVyIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uRGF0YSBJblJlc3BvbnNlVG89Ik9ORUxPR0lOXzVlMDM3MzczLTBiMTgtNDUzZS05N2EwLTA1YjU2MDY5OTM3MSIgTm90T25PckFmdGVyPSIyMDM5LTA2LTE0VDAyOjM5OjM4LjM5MloiIFJlY2lwaWVudD0iaHR0cHM6Ly9sb2NhbGhvc3Qvb2F1dGgyL2NhbGxiYWNrL3NhbWwiLz4NCiAgICAgICAgICAgIDwvc2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uPg0KICAgICAgICA8L3NhbWw6U3ViamVjdD4NCiAgICAgICAgPHNhbWw6Q29uZGl0aW9ucyBOb3RCZWZvcmU9IjIwMjAtMDYtMDhUMTY6MDA6MzguMzkyWiIgTm90T25PckFmdGVyPSIyMDM5LTA2LTE0VDAyOjM5OjM4LjM5MloiPg0KICAgICAgICAgICAgPHNhbWw6QXVkaWVuY2VSZXN0cmljdGlvbj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdWRpZW5jZT5NeUFwcDwvc2FtbDpBdWRpZW5jZT4NCiAgICAgICAgICAgIDwvc2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPg0KICAgICAgICA8L3NhbWw6Q29uZGl0aW9ucz4NCiAgICAgICAgPHNhbWw6QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50PSIyMDIwLTA2LTA4VDE2OjAwOjQwLjM5M1oiIFNlc3Npb25JbmRleD0iYWYyN2JiMTMtNmQxYy00MTMzLWFkNTMtMDVkN2MyNGZmZDM2OjowMjgxNWNkNS05ZWM5LTQ2NDktYTlmMC1kNWZkYjk1NTUxZGMiIFNlc3Npb25Ob3RPbk9yQWZ0ZXI9IjIwMzktMDYtMTRUMDI6Mzk6NDAuMzkzWiI+DQogICAgICAgICAgICA8c2FtbDpBdXRobkNvbnRleHQ+DQogICAgICAgICAgICAgICAgPHNhbWw6QXV0aG5Db250ZXh0Q2xhc3NSZWY+dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFjOmNsYXNzZXM6dW5zcGVjaWZpZWQ8L3NhbWw6QXV0aG5Db250ZXh0Q2xhc3NSZWY+DQogICAgICAgICAgICA8L3NhbWw6QXV0aG5Db250ZXh0Pg0KICAgICAgICA8L3NhbWw6QXV0aG5TdGF0ZW1lbnQ+DQogICAgICAgIDxzYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD4NCiAgICAgICAgICAgIDxzYW1sOkF0dHJpYnV0ZSBOYW1lPSJlbWFpbCIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+DQogICAgICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5qb2huZG9lQGVtYWlsLmNvbTwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT4NCiAgICAgICAgICAgIDwvc2FtbDpBdHRyaWJ1dGU+DQogICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGUgTmFtZT0ibG9naW4iIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI+am9obmRvZTwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT4NCiAgICAgICAgICAgIDwvc2FtbDpBdHRyaWJ1dGU+DQogICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGUgTmFtZT0iZ3JvdXBzIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmRldmVsb3Blcjwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPnByb2R1Y3QtbWFuYWdlcjwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPnNvbmFyLWFkbWluaXN0cmF0b3JzPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPg0KICAgICAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZT4NCiAgICAgICAgICAgIDxzYW1sOkF0dHJpYnV0ZSBOYW1lPSJuYW1lIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPkpvaG4gRG9lPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPg0KICAgICAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZT4NCiAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD4NCiAgICA8L3NhbWw6QXNzZXJ0aW9uPg0KPC9zYW1scDpSZXNwb25zZT4=
diff --git a/server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_minimal_response.txt b/server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_minimal_response.txt
deleted file mode 100644 (file)
index 37de1e3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIERlc3RpbmF0aW9uPSJodHRwOi8vbG9jYWxob3N0OjkwMDAvb2F1dGgyL2NhbGxiYWNrL3NhbWwiIElEPSJJRF85ZjFjOTUyYy0zZDA0LTQyN2ItYTE3NS05NDk3ZmQ5NGM4MmYiIEluUmVzcG9uc2VUbz0iT05FTE9HSU5fYzhmNzUxYzgtZWQ4OS00MmNlLTlhMTgtZTQyMjk0NTI0NzQ4IiBJc3N1ZUluc3RhbnQ9IjIwMjAtMDYtMDVUMjI6NTg6NDUuMTg1WiIgVmVyc2lvbj0iMi4wIj4NCiAgICA8c2FtbDpJc3N1ZXI+aHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL3NvbmFycXViZTwvc2FtbDpJc3N1ZXI+DQogICAgPHNhbWxwOlN0YXR1cz4NCiAgICAgICAgPHNhbWxwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPg0KICAgIDwvc2FtbHA6U3RhdHVzPg0KICAgIDxzYW1sOkFzc2VydGlvbiB4bWxucz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9InBmeGI2YTcwOGQzLWI0ODctN2Y4ZS0xNjhjLWVjN2JmZjljYWVkOSIgSXNzdWVJbnN0YW50PSIyMDIwLTA2LTA1VDIyOjU4OjQ1LjE4NFoiIFZlcnNpb249IjIuMCI+DQogICAgICAgIDxzYW1sOklzc3Vlcj5odHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvc29uYXJxdWJlPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4NCiAgPGRzOlNpZ25lZEluZm8+PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4NCiAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIi8+DQogIDxkczpSZWZlcmVuY2UgVVJJPSIjcGZ4YjZhNzA4ZDMtYjQ4Ny03ZjhlLTE2OGMtZWM3YmZmOWNhZWQ5Ij48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT51RFVNb3VsVXQrdjNUZ29VZEN0Y2hHSHp3Mk09PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPmJsdnhTZFhuVWdpaGhSK3UzbzV5NC9yZUVvNHdzL2JnRERCMFRUaXlxSDJQOTQvUHR4Qkg4TXZEdjQyTStYZEd0WWtWQUdPRlpJMHN1U2ZIRURKY1A3SUFSeEc0MnBGaDZqQjVKbVMxWGlNa2NSYVR6amE5QkVmZ3cySUFhYWRyUkQxNGdUb1RaSVpVV3JyVnlGM1U0L0JHbEphRHRTTlI4ajRQaHNPaDR4Qk5jWUh0ZXY2YTVBYm5naVkzZjZXWERoQnVMZEhJSnhUL0RQRUxJZGFESFRtZzRRVEtYemVzbEFQZGxMQy9EUkdJbUh2MWZNTVp0Z0VQNEZqQWtxVFkzUDZvdmg1M09nVHp6dUJkOEp0SlhudFZsbXVyc0ZhbUpidERyZk0rS1lyemNrUXpRbEFlVGlBdFVzeDN6akJKYUUwRS9hdytHRzAyd2FFUmIxc25maVpSL3Q5M050KzlLNFhsYWhrcEsrUyt3QmFtc2pJQmNBZEIzVERLZ3U3MlA5NXpZRkkvRzRCQko1U3liLy9xVFRhY0JsUFhMMkFWNllrK1lMU1BDbzE1eEFnYzFTWVBxZ3ZaZ09hbVcwcTYrMHpJWFVHTk9HdGdaUStINGkwdDNmMG1jQ0tRcFNaeHBqdytOTUE4TDlDSS9uQkdEOWI4MTVsOUNQZmNNMDFlYzV3Qm1XRWRDcW9xMy9lN2hkTW5KM3V0M1hVZTRsSTBLcW05M0kyT3JpeVA5bWlsU0JiOWhjZ2I0bTVITjJRamQ3dzI3S3AyMVI2YmNXYTdhQWptazlLajJldkZGWEVlcXRvZGptRW1kb1ZJOXR2YkpQcWswcUh1SndJaFF2STIvNEtZckR2U2J0a2xodmJxQnBHQU5tTFpYTm8yeHBaS3R3WGtoOVVXNkNBPTwvZHM6U2lnbmF0dXJlVmFsdWU+DQo8ZHM6S2V5SW5mbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlGNXpDQ0E4K2dBd0lCQWdJVUlYdjlPVnMvWFVpY2dSMWJzVjl1Y2NZaEhmb3dEUVlKS29aSWh2Y05BUUVMQlFBd2dZSXhDekFKQmdOVkJBWVRBa0ZWTVE4d0RRWURWUVFJREFaSFJVNUZWa0V4RURBT0JnTlZCQWNNQjFaRlVrNUpSVkl4RGpBTUJnTlZCQW9NQlZOUFRrRlNNUTB3Q3dZRFZRUUxEQVJSVlVKRk1ROHdEUVlEVlFRRERBWmFhWEJsYm1jeElEQWVCZ2txaGtpRzl3MEJDUUVXRVc1dmNtVndiSGxBWjIxaGFXd3VZMjl0TUI0WERUSXlNRFl4TXpFek1UUXlOMW9YRFRNeU1EWXhNREV6TVRReU4xb3dnWUl4Q3pBSkJnTlZCQVlUQWtGVk1ROHdEUVlEVlFRSURBWkhSVTVGVmtFeEVEQU9CZ05WQkFjTUIxWkZVazVKUlZJeERqQU1CZ05WQkFvTUJWTlBUa0ZTTVEwd0N3WURWUVFMREFSUlZVSkZNUTh3RFFZRFZRUUREQVphYVhCbGJtY3hJREFlQmdrcWhraUc5dzBCQ1FFV0VXNXZjbVZ3YkhsQVoyMWhhV3d1WTI5dE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBdTNuRlhZdklZZWRwUjg0YVprZG8vM3lCNVhITStZQ0ZKY0RzVk8xMHpFYmxMa25mUXNpTVBhMVhkOVVzdG5weHc2UC9TeXpJSm1POWppTU9kZUNlWTk4YTc0alA3ZDRKUGFPNmgzbDlJYldBY1llaWpRZzk1Nm5sc1ZGWTNGSERHcis3UGI4UWNPQXlWM3Y4OWppRjlERkI4d1hTKzVVZllyMk9mb1JSYjRsaTM5ZXpEeURkbDVPTGxNMTFuRXNzMnoxbUV2K3NVVWxvVGN5cmdqMzdQc2dld2t2eXltNnRGR1Nna1Y5WmE0U1ZSaEhGeVRoWTFWRnJZWlNKRlRuYXBVWWFSYzdrTXh6d1gvQUFIVURKcm1ZY2FWYzVCOE9EcDR3MkF4REpoZVF5Q1ZmWGpQRmFVcUJNRzJVL3JZZlZYdTBaYTdQbi92VW80VWFTVGh3Q0JLRGVoQ3d6KzY1VExkQStOeHlHRHhudlkvU2tzT3lMTEdDbXU4dEtrWGR1MHB6bm5JaEJYRUd2alVJVlM3ZDZhLzhnZWc5MU5vVFdhdTNpMFJGK0R3LzVOOURTenBsZDE1YlB0YjVDZTNCaWUxOXV2ZnZ1SDllZytEOHgvaGZGNmYzaWw0c1BsSUtkTy9PVmRNMjhMUmZtRHFtcVFOUHVkdmJxejd4eTRBUnV4azZBUmE0ZCthVDl6b3Zwd3Z4TkdUcjdoMW1kZ09VdFVDZElYTDNTSE5qZHdkQUF6MHVDV3p2RXhiRnUrTlErVjUrWG5reDcxaHlQRnY5K0RMVkdJdTdKaGRZczgwNndLc2hPMTNOZ2EzOGlnNmd1MzdscFZoZnBaWGhLeXdVaWlnRzZMWEFleVdXa01rK3ZsZjlNY1pkTUJEMTZkWlA0a1RzdlArclBWblVDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRkk1VVZMdFR5U3ZiR3FIN1VQOHhUTDR3eFpxM01COEdBMVVkSXdRWU1CYUFGSTVVVkx0VHlTdmJHcUg3VVA4eFRMNHd4WnEzTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCQUJBdFhzS05XeDBzRERGQTUzcVoxelJ5V0tXQU1vaDk1cGF3RkNyS2dURVc0WnJBNzNwYTc5MGVFMVkrdlQ2cVVYS0k0bGk5c2tJRGErNnBzQ2R4aFpJckhQUkFuVlpWZUIyMzczQnhyNWJ3L1hROGVsUkNqV2VNVUxiWUo5dGdzTFYwSTlDaUVQMGE2VG04dDB5RFZYTlVmeDM2RTVma2dMU3J4b1JvOFhKenhIYkpDbkxWWEhkYU5CeE9UN2pWY29tNldvNFBCMmJzalZ6aEhtNmFtbjVoWnA0ZE1IbTBNdjBsbjF3SDhqVm5pekhRQkxzR016dnZsNTgrOXMxcFAxN2NlUkRrcE5EeitFUXlBK1pBcnFrVzFNcXR3Vmhieno4UWdNcHJoZmxLa0FycnNDN3YwNkp2OGZxVWJuOUx2dFlLOUl3SFRYN0o4ZEZjc08vZ1VDNVBldllUM25yaU4zQXpiMjBnZ1NRMXlPRU1venZqNVQ5NlM2aXRmSFBpdDd2eUVRODRKUHJFcWZ1UURaUS9MS1pRcWZ2dVhYMWFBRzNUVTNUTVdCOVZNTUZzVHVNRlM4YmZyaE1YNzdnMFVkNHFKY0JPWU9IM2hSNTlhZ1NkZDJRWk5MUDN6WnNZUUhMTFFrcTk0amRUWEtUcW0vdzdtbFBGS1Y1OUhqVGJIQmhUdHhCSE1mdC9tdnZMRXVDOUtLRmZBT1hZUTZWK3M5TmswQlc0Z2dFZmV3YVg1OE9CdXk3SVNxUnRSRlBHaWExOFlSenpIcWtoanViSllNUGtJZllwRlZkK0MwSUkzRjBrZHk4VHRwY2NqeUtvOWJjSE1MeE80bjhQREFsMTk1Q1B0aE1pOGdVdlQwMDhMR0VvdHIrM2tYc291VEVaVFQwZ2xYS0xkTzJXPC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+DQogICAgICAgIDxzYW1sOlN1YmplY3Q+DQogICAgICAgICAgICA8c2FtbDpOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDp1bnNwZWNpZmllZCI+am9obmRvZTwvc2FtbDpOYW1lSUQ+DQogICAgICAgICAgICA8c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uIE1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlciI+DQogICAgICAgICAgICAgICAgPHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgSW5SZXNwb25zZVRvPSJPTkVMT0dJTl9jOGY3NTFjOC1lZDg5LTQyY2UtOWExOC1lNDIyOTQ1MjQ3NDgiIE5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTozNzo0My4xODRaIiBSZWNpcGllbnQ9Imh0dHA6Ly9sb2NhbGhvc3Q6OTAwMC9vYXV0aDIvY2FsbGJhY2svc2FtbCIvPg0KICAgICAgICAgICAgPC9zYW1sOlN1YmplY3RDb25maXJtYXRpb24+DQogICAgICAgIDwvc2FtbDpTdWJqZWN0Pg0KICAgICAgICA8c2FtbDpDb25kaXRpb25zIE5vdEJlZm9yZT0iMjAyMC0wNi0wNVQyMjo1ODo0My4xODRaIiBOb3RPbk9yQWZ0ZXI9IjIwMzktMDYtMTFUMDk6Mzc6NDMuMTg0WiI+DQogICAgICAgICAgICA8c2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF1ZGllbmNlPk15QXBwPC9zYW1sOkF1ZGllbmNlPg0KICAgICAgICAgICAgPC9zYW1sOkF1ZGllbmNlUmVzdHJpY3Rpb24+DQogICAgICAgIDwvc2FtbDpDb25kaXRpb25zPg0KICAgICAgICA8c2FtbDpBdXRoblN0YXRlbWVudCBBdXRobkluc3RhbnQ9IjIwMjAtMDYtMDVUMjI6NTg6NDUuMTg1WiIgU2Vzc2lvbkluZGV4PSI4MjJhZWYyYS0wZDJlLTQyY2EtYTdiMS0wMjgzZDhhZjZjZmI6OjAyODE1Y2Q1LTllYzktNDY0OS1hOWYwLWQ1ZmRiOTU1NTFkYyIgU2Vzc2lvbk5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTozNzo0NS4xODVaIj4NCiAgICAgICAgICAgIDxzYW1sOkF1dGhuQ29udGV4dD4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3Nlczp1bnNwZWNpZmllZDwvc2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj4NCiAgICAgICAgICAgIDwvc2FtbDpBdXRobkNvbnRleHQ+DQogICAgICAgIDwvc2FtbDpBdXRoblN0YXRlbWVudD4NCiAgICAgICAgPHNhbWw6QXR0cmlidXRlU3RhdGVtZW50Pg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9Im5hbWUiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI+Sm9obiBEb2U8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9ImxvZ2luIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmpvaG5kb2U8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICA8L3NhbWw6QXR0cmlidXRlU3RhdGVtZW50Pg0KICAgIDwvc2FtbDpBc3NlcnRpb24+DQo8L3NhbWxwOlJlc3BvbnNlPg==
diff --git a/server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_response_without_login.txt b/server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_response_without_login.txt
deleted file mode 100644 (file)
index 5826b4f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIERlc3RpbmF0aW9uPSJodHRwOi8vbG9jYWxob3N0OjkwMDAvb2F1dGgyL2NhbGxiYWNrL3NhbWwiIElEPSJJRF9lZTFlNzNkZi1iMWQ4LTQzODUtOGMxNC01YmJlYTZhYTJlMTkiIEluUmVzcG9uc2VUbz0iT05FTE9HSU5fMjY3ZTFiMDUtZTIzNy00YWIwLWFiYmItODZiNTBjNDJiMGQ5IiBJc3N1ZUluc3RhbnQ9IjIwMjAtMDYtMDVUMjM6MDU6MTAuNjQ2WiIgVmVyc2lvbj0iMi4wIj4NCiAgICA8c2FtbDpJc3N1ZXI+aHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL3NvbmFycXViZTwvc2FtbDpJc3N1ZXI+DQogICAgPHNhbWxwOlN0YXR1cz4NCiAgICAgICAgPHNhbWxwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPg0KICAgIDwvc2FtbHA6U3RhdHVzPg0KICAgIDxzYW1sOkFzc2VydGlvbiB4bWxucz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9InBmeDUzOTljNDIxLTcxZTYtYTIwYy00MmFhLTg3ZGZmOWY4OTA5YyIgSXNzdWVJbnN0YW50PSIyMDIwLTA2LTA1VDIzOjA1OjEwLjY0NVoiIFZlcnNpb249IjIuMCI+DQogICAgICAgIDxzYW1sOklzc3Vlcj5odHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvc29uYXJxdWJlPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4NCiAgPGRzOlNpZ25lZEluZm8+PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4NCiAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIi8+DQogIDxkczpSZWZlcmVuY2UgVVJJPSIjcGZ4NTM5OWM0MjEtNzFlNi1hMjBjLTQyYWEtODdkZmY5Zjg5MDljIj48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT40eERlSHhWWFArWElnK0VBNHlHdmxTQkx5YmM9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPkROQzhzSDJLMjFlSXNaTGYxREdzbS9hTHhqMC9BOVRpbEhqUjNJZlNMRDZSTHYzWlRCcnNaT1A3UFdDVnNjVklhQVRnT0d1TStCWVlYRGFaVVlNTDQvS1p5cVVDRFNkbWRqa0hSZUxYSXVnU1RoaHJDRTI0VElJbnFuaXpsdVV4dWtLQUJEUkp4RVZaZ01ocVZpcHVjSHdWdjBjQWlRd0xRWmphSjl5TGJ6b0lNL09RZjJ2NE8ySTJ5azJYZVBpKytXeUJwVGNPN2NIWVZBSHRlYURqUFFnYklMcUtWOHdTSW12NkQzL2kxSisrMk41L2IrRlp0Sk1RTEUwbUdzU0hiQUc2ZmNXekplSWlUK0tqNTdzVUd2RldQSGNqSVRPQU50WCtYd0VCaDZpWVFYb3FhOFZqMzhZOU9mbm9FcThwTHBCTjBHODdzY1dta29jRE12RVJuQ2NoTGY0VVJsQmJwRTZaaWJzNnNiUmdzcVRPR3pGNjhhNXVhZlBPNzFCRHh3Qy9wK1c2azlRYWVISXBFNTduYzN0cUNCV2ZuczR6dHJQUDVDRWRJS2VNbVpZRStQOURibnV2bE9lU1U4NmlhZVZ5SjB0NnIxYlo1QkNkQVNNUk9WaFRUZFc4MEtFTmVGdlltcUk1OCtXQWpja3VFeUViR3NhajJyNkpCUmlxc1JOaDlJa21vbkhGaEpOU3c4VjRIY3dubjVjd1p1Sk1WNWpiWlBGY3ByUE5vWUp3L3VuaGpFelVlWUdKOG1ldlVaQkpYWktCRDhXLzMzZHdaeUl4WFlIZDJuUXlPMlVTM2hudXhJZnA4bUZyYjduWVM4Zk9KL1UvY2pleDU2MDFKM3VmQ1FwQTZmM0lGeVVwOXZKS2IvWFIzK3hmdFlyMUhMNTBnY1h4cFp3PTwvZHM6U2lnbmF0dXJlVmFsdWU+DQo8ZHM6S2V5SW5mbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlGNXpDQ0E4K2dBd0lCQWdJVUlYdjlPVnMvWFVpY2dSMWJzVjl1Y2NZaEhmb3dEUVlKS29aSWh2Y05BUUVMQlFBd2dZSXhDekFKQmdOVkJBWVRBa0ZWTVE4d0RRWURWUVFJREFaSFJVNUZWa0V4RURBT0JnTlZCQWNNQjFaRlVrNUpSVkl4RGpBTUJnTlZCQW9NQlZOUFRrRlNNUTB3Q3dZRFZRUUxEQVJSVlVKRk1ROHdEUVlEVlFRRERBWmFhWEJsYm1jeElEQWVCZ2txaGtpRzl3MEJDUUVXRVc1dmNtVndiSGxBWjIxaGFXd3VZMjl0TUI0WERUSXlNRFl4TXpFek1UUXlOMW9YRFRNeU1EWXhNREV6TVRReU4xb3dnWUl4Q3pBSkJnTlZCQVlUQWtGVk1ROHdEUVlEVlFRSURBWkhSVTVGVmtFeEVEQU9CZ05WQkFjTUIxWkZVazVKUlZJeERqQU1CZ05WQkFvTUJWTlBUa0ZTTVEwd0N3WURWUVFMREFSUlZVSkZNUTh3RFFZRFZRUUREQVphYVhCbGJtY3hJREFlQmdrcWhraUc5dzBCQ1FFV0VXNXZjbVZ3YkhsQVoyMWhhV3d1WTI5dE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBdTNuRlhZdklZZWRwUjg0YVprZG8vM3lCNVhITStZQ0ZKY0RzVk8xMHpFYmxMa25mUXNpTVBhMVhkOVVzdG5weHc2UC9TeXpJSm1POWppTU9kZUNlWTk4YTc0alA3ZDRKUGFPNmgzbDlJYldBY1llaWpRZzk1Nm5sc1ZGWTNGSERHcis3UGI4UWNPQXlWM3Y4OWppRjlERkI4d1hTKzVVZllyMk9mb1JSYjRsaTM5ZXpEeURkbDVPTGxNMTFuRXNzMnoxbUV2K3NVVWxvVGN5cmdqMzdQc2dld2t2eXltNnRGR1Nna1Y5WmE0U1ZSaEhGeVRoWTFWRnJZWlNKRlRuYXBVWWFSYzdrTXh6d1gvQUFIVURKcm1ZY2FWYzVCOE9EcDR3MkF4REpoZVF5Q1ZmWGpQRmFVcUJNRzJVL3JZZlZYdTBaYTdQbi92VW80VWFTVGh3Q0JLRGVoQ3d6KzY1VExkQStOeHlHRHhudlkvU2tzT3lMTEdDbXU4dEtrWGR1MHB6bm5JaEJYRUd2alVJVlM3ZDZhLzhnZWc5MU5vVFdhdTNpMFJGK0R3LzVOOURTenBsZDE1YlB0YjVDZTNCaWUxOXV2ZnZ1SDllZytEOHgvaGZGNmYzaWw0c1BsSUtkTy9PVmRNMjhMUmZtRHFtcVFOUHVkdmJxejd4eTRBUnV4azZBUmE0ZCthVDl6b3Zwd3Z4TkdUcjdoMW1kZ09VdFVDZElYTDNTSE5qZHdkQUF6MHVDV3p2RXhiRnUrTlErVjUrWG5reDcxaHlQRnY5K0RMVkdJdTdKaGRZczgwNndLc2hPMTNOZ2EzOGlnNmd1MzdscFZoZnBaWGhLeXdVaWlnRzZMWEFleVdXa01rK3ZsZjlNY1pkTUJEMTZkWlA0a1RzdlArclBWblVDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRkk1VVZMdFR5U3ZiR3FIN1VQOHhUTDR3eFpxM01COEdBMVVkSXdRWU1CYUFGSTVVVkx0VHlTdmJHcUg3VVA4eFRMNHd4WnEzTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCQUJBdFhzS05XeDBzRERGQTUzcVoxelJ5V0tXQU1vaDk1cGF3RkNyS2dURVc0WnJBNzNwYTc5MGVFMVkrdlQ2cVVYS0k0bGk5c2tJRGErNnBzQ2R4aFpJckhQUkFuVlpWZUIyMzczQnhyNWJ3L1hROGVsUkNqV2VNVUxiWUo5dGdzTFYwSTlDaUVQMGE2VG04dDB5RFZYTlVmeDM2RTVma2dMU3J4b1JvOFhKenhIYkpDbkxWWEhkYU5CeE9UN2pWY29tNldvNFBCMmJzalZ6aEhtNmFtbjVoWnA0ZE1IbTBNdjBsbjF3SDhqVm5pekhRQkxzR016dnZsNTgrOXMxcFAxN2NlUkRrcE5EeitFUXlBK1pBcnFrVzFNcXR3Vmhieno4UWdNcHJoZmxLa0FycnNDN3YwNkp2OGZxVWJuOUx2dFlLOUl3SFRYN0o4ZEZjc08vZ1VDNVBldllUM25yaU4zQXpiMjBnZ1NRMXlPRU1venZqNVQ5NlM2aXRmSFBpdDd2eUVRODRKUHJFcWZ1UURaUS9MS1pRcWZ2dVhYMWFBRzNUVTNUTVdCOVZNTUZzVHVNRlM4YmZyaE1YNzdnMFVkNHFKY0JPWU9IM2hSNTlhZ1NkZDJRWk5MUDN6WnNZUUhMTFFrcTk0amRUWEtUcW0vdzdtbFBGS1Y1OUhqVGJIQmhUdHhCSE1mdC9tdnZMRXVDOUtLRmZBT1hZUTZWK3M5TmswQlc0Z2dFZmV3YVg1OE9CdXk3SVNxUnRSRlBHaWExOFlSenpIcWtoanViSllNUGtJZllwRlZkK0MwSUkzRjBrZHk4VHRwY2NqeUtvOWJjSE1MeE80bjhQREFsMTk1Q1B0aE1pOGdVdlQwMDhMR0VvdHIrM2tYc291VEVaVFQwZ2xYS0xkTzJXPC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+DQogICAgICAgIDxzYW1sOlN1YmplY3Q+DQogICAgICAgICAgICA8c2FtbDpOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDp1bnNwZWNpZmllZCI+am9obmRvZTwvc2FtbDpOYW1lSUQ+DQogICAgICAgICAgICA8c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uIE1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlciI+DQogICAgICAgICAgICAgICAgPHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgSW5SZXNwb25zZVRvPSJPTkVMT0dJTl8yNjdlMWIwNS1lMjM3LTRhYjAtYWJiYi04NmI1MGM0MmIwZDkiIE5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTo0NDowOC42NDVaIiBSZWNpcGllbnQ9Imh0dHA6Ly9sb2NhbGhvc3Q6OTAwMC9vYXV0aDIvY2FsbGJhY2svc2FtbCIvPg0KICAgICAgICAgICAgPC9zYW1sOlN1YmplY3RDb25maXJtYXRpb24+DQogICAgICAgIDwvc2FtbDpTdWJqZWN0Pg0KICAgICAgICA8c2FtbDpDb25kaXRpb25zIE5vdEJlZm9yZT0iMjAyMC0wNi0wNVQyMzowNTowOC42NDVaIiBOb3RPbk9yQWZ0ZXI9IjIwMzktMDYtMTFUMDk6NDQ6MDguNjQ1WiI+DQogICAgICAgICAgICA8c2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF1ZGllbmNlPk15QXBwPC9zYW1sOkF1ZGllbmNlPg0KICAgICAgICAgICAgPC9zYW1sOkF1ZGllbmNlUmVzdHJpY3Rpb24+DQogICAgICAgIDwvc2FtbDpDb25kaXRpb25zPg0KICAgICAgICA8c2FtbDpBdXRoblN0YXRlbWVudCBBdXRobkluc3RhbnQ9IjIwMjAtMDYtMDVUMjM6MDU6MTAuNjQ3WiIgU2Vzc2lvbkluZGV4PSJhODUzNWM1My1iZjdkLTRhZTctYWY4ZC0wNTZjYzgwZTEzOTk6OjAyODE1Y2Q1LTllYzktNDY0OS1hOWYwLWQ1ZmRiOTU1NTFkYyIgU2Vzc2lvbk5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTo0NDoxMC42NDdaIj4NCiAgICAgICAgICAgIDxzYW1sOkF1dGhuQ29udGV4dD4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3Nlczp1bnNwZWNpZmllZDwvc2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj4NCiAgICAgICAgICAgIDwvc2FtbDpBdXRobkNvbnRleHQ+DQogICAgICAgIDwvc2FtbDpBdXRoblN0YXRlbWVudD4NCiAgICAgICAgPHNhbWw6QXR0cmlidXRlU3RhdGVtZW50Pg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9Im5hbWUiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI+Sm9obiBEb2U8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9Imdyb3VwcyIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+DQogICAgICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5kZXZlbG9wZXI8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5wcm9kdWN0LW1hbmFnZXI8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9ImVtYWlsIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmpvaG5kb2VAZW1haWwuY29tPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPg0KICAgICAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZT4NCiAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD4NCiAgICA8L3NhbWw6QXNzZXJ0aW9uPg0KPC9zYW1scDpSZXNwb25zZT4=
diff --git a/server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_response_without_name.txt b/server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/encoded_response_without_name.txt
deleted file mode 100644 (file)
index 4dc183e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIERlc3RpbmF0aW9uPSJodHRwOi8vbG9jYWxob3N0OjkwMDAvb2F1dGgyL2NhbGxiYWNrL3NhbWwiIElEPSJJRF8wOGI3NzQxZS1lNjkwLTRiY2UtYjY4OS00YWY5NmEzMTZkYmYiIEluUmVzcG9uc2VUbz0iT05FTE9HSU5fZGE0ODgyODYtMDM3Yy00MWZjLWEwZGEtZmI5Njg1ZWU3NWMxIiBJc3N1ZUluc3RhbnQ9IjIwMjAtMDYtMDVUMjM6MDc6MjUuNjc1WiIgVmVyc2lvbj0iMi4wIj4NCiAgICA8c2FtbDpJc3N1ZXI+aHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL3NvbmFycXViZTwvc2FtbDpJc3N1ZXI+DQogICAgPHNhbWxwOlN0YXR1cz4NCiAgICAgICAgPHNhbWxwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPg0KICAgIDwvc2FtbHA6U3RhdHVzPg0KICAgIDxzYW1sOkFzc2VydGlvbiB4bWxucz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9InBmeDE4YzYyMzM2LTI1NmItN2YwZS03MGY0LTI5ZWRjMjFlNGM1MSIgSXNzdWVJbnN0YW50PSIyMDIwLTA2LTA1VDIzOjA3OjI1LjY3NVoiIFZlcnNpb249IjIuMCI+DQogICAgICAgIDxzYW1sOklzc3Vlcj5odHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvc29uYXJxdWJlPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4NCiAgPGRzOlNpZ25lZEluZm8+PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4NCiAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIi8+DQogIDxkczpSZWZlcmVuY2UgVVJJPSIjcGZ4MThjNjIzMzYtMjU2Yi03ZjBlLTcwZjQtMjllZGMyMWU0YzUxIj48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT4zdHlYQjA1MXlTMHNQSDd5TWxwWmJUQXVOKzA9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPkFSLzUvNmcwWXR6MWl5L3VrMWovbmNwU3JCK1UycHI2NUk5TU02TGxTdHpGZzgzRlJyMXFnQ3FMZDBPQkJHN2V1dndJNkVwUVowRmNldDZaZWU4WmtkS0xDQWozK2taSXBMRjdtQnlJdzdnOGdKODJXMVV4Rm00UGZzQ2hERTdOQVlQdzRuNEdsNENyU0g0MUN0RGliYlJLeTZ4Tlg1Vmo1bE5ORWp0R2pEZ0VNTkxLalB4QWdCVnhnWjBZdE9lS0RuYXFwdm5NcnI1eHdhZkpqMVdXTWRnUklHVStjdGZCWkVxRHJNN29MN245eWR0NXZieXNjcjh1TGFZQVJCeVBGckJsa1QyMi85VVdkM0Z4eEp3cXQ1ZnZaQ3E3UkVJMWNXLzBRWnYyNEhVbnozMzRHWU05S3pjelJjL3pGbDlITlBpUHNNUEthWUtnTXJKcEtQVDdnYWlTRXg4MXp5eHlNbUNyV3FIWVNrZHErN1dFcEpzY21qYWtUNUZsb1o0QVVyVVBSVEZXTmVhd056bkt3cEtVa0t0OWRIZVp2SENyaXUySEd2d2tnVy9kK1NSS25xSmdrWTZaWXl6RDBoMzQzMDl6TUY5Z3FvSU9DQXZiUEZ2em80cHRoOEYrM2VjTHJvM0c0QWdzWHNvejlyWlpJV0FMYXhqNjdiZVdFTzZPUkJ1NWpKMVh5S29MdWJKMGhSZjgvRGVCa1k4VDZGSklLc09MMU5BdkVlcFp0dWc0LzVGVXNUbmpDc29wNjNQei9DcU5QeXNBT1A1cHdBS0tVeWdFOW5zNTU3R1ZZUHc4NldNbEN2NS84STRjV0JvRlEySEl6OVJZcXphVDJtSlhmbDczWEhuNkJxRkpBNEpwaW5hWGh2akFzaDU3R1dtbWovTit4SWpPRjYwPTwvZHM6U2lnbmF0dXJlVmFsdWU+DQo8ZHM6S2V5SW5mbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlGNXpDQ0E4K2dBd0lCQWdJVUlYdjlPVnMvWFVpY2dSMWJzVjl1Y2NZaEhmb3dEUVlKS29aSWh2Y05BUUVMQlFBd2dZSXhDekFKQmdOVkJBWVRBa0ZWTVE4d0RRWURWUVFJREFaSFJVNUZWa0V4RURBT0JnTlZCQWNNQjFaRlVrNUpSVkl4RGpBTUJnTlZCQW9NQlZOUFRrRlNNUTB3Q3dZRFZRUUxEQVJSVlVKRk1ROHdEUVlEVlFRRERBWmFhWEJsYm1jeElEQWVCZ2txaGtpRzl3MEJDUUVXRVc1dmNtVndiSGxBWjIxaGFXd3VZMjl0TUI0WERUSXlNRFl4TXpFek1UUXlOMW9YRFRNeU1EWXhNREV6TVRReU4xb3dnWUl4Q3pBSkJnTlZCQVlUQWtGVk1ROHdEUVlEVlFRSURBWkhSVTVGVmtFeEVEQU9CZ05WQkFjTUIxWkZVazVKUlZJeERqQU1CZ05WQkFvTUJWTlBUa0ZTTVEwd0N3WURWUVFMREFSUlZVSkZNUTh3RFFZRFZRUUREQVphYVhCbGJtY3hJREFlQmdrcWhraUc5dzBCQ1FFV0VXNXZjbVZ3YkhsQVoyMWhhV3d1WTI5dE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBdTNuRlhZdklZZWRwUjg0YVprZG8vM3lCNVhITStZQ0ZKY0RzVk8xMHpFYmxMa25mUXNpTVBhMVhkOVVzdG5weHc2UC9TeXpJSm1POWppTU9kZUNlWTk4YTc0alA3ZDRKUGFPNmgzbDlJYldBY1llaWpRZzk1Nm5sc1ZGWTNGSERHcis3UGI4UWNPQXlWM3Y4OWppRjlERkI4d1hTKzVVZllyMk9mb1JSYjRsaTM5ZXpEeURkbDVPTGxNMTFuRXNzMnoxbUV2K3NVVWxvVGN5cmdqMzdQc2dld2t2eXltNnRGR1Nna1Y5WmE0U1ZSaEhGeVRoWTFWRnJZWlNKRlRuYXBVWWFSYzdrTXh6d1gvQUFIVURKcm1ZY2FWYzVCOE9EcDR3MkF4REpoZVF5Q1ZmWGpQRmFVcUJNRzJVL3JZZlZYdTBaYTdQbi92VW80VWFTVGh3Q0JLRGVoQ3d6KzY1VExkQStOeHlHRHhudlkvU2tzT3lMTEdDbXU4dEtrWGR1MHB6bm5JaEJYRUd2alVJVlM3ZDZhLzhnZWc5MU5vVFdhdTNpMFJGK0R3LzVOOURTenBsZDE1YlB0YjVDZTNCaWUxOXV2ZnZ1SDllZytEOHgvaGZGNmYzaWw0c1BsSUtkTy9PVmRNMjhMUmZtRHFtcVFOUHVkdmJxejd4eTRBUnV4azZBUmE0ZCthVDl6b3Zwd3Z4TkdUcjdoMW1kZ09VdFVDZElYTDNTSE5qZHdkQUF6MHVDV3p2RXhiRnUrTlErVjUrWG5reDcxaHlQRnY5K0RMVkdJdTdKaGRZczgwNndLc2hPMTNOZ2EzOGlnNmd1MzdscFZoZnBaWGhLeXdVaWlnRzZMWEFleVdXa01rK3ZsZjlNY1pkTUJEMTZkWlA0a1RzdlArclBWblVDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRkk1VVZMdFR5U3ZiR3FIN1VQOHhUTDR3eFpxM01COEdBMVVkSXdRWU1CYUFGSTVVVkx0VHlTdmJHcUg3VVA4eFRMNHd4WnEzTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCQUJBdFhzS05XeDBzRERGQTUzcVoxelJ5V0tXQU1vaDk1cGF3RkNyS2dURVc0WnJBNzNwYTc5MGVFMVkrdlQ2cVVYS0k0bGk5c2tJRGErNnBzQ2R4aFpJckhQUkFuVlpWZUIyMzczQnhyNWJ3L1hROGVsUkNqV2VNVUxiWUo5dGdzTFYwSTlDaUVQMGE2VG04dDB5RFZYTlVmeDM2RTVma2dMU3J4b1JvOFhKenhIYkpDbkxWWEhkYU5CeE9UN2pWY29tNldvNFBCMmJzalZ6aEhtNmFtbjVoWnA0ZE1IbTBNdjBsbjF3SDhqVm5pekhRQkxzR016dnZsNTgrOXMxcFAxN2NlUkRrcE5EeitFUXlBK1pBcnFrVzFNcXR3Vmhieno4UWdNcHJoZmxLa0FycnNDN3YwNkp2OGZxVWJuOUx2dFlLOUl3SFRYN0o4ZEZjc08vZ1VDNVBldllUM25yaU4zQXpiMjBnZ1NRMXlPRU1venZqNVQ5NlM2aXRmSFBpdDd2eUVRODRKUHJFcWZ1UURaUS9MS1pRcWZ2dVhYMWFBRzNUVTNUTVdCOVZNTUZzVHVNRlM4YmZyaE1YNzdnMFVkNHFKY0JPWU9IM2hSNTlhZ1NkZDJRWk5MUDN6WnNZUUhMTFFrcTk0amRUWEtUcW0vdzdtbFBGS1Y1OUhqVGJIQmhUdHhCSE1mdC9tdnZMRXVDOUtLRmZBT1hZUTZWK3M5TmswQlc0Z2dFZmV3YVg1OE9CdXk3SVNxUnRSRlBHaWExOFlSenpIcWtoanViSllNUGtJZllwRlZkK0MwSUkzRjBrZHk4VHRwY2NqeUtvOWJjSE1MeE80bjhQREFsMTk1Q1B0aE1pOGdVdlQwMDhMR0VvdHIrM2tYc291VEVaVFQwZ2xYS0xkTzJXPC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+DQogICAgICAgIDxzYW1sOlN1YmplY3Q+DQogICAgICAgICAgICA8c2FtbDpOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDp1bnNwZWNpZmllZCI+am9obmRvZTwvc2FtbDpOYW1lSUQ+DQogICAgICAgICAgICA8c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uIE1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlciI+DQogICAgICAgICAgICAgICAgPHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgSW5SZXNwb25zZVRvPSJPTkVMT0dJTl9kYTQ4ODI4Ni0wMzdjLTQxZmMtYTBkYS1mYjk2ODVlZTc1YzEiIE5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTo0NjoyMy42NzVaIiBSZWNpcGllbnQ9Imh0dHA6Ly9sb2NhbGhvc3Q6OTAwMC9vYXV0aDIvY2FsbGJhY2svc2FtbCIvPg0KICAgICAgICAgICAgPC9zYW1sOlN1YmplY3RDb25maXJtYXRpb24+DQogICAgICAgIDwvc2FtbDpTdWJqZWN0Pg0KICAgICAgICA8c2FtbDpDb25kaXRpb25zIE5vdEJlZm9yZT0iMjAyMC0wNi0wNVQyMzowNzoyMy42NzVaIiBOb3RPbk9yQWZ0ZXI9IjIwMzktMDYtMTFUMDk6NDY6MjMuNjc1WiI+DQogICAgICAgICAgICA8c2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPg0KICAgICAgICAgICAgICAgIDxzYW1sOkF1ZGllbmNlPk15QXBwPC9zYW1sOkF1ZGllbmNlPg0KICAgICAgICAgICAgPC9zYW1sOkF1ZGllbmNlUmVzdHJpY3Rpb24+DQogICAgICAgIDwvc2FtbDpDb25kaXRpb25zPg0KICAgICAgICA8c2FtbDpBdXRoblN0YXRlbWVudCBBdXRobkluc3RhbnQ9IjIwMjAtMDYtMDVUMjM6MDc6MjUuNjc2WiIgU2Vzc2lvbkluZGV4PSIwODljNjA2Yi0zMjVmLTQ0NDktODM1NS1hNTQ5NWNiZTRjNGM6OjAyODE1Y2Q1LTllYzktNDY0OS1hOWYwLWQ1ZmRiOTU1NTFkYyIgU2Vzc2lvbk5vdE9uT3JBZnRlcj0iMjAzOS0wNi0xMVQwOTo0NjoyNS42NzZaIj4NCiAgICAgICAgICAgIDxzYW1sOkF1dGhuQ29udGV4dD4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3Nlczp1bnNwZWNpZmllZDwvc2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj4NCiAgICAgICAgICAgIDwvc2FtbDpBdXRobkNvbnRleHQ+DQogICAgICAgIDwvc2FtbDpBdXRoblN0YXRlbWVudD4NCiAgICAgICAgPHNhbWw6QXR0cmlidXRlU3RhdGVtZW50Pg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9ImxvZ2luIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmpvaG5kb2U8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9Imdyb3VwcyIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+DQogICAgICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5kZXZlbG9wZXI8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5wcm9kdWN0LW1hbmFnZXI8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICAgICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9ImVtYWlsIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmpvaG5kb2VAZW1haWwuY29tPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPg0KICAgICAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZT4NCiAgICAgICAgPC9zYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD4NCiAgICA8L3NhbWw6QXNzZXJ0aW9uPg0KPC9zYW1scDpSZXNwb25zZT4=
diff --git a/server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/how_to_generate_test_response.txt b/server/sonar-auth-saml/src/test/resources/org/sonar/auth/saml/SamlIdentityProviderTest/how_to_generate_test_response.txt
deleted file mode 100644 (file)
index bd832ee..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# How to generate test responses for unit tests requiring encoded user response
-
-1. Set the server log in TRACE
-2. Login with a user
-3. Search in the logs for "[c.o.saml2.Auth] processResponse success -->"
-4. The value after the "-->" is the encoded response that can be used in test
\ No newline at end of file