diff --git a/gms-client/gms-cli/src/main/resources/application.properties b/gms-client/gms-cli/src/main/resources/application.properties deleted file mode 100644 index 2a867fa5f89b8104fe8d51524d699a0d5c9b064f..0000000000000000000000000000000000000000 --- a/gms-client/gms-cli/src/main/resources/application.properties +++ /dev/null @@ -1,2 +0,0 @@ -spring.main.banner-mode=off -logging.level.root=OFF \ No newline at end of file diff --git a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/AddMemberCall.java b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/AddMemberCall.java index 1a414cd9ffe6bdbac43510168d7babe81e6b3134..70bb477eb621127bacf3f24140c33a757da671c5 100644 --- a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/AddMemberCall.java +++ b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/AddMemberCall.java @@ -14,7 +14,7 @@ public class AddMemberCall extends BaseCall<GmsClient> { public boolean addMember(String completeGroupName, String userId) { - String endpoint = "membership"; + String endpoint = "ws/jwt/membership"; if (completeGroupName != null && !completeGroupName.isBlank()) { endpoint += "/" + completeGroupName; } diff --git a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/AddPermissionCall.java b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/AddPermissionCall.java index 01562e6ae9ec574db0ada3bf4257231c7bca3a96..ace30eccf540a97fb56e84fdee2dca5eea1d21a6 100644 --- a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/AddPermissionCall.java +++ b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/AddPermissionCall.java @@ -16,7 +16,7 @@ public class AddPermissionCall extends BaseCall<GmsClient> { public String addPermission(String completeGroupName, String userId, Permission permission) { - String endpoint = "permission"; + String endpoint = "ws/jwt/permission"; if (completeGroupName != null && !completeGroupName.isBlank()) { endpoint += "/" + completeGroupName; } diff --git a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/CreateGroupCall.java b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/CreateGroupCall.java index 1d7a6db5d16a6598f9373cba630ea21e399efdab..edb5158ce23c9027e23f0dea538a61f4a39d8026 100644 --- a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/CreateGroupCall.java +++ b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/CreateGroupCall.java @@ -14,7 +14,7 @@ public class CreateGroupCall extends BaseCall<GmsClient> { public boolean createGroup(String completeGroupName, boolean leaf) { - HttpRequest groupsRequest = client.newRequest(completeGroupName) + HttpRequest groupsRequest = client.newRequest("ws/jwt/" + completeGroupName) .header("Accept", "text/plain") .header("Content-Type", "application/x-www-form-urlencoded") .POST(BodyPublishers.ofString("leaf=" + leaf)) diff --git a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/DeleteGroupCall.java b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/DeleteGroupCall.java index 4b9f0d423d3ffec07886500740c8c8692461b49e..bbde41dc7dfe37f830a3228a13a641b278f5dc23 100644 --- a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/DeleteGroupCall.java +++ b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/DeleteGroupCall.java @@ -13,7 +13,7 @@ public class DeleteGroupCall extends BaseCall<GmsClient> { public boolean deleteGroup(String completeGroupName) { - HttpRequest groupsRequest = client.newRequest(completeGroupName) + HttpRequest groupsRequest = client.newRequest("ws/jwt/" + completeGroupName) .header("Accept", "text/plain") .DELETE() .build(); diff --git a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/GetGroupPermissionsCall.java b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/GetGroupPermissionsCall.java index d4c6838ad8afd04bb4cfd8f8a3ec2feb213b1bd1..5e782d12c0d473c475e0522626fab8cc312da2da 100644 --- a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/GetGroupPermissionsCall.java +++ b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/GetGroupPermissionsCall.java @@ -20,7 +20,7 @@ public class GetGroupPermissionsCall extends BaseCall<GmsClient> { List<GroupPermission> groupPermissions = new ArrayList<>(); - String endpoint = "permission"; + String endpoint = "ws/jwt/permission"; endpoint += "/" + groupId; HttpRequest groupsRequest = client.newRequest(endpoint) diff --git a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/GetUserGroupsCall.java b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/GetUserGroupsCall.java index a2c49348353bb6ec5962fe462c670b8009f80425..a6a4b66438be803b9c0f4b49f5208f427e21bce4 100644 --- a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/GetUserGroupsCall.java +++ b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/GetUserGroupsCall.java @@ -22,7 +22,7 @@ public class GetUserGroupsCall extends BaseCall<GmsClient> { List<String> groups = new ArrayList<>(); - HttpRequest groupsRequest = client.newRequest("search") + HttpRequest groupsRequest = client.newRequest("vo/search") .header("Accept", "text/plain") .GET() .build(); @@ -52,7 +52,7 @@ public class GetUserGroupsCall extends BaseCall<GmsClient> { List<String> groups = new ArrayList<>(); - String endpoint = "membership"; + String endpoint = "ws/jwt/membership"; if (prefix != null && !prefix.isBlank()) { endpoint += "/" + prefix; } diff --git a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/GetUserPermissionsCall.java b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/GetUserPermissionsCall.java index 67aa39adc43c7674082512ada555d91246a3cfbc..8f4e9ed7916d1af0a752321a9fb4797a70181b85 100644 --- a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/GetUserPermissionsCall.java +++ b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/GetUserPermissionsCall.java @@ -20,7 +20,7 @@ public class GetUserPermissionsCall extends BaseCall<GmsClient> { List<UserPermission> userPermissions = new ArrayList<>(); - String endpoint = "permission"; + String endpoint = "ws/jwt/permission"; endpoint += "?user_id=" + userId; HttpRequest groupsRequest = client.newRequest(endpoint) diff --git a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/ListGroupsCall.java b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/ListGroupsCall.java index 4b3411c76a6329df632e4bda00656f87c1d38568..2c3123ef896e211fe76c41fec92224d5030620c6 100644 --- a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/ListGroupsCall.java +++ b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/ListGroupsCall.java @@ -23,7 +23,7 @@ public class ListGroupsCall extends BaseCall<GmsClient> { List<String> groups = new ArrayList<>(); - String uri = "list"; + String uri = "ws/jwt/list"; if (prefix != null && !prefix.isBlank()) { uri += "/" + prefix; } diff --git a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/RemoveMemberCall.java b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/RemoveMemberCall.java index 546ccfeca73b8cce2ae71990501f920c3ca0a434..7daf15ecd214c59a820b8ad03ed071216b01b385 100644 --- a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/RemoveMemberCall.java +++ b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/RemoveMemberCall.java @@ -13,7 +13,7 @@ public class RemoveMemberCall extends BaseCall<GmsClient> { public boolean removeMember(String completeGroupName, String userId) { - String endpoint = "membership"; + String endpoint = "ws/jwt/membership"; if (completeGroupName != null && !completeGroupName.isBlank()) { endpoint += "/" + completeGroupName; } diff --git a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/RemovePermissionCall.java b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/RemovePermissionCall.java index f950614e7b7a0c0c0f2b8726b18cb4a82b92dab2..3602a551cc25a27f31a971a3876b0e108064eec0 100644 --- a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/RemovePermissionCall.java +++ b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/RemovePermissionCall.java @@ -13,7 +13,7 @@ public class RemovePermissionCall extends BaseCall<GmsClient> { public boolean removePermission(String completeGroupName, String userId) { - String endpoint = "permission"; + String endpoint = "ws/jwt/permission"; if (completeGroupName != null && !completeGroupName.isBlank()) { endpoint += "/" + completeGroupName; } diff --git a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/SetPermissionCall.java b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/SetPermissionCall.java index 9f62ebe552efbeb8ecf8f1a39e62cbef2d3619da..97ceb21c0b40fd67ab698ae1bff321a4a060f790 100644 --- a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/SetPermissionCall.java +++ b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/SetPermissionCall.java @@ -14,7 +14,7 @@ public class SetPermissionCall extends BaseCall<GmsClient> { public String setPermission(String completeGroupName, String userId, Permission permission) { - String endpoint = "permission"; + String endpoint = "ws/jwt/permission"; if (completeGroupName != null && !completeGroupName.isBlank()) { endpoint += "/" + completeGroupName; } diff --git a/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/AddMemberTest.java b/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/AddMemberTest.java index 250eec2e5a5f8e4c39d6dc1f5aebc40c5d7ef9bf..268b2f0f957e5908584de13e9b437984b377a8ee 100644 --- a/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/AddMemberTest.java +++ b/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/AddMemberTest.java @@ -28,6 +28,6 @@ public class AddMemberTest extends BaseGmsClientTest { when(httpClient.sendAsync(any(), any())).thenReturn(response); gmsClient.addMember("LBT.INAF", "user"); - verify(httpClient, times(1)).sendAsync(endpointEq("POST", "membership/LBT.INAF"), any()); + verify(httpClient, times(1)).sendAsync(endpointEq("POST", "ws/jwt/membership/LBT.INAF"), any()); } } diff --git a/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/AddPermissionTest.java b/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/AddPermissionTest.java index 04131a84c207cf30cc39245f639bf40c74d2dd41..4c68372d3e8ebdb3e4c62c2ba791145f3556c450 100644 --- a/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/AddPermissionTest.java +++ b/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/AddPermissionTest.java @@ -29,6 +29,6 @@ public class AddPermissionTest extends BaseGmsClientTest { when(httpClient.sendAsync(any(), any())).thenReturn(response); gmsClient.addPermission("LBT.INAF", "user", Permission.ADMIN); - verify(httpClient, times(1)).sendAsync(endpointEq("POST", "permission/LBT.INAF"), any()); + verify(httpClient, times(1)).sendAsync(endpointEq("POST", "ws/jwt/permission/LBT.INAF"), any()); } } diff --git a/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/CreateGroupTest.java b/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/CreateGroupTest.java index dfd3fd0add2552aec3b1a03c4d83898ab3998a35..8c62a3fc3e52fe29fb60a77ddb16f243161e0548 100644 --- a/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/CreateGroupTest.java +++ b/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/CreateGroupTest.java @@ -28,6 +28,6 @@ public class CreateGroupTest extends BaseGmsClientTest { when(httpClient.sendAsync(any(), any())).thenReturn(response); gmsClient.createGroup("LBT.INAF", false); - verify(httpClient, times(1)).sendAsync(endpointEq("POST", "LBT.INAF"), any()); + verify(httpClient, times(1)).sendAsync(endpointEq("POST", "ws/jwt/LBT.INAF"), any()); } } diff --git a/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/DeleteGroupTest.java b/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/DeleteGroupTest.java index dd87b4ea61aa5551ea65d9df0b2d02c3622db748..e5b1161ba230b8c11170ec0b9eb16a4e9cecdb0b 100644 --- a/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/DeleteGroupTest.java +++ b/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/DeleteGroupTest.java @@ -28,6 +28,6 @@ public class DeleteGroupTest extends BaseGmsClientTest { when(httpClient.sendAsync(any(), any())).thenReturn(response); gmsClient.deleteGroup("LBT.INAF"); - verify(httpClient, times(1)).sendAsync(endpointEq("DELETE", "LBT.INAF"), any()); + verify(httpClient, times(1)).sendAsync(endpointEq("DELETE", "ws/jwt/LBT.INAF"), any()); } } diff --git a/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/GetUserGroupsTest.java b/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/GetUserGroupsTest.java index 7741eb4a97dd7811954aec414e60418f3ee849e5..3b2dee689ffc556752cb0af3027803482f97d130 100644 --- a/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/GetUserGroupsTest.java +++ b/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/GetUserGroupsTest.java @@ -34,7 +34,7 @@ public class GetUserGroupsTest extends BaseGmsClientTest { when(httpClient.sendAsync(any(), any())).thenReturn(response); List<String> groups = gmsClient.getMyGroups("LBT."); - verify(httpClient, times(1)).sendAsync(endpointEq("GET", "search"), any()); + verify(httpClient, times(1)).sendAsync(endpointEq("GET", "vo/search"), any()); assertEquals(2, groups.size()); assertEquals("INAF", groups.get(0)); @@ -52,7 +52,7 @@ public class GetUserGroupsTest extends BaseGmsClientTest { when(httpClient.sendAsync(any(), any())).thenReturn(response); List<String> groups = gmsClient.listGroups("LBT."); - verify(httpClient, times(1)).sendAsync(endpointEq("GET", "list/LBT."), any()); + verify(httpClient, times(1)).sendAsync(endpointEq("GET", "ws/jwt/list/LBT."), any()); assertEquals(2, groups.size()); assertEquals("INAF", groups.get(0)); diff --git a/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/RemoveMemberTest.java b/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/RemoveMemberTest.java index 298909eb5d1f485160fd8cf163876511b25fd774..845dbb21087a48ddc68d35a36dfafa95fd18873b 100644 --- a/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/RemoveMemberTest.java +++ b/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/RemoveMemberTest.java @@ -28,6 +28,6 @@ public class RemoveMemberTest extends BaseGmsClientTest { when(httpClient.sendAsync(any(), any())).thenReturn(response); gmsClient.removeMember("LBT.INAF", "user"); - verify(httpClient, times(1)).sendAsync(endpointEq("DELETE", "membership/LBT.INAF?user_id=user"), any()); + verify(httpClient, times(1)).sendAsync(endpointEq("DELETE", "ws/jwt/membership/LBT.INAF?user_id=user"), any()); } } diff --git a/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/RemovePermissionTest.java b/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/RemovePermissionTest.java index d48577c9e1af8b6b9265b07e50e4bd4ebfb82b88..c1a86b0c51085af59139c3f492ad6611c1a5868d 100644 --- a/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/RemovePermissionTest.java +++ b/gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/RemovePermissionTest.java @@ -28,6 +28,6 @@ public class RemovePermissionTest extends BaseGmsClientTest { when(httpClient.sendAsync(any(), any())).thenReturn(response); gmsClient.removePermission("LBT.INAF", "user"); - verify(httpClient, times(1)).sendAsync(endpointEq("DELETE", "permission/LBT.INAF?user_id=user"), any()); + verify(httpClient, times(1)).sendAsync(endpointEq("DELETE", "ws/jwt/permission/LBT.INAF?user_id=user"), any()); } } diff --git a/gms/pom.xml b/gms/pom.xml index 2f599fbbdf941399174822a076d7d14129206bcf..011a3eb4433a5152635ee5cf1be5f21a2d357e1c 100644 --- a/gms/pom.xml +++ b/gms/pom.xml @@ -68,36 +68,46 @@ </dependency> </dependencies> + <profiles> + <profile> + <id>build-gui</id> + <build> + <plugins> + <plugin> + <groupId>com.github.eirslett</groupId> + <artifactId>frontend-maven-plugin</artifactId> + <version>1.7.6</version> + <configuration> + <nodeVersion>v12.6.0</nodeVersion> + <environmentVariables> + <VUE_APP_SHOW_USER_ID_IN_SEARCH>${show.user_id_in_search}</VUE_APP_SHOW_USER_ID_IN_SEARCH> + </environmentVariables> + </configuration> + <executions> + <execution> + <goals> + <goal>install-node-and-npm</goal> + </goals> + </execution> + <execution> + <id>npm install</id> + <goals> + <goal>npm</goal> + </goals> + <configuration> + <arguments>run build --prefix ../gms-ui</arguments> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> + <build> <finalName>gms</finalName> <plugins> - <plugin> - <groupId>com.github.eirslett</groupId> - <artifactId>frontend-maven-plugin</artifactId> - <version>1.7.6</version> - <configuration> - <nodeVersion>v12.6.0</nodeVersion> - <environmentVariables> - <VUE_APP_SHOW_USER_ID_IN_SEARCH>${show.user_id_in_search}</VUE_APP_SHOW_USER_ID_IN_SEARCH> - </environmentVariables> - </configuration> - <executions> - <execution> - <goals> - <goal>install-node-and-npm</goal> - </goals> - </execution> - <execution> - <id>npm install</id> - <goals> - <goal>npm</goal> - </goals> - <configuration> - <arguments>run build --prefix ../gms-ui</arguments> - </configuration> - </execution> - </executions> - </plugin> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.1.0</version> diff --git a/gms/src/main/java/it/inaf/ia2/gms/GmsApplication.java b/gms/src/main/java/it/inaf/ia2/gms/GmsApplication.java index f3f4a5bcab393988d1e053c5e80897e8a73632be..69bcf3d5e839759bc0a4dc65976cec26fb04db62 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/GmsApplication.java +++ b/gms/src/main/java/it/inaf/ia2/gms/GmsApplication.java @@ -16,7 +16,7 @@ public class GmsApplication { public static void main(String[] args) { SpringApplication.run(GmsApplication.class, args); } - + @Bean public RapClient rapClient() { return ServiceLocator.getInstance().getRapClient(); diff --git a/gms/src/main/java/it/inaf/ia2/gms/authn/GmsLoginFilter.java b/gms/src/main/java/it/inaf/ia2/gms/authn/GmsLoginFilter.java index a2a081a693173367e466b070a88378e43943602b..af5000bcdba79cff1d09dfcf334378e0d3277956 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/authn/GmsLoginFilter.java +++ b/gms/src/main/java/it/inaf/ia2/gms/authn/GmsLoginFilter.java @@ -26,6 +26,11 @@ public class GmsLoginFilter extends LoginFilter { private boolean shouldNotFilter(HttpServletRequest request) throws ServletException { + if (request.getUserPrincipal() != null) { + // Principal set using JWT + return true; + } + // Allow CORS check if ("OPTIONS".equals(request.getMethod())) { return true; diff --git a/gms/src/main/java/it/inaf/ia2/gms/authn/JWTFilter.java b/gms/src/main/java/it/inaf/ia2/gms/authn/JWTFilter.java index 6273aed731e85b1c44a8ed7cc4e9deb0c0fb4cb0..f2c047c6cfdd7ae965443cc2c1768f21b9d55752 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/authn/JWTFilter.java +++ b/gms/src/main/java/it/inaf/ia2/gms/authn/JWTFilter.java @@ -1,5 +1,6 @@ package it.inaf.ia2.gms.authn; +import it.inaf.ia2.aa.data.User; import it.inaf.ia2.gms.persistence.LoggingDAO; import it.inaf.ia2.rap.client.RapClient; import java.io.IOException; @@ -13,6 +14,7 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; public class JWTFilter implements Filter { @@ -31,9 +33,21 @@ public class JWTFilter implements Filter { HttpServletResponse response = (HttpServletResponse) res; String authHeader = request.getHeader("Authorization"); + if (authHeader == null) { - loggingDAO.logAction("Attempt to access WS without token", request); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Missing Authorization token"); + + if (request.isRequestedSessionIdValid()) { + HttpSession session = request.getSession(false); + User user = (User) session.getAttribute("user_data"); + if (user != null) { + rapClient.setAccessToken(user.getAccessToken()); + ServletRequestWithSessionPrincipal wrappedRequest = new ServletRequestWithSessionPrincipal(request, user); + fc.doFilter(wrappedRequest, res); + return; + } + } + + fc.doFilter(req, res); return; } @@ -54,9 +68,24 @@ public class JWTFilter implements Filter { fc.doFilter(wrappedRequest, res); } + private static class ServletRequestWithSessionPrincipal extends HttpServletRequestWrapper { + + private final User principal; + + public ServletRequestWithSessionPrincipal(HttpServletRequest request, User user) { + super(request); + this.principal = user; + } + + @Override + public Principal getUserPrincipal() { + return principal; + } + } + private static class ServletRequestWithJWTPrincipal extends HttpServletRequestWrapper { - private final Principal principal; + private final RapPrincipal principal; public ServletRequestWithJWTPrincipal(HttpServletRequest request, Map<String, Object> jwtClaims) { super(request); diff --git a/gms/src/main/java/it/inaf/ia2/gms/authn/SecurityConfig.java b/gms/src/main/java/it/inaf/ia2/gms/authn/SecurityConfig.java index 57df36edd76cbcaf38fb4711bf4cc4b3f2f08c33..b2aa5b75b3a1735abe6c78e7587a91d3eae57658 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/authn/SecurityConfig.java +++ b/gms/src/main/java/it/inaf/ia2/gms/authn/SecurityConfig.java @@ -51,7 +51,7 @@ public class SecurityConfig { public FilterRegistrationBean serviceJWTFilter(LoggingDAO loggingDAO, RapClient rapClient) { FilterRegistrationBean bean = new FilterRegistrationBean(); bean.setFilter(new JWTFilter(loggingDAO, rapClient)); - bean.addUrlPatterns("/ws/jwt/*"); + bean.addUrlPatterns("/*"); bean.setOrder(Ordered.HIGHEST_PRECEDENCE); return bean; } diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsController.java b/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsController.java index fe9137ed62cca9a1d3337718d95fdb967923a464..4bef932ad8648333180f7c8bf2b4a6ada9078879 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsController.java +++ b/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsController.java @@ -1,7 +1,6 @@ package it.inaf.ia2.gms.controller; import com.opencsv.CSVWriter; -import it.inaf.ia2.gms.authn.SessionData; import it.inaf.ia2.gms.manager.GroupStatusManager; import it.inaf.ia2.gms.manager.GroupsManager; import it.inaf.ia2.gms.model.request.AddGroupRequest; @@ -16,6 +15,7 @@ import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.service.GroupsTreeBuilder; import java.io.OutputStream; import java.io.OutputStreamWriter; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; @@ -34,7 +34,7 @@ import org.springframework.web.bind.annotation.RestController; public class GroupsController { @Autowired - private SessionData session; + private HttpServletRequest servletRequest; @Autowired private GroupsManager groupsManager; @@ -96,8 +96,7 @@ public class GroupsController { @GetMapping(value = "/group/status/{groupId}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) public void downloadStatus(@PathVariable("groupId") String groupId, HttpServletResponse response) throws Exception { - try (OutputStream out = response.getOutputStream(); - CSVWriter writer = new CSVWriter(new OutputStreamWriter(out))) { + try ( OutputStream out = response.getOutputStream(); CSVWriter writer = new CSVWriter(new OutputStreamWriter(out))) { writer.writeNext(new String[]{"program", "email"}); @@ -108,6 +107,6 @@ public class GroupsController { } private <T extends PaginatedModelRequest & SearchFilterRequest> PaginatedData<GroupNode> getGroupsPanel(GroupEntity parentGroup, T request) { - return groupsTreeBuilder.listSubGroups(parentGroup, request, session.getUserId()); + return groupsTreeBuilder.listSubGroups(parentGroup, request, servletRequest.getUserPrincipal().getName()); } } diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsTabResponseBuilder.java b/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsTabResponseBuilder.java index 2718b19cd8d586c6fd8ca882b31466a4538f29bb..2da6216a9c827234cdcf4f7e068cda6c49fbd5c7 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsTabResponseBuilder.java +++ b/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsTabResponseBuilder.java @@ -1,6 +1,5 @@ package it.inaf.ia2.gms.controller; -import it.inaf.ia2.gms.authn.SessionData; import it.inaf.ia2.gms.manager.GroupsManager; import it.inaf.ia2.gms.manager.InvitedRegistrationManager; import it.inaf.ia2.gms.manager.PermissionsManager; @@ -10,6 +9,7 @@ import it.inaf.ia2.gms.model.response.GroupsTabResponse; import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.service.GroupsService; import it.inaf.ia2.gms.service.GroupsTreeBuilder; +import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -17,7 +17,7 @@ import org.springframework.stereotype.Component; public class GroupsTabResponseBuilder { @Autowired - private SessionData session; + HttpServletRequest servletRequest; @Autowired private PermissionsManager permissionsManager; @@ -46,7 +46,7 @@ public class GroupsTabResponseBuilder { Permission permission = permissionsManager.getCurrentUserPermission(group); response.setPermission(permission); - response.setGroupsPanel(groupsListBuilder.listSubGroups(group, request, session.getUserId())); + response.setGroupsPanel(groupsListBuilder.listSubGroups(group, request, servletRequest.getUserPrincipal().getName())); response.setLeaf(group.isLeaf()); diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/JWTWebServiceController.java b/gms/src/main/java/it/inaf/ia2/gms/controller/JWTWebServiceController.java index 22ce42638c8767c29c72f1ee8e4147e1652ca164..554d4437ef63752fda45efd5468b6cf01dc0b355 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/controller/JWTWebServiceController.java +++ b/gms/src/main/java/it/inaf/ia2/gms/controller/JWTWebServiceController.java @@ -39,15 +39,16 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** - * Web service called by other web applications using JWT (delegation). + * This class needs some refactoring: it contains all endpoints that used JWT. + * Now all endpoints accept both a JWT token or a session, so some of them could + * be removed and others should be moved on dedicated classes. Some endpoints + * match 2 patters to achieve a smooth transition. */ @RestController -@RequestMapping("/ws/jwt") public class JWTWebServiceController { @Autowired @@ -63,7 +64,7 @@ public class JWTWebServiceController { private GroupsService groupsService; @Autowired - private GroupNameService groupNameService; + protected GroupNameService groupNameService; @Autowired private MembershipManager membershipManager; @@ -83,7 +84,7 @@ public class JWTWebServiceController { /** * This endpoint is compliant with the IVOA GMS standard. */ - @GetMapping(value = "/search", produces = MediaType.TEXT_PLAIN_VALUE) + @GetMapping(value = {"/ws/jwt/search", "/vo/search"}, produces = MediaType.TEXT_PLAIN_VALUE) public void getGroups(HttpServletResponse response) throws IOException { List<GroupEntity> memberships = membershipManager.getCurrentUserMemberships(); @@ -104,10 +105,10 @@ public class JWTWebServiceController { * be defined adding ".+", otherwise Spring will think it is a file * extension (thanks https://stackoverflow.com/a/16333149/771431) */ - @GetMapping(value = "/search/{group:.+}", produces = MediaType.TEXT_PLAIN_VALUE) + @GetMapping(value = {"/ws/jwt/search/{group:.+}", "/vo/search/{group:.+}"}, produces = MediaType.TEXT_PLAIN_VALUE) public void isMemberOf(@PathVariable("group") String group, HttpServletResponse response) throws IOException { - List<String> groupNames = extractGroupNames(group); + List<String> groupNames = groupNameService.extractGroupNames(group); boolean isMember = membershipManager.isCurrentUserMemberOf("ROOT"); if (!isMember) { @@ -135,13 +136,12 @@ public class JWTWebServiceController { // else: empty response (as defined by GMS standard) } - @GetMapping(value = {"/list/{group:.+}", "/list"}, produces = MediaType.TEXT_PLAIN_VALUE) - public void listGroups(@PathVariable("group") Optional<String> group, Principal principal, HttpServletResponse response) throws IOException { + @GetMapping(value = {"/ws/jwt/list/{group:.+}", "/ws/jwt/list"}, produces = MediaType.TEXT_PLAIN_VALUE) + public void listGroups(@PathVariable("group") Optional<String> groupNames, Principal principal, HttpServletResponse response) throws IOException { String userId = principal.getName(); - List<String> groupNames = extractGroupNames(group); - GroupEntity parentGroup = getGroupFromNames(groupNames); + GroupEntity parentGroup = groupNameService.getGroupFromNames(groupNames); List<GroupEntity> allSubGroups = groupsDAO.getDirectSubGroups(parentGroup.getPath()); @@ -157,7 +157,7 @@ public class JWTWebServiceController { try ( PrintWriter pw = new PrintWriter(response.getOutputStream())) { for (String groupName : groupNameService.getGroupsNames(visibleSubgroups)) { - pw.println(getShortGroupName(groupName, group)); + pw.println(groupNameService.getShortGroupName(groupName, groupNames)); } } } @@ -166,10 +166,10 @@ public class JWTWebServiceController { * Creates a group and its ancestors if they are missing. It doesn't fail if * the last group already exists. */ - @PostMapping(value = "/{group:.+}", produces = MediaType.TEXT_PLAIN_VALUE) + @PostMapping(value = "/ws/jwt/{group:.+}", produces = MediaType.TEXT_PLAIN_VALUE) public void createGroup(@PathVariable("group") String groupParam, HttpServletRequest request, HttpServletResponse response) throws IOException { - List<String> groupNames = extractGroupNames(groupParam); + List<String> groupNames = groupNameService.extractGroupNames(groupParam); String leafParam = request.getParameter("leaf"); boolean leaf = leafParam == null ? false : Boolean.valueOf(leafParam); @@ -191,29 +191,29 @@ public class JWTWebServiceController { } } - @DeleteMapping(value = "/{group:.+}", produces = MediaType.TEXT_PLAIN_VALUE) + @DeleteMapping(value = "/ws/jwt/{group:.+}", produces = MediaType.TEXT_PLAIN_VALUE) public void deleteGroup(@PathVariable("group") String groupParam, HttpServletResponse response) { - GroupEntity group = getGroupFromNames(extractGroupNames(groupParam)); + GroupEntity group = groupNameService.getGroupFromNames(Optional.of(groupParam)); groupsDAO.deleteGroup(group); response.setStatus(HttpServletResponse.SC_NO_CONTENT); } - @GetMapping(value = {"/membership/{group:.+}", "/membership"}, produces = MediaType.TEXT_PLAIN_VALUE) - public void getMembership(@PathVariable("group") Optional<String> group, @RequestParam("user_id") String userId, HttpServletResponse response) throws IOException { + @GetMapping(value = {"/ws/jwt/membership/{group:.+}", "/ws/jwt/membership"}, produces = MediaType.TEXT_PLAIN_VALUE) + public void getMembership(@PathVariable("group") Optional<String> groupNames, @RequestParam("user_id") String userId, HttpServletResponse response) throws IOException { - GroupEntity parent = getGroupFromNames(extractGroupNames(group)); + GroupEntity parent = groupNameService.getGroupFromNames(groupNames); List<GroupEntity> groups = membershipManager.getUserGroups(parent, userId); try ( PrintWriter pw = new PrintWriter(response.getOutputStream())) { for (String groupName : groupNameService.getGroupsNames(groups)) { - pw.println(getShortGroupName(groupName, group)); + pw.println(groupNameService.getShortGroupName(groupName, groupNames)); } } } - @PostMapping(value = {"/membership/{group:.+}", "/membership"}, produces = MediaType.TEXT_PLAIN_VALUE) - public void addMember(@PathVariable("group") Optional<String> group, HttpServletRequest request, HttpServletResponse response) throws IOException { + @PostMapping(value = {"/ws/jwt/membership/{group:.+}", "/ws/jwt/membership"}, produces = MediaType.TEXT_PLAIN_VALUE) + public void addMember(@PathVariable("group") Optional<String> groupNames, HttpServletRequest request, HttpServletResponse response) throws IOException { String targetUserId = request.getParameter("user_id"); if (targetUserId == null) { @@ -221,25 +221,25 @@ public class JWTWebServiceController { return; } - GroupEntity groupEntity = getGroupFromNames(extractGroupNames(group)); + GroupEntity groupEntity = groupNameService.getGroupFromNames(groupNames); membershipManager.addMember(groupEntity, targetUserId); } - @DeleteMapping(value = {"/membership/{group:.+}", "/membership"}, produces = MediaType.TEXT_PLAIN_VALUE) - public void removeMember(@PathVariable("group") Optional<String> group, @RequestParam("user_id") String userId, + @DeleteMapping(value = {"/ws/jwt/membership/{group:.+}", "/ws/jwt/membership"}, produces = MediaType.TEXT_PLAIN_VALUE) + public void removeMember(@PathVariable("group") Optional<String> groupNames, @RequestParam("user_id") String userId, HttpServletRequest request, HttpServletResponse response) throws IOException { - GroupEntity groupEntity = getGroupFromNames(extractGroupNames(group)); + GroupEntity groupEntity = groupNameService.getGroupFromNames(groupNames); membershipManager.removeMember(groupEntity, userId); response.setStatus(HttpServletResponse.SC_NO_CONTENT); } - @GetMapping(value = {"/permission/{group:.+}", "/permission"}, produces = MediaType.TEXT_PLAIN_VALUE) + @GetMapping(value = {"/ws/jwt/permission/{group:.+}", "/ws/jwt/permission"}, produces = MediaType.TEXT_PLAIN_VALUE) public void getUserPermission(@PathVariable("group") Optional<String> groupNames, @RequestParam("user_id") Optional<String> userId, HttpServletRequest request, HttpServletResponse response) throws IOException { - GroupEntity groupEntity = getGroupFromNames(extractGroupNames(groupNames)); + GroupEntity groupEntity = groupNameService.getGroupFromNames(groupNames); if (userId.isPresent()) { try ( PrintWriter pw = new PrintWriter(response.getOutputStream())) { for (UserPermission userPermission : searchService.getUserPermission(groupEntity, userId.get(), permissionsManager.getCurrentUserPermissions(groupEntity))) { @@ -249,36 +249,36 @@ public class JWTWebServiceController { } } else { try ( PrintWriter pw = new PrintWriter(response.getOutputStream())) { - for (it.inaf.ia2.gms.model.UserPermission up : permissionsManager.getAllPermissions(groupEntity)) { + for (it.inaf.ia2.gms.model.RapUserPermission up : permissionsManager.getAllPermissions(groupEntity)) { pw.println(up.getUser().getId() + " " + up.getPermission()); } } } } - @PostMapping(value = {"/permission/{group:.+}", "/permission/"}, produces = MediaType.TEXT_PLAIN_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + @PostMapping(value = {"/ws/jwt/permission/{group:.+}", "/ws/jwt/permission/"}, produces = MediaType.TEXT_PLAIN_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) public void addPermission(@PathVariable("group") Optional<String> groupNames, @RequestParam("user_id") String targetUserId, @RequestParam("permission") Permission permission) throws IOException { - GroupEntity groupEntity = getGroupFromNames(extractGroupNames(groupNames)); + GroupEntity groupEntity = groupNameService.getGroupFromNames(groupNames); permissionsManager.addPermission(groupEntity, targetUserId, permission); } - @PutMapping(value = {"/permission/{group:.+}", "/permission/"}, produces = MediaType.TEXT_PLAIN_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + @PutMapping(value = {"/ws/jwt/permission/{group:.+}", "/ws/jwt/permission/"}, produces = MediaType.TEXT_PLAIN_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) public void setPermission(@PathVariable("group") Optional<String> groupNames, @RequestParam("user_id") String targetUserId, @RequestParam("permission") Permission permission) throws IOException { - GroupEntity groupEntity = getGroupFromNames(extractGroupNames(groupNames)); + GroupEntity groupEntity = groupNameService.getGroupFromNames(groupNames); permissionsManager.createOrUpdatePermission(groupEntity, targetUserId, permission); } - @DeleteMapping(value = {"/permission/{group:.+}", "/permission/"}, produces = MediaType.TEXT_PLAIN_VALUE) + @DeleteMapping(value = {"/ws/jwt/permission/{group:.+}", "/ws/jwt/permission/"}, produces = MediaType.TEXT_PLAIN_VALUE) public void removePermission(@PathVariable("group") Optional<String> groupNames, @RequestParam("user_id") String userId, HttpServletRequest request, HttpServletResponse response) throws IOException { - GroupEntity groupEntity = getGroupFromNames(extractGroupNames(groupNames)); + GroupEntity groupEntity = groupNameService.getGroupFromNames(groupNames); permissionsManager.removePermission(groupEntity, userId); response.setStatus(HttpServletResponse.SC_NO_CONTENT); } - @GetMapping(value = "/check-invited-registration", produces = MediaType.TEXT_PLAIN_VALUE) + @GetMapping(value = {"/ws/jwt/check-invited-registration", "/check-invited-registration"}, produces = MediaType.TEXT_PLAIN_VALUE) public void completeInvitedRegistrationIfNecessary(Principal principal, HttpServletResponse response) throws IOException { String userId = principal.getName(); @@ -300,7 +300,7 @@ public class JWTWebServiceController { } } - @PostMapping(value = "/invited-registration", produces = MediaType.TEXT_PLAIN_VALUE) + @PostMapping(value = {"/ws/jwt/invited-registration", "/invited-registration"}, produces = MediaType.TEXT_PLAIN_VALUE) public void addInvitedRegistration(@RequestParam("token_hash") String tokenHash, @RequestParam("email") String email, @RequestParam("groups") String groupNamesAndPermissionsParam, HttpServletResponse response) { @@ -311,7 +311,7 @@ public class JWTWebServiceController { int lastSpaceIndex = param.lastIndexOf(" "); String groupName = param.substring(0, lastSpaceIndex); Permission permission = Permission.valueOf(param.substring(lastSpaceIndex + 1)); - GroupEntity groupEntity = getGroupFromNames(extractGroupNames(groupName)); + GroupEntity groupEntity = groupNameService.getGroupFromNames(Optional.of(groupName)); groupsPermissions.put(groupEntity, permission); } } @@ -321,10 +321,10 @@ public class JWTWebServiceController { response.setStatus(HttpServletResponse.SC_CREATED); } - @GetMapping(value = "/email/{group:.+}", produces = MediaType.TEXT_PLAIN_VALUE) + @GetMapping(value = {"/ws/jwt/email/{group:.+}", "/email/{group:.+}"}, produces = MediaType.TEXT_PLAIN_VALUE) public void getEmailOfMembers(@PathVariable("group") String groupNames, @RequestParam("permission") Optional<Permission> permission, HttpServletResponse response) throws IOException { - GroupEntity groupEntity = getGroupFromNames(extractGroupNames(groupNames)); + GroupEntity groupEntity = groupNameService.getGroupFromNames(Optional.of(groupNames)); Set<String> selectedUserIds = null; if (permission.isPresent()) { @@ -346,68 +346,7 @@ public class JWTWebServiceController { } } - private GroupEntity getGroupFromNames(List<String> groupNames) { - if (groupNames.isEmpty()) { - return getRoot(); - } - return getGroupFromNamesAndIndex(groupNames, groupNames.size() - 1); - } - - private GroupEntity getGroupFromNamesAndIndex(List<String> groupNames, int index) { - String parentPath = ""; // starting from ROOT - GroupEntity group = null; - for (int i = 0; i < index + 1; i++) { - String groupName = groupNames.get(i); - group = groupsDAO.findGroupByParentAndName(parentPath, groupName) - .orElseThrow(() -> new BadRequestException("Unable to find group " + groupName)); - parentPath = group.getPath(); - } - if (group == null) { - throw new IllegalStateException(); - } - return group; - } - - private GroupEntity getRoot() { - return groupsDAO.findGroupById("ROOT") - .orElseThrow(() -> new IllegalStateException("Missing root group")); - } - - private List<String> extractGroupNames(Optional<String> group) { - return extractGroupNames(group.orElse(null)); - } - - private List<String> extractGroupNames(String groupStr) { - - if (groupStr == null || groupStr.isEmpty()) { - return new ArrayList<>(); - } - - List<String> names = new ArrayList<>(); - String currentName = ""; - for (int i = 0; i < groupStr.length(); i++) { - char c = groupStr.charAt(i); - // dot is the group separator and it must be escaped if used inside - // group names - if (c == '.' && groupStr.charAt(i - 1) != '\\') { - names.add(currentName.replace("\\.", ".")); - currentName = ""; - } else { - currentName += c; - } - } - names.add(currentName); - return names; - } - - private String getShortGroupName(String completeGroupName, Optional<String> groupPrefix) { - if (groupPrefix.isPresent()) { - return completeGroupName.substring(groupPrefix.get().length() + 1); - } - return completeGroupName; - } - - @PostMapping(value = "/join", produces = MediaType.APPLICATION_JSON_VALUE) + @PostMapping(value = {"/ws/jwt/join", "/join"}, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<?> join(RapPrincipal principal) { String fromUser = principal.getName(); diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/PermissionsController.java b/gms/src/main/java/it/inaf/ia2/gms/controller/PermissionsController.java index 9742396d930bb9bc279952e7c10f2661a78edbc0..84e3faf3a5063af96e787b1f33ecdacf13854066 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/controller/PermissionsController.java +++ b/gms/src/main/java/it/inaf/ia2/gms/controller/PermissionsController.java @@ -1,5 +1,6 @@ package it.inaf.ia2.gms.controller; +import it.inaf.ia2.gms.exception.BadRequestException; import it.inaf.ia2.gms.manager.GroupsManager; import it.inaf.ia2.gms.manager.PermissionsManager; import it.inaf.ia2.gms.model.request.AddPermissionRequest; @@ -7,15 +8,20 @@ import it.inaf.ia2.gms.model.request.MemberRequest; import it.inaf.ia2.gms.model.response.PaginatedData; import it.inaf.ia2.gms.model.request.PaginatedModelRequest; import it.inaf.ia2.gms.model.Permission; -import it.inaf.ia2.gms.model.UserPermission; +import it.inaf.ia2.gms.model.RapUserPermission; import it.inaf.ia2.gms.model.request.TabRequest; import it.inaf.ia2.gms.model.request.UpdatePermissionRequest; +import it.inaf.ia2.gms.model.response.UserPermission; import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.persistence.model.PermissionEntity; +import it.inaf.ia2.gms.service.GroupNameService; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -39,10 +45,10 @@ public class PermissionsController { private PermissionsManager permissionsManager; @GetMapping(value = "/permissions", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity<PaginatedData<UserPermission>> getPermissionsTab(TabRequest request) { + public ResponseEntity<PaginatedData<RapUserPermission>> getPermissionsTab(TabRequest request) { GroupEntity group = groupsManager.getGroupById(request.getGroupId()); - PaginatedData<UserPermission> permissionsPanel = getPermissionsPanel(group, request); + PaginatedData<RapUserPermission> permissionsPanel = getPermissionsPanel(group, request); return ResponseEntity.ok(permissionsPanel); } @@ -63,7 +69,7 @@ public class PermissionsController { } @PostMapping(value = "/permission", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity<PaginatedData<UserPermission>> addPermission(@Valid @RequestBody AddPermissionRequest request) { + public ResponseEntity<PaginatedData<RapUserPermission>> addPermission(@Valid @RequestBody AddPermissionRequest request) { GroupEntity group = groupsManager.getGroupById(request.getGroupId()); if (request.isOverride()) { @@ -88,7 +94,7 @@ public class PermissionsController { } @DeleteMapping(value = "/permission", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity<PaginatedData<UserPermission>> deletePermission(@Valid MemberRequest request) { + public ResponseEntity<PaginatedData<RapUserPermission>> deletePermission(@Valid MemberRequest request) { GroupEntity group = groupsManager.getGroupById(request.getGroupId()); permissionsManager.removePermission(group, request.getUserId()); @@ -96,8 +102,8 @@ public class PermissionsController { return ResponseEntity.ok(getPermissionsPanel(group, request)); } - private PaginatedData<UserPermission> getPermissionsPanel(GroupEntity group, PaginatedModelRequest request) { - List<UserPermission> permissions = permissionsManager.getAllPermissions(group); + private PaginatedData<RapUserPermission> getPermissionsPanel(GroupEntity group, PaginatedModelRequest request) { + List<RapUserPermission> permissions = permissionsManager.getAllPermissions(group); Collections.sort(permissions, (p1, p2) -> { return p1.getUser().getDisplayName().compareTo(p2.getUser().getDisplayName()); }); diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/SearchController.java b/gms/src/main/java/it/inaf/ia2/gms/controller/SearchController.java index 46ec4842a75fd7d3035016dfe9ba3cfd22b57096..a7fcc04bd49d13e89763ad95920004261b1d32b6 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/controller/SearchController.java +++ b/gms/src/main/java/it/inaf/ia2/gms/controller/SearchController.java @@ -1,10 +1,10 @@ package it.inaf.ia2.gms.controller; -import it.inaf.ia2.gms.authn.SessionData; import it.inaf.ia2.gms.model.response.PaginatedData; import it.inaf.ia2.gms.model.response.SearchResponseItem; import it.inaf.ia2.gms.model.response.UserSearchResponse; import it.inaf.ia2.gms.service.SearchService; +import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -17,7 +17,7 @@ import org.springframework.web.bind.annotation.RestController; public class SearchController { @Autowired - private SessionData sessionData; + private HttpServletRequest servletRequest; @Autowired private SearchService searchService; @@ -26,14 +26,14 @@ public class SearchController { public ResponseEntity<PaginatedData<SearchResponseItem>> getSearchResults(@RequestParam("query") String query, @RequestParam("page") int page, @RequestParam("pageSize") int pageSize) { - PaginatedData<SearchResponseItem> response = searchService.search(query, sessionData.getUserId(), page, pageSize); + PaginatedData<SearchResponseItem> response = searchService.search(query, servletRequest.getUserPrincipal().getName(), page, pageSize); return ResponseEntity.ok(response); } @GetMapping(value = "/search/user/{userId}", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<UserSearchResponse> getSearchResultUser(@PathVariable("userId") String userId) { - UserSearchResponse response = searchService.getUserSearchResult(sessionData.getUserId(), userId); + UserSearchResponse response = searchService.getUserSearchResult(servletRequest.getUserPrincipal().getName(), userId); return ResponseEntity.ok(response); } } diff --git a/gms/src/main/java/it/inaf/ia2/gms/manager/InvitedRegistrationManager.java b/gms/src/main/java/it/inaf/ia2/gms/manager/InvitedRegistrationManager.java index 82dace994e99bd7ca7a5a0bf76e717ff7575a00d..7c9525d7e3ed319fb3c996df5e1c23ddc466369a 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/manager/InvitedRegistrationManager.java +++ b/gms/src/main/java/it/inaf/ia2/gms/manager/InvitedRegistrationManager.java @@ -26,6 +26,7 @@ import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -54,7 +55,7 @@ public class InvitedRegistrationManager extends UserAwareComponent { private RapClient rapClient; @Autowired - private SessionData sessionData; + private HttpServletRequest servletRequest; @Autowired private LoggingDAO loggingDAO; @@ -104,7 +105,7 @@ public class InvitedRegistrationManager extends UserAwareComponent { public Optional<List<InvitedRegistration>> completeInvitedRegistrationIfNecessary() { - List<InvitedRegistration> invitedRegistrations = completeInvitedRegistrationIfNecessary(sessionData.getUserId()); + List<InvitedRegistration> invitedRegistrations = completeInvitedRegistrationIfNecessary(servletRequest.getUserPrincipal().getName()); InvitedRegistration invitedRegistrationFromToken = (InvitedRegistration) httpSession.getAttribute(INVITED_REGISTRATION); diff --git a/gms/src/main/java/it/inaf/ia2/gms/manager/PermissionsManager.java b/gms/src/main/java/it/inaf/ia2/gms/manager/PermissionsManager.java index 4fd1bdfef3ba6afafcbc3a97b69dd7ba4db18154..00a254533c3198b68fa9773ed5dc48218b9aba91 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/manager/PermissionsManager.java +++ b/gms/src/main/java/it/inaf/ia2/gms/manager/PermissionsManager.java @@ -2,7 +2,7 @@ package it.inaf.ia2.gms.manager; import it.inaf.ia2.gms.exception.UnauthorizedException; import it.inaf.ia2.gms.model.Permission; -import it.inaf.ia2.gms.model.UserPermission; +import it.inaf.ia2.gms.model.RapUserPermission; import it.inaf.ia2.gms.persistence.LoggingDAO; import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.persistence.model.PermissionEntity; @@ -34,7 +34,7 @@ public class PermissionsManager extends UserAwareComponent { this.loggingDAO = loggingDAO; } - public List<UserPermission> getAllPermissions(GroupEntity group) { + public List<RapUserPermission> getAllPermissions(GroupEntity group) { verifyUserCanManagePermissions(group); @@ -47,12 +47,12 @@ public class PermissionsManager extends UserAwareComponent { Map<String, RapUser> users = rapClient.getUsers(userIdentifiers).stream() .collect(Collectors.toMap(RapUser::getId, Function.identity())); - List<UserPermission> result = new ArrayList<>(); + List<RapUserPermission> result = new ArrayList<>(); for (PermissionEntity p : permissions) { RapUser rapUser = users.get(p.getUserId()); if (rapUser != null) { - UserPermission permission = new UserPermission(); + RapUserPermission permission = new RapUserPermission(); permission.setPermission(p.getPermission()); permission.setUser(rapUser); result.add(permission); @@ -117,6 +117,11 @@ public class PermissionsManager extends UserAwareComponent { } } + public List<PermissionEntity> findUserPermissions(GroupEntity group, String userId) { + verifyUserCanManagePermissions(group); + return permissionsService.findUserPermissions(group, userId); + } + public Permission getUserPermission(GroupEntity group, String userId) { return getUserPermission(group, userId, true); } diff --git a/gms/src/main/java/it/inaf/ia2/gms/manager/UserAwareComponent.java b/gms/src/main/java/it/inaf/ia2/gms/manager/UserAwareComponent.java index f6af17ca33b29f359814e53043a3aa3eceb938d0..ad7dece5ef1060520d47968c7158f908b1afab76 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/manager/UserAwareComponent.java +++ b/gms/src/main/java/it/inaf/ia2/gms/manager/UserAwareComponent.java @@ -1,23 +1,14 @@ package it.inaf.ia2.gms.manager; -import it.inaf.ia2.gms.authn.RapPrincipal; -import it.inaf.ia2.gms.authn.SessionData; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; public abstract class UserAwareComponent { - @Autowired(required = false) - private SessionData session; - @Autowired private HttpServletRequest request; protected String getCurrentUserId() { - if (request.getUserPrincipal() != null && request.getUserPrincipal() instanceof RapPrincipal) { - return request.getUserPrincipal().getName(); - } else { - return session.getUserId(); - } + return request.getUserPrincipal().getName(); } } diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/GroupPermission.java b/gms/src/main/java/it/inaf/ia2/gms/model/GroupPermission.java new file mode 100644 index 0000000000000000000000000000000000000000..0846da98be18559f67eb2a676a8b327e846dc8a5 --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/model/GroupPermission.java @@ -0,0 +1,16 @@ +package it.inaf.ia2.gms.model; + +import it.inaf.ia2.gms.model.response.UserGroup; + +public class GroupPermission extends UserGroup { + + private Permission permission; + + public Permission getPermission() { + return permission; + } + + public void setPermission(Permission permission) { + this.permission = permission; + } +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/RapUserPermission.java b/gms/src/main/java/it/inaf/ia2/gms/model/RapUserPermission.java new file mode 100644 index 0000000000000000000000000000000000000000..8417970e0bb3cb650b68d408e0132764e92d5c01 --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/model/RapUserPermission.java @@ -0,0 +1,25 @@ +package it.inaf.ia2.gms.model; + +import it.inaf.ia2.rap.data.RapUser; + +public class RapUserPermission { + + private RapUser user; + private Permission permission; + + public RapUser getUser() { + return user; + } + + public void setUser(RapUser user) { + this.user = user; + } + + public Permission getPermission() { + return permission; + } + + public void setPermission(Permission permission) { + this.permission = permission; + } +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/UserPermission.java b/gms/src/main/java/it/inaf/ia2/gms/model/UserPermission.java index 43a9e0abe60bf617736b904a8337b4c9b07f0f68..38b95068b9189546822c6e474af0407c6babec84 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/model/UserPermission.java +++ b/gms/src/main/java/it/inaf/ia2/gms/model/UserPermission.java @@ -1,18 +1,16 @@ package it.inaf.ia2.gms.model; -import it.inaf.ia2.rap.data.RapUser; - public class UserPermission { - private RapUser user; + private String userId; private Permission permission; - public RapUser getUser() { - return user; + public String getUserId() { + return userId; } - public void setUser(RapUser user) { - this.user = user; + public void setUserId(String userId) { + this.userId = userId; } public Permission getPermission() { diff --git a/gms/src/main/java/it/inaf/ia2/gms/persistence/GroupsDAO.java b/gms/src/main/java/it/inaf/ia2/gms/persistence/GroupsDAO.java index 3cbffa59790a17845926da0690266a4bf1e93048..abe3041c36bcd623a5c579ea29d16699d3d9838d 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/persistence/GroupsDAO.java +++ b/gms/src/main/java/it/inaf/ia2/gms/persistence/GroupsDAO.java @@ -8,6 +8,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -159,6 +160,36 @@ public class GroupsDAO { }); } + /** + * @param groupIds + * @return map having group id as keys and group complete name as values + */ + public Map<String, String> getGroupCompleteNamesFromId(Set<String> groupIds) { + + Map<String, String> result = new HashMap<>(); + + if (groupIds.isEmpty()) { + return result; + } + + String sql = "SELECT id, complete_name FROM group_complete_name WHERE id IN (" + + String.join(",", Collections.nCopies(groupIds.size(), "?")) + ")"; + + jdbcTemplate.query(conn -> { + PreparedStatement ps = conn.prepareStatement(sql); + int i = 0; + for (String groupId : groupIds) { + ps.setString(++i, groupId); + } + return ps; + }, (rs, index) -> { + result.put(rs.getString("id"), rs.getString("complete_name")); + return null; + }); + + return result; + } + public Optional<GroupEntity> findGroupByParentAndName(String parentPath, String childName) { String sql = "SELECT id, path, is_leaf, locked from gms_group WHERE name = ? AND path ~ ?"; diff --git a/gms/src/main/java/it/inaf/ia2/gms/persistence/LoggingDAO.java b/gms/src/main/java/it/inaf/ia2/gms/persistence/LoggingDAO.java index cf7cf8d53fb68ad3d662d3cd51f1331528a53676..dc26fd488dede187917961d2a3ebad10d73551b0 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/persistence/LoggingDAO.java +++ b/gms/src/main/java/it/inaf/ia2/gms/persistence/LoggingDAO.java @@ -1,7 +1,5 @@ package it.inaf.ia2.gms.persistence; -import it.inaf.ia2.gms.authn.RapPrincipal; -import it.inaf.ia2.gms.authn.SessionData; import java.io.PrintWriter; import java.io.StringWriter; import java.sql.PreparedStatement; @@ -9,7 +7,6 @@ import javax.servlet.http.HttpServletRequest; import javax.sql.DataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; @@ -24,9 +21,6 @@ public class LoggingDAO { @Autowired(required = false) private HttpServletRequest request; - @Autowired(required = false) - private SessionData sessionData; - @Autowired public LoggingDAO(DataSource dataSource) { jdbcTemplate = new JdbcTemplate(dataSource); @@ -89,13 +83,8 @@ public class LoggingDAO { } private String getUser(HttpServletRequest request) { - if (request.getUserPrincipal() != null && request.getUserPrincipal() instanceof RapPrincipal) { + if (request != null && request.getUserPrincipal() != null) { return request.getUserPrincipal().getName(); - } else if (request.getSession(false) != null) { - try { - return sessionData.getUserId(); - } catch (BeanCreationException ex) { - } } return null; } diff --git a/gms/src/main/java/it/inaf/ia2/gms/persistence/PermissionsDAO.java b/gms/src/main/java/it/inaf/ia2/gms/persistence/PermissionsDAO.java index 48bc56e4ce55d914c0d7d76eb0874384c3bf5770..7191496a4b8903e0731e598fd3f0cf92a27f965f 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/persistence/PermissionsDAO.java +++ b/gms/src/main/java/it/inaf/ia2/gms/persistence/PermissionsDAO.java @@ -81,6 +81,10 @@ public class PermissionsDAO { }); } + /** + * Finds all direct user permissions for a given parent path (returns also + * all sub-groups permissions). + */ public List<PermissionEntity> findUserPermissions(String userId, String path) { String sql = "SELECT group_id, permission, group_path FROM gms_permission WHERE user_id = ?\n" diff --git a/gms/src/main/java/it/inaf/ia2/gms/rap/RapClient.java b/gms/src/main/java/it/inaf/ia2/gms/rap/RapClient.java deleted file mode 100644 index 189472a49d8ea269b640e20894f3f7850d199f2e..0000000000000000000000000000000000000000 --- a/gms/src/main/java/it/inaf/ia2/gms/rap/RapClient.java +++ /dev/null @@ -1,173 +0,0 @@ -package it.inaf.ia2.gms.rap; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import it.inaf.ia2.gms.authn.SessionData; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Function; -import javax.servlet.http.HttpServletRequest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.HttpServerErrorException; -import org.springframework.web.client.HttpStatusCodeException; -import org.springframework.web.client.RestTemplate; - -@Component -public class RapClient { - - @Value("${rap.ws-url}") - private String rapBaseUrl; - - @Value("${security.oauth2.client.access-token-uri}") - private String accessTokenUri; - - @Value("${security.oauth2.client.client-id}") - private String clientId; - - @Value("${security.oauth2.client.client-secret}") - private String clientSecret; - - @Value("${security.oauth2.client.scope}") - private String scope; - - @Autowired - private HttpServletRequest request; - - @Autowired(required = false) - private SessionData sessionData; - -// private final RestTemplate rapRestTemplate; -// -// private final RestTemplate refreshTokenRestTemplate; - - private final ObjectMapper objectMapper = new ObjectMapper(); -// -// @Autowired -// public RapClient(RestTemplate rapRestTemplate) { -// this.rapRestTemplate = rapRestTemplate; -// this.refreshTokenRestTemplate = new RestTemplate(); -// } -// -// public RapUser getUser(String userId) { -// -// String url = rapBaseUrl + "/user/" + userId; -// -// return httpCall(entity -> { -// return rapRestTemplate.exchange(url, HttpMethod.GET, entity, new ParameterizedTypeReference<RapUser>() { -// }).getBody(); -// }); -// } -// -// public List<RapUser> getUsers(Set<String> identifiers) { -// -// if (identifiers.isEmpty()) { -// return new ArrayList<>(); -// } -// -// String url = rapBaseUrl + "/user?identifiers=" + String.join(",", identifiers); -// -// return httpCall(entity -> { -// return rapRestTemplate.exchange(url, HttpMethod.GET, entity, new ParameterizedTypeReference<List<RapUser>>() { -// }).getBody(); -// }); -// } -// -// public List<RapUser> searchUsers(String searchText) { -// -// if (searchText == null || searchText.trim().isEmpty()) { -// return new ArrayList<>(); -// } -// -// String url = rapBaseUrl + "/user?search=" + searchText; -// -// return httpCall(entity -> { -// return rapRestTemplate.exchange(url, HttpMethod.GET, entity, new ParameterizedTypeReference<List<RapUser>>() { -// }).getBody(); -// }); -// } -// -// private <R> R httpCall(Function<HttpEntity<?>, R> function) { -// return httpCall(function, null); -// } -// -// private <R, T> R httpCall(Function<HttpEntity<?>, R> function, T body) { -// try { -// try { -// return function.apply(getEntity(body)); -// } catch (HttpClientErrorException.Unauthorized ex) { -// if (request.getSession(false) == null || sessionData.getExpiresIn() > 0) { -// // we can't refresh the token without a session -// throw ex; -// } -// refreshToken(); -// return function.apply(getEntity(body)); -// } -// } catch (HttpStatusCodeException ex) { -// try { -// Map<String, String> map = objectMapper.readValue(ex.getResponseBodyAsString(), Map.class); -// if (map.containsKey("error")) { -// String error = map.get("error"); -// if (ex instanceof HttpClientErrorException) { -// throw new HttpClientErrorException(ex.getStatusCode(), error); -// } else if (ex instanceof HttpServerErrorException) { -// throw new HttpServerErrorException(ex.getStatusCode(), error); -// } -// } -// } catch (JsonProcessingException ignore) { -// } -// throw ex; -// } -// } -// -// private <T> HttpEntity<T> getEntity(T body) { -// -// HttpHeaders headers = new HttpHeaders(); -// headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); -// if (request.getSession(false) != null) { -// headers.add("Authorization", "Bearer " + sessionData.getAccessToken()); -// } else { -// // from JWT web service -// headers.add("Authorization", request.getHeader("Authorization")); -// } -// -// return new HttpEntity<>(body, headers); -// } -// -// public void refreshToken() { -// -// HttpHeaders headers = new HttpHeaders(); -// headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); -// headers.setBasicAuth(clientId, clientSecret); -// -// headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); -// -// MultiValueMap<String, String> map = new LinkedMultiValueMap<>(); -// map.add("grant_type", "refresh_token"); -// map.add("refresh_token", sessionData.getRefreshToken()); -// map.add("scope", scope.replace(",", " ")); -// -// HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers); -// -// ResponseEntity<Map> response = refreshTokenRestTemplate.postForEntity(accessTokenUri, request, Map.class); -// -// Map<String, Object> values = response.getBody(); -// -// sessionData.setAccessToken((String) values.get("access_token")); -// sessionData.setRefreshToken((String) values.get("refresh_token")); -// sessionData.setExpiresIn((int) values.get("expires_in")); -// } -} diff --git a/gms/src/main/java/it/inaf/ia2/gms/service/GroupNameService.java b/gms/src/main/java/it/inaf/ia2/gms/service/GroupNameService.java index 5668fb21a63083f43acd0718666cb8f7d7a18242..be619b1700e66d1291ecfc174e50d7f5bd383ecb 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/service/GroupNameService.java +++ b/gms/src/main/java/it/inaf/ia2/gms/service/GroupNameService.java @@ -1,15 +1,17 @@ package it.inaf.ia2.gms.service; +import it.inaf.ia2.gms.exception.BadRequestException; import it.inaf.ia2.gms.persistence.GroupsDAO; import it.inaf.ia2.gms.persistence.model.GroupEntity; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; -import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -20,8 +22,12 @@ import org.springframework.stereotype.Service; @Service public class GroupNameService { + private final GroupsDAO groupsDAO; + @Autowired - private GroupsDAO groupsDAO; + public GroupNameService(GroupsDAO groupsDAO) { + this.groupsDAO = groupsDAO; + } public List<String> getGroupsNamesFromIdentifiers(Set<String> groupIdentifiers) { return getGroupsNames(groupsDAO.findGroupsByIds(groupIdentifiers)); @@ -37,113 +43,116 @@ public class GroupNameService { */ public List<String> getGroupsNames(List<GroupEntity> groups) { - // We need to return the complete group name, so it is necessary to load - // all the parents too. - Map<String, String> idNameMap = new HashMap<>(); - Set<String> allIdentifiers = getAllIdentifiers(groups); - for (GroupEntity group : groupsDAO.findGroupsByIds(allIdentifiers)) { - idNameMap.put(group.getId(), group.getName()); - } + Set<String> groupIds = groups.stream().map(g -> g.getId()).collect(Collectors.toSet()); - List<String> names = new ArrayList<>(); - for (GroupEntity group : groups) { - names.add(getGroupCompleteName(group, idNameMap)); + List<String> names = new ArrayList<>(groupsDAO.getGroupCompleteNamesFromId(groupIds).values()); + if (groupIds.contains("ROOT")) { + names.add("Root"); } - return names; - } - private Set<String> getAllIdentifiers(List<GroupEntity> groups) { - - Set<String> allIdentifiers = new HashSet<>(); - for (GroupEntity group : groups) { - if (!"".equals(group.getPath())) { - String[] ids = group.getPath().split("\\."); - for (String id : ids) { - allIdentifiers.add(id); - } - } - } + Collections.sort(names); - return allIdentifiers; + return names; } - private String getGroupCompleteName(GroupEntity group, Map<String, String> idNameMap) { + /** + * @param groups + * @return map having group id as keys and group names as values + */ + public Map<String, List<String>> getNames(Set<GroupEntity> groups) { - if ("ROOT".equals(group.getId())) { - return group.getName(); - } + Set<String> groupIds = groups.stream() + .map(g -> g.getId()).collect(Collectors.toSet()); - List<String> names = new ArrayList<>(); + return getNamesFromIds(groupIds); + } - for (String groupId : group.getPath().split("\\.")) { + public Map<String, List<String>> getNamesFromIds(Set<String> groupIds) { - String groupName = idNameMap.get(groupId); + Map<String, List<String>> result = new HashMap<>(); - // Dot inside names is considered a special character (because it is - // used to separate the group from its parents), so we use a - // backslash to escape it (client apps need to be aware of this). - groupName = groupName.replace("\\.", "\\\\."); + if (groupIds.contains("ROOT")) { + result.put("ROOT", Collections.singletonList("Root")); + } - names.add(groupName); + for (Map.Entry<String, String> entry : groupsDAO.getGroupCompleteNamesFromId(groupIds).entrySet()) { + List<String> names = splitNames(entry.getValue()); + result.put(entry.getKey(), names); } - return String.join(".", names); + return result; } - /** - * @param groupsIdPath map having group id as keys and group paths as values - * @return map having group id as keys and group names as values - */ - public Map<String, List<String>> getNames(List<Map.Entry<String, String>> groupsIdPath) { + private List<String> splitNames(String completeGroupName) { + return Arrays.asList(completeGroupName.split("(?<!\\\\)\\.")); + } - Set<String> allIdentifiers = new HashSet<>(); - for (Map.Entry<String, String> entry : groupsIdPath) { - allIdentifiers.addAll(getIdentifiers(entry.getValue())); + public String getShortGroupName(String completeGroupName, Optional<String> groupPrefix) { + if (groupPrefix.isPresent()) { + return completeGroupName.substring(groupPrefix.get().length() + 1); } + return completeGroupName; + } - Map<String, String> groupSingleNamesMap = getGroupSingleNamesMap(allIdentifiers); + public GroupEntity getGroupFromNames(Optional<String> group) { - Map<String, List<String>> groupCompleteNamesMap = new HashMap<>(); - for (Map.Entry<String, String> entry : groupsIdPath) { - List<String> groupCompleteName = getGroupCompleteName(groupSingleNamesMap, entry.getValue()); - groupCompleteNamesMap.put(entry.getKey(), groupCompleteName); + List<String> groupNames = extractGroupNames(group); + + if (groupNames.isEmpty()) { + return getRoot(); } + return getGroupFromNamesAndIndex(groupNames, groupNames.size() - 1); + } - return groupCompleteNamesMap; + public GroupEntity getGroupFromNamesAndIndex(Optional<String> group, int index) { + List<String> groupNames = extractGroupNames(group); + return getGroupFromNamesAndIndex(groupNames, index); } - private Map<String, String> getGroupSingleNamesMap(Set<String> allIdentifiers) { - Map<String, String> groupNamesMap = new HashMap<>(); - for (GroupEntity group : groupsDAO.findGroupsByIds(allIdentifiers)) { - groupNamesMap.put(group.getId(), group.getName()); + private GroupEntity getGroupFromNamesAndIndex(List<String> groupNames, int index) { + String parentPath = ""; // starting from ROOT + GroupEntity group = null; + for (int i = 0; i < index + 1; i++) { + String groupName = groupNames.get(i); + group = groupsDAO.findGroupByParentAndName(parentPath, groupName) + .orElseThrow(() -> new BadRequestException("Unable to find group " + groupName)); + parentPath = group.getPath(); } + if (group == null) { + throw new IllegalStateException(); + } + return group; + } - return groupNamesMap; + private List<String> extractGroupNames(Optional<String> group) { + return extractGroupNames(group.orElse(null)); } - private List<String> getGroupCompleteName(Map<String, String> groupNamesMap, String groupPath) { + public List<String> extractGroupNames(String groupStr) { + + if (groupStr == null || groupStr.isEmpty()) { + return new ArrayList<>(); + } + List<String> names = new ArrayList<>(); - if (groupPath.isEmpty()) { - names.add("Root"); - } else { - List<String> identifiers = getIdentifiers(groupPath); - for (String groupId : identifiers) { - names.add(groupNamesMap.get(groupId)); + String currentName = ""; + for (int i = 0; i < groupStr.length(); i++) { + char c = groupStr.charAt(i); + // dot is the group separator and it must be escaped if used inside + // group names + if (c == '.' && groupStr.charAt(i - 1) != '\\') { + names.add(currentName.replace("\\.", ".")); + currentName = ""; + } else { + currentName += c; } } + names.add(currentName); return names; } - /** - * Returns the list of all identifiers including parent ones. - */ - private List<String> getIdentifiers(String groupPath) { - List<String> identifiers = new ArrayList<>(); - if (!groupPath.isEmpty()) { - for (String id : groupPath.split(Pattern.quote("."))) { - identifiers.add(id); - } - } - return identifiers; + private GroupEntity getRoot() { + return groupsDAO.findGroupById("ROOT") + .orElseThrow(() -> new IllegalStateException("Missing root group")); } } diff --git a/gms/src/main/java/it/inaf/ia2/gms/service/SearchService.java b/gms/src/main/java/it/inaf/ia2/gms/service/SearchService.java index bd7f6355a0cb649d03d4b5aa50dfb2622d5f7aff..8ba7f3c95737f20403746e13fe26a0a68413d88d 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/service/SearchService.java +++ b/gms/src/main/java/it/inaf/ia2/gms/service/SearchService.java @@ -14,10 +14,10 @@ import it.inaf.ia2.gms.persistence.PermissionsDAO; import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.persistence.model.PermissionEntity; import it.inaf.ia2.rap.client.RapClient; -import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -75,22 +75,16 @@ public class SearchService { // Select only the groups visible to the user List<PermissionEntity> permissions = permissionsDAO.findUserPermissions(userId); - - List<Map.Entry<String, String>> groupsIdPath = new ArrayList<>(); - for (GroupEntity group : allGroups) { - PermissionUtils.getGroupPermission(group, permissions).ifPresent(permission -> { - groupsIdPath.add(new SimpleEntry<>(group.getId(), group.getPath())); - }); - } + Set<GroupEntity> visibleGroups = getVisibleGroups(allGroups, permissions); List<SearchResponseItem> items = new ArrayList<>(); - Map<String, List<String>> groupNames = groupNameService.getNames(groupsIdPath); - for (Map.Entry<String, String> entry : groupsIdPath) { - String groupId = entry.getKey(); + Map<String, List<String>> groupNames = groupNameService.getNames(visibleGroups); + + for (GroupEntity group : visibleGroups) { SearchResponseItem item = new SearchResponseItem(); item.setType(SearchResponseType.GROUP); - item.setId(groupId); - List<String> names = groupNames.get(groupId); + item.setId(group.getId()); + List<String> names = groupNames.get(group.getId()); item.setLabel(String.join(" / ", names)); items.add(item); } @@ -129,15 +123,9 @@ public class SearchService { List<GroupEntity> allGroups = membershipsDAO.getUserMemberships(targetUserId); // Select only groups visible to the actor user - List<Map.Entry<String, String>> visibleGroupsIdPath = new ArrayList<>(); - for (GroupEntity group : allGroups) { - - PermissionUtils.getGroupPermission(group, actorPermissions).ifPresent(permission -> { - visibleGroupsIdPath.add(new SimpleEntry<>(group.getId(), group.getPath())); - }); - } + Set<GroupEntity> visibleGroups = getVisibleGroups(allGroups, actorPermissions); - return groupNameService.getNames(visibleGroupsIdPath).entrySet().stream() + return groupNameService.getNames(visibleGroups).entrySet().stream() .map(entry -> { UserGroup ug = new UserGroup(); ug.setGroupId(entry.getKey()); @@ -147,6 +135,12 @@ public class SearchService { .collect(Collectors.toList()); } + private Set<GroupEntity> getVisibleGroups(List<GroupEntity> allGroups, List<PermissionEntity> permissions) { + return allGroups.stream() + .filter(g -> PermissionUtils.getGroupPermission(g, permissions).isPresent()) + .collect(Collectors.toSet()); + } + public List<UserPermission> getUserPermission(GroupEntity group, String targetUserId, List<PermissionEntity> actorPermissions) { List<UserPermission> permissions = new ArrayList<>(); @@ -159,12 +153,10 @@ public class SearchService { = permissionsDAO.findUserPermissions(targetUserId).stream() .collect(Collectors.toMap(PermissionEntity::getGroupId, p -> p)); - List<Map.Entry<String, String>> groupsIdPath = new ArrayList<>(); - for (PermissionEntity p : targetUserPermissions.values()) { - groupsIdPath.add(new SimpleEntry<>(p.getGroupId(), p.getGroupPath())); - } + Set<String> groupIds = targetUserPermissions.values().stream() + .map(p -> p.getGroupId()).collect(Collectors.toSet()); - for (Map.Entry<String, List<String>> entry : groupNameService.getNames(groupsIdPath).entrySet()) { + for (Map.Entry<String, List<String>> entry : groupNameService.getNamesFromIds(groupIds).entrySet()) { UserPermission up = new UserPermission(); up.setGroupId(entry.getKey()); up.setGroupCompleteName(entry.getValue()); diff --git a/gms/src/main/resources/sql/init.sql b/gms/src/main/resources/sql/init.sql index 05aec53ca465b3b7fe8241685973524e74e2daae..56103d17830c7a050f92fbc250e40f74188d6910 100644 --- a/gms/src/main/resources/sql/init.sql +++ b/gms/src/main/resources/sql/init.sql @@ -63,3 +63,16 @@ CREATE TABLE invited_registration_request_group ( FOREIGN KEY (request_id) REFERENCES invited_registration_request(id), FOREIGN KEY (group_id) REFERENCES gms_group(id) ); + +CREATE VIEW group_complete_name AS +SELECT id, string_agg(name, '.') AS complete_name +FROM ( + SELECT replace(name, '.', '\.') AS name, p.id + FROM gms_group g + JOIN ( + SELECT UNNEST(string_to_array(path::varchar, '.')) AS rel_id, id + FROM gms_group + ) AS p ON g.id = p.rel_id + ORDER BY p.id, nlevel(g.path) +) AS j +GROUP BY id ORDER BY complete_name; diff --git a/gms/src/test/java/it/inaf/ia2/gms/GmsTestUtils.java b/gms/src/test/java/it/inaf/ia2/gms/GmsTestUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..ed79a9b487d01f080584b3eca67379d05dba4e4c --- /dev/null +++ b/gms/src/test/java/it/inaf/ia2/gms/GmsTestUtils.java @@ -0,0 +1,19 @@ +package it.inaf.ia2.gms; + +import java.security.Principal; +import javax.servlet.http.HttpServletRequest; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class GmsTestUtils { + + public static void mockPrincipal(HttpServletRequest mockedServletRequest) { + mockPrincipal(mockedServletRequest, "admin_id"); + } + + public static void mockPrincipal(HttpServletRequest mockedServletRequest, String userId) { + Principal principal = mock(Principal.class); + when(principal.getName()).thenReturn(userId); + when(mockedServletRequest.getUserPrincipal()).thenReturn(principal); + } +} diff --git a/gms/src/test/java/it/inaf/ia2/gms/authn/SessionDataTest.java b/gms/src/test/java/it/inaf/ia2/gms/authn/SessionDataTest.java index 00648021317db5c3704b58e56feb509e7072f644..75d44989f48e75cce0fd7d7c62b8079c91acd6e7 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/authn/SessionDataTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/authn/SessionDataTest.java @@ -1,6 +1,7 @@ package it.inaf.ia2.gms.authn; import it.inaf.ia2.aa.data.User; +import it.inaf.ia2.rap.client.RapClient; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import static org.junit.Assert.assertTrue; @@ -18,6 +19,9 @@ public class SessionDataTest { @Mock private HttpServletRequest request; + + @Mock + private RapClient rapClient; @InjectMocks private SessionData sessionData; diff --git a/gms/src/test/java/it/inaf/ia2/gms/controller/GroupsControllerTest.java b/gms/src/test/java/it/inaf/ia2/gms/controller/GroupsControllerTest.java index f09287e45d31828aad7464f635384ecc9eca5fab..cdbdb8b42f3ce19f906ebcb99d35b604c01a58a2 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/controller/GroupsControllerTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/controller/GroupsControllerTest.java @@ -1,7 +1,7 @@ package it.inaf.ia2.gms.controller; import com.fasterxml.jackson.databind.ObjectMapper; -import it.inaf.ia2.gms.authn.SessionData; +import it.inaf.ia2.gms.GmsTestUtils; import it.inaf.ia2.gms.manager.GroupsManager; import it.inaf.ia2.gms.manager.PermissionsManager; import it.inaf.ia2.gms.model.GroupNode; @@ -14,6 +14,7 @@ import it.inaf.ia2.gms.service.GroupsService; import it.inaf.ia2.gms.service.GroupsTreeBuilder; import java.util.ArrayList; import java.util.List; +import javax.servlet.http.HttpServletRequest; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import org.junit.Before; @@ -50,7 +51,7 @@ public class GroupsControllerTest { private GroupsService groupsService; @Mock - private SessionData session; + private HttpServletRequest servletRequest; @Mock private PermissionsManager permissionsManager; @@ -71,6 +72,7 @@ public class GroupsControllerTest { @Before public void init() { mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); + GmsTestUtils.mockPrincipal(servletRequest); } @Test @@ -104,8 +106,6 @@ public class GroupsControllerTest { PaginatedData<GroupNode> paginatedData = new PaginatedData<>(nodes, 1, 10); when(groupsTreeBuilder.listSubGroups(any(), any(), any())).thenReturn(paginatedData); - when(session.getUserId()).thenReturn("admin_id"); - mockMvc.perform(post("/group") .content(mapper.writeValueAsString(request)) .contentType(MediaType.APPLICATION_JSON)) diff --git a/gms/src/test/java/it/inaf/ia2/gms/controller/GroupsTabResponseBuilderTest.java b/gms/src/test/java/it/inaf/ia2/gms/controller/GroupsTabResponseBuilderTest.java index 937fbe74b33dd9e0756099bcb62d47f14a00ffb1..07f1e8577751f8a8c61340f530a971457bb3b269 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/controller/GroupsTabResponseBuilderTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/controller/GroupsTabResponseBuilderTest.java @@ -1,6 +1,6 @@ package it.inaf.ia2.gms.controller; -import it.inaf.ia2.gms.authn.SessionData; +import it.inaf.ia2.gms.GmsTestUtils; import it.inaf.ia2.gms.manager.GroupsManager; import it.inaf.ia2.gms.manager.InvitedRegistrationManager; import it.inaf.ia2.gms.manager.PermissionsManager; @@ -13,6 +13,7 @@ import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.service.GroupsService; import it.inaf.ia2.gms.service.GroupsTreeBuilder; import java.util.ArrayList; +import javax.servlet.http.HttpServletRequest; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import org.junit.Test; @@ -28,7 +29,7 @@ import org.mockito.junit.MockitoJUnitRunner; public class GroupsTabResponseBuilderTest { @Mock - private SessionData session; + private HttpServletRequest servletRequest; @Mock private GroupsManager groupsManager; @@ -51,7 +52,7 @@ public class GroupsTabResponseBuilderTest { @Test public void testGetGroupsTab() { - when(session.getUserId()).thenReturn("admin_id"); + GmsTestUtils.mockPrincipal(servletRequest); GroupEntity root = new GroupEntity(); root.setId("ROOT"); diff --git a/gms/src/test/java/it/inaf/ia2/gms/controller/JWTWebServiceControllerTest.java b/gms/src/test/java/it/inaf/ia2/gms/controller/JWTWebServiceControllerTest.java index 89453288494407d08101c36f322287d73aae4017..1a086e3dcf0112b6437841e576ef81227f0e0393 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/controller/JWTWebServiceControllerTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/controller/JWTWebServiceControllerTest.java @@ -4,12 +4,13 @@ import it.inaf.ia2.gms.manager.GroupsManager; import it.inaf.ia2.gms.manager.MembershipManager; import it.inaf.ia2.gms.manager.PermissionsManager; import it.inaf.ia2.gms.model.Permission; -import it.inaf.ia2.gms.model.UserPermission; +import it.inaf.ia2.gms.model.RapUserPermission; import it.inaf.ia2.gms.persistence.GroupsDAO; import it.inaf.ia2.gms.persistence.PermissionsDAO; import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.persistence.model.MembershipEntity; import it.inaf.ia2.gms.persistence.model.PermissionEntity; +import it.inaf.ia2.gms.service.GroupNameService; import it.inaf.ia2.gms.service.GroupsService; import it.inaf.ia2.gms.service.JoinService; import it.inaf.ia2.rap.data.RapUser; @@ -81,6 +82,7 @@ public class JWTWebServiceControllerTest { @Before public void init() { + controller.groupNameService = new GroupNameService(groupsDAO); mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); root = getRoot(); lbt = getLbtGroup(); @@ -193,8 +195,8 @@ public class JWTWebServiceControllerTest { when(groupsDAO.findGroupByParentAndName("", "LBT")).thenReturn(Optional.of(lbt)); when(groupsDAO.findGroupByParentAndName("lbt_id", "INAF")).thenReturn(Optional.of(inaf)); - List<UserPermission> permissions = new ArrayList<>(); - UserPermission up = new UserPermission(); + List<RapUserPermission> permissions = new ArrayList<>(); + RapUserPermission up = new RapUserPermission(); up.setUser(getRapUser()); up.setPermission(Permission.ADMIN); permissions.add(up); diff --git a/gms/src/test/java/it/inaf/ia2/gms/controller/SearchControllerTest.java b/gms/src/test/java/it/inaf/ia2/gms/controller/SearchControllerTest.java index f419eba57f56c1c58302ffd750434f5eaf4bd39b..bfe0b1a1bb7b81ff65c4010b430779c011d2d1f5 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/controller/SearchControllerTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/controller/SearchControllerTest.java @@ -1,12 +1,13 @@ package it.inaf.ia2.gms.controller; import com.fasterxml.jackson.databind.ObjectMapper; -import it.inaf.ia2.gms.authn.SessionData; +import it.inaf.ia2.gms.GmsTestUtils; import it.inaf.ia2.gms.model.response.PaginatedData; import it.inaf.ia2.gms.model.response.SearchResponseItem; import it.inaf.ia2.gms.model.response.UserSearchResponse; import it.inaf.ia2.gms.service.SearchService; import java.util.ArrayList; +import javax.servlet.http.HttpServletRequest; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -29,7 +30,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; public class SearchControllerTest { @Mock - private SessionData session; + private HttpServletRequest servletRequest; @Mock private SearchService searchService; @@ -44,8 +45,7 @@ public class SearchControllerTest { @Before public void init() { mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); - - when(session.getUserId()).thenReturn("admin_id"); + GmsTestUtils.mockPrincipal(servletRequest); } @Test @@ -56,7 +56,7 @@ public class SearchControllerTest { when(searchService.search(any(), any(), anyInt(), anyInt())).thenReturn(response); mockMvc.perform(get("/search?query=searchText&page=1&pageSize=10") - .contentType(MediaType.APPLICATION_JSON_UTF8)) + .contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isOk()); verify(searchService, times(1)).search(eq("searchText"), eq("admin_id"), eq(1), eq(10)); @@ -68,7 +68,7 @@ public class SearchControllerTest { when(searchService.getUserSearchResult(any(), any())).thenReturn(new UserSearchResponse()); mockMvc.perform(get("/search/user/user_id") - .contentType(MediaType.APPLICATION_JSON_UTF8)) + .contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isOk()); verify(searchService, times(1)).getUserSearchResult(eq("admin_id"), eq("user_id")); diff --git a/gms/src/test/java/it/inaf/ia2/gms/manager/InvitedRegistrationManagerTest.java b/gms/src/test/java/it/inaf/ia2/gms/manager/InvitedRegistrationManagerTest.java index 192c62e1a42b1750b4849c44660cc7d5e238745c..4ce897a21f44e4e3c047087336188913ba198e60 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/manager/InvitedRegistrationManagerTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/manager/InvitedRegistrationManagerTest.java @@ -1,6 +1,6 @@ package it.inaf.ia2.gms.manager; -import it.inaf.ia2.gms.authn.SessionData; +import it.inaf.ia2.gms.GmsTestUtils; import it.inaf.ia2.gms.model.Permission; import it.inaf.ia2.gms.persistence.GroupsDAO; import it.inaf.ia2.gms.persistence.InvitedRegistrationDAO; @@ -19,6 +19,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.junit.Before; import org.junit.Test; @@ -51,7 +52,7 @@ public class InvitedRegistrationManagerTest { @Mock private RapClient rapClient; @Mock - private SessionData sessionData; + private HttpServletRequest servletRequest; @Mock private LoggingDAO loggingDAO; @Mock @@ -95,7 +96,7 @@ public class InvitedRegistrationManagerTest { when(httpSession.getAttribute(eq("invited-registration"))).thenReturn(regFromToken); - when(sessionData.getUserId()).thenReturn(USER_ID); + GmsTestUtils.mockPrincipal(servletRequest, USER_ID); RapUser user = new RapUser(); user.setId(USER_ID); @@ -145,7 +146,7 @@ public class InvitedRegistrationManagerTest { when(httpSession.getAttribute(eq("invited-registration"))).thenReturn(regFromToken); - when(sessionData.getUserId()).thenReturn(USER_ID); + GmsTestUtils.mockPrincipal(servletRequest, USER_ID); RapUser user = new RapUser(); user.setId(USER_ID); diff --git a/gms/src/test/java/it/inaf/ia2/gms/manager/PermissionsManagerIntegrationTest.java b/gms/src/test/java/it/inaf/ia2/gms/manager/PermissionsManagerIntegrationTest.java index 5eec6c7d48b9dcb3ee02e115f3e7c9ba873fb002..93190b4c73ed43306a2784da6d1e51262bbb4f8e 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/manager/PermissionsManagerIntegrationTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/manager/PermissionsManagerIntegrationTest.java @@ -2,7 +2,7 @@ package it.inaf.ia2.gms.manager; import it.inaf.ia2.gms.DataSourceConfig; import it.inaf.ia2.gms.model.Permission; -import it.inaf.ia2.gms.model.UserPermission; +import it.inaf.ia2.gms.model.RapUserPermission; import it.inaf.ia2.gms.persistence.GroupsDAO; import it.inaf.ia2.gms.persistence.LoggingDAO; import it.inaf.ia2.gms.persistence.PermissionsDAO; @@ -73,7 +73,7 @@ public class PermissionsManagerIntegrationTest { superAdminPermission.setGroupPath(root.getPath()); permissionsDAO.createOrUpdatePermission(superAdminPermission); - List<UserPermission> permissions = permissionsManager.getAllPermissions(root); + List<RapUserPermission> permissions = permissionsManager.getAllPermissions(root); assertEquals(1, permissions.size()); assertEquals(Permission.ADMIN, permissions.get(0).getPermission()); diff --git a/gms/src/test/java/it/inaf/ia2/gms/persistence/GroupsDAOTest.java b/gms/src/test/java/it/inaf/ia2/gms/persistence/GroupsDAOTest.java index fd56e8a6302bab237d6d0ffb69930f77e8a59dd7..17fb805a987694fb50bcd2fda50c433a4d3b0839 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/persistence/GroupsDAOTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/persistence/GroupsDAOTest.java @@ -5,9 +5,11 @@ import it.inaf.ia2.gms.HooksConfig; import it.inaf.ia2.gms.model.GroupBreadcrumb; import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.service.hook.GroupsHook; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.UUID; import javax.sql.DataSource; import static org.junit.Assert.assertEquals; @@ -114,6 +116,15 @@ public class GroupsDAOTest { assertTrue(optGroup.isPresent()); assertEquals(lbtInaf.getId(), optGroup.get().getId()); + // Complete names + Set<String> groupIds = new HashSet<>(); + groupIds.add(groups.get(0).getId()); + groupIds.add(lbt.getId()); + Map<String, String> completeGroupNames = dao.getGroupCompleteNamesFromId(groupIds); + assertEquals(2, completeGroupNames.size()); + assertEquals("LBT", completeGroupNames.get(lbt.getId())); + assertEquals("LBT.INAF", completeGroupNames.get(groups.get(0).getId())); + // Children map Map<String, Boolean> childrenMap = dao.getHasChildrenMap(Sets.newSet(root.getId())); assertEquals(1, childrenMap.size()); @@ -151,4 +162,9 @@ public class GroupsDAOTest { private String getNewGroupId() { return UUID.randomUUID().toString().replaceAll("-", ""); } + + @Test + public void testGroupCompleteNamesEmptyInput() { + assertTrue(dao.getGroupCompleteNamesFromId(new HashSet<>()).isEmpty()); + } } diff --git a/gms/src/test/java/it/inaf/ia2/gms/service/GroupNameServiceTest.java b/gms/src/test/java/it/inaf/ia2/gms/service/GroupNameServiceTest.java index 1ec9f9aee50f263f31ff2ac0cfaad63f9c76aa18..2b4b74c84f830201b263fdb7241bebd94e554fdc 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/service/GroupNameServiceTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/service/GroupNameServiceTest.java @@ -4,8 +4,11 @@ import it.inaf.ia2.gms.persistence.GroupsDAO; import it.inaf.ia2.gms.persistence.model.GroupEntity; import java.util.AbstractMap; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import static org.junit.Assert.assertEquals; import org.junit.Test; import org.junit.runner.RunWith; @@ -27,54 +30,38 @@ public class GroupNameServiceTest { @Test public void getNamesTest() { - mockGroupsDAO(); + GroupEntity group = new GroupEntity(); + group.setName("Child\\.withDot"); + group.setId("def"); + group.setPath("abc.def"); - List<Map.Entry<String, String>> groupsIdPath = new ArrayList<>(); - groupsIdPath.add(new AbstractMap.SimpleEntry<>("def", "abc.def")); - - Map<String, List<String>> names = groupNameService.getNames(groupsIdPath); - assertEquals(1, names.size()); - assertEquals(2, names.get("def").size()); - assertEquals("Group 1", names.get("def").get(0)); - assertEquals("Group 2", names.get("def").get(1)); - } + Set<GroupEntity> groups = new HashSet<>(); + groups.add(group); - public void mockGroupsDAO() { + Map<String, String> daoResponse = new HashMap<>(); + daoResponse.put("def", "Parent_group.Child\\.withDot"); - List<GroupEntity> groups = new ArrayList<>(); + when(groupsDAO.getGroupCompleteNamesFromId(any())).thenReturn(daoResponse); - GroupEntity group1 = new GroupEntity(); - group1.setId("abc"); - group1.setName("Group 1"); - group1.setPath("abc"); - groups.add(group1); - - GroupEntity group2 = new GroupEntity(); - group2.setId("def"); - group2.setName("Group 2"); - group2.setPath("abc.def"); - groups.add(group2); - - when(groupsDAO.findGroupsByIds(any())).thenReturn(groups); + Map<String, List<String>> names = groupNameService.getNames(groups); + assertEquals(1, names.size()); + assertEquals(2, names.get("def").size()); + assertEquals("Parent_group", names.get("def").get(0)); + assertEquals("Child\\.withDot", names.get("def").get(1)); } @Test public void getRootTest() { - List<GroupEntity> groups = new ArrayList<>(); - - GroupEntity root = new GroupEntity(); - root.setId("ROOT"); - root.setName("Root"); - root.setPath(""); - groups.add(root); + Set<String> groupIds = new HashSet<>(); + groupIds.add("ROOT"); - when(groupsDAO.findGroupsByIds(any())).thenReturn(groups); + when(groupsDAO.getGroupCompleteNamesFromId(any())).thenReturn(new HashMap<>()); List<Map.Entry<String, String>> groupsIdPath = new ArrayList<>(); groupsIdPath.add(new AbstractMap.SimpleEntry<>("ROOT", "")); - Map<String, List<String>> names = groupNameService.getNames(groupsIdPath); + Map<String, List<String>> names = groupNameService.getNamesFromIds(groupIds); assertEquals(1, names.size()); assertEquals(1, names.get("ROOT").size()); assertEquals("Root", names.get("ROOT").get(0)); diff --git a/gms/src/test/java/it/inaf/ia2/gms/service/SearchServiceTest.java b/gms/src/test/java/it/inaf/ia2/gms/service/SearchServiceTest.java index bb44208ef9f8a15c0a99a6e231e869a1f442831d..72b06ce8161daa4c1b08b6327346c1e410d77439 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/service/SearchServiceTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/service/SearchServiceTest.java @@ -20,7 +20,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Map.Entry; +import java.util.Set; import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; @@ -64,10 +64,10 @@ public class SearchServiceTest { when(groupNameService.getNames(any())).then(invocation -> { Map<String, List<String>> result = new HashMap<>(); - List<Map.Entry<String, String>> arg = invocation.getArgument(0); - for (Entry<String, String> entry : arg) { + Set<GroupEntity> arg = invocation.getArgument(0); + for (GroupEntity group : arg) { List<String> names = new ArrayList<>(); - switch (entry.getKey()) { + switch (group.getId()) { case "ROOT": names.add("Root"); break; @@ -75,7 +75,7 @@ public class SearchServiceTest { names.add("Group 1"); break; } - result.put(entry.getKey(), names); + result.put(group.getId(), names); } return result; }); @@ -136,6 +136,11 @@ public class SearchServiceTest { @Test public void testGetUserSearchResult() { + Map<String, List<String>> nameResult = new HashMap<>(); + nameResult.put("group1_id", Collections.singletonList("Group 1")); + + when(groupNameService.getNamesFromIds(any())).thenReturn(nameResult); + GroupEntity group1 = new GroupEntity(); group1.setId("group1_id"); group1.setName("Group 1");