diff options
author | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2017-09-06 15:52:43 +0200 |
---|---|---|
committer | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2017-09-13 15:50:55 +0200 |
commit | 7e778849d1c669cd87c90de21cb3d1ea6494e759 (patch) | |
tree | 0545591c3034fc933cea52b1f63bda9f64b58e90 | |
parent | 3de079f32f95e92f08f03d599d7b483086b87cfa (diff) | |
download | sonarqube-7e778849d1c669cd87c90de21cb3d1ea6494e759.tar.gz sonarqube-7e778849d1c669cd87c90de21cb3d1ea6494e759.zip |
SONAR-9741 add authentication to api/system/health
10 files changed, 242 insertions, 13 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java index e2a45829e09..4cedd539219 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java +++ b/server/sonar-server/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java @@ -59,7 +59,7 @@ public class UserSessionInitializer { "/batch/index", "/batch/file", "/maintenance/*", "/setup/*", "/sessions/*", "/oauth2/callback/*", - "/api/system/db_migration_status", "/api/system/status", "/api/system/migrate_db", "/api/system/health", + "/api/system/db_migration_status", "/api/system/status", "/api/system/migrate_db", "/api/server/version", "/api/users/identity_providers", "/api/l10n/index", LOGIN_URL, LOGOUT_URL, VALIDATE_URL); diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/HealthAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/HealthAction.java index b4931a745cb..f71f03d3be9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/HealthAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/HealthAction.java @@ -22,16 +22,23 @@ package org.sonar.server.platform.ws; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.platform.WebServer; +import org.sonar.server.user.SystemPasscode; +import org.sonar.server.user.UserSession; import org.sonar.server.ws.WsUtils; public class HealthAction implements SystemWsAction { private final WebServer webServer; private final HealthActionSupport support; + private final SystemPasscode systemPasscode; + private final UserSession userSession; - public HealthAction(WebServer webServer, HealthActionSupport support) { + public HealthAction(WebServer webServer, HealthActionSupport support, SystemPasscode systemPasscode, UserSession userSession) { this.webServer = webServer; this.support = support; + this.systemPasscode = systemPasscode; + this.userSession = userSession; } @Override @@ -41,6 +48,10 @@ public class HealthAction implements SystemWsAction { @Override public void handle(Request request, Response response) throws Exception { + if (!isPassCodeAuthenticated(request) && !isSystemAdmin()) { + throw new ForbiddenException("Insufficient privileges"); + } + if (webServer.isStandalone()) { WsUtils.writeProtobuf(support.checkNodeHealth(), request, response); } else { @@ -48,4 +59,12 @@ public class HealthAction implements SystemWsAction { } } + private boolean isSystemAdmin() { + return userSession.isSystemAdministrator(); + } + + private boolean isPassCodeAuthenticated(Request request) { + return systemPasscode.isConfigured() && systemPasscode.isValid(request); + } + } diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SafeModeHealthAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SafeModeHealthAction.java index 1c7f953354a..6793f98ae51 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SafeModeHealthAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SafeModeHealthAction.java @@ -22,13 +22,17 @@ package org.sonar.server.platform.ws; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.user.SystemPasscode; import org.sonar.server.ws.WsUtils; public class SafeModeHealthAction implements SystemWsAction { private final HealthActionSupport support; + private final SystemPasscode systemPasscode; - public SafeModeHealthAction(HealthActionSupport support) { + public SafeModeHealthAction(HealthActionSupport support, SystemPasscode systemPasscode) { this.support = support; + this.systemPasscode = systemPasscode; } @Override @@ -38,6 +42,10 @@ public class SafeModeHealthAction implements SystemWsAction { @Override public void handle(Request request, Response response) throws Exception { + if (!systemPasscode.isConfigured() || !systemPasscode.isValid(request)) { + throw new ForbiddenException("Insufficient privileges"); + } + WsUtils.writeProtobuf(support.checkNodeHealth(), request, response); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java b/server/sonar-server/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java index 7697b6ff590..b8fcf9fd7ce 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java @@ -110,7 +110,6 @@ public class UserSessionInitializerTest { assertPathIsIgnored("/api/system/db_migration_status"); assertPathIsIgnored("/api/system/status"); assertPathIsIgnored("/api/system/migrate_db"); - assertPathIsIgnored("/api/system/health"); assertPathIsIgnored("/api/server/version"); assertPathIsIgnored("/api/users/identity_providers"); assertPathIsIgnored("/api/l10n/index"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/HealthActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/HealthActionTest.java index 11522e7aabf..33ed30afca1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/HealthActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/HealthActionTest.java @@ -29,14 +29,20 @@ import java.util.List; import java.util.Random; import java.util.stream.IntStream; import org.apache.commons.lang.RandomStringUtils; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.WebService; import org.sonar.cluster.health.NodeDetails; import org.sonar.cluster.health.NodeHealth; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.health.ClusterHealth; import org.sonar.server.health.Health; import org.sonar.server.health.HealthChecker; import org.sonar.server.platform.WebServer; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.user.SystemPasscode; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.TestResponse; import org.sonar.server.ws.WsActionTester; @@ -47,6 +53,7 @@ import static java.util.Collections.singleton; import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.sonar.api.utils.DateUtils.formatDateTime; @@ -58,10 +65,16 @@ import static org.sonar.server.health.Health.newHealthCheckBuilder; import static org.sonar.test.JsonAssert.assertJson; public class HealthActionTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + private final Random random = new Random(); private HealthChecker healthChecker = mock(HealthChecker.class); private WebServer webServer = mock(WebServer.class); - private WsActionTester underTest = new WsActionTester(new HealthAction(webServer, new HealthActionSupport(healthChecker))); + private SystemPasscode systemPasscode = mock(SystemPasscode.class); + private WsActionTester underTest = new WsActionTester(new HealthAction(webServer, new HealthActionSupport(healthChecker), systemPasscode, userSessionRule)); @Test public void verify_definition() { @@ -77,7 +90,82 @@ public class HealthActionTest { } @Test + public void request_fails_with_ForbiddenException_when_anonymous() { + TestRequest request = underTest.newRequest(); + + expectForbiddenException(); + + request.execute(); + } + + @Test + public void request_fails_with_SystemPasscode_enabled_and_anonymous() { + when(systemPasscode.isConfigured()).thenReturn(true); + TestRequest request = underTest.newRequest(); + + expectForbiddenException(); + + request.execute(); + } + + @Test + public void request_fails_with_SystemPasscode_enabled_but_no_passcode_and_user_is_not_system_administrator() { + when(systemPasscode.isConfigured()).thenReturn(true); + when(systemPasscode.isValid(any(Request.class))).thenReturn(false); + userSessionRule.logIn(); + when(healthChecker.checkCluster()).thenReturn(randomStatusMinimalClusterHealth()); + TestRequest request = underTest.newRequest(); + + expectForbiddenException(); + + request.execute(); + } + + @Test + public void request_succeeds_with_SystemPasscode_enabled_and_passcode() { + when(systemPasscode.isConfigured()).thenReturn(true); + when(systemPasscode.isValid(any(Request.class))).thenReturn(true); + when(healthChecker.checkCluster()).thenReturn(randomStatusMinimalClusterHealth()); + TestRequest request = underTest.newRequest(); + + request.execute(); + } + + @Test + public void request_succeeds_with_SystemPasscode_disabled_and_user_is_system_administrator() { + when(systemPasscode.isConfigured()).thenReturn(false); + userSessionRule.logIn().setSystemAdministrator(); + when(healthChecker.checkCluster()).thenReturn(randomStatusMinimalClusterHealth()); + TestRequest request = underTest.newRequest(); + + request.execute(); + } + + @Test + public void request_succeeds_with_SystemPasscode_enabled_but_no_passcode_and_user_is_system_administrator() { + when(systemPasscode.isConfigured()).thenReturn(true); + when(systemPasscode.isValid(any(Request.class))).thenReturn(false); + userSessionRule.logIn().setSystemAdministrator(); + when(healthChecker.checkCluster()).thenReturn(randomStatusMinimalClusterHealth()); + TestRequest request = underTest.newRequest(); + + request.execute(); + } + + @Test + public void request_succeeds_with_SystemPasscode_enabled_and_passcode_and_user_is_system_administrator() { + when(systemPasscode.isConfigured()).thenReturn(true); + when(systemPasscode.isValid(any(Request.class))).thenReturn(true); + userSessionRule.logIn().setSystemAdministrator(); + when(healthChecker.checkCluster()).thenReturn(randomStatusMinimalClusterHealth()); + TestRequest request = underTest.newRequest(); + + request.execute(); + } + + @Test public void verify_response_example() { + authenticateWithRandomMethod(); when(webServer.isStandalone()).thenReturn(false); long time = parseDateTime("2015-08-13T23:34:59+0200").getTime(); when(healthChecker.checkCluster()) @@ -153,6 +241,7 @@ public class HealthActionTest { @Test public void request_returns_status_and_causes_from_HealthChecker_checkNode_method_when_standalone() { + authenticateWithRandomMethod(); Health.Status randomStatus = Health.Status.values()[new Random().nextInt(Health.Status.values().length)]; Health.Builder builder = newHealthCheckBuilder() .setStatus(randomStatus); @@ -169,6 +258,7 @@ public class HealthActionTest { @Test public void response_contains_status_and_causes_from_HealthChecker_checkCluster_when_standalone() { + authenticateWithRandomMethod(); Health.Status randomStatus = Health.Status.values()[random.nextInt(Health.Status.values().length)]; String[] causes = IntStream.range(0, random.nextInt(33)).mapToObj(i -> randomAlphanumeric(4)).toArray(String[]::new); Health.Builder healthBuilder = newHealthCheckBuilder() @@ -186,6 +276,7 @@ public class HealthActionTest { @Test public void response_contains_information_of_nodes_when_clustered() { + authenticateWithRandomMethod(); NodeHealth nodeHealth = randomNodeHealth(); when(webServer.isStandalone()).thenReturn(false); when(healthChecker.checkCluster()).thenReturn(new ClusterHealth(GREEN, singleton(nodeHealth))); @@ -208,6 +299,7 @@ public class HealthActionTest { @Test public void response_sort_nodes_by_type_name_host_then_port_when_clustered() { + authenticateWithRandomMethod(); // using created field as a unique identifier. pseudo random value to ensure sorting is not based on created field List<NodeHealth> nodeHealths = new ArrayList<>(Arrays.asList( randomNodeHealth(NodeDetails.Type.APPLICATION, "1_name", "1_host", 1, 99), @@ -268,4 +360,37 @@ public class HealthActionTest { .build(); } + private ClusterHealth randomStatusMinimalClusterHealth() { + return new ClusterHealth(newHealthCheckBuilder() + .setStatus(Health.Status.values()[random.nextInt(Health.Status.values().length)]) + .build(), emptySet()); + } + + private void expectForbiddenException() { + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage("Insufficient privileges"); + } + + /** + * Randomly choose of one the valid authentication method: + * <ul> + * <li>system administrator and passcode disabled</li> + * <li>system administrator and passcode enabled</li> + * <li>passcode</li> + * </ul> + */ + private void authenticateWithRandomMethod() { + if (random.nextBoolean()) { + when(systemPasscode.isConfigured()).thenReturn(true); + if (random.nextBoolean()) { + when(systemPasscode.isValid(any(Request.class))).thenReturn(true); + } else { + when(systemPasscode.isValid(any(Request.class))).thenReturn(false); + userSessionRule.logIn().setSystemAdministrator(); + } + } else { + userSessionRule.logIn().setSystemAdministrator(); + } + } + } diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SafeModeHealthActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SafeModeHealthActionTest.java index 340171ce67c..0ee02bbd5f5 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SafeModeHealthActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SafeModeHealthActionTest.java @@ -23,10 +23,15 @@ import java.util.Arrays; import java.util.Random; import java.util.stream.IntStream; import org.apache.commons.lang.RandomStringUtils; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.WebService; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.health.Health; import org.sonar.server.health.HealthChecker; +import org.sonar.server.user.SystemPasscode; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.TestResponse; import org.sonar.server.ws.WsActionTester; @@ -34,15 +39,20 @@ import org.sonarqube.ws.WsSystem; import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.sonar.server.health.Health.newHealthCheckBuilder; import static org.sonar.test.JsonAssert.assertJson; public class SafeModeHealthActionTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + private final Random random = new Random(); private HealthChecker healthChecker = mock(HealthChecker.class); - private WsActionTester underTest = new WsActionTester(new SafeModeHealthAction(new HealthActionSupport(healthChecker))); + private SystemPasscode systemPasscode = mock(SystemPasscode.class); + private WsActionTester underTest = new WsActionTester(new SafeModeHealthAction(new HealthActionSupport(healthChecker), systemPasscode)); @Test public void verify_definition() { @@ -58,7 +68,42 @@ public class SafeModeHealthActionTest { } @Test + public void request_fails_with_ForbiddenException_when_PassCode_disabled() { + when(systemPasscode.isConfigured()).thenReturn(false); + when(systemPasscode.isValid(any(Request.class))).thenReturn(random.nextBoolean()); + TestRequest request = underTest.newRequest(); + + expectForbiddenException(); + + request.execute(); + } + + @Test + public void request_fails_with_ForbiddenException_when_PassCode_enabled_but_no_passcode() { + when(systemPasscode.isConfigured()).thenReturn(true); + when(systemPasscode.isValid(any(Request.class))).thenReturn(false); + TestRequest request = underTest.newRequest(); + + expectForbiddenException(); + + request.execute(); + } + + @Test + public void request_succeeds_when_PassCode_enabled_and_valid_passcode() { + authenticateWithPasscode(); + when(healthChecker.checkNode()) + .thenReturn(newHealthCheckBuilder() + .setStatus(Health.Status.values()[random.nextInt(Health.Status.values().length)]) + .build()); + TestRequest request = underTest.newRequest(); + + request.execute(); + } + + @Test public void verify_response_example() { + authenticateWithPasscode(); when(healthChecker.checkNode()) .thenReturn(newHealthCheckBuilder() .setStatus(Health.Status.RED) @@ -74,6 +119,7 @@ public class SafeModeHealthActionTest { @Test public void request_returns_status_and_causes_from_HealthChecker_checkNode_method() { + authenticateWithPasscode(); Health.Status randomStatus = Health.Status.values()[new Random().nextInt(Health.Status.values().length)]; Health.Builder builder = newHealthCheckBuilder() .setStatus(randomStatus); @@ -89,6 +135,7 @@ public class SafeModeHealthActionTest { @Test public void response_contains_status_and_causes_from_HealthChecker_checkCluster() { + authenticateWithPasscode(); Health.Status randomStatus = Health.Status.values()[random.nextInt(Health.Status.values().length)]; String[] causes = IntStream.range(0, random.nextInt(33)).mapToObj(i -> randomAlphanumeric(4)).toArray(String[]::new); Health.Builder healthBuilder = newHealthCheckBuilder() @@ -103,4 +150,14 @@ public class SafeModeHealthActionTest { .containsOnly(causes); } + private void expectForbiddenException() { + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage("Insufficient privileges"); + } + + private void authenticateWithPasscode() { + when(systemPasscode.isConfigured()).thenReturn(true); + when(systemPasscode.isValid(any(Request.class))).thenReturn(true); + } + } diff --git a/tests/src/test/java/org/sonarqube/tests/cluster/Cluster.java b/tests/src/test/java/org/sonarqube/tests/cluster/Cluster.java index 74efbf7b53a..58fb754f4b2 100644 --- a/tests/src/test/java/org/sonarqube/tests/cluster/Cluster.java +++ b/tests/src/test/java/org/sonarqube/tests/cluster/Cluster.java @@ -37,6 +37,7 @@ class Cluster implements AutoCloseable { private final String clusterName; private final List<Node> nodes = new ArrayList<>(); + private final String systemPassCode = "fooBar2000"; Cluster(@Nullable String name) { this.clusterName = name; @@ -50,6 +51,7 @@ class Cluster implements AutoCloseable { Node addNode(NodeConfig config, Consumer<OrchestratorBuilder> consumer) { OrchestratorBuilder builder = newOrchestratorBuilder(config); + builder.setServerProperty("sonar.web.systemPasscode", systemPassCode); switch (config.getType()) { case SEARCH: @@ -71,7 +73,7 @@ class Cluster implements AutoCloseable { } consumer.accept(builder); Orchestrator orchestrator = builder.build(); - Node node = new Node(config, orchestrator); + Node node = new Node(config, orchestrator, systemPassCode); nodes.add(node); return node; } diff --git a/tests/src/test/java/org/sonarqube/tests/cluster/Node.java b/tests/src/test/java/org/sonarqube/tests/cluster/Node.java index 7826325d34d..e8846c28042 100644 --- a/tests/src/test/java/org/sonarqube/tests/cluster/Node.java +++ b/tests/src/test/java/org/sonarqube/tests/cluster/Node.java @@ -42,12 +42,14 @@ class Node { private final NodeConfig config; private final Orchestrator orchestrator; + private final String systemPassCode; private LogsTailer logsTailer; private final LogsTailer.Content content = new LogsTailer.Content(); - Node(NodeConfig config, Orchestrator orchestrator) { + Node(NodeConfig config, Orchestrator orchestrator, String systemPassCode) { this.config = config; this.orchestrator = orchestrator; + this.systemPassCode = systemPassCode; } NodeConfig getConfig() { @@ -142,7 +144,7 @@ class Node { return Optional.empty(); } try { - return Optional.ofNullable(ItUtils.newAdminWsClient(orchestrator).system().health()); + return Optional.ofNullable(ItUtils.newSystemUserWsClient(orchestrator, systemPassCode).system().health()); } catch (Exception e) { return Optional.empty(); } diff --git a/tests/src/test/java/org/sonarqube/tests/serverSystem/SystemStateTest.java b/tests/src/test/java/org/sonarqube/tests/serverSystem/SystemStateTest.java index b61b5ba8237..a305187d881 100644 --- a/tests/src/test/java/org/sonarqube/tests/serverSystem/SystemStateTest.java +++ b/tests/src/test/java/org/sonarqube/tests/serverSystem/SystemStateTest.java @@ -24,9 +24,11 @@ import com.sonar.orchestrator.util.NetworkUtils; import java.io.File; import java.io.IOException; import java.net.InetAddress; +import java.util.Arrays; import java.util.Optional; import java.util.function.Supplier; import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.RandomStringUtils; import org.junit.Rule; import org.junit.Test; import org.junit.rules.DisableOnDebug; @@ -38,8 +40,8 @@ import org.sonarqube.ws.WsSystem; import org.sonarqube.ws.client.WsClient; import static com.google.common.base.Preconditions.checkState; -import static java.util.stream.Collectors.joining; import static org.assertj.core.api.Assertions.assertThat; +import static util.ItUtils.newSystemUserWsClient; import static util.ItUtils.newWsClient; import static util.ItUtils.pluginArtifact; @@ -50,10 +52,11 @@ public class SystemStateTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); - @Rule public TestRule safeguard = new DisableOnDebug(Timeout.seconds(300)); + private final String systemPassCode = RandomStringUtils.randomAlphanumeric(15); + @Test public void test_status_and_health_during_server_lifecycle() throws Exception { try (Commander commander = new Commander()) { @@ -130,6 +133,7 @@ public class SystemStateTest { .setServerProperty("sonar.web.startupLock.path", lock.webFile.getAbsolutePath()) .setServerProperty("sonar.ce.startupLock.path", lock.ceFile.getAbsolutePath()) .setServerProperty("sonar.search.httpPort", "" + esHttpPort) + .setServerProperty("sonar.web.systemPasscode", systemPassCode) .build(); elasticsearch = new Elasticsearch(esHttpPort); @@ -185,7 +189,7 @@ public class SystemStateTest { Optional<WsSystem.HealthResponse> healthResponse() { if (orchestrator.getServer() != null) { - WsClient wsClient = newWsClient(orchestrator); + WsClient wsClient = newSystemUserWsClient(orchestrator, systemPassCode); try { return Optional.of(wsClient.system().health()); } catch (Exception e) { @@ -203,10 +207,11 @@ public class SystemStateTest { void verifyHealth(WsSystem.Health expectedHealth, String... expectedMessages) { WsSystem.HealthResponse response = healthResponse().get(); assertThat(response.getHealth()) - .as(response.getCausesList().stream().map(WsSystem.Cause::getMessage).collect(joining(","))) + .describedAs("Expected status %s in response %s", expectedHealth, response) .isEqualTo(expectedHealth); assertThat(response.getCausesList()) .extracting(WsSystem.Cause::getMessage) + .describedAs("Expected causes %s in response %s", Arrays.asList(expectedMessages), response) .containsExactlyInAnyOrder(expectedMessages); } diff --git a/tests/src/test/java/util/ItUtils.java b/tests/src/test/java/util/ItUtils.java index d86b0b91ffc..05f231afc6c 100644 --- a/tests/src/test/java/util/ItUtils.java +++ b/tests/src/test/java/util/ItUtils.java @@ -130,6 +130,18 @@ public class ItUtils { } /** + * @deprecated replaced by {@link Tester#wsClient()} + */ + @Deprecated + public static WsClient newSystemUserWsClient(Orchestrator orchestrator, @Nullable String systemPassCode) { + Server server = orchestrator.getServer(); + return WsClientFactories.getDefault().newClient(HttpConnector.newBuilder() + .url(server.getUrl()) + .systemPassCode(systemPassCode) + .build()); + } + + /** * Locate the directory of sample project * * @param relativePath path related to the directory it/projects, for example "qualitygate/xoo-sample" |