Commit 27bf0c93 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

isMemberOf bugfix

parent 5a8ed6cd
......@@ -110,31 +110,31 @@ public class JWTWebServiceController {
@GetMapping(value = {"/ws/jwt/search/**", "/vo/search/**"}, produces = MediaType.TEXT_PLAIN_VALUE)
public void isMemberOf(HttpServletRequest request, HttpServletResponse response) throws IOException {
String group = getGroupFromRequest(request, "/ws/jwt/search/", "/vo/search/");
List<String> groupNames = groupNameService.extractGroupNames(group);
boolean isMember = membershipManager.isCurrentUserMemberOf("ROOT");
if (!isMember) {
String parentPath = ""; // starting from ROOT
for (String groupName : groupNames) {
Optional<GroupEntity> optionalGroup = groupsDAO.findGroupByParentAndName(parentPath, groupName);
if (optionalGroup.isPresent()) {
GroupEntity groupEntity = optionalGroup.get();
parentPath = groupEntity.getPath();
isMember = membershipManager.isCurrentUserMemberOf(groupEntity.getId());
if (isMember) {
break;
}
} else {
break;
String groupNamesString = getGroupFromRequest(request, "/ws/jwt/search/", "/vo/search/");
List<String> groupNames = groupNameService.extractGroupNames(groupNamesString);
GroupEntity group = null;
String parentPath = ""; // starting from ROOT
for (String groupName : groupNames) {
Optional<GroupEntity> optionalGroup = groupsDAO.findGroupByParentAndName(parentPath, groupName);
if (optionalGroup.isPresent()) {
GroupEntity groupEntity = optionalGroup.get();
parentPath = groupEntity.getPath();
boolean isMember = membershipManager.isCurrentUserMemberOf(groupEntity.getId());
if (isMember) {
group = groupEntity;
}
} else {
group = null;
break;
}
}
if (isMember) {
if (group != null) {
try ( PrintWriter pw = new PrintWriter(response.getOutputStream())) {
pw.println(group);
pw.println(groupNameService.getCompleteName(groupNames));
}
}
// else: empty response (as defined by GMS standard)
......
......@@ -120,18 +120,22 @@ public class MembershipsDAO {
public boolean isMemberOf(String userId, String groupId) {
String sql = "SELECT COUNT(*) FROM gms_membership "
+ " WHERE user_id = ? AND group_id = ?";
String sql = "SELECT COUNT(*)\n"
+ "FROM gms_membership m\n"
+ "JOIN gms_group g ON g.id = m.group_id\n"
+ "JOIN gms_group gs ON g.path @> gs.path\n"
+ "WHERE gs.id = ?\n"
+ "AND m.user_id = ?";
return jdbcTemplate.query(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, userId);
ps.setString(2, groupId);
ps.setString(1, groupId);
ps.setString(2, userId);
return ps;
}, resultSet -> {
resultSet.next();
int count = resultSet.getInt(1);
return count == 1;
return count > 0;
});
}
......
......@@ -157,6 +157,12 @@ public class GroupNameService {
return names;
}
public String getCompleteName(List<String> names) {
return String.join(".", names.stream()
.map(n -> n.replace(".", "\\."))
.collect(Collectors.toList()));
}
private GroupEntity getRoot() {
return groupsDAO.findGroupById("ROOT")
.orElseThrow(() -> new IllegalStateException("Missing root group"));
......
......@@ -115,11 +115,15 @@ public class JWTWebServiceControllerTest {
when(membershipManager.isCurrentUserMemberOf(eq(group3.getId()))).thenReturn(true);
String group = "group\\.1.subgroup.subsubgroup";
String group = "group%5C.1.subgroup.subsubgroup";
mockMvc.perform(get("/ws/jwt/search/" + group).principal(principal))
mockMvc.perform(get("/vo/search/" + group).principal(principal))
.andExpect(status().isOk())
.andExpect(content().string(group + "\n"));
.andExpect(content().string("group\\.1.subgroup.subsubgroup\n"));
mockMvc.perform(get("/vo/search/" + group + "/inexistent").principal(principal))
.andExpect(status().isOk())
.andExpect(content().string(""));
}
@Test
......
......@@ -37,8 +37,8 @@ public class MembershipsDAOTest {
@Test
public void testAddAndRemoveMembers() {
groupsDAO.createGroup(groupEntity("A"));
groupsDAO.createGroup(groupEntity("B"));
groupsDAO.createGroup(groupEntity("A", "A"));
groupsDAO.createGroup(groupEntity("B", "B"));
assertTrue(membershipsDAO.findByGroup("A").isEmpty());
......@@ -72,11 +72,48 @@ public class MembershipsDAOTest {
membershipsDAO.deleteAllGroupsMembership(new ArrayList<>());
}
private GroupEntity groupEntity(String groupId) {
@Test
public void testIsMemberOfRecursive() {
groupsDAO.createGroup(groupEntity("ROOT", ""));
groupsDAO.createGroup(groupEntity("A", "A"));
groupsDAO.createGroup(groupEntity("E", "A.E"));
groupsDAO.createGroup(groupEntity("F", "A.E.F"));
groupsDAO.createGroup(groupEntity("B", "B"));
groupsDAO.createGroup(groupEntity("C", "B.C"));
groupsDAO.createGroup(groupEntity("D", "B.C.D"));
membershipsDAO.addMember(membershipEntity(USER_1, "F"));
membershipsDAO.addMember(membershipEntity(USER_1, "C"));
assertFalse(membershipsDAO.isMemberOf(USER_1, "ROOT"));
assertFalse(membershipsDAO.isMemberOf(USER_1, "A"));
assertFalse(membershipsDAO.isMemberOf(USER_1, "B"));
assertTrue(membershipsDAO.isMemberOf(USER_1, "C"));
assertTrue(membershipsDAO.isMemberOf(USER_1, "D"));
assertFalse(membershipsDAO.isMemberOf(USER_1, "E"));
assertTrue(membershipsDAO.isMemberOf(USER_1, "F"));
membershipsDAO.addMember(membershipEntity(USER_1, "ROOT"));
assertTrue(membershipsDAO.isMemberOf(USER_1, "ROOT"));
assertTrue(membershipsDAO.isMemberOf(USER_1, "A"));
assertTrue(membershipsDAO.isMemberOf(USER_1, "B"));
assertTrue(membershipsDAO.isMemberOf(USER_1, "C"));
assertTrue(membershipsDAO.isMemberOf(USER_1, "D"));
assertTrue(membershipsDAO.isMemberOf(USER_1, "E"));
assertTrue(membershipsDAO.isMemberOf(USER_1, "F"));
assertFalse(membershipsDAO.isMemberOf(USER_1, "inexistent-id"));
}
private GroupEntity groupEntity(String groupId, String groupPath) {
GroupEntity groupEntity = new GroupEntity();
groupEntity.setId(groupId);
groupEntity.setName(groupId);
groupEntity.setPath(groupId);
groupEntity.setPath(groupPath);
groupEntity.setLeaf(false);
return groupEntity;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment