]> source.dussan.org Git - sonarqube.git/blob
46ddd229898075774028b47e29b3db80eb1afd75
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2021 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.authentication;
21
22 import java.util.Optional;
23 import java.util.Set;
24 import java.util.stream.Collectors;
25 import javax.annotation.Nullable;
26 import org.junit.Before;
27 import org.junit.Rule;
28 import org.junit.Test;
29 import org.junit.rules.ExpectedException;
30 import org.sonar.api.config.internal.MapSettings;
31 import org.sonar.api.impl.utils.AlwaysIncreasingSystem2;
32 import org.sonar.api.server.authentication.UserIdentity;
33 import org.sonar.api.utils.log.LogTester;
34 import org.sonar.db.DbTester;
35 import org.sonar.db.user.GroupDto;
36 import org.sonar.db.user.UserDto;
37 import org.sonar.server.authentication.event.AuthenticationEvent;
38 import org.sonar.server.authentication.event.AuthenticationEvent.Source;
39 import org.sonar.server.authentication.event.AuthenticationException;
40 import org.sonar.server.es.EsTester;
41 import org.sonar.server.user.NewUserNotifier;
42 import org.sonar.server.user.UserUpdater;
43 import org.sonar.server.user.index.UserIndexer;
44 import org.sonar.server.usergroups.DefaultGroupFinder;
45
46 import static java.util.Arrays.stream;
47 import static org.assertj.core.api.Assertions.assertThat;
48 import static org.assertj.core.api.Assertions.assertThatThrownBy;
49 import static org.mockito.Mockito.mock;
50 import static org.sonar.db.user.UserTesting.newUserDto;
51 import static org.sonar.process.ProcessProperties.Property.ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS;
52 import static org.sonar.server.authentication.event.AuthenticationEvent.Method.BASIC;
53 import static org.sonar.server.authentication.event.AuthenticationExceptionMatcher.authenticationException;
54
55 public class UserRegistrarImplTest {
56   private static final String USER_LOGIN = "johndoo";
57
58   private static final UserIdentity USER_IDENTITY = UserIdentity.builder()
59     .setProviderId("ABCD")
60     .setProviderLogin(USER_LOGIN)
61     .setName("John")
62     .setEmail("john@email.com")
63     .build();
64
65   private static final TestIdentityProvider IDENTITY_PROVIDER = new TestIdentityProvider()
66     .setKey("github")
67     .setName("name of github")
68     .setEnabled(true)
69     .setAllowsUsersToSignUp(true);
70
71   private final MapSettings settings = new MapSettings().setProperty("sonar.internal.pbkdf2.iterations", "1");
72
73   @Rule
74   public ExpectedException expectedException = ExpectedException.none();
75   @Rule
76   public DbTester db = DbTester.create(new AlwaysIncreasingSystem2());
77   @Rule
78   public EsTester es = EsTester.create();
79   @Rule
80   public LogTester logTester = new LogTester();
81
82   private final UserIndexer userIndexer = new UserIndexer(db.getDbClient(), es.client());
83   private final CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient(), settings.asConfig());
84   private final DefaultGroupFinder groupFinder = new DefaultGroupFinder(db.getDbClient());
85   private final UserUpdater userUpdater = new UserUpdater(mock(NewUserNotifier.class), db.getDbClient(), userIndexer, groupFinder, settings.asConfig(), localAuthentication);
86
87   private final UserRegistrarImpl underTest = new UserRegistrarImpl(db.getDbClient(), userUpdater, groupFinder);
88   private GroupDto defaultGroup;
89
90   @Before
91   public void setUp() {
92     defaultGroup = insertDefaultGroup();
93   }
94
95   @Test
96   public void authenticate_new_user() {
97     UserDto createdUser = underTest.register(newUserRegistration());
98
99     UserDto user = db.users().selectUserByLogin(createdUser.getLogin()).get();
100     assertThat(user).isNotNull();
101     assertThat(user.isActive()).isTrue();
102     assertThat(user.getName()).isEqualTo("John");
103     assertThat(user.getEmail()).isEqualTo("john@email.com");
104     assertThat(user.getExternalLogin()).isEqualTo(USER_LOGIN);
105     assertThat(user.getExternalIdentityProvider()).isEqualTo("github");
106     assertThat(user.getExternalId()).isEqualTo("ABCD");
107     assertThat(user.isRoot()).isFalse();
108     checkGroupMembership(user, defaultGroup);
109   }
110
111   @Test
112   public void authenticate_new_user_with_sq_identity() {
113     TestIdentityProvider sqIdentityProvider = new TestIdentityProvider()
114       .setKey("sonarqube")
115       .setName("sonarqube identity name")
116       .setEnabled(true)
117       .setAllowsUsersToSignUp(true);
118
119     UserDto createdUser = underTest.register(UserRegistration.builder()
120       .setUserIdentity(USER_IDENTITY)
121       .setProvider(sqIdentityProvider)
122       .setSource(Source.realm(BASIC, sqIdentityProvider.getName()))
123       .build());
124
125     UserDto user = db.users().selectUserByLogin(createdUser.getLogin()).get();
126     assertThat(user).isNotNull();
127     assertThat(user.isActive()).isTrue();
128     assertThat(user.getLogin()).isEqualTo(USER_LOGIN);
129     assertThat(user.getName()).isEqualTo("John");
130     assertThat(user.getEmail()).isEqualTo("john@email.com");
131     assertThat(user.getExternalLogin()).isEqualTo(USER_LOGIN);
132     assertThat(user.getExternalIdentityProvider()).isEqualTo("sonarqube");
133     assertThat(user.getExternalId()).isEqualTo("ABCD");
134     assertThat(user.isLocal()).isFalse();
135     assertThat(user.isRoot()).isFalse();
136     checkGroupMembership(user, defaultGroup);
137   }
138
139   @Test
140   public void authenticate_new_user_generates_login() {
141     underTest.register(newUserRegistration(UserIdentity.builder()
142       .setProviderId("ABCD")
143       .setProviderLogin(USER_LOGIN)
144       .setName("John Doe")
145       .setEmail("john@email.com")
146       .build()));
147
148     UserDto user = db.getDbClient().userDao().selectByEmail(db.getSession(), "john@email.com").get(0);
149     assertThat(user).isNotNull();
150     assertThat(user.isActive()).isTrue();
151     assertThat(user.getLogin()).isNotEqualTo("John Doe").startsWith("john-doe");
152     assertThat(user.getEmail()).isEqualTo("john@email.com");
153     assertThat(user.getExternalLogin()).isEqualTo(USER_LOGIN);
154     assertThat(user.getExternalIdentityProvider()).isEqualTo("github");
155     assertThat(user.getExternalId()).isEqualTo("ABCD");
156   }
157
158   @Test
159   public void authenticate_new_user_assigns_user_to_groups() {
160     GroupDto group1 = db.users().insertGroup("group1");
161     GroupDto group2 = db.users().insertGroup("group2");
162
163     UserDto loggedInUser = authenticate(USER_LOGIN, USER_IDENTITY.getEmail(), "group1", "group2", "group3");
164
165     Optional<UserDto> user = db.users().selectUserByLogin(loggedInUser.getLogin());
166     checkGroupMembership(user.get(), group1, group2, defaultGroup);
167   }
168
169   @Test
170   public void authenticate_new_user_sets_onboarded_flag_to_false_when_onboarding_setting_is_set_to_true() {
171     settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS.getKey(), true);
172
173     UserDto user = underTest.register(newUserRegistration());
174
175     assertThat(db.users().selectUserByLogin(user.getLogin()).get().isOnboarded()).isFalse();
176   }
177
178   @Test
179   public void authenticate_new_user_sets_onboarded_flag_to_true_when_onboarding_setting_is_set_to_false() {
180     settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS.getKey(), false);
181
182     UserDto user = underTest.register(newUserRegistration());
183
184     assertThat(db.users().selectUserByLogin(user.getLogin()).get().isOnboarded()).isTrue();
185   }
186
187   @Test
188   public void authenticate_new_user_sets_external_id_to_provider_login_when_id_is_null() {
189     UserIdentity newUser = UserIdentity.builder()
190       .setProviderId(null)
191       .setProviderLogin("johndoo")
192       .setName("JOhn")
193       .build();
194
195     UserDto user = underTest.register(newUserRegistration(newUser));
196
197     assertThat(db.users().selectUserByLogin(user.getLogin()).get())
198       .extracting(UserDto::getLogin, UserDto::getExternalId, UserDto::getExternalLogin)
199       .contains(user.getLogin(), "johndoo", "johndoo");
200   }
201
202   @Test
203   public void authenticate_new_user_with_gitlab_provider() {
204     UserRegistration registration = UserRegistration.builder()
205       .setUserIdentity(USER_IDENTITY)
206       .setProvider(new TestIdentityProvider()
207         .setKey("gitlab")
208         .setName("name of gitlab")
209         .setEnabled(true)
210         .setAllowsUsersToSignUp(true))
211       .setSource(Source.local(BASIC))
212       .build();
213
214     UserDto newUser = underTest.register(registration);
215     assertThat(newUser)
216       .extracting(UserDto::getExternalIdentityProvider, UserDto::getExternalLogin)
217       .containsExactly("gitlab", USER_IDENTITY.getProviderLogin());
218   }
219
220   @Test
221   public void authenticate_new_user_throws_AuthenticationException_when_when_email_already_exists() {
222     db.users().insertUser(u -> u.setEmail("john@email.com"));
223     Source source = Source.local(BASIC);
224
225     expectedException.expect(authenticationException().from(source)
226       .withLogin(USER_IDENTITY.getProviderLogin())
227       .andPublicMessage("This account is already associated with another authentication method."
228         + " Sign in using the current authentication method,"
229         + " or contact your administrator to transfer your account to a different authentication method."));
230     expectedException.expectMessage("Email 'john@email.com' is already used");
231
232     underTest.register(newUserRegistration());
233   }
234
235   @Test
236   public void authenticate_new_user_throws_AuthenticationException_when_email_already_exists_multiple_times() {
237     db.users().insertUser(u -> u.setEmail("john@email.com"));
238     db.users().insertUser(u -> u.setEmail("john@email.com"));
239     Source source = Source.realm(AuthenticationEvent.Method.FORM, IDENTITY_PROVIDER.getName());
240
241     expectedException.expect(authenticationException().from(source)
242       .withLogin(USER_IDENTITY.getProviderLogin())
243       .andPublicMessage("This account is already associated with another authentication method."
244         + " Sign in using the current authentication method,"
245         + " or contact your administrator to transfer your account to a different authentication method."));
246     expectedException.expectMessage("Email 'john@email.com' is already used");
247
248     underTest.register(newUserRegistration(source));
249   }
250
251   @Test
252   public void authenticate_new_user_fails_when_allow_users_to_signup_is_false() {
253     TestIdentityProvider identityProvider = new TestIdentityProvider()
254       .setKey("github")
255       .setName("Github")
256       .setEnabled(true)
257       .setAllowsUsersToSignUp(false);
258     Source source = Source.realm(AuthenticationEvent.Method.FORM, identityProvider.getName());
259
260     expectedException.expect(authenticationException().from(source).withLogin(USER_IDENTITY.getProviderLogin()).andPublicMessage("'github' users are not allowed to sign up"));
261     expectedException.expectMessage("User signup disabled for provider 'github'");
262
263     underTest.register(UserRegistration.builder()
264       .setUserIdentity(USER_IDENTITY)
265       .setProvider(identityProvider)
266       .setSource(source)
267       .build());
268   }
269
270   @Test
271   public void authenticate_existing_user_doesnt_change_group_membership() {
272     UserDto user = db.users().insertUser(u -> u.setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
273     GroupDto group1 = db.users().insertGroup("group1");
274     db.users().insertMember(group1, user);
275     db.users().insertMember(defaultGroup, user);
276
277     authenticate(user.getExternalLogin(), user.getEmail(), "group1");
278
279     checkGroupMembership(user, group1, defaultGroup);
280   }
281
282   @Test
283   public void authenticate_and_update_existing_user_matching_external_id() {
284     UserDto user = db.users().insertUser(u -> u
285       .setLogin("Old login")
286       .setName("Old name")
287       .setEmail("Old email")
288       .setExternalId(USER_IDENTITY.getProviderId())
289       .setExternalLogin("old identity")
290       .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
291
292     underTest.register(newUserRegistration());
293
294     assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
295       .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
296         UserDto::isActive)
297       .contains(USER_LOGIN, "John", "john@email.com", "ABCD", "johndoo", "github", true);
298   }
299
300   @Test
301   public void authenticate_and_update_existing_user_matching_external_login_and_email() {
302     UserDto user = db.users().insertUser(u -> u
303       .setLogin("Old login")
304       .setName("Old name")
305       .setEmail(USER_IDENTITY.getEmail())
306       .setExternalId("Old id")
307       .setExternalLogin(USER_IDENTITY.getProviderLogin())
308       .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
309
310     underTest.register(newUserRegistration());
311
312     assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
313       .extracting(UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
314         UserDto::isActive)
315       .contains("John", "john@email.com", "ABCD", "johndoo", "github", true);
316   }
317
318   @Test
319   public void authenticate_existing_user_should_not_update_login() {
320     UserDto user = db.users().insertUser(u -> u
321       .setLogin("old login")
322       .setName(USER_IDENTITY.getName())
323       .setEmail(USER_IDENTITY.getEmail())
324       .setExternalId(USER_IDENTITY.getProviderId())
325       .setExternalLogin("old identity")
326       .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
327
328     underTest.register(newUserRegistration());
329
330     // no new user should be created
331     assertThat(db.countRowsOfTable(db.getSession(), "users")).isEqualTo(1);
332     assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
333       .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
334         UserDto::isActive)
335       .containsExactly("old login", USER_IDENTITY.getName(), USER_IDENTITY.getEmail(), USER_IDENTITY.getProviderId(), USER_IDENTITY.getProviderLogin(),
336         IDENTITY_PROVIDER.getKey(), true);
337   }
338
339   @Test
340   public void authenticate_existing_user_matching_external_login_and_email_when_external_id_is_null() {
341     UserDto user = db.users().insertUser(u -> u
342       .setName("Old name")
343       .setExternalId("Old id")
344       .setEmail("john@email.com")
345       .setExternalLogin("johndoo")
346       .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
347
348     underTest.register(newUserRegistration(UserIdentity.builder()
349       .setProviderId(null)
350       .setProviderLogin("johndoo")
351       .setName("John")
352       .setEmail("john@email.com")
353       .build()));
354
355     assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
356       .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
357         UserDto::isActive)
358       .contains(user.getLogin(), "John", "john@email.com", "johndoo", "johndoo", "github", true);
359   }
360
361   @Test
362   public void do_not_authenticate_gitlab_user_matching_external_login() {
363     db.users().insertUser(u -> u
364       .setLogin("Old login")
365       .setName("Old name")
366       .setEmail(USER_IDENTITY.getEmail())
367       .setExternalId("Old id")
368       .setExternalLogin(USER_IDENTITY.getProviderLogin())
369       .setExternalIdentityProvider("gitlab"));
370
371     UserRegistration registration = UserRegistration.builder()
372       .setUserIdentity(USER_IDENTITY)
373       .setProvider(new TestIdentityProvider()
374         .setKey("gitlab")
375         .setName("name of gitlab")
376         .setEnabled(true))
377       .setSource(Source.local(BASIC))
378       .build();
379
380     assertThatThrownBy(() -> underTest.register(registration))
381       .isInstanceOf(AuthenticationException.class)
382       .hasMessage(String.format("Login '%s' is already used", USER_IDENTITY.getProviderLogin()));
383   }
384
385   @Test
386   public void do_not_authenticate_and_update_existing_user_matching_external_login_if_emails_do_not_match() {
387     db.users().insertUser(u -> u
388       .setLogin("Old login")
389       .setName("Old name")
390       .setEmail("another-email@sonarsource.com")
391       .setExternalId("Old id")
392       .setExternalLogin(USER_IDENTITY.getProviderLogin())
393       .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
394
395     assertThatThrownBy(() -> underTest.register(newUserRegistration()))
396       .isInstanceOf(AuthenticationException.class)
397       .hasMessage(String.format("Login '%s' is already used", USER_IDENTITY.getProviderLogin()));
398
399     assertThat(logTester.logs()).contains(String.format("User with login '%s' tried to login with email '%s' which doesn't match the email on record '%s'",
400       USER_IDENTITY.getProviderLogin(), USER_IDENTITY.getEmail(), "another-email@sonarsource.com"));
401   }
402
403   @Test
404   public void authenticate_and_update_existing_user_matching_external_login_if_email_is_missing() {
405     db.users().insertUser(u -> u
406       .setLogin("Old login")
407       .setName("Old name")
408       .setExternalId("Old id")
409       .setEmail(null)
410       .setExternalLogin(USER_IDENTITY.getProviderLogin())
411       .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
412
413     underTest.register(newUserRegistration());
414
415     Optional<UserDto> user = db.users().selectUserByLogin("Old login");
416     assertThat(user).isPresent();
417     assertThat(user.get().getEmail()).isEqualTo(USER_IDENTITY.getEmail());
418   }
419
420   @Test
421   public void do_not_authenticate_and_update_existing_user_matching_external_id_if_external_provider_does_not_match() {
422     db.users().insertUser(u -> u
423       .setLogin("Old login")
424       .setName("Old name")
425       .setExternalId(USER_IDENTITY.getProviderId())
426       .setEmail(null)
427       .setExternalLogin(USER_IDENTITY.getProviderLogin())
428       .setExternalIdentityProvider("Old provider"));
429
430     underTest.register(newUserRegistration());
431     assertThat(db.countRowsOfTable("users")).isEqualTo(2);
432   }
433
434   @Test
435   public void authenticate_existing_user_should_update_login() {
436     UserDto user = db.users().insertUser(u -> u
437       .setLogin("Old login")
438       .setExternalId(USER_IDENTITY.getProviderId())
439       .setExternalLogin("old identity")
440       .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
441
442     underTest.register(newUserRegistration());
443
444     assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
445       .extracting(UserDto::getLogin, UserDto::getExternalLogin)
446       .contains(USER_LOGIN, USER_IDENTITY.getProviderLogin());
447   }
448
449   @Test
450   public void authenticate_existing_disabled_user_should_reactivate_it() {
451     db.users().insertUser(u -> u
452       .setLogin(USER_LOGIN)
453       .setActive(false)
454       .setName("Old name")
455       .setEmail(USER_IDENTITY.getEmail())
456       .setExternalId("Old id")
457       .setExternalLogin(USER_IDENTITY.getProviderLogin())
458       .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
459
460     underTest.register(newUserRegistration());
461
462     UserDto userDto = db.users().selectUserByLogin(USER_LOGIN).get();
463     assertThat(userDto.isActive()).isTrue();
464     assertThat(userDto.getName()).isEqualTo(USER_IDENTITY.getName());
465     assertThat(userDto.getEmail()).isEqualTo(USER_IDENTITY.getEmail());
466     assertThat(userDto.getExternalId()).isEqualTo(USER_IDENTITY.getProviderId());
467     assertThat(userDto.getExternalLogin()).isEqualTo(USER_IDENTITY.getProviderLogin());
468     assertThat(userDto.getExternalIdentityProvider()).isEqualTo(IDENTITY_PROVIDER.getKey());
469     assertThat(userDto.isRoot()).isFalse();
470   }
471
472   @Test
473   public void authenticating_existing_user_throws_AuthenticationException_when_email_already_exists() {
474     UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
475     UserDto currentUser = db.users().insertUser(u -> u.setEmail(null));
476     UserIdentity userIdentity = UserIdentity.builder()
477       .setProviderLogin("johndoo")
478       .setName("John")
479       .setEmail("john@email.com")
480       .build();
481
482     Source source = Source.realm(AuthenticationEvent.Method.FORM, IDENTITY_PROVIDER.getName());
483     expectedException.expect(authenticationException().from(source)
484       .withLogin(userIdentity.getProviderLogin())
485       .andPublicMessage("This account is already associated with another authentication method."
486         + " Sign in using the current authentication method,"
487         + " or contact your administrator to transfer your account to a different authentication method."));
488     expectedException.expectMessage("Email 'john@email.com' is already used");
489
490     underTest.register(newUserRegistration(userIdentity, source));
491   }
492
493   @Test
494   public void authenticate_existing_user_succeeds_when_email_has_not_changed() {
495     UserDto currentUser = db.users().insertUser(u -> u.setEmail("john@email.com")
496       .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
497     UserIdentity userIdentity = UserIdentity.builder()
498       .setProviderId(currentUser.getExternalId())
499       .setProviderLogin(currentUser.getExternalLogin())
500       .setName("John")
501       .setEmail("john@email.com")
502       .build();
503
504     underTest.register(newUserRegistration(userIdentity));
505
506     UserDto currentUserReloaded = db.users().selectUserByLogin(currentUser.getLogin()).get();
507     assertThat(currentUserReloaded.getEmail()).isEqualTo("john@email.com");
508   }
509
510   @Test
511   public void authenticate_existing_user_and_add_new_groups() {
512     UserDto user = db.users().insertUser(newUserDto()
513       .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey())
514       .setExternalLogin(USER_IDENTITY.getProviderLogin())
515       .setEmail(USER_IDENTITY.getEmail())
516       .setActive(true)
517       .setName("John"));
518     GroupDto group1 = db.users().insertGroup("group1");
519     GroupDto group2 = db.users().insertGroup("group2");
520
521     authenticate(USER_IDENTITY.getProviderLogin(), USER_IDENTITY.getEmail(), "group1", "group2", "group3");
522
523     checkGroupMembership(user, group1, group2);
524   }
525
526   @Test
527   public void authenticate_existing_user_and_remove_groups() {
528     UserDto user = db.users().insertUser(newUserDto()
529       .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey())
530       .setExternalLogin(USER_IDENTITY.getProviderLogin())
531       .setEmail(USER_IDENTITY.getEmail())
532       .setActive(true)
533       .setName("John"));
534     GroupDto group1 = db.users().insertGroup("group1");
535     GroupDto group2 = db.users().insertGroup("group2");
536     db.users().insertMember(group1, user);
537     db.users().insertMember(group2, user);
538
539     authenticate(USER_IDENTITY.getProviderLogin(), USER_IDENTITY.getEmail(), "group1");
540
541     checkGroupMembership(user, group1);
542   }
543
544   @Test
545   public void authenticate_existing_user_and_remove_all_groups_expect_default() {
546     UserDto user = db.users().insertUser(newUserDto()
547       .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey())
548       .setExternalLogin(USER_IDENTITY.getProviderLogin()));
549     GroupDto group1 = db.users().insertGroup("group1");
550     GroupDto group2 = db.users().insertGroup("group2");
551     db.users().insertMember(group1, user);
552     db.users().insertMember(group2, user);
553     db.users().insertMember(defaultGroup, user);
554
555     authenticate(user.getExternalLogin(), user.getEmail());
556
557     checkGroupMembership(user, defaultGroup);
558   }
559
560   private static UserRegistration newUserRegistration(UserIdentity userIdentity) {
561     return newUserRegistration(userIdentity, Source.local(BASIC));
562   }
563
564   private static UserRegistration newUserRegistration(UserIdentity userIdentity, Source source) {
565     return UserRegistration.builder()
566       .setUserIdentity(userIdentity)
567       .setProvider(IDENTITY_PROVIDER)
568       .setSource(source)
569       .build();
570   }
571
572   private static UserRegistration newUserRegistration(Source source) {
573     return newUserRegistration(USER_IDENTITY, source);
574   }
575
576   private static UserRegistration newUserRegistration() {
577     return newUserRegistration(USER_IDENTITY, Source.local(BASIC));
578   }
579
580   private UserDto authenticate(String providerLogin, @Nullable String email, String... groups) {
581     return underTest.register(newUserRegistration(UserIdentity.builder()
582       .setProviderLogin(providerLogin)
583       .setName("John")
584       .setEmail(email)
585       .setGroups(Set.of(groups))
586       .build()));
587   }
588
589   private void checkGroupMembership(UserDto user, GroupDto... expectedGroups) {
590     assertThat(db.users().selectGroupUuidsOfUser(user)).containsOnly(stream(expectedGroups).map(GroupDto::getUuid).collect(Collectors.toList()).toArray(new String[] {}));
591   }
592
593   private GroupDto insertDefaultGroup() {
594     return db.users().insertDefaultGroup();
595   }
596
597 }