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 ed7be0d35da5a9abed52c142cd33b71782d43fac..72d55a11a81e512d12c34f3fd1694bd90d66d753 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 @@ -56,13 +56,14 @@ public class JWTFilter implements Filter { Map<String, Object> claims = userManager.parseIdTokenClaims(token); if (claims.get("sub") == null) { - loggingDAO.logAction(ActionType.UNAUTHORIZED_ACCESS_ATTEMPT, "Attempt to access API with invalid token", request); + loggingDAO.logAction(ActionType.UNAUTHORIZED_ACCESS_ATTEMPT, "Attempt to access API with invalid token " + request.getRequestURI(), request); response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid access token: missing sub claim"); return; } ServletRequestWithJWTPrincipal wrappedRequest = new ServletRequestWithJWTPrincipal(request, token, claims); - loggingDAO.logAction(ActionType.UNAUTHORIZED_ACCESS_ATTEMPT, "API access from " + wrappedRequest.getUserPrincipal().getName(), request); + + loggingDAO.logAction(ActionType.API_CALL, request.getRequestURI() + " called by " + wrappedRequest.getUserPrincipal().getName(), request); fc.doFilter(wrappedRequest, res); } diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/HomePageController.java b/gms/src/main/java/it/inaf/ia2/gms/controller/HomePageController.java index d9f18f65b0b612d9c8dc5bc2b0e7a5c051bf7224..6fbf33f971a920b80e76d5f7fd6b217203f98d52 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/controller/HomePageController.java +++ b/gms/src/main/java/it/inaf/ia2/gms/controller/HomePageController.java @@ -1,18 +1,12 @@ package it.inaf.ia2.gms.controller; import it.inaf.ia2.gms.authn.SessionData; -import it.inaf.ia2.gms.exception.UnauthorizedException; import it.inaf.ia2.gms.manager.InvitedRegistrationManager; -import it.inaf.ia2.gms.model.GroupBreadcrumb; -import it.inaf.ia2.gms.model.GroupNode; -import it.inaf.ia2.gms.model.Permission; import it.inaf.ia2.gms.model.request.GroupsRequest; import it.inaf.ia2.gms.model.response.GroupsTabResponse; import it.inaf.ia2.gms.model.response.HomePageResponse; -import it.inaf.ia2.gms.model.response.PaginatedData; import it.inaf.ia2.gms.persistence.model.InvitedRegistration; import java.io.IOException; -import java.util.ArrayList; import java.util.List; import java.util.Optional; import javax.servlet.ServletException; @@ -48,37 +42,14 @@ public class HomePageController { response.setUser(session.getUserName()); - try { - GroupsTabResponse groupsTabResponse = groupsTabResponseBuilder.getGroupsTab(request); - response.setBreadcrumbs(groupsTabResponse.getBreadcrumbs()); - response.setGroupsPanel(groupsTabResponse.getGroupsPanel()); - response.setPermission(groupsTabResponse.getPermission()); - } catch (UnauthorizedException ex) { - if ("ROOT".equals(request.getGroupId())) { - response.setBreadcrumbs(getRootBreadcrumbs()); - response.setGroupsPanel(getEmptyGroupsPanel(request)); - response.setPermission(Permission.TRAVERSE); - } else { - throw ex; - } - } + GroupsTabResponse groupsTabResponse = groupsTabResponseBuilder.getGroupsTab(request); + response.setBreadcrumbs(groupsTabResponse.getBreadcrumbs()); + response.setGroupsPanel(groupsTabResponse.getGroupsPanel()); + response.setPermission(groupsTabResponse.getPermission()); return ResponseEntity.ok(response); } - private List<GroupBreadcrumb> getRootBreadcrumbs() { - List<GroupBreadcrumb> breadcrumbs = new ArrayList<>(); - GroupBreadcrumb breadcrumb = new GroupBreadcrumb(); - breadcrumb.setGroupId("ROOT"); - breadcrumb.setGroupName("ROOT"); - breadcrumbs.add(breadcrumb); - return breadcrumbs; - } - - private PaginatedData<GroupNode> getEmptyGroupsPanel(GroupsRequest request) { - return new PaginatedData<>(new ArrayList<>(), 1, request.getPaginatorPageSize()); - } - @GetMapping(value = "/", produces = MediaType.TEXT_HTML_VALUE) public String index(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { diff --git a/gms/src/main/java/it/inaf/ia2/gms/manager/GroupsManager.java b/gms/src/main/java/it/inaf/ia2/gms/manager/GroupsManager.java index dcbadeabd68c98e8d740635505b66a5fee01888a..6a76c6ba2862854f6779c604f3f8f9551c1dbd88 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/manager/GroupsManager.java +++ b/gms/src/main/java/it/inaf/ia2/gms/manager/GroupsManager.java @@ -84,6 +84,10 @@ public class GroupsManager extends UserAwareComponent { } public void verifyUserCanReadGroup(GroupEntity group) { + if (GroupsService.ROOT.equals(group.getId())) { + // Everybody can read the root + return; + } if (permissionsManager.getCurrentUserPermission(group) == null) { loggingDAO.logAction(ActionType.UNAUTHORIZED_ACCESS_ATTEMPT, "Unauthorized group management request, group_id=" + group.getId()); throw new UnauthorizedException("Missing permission to see this group"); 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 f684d6dd28134cac298402e5671fb8b721243997..eb1271e189584bc718030d261082bd849f9cf426 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 @@ -10,6 +10,7 @@ import it.inaf.ia2.gms.service.PermissionUtils; import it.inaf.ia2.gms.service.PermissionsService; import it.inaf.ia2.gms.authn.RapClient; import it.inaf.ia2.gms.persistence.model.ActionType; +import it.inaf.ia2.gms.service.GroupsService; import it.inaf.ia2.rap.data.RapUser; import java.util.ArrayList; import java.util.List; @@ -159,6 +160,8 @@ public class PermissionsManager extends UserAwareComponent { public Permission getCurrentUserPermission(GroupEntity group) { List<PermissionEntity> permissions = permissionsService.findUserPermissions(group, getCurrentUserId()); - return PermissionUtils.getGroupPermission(group, permissions).orElse(null); + return PermissionUtils.getGroupPermission(group, permissions).orElse( + GroupsService.ROOT.equals(group.getId()) ? Permission.TRAVERSE : null + ); } } diff --git a/gms/src/main/java/it/inaf/ia2/gms/persistence/model/ActionType.java b/gms/src/main/java/it/inaf/ia2/gms/persistence/model/ActionType.java index f867604ecfc355ae5d0ff118b432dfe23086713c..99827192322b6be1f9030cc79f715a9e1016d1e2 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/persistence/model/ActionType.java +++ b/gms/src/main/java/it/inaf/ia2/gms/persistence/model/ActionType.java @@ -15,5 +15,6 @@ public enum ActionType { INVITED_REGISTRATION_OPENED, INVITED_REGISTRATION_DELETED, INVITED_REGISTRATION_COMPLETED, + API_CALL, UNAUTHORIZED_ACCESS_ATTEMPT } diff --git a/gms/src/test/java/it/inaf/ia2/gms/manager/GroupsManagerTest.java b/gms/src/test/java/it/inaf/ia2/gms/manager/GroupsManagerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9a63a0ce79a98a8cfe79eda7a7d93a00ef4f7c8c --- /dev/null +++ b/gms/src/test/java/it/inaf/ia2/gms/manager/GroupsManagerTest.java @@ -0,0 +1,56 @@ +package it.inaf.ia2.gms.manager; + +import it.inaf.ia2.gms.exception.UnauthorizedException; +import it.inaf.ia2.gms.persistence.LoggingDAO; +import it.inaf.ia2.gms.persistence.model.GroupEntity; +import it.inaf.ia2.gms.service.GroupsService; +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class GroupsManagerTest { + + @Mock + private GroupsService groupsService; + @Mock + private PermissionsManager permissionsManager; + @Mock + private LoggingDAO loggingDAO; + + @InjectMocks + private GroupsManager groupsManager; + + @Test + public void testRootAlwaysReadable() { + + GroupEntity root = new GroupEntity(); + root.setName("ROOT"); + root.setId(GroupsService.ROOT); + root.setPath(""); + + groupsManager.verifyUserCanReadGroup(root); + } + + @Test + public void testVerifyUserCanReadGroupFails() { + + boolean exception = false; + + GroupEntity group = new GroupEntity(); + group.setName("group_name"); + group.setId("group_id"); + group.setPath("group_id"); + + try { + groupsManager.verifyUserCanReadGroup(group); + } catch (UnauthorizedException ex) { + exception = true; + } + + assertTrue(exception); + } +} diff --git a/gms/src/test/java/it/inaf/ia2/gms/manager/PermissionsManagerTest.java b/gms/src/test/java/it/inaf/ia2/gms/manager/PermissionsManagerTest.java index 072a3eea0752df31792df08794120216a3e638be..403268696f3372374e4ed3e85af80b2c3d2a088e 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/manager/PermissionsManagerTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/manager/PermissionsManagerTest.java @@ -5,11 +5,13 @@ import it.inaf.ia2.gms.model.Permission; import it.inaf.ia2.gms.persistence.LoggingDAO; import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.persistence.model.PermissionEntity; +import it.inaf.ia2.gms.service.GroupsService; import it.inaf.ia2.gms.service.PermissionsService; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.servlet.http.HttpServletRequest; +import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -137,6 +139,18 @@ public class PermissionsManagerTest { permissionsManager.removePermission(group, TARGET_USER_ID); } + @Test + public void testGetCurrentUserPermissionAlwaysTraverseRoot() { + when(permissionsService.findUserPermissions(any(), any())).thenReturn(new ArrayList<>()); + + GroupEntity root = new GroupEntity(); + root.setName("ROOT"); + root.setId(GroupsService.ROOT); + root.setPath(""); + + assertEquals(Permission.TRAVERSE, permissionsManager.getCurrentUserPermission(root)); + } + private List<PermissionEntity> getUserPermissions(GroupEntity group, Permission permission) { PermissionEntity entity = new PermissionEntity(); entity.setPermission(permission);