From e9bd29e870b1f00eb7a2e62142eac2f152ae3a82 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Tue, 8 Jan 2019 12:33:58 +0100 Subject: [PATCH] SONAR-11610 Create api/users/update_login WS --- .../org/sonar/server/user/UserUpdater.java | 18 +- .../server/user/ws/UpdateLoginAction.java | 111 +++++++++ .../sonar/server/user/ws/UsersWsModule.java | 1 + .../server/user/UserUpdaterUpdateTest.java | 61 +++-- .../server/user/ws/UpdateLoginActionTest.java | 224 ++++++++++++++++++ .../server/user/ws/UsersWsModuleTest.java | 4 +- .../ws/client/users/UpdateLoginRequest.java | 61 +++++ .../ws/client/users/UsersService.java | 18 +- 8 files changed, 471 insertions(+), 27 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/user/ws/UpdateLoginAction.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/user/ws/UpdateLoginActionTest.java create mode 100644 sonar-ws/src/main/java/org/sonarqube/ws/client/users/UpdateLoginRequest.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/UserUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/user/UserUpdater.java index 5300f19b6d4..f85f3ce7ef3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/UserUpdater.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/UserUpdater.java @@ -225,14 +225,18 @@ public class UserUpdater { private boolean updateLogin(DbSession dbSession, UpdateUser updateUser, UserDto userDto, List messages) { String newLogin = updateUser.login(); - if (updateUser.isLoginChanged() && validateLoginFormat(newLogin, messages) && !Objects.equals(userDto.getLogin(), newLogin)) { - checkLoginUniqueness(dbSession, newLogin); - dbClient.propertiesDao().selectByKeyAndMatchingValue(dbSession, DEFAULT_ISSUE_ASSIGNEE, userDto.getLogin()) - .forEach(p -> dbClient.propertiesDao().saveProperty(p.setValue(newLogin))); - userDto.setLogin(newLogin); - return true; + if (!updateUser.isLoginChanged() || !validateLoginFormat(newLogin, messages) || Objects.equals(userDto.getLogin(), newLogin)) { + return false; } - return false; + checkLoginUniqueness(dbSession, newLogin); + dbClient.propertiesDao().selectByKeyAndMatchingValue(dbSession, DEFAULT_ISSUE_ASSIGNEE, userDto.getLogin()) + .forEach(p -> dbClient.propertiesDao().saveProperty(p.setValue(newLogin))); + userDto.setLogin(newLogin); + if (userDto.isLocal()) { + userDto.setExternalLogin(newLogin); + userDto.setExternalId(newLogin); + } + return true; } private static boolean updateName(UpdateUser updateUser, UserDto userDto, List messages) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/UpdateLoginAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/UpdateLoginAction.java new file mode 100644 index 00000000000..a8cf9135bbf --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/UpdateLoginAction.java @@ -0,0 +1,111 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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.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.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.user.UserDto; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.organization.OrganizationUpdater; +import org.sonar.server.user.UpdateUser; +import org.sonar.server.user.UserSession; +import org.sonar.server.user.UserUpdater; + +import static java.lang.String.format; +import static org.sonar.server.user.UserUpdater.LOGIN_MAX_LENGTH; +import static org.sonar.server.user.UserUpdater.LOGIN_MIN_LENGTH; + +public class UpdateLoginAction implements UsersWsAction { + + public static final String PARAM_LOGIN = "login"; + public static final String PARAM_NEW_LOGIN = "newLogin"; + + private final DbClient dbClient; + private final UserSession userSession; + private final UserUpdater userUpdater; + private final OrganizationUpdater organizationUpdater; + + public UpdateLoginAction(DbClient dbClient, UserSession userSession, UserUpdater userUpdater, OrganizationUpdater organizationUpdater) { + this.dbClient = dbClient; + this.userSession = userSession; + this.userUpdater = userUpdater; + this.organizationUpdater = organizationUpdater; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("update_login") + .setDescription("Update a user login. A login can be updated many times,
" + + "Updating the login of a user will invalidate his browser session, he will be required to login again.
" + + "Requires Administer System permission") + .setSince("7.6") + .setPost(true) + .setHandler(this); + + action.createParam(PARAM_LOGIN) + .setRequired(true) + .setDescription("The current login (case-sensitive)") + .setExampleValue("mylogin"); + + action.createParam(PARAM_NEW_LOGIN) + .setRequired(true) + .setMaximumLength(LOGIN_MAX_LENGTH) + .setMinimumLength(LOGIN_MIN_LENGTH) + .setDescription("The new login. It must not already exist.") + .setExampleValue("mynewlogin"); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkLoggedIn().checkIsSystemAdministrator(); + String login = request.mandatoryParam(PARAM_LOGIN); + String newLogin = request.mandatoryParam(PARAM_NEW_LOGIN); + try (DbSession dbSession = dbClient.openSession(false)) { + UserDto user = getUser(dbSession, login); + userUpdater.updateAndCommit( + dbSession, + user, + new UpdateUser().setLogin(newLogin), + u -> updatePersonalOrganization(dbSession, u)); + response.noContent(); + } + } + + private UserDto getUser(DbSession dbSession, String login) { + UserDto user = dbClient.userDao().selectByLogin(dbSession, login); + if (user == null || !user.isActive()) { + throw new NotFoundException(format("User '%s' doesn't exist", login)); + } + return user; + } + + private void updatePersonalOrganization(DbSession dbSession, UserDto user) { + String personalOrganizationUuid = user.getOrganizationUuid(); + if (personalOrganizationUuid == null) { + return; + } + dbClient.organizationDao().selectByUuid(dbSession, personalOrganizationUuid) + .ifPresent(organization -> organizationUpdater.updateOrganizationKey(dbSession, organization, user.getLogin())); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/UsersWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/UsersWsModule.java index 1fb48b966f6..8e94362ab4b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/UsersWsModule.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/UsersWsModule.java @@ -36,6 +36,7 @@ public class UsersWsModule extends Module { UsersWs.class, CreateAction.class, UpdateAction.class, + UpdateLoginAction.class, DeactivateAction.class, ChangePasswordAction.class, CurrentAction.class, diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/UserUpdaterUpdateTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/UserUpdaterUpdateTest.java index 65483a6d88b..9b03952c851 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/UserUpdaterUpdateTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/UserUpdaterUpdateTest.java @@ -36,7 +36,6 @@ import org.sonar.db.property.PropertyDto; import org.sonar.db.property.PropertyQuery; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; -import org.sonar.db.user.UserTesting; import org.sonar.server.authentication.CredentialsLocalAuthentication; import org.sonar.server.es.EsTester; import org.sonar.server.exceptions.BadRequestException; @@ -55,6 +54,7 @@ import static org.assertj.core.api.Assertions.tuple; import static org.assertj.core.data.MapEntry.entry; import static org.mockito.Mockito.mock; import static org.sonar.api.CoreProperties.DEFAULT_ISSUE_ASSIGNEE; +import static org.sonar.db.user.UserTesting.newExternalUser; import static org.sonar.db.user.UserTesting.newLocalUser; import static org.sonar.db.user.UserTesting.newUserDto; @@ -117,7 +117,7 @@ public class UserUpdaterUpdateTest { @Test public void update_user_external_identity_when_user_was_not_local() { - UserDto user = db.users().insertUser(UserTesting.newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com")); + UserDto user = db.users().insertUser(newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com")); createDefaultGroup(); underTest.updateAndCommit(session, user, new UpdateUser() @@ -172,23 +172,50 @@ public class UserUpdaterUpdateTest { } @Test - public void update_only_login() { - UserDto oldUser = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@lesbronzes.fr")); + public void update_only_login_of_local_account() { + UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@lesbronzes.fr")); createDefaultGroup(); - underTest.updateAndCommit(session, oldUser, new UpdateUser() + underTest.updateAndCommit(session, user, new UpdateUser() .setLogin("new_login"), u -> { }); assertThat(dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN)).isNull(); - UserDto dto = dbClient.userDao().selectByUuid(session, oldUser.getUuid()); - assertThat(dto.getLogin()).isEqualTo("new_login"); + UserDto userReloaded = dbClient.userDao().selectByUuid(session, user.getUuid()); + assertThat(userReloaded.getLogin()).isEqualTo("new_login"); + assertThat(userReloaded.getExternalIdentityProvider()).isEqualTo("sonarqube"); + assertThat(userReloaded.getExternalLogin()).isEqualTo("new_login"); + assertThat(userReloaded.getExternalId()).isEqualTo("new_login"); + // Following fields has not changed + assertThat(userReloaded.isLocal()).isTrue(); + assertThat(userReloaded.getName()).isEqualTo(user.getName()); + assertThat(userReloaded.getEmail()).isEqualTo(user.getEmail()); + assertThat(userReloaded.getScmAccountsAsList()).containsAll(user.getScmAccountsAsList()); + assertThat(userReloaded.getSalt()).isEqualTo(user.getSalt()); + assertThat(userReloaded.getCryptedPassword()).isEqualTo(user.getCryptedPassword()); + } + + @Test + public void update_only_login_of_external_account() { + UserDto user = db.users().insertUser(newExternalUser(DEFAULT_LOGIN, "Marius", "marius@lesbronzes.fr")); + createDefaultGroup(); + + underTest.updateAndCommit(session, user, new UpdateUser() + .setLogin("new_login"), u -> { + }); + + assertThat(dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN)).isNull(); + UserDto userReloaded = dbClient.userDao().selectByUuid(session, user.getUuid()); + assertThat(userReloaded.getLogin()).isEqualTo("new_login"); // Following fields has not changed - assertThat(dto.getName()).isEqualTo(oldUser.getName()); - assertThat(dto.getEmail()).isEqualTo(oldUser.getEmail()); - assertThat(dto.getScmAccountsAsList()).containsAll(oldUser.getScmAccountsAsList()); - assertThat(dto.getSalt()).isEqualTo(oldUser.getSalt()); - assertThat(dto.getCryptedPassword()).isEqualTo(oldUser.getCryptedPassword()); + assertThat(userReloaded.isLocal()).isFalse(); + assertThat(userReloaded.getExternalLogin()).isEqualTo(user.getExternalLogin()); + assertThat(userReloaded.getExternalId()).isEqualTo(user.getExternalId()); + assertThat(userReloaded.getName()).isEqualTo(user.getName()); + assertThat(userReloaded.getEmail()).isEqualTo(user.getEmail()); + assertThat(userReloaded.getScmAccountsAsList()).containsAll(user.getScmAccountsAsList()); + assertThat(userReloaded.getSalt()).isEqualTo(user.getSalt()); + assertThat(userReloaded.getCryptedPassword()).isEqualTo(user.getCryptedPassword()); } @Test @@ -352,7 +379,7 @@ public class UserUpdaterUpdateTest { @Test public void update_only_external_id() { - UserDto user = db.users().insertUser(UserTesting.newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com") + UserDto user = db.users().insertUser(newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com") .setExternalId("1234") .setExternalLogin("john.smith") .setExternalIdentityProvider("github")); @@ -368,7 +395,7 @@ public class UserUpdaterUpdateTest { @Test public void update_only_external_login() { - UserDto user = db.users().insertUser(UserTesting.newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com") + UserDto user = db.users().insertUser(newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com") .setExternalId("ABCD") .setExternalLogin("john") .setExternalIdentityProvider("github")); @@ -384,7 +411,7 @@ public class UserUpdaterUpdateTest { @Test public void update_only_external_identity_provider() { - UserDto user = db.users().insertUser(UserTesting.newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com") + UserDto user = db.users().insertUser(newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com") .setExternalId("ABCD") .setExternalLogin("john") .setExternalIdentityProvider("github")); @@ -400,7 +427,7 @@ public class UserUpdaterUpdateTest { @Test public void does_not_update_user_when_no_change() { - UserDto user = UserTesting.newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com") + UserDto user = newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com") .setScmAccounts(asList("ma1", "ma2")); db.users().insertUser(user); createDefaultGroup(); @@ -417,7 +444,7 @@ public class UserUpdaterUpdateTest { @Test public void does_not_update_user_when_no_change_and_scm_account_reordered() { - UserDto user = UserTesting.newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com") + UserDto user = newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com") .setScmAccounts(asList("ma1", "ma2")); db.users().insertUser(user); createDefaultGroup(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/UpdateLoginActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/UpdateLoginActionTest.java new file mode 100644 index 00000000000..782a680c38f --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/UpdateLoginActionTest.java @@ -0,0 +1,224 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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.user.ws; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.config.internal.MapSettings; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.server.ws.WebService.Param; +import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactoryFast; +import org.sonar.db.DbTester; +import org.sonar.db.organization.OrganizationDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.es.EsTester; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.organization.OrganizationUpdater; +import org.sonar.server.organization.OrganizationUpdaterImpl; +import org.sonar.server.organization.OrganizationValidationImpl; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.user.NewUserNotifier; +import org.sonar.server.user.UserUpdater; +import org.sonar.server.user.index.UserIndexer; +import org.sonar.server.ws.TestResponse; +import org.sonar.server.ws.WsActionTester; + +import static java.lang.String.format; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; +import static org.mockito.Mockito.mock; + +public class UpdateLoginActionTest { + + private System2 system2 = new System2(); + + @Rule + public DbTester db = DbTester.create(system2); + @Rule + public EsTester es = EsTester.create(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone().logIn().setSystemAdministrator(); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private MapSettings settings = new MapSettings(); + private OrganizationUpdater organizationUpdater = new OrganizationUpdaterImpl(db.getDbClient(), mock(System2.class), UuidFactoryFast.getInstance(), + new OrganizationValidationImpl(), settings.asConfig(), null, null, null, null); + + private WsActionTester ws = new WsActionTester(new UpdateLoginAction(db.getDbClient(), userSession, + new UserUpdater(system2, mock(NewUserNotifier.class), db.getDbClient(), new UserIndexer(db.getDbClient(), es.client()), + null, null, null, null, null, null), + organizationUpdater)); + + @Test + public void update_login_from_sonarqube_account() { + userSession.logIn().setSystemAdministrator(); + UserDto user = db.users().insertUser(u -> u + .setLogin("old_login") + .setLocal(true) + .setExternalIdentityProvider("sonarqube") + .setExternalLogin("old_login") + .setExternalId("old_login")); + + ws.newRequest() + .setParam("login", user.getLogin()) + .setParam("newLogin", "new_login") + .execute(); + + assertThat(db.getDbClient().userDao().selectByLogin(db.getSession(), "old_login")).isNull(); + UserDto userReloaded = db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()); + assertThat(userReloaded.getLogin()).isEqualTo("new_login"); + assertThat(userReloaded.getExternalLogin()).isEqualTo("new_login"); + assertThat(userReloaded.getExternalId()).isEqualTo("new_login"); + assertThat(userReloaded.isLocal()).isTrue(); + assertThat(userReloaded.getCryptedPassword()).isNotNull().isEqualTo(user.getCryptedPassword()); + assertThat(userReloaded.getSalt()).isNotNull().isEqualTo(user.getSalt()); + } + + @Test + public void update_login_from_external_account() { + userSession.logIn().setSystemAdministrator(); + UserDto user = db.users().insertUser(u -> u + .setLogin("old_login") + .setLocal(false) + .setExternalIdentityProvider("github") + .setExternalLogin("github_login") + .setExternalId("github_id") + .setCryptedPassword(null) + .setSalt(null)); + + ws.newRequest() + .setParam("login", user.getLogin()) + .setParam("newLogin", "new_login") + .execute(); + + UserDto userReloaded = db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()); + assertThat(userReloaded.getLogin()).isEqualTo("new_login"); + assertThat(userReloaded.getExternalLogin()).isEqualTo("github_login"); + assertThat(userReloaded.getExternalId()).isEqualTo("github_id"); + assertThat(userReloaded.isLocal()).isFalse(); + assertThat(userReloaded.getCryptedPassword()).isNull(); + assertThat(userReloaded.getSalt()).isNull(); + } + + @Test + public void update_personal_organization_when_updating_login() { + userSession.logIn().setSystemAdministrator(); + String oldLogin = "old_login"; + OrganizationDto personalOrganization = db.organizations().insert(o -> o.setKey(oldLogin).setGuarded(true)); + UserDto user = db.users().insertUser(u -> u.setLogin(oldLogin).setOrganizationUuid(personalOrganization.getUuid())); + + ws.newRequest() + .setParam("login", oldLogin) + .setParam("newLogin", "new_login") + .execute(); + + UserDto userReloaded = db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()); + assertThat(userReloaded.getLogin()).isEqualTo("new_login"); + OrganizationDto organizationReloaded = db.getDbClient().organizationDao().selectByUuid(db.getSession(), personalOrganization.getUuid()).get(); + assertThat(organizationReloaded.getKey()).isEqualTo("new_login"); + } + + @Test + public void fail_with_IAE_when_new_login_is_already_used() { + userSession.logIn().setSystemAdministrator(); + UserDto user = db.users().insertUser(); + UserDto user2 = db.users().insertUser(); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage(format("A user with login '%s' already exists", user2.getLogin())); + + ws.newRequest() + .setParam("login", user.getLogin()) + .setParam("newLogin", user2.getLogin()) + .execute(); + } + + @Test + public void fail_with_NFE_when_login_does_not_match_active_user() { + userSession.logIn().setSystemAdministrator(); + UserDto user = db.users().insertDisabledUser(); + + expectedException.expect(NotFoundException.class); + expectedException.expectMessage(format("User '%s' doesn't exist", user.getLogin())); + + ws.newRequest() + .setParam("login", user.getLogin()) + .setParam("newLogin", "new_login") + .execute(); + } + + @Test + public void fail_with_NFE_when_login_does_not_match_existing_user() { + userSession.logIn().setSystemAdministrator(); + + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("User 'unknown' doesn't exist"); + + ws.newRequest() + .setParam("login", "unknown") + .setParam("newLogin", "new_login") + .execute(); + } + + @Test + public void fail_when_not_system_administrator() { + userSession.logIn(); + + expectedException.expect(ForbiddenException.class); + + ws.newRequest() + .setParam("login", "old_login") + .setParam("newLogin", "new_login") + .execute(); + } + + @Test + public void response_has_no_content() { + UserDto user = db.users().insertUser(); + userSession.logIn().setSystemAdministrator(); + + TestResponse response = ws.newRequest() + .setParam("login", user.getLogin()) + .setParam("newLogin", "new_login") + .execute(); + + assertThat(response.getStatus()).isEqualTo(204); + assertThat(response.getInput()).isEmpty(); + } + + @Test + public void test_definition() { + WebService.Action def = ws.getDef(); + assertThat(def.key()).isEqualTo("update_login"); + assertThat(def.isPost()).isTrue(); + assertThat(def.isInternal()).isFalse(); + assertThat(def.since()).isEqualTo("7.6"); + + assertThat(def.params()) + .extracting(Param::key, Param::isRequired, Param::maximumLength, Param::minimumLength) + .containsExactlyInAnyOrder( + tuple("login", true, null, null), + tuple("newLogin", true, 255, 2)); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsModuleTest.java index 909f1163e63..1fbd80a8f78 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsModuleTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsModuleTest.java @@ -34,7 +34,7 @@ public class UsersWsModuleTest { public void verify_count_of_added_components() { ComponentContainer container = new ComponentContainer(); new UsersWsModule(new ConfigurationBridge(settings)).configure(container); - assertThat(container.size()).isEqualTo(2 + 14); + assertThat(container.size()).isEqualTo(2 + 15); } @Test @@ -43,6 +43,6 @@ public class UsersWsModuleTest { ComponentContainer container = new ComponentContainer(); new UsersWsModule(new ConfigurationBridge(settings)).configure(container); - assertThat(container.size()).isEqualTo(2 + 15); + assertThat(container.size()).isEqualTo(2 + 16); } } diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UpdateLoginRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UpdateLoginRequest.java new file mode 100644 index 00000000000..62eb60e66ce --- /dev/null +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UpdateLoginRequest.java @@ -0,0 +1,61 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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.sonarqube.ws.client.users; + +import javax.annotation.Generated; + +/** + * This is part of the internal API. + * This is a POST request. + * @see Further information about this action online (including a response example) + * @since 7.6 + */ +@Generated("sonar-ws-generator") +public class UpdateLoginRequest { + + private String login; + private String newLogin; + + /** + * This is a mandatory parameter. + * Example value: "mylogin" + */ + public UpdateLoginRequest setLogin(String login) { + this.login = login; + return this; + } + + public String getLogin() { + return login; + } + + /** + * This is a mandatory parameter. + * Example value: "mynewlogin" + */ + public UpdateLoginRequest setNewLogin(String newLogin) { + this.newLogin = newLogin; + return this; + } + + public String getNewLogin() { + return newLogin; + } +} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UsersService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UsersService.java index 8b71cb051e7..dcbda8e2c2b 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UsersService.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UsersService.java @@ -169,7 +169,7 @@ public class UsersService extends BaseService { .setParam("parameter", request.getParameter()) .setParam("type", request.getType()) .setMediaType(MediaTypes.JSON) - ).content(); + ).content(); } /** @@ -220,4 +220,20 @@ public class UsersService extends BaseService { .setMediaType(MediaTypes.JSON) ).content(); } + + /** + * + * This is part of the internal API. + * This is a POST request. + * @see Further information about this action online (including a response example) + * @since 7.6 + */ + public void updateLogin(UpdateLoginRequest request) { + call( + new PostRequest(path("update_login")) + .setParam("login", request.getLogin()) + .setParam("newLogin", request.getNewLogin()) + .setMediaType(MediaTypes.JSON) + ).content(); + } } -- 2.39.5