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.Collections;
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.db.DbTester;
34 import org.sonar.db.user.GroupDto;
35 import org.sonar.db.user.UserDto;
36 import org.sonar.server.organization.DefaultOrganizationProvider;
37 import org.sonar.server.organization.DefaultOrganizationProviderRule;
38 import org.sonar.server.user.NewUserNotifier;
39 import org.sonar.server.user.UserUpdater;
40 import org.sonar.server.user.index.UserIndexer;
42 import static com.google.common.collect.Sets.newHashSet;
43 import static org.assertj.core.api.Assertions.assertThat;
44 import static org.mockito.Mockito.mock;
45 import static org.sonar.db.user.UserTesting.newUserDto;
47 public class UserIdentityAuthenticatorTest {
49 private static String USER_LOGIN = "github-johndoo";
50 private static String DEFAULT_GROUP = "default";
52 private static UserIdentity USER_IDENTITY = UserIdentity.builder()
53 .setProviderLogin("johndoo")
56 .setEmail("john@email.com")
59 private static TestIdentityProvider IDENTITY_PROVIDER = new TestIdentityProvider()
62 .setAllowsUsersToSignUp(true);
65 public ExpectedException thrown = ExpectedException.none();
67 private System2 system2 = mock(System2.class);
70 public DbTester db = DbTester.create(system2);
72 private Settings settings = new MapSettings();
73 private DefaultOrganizationProvider defaultOrganizationProvider = DefaultOrganizationProviderRule.create(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);
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 underTest.authenticate(UserIdentity.builder()
111 .setProviderLogin("johndoo")
112 .setLogin(USER_LOGIN)
114 // group3 doesn't exist in db, it will be ignored
115 .setGroups(newHashSet("group1", "group2", "group3"))
116 .build(), IDENTITY_PROVIDER);
118 Optional<UserDto> user = db.users().selectUserByLogin(USER_LOGIN);
119 assertThat(user).isPresent();
121 assertThat(db.users().selectGroupIdsOfUser(user.get())).containsOnly(group1.getId(), group2.getId());
125 public void authenticate_existing_user() throws Exception {
126 db.users().insertUser(newUserDto()
127 .setLogin(USER_LOGIN)
130 .setEmail("Old email")
131 .setExternalIdentity("old identity")
132 .setExternalIdentityProvider("old provide"));
134 underTest.authenticate(USER_IDENTITY, IDENTITY_PROVIDER);
136 UserDto userDto = db.users().selectUserByLogin(USER_LOGIN).get();
137 assertThat(userDto.isActive()).isTrue();
138 assertThat(userDto.getName()).isEqualTo("John");
139 assertThat(userDto.getEmail()).isEqualTo("john@email.com");
140 assertThat(userDto.getExternalIdentity()).isEqualTo("johndoo");
141 assertThat(userDto.getExternalIdentityProvider()).isEqualTo("github");
145 public void authenticate_existing_disabled_user() throws Exception {
146 db.users().insertUser(newUserDto()
147 .setLogin(USER_LOGIN)
150 .setEmail("Old email")
151 .setExternalIdentity("old identity")
152 .setExternalIdentityProvider("old provide"));
154 underTest.authenticate(USER_IDENTITY, IDENTITY_PROVIDER);
156 UserDto userDto = db.users().selectUserByLogin(USER_LOGIN).get();
157 assertThat(userDto.isActive()).isTrue();
158 assertThat(userDto.getName()).isEqualTo("John");
159 assertThat(userDto.getEmail()).isEqualTo("john@email.com");
160 assertThat(userDto.getExternalIdentity()).isEqualTo("johndoo");
161 assertThat(userDto.getExternalIdentityProvider()).isEqualTo("github");
165 public void authenticate_existing_user_and_add_new_groups() throws Exception {
166 UserDto user = db.users().insertUser(newUserDto()
167 .setLogin(USER_LOGIN)
170 GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
171 GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
173 underTest.authenticate(UserIdentity.builder()
174 .setProviderLogin("johndoo")
175 .setLogin(USER_LOGIN)
177 // group3 doesn't exist in db, it will be ignored
178 .setGroups(newHashSet("group1", "group2", "group3"))
179 .build(), IDENTITY_PROVIDER);
181 assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(group1.getId(), group2.getId());
185 public void authenticate_existing_user_and_remove_groups() throws Exception {
186 UserDto user = db.users().insertUser(newUserDto()
187 .setLogin(USER_LOGIN)
190 GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
191 GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
192 db.users().insertMember(group1, user);
193 db.users().insertMember(group2, user);
195 underTest.authenticate(UserIdentity.builder()
196 .setProviderLogin("johndoo")
197 .setLogin(USER_LOGIN)
199 // Only group1 is returned by the id provider => group2 will be removed
200 .setGroups(newHashSet("group1"))
201 .build(), IDENTITY_PROVIDER);
203 assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(group1.getId());
207 public void authenticate_existing_user_and_remove_all_groups() throws Exception {
208 UserDto user = db.users().insertUser(newUserDto()
209 .setLogin(USER_LOGIN)
212 GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
213 GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
214 db.users().insertMember(group1, user);
215 db.users().insertMember(group2, user);
217 underTest.authenticate(UserIdentity.builder()
218 .setProviderLogin("johndoo")
219 .setLogin(USER_LOGIN)
221 // No group => group1 and group2 will be removed
222 .setGroups(Collections.emptySet())
223 .build(), IDENTITY_PROVIDER);
225 assertThat(db.users().selectGroupIdsOfUser(user)).isEmpty();
229 public void fail_to_authenticate_new_user_when_allow_users_to_signup_is_false() throws Exception {
230 TestIdentityProvider identityProvider = new TestIdentityProvider()
234 .setAllowsUsersToSignUp(false);
236 thrown.expect(UnauthorizedException.class);
237 thrown.expectMessage("'github' users are not allowed to sign up");
238 underTest.authenticate(USER_IDENTITY, identityProvider);
242 public void fail_to_authenticate_new_user_when_email_already_exists() throws Exception {
243 db.users().insertUser(newUserDto()
244 .setLogin("Existing user with same email")
246 .setEmail("john@email.com"));
248 thrown.expect(UnauthorizedException.class);
249 thrown.expectMessage("You can't sign up because email 'john@email.com' is already used by an existing user. " +
250 "This means that you probably already registered with another account.");
251 underTest.authenticate(USER_IDENTITY, IDENTITY_PROVIDER);