3 * Copyright (C) 2009-2016 SonarSource SA
4 * mailto:contact 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.Arrays;
23 import java.util.Optional;
24 import org.junit.Before;
25 import org.junit.Rule;
26 import org.junit.Test;
27 import org.junit.rules.ExpectedException;
28 import org.sonar.api.config.MapSettings;
29 import org.sonar.api.config.Settings;
30 import org.sonar.api.server.authentication.UnauthorizedException;
31 import org.sonar.api.server.authentication.UserIdentity;
32 import org.sonar.api.utils.System2;
33 import org.sonar.api.utils.internal.AlwaysIncreasingSystem2;
34 import org.sonar.core.util.stream.Collectors;
35 import org.sonar.db.DbTester;
36 import org.sonar.db.organization.OrganizationDto;
37 import org.sonar.db.user.GroupDto;
38 import org.sonar.db.user.UserDto;
39 import org.sonar.server.organization.DefaultOrganizationProvider;
40 import org.sonar.server.organization.TestDefaultOrganizationProvider;
41 import org.sonar.server.user.NewUserNotifier;
42 import org.sonar.server.user.UserUpdater;
43 import org.sonar.server.user.index.UserIndexer;
45 import static org.assertj.core.api.Assertions.assertThat;
46 import static org.mockito.Mockito.mock;
47 import static org.sonar.db.user.UserTesting.newUserDto;
49 public class UserIdentityAuthenticatorTest {
51 private static String USER_LOGIN = "github-johndoo";
52 private static String DEFAULT_GROUP = "default";
54 private static UserIdentity USER_IDENTITY = UserIdentity.builder()
55 .setProviderLogin("johndoo")
58 .setEmail("john@email.com")
61 private static TestIdentityProvider IDENTITY_PROVIDER = new TestIdentityProvider()
64 .setAllowsUsersToSignUp(true);
67 public ExpectedException thrown = ExpectedException.none();
70 public DbTester db = DbTester.create(new AlwaysIncreasingSystem2());
72 private Settings settings = new MapSettings();
73 private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
74 private UserUpdater userUpdater = new UserUpdater(
75 mock(NewUserNotifier.class),
78 mock(UserIndexer.class),
80 defaultOrganizationProvider);
81 private UserIdentityAuthenticator underTest = new UserIdentityAuthenticator(db.getDbClient(), userUpdater, defaultOrganizationProvider);
82 private GroupDto defaultGroup;
85 public void setUp() throws Exception {
86 settings.setProperty("sonar.defaultGroup", DEFAULT_GROUP);
87 defaultGroup = db.users().insertGroup(db.getDefaultOrganization(), DEFAULT_GROUP);
91 public void authenticate_new_user() throws Exception {
92 underTest.authenticate(USER_IDENTITY, IDENTITY_PROVIDER);
94 UserDto user = db.users().selectUserByLogin(USER_LOGIN).get();
95 assertThat(user).isNotNull();
96 assertThat(user.isActive()).isTrue();
97 assertThat(user.getName()).isEqualTo("John");
98 assertThat(user.getEmail()).isEqualTo("john@email.com");
99 assertThat(user.getExternalIdentity()).isEqualTo("johndoo");
100 assertThat(user.getExternalIdentityProvider()).isEqualTo("github");
102 assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(defaultGroup.getId());
106 public void authenticate_new_user_with_groups() throws Exception {
107 GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
108 GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
110 authenticate(USER_LOGIN, "group1", "group2", "group3");
112 Optional<UserDto> user = db.users().selectUserByLogin(USER_LOGIN);
113 assertThat(user).isPresent();
115 assertThat(db.users().selectGroupIdsOfUser(user.get())).containsOnly(group1.getId(), group2.getId());
119 public void authenticate_existing_user() throws Exception {
120 db.users().insertUser(newUserDto()
121 .setLogin(USER_LOGIN)
124 .setEmail("Old email")
125 .setExternalIdentity("old identity")
126 .setExternalIdentityProvider("old provide"));
128 underTest.authenticate(USER_IDENTITY, IDENTITY_PROVIDER);
130 UserDto userDto = db.users().selectUserByLogin(USER_LOGIN).get();
131 assertThat(userDto.isActive()).isTrue();
132 assertThat(userDto.getName()).isEqualTo("John");
133 assertThat(userDto.getEmail()).isEqualTo("john@email.com");
134 assertThat(userDto.getExternalIdentity()).isEqualTo("johndoo");
135 assertThat(userDto.getExternalIdentityProvider()).isEqualTo("github");
139 public void authenticate_existing_disabled_user() throws Exception {
140 db.users().insertUser(newUserDto()
141 .setLogin(USER_LOGIN)
144 .setEmail("Old email")
145 .setExternalIdentity("old identity")
146 .setExternalIdentityProvider("old provide"));
148 underTest.authenticate(USER_IDENTITY, IDENTITY_PROVIDER);
150 UserDto userDto = db.users().selectUserByLogin(USER_LOGIN).get();
151 assertThat(userDto.isActive()).isTrue();
152 assertThat(userDto.getName()).isEqualTo("John");
153 assertThat(userDto.getEmail()).isEqualTo("john@email.com");
154 assertThat(userDto.getExternalIdentity()).isEqualTo("johndoo");
155 assertThat(userDto.getExternalIdentityProvider()).isEqualTo("github");
159 public void authenticate_existing_user_and_add_new_groups() throws Exception {
160 UserDto user = db.users().insertUser(newUserDto()
161 .setLogin(USER_LOGIN)
164 GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
165 GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
167 authenticate(USER_LOGIN, "group1", "group2", "group3");
169 assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(group1.getId(), group2.getId());
173 public void authenticate_existing_user_and_remove_groups() throws Exception {
174 UserDto user = db.users().insertUser(newUserDto()
175 .setLogin(USER_LOGIN)
178 GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
179 GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
180 db.users().insertMember(group1, user);
181 db.users().insertMember(group2, user);
183 authenticate(USER_LOGIN, "group1");
185 assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(group1.getId());
189 public void authenticate_existing_user_and_remove_all_groups() throws Exception {
190 UserDto user = db.users().insertUser(newUserDto()
191 .setLogin(USER_LOGIN)
194 GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
195 GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
196 db.users().insertMember(group1, user);
197 db.users().insertMember(group2, user);
199 authenticate(USER_LOGIN);
201 assertThat(db.users().selectGroupIdsOfUser(user)).isEmpty();
205 public void authenticate_new_user_and_add_it_to_no_group_sets_root_flag_to_false() {
206 authenticate(USER_LOGIN);
208 db.rootFlag().verify(USER_LOGIN, false);
212 public void authenticate_new_user_and_add_it_to_admin_group_of_default_organization_sets_root_flag_to_true() {
213 GroupDto adminGroup = db.users().insertAdminGroup(db.getDefaultOrganization());
215 authenticate(USER_LOGIN, adminGroup.getName());
217 db.rootFlag().verify(USER_LOGIN, true);
221 public void authenticate_new_user_and_add_it_to_admin_group_of_other_organization_does_not_set_root_flag_to_true() {
222 OrganizationDto otherOrganization = db.organizations().insert();
223 GroupDto adminGroup = db.users().insertAdminGroup(otherOrganization);
225 authenticate(USER_LOGIN, adminGroup.getName());
227 db.rootFlag().verify(USER_LOGIN, false);
231 public void authenticate_existing_user_and_add_it_to_no_group_sets_root_flag_to_false() {
232 UserDto userDto = db.users().insertUser();
234 authenticate(userDto.getLogin());
236 db.rootFlag().verify(userDto, false);
240 public void authenticate_existing_user_and_add_it_to_admin_group_of_default_organization_sets_root_flag_to_true() {
241 GroupDto adminGroup = db.users().insertAdminGroup(db.getDefaultOrganization());
242 UserDto userDto = db.users().insertUser();
244 authenticate(userDto.getLogin(), adminGroup.getName());
246 db.rootFlag().verify(userDto, true);
250 public void authenticate_existing_user_and_add_it_to_admin_group_of_other_organization_sets_root_flag_to_false() {
251 OrganizationDto otherOrganization = db.organizations().insert();
252 GroupDto adminGroup = db.users().insertAdminGroup(otherOrganization);
253 UserDto userDto = db.users().insertUser();
255 authenticate(userDto.getLogin(), adminGroup.getName());
257 db.rootFlag().verify(userDto, false);
261 public void authenticate_existing_user_and_remove_it_from_admin_group_of_default_organization_sets_root_flag_to_false() {
262 GroupDto adminGroup = db.users().insertAdminGroup(db.getDefaultOrganization());
263 UserDto userDto = db.users().makeRoot(db.users().insertUser());
264 db.users().insertMembers(adminGroup, userDto);
266 authenticate(userDto.getLogin());
268 db.rootFlag().verify(userDto, false);
272 public void authenticate_existing_user_with_user_permission_admin_on_default_organization_with_no_group_does_not_set_root_flag_to_false() {
273 UserDto rootUser = db.users().insertRootByUserPermission();
275 authenticate(rootUser.getLogin());
278 db.rootFlag().verify(rootUser, true);
282 public void authenticate_existing_user_with_user_permission_admin_on_default_organization_with_non_admin_groups_does_not_set_root_flag_to_false() {
283 OrganizationDto otherOrganization = db.organizations().insert();
284 GroupDto defaultOrgGroup = db.users().insertGroup(db.getDefaultOrganization());
285 GroupDto otherOrgGroup = db.users().insertGroup(otherOrganization);
286 UserDto rootUser = db.users().insertRootByUserPermission();
288 authenticate(rootUser.getLogin(), defaultOrgGroup.getName(), otherOrgGroup.getName());
290 db.rootFlag().verify(rootUser, true);
294 public void authenticate_user_multiple_times_sets_root_flag_to_true_only_if_at_least_one_group_is_admin() {
295 GroupDto defaultAdminGroup = db.users().insertAdminGroup(db.getDefaultOrganization(), "admin_of_default");
296 GroupDto defaultSomeGroup = db.users().insertGroup(db.getDefaultOrganization(), "some_group_of_default");
297 OrganizationDto otherOrganization = db.organizations().insert();
298 GroupDto otherAdminGroup = db.users().insertAdminGroup(otherOrganization, "admin_of_other");
299 GroupDto otherSomeGroup = db.users().insertGroup(otherOrganization, "some_group_of_other");
301 authenticate(USER_LOGIN, defaultAdminGroup.getName(), defaultSomeGroup.getName(), otherAdminGroup.getName(), otherSomeGroup.getName());
302 db.rootFlag().verify(USER_LOGIN, true);
304 authenticate(USER_LOGIN, defaultAdminGroup.getName(), defaultSomeGroup.getName(), otherAdminGroup.getName());
305 db.rootFlag().verify(USER_LOGIN, true);
307 authenticate(USER_LOGIN, otherAdminGroup.getName(), defaultAdminGroup.getName());
308 db.rootFlag().verify(USER_LOGIN, true);
310 authenticate(USER_LOGIN, otherAdminGroup.getName());
311 db.rootFlag().verify(USER_LOGIN, false);
313 authenticate(USER_LOGIN, otherAdminGroup.getName(), otherSomeGroup.getName());
314 db.rootFlag().verify(USER_LOGIN, false);
316 authenticate(USER_LOGIN, otherAdminGroup.getName(), otherSomeGroup.getName());
317 db.rootFlag().verify(USER_LOGIN, false);
319 authenticate(USER_LOGIN, otherAdminGroup.getName(), defaultAdminGroup.getName());
320 db.rootFlag().verify(USER_LOGIN, true);
322 authenticate(USER_LOGIN, defaultSomeGroup.getName(), defaultAdminGroup.getName());
323 db.rootFlag().verify(USER_LOGIN, true);
325 authenticate(USER_LOGIN, otherSomeGroup.getName(), defaultAdminGroup.getName());
326 db.rootFlag().verify(USER_LOGIN, true);
328 authenticate(USER_LOGIN, otherSomeGroup.getName(), defaultSomeGroup.getName());
329 db.rootFlag().verify(USER_LOGIN, false);
333 public void fail_to_authenticate_new_user_when_allow_users_to_signup_is_false() throws Exception {
334 TestIdentityProvider identityProvider = new TestIdentityProvider()
338 .setAllowsUsersToSignUp(false);
340 thrown.expect(UnauthorizedException.class);
341 thrown.expectMessage("'github' users are not allowed to sign up");
342 underTest.authenticate(USER_IDENTITY, identityProvider);
346 public void fail_to_authenticate_new_user_when_email_already_exists() throws Exception {
347 db.users().insertUser(newUserDto()
348 .setLogin("Existing user with same email")
350 .setEmail("john@email.com"));
352 thrown.expect(UnauthorizedException.class);
353 thrown.expectMessage("You can't sign up because email 'john@email.com' is already used by an existing user. " +
354 "This means that you probably already registered with another account.");
355 underTest.authenticate(USER_IDENTITY, IDENTITY_PROVIDER);
358 private void authenticate(String login, String... groups) {
359 underTest.authenticate(UserIdentity.builder()
360 .setProviderLogin("johndoo")
364 .setGroups(Arrays.stream(groups).collect(Collectors.toSet()))
365 .build(), IDENTITY_PROVIDER);