From ca5d96df67df3c95a769fbf5441a7b6fb2c6135f Mon Sep 17 00:00:00 2001 From: charitha Date: Thu, 24 Nov 2016 13:29:25 +0530 Subject: [PATCH 1/4] Add test cases to verify DAO functionality --- .../mgt/core/dao/impl/GroupDAOImpl.java | 6 +- .../mgt/core/dao/GroupPersistTests.java | 84 ++++++++++++++++++- 2 files changed, 83 insertions(+), 7 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/GroupDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/GroupDAOImpl.java index 17810adf96..52dba3579a 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/GroupDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/GroupDAOImpl.java @@ -608,10 +608,10 @@ public class GroupDAOImpl implements GroupDAO { "(SELECT GROUP_ID FROM DM_ROLE_GROUP_MAP WHERE ROLE IN ("; int index = 0; - while (index++ < rolesCount) { - sql += (rolesCount - 1 != index) ? "?," : "?"; + while (index++ < rolesCount - 1) { + sql += "?,"; } - sql += ")) gr WHERE g.ID = gr.GROUP_ID AND TENANT_ID = ? GROUP BY g.ID"; + sql += "?)) gr WHERE g.ID = gr.GROUP_ID AND TENANT_ID = ? GROUP BY g.ID"; stmt = conn.prepareStatement(sql); index = 0; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/dao/GroupPersistTests.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/dao/GroupPersistTests.java index a82e19d8d4..1115faeab1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/dao/GroupPersistTests.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/dao/GroupPersistTests.java @@ -31,6 +31,7 @@ import org.wso2.carbon.device.mgt.core.common.BaseDeviceManagementTest; import org.wso2.carbon.device.mgt.core.common.TestDataHolder; import java.sql.SQLException; +import java.util.ArrayList; import java.util.List; public class GroupPersistTests extends BaseDeviceManagementTest { @@ -47,7 +48,7 @@ public class GroupPersistTests extends BaseDeviceManagementTest { } @Test - public void testAddGroupTest() { + public void addGroupTest() { DeviceGroup deviceGroup = TestDataHolder.generateDummyGroupData(); try { GroupManagementDAOFactory.beginTransaction(); @@ -72,7 +73,7 @@ public class GroupPersistTests extends BaseDeviceManagementTest { log.debug("Group name: " + group.getName()); } - @Test(dependsOnMethods = {"testAddGroupTest"}) + @Test(dependsOnMethods = {"addGroupTest"}) public void getGroupTest() { try { GroupManagementDAOFactory.openConnection(); @@ -96,7 +97,82 @@ public class GroupPersistTests extends BaseDeviceManagementTest { } } - @Test(dependsOnMethods = {"testAddGroupTest"}) + @Test(dependsOnMethods = {"addGroupTest"}) + public void shareGroupTest() { + try { + GroupManagementDAOFactory.beginTransaction(); + List addedRoles = new ArrayList<>(); + for (int i = 0; i < 3; i++) { + String role = "role-" + i; + groupDAO.addRole(groupId, role, TestDataHolder.SUPER_TENANT_ID); + addedRoles.add(role); + } + GroupManagementDAOFactory.commitTransaction(); + List roles = groupDAO.getRoles(groupId, TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(roles, addedRoles, "Added roles are not equal to returned roles."); + log.debug("Group shared with roles."); + } catch (GroupManagementDAOException e) { + String msg = "Error occurred while find group by name."; + log.error(msg, e); + Assert.fail(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while opening a connection to the data source."; + log.error(msg, e); + Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = {"shareGroupTest"}) + public void getShareGroupTest() { + try { + GroupManagementDAOFactory.openConnection(); + List roles = groupDAO.getRoles(groupId, TestDataHolder.SUPER_TENANT_ID); + roles.remove(0); + List deviceGroups = groupDAO.getGroups(roles.toArray(new String[roles.size()]), TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(deviceGroups.size(), 1, "Unexpected number of device groups found with role."); + Assert.assertEquals(deviceGroups.get(0).getGroupId(), groupId, "Unexpected groupId found with role."); + log.debug("Group found for given roles."); + } catch (GroupManagementDAOException e) { + String msg = "Error occurred while getting groups shared with roles."; + log.error(msg, e); + Assert.fail(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while opening a connection to the data source."; + log.error(msg, e); + Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = {"getShareGroupTest"}) + public void unshareGroupTest() { + try { + GroupManagementDAOFactory.beginTransaction(); + List rolesToRemove = groupDAO.getRoles(groupId, TestDataHolder.SUPER_TENANT_ID); + for (String role : rolesToRemove) { + groupDAO.removeRole(groupId, role, TestDataHolder.SUPER_TENANT_ID); + } + GroupManagementDAOFactory.commitTransaction(); + List roles = groupDAO.getRoles(groupId, TestDataHolder.SUPER_TENANT_ID); + Assert.assertNotEquals(roles, rolesToRemove, "Roles not removed."); + log.debug("Group unshared with given roles."); + } catch (GroupManagementDAOException e) { + String msg = "Error occurred while find group by name."; + log.error(msg, e); + Assert.fail(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while opening a connection to the data source."; + log.error(msg, e); + Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = {"addGroupTest"}) public void addDeviceToGroupTest() { Device initialTestDevice = TestDataHolder.initialTestDevice; DeviceGroup deviceGroup = getGroupById(groupId); @@ -162,7 +238,7 @@ public class GroupPersistTests extends BaseDeviceManagementTest { } } - @Test(dependsOnMethods = {"removeDeviceFromGroupTest"}) + @Test(dependsOnMethods = {"removeDeviceFromGroupTest", "unshareGroupTest"}) public void updateGroupTest() { String name = "Test Updated"; String desc = "Desc updated"; From 3fe18ba4bb7ce5f3931b1abb170901fa1532768e Mon Sep 17 00:00:00 2001 From: Rasika Perera Date: Fri, 25 Nov 2016 08:17:39 +0530 Subject: [PATCH 2/4] Refactoring group sharing modal --- .../app/pages/cdmf.page.groups/groups.hbs | 136 +++++----- .../app/pages/cdmf.page.groups/groups.js | 4 + .../cdmf.page.groups/public/js/listing.js | 247 +++++++----------- 3 files changed, 169 insertions(+), 218 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.groups/groups.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.groups/groups.hbs index 5bc33e4377..ad4c096949 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.groups/groups.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.groups/groups.hbs @@ -80,7 +80,7 @@ - - -
- - -
@@ -201,25 +171,10 @@

Enter Group Sharing Role Name

- -

- Role Permissions +

- - - {{#each groupPermissions}} - - - - - {{/each}} - -
{{this}} - - - -
+ +
+
+
+
+

New Role was successfully created.

+
+ Do you need to Add / Remove users to the chosen roles? + +
@@ -256,7 +247,8 @@ Yes - + Cancel
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.groups/groups.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.groups/groups.js index 0c04f9bb2d..f432193231 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.groups/groups.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.groups/groups.js @@ -23,6 +23,10 @@ function onRequest(context) { var groupPermissions = require("/app/pages/cdmf.page.groups/public/group-permissions.json"); var currentUser = session.get(constants.USER_SESSION_KEY); var page = {}; + var rolesResult = userModule.getRoles(); + if (rolesResult.status == "success") { + page.userRoles = rolesResult.content; + } if (currentUser) { page.permissions = userModule.getUIPermissions(); page.permissions.list = stringify(page.permissions); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.groups/public/js/listing.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.groups/public/js/listing.js index 1770cd26c4..1548ff4c71 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.groups/public/js/listing.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.groups/public/js/listing.js @@ -110,12 +110,12 @@ function loadGroups() { var objects = []; $(data.deviceGroups).each(function (index) { objects.push({ - groupId: data.deviceGroups[index].id, - name: data.deviceGroups[index].name, - description: data.deviceGroups[index].description, - owner: data.deviceGroups[index].owner, - dateOfCreation: data.deviceGroups[index].dateOfCreation - }) + groupId: data.deviceGroups[index].id, + name: data.deviceGroups[index].name, + description: data.deviceGroups[index].description, + owner: data.deviceGroups[index].owner, + dateOfCreation: data.deviceGroups[index].dateOfCreation + }) }); var json = { "recordsTotal": data.count, @@ -154,34 +154,50 @@ function loadGroups() { class: 'text-right content-fill text-left-on-grid-view no-wrap', render: function (id, type, row, meta) { var html; - if ($.hasPermission("VIEW_GROUP_DEVICES")){ - html = '' + - '' + - ''; - - html += '' + - '' + - ''; + if ($.hasPermission("VIEW_GROUP_DEVICES")) { + html = '' + + '' + + + ''; + + html += '' + + '' + + + ''; } else { html = ''; } - if($.hasPermission("SHARE_GROUP")) { - html += ''; } else { html += ''; } - if($.hasPermission("UPDATE_GROUP")) { - html += '' + + if ($.hasPermission("UPDATE_GROUP")) { + html += + '' + ''; } else { html += ''; } if ($.hasPermission("REMOVE_GROUP")) { - html += '' + + html += + '' + + ''; } else { html += ''; @@ -336,7 +352,7 @@ function hidePopup() { $(modalPopupContent).html(""); $(modalPopupContent).removeClass("operation-data"); $(modalPopup).modal('hide'); - $('body').removeClass('modal-open').css('padding-right','0px'); + $('body').removeClass('modal-open').css('padding-right', '0px'); $('.modal-backdrop').remove(); } @@ -352,33 +368,37 @@ function attachEvents() { $("a.share-group-link").click(function () { var groupId = $(this).data("group-id"); var groupOwner = $(this).data("group-owner"); + $(modalPopupContent).html($('#share-group-w1-modal-content').html()); - $("a#share-group-next-link").show(); showPopup(); - $("a#share-group-next-link").click(function () { - var successCallback = function (data) { - if(data === 'true') { - getAllRoles(groupId, selectedUser); - } else { - var errorMsgWrapper = "#notification-error-msg"; - var errorMsg = "#notification-error-msg span"; - $(errorMsg).text("User does not exist."); - $(errorMsgWrapper).removeClass("hidden"); + + markAlreadySavedUsersRoles(groupId); + var shareGroupNextLink = $("a#share-group-next-link"); + shareGroupNextLink.click(function () { + var roles = []; + $('.modal .roleCheckBoxes').each( + function () { + if ($(this).is(':checked')) { + roles.push($(this).data('role-name')); + } } - } - var selectedUser = $('#share-user-selector').val(); - if (selectedUser == $("#group-listing").data("current-user")) { - $("#user-names").html("Please specify a user other than current user."); - $("a#share-group-next-link").hide(); - } else { - invokerUtil.get("/api/device-mgt/v1.0/users/checkUser?username=" + selectedUser, - successCallback, function (message) { - displayErrors(message); - }); - } + ); + updateGroupShare(groupId, roles); }); - $("a#share-group-w1-cancel-link").click(function () { - hidePopup(); + + var shareGroupNewRoleFromSelectionLink = $("a#share-group-new-role-from-selection"); + shareGroupNewRoleFromSelectionLink.click(function () { + var roles = []; + $('.modal .roleCheckBoxes').each( + function () { + if ($(this).is(':checked')) { + roles.push($(this).data('role-name')); + } + } + ); + addNewRole(roles); + // $(modalPopupContent).html($('#share-group-w3-modal-content').html()); + // createNewRole(roles); }); }); @@ -408,8 +428,8 @@ function attachEvents() { }; invokerUtil.delete("/api/device-mgt/v1.0/groups/id/" + groupId, - successCallback, function (message) { - displayErrors(message); + successCallback, function (message) { + displayErrors(message); }); }); @@ -453,8 +473,8 @@ function attachEvents() { }; invokerUtil.put("/api/device-mgt/v1.0/groups/id/" + groupId, group, - successCallback, function (message) { - displayErrors(message); + successCallback, function (message) { + displayErrors(message); }); }); @@ -464,16 +484,22 @@ function attachEvents() { }); } -function getAllRoles(groupId, selectedUser) { - $(modalPopupContent).html($('#share-group-w2-modal-content').html()); - $("a#share-group-yes-link").hide(); +function markAlreadySavedUsersRoles(groupId) { var successCallback = function (data, textStatus, xhr) { data = JSON.parse(data); if (xhr.status == 200) { if (data.roles.length > 0) { - generateRoleMap(groupId, selectedUser, data.roles); + for (var i = 0; i < data.roles.length; i++) { + $('.roleCheckBoxes').each( + function () { + if (data.roles[i] == $(this).data('role-name')) { + $(this).attr('checked', true); + } + } + ); + } } else { - $('#user-roles').html("There is no any roles for this group."); + return; } } else { displayErrors(xhr); @@ -481,98 +507,17 @@ function getAllRoles(groupId, selectedUser) { }; invokerUtil.get("/api/device-mgt/v1.0/groups/id/" + groupId + "/roles", - successCallback, function (message) { - displayErrors(message); - }); - - $("a#share-group-w2-cancel-link").click(function () { - hidePopup(); - }); -} - -function generateRoleMap(groupId, selectedUser, allRoles) { - var successCallback = function (data, textStatus, xhr) { - data = JSON.parse(data); - if (xhr.status == 200) { - var userRoles = []; - if(data != "EMPTY") { - userRoles = data.roles; - } - var str = $('#user-roles').html(); - - for (var i = 0; i < allRoles.length; i++) { - var isChecked = ''; - for (var j = 0; j < userRoles.length; j++) { - if (allRoles[i] == userRoles[j]) { - isChecked = 'checked'; - break; - } - } - str += '

'; - } - - $('#user-roles').html(str); - $("a#share-group-yes-link").show(); - $("a#share-group-yes-link").show(); - $("a#share-group-yes-link").click(function () { - var roles = []; - for (var i = 0; i < allRoles.length; i++) { - if ($('#user-role-' + allRoles[i]).is(':checked')) { - roles.push(allRoles[i]); - } - } - updateGroupShare(groupId, selectedUser, roles); - }); - $("a#share-group-w2-add-new-role-link").click(function () { - addNewRole(groupId, selectedUser, allRoles); - }); - } else { - displayErrors(xhr); - } - }; - - invokerUtil.get("/api/device-mgt/v1.0/groups/id/" + groupId + "/roles?userName=" + selectedUser, - successCallback, function (message) { + successCallback, function (message) { displayErrors(message); }); - - $("a#share-group-w2-cancel-link").click(function () { - hidePopup(); - }); } -function addNewRole(groupId, selectedUser, allRoles) { +function addNewRole(roles) { $(modalPopupContent).html($('#share-group-w3-modal-content').html()); - function getPermissions() { - var PERMISSION_PREFIX = '/permission/admin/'; - var permissions = []; - $('#permission-table-container').find('tr').each(function () { - var row = $(this).closest('tr'); - var permission = $(row).find('td:nth-child(1)').text(); - var check = $(row).find('td:nth-child(2) a').data('value'); - if(check === 'checked') { - permission = PERMISSION_PREFIX + permission; - permissions.push(permission); - } - }); - return permissions; - }; $("a#share-group-w3-yes-link").click(function () { - var successCallback = function (data, status, jqXHR) { - if(status == "success") { - getAllRoles(groupId, selectedUser); - } - } var roleName = $('#group-sharing-role-name').val(); - var users = []; - if(roleName) { - var groupRoleInfo = {"roleName": roleName, "permissions": getPermissions(), "users": users}; - var currentUser = $("#group-listing").data("current-user"); - invokerUtil.post("/api/device-mgt/v1.0/groups/id/" + groupId + "/roles/create?userName=" + currentUser, - groupRoleInfo, successCallback, function (message) { - displayErrors(message); - }); + if (roleName) { + createNewCombinedRole(roleName, roles); } else { var errorMsgWrapper = "#notification-error-msg"; var errorMsg = "#notification-error-msg span"; @@ -588,7 +533,7 @@ function addNewRole(groupId, selectedUser, allRoles) { function togglePermissionAction(element) { $(element).data('value', 'checked'); var icon = $(element).find("i")[1]; - if($(icon).hasClass('fw-minus')) { + if ($(icon).hasClass('fw-minus')) { $(icon).removeClass('fw-minus'); $(icon).addClass('fw-add'); $(element).data('value', 'unchecked'); @@ -599,7 +544,7 @@ function togglePermissionAction(element) { } } -function updateGroupShare(groupId, selectedUser, roles) { +function updateGroupShare(groupId, roles) { var successCallback = function (data) { $(modalPopupContent).html($('#share-group-200-content').html()); setTimeout(function () { @@ -608,11 +553,21 @@ function updateGroupShare(groupId, selectedUser, roles) { }, 2000); }; - var deviceGroupShare = {"username": selectedUser, "groupRoles": roles }; invokerUtil.post("/api/device-mgt/v1.0/groups/id/" + groupId + "/share", - deviceGroupShare, successCallback, function (message) { - displayErrors(message); - }); + roles, successCallback, function (message) { + displayErrors(message); + }); +} + +function createNewCombinedRole(roleName, roleList) { + var successCallback = function (data, status, jqXHR, isLast) { + $(modalPopupContent).html($('#create-combined-role-200-content').html()); + showPopup(); + }; + invokerUtil.post("/api/device-mgt/v1.0/roles/create-combined-role/" + roleName, roleList, + successCallback, function (message) { + displayErrors(message); + }); } function displayErrors(jqXHR) { From aaade2363ca5f0ba238ac25de78344c34c2cd33d Mon Sep 17 00:00:00 2001 From: Rasika Perera Date: Fri, 25 Nov 2016 08:18:10 +0530 Subject: [PATCH 3/4] Adding new api to create combined roles --- .../service/api/RoleManagementService.java | 64 ++++++++ .../impl/RoleManagementServiceImpl.java | 142 ++++++++++++++++-- 2 files changed, 190 insertions(+), 16 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/RoleManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/RoleManagementService.java index cc2fef4ff2..cc894b9c0b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/RoleManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/RoleManagementService.java @@ -356,6 +356,70 @@ public interface RoleManagementService { value = "The properties required to add a new role.", required = true) RoleInfo role); + @POST + @Path("/create-combined-role/{roleName}") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Adding a combined Role", + notes = "WSO2 EMM supports role-based access control (RBAC) and role management. Add a new combined role to WSO2 EMM using this REST API.", + tags = "Role Management", + authorizations = { + @Authorization( + value="permission", + scopes = { @AuthorizationScope(scope = "/device-mgt/roles/manage", + description = "Manage Roles") } + ) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 201, + message = "Created. \n Successfully created the role.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The URL to the newly added role."), + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 303, + message = "See Other. \n The source can be retrieved from the URL specified in the location header.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while adding a new role.", + response = ErrorResponse.class) + }) + Response addCombinedRole( + @ApiParam( + name = "roles", + value = "List of roles names required to add a new combined role.", + required = true) List roles, + @PathParam("roleName") String roleName, + @QueryParam("user-store") String userStoreName); + @PUT @Path("/{roleName}") @ApiOperation( diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/RoleManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/RoleManagementServiceImpl.java index 29db06c3d0..35ccabfab3 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/RoleManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/RoleManagementServiceImpl.java @@ -30,13 +30,26 @@ import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.FilteringUtil; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; import org.wso2.carbon.device.mgt.jaxrs.util.SetReferenceTransformer; -import org.wso2.carbon.user.api.*; +import org.wso2.carbon.user.api.AuthorizationManager; +import org.wso2.carbon.user.api.Permission; +import org.wso2.carbon.user.api.UserRealm; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; import org.wso2.carbon.user.core.common.AbstractUserStoreManager; import org.wso2.carbon.user.mgt.UserRealmProxy; import org.wso2.carbon.user.mgt.common.UIPermissionNode; import org.wso2.carbon.user.mgt.common.UserAdminException; -import javax.ws.rs.*; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.UnsupportedEncodingException; @@ -45,7 +58,9 @@ import java.net.URISyntaxException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import static org.wso2.carbon.device.mgt.jaxrs.util.Constants.PRIMARY_USER_STORE; @@ -69,7 +84,7 @@ public class RoleManagementServiceImpl implements RoleManagementService { RoleList targetRoles = new RoleList(); //if user store is null set it to primary - if(userStore == null || "".equals(userStore)){ + if (userStore == null || "".equals(userStore)) { userStore = PRIMARY_USER_STORE; } @@ -94,7 +109,8 @@ public class RoleManagementServiceImpl implements RoleManagementService { @Path("/{roleName}/permissions") @Override public Response getPermissionsOfRole(@PathParam("roleName") String roleName, - @QueryParam("user-store") String userStoreName, @HeaderParam("If-Modified-Since") String ifModifiedSince) { + @QueryParam("user-store") String userStoreName, + @HeaderParam("If-Modified-Since") String ifModifiedSince) { if (userStoreName != null && !userStoreName.isEmpty()) { roleName = userStoreName + "/" + roleName; } @@ -166,7 +182,7 @@ public class RoleManagementServiceImpl implements RoleManagementService { @Path("/{roleName}") @Override public Response getRole(@PathParam("roleName") String roleName, @QueryParam("user-store") String userStoreName, - @HeaderParam("If-Modified-Since") String ifModifiedSince) { + @HeaderParam("If-Modified-Since") String ifModifiedSince) { if (log.isDebugEnabled()) { log.debug("Getting the list of user roles"); } @@ -181,7 +197,7 @@ public class RoleManagementServiceImpl implements RoleManagementService { if (!userStoreManager.isExistingRole(roleName)) { return Response.status(404).entity( new ErrorResponse.ErrorResponseBuilder().setMessage("No role exists with the name '" + - roleName + "'").build()).build(); + roleName + "'").build()).build(); } roleInfo.setRoleName(roleName); roleInfo.setUsers(userStoreManager.getUserListOfRole(roleName)); @@ -235,7 +251,7 @@ public class RoleManagementServiceImpl implements RoleManagementService { //TODO fix what's returned in the entity return Response.created(new URI(API_BASE_PATH + "/" + URLEncoder.encode(roleInfo.getRoleName(), "UTF-8"))). entity("Role '" + roleInfo.getRoleName() + "' has " + "successfully been" - + " added").build(); + + " added").build(); } catch (UserStoreException e) { String msg = "Error occurred while adding role '" + roleInfo.getRoleName() + "'"; log.error(msg, e); @@ -255,11 +271,76 @@ public class RoleManagementServiceImpl implements RoleManagementService { } } + @POST + @Path("/create-combined-role/{roleName}") + @Override + public Response addCombinedRole(List roles, @PathParam("roleName") String roleName, + @QueryParam("user-store") String userStoreName) { + if (userStoreName != null && !userStoreName.isEmpty()) { + roleName = userStoreName + "/" + roleName; + } + if (roles.size() < 2) { + return Response.status(400).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("Combining Roles requires at least two roles.") + .build() + ).build(); + } + for (String role : roles) { + RequestValidationUtil.validateRoleName(role); + } + try { + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + if (log.isDebugEnabled()) { + log.debug("Persisting the role in the underlying user store"); + } + + HashSet permsSet = new HashSet<>(); + try { + for (String role : roles) { + mergePermissions(new UIPermissionNode[]{getRolePermissions(role)}, permsSet); + } + } catch (IllegalArgumentException e) { + return Response.status(404).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(e.getMessage()).build() + ).build(); + } + + Permission[] permissions = permsSet.toArray(new Permission[permsSet.size()]); + userStoreManager.addRole(roleName, new String[0], permissions); + + //TODO fix what's returned in the entity + return Response.created(new URI(API_BASE_PATH + "/" + URLEncoder.encode(roleName, "UTF-8"))). + entity("Role '" + roleName + "' has " + "successfully been" + + " added").build(); + } catch (UserAdminException e) { + String msg = "Error occurred while retrieving the permissions of role '" + roleName + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (UserStoreException e) { + String msg = "Error occurred while adding role '" + roleName + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (URISyntaxException e) { + String msg = "Error occurred while composing the URI at which the information of the newly created role " + + "can be retrieved"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (UnsupportedEncodingException e) { + String msg = "Error occurred while encoding role name"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + @PUT @Path("/{roleName}") @Override public Response updateRole(@PathParam("roleName") String roleName, RoleInfo roleInfo, - @QueryParam("user-store") String userStoreName) { + @QueryParam("user-store") String userStoreName) { if (userStoreName != null && !userStoreName.isEmpty()) { roleName = userStoreName + "/" + roleName; } @@ -271,7 +352,7 @@ public class RoleManagementServiceImpl implements RoleManagementService { if (!userStoreManager.isExistingRole(roleName)) { return Response.status(404).entity( new ErrorResponse.ErrorResponseBuilder().setMessage("No role exists with the name '" + - roleName + "'").build()).build(); + roleName + "'").build()).build(); } final AuthorizationManager authorizationManager = userRealm.getAuthorizationManager(); @@ -287,7 +368,7 @@ public class RoleManagementServiceImpl implements RoleManagementService { if (roleInfo.getUsers() != null) { SetReferenceTransformer transformer = new SetReferenceTransformer<>(); transformer.transform(Arrays.asList(userStoreManager.getUserListOfRole(newRoleName)), - Arrays.asList(roleInfo.getUsers())); + Arrays.asList(roleInfo.getUsers())); final String[] usersToAdd = transformer.getObjectsToAdd().toArray(new String[transformer .getObjectsToAdd().size()]); final String[] usersToDelete = transformer.getObjectsToRemove().toArray(new String[transformer @@ -307,7 +388,7 @@ public class RoleManagementServiceImpl implements RoleManagementService { } //TODO: Need to send the updated role information in the entity back to the client return Response.status(Response.Status.OK).entity("Role '" + roleInfo.getRoleName() + "' has " + - "successfully been updated").build(); + "successfully been updated").build(); } catch (UserStoreException e) { String msg = "Error occurred while updating role '" + roleName + "'"; log.error(msg, e); @@ -330,7 +411,7 @@ public class RoleManagementServiceImpl implements RoleManagementService { if (!userStoreManager.isExistingRole(roleName)) { return Response.status(404).entity( new ErrorResponse.ErrorResponseBuilder().setMessage("No role exists with the name '" + - roleName + "'").build()).build(); + roleName + "'").build()).build(); } final AuthorizationManager authorizationManager = userRealm.getAuthorizationManager(); @@ -354,7 +435,7 @@ public class RoleManagementServiceImpl implements RoleManagementService { @Path("/{roleName}/users") @Override public Response updateUsersOfRole(@PathParam("roleName") String roleName, - @QueryParam("user-store") String userStoreName, List users) { + @QueryParam("user-store") String userStoreName, List users) { if (userStoreName != null && !userStoreName.isEmpty()) { roleName = userStoreName + "/" + roleName; } @@ -367,7 +448,7 @@ public class RoleManagementServiceImpl implements RoleManagementService { } SetReferenceTransformer transformer = new SetReferenceTransformer<>(); transformer.transform(Arrays.asList(userStoreManager.getUserListOfRole(roleName)), - users); + users); final String[] usersToAdd = transformer.getObjectsToAdd().toArray(new String[transformer .getObjectsToAdd().size()]); final String[] usersToDelete = transformer.getObjectsToRemove().toArray(new String[transformer @@ -376,7 +457,8 @@ public class RoleManagementServiceImpl implements RoleManagementService { userStoreManager.updateUserListOfRole(roleName, usersToDelete, usersToAdd); return Response.status(Response.Status.OK).entity("Role '" + roleName + "' has " + - "successfully been updated with the user list").build(); + "successfully been updated with the user list") + .build(); } catch (UserStoreException e) { String msg = "Error occurred while updating the users of the role '" + roleName + "'"; log.error(msg, e); @@ -400,7 +482,8 @@ public class RoleManagementServiceImpl implements RoleManagementService { // removing all internal roles, roles created for Service-providers and application related roles. List filteredRoles = new ArrayList<>(); for (String role : roles) { - if (!(role.startsWith("Internal/") || role.startsWith("Authentication/") || role.startsWith("Application/"))) { + if (!(role.startsWith("Internal/") || role.startsWith("Authentication/") || role.startsWith( + "Application/"))) { if (!filterRolesByName) { filteredRoles.add(role); } else { @@ -413,4 +496,31 @@ public class RoleManagementServiceImpl implements RoleManagementService { return filteredRoles; } + private Set mergePermissions(UIPermissionNode[] permissionNodes, Set permissions) + throws UserStoreException, UserAdminException { + for (UIPermissionNode permissionNode : permissionNodes) { + if (permissionNode.getNodeList().length > 0) { + mergePermissions(permissionNode.getNodeList(), permissions); + } + if (permissionNode.isSelected()) { + permissions.add(new Permission(permissionNode.getResourcePath(), CarbonConstants.UI_PERMISSION_ACTION)); + } + } + return permissions; + } + + private UIPermissionNode getRolePermissions(String roleName) throws UserStoreException, UserAdminException { + final UserRealm userRealm = DeviceMgtAPIUtils.getUserRealm(); + if (!userRealm.getUserStoreManager().isExistingRole(roleName)) { + throw new IllegalArgumentException("No role exists with the name '" + roleName + "'"); + } + + final UIPermissionNode rolePermissions = this.getUIPermissionNode(roleName, userRealm); + if (rolePermissions == null) { + if (log.isDebugEnabled()) { + log.debug("No permissions found for the role '" + roleName + "'"); + } + } + return rolePermissions; + } } From 05453e737928db6d7ccebefcdddcb0738468fdbd Mon Sep 17 00:00:00 2001 From: Rasika Perera Date: Fri, 25 Nov 2016 10:35:45 +0530 Subject: [PATCH 4/4] Removed 'role' suffix from roles listing page --- .../app/pages/cdmf.page.roles/public/js/role-listing.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.roles/public/js/role-listing.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.roles/public/js/role-listing.js index 0bf58e868f..de38fad9a6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.roles/public/js/role-listing.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.roles/public/js/role-listing.js @@ -131,7 +131,7 @@ function loadRoles() { class: "fade-edge", data: "name", render: function (name, type, row, meta) { - return '

' + name + 'role

'; + return '

' + name + '

'; } }, {