From 38cdd94f3c74608091ce1e6be325121bb5d290a8 Mon Sep 17 00:00:00 2001 From: Rasika Perera Date: Tue, 3 May 2016 00:33:19 +0530 Subject: [PATCH] Adding group permission checking for Device Access Authorizations --- .../DeviceAccessAuthorizationService.java | 26 +++ .../DeviceAccessAuthorizationServiceImpl.java | 220 +++++++++--------- .../internal/DeviceManagementDataHolder.java | 11 + .../DeviceManagementServiceComponent.java | 1 + 4 files changed, 146 insertions(+), 112 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/authorization/DeviceAccessAuthorizationService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/authorization/DeviceAccessAuthorizationService.java index 5c6b9b4b4b..e54901bc6c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/authorization/DeviceAccessAuthorizationService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/authorization/DeviceAccessAuthorizationService.java @@ -51,6 +51,32 @@ public interface DeviceAccessAuthorizationService { DeviceAuthorizationResult isUserAuthorized(List deviceIdentifiers) throws DeviceAccessAuthorizationException; + /** + * This method will check whether the given user has the access to the device identified by the given + * DeviceIdentifier. + * + * @param deviceIdentifier - DeviceIdentifier of the device to be checked. + * @param username - Username of the user to be checked for authorization. + * @param permission - Permission + * @return Boolean authorization result. + * @throws DeviceAccessAuthorizationException if something goes wrong when checking the authorization. + */ + boolean isUserAuthorized(DeviceIdentifier deviceIdentifier, String username, String permission) throws DeviceAccessAuthorizationException; + + /** + * This method will check whether the given user has the access to the devices identified by the given + * DeviceIdentifier list. + * + * @param deviceIdentifiers - List of DeviceIdentifiers to be checked for authorization. + * @param username - User name + * @param permission - Permission + * @return DeviceAuthorizationResult - Authorization result including the list of authorized devices & + * unauthorized devices. + * @throws DeviceAccessAuthorizationException if something goes wrong when checking the authorization. + */ + DeviceAuthorizationResult isUserAuthorized(List deviceIdentifiers, String username, String permission) throws + DeviceAccessAuthorizationException; + /** * This method will check whether the given user has the access to the device identified by the given * DeviceIdentifier. diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/authorization/DeviceAccessAuthorizationServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/authorization/DeviceAccessAuthorizationServiceImpl.java index 857f0f63e9..cb0dc03ccf 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/authorization/DeviceAccessAuthorizationServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/authorization/DeviceAccessAuthorizationServiceImpl.java @@ -20,20 +20,26 @@ package org.wso2.carbon.device.mgt.core.authorization; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.context.CarbonContext; -import org.wso2.carbon.device.mgt.common.*; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; import org.wso2.carbon.device.mgt.common.authorization.DeviceAuthorizationResult; +import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; +import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; import org.wso2.carbon.device.mgt.common.permission.mgt.Permission; import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagementException; import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionUtils; import org.wso2.carbon.user.api.UserRealm; import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.user.api.UserStoreManager; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -66,158 +72,148 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori } @Override - public boolean isUserAuthorized(DeviceIdentifier deviceIdentifier) throws DeviceAccessAuthorizationException { - boolean status; - String username = this.getUserName(); + public boolean isUserAuthorized(DeviceIdentifier deviceIdentifier, String username, String permission) + throws DeviceAccessAuthorizationException { int tenantId = this.getTenantId(); if (username == null || username.isEmpty()) { - return !DeviceManagementDataHolder.getInstance().requireDeviceAuthorization(deviceIdentifier.getType()); + return false; } - try { - //Check for admin users. If the user is an admin user we authorize the access to that device. - status = isAdminUser(username, tenantId); - } catch (UserStoreException e) { - throw new DeviceAccessAuthorizationException("Unable to authorize the access to device : " + - deviceIdentifier.getId() + " for the user : " + username, e); + //check for admin and ownership permissions + if (isAdminOrDeviceOwner(username, tenantId, deviceIdentifier)) { + return true; } - //Check for device ownership. If the user is the owner of the device we allow the access. - if (!status) { - try { - Device device = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider(). - getDevice(deviceIdentifier); - EnrolmentInfo enrolmentInfo = device.getEnrolmentInfo(); - if (enrolmentInfo != null && username.equalsIgnoreCase(enrolmentInfo.getOwner())) { - status = true; - } - } catch (DeviceManagementException e) { - throw new DeviceAccessAuthorizationException("Unable to authorize the access to device : " + - deviceIdentifier.getId() + " for the user : " + username, e); + //check for group permissions + try { + if (permission == null || permission.isEmpty()) { + return false; } + return checkGroupsPermission(username, tenantId, permission); + } catch (GroupManagementException | UserStoreException e) { + throw new DeviceAccessAuthorizationException("Unable to authorize the access to device : " + + deviceIdentifier.getId() + " for the user : " + + username, e); } - return status; } @Override - public DeviceAuthorizationResult isUserAuthorized(List deviceIdentifiers) throws - DeviceAccessAuthorizationException { - boolean status; - DeviceAuthorizationResult deviceAuthorizationResult = new DeviceAuthorizationResult(); - String username = this.getUserName(); + public boolean isUserAuthorized(DeviceIdentifier deviceIdentifier, String username) + throws DeviceAccessAuthorizationException { + return isUserAuthorized(deviceIdentifier, username, null); + } + + @Override + public boolean isUserAuthorized(DeviceIdentifier deviceIdentifier) throws DeviceAccessAuthorizationException { + return isUserAuthorized(deviceIdentifier, this.getUserName(), null); + } + + @Override + public DeviceAuthorizationResult isUserAuthorized(List deviceIdentifiers, String username, + String permission) + throws DeviceAccessAuthorizationException { int tenantId = this.getTenantId(); if (username == null || username.isEmpty()) { - return deviceAuthorizationResult; - } - try { - //Check for admin users. If the user is an admin user we authorize the access to that device. - status = isAdminUser(username, tenantId); - } catch (UserStoreException e) { - throw new DeviceAccessAuthorizationException("Unable to authorize the access to devices for the user : " + - username, e); + return null; } - //Check for device ownership. If the user is the owner of the device we allow the access. - if (!status) { - try { - //Get the list of devices of the user - List devicesOfUser = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider(). - getDevicesOfUser(username); - //Convert device-list to a Map - Map ownershipData = this.getOwnershipOfDevices(devicesOfUser); - for (DeviceIdentifier deviceIdentifier : deviceIdentifiers) { - if (ownershipData.containsKey(deviceIdentifier.getId())) { + DeviceAuthorizationResult deviceAuthorizationResult = new DeviceAuthorizationResult(); + for (DeviceIdentifier deviceIdentifier : deviceIdentifiers) { + //check for admin and ownership permissions + if (isAdminOrDeviceOwner(username, tenantId, deviceIdentifier)) { + deviceAuthorizationResult.addAuthorizedDevice(deviceIdentifier); + } else { + try { + if (permission == null || permission.isEmpty()) { + return null; + } + //check for group permissions + if (checkGroupsPermission(username, tenantId, permission)) { deviceAuthorizationResult.addAuthorizedDevice(deviceIdentifier); } else { deviceAuthorizationResult.addUnauthorizedDevice(deviceIdentifier); } + } catch (GroupManagementException | UserStoreException e) { + throw new DeviceAccessAuthorizationException("Unable to authorize the access to device : " + + deviceIdentifier.getId() + " for the user : " + + username, e); } - } catch (DeviceManagementException e) { - throw new DeviceAccessAuthorizationException("Unable to authorize the access to devices for the user : " - + username, e); } - } else { - deviceAuthorizationResult.setAuthorizedDevices(deviceIdentifiers); } return deviceAuthorizationResult; } @Override - public boolean isUserAuthorized(DeviceIdentifier deviceIdentifier, String username) + public DeviceAuthorizationResult isUserAuthorized(List deviceIdentifiers, String username) + throws DeviceAccessAuthorizationException { + return isUserAuthorized(deviceIdentifiers, username, null); + } + + @Override + public DeviceAuthorizationResult isUserAuthorized(List deviceIdentifiers) + throws DeviceAccessAuthorizationException { + return isUserAuthorized(deviceIdentifiers, this.getUserName(), null); + } + + private boolean isAdminOrDeviceOwner(String username, int tenantId, DeviceIdentifier deviceIdentifier) throws DeviceAccessAuthorizationException { - boolean status; - int tenantId = this.getTenantId(); - if (username == null || username.isEmpty()) { - return false; - } try { - //Check for admin users. If the user is an admin user we authorize the access to that device. - status = isAdminUser(username, tenantId); + //First Check for admin users. If the user is an admin user we authorize the access to that device. + //Secondly Check for device ownership. If the user is the owner of the device we allow the access. + return (isAdminUser(username, tenantId) || isDeviceOwner(deviceIdentifier, username)); } catch (UserStoreException e) { throw new DeviceAccessAuthorizationException("Unable to authorize the access to device : " + - deviceIdentifier.getId() + " for the user : " + username, e); + deviceIdentifier.getId() + " for the user : " + + username, e); } - //Check for device ownership. If the user is the owner of the device we allow the access. - if (!status) { - try { - Device device = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider(). - getDevice(deviceIdentifier); - EnrolmentInfo enrolmentInfo = device.getEnrolmentInfo(); - if (enrolmentInfo != null && username.equalsIgnoreCase(enrolmentInfo.getOwner())) { - status = true; + } + + private boolean checkGroupsPermission(String username, int tenantId, String permission) + throws GroupManagementException, UserStoreException { + List groups = + DeviceManagementDataHolder.getInstance().getGroupManagementProviderService().getGroups(username, + permission); + UserRealm userRealm = DeviceManagementDataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId); + if (userRealm != null && userRealm.getAuthorizationManager() != null) { + Iterator groupIterator = groups.iterator(); + while (groupIterator.hasNext()) { + DeviceGroup deviceGroup = groupIterator.next(); + Iterator rolesIterator = deviceGroup.getRoles().iterator(); + while (rolesIterator.hasNext()) { + String role = rolesIterator.next(); + if (userRealm.getAuthorizationManager().isRoleAuthorized( + "Internal/group-" + deviceGroup.getId() + "-" + role, permission, + CarbonConstants.UI_PERMISSION_ACTION)) { + return true; + } } - } catch (DeviceManagementException e) { - throw new DeviceAccessAuthorizationException("Unable to authorize the access to device : " + - deviceIdentifier.getId() + " for the user : " + username, e); } } - return status; + return false; } - @Override - public DeviceAuthorizationResult isUserAuthorized(List deviceIdentifiers, String username) - throws DeviceAccessAuthorizationException { - boolean status; - int tenantId = this.getTenantId(); - DeviceAuthorizationResult deviceAuthorizationResult = new DeviceAuthorizationResult(); - if (username == null || username.isEmpty()) { - return null; - } - try { - //Check for admin users. If the user is an admin user we authorize the access to that device. - status = isAdminUser(username, tenantId); - } catch (UserStoreException e) { - throw new DeviceAccessAuthorizationException("Unable to authorize the access to devices for the user : " + - username, e); - } + private boolean isDeviceOwner(DeviceIdentifier deviceIdentifier, String username) + throws DeviceAccessAuthorizationException { //Check for device ownership. If the user is the owner of the device we allow the access. - if (!status) { - try { - Device device; - EnrolmentInfo enrolmentInfo; - for (DeviceIdentifier deviceIdentifier : deviceIdentifiers) { - device = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider(). - getDevice(deviceIdentifier); - enrolmentInfo = device.getEnrolmentInfo(); - if (enrolmentInfo != null && username.equalsIgnoreCase(enrolmentInfo.getOwner())) { - deviceAuthorizationResult.addAuthorizedDevice(deviceIdentifier); - } else { - deviceAuthorizationResult.addUnauthorizedDevice(deviceIdentifier); - } - } - } catch (DeviceManagementException e) { - throw new DeviceAccessAuthorizationException("Unable to authorize the access to devices for the user : " - + username, e); + try { + Device device = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider(). + getDevice(deviceIdentifier); + EnrolmentInfo enrolmentInfo = device.getEnrolmentInfo(); + if (enrolmentInfo != null && username.equalsIgnoreCase(enrolmentInfo.getOwner())) { + return true; } - } else { - deviceAuthorizationResult.setAuthorizedDevices(deviceIdentifiers); + } catch (DeviceManagementException e) { + throw new DeviceAccessAuthorizationException("Unable to authorize the access to device : " + + deviceIdentifier.getId() + " for the user : " + + username, e); } - return deviceAuthorizationResult; + return false; } private boolean isAdminUser(String username, int tenantId) throws UserStoreException { UserRealm userRealm = DeviceManagementDataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId); if (userRealm != null && userRealm.getAuthorizationManager() != null) { return userRealm.getAuthorizationManager() - .isUserAuthorized(removeTenantDomain(username), PermissionUtils.getAbsolutePermissionPath(EMM_ADMIN_PERMISSION), - PermissionMethod.UI_EXECUTE); + .isUserAuthorized(removeTenantDomain(username), + PermissionUtils.getAbsolutePermissionPath(EMM_ADMIN_PERMISSION), + PermissionMethod.UI_EXECUTE); } return false; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementDataHolder.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementDataHolder.java index ee594bc657..b09c1e8149 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementDataHolder.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementDataHolder.java @@ -25,6 +25,7 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager; import org.wso2.carbon.device.mgt.core.app.mgt.config.AppManagementConfig; import org.wso2.carbon.device.mgt.core.config.license.LicenseConfig; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService; import org.wso2.carbon.ntask.core.service.TaskService; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.user.core.service.RealmService; @@ -47,6 +48,7 @@ public class DeviceManagementDataHolder { private ConfigurationContextService configurationContextService; private HashMap requireDeviceAuthorization = new HashMap<>(); private DeviceAccessAuthorizationService deviceAccessAuthorizationService; + private GroupManagementProviderService groupManagementProviderService; private TaskService taskService; //private EmailSenderService emailSenderService; @@ -91,6 +93,15 @@ public class DeviceManagementDataHolder { this.deviceManagerProvider = deviceManagerProvider; } + public GroupManagementProviderService getGroupManagementProviderService() { + return groupManagementProviderService; + } + + public void setGroupManagementProviderService( + GroupManagementProviderService groupManagementProviderService) { + this.groupManagementProviderService = groupManagementProviderService; + } + public RegistryService getRegistryService() { if (registryService == null) { throw new IllegalStateException("Registry service is not initialized properly"); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java index 96cebe50db..35f7e50f00 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java @@ -195,6 +195,7 @@ public class DeviceManagementServiceComponent { /* Registering Group Management Service */ GroupManagementProviderService groupManagementProvider = new GroupManagementProviderServiceImpl(); + DeviceManagementDataHolder.getInstance().setGroupManagementProviderService(groupManagementProvider); bundleContext.registerService(GroupManagementProviderService.class.getName(), groupManagementProvider, null); /* Registering Tenant Configuration Management Service */