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

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