]> source.dussan.org Git - sonarqube.git/blob
658b74e50aaec0e6072c348ec3f4123962d574aa
[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.usergroups.ws;
21
22 import org.junit.Rule;
23 import org.junit.Test;
24 import org.sonar.api.impl.utils.AlwaysIncreasingSystem2;
25 import org.sonar.api.server.ws.Change;
26 import org.sonar.api.server.ws.WebService.Action;
27 import org.sonar.core.permission.GlobalPermissions;
28 import org.sonar.db.DbTester;
29 import org.sonar.db.user.GroupDto;
30 import org.sonar.db.user.UserDto;
31 import org.sonar.server.exceptions.BadRequestException;
32 import org.sonar.server.exceptions.ForbiddenException;
33 import org.sonar.server.exceptions.NotFoundException;
34 import org.sonar.server.tester.UserSessionRule;
35 import org.sonar.server.usergroups.DefaultGroupFinder;
36 import org.sonar.server.ws.TestRequest;
37 import org.sonar.server.ws.TestResponse;
38 import org.sonar.server.ws.WsActionTester;
39
40 import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
41 import static org.assertj.core.api.Assertions.assertThat;
42 import static org.assertj.core.api.Assertions.assertThatThrownBy;
43 import static org.assertj.core.api.Assertions.tuple;
44 import static org.sonar.db.permission.GlobalPermission.ADMINISTER;
45 import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME;
46 import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_LOGIN;
47
48 public class RemoveUserActionTest {
49
50   @Rule
51   public DbTester db = DbTester.create(new AlwaysIncreasingSystem2());
52   @Rule
53   public UserSessionRule userSession = UserSessionRule.standalone();
54
55   private final WsActionTester ws = new WsActionTester(
56     new RemoveUserAction(db.getDbClient(), userSession, new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient()))));
57
58   @Test
59   public void verify_definition() {
60     Action wsDef = ws.getDef();
61
62     assertThat(wsDef.isInternal()).isFalse();
63     assertThat(wsDef.since()).isEqualTo("5.2");
64     assertThat(wsDef.isPost()).isTrue();
65     assertThat(wsDef.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly(
66       tuple("10.0", "Parameter 'id' is removed. Use 'name' instead."),
67       tuple("8.4", "Parameter 'id' is deprecated. Format changes from integer to string. Use 'name' instead."));
68   }
69
70   @Test
71   public void does_nothing_if_user_is_not_in_group() {
72     // keep an administrator
73     insertAnAdministrator();
74     insertDefaultGroup();
75
76     GroupDto group = db.users().insertGroup("admins");
77     UserDto user = db.users().insertUser("my-admin");
78     loginAsAdmin();
79
80     newRequest()
81       .setParam(PARAM_GROUP_NAME, group.getName())
82       .setParam(PARAM_LOGIN, user.getLogin())
83       .execute();
84
85     assertThat(db.users().selectGroupUuidsOfUser(user)).isEmpty();
86   }
87
88   @Test
89   public void remove_user_by_group_name() {
90     insertAnAdministrator();
91     insertDefaultGroup();
92     GroupDto group = db.users().insertGroup("a_group");
93     UserDto user = db.users().insertUser("a_user");
94     db.users().insertMember(group, user);
95     loginAsAdmin();
96
97     newRequest()
98       .setParam(PARAM_GROUP_NAME, group.getName())
99       .setParam(PARAM_LOGIN, user.getLogin())
100       .execute();
101
102     assertThat(db.users().selectGroupUuidsOfUser(user)).isEmpty();
103   }
104
105   @Test
106   public void remove_user_only_from_one_group() {
107     // keep an administrator
108     insertAnAdministrator();
109     insertDefaultGroup();
110
111     GroupDto users = db.users().insertGroup("user");
112     GroupDto admins = db.users().insertGroup("admins");
113     UserDto user = db.users().insertUser("user");
114     db.users().insertMember(users, user);
115     db.users().insertMember(admins, user);
116     loginAsAdmin();
117
118     newRequest()
119       .setParam(PARAM_GROUP_NAME, admins.getName())
120       .setParam(PARAM_LOGIN, user.getLogin())
121       .execute();
122
123     assertThat(db.users().selectGroupUuidsOfUser(user)).containsOnly(users.getUuid());
124   }
125
126   @Test
127   public void response_status_is_no_content() {
128     // keep an administrator
129     insertAnAdministrator();
130     insertDefaultGroup();
131     GroupDto users = db.users().insertGroup("users");
132     UserDto user = db.users().insertUser("my-admin");
133     db.users().insertMember(users, user);
134     loginAsAdmin();
135
136     TestResponse response = newRequest()
137       .setParam(PARAM_GROUP_NAME, users.getName())
138       .setParam(PARAM_LOGIN, user.getLogin())
139       .execute();
140
141     assertThat(response.getStatus()).isEqualTo(HTTP_NO_CONTENT);
142   }
143
144   @Test
145   public void fail_if_unknown_group() {
146     UserDto user = db.users().insertUser("my-admin");
147     loginAsAdmin();
148     TestRequest request = newRequest()
149       .setParam(PARAM_GROUP_NAME, "unknown")
150       .setParam(PARAM_LOGIN, user.getLogin());
151
152     assertThatThrownBy(request::execute)
153       .isInstanceOf(NotFoundException.class);
154   }
155
156   @Test
157   public void fail_if_unknown_user() {
158     insertDefaultGroup();
159     GroupDto group = db.users().insertGroup("admins");
160     loginAsAdmin();
161     TestRequest request = newRequest()
162       .setParam(PARAM_GROUP_NAME, group.getName())
163       .setParam(PARAM_LOGIN, "my-admin");
164
165     assertThatThrownBy(request::execute)
166       .isInstanceOf(NotFoundException.class);
167   }
168
169   @Test
170   public void throw_ForbiddenException_if_not_administrator() {
171     GroupDto group = db.users().insertGroup("a-group");
172     UserDto user = db.users().insertUser();
173     db.users().insertMember(group, user);
174     userSession.logIn("admin");
175     TestRequest request = newRequest()
176       .setParam(PARAM_GROUP_NAME, group.getName())
177       .setParam(PARAM_LOGIN, user.getLogin());
178
179     assertThatThrownBy(request::execute)
180       .isInstanceOf(ForbiddenException.class)
181       .hasMessage("Insufficient privileges");
182   }
183
184   @Test
185   public void fail_to_remove_the_last_administrator() {
186     db.users().insertDefaultGroup();
187     GroupDto adminGroup = db.users().insertGroup("sonar-admins");
188     db.users().insertPermissionOnGroup(adminGroup, GlobalPermissions.SYSTEM_ADMIN);
189     UserDto adminUser = db.users().insertUser("the-single-admin");
190     db.users().insertMember(adminGroup, adminUser);
191     loginAsAdmin();
192     TestRequest request = newRequest()
193       .setParam(PARAM_GROUP_NAME, adminGroup.getName())
194       .setParam(PARAM_LOGIN, adminUser.getLogin());
195
196     assertThatThrownBy(request::execute)
197       .isInstanceOf(BadRequestException.class)
198       .hasMessage("The last administrator user cannot be removed");
199   }
200
201   @Test
202   public void fail_to_remove_user_from_default_group() {
203     UserDto user = db.users().insertUser();
204     GroupDto defaultGroup = db.users().insertDefaultGroup();
205     db.users().insertMember(defaultGroup, user);
206     loginAsAdmin();
207     TestRequest request = newRequest()
208       .setParam(PARAM_GROUP_NAME, defaultGroup.getName())
209       .setParam(PARAM_LOGIN, user.getLogin());
210
211     assertThatThrownBy(request::execute)
212       .isInstanceOf(IllegalArgumentException.class)
213       .hasMessage("Default group 'sonar-users' cannot be used to perform this action");
214   }
215
216   private TestRequest newRequest() {
217     return ws.newRequest();
218   }
219
220   private void loginAsAdmin() {
221     userSession.logIn("admin").addPermission(ADMINISTER);
222   }
223
224   private void insertAnAdministrator() {
225     db.users().insertAdminByUserPermission();
226   }
227
228   private void insertDefaultGroup() {
229     db.users().insertDefaultGroup();
230   }
231
232 }