]> source.dussan.org Git - sonarqube.git/blob
d3dbecc8fd7b157c6a064df21fa2ffc92cbbbdb0
[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.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;
41
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;
46
47 public class UserIdentityAuthenticatorTest {
48
49   private static String USER_LOGIN = "github-johndoo";
50   private static String DEFAULT_GROUP = "default";
51
52   private static UserIdentity USER_IDENTITY = UserIdentity.builder()
53     .setProviderLogin("johndoo")
54     .setLogin(USER_LOGIN)
55     .setName("John")
56     .setEmail("john@email.com")
57     .build();
58
59   private static TestIdentityProvider IDENTITY_PROVIDER = new TestIdentityProvider()
60     .setKey("github")
61     .setEnabled(true)
62     .setAllowsUsersToSignUp(true);
63
64   @Rule
65   public ExpectedException thrown = ExpectedException.none();
66
67   private System2 system2 = mock(System2.class);
68
69   @Rule
70   public DbTester db = DbTester.create(system2);
71
72   private Settings settings = new MapSettings();
73   private DefaultOrganizationProvider defaultOrganizationProvider = DefaultOrganizationProviderRule.create(db);
74   private UserUpdater userUpdater = new UserUpdater(
75     mock(NewUserNotifier.class),
76     settings,
77     db.getDbClient(),
78     mock(UserIndexer.class),
79     system2,
80     defaultOrganizationProvider);
81   private UserIdentityAuthenticator underTest = new UserIdentityAuthenticator(db.getDbClient(), userUpdater);
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     underTest.authenticate(UserIdentity.builder()
111       .setProviderLogin("johndoo")
112       .setLogin(USER_LOGIN)
113       .setName("John")
114       // group3 doesn't exist in db, it will be ignored
115       .setGroups(newHashSet("group1", "group2", "group3"))
116       .build(), IDENTITY_PROVIDER);
117
118     Optional<UserDto> user = db.users().selectUserByLogin(USER_LOGIN);
119     assertThat(user).isPresent();
120
121     assertThat(db.users().selectGroupIdsOfUser(user.get())).containsOnly(group1.getId(), group2.getId());
122   }
123
124   @Test
125   public void authenticate_existing_user() throws Exception {
126     db.users().insertUser(newUserDto()
127       .setLogin(USER_LOGIN)
128       .setActive(true)
129       .setName("Old name")
130       .setEmail("Old email")
131       .setExternalIdentity("old identity")
132       .setExternalIdentityProvider("old provide"));
133
134     underTest.authenticate(USER_IDENTITY, IDENTITY_PROVIDER);
135
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");
142   }
143
144   @Test
145   public void authenticate_existing_disabled_user() throws Exception {
146     db.users().insertUser(newUserDto()
147       .setLogin(USER_LOGIN)
148       .setActive(false)
149       .setName("Old name")
150       .setEmail("Old email")
151       .setExternalIdentity("old identity")
152       .setExternalIdentityProvider("old provide"));
153
154     underTest.authenticate(USER_IDENTITY, IDENTITY_PROVIDER);
155
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");
162   }
163
164   @Test
165   public void authenticate_existing_user_and_add_new_groups() throws Exception {
166     UserDto user = db.users().insertUser(newUserDto()
167       .setLogin(USER_LOGIN)
168       .setActive(true)
169       .setName("John"));
170     GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
171     GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
172
173     underTest.authenticate(UserIdentity.builder()
174       .setProviderLogin("johndoo")
175       .setLogin(USER_LOGIN)
176       .setName("John")
177       // group3 doesn't exist in db, it will be ignored
178       .setGroups(newHashSet("group1", "group2", "group3"))
179       .build(), IDENTITY_PROVIDER);
180
181     assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(group1.getId(), group2.getId());
182   }
183
184   @Test
185   public void authenticate_existing_user_and_remove_groups() throws Exception {
186     UserDto user = db.users().insertUser(newUserDto()
187       .setLogin(USER_LOGIN)
188       .setActive(true)
189       .setName("John"));
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);
194
195     underTest.authenticate(UserIdentity.builder()
196       .setProviderLogin("johndoo")
197       .setLogin(USER_LOGIN)
198       .setName("John")
199       // Only group1 is returned by the id provider => group2 will be removed
200       .setGroups(newHashSet("group1"))
201       .build(), IDENTITY_PROVIDER);
202
203     assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(group1.getId());
204   }
205
206   @Test
207   public void authenticate_existing_user_and_remove_all_groups() throws Exception {
208     UserDto user = db.users().insertUser(newUserDto()
209       .setLogin(USER_LOGIN)
210       .setActive(true)
211       .setName("John"));
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);
216
217     underTest.authenticate(UserIdentity.builder()
218       .setProviderLogin("johndoo")
219       .setLogin(USER_LOGIN)
220       .setName("John")
221       // No group => group1 and group2 will be removed
222       .setGroups(Collections.emptySet())
223       .build(), IDENTITY_PROVIDER);
224
225     assertThat(db.users().selectGroupIdsOfUser(user)).isEmpty();
226   }
227
228   @Test
229   public void fail_to_authenticate_new_user_when_allow_users_to_signup_is_false() throws Exception {
230     TestIdentityProvider identityProvider = new TestIdentityProvider()
231       .setKey("github")
232       .setName("Github")
233       .setEnabled(true)
234       .setAllowsUsersToSignUp(false);
235
236     thrown.expect(UnauthorizedException.class);
237     thrown.expectMessage("'github' users are not allowed to sign up");
238     underTest.authenticate(USER_IDENTITY, identityProvider);
239   }
240
241   @Test
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")
245       .setActive(true)
246       .setEmail("john@email.com"));
247
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);
252   }
253
254 }