You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GroupsActionTest.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2020 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. import org.junit.Rule;
  22. import org.junit.Test;
  23. import org.junit.rules.ExpectedException;
  24. import org.sonar.api.server.ws.WebService;
  25. import org.sonar.api.server.ws.WebService.Param;
  26. import org.sonar.db.DbTester;
  27. import org.sonar.db.user.GroupDto;
  28. import org.sonar.db.user.UserDto;
  29. import org.sonar.server.exceptions.ForbiddenException;
  30. import org.sonar.server.exceptions.NotFoundException;
  31. import org.sonar.server.tester.UserSessionRule;
  32. import org.sonar.server.usergroups.DefaultGroupFinder;
  33. import org.sonar.server.ws.TestRequest;
  34. import org.sonar.server.ws.WsActionTester;
  35. import org.sonarqube.ws.MediaTypes;
  36. import org.sonarqube.ws.Users.GroupsWsResponse;
  37. import static java.util.Collections.singletonList;
  38. import static org.assertj.core.api.Assertions.assertThat;
  39. import static org.assertj.core.api.Assertions.tuple;
  40. import static org.sonar.api.server.ws.WebService.SelectionMode.ALL;
  41. import static org.sonar.api.server.ws.WebService.SelectionMode.DESELECTED;
  42. import static org.sonar.api.server.ws.WebService.SelectionMode.SELECTED;
  43. import static org.sonar.db.permission.OrganizationPermission.SCAN;
  44. import static org.sonar.db.user.GroupTesting.newGroupDto;
  45. import static org.sonar.db.user.UserTesting.newUserDto;
  46. import static org.sonar.test.JsonAssert.assertJson;
  47. public class GroupsActionTest {
  48. private static final String USER_LOGIN = "john";
  49. @Rule
  50. public ExpectedException expectedException = ExpectedException.none();
  51. @Rule
  52. public DbTester db = DbTester.create();
  53. @Rule
  54. public UserSessionRule userSession = UserSessionRule.standalone().logIn().setRoot();
  55. private WsActionTester ws = new WsActionTester(new GroupsAction(db.getDbClient(), userSession,
  56. new DefaultGroupFinder(db.getDbClient())));
  57. @Test
  58. public void empty_groups() {
  59. insertUser();
  60. insertDefaultGroup();
  61. GroupsWsResponse response = call(ws.newRequest().setParam("login", USER_LOGIN));
  62. assertThat(response.getGroupsList()).isEmpty();
  63. }
  64. @Test
  65. public void return_selected_groups_selected_param_is_set_to_all() {
  66. UserDto user = insertUser();
  67. GroupDto usersGroup = insertDefaultGroup();
  68. GroupDto adminGroup = insertGroup("sonar-admins", "Sonar Admins");
  69. addUserToGroup(user, usersGroup);
  70. GroupsWsResponse response = call(ws.newRequest().setParam("login", USER_LOGIN).setParam(Param.SELECTED, ALL.value()));
  71. assertThat(response.getGroupsList())
  72. .extracting(GroupsWsResponse.Group::getId, GroupsWsResponse.Group::getName, GroupsWsResponse.Group::getDescription, GroupsWsResponse.Group::getSelected)
  73. .containsOnly(
  74. tuple(usersGroup.getUuid(), usersGroup.getName(), usersGroup.getDescription(), true),
  75. tuple(adminGroup.getUuid(), adminGroup.getName(), adminGroup.getDescription(), false));
  76. }
  77. @Test
  78. public void return_selected_groups_selected_param_is_set_to_selected() {
  79. UserDto user = insertUser();
  80. GroupDto usersGroup = insertDefaultGroup();
  81. insertGroup("sonar-admins", "Sonar Admins");
  82. addUserToGroup(user, usersGroup);
  83. GroupsWsResponse response = call(ws.newRequest().setParam("login", USER_LOGIN).setParam(Param.SELECTED, SELECTED.value()));
  84. assertThat(response.getGroupsList())
  85. .extracting(GroupsWsResponse.Group::getId, GroupsWsResponse.Group::getName, GroupsWsResponse.Group::getDescription, GroupsWsResponse.Group::getSelected)
  86. .containsOnly(tuple(usersGroup.getUuid(), usersGroup.getName(), usersGroup.getDescription(), true));
  87. }
  88. @Test
  89. public void return_selected_groups_selected_param_is_not_set() {
  90. UserDto user = insertUser();
  91. GroupDto usersGroup = insertDefaultGroup();
  92. insertGroup("sonar-admins", "Sonar Admins");
  93. addUserToGroup(user, usersGroup);
  94. GroupsWsResponse response = call(ws.newRequest().setParam("login", USER_LOGIN));
  95. assertThat(response.getGroupsList())
  96. .extracting(GroupsWsResponse.Group::getId, GroupsWsResponse.Group::getName, GroupsWsResponse.Group::getDescription, GroupsWsResponse.Group::getSelected)
  97. .containsOnly(tuple(usersGroup.getUuid(), usersGroup.getName(), usersGroup.getDescription(), true));
  98. }
  99. @Test
  100. public void return_not_selected_groups_selected_param_is_set_to_deselected() {
  101. UserDto user = insertUser();
  102. GroupDto usersGroup = insertDefaultGroup();
  103. GroupDto adminGroup = insertGroup("sonar-admins", "Sonar Admins");
  104. addUserToGroup(user, usersGroup);
  105. GroupsWsResponse response = call(ws.newRequest().setParam("login", USER_LOGIN).setParam(Param.SELECTED, DESELECTED.value()));
  106. assertThat(response.getGroupsList())
  107. .extracting(GroupsWsResponse.Group::getId, GroupsWsResponse.Group::getName, GroupsWsResponse.Group::getDescription, GroupsWsResponse.Group::getSelected)
  108. .containsOnly(tuple(adminGroup.getUuid(), adminGroup.getName(), adminGroup.getDescription(), false));
  109. }
  110. @Test
  111. public void search_with_pagination() {
  112. UserDto user = insertUser();
  113. insertDefaultGroup();
  114. for (int i = 1; i <= 9; i++) {
  115. GroupDto groupDto = insertGroup("group-" + i, "group-" + i);
  116. addUserToGroup(user, groupDto);
  117. }
  118. GroupsWsResponse response = call(ws.newRequest().setParam("login", USER_LOGIN)
  119. .setParam(Param.PAGE_SIZE, "3")
  120. .setParam(Param.PAGE, "2")
  121. .setParam(Param.SELECTED, ALL.value()));
  122. assertThat(response.getGroupsList()).extracting(GroupsWsResponse.Group::getName).containsOnly("group-4", "group-5", "group-6");
  123. assertThat(response.getPaging().getPageSize()).isEqualTo(3);
  124. assertThat(response.getPaging().getPageIndex()).isEqualTo(2);
  125. assertThat(response.getPaging().getTotal()).isEqualTo(10);
  126. }
  127. @Test
  128. public void search_by_text_query() {
  129. UserDto user = insertUser();
  130. GroupDto usersGroup = insertDefaultGroup();
  131. GroupDto adminGroup = insertGroup("sonar-admins", "Sonar Admins");
  132. addUserToGroup(user, usersGroup);
  133. assertThat(call(ws.newRequest().setParam("login", USER_LOGIN).setParam("q", "admin").setParam(Param.SELECTED, ALL.value())).getGroupsList())
  134. .extracting(GroupsWsResponse.Group::getName).containsOnly(adminGroup.getName());
  135. assertThat(call(ws.newRequest().setParam("login", USER_LOGIN).setParam("q", "users").setParam(Param.SELECTED, ALL.value())).getGroupsList())
  136. .extracting(GroupsWsResponse.Group::getName).containsOnly(usersGroup.getName());
  137. }
  138. @Test
  139. public void return_default_group_information() {
  140. UserDto user = insertUser();
  141. GroupDto usersGroup = insertDefaultGroup();
  142. GroupDto adminGroup = insertGroup("sonar-admins", "Sonar Admins");
  143. addUserToGroup(user, usersGroup);
  144. GroupsWsResponse response = call(ws.newRequest().setParam("login", USER_LOGIN).setParam(Param.SELECTED, ALL.value()));
  145. assertThat(response.getGroupsList())
  146. .extracting(GroupsWsResponse.Group::getId, GroupsWsResponse.Group::getName, GroupsWsResponse.Group::getDefault)
  147. .containsOnly(
  148. tuple(usersGroup.getUuid(), usersGroup.getName(), true),
  149. tuple(adminGroup.getUuid(), adminGroup.getName(), false));
  150. }
  151. @Test
  152. public void return_groups() {
  153. UserDto user = insertUser();
  154. GroupDto group = db.users().insertDefaultGroup();
  155. addUserToGroup(user, group);
  156. GroupsWsResponse response = call(ws.newRequest()
  157. .setParam("login", USER_LOGIN)
  158. .setParam(Param.SELECTED, ALL.value()));
  159. assertThat(response.getGroupsList())
  160. .extracting(GroupsWsResponse.Group::getId, GroupsWsResponse.Group::getName, GroupsWsResponse.Group::getDescription, GroupsWsResponse.Group::getSelected,
  161. GroupsWsResponse.Group::getDefault)
  162. .containsOnly(tuple(group.getUuid(), group.getName(), group.getDescription(), true, true));
  163. }
  164. @Test
  165. public void fail_when_no_default_group() {
  166. UserDto user = insertUser();
  167. GroupDto group = db.users().insertGroup("group1");
  168. addUserToGroup(user, group);
  169. expectedException.expect(IllegalStateException.class);
  170. expectedException.expectMessage("Default group cannot be found");
  171. call(ws.newRequest().setParam("login", USER_LOGIN));
  172. }
  173. @Test
  174. public void fail_on_unknown_user() {
  175. insertDefaultGroup();
  176. expectedException.expect(NotFoundException.class);
  177. expectedException.expectMessage("Unknown user: john");
  178. call(ws.newRequest().setParam("login", USER_LOGIN));
  179. }
  180. @Test
  181. public void fail_on_disabled_user() {
  182. UserDto userDto = db.users().insertUser(user -> user.setLogin("disabled").setActive(false));
  183. insertDefaultGroup();
  184. expectedException.expect(NotFoundException.class);
  185. expectedException.expectMessage("Unknown user: disabled");
  186. call(ws.newRequest().setParam("login", userDto.getLogin()));
  187. }
  188. @Test
  189. public void fail_when_page_size_is_greater_than_500() {
  190. UserDto user = insertUser();
  191. insertDefaultGroup();
  192. expectedException.expect(IllegalArgumentException.class);
  193. expectedException.expectMessage("The 'ps' parameter must be less than 500");
  194. call(ws.newRequest()
  195. .setParam("login", user.getLogin())
  196. .setParam(Param.PAGE_SIZE, "501"));
  197. }
  198. @Test
  199. public void fail_on_missing_permission() {
  200. userSession.logIn().addPermission(SCAN);
  201. expectedException.expect(ForbiddenException.class);
  202. call(ws.newRequest().setParam("login", USER_LOGIN));
  203. }
  204. @Test
  205. public void fail_when_no_permission() {
  206. userSession.logIn("not-admin");
  207. expectedException.expect(ForbiddenException.class);
  208. call(ws.newRequest().setParam("login", USER_LOGIN));
  209. }
  210. @Test
  211. public void test_json_example() {
  212. UserDto user = insertUser();
  213. GroupDto usersGroup = insertDefaultGroup();
  214. insertGroup("sonar-admins", "Sonar Admins");
  215. addUserToGroup(user, usersGroup);
  216. String response = ws.newRequest()
  217. .setMediaType(MediaTypes.JSON)
  218. .setParam("login", USER_LOGIN)
  219. .setParam(Param.SELECTED, ALL.value())
  220. .setParam(Param.PAGE_SIZE, "25")
  221. .setParam(Param.PAGE, "1")
  222. .execute().getInput();
  223. assertJson(response).ignoreFields("id").isSimilarTo(ws.getDef().responseExampleAsString());
  224. }
  225. @Test
  226. public void verify_definition() {
  227. WebService.Action action = ws.getDef();
  228. assertThat(action.since()).isEqualTo("5.2");
  229. assertThat(action.isPost()).isFalse();
  230. assertThat(action.isInternal()).isFalse();
  231. assertThat(action.responseExampleAsString()).isNotEmpty();
  232. assertThat(action.params()).extracting(Param::key).containsOnly("p", "q", "ps", "login", "selected");
  233. WebService.Param qualifiers = action.param("login");
  234. assertThat(qualifiers.isRequired()).isTrue();
  235. }
  236. private GroupDto insertGroup(String name, String description) {
  237. return db.users().insertGroup(newGroupDto().setName(name).setDescription(description));
  238. }
  239. private GroupDto insertDefaultGroup() {
  240. return db.users().insertDefaultGroup();
  241. }
  242. private void addUserToGroup(UserDto user, GroupDto usersGroup) {
  243. db.users().insertMember(usersGroup, user);
  244. }
  245. private UserDto insertUser() {
  246. return db.users().insertUser(newUserDto()
  247. .setActive(true)
  248. .setEmail("john@email.com")
  249. .setLogin(USER_LOGIN)
  250. .setName("John")
  251. .setScmAccounts(singletonList("jn")));
  252. }
  253. private GroupsWsResponse call(TestRequest request) {
  254. return request.executeProtobuf(GroupsWsResponse.class);
  255. }
  256. }