diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java index 4693f26435..fa4e20d85f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -25,6 +25,8 @@ import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.device.mgt.common.*; import org.wso2.carbon.device.mgt.common.app.mgt.Application; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; +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.operation.mgt.Operation; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; import org.wso2.carbon.device.mgt.common.search.SearchContext; @@ -78,6 +80,13 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { // RequestValidationUtil.validateSelectionCriteria(type, user, roleName, ownership, status); RequestValidationUtil.validatePaginationParameters(offset, limit); DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + DeviceAccessAuthorizationService deviceAccessAuthorizationService = + DeviceMgtAPIUtils.getDeviceAccessAuthorizationService(); + if (deviceAccessAuthorizationService == null) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("Device access authorization service is " + + "failed").build()).build(); + } PaginationRequest request = new PaginationRequest(offset, limit); PaginationResult result; DeviceList devices = new DeviceList(); @@ -100,6 +109,30 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { request.setStatus(status); } + // this is the user who initiates the request + String authorizedUser = CarbonContext.getThreadLocalCarbonContext().getUsername(); + + // check whether the user is device-mgt admin + if (deviceAccessAuthorizationService.isDeviceAdminUser()) { + if (user != null && !user.isEmpty()) { + request.setOwner(user); + } + } else { + if (user != null && !user.isEmpty()) { + if (user.equals(authorizedUser)) { + request.setOwner(user); + } else { + String msg = "User '" + authorizedUser + "' is not authorized to retrieve devices of '" + user + + "' user"; + log.error(msg); + return Response.status(Response.Status.UNAUTHORIZED).entity( + new ErrorResponse.ErrorResponseBuilder().setCode(401l).setMessage(msg).build()).build(); + } + } else { + request.setOwner(authorizedUser); + } + } + if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) { Date sinceDate; SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z"); @@ -149,6 +182,11 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { log.error(msg, e); return Response.serverError().entity( new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (DeviceAccessAuthorizationException e) { + String msg = "Error occurred while checking device access authorization"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); } } @@ -186,10 +224,24 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { @PathParam("type") @Size(max = 45) String type, @PathParam("id") @Size(max = 45) String id, @HeaderParam("If-Modified-Since") String ifModifiedSince) { - Device device; + Device device = null; try { RequestValidationUtil.validateDeviceIdentifier(type, id); DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + DeviceAccessAuthorizationService deviceAccessAuthorizationService = + DeviceMgtAPIUtils.getDeviceAccessAuthorizationService(); + + // this is the user who initiates the request + String authorizedUser = CarbonContext.getThreadLocalCarbonContext().getUsername(); + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(id, type); + // check whether the user is authorized + if (!deviceAccessAuthorizationService.isUserAuthorized(deviceIdentifier, authorizedUser)) { + String msg = "User '" + authorizedUser + "' is not authorized to retrieve the given device id '" + id; + log.error(msg); + return Response.status(Response.Status.UNAUTHORIZED).entity( + new ErrorResponse.ErrorResponseBuilder().setCode(401l).setMessage(msg).build()).build(); + } + if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) { Date sinceDate; SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z"); @@ -213,6 +265,11 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { log.error(msg, e); return Response.serverError().entity( new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (DeviceAccessAuthorizationException e) { + String msg = "Error occurred while checking the device authorization."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); } if (device == null) { return Response.status(Response.Status.NOT_FOUND).entity( @@ -233,7 +290,6 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { DeviceManagementProviderService dms; try { RequestValidationUtil.validateDeviceIdentifier(type, id); - dms = DeviceMgtAPIUtils.getDeviceManagementService(); FeatureManager fm = dms.getFeatureManager(type); if (fm == null) { 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 aa748fdae5..c15e92eb9f 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 @@ -24,6 +24,7 @@ import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.analytics.dashboard.GadgetDataService; import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService; @@ -104,6 +105,18 @@ public class DeviceMgtAPIUtils { return deviceManagementProviderService; } + public static DeviceAccessAuthorizationService getDeviceAccessAuthorizationService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + DeviceAccessAuthorizationService deviceAccessAuthorizationService = + (DeviceAccessAuthorizationService) ctx.getOSGiService(DeviceAccessAuthorizationService.class, null); + if (deviceAccessAuthorizationService == null) { + String msg = "DeviceAccessAuthorization service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return deviceAccessAuthorizationService; + } + public static GroupManagementProviderService getGroupManagementProviderService() { PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); GroupManagementProviderService groupManagementProviderService = 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 610727edb0..18706fe7de 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 @@ -115,6 +115,14 @@ public interface DeviceAccessAuthorizationService { boolean isUserAuthorized(DeviceIdentifier deviceIdentifier, String username) throws DeviceAccessAuthorizationException; + /** + * This method will check whether the authenticated user has the admin permissions. + * + * @return Boolean authorization result. + * @throws DeviceAccessAuthorizationException if something goes wrong when checking the authorization. + */ + boolean isDeviceAdminUser() throws DeviceAccessAuthorizationException; + /** * This method will check whether the given user has the access to the devices identified by the given * DeviceIdentifier list. 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 31d1be6658..eee383826b 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 @@ -106,6 +106,18 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori return isUserAuthorized(deviceIdentifier, this.getUserName(), null); } + @Override + public boolean isDeviceAdminUser() throws DeviceAccessAuthorizationException { + String username = this.getUserName(); + int tenantId = this.getTenantId(); + try { + return isAdminUser(username, tenantId); + } catch (UserStoreException e) { + throw new DeviceAccessAuthorizationException("Unable to check the admin permissions of user : " + + username + " in tenant : " + tenantId, e); + } + } + @Override public DeviceAuthorizationResult isUserAuthorized(List deviceIdentifiers, String username, String[] groupPermissions)