]> source.dussan.org Git - sonarqube.git/blob
97a020eb7fd456bd1dc70f81db52bd6537f13d7e
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2023 SonarSource SA
4  * mailto:info 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.user.ws;
21
22 import org.junit.Rule;
23 import org.junit.Test;
24 import org.sonar.api.config.internal.MapSettings;
25 import org.sonar.auth.ldap.LdapSettingsManager;
26 import org.sonar.db.DbClient;
27 import org.sonar.db.DbSession;
28 import org.sonar.db.DbTester;
29 import org.sonar.db.user.UserDto;
30 import org.sonar.server.authentication.CredentialsLocalAuthentication;
31 import org.sonar.server.authentication.IdentityProviderRepositoryRule;
32 import org.sonar.server.authentication.TestIdentityProvider;
33 import org.sonar.server.es.EsTester;
34 import org.sonar.server.exceptions.ForbiddenException;
35 import org.sonar.server.exceptions.NotFoundException;
36 import org.sonar.server.exceptions.UnauthorizedException;
37 import org.sonar.server.tester.UserSessionRule;
38 import org.sonar.server.user.NewUserNotifier;
39 import org.sonar.server.user.UserUpdater;
40 import org.sonar.server.user.index.UserIndexer;
41 import org.sonar.server.usergroups.DefaultGroupFinder;
42 import org.sonar.server.ws.TestRequest;
43 import org.sonar.server.ws.WsActionTester;
44
45 import static com.google.common.collect.Lists.newArrayList;
46 import static org.assertj.core.api.Assertions.assertThat;
47 import static org.assertj.core.api.Assertions.assertThatThrownBy;
48 import static org.mockito.Mockito.mock;
49 import static org.sonar.db.user.UserTesting.newUserDto;
50
51 public class UpdateIdentityProviderActionIT {
52   private final static String SQ_AUTHORITY = "sonarqube";
53
54   @Rule
55   public IdentityProviderRepositoryRule identityProviderRepository = new IdentityProviderRepositoryRule()
56     .addIdentityProvider(new TestIdentityProvider().setName("Gitlab").setKey("gitlab").setEnabled(true))
57     .addIdentityProvider(new TestIdentityProvider().setName("Github").setKey("github").setEnabled(true));
58
59   @Rule
60   public DbTester db = DbTester.create();
61   @Rule
62   public EsTester es = EsTester.create();
63   @Rule
64   public UserSessionRule userSession = UserSessionRule.standalone().logIn().setSystemAdministrator();
65
66   private final MapSettings settings = new MapSettings().setProperty("sonar.internal.pbkdf2.iterations", "1");
67   private final DbClient dbClient = db.getDbClient();
68   private final DbSession dbSession = db.getSession();
69   private final UserIndexer userIndexer = new UserIndexer(dbClient, es.client());
70   private final CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(dbClient, settings.asConfig());
71
72   private final LdapSettingsManager ldapSettingsManager = mock(LdapSettingsManager.class);
73
74   private final WsActionTester underTest = new WsActionTester(new UpdateIdentityProviderAction(dbClient, identityProviderRepository,
75     new UserUpdater(mock(NewUserNotifier.class), dbClient, userIndexer, new DefaultGroupFinder(db.getDbClient()), settings.asConfig(), null, localAuthentication),
76     userSession));
77
78   @Test
79   public void change_identity_provider_of_a_local_user_all_params() {
80     String userLogin = "login-1";
81     String newExternalLogin = "login@github.com";
82     String newExternalIdentityProvider = "github";
83     createUser(true, userLogin, userLogin, SQ_AUTHORITY);
84     TestRequest request = underTest.newRequest()
85       .setParam("login", userLogin)
86       .setParam("newExternalProvider", newExternalIdentityProvider)
87       .setParam("newExternalIdentity", newExternalLogin);
88
89     request.execute();
90     assertThat(dbClient.userDao().selectByExternalLoginAndIdentityProvider(dbSession, newExternalLogin, newExternalIdentityProvider))
91       .isNotNull()
92       .extracting(UserDto::isLocal, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider)
93       .contains(false, newExternalLogin, newExternalIdentityProvider);
94   }
95
96   @Test
97   public void change_identity_provider_of_a_local_user_mandatory_params_only_provider_login_stays_same() {
98     String userLogin = "login-1";
99     String newExternalIdentityProvider = "github";
100     createUser(true, userLogin, userLogin, SQ_AUTHORITY);
101     TestRequest request = underTest.newRequest()
102       .setParam("login", userLogin)
103       .setParam("newExternalProvider", newExternalIdentityProvider);
104
105     request.execute();
106     assertThat(dbClient.userDao().selectByExternalLoginAndIdentityProvider(dbSession, userLogin, newExternalIdentityProvider))
107       .isNotNull()
108       .extracting(UserDto::isLocal, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider)
109       .contains(false, userLogin, newExternalIdentityProvider);
110   }
111
112   @Test
113   public void change_identity_provider_of_a_external_user_to_new_one() {
114     String userLogin = "login-1";
115     String oldExternalIdentityProvider = "gitlab";
116     String oldExternalIdentity = "john@gitlab.com";
117     createUser(false, userLogin, oldExternalIdentity, oldExternalIdentityProvider);
118
119     String newExternalIdentityProvider = "github";
120     String newExternalIdentity = "john@github.com";
121     TestRequest request = underTest.newRequest()
122       .setParam("login", userLogin)
123       .setParam("newExternalProvider", newExternalIdentityProvider)
124       .setParam("newExternalIdentity", newExternalIdentity);
125
126     request.execute();
127     assertThat(dbClient.userDao().selectByExternalLoginAndIdentityProvider(dbSession, newExternalIdentity, newExternalIdentityProvider))
128       .isNotNull()
129       .extracting(UserDto::isLocal, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider)
130       .contains(false, newExternalIdentity, newExternalIdentityProvider);
131   }
132
133   @Test
134   public void change_identity_provider_of_a_local_user_to_ldap_default_using_sonarqube_as_parameter() {
135     String userLogin = "login-1";
136     String newExternalIdentityProvider = "LDAP_default";
137     createUser(true, userLogin, userLogin, SQ_AUTHORITY);
138     TestRequest request = underTest.newRequest()
139       .setParam("login", userLogin)
140       .setParam("newExternalProvider", "sonarqube");
141
142     request.execute();
143     assertThat(dbClient.userDao().selectByExternalLoginAndIdentityProvider(dbSession, userLogin, newExternalIdentityProvider))
144       .isNotNull()
145       .extracting(UserDto::isLocal, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider)
146       .contains(false, userLogin, newExternalIdentityProvider);
147   }
148
149   @Test
150   public void change_identity_provider_of_a_local_user_to_ldap_default_using_ldap_as_parameter() {
151     String userLogin = "login-1";
152     String newExternalIdentityProvider = "LDAP_default";
153     createUser(true, userLogin, userLogin, SQ_AUTHORITY);
154     TestRequest request = underTest.newRequest()
155       .setParam("login", userLogin)
156       .setParam("newExternalProvider", "LDAP");
157
158     request.execute();
159     assertThat(dbClient.userDao().selectByExternalLoginAndIdentityProvider(dbSession, userLogin, newExternalIdentityProvider))
160       .isNotNull()
161       .extracting(UserDto::isLocal, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider)
162       .contains(false, userLogin, newExternalIdentityProvider);
163   }
164
165   @Test
166   public void change_identity_provider_of_a_local_user_to_ldap_default_using_ldap_server_key_as_parameter() {
167     String userLogin = "login-1";
168     String newExternalIdentityProvider = "LDAP_server42";
169     createUser(true, userLogin, userLogin, SQ_AUTHORITY);
170     TestRequest request = underTest.newRequest()
171       .setParam("login", userLogin)
172       .setParam("newExternalProvider", newExternalIdentityProvider);
173
174     request.execute();
175     assertThat(dbClient.userDao().selectByExternalLoginAndIdentityProvider(dbSession, userLogin, newExternalIdentityProvider))
176       .isNotNull()
177       .extracting(UserDto::isLocal, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider)
178       .contains(false, userLogin, newExternalIdentityProvider);
179   }
180
181   @Test
182   public void fail_if_user_not_exist() {
183     TestRequest request = underTest.newRequest()
184       .setParam("login", "not-existing")
185       .setParam("newExternalProvider", "gitlab");
186
187     assertThatThrownBy(request::execute)
188       .isInstanceOf(NotFoundException.class)
189       .hasMessage("User 'not-existing' doesn't exist");
190   }
191
192   @Test
193   public void fail_if_identity_provider_not_exist() {
194     createUser(true, "login-1", "login-1", SQ_AUTHORITY);
195     TestRequest request = underTest.newRequest()
196       .setParam("login", "login-1")
197       .setParam("newExternalProvider", "not-existing");
198
199     assertThatThrownBy(request::execute)
200       .isInstanceOf(IllegalArgumentException.class)
201       .hasMessage("Value of parameter 'newExternalProvider' (not-existing) must be one of: [github, gitlab] or [LDAP, LDAP_{serverKey}]");
202   }
203
204   @Test
205   public void fail_if_anonymous() {
206     userSession.anonymous();
207     TestRequest request = underTest.newRequest()
208       .setParam("login", "not-existing")
209       .setParam("newExternalProvider", "something");
210
211     assertThatThrownBy(request::execute)
212       .isInstanceOf(UnauthorizedException.class);
213   }
214
215   @Test
216   public void fail_if_not_admin() {
217     userSession.logIn("some-user");
218     TestRequest request = underTest.newRequest()
219       .setParam("login", "not-existing")
220       .setParam("newExternalProvider", "something");
221
222     assertThatThrownBy(request::execute)
223       .isInstanceOf(ForbiddenException.class);
224   }
225
226   private void createUser(boolean local, String login, String externalLogin, String externalIdentityProvider) {
227     UserDto userDto = newUserDto()
228       .setEmail("john@email.com")
229       .setLogin(login)
230       .setName("John")
231       .setScmAccounts(newArrayList("jn"))
232       .setActive(true)
233       .setLocal(local)
234       .setExternalLogin(externalLogin)
235       .setExternalIdentityProvider(externalIdentityProvider);
236     dbClient.userDao().insert(dbSession, userDto);
237     userIndexer.commitAndIndex(dbSession, userDto);
238   }
239
240 }