Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SONAR-6470 New Java WS to show a user's groups
- Loading branch information
1 parent
f7c5f42
commit 912e988
Showing
16 changed files
with
476 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
139 changes: 139 additions & 0 deletions
139
server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* | ||
* SonarQube, open source software quality management tool. | ||
* Copyright (C) 2008-2014 SonarSource | ||
* mailto:contact AT sonarsource DOT com | ||
* | ||
* SonarQube is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 3 of the License, or (at your option) any later version. | ||
* | ||
* SonarQube is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with this program; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
*/ | ||
package org.sonar.server.user.ws; | ||
|
||
import org.sonar.api.server.ws.Request; | ||
import org.sonar.api.server.ws.Response; | ||
import org.sonar.api.server.ws.WebService.NewAction; | ||
import org.sonar.api.server.ws.WebService.NewController; | ||
import org.sonar.api.server.ws.WebService.Param; | ||
import org.sonar.api.utils.Paging; | ||
import org.sonar.api.utils.text.JsonWriter; | ||
import org.sonar.core.persistence.DbSession; | ||
import org.sonar.core.user.GroupMembershipDto; | ||
import org.sonar.core.user.GroupMembershipQuery; | ||
import org.sonar.core.user.UserDto; | ||
import org.sonar.server.db.DbClient; | ||
|
||
import javax.annotation.Nullable; | ||
|
||
import java.util.List; | ||
|
||
public class GroupsAction implements BaseUsersWsAction { | ||
|
||
private static final String PARAM_LOGIN = "login"; | ||
private static final String PARAM_SELECTED = "selected"; | ||
private static final String PARAM_QUERY = "q"; | ||
|
||
private static final String SELECTION_ALL = "all"; | ||
private static final String SELECTION_SELECTED = "selected"; | ||
private static final String SELECTION_DESELECTED = "deselected"; | ||
|
||
private final DbClient dbClient; | ||
|
||
public GroupsAction(DbClient dbClient) { | ||
this.dbClient = dbClient; | ||
} | ||
|
||
@Override | ||
public void define(NewController context) { | ||
NewAction action = context.createAction("groups") | ||
.setDescription("List the groups a user belongs to.") | ||
.setHandler(this) | ||
.setResponseExample(getClass().getResource("example-groups.json")) | ||
.setSince("5.2"); | ||
|
||
action.createParam(PARAM_LOGIN) | ||
.setDescription("A user login") | ||
.setExampleValue("admin") | ||
.setRequired(true); | ||
|
||
action.createParam(PARAM_SELECTED) | ||
.setDescription("If specified, only show groups the user is member of (selected) or not (deselected).") | ||
.setPossibleValues(SELECTION_SELECTED, SELECTION_DESELECTED, SELECTION_ALL) | ||
.setDefaultValue(SELECTION_ALL); | ||
|
||
action.createParam(PARAM_QUERY) | ||
.setDescription("If specified, only show groups whose name contains the query.") | ||
.setExampleValue("user"); | ||
|
||
action.addPagingParams(25); | ||
} | ||
|
||
@Override | ||
public void handle(Request request, Response response) throws Exception { | ||
String login = request.mandatoryParam(PARAM_LOGIN); | ||
int pageSize = request.mandatoryParamAsInt(Param.PAGE_SIZE); | ||
int page = request.mandatoryParamAsInt(Param.PAGE); | ||
String queryString = request.param(PARAM_QUERY); | ||
String selected = request.param(PARAM_SELECTED); | ||
|
||
GroupMembershipQuery query = GroupMembershipQuery.builder() | ||
.login(login) | ||
.groupSearch(queryString) | ||
.membership(getMembership(selected)) | ||
.pageIndex(page) | ||
.pageSize(pageSize) | ||
.build(); | ||
|
||
DbSession session = dbClient.openSession(false); | ||
try { | ||
UserDto user = dbClient.userDao().selectByLogin(session, login); | ||
int total = dbClient.groupMembershipDao().countGroups(session, query, user.getId()); | ||
Paging paging = Paging.create(pageSize, page, total); | ||
List<GroupMembershipDto> groups = dbClient.groupMembershipDao().selectGroups(session, query, user.getId(), paging.offset(), pageSize); | ||
|
||
JsonWriter json = response.newJsonWriter().beginObject(); | ||
writeGroups(json, groups); | ||
writePaging(json, paging); | ||
json.endObject().close(); | ||
} finally { | ||
session.close(); | ||
} | ||
} | ||
|
||
private void writeGroups(JsonWriter json, List<GroupMembershipDto> groups) { | ||
json.name("groups").beginArray(); | ||
for (GroupMembershipDto group : groups) { | ||
json.beginObject() | ||
.prop("name", group.getName()) | ||
.prop("description", group.getDescription()) | ||
.prop("selected", group.getUserId() != null) | ||
.endObject(); | ||
} | ||
json.endArray(); | ||
} | ||
|
||
private void writePaging(JsonWriter json, Paging paging) { | ||
json.prop("p", paging.pageIndex()) | ||
.prop("ps", paging.pageSize()) | ||
.prop("total", paging.total()); | ||
} | ||
|
||
private String getMembership(@Nullable String selected) { | ||
String membership = GroupMembershipQuery.ANY; | ||
if (SELECTION_SELECTED.equals(selected)) { | ||
membership = GroupMembershipQuery.IN; | ||
} else if (SELECTION_DESELECTED.equals(selected)) { | ||
membership = GroupMembershipQuery.OUT; | ||
} | ||
return membership; | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
server/sonar-server/src/main/resources/org/sonar/server/user/ws/example-groups.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"p": 1, | ||
"ps": 25, | ||
"total": 2, | ||
"groups": [ | ||
{"name": "sonar-admins", "description": "Sonar Admins", "selected": false}, | ||
{"name": "sonar-users", "description": "Sonar Users", "selected": true} | ||
] | ||
} |
199 changes: 199 additions & 0 deletions
199
server/sonar-server/src/test/java/org/sonar/server/user/ws/GroupsActionTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
/* | ||
* SonarQube, open source software quality management tool. | ||
* Copyright (C) 2008-2014 SonarSource | ||
* mailto:contact AT sonarsource DOT com | ||
* | ||
* SonarQube is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 3 of the License, or (at your option) any later version. | ||
* | ||
* SonarQube is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with this program; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
*/ | ||
|
||
package org.sonar.server.user.ws; | ||
|
||
import org.junit.After; | ||
import org.junit.Before; | ||
import org.junit.ClassRule; | ||
import org.junit.Test; | ||
import org.sonar.api.server.ws.WebService; | ||
import org.sonar.api.utils.System2; | ||
import org.sonar.core.persistence.DbSession; | ||
import org.sonar.core.persistence.DbTester; | ||
import org.sonar.core.user.GroupDto; | ||
import org.sonar.core.user.GroupMembershipDao; | ||
import org.sonar.core.user.UserDto; | ||
import org.sonar.core.user.UserGroupDto; | ||
import org.sonar.server.db.DbClient; | ||
import org.sonar.server.exceptions.NotFoundException; | ||
import org.sonar.server.user.db.GroupDao; | ||
import org.sonar.server.user.db.UserDao; | ||
import org.sonar.server.user.db.UserGroupDao; | ||
import org.sonar.server.ws.WsTester; | ||
|
||
public class GroupsActionTest { | ||
|
||
@ClassRule | ||
public static final DbTester dbTester = new DbTester(); | ||
|
||
WebService.Controller controller; | ||
|
||
WsTester tester; | ||
|
||
DbClient dbClient; | ||
|
||
DbSession session; | ||
|
||
@Before | ||
public void setUp() throws Exception { | ||
dbTester.truncateTables(); | ||
|
||
System2 system2 = new System2(); | ||
UserDao userDao = new UserDao(dbTester.myBatis(), system2); | ||
GroupDao groupDao = new GroupDao(system2); | ||
UserGroupDao userGroupDao = new UserGroupDao(); | ||
GroupMembershipDao groupMembershipDao = new GroupMembershipDao(dbTester.myBatis()); | ||
|
||
dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), userDao, groupDao, userGroupDao, groupMembershipDao); | ||
session = dbClient.openSession(false); | ||
session.commit(); | ||
|
||
tester = new WsTester(new UsersWs(new GroupsAction(dbClient))); | ||
controller = tester.controller("api/users"); | ||
|
||
} | ||
|
||
@After | ||
public void tearDown() throws Exception { | ||
session.close(); | ||
} | ||
|
||
@Test(expected = NotFoundException.class) | ||
public void fail_on_unknown_user() throws Exception { | ||
tester.newGetRequest("api/users", "groups") | ||
.setParam("login", "john").execute(); | ||
} | ||
|
||
@Test | ||
public void empty_groups() throws Exception { | ||
createUser(); | ||
session.commit(); | ||
|
||
tester.newGetRequest("api/users", "groups") | ||
.setParam("login", "john") | ||
.execute() | ||
.assertJson(getClass(), "empty.json"); | ||
} | ||
|
||
@Test | ||
public void all_groups() throws Exception { | ||
UserDto user = createUser(); | ||
GroupDto usersGroup = createGroup("sonar-users", "Sonar Users"); | ||
createGroup("sonar-admins", "Sonar Admins"); | ||
addUserToGroup(user, usersGroup); | ||
session.commit(); | ||
|
||
tester.newGetRequest("api/users", "groups") | ||
.setParam("login", "john") | ||
.execute() | ||
.assertJson(getClass(), "all.json"); | ||
} | ||
|
||
@Test | ||
public void selected_groups() throws Exception { | ||
UserDto user = createUser(); | ||
GroupDto usersGroup = createGroup("sonar-users", "Sonar Users"); | ||
createGroup("sonar-admins", "Sonar Admins"); | ||
addUserToGroup(user, usersGroup); | ||
session.commit(); | ||
|
||
tester.newGetRequest("api/users", "groups") | ||
.setParam("login", "john") | ||
.setParam("selected", "selected") | ||
.execute() | ||
.assertJson(getClass(), "selected.json"); | ||
} | ||
|
||
@Test | ||
public void deselected_groups() throws Exception { | ||
UserDto user = createUser(); | ||
GroupDto usersGroup = createGroup("sonar-users", "Sonar Users"); | ||
createGroup("sonar-admins", "Sonar Admins"); | ||
addUserToGroup(user, usersGroup); | ||
session.commit(); | ||
|
||
tester.newGetRequest("api/users", "groups") | ||
.setParam("login", "john") | ||
.setParam("selected", "deselected") | ||
.execute() | ||
.assertJson(getClass(), "deselected.json"); | ||
} | ||
|
||
private UserDto createUser() { | ||
return dbClient.userDao().insert(session, new UserDto() | ||
.setActive(true) | ||
.setEmail("john@email.com") | ||
.setLogin("john") | ||
.setName("John") | ||
.setScmAccounts("jn")); | ||
} | ||
|
||
@Test | ||
public void paging() throws Exception { | ||
UserDto user = createUser(); | ||
GroupDto usersGroup = createGroup("sonar-users", "Sonar Users"); | ||
createGroup("sonar-admins", "Sonar Admins"); | ||
addUserToGroup(user, usersGroup); | ||
session.commit(); | ||
|
||
tester.newGetRequest("api/users", "groups") | ||
.setParam("login", "john") | ||
.setParam("ps", "1") | ||
.execute() | ||
.assertJson(getClass(), "all_page1.json"); | ||
|
||
tester.newGetRequest("api/users", "groups") | ||
.setParam("login", "john") | ||
.setParam("ps", "1") | ||
.setParam("p", "2") | ||
.execute() | ||
.assertJson(getClass(), "all_page2.json"); | ||
} | ||
|
||
@Test | ||
public void filtering() throws Exception { | ||
UserDto user = createUser(); | ||
GroupDto usersGroup = createGroup("sonar-users", "Sonar Users"); | ||
createGroup("sonar-admins", "Sonar Admins"); | ||
addUserToGroup(user, usersGroup); | ||
session.commit(); | ||
|
||
tester.newGetRequest("api/users", "groups") | ||
.setParam("login", "john") | ||
.setParam("q", "users") | ||
.execute() | ||
.assertJson(getClass(), "all_users.json"); | ||
|
||
tester.newGetRequest("api/users", "groups") | ||
.setParam("login", "john") | ||
.setParam("q", "admin") | ||
.execute() | ||
.assertJson(getClass(), "all_admin.json"); | ||
} | ||
|
||
private GroupDto createGroup(String name, String description) { | ||
return dbClient.groupDao().insert(session, new GroupDto().setName(name).setDescription(description)); | ||
} | ||
|
||
private void addUserToGroup(UserDto user, GroupDto usersGroup) { | ||
dbClient.userGroupDao().insert(session, new UserGroupDto().setUserId(user.getId()).setGroupId(usersGroup.getId())); | ||
} | ||
} |
Oops, something went wrong.