3 * Copyright (C) 2009-2021 SonarSource SA
4 * mailto:info AT sonarsource DOT com
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.
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.
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.
20 package org.sonar.server.authentication;
22 import java.util.Optional;
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.UserRegistration.ExistingEmailStrategy;
38 import org.sonar.server.authentication.event.AuthenticationEvent;
39 import org.sonar.server.authentication.event.AuthenticationEvent.Source;
40 import org.sonar.server.authentication.event.AuthenticationException;
41 import org.sonar.server.authentication.exception.EmailAlreadyExistsRedirectionException;
42 import org.sonar.server.es.EsTester;
43 import org.sonar.server.user.NewUserNotifier;
44 import org.sonar.server.user.UserUpdater;
45 import org.sonar.server.user.index.UserIndexer;
46 import org.sonar.server.usergroups.DefaultGroupFinder;
48 import static java.util.Arrays.stream;
49 import static org.assertj.core.api.Assertions.assertThat;
50 import static org.assertj.core.api.Assertions.assertThatThrownBy;
51 import static org.mockito.Mockito.mock;
52 import static org.sonar.db.user.UserTesting.newUserDto;
53 import static org.sonar.process.ProcessProperties.Property.ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS;
54 import static org.sonar.server.authentication.UserRegistration.ExistingEmailStrategy.FORBID;
55 import static org.sonar.server.authentication.event.AuthenticationEvent.Method.BASIC;
56 import static org.sonar.server.authentication.event.AuthenticationExceptionMatcher.authenticationException;
58 public class UserRegistrarImplTest {
59 private static final String USER_LOGIN = "johndoo";
61 private static final UserIdentity USER_IDENTITY = UserIdentity.builder()
62 .setProviderId("ABCD")
63 .setProviderLogin(USER_LOGIN)
65 .setEmail("john@email.com")
68 private static final TestIdentityProvider IDENTITY_PROVIDER = new TestIdentityProvider()
70 .setName("name of github")
72 .setAllowsUsersToSignUp(true);
74 private final MapSettings settings = new MapSettings().setProperty("sonar.internal.pbkdf2.iterations", "1");
77 public ExpectedException expectedException = ExpectedException.none();
79 public DbTester db = DbTester.create(new AlwaysIncreasingSystem2());
81 public EsTester es = EsTester.create();
83 public LogTester logTester = new LogTester();
85 private final UserIndexer userIndexer = new UserIndexer(db.getDbClient(), es.client());
86 private final CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient(), settings.asConfig());
87 private final DefaultGroupFinder groupFinder = new DefaultGroupFinder(db.getDbClient());
88 private final UserUpdater userUpdater = new UserUpdater(mock(NewUserNotifier.class), db.getDbClient(), userIndexer, groupFinder, settings.asConfig(), localAuthentication);
90 private final UserRegistrarImpl underTest = new UserRegistrarImpl(db.getDbClient(), userUpdater, groupFinder);
91 private GroupDto defaultGroup;
95 defaultGroup = insertDefaultGroup();
99 public void authenticate_new_user() {
100 UserDto createdUser = underTest.register(newUserRegistration());
102 UserDto user = db.users().selectUserByLogin(createdUser.getLogin()).get();
103 assertThat(user).isNotNull();
104 assertThat(user.isActive()).isTrue();
105 assertThat(user.getName()).isEqualTo("John");
106 assertThat(user.getEmail()).isEqualTo("john@email.com");
107 assertThat(user.getExternalLogin()).isEqualTo(USER_LOGIN);
108 assertThat(user.getExternalIdentityProvider()).isEqualTo("github");
109 assertThat(user.getExternalId()).isEqualTo("ABCD");
110 assertThat(user.isRoot()).isFalse();
111 checkGroupMembership(user, defaultGroup);
115 public void authenticate_new_user_with_sq_identity() {
116 TestIdentityProvider sqIdentityProvider = new TestIdentityProvider()
118 .setName("sonarqube identity name")
120 .setAllowsUsersToSignUp(true);
122 UserDto createdUser = underTest.register(UserRegistration.builder()
123 .setUserIdentity(USER_IDENTITY)
124 .setProvider(sqIdentityProvider)
125 .setSource(Source.realm(BASIC, sqIdentityProvider.getName()))
126 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
129 UserDto user = db.users().selectUserByLogin(createdUser.getLogin()).get();
130 assertThat(user).isNotNull();
131 assertThat(user.isActive()).isTrue();
132 assertThat(user.getLogin()).isEqualTo(USER_LOGIN);
133 assertThat(user.getName()).isEqualTo("John");
134 assertThat(user.getEmail()).isEqualTo("john@email.com");
135 assertThat(user.getExternalLogin()).isEqualTo(USER_LOGIN);
136 assertThat(user.getExternalIdentityProvider()).isEqualTo("sonarqube");
137 assertThat(user.getExternalId()).isEqualTo("ABCD");
138 assertThat(user.isLocal()).isFalse();
139 assertThat(user.isRoot()).isFalse();
140 checkGroupMembership(user, defaultGroup);
144 public void authenticate_new_user_generates_login() {
145 underTest.register(newUserRegistration(UserIdentity.builder()
146 .setProviderId("ABCD")
147 .setProviderLogin(USER_LOGIN)
149 .setEmail("john@email.com")
152 UserDto user = db.getDbClient().userDao().selectByEmail(db.getSession(), "john@email.com").get(0);
153 assertThat(user).isNotNull();
154 assertThat(user.isActive()).isTrue();
155 assertThat(user.getLogin()).isNotEqualTo("John Doe").startsWith("john-doe");
156 assertThat(user.getEmail()).isEqualTo("john@email.com");
157 assertThat(user.getExternalLogin()).isEqualTo(USER_LOGIN);
158 assertThat(user.getExternalIdentityProvider()).isEqualTo("github");
159 assertThat(user.getExternalId()).isEqualTo("ABCD");
163 public void authenticate_new_user_assigns_user_to_groups() {
164 GroupDto group1 = db.users().insertGroup("group1");
165 GroupDto group2 = db.users().insertGroup("group2");
167 UserDto loggedInUser = authenticate(USER_LOGIN, USER_IDENTITY.getEmail(), "group1", "group2", "group3");
169 Optional<UserDto> user = db.users().selectUserByLogin(loggedInUser.getLogin());
170 checkGroupMembership(user.get(), group1, group2, defaultGroup);
174 public void authenticate_new_user_sets_onboarded_flag_to_false_when_onboarding_setting_is_set_to_true() {
175 settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS.getKey(), true);
177 UserDto user = underTest.register(newUserRegistration());
179 assertThat(db.users().selectUserByLogin(user.getLogin()).get().isOnboarded()).isFalse();
183 public void authenticate_new_user_sets_onboarded_flag_to_true_when_onboarding_setting_is_set_to_false() {
184 settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS.getKey(), false);
186 UserDto user = underTest.register(newUserRegistration());
188 assertThat(db.users().selectUserByLogin(user.getLogin()).get().isOnboarded()).isTrue();
192 public void authenticate_new_user_sets_external_id_to_provider_login_when_id_is_null() {
193 UserIdentity newUser = UserIdentity.builder()
195 .setProviderLogin("johndoo")
199 UserDto user = underTest.register(newUserRegistration(newUser));
201 assertThat(db.users().selectUserByLogin(user.getLogin()).get())
202 .extracting(UserDto::getLogin, UserDto::getExternalId, UserDto::getExternalLogin)
203 .contains(user.getLogin(), "johndoo", "johndoo");
207 public void authenticate_new_user_with_gitlab_provider() {
208 UserRegistration registration = UserRegistration.builder()
209 .setUserIdentity(USER_IDENTITY)
210 .setProvider(new TestIdentityProvider()
212 .setName("name of gitlab")
214 .setAllowsUsersToSignUp(true))
215 .setSource(Source.local(BASIC))
216 .setExistingEmailStrategy(FORBID)
219 UserDto newUser = underTest.register(registration);
221 .extracting(UserDto::getExternalIdentityProvider, UserDto::getExternalLogin)
222 .containsExactly("gitlab", USER_IDENTITY.getProviderLogin());
226 public void authenticate_new_user_update_existing_user_email_when_strategy_is_ALLOW() {
227 UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
228 UserIdentity newUser = UserIdentity.builder()
229 .setProviderLogin("johndoo")
230 .setName(existingUser.getName())
231 .setEmail(existingUser.getEmail())
234 UserDto user = underTest.register(UserRegistration.builder()
235 .setUserIdentity(newUser)
236 .setProvider(IDENTITY_PROVIDER)
237 .setSource(Source.local(BASIC))
238 .setExistingEmailStrategy(ExistingEmailStrategy.ALLOW)
241 UserDto newUserReloaded = db.users().selectUserByLogin(user.getLogin()).get();
242 assertThat(newUserReloaded.getEmail()).isEqualTo(existingUser.getEmail());
243 UserDto existingUserReloaded = db.users().selectUserByLogin(existingUser.getLogin()).get();
244 assertThat(existingUserReloaded.getEmail()).isNull();
248 public void authenticate_new_user_throws_EmailAlreadyExistException_when_email_already_exists_and_strategy_is_WARN() {
249 UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
250 UserIdentity newUser = UserIdentity.builder()
251 .setProviderLogin("johndoo")
252 .setName(existingUser.getName())
253 .setEmail(existingUser.getEmail())
256 expectedException.expect(EmailAlreadyExistsRedirectionException.class);
258 underTest.register(UserRegistration.builder()
259 .setUserIdentity(newUser)
260 .setProvider(IDENTITY_PROVIDER)
261 .setSource(Source.local(BASIC))
262 .setExistingEmailStrategy(ExistingEmailStrategy.WARN)
267 public void authenticate_new_user_throws_AuthenticationException_when_when_email_already_exists_and_strategy_is_FORBID() {
268 db.users().insertUser(u -> u.setEmail("john@email.com"));
269 Source source = Source.local(BASIC);
271 expectedException.expect(authenticationException().from(source)
272 .withLogin(USER_IDENTITY.getProviderLogin())
273 .andPublicMessage("You can't sign up because email 'john@email.com' is already used by an existing user. " +
274 "This means that you probably already registered with another account."));
275 expectedException.expectMessage("Email 'john@email.com' is already used");
277 underTest.register(newUserRegistration());
281 public void authenticate_new_user_throws_AuthenticationException_when_email_already_exists_multiple_times() {
282 db.users().insertUser(u -> u.setEmail("john@email.com"));
283 db.users().insertUser(u -> u.setEmail("john@email.com"));
284 Source source = Source.realm(AuthenticationEvent.Method.FORM, IDENTITY_PROVIDER.getName());
286 expectedException.expect(authenticationException().from(source)
287 .withLogin(USER_IDENTITY.getProviderLogin())
288 .andPublicMessage("You can't sign up because email 'john@email.com' is already used by an existing user. " +
289 "This means that you probably already registered with another account."));
290 expectedException.expectMessage("Email 'john@email.com' is already used");
292 underTest.register(newUserRegistration(source));
296 public void authenticate_new_user_fails_when_allow_users_to_signup_is_false() {
297 TestIdentityProvider identityProvider = new TestIdentityProvider()
301 .setAllowsUsersToSignUp(false);
302 Source source = Source.realm(AuthenticationEvent.Method.FORM, identityProvider.getName());
304 expectedException.expect(authenticationException().from(source).withLogin(USER_IDENTITY.getProviderLogin()).andPublicMessage("'github' users are not allowed to sign up"));
305 expectedException.expectMessage("User signup disabled for provider 'github'");
307 underTest.register(UserRegistration.builder()
308 .setUserIdentity(USER_IDENTITY)
309 .setProvider(identityProvider)
311 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
316 public void authenticate_existing_user_doesnt_change_group_membership() {
317 UserDto user = db.users().insertUser(u -> u.setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
318 GroupDto group1 = db.users().insertGroup("group1");
319 db.users().insertMember(group1, user);
320 db.users().insertMember(defaultGroup, user);
322 authenticate(user.getExternalLogin(), user.getEmail(), "group1");
324 checkGroupMembership(user, group1, defaultGroup);
328 public void authenticate_and_update_existing_user_matching_external_id() {
329 UserDto user = db.users().insertUser(u -> u
330 .setLogin("Old login")
332 .setEmail("Old email")
333 .setExternalId(USER_IDENTITY.getProviderId())
334 .setExternalLogin("old identity")
335 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
337 underTest.register(newUserRegistration());
339 assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
340 .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
342 .contains(USER_LOGIN, "John", "john@email.com", "ABCD", "johndoo", "github", true);
346 public void authenticate_and_update_existing_user_matching_external_login_and_email() {
347 UserDto user = db.users().insertUser(u -> u
348 .setLogin("Old login")
350 .setEmail(USER_IDENTITY.getEmail())
351 .setExternalId("Old id")
352 .setExternalLogin(USER_IDENTITY.getProviderLogin())
353 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
355 underTest.register(newUserRegistration());
357 assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
358 .extracting(UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
360 .contains("John", "john@email.com", "ABCD", "johndoo", "github", true);
364 public void authenticate_existing_user_should_not_update_login() {
365 UserDto user = db.users().insertUser(u -> u
366 .setLogin("old login")
367 .setName(USER_IDENTITY.getName())
368 .setEmail(USER_IDENTITY.getEmail())
369 .setExternalId(USER_IDENTITY.getProviderId())
370 .setExternalLogin("old identity")
371 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
373 underTest.register(newUserRegistration());
375 // no new user should be created
376 assertThat(db.countRowsOfTable(db.getSession(), "users")).isEqualTo(1);
377 assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
378 .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
380 .containsExactly("old login", USER_IDENTITY.getName(), USER_IDENTITY.getEmail(), USER_IDENTITY.getProviderId(), USER_IDENTITY.getProviderLogin(),
381 IDENTITY_PROVIDER.getKey(), true);
385 public void authenticate_existing_user_matching_external_login_and_email_when_external_id_is_null() {
386 UserDto user = db.users().insertUser(u -> u
388 .setExternalId("Old id")
389 .setEmail("john@email.com")
390 .setExternalLogin("johndoo")
391 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
393 underTest.register(newUserRegistration(UserIdentity.builder()
395 .setProviderLogin("johndoo")
397 .setEmail("john@email.com")
400 assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
401 .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
403 .contains(user.getLogin(), "John", "john@email.com", "johndoo", "johndoo", "github", true);
407 public void do_not_authenticate_gitlab_user_matching_external_login() {
408 db.users().insertUser(u -> u
409 .setLogin("Old login")
411 .setEmail(USER_IDENTITY.getEmail())
412 .setExternalId("Old id")
413 .setExternalLogin(USER_IDENTITY.getProviderLogin())
414 .setExternalIdentityProvider("gitlab"));
416 UserRegistration registration = UserRegistration.builder()
417 .setUserIdentity(USER_IDENTITY)
418 .setProvider(new TestIdentityProvider()
420 .setName("name of gitlab")
422 .setSource(Source.local(BASIC))
423 .setExistingEmailStrategy(FORBID)
426 assertThatThrownBy(() -> underTest.register(registration))
427 .isInstanceOf(AuthenticationException.class)
428 .hasMessage(String.format("Login '%s' is already used", USER_IDENTITY.getProviderLogin()));
432 public void do_not_authenticate_and_update_existing_user_matching_external_login_if_emails_do_not_match() {
433 db.users().insertUser(u -> u
434 .setLogin("Old login")
436 .setEmail("another-email@sonarsource.com")
437 .setExternalId("Old id")
438 .setExternalLogin(USER_IDENTITY.getProviderLogin())
439 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
441 assertThatThrownBy(() -> underTest.register(newUserRegistration()))
442 .isInstanceOf(AuthenticationException.class)
443 .hasMessage(String.format("Login '%s' is already used", USER_IDENTITY.getProviderLogin()));
445 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'",
446 USER_IDENTITY.getProviderLogin(), USER_IDENTITY.getEmail(), "another-email@sonarsource.com"));
450 public void do_not_authenticate_and_update_existing_user_matching_external_login_if_email_is_missing() {
451 db.users().insertUser(u -> u
452 .setLogin("Old login")
454 .setExternalId("Old id")
456 .setExternalLogin(USER_IDENTITY.getProviderLogin())
457 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
459 assertThatThrownBy(() -> underTest.register(newUserRegistration()))
460 .isInstanceOf(AuthenticationException.class)
461 .hasMessage(String.format("Login '%s' is already used", USER_IDENTITY.getProviderLogin()));
463 assertThat(logTester.logs()).contains(String.format("User with login '%s' tried to login with email '%s' but we don't have a email on record",
464 USER_IDENTITY.getProviderLogin(), USER_IDENTITY.getEmail()));
468 public void do_not_authenticate_and_update_existing_user_matching_external_id_if_external_provider_does_not_match() {
469 db.users().insertUser(u -> u
470 .setLogin("Old login")
472 .setExternalId(USER_IDENTITY.getProviderId())
474 .setExternalLogin(USER_IDENTITY.getProviderLogin())
475 .setExternalIdentityProvider("Old provider"));
477 underTest.register(newUserRegistration());
478 assertThat(db.countRowsOfTable("users")).isEqualTo(2);
482 public void authenticate_existing_user_should_update_login() {
483 UserDto user = db.users().insertUser(u -> u
484 .setLogin("Old login")
485 .setExternalId(USER_IDENTITY.getProviderId())
486 .setExternalLogin("old identity")
487 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
489 underTest.register(newUserRegistration());
491 assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
492 .extracting(UserDto::getLogin, UserDto::getExternalLogin)
493 .contains(USER_LOGIN, USER_IDENTITY.getProviderLogin());
497 public void authenticate_existing_disabled_user_should_reactivate_it() {
498 db.users().insertUser(u -> u
499 .setLogin(USER_LOGIN)
502 .setEmail(USER_IDENTITY.getEmail())
503 .setExternalId("Old id")
504 .setExternalLogin(USER_IDENTITY.getProviderLogin())
505 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
507 underTest.register(newUserRegistration());
509 UserDto userDto = db.users().selectUserByLogin(USER_LOGIN).get();
510 assertThat(userDto.isActive()).isTrue();
511 assertThat(userDto.getName()).isEqualTo(USER_IDENTITY.getName());
512 assertThat(userDto.getEmail()).isEqualTo(USER_IDENTITY.getEmail());
513 assertThat(userDto.getExternalId()).isEqualTo(USER_IDENTITY.getProviderId());
514 assertThat(userDto.getExternalLogin()).isEqualTo(USER_IDENTITY.getProviderLogin());
515 assertThat(userDto.getExternalIdentityProvider()).isEqualTo(IDENTITY_PROVIDER.getKey());
516 assertThat(userDto.isRoot()).isFalse();
520 public void authenticate_existing_user_when_email_already_exists_and_strategy_is_ALLOW() {
521 UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
522 UserDto currentUser = db.users().insertUser(u -> u.setExternalId("id").setExternalLogin("login").setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()).setEmail(null));
524 UserIdentity userIdentity = UserIdentity.builder()
525 .setProviderLogin(currentUser.getExternalLogin())
526 .setProviderId(currentUser.getExternalId())
528 .setEmail("john@email.com")
531 currentUser = underTest.register(UserRegistration.builder()
532 .setUserIdentity(userIdentity)
533 .setProvider(IDENTITY_PROVIDER)
534 .setSource(Source.local(BASIC))
535 .setExistingEmailStrategy(ExistingEmailStrategy.ALLOW)
538 UserDto existingUserReloaded = db.users().selectUserByLogin(existingUser.getLogin()).get();
539 assertThat(existingUserReloaded.getEmail()).isNull();
541 UserDto currentUserReloaded = db.users().selectUserByLogin(currentUser.getLogin()).get();
542 assertThat(currentUserReloaded.getEmail()).isEqualTo("john@email.com");
547 public void authenticating_existing_user_throws_EmailAlreadyExistException_when_email_already_exists_and_strategy_is_WARN() {
548 UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
549 UserDto currentUser = db.users().insertUser(u -> u.setEmail(null));
550 UserIdentity userIdentity = UserIdentity.builder()
551 .setProviderLogin("johndoo")
553 .setEmail("john@email.com")
556 expectedException.expect(EmailAlreadyExistsRedirectionException.class);
558 underTest.register(UserRegistration.builder()
559 .setUserIdentity(userIdentity)
560 .setProvider(IDENTITY_PROVIDER)
561 .setSource(Source.local(BASIC))
562 .setExistingEmailStrategy(ExistingEmailStrategy.WARN)
567 public void authenticating_existing_user_throws_AuthenticationException_when_email_already_exists_and_strategy_is_FORBID() {
568 UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
569 UserDto currentUser = db.users().insertUser(u -> u.setEmail(null));
570 UserIdentity userIdentity = UserIdentity.builder()
571 .setProviderLogin("johndoo")
573 .setEmail("john@email.com")
576 Source source = Source.realm(AuthenticationEvent.Method.FORM, IDENTITY_PROVIDER.getName());
577 expectedException.expect(authenticationException().from(source)
578 .withLogin(userIdentity.getProviderLogin())
579 .andPublicMessage("You can't sign up because email 'john@email.com' is already used by an existing user. " +
580 "This means that you probably already registered with another account."));
581 expectedException.expectMessage("Email 'john@email.com' is already used");
583 underTest.register(newUserRegistration(userIdentity, source));
587 public void authenticate_existing_user_succeeds_when_email_has_not_changed_and_strategy_is_FORBID() {
588 UserDto currentUser = db.users().insertUser(u -> u.setEmail("john@email.com")
589 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
590 UserIdentity userIdentity = UserIdentity.builder()
591 .setProviderId(currentUser.getExternalId())
592 .setProviderLogin(currentUser.getExternalLogin())
594 .setEmail("john@email.com")
597 underTest.register(newUserRegistration(userIdentity));
599 UserDto currentUserReloaded = db.users().selectUserByLogin(currentUser.getLogin()).get();
600 assertThat(currentUserReloaded.getEmail()).isEqualTo("john@email.com");
604 public void authenticate_existing_user_and_add_new_groups() {
605 UserDto user = db.users().insertUser(newUserDto()
606 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey())
607 .setExternalLogin(USER_IDENTITY.getProviderLogin())
608 .setEmail(USER_IDENTITY.getEmail())
611 GroupDto group1 = db.users().insertGroup("group1");
612 GroupDto group2 = db.users().insertGroup("group2");
614 authenticate(USER_IDENTITY.getProviderLogin(), USER_IDENTITY.getEmail(), "group1", "group2", "group3");
616 checkGroupMembership(user, group1, group2);
620 public void authenticate_existing_user_and_remove_groups() {
621 UserDto user = db.users().insertUser(newUserDto()
622 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey())
623 .setExternalLogin(USER_IDENTITY.getProviderLogin())
624 .setEmail(USER_IDENTITY.getEmail())
627 GroupDto group1 = db.users().insertGroup("group1");
628 GroupDto group2 = db.users().insertGroup("group2");
629 db.users().insertMember(group1, user);
630 db.users().insertMember(group2, user);
632 authenticate(USER_IDENTITY.getProviderLogin(), USER_IDENTITY.getEmail(), "group1");
634 checkGroupMembership(user, group1);
638 public void authenticate_existing_user_and_remove_all_groups_expect_default() {
639 UserDto user = db.users().insertUser(newUserDto()
640 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey())
641 .setExternalLogin(USER_IDENTITY.getProviderLogin()));
642 GroupDto group1 = db.users().insertGroup("group1");
643 GroupDto group2 = db.users().insertGroup("group2");
644 db.users().insertMember(group1, user);
645 db.users().insertMember(group2, user);
646 db.users().insertMember(defaultGroup, user);
648 authenticate(user.getExternalLogin(), user.getEmail());
650 checkGroupMembership(user, defaultGroup);
653 private static UserRegistration newUserRegistration(UserIdentity userIdentity) {
654 return newUserRegistration(userIdentity, Source.local(BASIC));
657 private static UserRegistration newUserRegistration(UserIdentity userIdentity, Source source) {
658 return UserRegistration.builder()
659 .setUserIdentity(userIdentity)
660 .setProvider(IDENTITY_PROVIDER)
662 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
666 private static UserRegistration newUserRegistration(Source source) {
667 return newUserRegistration(USER_IDENTITY, source);
670 private static UserRegistration newUserRegistration() {
671 return newUserRegistration(USER_IDENTITY, Source.local(BASIC));
674 private UserDto authenticate(String providerLogin, @Nullable String email, String... groups) {
675 return underTest.register(newUserRegistration(UserIdentity.builder()
676 .setProviderLogin(providerLogin)
679 .setGroups(Set.of(groups))
683 private void checkGroupMembership(UserDto user, GroupDto... expectedGroups) {
684 assertThat(db.users().selectGroupUuidsOfUser(user)).containsOnly(stream(expectedGroups).map(GroupDto::getUuid).collect(Collectors.toList()).toArray(new String[] {}));
687 private GroupDto insertDefaultGroup() {
688 return db.users().insertDefaultGroup();