import org.sonar.api.web.UrlPattern;
import org.sonar.db.user.UserDto;
import org.sonar.server.authentication.BasicAuthentication;
+import org.sonar.server.authentication.HttpHeadersAuthentication;
import org.sonar.server.authentication.JwtHttpHandler;
+import org.sonar.server.authentication.UserAuthResult;
import org.sonar.server.authentication.event.AuthenticationException;
+import org.sonar.server.usertoken.UserTokenAuthentication;
import org.sonar.server.ws.ServletFilterHandler;
import org.sonarqube.ws.MediaTypes;
private final Configuration config;
private final JwtHttpHandler jwtHttpHandler;
private final BasicAuthentication basicAuthentication;
+ private final HttpHeadersAuthentication httpHeadersAuthentication;
+ private final UserTokenAuthentication userTokenAuthentication;
+
+ public ValidateAction(Configuration config, BasicAuthentication basicAuthentication, JwtHttpHandler jwtHttpHandler, HttpHeadersAuthentication httpHeadersAuthentication,
+ UserTokenAuthentication userTokenAuthentication) {
- public ValidateAction(Configuration config, BasicAuthentication basicAuthentication, JwtHttpHandler jwtHttpHandler) {
this.config = config;
this.basicAuthentication = basicAuthentication;
this.jwtHttpHandler = jwtHttpHandler;
+ this.httpHeadersAuthentication = httpHeadersAuthentication;
+ this.userTokenAuthentication = userTokenAuthentication;
}
@Override
private boolean authenticate(HttpRequest request, HttpResponse response) {
try {
- Optional<UserDto> user = jwtHttpHandler.validateToken(request, response);
- if (user.isPresent()) {
- return true;
- }
- user = basicAuthentication.authenticate(request);
- if (user.isPresent()) {
- return true;
- }
- return !config.getBoolean(CORE_FORCE_AUTHENTICATION_PROPERTY).orElse(CORE_FORCE_AUTHENTICATION_DEFAULT_VALUE);
+ Optional<UserDto> user = httpHeadersAuthentication.authenticate(request, response)
+ .or(() -> jwtHttpHandler.validateToken(request, response))
+ .or(() -> basicAuthentication.authenticate(request))
+ .or(() -> userTokenAuthentication.authenticate(request).map(UserAuthResult::getUserDto));
+ return user.isPresent() || !config.getBoolean(CORE_FORCE_AUTHENTICATION_PROPERTY).orElse(CORE_FORCE_AUTHENTICATION_DEFAULT_VALUE);
} catch (AuthenticationException e) {
return false;
}
*/
package org.sonar.server.authentication.ws;
+import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Optional;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.web.FilterChain;
import org.sonar.server.authentication.BasicAuthentication;
+import org.sonar.server.authentication.HttpHeadersAuthentication;
import org.sonar.server.authentication.JwtHttpHandler;
+import org.sonar.server.authentication.UserAuthResult;
import org.sonar.server.authentication.event.AuthenticationException;
+import org.sonar.server.usertoken.UserTokenAuthentication;
import org.sonar.server.ws.ServletFilterHandler;
import org.sonar.test.JsonAssert;
import org.sonarqube.ws.MediaTypes;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.sonar.db.user.UserTesting.newUserDto;
+import static org.sonar.server.authentication.UserAuthResult.AuthType.TOKEN;
public class ValidateActionTest {
private final BasicAuthentication basicAuthentication = mock(BasicAuthentication.class);
private final JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
+ private final HttpHeadersAuthentication httpHeadersAuthentication = mock(HttpHeadersAuthentication.class);
+ private final UserTokenAuthentication userTokenAuthentication = mock(UserTokenAuthentication.class);
private final MapSettings settings = new MapSettings();
- private final ValidateAction underTest = new ValidateAction(settings.asConfig(), basicAuthentication, jwtHttpHandler);
+ private final ValidateAction underTest = new ValidateAction(settings.asConfig(), basicAuthentication, jwtHttpHandler, httpHeadersAuthentication, userTokenAuthentication);
@Before
public void setUp() throws Exception {
PrintWriter writer = new PrintWriter(stringWriter);
when(response.getWriter()).thenReturn(writer);
+ when(basicAuthentication.authenticate(request)).thenReturn(Optional.empty());
+ when(jwtHttpHandler.validateToken(request, response)).thenReturn(Optional.empty());
+ when(httpHeadersAuthentication.authenticate(request, response)).thenReturn(Optional.empty());
+ when(userTokenAuthentication.authenticate(request)).thenReturn(Optional.empty());
}
@Test
- public void verify_definition() {
+ public void define_shouldDefineWS() {
String controllerKey = "foo";
WebService.Context context = new WebService.Context();
WebService.NewController newController = context.createController(controllerKey);
}
@Test
- public void return_true_when_jwt_token_is_set() throws Exception {
+ public void doFilter_whenJwtToken_shouldReturnTrue() throws Exception {
when(jwtHttpHandler.validateToken(request, response)).thenReturn(Optional.of(newUserDto()));
- when(basicAuthentication.authenticate(request)).thenReturn(Optional.empty());
-
underTest.doFilter(request, response, chain);
-
- verify(response).setContentType(MediaTypes.JSON);
- JsonAssert.assertJson(stringWriter.toString()).isSimilarTo("{\"valid\":true}");
+ verifyResponseIsTrue();
}
@Test
- public void return_true_when_basic_auth() throws Exception {
- when(jwtHttpHandler.validateToken(request, response)).thenReturn(Optional.empty());
+ public void doFilter_whenBasicAuth_shouldReturnTrue() throws Exception {
when(basicAuthentication.authenticate(request)).thenReturn(Optional.of(newUserDto()));
-
underTest.doFilter(request, response, chain);
-
- verify(response).setContentType(MediaTypes.JSON);
- JsonAssert.assertJson(stringWriter.toString()).isSimilarTo("{\"valid\":true}");
+ verifyResponseIsTrue();
}
@Test
- public void return_true_when_no_jwt_nor_basic_auth_and_no_force_authentication() throws Exception {
+ public void doFilter_whenNoForceAuthentication_shoudlReturnTrue() throws Exception {
settings.setProperty("sonar.forceAuthentication", "false");
- when(jwtHttpHandler.validateToken(request, response)).thenReturn(Optional.empty());
- when(basicAuthentication.authenticate(request)).thenReturn(Optional.empty());
-
underTest.doFilter(request, response, chain);
-
- verify(response).setContentType(MediaTypes.JSON);
- JsonAssert.assertJson(stringWriter.toString()).isSimilarTo("{\"valid\":true}");
+ verifyResponseIsTrue();
}
@Test
- public void return_false_when_no_jwt_nor_basic_auth_and_force_authentication_is_true() throws Exception {
+ public void doFilter_whenForceAuthentication_shouldReturnFalse() throws Exception {
settings.setProperty("sonar.forceAuthentication", "true");
- when(jwtHttpHandler.validateToken(request, response)).thenReturn(Optional.empty());
- when(basicAuthentication.authenticate(request)).thenReturn(Optional.empty());
-
underTest.doFilter(request, response, chain);
-
- verify(response).setContentType(MediaTypes.JSON);
- JsonAssert.assertJson(stringWriter.toString()).isSimilarTo("{\"valid\":false}");
+ verifyResponseIsFalse();
}
@Test
- public void return_false_when_no_jwt_nor_basic_auth_and_force_authentication_fallback_to_default() throws Exception {
- when(jwtHttpHandler.validateToken(request, response)).thenReturn(Optional.empty());
- when(basicAuthentication.authenticate(request)).thenReturn(Optional.empty());
-
+ public void doFilter_whenDefaultForceAuthentication_shouldReturnFalse() throws Exception {
underTest.doFilter(request, response, chain);
-
- verify(response).setContentType(MediaTypes.JSON);
- JsonAssert.assertJson(stringWriter.toString()).isSimilarTo("{\"valid\":false}");
+ verifyResponseIsFalse();
}
@Test
- public void return_false_when_jwt_throws_unauthorized_exception() throws Exception {
+ public void doFilter_whenJwtThrowsUnauthorizedException_shouldReturnFalse() throws Exception {
doThrow(AuthenticationException.class).when(jwtHttpHandler).validateToken(request, response);
- when(basicAuthentication.authenticate(request)).thenReturn(Optional.empty());
+ underTest.doFilter(request, response, chain);
+ verifyResponseIsFalse();
+ }
+ @Test
+ public void doFilter_whenBasicAuthenticatorThrowsUnauthorizedException_shouldReturnFalse() throws Exception {
+ doThrow(AuthenticationException.class).when(basicAuthentication).authenticate(request);
underTest.doFilter(request, response, chain);
+ verifyResponseIsFalse();
+ }
- verify(response).setContentType(MediaTypes.JSON);
- JsonAssert.assertJson(stringWriter.toString()).isSimilarTo("{\"valid\":false}");
+ @Test
+ public void doFiler_whenHttpHeaderAuthentication_shouldReturnTrue() throws IOException {
+ when(httpHeadersAuthentication.authenticate(request, response)).thenReturn(Optional.of(newUserDto()));
+ underTest.doFilter(request, response, chain);
+ verifyResponseIsTrue();
}
@Test
- public void return_false_when_basic_authenticator_throws_unauthorized_exception() throws Exception {
- when(jwtHttpHandler.validateToken(request, response)).thenReturn(Optional.empty());
- doThrow(AuthenticationException.class).when(basicAuthentication).authenticate(request);
+ public void doFiler_whenHttpHeaderAuthenticationThrowsUnauthorizedException_shouldReturnFalse() throws IOException {
+ doThrow(AuthenticationException.class).when(httpHeadersAuthentication).authenticate(request, response);
+ underTest.doFilter(request, response, chain);
+ verifyResponseIsFalse();
+ }
+
+ @Test
+ public void doFilter_whenUserTokenAuthentication_shouldReturnTrue() throws IOException {
+ when(userTokenAuthentication.authenticate(request)).thenReturn(Optional.of(new UserAuthResult(newUserDto(), TOKEN)));
+ underTest.doFilter(request, response, chain);
+ verifyResponseIsTrue();
+ }
+ @Test
+ public void doFiler_whenUserTokenAuthenticationThrowsUnauthorizedException_shouldReturnFalse() throws IOException {
+ doThrow(AuthenticationException.class).when(httpHeadersAuthentication).authenticate(request, response);
underTest.doFilter(request, response, chain);
+ verifyResponseIsFalse();
+ }
+
+ private void verifyResponseIsFalse() {
+ verifyResponse("{\"valid\":false}");
+ }
+
+ private void verifyResponseIsTrue() {
+ verifyResponse("{\"valid\":true}");
+ }
+ private void verifyResponse(String expectedJson) {
verify(response).setContentType(MediaTypes.JSON);
- JsonAssert.assertJson(stringWriter.toString()).isSimilarTo("{\"valid\":false}");
+ JsonAssert.assertJson(stringWriter.toString()).isSimilarTo(expectedJson);
}
}