redirectToUnauthorized(response);
}
- static void handleAuthenticationError(AuthenticationException e, HttpServletResponse response) {
- redirectTo(response, getPath(e));
+ static void handleAuthenticationError(AuthenticationException e, HttpServletResponse response, String contextPath) {
+ redirectTo(response, getPath(e, contextPath));
}
- private static String getPath(AuthenticationException e) {
+ private static String getPath(AuthenticationException e, String contextPath) {
String publicMessage = e.getPublicMessage();
if (publicMessage == null || publicMessage.isEmpty()) {
return UNAUTHORIZED_PATH;
}
- return format(UNAUTHORIZED_PATH_WITH_MESSAGE, encodeMessage(publicMessage));
+ return contextPath + format(UNAUTHORIZED_PATH_WITH_MESSAGE, encodeMessage(publicMessage));
}
private static String encodeMessage(String message) {
}
return null;
}
+
+ String getContextPath() {
+ return server.getContextPath();
+ }
}
}
} catch (AuthenticationException e) {
authenticationEvent.loginFailure(request, e);
- handleAuthenticationError(e, response);
+ handleAuthenticationError(e, response, getContextPath());
} catch (Exception e) {
handleError(e, response, format("Fail to initialize authentication with provider '%s'", provider.getKey()));
}
}
} catch (AuthenticationException e) {
authenticationEvent.loginFailure(request, e);
- handleAuthenticationError(e, response);
+ handleAuthenticationError(e, response, getContextPath());
} catch (Exception e) {
handleError(e, response, format("Fail to callback authentication with '%s'", provider.getKey()));
}
}
if (isNotLocalOrJwt(e.getSource())) {
// redirect to Unauthorized error page
- handleAuthenticationError(e, response);
+ handleAuthenticationError(e, response, request.getContextPath());
return false;
}
// Rails will redirect to login page
assertThat(authenticationException.getPublicMessage()).isEqualTo("Email john@email.com is already used");
}
+ @Test
+ public void redirect_with_context_path_when_failing_because_of_UnauthorizedException() throws Exception {
+ when(server.getContextPath()).thenReturn("/sonarqube");
+ IdentityProvider identityProvider = new FailWithUnauthorizedExceptionIdProvider("failing");
+ when(request.getRequestURI()).thenReturn("/sonarqube/sessions/init/" + identityProvider.getKey());
+ identityProviderRepository.addIdentityProvider(identityProvider);
+
+ underTest.doFilter(request, response, chain);
+
+ verify(response).sendRedirect("/sonarqube/sessions/unauthorized?message=Email+john%40email.com+is+already+used");
+ }
+
private void assertOAuth2InitCalled() {
assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty();
assertThat(oAuth2IdentityProvider.isInitCalled()).isTrue();
public boolean isEnabled() {
return true;
}
-
@Override
public boolean allowsUsersToSignUp() {
return false;
}
+
}
}
assertThat(authenticationException.getPublicMessage()).isEqualTo("Email john@email.com is already used");
}
+ @Test
+ public void redirect_with_context_path_when_failing_because_of_UnauthorizedExceptionException() throws Exception {
+ when(server.getContextPath()).thenReturn("/sonarqube");
+ FailWithUnauthorizedExceptionIdProvider identityProvider = new FailWithUnauthorizedExceptionIdProvider();
+ identityProvider
+ .setKey("failing")
+ .setName("name of failing")
+ .setEnabled(true);
+ when(request.getRequestURI()).thenReturn("/sonarqube/oauth2/callback/" + identityProvider.getKey());
+ identityProviderRepository.addIdentityProvider(identityProvider);
+
+ underTest.doFilter(request, response, chain);
+
+ verify(response).sendRedirect("/sonarqube/sessions/unauthorized?message=Email+john%40email.com+is+already+used");
+ }
+
@Test
public void fail_when_no_oauth2_provider_provided() throws Exception {
when(request.getRequestURI()).thenReturn("/oauth2/callback");
import org.mockito.ArgumentCaptor;
import org.sonar.api.config.MapSettings;
import org.sonar.api.config.Settings;
+import org.sonar.api.server.authentication.BaseIdentityProvider;
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
verifyZeroInteractions(userSession);
}
+ @Test
+ public void return_to_session_unauthorized_when_error_on_from_external_provider() throws Exception {
+ when(ssoAuthenticator.authenticate(request, response)).thenReturn(Optional.empty());
+ doThrow(AuthenticationException.newBuilder().setSource(Source.external(newBasicIdentityProvider("failing"))).setPublicMessage("Token id hasn't been found").build())
+ .when(jwtHttpHandler).validateToken(request, response);
+
+ assertThat(underTest.initUserSession(request, response)).isFalse();
+
+ verify(response).sendRedirect("/sessions/unauthorized?message=Token+id+hasn%27t+been+found");
+ }
+
+ @Test
+ public void return_to_session_unauthorized_when_error_on_from_external_provider_with_context_path() throws Exception {
+ when(request.getContextPath()).thenReturn("/sonarqube");
+ when(ssoAuthenticator.authenticate(request, response)).thenReturn(Optional.empty());
+ doThrow(AuthenticationException.newBuilder().setSource(Source.external(newBasicIdentityProvider("failing"))).setPublicMessage("Token id hasn't been found").build())
+ .when(jwtHttpHandler).validateToken(request, response);
+
+ assertThat(underTest.initUserSession(request, response)).isFalse();
+
+ verify(response).sendRedirect("/sonarqube/sessions/unauthorized?message=Token+id+hasn%27t+been+found");
+ }
+
private void assertPathIsIgnored(String path) {
when(request.getRequestURI()).thenReturn(path);
verify(userSession).set(any(UserSession.class));
reset(userSession, jwtHttpHandler, basicAuthenticator);
}
+
+ private static BaseIdentityProvider newBasicIdentityProvider(String name) {
+ BaseIdentityProvider mock = mock(BaseIdentityProvider.class);
+ when(mock.getName()).thenReturn(name);
+ return mock;
+ }
}