]> source.dussan.org Git - sonarqube.git/blob
e65a5a631b0b4816f8154970a4d633832158a745
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2016 SonarSource SA
4  * mailto:contact 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.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;
44
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;
48
49 public class UserIdentityAuthenticatorTest {
50
51   private static String USER_LOGIN = "github-johndoo";
52   private static String DEFAULT_GROUP = "default";
53
54   private static UserIdentity USER_IDENTITY = UserIdentity.builder()
55     .setProviderLogin("johndoo")
56     .setLogin(USER_LOGIN)
57     .setName("John")
58     .setEmail("john@email.com")
59     .build();
60
61   private static TestIdentityProvider IDENTITY_PROVIDER = new TestIdentityProvider()
62     .setKey("github")
63     .setEnabled(true)
64     .setAllowsUsersToSignUp(true);
65
66   @Rule
67   public ExpectedException thrown = ExpectedException.none();
68
69   @Rule
70   public DbTester db = DbTester.create(new AlwaysIncreasingSystem2());
71
72   private Settings settings = new MapSettings();
73   private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
74   private UserUpdater userUpdater = new UserUpdater(
75     mock(NewUserNotifier.class),
76     settings,
77     db.getDbClient(),
78     mock(UserIndexer.class),
79     System2.INSTANCE,
80     defaultOrganizationProvider);
81   private UserIdentityAuthenticator underTest = new UserIdentityAuthenticator(db.getDbClient(), userUpdater, defaultOrganizationProvider);
82   private GroupDto defaultGroup;
83
84   @Before
85   public void setUp() throws Exception {
86     settings.setProperty("sonar.defaultGroup", DEFAULT_GROUP);
87     defaultGroup = db.users().insertGroup(db.getDefaultOrganization(), DEFAULT_GROUP);
88   }
89
90   @Test
91   public void authenticate_new_user() throws Exception {
92     underTest.authenticate(USER_IDENTITY, IDENTITY_PROVIDER);
93
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");
101
102     assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(defaultGroup.getId());
103   }
104
105   @Test
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");
109
110     authenticate(USER_LOGIN, "group1", "group2", "group3");
111
112     Optional<UserDto> user = db.users().selectUserByLogin(USER_LOGIN);
113     assertThat(user).isPresent();
114
115     assertThat(db.users().selectGroupIdsOfUser(user.get())).containsOnly(group1.getId(), group2.getId());
116   }
117
118   @Test
119   public void authenticate_existing_user() throws Exception {
120     db.users().insertUser(newUserDto()
121       .setLogin(USER_LOGIN)
122       .setActive(true)
123       .setName("Old name")
124       .setEmail("Old email")
125       .setExternalIdentity("old identity")
126       .setExternalIdentityProvider("old provide"));
127
128     underTest.authenticate(USER_IDENTITY, IDENTITY_PROVIDER);
129
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");
136   }
137
138   @Test
139   public void authenticate_existing_disabled_user() throws Exception {
140     db.users().insertUser(newUserDto()
141       .setLogin(USER_LOGIN)
142       .setActive(false)
143       .setName("Old name")
144       .setEmail("Old email")
145       .setExternalIdentity("old identity")
146       .setExternalIdentityProvider("old provide"));
147
148     underTest.authenticate(USER_IDENTITY, IDENTITY_PROVIDER);
149
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");
156   }
157
158   @Test
159   public void authenticate_existing_user_and_add_new_groups() throws Exception {
160     UserDto user = db.users().insertUser(newUserDto()
161       .setLogin(USER_LOGIN)
162       .setActive(true)
163       .setName("John"));
164     GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
165     GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
166
167     authenticate(USER_LOGIN, "group1", "group2", "group3");
168
169     assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(group1.getId(), group2.getId());
170   }
171
172   @Test
173   public void authenticate_existing_user_and_remove_groups() throws Exception {
174     UserDto user = db.users().insertUser(newUserDto()
175       .setLogin(USER_LOGIN)
176       .setActive(true)
177       .setName("John"));
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);
182
183     authenticate(USER_LOGIN, "group1");
184
185     assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(group1.getId());
186   }
187
188   @Test
189   public void authenticate_existing_user_and_remove_all_groups() throws Exception {
190     UserDto user = db.users().insertUser(newUserDto()
191       .setLogin(USER_LOGIN)
192       .setActive(true)
193       .setName("John"));
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);
198
199     authenticate(USER_LOGIN);
200
201     assertThat(db.users().selectGroupIdsOfUser(user)).isEmpty();
202   }
203
204   @Test
205   public void authenticate_new_user_and_add_it_to_no_group_sets_root_flag_to_false() {
206     authenticate(USER_LOGIN);
207
208     db.rootFlag().verify(USER_LOGIN, false);
209   }
210
211   @Test
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());
214
215     authenticate(USER_LOGIN, adminGroup.getName());
216
217     db.rootFlag().verify(USER_LOGIN, true);
218   }
219
220   @Test
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);
224
225     authenticate(USER_LOGIN, adminGroup.getName());
226
227     db.rootFlag().verify(USER_LOGIN, false);
228   }
229
230   @Test
231   public void authenticate_existing_user_and_add_it_to_no_group_sets_root_flag_to_false() {
232     UserDto userDto = db.users().insertUser();
233
234     authenticate(userDto.getLogin());
235
236     db.rootFlag().verify(userDto, false);
237   }
238
239   @Test
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();
243
244     authenticate(userDto.getLogin(), adminGroup.getName());
245
246     db.rootFlag().verify(userDto, true);
247   }
248
249   @Test
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();
254
255     authenticate(userDto.getLogin(), adminGroup.getName());
256
257     db.rootFlag().verify(userDto, false);
258   }
259
260   @Test
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);
265
266     authenticate(userDto.getLogin());
267
268     db.rootFlag().verify(userDto, false);
269   }
270
271   @Test
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();
274
275     authenticate(rootUser.getLogin());
276
277
278     db.rootFlag().verify(rootUser, true);
279   }
280
281   @Test
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();
287
288     authenticate(rootUser.getLogin(), defaultOrgGroup.getName(), otherOrgGroup.getName());
289
290     db.rootFlag().verify(rootUser, true);
291   }
292
293   @Test
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");
300
301     authenticate(USER_LOGIN, defaultAdminGroup.getName(), defaultSomeGroup.getName(), otherAdminGroup.getName(), otherSomeGroup.getName());
302     db.rootFlag().verify(USER_LOGIN, true);
303
304     authenticate(USER_LOGIN, defaultAdminGroup.getName(), defaultSomeGroup.getName(), otherAdminGroup.getName());
305     db.rootFlag().verify(USER_LOGIN, true);
306
307     authenticate(USER_LOGIN, otherAdminGroup.getName(), defaultAdminGroup.getName());
308     db.rootFlag().verify(USER_LOGIN, true);
309
310     authenticate(USER_LOGIN, otherAdminGroup.getName());
311     db.rootFlag().verify(USER_LOGIN, false);
312
313     authenticate(USER_LOGIN, otherAdminGroup.getName(), otherSomeGroup.getName());
314     db.rootFlag().verify(USER_LOGIN, false);
315
316     authenticate(USER_LOGIN, otherAdminGroup.getName(), otherSomeGroup.getName());
317     db.rootFlag().verify(USER_LOGIN, false);
318
319     authenticate(USER_LOGIN, otherAdminGroup.getName(), defaultAdminGroup.getName());
320     db.rootFlag().verify(USER_LOGIN, true);
321
322     authenticate(USER_LOGIN, defaultSomeGroup.getName(), defaultAdminGroup.getName());
323     db.rootFlag().verify(USER_LOGIN, true);
324
325     authenticate(USER_LOGIN, otherSomeGroup.getName(), defaultAdminGroup.getName());
326     db.rootFlag().verify(USER_LOGIN, true);
327
328     authenticate(USER_LOGIN, otherSomeGroup.getName(), defaultSomeGroup.getName());
329     db.rootFlag().verify(USER_LOGIN, false);
330   }
331
332   @Test
333   public void fail_to_authenticate_new_user_when_allow_users_to_signup_is_false() throws Exception {
334     TestIdentityProvider identityProvider = new TestIdentityProvider()
335       .setKey("github")
336       .setName("Github")
337       .setEnabled(true)
338       .setAllowsUsersToSignUp(false);
339
340     thrown.expect(UnauthorizedException.class);
341     thrown.expectMessage("'github' users are not allowed to sign up");
342     underTest.authenticate(USER_IDENTITY, identityProvider);
343   }
344
345   @Test
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")
349       .setActive(true)
350       .setEmail("john@email.com"));
351
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);
356   }
357
358   private void authenticate(String login, String... groups) {
359     underTest.authenticate(UserIdentity.builder()
360       .setProviderLogin("johndoo")
361       .setLogin(login)
362       .setName("John")
363       // No group
364       .setGroups(Arrays.stream(groups).collect(Collectors.toSet()))
365       .build(), IDENTITY_PROVIDER);
366   }
367
368 }