From: Jean-Baptiste Lievremont Date: Tue, 5 May 2015 11:58:38 +0000 (+0200) Subject: SONAR-6469 New Java WS to deactivate a user X-Git-Tag: 5.2-RC1~2034 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=refs%2Fpull%2F287%2Fhead;p=sonarqube.git SONAR-6469 New Java WS to deactivate a user --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index 9012a2c3f9a..ee2eb8f31e2 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -19,13 +19,7 @@ */ package org.sonar.server.platform; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Properties; - -import javax.annotation.Nullable; - +import com.google.common.collect.Lists; import org.sonar.api.config.EmailSettings; import org.sonar.api.issue.action.Actions; import org.sonar.api.platform.ComponentContainer; @@ -398,7 +392,12 @@ import org.sonar.server.view.index.ViewIndexer; import org.sonar.server.ws.ListingWs; import org.sonar.server.ws.WebServiceEngine; -import com.google.common.collect.Lists; +import javax.annotation.Nullable; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Properties; class ServerComponents { @@ -757,6 +756,7 @@ class ServerComponents { pico.addSingleton(UsersWs.class); pico.addSingleton(org.sonar.server.user.ws.CreateAction.class); pico.addSingleton(org.sonar.server.user.ws.UpdateAction.class); + pico.addSingleton(org.sonar.server.user.ws.DeactivateAction.class); pico.addSingleton(org.sonar.server.user.ws.CurrentUserAction.class); pico.addSingleton(org.sonar.server.user.ws.SearchAction.class); pico.addSingleton(org.sonar.server.issue.ws.AuthorsAction.class); diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/DeactivateAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/DeactivateAction.java new file mode 100644 index 00000000000..fc53f38bf3a --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/DeactivateAction.java @@ -0,0 +1,86 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.user.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.server.ws.WebService.NewAction; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.user.UserSession; +import org.sonar.server.user.UserUpdater; +import org.sonar.server.user.index.UserDoc; +import org.sonar.server.user.index.UserIndex; + +public class DeactivateAction implements BaseUsersWsAction { + + private static final String PARAM_LOGIN = "login"; + + private final UserIndex index; + private final UserUpdater userUpdater; + + public DeactivateAction(UserIndex index, UserUpdater userUpdater) { + this.index = index; + this.userUpdater = userUpdater; + } + + @Override + public void define(WebService.NewController controller) { + NewAction action = controller.createAction("deactivate") + .setDescription("Deactivate a user. Requires Administer System permission") + .setSince("3.7") + .setPost(true) + .setHandler(this); + + action.createParam("login") + .setDescription("User login") + .setRequired(true) + .setExampleValue("myuser"); + } + + @Override + public void handle(Request request, Response response) throws Exception { + UserSession.get().checkLoggedIn().checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN); + + String login = request.mandatoryParam(PARAM_LOGIN); + userUpdater.deactivateUserByLogin(login); + + writeResponse(response, login); + } + + private void writeResponse(Response response, String login) { + UserDoc user = index.getByLogin(login); + JsonWriter json = response.newJsonWriter().beginObject(); + writeUser(json, user); + json.endObject().close(); + } + + private void writeUser(JsonWriter json, UserDoc user) { + json.name("user").beginObject() + .prop("login", user.login()) + .prop("name", user.name()) + .prop("email", user.email()) + .prop("active", user.active()) + .name("scmAccounts").beginArray().values(user.scmAccounts()).endArray() + .endObject(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/UsersWs.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/UsersWs.java index 492de53a274..7a96a62140d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/UsersWs.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/UsersWs.java @@ -39,7 +39,6 @@ public class UsersWs implements WebService { .setDescription("Users management"); defineSearchAction(controller); - defineDeactivateAction(controller); for (BaseUsersWsAction action : actions) { action.define(controller); } @@ -69,20 +68,4 @@ public class UsersWs implements WebService { RailsHandler.addFormatParam(action); } - - private void defineDeactivateAction(NewController controller) { - NewAction action = controller.createAction("deactivate") - .setDescription("Deactivate a user. Requires Administer System permission") - .setSince("3.7") - .setPost(true) - .setHandler(RailsHandler.INSTANCE); - - action.createParam("login") - .setDescription("User login") - .setRequired(true) - .setExampleValue("myuser"); - - RailsHandler.addFormatParam(action); - } - } diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/DeactivateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/DeactivateActionTest.java new file mode 100644 index 00000000000..772e91dc61f --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/DeactivateActionTest.java @@ -0,0 +1,146 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.user.ws; + +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.api.config.Settings; +import org.sonar.api.i18n.I18n; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.utils.System2; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.DbTester; +import org.sonar.core.user.UserDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.es.EsTester; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.user.MockUserSession; +import org.sonar.server.user.NewUserNotifier; +import org.sonar.server.user.UserUpdater; +import org.sonar.server.user.db.UserDao; +import org.sonar.server.user.index.UserDoc; +import org.sonar.server.user.index.UserIndex; +import org.sonar.server.user.index.UserIndexDefinition; +import org.sonar.server.user.index.UserIndexer; +import org.sonar.server.ws.WsTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +@RunWith(MockitoJUnitRunner.class) +public class DeactivateActionTest { + + static final Settings settings = new Settings(); + + @ClassRule + public static final DbTester dbTester = new DbTester(); + + @ClassRule + public static final EsTester esTester = new EsTester().addDefinitions(new UserIndexDefinition(settings)); + + WebService.Controller controller; + + WsTester tester; + + UserIndex index; + + DbClient dbClient; + + UserIndexer userIndexer; + + DbSession session; + + @Mock + I18n i18n; + + @Before + public void setUp() throws Exception { + dbTester.truncateTables(); + esTester.truncateIndices(); + + System2 system2 = new System2(); + UserDao userDao = new UserDao(dbTester.myBatis(), system2); + dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), userDao); + session = dbClient.openSession(false); + session.commit(); + + userIndexer = (UserIndexer) new UserIndexer(dbClient, esTester.client()).setEnabled(true); + index = new UserIndex(esTester.client()); + tester = new WsTester(new UsersWs(new DeactivateAction(index, + new UserUpdater(mock(NewUserNotifier.class), settings, dbClient, userIndexer, system2)))); + controller = tester.controller("api/users"); + + } + + @After + public void tearDown() throws Exception { + session.close(); + } + + @Test + public void deactivate_user() throws Exception { + createUser(); + + MockUserSession.set().setLogin("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + tester.newPostRequest("api/users", "deactivate") + .setParam("login", "john") + .execute() + .assertJson(getClass(), "deactivate_user.json"); + + UserDoc user = index.getByLogin("john"); + assertThat(user.active()).isFalse(); + } + + @Test(expected = ForbiddenException.class) + public void fail_on_missing_permission() throws Exception { + createUser(); + + MockUserSession.set().setLogin("not_admin"); + tester.newPostRequest("api/users", "deactivate") + .setParam("login", "john").execute(); + } + + @Test(expected = NotFoundException.class) + public void fail_on_unknown_user() throws Exception { + MockUserSession.set().setLogin("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + tester.newPostRequest("api/users", "deactivate") + .setParam("login", "john").execute(); + } + + private void createUser() { + dbClient.userDao().insert(session, new UserDto() + .setActive(true) + .setEmail("john@email.com") + .setLogin("john") + .setName("John") + .setScmAccounts("jn")); + session.commit(); + userIndexer.index(); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsTest.java index f7da72560d7..75f3f8ffc2b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsTest.java @@ -41,7 +41,8 @@ public class UsersWsTest { WsTester tester = new WsTester(new UsersWs( new CreateAction(mock(UserIndex.class), mock(UserUpdater.class), mock(I18n.class)), new UpdateAction(mock(UserIndex.class), mock(UserUpdater.class)), - new CurrentUserAction())); + new CurrentUserAction(), + new DeactivateAction(mock(UserIndex.class), mock(UserUpdater.class)))); controller = tester.controller("api/users"); } @@ -84,8 +85,7 @@ public class UsersWsTest { WebService.Action action = controller.action("deactivate"); assertThat(action).isNotNull(); assertThat(action.isPost()).isTrue(); - assertThat(action.handler()).isInstanceOf(RailsHandler.class); - assertThat(action.params()).hasSize(2); + assertThat(action.params()).hasSize(1); } @Test diff --git a/server/sonar-server/src/test/resources/org/sonar/server/user/ws/DeactivateActionTest/deactivate_user.json b/server/sonar-server/src/test/resources/org/sonar/server/user/ws/DeactivateActionTest/deactivate_user.json new file mode 100644 index 00000000000..b532305cb1b --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/user/ws/DeactivateActionTest/deactivate_user.json @@ -0,0 +1,9 @@ +{ + "user": { + "login": "john", + "name": "John", + "email": "john@email.com", + "scmAccounts": ["jn"], + "active": false + } +}