3 * Copyright (C) 2009-2019 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;
23 import java.util.stream.Collectors;
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.server.authentication.UserIdentity;
30 import org.sonar.api.utils.System2;
31 import org.sonar.core.util.stream.MoreCollectors;
32 import org.sonar.db.DbTester;
33 import org.sonar.db.organization.OrganizationDto;
34 import org.sonar.db.user.GroupDto;
35 import org.sonar.db.user.UserDto;
36 import org.sonar.server.authentication.UserRegistration.ExistingEmailStrategy;
37 import org.sonar.server.authentication.event.AuthenticationEvent;
38 import org.sonar.server.authentication.event.AuthenticationEvent.Source;
39 import org.sonar.server.authentication.exception.EmailAlreadyExistsRedirectionException;
40 import org.sonar.server.es.EsTester;
41 import org.sonar.server.organization.DefaultOrganizationProvider;
42 import org.sonar.server.organization.MemberUpdater;
43 import org.sonar.server.organization.OrganizationUpdater;
44 import org.sonar.server.organization.TestDefaultOrganizationProvider;
45 import org.sonar.server.organization.TestOrganizationFlags;
46 import org.sonar.server.user.NewUserNotifier;
47 import org.sonar.server.user.UserUpdater;
48 import org.sonar.server.user.index.UserIndexer;
49 import org.sonar.server.usergroups.DefaultGroupFinder;
51 import static com.google.common.collect.Sets.newHashSet;
52 import static java.util.Arrays.stream;
53 import static org.assertj.core.api.Assertions.assertThat;
54 import static org.mockito.Mockito.mock;
55 import static org.sonar.db.user.UserTesting.newUserDto;
56 import static org.sonar.process.ProcessProperties.Property.ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS;
57 import static org.sonar.server.authentication.UserRegistration.ExistingEmailStrategy.FORBID;
58 import static org.sonar.server.authentication.event.AuthenticationEvent.Method.BASIC;
59 import static org.sonar.server.authentication.event.AuthenticationExceptionMatcher.authenticationException;
61 public class UserRegistrarImplTest {
63 private System2 system2 = new AlwaysIncreasingSystem2();
65 private static String USER_LOGIN = "github-johndoo";
67 private static UserIdentity USER_IDENTITY = UserIdentity.builder()
68 .setProviderId("ABCD")
69 .setProviderLogin("johndoo")
72 .setEmail("john@email.com")
75 private static TestIdentityProvider IDENTITY_PROVIDER = new TestIdentityProvider()
77 .setName("name of github")
79 .setAllowsUsersToSignUp(true);
81 private MapSettings settings = new MapSettings();
84 public ExpectedException expectedException = ExpectedException.none();
86 public DbTester db = DbTester.create(new AlwaysIncreasingSystem2());
88 public EsTester es = EsTester.create();
89 private UserIndexer userIndexer = new UserIndexer(db.getDbClient(), es.client());
90 private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
91 private OrganizationUpdater organizationUpdater = mock(OrganizationUpdater.class);
92 private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone();
93 private CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient());
94 private UserUpdater userUpdater = new UserUpdater(
96 mock(NewUserNotifier.class),
100 defaultOrganizationProvider,
101 new DefaultGroupFinder(db.getDbClient()),
103 localAuthentication);
105 private DefaultGroupFinder defaultGroupFinder = new DefaultGroupFinder(db.getDbClient());
107 private UserRegistrarImpl underTest = new UserRegistrarImpl(db.getDbClient(), userUpdater, defaultOrganizationProvider, organizationFlags,
108 defaultGroupFinder, new MemberUpdater(db.getDbClient(), defaultGroupFinder, userIndexer));
111 public void authenticate_new_user() {
112 organizationFlags.setEnabled(true);
114 underTest.register(UserRegistration.builder()
115 .setUserIdentity(USER_IDENTITY)
116 .setProvider(IDENTITY_PROVIDER)
117 .setSource(Source.realm(BASIC, IDENTITY_PROVIDER.getName()))
118 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
121 UserDto user = db.users().selectUserByLogin(USER_LOGIN).get();
122 assertThat(user).isNotNull();
123 assertThat(user.isActive()).isTrue();
124 assertThat(user.getName()).isEqualTo("John");
125 assertThat(user.getEmail()).isEqualTo("john@email.com");
126 assertThat(user.getExternalLogin()).isEqualTo("johndoo");
127 assertThat(user.getExternalIdentityProvider()).isEqualTo("github");
128 assertThat(user.getExternalId()).isEqualTo("ABCD");
129 assertThat(user.isRoot()).isFalse();
130 checkGroupMembership(user);
134 public void authenticate_new_user_generate_login_when_no_login_provided() {
135 organizationFlags.setEnabled(true);
137 underTest.register(UserRegistration.builder()
138 .setUserIdentity(UserIdentity.builder()
139 .setProviderId("ABCD")
140 .setProviderLogin("johndoo")
142 .setEmail("john@email.com")
144 .setProvider(IDENTITY_PROVIDER)
145 .setSource(Source.realm(BASIC, IDENTITY_PROVIDER.getName()))
146 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
149 UserDto user = db.getDbClient().userDao().selectByEmail(db.getSession(), "john@email.com").get(0);
150 assertThat(user).isNotNull();
151 assertThat(user.isActive()).isTrue();
152 assertThat(user.getLogin()).isNotEqualTo("John Doe").startsWith("john-doe");
153 assertThat(user.getEmail()).isEqualTo("john@email.com");
154 assertThat(user.getExternalLogin()).isEqualTo("johndoo");
155 assertThat(user.getExternalIdentityProvider()).isEqualTo("github");
156 assertThat(user.getExternalId()).isEqualTo("ABCD");
160 public void authenticate_new_user_with_groups() {
161 organizationFlags.setEnabled(true);
162 GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
163 GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
165 authenticate(USER_LOGIN, "group1", "group2", "group3");
167 Optional<UserDto> user = db.users().selectUserByLogin(USER_LOGIN);
168 checkGroupMembership(user.get(), group1, group2);
172 public void authenticate_new_user_and_force_default_group_when_organizations_are_disabled() {
173 organizationFlags.setEnabled(false);
174 UserDto user = db.users().insertUser();
175 GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
176 GroupDto defaultGroup = insertDefaultGroup();
177 db.users().insertMember(group1, user);
178 db.users().insertMember(defaultGroup, user);
180 authenticate(user.getLogin(), "group1");
182 checkGroupMembership(user, group1, defaultGroup);
186 public void does_not_force_default_group_when_authenticating_new_user_if_organizations_are_enabled() {
187 organizationFlags.setEnabled(true);
188 UserDto user = db.users().insertUser();
189 GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
190 GroupDto defaultGroup = insertDefaultGroup();
191 db.users().insertMember(group1, user);
192 db.users().insertMember(defaultGroup, user);
194 authenticate(user.getLogin(), "group1");
196 checkGroupMembership(user, group1);
200 public void authenticate_new_user_sets_onboarded_flag_to_false_when_onboarding_setting_is_set_to_true() {
201 organizationFlags.setEnabled(true);
202 settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS.getKey(), true);
204 underTest.register(UserRegistration.builder()
205 .setUserIdentity(USER_IDENTITY)
206 .setProvider(IDENTITY_PROVIDER)
207 .setSource(Source.local(BASIC))
208 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
211 assertThat(db.users().selectUserByLogin(USER_LOGIN).get().isOnboarded()).isFalse();
215 public void authenticate_new_user_sets_onboarded_flag_to_true_when_onboarding_setting_is_set_to_false() {
216 organizationFlags.setEnabled(true);
217 settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS.getKey(), false);
219 underTest.register(UserRegistration.builder()
220 .setUserIdentity(USER_IDENTITY)
221 .setProvider(IDENTITY_PROVIDER)
222 .setSource(Source.local(BASIC))
223 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
226 assertThat(db.users().selectUserByLogin(USER_LOGIN).get().isOnboarded()).isTrue();
230 public void external_id_is_set_to_provider_login_when_null() {
231 organizationFlags.setEnabled(true);
232 UserIdentity newUser = UserIdentity.builder()
235 .setProviderLogin("johndoo")
239 underTest.register(UserRegistration.builder()
240 .setUserIdentity(newUser)
241 .setProvider(IDENTITY_PROVIDER)
242 .setSource(Source.local(BASIC))
243 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
246 assertThat(db.users().selectUserByLogin(newUser.getLogin()).get())
247 .extracting(UserDto::getLogin, UserDto::getExternalId, UserDto::getExternalLogin)
248 .contains("john", "johndoo", "johndoo");
252 public void authenticate_new_user_update_existing_user_email_when_strategy_is_ALLOW() {
253 organizationFlags.setEnabled(true);
254 UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
255 UserIdentity newUser = UserIdentity.builder()
256 .setProviderLogin("johndoo")
257 .setLogin("new_login")
258 .setName(existingUser.getName())
259 .setEmail(existingUser.getEmail())
262 underTest.register(UserRegistration.builder()
263 .setUserIdentity(newUser)
264 .setProvider(IDENTITY_PROVIDER)
265 .setSource(Source.local(BASIC))
266 .setExistingEmailStrategy(ExistingEmailStrategy.ALLOW)
269 UserDto newUserReloaded = db.users().selectUserByLogin(newUser.getLogin()).get();
270 assertThat(newUserReloaded.getEmail()).isEqualTo(existingUser.getEmail());
271 UserDto existingUserReloaded = db.users().selectUserByLogin(existingUser.getLogin()).get();
272 assertThat(existingUserReloaded.getEmail()).isNull();
276 public void throw_EmailAlreadyExistException_when_authenticating_new_user_when_email_already_exists_and_strategy_is_WARN() {
277 organizationFlags.setEnabled(true);
278 UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
279 UserIdentity newUser = UserIdentity.builder()
280 .setProviderLogin("johndoo")
281 .setLogin("new_login")
282 .setName(existingUser.getName())
283 .setEmail(existingUser.getEmail())
286 expectedException.expect(EmailAlreadyExistsRedirectionException.class);
288 underTest.register(UserRegistration.builder()
289 .setUserIdentity(newUser)
290 .setProvider(IDENTITY_PROVIDER)
291 .setSource(Source.local(BASIC))
292 .setExistingEmailStrategy(ExistingEmailStrategy.WARN)
297 public void throw_AuthenticationException_when_authenticating_new_user_when_email_already_exists_and_strategy_is_FORBID() {
298 db.users().insertUser(u -> u.setEmail("john@email.com"));
299 Source source = Source.realm(AuthenticationEvent.Method.FORM, IDENTITY_PROVIDER.getName());
301 expectedException.expect(authenticationException().from(source)
302 .withLogin(USER_IDENTITY.getProviderLogin())
303 .andPublicMessage("You can't sign up because email 'john@email.com' is already used by an existing user. " +
304 "This means that you probably already registered with another account."));
305 expectedException.expectMessage("Email 'john@email.com' is already used");
307 underTest.register(UserRegistration.builder()
308 .setUserIdentity(USER_IDENTITY)
309 .setProvider(IDENTITY_PROVIDER)
311 .setExistingEmailStrategy(FORBID)
312 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
317 public void throw_AuthenticationException_when_authenticating_new_user_and_email_already_exists_multiple_times() {
318 db.users().insertUser(u -> u.setEmail("john@email.com"));
319 db.users().insertUser(u -> u.setEmail("john@email.com"));
320 Source source = Source.realm(AuthenticationEvent.Method.FORM, IDENTITY_PROVIDER.getName());
322 expectedException.expect(authenticationException().from(source)
323 .withLogin(USER_IDENTITY.getProviderLogin())
324 .andPublicMessage("You can't sign up because email 'john@email.com' is already used by an existing user. " +
325 "This means that you probably already registered with another account."));
326 expectedException.expectMessage("Email 'john@email.com' is already used");
328 underTest.register(UserRegistration.builder()
329 .setUserIdentity(USER_IDENTITY)
330 .setProvider(IDENTITY_PROVIDER)
332 .setExistingEmailStrategy(FORBID)
333 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
338 public void fail_to_authenticate_new_user_when_allow_users_to_signup_is_false() {
339 TestIdentityProvider identityProvider = new TestIdentityProvider()
343 .setAllowsUsersToSignUp(false);
344 Source source = Source.realm(AuthenticationEvent.Method.FORM, identityProvider.getName());
346 expectedException.expect(authenticationException().from(source).withLogin(USER_IDENTITY.getProviderLogin()).andPublicMessage("'github' users are not allowed to sign up"));
347 expectedException.expectMessage("User signup disabled for provider 'github'");
349 underTest.register(UserRegistration.builder()
350 .setUserIdentity(USER_IDENTITY)
351 .setProvider(identityProvider)
353 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
358 public void authenticate_and_update_existing_user_matching_login() {
359 db.users().insertUser(u -> u
360 .setLogin(USER_LOGIN)
362 .setEmail("Old email")
363 .setExternalId("old id")
364 .setExternalLogin("old identity")
365 .setExternalIdentityProvider("old provide"));
367 underTest.register(UserRegistration.builder()
368 .setUserIdentity(USER_IDENTITY)
369 .setProvider(IDENTITY_PROVIDER)
370 .setSource(Source.local(BASIC))
371 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
374 assertThat(db.users().selectUserByLogin(USER_LOGIN).get())
375 .extracting(UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider, UserDto::isActive)
376 .contains("John", "john@email.com", "ABCD", "johndoo", "github", true);
380 public void authenticate_and_update_existing_user_matching_external_id() {
381 UserDto user = db.users().insertUser(u -> u
382 .setLogin("Old login")
384 .setEmail("Old email")
385 .setExternalId(USER_IDENTITY.getProviderId())
386 .setExternalLogin("old identity")
387 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
389 underTest.register(UserRegistration.builder()
390 .setUserIdentity(USER_IDENTITY)
391 .setProvider(IDENTITY_PROVIDER)
392 .setSource(Source.local(BASIC))
393 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
396 assertThat(db.users().selectUserByLogin("Old login")).isNotPresent();
397 assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
398 .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
400 .contains(USER_LOGIN, "John", "john@email.com", "ABCD", "johndoo", "github", true);
404 public void authenticate_and_update_existing_user_matching_external_login() {
405 UserDto user = db.users().insertUser(u -> u
406 .setLogin("Old login")
408 .setEmail(USER_IDENTITY.getEmail())
409 .setExternalId("Old id")
410 .setExternalLogin(USER_IDENTITY.getProviderLogin())
411 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
413 underTest.register(UserRegistration.builder()
414 .setUserIdentity(USER_IDENTITY)
415 .setProvider(IDENTITY_PROVIDER)
416 .setSource(Source.local(BASIC))
417 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
420 assertThat(db.users().selectUserByLogin("Old login")).isNotPresent();
421 assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
422 .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
424 .contains(USER_LOGIN, "John", "john@email.com", "ABCD", "johndoo", "github", true);
428 public void authenticate_existing_user_and_update_only_login() {
429 UserDto user = db.users().insertUser(u -> u
430 .setLogin("old login")
431 .setName(USER_IDENTITY.getName())
432 .setEmail(USER_IDENTITY.getEmail())
433 .setExternalId(USER_IDENTITY.getProviderId())
434 .setExternalLogin("old identity")
435 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
437 underTest.register(UserRegistration.builder()
438 .setUserIdentity(USER_IDENTITY)
439 .setProvider(IDENTITY_PROVIDER)
440 .setSource(Source.local(BASIC))
441 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
444 assertThat(db.users().selectUserByLogin("Old login")).isNotPresent();
445 assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
446 .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
448 .containsExactlyInAnyOrder(USER_LOGIN, USER_IDENTITY.getName(), USER_IDENTITY.getEmail(), USER_IDENTITY.getProviderId(), USER_IDENTITY.getProviderLogin(),
449 IDENTITY_PROVIDER.getKey(),
454 public void authenticate_existing_user_and_update_only_identity_provider_key() {
455 UserDto user = db.users().insertUser(u -> u
456 .setLogin(USER_LOGIN)
457 .setName(USER_IDENTITY.getName())
458 .setEmail(USER_IDENTITY.getEmail())
459 .setExternalId(USER_IDENTITY.getProviderId())
460 .setExternalLogin(USER_IDENTITY.getProviderLogin())
461 .setExternalIdentityProvider("old identity provider"));
463 underTest.register(UserRegistration.builder()
464 .setUserIdentity(USER_IDENTITY)
465 .setProvider(IDENTITY_PROVIDER)
466 .setSource(Source.local(BASIC))
467 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
470 assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
471 .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
473 .containsExactlyInAnyOrder(USER_LOGIN, USER_IDENTITY.getName(), USER_IDENTITY.getEmail(), USER_IDENTITY.getProviderId(), USER_IDENTITY.getProviderLogin(),
474 IDENTITY_PROVIDER.getKey(),
479 public void authenticate_existing_user_matching_login_when_external_id_is_null() {
480 UserDto user = db.users().insertUser(u -> u
481 .setLogin(USER_LOGIN)
483 .setEmail("Old email")
484 .setExternalId("Old id")
485 .setExternalLogin("old identity")
486 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
488 underTest.register(UserRegistration.builder()
489 .setUserIdentity(UserIdentity.builder()
491 .setProviderLogin("johndoo")
492 .setLogin(USER_LOGIN)
494 .setEmail("john@email.com")
496 .setProvider(IDENTITY_PROVIDER)
497 .setSource(Source.local(BASIC))
498 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
501 assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
502 .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
504 .contains(user.getLogin(), "John", "john@email.com", "johndoo", "johndoo", "github", true);
508 public void authenticate_existing_user_when_login_is_not_provided() {
509 UserDto user = db.users().insertUser(u -> u.setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
511 underTest.register(UserRegistration.builder()
512 .setUserIdentity(UserIdentity.builder()
513 .setProviderId(user.getExternalId())
514 .setProviderLogin(user.getExternalLogin())
516 .setName(user.getName())
517 .setEmail(user.getEmail())
519 .setProvider(IDENTITY_PROVIDER)
520 .setSource(Source.local(BASIC))
521 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
524 // No new user is created
525 assertThat(db.countRowsOfTable(db.getSession(), "users")).isEqualTo(1);
526 assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
527 .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
529 .contains(user.getLogin(), user.getName(), user.getEmail(), user.getExternalId(), user.getExternalLogin(), user.getExternalIdentityProvider(), true);
533 public void authenticate_existing_user_with_login_update_and_strategy_is_ALLOW() {
534 UserDto user = db.users().insertUser(u -> u
535 .setLogin("Old login")
536 .setExternalId(USER_IDENTITY.getProviderId())
537 .setExternalLogin("old identity")
538 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
540 underTest.register(UserRegistration.builder()
541 .setUserIdentity(USER_IDENTITY)
542 .setProvider(IDENTITY_PROVIDER)
543 .setSource(Source.local(BASIC))
544 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
547 assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
548 .extracting(UserDto::getLogin, UserDto::getExternalLogin)
549 .contains(USER_LOGIN, USER_IDENTITY.getProviderLogin());
553 public void authenticate_existing_disabled_user() {
554 organizationFlags.setEnabled(true);
555 db.users().insertUser(u -> u
556 .setLogin(USER_LOGIN)
559 .setEmail("Old email")
560 .setExternalId("old id")
561 .setExternalLogin("old identity")
562 .setExternalIdentityProvider("old provide"));
564 underTest.register(UserRegistration.builder()
565 .setUserIdentity(USER_IDENTITY)
566 .setProvider(IDENTITY_PROVIDER)
567 .setSource(Source.local(BASIC))
568 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
571 UserDto userDto = db.users().selectUserByLogin(USER_LOGIN).get();
572 assertThat(userDto.isActive()).isTrue();
573 assertThat(userDto.getName()).isEqualTo("John");
574 assertThat(userDto.getEmail()).isEqualTo("john@email.com");
575 assertThat(userDto.getExternalId()).isEqualTo("ABCD");
576 assertThat(userDto.getExternalLogin()).isEqualTo("johndoo");
577 assertThat(userDto.getExternalIdentityProvider()).isEqualTo("github");
578 assertThat(userDto.isRoot()).isFalse();
582 public void authenticate_existing_user_when_email_already_exists_and_strategy_is_ALLOW() {
583 organizationFlags.setEnabled(true);
584 UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
585 UserDto currentUser = db.users().insertUser(u -> u.setEmail(null));
586 UserIdentity userIdentity = UserIdentity.builder()
587 .setLogin(currentUser.getLogin())
588 .setProviderLogin("johndoo")
590 .setEmail("john@email.com")
593 underTest.register(UserRegistration.builder()
594 .setUserIdentity(userIdentity)
595 .setProvider(IDENTITY_PROVIDER)
596 .setSource(Source.local(BASIC))
597 .setExistingEmailStrategy(ExistingEmailStrategy.ALLOW)
600 UserDto currentUserReloaded = db.users().selectUserByLogin(currentUser.getLogin()).get();
601 assertThat(currentUserReloaded.getEmail()).isEqualTo("john@email.com");
602 UserDto existingUserReloaded = db.users().selectUserByLogin(existingUser.getLogin()).get();
603 assertThat(existingUserReloaded.getEmail()).isNull();
607 public void throw_EmailAlreadyExistException_when_authenticating_existing_user_when_email_already_exists_and_strategy_is_WARN() {
608 organizationFlags.setEnabled(true);
609 UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
610 UserDto currentUser = db.users().insertUser(u -> u.setEmail(null));
611 UserIdentity userIdentity = UserIdentity.builder()
612 .setLogin(currentUser.getLogin())
613 .setProviderLogin("johndoo")
615 .setEmail("john@email.com")
618 expectedException.expect(EmailAlreadyExistsRedirectionException.class);
620 underTest.register(UserRegistration.builder()
621 .setUserIdentity(userIdentity)
622 .setProvider(IDENTITY_PROVIDER)
623 .setSource(Source.local(BASIC))
624 .setExistingEmailStrategy(ExistingEmailStrategy.WARN)
629 public void throw_AuthenticationException_when_authenticating_existing_user_when_email_already_exists_and_strategy_is_FORBID() {
630 organizationFlags.setEnabled(true);
631 UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
632 UserDto currentUser = db.users().insertUser(u -> u.setEmail(null));
633 UserIdentity userIdentity = UserIdentity.builder()
634 .setLogin(currentUser.getLogin())
635 .setProviderLogin("johndoo")
637 .setEmail("john@email.com")
640 expectedException.expect(authenticationException().from(Source.realm(AuthenticationEvent.Method.FORM, IDENTITY_PROVIDER.getName()))
641 .withLogin(userIdentity.getProviderLogin())
642 .andPublicMessage("You can't sign up because email 'john@email.com' is already used by an existing user. " +
643 "This means that you probably already registered with another account."));
644 expectedException.expectMessage("Email 'john@email.com' is already used");
646 underTest.register(UserRegistration.builder()
647 .setUserIdentity(userIdentity)
648 .setProvider(IDENTITY_PROVIDER)
649 .setSource(Source.realm(AuthenticationEvent.Method.FORM, IDENTITY_PROVIDER.getName()))
650 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
655 public void does_not_fail_to_authenticate_user_when_email_has_not_changed_and_strategy_is_FORBID() {
656 organizationFlags.setEnabled(true);
657 UserDto currentUser = db.users().insertUser(u -> u.setEmail("john@email.com")
658 .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
659 UserIdentity userIdentity = UserIdentity.builder()
660 .setLogin(currentUser.getLogin())
661 .setProviderId(currentUser.getExternalId())
662 .setProviderLogin(currentUser.getExternalLogin())
664 .setEmail("john@email.com")
667 underTest.register(UserRegistration.builder()
668 .setUserIdentity(userIdentity)
669 .setProvider(IDENTITY_PROVIDER)
670 .setSource(Source.local(BASIC))
671 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
674 UserDto currentUserReloaded = db.users().selectUserByLogin(currentUser.getLogin()).get();
675 assertThat(currentUserReloaded.getEmail()).isEqualTo("john@email.com");
679 public void authenticate_existing_user_and_add_new_groups() {
680 organizationFlags.setEnabled(true);
681 UserDto user = db.users().insertUser(newUserDto()
682 .setLogin(USER_LOGIN)
685 GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
686 GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
688 authenticate(USER_LOGIN, "group1", "group2", "group3");
690 checkGroupMembership(user, group1, group2);
694 public void authenticate_existing_user_and_remove_groups() {
695 organizationFlags.setEnabled(true);
696 UserDto user = db.users().insertUser(newUserDto()
697 .setLogin(USER_LOGIN)
700 GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
701 GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
702 db.users().insertMember(group1, user);
703 db.users().insertMember(group2, user);
705 authenticate(USER_LOGIN, "group1");
707 checkGroupMembership(user, group1);
711 public void authenticate_existing_user_and_remove_all_groups_expect_default_when_organizations_are_disabled() {
712 organizationFlags.setEnabled(false);
713 UserDto user = db.users().insertUser();
714 GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
715 GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
716 GroupDto defaultGroup = insertDefaultGroup();
717 db.users().insertMember(group1, user);
718 db.users().insertMember(group2, user);
719 db.users().insertMember(defaultGroup, user);
721 authenticate(user.getLogin());
723 checkGroupMembership(user, defaultGroup);
727 public void does_not_force_default_group_when_authenticating_existing_user_when_organizations_are_enabled() {
728 organizationFlags.setEnabled(true);
729 UserDto user = db.users().insertUser();
730 GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
731 GroupDto defaultGroup = insertDefaultGroup();
732 db.users().insertMember(group1, user);
733 db.users().insertMember(defaultGroup, user);
735 authenticate(user.getLogin(), "group1");
737 checkGroupMembership(user, group1);
741 public void ignore_groups_on_non_default_organizations() {
742 organizationFlags.setEnabled(true);
743 OrganizationDto org = db.organizations().insert();
744 UserDto user = db.users().insertUser(newUserDto()
745 .setLogin(USER_LOGIN)
748 String groupName = "a-group";
749 GroupDto groupInDefaultOrg = db.users().insertGroup(db.getDefaultOrganization(), groupName);
750 GroupDto groupInOrg = db.users().insertGroup(org, groupName);
752 // adding a group with the same name than in non-default organization
753 underTest.register(UserRegistration.builder()
754 .setUserIdentity(UserIdentity.builder()
755 .setProviderLogin("johndoo")
756 .setLogin(user.getLogin())
757 .setName(user.getName())
758 .setGroups(newHashSet(groupName))
760 .setProvider(IDENTITY_PROVIDER)
761 .setSource(Source.local(BASIC))
762 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
765 checkGroupMembership(user, groupInDefaultOrg);
768 private void authenticate(String login, String... groups) {
769 underTest.register(UserRegistration.builder()
770 .setUserIdentity(UserIdentity.builder()
771 .setProviderLogin("johndoo")
775 .setGroups(stream(groups).collect(MoreCollectors.toSet()))
777 .setProvider(IDENTITY_PROVIDER)
778 .setSource(Source.local(BASIC))
779 .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
783 private void checkGroupMembership(UserDto user, GroupDto... expectedGroups) {
784 assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(stream(expectedGroups).map(GroupDto::getId).collect(Collectors.toList()).toArray(new Integer[] {}));
787 private GroupDto insertDefaultGroup() {
788 return db.users().insertDefaultGroup(db.getDefaultOrganization(), "sonar-users");