aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatteo Mara <matteo.mara@sonarsource.com>2022-07-05 15:52:26 +0200
committersonartech <sonartech@sonarsource.com>2022-07-06 20:03:56 +0000
commit6354fe3096b07caf9eb017ab7b4e0565f6d303fc (patch)
tree593d31be7e2902f186e85d6d0a588288162a73fe
parent6a401f73236a70f702b64646d8bdec7c5a90e15d (diff)
downloadsonarqube-6354fe3096b07caf9eb017ab7b4e0565f6d303fc.tar.gz
sonarqube-6354fe3096b07caf9eb017ab7b4e0565f6d303fc.zip
SONAR-16567 add an analysis warning when using a token expiring in less than 7 days.
-rw-r--r--server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java15
-rw-r--r--server/sonar-webserver-auth/src/main/java/org/sonar/server/user/TokenUserSession.java3
-rw-r--r--server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java20
-rw-r--r--server/sonar-webserver-auth/src/test/java/org/sonar/server/user/TokenUserSessionTest.java16
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/DefaultScannerWsClient.java45
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClientProvider.java5
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/DefaultScannerWsClientTest.java59
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PluginFilesTest.java6
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerWsClientProviderTest.java6
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/MockWsResponse.java6
10 files changed, 160 insertions, 21 deletions
diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java
index bb6f0e7773e..880fc46ccb5 100644
--- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java
+++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java
@@ -19,22 +19,26 @@
*/
package org.sonar.server.authentication;
+import java.util.Optional;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.sonar.api.config.Configuration;
import org.sonar.api.server.ServerSide;
import org.sonar.api.web.ServletFilter.UrlPattern;
+import org.sonar.db.user.UserTokenDto;
import org.sonar.server.authentication.event.AuthenticationEvent;
import org.sonar.server.authentication.event.AuthenticationEvent.Source;
import org.sonar.server.authentication.event.AuthenticationException;
import org.sonar.server.user.ThreadLocalUserSession;
+import org.sonar.server.user.TokenUserSession;
import org.sonar.server.user.UserSession;
import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
import static org.apache.commons.lang.StringUtils.defaultString;
import static org.sonar.api.CoreProperties.CORE_FORCE_AUTHENTICATION_DEFAULT_VALUE;
import static org.sonar.api.CoreProperties.CORE_FORCE_AUTHENTICATION_PROPERTY;
+import static org.sonar.api.utils.DateUtils.formatDateTime;
import static org.sonar.api.web.ServletFilter.UrlPattern.Builder.staticResourcePatterns;
import static org.sonar.server.authentication.AuthenticationError.handleAuthenticationError;
@@ -48,6 +52,8 @@ public class UserSessionInitializer {
*/
private static final String ACCESS_LOG_LOGIN = "LOGIN";
+ private static final String SQ_AUTHENTICATION_TOKEN_EXPIRATION = "sq-authentication-token-expiration";
+
// SONAR-6546 these urls should be get from WebService
private static final Set<String> SKIPPED_URLS = Set.of(
"/batch/index", "/batch/file",
@@ -76,6 +82,7 @@ public class UserSessionInitializer {
.includes(URL_USING_PASSCODE)
.build();
+
private final Configuration config;
private final ThreadLocalUserSession threadLocalSession;
private final AuthenticationEvent authenticationEvent;
@@ -128,9 +135,17 @@ public class UserSessionInitializer {
.build();
}
threadLocalSession.set(session);
+ checkTokenUserSession(response, session);
request.setAttribute(ACCESS_LOG_LOGIN, defaultString(session.getLogin(), "-"));
}
+ private static void checkTokenUserSession(HttpServletResponse response, UserSession session) {
+ if (session instanceof TokenUserSession) {
+ UserTokenDto userTokenDto = ((TokenUserSession) session).getUserToken();
+ Optional.ofNullable(userTokenDto.getExpirationDate()).ifPresent(expirationDate -> response.addHeader(SQ_AUTHENTICATION_TOKEN_EXPIRATION, formatDateTime(expirationDate)));
+ }
+ }
+
public void removeUserSession() {
threadLocalSession.unload();
}
diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/TokenUserSession.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/TokenUserSession.java
index 7f0b730aa7e..9c1e401e4cf 100644
--- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/TokenUserSession.java
+++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/TokenUserSession.java
@@ -73,4 +73,7 @@ public class TokenUserSession extends ServerUserSession {
}
}
+ public UserTokenDto getUserToken() {
+ return userToken;
+ }
}
diff --git a/server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java b/server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java
index dcaac1ea2ef..f577adaea42 100644
--- a/server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java
+++ b/server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java
@@ -19,6 +19,8 @@
*/
package org.sonar.server.authentication;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -30,6 +32,8 @@ import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.server.authentication.BaseIdentityProvider;
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
+import org.sonar.db.user.UserDto;
+import org.sonar.db.user.UserTokenDto;
import org.sonar.server.authentication.event.AuthenticationEvent;
import org.sonar.server.authentication.event.AuthenticationEvent.Method;
import org.sonar.server.authentication.event.AuthenticationEvent.Source;
@@ -37,6 +41,7 @@ import org.sonar.server.authentication.event.AuthenticationException;
import org.sonar.server.tester.AnonymousMockUserSession;
import org.sonar.server.tester.MockUserSession;
import org.sonar.server.user.ThreadLocalUserSession;
+import org.sonar.server.user.TokenUserSession;
import org.sonar.server.user.UserSession;
import static org.assertj.core.api.Assertions.assertThat;
@@ -47,6 +52,7 @@ import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import static org.sonar.api.utils.DateUtils.formatDateTime;
public class UserSessionInitializerTest {
@@ -195,6 +201,20 @@ public class UserSessionInitializerTest {
verify(response).sendRedirect("/sonarqube/sessions/unauthorized");
}
+ @Test
+ public void expiration_header_added_when_authenticating_with_an_expiring_token() {
+ long expirationTimestamp = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli();
+ UserDto userDto = new UserDto();
+ UserTokenDto userTokenDto = new UserTokenDto().setExpirationDate(expirationTimestamp);
+ UserSession session = new TokenUserSession(DbTester.create().getDbClient(), userDto, userTokenDto);
+
+ when(authenticator.authenticate(request, response)).thenReturn(session);
+ when(threadLocalSession.isLoggedIn()).thenReturn(true);
+
+ assertThat(underTest.initUserSession(request, response)).isTrue();
+ verify(response).addHeader("sq-authentication-token-expiration", formatDateTime(expirationTimestamp));
+ }
+
private void assertPathIsIgnored(String path) {
when(request.getRequestURI()).thenReturn(path);
diff --git a/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/TokenUserSessionTest.java b/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/TokenUserSessionTest.java
index 6ffe52c179c..0af1c638820 100644
--- a/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/TokenUserSessionTest.java
+++ b/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/TokenUserSessionTest.java
@@ -42,6 +42,22 @@ public class TokenUserSessionTest {
private final DbClient dbClient = db.getDbClient();
@Test
+ public void token_can_be_retrieved_from_the_session() {
+ ComponentDto project1 = db.components().insertPrivateProject();
+
+ UserDto user = db.users().insertUser();
+
+ db.users().insertProjectPermissionOnUser(user, SCAN, project1);
+
+ TokenUserSession userSession = mockTokenUserSession(user);
+
+ assertThat(userSession.getUserToken()).isNotNull();
+ assertThat(userSession.getUserToken().getName()).isEqualTo("User Token");
+ assertThat(userSession.getUserToken().getUserUuid()).isEqualTo("userUid");
+ assertThat(userSession.getUserToken().getType()).isEqualTo("USER_TOKEN");
+ }
+
+ @Test
public void test_hasProjectsPermission_for_UserToken() {
ComponentDto project1 = db.components().insertPrivateProject();
ComponentDto project2 = db.components().insertPrivateProject();
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/DefaultScannerWsClient.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/DefaultScannerWsClient.java
index 8dc5dc3a39f..0be294a4f99 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/DefaultScannerWsClient.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/DefaultScannerWsClient.java
@@ -23,11 +23,18 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import javax.annotation.CheckForNull;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.CoreProperties;
+import org.sonar.api.notifications.AnalysisWarnings;
import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
@@ -41,21 +48,28 @@ import org.sonarqube.ws.client.WsResponse;
import static java.lang.String.format;
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
import static java.net.HttpURLConnection.HTTP_FORBIDDEN;
+import static java.net.HttpURLConnection.HTTP_OK;
import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
+import static org.sonar.api.utils.DateUtils.DATETIME_FORMAT;
import static org.sonar.api.utils.Preconditions.checkState;
public class DefaultScannerWsClient implements ScannerWsClient {
private static final int MAX_ERROR_MSG_LEN = 128;
+ private static final String SQ_TOKEN_EXPIRATION_HEADER = "sq-authentication-token-expiration";
private static final Logger LOG = Loggers.get(DefaultScannerWsClient.class);
+ private final Set<String> warningMessages = new HashSet<>();
+
private final WsClient target;
private final boolean hasCredentials;
private final GlobalAnalysisMode globalMode;
+ private final AnalysisWarnings analysisWarnings;
- public DefaultScannerWsClient(WsClient target, boolean hasCredentials, GlobalAnalysisMode globalMode) {
+ public DefaultScannerWsClient(WsClient target, boolean hasCredentials, GlobalAnalysisMode globalMode, AnalysisWarnings analysisWarnings) {
this.target = target;
this.hasCredentials = hasCredentials;
this.globalMode = globalMode;
+ this.analysisWarnings = analysisWarnings;
}
/**
@@ -73,6 +87,7 @@ public class DefaultScannerWsClient implements ScannerWsClient {
WsResponse response = target.wsConnector().call(request);
profiler.stopDebug(format("%s %d %s", request.getMethod(), response.code(), response.requestUrl()));
failIfUnauthorized(response);
+ checkAuthenticationWarnings(response);
return response;
}
@@ -96,7 +111,6 @@ public class DefaultScannerWsClient implements ScannerWsClient {
// not authenticated - see https://jira.sonarsource.com/browse/SONAR-4048
throw MessageException.of(format("Not authorized. Analyzing this project requires authentication. "
+ "Please provide a user token in %s or other credentials in %s and %s.", CoreProperties.LOGIN, CoreProperties.LOGIN, CoreProperties.PASSWORD));
-
}
if (code == HTTP_FORBIDDEN) {
throw MessageException.of("You're not authorized to run analysis. Please contact the project administrator.");
@@ -112,6 +126,33 @@ public class DefaultScannerWsClient implements ScannerWsClient {
response.failIfNotSuccessful();
}
+ private void checkAuthenticationWarnings(WsResponse response) {
+ if (response.code() == HTTP_OK) {
+ response.header(SQ_TOKEN_EXPIRATION_HEADER).ifPresent(expirationDate -> {
+ if (isTokenExpiringInOneWeek(expirationDate)) {
+ addAnalysisWarning(expirationDate);
+ }
+ });
+ }
+ }
+
+ private static boolean isTokenExpiringInOneWeek(String expirationDate) {
+ ZonedDateTime localDateTime = ZonedDateTime.now(ZoneOffset.UTC);
+ ZonedDateTime headerDateTime = LocalDateTime.from(DateTimeFormatter.ofPattern(DATETIME_FORMAT)
+ .parse(expirationDate)).minusDays(7).atZone(ZoneOffset.UTC);
+ return localDateTime.isAfter(headerDateTime);
+ }
+
+ private void addAnalysisWarning(String tokenExpirationDate) {
+ String warningMessage = "The token used for this analysis will expire on: " + tokenExpirationDate;
+ if (!warningMessages.contains(warningMessage)) {
+ warningMessages.add(warningMessage);
+ LOG.warn(warningMessage);
+ LOG.warn("Analysis executed with this token after the expiration date will fail.");
+ }
+ analysisWarnings.addUnique(warningMessage + "\nAnalysis executed with this token after the expiration date will fail.");
+ }
+
/**
* Tries to form a short and relevant error message from the exception, to be displayed in the console.
*/
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClientProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClientProvider.java
index 8e86aa8b0b4..7a45f5cc35a 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClientProvider.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClientProvider.java
@@ -20,6 +20,7 @@
package org.sonar.scanner.bootstrap;
import org.sonar.api.CoreProperties;
+import org.sonar.api.notifications.AnalysisWarnings;
import org.sonar.api.utils.System2;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
import org.sonarqube.ws.client.HttpConnector;
@@ -37,7 +38,7 @@ public class ScannerWsClientProvider {
@Bean("DefaultScannerWsClient")
public DefaultScannerWsClient provide(ScannerProperties scannerProps, EnvironmentInformation env, GlobalAnalysisMode globalMode,
- System2 system) {
+ System2 system, AnalysisWarnings analysisWarnings) {
String url = defaultIfBlank(scannerProps.property("sonar.host.url"), "http://localhost:9000");
HttpConnector.Builder connectorBuilder = HttpConnector.newBuilder();
@@ -58,6 +59,6 @@ public class ScannerWsClientProvider {
}
return new DefaultScannerWsClient(WsClientFactories.getDefault().newClient(connectorBuilder.build()), login != null,
- globalMode);
+ globalMode, analysisWarnings);
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/DefaultScannerWsClientTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/DefaultScannerWsClientTest.java
index 752b6ef0891..3da98be8901 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/DefaultScannerWsClientTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/DefaultScannerWsClientTest.java
@@ -19,12 +19,16 @@
*/
package org.sonar.scanner.bootstrap;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mockito;
+import org.sonar.api.notifications.AnalysisWarnings;
import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
@@ -39,6 +43,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import static org.sonar.api.utils.DateUtils.DATETIME_FORMAT;
public class DefaultScannerWsClientTest {
@@ -47,6 +52,8 @@ public class DefaultScannerWsClientTest {
private final WsClient wsClient = mock(WsClient.class, Mockito.RETURNS_DEEP_STUBS);
+ private final AnalysisWarnings analysisWarnings = mock(AnalysisWarnings.class);
+
@Test
public void log_and_profile_request_if_debug_level() {
WsRequest request = newRequest();
@@ -54,7 +61,7 @@ public class DefaultScannerWsClientTest {
when(wsClient.wsConnector().call(request)).thenReturn(response);
logTester.setLevel(LoggerLevel.DEBUG);
- DefaultScannerWsClient underTest = new DefaultScannerWsClient(wsClient, false, new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap())));
+ DefaultScannerWsClient underTest = new DefaultScannerWsClient(wsClient, false, new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap())), analysisWarnings);
WsResponse result = underTest.call(request);
@@ -92,10 +99,10 @@ public class DefaultScannerWsClientTest {
when(wsClient.wsConnector().call(request)).thenReturn(response);
assertThatThrownBy(() -> new DefaultScannerWsClient(wsClient, false,
- new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap()))).call(request))
- .isInstanceOf(MessageException.class)
- .hasMessage("Not authorized. Analyzing this project requires authentication. Please provide a user token in sonar.login or other " +
- "credentials in sonar.login and sonar.password.");
+ new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap())), analysisWarnings).call(request))
+ .isInstanceOf(MessageException.class)
+ .hasMessage("Not authorized. Analyzing this project requires authentication. Please provide a user token in sonar.login or other " +
+ "credentials in sonar.login and sonar.password.");
}
@Test
@@ -105,9 +112,9 @@ public class DefaultScannerWsClientTest {
when(wsClient.wsConnector().call(request)).thenReturn(response);
assertThatThrownBy(() -> new DefaultScannerWsClient(wsClient, /* credentials are configured */true,
- new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap()))).call(request))
- .isInstanceOf(MessageException.class)
- .hasMessage("Not authorized. Please check the properties sonar.login and sonar.password.");
+ new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap())), analysisWarnings).call(request))
+ .isInstanceOf(MessageException.class)
+ .hasMessage("Not authorized. Please check the properties sonar.login and sonar.password.");
}
@Test
@@ -118,9 +125,33 @@ public class DefaultScannerWsClientTest {
when(wsClient.wsConnector().call(request)).thenReturn(response);
assertThatThrownBy(() -> new DefaultScannerWsClient(wsClient, true,
- new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap()))).call(request))
- .isInstanceOf(MessageException.class)
- .hasMessage("You're not authorized to run analysis. Please contact the project administrator.");
+ new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap())), analysisWarnings).call(request))
+ .isInstanceOf(MessageException.class)
+ .hasMessage("You're not authorized to run analysis. Please contact the project administrator.");
+ }
+
+ @Test
+ public void warnings_are_added_when_expiration_approaches() {
+ WsRequest request = newRequest();
+ String expirationDate = DateTimeFormatter
+ .ofPattern(DATETIME_FORMAT)
+ .format(LocalDateTime.now().atOffset(ZoneOffset.UTC).plusDays(5));
+ WsResponse response = newResponse()
+ .setCode(200)
+ .setExpirationDate(expirationDate);
+ when(wsClient.wsConnector().call(request)).thenReturn(response);
+
+ logTester.setLevel(LoggerLevel.DEBUG);
+ DefaultScannerWsClient underTest = new DefaultScannerWsClient(wsClient, false, new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap())), analysisWarnings);
+ underTest.call(request);
+ //the second call should not add the same warning twice
+ underTest.call(request);
+
+ // check logs
+ List<String> warningLogs = logTester.logs(LoggerLevel.WARN);
+ assertThat(warningLogs).hasSize(2);
+ assertThat(warningLogs.get(0)).contains("The token used for this analysis will expire on: " + expirationDate);
+ assertThat(warningLogs.get(1)).contains("Analysis executed with this token after the expiration date will fail.");
}
@Test
@@ -132,9 +163,9 @@ public class DefaultScannerWsClientTest {
when(wsClient.wsConnector().call(request)).thenReturn(response);
assertThatThrownBy(() -> new DefaultScannerWsClient(wsClient, true,
- new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap()))).call(request))
- .isInstanceOf(MessageException.class)
- .hasMessage("Boo! bad request! bad!");
+ new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap())), analysisWarnings).call(request))
+ .isInstanceOf(MessageException.class)
+ .hasMessage("Boo! bad request! bad!");
}
private MockWsResponse newResponse() {
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PluginFilesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PluginFilesTest.java
index d2b7cd4840d..233028242bd 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PluginFilesTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PluginFilesTest.java
@@ -48,6 +48,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.notifications.AnalysisWarnings;
import org.sonar.scanner.bootstrap.ScannerPluginInstaller.InstalledPlugin;
import org.sonarqube.ws.client.HttpConnector;
import org.sonarqube.ws.client.WsClientFactories;
@@ -56,6 +57,7 @@ import static org.apache.commons.io.FileUtils.moveFile;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.ThrowableAssert.ThrowingCallable;
+import static org.mockito.Mockito.mock;
public class PluginFilesTest {
@@ -64,6 +66,8 @@ public class PluginFilesTest {
@Rule
public MockWebServer server = new MockWebServer();
+ private final AnalysisWarnings analysisWarnings = mock(AnalysisWarnings.class);
+
private File userHome;
private PluginFiles underTest;
@@ -72,7 +76,7 @@ public class PluginFilesTest {
HttpConnector connector = HttpConnector.newBuilder().url(server.url("/").toString()).build();
GlobalAnalysisMode analysisMode = new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap()));
DefaultScannerWsClient wsClient = new DefaultScannerWsClient(WsClientFactories.getDefault().newClient(connector), false,
- analysisMode);
+ analysisMode, analysisWarnings);
userHome = temp.newFolder();
MapSettings settings = new MapSettings();
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerWsClientProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerWsClientProviderTest.java
index e6e6d3ba627..c4db3d9258b 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerWsClientProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerWsClientProviderTest.java
@@ -40,7 +40,8 @@ public class ScannerWsClientProviderTest {
ScannerProperties settings = new ScannerProperties(new HashMap<>());
DefaultScannerWsClient client = underTest.provide(settings, env, new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap())),
- mock(System2.class));
+ mock(System2.class),warning -> {
+ });
assertThat(client).isNotNull();
assertThat(client.baseUrl()).isEqualTo("http://localhost:9000/");
@@ -61,7 +62,8 @@ public class ScannerWsClientProviderTest {
ScannerProperties settings = new ScannerProperties(props);
DefaultScannerWsClient client = underTest.provide(settings, env, new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap())),
- mock(System2.class));
+ mock(System2.class),warning -> {
+ });
assertThat(client).isNotNull();
HttpConnector httpConnector = (HttpConnector) client.wsConnector();
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/MockWsResponse.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/MockWsResponse.java
index 70c889f0501..2e799b1806d 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/MockWsResponse.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/MockWsResponse.java
@@ -35,6 +35,7 @@ import static java.util.Objects.requireNonNull;
public class MockWsResponse extends BaseResponse {
private static final String CONTENT_TYPE_HEADER = "Content-Type";
+ private static final String SQ_TOKEN_EXPIRATION_HEADER = "sq-authentication-token-expiration";
private int code = HttpURLConnection.HTTP_OK;
private String requestUrl;
@@ -66,6 +67,11 @@ public class MockWsResponse extends BaseResponse {
return this;
}
+ public MockWsResponse setExpirationDate(String expirationDate) {
+ headers.put(SQ_TOKEN_EXPIRATION_HEADER, expirationDate);
+ return this;
+ }
+
public MockWsResponse setRequestUrl(String requestUrl) {
this.requestUrl = requestUrl;
return this;