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.

UserUpdaterReactivateTest.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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 org.junit.Rule;
  23. import org.junit.Test;
  24. import org.junit.rules.ExpectedException;
  25. import org.sonar.api.config.internal.MapSettings;
  26. import org.sonar.api.impl.utils.AlwaysIncreasingSystem2;
  27. import org.sonar.api.utils.System2;
  28. import org.sonar.db.DbClient;
  29. import org.sonar.db.DbSession;
  30. import org.sonar.db.DbTester;
  31. import org.sonar.db.user.GroupDto;
  32. import org.sonar.db.user.GroupTesting;
  33. import org.sonar.db.user.UserDto;
  34. import org.sonar.server.authentication.CredentialsLocalAuthentication;
  35. import org.sonar.server.authentication.CredentialsLocalAuthentication.HashMethod;
  36. import org.sonar.server.es.EsTester;
  37. import org.sonar.server.organization.DefaultOrganizationProvider;
  38. import org.sonar.server.organization.TestDefaultOrganizationProvider;
  39. import org.sonar.server.user.index.UserIndexer;
  40. import org.sonar.server.usergroups.DefaultGroupFinder;
  41. import static java.lang.String.format;
  42. import static java.util.Collections.singletonList;
  43. import static org.assertj.core.api.Assertions.assertThat;
  44. import static org.mockito.Mockito.mock;
  45. import static org.sonar.process.ProcessProperties.Property.ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS;
  46. public class UserUpdaterReactivateTest {
  47. private System2 system2 = new AlwaysIncreasingSystem2();
  48. @Rule
  49. public ExpectedException expectedException = ExpectedException.none();
  50. @Rule
  51. public EsTester es = EsTester.create();
  52. @Rule
  53. public DbTester db = DbTester.create(system2);
  54. private DbClient dbClient = db.getDbClient();
  55. private NewUserNotifier newUserNotifier = mock(NewUserNotifier.class);
  56. private DbSession session = db.getSession();
  57. private UserIndexer userIndexer = new UserIndexer(dbClient, es.client());
  58. private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
  59. private MapSettings settings = new MapSettings();
  60. private CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient());
  61. private UserUpdater underTest = new UserUpdater(newUserNotifier, dbClient, userIndexer, defaultOrganizationProvider,
  62. new DefaultGroupFinder(dbClient, defaultOrganizationProvider),
  63. settings.asConfig(), localAuthentication);
  64. @Test
  65. public void reactivate_user() {
  66. UserDto user = db.users().insertUser(u -> u.setActive(false));
  67. createDefaultGroup();
  68. underTest.reactivateAndCommit(db.getSession(), user, NewUser.builder()
  69. .setLogin("marius")
  70. .setName("Marius2")
  71. .setEmail("marius2@mail.com")
  72. .setPassword("password2")
  73. .build(),
  74. u -> {
  75. });
  76. UserDto reloaded = dbClient.userDao().selectByUuid(session, user.getUuid());
  77. assertThat(reloaded.isActive()).isTrue();
  78. assertThat(reloaded.getLogin()).isEqualTo("marius");
  79. assertThat(reloaded.getName()).isEqualTo("Marius2");
  80. assertThat(reloaded.getEmail()).isEqualTo("marius2@mail.com");
  81. assertThat(reloaded.getScmAccounts()).isNull();
  82. assertThat(reloaded.isLocal()).isTrue();
  83. assertThat(reloaded.getSalt()).isNull();
  84. assertThat(reloaded.getHashMethod()).isEqualTo(HashMethod.BCRYPT.name());
  85. assertThat(reloaded.getCryptedPassword()).isNotNull().isNotEqualTo("650d2261c98361e2f67f90ce5c65a95e7d8ea2fg");
  86. assertThat(reloaded.getCreatedAt()).isEqualTo(user.getCreatedAt());
  87. assertThat(reloaded.getUpdatedAt()).isGreaterThan(user.getCreatedAt());
  88. }
  89. @Test
  90. public void reactivate_user_without_providing_login() {
  91. UserDto user = db.users().insertUser(u -> u.setActive(false));
  92. createDefaultGroup();
  93. underTest.reactivateAndCommit(db.getSession(), user, NewUser.builder()
  94. .setName("Marius2")
  95. .setEmail("marius2@mail.com")
  96. .setPassword("password2")
  97. .build(),
  98. u -> {
  99. });
  100. UserDto reloaded = dbClient.userDao().selectByUuid(session, user.getUuid());
  101. assertThat(reloaded.isActive()).isTrue();
  102. assertThat(reloaded.getLogin()).isEqualTo(user.getLogin());
  103. }
  104. @Test
  105. public void reactivate_user_not_having_password() {
  106. UserDto user = db.users().insertDisabledUser(u -> u.setSalt(null).setCryptedPassword(null));
  107. createDefaultGroup();
  108. UserDto dto = underTest.reactivateAndCommit(db.getSession(), user, NewUser.builder()
  109. .setLogin(user.getLogin())
  110. .setName(user.getName())
  111. .build(),
  112. u -> {
  113. });
  114. assertThat(dto.isActive()).isTrue();
  115. assertThat(dto.getName()).isEqualTo(user.getName());
  116. assertThat(dto.getScmAccounts()).isNull();
  117. assertThat(dto.getSalt()).isNull();
  118. assertThat(dto.getCryptedPassword()).isNull();
  119. assertThat(dto.getCreatedAt()).isEqualTo(user.getCreatedAt());
  120. assertThat(dto.getUpdatedAt()).isGreaterThan(user.getCreatedAt());
  121. }
  122. @Test
  123. public void reactivate_user_with_external_provider() {
  124. UserDto user = db.users().insertDisabledUser(u -> u.setLocal(true));
  125. createDefaultGroup();
  126. underTest.reactivateAndCommit(db.getSession(), user, NewUser.builder()
  127. .setLogin(user.getLogin())
  128. .setName(user.getName())
  129. .setExternalIdentity(new ExternalIdentity("github", "john", "ABCD"))
  130. .build(), u -> {
  131. });
  132. session.commit();
  133. UserDto dto = dbClient.userDao().selectByUuid(session, user.getUuid());
  134. assertThat(dto.isLocal()).isFalse();
  135. assertThat(dto.getExternalId()).isEqualTo("ABCD");
  136. assertThat(dto.getExternalLogin()).isEqualTo("john");
  137. assertThat(dto.getExternalIdentityProvider()).isEqualTo("github");
  138. }
  139. @Test
  140. public void reactivate_user_using_same_external_info_but_was_local() {
  141. UserDto user = db.users().insertDisabledUser(u -> u.setLocal(true)
  142. .setExternalId("ABCD")
  143. .setExternalLogin("john")
  144. .setExternalIdentityProvider("github"));
  145. createDefaultGroup();
  146. underTest.reactivateAndCommit(db.getSession(), user, NewUser.builder()
  147. .setLogin(user.getLogin())
  148. .setName(user.getName())
  149. .setExternalIdentity(new ExternalIdentity("github", "john", "ABCD"))
  150. .build(), u -> {
  151. });
  152. session.commit();
  153. UserDto dto = dbClient.userDao().selectByUuid(session, user.getUuid());
  154. assertThat(dto.isLocal()).isFalse();
  155. assertThat(dto.getExternalId()).isEqualTo("ABCD");
  156. assertThat(dto.getExternalLogin()).isEqualTo("john");
  157. assertThat(dto.getExternalIdentityProvider()).isEqualTo("github");
  158. }
  159. @Test
  160. public void reactivate_user_with_local_provider() {
  161. UserDto user = db.users().insertDisabledUser(u -> u.setLocal(false)
  162. .setExternalId("ABCD")
  163. .setExternalLogin("john")
  164. .setExternalIdentityProvider("github"));
  165. createDefaultGroup();
  166. underTest.reactivateAndCommit(db.getSession(), user, NewUser.builder()
  167. .setLogin(user.getLogin())
  168. .setName(user.getName())
  169. .build(), u -> {
  170. });
  171. session.commit();
  172. UserDto dto = dbClient.userDao().selectByUuid(session, user.getUuid());
  173. assertThat(dto.isLocal()).isTrue();
  174. assertThat(dto.getExternalId()).isEqualTo(user.getLogin());
  175. assertThat(dto.getExternalLogin()).isEqualTo(user.getLogin());
  176. assertThat(dto.getExternalIdentityProvider()).isEqualTo("sonarqube");
  177. }
  178. @Test
  179. public void fail_to_reactivate_user_if_active() {
  180. UserDto user = db.users().insertUser();
  181. createDefaultGroup();
  182. expectedException.expect(IllegalArgumentException.class);
  183. expectedException.expectMessage(format("An active user with login '%s' already exists", user.getLogin()));
  184. underTest.reactivateAndCommit(db.getSession(), user, NewUser.builder()
  185. .setLogin(user.getLogin())
  186. .setName(user.getName())
  187. .build(), u -> {
  188. });
  189. }
  190. @Test
  191. public void associate_default_groups_when_reactivating_user() {
  192. UserDto userDto = db.users().insertDisabledUser();
  193. GroupDto groupDto = db.users().insertGroup(GroupTesting.newGroupDto().setName("sonar-devs"));
  194. db.users().insertMember(groupDto, userDto);
  195. GroupDto defaultGroup = createDefaultGroup();
  196. underTest.reactivateAndCommit(db.getSession(), userDto, NewUser.builder()
  197. .setLogin(userDto.getLogin())
  198. .setName(userDto.getName())
  199. .build(), u -> {
  200. });
  201. session.commit();
  202. Multimap<String, String> groups = dbClient.groupMembershipDao().selectGroupsByLogins(session, singletonList(userDto.getLogin()));
  203. assertThat(groups.get(userDto.getLogin()).stream().anyMatch(g -> g.equals(defaultGroup.getName()))).isTrue();
  204. }
  205. @Test
  206. public void reactivate_not_onboarded_user_if_onboarding_setting_is_set_to_false() {
  207. settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS.getKey(), false);
  208. UserDto user = db.users().insertDisabledUser(u -> u.setOnboarded(false));
  209. createDefaultGroup();
  210. underTest.reactivateAndCommit(db.getSession(), user, NewUser.builder()
  211. .setLogin(user.getLogin())
  212. .setName(user.getName())
  213. .build(), u -> {
  214. });
  215. assertThat(dbClient.userDao().selectByLogin(session, user.getLogin()).isOnboarded()).isTrue();
  216. }
  217. @Test
  218. public void reactivate_onboarded_user_if_onboarding_setting_is_set_to_true() {
  219. settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS.getKey(), true);
  220. UserDto user = db.users().insertDisabledUser(u -> u.setOnboarded(true));
  221. createDefaultGroup();
  222. underTest.reactivateAndCommit(db.getSession(), user, NewUser.builder()
  223. .setLogin(user.getLogin())
  224. .setName(user.getName())
  225. .build(), u -> {
  226. });
  227. assertThat(dbClient.userDao().selectByLogin(session, user.getLogin()).isOnboarded()).isFalse();
  228. }
  229. @Test
  230. public void does_not_set_notifications_readDate_setting_when_reactivating_user() {
  231. createDefaultGroup();
  232. UserDto user = db.users().insertDisabledUser();
  233. underTest.reactivateAndCommit(db.getSession(), user, NewUser.builder()
  234. .setLogin(user.getLogin())
  235. .setName(user.getName())
  236. .build(), u -> {
  237. });
  238. assertThat(dbClient.userPropertiesDao().selectByUser(session, user)).isEmpty();
  239. }
  240. @Test
  241. public void fail_to_reactivate_user_when_login_already_exists() {
  242. createDefaultGroup();
  243. UserDto user = db.users().insertUser(u -> u.setActive(false));
  244. UserDto existingUser = db.users().insertUser(u -> u.setLogin("existing_login"));
  245. expectedException.expect(IllegalArgumentException.class);
  246. expectedException.expectMessage("A user with login 'existing_login' already exists");
  247. underTest.reactivateAndCommit(db.getSession(), user, NewUser.builder()
  248. .setLogin(existingUser.getLogin())
  249. .setName("Marius2")
  250. .setPassword("password2")
  251. .build(),
  252. u -> {
  253. });
  254. }
  255. @Test
  256. public void fail_to_reactivate_user_when_external_id_and_external_provider_already_exists() {
  257. createDefaultGroup();
  258. UserDto user = db.users().insertUser(u -> u.setActive(false));
  259. UserDto existingUser = db.users().insertUser(u -> u.setExternalId("existing_external_id").setExternalIdentityProvider("existing_external_provider"));
  260. expectedException.expect(IllegalArgumentException.class);
  261. expectedException.expectMessage("A user with provider id 'existing_external_id' and identity provider 'existing_external_provider' already exists");
  262. underTest.reactivateAndCommit(db.getSession(), user, NewUser.builder()
  263. .setLogin(user.getLogin())
  264. .setName("Marius2")
  265. .setExternalIdentity(new ExternalIdentity(existingUser.getExternalIdentityProvider(), existingUser.getExternalLogin(), existingUser.getExternalId()))
  266. .build(),
  267. u -> {
  268. });
  269. }
  270. private GroupDto createDefaultGroup() {
  271. return db.users().insertDefaultGroup();
  272. }
  273. }