From 7c9d3a2108a692e86f5e7dab0820c164903b4838 Mon Sep 17 00:00:00 2001 From: Rajitha Kumara Date: Sun, 23 Jul 2023 15:12:37 +0000 Subject: [PATCH] Fixes for grouping issues (#186) Co-authored-by: rajitha Reviewed-on: https://repository.entgra.net/community/device-mgt-core/pulls/186 Co-authored-by: Rajitha Kumara Co-committed-by: Rajitha Kumara --- .../service/api/GroupManagementService.java | 9 +- .../impl/GroupManagementServiceImpl.java | 5 +- .../impl/GroupManagementServiceImplTest.java | 6 +- .../core/dao/impl/AbstractGroupDAOImpl.java | 3 +- .../GroupManagementProviderService.java | 2 + .../GroupManagementProviderServiceImpl.java | 119 +++++++++++++++--- 6 files changed, 117 insertions(+), 27 deletions(-) diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/GroupManagementService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/GroupManagementService.java index 33614a7328..c447c48a5b 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/GroupManagementService.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/GroupManagementService.java @@ -533,7 +533,14 @@ public interface GroupManagementService { defaultValue = "1") @DefaultValue("1") @QueryParam("depth") - int depth); + int depth, + @ApiParam( + name = "allowed", + value = "Whether to return allowed group", + defaultValue = "false") + @QueryParam("allowed") + @DefaultValue("false") + boolean allowed); @Path("/name/{groupName}") @GET diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/GroupManagementServiceImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/GroupManagementServiceImpl.java index de2991e7a7..4c43698395 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/GroupManagementServiceImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/GroupManagementServiceImpl.java @@ -176,10 +176,11 @@ public class GroupManagementServiceImpl implements GroupManagementService { } @Override - public Response getGroup(int groupId, boolean requireGroupProps, int depth) { + public Response getGroup(int groupId, boolean requireGroupProps, int depth, boolean allowed) { try { GroupManagementProviderService service = DeviceMgtAPIUtils.getGroupManagementProviderService(); - DeviceGroup deviceGroup = service.getGroup(groupId, requireGroupProps, depth); + DeviceGroup deviceGroup = allowed ? service.getUserOwnGroup(groupId, requireGroupProps, depth): + service.getGroup(groupId, requireGroupProps, depth); if (deviceGroup != null) { return Response.status(Response.Status.OK).entity(deviceGroup).build(); } else { diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/test/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/GroupManagementServiceImplTest.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/test/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/GroupManagementServiceImplTest.java index d648120b0d..4c069623c7 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/test/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/GroupManagementServiceImplTest.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/test/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/GroupManagementServiceImplTest.java @@ -176,13 +176,13 @@ public class GroupManagementServiceImplTest { Mockito.doReturn(new DeviceGroup()).when(groupManagementProviderService).getGroup(1, false, 1); Mockito.doReturn(null).when(groupManagementProviderService).getGroup(2, false, 1); Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).getGroup(3, false, 1); - Response response = groupManagementService.getGroup(1, false, 1); + Response response = groupManagementService.getGroup(1, false, 1, false); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "getGroup request failed for a request with valid parameters"); - response = groupManagementService.getGroup(2, false, 1); + response = groupManagementService.getGroup(2, false, 1, false); Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(), "getGroup request returned a group for a non-existing group"); - response = groupManagementService.getGroup(3, false, 1); + response = groupManagementService.getGroup(3, false, 1, false); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), "getGroup request returned a group for a in-valid request"); } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java index f7d8e533ea..657924ca80 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java @@ -1353,7 +1353,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { + "FROM DM_DEVICE d, " + "(SELECT dgm.DEVICE_ID " + "FROM DM_DEVICE_GROUP_MAP dgm " - + "WHERE dgm.GROUP_ID = (SELECT ID FROM DM_GROUP WHERE GROUP_NAME = ? )) dgm1 " + + "WHERE dgm.GROUP_ID = (SELECT ID FROM DM_GROUP WHERE GROUP_NAME = ? AND TENANT_ID = ?)) dgm1 " + "WHERE d.ID = dgm1.DEVICE_ID AND d.TENANT_ID = ?) gd, DM_DEVICE_TYPE t " + "WHERE gd.DEVICE_TYPE_ID = t.ID) d1 " + "WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ?"; @@ -1362,6 +1362,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { stmt.setString(1, groupName); stmt.setInt(2, tenantId); stmt.setInt(3, tenantId); + stmt.setInt(4, tenantId); try (ResultSet rs = stmt.executeQuery()) { devices = new ArrayList<>(); while (rs.next()) { diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java index 20d9bbd386..9447f6a9ea 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java @@ -351,4 +351,6 @@ public interface GroupManagementProviderService { * @throws GroupManagementException */ DeviceTypesOfGroups getDeviceTypesOfGroups(List identifiers) throws GroupManagementException; + + DeviceGroup getUserOwnGroup(int groupId, boolean requireGroupProps, int depth) throws GroupManagementException; } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderServiceImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderServiceImpl.java index d5ef09b14e..c63810fb1f 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderServiceImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderServiceImpl.java @@ -570,20 +570,28 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid String parentPath; List childrenGroups; if (StringUtils.isBlank(username)) { - GroupManagementDAOFactory.openConnection(); - rootGroups = groupDAO.getGroups(request, tenantId); - for (DeviceGroup rootGroup : rootGroups) { - parentPath = DeviceManagerUtil.createParentPath(rootGroup); - childrenGroups = groupDAO.getChildrenGroups(parentPath, tenantId); - createGroupWithChildren( - rootGroup, childrenGroups, requireGroupProps, tenantId, request.getDepth(), 0); - if (requireGroupProps) { - populateGroupProperties(rootGroup, tenantId); + try { + GroupManagementDAOFactory.openConnection(); + rootGroups = groupDAO.getGroups(request, tenantId); + for (DeviceGroup rootGroup : rootGroups) { + parentPath = DeviceManagerUtil.createParentPath(rootGroup); + childrenGroups = groupDAO.getChildrenGroups(parentPath, tenantId); + createGroupWithChildren( + rootGroup, childrenGroups, requireGroupProps, tenantId, request.getDepth(), 0); + if (requireGroupProps) { + populateGroupProperties(rootGroup, tenantId); + } } + } catch (SQLException e) { + String msg = "Error occurred while opening a connection to the data source to retrieve all groups " + + "with hierarchy"; + log.error(msg, e); + throw new GroupManagementException(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); } } else { List allDeviceGroupIdsOfUser = getGroupIds(username); - GroupManagementDAOFactory.openConnection(); rootGroups = this.getGroups(allDeviceGroupIdsOfUser, tenantId); if (requireGroupProps) { for (DeviceGroup rootGroup : rootGroups) { @@ -591,19 +599,12 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid } } } - } catch (GroupManagementDAOException e) { String msg = "Error occurred while retrieving all groups with hierarchy"; log.error(msg, e); throw new GroupManagementException(msg, e); - } catch (SQLException e) { - String msg = "Error occurred while opening a connection to the data source to retrieve all groups " - + "with hierarchy"; - log.error(msg, e); - throw new GroupManagementException(msg, e); - } finally { - GroupManagementDAOFactory.closeConnection(); } + PaginationResult groupResult = new PaginationResult(); groupResult.setData(rootGroups); if (StringUtils.isBlank(username)) { @@ -616,6 +617,7 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid private List getGroups(List groupIds, int tenantId) throws GroupManagementException { try { + GroupManagementDAOFactory.openConnection(); Listgroups = groupDAO.getGroups(groupIds, tenantId); if (groups == null) { String msg = "Retrieved null when getting groups for group ids " + groupIds.toString(); @@ -625,10 +627,17 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid if (groups.isEmpty()) return groups; groups.sort(Comparator.comparing(DeviceGroup::getGroupId)); return getTree(groups); + } catch (SQLException e) { + String msg = "Error occurred while opening a connection to the data source to retrieve all groups " + + "with hierarchy"; + log.error(msg, e); + throw new GroupManagementException(msg, e); } catch (GroupManagementDAOException ex) { String msg = "Error occurred while getting groups for group ids " + groupIds.toString(); log.error(msg, ex); throw new GroupManagementException(msg, ex); + } finally { + GroupManagementDAOFactory.closeConnection(); } } @@ -636,8 +645,8 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid List tree = new ArrayList<>(); for (DeviceGroup deviceGroup : groups) { DeviceGroup treeNode = tree.stream(). - filter(node -> deviceGroup.getParentPath(). - contains(Integer.toString(node.getGroupId()))). + filter(node -> Arrays.stream(deviceGroup.getParentPath().split("/")). + collect(Collectors.toList()).contains(Integer.toString(node.getGroupId()))). findFirst().orElse(null); if (treeNode != null) { if (Objects.equals(treeNode.getParentPath(), deviceGroup.getParentPath())) { @@ -657,6 +666,76 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid return tree; } + private DeviceGroup findGroupFromTree(List tree, int groupId) { + for (DeviceGroup node: tree) { + if (node.getGroupId() == groupId) return node; + if (node.getChildrenGroups() != null) { + DeviceGroup tempNode = findGroupFromTree(node.getChildrenGroups(), groupId); + if (tempNode != null) { + return tempNode; + } + } + } + return null; + } + + private boolean isAdminUser(String username, UserStoreManager userStoreManager) + throws GroupManagementException { + try { + if (!userStoreManager.isExistingUser(username)) { + String msg = "User doesn't exists with given username " + username; + throw new GroupManagementException(msg); + } + + String []currentRoles = userStoreManager.getRoleListOfUser(username); + for (String role : currentRoles) { + if (role.equals("admin")) return true; + } + + return false; + } catch (UserStoreException e) { + String msg = "Error occurred while requesting user details"; + log.error(msg, e); + throw new GroupManagementException(msg, e); + } + } + + @Override + public DeviceGroup getUserOwnGroup(int groupId, boolean requireGroupProps, int depth) throws GroupManagementException { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + String username = ctx.getUsername(); + int tenantId = ctx.getTenantId(); + try { + UserStoreManager userStoreManager = DeviceManagementDataHolder.getInstance(). + getRealmService().getTenantUserRealm(tenantId).getUserStoreManager(); + if (isAdminUser(username, userStoreManager)) { + return getGroup(groupId, requireGroupProps); + } + + List userOwnGroupIds = this.getGroupIds(username); + if (userOwnGroupIds == null) { + String msg = "Retrieved null when getting group ids for user " + username; + log.error(msg); + throw new GroupManagementException(msg); + } + + DeviceGroup deviceGroup = findGroupFromTree( + getGroups(userOwnGroupIds, tenantId), groupId); + if (deviceGroup != null && requireGroupProps) + populateGroupProperties(deviceGroup, tenantId); + + return deviceGroup; + } catch (UserStoreException e) { + String msg = "Error occurred while getting user store manager service"; + log.error(msg, e); + throw new GroupManagementException(msg, e); + } catch (GroupManagementDAOException e) { + String msg = "Error occurred while obtaining group '" + groupId + "'"; + log.error(msg, e); + throw new GroupManagementException(msg, e); + } + } + @Override public List getGroups(String username, boolean requireGroupProps) throws GroupManagementException { if (username == null || username.isEmpty()) {