From 1b181d06e75aaebc188155ab60888bb6ba98226c Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Fri, 2 Dec 2016 17:12:57 +0100 Subject: [PATCH] SONAR-7774 Create AuthenticationWsAction marker interface --- .../UserSessionInitializer.java | 8 +-- .../authentication/ws/AuthenticationWs.java | 52 ++++--------------- .../ws/AuthenticationWsAction.java | 29 +++++++++++ .../server/authentication/ws/LoginAction.java | 25 +++++++-- .../authentication/ws/LogoutAction.java | 19 +++++-- .../authentication/ws/ValidateAction.java | 20 +++++-- .../ws/AuthenticationWsTest.java | 8 ++- 7 files changed, 104 insertions(+), 57 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/authentication/ws/AuthenticationWsAction.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java index 9a721554920..df21619b05b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java +++ b/server/sonar-server/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java @@ -41,9 +41,9 @@ import static org.sonar.api.web.ServletFilter.UrlPattern.Builder.staticResourceP import static org.sonar.server.authentication.AuthenticationError.handleAuthenticationError; import static org.sonar.server.authentication.event.AuthenticationEvent.Method; import static org.sonar.server.authentication.event.AuthenticationEvent.Source; -import static org.sonar.server.authentication.ws.LoginAction.AUTH_LOGIN_URL; -import static org.sonar.server.authentication.ws.LogoutAction.AUTH_LOGOUT_URL; -import static org.sonar.server.authentication.ws.ValidateAction.AUTH_VALIDATE_URL; +import static org.sonar.server.authentication.ws.LoginAction.LOGIN_URL; +import static org.sonar.server.authentication.ws.LogoutAction.LOGOUT_URL; +import static org.sonar.server.authentication.ws.ValidateAction.VALIDATE_URL; import static org.sonar.server.user.ServerUserSession.createForAnonymous; import static org.sonar.server.user.ServerUserSession.createForUser; @@ -65,7 +65,7 @@ public class UserSessionInitializer { "/sessions/*", "/api/system/db_migration_status", "/api/system/status", "/api/system/migrate_db", "/api/server/index", "/api/server/setup", "/api/server/version", - AUTH_LOGIN_URL, AUTH_VALIDATE_URL, AUTH_LOGOUT_URL); + LOGIN_URL, LOGOUT_URL, VALIDATE_URL); private static final UrlPattern URL_PATTERN = UrlPattern.builder() .includes("/*") diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/AuthenticationWs.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/AuthenticationWs.java index f17864b081e..b8c186ec4d4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/AuthenticationWs.java +++ b/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/AuthenticationWs.java @@ -19,55 +19,23 @@ */ package org.sonar.server.authentication.ws; -import com.google.common.io.Resources; -import org.sonar.api.server.ws.RailsHandler; +import java.util.List; import org.sonar.api.server.ws.WebService; -import org.sonar.server.ws.ServletFilterHandler; public class AuthenticationWs implements WebService { + public static final String AUTHENTICATION_CONTROLLER = "api/authentication"; + private final List actions; + + public AuthenticationWs(List actions) { + this.actions = actions; + } + @Override public void define(Context context) { - NewController controller = context.createController("api/authentication"); + NewController controller = context.createController(AUTHENTICATION_CONTROLLER); controller.setDescription("Handle authentication."); - - defineLoginAction(controller); - defineLogoutAction(controller); - defineValidateAction(controller); - + actions.forEach(action -> action.define(controller)); controller.done(); } - - private void defineValidateAction(NewController controller) { - NewAction action = controller.createAction("validate") - .setDescription("Check credentials.") - .setSince("3.3") - .setHandler(ServletFilterHandler.INSTANCE) - .setResponseExample(Resources.getResource(this.getClass(), "example-validate.json")); - - RailsHandler.addFormatParam(action); - } - - private static void defineLoginAction(NewController controller) { - NewAction action = controller.createAction("login") - .setDescription("Authenticate a user.") - .setSince("6.0") - .setPost(true) - .setHandler(ServletFilterHandler.INSTANCE); - action.createParam("login") - .setDescription("Login of the user") - .setRequired(true); - action.createParam("password") - .setDescription("Password of the user") - .setRequired(true); - } - - private static void defineLogoutAction(NewController controller) { - controller.createAction("logout") - .setDescription("Logout a user.") - .setSince("6.3") - .setPost(true) - .setHandler(ServletFilterHandler.INSTANCE); - } - } diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/AuthenticationWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/AuthenticationWsAction.java new file mode 100644 index 00000000000..d285d77903a --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/AuthenticationWsAction.java @@ -0,0 +1,29 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.authentication.ws; + +import org.sonar.api.server.ws.WebService; + +@FunctionalInterface +public interface AuthenticationWsAction { + // marker interface + + void define(WebService.NewController controller); +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/LoginAction.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/LoginAction.java index 6ca2cfead94..7e3cd764801 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/LoginAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/LoginAction.java @@ -29,6 +29,7 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.sonar.api.server.ws.WebService; import org.sonar.api.web.ServletFilter; import org.sonar.db.DbClient; import org.sonar.db.user.UserDto; @@ -39,17 +40,20 @@ import org.sonar.server.authentication.event.AuthenticationException; import org.sonar.server.exceptions.UnauthorizedException; import org.sonar.server.user.ServerUserSession; import org.sonar.server.user.ThreadLocalUserSession; +import org.sonar.server.ws.ServletFilterHandler; import static java.net.HttpURLConnection.HTTP_BAD_REQUEST; import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED; import static org.apache.commons.lang.StringUtils.isEmpty; import static org.sonar.server.authentication.event.AuthenticationEvent.Method; 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 { +public class LoginAction extends ServletFilter implements AuthenticationWsAction { - public static final String AUTH_LOGIN_URL = "/api/authentication/login"; + private static final String LOGIN_ACTION = "login"; + public static final String LOGIN_URL = "/" + AUTHENTICATION_CONTROLLER + "/" + LOGIN_ACTION; private final DbClient dbClient; private final CredentialsAuthenticator credentialsAuthenticator; @@ -66,9 +70,24 @@ public class LoginAction extends ServletFilter { this.authenticationEvent = authenticationEvent; } + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction(LOGIN_ACTION) + .setDescription("Authenticate a user.") + .setSince("6.0") + .setPost(true) + .setHandler(ServletFilterHandler.INSTANCE); + action.createParam("login") + .setDescription("Login of the user") + .setRequired(true); + action.createParam("password") + .setDescription("Password of the user") + .setRequired(true); + } + @Override public UrlPattern doGetPattern() { - return UrlPattern.create(AUTH_LOGIN_URL); + return UrlPattern.create(LOGIN_URL); } @Override diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/LogoutAction.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/LogoutAction.java index 2fe77c2f8bc..aa48ec86df3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/LogoutAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/LogoutAction.java @@ -29,18 +29,22 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.sonar.api.server.ws.WebService; import org.sonar.api.web.ServletFilter; import org.sonar.server.authentication.JwtHttpHandler; import org.sonar.server.authentication.event.AuthenticationEvent; import org.sonar.server.authentication.event.AuthenticationException; +import org.sonar.server.ws.ServletFilterHandler; import static java.net.HttpURLConnection.HTTP_BAD_REQUEST; import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED; +import static org.sonar.server.authentication.ws.AuthenticationWs.AUTHENTICATION_CONTROLLER; import static org.sonarqube.ws.client.WsRequest.Method.POST; -public class LogoutAction extends ServletFilter { +public class LogoutAction extends ServletFilter implements AuthenticationWsAction { - public static final String AUTH_LOGOUT_URL = "/api/authentication/logout"; + private static final String LOGOUT_ACTION = "logout"; + public static final String LOGOUT_URL = "/" + AUTHENTICATION_CONTROLLER + "/" + LOGOUT_ACTION; private final JwtHttpHandler jwtHttpHandler; private final AuthenticationEvent authenticationEvent; @@ -50,9 +54,18 @@ public class LogoutAction extends ServletFilter { this.authenticationEvent = authenticationEvent; } + @Override + public void define(WebService.NewController controller) { + controller.createAction(LOGOUT_ACTION) + .setDescription("Logout a user.") + .setSince("6.3") + .setPost(true) + .setHandler(ServletFilterHandler.INSTANCE); + } + @Override public UrlPattern doGetPattern() { - return UrlPattern.create(AUTH_LOGOUT_URL); + return UrlPattern.create(LOGOUT_URL); } @Override diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/ValidateAction.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/ValidateAction.java index 60791c2607a..1aed8f0ed5b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/ValidateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/ValidateAction.java @@ -20,6 +20,7 @@ package org.sonar.server.authentication.ws; +import com.google.common.io.Resources; import java.io.IOException; import java.util.Optional; import javax.servlet.FilterChain; @@ -30,19 +31,23 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.sonar.api.config.Settings; +import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.text.JsonWriter; import org.sonar.api.web.ServletFilter; import org.sonar.db.user.UserDto; import org.sonar.server.authentication.BasicAuthenticator; import org.sonar.server.authentication.JwtHttpHandler; import org.sonar.server.authentication.event.AuthenticationException; +import org.sonar.server.ws.ServletFilterHandler; import org.sonarqube.ws.MediaTypes; 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 { +public class ValidateAction extends ServletFilter implements AuthenticationWsAction { - public static final String AUTH_VALIDATE_URL = "/api/authentication/validate"; + private static final String VALIDATE_ACTION = "validate"; + public static final String VALIDATE_URL = "/" + AUTHENTICATION_CONTROLLER + "/" + VALIDATE_ACTION; private final Settings settings; private final JwtHttpHandler jwtHttpHandler; @@ -54,9 +59,18 @@ public class ValidateAction extends ServletFilter { this.jwtHttpHandler = jwtHttpHandler; } + @Override + public void define(WebService.NewController controller) { + controller.createAction("validate") + .setDescription("Check credentials.") + .setSince("3.3") + .setHandler(ServletFilterHandler.INSTANCE) + .setResponseExample(Resources.getResource(this.getClass(), "example-validate.json")); + } + @Override public UrlPattern doGetPattern() { - return UrlPattern.create(AUTH_VALIDATE_URL); + return UrlPattern.create(VALIDATE_URL); } @Override diff --git a/server/sonar-server/src/test/java/org/sonar/server/authentication/ws/AuthenticationWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/authentication/ws/AuthenticationWsTest.java index 980e4a2e433..86c916212a1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/authentication/ws/AuthenticationWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/authentication/ws/AuthenticationWsTest.java @@ -19,6 +19,7 @@ */ package org.sonar.server.authentication.ws; +import java.util.Arrays; import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.server.ws.ServletFilterHandler; @@ -28,7 +29,10 @@ import static org.assertj.core.api.Assertions.assertThat; public class AuthenticationWsTest { - WsTester tester = new WsTester(new AuthenticationWs()); + WsTester tester = new WsTester(new AuthenticationWs(Arrays.asList( + new LoginAction(null, null, null, null, null), + new LogoutAction(null, null), + new ValidateAction(null, null, null)))); @Test public void define_ws() { @@ -41,7 +45,7 @@ public class AuthenticationWsTest { assertThat(validate).isNotNull(); assertThat(validate.handler()).isInstanceOf(ServletFilterHandler.class); assertThat(validate.responseExampleAsString()).isNotEmpty(); - assertThat(validate.params()).hasSize(1); + assertThat(validate.params()).isEmpty(); WebService.Action login = controller.action("login"); assertThat(login).isNotNull(); -- 2.39.5