]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-19045 Migrate from javaxi.servlet to framework agnostic plugin api classes
authorAntoine Vinot <antoine.vinot@sonarsource.com>
Thu, 13 Apr 2023 14:57:56 +0000 (16:57 +0200)
committersonartech <sonartech@sonarsource.com>
Mon, 24 Apr 2023 20:04:23 +0000 (20:04 +0000)
Co-authored-by: Eric Giffon <eric.giffon@sonarsource.com>
Co-authored-by: Alain Kermis <alain.kermis@sonarsource.com>
Co-authored-by: Antoine Vinot <antoine.vinot@sonarsource.com>
Co-authored-by: Jacek Poreda <jacek.poreda@sonarsource.com>
115 files changed:
gradle.properties
server/sonar-auth-bitbucket/build.gradle
server/sonar-auth-bitbucket/src/main/java/org/sonar/auth/bitbucket/BitbucketIdentityProvider.java
server/sonar-auth-bitbucket/src/test/java/org/sonar/auth/bitbucket/IntegrationTest.java
server/sonar-auth-github/build.gradle
server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubIdentityProvider.java
server/sonar-auth-github/src/test/java/org/sonar/auth/github/IntegrationTest.java
server/sonar-auth-gitlab/src/main/java/org/sonar/auth/gitlab/GitLabIdentityProvider.java
server/sonar-auth-gitlab/src/test/java/org/sonar/auth/gitlab/IntegrationTest.java
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/DefaultLdapAuthenticatorIT.java
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/DefaultLdapGroupsProviderIT.java
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/DefaultLdapUsersProviderIT.java
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/KerberosIT.java
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/LdapRealmIT.java
server/sonar-auth-ldap/src/main/java/org/sonar/auth/ldap/LdapAuthenticator.java
server/sonar-auth-ldap/src/main/java/org/sonar/auth/ldap/LdapGroupsProvider.java
server/sonar-auth-ldap/src/main/java/org/sonar/auth/ldap/LdapUsersProvider.java
server/sonar-auth-saml/build.gradle
server/sonar-auth-saml/src/it/java/org/sonar/auth/saml/SamlIdentityProviderIT.java
server/sonar-auth-saml/src/main/java/org/sonar/auth/saml/SamlAuthStatusPageGenerator.java
server/sonar-auth-saml/src/main/java/org/sonar/auth/saml/SamlAuthenticator.java
server/sonar-auth-saml/src/main/java/org/sonar/auth/saml/SamlIdentityProvider.java
server/sonar-auth-saml/src/test/java/org/sonar/auth/saml/SamlAuthStatusPageGeneratorTest.java
server/sonar-auth-saml/src/test/java/org/sonar/auth/saml/SamlAuthenticatorTest.java
server/sonar-webserver-api/src/main/java/org/sonar/server/http/JavaxHttpRequest.java [new file with mode: 0644]
server/sonar-webserver-api/src/main/java/org/sonar/server/http/JavaxHttpResponse.java [new file with mode: 0644]
server/sonar-webserver-api/src/test/java/org/sonar/server/http/JavaxHttpRequestTest.java [new file with mode: 0644]
server/sonar-webserver-api/src/test/java/org/sonar/server/http/JavaxHttpResponseTest.java [new file with mode: 0644]
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/AuthenticationError.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/AuthenticationFilter.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/AuthenticationRedirection.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/BaseContextFactory.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/BasicAuthentication.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/Cookies.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/CredentialsAuthentication.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/CredentialsExternalAuthentication.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/DefaultAdminCredentialsVerifierFilter.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/GithubWebhookAuthentication.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/HttpHeadersAuthentication.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/InitFilter.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/JwtCsrfVerifier.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/JwtHttpHandler.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/LdapCredentialsAuthentication.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/OAuth2AuthenticationParameters.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/OAuth2AuthenticationParametersImpl.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/OAuth2CallbackFilter.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/OAuth2ContextFactory.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/OAuthCsrfVerifier.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/RequestAuthenticator.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/RequestAuthenticatorImpl.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/ResetPasswordFilter.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/SamlValidationCspHeaders.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/SamlValidationRedirectionFilter.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/event/AuthenticationEvent.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/event/AuthenticationEventImpl.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/usertoken/UserTokenAuthentication.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/BaseContextFactoryTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/BasicAuthenticationTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/CookiesTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/CredentialsAuthenticationTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/CredentialsExternalAuthenticationTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/DefaultAdminCredentialsVerifierFilterTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/GithubWebhookAuthenticationTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/HttpHeadersAuthenticationTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/InitFilterTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/JwtCsrfVerifierTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/JwtHttpHandlerTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/LdapCredentialsAuthenticationTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/OAuth2AuthenticationParametersImplTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/OAuth2CallbackFilterTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/OAuth2ContextFactoryTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/OAuthCsrfVerifierTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/RequestAuthenticatorImplTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/ResetPasswordFilterTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/SamlValidationCspHeadersTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/SamlValidationRedirectionFilterTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/event/AuthenticationEventImplTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/usertoken/UserTokenAuthenticationTest.java
server/sonar-webserver-core/src/main/java/org/sonar/server/plugins/PluginsRiskConsentFilter.java
server/sonar-webserver-core/src/test/java/org/sonar/server/plugins/PluginsRiskConsentFilterTest.java
server/sonar-webserver-pushapi/src/testFixtures/java/org/sonar/server/pushapi/DumbPushResponse.java
server/sonar-webserver-pushapi/src/testFixtures/java/org/sonar/server/pushapi/TestPushRequest.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/authentication/ws/LoginActionIT.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/ChangePasswordActionIT.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/authentication/ws/LoginAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/authentication/ws/LogoutAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/authentication/ws/ValidateAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/saml/ws/ValidationAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/saml/ws/ValidationInitAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/ChangePasswordAction.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/authentication/ws/LogoutActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/authentication/ws/ValidateActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/saml/ws/ValidationActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/saml/ws/ValidationInitActionTest.java
server/sonar-webserver-ws/src/main/java/org/sonar/server/ws/ServletRequest.java
server/sonar-webserver-ws/src/main/java/org/sonar/server/ws/ServletResponse.java
server/sonar-webserver-ws/src/test/java/org/sonar/server/ws/ServletRequestTest.java
server/sonar-webserver-ws/src/test/java/org/sonar/server/ws/ServletResponseTest.java
server/sonar-webserver/src/it/java/org/sonar/server/platform/web/SonarLintConnectionFilterIT.java
server/sonar-webserver/src/main/java/org/sonar/server/platform/web/MasterServletFilter.java
server/sonar-webserver/src/main/java/org/sonar/server/platform/web/RegisterServletFilters.java
server/sonar-webserver/src/main/java/org/sonar/server/platform/web/SonarLintConnectionFilter.java
server/sonar-webserver/src/main/java/org/sonar/server/platform/web/UserSessionFilter.java
server/sonar-webserver/src/main/java/org/sonar/server/platform/web/WebServiceFilter.java
server/sonar-webserver/src/main/java/org/sonar/server/platform/web/WebServiceReroutingFilter.java
server/sonar-webserver/src/test/java/org/sonar/server/platform/web/MasterServletFilterTest.java
server/sonar-webserver/src/test/java/org/sonar/server/platform/web/RegisterServletFiltersTest.java
server/sonar-webserver/src/test/java/org/sonar/server/platform/web/UserSessionFilterTest.java
server/sonar-webserver/src/test/java/org/sonar/server/platform/web/WebServiceFilterTest.java
server/sonar-webserver/src/test/java/org/sonar/server/platform/web/WebServiceReroutingFilterTest.java
sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java
sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultExternalIssue.java
sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/rule/internal/DefaultAdHocRule.java

index 06e22e2c3b537dce4cbe6cccb0821dac77e7730c..d8fcfd18a4ecc8a7ba142713b0138f9a61af4669 100644 (file)
@@ -1,6 +1,6 @@
 group=org.sonarsource.sonarqube
 version=10.1
-pluginApiVersion=9.15.0.435
+pluginApiVersion=9.16.0.560
 description=Open source platform for continuous inspection of code quality
 projectTitle=SonarQube
 org.gradle.jvmargs=-Xmx2048m
index 445a0c2be169a45666bd3cb43d02a0a92562cf05..8329723c6e26ed3b12276d5455d1b12ea9ab5a55 100644 (file)
@@ -22,4 +22,5 @@ dependencies {
     testImplementation 'junit:junit'
     testImplementation 'org.assertj:assertj-core'
     testImplementation 'org.mockito:mockito-core'
+    testImplementation project(path: ':server:sonar-webserver-api')
 }
index ad0a29ebda12d29e82a37f33a0ae0f86744faf70..58dd889d670ddd4b5ca042318abe7164de0a5f1f 100755 (executable)
@@ -33,12 +33,12 @@ import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import javax.annotation.CheckForNull;
-import javax.servlet.http.HttpServletRequest;
 import org.sonar.api.server.ServerSide;
 import org.sonar.api.server.authentication.Display;
 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.server.http.HttpRequest;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 
@@ -122,7 +122,7 @@ public class BitbucketIdentityProvider implements OAuth2IdentityProvider {
   }
 
   private void onCallback(CallbackContext context) throws InterruptedException, ExecutionException, IOException {
-    HttpServletRequest request = context.getRequest();
+    HttpRequest request = context.getHttpRequest();
     OAuth20Service scribe = newScribeBuilder(context).build(scribeApi);
     String code = request.getParameter(OAuthConstants.CODE);
     OAuth2AccessToken accessToken = scribe.getAccessToken(code);
index cce09beccf30f8cb6d01cd98176def8014b4b2af..9b47ec7abc36a750ceb3fa517cb6366f13abd74a 100644 (file)
@@ -36,7 +36,10 @@ 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.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.utils.System2;
+import org.sonar.server.http.JavaxHttpRequest;
 
 import static java.lang.String.format;
 import static java.net.URLEncoder.encode;
@@ -253,14 +256,24 @@ public class IntegrationTest {
       return CALLBACK_URL;
     }
 
+    @Override
+    public HttpRequest getHttpRequest() {
+      return new JavaxHttpRequest(request);
+    }
+
+    @Override
+    public HttpResponse getHttpResponse() {
+      throw new UnsupportedOperationException("not used");
+    }
+
     @Override
     public HttpServletRequest getRequest() {
-      return request;
+      throw new UnsupportedOperationException("deprecated");
     }
 
     @Override
     public HttpServletResponse getResponse() {
-      throw new UnsupportedOperationException("not used");
+      throw new UnsupportedOperationException("deprecated");
     }
   }
 
@@ -287,6 +300,16 @@ public class IntegrationTest {
       return CALLBACK_URL;
     }
 
