From e651645fad1057d90eecc8d0e94c846cdfdf16de Mon Sep 17 00:00:00 2001 From: Jayasanka Weerasinghe Date: Tue, 24 Mar 2020 19:14:44 +0530 Subject: [PATCH] Create an endpoint to get permissions of a given user --- .../mgt/jaxrs/beans/PermissionList.java | 41 +++++++++++ .../service/api/UserManagementService.java | 53 ++++++++++++++ .../impl/RoleManagementServiceImpl.java | 20 +---- .../impl/UserManagementServiceImpl.java | 73 +++++++++++++++++++ .../mgt/jaxrs/util/DeviceMgtAPIUtils.java | 24 ++++++ .../src/main/resources/conf/mdm-ui-config.xml | 1 + 6 files changed, 193 insertions(+), 19 deletions(-) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PermissionList.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PermissionList.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PermissionList.java new file mode 100644 index 00000000000..9ec30f2ebaa --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PermissionList.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.io.Serializable; +import java.util.List; + +@ApiModel(value = "Permission List") +public class PermissionList implements Serializable { + + private List permissions; + + @ApiModelProperty(value = "Returns the list of permissions") + @JsonProperty("permissions") + public List getList() { + return permissions; + } + + public void setList(List roles) { + this.permissions = roles; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java index 9faf6d7ac2e..397c35b3365 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java @@ -57,6 +57,7 @@ import org.wso2.carbon.device.mgt.jaxrs.beans.Credential; import org.wso2.carbon.device.mgt.jaxrs.beans.EnrollmentInvitation; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.beans.OldPasswordResetWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.PermissionList; import org.wso2.carbon.device.mgt.jaxrs.beans.RoleList; import org.wso2.carbon.device.mgt.jaxrs.beans.UserInfo; import org.wso2.carbon.device.mgt.jaxrs.util.Constants; @@ -164,6 +165,12 @@ import java.util.List; description = "Get activities", key = "perm:get-activity", permissions = {"/device-mgt/devices/owning-device/view"} + ), + @Scope( + name = "Getting the Permissions of the User", + description = "Getting the Permissions of the User", + key = "perm:user:permission-view", + permissions = {"/login"} ) } ) @@ -1168,4 +1175,50 @@ public interface UserManagementService { required = true, defaultValue = "admin") @PathParam("username") String username); + + @GET + @Path("/current-user/permissions") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting the permission details of the current user", + notes = "A user may granted more than one permission in IoTS. Using this REST API " + + "you can get the permission/permission the current user has granted. ", + tags = "User Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:user:permission-view") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of permissions the user " + + "has granted.", + response = PermissionList.class, + responseHeaders = { + @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 was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist.\n", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the " + + "list of roles assigned to the specified user.", + response = ErrorResponse.class) + }) + Response getPermissionsOfUser(); } 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 6c1600d3d47..33ef151a4e6 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 @@ -257,7 +257,7 @@ public class RoleManagementServiceImpl implements RoleManagementService { // Get the permission nodes and hand picking only device management and login perms final UIPermissionNode rolePermissions = this.getUIPermissionNode(roleName, userRealm); List permList = new ArrayList<>(); - this.iteratePermissions(rolePermissions, permList); + DeviceMgtAPIUtils.iteratePermissions(rolePermissions, permList); roleInfo.setPermissionList(rolePermissions); String[] permListAr = new String[permList.size()]; roleInfo.setPermissions(permList.toArray(permListAr)); @@ -278,24 +278,6 @@ public class RoleManagementServiceImpl implements RoleManagementService { } } - private List iteratePermissions(UIPermissionNode uiPermissionNode, List list) { - //To prevent NullPointer exceptions - if (uiPermissionNode == null) { - return list; - } - for (UIPermissionNode permissionNode : uiPermissionNode.getNodeList()) { - if (permissionNode != null) { - list.add(permissionNode.getResourcePath()); - if (permissionNode.getNodeList() != null - && permissionNode.getNodeList().length > 0) { - iteratePermissions(permissionNode, list); - } - } - } - return list; - } - - private List getAuthorizedPermissions(UIPermissionNode uiPermissionNode, List list) { for (UIPermissionNode permissionNode : uiPermissionNode.getNodeList()) { if (permissionNode.isSelected()) { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java index a059ce3c474..5d5b0572964 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java @@ -40,6 +40,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpStatus; import org.eclipse.wst.common.uriresolver.internal.util.URIEncoder; +import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; @@ -57,6 +58,7 @@ import org.wso2.carbon.device.mgt.jaxrs.beans.Credential; import org.wso2.carbon.device.mgt.jaxrs.beans.EnrollmentInvitation; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.beans.OldPasswordResetWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.PermissionList; import org.wso2.carbon.device.mgt.jaxrs.beans.RoleList; import org.wso2.carbon.device.mgt.jaxrs.beans.UserInfo; import org.wso2.carbon.device.mgt.jaxrs.exception.BadRequestException; @@ -74,6 +76,9 @@ import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreManager; import org.wso2.carbon.user.core.UserCoreConstants; import org.wso2.carbon.user.core.service.RealmService; +import org.wso2.carbon.user.mgt.UserRealmProxy; +import org.wso2.carbon.user.mgt.common.UIPermissionNode; +import org.wso2.carbon.user.mgt.common.UserAdminException; import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.multitenancy.MultitenantConstants; @@ -1029,6 +1034,48 @@ public class UserManagementServiceImpl implements UserManagementService { } } + @GET + @Override + @Path("/current-user/permissions") + public Response getPermissionsOfUser() { + String username = CarbonContext.getThreadLocalCarbonContext().getUsername(); + try { + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + if (!userStoreManager.isExistingUser(username)) { + String message = "User by username: " + username + " does not exist for permission retrieval."; + log.error(message); + return Response.status(Response.Status.NOT_FOUND) + .entity(new ErrorResponse.ErrorResponseBuilder().setMessage(message).build()).build(); + } + // Get a list of roles which the user assigned to + List roles = getFilteredRoles(userStoreManager, username); + List permissions = new ArrayList<>(); + UserRealm userRealm = DeviceMgtAPIUtils.getUserRealm(); + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + // Get permissions for each role + for (String roleName : roles) { + try { + permissions.addAll(getPermissionsListFromRole(roleName, userRealm, tenantId)); + } catch (UserAdminException e) { + String message = "Error occurred while retrieving the permissions of role '" + roleName + "'"; + log.error(message, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(new ErrorResponse.ErrorResponseBuilder().setMessage(message).build()) + .build(); + } + } + PermissionList permissionList = new PermissionList(); + permissionList.setList(permissions); + return Response.status(Response.Status.OK).entity(permissionList).build(); + } catch (UserStoreException e) { + String message = "Error occurred while trying to retrieve roles of the user '" + username + "'"; + log.error(message, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(new ErrorResponse.ErrorResponseBuilder().setMessage(message).build()) + .build(); + } + } + private Map buildDefaultUserClaims(String firstName, String lastName, String emailAddress, boolean isFresh) { Map defaultUserClaims = new HashMap<>(); @@ -1174,4 +1221,30 @@ public class UserManagementServiceImpl implements UserManagementService { private boolean skipSearch(List commonUsers) { return commonUsers != null && commonUsers.size() == 0; } + + /** + * Returns a list of permissions of a given role + * @param roleName name of the role + * @param tenantId the user's tenetId + * @param userRealm user realm of the tenant + * @return list of permissions + * @throws UserAdminException If unable to get the permissions + */ + private static List getPermissionsListFromRole(String roleName, UserRealm userRealm, int tenantId) + throws UserAdminException { + org.wso2.carbon.user.core.UserRealm userRealmCore; + try { + userRealmCore = (org.wso2.carbon.user.core.UserRealm) userRealm; + } catch (ClassCastException e) { + String message = "Provided UserRealm object is not an instance of org.wso2.carbon.user.core.UserRealm"; + log.error(message, e); + throw new UserAdminException(message, e); + } + UserRealmProxy userRealmProxy = new UserRealmProxy(userRealmCore); + List permissionsList = new ArrayList<>(); + final UIPermissionNode rolePermissions = userRealmProxy.getRolePermissions(roleName, tenantId); + DeviceMgtAPIUtils.iteratePermissions(rolePermissions, permissionsList); + return permissionsList; + } + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java index f6796a62174..5f2fc3cbf21 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java @@ -82,6 +82,7 @@ import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreManager; import org.wso2.carbon.user.core.jdbc.JDBCUserStoreManager; import org.wso2.carbon.user.core.service.RealmService; +import org.wso2.carbon.user.mgt.common.UIPermissionNode; import javax.cache.Cache; import javax.cache.Caching; @@ -781,4 +782,27 @@ public class DeviceMgtAPIUtils { typeVersion.setVersionStatus(deviceTypeVersion.getVersionStatus()); return typeVersion; } + + /** + * Extract permissions from a UiPermissionNode using recursions + * @param uiPermissionNode an UiPermissionNode Object to extract permissions + * @param list provided list to add permissions + */ + public static void iteratePermissions(UIPermissionNode uiPermissionNode, List list) { + // To prevent NullPointer exceptions + if (uiPermissionNode == null) { + return; + } + for (UIPermissionNode permissionNode : uiPermissionNode.getNodeList()) { + if (permissionNode != null) { + if(permissionNode.isSelected()){ + list.add(permissionNode.getResourcePath()); + } + if (permissionNode.getNodeList() != null + && permissionNode.getNodeList().length > 0) { + iteratePermissions(permissionNode, list); + } + } + } + } } diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml index ff0753ee1f5..ba0af7305a5 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml @@ -145,6 +145,7 @@ perm:devices:permanent-delete perm:android:manage-configuration perm:android:view-configuration + perm:user:permission-view device-mgt