You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UserUpdaterUpdateTest.java 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.server.user;
  21. import com.google.common.collect.Multimap;
  22. import java.util.List;
  23. import org.elasticsearch.search.SearchHit;
  24. import org.junit.Rule;
  25. import org.junit.Test;
  26. import org.junit.rules.ExpectedException;
  27. import org.sonar.api.config.internal.MapSettings;
  28. import org.sonar.api.utils.System2;
  29. import org.sonar.api.utils.internal.AlwaysIncreasingSystem2;
  30. import org.sonar.db.DbClient;
  31. import org.sonar.db.DbSession;
  32. import org.sonar.db.DbTester;
  33. import org.sonar.db.component.ComponentDto;
  34. import org.sonar.db.property.PropertyDto;
  35. import org.sonar.db.property.PropertyQuery;
  36. import org.sonar.db.user.GroupDto;
  37. import org.sonar.db.user.UserDto;
  38. import org.sonar.server.authentication.CredentialsLocalAuthentication;
  39. import org.sonar.server.es.EsTester;
  40. import org.sonar.server.exceptions.BadRequestException;
  41. import org.sonar.server.organization.DefaultOrganizationProvider;
  42. import org.sonar.server.organization.OrganizationUpdater;
  43. import org.sonar.server.organization.TestDefaultOrganizationProvider;
  44. import org.sonar.server.organization.TestOrganizationFlags;
  45. import org.sonar.server.user.index.UserIndexDefinition;
  46. import org.sonar.server.user.index.UserIndexer;
  47. import org.sonar.server.usergroups.DefaultGroupFinder;
  48. import static java.util.Arrays.asList;
  49. import static java.util.Collections.singletonList;
  50. import static org.assertj.core.api.Assertions.assertThat;
  51. import static org.assertj.core.api.Assertions.tuple;
  52. import static org.assertj.core.data.MapEntry.entry;
  53. import static org.mockito.Mockito.mock;
  54. import static org.sonar.api.CoreProperties.DEFAULT_ISSUE_ASSIGNEE;
  55. import static org.sonar.db.user.UserTesting.newExternalUser;
  56. import static org.sonar.db.user.UserTesting.newLocalUser;
  57. import static org.sonar.db.user.UserTesting.newUserDto;
  58. public class UserUpdaterUpdateTest {
  59. private static final String DEFAULT_LOGIN = "marius";
  60. private System2 system2 = new AlwaysIncreasingSystem2();
  61. @Rule
  62. public ExpectedException expectedException = ExpectedException.none();
  63. @Rule
  64. public EsTester es = EsTester.create();
  65. @Rule
  66. public DbTester db = DbTester.create(system2);
  67. private DbClient dbClient = db.getDbClient();
  68. private NewUserNotifier newUserNotifier = mock(NewUserNotifier.class);
  69. private DbSession session = db.getSession();
  70. private UserIndexer userIndexer = new UserIndexer(dbClient, es.client());
  71. private OrganizationUpdater organizationUpdater = mock(OrganizationUpdater.class);
  72. private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
  73. private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone();
  74. private MapSettings settings = new MapSettings();
  75. private CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient());
  76. private UserUpdater underTest = new UserUpdater(system2, newUserNotifier, dbClient, userIndexer, organizationFlags, defaultOrganizationProvider, organizationUpdater,
  77. new DefaultGroupFinder(dbClient), settings.asConfig(), localAuthentication);
  78. @Test
  79. public void update_user() {
  80. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@email.com")
  81. .setScmAccounts(asList("ma", "marius33")));
  82. createDefaultGroup();
  83. userIndexer.indexOnStartup(null);
  84. underTest.updateAndCommit(session, user, new UpdateUser()
  85. .setName("Marius2")
  86. .setEmail("marius2@mail.com")
  87. .setScmAccounts(singletonList("ma2")), u -> {
  88. });
  89. UserDto updatedUser = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
  90. assertThat(updatedUser.isActive()).isTrue();
  91. assertThat(updatedUser.getName()).isEqualTo("Marius2");
  92. assertThat(updatedUser.getEmail()).isEqualTo("marius2@mail.com");
  93. assertThat(updatedUser.getScmAccountsAsList()).containsOnly("ma2");
  94. assertThat(updatedUser.getCreatedAt()).isEqualTo(user.getCreatedAt());
  95. assertThat(updatedUser.getUpdatedAt()).isGreaterThan(user.getCreatedAt());
  96. List<SearchHit> indexUsers = es.getDocuments(UserIndexDefinition.TYPE_USER);
  97. assertThat(indexUsers).hasSize(1);
  98. assertThat(indexUsers.get(0).getSourceAsMap())
  99. .contains(
  100. entry("login", DEFAULT_LOGIN),
  101. entry("name", "Marius2"),
  102. entry("email", "marius2@mail.com"));
  103. }
  104. @Test
  105. public void update_user_external_identity_when_user_was_not_local() {
  106. UserDto user = db.users().insertUser(newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com"));
  107. createDefaultGroup();
  108. underTest.updateAndCommit(session, user, new UpdateUser()
  109. .setName("Marius2")
  110. .setEmail("marius2@email.com")
  111. .setExternalIdentity(new ExternalIdentity("github", "john", "ABCD")), u -> {
  112. });
  113. UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
  114. assertThat(dto.getExternalId()).isEqualTo("ABCD");
  115. assertThat(dto.getExternalLogin()).isEqualTo("john");
  116. assertThat(dto.getExternalIdentityProvider()).isEqualTo("github");
  117. assertThat(dto.getUpdatedAt()).isGreaterThan(user.getCreatedAt());
  118. }
  119. @Test
  120. public void update_user_external_identity_when_user_was_local() {
  121. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@email.com"));
  122. createDefaultGroup();
  123. underTest.updateAndCommit(session, user, new UpdateUser()
  124. .setName("Marius2")
  125. .setEmail("marius2@email.com")
  126. .setExternalIdentity(new ExternalIdentity("github", "john", "ABCD")), u -> {
  127. });
  128. UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
  129. assertThat(dto.getExternalId()).isEqualTo("ABCD");
  130. assertThat(dto.getExternalLogin()).isEqualTo("john");
  131. assertThat(dto.getExternalIdentityProvider()).isEqualTo("github");
  132. // Password must be removed
  133. assertThat(dto.getCryptedPassword()).isNull();
  134. assertThat(dto.getSalt()).isNull();
  135. assertThat(dto.getUpdatedAt()).isGreaterThan(user.getCreatedAt());
  136. }
  137. @Test
  138. public void update_user_with_scm_accounts_containing_blank_entry() {
  139. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@lesbronzes.fr")
  140. .setScmAccounts(asList("ma", "marius33")));
  141. createDefaultGroup();
  142. underTest.updateAndCommit(session, user, new UpdateUser()
  143. .setName("Marius2")
  144. .setEmail("marius2@mail.com")
  145. .setPassword("password2")
  146. .setScmAccounts(asList("ma2", "", null)), u -> {
  147. });
  148. UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
  149. assertThat(dto.getScmAccountsAsList()).containsOnly("ma2");
  150. }
  151. @Test
  152. public void update_only_login_of_local_account() {
  153. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@lesbronzes.fr"));
  154. createDefaultGroup();
  155. underTest.updateAndCommit(session, user, new UpdateUser()
  156. .setLogin("new_login"), u -> {
  157. });
  158. assertThat(dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN)).isNull();
  159. UserDto userReloaded = dbClient.userDao().selectByUuid(session, user.getUuid());
  160. assertThat(userReloaded.getLogin()).isEqualTo("new_login");
  161. assertThat(userReloaded.getExternalIdentityProvider()).isEqualTo("sonarqube");
  162. assertThat(userReloaded.getExternalLogin()).isEqualTo("new_login");
  163. assertThat(userReloaded.getExternalId()).isEqualTo("new_login");
  164. // Following fields has not changed
  165. assertThat(userReloaded.isLocal()).isTrue();
  166. assertThat(userReloaded.getName()).isEqualTo(user.getName());
  167. assertThat(userReloaded.getEmail()).isEqualTo(user.getEmail());
  168. assertThat(userReloaded.getScmAccountsAsList()).containsAll(user.getScmAccountsAsList());
  169. assertThat(userReloaded.getSalt()).isEqualTo(user.getSalt());
  170. assertThat(userReloaded.getCryptedPassword()).isEqualTo(user.getCryptedPassword());
  171. }
  172. @Test
  173. public void update_only_login_of_external_account() {
  174. UserDto user = db.users().insertUser(newExternalUser(DEFAULT_LOGIN, "Marius", "marius@lesbronzes.fr"));
  175. createDefaultGroup();
  176. underTest.updateAndCommit(session, user, new UpdateUser()
  177. .setLogin("new_login"), u -> {
  178. });
  179. assertThat(dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN)).isNull();
  180. UserDto userReloaded = dbClient.userDao().selectByUuid(session, user.getUuid());
  181. assertThat(userReloaded.getLogin()).isEqualTo("new_login");
  182. // Following fields has not changed
  183. assertThat(userReloaded.isLocal()).isFalse();
  184. assertThat(userReloaded.getExternalLogin()).isEqualTo(user.getExternalLogin());
  185. assertThat(userReloaded.getExternalId()).isEqualTo(user.getExternalId());
  186. assertThat(userReloaded.getName()).isEqualTo(user.getName());
  187. assertThat(userReloaded.getEmail()).isEqualTo(user.getEmail());
  188. assertThat(userReloaded.getScmAccountsAsList()).containsAll(user.getScmAccountsAsList());
  189. assertThat(userReloaded.getSalt()).isEqualTo(user.getSalt());
  190. assertThat(userReloaded.getCryptedPassword()).isEqualTo(user.getCryptedPassword());
  191. }
  192. @Test
  193. public void update_index_when_updating_user_login() {
  194. UserDto oldUser = db.users().insertUser();
  195. createDefaultGroup();
  196. userIndexer.indexOnStartup(null);
  197. underTest.updateAndCommit(session, oldUser, new UpdateUser()
  198. .setLogin("new_login"), u -> {
  199. });
  200. List<SearchHit> indexUsers = es.getDocuments(UserIndexDefinition.TYPE_USER);
  201. assertThat(indexUsers).hasSize(1);
  202. assertThat(indexUsers.get(0).getSourceAsMap())
  203. .contains(entry("login", "new_login"));
  204. }
  205. @Test
  206. public void update_default_assignee_when_updating_login() {
  207. createDefaultGroup();
  208. UserDto oldUser = db.users().insertUser();
  209. ComponentDto project1 = db.components().insertPrivateProject();
  210. ComponentDto project2 = db.components().insertPrivateProject();
  211. ComponentDto anotherProject = db.components().insertPrivateProject();
  212. db.properties().insertProperties(
  213. new PropertyDto().setKey(DEFAULT_ISSUE_ASSIGNEE).setValue(oldUser.getLogin()),
  214. new PropertyDto().setKey(DEFAULT_ISSUE_ASSIGNEE).setValue(oldUser.getLogin()).setResourceId(project1.getId()),
  215. new PropertyDto().setKey(DEFAULT_ISSUE_ASSIGNEE).setValue(oldUser.getLogin()).setResourceId(project2.getId()),
  216. new PropertyDto().setKey(DEFAULT_ISSUE_ASSIGNEE).setValue("another login").setResourceId(anotherProject.getId()));
  217. userIndexer.indexOnStartup(null);
  218. underTest.updateAndCommit(session, oldUser, new UpdateUser()
  219. .setLogin("new_login"), u -> {
  220. });
  221. assertThat(db.getDbClient().propertiesDao().selectByQuery(PropertyQuery.builder().setKey(DEFAULT_ISSUE_ASSIGNEE).build(), db.getSession()))
  222. .extracting(PropertyDto::getValue, PropertyDto::getResourceId)
  223. .containsOnly(
  224. tuple("new_login", null),
  225. tuple("new_login", project1.getId()),
  226. tuple("new_login", project2.getId()),
  227. tuple("another login", anotherProject.getId()));
  228. }
  229. @Test
  230. public void update_only_user_name() {
  231. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@lesbronzes.fr")
  232. .setScmAccounts(asList("ma", "marius33"))
  233. .setSalt("salt")
  234. .setCryptedPassword("crypted password"));
  235. createDefaultGroup();
  236. underTest.updateAndCommit(session, user, new UpdateUser()
  237. .setName("Marius2"), u -> {
  238. });
  239. UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
  240. assertThat(dto.getName()).isEqualTo("Marius2");
  241. // Following fields has not changed
  242. assertThat(dto.getEmail()).isEqualTo("marius@lesbronzes.fr");
  243. assertThat(dto.getScmAccountsAsList()).containsOnly("ma", "marius33");
  244. assertThat(dto.getSalt()).isEqualTo("salt");
  245. assertThat(dto.getCryptedPassword()).isEqualTo("crypted password");
  246. }
  247. @Test
  248. public void update_only_user_email() {
  249. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@lesbronzes.fr")
  250. .setScmAccounts(asList("ma", "marius33"))
  251. .setSalt("salt")
  252. .setCryptedPassword("crypted password"));
  253. createDefaultGroup();
  254. underTest.updateAndCommit(session, user, new UpdateUser()
  255. .setEmail("marius2@mail.com"), u -> {
  256. });
  257. UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
  258. assertThat(dto.getEmail()).isEqualTo("marius2@mail.com");
  259. // Following fields has not changed
  260. assertThat(dto.getName()).isEqualTo("Marius");
  261. assertThat(dto.getScmAccountsAsList()).containsOnly("ma", "marius33");
  262. assertThat(dto.getSalt()).isEqualTo("salt");
  263. assertThat(dto.getCryptedPassword()).isEqualTo("crypted password");
  264. }
  265. @Test
  266. public void update_only_scm_accounts() {
  267. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@lesbronzes.fr")
  268. .setScmAccounts(asList("ma", "marius33"))
  269. .setSalt("salt")
  270. .setCryptedPassword("crypted password"));
  271. createDefaultGroup();
  272. underTest.updateAndCommit(session, user, new UpdateUser()
  273. .setScmAccounts(asList("ma2")), u -> {
  274. });
  275. UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
  276. assertThat(dto.getScmAccountsAsList()).containsOnly("ma2");
  277. // Following fields has not changed
  278. assertThat(dto.getName()).isEqualTo("Marius");
  279. assertThat(dto.getEmail()).isEqualTo("marius@lesbronzes.fr");
  280. assertThat(dto.getSalt()).isEqualTo("salt");
  281. assertThat(dto.getCryptedPassword()).isEqualTo("crypted password");
  282. }
  283. @Test
  284. public void update_scm_accounts_with_same_values() {
  285. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@lesbronzes.fr")
  286. .setScmAccounts(asList("ma", "marius33")));
  287. createDefaultGroup();
  288. underTest.updateAndCommit(session, user, new UpdateUser()
  289. .setScmAccounts(asList("ma", "marius33")), u -> {
  290. });
  291. UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
  292. assertThat(dto.getScmAccountsAsList()).containsOnly("ma", "marius33");
  293. }
  294. @Test
  295. public void remove_scm_accounts() {
  296. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@lesbronzes.fr")
  297. .setScmAccounts(asList("ma", "marius33")));
  298. createDefaultGroup();
  299. underTest.updateAndCommit(session, user, new UpdateUser()
  300. .setScmAccounts(null), u -> {
  301. });
  302. UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
  303. assertThat(dto.getScmAccounts()).isNull();
  304. }
  305. @Test
  306. public void update_only_user_password() {
  307. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@lesbronzes.fr")
  308. .setScmAccounts(asList("ma", "marius33"))
  309. .setSalt("salt")
  310. .setCryptedPassword("crypted password"));
  311. createDefaultGroup();
  312. underTest.updateAndCommit(session, user, new UpdateUser()
  313. .setPassword("password2"), u -> {
  314. });
  315. UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
  316. assertThat(dto.getSalt()).isNotEqualTo("salt");
  317. assertThat(dto.getCryptedPassword()).isNotEqualTo("crypted password");
  318. // Following fields has not changed
  319. assertThat(dto.getName()).isEqualTo("Marius");
  320. assertThat(dto.getScmAccountsAsList()).containsOnly("ma", "marius33");
  321. assertThat(dto.getEmail()).isEqualTo("marius@lesbronzes.fr");
  322. }
  323. @Test
  324. public void update_only_external_id() {
  325. UserDto user = db.users().insertUser(newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com")
  326. .setExternalId("1234")
  327. .setExternalLogin("john.smith")
  328. .setExternalIdentityProvider("github"));
  329. createDefaultGroup();
  330. underTest.updateAndCommit(session, user, new UpdateUser().setExternalIdentity(new ExternalIdentity("github", "john.smith", "ABCD")), u -> {
  331. });
  332. assertThat(dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN))
  333. .extracting(UserDto::getExternalId)
  334. .isEqualTo("ABCD");
  335. }
  336. @Test
  337. public void update_only_external_login() {
  338. UserDto user = db.users().insertUser(newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com")
  339. .setExternalId("ABCD")
  340. .setExternalLogin("john")
  341. .setExternalIdentityProvider("github"));
  342. createDefaultGroup();
  343. underTest.updateAndCommit(session, user, new UpdateUser().setExternalIdentity(new ExternalIdentity("github", "john.smith", "ABCD")), u -> {
  344. });
  345. assertThat(dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN))
  346. .extracting(UserDto::getExternalLogin, UserDto::getExternalIdentityProvider)
  347. .containsOnly("john.smith", "github");
  348. }
  349. @Test
  350. public void update_only_external_identity_provider() {
  351. UserDto user = db.users().insertUser(newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com")
  352. .setExternalId("ABCD")
  353. .setExternalLogin("john")
  354. .setExternalIdentityProvider("github"));
  355. createDefaultGroup();
  356. underTest.updateAndCommit(session, user, new UpdateUser().setExternalIdentity(new ExternalIdentity("bitbucket", "john", "ABCD")), u -> {
  357. });
  358. assertThat(dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN))
  359. .extracting(UserDto::getExternalLogin, UserDto::getExternalIdentityProvider)
  360. .containsOnly("john", "bitbucket");
  361. }
  362. @Test
  363. public void does_not_update_user_when_no_change() {
  364. UserDto user = newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com")
  365. .setScmAccounts(asList("ma1", "ma2"));
  366. db.users().insertUser(user);
  367. createDefaultGroup();
  368. underTest.updateAndCommit(session, user, new UpdateUser()
  369. .setName(user.getName())
  370. .setEmail(user.getEmail())
  371. .setScmAccounts(user.getScmAccountsAsList())
  372. .setExternalIdentity(new ExternalIdentity(user.getExternalIdentityProvider(), user.getExternalLogin(), user.getExternalId())), u -> {
  373. });
  374. assertThat(dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN).getUpdatedAt()).isEqualTo(user.getUpdatedAt());
  375. }
  376. @Test
  377. public void does_not_update_user_when_no_change_and_scm_account_reordered() {
  378. UserDto user = newExternalUser(DEFAULT_LOGIN, "Marius", "marius@email.com")
  379. .setScmAccounts(asList("ma1", "ma2"));
  380. db.users().insertUser(user);
  381. createDefaultGroup();
  382. underTest.updateAndCommit(session, user, new UpdateUser()
  383. .setName(user.getName())
  384. .setEmail(user.getEmail())
  385. .setScmAccounts(asList("ma2", "ma1"))
  386. .setExternalIdentity(new ExternalIdentity(user.getExternalIdentityProvider(), user.getExternalLogin(), user.getExternalId())), u -> {
  387. });
  388. assertThat(dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN).getUpdatedAt()).isEqualTo(user.getUpdatedAt());
  389. }
  390. @Test
  391. public void update_user_and_index_other_user() {
  392. createDefaultGroup();
  393. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@email.com")
  394. .setScmAccounts(asList("ma", "marius33")));
  395. UserDto otherUser = db.users().insertUser();
  396. underTest.updateAndCommit(session, user, new UpdateUser()
  397. .setName("Marius2")
  398. .setEmail("marius2@mail.com")
  399. .setPassword("password2")
  400. .setScmAccounts(asList("ma2")), u -> {
  401. }, otherUser);
  402. assertThat(es.getIds(UserIndexDefinition.TYPE_USER)).containsExactlyInAnyOrder(user.getUuid(), otherUser.getUuid());
  403. }
  404. @Test
  405. public void fail_to_set_null_password_when_local_user() {
  406. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@email.com"));
  407. createDefaultGroup();
  408. expectedException.expect(BadRequestException.class);
  409. expectedException.expectMessage("Password can't be empty");
  410. underTest.updateAndCommit(session, user, new UpdateUser().setPassword(null), u -> {
  411. });
  412. }
  413. @Test
  414. public void fail_to_update_password_when_user_is_not_local() {
  415. UserDto user = db.users().insertUser(newUserDto()
  416. .setLogin(DEFAULT_LOGIN)
  417. .setLocal(false));
  418. createDefaultGroup();
  419. expectedException.expect(BadRequestException.class);
  420. expectedException.expectMessage("Password cannot be changed when external authentication is used");
  421. underTest.updateAndCommit(session, user, new UpdateUser().setPassword("password2"), u -> {
  422. });
  423. }
  424. @Test
  425. public void not_associate_default_group_when_updating_user() {
  426. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@email.com"));
  427. GroupDto defaultGroup = createDefaultGroup();
  428. // Existing user, he has no group, and should not be associated to the default one
  429. underTest.updateAndCommit(session, user, new UpdateUser()
  430. .setName("Marius2")
  431. .setEmail("marius2@mail.com")
  432. .setPassword("password2")
  433. .setScmAccounts(asList("ma2")), u -> {
  434. });
  435. Multimap<String, String> groups = dbClient.groupMembershipDao().selectGroupsByLogins(session, asList(DEFAULT_LOGIN));
  436. assertThat(groups.get(DEFAULT_LOGIN).stream().anyMatch(g -> g.equals(defaultGroup.getName()))).isFalse();
  437. }
  438. @Test
  439. public void not_associate_default_group_when_updating_user_if_already_existing() {
  440. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@email.com"));
  441. GroupDto defaultGroup = createDefaultGroup();
  442. db.users().insertMember(defaultGroup, user);
  443. // User is already associate to the default group
  444. Multimap<String, String> groups = dbClient.groupMembershipDao().selectGroupsByLogins(session, asList(DEFAULT_LOGIN));
  445. assertThat(groups.get(DEFAULT_LOGIN).stream().anyMatch(g -> g.equals(defaultGroup.getName()))).as("Current user groups : %s", groups.get(defaultGroup.getName())).isTrue();
  446. underTest.updateAndCommit(session, user, new UpdateUser()
  447. .setName("Marius2")
  448. .setEmail("marius2@mail.com")
  449. .setPassword("password2")
  450. .setScmAccounts(asList("ma2")), u -> {
  451. });
  452. // Nothing as changed
  453. groups = dbClient.groupMembershipDao().selectGroupsByLogins(session, asList(DEFAULT_LOGIN));
  454. assertThat(groups.get(DEFAULT_LOGIN).stream().anyMatch(g -> g.equals(defaultGroup.getName()))).isTrue();
  455. }
  456. @Test
  457. public void fail_to_update_user_when_scm_account_is_already_used() {
  458. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@email.com").setScmAccounts(singletonList("ma")));
  459. db.users().insertUser(newLocalUser("john", "John", "john@email.com").setScmAccounts(singletonList("jo")));
  460. createDefaultGroup();
  461. expectedException.expect(BadRequestException.class);
  462. expectedException.expectMessage("The scm account 'jo' is already used by user(s) : 'John (john)'");
  463. underTest.updateAndCommit(session, user, new UpdateUser()
  464. .setName("Marius2")
  465. .setEmail("marius2@mail.com")
  466. .setPassword("password2")
  467. .setScmAccounts(asList("jo")), u -> {
  468. });
  469. }
  470. @Test
  471. public void fail_to_update_user_when_scm_account_is_user_login() {
  472. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@lesbronzes.fr"));
  473. createDefaultGroup();
  474. expectedException.expect(BadRequestException.class);
  475. expectedException.expectMessage("Login and email are automatically considered as SCM accounts");
  476. underTest.updateAndCommit(session, user, new UpdateUser().setScmAccounts(asList(DEFAULT_LOGIN)), u -> {
  477. });
  478. }
  479. @Test
  480. public void fail_to_update_user_when_scm_account_is_existing_user_email() {
  481. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@lesbronzes.fr"));
  482. createDefaultGroup();
  483. expectedException.expect(BadRequestException.class);
  484. expectedException.expectMessage("Login and email are automatically considered as SCM accounts");
  485. underTest.updateAndCommit(session, user, new UpdateUser().setScmAccounts(asList("marius@lesbronzes.fr")), u -> {
  486. });
  487. }
  488. @Test
  489. public void fail_to_update_user_when_scm_account_is_new_user_email() {
  490. UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@lesbronzes.fr"));
  491. createDefaultGroup();
  492. expectedException.expect(BadRequestException.class);
  493. expectedException.expectMessage("Login and email are automatically considered as SCM accounts");
  494. underTest.updateAndCommit(session, user, new UpdateUser()
  495. .setEmail("marius@newmail.com")
  496. .setScmAccounts(asList("marius@newmail.com")), u -> {
  497. });
  498. }
  499. @Test
  500. public void fail_to_update_login_when_format_is_invalid() {
  501. UserDto user = db.users().insertUser();
  502. createDefaultGroup();
  503. expectedException.expect(BadRequestException.class);
  504. expectedException.expectMessage("Use only letters, numbers, and .-_@ please.");
  505. underTest.updateAndCommit(session, user, new UpdateUser().setLogin("With space"), u -> {
  506. });
  507. }
  508. @Test
  509. public void fail_to_update_user_when_login_already_exists() {
  510. createDefaultGroup();
  511. UserDto user = db.users().insertUser(u -> u.setActive(false));
  512. UserDto existingUser = db.users().insertUser(u -> u.setLogin("existing_login"));
  513. expectedException.expect(IllegalArgumentException.class);
  514. expectedException.expectMessage("A user with login 'existing_login' already exists");
  515. underTest.updateAndCommit(session, user, new UpdateUser().setLogin(existingUser.getLogin()), u -> {
  516. });
  517. }
  518. @Test
  519. public void fail_to_update_user_when_external_id_and_external_provider_already_exists() {
  520. createDefaultGroup();
  521. UserDto user = db.users().insertUser(u -> u.setActive(false));
  522. UserDto existingUser = db.users().insertUser(u -> u.setExternalId("existing_external_id").setExternalIdentityProvider("existing_external_provider"));
  523. expectedException.expect(IllegalArgumentException.class);
  524. expectedException.expectMessage("A user with provider id 'existing_external_id' and identity provider 'existing_external_provider' already exists");
  525. underTest.updateAndCommit(session, user, new UpdateUser()
  526. .setExternalIdentity(new ExternalIdentity(existingUser.getExternalIdentityProvider(), existingUser.getExternalLogin(), existingUser.getExternalId())), u -> {
  527. });
  528. }
  529. private GroupDto createDefaultGroup() {
  530. return db.users().insertDefaultGroup(db.getDefaultOrganization());
  531. }
  532. }