+    @Override
+    public HttpRequest getHttpRequest() {
+      return null;
+    }
+
+    @Override
+    public HttpResponse getHttpResponse() {
+      return null;
+    }
+
     @Override
     public HttpServletRequest getRequest() {
       return null;
index 811d44118a316ec50a8f0ceb2e88f3532f207f58..f78f4ba0b22af29bda2511cf46c145389fe30221 100644 (file)
@@ -22,4 +22,5 @@ dependencies {
     testImplementation 'junit:junit'
     testImplementation 'org.assertj:assertj-core'
     testImplementation 'org.mockito:mockito-core'
+    testImplementation project(path: ':server:sonar-webserver-api')
 }
index caf4ddc05dbcc0576f485b2bd5060117f91f63c2..3acf65ff2cd4c6210cec546f057579cbde8b782c 100644 (file)
@@ -24,11 +24,11 @@ import com.github.scribejava.core.model.OAuth2AccessToken;
 import com.github.scribejava.core.oauth.OAuth20Service;
 import java.io.IOException;
 import java.util.concurrent.ExecutionException;
-import javax.servlet.http.HttpServletRequest;
 import org.sonar.api.server.authentication.Display;
 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.server.http.HttpRequest;
 
 import static com.google.common.base.Preconditions.checkState;
 import static java.lang.String.format;
@@ -106,7 +106,7 @@ public class GitHubIdentityProvider implements OAuth2IdentityProvider {
   private void onCallback(CallbackContext context) throws InterruptedException, ExecutionException, IOException {
     context.verifyCsrfState();
 
-    HttpServletRequest request = context.getRequest();
+    HttpRequest request = context.getHttpRequest();
     OAuth20Service scribe = newScribeBuilder(context).build(scribeApi);
     String code = request.getParameter("code");
     OAuth2AccessToken accessToken = scribe.getAccessToken(code);
index 390ba079e9e92bba3b0357b9e86e7e8ca3fa3e1c..3d8a1f0d8d3700e45fc2e4c01b232d3e3d497304 100644 (file)
@@ -37,7 +37,10 @@ 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.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.utils.System2;
+import org.sonar.server.http.JavaxHttpRequest;
 
 import static java.lang.String.format;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -403,14 +406,24 @@ public class IntegrationTest {
       return CALLBACK_URL;
     }
 
+    @Override
+    public HttpRequest getHttpRequest() {
+      return new JavaxHttpRequest(request);
+    }
+
+    @Override
+    public HttpResponse getHttpResponse() {
+      throw new UnsupportedOperationException("not used");
+    }
+
     @Override
     public HttpServletRequest getRequest() {
-      return request;
+      throw new UnsupportedOperationException("deprecated");
     }
 
     @Override
     public HttpServletResponse getResponse() {
-      throw new UnsupportedOperationException("not used");
+      throw new UnsupportedOperationException("deprecated");
     }
   }
 
@@ -437,6 +450,16 @@ public class IntegrationTest {
       return CALLBACK_URL;
     }
 
+    @Override
+    public HttpRequest getHttpRequest() {
+      return null;
+    }
+
+    @Override
+    public HttpResponse getHttpResponse() {
+      return null;
+    }
+
     @Override
     public HttpServletRequest getRequest() {
       return null;
index a425e98f752583fa71fb2aa2892cab02e12c6846..042c40678eb29562da622d344434aeb7404db04b 100644 (file)
@@ -30,10 +30,10 @@ import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.stream.Stream;
-import javax.servlet.http.HttpServletRequest;
 import org.sonar.api.server.authentication.Display;
 import org.sonar.api.server.authentication.OAuth2IdentityProvider;
 import org.sonar.api.server.authentication.UserIdentity;
+import org.sonar.api.server.http.HttpRequest;
 
 import static com.google.common.base.Preconditions.checkState;
 import static java.util.stream.Collectors.toSet;
@@ -109,7 +109,7 @@ public class GitLabIdentityProvider implements OAuth2IdentityProvider {
   }
 
   private void onCallback(CallbackContext context) throws InterruptedException, ExecutionException, IOException {
-    HttpServletRequest request = context.getRequest();
+    HttpRequest request = context.getHttpRequest();
     OAuth20Service scribe = newScribeBuilder(context, gitLabSettings.syncUserGroups()).build(scribeApi);
     String code = request.getParameter(OAuthConstants.CODE);
     OAuth2AccessToken accessToken = scribe.getAccessToken(code);
index 3f8d35e3f6fc7e8a00c6d9ef073597ee037e2a35..dfeabc36e1401bf7d9f536012a1db6c602ac6d7e 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.auth.gitlab;
 
-import javax.servlet.http.HttpServletRequest;
 import okhttp3.mockwebserver.MockResponse;
 import okhttp3.mockwebserver.MockWebServer;
 import org.assertj.core.api.Assertions;
@@ -31,6 +30,7 @@ import org.mockito.Mockito;
 import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.server.authentication.OAuth2IdentityProvider;
 import org.sonar.api.server.authentication.UserIdentity;
+import org.sonar.api.server.http.HttpRequest;
 
 import static java.lang.String.format;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -76,9 +76,9 @@ public class IntegrationTest {
     OAuth2IdentityProvider.CallbackContext callbackContext = Mockito.mock(OAuth2IdentityProvider.CallbackContext.class);
     when(callbackContext.getCallbackUrl()).thenReturn("http://server/callback");
 
-    HttpServletRequest httpServletRequest = Mockito.mock(HttpServletRequest.class);
-    when(httpServletRequest.getParameter("code")).thenReturn(ANY_CODE_VALUE);
-    when(callbackContext.getRequest()).thenReturn(httpServletRequest);
+    HttpRequest httpRequest = Mockito.mock(HttpRequest.class);
+    when(httpRequest.getParameter("code")).thenReturn(ANY_CODE_VALUE);
+    when(callbackContext.getHttpRequest()).thenReturn(httpRequest);
 
     gitlab.enqueue(new MockResponse().setBody(
       "{\n" + " \"access_token\": \"de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54\",\n" + " \"token_type\": \"bearer\",\n" + " \"expires_in\": 7200,\n"
@@ -104,9 +104,9 @@ public class IntegrationTest {
     OAuth2IdentityProvider.CallbackContext callbackContext = Mockito.mock(OAuth2IdentityProvider.CallbackContext.class);
     when(callbackContext.getCallbackUrl()).thenReturn("http://server/callback");
 
-    HttpServletRequest httpServletRequest = Mockito.mock(HttpServletRequest.class);
-    when(httpServletRequest.getParameter("code")).thenReturn(ANY_CODE_VALUE);
-    when(callbackContext.getRequest()).thenReturn(httpServletRequest);
+    HttpRequest httpRequest = Mockito.mock(HttpRequest.class);
+    when(httpRequest.getParameter("code")).thenReturn(ANY_CODE_VALUE);
+    when(callbackContext.getHttpRequest()).thenReturn(httpRequest);
 
     gitlab.enqueue(new MockResponse().setBody(
       "{\n" + " \"access_token\": \"de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54\",\n" + " \"token_type\": \"bearer\",\n" + " \"expires_in\": 7200,\n"
@@ -133,9 +133,9 @@ public class IntegrationTest {
     OAuth2IdentityProvider.CallbackContext callbackContext = Mockito.mock(OAuth2IdentityProvider.CallbackContext.class);
     when(callbackContext.getCallbackUrl()).thenReturn("http://server/callback");
 
-    HttpServletRequest httpServletRequest = Mockito.mock(HttpServletRequest.class);
-    when(httpServletRequest.getParameter("code")).thenReturn(ANY_CODE_VALUE);
-    when(callbackContext.getRequest()).thenReturn(httpServletRequest);
+    HttpRequest httpRequest = Mockito.mock(HttpRequest.class);
+    when(httpRequest.getParameter("code")).thenReturn(ANY_CODE_VALUE);
+    when(callbackContext.getHttpRequest()).thenReturn(httpRequest);
 
     gitlab.enqueue(new MockResponse().setBody(
       "{\n" + " \"access_token\": \"de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54\",\n" + " \"token_type\": \"bearer\",\n" + " \"expires_in\": 7200,\n"
@@ -173,9 +173,9 @@ public class IntegrationTest {
     OAuth2IdentityProvider.CallbackContext callbackContext = Mockito.mock(OAuth2IdentityProvider.CallbackContext.class);
     when(callbackContext.getCallbackUrl()).thenReturn("http://server/callback");
 
-    HttpServletRequest httpServletRequest = Mockito.mock(HttpServletRequest.class);
-    when(httpServletRequest.getParameter("code")).thenReturn(ANY_CODE_VALUE);
-    when(callbackContext.getRequest()).thenReturn(httpServletRequest);
+    HttpRequest httpRequest = Mockito.mock(HttpRequest.class);
+    when(httpRequest.getParameter("code")).thenReturn(ANY_CODE_VALUE);
+    when(callbackContext.getHttpRequest()).thenReturn(httpRequest);
 
     gitlab.enqueue(new MockResponse().setBody(
       "{\n" + " \"access_token\": \"de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54\",\n" + " \"token_type\": \"bearer\",\n" + " \"expires_in\": 7200,\n"
index 1f3ee94fc24ebd4e4c04776f9d4e776548ab43d9..e9264d06275f8f95676a5f263a262a96b6f51ae9 100644 (file)
@@ -19,9 +19,9 @@
  */
 package org.sonar.auth.ldap;
 
-import javax.servlet.http.HttpServletRequest;
 import org.junit.ClassRule;
 import org.junit.Test;
+import org.sonar.api.server.http.HttpRequest;
 import org.sonar.auth.ldap.server.LdapServer;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -163,7 +163,7 @@ public class DefaultLdapAuthenticatorIT {
   }
 
   private static LdapAuthenticator.Context createContext(String username, String password) {
-    return new LdapAuthenticator.Context(username, password, mock(HttpServletRequest.class));
+    return new LdapAuthenticator.Context(username, password, mock(HttpRequest.class));
   }
 
 }
index 0534682719a65e936bdeb56d9f10cef93a70332e..b505fd389722988a9c829bd58e367f0dd1fd678f 100644 (file)
 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.api.server.http.HttpRequest;
 import org.sonar.auth.ldap.server.LdapServer;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -175,7 +175,7 @@ public class DefaultLdapGroupsProviderIT {
   }
 
   private static LdapGroupsProvider.Context createContext(String serverName, String userName) {
-    return new LdapGroupsProvider.Context(serverName, userName, mock(HttpServletRequest.class));
+    return new LdapGroupsProvider.Context(serverName, userName, mock(HttpRequest.class));
   }
 
 }
index ea6894e7e80542c6e9d23b2406a65578c978f4db..91d0592b7c364cb7271fa98f247032a7a2462ace 100644 (file)
  */
 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.api.server.http.HttpRequest;
 import org.sonar.auth.ldap.server.LdapServer;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -92,6 +92,6 @@ public class DefaultLdapUsersProviderIT {
   }
 
   private static LdapUsersProvider.Context createContext(String serverKey, String username) {
-    return new LdapUsersProvider.Context(serverKey, username, mock(HttpServletRequest.class));
+    return new LdapUsersProvider.Context(serverKey, username, mock(HttpRequest.class));
   }
 }
index 08f1dfc571496ca129646bb307b5608e6f197884..0f933d5e148cdb4c52af197b2cad1aec4194f282 100644 (file)
 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.api.server.http.HttpRequest;
 import org.sonar.auth.ldap.server.LdapServer;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -54,14 +54,14 @@ public class KerberosIT {
 
   @Test
   public void test_wrong_password() {
-    LdapAuthenticator.Context wrongPasswordContext = new LdapAuthenticator.Context("Godin@EXAMPLE.ORG", "wrong_user_password", Mockito.mock(HttpServletRequest.class));
+    LdapAuthenticator.Context wrongPasswordContext = new LdapAuthenticator.Context("Godin@EXAMPLE.ORG", "wrong_user_password", Mockito.mock(HttpRequest.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));
+    LdapAuthenticator.Context correctPasswordContext = new LdapAuthenticator.Context("Godin@EXAMPLE.ORG", "user_password", Mockito.mock(HttpRequest.class));
     assertThat(authenticator.doAuthenticate(correctPasswordContext).isSuccess()).isTrue();
 
   }
@@ -70,14 +70,14 @@ public class KerberosIT {
   public void test_default_realm() {
 
     // Using default realm from krb5.conf:
-    LdapAuthenticator.Context defaultRealmContext = new LdapAuthenticator.Context("Godin", "user_password", Mockito.mock(HttpServletRequest.class));
+    LdapAuthenticator.Context defaultRealmContext = new LdapAuthenticator.Context("Godin", "user_password", Mockito.mock(HttpRequest.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));
+    LdapGroupsProvider.Context groupsContext = new LdapGroupsProvider.Context("default", "godin", Mockito.mock(HttpRequest.class));
     assertThat(groupsProvider.doGetGroups(groupsContext))
       .containsOnly("sonar-users");
   }
index 4075ca0311d215a0ef2d167b3a662a9c9578f2a3..318bfd701fc725121cfb5a161945128fb41f8002 100644 (file)
  */
 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.api.server.http.HttpRequest;
 import org.sonar.auth.ldap.server.LdapServer;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -117,12 +117,12 @@ public class LdapRealmIT {
     LdapGroupsProvider groupsProvider = realm.getGroupsProvider();
     assertThat(groupsProvider).isInstanceOf(LdapGroupsProvider.class).isInstanceOf(DefaultLdapGroupsProvider.class);
 
-    LdapUsersProvider.Context userContext = new DefaultLdapUsersProvider.Context("<default>", "tester", Mockito.mock(HttpServletRequest.class));
+    LdapUsersProvider.Context userContext = new DefaultLdapUsersProvider.Context("<default>", "tester", Mockito.mock(HttpRequest.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));
+    LdapGroupsProvider.Context groupsContext = new DefaultLdapGroupsProvider.Context("default", "tester", Mockito.mock(HttpRequest.class));
     assertThatThrownBy(() -> groupsProvider.doGetGroups(groupsContext))
       .isInstanceOf(LdapException.class)
       .hasMessage("Unable to retrieve groups for user tester in server with key <default>");
index 33f1912b4a2e55d1b462fd4f9060f8f6735f57cc..dfb8a93ecbd416e42e1c6f9a63464113cfbe4e1f 100644 (file)
@@ -20,7 +20,7 @@
 package org.sonar.auth.ldap;
 
 import javax.annotation.Nullable;
-import javax.servlet.http.HttpServletRequest;
+import org.sonar.api.server.http.HttpRequest;
 
 import static java.util.Objects.requireNonNull;
 
@@ -35,9 +35,9 @@ public interface LdapAuthenticator {
   final class Context {
     private String username;
     private String password;
-    private HttpServletRequest request;
+    private HttpRequest request;
 
-    public Context(@Nullable String username, @Nullable String password, HttpServletRequest request) {
+    public Context(@Nullable String username, @Nullable String password, HttpRequest request) {
       requireNonNull(request);
       this.request = request;
       this.username = username;
@@ -58,7 +58,7 @@ public interface LdapAuthenticator {
       return password;
     }
 
-    public HttpServletRequest getRequest() {
+    public HttpRequest getRequest() {
       return request;
     }
   }
index 629ead0826574d18e37043a4b333a66d21580e4d..1cbacb929bd8608f0d3e4c7512200b401107ac65 100644 (file)
 package org.sonar.auth.ldap;
 
 import java.util.Collection;
-import javax.servlet.http.HttpServletRequest;
+import org.sonar.api.server.http.HttpRequest;
 
 public interface LdapGroupsProvider {
 
   Collection<String> doGetGroups(Context context);
 
-  record Context(String serverKey, String username, HttpServletRequest request) {
+  record Context(String serverKey, String username, HttpRequest request) {
   }
 }
index 7c3ba105863650ead8f055f6e6d568479e5ca4ec..73258e59a6d55e86fd5e1be1c5387dd7cbbfe13f 100644 (file)
  */
 package org.sonar.auth.ldap;
 
-import javax.servlet.http.HttpServletRequest;
+import org.sonar.api.server.http.HttpRequest;
 
 public interface LdapUsersProvider {
 
   LdapUserDetails doGetUserDetails(Context context);
 
-  record Context(String serverKey, String username, HttpServletRequest request) {
+  record Context(String serverKey, String username, HttpRequest request) {
 
   }
 }
index db3de357a60ec233147abac807dd456f29a8bf67..cafc01888bba672413b558ad22ffb4184c6f4a9e 100644 (file)
@@ -14,6 +14,7 @@ dependencies {
     compileOnlyApi 'javax.servlet:javax.servlet-api'
     compileOnlyApi 'org.json:json'
     compileOnlyApi project(':server:sonar-db-dao')
+    compileOnlyApi project(':server:sonar-webserver-api')
     compileOnlyApi project(':sonar-core')
 
     testImplementation 'com.tngtech.java:junit-dataprovider'
index f67636785e38822d197c255caa2ba11dd727aea0..ea83ab6ad4905f0bfba5fb384d3a14f2a3770720 100644 (file)
@@ -37,10 +37,14 @@ 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.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.testfixtures.log.LogAndArguments;
 import org.sonar.api.testfixtures.log.LogTester;
+import org.sonar.api.utils.System2;
 import org.sonar.db.DbTester;
+import org.sonar.server.http.JavaxHttpRequest;
+import org.sonar.server.http.JavaxHttpResponse;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -366,14 +370,24 @@ public class SamlIdentityProviderIT {
       return SQ_CALLBACK_URL;
     }
 
+    @Override
+    public HttpRequest getHttpRequest() {
+      return new JavaxHttpRequest(mock(HttpServletRequest.class));
+    }
+
+    @Override
+    public HttpResponse getHttpResponse() {
+      return new JavaxHttpResponse(response);
+    }
+
     @Override
     public HttpServletRequest getRequest() {
-      return mock(HttpServletRequest.class);
+      throw new UnsupportedOperationException("deprecated");
     }
 
     @Override
     public HttpServletResponse getResponse() {
-      return response;
+      throw new UnsupportedOperationException("deprecated");
     }
   }
 
@@ -392,7 +406,7 @@ public class SamlIdentityProviderIT {
       this.expectedCallbackUrl = expectedCallbackUrl;
       Map<String, String[]> parameterMap = new HashMap<>();
       parameterMap.put("SAMLResponse", new String[]{loadResponse(encodedResponseFile)});
-      when(getRequest().getParameterMap()).thenReturn(parameterMap);
+      when(((JavaxHttpRequest) getHttpRequest()).getDelegate().getParameterMap()).thenReturn(parameterMap);
     }
 
 
@@ -430,14 +444,24 @@ public class SamlIdentityProviderIT {
       return this.expectedCallbackUrl;
     }
 
+    @Override
+    public HttpRequest getHttpRequest() {
+      return new JavaxHttpRequest(request);
+    }
+
+    @Override
+    public HttpResponse getHttpResponse() {
+      return new JavaxHttpResponse(response);
+    }
+
     @Override
     public HttpServletRequest getRequest() {
-      return this.request;
+      return null;
     }
 
     @Override
     public HttpServletResponse getResponse() {
-      return this.response;
+      return null;
     }
   }
 }
index 5c774e2d501dc639ef4eead3ca3ce75d335f8aad..15dcca746e6025bf5927527e1c54cedfba538148 100644 (file)
@@ -25,8 +25,8 @@ import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.util.Base64;
 import java.util.Map;
-import javax.servlet.http.HttpServletRequest;
 import org.json.JSONObject;
+import org.sonar.api.server.http.HttpRequest;
 
 public final class SamlAuthStatusPageGenerator {
 
@@ -38,7 +38,7 @@ public final class SamlAuthStatusPageGenerator {
     throw new IllegalStateException("This Utility class cannot be instantiated");
   }
 
-  public static String getSamlAuthStatusHtml(HttpServletRequest request, SamlAuthenticationStatus samlAuthenticationStatus) {
+  public static String getSamlAuthStatusHtml(HttpRequest request, SamlAuthenticationStatus samlAuthenticationStatus) {
     Map<String, String> substitutionsMap = getSubstitutionsMap(request, samlAuthenticationStatus);
     String htmlTemplate = getPlainTemplate();
 
@@ -48,7 +48,7 @@ public final class SamlAuthStatusPageGenerator {
       .reduce(htmlTemplate, (accumulator, pattern) -> accumulator.replace(pattern, substitutionsMap.get(pattern)));
   }
 
-  private static Map<String, String> getSubstitutionsMap(HttpServletRequest request, SamlAuthenticationStatus samlAuthenticationStatus) {
+  private static Map<String, String> getSubstitutionsMap(HttpRequest request, SamlAuthenticationStatus samlAuthenticationStatus) {
     return Map.of(
       WEB_CONTEXT, request.getContextPath(),
       SAML_AUTHENTICATION_STATUS, getBase64EncodedStatus(samlAuthenticationStatus));
index 42e0697fe1c865fc8ac6447cea0d9f9470e8a822..13d2200bc71cdce2be15c2fb9dba2573393ca374 100644 (file)
@@ -38,8 +38,12 @@ import javax.servlet.http.HttpServletResponse;
 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.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
+import org.sonar.server.http.JavaxHttpRequest;
+import org.sonar.server.http.JavaxHttpResponse;
 
 import static java.util.Collections.emptySet;
 import static java.util.Objects.requireNonNull;
@@ -62,8 +66,8 @@ public class SamlAuthenticator {
     this.samlMessageIdChecker = samlMessageIdChecker;
   }
 
-  public UserIdentity buildUserIdentity(OAuth2IdentityProvider.CallbackContext context, HttpServletRequest processedRequest) {
-    Auth auth = this.initSamlAuth(processedRequest, context.getResponse());
+  public UserIdentity buildUserIdentity(OAuth2IdentityProvider.CallbackContext context, HttpRequest processedRequest) {
+    Auth auth = this.initSamlAuth(processedRequest, context.getHttpResponse());
     processResponse(auth);
     context.verifyCsrfState(STATE_REQUEST_PARAMETER);
 
@@ -83,18 +87,22 @@ public class SamlAuthenticator {
     return userIdentityBuilder.build();
   }
 
-  public void initLogin(String callbackUrl, String relayState, HttpServletRequest request, HttpServletResponse response) {
+  public void initLogin(String callbackUrl, String relayState, HttpRequest request, HttpResponse response) {
     Auth auth = this.initSamlAuth(callbackUrl, request, response);
     login(auth, relayState);
   }
 
-  private Auth initSamlAuth(HttpServletRequest request, HttpServletResponse response) {
+  private Auth initSamlAuth(HttpRequest request, HttpResponse response) {
     return initSamlAuth(null, request, response);
   }
 
-  private Auth initSamlAuth(@Nullable String callbackUrl, HttpServletRequest request, HttpServletResponse response) {
+  private Auth initSamlAuth(@Nullable String callbackUrl, HttpRequest request, HttpResponse response) {
     try {
-      return new Auth(initSettings(callbackUrl), request, response);
+      //no way around this as onelogin requires javax request/response
+      HttpServletRequest httpServletRequest = ((JavaxHttpRequest) request).getDelegate();
+      HttpServletResponse httpServletResponse = ((JavaxHttpResponse) response).getDelegate();
+
+      return new Auth(initSettings(callbackUrl), httpServletRequest, httpServletResponse);
     } catch (SettingsException e) {
       throw new IllegalStateException("Failed to create a SAML Auth", e);
     }
@@ -208,7 +216,7 @@ public class SamlAuthenticator {
     samlMessageIdChecker.check(auth);
   }
 
-  public String getAuthenticationStatusPage(HttpServletRequest request, HttpServletResponse response) {
+  public String getAuthenticationStatusPage(HttpRequest request, HttpResponse response) {
     try {
       Auth auth = initSamlAuth(request, response);
       return getSamlAuthStatusHtml(request, getSamlAuthenticationStatus(auth, samlSettings));
@@ -217,4 +225,3 @@ public class SamlAuthenticator {
     }
   }
 }
-
index d5784328c5d7a4bc9a469e07f8b3416507cfb2de..e38b8e8fc86a8b637e6669a8d7cd4a2f72ac4d8e 100644 (file)
@@ -26,6 +26,8 @@ import org.sonar.api.server.ServerSide;
 import org.sonar.api.server.authentication.Display;
 import org.sonar.api.server.authentication.OAuth2IdentityProvider;
 import org.sonar.api.server.authentication.UserIdentity;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.server.http.JavaxHttpRequest;
 
 @ServerSide
 public class SamlIdentityProvider implements OAuth2IdentityProvider {
@@ -74,7 +76,8 @@ public class SamlIdentityProvider implements OAuth2IdentityProvider {
   @Override
   public void init(InitContext context) {
     SamlAuthenticator samlAuthenticator = new SamlAuthenticator(samlSettings, samlMessageIdChecker);
-    samlAuthenticator.initLogin(context.getCallbackUrl(), context.generateCsrfState(), context.getRequest(), context.getResponse());
+    samlAuthenticator.initLogin(context.getCallbackUrl(), context.generateCsrfState(),
+      context.getHttpRequest(), context.getHttpResponse());
   }
 
   @Override
@@ -86,7 +89,7 @@ public class SamlIdentityProvider implements OAuth2IdentityProvider {
     // - https://github.com/onelogin/java-saml/issues/198
     // - https://github.com/onelogin/java-saml/issues/95
     //
-    HttpServletRequest processedRequest = useProxyHeadersInRequest(context.getRequest());
+    HttpRequest processedRequest = useProxyHeadersInRequest(context.getHttpRequest());
 
     SamlAuthenticator samlAuthenticator = new SamlAuthenticator(samlSettings, samlMessageIdChecker);
     UserIdentity userIdentity = samlAuthenticator.buildUserIdentity(context, processedRequest);
@@ -95,10 +98,10 @@ public class SamlIdentityProvider implements OAuth2IdentityProvider {
 
   }
 
-  private static HttpServletRequest useProxyHeadersInRequest(HttpServletRequest request) {
+  private static HttpRequest useProxyHeadersInRequest(HttpRequest request) {
     String forwardedScheme = request.getHeader("X-Forwarded-Proto");
     if (forwardedScheme != null) {
-      request = new HttpServletRequestWrapper(request) {
+      HttpServletRequest httpServletRequest = new HttpServletRequestWrapper(((JavaxHttpRequest) request).getDelegate()) {
         @Override
         public String getScheme() {
           return forwardedScheme;
@@ -110,6 +113,7 @@ public class SamlIdentityProvider implements OAuth2IdentityProvider {
           return new StringBuffer(HTTPS_PATTERN.matcher(originalURL.toString()).replaceFirst(forwardedScheme + "://"));
         }
       };
+      return new JavaxHttpRequest(httpServletRequest);
     }
 
     return request;
index 9fd398321f21bc06ea0160d54a0f5838d00926a4..2f84a89a6d740c5b98a98827783c03dc505214e6 100644 (file)
@@ -21,8 +21,8 @@ package org.sonar.auth.saml;
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import javax.servlet.http.HttpServletRequest;
 import org.junit.Test;
+import org.sonar.api.server.http.HttpRequest;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -35,16 +35,16 @@ public class SamlAuthStatusPageGeneratorTest {
   @Test
   public void getSamlAuthStatusHtml_whenCalled_shouldGeneratePageWithData() {
     SamlAuthenticationStatus samlAuthenticationStatus = mock(SamlAuthenticationStatus.class);
-    HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
+    HttpRequest request = mock(HttpRequest.class);
 
     when(samlAuthenticationStatus.getStatus()).thenReturn(null);
     when(samlAuthenticationStatus.getErrors()).thenReturn(new ArrayList<>());
     when(samlAuthenticationStatus.getWarnings()).thenReturn(new ArrayList<>());
     when(samlAuthenticationStatus.getAvailableAttributes()).thenReturn(new HashMap<>());
     when(samlAuthenticationStatus.getMappedAttributes()).thenReturn(new HashMap<>());
-    when(httpServletRequest.getContextPath()).thenReturn("context");
+    when(request.getContextPath()).thenReturn("context");
 
-    String completeHtmlTemplate = getSamlAuthStatusHtml(httpServletRequest, samlAuthenticationStatus);
+    String completeHtmlTemplate = getSamlAuthStatusHtml(request, samlAuthenticationStatus);
 
     assertThat(completeHtmlTemplate).contains(EMPTY_DATA_RESPONSE);
   }
index 1c473879e3d10c5f2bfb7d7341313a8597fcc492..fb6e9f2cdeb911e54d415bc1c15139efe2b769a5 100644 (file)
@@ -22,8 +22,12 @@ package org.sonar.auth.saml;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.junit.Test;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.server.http.JavaxHttpRequest;
+import org.sonar.server.http.JavaxHttpResponse;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertFalse;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -32,8 +36,8 @@ public class SamlAuthenticatorTest {
   @Test
   public void authentication_status_with_errors_returned_when_init_fails() {
     SamlAuthenticator samlAuthenticator = new SamlAuthenticator(mock(SamlSettings.class), mock(SamlMessageIdChecker.class));
-    HttpServletRequest request = mock(HttpServletRequest.class);
-    HttpServletResponse response = mock(HttpServletResponse.class);
+    HttpRequest request = new JavaxHttpRequest(mock(HttpServletRequest.class));
+    HttpResponse response = new JavaxHttpResponse(mock(HttpServletResponse.class));
     when(request.getContextPath()).thenReturn("context");
 
     String authenticationStatus = samlAuthenticator.getAuthenticationStatusPage(request, response);
diff --git a/server/sonar-webserver-api/src/main/java/org/sonar/server/http/JavaxHttpRequest.java b/server/sonar-webserver-api/src/main/java/org/sonar/server/http/JavaxHttpRequest.java
new file mode 100644 (file)
index 0000000..08332a2
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * 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.server.http;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Enumeration;
+import javax.servlet.http.HttpServletRequest;
+import org.sonar.api.server.http.Cookie;
+import org.sonar.api.server.http.HttpRequest;
+
+/**
+ * Implementation of {@link HttpRequest} based on a delegate of {@link HttpServletRequest} from the Javax Servlet API.
+ */
+public class JavaxHttpRequest implements HttpRequest {
+
+  private final HttpServletRequest delegate;
+
+  public JavaxHttpRequest(HttpServletRequest delegate) {
+    this.delegate = delegate;
+  }
+
+  public HttpServletRequest getDelegate() {
+    return delegate;
+  }
+
+  @Override
+  public int getServerPort() {
+    return delegate.getServerPort();
+  }
+
+  @Override
+  public boolean isSecure() {
+    return delegate.isSecure();
+  }
+
+  @Override
+  public String getScheme() {
+    return delegate.getScheme();
+  }
+
+  @Override
+  public String getServerName() {
+    return delegate.getServerName();
+  }
+
+  @Override
+  public String getRequestURL() {
+    return delegate.getRequestURL().toString();
+  }
+
+  @Override
+  public String getRequestURI() {
+    return delegate.getRequestURI();
+  }
+
+  @Override
+  public String getQueryString() {
+    return delegate.getQueryString();
+  }
+
+  @Override
+  public String getContextPath() {
+    return delegate.getContextPath();
+  }
+
+  @Override
+  public String getParameter(String name) {
+    return delegate.getParameter(name);
+  }
+
+  @Override
+  public String[] getParameterValues(String name) {
+    return delegate.getParameterValues(name);
+  }
+
+  @Override
+  public String getHeader(String name) {
+    return delegate.getHeader(name);
+  }
+
+  @Override
+  public Enumeration<String> getHeaderNames() {
+    return delegate.getHeaderNames();
+  }
+
+  @Override
+  public Enumeration<String> getHeaders(String name) {
+    return delegate.getHeaders(name);
+  }
+
+  @Override
+  public String getMethod() {
+    return delegate.getMethod();
+  }
+
+  @Override
+  public String getRemoteAddr() {
+    return delegate.getRemoteAddr();
+  }
+
+  @Override
+  public void setAttribute(String name, Object value) {
+    delegate.setAttribute(name, value);
+  }
+
+  @Override
+  public String getServletPath() {
+    return delegate.getServletPath();
+  }
+
+  @Override
+  public BufferedReader getReader() throws IOException {
+    return delegate.getReader();
+  }
+
+  @Override
+  public Cookie[] getCookies() {
+    javax.servlet.http.Cookie[] cookies = delegate.getCookies();
+    if (cookies != null) {
+      return Arrays.stream(cookies)
+        .map(JavaxCookie::new)
+        .toArray(Cookie[]::new);
+    }
+    return new Cookie[0];
+  }
+
+  public static class JavaxCookie implements Cookie {
+    private final javax.servlet.http.Cookie delegate;
+
+    public JavaxCookie(javax.servlet.http.Cookie delegate) {
+      this.delegate = delegate;
+    }
+
+    @Override
+    public String getName() {
+      return delegate.getName();
+    }
+
+    @Override
+    public String getValue() {
+      return delegate.getValue();
+    }
+
+    @Override
+    public String getPath() {
+      return delegate.getPath();
+    }
+
+    @Override
+    public boolean isSecure() {
+      return delegate.getSecure();
+    }
+
+    @Override
+    public boolean isHttpOnly() {
+      return delegate.isHttpOnly();
+    }
+
+    @Override
+    public int getMaxAge() {
+      return delegate.getMaxAge();
+    }
+  }
+}
diff --git a/server/sonar-webserver-api/src/main/java/org/sonar/server/http/JavaxHttpResponse.java b/server/sonar-webserver-api/src/main/java/org/sonar/server/http/JavaxHttpResponse.java
new file mode 100644 (file)
index 0000000..37f7cf9
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * 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.server.http;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Collection;
+import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.server.http.Cookie;
+import org.sonar.api.server.http.HttpResponse;
+
+/**
+ * Implementation of {@link HttpResponse} based on a delegate of {@link HttpServletResponse} from the Javax Servlet API.
+ */
+public class JavaxHttpResponse implements HttpResponse {
+
+  private final HttpServletResponse delegate;
+
+  public JavaxHttpResponse(HttpServletResponse delegate) {
+    this.delegate = delegate;
+  }
+
+  public HttpServletResponse getDelegate() {
+    return delegate;
+  }
+
+  @Override
+  public void addHeader(String name, String value) {
+    delegate.addHeader(name, value);
+  }
+
+  @Override
+  public String getHeader(String name) {
+    return delegate.getHeader(name);
+  }
+
+  @Override
+  public Collection<String> getHeaders(String name) {
+    return delegate.getHeaders(name);
+  }
+
+  @Override
+  public void setStatus(int status) {
+    delegate.setStatus(status);
+  }
+
+  @Override
+  public int getStatus() {
+    return delegate.getStatus();
+  }
+
+  @Override
+  public void setContentType(String contentType) {
+    delegate.setContentType(contentType);
+  }
+
+  @Override
+  public PrintWriter getWriter() throws IOException {
+    return delegate.getWriter();
+  }
+
+  @Override
+  public void setHeader(String name, String value) {
+    delegate.setHeader(name, value);
+  }
+
+  @Override
+  public void sendRedirect(String location) throws IOException {
+    delegate.sendRedirect(location);
+  }
+
+  @Override
+  public void addCookie(Cookie cookie) {
+    javax.servlet.http.Cookie javaxCookie = new javax.servlet.http.Cookie(cookie.getName(), cookie.getValue());
+    javaxCookie.setPath(cookie.getPath());
+    javaxCookie.setSecure(cookie.isSecure());
+    javaxCookie.setHttpOnly(cookie.isHttpOnly());
+    javaxCookie.setMaxAge(cookie.getMaxAge());
+    delegate.addCookie(javaxCookie);
+  }
+
+  @Override
+  public OutputStream getOutputStream() throws IOException {
+    return delegate.getOutputStream();
+  }
+
+  @Override
+  public void setCharacterEncoding(String charset) {
+    delegate.setCharacterEncoding(charset);
+  }
+}
diff --git a/server/sonar-webserver-api/src/test/java/org/sonar/server/http/JavaxHttpRequestTest.java b/server/sonar-webserver-api/src/test/java/org/sonar/server/http/JavaxHttpRequestTest.java
new file mode 100644 (file)
index 0000000..1415dd4
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 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.server.http;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Enumeration;
+import javax.servlet.http.HttpServletRequest;
+import org.junit.Test;
+import org.sonar.api.server.http.Cookie;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class JavaxHttpRequestTest {
+
+  @Test
+  public void delegate_methods() throws IOException {
+    HttpServletRequest requestMock = mock(HttpServletRequest.class);
+    Enumeration<String> enumeration = Collections.enumeration(Collections.emptySet());
+    when(requestMock.getHeaderNames()).thenReturn(enumeration);
+    when(requestMock.getRemoteAddr()).thenReturn("192.168.0.1");
+    when(requestMock.getServletPath()).thenReturn("/servlet-path");
+    BufferedReader bufferedReader = mock(BufferedReader.class);
+    when(requestMock.getReader()).thenReturn(bufferedReader);
+    javax.servlet.http.Cookie[] cookies = new javax.servlet.http.Cookie[0];
+    when(requestMock.getCookies()).thenReturn(cookies);
+    when(requestMock.getServerPort()).thenReturn(80);
+    when(requestMock.isSecure()).thenReturn(true);
+    when(requestMock.getScheme()).thenReturn("https");
+    when(requestMock.getServerName()).thenReturn("hostname");
+    when(requestMock.getRequestURL()).thenReturn(new StringBuffer("https://hostname:80/path"));
+    when(requestMock.getRequestURI()).thenReturn("/path");
+    when(requestMock.getQueryString()).thenReturn("param1=value1");
+    when(requestMock.getContextPath()).thenReturn("/path");
+    when(requestMock.getMethod()).thenReturn("POST");
+    when(requestMock.getParameter("param1")).thenReturn("value1");
+    when(requestMock.getParameterValues("param1")).thenReturn(new String[] {"value1"});
+    when(requestMock.getHeader("header1")).thenReturn("hvalue1");
+    Enumeration<String> headers = mock(Enumeration.class);
+    when(requestMock.getHeaders("header1")).thenReturn(headers);
+
+    JavaxHttpRequest underTest = new JavaxHttpRequest(requestMock);
+
+    assertThat(underTest.getDelegate()).isSameAs(requestMock);
+    assertThat(underTest.getServerPort()).isEqualTo(80);
+    assertThat(underTest.isSecure()).isTrue();
+    assertThat(underTest.getScheme()).isEqualTo("https");
+    assertThat(underTest.getServerName()).isEqualTo("hostname");
+    assertThat(underTest.getRequestURL()).isEqualTo("https://hostname:80/path");
+    assertThat(underTest.getRequestURI()).isEqualTo("/path");
+    assertThat(underTest.getQueryString()).isEqualTo("param1=value1");
+    assertThat(underTest.getContextPath()).isEqualTo("/path");
+    assertThat(underTest.getMethod()).isEqualTo("POST");
+    assertThat(underTest.getParameter("param1")).isEqualTo("value1");
+    assertThat(underTest.getParameterValues("param1")).containsExactly("value1");
+    assertThat(underTest.getHeader("header1")).isEqualTo("hvalue1");
+    assertThat(underTest.getHeaders("header1")).isEqualTo(headers);
+    assertThat(underTest.getHeaderNames()).isEqualTo(enumeration);
+    assertThat(underTest.getRemoteAddr()).isEqualTo("192.168.0.1");
+    assertThat(underTest.getServletPath()).isEqualTo("/servlet-path");
+    assertThat(underTest.getReader()).isEqualTo(bufferedReader);
+    assertThat(underTest.getCookies()).isEqualTo(cookies);
+
+    underTest.setAttribute("name", "value");
+    verify(requestMock).setAttribute("name", "value");
+  }
+
+  @Test
+  public void delegate_methods_for_cookie() {
+    javax.servlet.http.Cookie mockCookie = new javax.servlet.http.Cookie("name", "value");
+    mockCookie.setSecure(true);
+    mockCookie.setPath("path");
+    mockCookie.setHttpOnly(true);
+    mockCookie.setMaxAge(100);
+
+    Cookie cookie = new JavaxHttpRequest.JavaxCookie(mockCookie);
+    assertThat(cookie.getName()).isEqualTo("name");
+    assertThat(cookie.getValue()).isEqualTo("value");
+    assertThat(cookie.getPath()).isEqualTo("path");
+    assertThat(cookie.isSecure()).isTrue();
+    assertThat(cookie.isHttpOnly()).isTrue();
+    assertThat(cookie.getMaxAge()).isEqualTo(100);
+  }
+
+}
diff --git a/server/sonar-webserver-api/src/test/java/org/sonar/server/http/JavaxHttpResponseTest.java b/server/sonar-webserver-api/src/test/java/org/sonar/server/http/JavaxHttpResponseTest.java
new file mode 100644 (file)
index 0000000..8c1ea17
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 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.server.http;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import org.junit.Test;
+import org.sonar.api.server.http.Cookie;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class JavaxHttpResponseTest {
+
+  @Test
+  public void delegate_methods() throws IOException {
+    HttpServletResponse responseMock = mock(HttpServletResponse.class);
+    when(responseMock.getHeader("h1")).thenReturn("hvalue1");
+    when(responseMock.getHeaders("h1")).thenReturn(List.of("hvalue1"));
+    when(responseMock.getStatus()).thenReturn(200);
+    ServletOutputStream outputStream = mock(ServletOutputStream.class);
+    when(responseMock.getOutputStream()).thenReturn(outputStream);
+    PrintWriter writer = mock(PrintWriter.class);
+    when(responseMock.getWriter()).thenReturn(writer);
+
+    JavaxHttpResponse underTest = new JavaxHttpResponse(responseMock);
+
+    assertThat(underTest.getDelegate()).isSameAs(responseMock);
+    assertThat(underTest.getHeader("h1")).isEqualTo("hvalue1");
+    assertThat(underTest.getHeaders("h1")).asList().containsExactly("hvalue1");
+    assertThat(underTest.getStatus()).isEqualTo(200);
+    assertThat(underTest.getWriter()).isEqualTo(writer);
+    assertThat(underTest.getOutputStream()).isEqualTo(outputStream);
+
+    underTest.addHeader("h2", "hvalue2");
+    underTest.setHeader("h3", "hvalue3");
+    underTest.setStatus(201);
+    underTest.setContentType("text/plain");
+    underTest.sendRedirect("http://redirect");
+    underTest.setCharacterEncoding("UTF-8");
+
+    Cookie cookie = mock(Cookie.class);
+    when(cookie.getName()).thenReturn("name");
+    when(cookie.getValue()).thenReturn("value");
+    underTest.addCookie(cookie);
+    verify(responseMock).addHeader("h2", "hvalue2");
+    verify(responseMock).setHeader("h3", "hvalue3");
+    verify(responseMock).setStatus(201);
+    verify(responseMock).setContentType("text/plain");
+    verify(responseMock).sendRedirect("http://redirect");
+    verify(responseMock).setCharacterEncoding("UTF-8");
+    verify(responseMock).addCookie(any(javax.servlet.http.Cookie.class));
+  }
+}
index 5f0e8354b7e578005b810b714620c4d2226a624b..7a0aaa9eae9ac6af08894d9f997f66bec715a605 100644 (file)
@@ -19,8 +19,8 @@
  */
 package org.sonar.server.authentication;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 import org.sonar.server.authentication.event.AuthenticationException;
@@ -41,17 +41,17 @@ public final class AuthenticationError {
     // Utility class
   }
 
-  static void handleError(Exception e, HttpServletRequest request, HttpServletResponse response, String message) {
+  static void handleError(Exception e, HttpRequest request, HttpResponse response, String message) {
     LOGGER.warn(message, e);
     redirectToUnauthorized(request, response);
   }
 
-  public static void handleError(HttpServletRequest request, HttpServletResponse response, String message) {
+  public static void handleError(HttpRequest request, HttpResponse response, String message) {
     LOGGER.warn(message);
     redirectToUnauthorized(request, response);
   }
 
-  static void handleAuthenticationError(AuthenticationException e, HttpServletRequest request, HttpServletResponse response) {
+  static void handleAuthenticationError(AuthenticationException e, HttpRequest request, HttpResponse response) {
     String publicMessage = e.getPublicMessage();
     if (publicMessage != null && !publicMessage.isEmpty()) {
       addErrorCookie(request, response, publicMessage);
@@ -59,7 +59,7 @@ public final class AuthenticationError {
     redirectToUnauthorized(request, response);
   }
 
-  public static void addErrorCookie(HttpServletRequest request, HttpServletResponse response, String value) {
+  public static void addErrorCookie(HttpRequest request, HttpResponse response, String value) {
     response.addCookie(newCookieBuilder(request)
       .setName(AUTHENTICATION_ERROR_COOKIE)
       .setValue(encodeMessage(value))
@@ -68,7 +68,7 @@ public final class AuthenticationError {
       .build());
   }
 
-  private static void redirectToUnauthorized(HttpServletRequest request, HttpServletResponse response) {
+  private static void redirectToUnauthorized(HttpRequest request, HttpResponse response) {
     redirectTo(response, request.getContextPath() + UNAUTHORIZED_PATH);
   }
 }
index b88fd9196028162b5b7a9c996c11256c2d1f4221..8fb7f6e72164a41fd11797315f232f6c7f44e02f 100644 (file)
 package org.sonar.server.authentication;
 
 import javax.annotation.CheckForNull;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.sonar.api.server.authentication.IdentityProvider;
-import org.sonar.api.web.ServletFilter;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.api.web.HttpFilter;
 
 import static com.google.common.base.Strings.isNullOrEmpty;
 import static java.lang.String.format;
 import static org.sonar.server.authentication.AuthenticationError.handleError;
 
-public abstract class AuthenticationFilter extends ServletFilter {
+public abstract class AuthenticationFilter extends HttpFilter {
 
   static final String CALLBACK_PATH = "/oauth2/callback/";
   private final IdentityProviderRepository identityProviderRepository;
 
-  public AuthenticationFilter(IdentityProviderRepository identityProviderRepository) {
+  protected AuthenticationFilter(IdentityProviderRepository identityProviderRepository) {
     this.identityProviderRepository = identityProviderRepository;
   }
 
@@ -43,7 +43,7 @@ public abstract class AuthenticationFilter extends ServletFilter {
    *         case the request is fully handled and caller should not handle it
    */
   @CheckForNull
-  IdentityProvider resolveProviderOrHandleResponse(HttpServletRequest request, HttpServletResponse response, String path) {
+  IdentityProvider resolveProviderOrHandleResponse(HttpRequest request, HttpResponse response, String path) {
     String requestUri = request.getRequestURI();
     String providerKey = extractKeyProvider(requestUri, request.getContextPath() + path);
     if (providerKey == null) {
index 1512ee87fb6b74154438c293d0a32d1008c02dfb..c257c9f4975513198f9d20da9877c31c1d6e5b51 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.server.authentication;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.server.http.HttpResponse;
 
 import static java.lang.String.format;
 import static java.net.URLEncoder.encode;
@@ -43,7 +44,15 @@ public class AuthenticationRedirection {
     }
   }
 
-  public static void redirectTo(HttpServletResponse response, String url) {
+  public static void redirectTo(HttpResponse response, String url) {
+    try {
+      response.sendRedirect(url);
+    } catch (IOException e) {
+      throw new IllegalStateException(format("Fail to redirect to %s", url), e);
+    }
+  }
+
+  static void redirectTo(HttpServletResponse response, String url) {
     try {
       response.sendRedirect(url);
     } catch (IOException e) {
index d6c0b366b652e73d907965f75de0a747a2976834..890c110e0e01873d478c6e682a8c35a5526ccbc1 100644 (file)
@@ -24,8 +24,12 @@ import javax.servlet.http.HttpServletResponse;
 import org.sonar.api.platform.Server;
 import org.sonar.api.server.authentication.BaseIdentityProvider;
 import org.sonar.api.server.authentication.UserIdentity;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.authentication.event.AuthenticationEvent.Source;
+import org.sonar.server.http.JavaxHttpRequest;
+import org.sonar.server.http.JavaxHttpResponse;
 import org.sonar.server.user.ThreadLocalUserSession;
 import org.sonar.server.user.UserSessionFactory;
 
@@ -46,31 +50,41 @@ public class BaseContextFactory {
     this.threadLocalUserSession = threadLocalUserSession;
   }
 
-  public BaseIdentityProvider.Context newContext(HttpServletRequest request, HttpServletResponse response, BaseIdentityProvider identityProvider) {
+  public BaseIdentityProvider.Context newContext(HttpRequest request, HttpResponse response, BaseIdentityProvider identityProvider) {
     return new ContextImpl(request, response, identityProvider);
   }
 
   private class ContextImpl implements BaseIdentityProvider.Context {
-    private final HttpServletRequest request;
-    private final HttpServletResponse response;
+    private final HttpRequest request;
+    private final HttpResponse response;
     private final BaseIdentityProvider identityProvider;
 
-    public ContextImpl(HttpServletRequest request, HttpServletResponse response, BaseIdentityProvider identityProvider) {
+    public ContextImpl(HttpRequest request, HttpResponse response, BaseIdentityProvider identityProvider) {
       this.request = request;
       this.response = response;
       this.identityProvider = identityProvider;
     }
 
     @Override
-    public HttpServletRequest getRequest() {
+    public HttpRequest getHttpRequest() {
       return request;
     }
 
     @Override
-    public HttpServletResponse getResponse() {
+    public HttpResponse getHttpResponse() {
       return response;
     }
 
+    @Override
+    public HttpServletRequest getRequest() {
+      return ((JavaxHttpRequest) request).getDelegate();
+    }
+
+    @Override
+    public HttpServletResponse getResponse() {
+      return ((JavaxHttpResponse) response).getDelegate();
+    }
+
     @Override
     public String getServerBaseURL() {
       return server.getPublicRootUrl();
index c3f6a619e92e24ebd10431adf2bcbaf07e2d726e..e012d8c210b656c0d827c546d9b8e6d9e5dcfa1c 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.server.authentication;
 import java.util.Base64;
 import java.util.Optional;
 import javax.servlet.http.HttpServletRequest;
+import org.sonar.api.server.http.HttpRequest;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.authentication.event.AuthenticationEvent;
 import org.sonar.server.authentication.event.AuthenticationException;
@@ -49,12 +50,12 @@ public class BasicAuthentication {
     this.userTokenAuthentication = userTokenAuthentication;
   }
 
-  public Optional<UserDto> authenticate(HttpServletRequest request) {
+  public Optional<UserDto> authenticate(HttpRequest request) {
     return extractCredentialsFromHeader(request)
       .flatMap(credentials -> Optional.ofNullable(authenticate(credentials, request)));
   }
 
-  public static Optional<Credentials> extractCredentialsFromHeader(HttpServletRequest request) {
+  public static Optional<Credentials> extractCredentialsFromHeader(HttpRequest request) {
     String authorizationHeader = request.getHeader("Authorization");
     if (authorizationHeader == null || !startsWithIgnoreCase(authorizationHeader, "BASIC")) {
       return Optional.empty();
@@ -86,7 +87,7 @@ public class BasicAuthentication {
     }
   }
 
-  private UserDto authenticate(Credentials credentials, HttpServletRequest request) {
+  private UserDto authenticate(Credentials credentials, HttpRequest request) {
     if (credentials.getPassword().isEmpty()) {
       Optional<UserAuthResult> userAuthResult = userTokenAuthentication.authenticate(request);
       if (userAuthResult.isPresent()) {
index 009302b18f0c37fd6b8f373973d24ec250b33190..bc393a722ef6197306e5f7b8009e50bd30dfa131 100644 (file)
@@ -22,8 +22,9 @@ package org.sonar.server.authentication;
 import java.util.Arrays;
 import java.util.Optional;
 import javax.annotation.Nullable;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
+import org.sonar.api.server.http.Cookie;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.server.http.JavaxHttpRequest.JavaxCookie;
 
 import static com.google.common.base.Strings.isNullOrEmpty;
 import static java.util.Objects.requireNonNull;
@@ -44,7 +45,7 @@ public class Cookies {
     // Only static methods
   }
 
-  public static Optional<Cookie> findCookie(String cookieName, HttpServletRequest request) {
+  public static Optional<Cookie> findCookie(String cookieName, HttpRequest request) {
     Cookie[] cookies = request.getCookies();
     if (cookies == null) {
       return Optional.empty();
@@ -54,13 +55,13 @@ public class Cookies {
       .findFirst();
   }
 
-  public static CookieBuilder newCookieBuilder(HttpServletRequest request) {
+  public static CookieBuilder newCookieBuilder(HttpRequest request) {
     return new CookieBuilder(request);
   }
 
   public static class CookieBuilder {
 
-    private final HttpServletRequest request;
+    private final HttpRequest request;
 
     private String name;
     private String value;
@@ -69,7 +70,7 @@ public class Cookies {
 
     private String sameSite;
 
-    CookieBuilder(HttpServletRequest request) {
+    CookieBuilder(HttpRequest request) {
       this.request = request;
     }
 
@@ -114,12 +115,12 @@ public class Cookies {
     }
 
     public Cookie build() {
-      Cookie cookie = new Cookie(requireNonNull(name), value);
+      javax.servlet.http.Cookie cookie = new javax.servlet.http.Cookie(requireNonNull(name), value);
       cookie.setPath(getContextPath(request));
       cookie.setSecure(isHttps(request));
       cookie.setHttpOnly(httpOnly);
       cookie.setMaxAge(expiry);
-      return cookie;
+      return new JavaxCookie(cookie);
     }
 
     public String toValueString() {
@@ -133,11 +134,11 @@ public class Cookies {
       return output;
     }
 
-    private static boolean isHttps(HttpServletRequest request) {
+    private static boolean isHttps(HttpRequest request) {
       return HTTPS_VALUE.equalsIgnoreCase(request.getHeader(HTTPS_HEADER));
     }
 
-    private static String getContextPath(HttpServletRequest request) {
+    private static String getContextPath(HttpRequest request) {
       String path = request.getContextPath();
       return isNullOrEmpty(path) ? "/" : path;
     }
index 34d6768cab9ebebe35140dec578de21c39397c71..8f0f98c2c2ef4027a91a98b02a50602a867813b4 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.server.authentication;
 
 import java.util.Optional;
 import javax.servlet.http.HttpServletRequest;
+import org.sonar.api.server.http.HttpRequest;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.user.UserDto;
@@ -52,13 +53,13 @@ public class CredentialsAuthentication {
     this.ldapCredentialsAuthentication = ldapCredentialsAuthentication;
   }
 
-  public UserDto authenticate(Credentials credentials, HttpServletRequest request, Method method) {
+  public UserDto authenticate(Credentials credentials, HttpRequest request, Method method) {
     try (DbSession dbSession = dbClient.openSession(false)) {
       return authenticate(dbSession, credentials, request, method);
     }
   }
 
-  private UserDto authenticate(DbSession dbSession, Credentials credentials, HttpServletRequest request, Method method) {
+  private UserDto authenticate(DbSession dbSession, Credentials credentials, HttpRequest request, Method method) {
     UserDto localUser = dbClient.userDao().selectActiveUserByLogin(dbSession, credentials.getLogin());
     if (localUser != null && localUser.isLocal()) {
       String password = getNonNullPassword(credentials);
index fe39adf964ddaa96ee5ba8ddeba5e1e1d3cf12f5..e78c5e6c9ff092839b8fec04b934c6bf94436c91 100644 (file)
@@ -24,6 +24,8 @@ import java.util.HashSet;
 import java.util.Locale;
 import java.util.Optional;
 import javax.servlet.http.HttpServletRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.sonar.api.Startable;
 import org.sonar.api.config.Configuration;
 import org.sonar.api.security.Authenticator;
@@ -34,12 +36,12 @@ import org.sonar.api.security.UserDetails;
 import org.sonar.api.server.authentication.Display;
 import org.sonar.api.server.authentication.IdentityProvider;
 import org.sonar.api.server.authentication.UserIdentity;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
+import org.sonar.api.server.http.HttpRequest;
 import org.sonar.db.user.UserDto;
 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.http.JavaxHttpRequest;
 import org.sonar.server.user.SecurityRealmFactory;
 
 import static java.util.Objects.requireNonNull;
@@ -52,7 +54,7 @@ import static org.sonar.server.user.ExternalIdentity.SQ_AUTHORITY;
  */
 public class CredentialsExternalAuthentication implements Startable {
 
-  private static final Logger LOG = Loggers.get(CredentialsExternalAuthentication.class);
+  private static final Logger LOG = LoggerFactory.getLogger(CredentialsExternalAuthentication.class);
 
   private final Configuration config;
   private final SecurityRealmFactory securityRealmFactory;
@@ -82,16 +84,17 @@ public class CredentialsExternalAuthentication implements Startable {
     }
   }
 
-  public Optional<UserDto> authenticate(Credentials credentials, HttpServletRequest request, AuthenticationEvent.Method method) {
+  public Optional<UserDto> authenticate(Credentials credentials, HttpRequest request, AuthenticationEvent.Method method) {
     if (realm == null) {
       return Optional.empty();
     }
     return Optional.of(doAuthenticate(fixCase(credentials), request, method));
   }
 
-  private UserDto doAuthenticate(Credentials credentials, HttpServletRequest request, AuthenticationEvent.Method method) {
+  private UserDto doAuthenticate(Credentials credentials, HttpRequest request, AuthenticationEvent.Method method) {
     try {
-      ExternalUsersProvider.Context externalUsersProviderContext = new ExternalUsersProvider.Context(credentials.getLogin(), request);
+      HttpServletRequest httpServletRequest = ((JavaxHttpRequest) request).getDelegate();
+      ExternalUsersProvider.Context externalUsersProviderContext = new ExternalUsersProvider.Context(credentials.getLogin(), request, httpServletRequest);
       UserDetails details = externalUsersProvider.doGetUserDetails(externalUsersProviderContext);
       if (details == null) {
         throw AuthenticationException.newBuilder()
@@ -100,7 +103,8 @@ public class CredentialsExternalAuthentication implements Startable {
           .setMessage("No user details")
           .build();
       }
-      Authenticator.Context authenticatorContext = new Authenticator.Context(credentials.getLogin(), credentials.getPassword().orElse(null), request);
+
+      Authenticator.Context authenticatorContext = new Authenticator.Context(credentials.getLogin(), credentials.getPassword().orElse(null), request, httpServletRequest);
       boolean status = authenticator.doAuthenticate(authenticatorContext);
       if (!status) {
         throw AuthenticationException.newBuilder()
@@ -129,14 +133,15 @@ public class CredentialsExternalAuthentication implements Startable {
     return Source.realm(method, realm.getName());
   }
 
-  private UserDto synchronize(String userLogin, UserDetails details, HttpServletRequest request, AuthenticationEvent.Method method) {
+  private UserDto synchronize(String userLogin, UserDetails details, HttpRequest request, AuthenticationEvent.Method method) {
     String name = details.getName();
     UserIdentity.Builder userIdentityBuilder = UserIdentity.builder()
       .setName(isEmpty(name) ? userLogin : name)
       .setEmail(trimToNull(details.getEmail()))
       .setProviderLogin(userLogin);
     if (externalGroupsProvider != null) {
-      ExternalGroupsProvider.Context context = new ExternalGroupsProvider.Context(userLogin, request);
+      HttpServletRequest httpServletRequest = ((JavaxHttpRequest) request).getDelegate();
+      ExternalGroupsProvider.Context context = new ExternalGroupsProvider.Context(userLogin, request, httpServletRequest);
       Collection<String> groups = externalGroupsProvider.doGetGroups(context);
       userIdentityBuilder.setGroups(new HashSet<>(groups));
     }
index 8c26397300fe20b670cbe405903ca06b55b96e6a..d551292c3b08a3b2ffbc460af2fd0ed64a5cbcd8 100644 (file)
@@ -21,21 +21,18 @@ package org.sonar.server.authentication;
 
 import java.io.IOException;
 import java.util.Set;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.sonar.api.config.Configuration;
-import org.sonar.api.web.ServletFilter;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.HttpFilter;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.server.user.ThreadLocalUserSession;
 
-import static org.sonar.api.web.ServletFilter.UrlPattern.Builder.staticResourcePatterns;
+import static org.sonar.api.web.UrlPattern.Builder.staticResourcePatterns;
 import static org.sonar.server.authentication.AuthenticationRedirection.redirectTo;
 
-public class DefaultAdminCredentialsVerifierFilter extends ServletFilter {
+public class DefaultAdminCredentialsVerifierFilter extends HttpFilter {
   private static final String RESET_PASSWORD_PATH = "/account/reset_password";
   private static final String CHANGE_ADMIN_PASSWORD_PATH = "/admin/change_admin_password";
   // This property is used by Orchestrator to disable this force redirect. It should never be used in production, which
@@ -67,14 +64,12 @@ public class DefaultAdminCredentialsVerifierFilter extends ServletFilter {
   }
 
   @Override
-  public void init(FilterConfig filterConfig) {
+  public void init() {
     // nothing to do
   }
 
   @Override
-  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
-    HttpServletRequest request = (HttpServletRequest) servletRequest;
-    HttpServletResponse response = (HttpServletResponse) servletResponse;
+  public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) throws IOException {
     boolean forceRedirect = config
       .getBoolean(SONAR_FORCE_REDIRECT_DEFAULT_ADMIN_CREDENTIALS)
       .orElse(true);
index dcd6fb19850dbaa2296f1e4edbaf3efa980840fc..d64279bd806fe2bfc09918d8bb55fc2057854666 100644 (file)
@@ -22,11 +22,11 @@ package org.sonar.server.authentication;
 import com.google.common.annotations.VisibleForTesting;
 import java.security.MessageDigest;
 import java.util.Optional;
-import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.codec.digest.HmacAlgorithms;
 import org.apache.commons.codec.digest.HmacUtils;
 import org.sonar.api.config.internal.Encryption;
 import org.sonar.api.config.internal.Settings;
+import org.sonar.api.server.http.HttpRequest;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 import org.sonar.db.DbClient;
@@ -77,7 +77,7 @@ public class GithubWebhookAuthentication {
     this.encryption = settings.getEncryption();
   }
 
-  public Optional<UserAuthResult> authenticate(HttpServletRequest request) {
+  public Optional<UserAuthResult> authenticate(HttpRequest request) {
     String githubAppId = request.getHeader(GITHUB_APP_ID_HEADER);
     if (isEmpty(githubAppId)) {
       return Optional.empty();
@@ -94,7 +94,7 @@ public class GithubWebhookAuthentication {
     return createAuthResult(request);
   }
 
-  private static String getGithubSignature(HttpServletRequest request, String githubAppId) {
+  private static String getGithubSignature(HttpRequest request, String githubAppId) {
     String githubSignature = request.getHeader(GITHUB_SIGNATURE_HEADER);
     if (isEmpty(githubSignature)) {
       logAuthenticationProblemAndThrow(format(MSG_UNAUTHENTICATED_GITHUB_CALLS_DENIED, githubAppId));
@@ -102,7 +102,7 @@ public class GithubWebhookAuthentication {
     return githubSignature;
   }
 
-  private static String getBody(HttpServletRequest request) {
+  private static String getBody(HttpRequest request) {
     try {
       return request.getReader().lines().collect(joining(System.lineSeparator()));
     } catch (Exception e) {
@@ -144,7 +144,7 @@ public class GithubWebhookAuthentication {
     return MessageDigest.isEqual(githubSignature.getBytes(UTF_8), computedSignature.getBytes(UTF_8));
   }
 
-  private Optional<UserAuthResult> createAuthResult(HttpServletRequest request) {
+  private Optional<UserAuthResult> createAuthResult(HttpRequest request) {
     UserAuthResult userAuthResult = UserAuthResult.withGithubWebhook();
     authenticationEvent.loginSuccess(request, GITHUB_WEBHOOK_USER_NAME, AuthenticationEvent.Source.githubWebhook());
     return Optional.of(userAuthResult);
index 30e5a207509caae184f2e1b4fe1b86b70a151475..392c1ab17157ef721e6f67f4941387fa0338bfde 100644 (file)
@@ -29,13 +29,13 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Optional;
 import javax.annotation.CheckForNull;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.sonar.api.Startable;
 import org.sonar.api.config.Configuration;
 import org.sonar.api.server.authentication.Display;
 import org.sonar.api.server.authentication.IdentityProvider;
 import org.sonar.api.server.authentication.UserIdentity;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
@@ -106,7 +106,7 @@ public class HttpHeadersAuthentication implements Startable {
     // Nothing to do
   }
 
-  public Optional<UserDto> authenticate(HttpServletRequest request, HttpServletResponse response) {
+  public Optional<UserDto> authenticate(HttpRequest request, HttpResponse response) {
     try {
       return doAuthenticate(request, response);
     } catch (BadRequestException e) {
@@ -117,7 +117,7 @@ public class HttpHeadersAuthentication implements Startable {
     }
   }
 
-  private Optional<UserDto> doAuthenticate(HttpServletRequest request, HttpServletResponse response) {
+  private Optional<UserDto> doAuthenticate(HttpRequest request, HttpResponse response) {
     if (!enabled) {
       return Optional.empty();
     }
@@ -137,7 +137,7 @@ public class HttpHeadersAuthentication implements Startable {
     return Optional.of(userDto);
   }
 
-  private Optional<UserDto> getUserFromToken(HttpServletRequest request, HttpServletResponse response) {
+  private Optional<UserDto> getUserFromToken(HttpRequest request, HttpResponse response) {
     Optional<JwtHttpHandler.Token> token = jwtHttpHandler.getToken(request, response);
     if (token.isEmpty()) {
       return Optional.empty();
@@ -175,7 +175,7 @@ public class HttpHeadersAuthentication implements Startable {
     return headerValuesByNames.get(settingsByKey.get(settingKey).toLowerCase(Locale.ENGLISH));
   }
 
-  private static Map<String, String> getHeaders(HttpServletRequest request) {
+  private static Map<String, String> getHeaders(HttpRequest request) {
     Map<String, String> headers = new HashMap<>();
     Collections.list(request.getHeaderNames()).forEach(header -> headers.put(header.toLowerCase(Locale.ENGLISH), request.getHeader(header)));
     return headers;
index fe35388cc5bbf2171a67c2a57485b20343cac76f..50b9e4fbe480f80862f6ce0561ae7abfbb8b5392 100644 (file)
  */
 package org.sonar.server.authentication;
 
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.sonar.api.server.authentication.BaseIdentityProvider;
 import org.sonar.api.server.authentication.IdentityProvider;
 import org.sonar.api.server.authentication.OAuth2IdentityProvider;
 import org.sonar.api.server.authentication.UnauthorizedException;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.server.authentication.event.AuthenticationEvent;
 import org.sonar.server.authentication.event.AuthenticationException;
 
@@ -61,17 +59,14 @@ public class InitFilter extends AuthenticationFilter {
   }
 
   @Override
-  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
-    HttpServletRequest httpRequest = (HttpServletRequest) request;
-    HttpServletResponse httpResponse = (HttpServletResponse) response;
-
-    IdentityProvider provider = resolveProviderOrHandleResponse(httpRequest, httpResponse, INIT_CONTEXT);
+  public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) {
+    IdentityProvider provider = resolveProviderOrHandleResponse(request, response, INIT_CONTEXT);
     if (provider != null) {
-      handleProvider(httpRequest, httpResponse, provider);
+      handleProvider(request, response, provider);
     }
   }
 
-  private void handleProvider(HttpServletRequest request, HttpServletResponse response, IdentityProvider provider) {
+  private void handleProvider(HttpRequest request, HttpResponse response, IdentityProvider provider) {
     try {
       if (provider instanceof BaseIdentityProvider baseIdentityProvider) {
         handleBaseIdentityProvider(request, response, baseIdentityProvider);
@@ -91,7 +86,7 @@ public class InitFilter extends AuthenticationFilter {
     }
   }
 
-  private void handleBaseIdentityProvider(HttpServletRequest request, HttpServletResponse response, BaseIdentityProvider provider) {
+  private void handleBaseIdentityProvider(HttpRequest request, HttpResponse response, BaseIdentityProvider provider) {
     try {
       provider.init(baseContextFactory.newContext(request, response, provider));
     } catch (UnauthorizedException e) {
@@ -103,7 +98,7 @@ public class InitFilter extends AuthenticationFilter {
     }
   }
 
-  private void handleOAuth2IdentityProvider(HttpServletRequest request, HttpServletResponse response, OAuth2IdentityProvider provider) {
+  private void handleOAuth2IdentityProvider(HttpRequest request, HttpResponse response, OAuth2IdentityProvider provider) {
     try {
       provider.init(oAuth2ContextFactory.newContext(request, response, provider));
     } catch (UnauthorizedException e) {
@@ -116,7 +111,7 @@ public class InitFilter extends AuthenticationFilter {
   }
 
   @Override
-  public void init(FilterConfig filterConfig) {
+  public void init() {
     // Nothing to do
   }
 
index c8a3edfc6c2a0f8c00829cdbbf00a210c256f095..05e00f772ae893f92060b629bebe2bab97b1b46a 100644 (file)
  */
 package org.sonar.server.authentication;
 
-import com.google.common.collect.ImmutableSet;
 import java.math.BigInteger;
 import java.security.SecureRandom;
 import java.util.Set;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.apache.commons.lang.StringUtils;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.server.authentication.event.AuthenticationException;
 
 import static org.apache.commons.lang.StringUtils.isBlank;
@@ -42,10 +41,10 @@ public class JwtCsrfVerifier {
   private static final String CSRF_STATE_COOKIE = "XSRF-TOKEN";
   private static final String CSRF_HEADER = "X-XSRF-TOKEN";
 
-  private static final Set<String> UPDATE_METHODS = ImmutableSet.of("POST", "PUT", "DELETE");
+  private static final Set<String> UPDATE_METHODS = Set.of("POST", "PUT", "DELETE");
   private static final String API_URL = "/api";
 
-  public String generateState(HttpServletRequest request, HttpServletResponse response, int timeoutInSeconds) {
+  public String generateState(HttpRequest request, HttpResponse response, int timeoutInSeconds) {
     // Create a state token to prevent request forgery.
     // Store it in the cookie for later validation.
     String state = new BigInteger(130, new SecureRandom()).toString(32);
@@ -59,7 +58,7 @@ public class JwtCsrfVerifier {
     return state;
   }
 
-  public void verifyState(HttpServletRequest request, @Nullable String csrfState, @Nullable String login) {
+  public void verifyState(HttpRequest request, @Nullable String csrfState, @Nullable String login) {
     if (!shouldRequestBeChecked(request)) {
       return;
     }
@@ -85,7 +84,7 @@ public class JwtCsrfVerifier {
     return null;
   }
 
-  public void refreshState(HttpServletRequest request, HttpServletResponse response, String csrfState, int timeoutInSeconds) {
+  public void refreshState(HttpRequest request, HttpResponse response, String csrfState, int timeoutInSeconds) {
     response.addHeader(SET_COOKIE,
       newCookieBuilder(request)
         .setName(CSRF_STATE_COOKIE)
@@ -96,11 +95,11 @@ public class JwtCsrfVerifier {
         .toValueString());
   }
 
-  public void removeState(HttpServletRequest request, HttpServletResponse response) {
+  public void removeState(HttpRequest request, HttpResponse response) {
     response.addCookie(newCookieBuilder(request).setName(CSRF_STATE_COOKIE).setValue(null).setHttpOnly(false).setExpiry(0).build());
   }
 
-  private static boolean shouldRequestBeChecked(HttpServletRequest request) {
+  private static boolean shouldRequestBeChecked(HttpRequest request) {
     if (UPDATE_METHODS.contains(request.getMethod())) {
       String path = request.getRequestURI().replaceFirst(request.getContextPath(), "");
       return path.startsWith(API_URL);
index fb89b6d52619c2d014dfe86f3ae7fcb8d9da8bfe..7a7cd16ea29aed0c1e906255e8c77c44626b3a60 100644 (file)
@@ -26,11 +26,11 @@ import java.util.Date;
 import java.util.Map;
 import java.util.Optional;
 import javax.annotation.Nullable;
-import javax.servlet.http.Cookie;
-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.server.http.Cookie;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
@@ -80,7 +80,7 @@ public class JwtHttpHandler {
     this.jwtCsrfVerifier = jwtCsrfVerifier;
   }
 
-  public void generateToken(UserDto user, Map<String, Object> properties, HttpServletRequest request, HttpServletResponse response) {
+  public void generateToken(UserDto user, Map<String, Object> properties, HttpRequest request, HttpResponse response) {
     String csrfState = jwtCsrfVerifier.generateState(request, response, sessionTimeoutInSeconds);
     long expirationTime = system2.now() + sessionTimeoutInSeconds * 1000L;
     SessionTokenDto sessionToken = createSessionToken(user, expirationTime);
@@ -108,16 +108,16 @@ public class JwtHttpHandler {
     }
   }
 
-  public void generateToken(UserDto user, HttpServletRequest request, HttpServletResponse response) {
+  public void generateToken(UserDto user, HttpRequest request, HttpResponse response) {
     generateToken(user, Collections.emptyMap(), request, response);
   }
 
-  public Optional<UserDto> validateToken(HttpServletRequest request, HttpServletResponse response) {
+  public Optional<UserDto> validateToken(HttpRequest request, HttpResponse response) {
     Optional<Token> token = getToken(request, response);
     return token.map(Token::getUserDto);
   }
 
-  public Optional<Token> getToken(HttpServletRequest request, HttpServletResponse response) {
+  public Optional<Token> getToken(HttpRequest request, HttpResponse response) {
     Optional<String> encodedToken = getTokenFromCookie(request);
     if (!encodedToken.isPresent()) {
       return Optional.empty();
@@ -127,9 +127,9 @@ public class JwtHttpHandler {
     }
   }
 
-  private static Optional<String> getTokenFromCookie(HttpServletRequest request) {
+  private static Optional<String> getTokenFromCookie(HttpRequest request) {
     Optional<Cookie> jwtCookie = findCookie(JWT_COOKIE, request);
-    if (!jwtCookie.isPresent()) {
+    if (jwtCookie.isEmpty()) {
       return Optional.empty();
     }
     Cookie cookie = jwtCookie.get();
@@ -140,15 +140,15 @@ public class JwtHttpHandler {
     return Optional.of(token);
   }
 
-  private Optional<Token> validateToken(DbSession dbSession, String tokenEncoded, HttpServletRequest request, HttpServletResponse response) {
+  private Optional<Token> validateToken(DbSession dbSession, String tokenEncoded, HttpRequest request, HttpResponse response) {
     Optional<Claims> claims = jwtSerializer.decode(tokenEncoded);
-    if (!claims.isPresent()) {
+    if (claims.isEmpty()) {
       return Optional.empty();
     }
     Claims token = claims.get();
 
     Optional<SessionTokenDto> sessionToken = dbClient.sessionTokensDao().selectByUuid(dbSession, token.getId());
-    if (!sessionToken.isPresent()) {
+    if (sessionToken.isEmpty()) {
       return Optional.empty();
     }
     // Check on expiration is already done when decoding the JWT token, but here is done a double check with the expiration date from DB.
@@ -175,7 +175,7 @@ public class JwtHttpHandler {
     return new Date(lastFreshTime);
   }
 
-  private void refreshToken(DbSession dbSession, SessionTokenDto tokenFromDb, Claims tokenFromCookie, HttpServletRequest request, HttpServletResponse response) {
+  private void refreshToken(DbSession dbSession, SessionTokenDto tokenFromDb, Claims tokenFromCookie, HttpRequest request, HttpResponse response) {
     long expirationTime = system2.now() + sessionTimeoutInSeconds * 1000L;
     String refreshToken = jwtSerializer.refresh(tokenFromCookie, expirationTime);
     response.addHeader(SET_COOKIE, createJwtSession(request, JWT_COOKIE, refreshToken, sessionTimeoutInSeconds));
@@ -185,13 +185,13 @@ public class JwtHttpHandler {
     dbSession.commit();
   }
 
-  public void removeToken(HttpServletRequest request, HttpServletResponse response) {
+  public void removeToken(HttpRequest request, HttpResponse response) {
     removeSessionToken(request);
     response.addCookie(createCookie(request, JWT_COOKIE, null, 0));
     jwtCsrfVerifier.removeState(request, response);
   }
 
-  private void removeSessionToken(HttpServletRequest request) {
+  private void removeSessionToken(HttpRequest request) {
     Optional<Cookie> jwtCookie = findCookie(JWT_COOKIE, request);
     if (!jwtCookie.isPresent()) {
       return;
@@ -206,11 +206,11 @@ public class JwtHttpHandler {
     }
   }
 
-  private static Cookie createCookie(HttpServletRequest request, String name, @Nullable String value, int expirationInSeconds) {
+  private static Cookie createCookie(HttpRequest request, String name, @Nullable String value, int expirationInSeconds) {
     return newCookieBuilder(request).setName(name).setValue(value).setHttpOnly(true).setExpiry(expirationInSeconds).build();
   }
 
-  private static String createJwtSession(HttpServletRequest request, String name, @Nullable String value, int expirationInSeconds) {
+  private static String createJwtSession(HttpRequest request, String name, @Nullable String value, int expirationInSeconds) {
     return newCookieBuilder(request).setName(name).setValue(value).setHttpOnly(true).setExpiry(expirationInSeconds).setSameSite(SAMESITE_LAX).toValueString();
   }
 
index 7278efdd6a60755d59b34f26e247f774254f3e3f..371d40741b3b46a5905cb800e4c640b1b7eb10be 100644 (file)
@@ -23,11 +23,11 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.Locale;
 import java.util.Optional;
-import javax.servlet.http.HttpServletRequest;
 import org.sonar.api.config.Configuration;
 import org.sonar.api.server.authentication.Display;
 import org.sonar.api.server.authentication.IdentityProvider;
 import org.sonar.api.server.authentication.UserIdentity;
+import org.sonar.api.server.http.HttpRequest;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 import org.sonar.auth.ldap.LdapAuthenticationResult;
@@ -69,14 +69,14 @@ public class LdapCredentialsAuthentication {
     this.ldapGroupsProvider = ldapRealm.getGroupsProvider();
   }
 
-  public Optional<UserDto> authenticate(Credentials credentials, HttpServletRequest request, AuthenticationEvent.Method method) {
+  public Optional<UserDto> authenticate(Credentials credentials, HttpRequest request, AuthenticationEvent.Method method) {
     if (isLdapAuthActivated) {
       return Optional.of(doAuthenticate(fixCase(credentials), request, method));
     }
     return Optional.empty();
   }
 
-  private UserDto doAuthenticate(Credentials credentials, HttpServletRequest request, AuthenticationEvent.Method method) {
+  private UserDto doAuthenticate(Credentials credentials, HttpRequest request, AuthenticationEvent.Method method) {
     try {
       LdapAuthenticator.Context ldapAuthenticatorContext = new LdapAuthenticator.Context(credentials.getLogin(), credentials.getPassword().orElse(null), request);
       LdapAuthenticationResult authenticationResult = ldapAuthenticator.doAuthenticate(ldapAuthenticatorContext);
@@ -117,7 +117,7 @@ public class LdapCredentialsAuthentication {
     return Source.realm(method, "ldap");
   }
 
-  private UserDto synchronize(String userLogin, String serverKey, LdapUserDetails userDetails, HttpServletRequest request, AuthenticationEvent.Method method) {
+  private UserDto synchronize(String userLogin, String serverKey, LdapUserDetails userDetails, HttpRequest request, AuthenticationEvent.Method method) {
     String name = userDetails.getName();
     UserIdentity.Builder userIdentityBuilder = UserIdentity.builder()
       .setName(isEmpty(name) ? userLogin : name)
index fbff32ebeb5b108349800c44fcd462be2187dc89..9600183b65cae62d2906fd75c30093c9df9c2fd3 100644 (file)
@@ -21,9 +21,9 @@ package org.sonar.server.authentication;
 
 import java.util.Optional;
 import javax.servlet.FilterConfig;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.sonar.api.server.authentication.OAuth2IdentityProvider;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 
 /**
  * This class is used to store some parameters during the OAuth2 authentication process, by using a cookie.
@@ -33,10 +33,10 @@ import org.sonar.api.server.authentication.OAuth2IdentityProvider;
  */
 public interface OAuth2AuthenticationParameters {
 
-  void init(HttpServletRequest request, HttpServletResponse response);
+  void init(HttpRequest request, HttpResponse response);
 
-  Optional<String> getReturnTo(HttpServletRequest request);
+  Optional<String> getReturnTo(HttpRequest request);
 
-  void delete(HttpServletRequest request, HttpServletResponse response);
+  void delete(HttpRequest request, HttpResponse response);
 
 }
index 27fc6955cb218732146ee0c8751a7fb2a858569e..bfaceb6de0549d0c6e110b9949daf081d0022922 100644 (file)
@@ -30,8 +30,9 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.regex.Pattern;
 import javax.annotation.Nullable;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.server.http.Cookie;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 
 import static java.net.URLDecoder.decode;
 import static java.nio.charset.StandardCharsets.UTF_8;
@@ -56,7 +57,7 @@ public class OAuth2AuthenticationParametersImpl implements OAuth2AuthenticationP
   }.getType();
 
   @Override
-  public void init(HttpServletRequest request, HttpServletResponse response) {
+  public void init(HttpRequest request, HttpResponse response) {
     String returnTo = request.getParameter(RETURN_TO_PARAMETER);
     Map<String, String> parameters = new HashMap<>();
     Optional<String> sanitizeRedirectUrl = sanitizeRedirectUrl(returnTo);
@@ -73,14 +74,14 @@ public class OAuth2AuthenticationParametersImpl implements OAuth2AuthenticationP
   }
 
   @Override
-  public Optional<String> getReturnTo(HttpServletRequest request) {
+  public Optional<String> getReturnTo(HttpRequest request) {
     return getParameter(request, RETURN_TO_PARAMETER)
       .flatMap(OAuth2AuthenticationParametersImpl::sanitizeRedirectUrl);
   }
 
-  private static Optional<String> getParameter(HttpServletRequest request, String parameterKey) {
-    Optional<javax.servlet.http.Cookie> cookie = findCookie(AUTHENTICATION_COOKIE_NAME, request);
-    if (!cookie.isPresent()) {
+  private static Optional<String> getParameter(HttpRequest request, String parameterKey) {
+    Optional<Cookie> cookie = findCookie(AUTHENTICATION_COOKIE_NAME, request);
+    if (cookie.isEmpty()) {
       return empty();
     }
 
@@ -92,7 +93,7 @@ public class OAuth2AuthenticationParametersImpl implements OAuth2AuthenticationP
   }
 
   @Override
-  public void delete(HttpServletRequest request, HttpServletResponse response) {
+  public void delete(HttpRequest request, HttpResponse response) {
     response.addCookie(newCookieBuilder(request)
       .setName(AUTHENTICATION_COOKIE_NAME)
       .setValue(null)
index c3b5a664073bb29de83327beb5790938e73b157a..6717fd026673b43232e96ac4969a07330497f373 100644 (file)
  */
 package org.sonar.server.authentication;
 
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.sonar.api.server.authentication.IdentityProvider;
 import org.sonar.api.server.authentication.OAuth2IdentityProvider;
 import org.sonar.api.server.authentication.UnauthorizedException;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.server.authentication.event.AuthenticationEvent;
 import org.sonar.server.authentication.event.AuthenticationException;
 import org.sonar.server.user.ThreadLocalUserSession;
@@ -59,20 +57,17 @@ public class OAuth2CallbackFilter extends AuthenticationFilter {
   }
 
   @Override
-  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
-    HttpServletRequest httpRequest = (HttpServletRequest) request;
-    HttpServletResponse httpResponse = (HttpServletResponse) response;
-
-    IdentityProvider provider = resolveProviderOrHandleResponse(httpRequest, httpResponse, CALLBACK_PATH);
+  public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) {
+    IdentityProvider provider = resolveProviderOrHandleResponse(request, response, CALLBACK_PATH);
     if (provider != null) {
-      handleProvider(httpRequest, (HttpServletResponse) response, provider);
+      handleProvider(request, response, provider);
     }
   }
 
-  private void handleProvider(HttpServletRequest request, HttpServletResponse response, IdentityProvider provider) {
+  private void handleProvider(HttpRequest request, HttpResponse response, IdentityProvider provider) {
     try {
       if (provider instanceof OAuth2IdentityProvider oAuth2IdentityProvider) {
-        handleOAuth2Provider(response, request, oAuth2IdentityProvider);
+        handleOAuth2Provider(request, response, oAuth2IdentityProvider);
       } else {
         handleError(request, response, format("Not an OAuth2IdentityProvider: %s", provider.getClass()));
       }
@@ -86,8 +81,8 @@ public class OAuth2CallbackFilter extends AuthenticationFilter {
     }
   }
 
-  private void handleOAuth2Provider(HttpServletResponse response, HttpServletRequest httpRequest, OAuth2IdentityProvider oAuth2Provider) {
-    OAuth2IdentityProvider.CallbackContext context = oAuth2ContextFactory.newCallback(httpRequest, response, oAuth2Provider);
+  private void handleOAuth2Provider(HttpRequest request, HttpResponse response, OAuth2IdentityProvider oAuth2Provider) {
+    OAuth2IdentityProvider.CallbackContext context = oAuth2ContextFactory.newCallback(request, response, oAuth2Provider);
     try {
       oAuth2Provider.callback(context);
     } catch (UnauthorizedException e) {
@@ -98,7 +93,7 @@ public class OAuth2CallbackFilter extends AuthenticationFilter {
         .build();
     }
     if (threadLocalUserSession.hasSession()) {
-      authenticationEvent.loginSuccess(httpRequest, threadLocalUserSession.getLogin(), Source.oauth2(oAuth2Provider));
+      authenticationEvent.loginSuccess(request, threadLocalUserSession.getLogin(), Source.oauth2(oAuth2Provider));
     } else {
       throw AuthenticationException.newBuilder()
         .setSource(Source.oauth2(oAuth2Provider))
@@ -108,7 +103,7 @@ public class OAuth2CallbackFilter extends AuthenticationFilter {
   }
 
   @Override
-  public void init(FilterConfig filterConfig) {
+  public void init() {
     // Nothing to do
   }
 
index 4c952ddcacdb4c19aed3cece28c6b4d3b32df06c..7fc0db4073c56142383574fd5da0f243696cbee4 100644 (file)
@@ -28,8 +28,12 @@ import org.sonar.api.platform.Server;
 import org.sonar.api.server.ServerSide;
 import org.sonar.api.server.authentication.OAuth2IdentityProvider;
 import org.sonar.api.server.authentication.UserIdentity;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.authentication.event.AuthenticationEvent;
+import org.sonar.server.http.JavaxHttpRequest;
+import org.sonar.server.http.JavaxHttpResponse;
 import org.sonar.server.user.ThreadLocalUserSession;
 import org.sonar.server.user.UserSessionFactory;
 
@@ -58,11 +62,11 @@ public class OAuth2ContextFactory {
     this.oAuthParameters = oAuthParameters;
   }
 
-  public OAuth2IdentityProvider.InitContext newContext(HttpServletRequest request, HttpServletResponse response, OAuth2IdentityProvider identityProvider) {
+  public OAuth2IdentityProvider.InitContext newContext(HttpRequest request, HttpResponse response, OAuth2IdentityProvider identityProvider) {
     return new OAuthContextImpl(request, response, identityProvider);
   }
 
-  public OAuth2IdentityProvider.CallbackContext newCallback(HttpServletRequest request, HttpServletResponse response, OAuth2IdentityProvider identityProvider) {
+  public OAuth2IdentityProvider.CallbackContext newCallback(HttpRequest request, HttpResponse response, OAuth2IdentityProvider identityProvider) {
     return new OAuthContextImpl(request, response, identityProvider);
   }
 
@@ -73,11 +77,11 @@ public class OAuth2ContextFactory {
 
   public class OAuthContextImpl implements OAuth2IdentityProvider.InitContext, OAuth2IdentityProvider.CallbackContext {
 
-    private final HttpServletRequest request;
-    private final HttpServletResponse response;
+    private final HttpRequest request;
+    private final HttpResponse response;
     private final OAuth2IdentityProvider identityProvider;
 
-    public OAuthContextImpl(HttpServletRequest request, HttpServletResponse response, OAuth2IdentityProvider identityProvider) {
+    public OAuthContextImpl(HttpRequest request, HttpResponse response, OAuth2IdentityProvider identityProvider) {
       this.request = request;
       this.response = response;
       this.identityProvider = identityProvider;
@@ -94,15 +98,25 @@ public class OAuth2ContextFactory {
     }
 
     @Override
-    public HttpServletRequest getRequest() {
+    public HttpRequest getHttpRequest() {
       return request;
     }
 
     @Override
-    public HttpServletResponse getResponse() {
+    public HttpResponse getHttpResponse() {
       return response;
     }
 
+    @Override
+    public HttpServletRequest getRequest() {
+      return ((JavaxHttpRequest) request).getDelegate();
+    }
+
+    @Override
+    public HttpServletResponse getResponse() {
+      return ((JavaxHttpResponse) response).getDelegate();
+    }
+
     @Override
     public void redirectTo(String url) {
       try {
@@ -127,7 +141,7 @@ public class OAuth2ContextFactory {
       try {
         Optional<String> redirectTo = oAuthParameters.getReturnTo(request);
         oAuthParameters.delete(request, response);
-        getResponse().sendRedirect(redirectTo.orElse(server.getContextPath() + "/"));
+        getHttpResponse().sendRedirect(redirectTo.orElse(server.getContextPath() + "/"));
       } catch (IOException e) {
         throw new IllegalStateException("Fail to redirect to requested page", e);
       }
index a7acad8720fd63e022dcec0a692def42c2c82814..3f4732a26fb06ccd17f43d3f82b6f0f79fc900e6 100644 (file)
@@ -21,10 +21,10 @@ package org.sonar.server.authentication;
 
 import java.math.BigInteger;
 import java.security.SecureRandom;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.sonar.api.server.authentication.OAuth2IdentityProvider;
+import org.sonar.api.server.http.Cookie;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.server.authentication.event.AuthenticationException;
 
 import static java.lang.String.format;
@@ -39,7 +39,7 @@ public class OAuthCsrfVerifier {
   private static final String CSRF_STATE_COOKIE = "OAUTHSTATE";
   private static final String DEFAULT_STATE_PARAMETER_NAME = "state";
 
-  public String generateState(HttpServletRequest request, HttpServletResponse response) {
+  public String generateState(HttpRequest request, HttpResponse response) {
     // Create a state token to prevent request forgery.
     // Store it in the session for later validation.
     String state = new BigInteger(130, new SecureRandom()).toString(32);
@@ -47,11 +47,11 @@ public class OAuthCsrfVerifier {
     return state;
   }
 
-  public void verifyState(HttpServletRequest request, HttpServletResponse response, OAuth2IdentityProvider provider) {
+  public void verifyState(HttpRequest request, HttpResponse response, OAuth2IdentityProvider provider) {
     verifyState(request, response, provider, DEFAULT_STATE_PARAMETER_NAME);
   }
 
-  public void verifyState(HttpServletRequest request, HttpServletResponse response, OAuth2IdentityProvider provider, String parameterName) {
+  public void verifyState(HttpRequest request, HttpResponse response, OAuth2IdentityProvider provider, String parameterName) {
     Cookie cookie = findCookie(CSRF_STATE_COOKIE, request)
       .orElseThrow(AuthenticationException.newBuilder()
         .setSource(Source.oauth2(provider))
index edba46fc8a20b1d3bb11abd22f82c919b1f646f3..235873c9f288bcda46e8ef3ed640730629772c5d 100644 (file)
@@ -19,9 +19,9 @@
  */
 package org.sonar.server.authentication;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.sonar.api.server.ServerSide;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.server.user.UserSession;
 
 @ServerSide
@@ -30,6 +30,6 @@ public interface RequestAuthenticator {
   /**
    * @throws org.sonar.server.authentication.event.AuthenticationException if user is not authenticated
    */
-  UserSession authenticate(HttpServletRequest request, HttpServletResponse response);
+  UserSession authenticate(HttpRequest request, HttpResponse response);
 
 }
index b74f1631c39b090078a646358f9e45901c7f515e..861c14d6d0b10858d5e1c5ab4ef9626458877686 100644 (file)
@@ -20,8 +20,8 @@
 package org.sonar.server.authentication;
 
 import java.util.function.Function;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.user.UserSession;
 import org.sonar.server.user.UserSessionFactory;
@@ -64,7 +64,7 @@ public class RequestAuthenticatorImpl implements RequestAuthenticator {
   }
 
   @Override
-  public UserSession authenticate(HttpServletRequest request, HttpServletResponse response) {
+  public UserSession authenticate(HttpRequest request, HttpResponse response) {
     UserAuthResult userAuthResult = loadUser(request, response);
     if (nonNull(userAuthResult.getUserDto())) {
       if (TOKEN.equals(userAuthResult.getAuthType())) {
@@ -77,7 +77,7 @@ public class RequestAuthenticatorImpl implements RequestAuthenticator {
     return userSessionFactory.createAnonymous();
   }
 
-  private UserAuthResult loadUser(HttpServletRequest request, HttpServletResponse response) {
+  private UserAuthResult loadUser(HttpRequest request, HttpResponse response) {
     Function<UserAuthResult.AuthType, Function<UserDto, UserAuthResult>> createUserAuthResult = type -> userDto -> new UserAuthResult(userDto, type);
     // SSO authentication should come first in order to update JWT if user from header is not the same is user from JWT
     return httpHeadersAuthentication.authenticate(request, response).map(createUserAuthResult.apply(SSO))
index 311c93d5b0e4701163d5ca5a043b0e687bdb3a55..68f494d988dee69b955c45cfdfdeb3ba8a89e093 100644 (file)
@@ -21,20 +21,17 @@ package org.sonar.server.authentication;
 
 import java.io.IOException;
 import java.util.Set;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.sonar.api.web.ServletFilter;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.HttpFilter;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.server.user.ThreadLocalUserSession;
 
-import static org.sonar.api.web.ServletFilter.UrlPattern.Builder.staticResourcePatterns;
+import static org.sonar.api.web.UrlPattern.Builder.staticResourcePatterns;
 import static org.sonar.server.authentication.AuthenticationRedirection.redirectTo;
 
-public class ResetPasswordFilter extends ServletFilter {
+public class ResetPasswordFilter extends HttpFilter {
   private static final String RESET_PASSWORD_PATH = "/account/reset_password";
 
   private static final Set<String> SKIPPED_URLS = Set.of(
@@ -57,15 +54,12 @@ public class ResetPasswordFilter extends ServletFilter {
   }
 
   @Override
-  public void init(FilterConfig filterConfig) {
+  public void init() {
     // nothing to do
   }
 
   @Override
-  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
-    HttpServletRequest request = (HttpServletRequest) servletRequest;
-    HttpServletResponse response = (HttpServletResponse) servletResponse;
-
+  public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) throws IOException {
     if (userSession.hasSession() && userSession.isLoggedIn() && userSession.shouldResetPassword()) {
       redirectTo(response, request.getContextPath() + RESET_PASSWORD_PATH);
     }
index 863449a733a10d40006acff6edd78da83d2f2270..8f96b039e7a6be7232895a80ff39d9e0b87460d4 100644 (file)
@@ -23,6 +23,7 @@ import java.math.BigInteger;
 import java.security.SecureRandom;
 import java.util.List;
 import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.server.http.HttpResponse;
 
 public class SamlValidationCspHeaders {
 
@@ -30,7 +31,7 @@ public class SamlValidationCspHeaders {
     throw new IllegalStateException("Utility class, cannot be instantiated");
   }
 
-  public static String addCspHeadersWithNonceToResponse(HttpServletResponse httpResponse) {
+  public static String addCspHeadersWithNonceToResponse(HttpResponse httpResponse) {
     final String nonce = getNonce();
 
     List<String> cspPolicies = List.of(
index a0d9e55b326b4a63bd7f4138f49d91bc7ee45598..4f150a64db8a7b71dd7a198f1ceb7f65cff5cac4 100644 (file)
@@ -25,20 +25,18 @@ import java.net.URI;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import javax.annotation.Nullable;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletResponse;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.internal.apachecommons.lang.StringEscapeUtils;
 import org.sonar.api.platform.Server;
-import org.sonar.api.web.ServletFilter;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.HttpFilter;
+import org.sonar.api.web.UrlPattern;
 
 import static org.sonar.server.authentication.AuthenticationFilter.CALLBACK_PATH;
 
-public class SamlValidationRedirectionFilter extends ServletFilter {
+public class SamlValidationRedirectionFilter extends HttpFilter {
 
   public static final String VALIDATION_RELAY_STATE = "validation-query";
   public static final String SAML_VALIDATION_CONTROLLER_CONTEXT = "saml";
@@ -58,8 +56,7 @@ public class SamlValidationRedirectionFilter extends ServletFilter {
   }
 
   @Override
-  public void init(FilterConfig filterConfig) throws ServletException {
-    super.init(filterConfig);
+  public void init() {
     this.redirectionPageTemplate = extractTemplate("validation-redirection.html");
   }
 
@@ -73,27 +70,25 @@ public class SamlValidationRedirectionFilter extends ServletFilter {
   }
 
   @Override
-  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+  public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) throws IOException {
     String relayState = request.getParameter(RELAY_STATE_PARAMETER);
 
     if (isSamlValidation(relayState)) {
 
-      HttpServletResponse httpResponse = (HttpServletResponse) response;
-
       URI redirectionEndpointUrl = URI.create(server.getContextPath() + "/")
         .resolve(SAML_VALIDATION_CONTROLLER_CONTEXT + "/")
         .resolve(SAML_VALIDATION_KEY);
       String samlResponse = StringEscapeUtils.escapeHtml(request.getParameter(SAML_RESPONSE_PARAMETER));
       String csrfToken = getCsrfTokenFromRelayState(relayState);
 
-      String nonce = SamlValidationCspHeaders.addCspHeadersWithNonceToResponse(httpResponse);
+      String nonce = SamlValidationCspHeaders.addCspHeadersWithNonceToResponse(response);
 
       String template = StringUtils.replaceEachRepeatedly(redirectionPageTemplate,
         new String[]{"%NONCE%", "%WEB_CONTEXT%", "%VALIDATION_URL%", "%SAML_RESPONSE%", "%CSRF_TOKEN%"},
         new String[]{nonce, server.getContextPath(), redirectionEndpointUrl.toString(), samlResponse, csrfToken});
 
-      httpResponse.setContentType("text/html");
-      httpResponse.getWriter().print(template);
+      response.setContentType("text/html");
+      response.getWriter().print(template);
       return;
     }
     chain.doFilter(request, response);
@@ -112,5 +107,4 @@ public class SamlValidationRedirectionFilter extends ServletFilter {
     }
     return "";
   }
-
 }
index fa6be146e7e508c10a5df641d0cae38783296c37..8a809380a131c9e20a951e761fc4b1cc9b21ce4e 100644 (file)
@@ -21,11 +21,11 @@ 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.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.db.user.UserTokenDto;
 import org.sonar.server.authentication.event.AuthenticationEvent;
 import org.sonar.server.authentication.event.AuthenticationEvent.Source;
@@ -39,7 +39,7 @@ 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.api.web.UrlPattern.Builder.staticResourcePatterns;
 import static org.sonar.server.authentication.AuthenticationError.handleAuthenticationError;
 
 @ServerSide
@@ -97,7 +97,7 @@ public class UserSessionInitializer {
     this.requestAuthenticator = requestAuthenticator;
   }
 
-  public boolean initUserSession(HttpServletRequest request, HttpServletResponse response) {
+  public boolean initUserSession(HttpRequest request, HttpResponse response) {
     String path = request.getRequestURI().replaceFirst(request.getContextPath(), "");
     try {
       // Do not set user session when url is excluded
@@ -126,7 +126,7 @@ public class UserSessionInitializer {
     return provider != AuthenticationEvent.Provider.LOCAL && provider != AuthenticationEvent.Provider.JWT;
   }
 
-  private void loadUserSession(HttpServletRequest request, HttpServletResponse response, boolean urlSupportsSystemPasscode) {
+  private void loadUserSession(HttpRequest request, HttpResponse response, boolean urlSupportsSystemPasscode) {
     UserSession session = requestAuthenticator.authenticate(request, response);
     if (!session.isLoggedIn() && !urlSupportsSystemPasscode && config.getBoolean(CORE_FORCE_AUTHENTICATION_PROPERTY).orElse(CORE_FORCE_AUTHENTICATION_DEFAULT_VALUE)) {
       // authentication is required
@@ -140,7 +140,7 @@ public class UserSessionInitializer {
     request.setAttribute(ACCESS_LOG_LOGIN, defaultString(session.getLogin(), "-"));
   }
 
-  private static void checkTokenUserSession(HttpServletResponse response, UserSession session) {
+  private static void checkTokenUserSession(HttpResponse response, UserSession session) {
     if (session instanceof TokenUserSession tokenUserSession) {
       UserTokenDto userTokenDto = tokenUserSession.getUserToken();
       Optional.ofNullable(userTokenDto.getExpirationDate()).ifPresent(expirationDate -> response.addHeader(SQ_AUTHENTICATION_TOKEN_EXPIRATION, formatDateTime(expirationDate)));
index 236132f4076812b27e445db8b6064b32673d0ccf..d64f6525a0187ec1d65fca55af1fa252eff386cc 100644 (file)
@@ -22,23 +22,23 @@ package org.sonar.server.authentication.event;
 import java.io.Serializable;
 import java.util.Objects;
 import javax.annotation.Nullable;
-import javax.servlet.http.HttpServletRequest;
 import org.sonar.api.server.authentication.BaseIdentityProvider;
 import org.sonar.api.server.authentication.IdentityProvider;
 import org.sonar.api.server.authentication.OAuth2IdentityProvider;
+import org.sonar.api.server.http.HttpRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
 public interface AuthenticationEvent {
 
-  void loginSuccess(HttpServletRequest request, @Nullable String login, Source source);
+  void loginSuccess(HttpRequest request, @Nullable String login, Source source);
 
-  void loginFailure(HttpServletRequest request, AuthenticationException e);
+  void loginFailure(HttpRequest request, AuthenticationException e);
 
-  void logoutSuccess(HttpServletRequest request, @Nullable String login);
+  void logoutSuccess(HttpRequest request, @Nullable String login);
 
-  void logoutFailure(HttpServletRequest request, String errorMessage);
+  void logoutFailure(HttpRequest request, String errorMessage);
 
   enum Method {
     /**
index 4cd38806e534ffbdf7619d300e39d56ea98569ea..6000f752b478cb304161f5c6a8da190f9249ab04 100644 (file)
@@ -22,7 +22,7 @@ package org.sonar.server.authentication.event;
 import com.google.common.base.Joiner;
 import java.util.Collections;
 import javax.annotation.Nullable;
-import javax.servlet.http.HttpServletRequest;
+import org.sonar.api.server.http.HttpRequest;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 import org.sonar.core.util.stream.MoreCollectors;
@@ -34,7 +34,7 @@ public class AuthenticationEventImpl implements AuthenticationEvent {
   private static final int FLOOD_THRESHOLD = 128;
 
   @Override
-  public void loginSuccess(HttpServletRequest request, @Nullable String login, Source source) {
+  public void loginSuccess(HttpRequest request, @Nullable String login, Source source) {
     checkRequest(request);
     requireNonNull(source, "source can't be null");
     if (!LOGGER.isDebugEnabled()) {
@@ -46,12 +46,12 @@ public class AuthenticationEventImpl implements AuthenticationEvent {
       preventLogFlood(emptyIfNull(login)));
   }
 
-  private static String getAllIps(HttpServletRequest request) {
+  private static String getAllIps(HttpRequest request) {
     return Collections.list(request.getHeaders("X-Forwarded-For")).stream().collect(MoreCollectors.join(Joiner.on(",")));
   }
 
   @Override
-  public void loginFailure(HttpServletRequest request, AuthenticationException e) {
+  public void loginFailure(HttpRequest request, AuthenticationException e) {
     checkRequest(request);
     requireNonNull(e, "AuthenticationException can't be null");
     if (!LOGGER.isDebugEnabled()) {
@@ -66,7 +66,7 @@ public class AuthenticationEventImpl implements AuthenticationEvent {
   }
 
   @Override
-  public void logoutSuccess(HttpServletRequest request, @Nullable String login) {
+  public void logoutSuccess(HttpRequest request, @Nullable String login) {
     checkRequest(request);
     if (!LOGGER.isDebugEnabled()) {
       return;
@@ -77,7 +77,7 @@ public class AuthenticationEventImpl implements AuthenticationEvent {
   }
 
   @Override
-  public void logoutFailure(HttpServletRequest request, String errorMessage) {
+  public void logoutFailure(HttpRequest request, String errorMessage) {
     checkRequest(request);
     requireNonNull(errorMessage, "error message can't be null");
     if (!LOGGER.isDebugEnabled()) {
@@ -88,7 +88,7 @@ public class AuthenticationEventImpl implements AuthenticationEvent {
       request.getRemoteAddr(), getAllIps(request));
   }
 
-  private static void checkRequest(HttpServletRequest request) {
+  private static void checkRequest(HttpRequest request) {
     requireNonNull(request, "request can't be null");
   }
 
index e86652beb9b545907721a0b2ae963413d61a90a3..8ee0e5e4e7f3f7fc9566c7777414527e47b5cfd7 100644 (file)
@@ -23,6 +23,7 @@ import java.util.Optional;
 import javax.annotation.Nullable;
 import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang.StringUtils;
+import org.sonar.api.server.http.HttpRequest;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.user.UserDto;
@@ -57,13 +58,13 @@ public class UserTokenAuthentication {
     this.authenticationEvent = authenticationEvent;
   }
 
-  public Optional<UserAuthResult> authenticate(HttpServletRequest request) {
+  public Optional<UserAuthResult> authenticate(HttpRequest request) {
     return findBearerToken(request)
       .or(() -> findTokenUsedWithBasicAuthentication(request))
       .map(userAuthResult -> login(request, userAuthResult));
   }
 
-  private static Optional<String> findBearerToken(HttpServletRequest request) {
+  private static Optional<String> findBearerToken(HttpRequest request) {
     // hack necessary as #org.sonar.server.monitoring.MetricsAction and org.sonar.server.platform.ws.SafeModeMonitoringMetricAction
     // are providing their own bearer token based authentication mechanism that we can't get rid of for backward compatibility reasons
     if (request.getServletPath().startsWith(API_MONITORING_METRICS_PATH)) {
@@ -77,7 +78,7 @@ public class UserTokenAuthentication {
     return Optional.empty();
   }
 
-  private static Optional<String> findTokenUsedWithBasicAuthentication(HttpServletRequest request) {
+  private static Optional<String> findTokenUsedWithBasicAuthentication(HttpRequest request) {
     Credentials credentials = extractCredentialsFromHeader(request).orElse(null);
     if (isTokenWithBasicAuthenticationMethod(credentials)) {
       return Optional.ofNullable(credentials.getLogin());
@@ -89,13 +90,13 @@ public class UserTokenAuthentication {
     return Optional.ofNullable(credentials).map(c -> c.getPassword().isEmpty()).orElse(false);
   }
 
-  private UserAuthResult login(HttpServletRequest request, String token) {
+  private UserAuthResult login(HttpRequest request, String token) {
     UserAuthResult userAuthResult = authenticateFromUserToken(token, request);
     authenticationEvent.loginSuccess(request, userAuthResult.getUserDto().getLogin(), AuthenticationEvent.Source.local(AuthenticationEvent.Method.SONARQUBE_TOKEN));
     return userAuthResult;
   }
 
-  private UserAuthResult authenticateFromUserToken(String token, HttpServletRequest request) {
+  private UserAuthResult authenticateFromUserToken(String token, HttpRequest request) {
     try (DbSession dbSession = dbClient.openSession(false)) {
       UserTokenDto userToken = authenticate(token);
       UserDto userDto = dbClient.userDao().selectByUuid(dbSession, userToken.getUserUuid());
index 6bf6127d4b211d379eba61c1ffbde8c5c1bcb84b..20f5816d63889233f527b3b4d5fd16e0789e853a 100644 (file)
@@ -21,7 +21,6 @@ package org.sonar.server.authentication;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
@@ -29,6 +28,8 @@ import org.sonar.api.platform.Server;
 import org.sonar.api.server.authentication.BaseIdentityProvider;
 import org.sonar.api.server.authentication.UserIdentity;
 import org.sonar.db.user.UserDto;
+import org.sonar.server.http.JavaxHttpRequest;
+import org.sonar.server.http.JavaxHttpResponse;
 import org.sonar.server.user.TestUserSessionFactory;
 import org.sonar.server.user.ThreadLocalUserSession;
 import org.sonar.server.user.UserSession;
@@ -51,30 +52,34 @@ public class BaseContextFactoryTest {
     .setEmail("john@email.com")
     .build();
 
-  private ThreadLocalUserSession threadLocalUserSession = mock(ThreadLocalUserSession.class);
+  private final ThreadLocalUserSession threadLocalUserSession = mock(ThreadLocalUserSession.class);
 
-  private TestUserRegistrar userIdentityAuthenticator = new TestUserRegistrar();
-  private Server server = mock(Server.class);
+  private final TestUserRegistrar userIdentityAuthenticator = new TestUserRegistrar();
+  private final Server server = mock(Server.class);
 
-  private HttpServletRequest request = mock(HttpServletRequest.class);
-  private HttpServletResponse response = mock(HttpServletResponse.class);
-  private BaseIdentityProvider identityProvider = mock(BaseIdentityProvider.class);
-  private JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
-  private TestUserSessionFactory userSessionFactory = TestUserSessionFactory.standalone();
+  private final HttpServletRequest request = mock(HttpServletRequest.class);
+  private final HttpServletResponse response = mock(HttpServletResponse.class);
+  private final BaseIdentityProvider identityProvider = mock(BaseIdentityProvider.class);
+  private final JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
+  private final TestUserSessionFactory userSessionFactory = TestUserSessionFactory.standalone();
 
-  private BaseContextFactory underTest = new BaseContextFactory(userIdentityAuthenticator, server, jwtHttpHandler, threadLocalUserSession, userSessionFactory);
+  private final BaseContextFactory underTest = new BaseContextFactory(userIdentityAuthenticator, server, jwtHttpHandler, threadLocalUserSession, userSessionFactory);
 
   @Before
   public void setUp() {
     when(server.getPublicRootUrl()).thenReturn(PUBLIC_ROOT_URL);
     when(identityProvider.getName()).thenReturn("GitHub");
     when(identityProvider.getKey()).thenReturn("github");
-    when(request.getSession()).thenReturn(mock(HttpSession.class));
   }
 
   @Test
   public void create_context() {
-    BaseIdentityProvider.Context context = underTest.newContext(request, response, identityProvider);
+    JavaxHttpRequest httpRequest = new JavaxHttpRequest(request);
+    JavaxHttpResponse httpResponse = new JavaxHttpResponse(response);
+    BaseIdentityProvider.Context context = underTest.newContext(httpRequest, httpResponse, identityProvider);
+
+    assertThat(context.getHttpRequest()).isEqualTo(httpRequest);
+    assertThat(context.getHttpResponse()).isEqualTo(httpResponse);
 
     assertThat(context.getRequest()).isEqualTo(request);
     assertThat(context.getResponse()).isEqualTo(response);
@@ -83,14 +88,17 @@ public class BaseContextFactoryTest {
 
   @Test
   public void authenticate() {
-    BaseIdentityProvider.Context context = underTest.newContext(request, response, identityProvider);
+    JavaxHttpRequest httpRequest = new JavaxHttpRequest(request);
+    JavaxHttpResponse httpResponse = new JavaxHttpResponse(response);
+
+    BaseIdentityProvider.Context context = underTest.newContext(httpRequest, httpResponse, identityProvider);
     ArgumentCaptor<UserDto> userArgumentCaptor = ArgumentCaptor.forClass(UserDto.class);
 
     context.authenticate(USER_IDENTITY);
 
     assertThat(userIdentityAuthenticator.isAuthenticated()).isTrue();
     verify(threadLocalUserSession).set(any(UserSession.class));
-    verify(jwtHttpHandler).generateToken(userArgumentCaptor.capture(), eq(request), eq(response));
+    verify(jwtHttpHandler).generateToken(userArgumentCaptor.capture(), eq(httpRequest), eq(httpResponse));
     assertThat(userArgumentCaptor.getValue().getExternalId()).isEqualTo(USER_IDENTITY.getProviderId());
     assertThat(userArgumentCaptor.getValue().getExternalLogin()).isEqualTo(USER_IDENTITY.getProviderLogin());
     assertThat(userArgumentCaptor.getValue().getExternalIdentityProvider()).isEqualTo("github");
index fc3a4f9fe4ed44510625bb533831748f8f06f332..eb8ba91b3715a9b7b552ec080c7b81dca451064e 100644 (file)
@@ -21,10 +21,10 @@ package org.sonar.server.authentication;
 
 import java.util.Base64;
 import java.util.Optional;
-import javax.servlet.http.HttpServletRequest;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.sonar.api.server.http.HttpRequest;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbTester;
 import org.sonar.db.user.UserDto;
@@ -67,7 +67,7 @@ public class BasicAuthenticationTest {
   private final CredentialsAuthentication credentialsAuthentication = mock(CredentialsAuthentication.class);
   private final UserTokenAuthentication userTokenAuthentication = mock(UserTokenAuthentication.class);
 
-  private final HttpServletRequest request = mock(HttpServletRequest.class);
+  private final HttpRequest request = mock(HttpRequest.class);
 
   private final AuthenticationEvent authenticationEvent = mock(AuthenticationEvent.class);
 
index 09c27ee4c699d4ab3f44f31e3b758ba8bd6e61d6..986adccce65d99fc8023088e4a26685d0ca99422 100644 (file)
@@ -19,9 +19,9 @@
  */
 package org.sonar.server.authentication;
 
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
 import org.junit.Test;
+import org.sonar.api.server.http.Cookie;
+import org.sonar.api.server.http.HttpRequest;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -35,7 +35,7 @@ public class CookiesTest {
   private static final String HTTPS_HEADER = "X-Forwarded-Proto";
 
 
-  private HttpServletRequest request = mock(HttpServletRequest.class);
+  private HttpRequest request = mock(HttpRequest.class);
 
   @Test
   public void create_cookie() {
@@ -44,7 +44,7 @@ public class CookiesTest {
     assertThat(cookie.getValue()).isEqualTo("value");
     assertThat(cookie.isHttpOnly()).isTrue();
     assertThat(cookie.getMaxAge()).isEqualTo(10);
-    assertThat(cookie.getSecure()).isFalse();
+    assertThat(cookie.isSecure()).isFalse();
     assertThat(cookie.getPath()).isEqualTo("/");
   }
 
@@ -63,7 +63,7 @@ public class CookiesTest {
     assertThat(cookie.getValue()).isEqualTo("value");
     assertThat(cookie.isHttpOnly()).isTrue();
     assertThat(cookie.getMaxAge()).isEqualTo(10);
-    assertThat(cookie.getSecure()).isFalse();
+    assertThat(cookie.isSecure()).isFalse();
     assertThat(cookie.getPath()).isEqualTo("/sonarqube");
   }
 
@@ -71,21 +71,21 @@ public class CookiesTest {
   public void create_not_secured_cookie_when_header_is_not_http() {
     when(request.getHeader(HTTPS_HEADER)).thenReturn("http");
     Cookie cookie = newCookieBuilder(request).setName("name").setValue("value").setHttpOnly(true).setExpiry(10).build();
-    assertThat(cookie.getSecure()).isFalse();
+    assertThat(cookie.isSecure()).isFalse();
   }
 
   @Test
   public void create_secured_cookie_when_X_Forwarded_Proto_header_is_https() {
     when(request.getHeader(HTTPS_HEADER)).thenReturn("https");
     Cookie cookie = newCookieBuilder(request).setName("name").setValue("value").setHttpOnly(true).setExpiry(10).build();
-    assertThat(cookie.getSecure()).isTrue();
+    assertThat(cookie.isSecure()).isTrue();
   }
 
   @Test
   public void create_secured_cookie_when_X_Forwarded_Proto_header_is_HTTPS() {
     when(request.getHeader(HTTPS_HEADER)).thenReturn("HTTPS");
     Cookie cookie = newCookieBuilder(request).setName("name").setValue("value").setHttpOnly(true).setExpiry(10).build();
-    assertThat(cookie.getSecure()).isTrue();
+    assertThat(cookie.isSecure()).isTrue();
   }
 
   @Test
index fdf214ad9f4f76ac84b4056447dc20a612203b69..7d5bc45ab2e0c66d20f5c9122923430b097909b2 100644 (file)
 package org.sonar.server.authentication;
 
 import java.util.Optional;
-import javax.servlet.http.HttpServletRequest;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.server.http.HttpRequest;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
@@ -60,7 +60,7 @@ public class CredentialsAuthenticationTest {
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
   private final DbClient dbClient = dbTester.getDbClient();
   private final DbSession dbSession = dbTester.getSession();
-  private final HttpServletRequest request = mock(HttpServletRequest.class);
+  private final HttpRequest request = mock(HttpRequest.class);
   private final AuthenticationEvent authenticationEvent = mock(AuthenticationEvent.class);
   private final MapSettings settings = new MapSettings().setProperty("sonar.internal.pbkdf2.iterations", NUMBER_OF_PBKDF2_ITERATIONS);
   private final CredentialsExternalAuthentication externalAuthentication = mock(CredentialsExternalAuthentication.class);
index c3da6a4bc3cf3667f81eed31cc46752ec9f4c690..0ff96ed24d1746222d099c1f61225cd5c646c330 100644 (file)
@@ -28,9 +28,11 @@ import org.sonar.api.security.ExternalGroupsProvider;
 import org.sonar.api.security.ExternalUsersProvider;
 import org.sonar.api.security.SecurityRealm;
 import org.sonar.api.security.UserDetails;
+import org.sonar.api.server.http.HttpRequest;
 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.http.JavaxHttpRequest;
 import org.sonar.server.user.SecurityRealmFactory;
 
 import static java.util.Arrays.asList;
@@ -53,20 +55,21 @@ public class CredentialsExternalAuthenticationTest {
 
   private static final String REALM_NAME = "realm name";
 
-  private MapSettings settings = new MapSettings();
+  private final MapSettings settings = new MapSettings();
 
-  private SecurityRealmFactory securityRealmFactory = mock(SecurityRealmFactory.class);
-  private SecurityRealm realm = mock(SecurityRealm.class);
-  private Authenticator authenticator = mock(Authenticator.class);
-  private ExternalUsersProvider externalUsersProvider = mock(ExternalUsersProvider.class);
-  private ExternalGroupsProvider externalGroupsProvider = mock(ExternalGroupsProvider.class);
+  private final SecurityRealmFactory securityRealmFactory = mock(SecurityRealmFactory.class);
+  private final SecurityRealm realm = mock(SecurityRealm.class);
+  private final Authenticator authenticator = mock(Authenticator.class);
+  private final ExternalUsersProvider externalUsersProvider = mock(ExternalUsersProvider.class);
+  private final ExternalGroupsProvider externalGroupsProvider = mock(ExternalGroupsProvider.class);
 
-  private TestUserRegistrar userIdentityAuthenticator = new TestUserRegistrar();
-  private AuthenticationEvent authenticationEvent = mock(AuthenticationEvent.class);
+  private final TestUserRegistrar userIdentityAuthenticator = new TestUserRegistrar();
+  private final AuthenticationEvent authenticationEvent = mock(AuthenticationEvent.class);
 
-  private HttpServletRequest request = mock(HttpServletRequest.class);
+  private final HttpRequest request = new JavaxHttpRequest(mock(HttpServletRequest.class));
 
-  private CredentialsExternalAuthentication underTest = new CredentialsExternalAuthentication(settings.asConfig(), securityRealmFactory, userIdentityAuthenticator, authenticationEvent);
+  private final CredentialsExternalAuthentication underTest = new CredentialsExternalAuthentication(settings.asConfig(), securityRealmFactory, userIdentityAuthenticator,
+    authenticationEvent);
 
   @Before
   public void setUp() throws Exception {
@@ -184,7 +187,8 @@ public class CredentialsExternalAuthenticationTest {
 
     when(externalUsersProvider.doGetUserDetails(any(ExternalUsersProvider.Context.class))).thenReturn(null);
 
-    assertThatThrownBy(() -> underTest.authenticate(new Credentials(LOGIN, PASSWORD), request, BASIC))
+    Credentials credentials = new Credentials(LOGIN, PASSWORD);
+    assertThatThrownBy(() -> underTest.authenticate(credentials, request, BASIC))
       .hasMessage("No user details")
       .isInstanceOf(AuthenticationException.class)
       .hasFieldOrPropertyWithValue("source", Source.realm(BASIC, REALM_NAME))
@@ -200,7 +204,8 @@ public class CredentialsExternalAuthenticationTest {
 
     when(authenticator.doAuthenticate(any(Authenticator.Context.class))).thenReturn(false);
 
-    assertThatThrownBy(() -> underTest.authenticate(new Credentials(LOGIN, PASSWORD), request, BASIC))
+    Credentials credentials = new Credentials(LOGIN, PASSWORD);
+    assertThatThrownBy(() -> underTest.authenticate(credentials, request, BASIC))
       .hasMessage("Realm returned authenticate=false")
       .isInstanceOf(AuthenticationException.class)
       .hasFieldOrPropertyWithValue("source", Source.realm(BASIC, REALM_NAME))
@@ -218,7 +223,8 @@ public class CredentialsExternalAuthenticationTest {
 
     when(externalUsersProvider.doGetUserDetails(any(ExternalUsersProvider.Context.class))).thenReturn(new UserDetails());
 
-    assertThatThrownBy(() -> underTest.authenticate(new Credentials(LOGIN, PASSWORD), request, SONARQUBE_TOKEN))
+    Credentials credentials = new Credentials(LOGIN, PASSWORD);
+    assertThatThrownBy(() -> underTest.authenticate(credentials, request, SONARQUBE_TOKEN))
       .hasMessage(expectedMessage)
       .isInstanceOf(AuthenticationException.class)
       .hasFieldOrPropertyWithValue("source", Source.realm(SONARQUBE_TOKEN, REALM_NAME))
@@ -238,7 +244,7 @@ public class CredentialsExternalAuthenticationTest {
     when(realm.doGetAuthenticator()).thenReturn(null);
     when(securityRealmFactory.getRealm()).thenReturn(realm);
 
-    assertThatThrownBy(() -> underTest.start())
+    assertThatThrownBy(underTest::start)
       .isInstanceOf(NullPointerException.class)
       .hasMessage("No authenticator available");
   }
@@ -249,7 +255,7 @@ public class CredentialsExternalAuthenticationTest {
     when(realm.getUsersProvider()).thenReturn(null);
     when(securityRealmFactory.getRealm()).thenReturn(realm);
 
-    assertThatThrownBy(() -> underTest.start())
+    assertThatThrownBy(underTest::start)
       .isInstanceOf(NullPointerException.class)
       .hasMessage("No users provider available");
   }
index 8cab76ac983bf498883cee62748f2d6b4e392508..79a1afdf27d1ef0c9938dd7be7e26963b19ebc4a 100644 (file)
@@ -23,14 +23,13 @@ import com.tngtech.java.junit.dataprovider.DataProvider;
 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
 import com.tngtech.java.junit.dataprovider.UseDataProvider;
 import java.util.Optional;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.sonar.api.config.Configuration;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.api.web.FilterChain;
 import org.sonar.server.user.ThreadLocalUserSession;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -43,8 +42,8 @@ import static org.mockito.Mockito.when;
 @RunWith(DataProviderRunner.class)
 public class DefaultAdminCredentialsVerifierFilterTest {
 
-  private final HttpServletRequest request = mock(HttpServletRequest.class);
-  private final HttpServletResponse response = mock(HttpServletResponse.class);
+  private final HttpRequest request = mock(HttpRequest.class);
+  private final HttpResponse response = mock(HttpResponse.class);
   private final FilterChain chain = mock(FilterChain.class);
   private final Configuration config = mock(Configuration.class);
   private final DefaultAdminCredentialsVerifier defaultAdminCredentialsVerifier = mock(DefaultAdminCredentialsVerifier.class);
@@ -66,7 +65,7 @@ public class DefaultAdminCredentialsVerifierFilterTest {
 
   @Test
   public void verify_other_methods() {
-    underTest.init(mock(FilterConfig.class));
+    underTest.init();
     underTest.destroy();
 
     verifyNoInteractions(request, response, chain, session);
index b3cde7ceae6515a428645b9f5d4b654f1e0a558d..f0bd6768b0922b6899a0da47f312a329a7db71d8 100644 (file)
@@ -23,13 +23,13 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.StringReader;
 import java.util.Optional;
-import javax.servlet.http.HttpServletRequest;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.sonar.api.config.internal.Encryption;
 import org.sonar.api.config.internal.Settings;
+import org.sonar.api.server.http.HttpRequest;
 import org.sonar.api.testfixtures.log.LogAndArguments;
 import org.sonar.api.testfixtures.log.LogTester;
 import org.sonar.api.utils.log.LoggerLevel;
@@ -88,7 +88,7 @@ public class GithubWebhookAuthenticationTest {
 
   @Test
   public void authenticate_withComputedSignatureMatchingGithubSignature_returnsAuthentication() {
-    HttpServletRequest request = mockRequest(GITHUB_PAYLOAD, GITHUB_SIGNATURE);
+    HttpRequest request = mockRequest(GITHUB_PAYLOAD, GITHUB_SIGNATURE);
 
     Optional<UserAuthResult> authentication = githubWebhookAuthentication.authenticate(request);
     assertThat(authentication).isPresent();
@@ -104,7 +104,7 @@ public class GithubWebhookAuthenticationTest {
 
   @Test
   public void authenticate_withoutGithubSignatureHeader_throws() {
-    HttpServletRequest request = mockRequest(GITHUB_PAYLOAD, null);
+    HttpRequest request = mockRequest(GITHUB_PAYLOAD, null);
 
     String expectedMessage = format(MSG_UNAUTHENTICATED_GITHUB_CALLS_DENIED, APP_ID);
     assertThatExceptionOfType(AuthenticationException.class)
@@ -115,7 +115,7 @@ public class GithubWebhookAuthenticationTest {
 
   @Test
   public void authenticate_withoutBody_throws() {
-    HttpServletRequest request = mockRequest(null, GITHUB_SIGNATURE);
+    HttpRequest request = mockRequest(null, GITHUB_SIGNATURE);
 
     assertThatExceptionOfType(AuthenticationException.class)
       .isThrownBy(() -> githubWebhookAuthentication.authenticate(request))
@@ -125,7 +125,7 @@ public class GithubWebhookAuthenticationTest {
 
   @Test
   public void authenticate_withExceptionWhileReadingBody_throws() throws IOException {
-    HttpServletRequest request = mockRequest(GITHUB_PAYLOAD, GITHUB_SIGNATURE);
+    HttpRequest request = mockRequest(GITHUB_PAYLOAD, GITHUB_SIGNATURE);
     when(request.getReader()).thenThrow(new IOException());
 
     assertThatExceptionOfType(AuthenticationException.class)
@@ -136,7 +136,7 @@ public class GithubWebhookAuthenticationTest {
 
   @Test
   public void authenticate_withoutAppId_returnsEmpty() {
-    HttpServletRequest request = mockRequest(null, GITHUB_SIGNATURE);
+    HttpRequest request = mockRequest(null, GITHUB_SIGNATURE);
     when(request.getHeader(GITHUB_APP_ID_HEADER)).thenReturn(null);
 
     assertThat(githubWebhookAuthentication.authenticate(request)).isEmpty();
@@ -145,7 +145,7 @@ public class GithubWebhookAuthenticationTest {
 
   @Test
   public void authenticate_withWrongPayload_throws() {
-    HttpServletRequest request = mockRequest(GITHUB_PAYLOAD + "_", GITHUB_SIGNATURE);
+    HttpRequest request = mockRequest(GITHUB_PAYLOAD + "_", GITHUB_SIGNATURE);
 
     assertThatExceptionOfType(AuthenticationException.class)
       .isThrownBy(() -> githubWebhookAuthentication.authenticate(request))
@@ -155,7 +155,7 @@ public class GithubWebhookAuthenticationTest {
 
   @Test
   public void authenticate_withWrongSignature_throws() {
-    HttpServletRequest request = mockRequest(GITHUB_PAYLOAD, GITHUB_SIGNATURE + "_");
+    HttpRequest request = mockRequest(GITHUB_PAYLOAD, GITHUB_SIGNATURE + "_");
 
     assertThatExceptionOfType(AuthenticationException.class)
       .isThrownBy(() -> githubWebhookAuthentication.authenticate(request))
@@ -165,7 +165,7 @@ public class GithubWebhookAuthenticationTest {
 
   @Test
   public void authenticate_whenNoWebhookSecret_throws() {
-    HttpServletRequest request = mockRequest(GITHUB_PAYLOAD, GITHUB_SIGNATURE);
+    HttpRequest request = mockRequest(GITHUB_PAYLOAD, GITHUB_SIGNATURE);
     db.getDbClient().almSettingDao().update(db.getSession(), almSettingDto.setWebhookSecret(null), true);
     db.commit();
 
@@ -176,8 +176,8 @@ public class GithubWebhookAuthenticationTest {
     assertThat(logTester.getLogs(LoggerLevel.WARN)).extracting(LogAndArguments::getFormattedMsg).contains(expectedMessage);
   }
 
-  private static HttpServletRequest mockRequest(@Nullable String payload, @Nullable String gitHubSignature) {
-    HttpServletRequest request = mock(HttpServletRequest.class, Mockito.RETURNS_DEEP_STUBS);
+  private static HttpRequest mockRequest(@Nullable String payload, @Nullable String gitHubSignature) {
+    HttpRequest request = mock(HttpRequest.class, Mockito.RETURNS_DEEP_STUBS);
     try {
       StringReader stringReader = new StringReader(requireNonNullElse(payload, ""));
       BufferedReader bufferedReader = new BufferedReader(stringReader);
index 0e1975a2f4dad13075031f9cb1f892de8e39058c..500f4d9176d49048e32eaf368e4d603b2ddbc902 100644 (file)
@@ -25,13 +25,13 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Optional;
 import javax.annotation.Nullable;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.impl.utils.AlwaysIncreasingSystem2;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbTester;
 import org.sonar.db.audit.AuditPersister;
@@ -96,7 +96,7 @@ public class HttpHeadersAuthenticationTest {
   private final UserRegistrarImpl userIdentityAuthenticator = new UserRegistrarImpl(db.getDbClient(),
     new UserUpdater(mock(NewUserNotifier.class), db.getDbClient(), defaultGroupFinder, settings.asConfig(), mock(AuditPersister.class), localAuthentication),
     defaultGroupFinder, mock(ManagedInstanceService.class));
-  private final HttpServletResponse response = mock(HttpServletResponse.class);
+  private final HttpResponse response = mock(HttpResponse.class);
   private final JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
   private final AuthenticationEvent authenticationEvent = mock(AuthenticationEvent.class);
   private final HttpHeadersAuthentication underTest = new HttpHeadersAuthentication(system2, settings.asConfig(), userIdentityAuthenticator, jwtHttpHandler,
@@ -114,7 +114,7 @@ public class HttpHeadersAuthenticationTest {
   public void create_user_when_authenticating_new_user() {
     startWithSso();
     setNotUserInToken();
-    HttpServletRequest request = createRequest(DEFAULT_LOGIN, DEFAULT_NAME, DEFAULT_EMAIL, GROUPS);
+    HttpRequest request = createRequest(DEFAULT_LOGIN, DEFAULT_NAME, DEFAULT_EMAIL, GROUPS);
 
     underTest.authenticate(request, response);
 
@@ -128,7 +128,7 @@ public class HttpHeadersAuthenticationTest {
     startWithSso();
     setNotUserInToken();
 
-    HttpServletRequest request = createRequest(DEFAULT_LOGIN, null, null, null);
+    HttpRequest request = createRequest(DEFAULT_LOGIN, null, null, null);
     underTest.authenticate(request, response);
 
     verifyUserInDb(DEFAULT_LOGIN, DEFAULT_LOGIN, null, sonarUsers);
@@ -141,7 +141,7 @@ public class HttpHeadersAuthenticationTest {
     setNotUserInToken();
     insertUser(newUserDto().setLogin(DEFAULT_LOGIN).setExternalLogin(DEFAULT_LOGIN).setExternalIdentityProvider("sonarqube").setName("old name").setEmail(DEFAULT_USER.getEmail()), group1);
     // Name, email and groups are different
-    HttpServletRequest request = createRequest(DEFAULT_LOGIN, DEFAULT_NAME, DEFAULT_EMAIL, GROUP2);
+    HttpRequest request = createRequest(DEFAULT_LOGIN, DEFAULT_NAME, DEFAULT_EMAIL, GROUP2);
 
     underTest.authenticate(request, response);
 
@@ -155,7 +155,7 @@ public class HttpHeadersAuthenticationTest {
     startWithSso();
     setNotUserInToken();
     insertUser(DEFAULT_USER, group1);
-    HttpServletRequest request = createRequest(DEFAULT_LOGIN, DEFAULT_NAME, DEFAULT_EMAIL, "");
+    HttpRequest request = createRequest(DEFAULT_LOGIN, DEFAULT_NAME, DEFAULT_EMAIL, "");
 
     underTest.authenticate(request, response);
 
@@ -172,7 +172,7 @@ public class HttpHeadersAuthenticationTest {
     headerValuesByName.put("X-Forwarded-Login", DEFAULT_LOGIN);
     headerValuesByName.put("X-Forwarded-Email", DEFAULT_USER.getEmail());
     headerValuesByName.put("X-Forwarded-Groups", null);
-    HttpServletRequest request = createRequest(headerValuesByName);
+    HttpRequest request = createRequest(headerValuesByName);
 
     underTest.authenticate(request, response);
 
@@ -185,7 +185,7 @@ public class HttpHeadersAuthenticationTest {
     startWithSso();
     setNotUserInToken();
     insertUser(DEFAULT_USER, group1, sonarUsers);
-    HttpServletRequest request = createRequest(DEFAULT_LOGIN, DEFAULT_NAME, DEFAULT_EMAIL, null);
+    HttpRequest request = createRequest(DEFAULT_LOGIN, DEFAULT_NAME, DEFAULT_EMAIL, null);
 
     underTest.authenticate(request, response);
 
@@ -198,7 +198,7 @@ public class HttpHeadersAuthenticationTest {
     startWithSso();
     UserDto user = insertUser(DEFAULT_USER, group1);
     setUserInToken(user, CLOSE_REFRESH_TIME);
-    HttpServletRequest request = createRequest(DEFAULT_LOGIN, "new name", "new email", GROUP2);
+    HttpRequest request = createRequest(DEFAULT_LOGIN, "new name", "new email", GROUP2);
 
     underTest.authenticate(request, response);
 
@@ -214,7 +214,7 @@ public class HttpHeadersAuthenticationTest {
     UserDto user = insertUser(DEFAULT_USER, group1);
     // Refresh time was updated 6 minutes ago => more than 5 minutes
     setUserInToken(user, NOW - 6 * 60 * 1000L);
-    HttpServletRequest request = createRequest(DEFAULT_LOGIN, "new name", DEFAULT_USER.getEmail(), GROUP2);
+    HttpRequest request = createRequest(DEFAULT_LOGIN, "new name", DEFAULT_USER.getEmail(), GROUP2);
 
     underTest.authenticate(request, response);
 
@@ -229,7 +229,7 @@ public class HttpHeadersAuthenticationTest {
     startWithSso();
     UserDto user = insertUser(DEFAULT_USER, group1);
     setUserInToken(user, null);
-    HttpServletRequest request = createRequest(DEFAULT_LOGIN, "new name", DEFAULT_USER.getEmail(), GROUP2);
+    HttpRequest request = createRequest(DEFAULT_LOGIN, "new name", DEFAULT_USER.getEmail(), GROUP2);
 
     underTest.authenticate(request, response);
 
@@ -246,7 +246,7 @@ public class HttpHeadersAuthenticationTest {
     UserDto user = insertUser(DEFAULT_USER, group1);
     // Refresh time was updated 6 minutes ago => less than 10 minutes ago so not updated
     setUserInToken(user, NOW - 6 * 60 * 1000L);
-    HttpServletRequest request = createRequest(DEFAULT_LOGIN, "new name", "new email", GROUP2);
+    HttpRequest request = createRequest(DEFAULT_LOGIN, "new name", "new email", GROUP2);
 
     underTest.authenticate(request, response);
 
@@ -261,7 +261,7 @@ public class HttpHeadersAuthenticationTest {
     startWithSso();
     insertUser(DEFAULT_USER, group1);
     setUserInToken(DEFAULT_USER, CLOSE_REFRESH_TIME);
-    HttpServletRequest request = createRequest("AnotherLogin", "Another name", "Another email", GROUP2);
+    HttpRequest request = createRequest("AnotherLogin", "Another name", "Another email", GROUP2);
 
     underTest.authenticate(request, response);
 
@@ -278,7 +278,7 @@ public class HttpHeadersAuthenticationTest {
     settings.setProperty("sonar.web.sso.groupsHeader", "head-groups");
     startWithSso();
     setNotUserInToken();
-    HttpServletRequest request = createRequest(ImmutableMap.of("head-login", DEFAULT_LOGIN, "head-name", DEFAULT_NAME, "head-email", DEFAULT_EMAIL, "head-groups", GROUPS));
+    HttpRequest request = createRequest(ImmutableMap.of("head-login", DEFAULT_LOGIN, "head-name", DEFAULT_NAME, "head-email", DEFAULT_EMAIL, "head-groups", GROUPS));
 
     underTest.authenticate(request, response);
 
@@ -294,7 +294,7 @@ public class HttpHeadersAuthenticationTest {
     settings.setProperty("sonar.web.sso.groupsHeader", "Groups");
     startWithSso();
     setNotUserInToken();
-    HttpServletRequest request = createRequest(ImmutableMap.of("login", DEFAULT_LOGIN, "name", DEFAULT_NAME, "email", DEFAULT_EMAIL, "groups", GROUPS));
+    HttpRequest request = createRequest(ImmutableMap.of("login", DEFAULT_LOGIN, "name", DEFAULT_NAME, "email", DEFAULT_EMAIL, "groups", GROUPS));
 
     underTest.authenticate(request, response);
 
@@ -306,7 +306,7 @@ public class HttpHeadersAuthenticationTest {
   public void trim_groups() {
     startWithSso();
     setNotUserInToken();
-    HttpServletRequest request = createRequest(DEFAULT_LOGIN, null, null, "  dev ,    admin ");
+    HttpRequest request = createRequest(DEFAULT_LOGIN, null, null, "  dev ,    admin ");
 
     underTest.authenticate(request, response);
 
@@ -360,14 +360,14 @@ public class HttpHeadersAuthenticationTest {
   }
 
   private void setUserInToken(UserDto user, @Nullable Long lastRefreshTime) {
-    when(jwtHttpHandler.getToken(any(HttpServletRequest.class), any(HttpServletResponse.class)))
+    when(jwtHttpHandler.getToken(any(HttpRequest.class), any(HttpResponse.class)))
       .thenReturn(Optional.of(new JwtHttpHandler.Token(
         user,
         lastRefreshTime == null ? Collections.emptyMap() : ImmutableMap.of("ssoLastRefreshTime", lastRefreshTime))));
   }
 
   private void setNotUserInToken() {
-    when(jwtHttpHandler.getToken(any(HttpServletRequest.class), any(HttpServletResponse.class))).thenReturn(Optional.empty());
+    when(jwtHttpHandler.getToken(any(HttpRequest.class), any(HttpResponse.class))).thenReturn(Optional.empty());
   }
 
   private UserDto insertUser(UserDto user, GroupDto... groups) {
@@ -377,13 +377,13 @@ public class HttpHeadersAuthenticationTest {
     return user;
   }
 
-  private static HttpServletRequest createRequest(Map<String, String> headerValuesByName) {
-    HttpServletRequest request = mock(HttpServletRequest.class);
+  private static HttpRequest createRequest(Map<String, String> headerValuesByName) {
+    HttpRequest request = mock(HttpRequest.class);
     setHeaders(request, headerValuesByName);
     return request;
   }
 
-  private static HttpServletRequest createRequest(String login, @Nullable String name, @Nullable String email, @Nullable String groups) {
+  private static HttpRequest createRequest(String login, @Nullable String name, @Nullable String email, @Nullable String groups) {
     Map<String, String> headerValuesByName = new HashMap<>();
     headerValuesByName.put("X-Forwarded-Login", login);
     if (name != null) {
@@ -395,12 +395,12 @@ public class HttpHeadersAuthenticationTest {
     if (groups != null) {
       headerValuesByName.put("X-Forwarded-Groups", groups);
     }
-    HttpServletRequest request = mock(HttpServletRequest.class);
+    HttpRequest request = mock(HttpRequest.class);
     setHeaders(request, headerValuesByName);
     return request;
   }
 
-  private static void setHeaders(HttpServletRequest request, Map<String, String> valuesByName) {
+  private static void setHeaders(HttpRequest request, Map<String, String> valuesByName) {
     valuesByName.forEach((key, value) -> when(request.getHeader(key)).thenReturn(value));
     when(request.getHeaderNames()).thenReturn(Collections.enumeration(valuesByName.keySet()));
   }
@@ -434,10 +434,10 @@ public class HttpHeadersAuthenticationTest {
   }
 
   private void verifyTokenIsUpdated(long refreshTime) {
-    verify(jwtHttpHandler).generateToken(any(UserDto.class), eq(ImmutableMap.of("ssoLastRefreshTime", refreshTime)), any(HttpServletRequest.class), any(HttpServletResponse.class));
+    verify(jwtHttpHandler).generateToken(any(UserDto.class), eq(ImmutableMap.of("ssoLastRefreshTime", refreshTime)), any(HttpRequest.class), any(HttpResponse.class));
   }
 
   private void verifyTokenIsNotUpdated() {
-    verify(jwtHttpHandler, never()).generateToken(any(UserDto.class), anyMap(), any(HttpServletRequest.class), any(HttpServletResponse.class));
+    verify(jwtHttpHandler, never()).generateToken(any(UserDto.class), anyMap(), any(HttpRequest.class), any(HttpResponse.class));
   }
 }
index cc84c22a853af0239512e6f69357ee7367e7f568..89a8abc4a69a488b7ae916ec4fbc7923c9627601 100644 (file)
  */
 package org.sonar.server.authentication;
 
-import javax.servlet.FilterChain;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -33,7 +29,11 @@ import org.sonar.api.server.authentication.Display;
 import org.sonar.api.server.authentication.IdentityProvider;
 import org.sonar.api.server.authentication.OAuth2IdentityProvider;
 import org.sonar.api.server.authentication.UnauthorizedException;
+import org.sonar.api.server.http.Cookie;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.testfixtures.log.LogTester;
+import org.sonar.api.web.FilterChain;
 import org.sonar.server.authentication.event.AuthenticationEvent;
 import org.sonar.server.authentication.event.AuthenticationException;
 
@@ -59,8 +59,8 @@ public class InitFilterTest {
   private BaseContextFactory baseContextFactory = mock(BaseContextFactory.class);
   private OAuth2ContextFactory oAuth2ContextFactory = mock(OAuth2ContextFactory.class);
 
-  private HttpServletRequest request = mock(HttpServletRequest.class);
-  private HttpServletResponse response = mock(HttpServletResponse.class);
+  private HttpRequest request = mock(HttpRequest.class);
+  private HttpResponse response = mock(HttpResponse.class);
   private FilterChain chain = mock(FilterChain.class);
 
   private FakeOAuth2IdentityProvider oAuth2IdentityProvider = new FakeOAuth2IdentityProvider(OAUTH2_PROVIDER_KEY, true);
@@ -203,7 +203,7 @@ public class InitFilterTest {
     assertThat(cookie.getPath()).isEqualTo("/");
     assertThat(cookie.isHttpOnly()).isFalse();
     assertThat(cookie.getMaxAge()).isEqualTo(300);
-    assertThat(cookie.getSecure()).isFalse();
+    assertThat(cookie.isSecure()).isFalse();
   }
 
   @Test
index 0393258502e787b5e271463956564f673d05dc89..c5874063957afc91030fcb42250f0f1ec1ec0bdb 100644 (file)
  */
 package org.sonar.server.authentication;
 
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.sonar.api.server.http.Cookie;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.server.authentication.event.AuthenticationEvent.Source;
 import org.sonar.server.authentication.event.AuthenticationException;
 
@@ -45,8 +45,8 @@ public class JwtCsrfVerifierTest {
 
   private ArgumentCaptor<Cookie> cookieArgumentCaptor = ArgumentCaptor.forClass(Cookie.class);
 
-  private HttpServletResponse response = mock(HttpServletResponse.class);
-  private HttpServletRequest request = mock(HttpServletRequest.class);
+  private HttpResponse response = mock(HttpResponse.class);
+  private HttpRequest request = mock(HttpRequest.class);
 
   private JwtCsrfVerifier underTest = new JwtCsrfVerifier();
 
@@ -183,7 +183,7 @@ public class JwtCsrfVerifierTest {
     assertThat(cookie.getPath()).isEqualTo("/");
     assertThat(cookie.isHttpOnly()).isFalse();
     assertThat(cookie.getMaxAge()).isEqualTo(TIMEOUT);
-    assertThat(cookie.getSecure()).isFalse();
+    assertThat(cookie.isSecure()).isFalse();
   }
 
   private void mockPostJavaWsRequest() {
index 06c25b916387f3e70e83747ddea411142795a04c..796b21783250d716144d9308b88d842cf8a95b2c 100644 (file)
@@ -25,21 +25,22 @@ import java.util.Date;
 import java.util.Map;
 import java.util.Optional;
 import javax.annotation.Nullable;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.server.http.Cookie;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.user.SessionTokenDto;
 import org.sonar.db.user.UserDto;
+import org.sonar.server.http.JavaxHttpRequest;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -77,8 +78,8 @@ public class JwtHttpHandlerTest {
   private DbSession dbSession = db.getSession();
   private ArgumentCaptor<Cookie> cookieArgumentCaptor = ArgumentCaptor.forClass(Cookie.class);
   private ArgumentCaptor<JwtSerializer.JwtSession> jwtArgumentCaptor = ArgumentCaptor.forClass(JwtSerializer.JwtSession.class);
-  private HttpServletRequest request = mock(HttpServletRequest.class);
-  private HttpServletResponse response = mock(HttpServletResponse.class);
+  private HttpRequest request = mock(HttpRequest.class);
+  private HttpResponse response = mock(HttpResponse.class);
   private HttpSession httpSession = mock(HttpSession.class);
   private System2 system2 = spy(System2.INSTANCE);
   private MapSettings settings = new MapSettings();
@@ -90,7 +91,6 @@ public class JwtHttpHandlerTest {
   @Before
   public void setUp() {
     when(system2.now()).thenReturn(NOW);
-    when(request.getSession()).thenReturn(httpSession);
     when(jwtSerializer.encode(any(JwtSerializer.JwtSession.class))).thenReturn(JWT_TOKEN);
     when(jwtCsrfVerifier.generateState(eq(request), eq(response), anyInt())).thenReturn(CSRF_STATE);
   }
@@ -274,7 +274,7 @@ public class JwtHttpHandlerTest {
 
   @Test
   public void validate_token_does_nothing_when_empty_value_in_jwt_cookie() {
-    when(request.getCookies()).thenReturn(new Cookie[] {new Cookie("JWT-SESSION", "")});
+    when(request.getCookies()).thenReturn(new Cookie[] {new JavaxHttpRequest.JavaxCookie(new javax.servlet.http.Cookie("JWT-SESSION", ""))});
 
     underTest.validateToken(request, response);
 
@@ -401,7 +401,7 @@ public class JwtHttpHandlerTest {
     assertThat(cookie.getPath()).isEqualTo("/");
     assertThat(cookie.isHttpOnly()).isTrue();
     assertThat(cookie.getMaxAge()).isEqualTo(expiry);
-    assertThat(cookie.getSecure()).isFalse();
+    assertThat(cookie.isSecure()).isFalse();
     assertThat(cookie.getValue()).isEqualTo(value);
   }
 
@@ -425,7 +425,7 @@ public class JwtHttpHandlerTest {
   }
 
   private Cookie addJwtCookie() {
-    Cookie cookie = new Cookie("JWT-SESSION", JWT_TOKEN);
+    Cookie cookie = new JavaxHttpRequest.JavaxCookie(new javax.servlet.http.Cookie("JWT-SESSION", JWT_TOKEN));
     when(request.getCookies()).thenReturn(new Cookie[] {cookie});
     return cookie;
   }
index 53171b041107dae6f570e137c76330967fefa643..285724f04e55b74d67a13b99948bbcd8845c4206 100644 (file)
@@ -20,7 +20,6 @@
 package org.sonar.server.authentication;
 
 import javax.annotation.Nullable;
-import javax.servlet.http.HttpServletRequest;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -29,6 +28,7 @@ import org.mockito.junit.MockitoJUnitRunner;
 import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.server.authentication.IdentityProvider;
 import org.sonar.api.server.authentication.UserIdentity;
+import org.sonar.api.server.http.HttpRequest;
 import org.sonar.auth.ldap.LdapAuthenticator;
 import org.sonar.auth.ldap.LdapGroupsProvider;
 import org.sonar.auth.ldap.LdapRealm;
@@ -87,7 +87,7 @@ public class LdapCredentialsAuthenticationTest {
   private AuthenticationEvent authenticationEvent;
 
   @Mock
-  private HttpServletRequest request = mock(HttpServletRequest.class);
+  private HttpRequest request = mock(HttpRequest.class);
 
   @Mock
   private LdapAuthenticator ldapAuthenticator;
index b77d4cfe08fed2f03c9b374aa7b9e000fc243b32..8bebc7b1a1d7378fc755e0d2273183a91843f23a 100644 (file)
@@ -22,13 +22,14 @@ package org.sonar.server.authentication;
 import com.tngtech.java.junit.dataprovider.DataProvider;
 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
 import java.util.Optional;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.sonar.api.server.http.Cookie;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.server.http.JavaxHttpRequest;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.any;
@@ -42,8 +43,8 @@ public class OAuth2AuthenticationParametersImplTest {
 
   private static final String AUTHENTICATION_COOKIE_NAME = "AUTH-PARAMS";
   private final ArgumentCaptor<Cookie> cookieArgumentCaptor = ArgumentCaptor.forClass(Cookie.class);
-  private final HttpServletResponse response = mock(HttpServletResponse.class);
-  private final HttpServletRequest request = mock(HttpServletRequest.class);
+  private final HttpResponse response = mock(HttpResponse.class);
+  private final HttpRequest request = mock(HttpRequest.class);
 
   private final OAuth2AuthenticationParameters underTest = new OAuth2AuthenticationParametersImpl();
 
@@ -65,7 +66,7 @@ public class OAuth2AuthenticationParametersImplTest {
     assertThat(cookie.getPath()).isEqualTo("/");
     assertThat(cookie.isHttpOnly()).isTrue();
     assertThat(cookie.getMaxAge()).isEqualTo(300);
-    assertThat(cookie.getSecure()).isFalse();
+    assertThat(cookie.isSecure()).isFalse();
   }
 
   @Test
@@ -105,7 +106,7 @@ public class OAuth2AuthenticationParametersImplTest {
 
   @Test
   public void get_return_to_parameter() {
-    when(request.getCookies()).thenReturn(new Cookie[] {new Cookie(AUTHENTICATION_COOKIE_NAME, "{\"return_to\":\"/admin/settings\"}")});
+    when(request.getCookies()).thenReturn(new Cookie[] {wrapCookie(AUTHENTICATION_COOKIE_NAME, "{\"return_to\":\"/admin/settings\"}")});
 
     Optional<String> redirection = underTest.getReturnTo(request);
 
@@ -123,7 +124,7 @@ public class OAuth2AuthenticationParametersImplTest {
 
   @Test
   public void get_return_to_is_empty_when_no_value() {
-    when(request.getCookies()).thenReturn(new Cookie[] {new Cookie(AUTHENTICATION_COOKIE_NAME, "{}")});
+    when(request.getCookies()).thenReturn(new Cookie[] {wrapCookie(AUTHENTICATION_COOKIE_NAME, "{}")});
 
     Optional<String> redirection = underTest.getReturnTo(request);
 
@@ -132,7 +133,7 @@ public class OAuth2AuthenticationParametersImplTest {
 
   @Test
   public void delete() {
-    when(request.getCookies()).thenReturn(new Cookie[] {new Cookie(AUTHENTICATION_COOKIE_NAME, "{\"return_to\":\"/admin/settings\"}")});
+    when(request.getCookies()).thenReturn(new Cookie[] {wrapCookie(AUTHENTICATION_COOKIE_NAME, "{\"return_to\":\"/admin/settings\"}")});
 
     underTest.delete(request, response);
 
@@ -143,4 +144,8 @@ public class OAuth2AuthenticationParametersImplTest {
     assertThat(updatedCookie.getPath()).isEqualTo("/");
     assertThat(updatedCookie.getMaxAge()).isZero();
   }
+
+  private JavaxHttpRequest.JavaxCookie wrapCookie(String name, String value) {
+    return new JavaxHttpRequest.JavaxCookie(new javax.servlet.http.Cookie(name, value));
+  }
 }
index 5b4699d557e97a0ab1d473699a61731ab8aa600e..b00ac7b54704db406812519d9ce6d81c70adfd5e 100644 (file)
  */
 package org.sonar.server.authentication;
 
-import javax.servlet.FilterChain;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -31,7 +27,11 @@ import org.slf4j.event.Level;
 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.server.http.Cookie;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.testfixtures.log.LogTester;
+import org.sonar.api.web.FilterChain;
 import org.sonar.server.authentication.event.AuthenticationEvent;
 import org.sonar.server.authentication.event.AuthenticationException;
 import org.sonar.server.user.ThreadLocalUserSession;
@@ -56,8 +56,8 @@ public class OAuth2CallbackFilterTest {
 
   private OAuth2ContextFactory oAuth2ContextFactory = mock(OAuth2ContextFactory.class);
 
-  private HttpServletRequest request = mock(HttpServletRequest.class);
-  private HttpServletResponse response = mock(HttpServletResponse.class);
+  private HttpRequest request = mock(HttpRequest.class);
+  private HttpResponse response = mock(HttpResponse.class);
   private FilterChain chain = mock(FilterChain.class);
 
   private FakeOAuth2IdentityProvider oAuth2IdentityProvider = new WellbehaveFakeOAuth2IdentityProvider(OAUTH2_PROVIDER_KEY, true, LOGIN);
@@ -174,7 +174,7 @@ public class OAuth2CallbackFilterTest {
     assertThat(cookie.getPath()).isEqualTo("/");
     assertThat(cookie.isHttpOnly()).isFalse();
     assertThat(cookie.getMaxAge()).isEqualTo(300);
-    assertThat(cookie.getSecure()).isFalse();
+    assertThat(cookie.isSecure()).isFalse();
   }
 
   @Test
index 507391bd9ce1b60980e9397160146289b21d094d..db2abe7a56ea3d5594bb8ec76d3ce7a6f6f55612 100644 (file)
  */
 package org.sonar.server.authentication;
 
-import com.google.common.collect.ImmutableSet;
 import java.util.Optional;
-import java.util.Set;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.platform.Server;
 import org.sonar.api.server.authentication.OAuth2IdentityProvider;
 import org.sonar.api.server.authentication.UserIdentity;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.db.user.UserDto;
-import org.sonar.server.authentication.OAuth2ContextFactory.OAuthContextImpl;
+import org.sonar.server.http.JavaxHttpRequest;
+import org.sonar.server.http.JavaxHttpResponse;
 import org.sonar.server.user.TestUserSessionFactory;
 import org.sonar.server.user.ThreadLocalUserSession;
 import org.sonar.server.user.UserSession;
@@ -56,25 +56,27 @@ public class OAuth2ContextFactoryTest {
     .setEmail("john@email.com")
     .build();
 
+  private final ThreadLocalUserSession threadLocalUserSession = mock(ThreadLocalUserSession.class);
+  private final TestUserRegistrar userIdentityAuthenticator = new TestUserRegistrar();
+  private final Server server = mock(Server.class);
+  private final OAuthCsrfVerifier csrfVerifier = mock(OAuthCsrfVerifier.class);
+  private final JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
+  private final TestUserSessionFactory userSessionFactory = TestUserSessionFactory.standalone();
+  private final OAuth2AuthenticationParameters oAuthParameters = mock(OAuth2AuthenticationParameters.class);
+  private final HttpServletRequest request = mock(HttpServletRequest.class);
+  private final HttpServletResponse response = mock(HttpServletResponse.class);
 
-  private ThreadLocalUserSession threadLocalUserSession = mock(ThreadLocalUserSession.class);
-  private TestUserRegistrar userIdentityAuthenticator = new TestUserRegistrar();
-  private Server server = mock(Server.class);
-  private OAuthCsrfVerifier csrfVerifier = mock(OAuthCsrfVerifier.class);
-  private JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
-  private TestUserSessionFactory userSessionFactory = TestUserSessionFactory.standalone();
-  private OAuth2AuthenticationParameters oAuthParameters = mock(OAuth2AuthenticationParameters.class);
-  private HttpServletRequest request = mock(HttpServletRequest.class);
-  private HttpServletResponse response = mock(HttpServletResponse.class);
-  private HttpSession session = mock(HttpSession.class);
-  private OAuth2IdentityProvider identityProvider = mock(OAuth2IdentityProvider.class);
+  private final HttpRequest httpRequest = new JavaxHttpRequest(request);
+  private final HttpResponse httpResponse = new JavaxHttpResponse(response);
 
-  private OAuth2ContextFactory underTest = new OAuth2ContextFactory(threadLocalUserSession, userIdentityAuthenticator, server, csrfVerifier, jwtHttpHandler, userSessionFactory,
+  private final OAuth2IdentityProvider identityProvider = mock(OAuth2IdentityProvider.class);
+
+  private final OAuth2ContextFactory underTest = new OAuth2ContextFactory(threadLocalUserSession, userIdentityAuthenticator, server, csrfVerifier, jwtHttpHandler,
+    userSessionFactory,
     oAuthParameters);
 
   @Before
   public void setUp() {
-    when(request.getSession()).thenReturn(session);
     when(identityProvider.getKey()).thenReturn(PROVIDER_KEY);
     when(identityProvider.getName()).thenReturn(PROVIDER_NAME);
   }
@@ -85,8 +87,12 @@ public class OAuth2ContextFactoryTest {
 
     OAuth2IdentityProvider.InitContext context = newInitContext();
 
+    assertThat(context.getHttpRequest()).isEqualTo(httpRequest);
+    assertThat(context.getHttpResponse()).isEqualTo(httpResponse);
+
     assertThat(context.getRequest()).isEqualTo(request);
     assertThat(context.getResponse()).isEqualTo(response);
+
     assertThat(context.getCallbackUrl()).isEqualTo("https://mydomain.com/oauth2/callback/github");
   }
 
@@ -96,7 +102,7 @@ public class OAuth2ContextFactoryTest {
 
     context.generateCsrfState();
 
-    verify(csrfVerifier).generateState(request, response);
+    verify(csrfVerifier).generateState(httpRequest, httpResponse);
   }
 
   @Test
@@ -114,8 +120,8 @@ public class OAuth2ContextFactoryTest {
 
     OAuth2IdentityProvider.CallbackContext callback = newCallbackContext();
 
-    assertThat(callback.getRequest()).isEqualTo(request);
-    assertThat(callback.getResponse()).isEqualTo(response);
+    assertThat(callback.getHttpRequest()).isEqualTo(httpRequest);
+    assertThat(callback.getHttpResponse()).isEqualTo(httpResponse);
     assertThat(callback.getCallbackUrl()).isEqualTo("https://mydomain.com/oauth2/callback/github");
   }
 
@@ -128,7 +134,7 @@ public class OAuth2ContextFactoryTest {
     assertThat(userIdentityAuthenticator.isAuthenticated()).isTrue();
     verify(threadLocalUserSession).set(any(UserSession.class));
     ArgumentCaptor<UserDto> userArgumentCaptor = ArgumentCaptor.forClass(UserDto.class);
-    verify(jwtHttpHandler).generateToken(userArgumentCaptor.capture(), eq(request), eq(response));
+    verify(jwtHttpHandler).generateToken(userArgumentCaptor.capture(), eq(httpRequest), eq(httpResponse));
     assertThat(userArgumentCaptor.getValue().getExternalId()).isEqualTo(USER_IDENTITY.getProviderId());
     assertThat(userArgumentCaptor.getValue().getExternalLogin()).isEqualTo(USER_IDENTITY.getProviderLogin());
     assertThat(userArgumentCaptor.getValue().getExternalIdentityProvider()).isEqualTo(PROVIDER_KEY);
@@ -137,7 +143,7 @@ public class OAuth2ContextFactoryTest {
   @Test
   public void redirect_to_home() throws Exception {
     when(server.getContextPath()).thenReturn("");
-    when(oAuthParameters.getReturnTo(request)).thenReturn(Optional.empty());
+    when(oAuthParameters.getReturnTo(httpRequest)).thenReturn(Optional.empty());
     OAuth2IdentityProvider.CallbackContext callback = newCallbackContext();
 
     callback.redirectToRequestedPage();
@@ -148,7 +154,7 @@ public class OAuth2ContextFactoryTest {
   @Test
   public void redirect_to_home_with_context() throws Exception {
     when(server.getContextPath()).thenReturn("/sonarqube");
-    when(oAuthParameters.getReturnTo(request)).thenReturn(Optional.empty());
+    when(oAuthParameters.getReturnTo(httpRequest)).thenReturn(Optional.empty());
     OAuth2IdentityProvider.CallbackContext callback = newCallbackContext();
 
     callback.redirectToRequestedPage();
@@ -158,7 +164,7 @@ public class OAuth2ContextFactoryTest {
 
   @Test
   public void redirect_to_requested_page() throws Exception {
-    when(oAuthParameters.getReturnTo(request)).thenReturn(Optional.of("/admin/settings"));
+    when(oAuthParameters.getReturnTo(httpRequest)).thenReturn(Optional.of("/admin/settings"));
     when(server.getContextPath()).thenReturn("");
     OAuth2IdentityProvider.CallbackContext callback = newCallbackContext();
 
@@ -169,7 +175,7 @@ public class OAuth2ContextFactoryTest {
 
   @Test
   public void redirect_to_requested_page_does_not_need_context() throws Exception {
-    when(oAuthParameters.getReturnTo(request)).thenReturn(Optional.of("/admin/settings"));
+    when(oAuthParameters.getReturnTo(httpRequest)).thenReturn(Optional.of("/admin/settings"));
     when(server.getContextPath()).thenReturn("/other");
     OAuth2IdentityProvider.CallbackContext callback = newCallbackContext();
 
@@ -184,26 +190,26 @@ public class OAuth2ContextFactoryTest {
 
     callback.verifyCsrfState();
 
-    verify(csrfVerifier).verifyState(request, response, identityProvider);
+    verify(csrfVerifier).verifyState(httpRequest, httpResponse, identityProvider);
   }
 
   @Test
   public void delete_oauth2_parameters_during_redirection() {
-    when(oAuthParameters.getReturnTo(request)).thenReturn(Optional.of("/admin/settings"));
+    when(oAuthParameters.getReturnTo(httpRequest)).thenReturn(Optional.of("/admin/settings"));
     when(server.getContextPath()).thenReturn("");
     OAuth2IdentityProvider.CallbackContext callback = newCallbackContext();
 
     callback.redirectToRequestedPage();
 
-    verify(oAuthParameters).delete(request, response);
+    verify(oAuthParameters).delete(httpRequest, httpResponse);
   }
 
   private OAuth2IdentityProvider.InitContext newInitContext() {
-    return underTest.newContext(request, response, identityProvider);
+    return underTest.newContext(httpRequest, httpResponse, identityProvider);
   }
 
   private OAuth2IdentityProvider.CallbackContext newCallbackContext() {
-    return underTest.newCallback(request, response, identityProvider);
+    return underTest.newCallback(httpRequest, httpResponse, identityProvider);
   }
 
 }
index 2ddce9d2432fcb3d427ede0a966b19dd888b963e..186794739d0d19e063dbc68c48a30c37c60e87c2 100644 (file)
  */
 package org.sonar.server.authentication;
 
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.platform.Server;
 import org.sonar.api.server.authentication.OAuth2IdentityProvider;
+import org.sonar.api.server.http.Cookie;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.server.authentication.event.AuthenticationEvent;
 import org.sonar.server.authentication.event.AuthenticationException;
+import org.sonar.server.http.JavaxHttpRequest;
 
 import static org.apache.commons.codec.digest.DigestUtils.sha1Hex;
 import static org.apache.commons.codec.digest.DigestUtils.sha256Hex;
@@ -45,8 +46,8 @@ public class OAuthCsrfVerifierTest {
 
   private OAuth2IdentityProvider identityProvider = mock(OAuth2IdentityProvider.class);
   private Server server = mock(Server.class);
-  private HttpServletResponse response = mock(HttpServletResponse.class);
-  private HttpServletRequest request = mock(HttpServletRequest.class);
+  private HttpResponse response = mock(HttpResponse.class);
+  private HttpRequest request = mock(HttpRequest.class);
 
   private OAuthCsrfVerifier underTest = new OAuthCsrfVerifier();
 
@@ -69,7 +70,7 @@ public class OAuthCsrfVerifierTest {
   @Test
   public void verify_state() {
     String state = "state";
-    when(request.getCookies()).thenReturn(new Cookie[]{new Cookie("OAUTHSTATE", sha256Hex(state))});
+    when(request.getCookies()).thenReturn(new Cookie[]{wrapCookie("OAUTHSTATE", sha256Hex(state))});
     when(request.getParameter("aStateParameter")).thenReturn(state);
 
     underTest.verifyState(request, response, identityProvider, "aStateParameter");
@@ -85,7 +86,7 @@ public class OAuthCsrfVerifierTest {
   @Test
   public void verify_state_using_default_state_parameter() {
     String state = "state";
-    when(request.getCookies()).thenReturn(new Cookie[]{new Cookie("OAUTHSTATE", sha256Hex(state))});
+    when(request.getCookies()).thenReturn(new Cookie[]{wrapCookie("OAUTHSTATE", sha256Hex(state))});
     when(request.getParameter("state")).thenReturn(state);
 
     underTest.verifyState(request, response, identityProvider);
@@ -100,7 +101,7 @@ public class OAuthCsrfVerifierTest {
 
   @Test
   public void fail_with_AuthenticationException_when_state_cookie_is_not_the_same_as_state_parameter() {
-    when(request.getCookies()).thenReturn(new Cookie[]{new Cookie("OAUTHSTATE", sha1Hex("state"))});
+    when(request.getCookies()).thenReturn(new Cookie[]{wrapCookie("OAUTHSTATE", sha1Hex("state"))});
     when(request.getParameter("state")).thenReturn("other value");
 
     assertThatThrownBy(() -> underTest.verifyState(request, response, identityProvider))
@@ -111,7 +112,7 @@ public class OAuthCsrfVerifierTest {
 
   @Test
   public void fail_with_AuthenticationException_when_state_cookie_is_null() {
-    when(request.getCookies()).thenReturn(new Cookie[]{new Cookie("OAUTHSTATE", null)});
+    when(request.getCookies()).thenReturn(new Cookie[]{wrapCookie("OAUTHSTATE", null)});
     when(request.getParameter("state")).thenReturn("state");
 
     assertThatThrownBy(() -> underTest.verifyState(request, response, identityProvider))
@@ -122,7 +123,7 @@ public class OAuthCsrfVerifierTest {
 
   @Test
   public void fail_with_AuthenticationException_when_state_parameter_is_empty() {
-    when(request.getCookies()).thenReturn(new Cookie[]{new Cookie("OAUTHSTATE", sha1Hex("state"))});
+    when(request.getCookies()).thenReturn(new Cookie[]{wrapCookie("OAUTHSTATE", sha1Hex("state"))});
     when(request.getParameter("state")).thenReturn("");
 
     assertThatThrownBy(() -> underTest.verifyState(request, response, identityProvider))
@@ -147,6 +148,10 @@ public class OAuthCsrfVerifierTest {
     assertThat(cookie.getPath()).isEqualTo("/");
     assertThat(cookie.isHttpOnly()).isTrue();
     assertThat(cookie.getMaxAge()).isEqualTo(-1);
-    assertThat(cookie.getSecure()).isFalse();
+    assertThat(cookie.isSecure()).isFalse();
+  }
+
+  private JavaxHttpRequest.JavaxCookie wrapCookie(String name, String value) {
+    return new JavaxHttpRequest.JavaxCookie(new javax.servlet.http.Cookie(name, value));
   }
 }
index 1e5e79dc30111c4e95def642f9472bef42abf701..e4dcfb40ce3360cb26efbb2a1283260d3b7a9240 100644 (file)
 package org.sonar.server.authentication;
 
 import java.util.Optional;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Test;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.db.user.UserDto;
 import org.sonar.db.user.UserTokenDto;
 import org.sonar.server.tester.AnonymousMockUserSession;
@@ -47,8 +47,8 @@ public class RequestAuthenticatorImplTest {
   private static final UserDto A_USER = newUserDto();
   private static final UserTokenDto A_USER_TOKEN = mockUserTokenDto(A_USER);
 
-  private final HttpServletRequest request = mock(HttpServletRequest.class);
-  private final HttpServletResponse response = mock(HttpServletResponse.class);
+  private final HttpRequest request = mock(HttpRequest.class);
+  private final HttpResponse response = mock(HttpResponse.class);
   private final JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
   private final BasicAuthentication basicAuthentication = mock(BasicAuthentication.class);
   private final UserTokenAuthentication userTokenAuthentication = mock(UserTokenAuthentication.class);
index 05ce7bdbfdd80b0f82d43af7cf356f10526e4cda..3e9b78e6375b88f89b7105775429549c05f2dc5a 100644 (file)
@@ -22,13 +22,12 @@ package org.sonar.server.authentication;
 import com.tngtech.java.junit.dataprovider.DataProvider;
 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
 import com.tngtech.java.junit.dataprovider.UseDataProvider;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.api.web.FilterChain;
 import org.sonar.server.user.ThreadLocalUserSession;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -41,8 +40,8 @@ import static org.mockito.Mockito.when;
 @RunWith(DataProviderRunner.class)
 public class ResetPasswordFilterTest {
 
-  private final HttpServletRequest request = mock(HttpServletRequest.class);
-  private final HttpServletResponse response = mock(HttpServletResponse.class);
+  private final HttpRequest request = mock(HttpRequest.class);
+  private final HttpResponse response = mock(HttpResponse.class);
   private final FilterChain chain = mock(FilterChain.class);
   private final ThreadLocalUserSession session = mock(ThreadLocalUserSession.class);
 
@@ -62,7 +61,7 @@ public class ResetPasswordFilterTest {
 
   @Test
   public void verify_other_methods() {
-    underTest.init(mock(FilterConfig.class));
+    underTest.init();
     underTest.destroy();
 
     verifyNoInteractions(request, response, chain, session);
index 2ca3c6a6ab61b80e70451339403b19a079f5abc2..8d504e2478ab4d4b0478c062c81c62469568db82 100644 (file)
@@ -19,8 +19,8 @@
  */
 package org.sonar.server.authentication;
 
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Test;
+import org.sonar.api.server.http.HttpResponse;
 
 import static org.mockito.ArgumentMatchers.contains;
 import static org.mockito.ArgumentMatchers.eq;
@@ -32,7 +32,7 @@ public class SamlValidationCspHeadersTest {
 
   @Test
   public void addCspHeadersWithNonceToResponse_whenCalled_shouldAddNonceToCspHeaders() {
-    HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
+    HttpResponse httpServletResponse = mock(HttpResponse.class);
 
     String nonce = addCspHeadersWithNonceToResponse(httpServletResponse);
 
index bfa90a614ee90c7a52d3da29e5d6025b9bd2f46e..13b930fe938297ef8e3aa7b74e61599741119170 100644 (file)
@@ -25,17 +25,15 @@ import com.tngtech.java.junit.dataprovider.UseDataProvider;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.List;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.mockito.internal.verification.VerificationModeFactory;
 import org.sonar.api.platform.Server;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.api.web.FilterChain;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.assertThrows;
@@ -60,7 +58,7 @@ public class SamlValidationRedirectionFilterTest {
     Server server = mock(Server.class);
     doReturn("contextPath").when(server).getContextPath();
     underTest = new SamlValidationRedirectionFilter(server);
-    underTest.init(mock(FilterConfig.class));
+    underTest.init();
   }
 
 
@@ -73,9 +71,9 @@ public class SamlValidationRedirectionFilterTest {
   }
 
   @Test
-  public void do_filter_validation_relay_state_with_csrfToken() throws ServletException, IOException {
-    HttpServletRequest servletRequest = mock(HttpServletRequest.class);
-    HttpServletResponse servletResponse = mock(HttpServletResponse.class);
+  public void do_filter_validation_relay_state_with_csrfToken() throws IOException {
+    HttpRequest servletRequest = mock(HttpRequest.class);
+    HttpResponse servletResponse = mock(HttpResponse.class);
     FilterChain filterChain = mock(FilterChain.class);
 
     String validSample = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
@@ -96,9 +94,9 @@ public class SamlValidationRedirectionFilterTest {
   }
 
   @Test
-  public void do_filter_validation_relay_state_with_malicious_csrfToken() throws ServletException, IOException {
-    HttpServletRequest servletRequest = mock(HttpServletRequest.class);
-    HttpServletResponse servletResponse = mock(HttpServletResponse.class);
+  public void do_filter_validation_relay_state_with_malicious_csrfToken() throws IOException {
+    HttpRequest servletRequest = mock(HttpRequest.class);
+    HttpResponse servletResponse = mock(HttpResponse.class);
     FilterChain filterChain = mock(FilterChain.class);
 
     String validSample = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
@@ -121,9 +119,9 @@ public class SamlValidationRedirectionFilterTest {
   }
 
   @Test
-  public void do_filter_validation_wrong_SAML_response() throws ServletException, IOException {
-    HttpServletRequest servletRequest = mock(HttpServletRequest.class);
-    HttpServletResponse servletResponse = mock(HttpServletResponse.class);
+  public void do_filter_validation_wrong_SAML_response() throws IOException {
+    HttpRequest servletRequest = mock(HttpRequest.class);
+    HttpResponse servletResponse = mock(HttpResponse.class);
     FilterChain filterChain = mock(FilterChain.class);
 
     String maliciousSaml = "test\"</input><script>/*hack website*/</script><input value=\"";
@@ -144,9 +142,9 @@ public class SamlValidationRedirectionFilterTest {
 
   @Test
   @UseDataProvider("invalidRelayStateValues")
-  public void do_filter_invalid_relayState_values(String relayStateValue) throws ServletException, IOException {
-    HttpServletRequest servletRequest = mock(HttpServletRequest.class);
-    HttpServletResponse servletResponse = mock(HttpServletResponse.class);
+  public void do_filter_invalid_relayState_values(String relayStateValue) throws IOException {
+    HttpRequest servletRequest = mock(HttpRequest.class);
+    HttpResponse servletResponse = mock(HttpResponse.class);
     FilterChain filterChain = mock(FilterChain.class);
     doReturn(relayStateValue).when(servletRequest).getParameter("RelayState");
 
index 48c84b3aff2c7a5d45b7f90c98dd4d72c26eac11..99f3ee2d89f50248849d346c73811fe8152dcd96 100644 (file)
@@ -21,15 +21,15 @@ 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;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.server.authentication.BaseIdentityProvider;
+import org.sonar.api.server.http.Cookie;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbTester;
 import org.sonar.db.user.UserDto;
@@ -60,8 +60,8 @@ public class UserSessionInitializerTest {
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
 
   private ThreadLocalUserSession threadLocalSession = mock(ThreadLocalUserSession.class);
-  private HttpServletRequest request = mock(HttpServletRequest.class);
-  private HttpServletResponse response = mock(HttpServletResponse.class);
+  private HttpRequest request = mock(HttpRequest.class);
+  private HttpResponse response = mock(HttpResponse.class);
   private RequestAuthenticator authenticator = mock(RequestAuthenticator.class);
   private AuthenticationEvent authenticationEvent = mock(AuthenticationEvent.class);
   private MapSettings settings = new MapSettings();
@@ -187,7 +187,7 @@ public class UserSessionInitializerTest {
     assertThat(cookie.getPath()).isEqualTo("/");
     assertThat(cookie.isHttpOnly()).isFalse();
     assertThat(cookie.getMaxAge()).isEqualTo(300);
-    assertThat(cookie.getSecure()).isFalse();
+    assertThat(cookie.isSecure()).isFalse();
   }
 
   @Test
index ca1ea2a3cde3a6ba70c4b507f12a63511f0fe4e2..b47c7d0f4613bb31e14c1852600828fa0ee49992 100644 (file)
@@ -24,11 +24,11 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
-import javax.servlet.http.HttpServletRequest;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.slf4j.event.Level;
+import org.sonar.api.server.http.HttpRequest;
 import org.sonar.api.testfixtures.log.LogTester;
 import org.sonar.api.utils.log.LoggerLevel;
 
@@ -49,7 +49,7 @@ public class AuthenticationEventImplTest {
   @Rule
   public LogTester logTester = new LogTester();
 
-  private AuthenticationEventImpl underTest = new AuthenticationEventImpl();
+  private final AuthenticationEventImpl underTest = new AuthenticationEventImpl();
 
   @Before
   public void setUp() {
@@ -60,7 +60,8 @@ public class AuthenticationEventImplTest {
   public void login_success_fails_with_NPE_if_request_is_null() {
     logTester.setLevel(LoggerLevel.INFO);
 
-    assertThatThrownBy(() -> underTest.loginSuccess(null, "login", Source.sso()))
+    Source sso = Source.sso();
+    assertThatThrownBy(() -> underTest.loginSuccess(null, "login", sso))
       .isInstanceOf(NullPointerException.class)
       .hasMessage("request can't be null");
   }
@@ -69,14 +70,14 @@ public class AuthenticationEventImplTest {
   public void login_success_fails_with_NPE_if_source_is_null() {
     logTester.setLevel(LoggerLevel.INFO);
 
-    assertThatThrownBy(() -> underTest.loginSuccess(mock(HttpServletRequest.class), "login", null))
+    assertThatThrownBy(() -> underTest.loginSuccess(mock(HttpRequest.class), "login", null))
       .isInstanceOf(NullPointerException.class)
       .hasMessage("source can't be null");
   }
 
   @Test
   public void login_success_does_not_interact_with_request_if_log_level_is_above_DEBUG() {
-    HttpServletRequest request = mock(HttpServletRequest.class);
+    HttpRequest request = mock(HttpRequest.class);
     logTester.setLevel(LoggerLevel.INFO);
 
     underTest.loginSuccess(request, "login", Source.sso());
@@ -115,7 +116,7 @@ public class AuthenticationEventImplTest {
 
   @Test
   public void login_success_logs_X_Forwarded_For_header_from_request() {
-    HttpServletRequest request = mockRequest("1.2.3.4", asList("2.3.4.5"));
+    HttpRequest request = mockRequest("1.2.3.4", asList("2.3.4.5"));
     underTest.loginSuccess(request, "foo", Source.realm(Method.EXTERNAL, "bar"));
 
     verifyLog("login success [method|EXTERNAL][provider|REALM|bar][IP|1.2.3.4|2.3.4.5][login|foo]");
@@ -123,7 +124,7 @@ public class AuthenticationEventImplTest {
 
   @Test
   public void login_success_logs_X_Forwarded_For_header_from_request_and_supports_multiple_headers() {
-    HttpServletRequest request = mockRequest("1.2.3.4", asList("2.3.4.5", "6.5.4.3"), asList("9.5.6.7"), asList("6.3.2.4"));
+    HttpRequest request = mockRequest("1.2.3.4", asList("2.3.4.5", "6.5.4.3"), asList("9.5.6.7"), asList("6.3.2.4"));
     underTest.loginSuccess(request, "foo", Source.realm(Method.EXTERNAL, "bar"));
 
     verifyLog("login success [method|EXTERNAL][provider|REALM|bar][IP|1.2.3.4|2.3.4.5,6.5.4.3,9.5.6.7,6.3.2.4][login|foo]");
@@ -133,7 +134,8 @@ public class AuthenticationEventImplTest {
   public void login_failure_fails_with_NPE_if_request_is_null() {
     logTester.setLevel(LoggerLevel.INFO);
 
-    assertThatThrownBy(() -> underTest.loginFailure(null, newBuilder().setSource(Source.sso()).build()))
+    AuthenticationException exception = newBuilder().setSource(Source.sso()).build();
+    assertThatThrownBy(() -> underTest.loginFailure(null, exception))
       .isInstanceOf(NullPointerException.class)
       .hasMessage("request can't be null");
   }
@@ -142,14 +144,14 @@ public class AuthenticationEventImplTest {
   public void login_failure_fails_with_NPE_if_AuthenticationException_is_null() {
     logTester.setLevel(LoggerLevel.INFO);
 
-    assertThatThrownBy(() -> underTest.loginFailure(mock(HttpServletRequest.class), null))
+    assertThatThrownBy(() -> underTest.loginFailure(mock(HttpRequest.class), null))
       .isInstanceOf(NullPointerException.class)
       .hasMessage("AuthenticationException can't be null");
   }
 
   @Test
   public void login_failure_does_not_interact_with_arguments_if_log_level_is_above_DEBUG() {
-    HttpServletRequest request = mock(HttpServletRequest.class);
+    HttpRequest request = mock(HttpRequest.class);
     AuthenticationException exception = mock(AuthenticationException.class);
     logTester.setLevel(LoggerLevel.INFO);
 
@@ -218,7 +220,7 @@ public class AuthenticationEventImplTest {
       .setMessage("Hop la!")
       .setLogin("foo")
       .build();
-    HttpServletRequest request = mockRequest("1.2.3.4", asList("2.3.4.5"));
+    HttpRequest request = mockRequest("1.2.3.4", asList("2.3.4.5"));
     underTest.loginFailure(request, exception);
 
     verifyLog("login failure [cause|Hop la!][method|EXTERNAL][provider|REALM|bar][IP|1.2.3.4|2.3.4.5][login|foo]");
@@ -231,7 +233,7 @@ public class AuthenticationEventImplTest {
       .setMessage("Boom!")
       .setLogin("foo")
       .build();
-    HttpServletRequest request = mockRequest("1.2.3.4", asList("2.3.4.5", "6.5.4.3"), asList("9.5.6.7"), asList("6.3.2.4"));
+    HttpRequest request = mockRequest("1.2.3.4", asList("2.3.4.5", "6.5.4.3"), asList("9.5.6.7"), asList("6.3.2.4"));
     underTest.loginFailure(request, exception);
 
     verifyLog("login failure [cause|Boom!][method|EXTERNAL][provider|REALM|bar][IP|1.2.3.4|2.3.4.5,6.5.4.3,9.5.6.7,6.3.2.4][login|foo]");
@@ -248,7 +250,7 @@ public class AuthenticationEventImplTest {
 
   @Test
   public void logout_success_does_not_interact_with_request_if_log_level_is_above_DEBUG() {
-    HttpServletRequest request = mock(HttpServletRequest.class);
+    HttpRequest request = mock(HttpRequest.class);
     logTester.setLevel(LoggerLevel.INFO);
 
     underTest.logoutSuccess(request, "foo");
@@ -279,7 +281,7 @@ public class AuthenticationEventImplTest {
 
   @Test
   public void logout_success_logs_X_Forwarded_For_header_from_request() {
-    HttpServletRequest request = mockRequest("1.2.3.4", asList("2.3.4.5"));
+    HttpRequest request = mockRequest("1.2.3.4", asList("2.3.4.5"));
     underTest.logoutSuccess(request, "foo");
 
     verifyLog("logout success [IP|1.2.3.4|2.3.4.5][login|foo]");
@@ -287,7 +289,7 @@ public class AuthenticationEventImplTest {
 
   @Test
   public void logout_success_logs_X_Forwarded_For_header_from_request_and_supports_multiple_headers() {
-    HttpServletRequest request = mockRequest("1.2.3.4", asList("2.3.4.5", "6.5.4.3"), asList("9.5.6.7"), asList("6.3.2.4"));
+    HttpRequest request = mockRequest("1.2.3.4", asList("2.3.4.5", "6.5.4.3"), asList("9.5.6.7"), asList("6.3.2.4"));
     underTest.logoutSuccess(request, "foo");
 
     verifyLog("logout success [IP|1.2.3.4|2.3.4.5,6.5.4.3,9.5.6.7,6.3.2.4][login|foo]");
@@ -306,14 +308,14 @@ public class AuthenticationEventImplTest {
   public void login_fails_with_NPE_if_error_message_is_null() {
     logTester.setLevel(LoggerLevel.INFO);
 
-    assertThatThrownBy(() -> underTest.logoutFailure(mock(HttpServletRequest.class), null))
+    assertThatThrownBy(() -> underTest.logoutFailure(mock(HttpRequest.class), null))
       .isInstanceOf(NullPointerException.class)
       .hasMessage("error message can't be null");
   }
 
   @Test
   public void logout_does_not_interact_with_request_if_log_level_is_above_DEBUG() {
-    HttpServletRequest request = mock(HttpServletRequest.class);
+    HttpRequest request = mock(HttpRequest.class);
     logTester.setLevel(LoggerLevel.INFO);
 
     underTest.logoutFailure(request, "bad csrf");
@@ -337,7 +339,7 @@ public class AuthenticationEventImplTest {
 
   @Test
   public void logout_logs_X_Forwarded_For_header_from_request() {
-    HttpServletRequest request = mockRequest("1.2.3.4", asList("2.3.4.5"));
+    HttpRequest request = mockRequest("1.2.3.4", asList("2.3.4.5"));
     underTest.logoutFailure(request, "bad token");
 
     verifyLog("logout failure [error|bad token][IP|1.2.3.4|2.3.4.5]");
@@ -345,7 +347,7 @@ public class AuthenticationEventImplTest {
 
   @Test
   public void logout_logs_X_Forwarded_For_header_from_request_and_supports_multiple_headers() {
-    HttpServletRequest request = mockRequest("1.2.3.4", asList("2.3.4.5", "6.5.4.3"), asList("9.5.6.7"), asList("6.3.2.4"));
+    HttpRequest request = mockRequest("1.2.3.4", asList("2.3.4.5", "6.5.4.3"), asList("9.5.6.7"), asList("6.3.2.4"));
     underTest.logoutFailure(request, "bad token");
 
     verifyLog("logout failure [error|bad token][IP|1.2.3.4|2.3.4.5,6.5.4.3,9.5.6.7,6.3.2.4]");
@@ -357,12 +359,12 @@ public class AuthenticationEventImplTest {
       .containsOnly(expected);
   }
 
-  private static HttpServletRequest mockRequest() {
+  private static HttpRequest mockRequest() {
     return mockRequest("");
   }
 
-  private static HttpServletRequest mockRequest(String remoteAddr, List<String>... remoteIps) {
-    HttpServletRequest res = mock(HttpServletRequest.class);
+  private static HttpRequest mockRequest(String remoteAddr, List<String>... remoteIps) {
+    HttpRequest res = mock(HttpRequest.class);
     when(res.getRemoteAddr()).thenReturn(remoteAddr);
     when(res.getHeaders("X-Forwarded-For"))
       .thenReturn(Collections.enumeration(
index 03b0fa8135fb5fa71e1d5a5290847e8fccd04051..597f85f7cf39ebe6652f18b03e3db64122c0d893 100644 (file)
@@ -26,11 +26,11 @@ import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.util.Base64;
 import java.util.Optional;
-import javax.servlet.http.HttpServletRequest;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.sonar.api.server.http.HttpRequest;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbTester;
 import org.sonar.db.user.UserDto;
@@ -78,7 +78,7 @@ public class UserTokenAuthenticationTest {
   private final TokenGenerator tokenGenerator = mock(TokenGenerator.class);
   private final UserLastConnectionDatesUpdater userLastConnectionDatesUpdater = mock(UserLastConnectionDatesUpdater.class);
   private final AuthenticationEvent authenticationEvent = mock(AuthenticationEvent.class);
-  private final HttpServletRequest request = mock(HttpServletRequest.class);
+  private final HttpRequest request = mock(HttpRequest.class);
   private final UserTokenAuthentication underTest = new UserTokenAuthentication(tokenGenerator, db.getDbClient(), userLastConnectionDatesUpdater, authenticationEvent);
 
   @Before
index 355f060d6c6cc407e6d760eed130178b3e2866bc..8d7470f2a36566a2452ed09a7b7ddc1b46fe7e05 100644 (file)
@@ -21,25 +21,22 @@ package org.sonar.server.plugins;
 
 import java.io.IOException;
 import java.util.Set;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.sonar.api.config.Configuration;
-import org.sonar.api.web.ServletFilter;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.HttpFilter;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.core.extension.PluginRiskConsent;
 import org.sonar.server.user.ThreadLocalUserSession;
 
-import static org.sonar.api.web.ServletFilter.UrlPattern.Builder.staticResourcePatterns;
+import static org.sonar.api.web.UrlPattern.Builder.staticResourcePatterns;
 import static org.sonar.core.config.CorePropertyDefinitions.PLUGINS_RISK_CONSENT;
 import static org.sonar.core.extension.PluginRiskConsent.NOT_ACCEPTED;
 import static org.sonar.core.extension.PluginRiskConsent.REQUIRED;
 import static org.sonar.server.authentication.AuthenticationRedirection.redirectTo;
 
-public class PluginsRiskConsentFilter extends ServletFilter {
+public class PluginsRiskConsentFilter extends HttpFilter {
 
   private static final String PLUGINS_RISK_CONSENT_PATH = "/admin/plugin_risk_consent"; //NOSONAR this path will be the same in every environment
 
@@ -57,14 +54,12 @@ public class PluginsRiskConsentFilter extends ServletFilter {
   }
 
   @Override
-  public void init(FilterConfig filterConfig) throws ServletException {
+  public void init() {
     //nothing to do
   }
 
   @Override
-  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
-    HttpServletRequest request = (HttpServletRequest) servletRequest;
-    HttpServletResponse response = (HttpServletResponse) servletResponse;
+  public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) throws IOException{
     PluginRiskConsent riskConsent = PluginRiskConsent.valueOf(config.get(PLUGINS_RISK_CONSENT).orElse(NOT_ACCEPTED.name()));
 
     if (userSession.hasSession() && userSession.isLoggedIn()
index f7de78c4887362d85ba465ff199f1f0782f4b077..575281794571b16112464defea356ea30f78f2a3 100644 (file)
 package org.sonar.server.plugins;
 
 import java.util.Optional;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletRequest;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.sonar.api.config.Configuration;
-import org.sonar.api.web.ServletFilter;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.core.extension.PluginRiskConsent;
 import org.sonar.server.user.ThreadLocalUserSession;
 
@@ -44,8 +43,8 @@ public class PluginsRiskConsentFilterTest {
   private Configuration configuration;
   private ThreadLocalUserSession userSession;
 
-  private ServletRequest servletRequest;
-  private HttpServletResponse servletResponse;
+  private HttpRequest request;
+  private HttpResponse response;
   private FilterChain chain;
 
   @Before
@@ -54,8 +53,8 @@ public class PluginsRiskConsentFilterTest {
     when(configuration.get(PLUGINS_RISK_CONSENT)).thenReturn(Optional.of(PluginRiskConsent.REQUIRED.name()));
     userSession = mock(ThreadLocalUserSession.class);
 
-    servletRequest = mock(HttpServletRequest.class);
-    servletResponse = mock(HttpServletResponse.class);
+    request = mock(HttpRequest.class);
+    response = mock(HttpResponse.class);
     chain = mock(FilterChain.class);
   }
 
@@ -65,9 +64,9 @@ public class PluginsRiskConsentFilterTest {
 
     when(userSession.hasSession()).thenReturn(true);
 
-    consentFilter.doFilter(servletRequest, servletResponse, chain);
+    consentFilter.doFilter(request, response, chain);
 
-    verify(servletResponse, times(0)).sendRedirect(Mockito.anyString());
+    verify(response, times(0)).sendRedirect(Mockito.anyString());
   }
 
   @Test
@@ -77,9 +76,9 @@ public class PluginsRiskConsentFilterTest {
     when(userSession.hasSession()).thenReturn(true);
     when(userSession.isLoggedIn()).thenReturn(false);
 
-    consentFilter.doFilter(servletRequest, servletResponse, chain);
+    consentFilter.doFilter(request, response, chain);
 
-    verify(servletResponse, times(0)).sendRedirect(Mockito.anyString());
+    verify(response, times(0)).sendRedirect(Mockito.anyString());
   }
 
   @Test
@@ -90,9 +89,9 @@ public class PluginsRiskConsentFilterTest {
     when(userSession.isLoggedIn()).thenReturn(false);
     when(configuration.get(PLUGINS_RISK_CONSENT)).thenReturn(Optional.of(PluginRiskConsent.REQUIRED.name()));
 
-    consentFilter.doFilter(servletRequest, servletResponse, chain);
+    consentFilter.doFilter(request, response, chain);
 
-    verify(servletResponse, times(0)).sendRedirect(Mockito.anyString());
+    verify(response, times(0)).sendRedirect(Mockito.anyString());
   }
 
   @Test
@@ -103,9 +102,9 @@ public class PluginsRiskConsentFilterTest {
     when(userSession.isLoggedIn()).thenReturn(false);
     when(configuration.get(PLUGINS_RISK_CONSENT)).thenReturn(Optional.of(PluginRiskConsent.ACCEPTED.name()));
 
-    consentFilter.doFilter(servletRequest, servletResponse, chain);
+    consentFilter.doFilter(request, response, chain);
 
-    verify(servletResponse, times(0)).sendRedirect(Mockito.anyString());
+    verify(response, times(0)).sendRedirect(Mockito.anyString());
   }
 
   @Test
@@ -116,9 +115,9 @@ public class PluginsRiskConsentFilterTest {
     when(userSession.isLoggedIn()).thenReturn(true);
     when(userSession.isSystemAdministrator()).thenReturn(false);
 
-    consentFilter.doFilter(servletRequest, servletResponse, chain);
+    consentFilter.doFilter(request, response, chain);
 
-    verify(servletResponse, times(0)).sendRedirect(Mockito.anyString());
+    verify(response, times(0)).sendRedirect(Mockito.anyString());
   }
 
   @Test
@@ -130,9 +129,9 @@ public class PluginsRiskConsentFilterTest {
     when(userSession.isSystemAdministrator()).thenReturn(false);
     when(configuration.get(PLUGINS_RISK_CONSENT)).thenReturn(Optional.of(PluginRiskConsent.REQUIRED.name()));
 
-    consentFilter.doFilter(servletRequest, servletResponse, chain);
+    consentFilter.doFilter(request, response, chain);
 
-    verify(servletResponse, times(0)).sendRedirect(Mockito.anyString());
+    verify(response, times(0)).sendRedirect(Mockito.anyString());
   }
 
   @Test
@@ -143,9 +142,9 @@ public class PluginsRiskConsentFilterTest {
     when(userSession.isLoggedIn()).thenReturn(true);
     when(userSession.isSystemAdministrator()).thenReturn(true);
 
-    consentFilter.doFilter(servletRequest, servletResponse, chain);
+    consentFilter.doFilter(request, response, chain);
 
-    verify(servletResponse, times(1)).sendRedirect(Mockito.anyString());
+    verify(response, times(1)).sendRedirect(Mockito.anyString());
   }
 
   @Test
@@ -157,16 +156,16 @@ public class PluginsRiskConsentFilterTest {
     when(userSession.isSystemAdministrator()).thenReturn(true);
     when(configuration.get(PLUGINS_RISK_CONSENT)).thenReturn(Optional.of(PluginRiskConsent.ACCEPTED.name()));
 
-    consentFilter.doFilter(servletRequest, servletResponse, chain);
+    consentFilter.doFilter(request, response, chain);
 
-    verify(servletResponse, times(0)).sendRedirect(Mockito.anyString());
+    verify(response, times(0)).sendRedirect(Mockito.anyString());
   }
 
   @Test
   public void doGetPattern_excludesNotEmpty() {
     PluginsRiskConsentFilter consentFilter = new PluginsRiskConsentFilter(configuration, userSession);
 
-    ServletFilter.UrlPattern urlPattern = consentFilter.doGetPattern();
+    UrlPattern urlPattern = consentFilter.doGetPattern();
 
     assertThat(urlPattern.getExclusions()).isNotEmpty();
 
index 792e919170d1429c0fd5cfc014403e18789e570c..8e1f1397b1a67f3ba78cd6fa89258192e0dd07ac 100644 (file)
@@ -32,18 +32,27 @@ import java.util.Map;
 import javax.annotation.CheckForNull;
 import javax.servlet.http.HttpServletResponse;
 import org.apache.commons.io.IOUtils;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.utils.text.JsonWriter;
 import org.sonar.api.utils.text.XmlWriter;
+import org.sonar.server.http.JavaxHttpResponse;
 import org.sonar.server.ws.ServletResponse;
 import org.sonar.server.ws.TestableResponse;
 
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class DumbPushResponse extends ServletResponse implements TestableResponse {
 
   public DumbPushResponse() {
-    super(mock(HttpServletResponse.class));
+    super(initMock());
+  }
+
+  private static HttpResponse initMock() {
+    JavaxHttpResponse mock = mock(JavaxHttpResponse.class);
+    when(mock.getDelegate()).thenReturn(mock(HttpServletResponse.class));
+    return mock;
   }
 
   private DumbPushResponse.InMemoryStream stream;
index 6dab22ea152b7ab8d69ac5a0ef8751daffe4051a..83cf2280a05e7b51b1965502e9090339702001a8 100644 (file)
@@ -41,6 +41,7 @@ import com.google.common.base.Throwables;
 import java.util.Map;
 import java.util.Optional;
 import javax.servlet.AsyncContext;
+import org.sonar.server.http.JavaxHttpRequest;
 import org.sonar.server.ws.ServletRequest;
 import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.TestResponse;
@@ -52,7 +53,7 @@ public class TestPushRequest extends ServletRequest {
   private TestRequest testRequest = new TestRequest();
 
   public TestPushRequest() {
-    super(null);
+    super(mock(JavaxHttpRequest.class));
   }
 
   @Override
index 364c0b4f25a3caa8cc8ec73465460c6cade6e52a..e9f7ce8169dc12d76cb971bb55748d2d761c43d6 100644 (file)
  */
 package org.sonar.server.authentication.ws;
 
-import javax.servlet.FilterChain;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.System2;
+import org.sonar.api.web.FilterChain;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
@@ -60,23 +60,23 @@ public class LoginActionIT {
   @Rule
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
 
-  private DbClient dbClient = dbTester.getDbClient();
+  private final DbClient dbClient = dbTester.getDbClient();
 
-  private DbSession dbSession = dbTester.getSession();
+  private final DbSession dbSession = dbTester.getSession();
 
-  private ThreadLocalUserSession threadLocalUserSession = new ThreadLocalUserSession();
+  private final ThreadLocalUserSession threadLocalUserSession = new ThreadLocalUserSession();
 
-  private HttpServletRequest request = mock(HttpServletRequest.class);
-  private HttpServletResponse response = mock(HttpServletResponse.class);
-  private FilterChain chain = mock(FilterChain.class);
+  private final HttpRequest request = mock(HttpRequest.class);
+  private final HttpResponse response = mock(HttpResponse.class);
+  private final FilterChain chain = mock(FilterChain.class);
 
-  private CredentialsAuthentication credentialsAuthentication = mock(CredentialsAuthentication.class);
-  private JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
-  private AuthenticationEvent authenticationEvent = mock(AuthenticationEvent.class);
-  private TestUserSessionFactory userSessionFactory = TestUserSessionFactory.standalone();
+  private final CredentialsAuthentication credentialsAuthentication = mock(CredentialsAuthentication.class);
+  private final JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
+  private final AuthenticationEvent authenticationEvent = mock(AuthenticationEvent.class);
+  private final TestUserSessionFactory userSessionFactory = TestUserSessionFactory.standalone();
 
-  private UserDto user = UserTesting.newUserDto().setLogin(LOGIN);
-  private LoginAction underTest = new LoginAction(credentialsAuthentication, jwtHttpHandler, threadLocalUserSession, authenticationEvent, userSessionFactory);
+  private final UserDto user = UserTesting.newUserDto().setLogin(LOGIN);
+  private final LoginAction underTest = new LoginAction(credentialsAuthentication, jwtHttpHandler, threadLocalUserSession, authenticationEvent, userSessionFactory);
 
   @Before
   public void setUp() {
@@ -131,7 +131,7 @@ public class LoginActionIT {
   }
 
   @Test
-  public void return_authorized_code_when_unauthorized_exception_is_thrown() throws Exception {
+  public void return_authorized_code_when_unauthorized_exception_is_thrown() {
     doThrow(new UnauthorizedException("error !")).when(credentialsAuthentication).authenticate(new Credentials(LOGIN, PASSWORD), request, FORM);
 
     executeRequest(LOGIN, PASSWORD);
@@ -142,28 +142,28 @@ public class LoginActionIT {
   }
 
   @Test
-  public void return_unauthorized_code_when_no_login() throws Exception {
+  public void return_unauthorized_code_when_no_login() {
     executeRequest(null, PASSWORD);
     verify(response).setStatus(401);
     verify(authenticationEvent).loginFailure(eq(request), any(AuthenticationException.class));
   }
 
   @Test
-  public void return_unauthorized_code_when_empty_login() throws Exception {
+  public void return_unauthorized_code_when_empty_login() {
     executeRequest("", PASSWORD);
     verify(response).setStatus(401);
     verify(authenticationEvent).loginFailure(eq(request), any(AuthenticationException.class));
   }
 
   @Test
-  public void return_unauthorized_code_when_no_password() throws Exception {
+  public void return_unauthorized_code_when_no_password() {
     executeRequest(LOGIN, null);
     verify(response).setStatus(401);
     verify(authenticationEvent).loginFailure(eq(request), any(AuthenticationException.class));
   }
 
   @Test
-  public void return_unauthorized_code_when_empty_password() throws Exception {
+  public void return_unauthorized_code_when_empty_password() {
     executeRequest(LOGIN, "");
     verify(response).setStatus(401);
     verify(authenticationEvent).loginFailure(eq(request), any(AuthenticationException.class));
index a1fdd23020dcb726991794c4b603823b93054dc6..83b30b34dba7639605a931e644814b88298c3b81 100644 (file)
@@ -22,17 +22,17 @@ package org.sonar.server.user.ws;
 import java.io.IOException;
 import java.util.Optional;
 import javax.annotation.Nullable;
-import javax.servlet.FilterChain;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.WriteListener;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.server.ws.WebService;
+import org.sonar.api.web.FilterChain;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.audit.NoOpAuditPersister;
@@ -75,8 +75,8 @@ public class ChangePasswordActionIT {
 
   private final ArgumentCaptor<UserDto> userDtoCaptor = ArgumentCaptor.forClass(UserDto.class);
 
-  private final HttpServletRequest request = mock(HttpServletRequest.class);
-  private final HttpServletResponse response = mock(HttpServletResponse.class);
+  private final HttpRequest request = mock(HttpRequest.class);
+  private final HttpResponse response = mock(HttpResponse.class);
   private final FilterChain chain = mock(FilterChain.class);
 
   private final MapSettings settings = new MapSettings().setProperty("sonar.internal.pbkdf2.iterations", "1");
@@ -88,7 +88,7 @@ public class ChangePasswordActionIT {
 
   private final JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
 
-  private final ChangePasswordAction changePasswordAction = new ChangePasswordAction(db.getDbClient(), userUpdater, userSessionRule, localAuthentication, jwtHttpHandler);
+  private final ChangePasswordAction underTest = new ChangePasswordAction(db.getDbClient(), userUpdater, userSessionRule, localAuthentication, jwtHttpHandler);
   private ServletOutputStream responseOutputStream;
 
   @Before
@@ -147,7 +147,8 @@ public class ChangePasswordActionIT {
     userSessionRule.logIn(user.getLogin());
     UserTestData anotherLocalUser = createLocalUser();
 
-    assertThatThrownBy(() -> executeTest(anotherLocalUser.getLogin(), "I dunno", NEW_PASSWORD))
+    String anotherLocalUserLogin = anotherLocalUser.getLogin();
+    assertThatThrownBy(() -> executeTest(anotherLocalUserLogin, "I dunno", NEW_PASSWORD))
       .isInstanceOf(ForbiddenException.class);
     verifyNoInteractions(jwtHttpHandler);
     assertThat(findSessionTokenDto(db.getSession(), user.getSessionTokenUuid())).isPresent();
@@ -184,9 +185,10 @@ public class ChangePasswordActionIT {
     UserDto user = db.users().insertUser(u -> u.setActive(false));
     userSessionRule.logIn(user);
 
-    assertThatThrownBy(() -> executeTest(user.getLogin(), null, "polop"))
+    String userLogin = user.getLogin();
+    assertThatThrownBy(() -> executeTest(userLogin, null, "polop"))
       .isInstanceOf(NotFoundException.class)
-      .hasMessage(format("User with login '%s' has not been found", user.getLogin()));
+      .hasMessage(format("User with login '%s' has not been found", userLogin));
     verifyNoInteractions(jwtHttpHandler);
   }
 
@@ -218,7 +220,6 @@ public class ChangePasswordActionIT {
     UserTestData user = createLocalUser();
     userSessionRule.logIn(user.userDto());
 
-
     executeTest(user.getLogin(), OLD_PASSWORD, null);
     verify(response).setStatus(HTTP_BAD_REQUEST);
     assertThat(responseOutputStream).hasToString("{\"result\":\"The 'password' parameter is missing\"}");
@@ -267,7 +268,7 @@ public class ChangePasswordActionIT {
     WebService.Context context = new WebService.Context();
     WebService.NewController newController = context.createController(controllerKey);
 
-    changePasswordAction.define(newController);
+    underTest.define(newController);
     newController.done();
 
     WebService.Action changePassword = context.controller(controllerKey).action("change_password");
@@ -283,7 +284,7 @@ public class ChangePasswordActionIT {
     when(request.getParameter(PARAM_LOGIN)).thenReturn(login);
     when(request.getParameter(PARAM_PREVIOUS_PASSWORD)).thenReturn(oldPassword);
     when(request.getParameter(PARAM_PASSWORD)).thenReturn(newPassword);
-    changePasswordAction.doFilter(request, response, chain);
+    underTest.doFilter(request, response, chain);
   }
 
   private UserTestData createLocalUser(String password) {
index 3c8eb7c21e6cee3d5f8abf001494b1742f1e4ed5..a1c0b780f0e5c16fa23c88765c33ded360715e30 100644 (file)
  */
 package org.sonar.server.authentication.ws;
 
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.api.web.ServletFilter;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.HttpFilter;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.authentication.Credentials;
 import org.sonar.server.authentication.CredentialsAuthentication;
@@ -46,7 +44,7 @@ import static org.sonar.server.authentication.event.AuthenticationEvent.Source;
 import static org.sonar.server.authentication.ws.AuthenticationWs.AUTHENTICATION_CONTROLLER;
 import static org.sonarqube.ws.client.WsRequest.Method.POST;
 
-public class LoginAction extends ServletFilter implements AuthenticationWsAction {
+public class LoginAction extends HttpFilter implements AuthenticationWsAction {
 
   private static final String LOGIN_ACTION = "login";
   public static final String LOGIN_URL = "/" + AUTHENTICATION_CONTROLLER + "/" + LOGIN_ACTION;
@@ -87,10 +85,7 @@ public class LoginAction extends ServletFilter implements AuthenticationWsAction
   }
 
   @Override
-  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) {
-    HttpServletRequest request = (HttpServletRequest) servletRequest;
-    HttpServletResponse response = (HttpServletResponse) servletResponse;
-
+  public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) {
     if (!request.getMethod().equals(POST.name())) {
       response.setStatus(HTTP_BAD_REQUEST);
       return;
@@ -108,7 +103,7 @@ public class LoginAction extends ServletFilter implements AuthenticationWsAction
     }
   }
 
-  private UserDto authenticate(HttpServletRequest request) {
+  private UserDto authenticate(HttpRequest request) {
     String login = request.getParameter("login");
     String password = request.getParameter("password");
     if (isEmpty(login) || isEmpty(password)) {
@@ -122,7 +117,7 @@ public class LoginAction extends ServletFilter implements AuthenticationWsAction
   }
 
   @Override
-  public void init(FilterConfig filterConfig) {
+  public void init() {
     // Nothing to do
   }
 
index 32990dfa2b00a22153d8037fc075c2640c6832ae..f655bfa3d7b73ce56c24c4162ef8918ec07807af 100644 (file)
 package org.sonar.server.authentication.ws;
 
 import java.util.Optional;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.api.web.ServletFilter;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.HttpFilter;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.server.authentication.JwtHttpHandler;
 import org.sonar.server.authentication.event.AuthenticationEvent;
 import org.sonar.server.authentication.event.AuthenticationException;
@@ -37,7 +35,7 @@ import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
 import static org.sonar.server.authentication.ws.AuthenticationWs.AUTHENTICATION_CONTROLLER;
 import static org.sonarqube.ws.client.WsRequest.Method.POST;
 
-public class LogoutAction extends ServletFilter implements AuthenticationWsAction {
+public class LogoutAction extends HttpFilter implements AuthenticationWsAction {
 
   private static final String LOGOUT_ACTION = "logout";
   public static final String LOGOUT_URL = "/" + AUTHENTICATION_CONTROLLER + "/" + LOGOUT_ACTION;
@@ -65,10 +63,7 @@ public class LogoutAction extends ServletFilter implements AuthenticationWsActio
   }
 
   @Override
-  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) {
-    HttpServletRequest request = (HttpServletRequest) servletRequest;
-    HttpServletResponse response = (HttpServletResponse) servletResponse;
-
+  public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) {
     if (!request.getMethod().equals(POST.name())) {
       response.setStatus(HTTP_BAD_REQUEST);
       return;
@@ -76,7 +71,7 @@ public class LogoutAction extends ServletFilter implements AuthenticationWsActio
     logout(request, response);
   }
 
-  private void logout(HttpServletRequest request, HttpServletResponse response) {
+  private void logout(HttpRequest request, HttpResponse response) {
     generateAuthenticationEvent(request, response);
     jwtHttpHandler.removeToken(request, response);
   }
@@ -84,7 +79,7 @@ public class LogoutAction extends ServletFilter implements AuthenticationWsActio
   /**
    * The generation of the authentication event should not prevent the removal of JWT cookie, that's why it's done in a separate method
    */
-  private void generateAuthenticationEvent(HttpServletRequest request, HttpServletResponse response) {
+  private void generateAuthenticationEvent(HttpRequest request, HttpResponse response) {
     try {
       Optional<JwtHttpHandler.Token> token = jwtHttpHandler.getToken(request, response);
       String userLogin = token.map(value -> value.getUserDto().getLogin()).orElse(null);
@@ -95,7 +90,7 @@ public class LogoutAction extends ServletFilter implements AuthenticationWsActio
   }
 
   @Override
-  public void init(FilterConfig filterConfig) {
+  public void init() {
     // Nothing to do
   }
 
index 1bc34b1299751c991eea3161452d2124f06b157f..476489706204b04fe1f7f6899a0eca6533b4fbc7 100644 (file)
@@ -22,16 +22,14 @@ package org.sonar.server.authentication.ws;
 import com.google.common.io.Resources;
 import java.io.IOException;
 import java.util.Optional;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.sonar.api.config.Configuration;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.api.web.ServletFilter;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.HttpFilter;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.authentication.BasicAuthentication;
 import org.sonar.server.authentication.JwtHttpHandler;
@@ -43,7 +41,7 @@ import static org.sonar.api.CoreProperties.CORE_FORCE_AUTHENTICATION_DEFAULT_VAL
 import static org.sonar.api.CoreProperties.CORE_FORCE_AUTHENTICATION_PROPERTY;
 import static org.sonar.server.authentication.ws.AuthenticationWs.AUTHENTICATION_CONTROLLER;
 
-public class ValidateAction extends ServletFilter implements AuthenticationWsAction {
+public class ValidateAction extends HttpFilter implements AuthenticationWsAction {
 
   private static final String VALIDATE_ACTION = "validate";
   public static final String VALIDATE_URL = "/" + AUTHENTICATION_CONTROLLER + "/" + VALIDATE_ACTION;
@@ -73,10 +71,7 @@ public class ValidateAction extends ServletFilter implements AuthenticationWsAct
   }
 
   @Override
-  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException {
-    HttpServletRequest request = (HttpServletRequest) servletRequest;
-    HttpServletResponse response = (HttpServletResponse) servletResponse;
-
+  public void doFilter(HttpRequest request, HttpResponse response, FilterChain filterChain) throws IOException {
     boolean isAuthenticated = authenticate(request, response);
     response.setContentType(MediaTypes.JSON);
 
@@ -87,7 +82,7 @@ public class ValidateAction extends ServletFilter implements AuthenticationWsAct
     }
   }
 
-  private boolean authenticate(HttpServletRequest request, HttpServletResponse response) {
+  private boolean authenticate(HttpRequest request, HttpResponse response) {
     try {
       Optional<UserDto> user = jwtHttpHandler.validateToken(request, response);
       if (user.isPresent()) {
@@ -104,7 +99,7 @@ public class ValidateAction extends ServletFilter implements AuthenticationWsAct
   }
 
   @Override
-  public void init(FilterConfig filterConfig) {
+  public void init() {
     // Nothing to do
   }
 
index c55a99f37f763194dbbbea317db5311aa69a9ad5..8a2b55341800965831bac5702ab17402100e9132 100644 (file)
@@ -22,15 +22,14 @@ package org.sonar.server.saml.ws;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.stream.Collectors;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequestWrapper;
-import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.api.web.ServletFilter;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.HttpFilter;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.auth.saml.SamlAuthenticator;
 import org.sonar.auth.saml.SamlIdentityProvider;
 import org.sonar.server.authentication.AuthenticationError;
@@ -39,12 +38,13 @@ import org.sonar.server.authentication.OAuthCsrfVerifier;
 import org.sonar.server.authentication.SamlValidationCspHeaders;
 import org.sonar.server.authentication.SamlValidationRedirectionFilter;
 import org.sonar.server.authentication.event.AuthenticationException;
+import org.sonar.server.http.JavaxHttpRequest;
 import org.sonar.server.user.ThreadLocalUserSession;
 import org.sonar.server.ws.ServletFilterHandler;
 
 import static org.sonar.server.saml.ws.SamlValidationWs.SAML_VALIDATION_CONTROLLER;
 
-public class ValidationAction extends ServletFilter implements SamlAction {
+public class ValidationAction extends HttpFilter implements SamlAction {
 
   static final String VALIDATION_CALLBACK_KEY = SamlValidationRedirectionFilter.SAML_VALIDATION_KEY;
   private static final String URL_DELIMITER = "/";
@@ -69,35 +69,32 @@ public class ValidationAction extends ServletFilter implements SamlAction {
   }
 
   @Override
-  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
-    HttpServletResponse httpResponse = (HttpServletResponse) response;
-    HttpServletRequest httpRequest = (HttpServletRequest) request;
-
+  public void doFilter(HttpRequest request, HttpResponse response, FilterChain filterChain) throws IOException {
     try {
-      oAuthCsrfVerifier.verifyState(httpRequest, httpResponse, samlIdentityProvider, "CSRFToken");
+      oAuthCsrfVerifier.verifyState(request, response, samlIdentityProvider, "CSRFToken");
     } catch (AuthenticationException exception) {
-      AuthenticationError.handleError(httpRequest, httpResponse, exception.getMessage());
+      AuthenticationError.handleError(request, response, exception.getMessage());
       return;
     }
 
     if (!userSession.hasSession() || !userSession.isSystemAdministrator()) {
-      AuthenticationError.handleError(httpRequest, httpResponse, "User needs to be logged in as system administrator to access this page.");
+      AuthenticationError.handleError(request, response, "User needs to be logged in as system administrator to access this page.");
       return;
     }
 
-    httpRequest = new HttpServletRequestWrapper(httpRequest) {
+    HttpServletRequest httpRequest = new HttpServletRequestWrapper(((JavaxHttpRequest) request).getDelegate()) {
       @Override
       public StringBuffer getRequestURL() {
         return new StringBuffer(oAuth2ContextFactory.generateCallbackUrl(SamlIdentityProvider.KEY));
       }
     };
 
-    httpResponse.setContentType("text/html");
+    response.setContentType("text/html");
 
-    String htmlResponse = samlAuthenticator.getAuthenticationStatusPage(httpRequest, httpResponse);
-    String nonce = SamlValidationCspHeaders.addCspHeadersWithNonceToResponse(httpResponse);
+    String htmlResponse = samlAuthenticator.getAuthenticationStatusPage(new JavaxHttpRequest(httpRequest), response);
+    String nonce = SamlValidationCspHeaders.addCspHeadersWithNonceToResponse(response);
     htmlResponse = htmlResponse.replace("%NONCE%", nonce);
-    httpResponse.getWriter().print(htmlResponse);
+    response.getWriter().print(htmlResponse);
   }
 
   @Override
index 6ec10cbf3583e6f751490da9de4744e03961f7b3..9960cb09151e0d6fa836d241321dd7e84419fca6 100644 (file)
 package org.sonar.server.saml.ws;
 
 import java.io.IOException;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.api.web.ServletFilter;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.HttpFilter;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.auth.saml.SamlAuthenticator;
 import org.sonar.auth.saml.SamlIdentityProvider;
 import org.sonar.server.authentication.AuthenticationError;
@@ -40,7 +38,7 @@ import org.sonar.server.ws.ServletFilterHandler;
 import static org.sonar.server.authentication.SamlValidationRedirectionFilter.SAML_VALIDATION_CONTROLLER_CONTEXT;
 import static org.sonar.server.authentication.SamlValidationRedirectionFilter.SAML_VALIDATION_KEY;
 
-public class ValidationInitAction extends ServletFilter implements SamlAction {
+public class ValidationInitAction extends HttpFilter implements SamlAction {
 
   public static final String VALIDATION_RELAY_STATE = "validation-query";
   public static final String VALIDATION_INIT_KEY = "validation_init";
@@ -73,10 +71,7 @@ public class ValidationInitAction extends ServletFilter implements SamlAction {
   }
 
   @Override
-  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
-    HttpServletRequest request = (HttpServletRequest) servletRequest;
-    HttpServletResponse response = (HttpServletResponse) servletResponse;
-
+  public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) throws IOException {
     try {
       userSession.checkIsSystemAdministrator();
     } catch (ForbiddenException e) {
@@ -84,7 +79,7 @@ public class ValidationInitAction extends ServletFilter implements SamlAction {
       return;
     }
 
-    String csrfState = oAuthCsrfVerifier.generateState(request,response);
+    String csrfState = oAuthCsrfVerifier.generateState(request, response);
 
     try {
       samlAuthenticator.initLogin(oAuth2ContextFactory.generateCallbackUrl(SamlIdentityProvider.KEY),
index c437c68568e60cb495470782a1d930f281e2b9ef..accc04598a5d6f68f403b2a0b55036128d6a47df 100644 (file)
@@ -25,16 +25,15 @@ import com.google.gson.stream.JsonWriter;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.util.Optional;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.server.ws.Change;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
-import org.sonar.api.web.ServletFilter;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.HttpFilter;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.user.UserDto;
@@ -61,7 +60,7 @@ import static org.sonarqube.ws.client.user.UsersWsParameters.PARAM_LOGIN;
 import static org.sonarqube.ws.client.user.UsersWsParameters.PARAM_PASSWORD;
 import static org.sonarqube.ws.client.user.UsersWsParameters.PARAM_PREVIOUS_PASSWORD;
 
-public class ChangePasswordAction extends ServletFilter implements BaseUsersWsAction {
+public class ChangePasswordAction extends HttpFilter implements BaseUsersWsAction {
 
   private static final Logger LOG = Loggers.get(ChangePasswordAction.class);
 
@@ -117,7 +116,7 @@ public class ChangePasswordAction extends ServletFilter implements BaseUsersWsAc
   }
 
   @Override
-  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
+  public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) {
     userSession.checkLoggedIn();
     try (DbSession dbSession = dbClient.openSession(false)) {
       String login = getParamOrThrow(request, PARAM_LOGIN);
@@ -148,7 +147,7 @@ public class ChangePasswordAction extends ServletFilter implements BaseUsersWsAc
     }
   }
 
-  private static String getParamOrThrow(ServletRequest request, String key) throws PasswordException {
+  private static String getParamOrThrow(HttpRequest request, String key) throws PasswordException {
     String value = request.getParameter(key);
     if (isNullOrEmpty(value)) {
       throw new PasswordException(format(MSG_PARAMETER_MISSING, key));
@@ -178,16 +177,14 @@ public class ChangePasswordAction extends ServletFilter implements BaseUsersWsAc
     return user;
   }
 
-  private void deleteTokensAndRefreshSession(ServletRequest request, ServletResponse response, DbSession dbSession, UserDto user) {
+  private void deleteTokensAndRefreshSession(HttpRequest request, HttpResponse response, DbSession dbSession, UserDto user) {
     dbClient.sessionTokensDao().deleteByUser(dbSession, user);
     refreshJwtToken(request, response, user);
   }
 
-  private void refreshJwtToken(ServletRequest request, ServletResponse response, UserDto user) {
-    HttpServletRequest httpRequest = (HttpServletRequest) request;
-    HttpServletResponse httpResponse = (HttpServletResponse) response;
-    jwtHttpHandler.removeToken(httpRequest, httpResponse);
-    jwtHttpHandler.generateToken(user, httpRequest, httpResponse);
+  private void refreshJwtToken(HttpRequest request, HttpResponse response, UserDto user) {
+    jwtHttpHandler.removeToken(request, response);
+    jwtHttpHandler.generateToken(user, request, response);
   }
 
   private void updatePassword(DbSession dbSession, UserDto user, String newPassword) {
@@ -196,14 +193,15 @@ public class ChangePasswordAction extends ServletFilter implements BaseUsersWsAc
     });
   }
 
-  private static void setResponseStatus(ServletResponse response, int newStatusCode) {
-    ((HttpServletResponse) response).setStatus(newStatusCode);
+  private static void setResponseStatus(HttpResponse response, int newStatusCode) {
+    response.setStatus(newStatusCode);
   }
 
-  private static void writeJsonResponse(String msg, ServletResponse response) {
+  private static void writeJsonResponse(String msg, HttpResponse response) {
     Gson gson = new GsonBuilder()
       .disableHtmlEscaping()
       .create();
+
     try (OutputStream output = response.getOutputStream();
          JsonWriter writer = gson.newJsonWriter(new OutputStreamWriter(output, UTF_8))) {
       response.setContentType(JSON);
index bb7f24fe94586e2bc7000f59c399ca5c54630bb0..168c29d9335cdb81afa34fedfc7ca4096bc397a4 100644 (file)
@@ -21,14 +21,11 @@ package org.sonar.server.authentication.ws;
 
 import java.util.Collections;
 import java.util.Optional;
-import javax.servlet.FilterChain;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.junit.Rule;
 import org.junit.Test;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.api.utils.System2;
-import org.sonar.db.DbTester;
+import org.sonar.api.web.FilterChain;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.authentication.JwtHttpHandler;
 import org.sonar.server.authentication.event.AuthenticationEvent;
@@ -49,15 +46,14 @@ public class LogoutActionTest {
 
   private static final UserDto USER = newUserDto().setLogin("john");
 
+  private final HttpRequest request = mock(HttpRequest.class);
+  private final HttpResponse response = mock(HttpResponse.class);
+  private final FilterChain chain = mock(FilterChain.class);
 
-  private HttpServletRequest request = mock(HttpServletRequest.class);
-  private HttpServletResponse response = mock(HttpServletResponse.class);
-  private FilterChain chain = mock(FilterChain.class);
+  private final JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
+  private final AuthenticationEvent authenticationEvent = mock(AuthenticationEvent.class);
 
-  private JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
-  private AuthenticationEvent authenticationEvent = mock(AuthenticationEvent.class);
-
-  private LogoutAction underTest = new LogoutAction(jwtHttpHandler, authenticationEvent);
+  private final LogoutAction underTest = new LogoutAction(jwtHttpHandler, authenticationEvent);
 
   @Test
   public void verify_definition() {
@@ -119,12 +115,12 @@ public class LogoutActionTest {
   public void generate_auth_event_on_failure() {
     setUser(USER);
     AuthenticationException exception = AuthenticationException.newBuilder().setMessage("error!").setSource(sso()).build();
-    doThrow(exception).when(jwtHttpHandler).getToken(any(HttpServletRequest.class), any(HttpServletResponse.class));
+    doThrow(exception).when(jwtHttpHandler).getToken(any(HttpRequest.class), any(HttpResponse.class));
 
     executeRequest();
 
     verify(authenticationEvent).logoutFailure(request, "error!");
-    verify(jwtHttpHandler).removeToken(any(HttpServletRequest.class), any(HttpServletResponse.class));
+    verify(jwtHttpHandler).removeToken(any(HttpRequest.class), any(HttpResponse.class));
     verifyNoInteractions(chain);
   }
 
@@ -134,12 +130,12 @@ public class LogoutActionTest {
   }
 
   private void setUser(UserDto user) {
-    when(jwtHttpHandler.getToken(any(HttpServletRequest.class), any(HttpServletResponse.class)))
+    when(jwtHttpHandler.getToken(any(HttpRequest.class), any(HttpResponse.class)))
       .thenReturn(Optional.of(new JwtHttpHandler.Token(user, Collections.emptyMap())));
   }
 
   private void setNoUser() {
-    when(jwtHttpHandler.getToken(any(HttpServletRequest.class), any(HttpServletResponse.class))).thenReturn(Optional.empty());
+    when(jwtHttpHandler.getToken(any(HttpRequest.class), any(HttpResponse.class))).thenReturn(Optional.empty());
   }
 
 }
index b6258f62367a6f416cfbb0520604a8409095c8b5..f41f4797cdf2574846e1ddd75764c48e316667b5 100644 (file)
@@ -22,13 +22,13 @@ package org.sonar.server.authentication.ws;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.Optional;
-import javax.servlet.FilterChain;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.server.ws.WebService;
+import org.sonar.api.web.FilterChain;
 import org.sonar.server.authentication.BasicAuthentication;
 import org.sonar.server.authentication.JwtHttpHandler;
 import org.sonar.server.authentication.event.AuthenticationException;
@@ -45,18 +45,18 @@ import static org.sonar.db.user.UserTesting.newUserDto;
 
 public class ValidateActionTest {
 
-  StringWriter stringWriter = new StringWriter();
+  private final StringWriter stringWriter = new StringWriter();
 
-  HttpServletRequest request = mock(HttpServletRequest.class);
-  HttpServletResponse response = mock(HttpServletResponse.class);
-  FilterChain chain = mock(FilterChain.class);
+  private final HttpRequest request = mock(HttpRequest.class);
+  private final HttpResponse response = mock(HttpResponse.class);
+  private final FilterChain chain = mock(FilterChain.class);
 
-  BasicAuthentication basicAuthentication = mock(BasicAuthentication.class);
-  JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
+  private final BasicAuthentication basicAuthentication = mock(BasicAuthentication.class);
+  private final JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
 
-  MapSettings settings = new MapSettings();
+  private final MapSettings settings = new MapSettings();
 
-  ValidateAction underTest = new ValidateAction(settings.asConfig(), basicAuthentication, jwtHttpHandler);
+  private final ValidateAction underTest = new ValidateAction(settings.asConfig(), basicAuthentication, jwtHttpHandler);
 
   @Before
   public void setUp() throws Exception {
index 659f9dc956a082ac4a3f71b7a712c718c34f720e..8e293ee563987b6ca8fc2beb15fa7ca1c095c1f9 100644 (file)
@@ -23,20 +23,22 @@ import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.List;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Test;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.server.ws.WebService;
+import org.sonar.api.web.FilterChain;
 import org.sonar.auth.saml.SamlAuthenticator;
 import org.sonar.auth.saml.SamlIdentityProvider;
 import org.sonar.server.authentication.OAuth2ContextFactory;
 import org.sonar.server.authentication.OAuthCsrfVerifier;
-import org.sonar.server.authentication.SamlValidationCspHeaders;
 import org.sonar.server.authentication.event.AuthenticationEvent;
 import org.sonar.server.authentication.event.AuthenticationException;
+import org.sonar.server.http.JavaxHttpRequest;
+import org.sonar.server.http.JavaxHttpResponse;
 import org.sonar.server.user.ThreadLocalUserSession;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -70,7 +72,6 @@ public class ValidationActionTest {
     underTest = new ValidationAction(userSession, samlAuthenticator, oAuth2ContextFactory, samlIdentityProvider, oAuthCsrfVerifier);
   }
 
-
   @Test
   public void do_get_pattern() {
     assertThat(underTest.doGetPattern().matches("/saml/validation")).isTrue();
@@ -81,8 +82,8 @@ public class ValidationActionTest {
   }
 
   @Test
-  public void do_filter_admin() throws ServletException, IOException {
-    HttpServletRequest servletRequest = mock(HttpServletRequest.class);
+  public void do_filter_admin() throws IOException {
+    HttpServletRequest servletRequest = spy(HttpServletRequest.class);
     HttpServletResponse servletResponse = mock(HttpServletResponse.class);
     StringWriter stringWriter = new StringWriter();
     doReturn(new PrintWriter(stringWriter)).when(servletResponse).getWriter();
@@ -93,7 +94,7 @@ public class ValidationActionTest {
     final String mockedHtmlContent = "mocked html content";
     doReturn(mockedHtmlContent).when(samlAuthenticator).getAuthenticationStatusPage(any(), any());
 
-    underTest.doFilter(servletRequest, servletResponse, filterChain);
+    underTest.doFilter(new JavaxHttpRequest(servletRequest), new JavaxHttpResponse(servletResponse), filterChain);
 
     verify(samlAuthenticator).getAuthenticationStatusPage(any(), any());
     verify(servletResponse).getWriter();
@@ -102,9 +103,9 @@ public class ValidationActionTest {
   }
 
   @Test
-  public void do_filter_not_authorized() throws ServletException, IOException {
-    HttpServletRequest servletRequest = spy(HttpServletRequest.class);
-    HttpServletResponse servletResponse = mock(HttpServletResponse.class);
+  public void do_filter_not_authorized() throws IOException {
+    HttpRequest servletRequest = spy(HttpRequest.class);
+    HttpResponse servletResponse = mock(HttpResponse.class);
     StringWriter stringWriter = new StringWriter();
     doReturn(new PrintWriter(stringWriter)).when(servletResponse).getWriter();
     FilterChain filterChain = mock(FilterChain.class);
@@ -118,9 +119,9 @@ public class ValidationActionTest {
   }
 
   @Test
-  public void do_filter_failed_csrf_verification() throws ServletException, IOException {
-    HttpServletRequest servletRequest = spy(HttpServletRequest.class);
-    HttpServletResponse servletResponse = mock(HttpServletResponse.class);
+  public void do_filter_failed_csrf_verification() throws IOException {
+    HttpRequest servletRequest = spy(HttpRequest.class);
+    HttpResponse servletResponse = mock(HttpResponse.class);
     StringWriter stringWriter = new StringWriter();
     doReturn(new PrintWriter(stringWriter)).when(servletResponse).getWriter();
     FilterChain filterChain = mock(FilterChain.class);
@@ -128,7 +129,7 @@ public class ValidationActionTest {
     doReturn("IdentityProviderName").when(samlIdentityProvider).getName();
     doThrow(AuthenticationException.newBuilder()
       .setSource(AuthenticationEvent.Source.oauth2(samlIdentityProvider))
-      .setMessage("Cookie is missing").build()).when(oAuthCsrfVerifier).verifyState(any(),any(),any(), any());
+      .setMessage("Cookie is missing").build()).when(oAuthCsrfVerifier).verifyState(any(), any(), any(), any());
 
     doReturn(true).when(userSession).hasSession();
     doReturn(true).when(userSession).isSystemAdministrator();
index 5f205f3da5677c63312ad63397c807ba2c0cd6db..5a6db55a32e92f1e67e51e4b8514615d130f35c6 100644 (file)
 package org.sonar.server.saml.ws;
 
 import java.io.IOException;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.server.ws.WebService;
+import org.sonar.api.web.FilterChain;
 import org.sonar.auth.saml.SamlAuthenticator;
 import org.sonar.server.authentication.OAuth2ContextFactory;
 import org.sonar.server.authentication.OAuthCsrfVerifier;
@@ -68,10 +67,10 @@ public class ValidationInitActionTest {
   }
 
   @Test
-  public void do_filter_as_admin() throws IOException, ServletException {
+  public void do_filter_as_admin() throws IOException {
     userSession.logIn().setSystemAdministrator();
-    HttpServletRequest servletRequest = mock(HttpServletRequest.class);
-    HttpServletResponse servletResponse = mock(HttpServletResponse.class);
+    HttpRequest servletRequest = mock(HttpRequest.class);
+    HttpResponse servletResponse = mock(HttpResponse.class);
     FilterChain filterChain = mock(FilterChain.class);
     String callbackUrl = "http://localhost:9000/api/validation_test";
 
@@ -86,10 +85,10 @@ public class ValidationInitActionTest {
   }
 
   @Test
-  public void do_filter_as_admin_with_init_issues() throws IOException, ServletException {
+  public void do_filter_as_admin_with_init_issues() throws IOException {
     userSession.logIn().setSystemAdministrator();
-    HttpServletRequest servletRequest = mock(HttpServletRequest.class);
-    HttpServletResponse servletResponse = mock(HttpServletResponse.class);
+    HttpRequest servletRequest = mock(HttpRequest.class);
+    HttpResponse servletResponse = mock(HttpResponse.class);
     FilterChain filterChain = mock(FilterChain.class);
     String callbackUrl = "http://localhost:9000/api/validation_test";
     when(oAuth2ContextFactory.generateCallbackUrl(anyString()))
@@ -104,10 +103,10 @@ public class ValidationInitActionTest {
   }
 
   @Test
-  public void do_filter_as_not_admin() throws IOException, ServletException {
+  public void do_filter_as_not_admin() throws IOException {
     userSession.logIn();
-    HttpServletRequest servletRequest = mock(HttpServletRequest.class);
-    HttpServletResponse servletResponse = mock(HttpServletResponse.class);
+    HttpRequest servletRequest = mock(HttpRequest.class);
+    HttpResponse servletResponse = mock(HttpResponse.class);
     FilterChain filterChain = mock(FilterChain.class);
     String callbackUrl = "http://localhost:9000/api/validation_test";
     when(oAuth2ContextFactory.generateCallbackUrl(anyString()))
@@ -120,10 +119,10 @@ public class ValidationInitActionTest {
   }
 
   @Test
-  public void do_filter_as_anonymous() throws IOException, ServletException {
+  public void do_filter_as_anonymous() throws IOException {
     userSession.anonymous();
-    HttpServletRequest servletRequest = mock(HttpServletRequest.class);
-    HttpServletResponse servletResponse = mock(HttpServletResponse.class);
+    HttpRequest servletRequest = mock(HttpRequest.class);
+    HttpResponse servletResponse = mock(HttpResponse.class);
     FilterChain filterChain = mock(FilterChain.class);
     String callbackUrl = "http://localhost:9000/api/validation_test";
     when(oAuth2ContextFactory.generateCallbackUrl(anyString()))
@@ -149,7 +148,7 @@ public class ValidationInitActionTest {
     assertThat(validationInitAction.handler()).isNotNull();
   }
 
-  private void mockCsrfTokenGeneration(HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
+  private void mockCsrfTokenGeneration(HttpRequest servletRequest, HttpResponse servletResponse) {
     when(oAuthCsrfVerifier.generateState(servletRequest, servletResponse)).thenReturn("CSRF_TOKEN");
   }
 }
index 65d3f4cb52e41d7295b4478c2ec5a8bf9e49c1c4..79b7bdbf15663661cabaaa897284f6455166f742 100644 (file)
@@ -34,7 +34,9 @@ import javax.servlet.AsyncContext;
 import javax.servlet.http.HttpServletRequest;
 import org.sonar.api.impl.ws.PartImpl;
 import org.sonar.api.impl.ws.ValidatingRequest;
+import org.sonar.api.server.http.HttpRequest;
 import org.sonar.api.utils.log.Loggers;
+import org.sonar.server.http.JavaxHttpRequest;
 import org.sonarqube.ws.MediaTypes;
 
 import static com.google.common.base.MoreObjects.firstNonNull;
@@ -51,8 +53,8 @@ public class ServletRequest extends ValidatingRequest {
 
   private final HttpServletRequest source;
 
-  public ServletRequest(HttpServletRequest source) {
-    this.source = source;
+  public ServletRequest(HttpRequest source) {
+    this.source = ((JavaxHttpRequest) source).getDelegate();
   }
 
   @Override
index 676bd9683b51a694f1b0a806e2c6bd9293cf6ee1..001ff235882d0bdf1e0933ad96af6e4f022cded9 100644 (file)
@@ -25,9 +25,11 @@ import java.io.OutputStreamWriter;
 import java.nio.charset.StandardCharsets;
 import java.util.Collection;
 import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.utils.text.JsonWriter;
 import org.sonar.api.utils.text.XmlWriter;
+import org.sonar.server.http.JavaxHttpResponse;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.sonarqube.ws.MediaTypes.JSON;
@@ -37,8 +39,9 @@ public class ServletResponse implements Response {
 
   private final ServletStream stream;
 
-  public ServletResponse(HttpServletResponse response) {
-    stream = new ServletStream(response);
+  public ServletResponse(HttpResponse response) {
+    HttpServletResponse httpServletResponse = ((JavaxHttpResponse) response).getDelegate();
+    stream = new ServletStream(httpServletResponse);
   }
 
   public static class ServletStream implements Stream {
index f491ecf89c798565b5ae920f06c67370d77cb8a3..297a6c7e67e3ec6a3e35152ad118ceb683cea85d 100644 (file)
  */
 package org.sonar.server.ws;
 
-import com.google.common.collect.ImmutableMap;
 import com.google.common.net.HttpHeaders;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.StringReader;
 import java.util.List;
+import java.util.Map;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.Part;
 import org.junit.Test;
+import org.sonar.server.http.JavaxHttpRequest;
 import org.sonarqube.ws.MediaTypes;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -39,10 +40,9 @@ import static org.mockito.Mockito.when;
 
 public class ServletRequestTest {
 
+  private final HttpServletRequest source = mock(HttpServletRequest.class);
 
-  private HttpServletRequest source = mock(HttpServletRequest.class);
-
-  private ServletRequest underTest = new ServletRequest(source);
+  private final ServletRequest underTest = new ServletRequest(new JavaxHttpRequest(source));
 
   @Test
   public void call_method() {
@@ -76,8 +76,8 @@ public class ServletRequestTest {
 
   @Test
   public void has_param_from_source() {
-    when(source.getParameterMap()).thenReturn(ImmutableMap.of("param", new String[] {"value"}));
-    ServletRequest request = new ServletRequest(source);
+    when(source.getParameterMap()).thenReturn(Map.of("param", new String[] {"value"}));
+    ServletRequest request = new ServletRequest(new JavaxHttpRequest(source));
     assertThat(request.hasParam("param")).isTrue();
   }
 
index 8f44be35c651eba411cac38b8da9807582d4b42b..39f4e209a27d728a94e29a6267e30731aa402166 100644 (file)
 package org.sonar.server.ws;
 
 import java.io.IOException;
-import java.nio.charset.Charset;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Test;
+import org.sonar.server.http.JavaxHttpResponse;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -36,11 +36,10 @@ import static org.sonarqube.ws.MediaTypes.XML;
 
 public class ServletResponseTest {
 
+  private final ServletOutputStream output = mock(ServletOutputStream.class);
+  private final HttpServletResponse response = mock(HttpServletResponse.class);
 
-  private ServletOutputStream output = mock(ServletOutputStream.class);
-  private HttpServletResponse response = mock(HttpServletResponse.class);
-
-  private ServletResponse underTest = new ServletResponse(response);
+  private final ServletResponse underTest = new ServletResponse(new JavaxHttpResponse(response));
 
   @Before
   public void setUp() throws Exception {
index 45f4be0b9bd2d80c1bca6b75df361c766f8fd779..ff14e8d21f255105ac4b03504bfaccf23a034004 100644 (file)
@@ -22,15 +22,15 @@ package org.sonar.server.platform.web;
 import java.io.IOException;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.impl.utils.TestSystem2;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.api.web.FilterChain;
 import org.sonar.db.DbTester;
 import org.sonar.db.user.UserDto;
+import org.sonar.server.http.JavaxHttpRequest;
 import org.sonar.server.user.ServerUserSession;
 import org.sonar.server.user.ThreadLocalUserSession;
 
@@ -48,7 +48,7 @@ public class SonarLintConnectionFilterIT {
   public DbTester dbTester = DbTester.create(system2);
 
   @Test
-  public void update() throws IOException, ServletException {
+  public void update() throws IOException {
     system2.setNow(10_000_000L);
     addUser(LOGIN, 1_000_000L);
 
@@ -57,7 +57,7 @@ public class SonarLintConnectionFilterIT {
   }
 
   @Test
-  public void update_first_time() throws IOException, ServletException {
+  public void update_first_time() throws IOException {
     system2.setNow(10_000_000L);
     addUser(LOGIN, null);
 
@@ -74,7 +74,7 @@ public class SonarLintConnectionFilterIT {
   }
 
   @Test
-  public void do_nothing_if_no_sonarlint_agent() throws IOException, ServletException {
+  public void do_nothing_if_no_sonarlint_agent() throws IOException {
     system2.setNow(10_000L);
     addUser(LOGIN, 1_000L);
 
@@ -84,7 +84,7 @@ public class SonarLintConnectionFilterIT {
   }
 
   @Test
-  public void do_nothing_if_not_logged_in() throws IOException, ServletException {
+  public void do_nothing_if_not_logged_in() throws IOException {
     system2.setNow(10_000_000L);
     addUser("invalid", 1_000_000L);
 
@@ -93,17 +93,17 @@ public class SonarLintConnectionFilterIT {
   }
 
   @Test
-  public void dont_fail_if_no_user_set() throws IOException, ServletException {
+  public void dont_fail_if_no_user_set() throws IOException {
     SonarLintConnectionFilter underTest = new SonarLintConnectionFilter(dbTester.getDbClient(), new ThreadLocalUserSession(), system2);
-    HttpServletRequest request = mock(HttpServletRequest.class);
-    when(request.getHeader("User-Agent")).thenReturn("sonarlint");
+    HttpServletRequest httpRequest = mock(HttpServletRequest.class);
+    when(httpRequest.getHeader("User-Agent")).thenReturn("sonarlint");
     FilterChain chain = mock(FilterChain.class);
-    underTest.doFilter(request, mock(ServletResponse.class), chain);
+    underTest.doFilter(new JavaxHttpRequest(httpRequest), mock(HttpResponse.class), chain);
     verify(chain).doFilter(any(), any());
   }
 
   @Test
-  public void only_update_if_not_updated_within_1h() throws IOException, ServletException {
+  public void only_update_if_not_updated_within_1h() throws IOException {
     system2.setNow(2_000_000L);
     addUser(LOGIN, 1_000_000L);
 
@@ -120,15 +120,15 @@ public class SonarLintConnectionFilterIT {
     return dbTester.getDbClient().userDao().selectByLogin(dbTester.getSession(), login).getLastSonarlintConnectionDate();
   }
 
-  private void runFilter(String loggedInUser, @Nullable String agent) throws IOException, ServletException {
+  private void runFilter(String loggedInUser, @Nullable String agent) throws IOException {
     UserDto user = dbTester.getDbClient().userDao().selectByLogin(dbTester.getSession(), loggedInUser);
     ThreadLocalUserSession session = new ThreadLocalUserSession();
     session.set(new ServerUserSession(dbTester.getDbClient(), user));
     SonarLintConnectionFilter underTest = new SonarLintConnectionFilter(dbTester.getDbClient(), session, system2);
-    HttpServletRequest request = mock(HttpServletRequest.class);
-    when(request.getHeader("User-Agent")).thenReturn(agent);
+    HttpServletRequest httpRequest = mock(HttpServletRequest.class);
+    when(httpRequest.getHeader("User-Agent")).thenReturn(agent);
     FilterChain chain = mock(FilterChain.class);
-    underTest.doFilter(request, mock(ServletResponse.class), chain);
+    underTest.doFilter(new JavaxHttpRequest(httpRequest), mock(HttpResponse.class), chain);
     verify(chain).doFilter(any(), any());
   }
 }
index 994bea92ca1e38d944c3e7df43b139189c5486ca..31e40cf4b2b688d83b5d48ce3b9f1976149a9d83 100644 (file)
@@ -35,8 +35,14 @@ import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.utils.log.Loggers;
+import org.sonar.api.web.HttpFilter;
 import org.sonar.api.web.ServletFilter;
+import org.sonar.server.http.JavaxHttpRequest;
+import org.sonar.server.http.JavaxHttpResponse;
 import org.sonar.server.platform.PlatformImpl;
 
 /**
@@ -46,7 +52,10 @@ public class MasterServletFilter implements Filter {
 
   private static final String SCIM_FILTER_PATH = "/api/scim/v2/";
   private static volatile MasterServletFilter instance;
+
+  @Deprecated(forRemoval = true)
   private ServletFilter[] filters;
+  private HttpFilter[] httpFilters;
   private FilterConfig config;
 
   public MasterServletFilter() {
@@ -60,7 +69,9 @@ public class MasterServletFilter implements Filter {
   public void init(FilterConfig config) {
     // Filters are already available in the container unless a database migration is required. See
     // org.sonar.server.startup.RegisterServletFilters.
-    init(config, PlatformImpl.getInstance().getContainer().getComponentsByType(ServletFilter.class));
+    List<ServletFilter> servletFilterList = PlatformImpl.getInstance().getContainer().getComponentsByType(ServletFilter.class);
+    List<HttpFilter> httpFilterList = PlatformImpl.getInstance().getContainer().getComponentsByType(HttpFilter.class);
+    init(config, servletFilterList, httpFilterList);
   }
 
   @CheckForNull
@@ -73,17 +84,18 @@ public class MasterServletFilter implements Filter {
     MasterServletFilter.instance = instance;
   }
 
-  void init(FilterConfig config, List<ServletFilter> filters) {
+  void init(FilterConfig config, List<ServletFilter> filters, List<HttpFilter> httpFilters) {
     this.config = config;
-    initFilters(filters);
+    initHttpFilters(httpFilters);
+    initServletFilters(filters);
   }
 
-  public void initFilters(List<ServletFilter> filterExtensions) {
-    LinkedList<ServletFilter> filterList = new LinkedList<>();
-    for (ServletFilter extension : filterExtensions) {
+  public void initHttpFilters(List<HttpFilter> filterExtensions) {
+    LinkedList<HttpFilter> filterList = new LinkedList<>();
+    for (HttpFilter extension : filterExtensions) {
       try {
         Loggers.get(MasterServletFilter.class).info(String.format("Initializing servlet filter %s [pattern=%s]", extension, extension.doGetPattern().label()));
-        extension.init(config);
+        extension.init();
         // As for scim we need to intercept traffic to URLs with path parameters
         // and that use is not properly handled when dealing with inclusions/exclusions of the WebServiceFilter,
         // we need to make sure the Scim filters are invoked before the WebserviceFilter
@@ -96,18 +108,34 @@ public class MasterServletFilter implements Filter {
         throw new IllegalStateException("Fail to initialize servlet filter: " + extension + ". Message: " + e.getMessage(), e);
       }
     }
-    filters = filterList.toArray(new ServletFilter[0]);
+    httpFilters = filterList.toArray(new HttpFilter[0]);
   }
 
-  private static boolean isScimFilter(ServletFilter extension) {
+  private static boolean isScimFilter(HttpFilter extension) {
     return extension.doGetPattern().getInclusions().stream()
       .anyMatch(s -> s.startsWith(SCIM_FILTER_PATH));
   }
 
+  @Deprecated(forRemoval = true)
+  public void initServletFilters(List<ServletFilter> filterExtensions) {
+    LinkedList<ServletFilter> filterList = new LinkedList<>();
+    for (ServletFilter extension : filterExtensions) {
+      try {
+        Loggers.get(MasterServletFilter.class).info(String.format("Initializing servlet filter %s [pattern=%s]", extension, extension.doGetPattern().label()));
+        extension.init(config);
+        // adding deprecated extensions as last
+        filterList.addLast(extension);
+      } catch (Exception e) {
+        throw new IllegalStateException("Fail to initialize servlet filter: " + extension + ". Message: " + e.getMessage(), e);
+      }
+    }
+    filters = filterList.toArray(new ServletFilter[0]);
+  }
+
   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
     HttpServletRequest hsr = (HttpServletRequest) request;
-    if (filters.length == 0) {
+    if (filters.length == 0 && httpFilters.length == 0) {
       chain.doFilter(hsr, response);
     } else {
       String path = hsr.getRequestURI().replaceFirst(hsr.getContextPath(), "");
@@ -118,6 +146,10 @@ public class MasterServletFilter implements Filter {
   }
 
   private void buildGodchain(String path, GodFilterChain godChain) {
+    Arrays.stream(httpFilters)
+      .filter(filter -> filter.doGetPattern().matches(path))
+      .forEachOrdered(godChain::addFilter);
+
     Arrays.stream(filters)
       .filter(filter -> filter.doGetPattern().matches(path))
       .forEachOrdered(godChain::addFilter);
@@ -128,6 +160,10 @@ public class MasterServletFilter implements Filter {
     for (ServletFilter filter : filters) {
       filter.destroy();
     }
+
+    for (HttpFilter filter : httpFilters) {
+      filter.destroy();
+    }
   }
 
   @VisibleForTesting
@@ -135,9 +171,14 @@ public class MasterServletFilter implements Filter {
     return filters;
   }
 
+  @VisibleForTesting
+  HttpFilter[] getHttpFilters() {
+    return httpFilters;
+  }
+
   private static final class GodFilterChain implements FilterChain {
-    private FilterChain chain;
-    private List<Filter> filters = new LinkedList<>();
+    private final FilterChain chain;
+    private final List<Filter> filters = new LinkedList<>();
     private Iterator<Filter> iterator;
 
     public GodFilterChain(FilterChain chain) {
@@ -146,20 +187,59 @@ public class MasterServletFilter implements Filter {
 
     @Override
     public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
+
       if (iterator == null) {
         iterator = filters.iterator();
       }
       if (iterator.hasNext()) {
-        iterator.next().doFilter(request, response, this);
+        Filter next = iterator.next();
+        next.doFilter(request, response, this);
       } else {
         chain.doFilter(request, response);
       }
     }
 
+    @Deprecated(forRemoval = true)
     public void addFilter(Filter filter) {
       Preconditions.checkState(iterator == null);
       filters.add(filter);
     }
+
+    public void addFilter(HttpFilter filter) {
+      Preconditions.checkState(iterator == null);
+      filters.add(new JavaxFilterAdapter(filter));
+    }
+  }
+
+  private static class JavaxFilterAdapter implements Filter {
+    private final HttpFilter httpFilter;
+
+    JavaxFilterAdapter(HttpFilter httpFilter) {
+      this.httpFilter = httpFilter;
+    }
+
+    @Override
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
+      HttpRequest javaxHttpRequest = new JavaxHttpRequest((HttpServletRequest) servletRequest);
+      HttpResponse javaxHttpResponse = new JavaxHttpResponse((HttpServletResponse) servletResponse);
+      httpFilter.doFilter(javaxHttpRequest, javaxHttpResponse, new HttpFilterChainAdapter(chain));
+    }
   }
 
+  private static class HttpFilterChainAdapter implements org.sonar.api.web.FilterChain {
+    private final FilterChain filterChain;
+
+    HttpFilterChainAdapter(FilterChain filterChain) {
+      this.filterChain = filterChain;
+    }
+
+    @Override
+    public void doFilter(HttpRequest httpRequest, HttpResponse httpResponse) throws IOException {
+      try {
+        filterChain.doFilter(((JavaxHttpRequest) httpRequest).getDelegate(), ((JavaxHttpResponse) httpResponse).getDelegate());
+      } catch (ServletException e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
 }
index c77b0204d7c6e7dcaff49a01bc0c1c264ed4d7b1..3967a6e3b653fd846ff204e1042afaeed98b191a 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.server.platform.web;
 
 import java.util.Arrays;
 import org.sonar.api.Startable;
+import org.sonar.api.web.HttpFilter;
 import org.sonar.api.web.ServletFilter;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -28,16 +29,24 @@ import org.springframework.beans.factory.annotation.Autowired;
  * @since 3.5
  */
 public class RegisterServletFilters implements Startable {
-  private final ServletFilter[] filters;
+  private final ServletFilter[] servletFilters;
+  private final HttpFilter[] httpFilters;
 
   @Autowired(required = false)
-  public RegisterServletFilters(ServletFilter[] filters) {
-    this.filters = filters;
+  @Deprecated(since = "10.1", forRemoval = true)
+  public RegisterServletFilters(ServletFilter[] servletFilters, HttpFilter[] httpFilters) {
+    this.servletFilters = servletFilters;
+    this.httpFilters = httpFilters;
+  }
+
+  @Autowired(required = false)
+  public RegisterServletFilters(HttpFilter[] httpFilters) {
+    this(new ServletFilter[0], httpFilters);
   }
 
   @Autowired(required = false)
   public RegisterServletFilters() {
-    this(new ServletFilter[0]);
+    this(new ServletFilter[0], new HttpFilter[0]);
   }
 
   @Override
@@ -45,9 +54,10 @@ public class RegisterServletFilters implements Startable {
     MasterServletFilter masterServletFilter = MasterServletFilter.getInstance();
     if (masterServletFilter != null) {
       // Probably a database upgrade. MasterSlaveFilter was instantiated by the servlet container
-      // while picocontainer was not completely up.
+      // while spring was not completely up.
       // See https://jira.sonarsource.com/browse/SONAR-3612
-      masterServletFilter.initFilters(Arrays.asList(filters));
+      masterServletFilter.initHttpFilters(Arrays.asList(httpFilters));
+      masterServletFilter.initServletFilters(Arrays.asList(servletFilters));
     }
   }
 
index e5ba6d2aca933280a7e555b40d176bc5546113c1..7d01689b9167fa4dc9a603d34646f3867c857308 100644 (file)
@@ -22,12 +22,12 @@ package org.sonar.server.platform.web;
 import java.io.IOException;
 import java.util.Locale;
 import java.util.Optional;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.utils.System2;
-import org.sonar.api.web.ServletFilter;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.HttpFilter;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.server.user.ThreadLocalUserSession;
@@ -35,7 +35,7 @@ import org.sonar.server.ws.ServletRequest;
 
 import static java.util.concurrent.TimeUnit.HOURS;
 
-public class SonarLintConnectionFilter extends ServletFilter {
+public class SonarLintConnectionFilter extends HttpFilter {
   private static final UrlPattern URL_PATTERN = UrlPattern.builder()
     .includes("/api/*")
     .excludes("/api/v2/*")
@@ -56,25 +56,14 @@ public class SonarLintConnectionFilter extends ServletFilter {
   }
 
   @Override
-  public void doFilter(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
-    HttpServletRequest request = (HttpServletRequest) servletRequest;
+  public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) throws IOException {
     ServletRequest wsRequest = new ServletRequest(request);
 
     Optional<String> agent = wsRequest.header("User-Agent");
     if (agent.isPresent() && agent.get().toLowerCase(Locale.ENGLISH).contains("sonarlint")) {
       update();
     }
-    chain.doFilter(servletRequest, servletResponse);
-  }
-
-  @Override
-  public void init(FilterConfig filterConfig) {
-    // Nothing to do
-  }
-
-  @Override
-  public void destroy() {
-    // Nothing to do
+    chain.doFilter(request, response);
   }
 
   public void update() {
index 777380a0a0369d7f59428e36cd34dfcd47c9b61f..104bc7d87aa349df23cbfe3c83e5f78ba7fde982 100644 (file)
@@ -34,6 +34,8 @@ import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 import org.sonar.db.DBSessions;
 import org.sonar.server.authentication.UserSessionInitializer;
+import org.sonar.server.http.JavaxHttpRequest;
+import org.sonar.server.http.JavaxHttpResponse;
 import org.sonar.server.platform.Platform;
 import org.sonar.server.platform.PlatformImpl;
 import org.sonar.server.setting.ThreadLocalSettings;
@@ -77,7 +79,7 @@ public class UserSessionFilter implements Filter {
   private static void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
     @Nullable UserSessionInitializer userSessionInitializer) throws IOException, ServletException {
     try {
-      if (userSessionInitializer == null || userSessionInitializer.initUserSession(request, response)) {
+      if (userSessionInitializer == null || userSessionInitializer.initUserSession(new JavaxHttpRequest(request), new JavaxHttpResponse(response))) {
         chain.doFilter(request, response);
       }
     } finally {
index 5d04f9e0381d9ec696b4ec792f966ab8bc9ca4a6..4ab60d22d29bd0f0fff18fc5408e0b62bb1c7a09 100644 (file)
@@ -23,12 +23,12 @@ import java.util.HashSet;
 import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Stream;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.api.web.ServletFilter;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.HttpFilter;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.core.util.stream.MoreCollectors;
 import org.sonar.server.ws.ServletFilterHandler;
 import org.sonar.server.ws.ServletRequest;
@@ -47,7 +47,7 @@ import static org.sonar.server.platform.web.WebServiceReroutingFilter.MOVED_WEB_
  *   <li>web services that directly implemented with servlet filter, see {@link ServletFilterHandler})</li>
  * </ul>
  */
-public class WebServiceFilter extends ServletFilter {
+public class WebServiceFilter extends HttpFilter {
 
   private final WebServiceEngine webServiceEngine;
   private final Set<String> includeUrls;
@@ -78,24 +78,12 @@ public class WebServiceFilter extends ServletFilter {
   }
 
   @Override
-  public void doFilter(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse, FilterChain chain) {
-    HttpServletRequest request = (HttpServletRequest) servletRequest;
-    HttpServletResponse response = (HttpServletResponse) servletResponse;
+  public void doFilter(HttpRequest request, HttpResponse response, FilterChain filterChain) {
     ServletRequest wsRequest = new ServletRequest(request);
     ServletResponse wsResponse = new ServletResponse(response);
     webServiceEngine.execute(wsRequest, wsResponse);
   }
 
-  @Override
-  public void init(FilterConfig filterConfig) {
-    // Nothing to do
-  }
-
-  @Override
-  public void destroy() {
-    // Nothing to do
-  }
-
   private static Function<WebService.Action, String> toPath() {
     return action -> "/" + action.path() + ".*";
   }
index dc58c49f10849031a26a4b3c4fc75fcaf1e22293..52547fe7918a6ec284894edd0229f1c2039e056d 100644 (file)
  */
 package org.sonar.server.platform.web;
 
-import com.google.common.collect.ImmutableMap;
 import java.util.Map;
 import java.util.Set;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.sonar.api.web.ServletFilter;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
+import org.sonar.api.web.FilterChain;
+import org.sonar.api.web.HttpFilter;
+import org.sonar.api.web.UrlPattern;
 import org.sonar.server.ws.ServletRequest;
 import org.sonar.server.ws.ServletResponse;
 import org.sonar.server.ws.WebServiceEngine;
@@ -34,12 +33,11 @@ import org.sonar.server.ws.WebServiceEngine;
 /**
  * This filter is used to execute renamed/moved web services
  */
-public class WebServiceReroutingFilter extends ServletFilter {
+public class WebServiceReroutingFilter extends HttpFilter {
 
-  private static final Map<String, String> REDIRECTS = ImmutableMap.<String, String>builder()
-    .put("/api/components/bulk_update_key", "/api/projects/bulk_update_key")
-    .put("/api/components/update_key", "/api/projects/update_key")
-    .build();
+  private static final Map<String, String> REDIRECTS = Map.of(
+    "/api/components/bulk_update_key", "/api/projects/bulk_update_key",
+    "/api/components/update_key", "/api/projects/update_key");
   static final Set<String> MOVED_WEB_SERVICES = REDIRECTS.keySet();
 
   private final WebServiceEngine webServiceEngine;
@@ -56,16 +54,15 @@ public class WebServiceReroutingFilter extends ServletFilter {
   }
 
   @Override
-  public void doFilter(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse, FilterChain chain) {
-    HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
-    RedirectionRequest wsRequest = new RedirectionRequest(httpRequest);
-    ServletResponse wsResponse = new ServletResponse((HttpServletResponse) servletResponse);
+  public void doFilter(HttpRequest request, HttpResponse response, FilterChain filterChain) {
+    RedirectionRequest wsRequest = new RedirectionRequest(request);
+    ServletResponse wsResponse = new ServletResponse(response);
 
     webServiceEngine.execute(wsRequest, wsResponse);
   }
 
   @Override
-  public void init(FilterConfig filterConfig) {
+  public void init() {
     // Nothing to do
   }
 
@@ -77,7 +74,7 @@ public class WebServiceReroutingFilter extends ServletFilter {
   private static class RedirectionRequest extends ServletRequest {
     private final String redirectedPath;
 
-    public RedirectionRequest(HttpServletRequest source) {
+    public RedirectionRequest(HttpRequest source) {
       super(source);
       this.redirectedPath = REDIRECTS.getOrDefault(source.getServletPath(), source.getServletPath());
     }
index 49077005dbd70a63c87ce648c9057c5ddcf49468..fa580be99bedba3f1418253effa3e7eb2cec271c 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.server.platform.web;
 
 import java.io.IOException;
 import java.util.Collections;
+import java.util.List;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
@@ -34,11 +35,17 @@ import org.junit.Test;
 import org.mockito.InOrder;
 import org.mockito.Mockito;
 import org.slf4j.event.Level;
+import org.sonar.api.server.http.HttpRequest;
+import org.sonar.api.server.http.HttpResponse;
 import org.sonar.api.testfixtures.log.LogTester;
+import org.sonar.api.web.HttpFilter;
 import org.sonar.api.web.ServletFilter;
 import org.sonar.api.web.ServletFilter.UrlPattern;
+import org.sonar.server.http.JavaxHttpRequest;
+import org.sonar.server.http.JavaxHttpResponse;
 
 import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
 import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -60,37 +67,43 @@ public class MasterServletFilterTest {
   }
 
   @Test
-  public void should_init_and_destroy_filters() throws Exception {
-    ServletFilter filter = createMockFilter();
+  public void should_init_and_destroy_filters() throws ServletException {
+    ServletFilter servletFilter = createMockServletFilter();
+    HttpFilter httpFilter = createMockHttpFilter();
     FilterConfig config = mock(FilterConfig.class);
     MasterServletFilter master = new MasterServletFilter();
-    master.init(config, singletonList(filter));
+    master.init(config, singletonList(servletFilter),  singletonList(httpFilter));
 
-    assertThat(master.getFilters()).containsOnly(filter);
-    verify(filter).init(config);
+    assertThat(master.getFilters()).containsOnly(servletFilter);
+    assertThat(master.getHttpFilters()).containsOnly(httpFilter);
+    verify(servletFilter).init(config);
+    verify(httpFilter).init();
 
     master.destroy();
-    verify(filter).destroy();
+    verify(servletFilter).destroy();
+    verify(httpFilter).destroy();
   }
 
   @Test
   public void servlet_container_should_instantiate_only_a_single_master_instance() {
     new MasterServletFilter();
 
-    assertThatThrownBy(() -> new MasterServletFilter())
+    assertThatThrownBy(MasterServletFilter::new)
       .isInstanceOf(IllegalStateException.class)
       .hasMessageContaining("Servlet filter org.sonar.server.platform.web.MasterServletFilter is already instantiated");
   }
 
   @Test
   public void should_propagate_initialization_failure() throws Exception {
-    ServletFilter filter = createMockFilter();
+    ServletFilter filter = createMockServletFilter();
     doThrow(new IllegalStateException("foo")).when(filter).init(any(FilterConfig.class));
 
     FilterConfig config = mock(FilterConfig.class);
     MasterServletFilter filters = new MasterServletFilter();
 
-    assertThatThrownBy(() -> filters.init(config, singletonList(filter)))
+    List<ServletFilter> servletFilters = singletonList(filter);
+    List<HttpFilter> httpFilters = emptyList();
+    assertThatThrownBy(() -> filters.init(config, servletFilters, httpFilters))
       .isInstanceOf(IllegalStateException.class)
       .hasMessageContaining("foo");
   }
@@ -99,7 +112,7 @@ public class MasterServletFilterTest {
   public void filters_should_be_optional() throws Exception {
     FilterConfig config = mock(FilterConfig.class);
     MasterServletFilter filters = new MasterServletFilter();
-    filters.init(config, Collections.emptyList());
+    filters.init(config, Collections.emptyList(), Collections.emptyList());
 
     ServletRequest request = mock(HttpServletRequest.class);
     ServletResponse response = mock(HttpServletResponse.class);
@@ -113,23 +126,31 @@ public class MasterServletFilterTest {
   public void should_add_scim_filter_first_for_scim_request() throws Exception {
     String scimPath = "/api/scim/v2/Groups";
     HttpServletRequest request = mock(HttpServletRequest.class);
+    HttpServletResponse response = mock(HttpServletResponse.class);
     when(request.getRequestURI()).thenReturn(scimPath);
     when(request.getContextPath()).thenReturn("");
-    ServletResponse response = mock(HttpServletResponse.class);
+
+    HttpRequest httpRequest = mock(JavaxHttpRequest.class);
+    HttpResponse httpResponse = mock(JavaxHttpResponse.class);
+    when(httpRequest.getRequestURI()).thenReturn(scimPath);
+    when(httpRequest.getContextPath()).thenReturn("");
+
     FilterChain chain = mock(FilterChain.class);
 
     ServletFilter filter1 = mockFilter(ServletFilter.class, request, response);
     ServletFilter filter2 = mockFilter(ServletFilter.class, request, response);
-    ServletFilter filter3 = mockFilter(WebServiceFilter.class, request, response);
-    when(filter3.doGetPattern()).thenReturn(UrlPattern.builder().includes(scimPath).build());
+    HttpFilter filter3 = mockHttpFilter(WebServiceFilter.class, httpRequest, httpResponse);
+    HttpFilter filter4 = mockHttpFilter(HttpFilter.class, httpRequest, httpResponse);
+    when(filter3.doGetPattern()).thenReturn(org.sonar.api.web.UrlPattern.builder().includes(scimPath).build());
 
     MasterServletFilter filters = new MasterServletFilter();
-    filters.init(mock(FilterConfig.class), asList(filter3, filter1, filter2));
+    filters.init(mock(FilterConfig.class), asList(filter1, filter2), asList(filter4, filter3));
 
     filters.doFilter(request, response, chain);
 
-    InOrder inOrder = Mockito.inOrder(filter1, filter2, filter3);
+    InOrder inOrder = Mockito.inOrder(filter1, filter2, filter3, filter4);
     inOrder.verify(filter3).doFilter(any(), any(), any());
+    inOrder.verify(filter4).doFilter(any(), any(), any());
     inOrder.verify(filter1).doFilter(any(), any(), any());
     inOrder.verify(filter2).doFilter(any(), any(), any());
   }
@@ -145,49 +166,56 @@ public class MasterServletFilterTest {
     return filter;
   }
 
+  private HttpFilter mockHttpFilter(Class<? extends HttpFilter> filterClazz, HttpRequest request, HttpResponse response) throws IOException {
+    HttpFilter filter = mock(filterClazz);
+    when(filter.doGetPattern()).thenReturn(org.sonar.api.web.UrlPattern.builder().build());
+    doAnswer(invocation -> {
+      org.sonar.api.web.FilterChain argument = invocation.getArgument(2, org.sonar.api.web.FilterChain.class);
+      argument.doFilter(request, response);
+      return null;
+    }).when(filter).doFilter(any(), any(), any());
+    return filter;
+  }
+
   @Test
   public void display_servlet_filter_patterns_in_INFO_log() {
-    ServletFilter filter = new PatternFilter(UrlPattern.builder().includes("/api/issues").excludes("/batch/projects").build());
+    HttpFilter filter = new PatternFilter(org.sonar.api.web.UrlPattern.builder().includes("/api/issues").excludes("/batch/projects").build());
     FilterConfig config = mock(FilterConfig.class);
     MasterServletFilter master = new MasterServletFilter();
 
-    master.init(config, singletonList(filter));
+    master.init(config, emptyList(), singletonList(filter));
 
     assertThat(logTester.logs(Level.INFO)).containsOnly("Initializing servlet filter PatternFilter [pattern=UrlPattern{inclusions=[/api/issues], exclusions=[/batch/projects]}]");
   }
 
-  private static ServletFilter createMockFilter() {
+  private static ServletFilter createMockServletFilter() {
     ServletFilter filter = mock(ServletFilter.class);
     when(filter.doGetPattern()).thenReturn(UrlPattern.builder().build());
     return filter;
   }
 
-  private static class PatternFilter extends ServletFilter {
+  private static HttpFilter createMockHttpFilter() {
+    HttpFilter filter = mock(HttpFilter.class);
+    when(filter.doGetPattern()).thenReturn(org.sonar.api.web.UrlPattern.builder().build());
+    return filter;
+  }
 
-    private final UrlPattern urlPattern;
+  private static class PatternFilter extends HttpFilter {
 
-    PatternFilter(UrlPattern urlPattern) {
+    private final org.sonar.api.web.UrlPattern urlPattern;
+
+    PatternFilter(org.sonar.api.web.UrlPattern urlPattern) {
       this.urlPattern = urlPattern;
     }
 
     @Override
-    public UrlPattern doGetPattern() {
+    public org.sonar.api.web.UrlPattern doGetPattern() {
       return urlPattern;
     }
 
     @Override
-    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
-      // Nothing to do
-    }
+    public void doFilter(HttpRequest request, HttpResponse response, org.sonar.api.web.FilterChain chain) throws IOException {
 
-    @Override
-    public void init(FilterConfig filterConfig) {
-      // Nothing to do
-    }
-
-    @Override
-    public void destroy() {
-      // Nothing to do
     }
 
     @Override
index d1e500bca57782e26a328f248a2b35c9a5292e7a..9b9a42b9bc64c1250e1514802835ec5c2ce46bbb 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.server.platform.web;
 
 import org.junit.Test;
+import org.sonar.api.web.HttpFilter;
 import org.sonar.api.web.ServletFilter;
 
 import static org.mockito.ArgumentMatchers.anyList;
@@ -30,15 +31,15 @@ public class RegisterServletFiltersTest {
   @Test
   public void should_not_fail_if_master_filter_is_not_up() {
     MasterServletFilter.setInstance(null);
-    new RegisterServletFilters(new ServletFilter[2]).start();
+    new RegisterServletFilters(new ServletFilter[2], new HttpFilter[2]).start();
   }
 
   @Test
   public void should_register_filters_if_master_filter_is_up() {
     MasterServletFilter.setInstance(mock(MasterServletFilter.class));
-    new RegisterServletFilters(new ServletFilter[2]).start();
+    new RegisterServletFilters(new ServletFilter[2], new HttpFilter[2]).start();
 
-    verify(MasterServletFilter.getInstance()).initFilters(anyList());
+    verify(MasterServletFilter.getInstance()).initServletFilters(anyList());
   }
 
   @Test
@@ -46,6 +47,7 @@ public class RegisterServletFiltersTest {
     MasterServletFilter.setInstance(mock(MasterServletFilter.class));
     new RegisterServletFilters().start();
     // do not fail
-    verify(MasterServletFilter.getInstance()).initFilters(anyList());
+    verify(MasterServletFilter.getInstance()).initHttpFilters(anyList());
+    verify(MasterServletFilter.getInstance()).initServletFilters(anyList());
   }
 }
index 8d0618a440fbea90147b3cc80db1b16d3f60a10a..2b8b886eac64d63d06f933753bde24bbea60bc55 100644 (file)
@@ -26,17 +26,21 @@ import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import org.assertj.core.api.Assertions;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.InOrder;
 import org.sonar.core.platform.ExtensionContainer;
 import org.sonar.db.DBSessions;
 import org.sonar.server.authentication.UserSessionInitializer;
+import org.sonar.server.http.JavaxHttpRequest;
+import org.sonar.server.http.JavaxHttpResponse;
 import org.sonar.server.platform.Platform;
 import org.sonar.server.setting.ThreadLocalSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
@@ -72,7 +76,7 @@ public class UserSessionFilterTest {
     underTest.doFilter(request, response, chain);
 
     verify(chain).doFilter(request, response);
-    verify(userSessionInitializer).initUserSession(request, response);
+    verify(userSessionInitializer).initUserSession(any(JavaxHttpRequest.class), any(JavaxHttpResponse.class));
   }
 
   @Test
@@ -82,7 +86,7 @@ public class UserSessionFilterTest {
     underTest.doFilter(request, response, chain);
 
     verify(chain, never()).doFilter(request, response);
-    verify(userSessionInitializer).initUserSession(request, response);
+    verify(userSessionInitializer).initUserSession(any(JavaxHttpRequest.class), any(JavaxHttpResponse.class));
   }
 
   @Test
@@ -155,14 +159,15 @@ public class UserSessionFilterTest {
   @Test
   public void just_for_fun_and_coverage() {
     UserSessionFilter filter = new UserSessionFilter();
-    filter.init(mock(FilterConfig.class));
-    filter.destroy();
-    // do not fail
+
+    FilterConfig filterConfig = mock(FilterConfig.class);
+    Assertions.assertThatNoException().isThrownBy(() -> filter.init(filterConfig));
+    Assertions.assertThatNoException().isThrownBy(filter::destroy);
   }
 
   private void mockUserSessionInitializer(boolean value) {
     when(container.getOptionalComponentByType(UserSessionInitializer.class)).thenReturn(Optional.of(userSessionInitializer));
-    when(userSessionInitializer.initUserSession(request, response)).thenReturn(value);
+    when(userSessionInitializer.initUserSession(any(JavaxHttpRequest.class), any(JavaxHttpResponse.class))).thenReturn(value);
   }
 
   private RuntimeException mockUserSessionInitializerRemoveUserSessionFailing() {
index 2972b59efd82fefefb41ffe9c3105b6144ad4066..faf45054ddb6829b39cf91b2787b7765d88203e6 100644 (file)
@@ -21,7 +21,6 @@ package org.sonar.server.platform.web;
 
 import java.util.ArrayList;
 import java.util.List;
-import javax.servlet.FilterChain;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -31,6 +30,9 @@ import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.RequestHandler;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
+import org.sonar.api.web.FilterChain;
+import org.sonar.server.http.JavaxHttpRequest;
+import org.sonar.server.http.JavaxHttpResponse;
 import org.sonar.server.ws.ServletFilterHandler;
 import org.sonar.server.ws.WebServiceEngine;
 
@@ -43,21 +45,19 @@ import static org.sonar.server.platform.web.WebServiceFilterTest.WsUrl.newWsUrl;
 
 public class WebServiceFilterTest {
 
-  private static final String RUNTIME_VERSION = "7.1.0.1234";
+  private final WebServiceEngine webServiceEngine = mock(WebServiceEngine.class);
 
-
-  private WebServiceEngine webServiceEngine = mock(WebServiceEngine.class);
-
-  private HttpServletRequest request = mock(HttpServletRequest.class);
-  private HttpServletResponse response = mock(HttpServletResponse.class);
-  private FilterChain chain = mock(FilterChain.class);
-  private ServletOutputStream responseOutput = mock(ServletOutputStream.class);
+  private final HttpServletRequest request = mock(HttpServletRequest.class);
+  private final HttpServletResponse response = mock(HttpServletResponse.class);
+  private final FilterChain chain = mock(FilterChain.class);
+  private final ServletOutputStream responseOutput = mock(ServletOutputStream.class);
   private WebServiceFilter underTest;
 
   @Before
   public void setUp() throws Exception {
     when(request.getContextPath()).thenReturn("");
-    when(response.getOutputStream()).thenReturn(responseOutput);
+    HttpServletResponse mockResponse = mock(HttpServletResponse.class);
+    when(mockResponse.getOutputStream()).thenReturn(responseOutput);
   }
 
   @Test
@@ -103,7 +103,7 @@ public class WebServiceFilterTest {
   public void execute_ws() {
     underTest = new WebServiceFilter(webServiceEngine);
 
-    underTest.doFilter(request, response, chain);
+    underTest.doFilter(new JavaxHttpRequest(request), new JavaxHttpResponse(response), chain);
 
     verify(webServiceEngine).execute(any(), any());
   }
@@ -132,8 +132,8 @@ public class WebServiceFilterTest {
   }
 
   static final class WsUrl {
-    private String controller;
-    private String[] actions;
+    private final String controller;
+    private final String[] actions;
     private RequestHandler requestHandler = EmptyRequestHandler.INSTANCE;
 
     WsUrl(String controller, String... actions) {
index 92ddd47b0f09cdf4eabde9f2c97f4503c527df35..682c4052e5121519281ce66d0f2c1b298b64ba4e 100644 (file)
  */
 package org.sonar.server.platform.web;
 
-import javax.servlet.FilterChain;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.sonar.api.web.FilterChain;
+import org.sonar.server.http.JavaxHttpRequest;
+import org.sonar.server.http.JavaxHttpResponse;
 import org.sonar.server.ws.ServletRequest;
 import org.sonar.server.ws.ServletResponse;
 import org.sonar.server.ws.WebServiceEngine;
@@ -37,14 +39,14 @@ import static org.mockito.Mockito.when;
 
 public class WebServiceReroutingFilterTest {
 
-  private WebServiceEngine webServiceEngine = mock(WebServiceEngine.class);
+  private final WebServiceEngine webServiceEngine = mock(WebServiceEngine.class);
 
-  private HttpServletRequest request = mock(HttpServletRequest.class);
-  private HttpServletResponse response = mock(HttpServletResponse.class);
-  private FilterChain chain = mock(FilterChain.class);
-  private ArgumentCaptor<ServletRequest> servletRequestCaptor = ArgumentCaptor.forClass(ServletRequest.class);
+  private final HttpServletRequest request = mock(HttpServletRequest.class);
+  private final HttpServletResponse response = mock(HttpServletResponse.class);
+  private final FilterChain chain = mock(FilterChain.class);
+  private final ArgumentCaptor<ServletRequest> servletRequestCaptor = ArgumentCaptor.forClass(ServletRequest.class);
 
-  private WebServiceReroutingFilter underTest = new WebServiceReroutingFilter(webServiceEngine);
+  private final WebServiceReroutingFilter underTest = new WebServiceReroutingFilter(webServiceEngine);
 
   @Before
   public void setUp() {
@@ -63,7 +65,7 @@ public class WebServiceReroutingFilterTest {
     when(request.getServletPath()).thenReturn("/api/components/update_key");
     when(request.getMethod()).thenReturn("POST");
 
-    underTest.doFilter(request, response, chain);
+    underTest.doFilter(new JavaxHttpRequest(request), new JavaxHttpResponse(response), chain);
 
     assertRedirection("/api/projects/update_key", "POST");
   }
index 08b92350a10964e31d4f86c48856fe1d79b499a0..324097ee15d5cb725241bb8745ea540b01ec59f2 100644 (file)
@@ -40,6 +40,7 @@ import javax.annotation.Nullable;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.builder.ToStringBuilder;
 import org.apache.commons.lang.builder.ToStringStyle;
+import org.sonar.api.code.CodeCharacteristic;
 import org.sonar.api.issue.Issue;
 import org.sonar.api.issue.IssueComment;
 import org.sonar.api.rule.RuleKey;
@@ -144,6 +145,12 @@ public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure.
     return type;
   }
 
+  @CheckForNull
+  @Override
+  public CodeCharacteristic characteristic() {
+    throw new IllegalStateException("Not implemented yet");
+  }
+
   public DefaultIssue setType(RuleType type) {
     this.type = type;
     return this;
index 2567c27bc88cb337b78dc8a0bbdc1214f67b9d2d..42418950a25bf99f9823e81fd5a72270bf3c799b 100644 (file)
  */
 package org.sonar.api.batch.sensor.issue.internal;
 
+import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.api.batch.fs.internal.DefaultInputProject;
 import org.sonar.api.batch.rule.Severity;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.batch.sensor.issue.ExternalIssue;
 import org.sonar.api.batch.sensor.issue.NewExternalIssue;
+import org.sonar.api.code.CodeCharacteristic;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rules.RuleType;
 
@@ -97,6 +99,12 @@ public class DefaultExternalIssue extends AbstractDefaultIssue<DefaultExternalIs
     return type;
   }
 
+  @CheckForNull
+  @Override
+  public CodeCharacteristic characteristic() {
+    throw new IllegalStateException("Not implemented yet");
+  }
+
   @Override
   public NewExternalIssue engineId(String engineId) {
     this.engineId = engineId;
@@ -130,4 +138,9 @@ public class DefaultExternalIssue extends AbstractDefaultIssue<DefaultExternalIs
     return this;
   }
 
+  @Override
+  public NewExternalIssue characteristic(CodeCharacteristic characteristic) {
+    throw new IllegalStateException("Not implemented yet");
+  }
+
 }
index 6f933c16200e2839d4212dc190b1133742526bb0..52a243b8fca73e4f2e610973f9e6b7923daa32fc 100644 (file)
@@ -26,6 +26,7 @@ import org.sonar.api.batch.sensor.internal.DefaultStorable;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.batch.sensor.rule.AdHocRule;
 import org.sonar.api.batch.sensor.rule.NewAdHocRule;
+import org.sonar.api.code.CodeCharacteristic;
 import org.sonar.api.rules.RuleType;
 
 import static org.apache.commons.lang.StringUtils.isNotBlank;
@@ -94,6 +95,12 @@ public class DefaultAdHocRule extends DefaultStorable implements AdHocRule, NewA
     return type;
   }
 
+  @CheckForNull
+  @Override
+  public CodeCharacteristic characteristic() {
+    throw new IllegalStateException("Not implemented yet");
+  }
+
   @Override
   public DefaultAdHocRule engineId(String engineId) {
     this.engineId = engineId;
@@ -124,4 +131,9 @@ public class DefaultAdHocRule extends DefaultStorable implements AdHocRule, NewA
     return this;
   }
 
+  @Override
+  public NewAdHocRule characteristic(CodeCharacteristic characteristic) {
+    throw new IllegalStateException("Not implemented yet");
+  }
+
 }