diff --git a/README.md b/README.md index a9d61eaa2a..0da219f7a4 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,11 @@ [![pipeline status](https://gitlab.com/entgra/carbon-device-mgt/badges/master/pipeline.svg)](https://gitlab.com/entgra/carbon-device-mgt/commits/master) -WSO2 CONNECTED DEVICE MANAGEMENT COMPONENTS +Entgra CONNECTED DEVICE MANAGEMENT COMPONENTS -WSO2 Connected Device Manager (WSO2 CDM) is a comprehensive platform that helps solve mobile computing challenges enterprises face today when dealing with both corporate owned, personally enabled (COPE) devices and employee owned devices as part of a bring your own device (BYOD) program. +Entgra Connected Device Manager (Entgra CDM) is a comprehensive platform that helps solve mobile computing challenges +enterprises face today when dealing with both corporate owned, personally enabled (COPE) devices and employee owned devices as part of a bring your own device (BYOD) program. -Whether it is device provisioning, device configuration management, policy enforcement, mobile application management, device data security, or compliance monitoring, WSO2 CDM offers a single enterprise-grade platform to develop extensions for IOT related device types. +Whether it is device provisioning, device configuration management, policy enforcement, mobile application +management, device data security, or compliance monitoring, Entgra CDM offers a single enterprise-grade platform to +develop extensions for IOT related device types. diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java index d4b52f2aab..ab50ccc8ab 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java @@ -60,6 +60,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.util.List; /** * Device related REST-API. This can be used to manipulated device related details. @@ -1452,5 +1453,198 @@ public interface DeviceManagementService { @ApiParam(name = "deviceOperation", value = "Operation object with device ids.", required = true) @Valid OperationRequest operationRequest); + @GET + @Path("/status/count/{type}/{status}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get Device Count with status", + notes = "Get specified device count with status.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:details") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the details of the device.", + response = int.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 = 304, + message = "Not Modified. Empty body because the client already has the latest version" + + " of the requested resource.\n"), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n A device with the specified device type and id was not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the device details.", + response = ErrorResponse.class) + }) + Response getDeviceCountByStatus( + @ApiParam( + name = "type", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @PathParam("type") + @Size(max = 45) + String type, + @ApiParam( + name = "status", + value = "The device identifier of the device you want ot get details.", + required = true) + @PathParam("status") + @Size(max = 45) + String status); + + + @GET + @Path("/status/ids/{type}/{status}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of a Device", + notes = "Get the details of a device by specifying the device type and device identifier and optionally " + + "the owner.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:details") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the details of the device.", + response = String[].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 = 304, + message = "Not Modified. Empty body because the client already has the latest version" + + " of the requested resource.\n"), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n A device with the specified device type and id was not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the device details.", + response = ErrorResponse.class) + }) + Response getDeviceIdentifiersByStatus( + @ApiParam( + name = "type", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @PathParam("type") + @Size(max = 45) + String type, + @ApiParam( + name = "status", + value = "The device identifier of the device you want ot get details.", + required = true) + @PathParam("status") + @Size(max = 45) + String status); + @PUT + @Path("/status/update/{type}/{status}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Changing the Status of a Devices", + notes = "Change the status of a devices from one state to another.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:change-status") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully changed the device status.", + response = Device.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 has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response bulkUpdateDeviceStatus(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("type") String type, + @ApiParam(name = "status", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("status") String status, + @ApiParam(name = "deviceList", value = "The payload containing the new name of the device.", required = true) + @Valid List deviceList); } 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 1d17ac9450..10aa8538fa 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 @@ -788,4 +788,52 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } } + + @GET + @Override + @Path("/status/count/{type}/{status}") + public Response getDeviceCountByStatus(@PathParam("type") String type, @PathParam("status") String status) { + int deviceCount; + try { + deviceCount = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceCountOfTypeByStatus(type, status); + return Response.status(Response.Status.OK).entity(deviceCount).build(); + } catch (DeviceManagementException e) { + String errorMessage = "Error while retrieving device count."; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } + } + + @GET + @Override + @Path("/status/ids/{type}/{status}") + public Response getDeviceIdentifiersByStatus(@PathParam("type") String type, @PathParam("status") String status) { + List deviceIds; + try { + deviceIds = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceIdentifiersByStatus(type, status); + return Response.status(Response.Status.OK).entity(deviceIds.toArray(new String[0])).build(); + } catch (DeviceManagementException e) { + String errorMessage = "Error while obtaining list of devices"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } + } + + @PUT + @Override + @Path("/status/update/{type}/{status}") + public Response bulkUpdateDeviceStatus(@PathParam("type") String type, @PathParam("status") String status, + @Valid List deviceList) { + try { + DeviceMgtAPIUtils.getDeviceManagementService().bulkUpdateDeviceStatus(type, deviceList, status); + } catch (DeviceManagementException e) { + String errorMessage = "Error while updating device status in bulk."; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } + return Response.status(Response.Status.OK).build(); + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java index b1f2ffb043..e768749d7f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java @@ -76,6 +76,17 @@ public interface DeviceDAO { */ int getDeviceCountByStatus(String status, int tenantId) throws DeviceManagementDAOException; + /** + * This method is used to get the device count by status and type. + * + * @param deviceType device type name. + * @param status enrollment status. + * @param tenantId tenant id. + * @return returns the device count of given status. + * @throws DeviceManagementDAOException + */ + int getDeviceCountByStatus(String deviceType, String status, int tenantId) throws DeviceManagementDAOException; + /** * This method is used to get the device count by ownership. * @@ -257,6 +268,11 @@ public interface DeviceDAO { */ int getDeviceCount(String username, int tenantId) throws DeviceManagementDAOException; + int getDeviceCount(String type, String status, int tenantId) throws DeviceManagementDAOException; + + List getDeviceIdentifiers(String type, String status, int tenantId) throws DeviceManagementDAOException; + + boolean setEnrolmentStatusInBulk(String deviceType, String status, int tenantId, List devices) throws DeviceManagementDAOException; /** * This method is used to retrieve the device count of a given tenant. * diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java index 2d0d877c03..66e15a47cf 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java @@ -39,7 +39,6 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; -import java.util.Iterator; import java.util.List; public abstract class AbstractDeviceDAOImpl implements DeviceDAO { @@ -515,6 +514,101 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { return deviceCount; } + /** + * Get device count of user. + * + * @return device count + * @throws DeviceManagementDAOException + */ + @Override + public int getDeviceCount(String type, String status, int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + int deviceCount = 0; + try { + conn = this.getConnection(); + String sql = "SELECT COUNT(d.ID) AS DEVICE_COUNT FROM (SELECT e.DEVICE_ID FROM DM_ENROLMENT e WHERE " + + "TENANT_ID = ? AND STATUS = ?) e, DM_DEVICE d, DM_DEVICE_TYPE t WHERE d.ID = e.DEVICE_ID AND " + + "d.DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ? AND t.NAME=?"; + stmt = conn.prepareStatement(sql); + stmt.setInt(1, tenantId); + stmt.setString(2, status); + stmt.setInt(3, tenantId); + stmt.setString(4, type); + rs = stmt.executeQuery(); + if (rs.next()) { + deviceCount = rs.getInt("DEVICE_COUNT"); + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while getting the device count", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return deviceCount; + } + + + public List getDeviceIdentifiers(String type, String status, int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + List deviceIDs = new ArrayList<>(); + try { + conn = this.getConnection(); + String sql = "SELECT d.DEVICE_IDENTIFICATION AS DEVICE_IDS FROM (SELECT e.DEVICE_ID FROM DM_ENROLMENT e WHERE " + + "TENANT_ID = ? AND STATUS = ?) e, DM_DEVICE d, DM_DEVICE_TYPE t WHERE d.ID = e.DEVICE_ID AND " + + "d.DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ? AND t.NAME=?"; + stmt = conn.prepareStatement(sql); + stmt.setInt(1, tenantId); + stmt.setString(2, status); + stmt.setInt(3, tenantId); + stmt.setString(4, type); + rs = stmt.executeQuery(); + while (rs.next()) { + deviceIDs.add(rs.getString("DEVICE_IDS")); + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving tenants which have " + + "device registered.", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return deviceIDs; + } + + @Override + public boolean setEnrolmentStatusInBulk(String deviceType, String status, + int tenantId, List devices) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + try { + conn = this.getConnection(); + StringBuilder sql = new StringBuilder("UPDATE DM_ENROLMENT SET STATUS = ? WHERE DEVICE_ID IN " + + "(SELECT d.ID FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE d.DEVICE_TYPE_ID = t.ID AND d.DEVICE_IDENTIFICATION IN ("); + for (int i = 0; i < devices.size(); i++) { + sql.append("?,"); + } + sql.deleteCharAt(sql.length() - 1); + sql.append(") AND t.NAME = ? AND d.TENANT_ID = ?) AND TENANT_ID = ?"); + stmt = conn.prepareStatement(sql.toString()); + stmt.setString(1, status); + int index = 1; + for (String device : devices) { + stmt.setString(++index, device); + } + stmt.setString(++index, deviceType); + stmt.setInt(++index, tenantId); + stmt.setInt(++index, tenantId); + stmt.executeUpdate(); + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while updating enrollment status in bulk", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, null); + } + return true; + } + /** * Get device count of all devices. * @@ -769,8 +863,8 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { try { conn = this.getConnection(); String sql = "SELECT COUNT(d.ID) AS DEVICE_COUNT FROM (SELECT e.DEVICE_ID FROM DM_ENROLMENT e WHERE " + - "TENANT_ID = ? AND STATUS = ?) e, DM_DEVICE d, " + - "DM_DEVICE_TYPE t WHERE d.ID = e.DEVICE_ID AND d.DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?"; + "TENANT_ID = ? AND STATUS = ?) e, DM_DEVICE d, " + + "DM_DEVICE_TYPE t WHERE d.ID = e.DEVICE_ID AND d.DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?"; stmt = conn.prepareStatement(sql); stmt.setInt(1, tenantId); stmt.setString(2, status); @@ -782,7 +876,36 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { } } catch (SQLException e) { throw new DeviceManagementDAOException("Error occurred while fetching the list of devices that matches to status " + - "'" + status + "'", e); + "'" + status + "'", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, null); + } + return deviceCount; + } + + @Override + public int getDeviceCountByStatus(String deviceType, String status, int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + int deviceCount = 0; + try { + conn = this.getConnection(); + String sql = "SELECT COUNT(d.ID) AS DEVICE_COUNT FROM (SELECT e.DEVICE_ID FROM DM_ENROLMENT e WHERE " + + "TENANT_ID = ? AND STATUS = ?) e, DM_DEVICE d, " + + "DM_DEVICE_TYPE t WHERE t.NAME = ? AND d.ID = e.DEVICE_ID AND d.DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setInt(1, tenantId); + stmt.setString(2, status); + stmt.setString(3, deviceType); + stmt.setInt(4, tenantId); + ResultSet rs = stmt.executeQuery(); + + if (rs.next()) { + deviceCount = rs.getInt("DEVICE_COUNT"); + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while fetching the list of devices that matches to status " + + "'" + status + "'", e); } finally { DeviceManagementDAOUtil.cleanupResources(stmt, null); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/Constants.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/Constants.java index 0ba5bb7d10..a944aec330 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/Constants.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/Constants.java @@ -25,4 +25,7 @@ public class Constants { public static final String PROP_AND = "PROP_AND"; public static final String PROP_OR = "PROP_OR"; public static final String LOCATION = "LOCATION"; + + public static final String ANY_DEVICE_PERMISSION = "/device-mgt/devices/any-device"; + public static final String UI_EXECUTE = "ui.execute"; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/impl/ProcessorImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/impl/ProcessorImpl.java index e77f700fa8..5510247082 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/impl/ProcessorImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/impl/ProcessorImpl.java @@ -25,8 +25,6 @@ import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; 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.device.details.DeviceInfo; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation; import org.wso2.carbon.device.mgt.common.search.SearchContext; @@ -34,11 +32,21 @@ import org.wso2.carbon.device.mgt.core.dao.ApplicationDAO; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil; -import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; -import org.wso2.carbon.device.mgt.core.search.mgt.*; +import org.wso2.carbon.device.mgt.core.search.mgt.Constants; +import org.wso2.carbon.device.mgt.core.search.mgt.InvalidOperatorException; +import org.wso2.carbon.device.mgt.core.search.mgt.Processor; +import org.wso2.carbon.device.mgt.core.search.mgt.QueryBuilder; +import org.wso2.carbon.device.mgt.core.search.mgt.QueryHolder; +import org.wso2.carbon.device.mgt.core.search.mgt.ResultSetAggregator; +import org.wso2.carbon.device.mgt.core.search.mgt.SearchMgtException; +import org.wso2.carbon.device.mgt.core.search.mgt.ValueType; import org.wso2.carbon.device.mgt.core.search.mgt.dao.SearchDAOException; -import java.sql.*; +import java.sql.Array; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -47,17 +55,9 @@ import java.util.Map; public class ProcessorImpl implements Processor { private ApplicationDAO applicationDAO; private static final Log log = LogFactory.getLog(ProcessorImpl.class); - private DeviceAccessAuthorizationService deviceAccessAuthorizationService; public ProcessorImpl() { applicationDAO = DeviceManagementDAOFactory.getApplicationDAO(); - deviceAccessAuthorizationService = DeviceManagementDataHolder.getInstance() - .getDeviceAccessAuthorizationService(); - if (deviceAccessAuthorizationService == null) { - String msg = "DeviceAccessAuthorization service has not initialized."; - log.error(msg); - throw new IllegalStateException(msg); - } } @Override @@ -115,35 +115,10 @@ public class ProcessorImpl implements Processor { devices.put(Constants.LOCATION, locationDevices); List finalDevices = aggregator.aggregate(devices); - finalDevices = authorizedDevices(finalDevices); this.setApplicationListOfDevices(finalDevices); return finalDevices; } - /** - * To get the authorized devices for a particular user - * - * @param devices Devices that satisfy search results - * @return Devices that satisfy search results and authorized to be viewed by particular user - */ - private List authorizedDevices(List devices) throws SearchMgtException { - List filteredList = new ArrayList<>(); - try { - for (Device device : devices) { - DeviceIdentifier deviceIdentifier = new DeviceIdentifier(device.getDeviceIdentifier(), - device.getType()); - if (deviceAccessAuthorizationService != null && deviceAccessAuthorizationService - .isUserAuthorized(deviceIdentifier)) { - filteredList.add(device); - } - } - return filteredList; - } catch (DeviceAccessAuthorizationException e) { - log.error("Error getting authorized search results for logged in user"); - throw new SearchMgtException(e); - } - } - @Override public List getUpdatedDevices(long epochTime) throws SearchMgtException { @@ -256,7 +231,6 @@ public class ProcessorImpl implements Processor { PreparedStatement stmt = null; ResultSet rs = null; List devices = new ArrayList<>(); - Map devs = new HashMap<>(); try { conn = this.getConnection(); stmt = conn.prepareStatement(queryHolder.getQuery()); @@ -281,59 +255,57 @@ public class ProcessorImpl implements Processor { rs = stmt.executeQuery(); while (rs.next()) { - if (!devs.containsKey(rs.getInt("ID"))) { - Device device = new Device(); - device.setId(rs.getInt("ID")); - device.setDescription(rs.getString("DESCRIPTION")); - device.setName(rs.getString("NAME")); - device.setType(rs.getString("DEVICE_TYPE_NAME")); - device.setDeviceIdentifier(rs.getString("DEVICE_IDENTIFICATION")); - - EnrolmentInfo enrolmentInfo = new EnrolmentInfo(); - enrolmentInfo.setStatus(EnrolmentInfo.Status.valueOf(rs.getString("DE_STATUS"))); - enrolmentInfo.setOwner(rs.getString("OWNER")); - enrolmentInfo.setOwnership(EnrolmentInfo.OwnerShip.valueOf(rs.getString("OWNERSHIP"))); - device.setEnrolmentInfo(enrolmentInfo); - - DeviceIdentifier identifier = new DeviceIdentifier(); - identifier.setType(rs.getString("DEVICE_TYPE_NAME")); - identifier.setId(rs.getString("DEVICE_IDENTIFICATION")); - - DeviceInfo deviceInfo = new DeviceInfo(); - deviceInfo.setAvailableRAMMemory(rs.getDouble("AVAILABLE_RAM_MEMORY")); - deviceInfo.setBatteryLevel(rs.getDouble("BATTERY_LEVEL")); - deviceInfo.setConnectionType(rs.getString("CONNECTION_TYPE")); - deviceInfo.setCpuUsage(rs.getDouble("CPU_USAGE")); - deviceInfo.setDeviceModel(rs.getString("DEVICE_MODEL")); - deviceInfo.setExternalAvailableMemory(rs.getDouble("EXTERNAL_AVAILABLE_MEMORY")); - deviceInfo.setExternalTotalMemory(rs.getDouble("EXTERNAL_TOTAL_MEMORY")); - deviceInfo.setInternalAvailableMemory(rs.getDouble("INTERNAL_AVAILABLE_MEMORY")); - deviceInfo.setInternalTotalMemory(rs.getDouble("EXTERNAL_TOTAL_MEMORY")); - deviceInfo.setOsVersion(rs.getString("OS_VERSION")); - deviceInfo.setOsBuildDate(rs.getString("OS_BUILD_DATE")); - deviceInfo.setPluggedIn(rs.getBoolean("PLUGGED_IN")); - deviceInfo.setSsid(rs.getString("SSID")); - deviceInfo.setTotalRAMMemory(rs.getDouble("TOTAL_RAM_MEMORY")); - deviceInfo.setVendor(rs.getString("VENDOR")); - deviceInfo.setUpdatedTime(new java.util.Date(rs.getLong("UPDATE_TIMESTAMP"))); - - DeviceLocation deviceLocation = new DeviceLocation(); - deviceLocation.setLatitude(rs.getDouble("LATITUDE")); - deviceLocation.setLongitude(rs.getDouble("LONGITUDE")); - deviceLocation.setStreet1(rs.getString("STREET1")); - deviceLocation.setStreet2(rs.getString("STREET2")); - deviceLocation.setCity(rs.getString("CITY")); - deviceLocation.setState(rs.getString("STATE")); - deviceLocation.setZip(rs.getString("ZIP")); - deviceLocation.setCountry(rs.getString("COUNTRY")); - deviceLocation.setDeviceId(rs.getInt("ID")); - deviceLocation.setUpdatedTime(new java.util.Date(rs.getLong("DL_UPDATED_TIMESTAMP"))); - - deviceInfo.setLocation(deviceLocation); - device.setDeviceInfo(deviceInfo); - devices.add(device); - devs.put(device.getId(), device.getId()); - } + Device device = new Device(); + device.setId(rs.getInt("ID")); + device.setDescription(rs.getString("DESCRIPTION")); + device.setName(rs.getString("NAME")); + device.setType(rs.getString("DEVICE_TYPE_NAME")); + device.setDeviceIdentifier(rs.getString("DEVICE_IDENTIFICATION")); + + EnrolmentInfo enrolmentInfo = new EnrolmentInfo(); + enrolmentInfo.setId(rs.getInt("ENROLLMENT_ID")); + enrolmentInfo.setStatus(EnrolmentInfo.Status.valueOf(rs.getString("DE_STATUS"))); + enrolmentInfo.setOwner(rs.getString("OWNER")); + enrolmentInfo.setOwnership(EnrolmentInfo.OwnerShip.valueOf(rs.getString("OWNERSHIP"))); + device.setEnrolmentInfo(enrolmentInfo); + + DeviceIdentifier identifier = new DeviceIdentifier(); + identifier.setType(rs.getString("DEVICE_TYPE_NAME")); + identifier.setId(rs.getString("DEVICE_IDENTIFICATION")); + + DeviceInfo deviceInfo = new DeviceInfo(); + deviceInfo.setAvailableRAMMemory(rs.getDouble("AVAILABLE_RAM_MEMORY")); + deviceInfo.setBatteryLevel(rs.getDouble("BATTERY_LEVEL")); + deviceInfo.setConnectionType(rs.getString("CONNECTION_TYPE")); + deviceInfo.setCpuUsage(rs.getDouble("CPU_USAGE")); + deviceInfo.setDeviceModel(rs.getString("DEVICE_MODEL")); + deviceInfo.setExternalAvailableMemory(rs.getDouble("EXTERNAL_AVAILABLE_MEMORY")); + deviceInfo.setExternalTotalMemory(rs.getDouble("EXTERNAL_TOTAL_MEMORY")); + deviceInfo.setInternalAvailableMemory(rs.getDouble("INTERNAL_AVAILABLE_MEMORY")); + deviceInfo.setInternalTotalMemory(rs.getDouble("EXTERNAL_TOTAL_MEMORY")); + deviceInfo.setOsVersion(rs.getString("OS_VERSION")); + deviceInfo.setOsBuildDate(rs.getString("OS_BUILD_DATE")); + deviceInfo.setPluggedIn(rs.getBoolean("PLUGGED_IN")); + deviceInfo.setSsid(rs.getString("SSID")); + deviceInfo.setTotalRAMMemory(rs.getDouble("TOTAL_RAM_MEMORY")); + deviceInfo.setVendor(rs.getString("VENDOR")); + deviceInfo.setUpdatedTime(new java.util.Date(rs.getLong("UPDATE_TIMESTAMP"))); + + DeviceLocation deviceLocation = new DeviceLocation(); + deviceLocation.setLatitude(rs.getDouble("LATITUDE")); + deviceLocation.setLongitude(rs.getDouble("LONGITUDE")); + deviceLocation.setStreet1(rs.getString("STREET1")); + deviceLocation.setStreet2(rs.getString("STREET2")); + deviceLocation.setCity(rs.getString("CITY")); + deviceLocation.setState(rs.getString("STATE")); + deviceLocation.setZip(rs.getString("ZIP")); + deviceLocation.setCountry(rs.getString("COUNTRY")); + deviceLocation.setDeviceId(rs.getInt("ID")); + deviceLocation.setUpdatedTime(new java.util.Date(rs.getLong("DL_UPDATED_TIMESTAMP"))); + + deviceInfo.setLocation(deviceLocation); + device.setDeviceInfo(deviceInfo); + devices.add(device); } } catch (SQLException e) { throw new SearchDAOException("Error occurred while aquiring the device details.", e); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/impl/QueryBuilderImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/impl/QueryBuilderImpl.java index 65b6af46fa..27e6457a2f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/impl/QueryBuilderImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/impl/QueryBuilderImpl.java @@ -331,7 +331,7 @@ public class QueryBuilderImpl implements QueryBuilder { "DD.EXTERNAL_TOTAL_MEMORY, DD.EXTERNAL_AVAILABLE_MEMORY, DD.CONNECTION_TYPE, \n" + "DD.SSID, DD.CPU_USAGE, DD.TOTAL_RAM_MEMORY, DD.AVAILABLE_RAM_MEMORY, \n" + "DD.PLUGGED_IN, DD.UPDATE_TIMESTAMP, DL.LATITUDE, DL.LONGITUDE, DL.STREET1, DL.STREET2, DL.CITY, DL.ZIP, \n" + - "DL.STATE, DL.COUNTRY, DL.UPDATE_TIMESTAMP AS DL_UPDATED_TIMESTAMP, DE.OWNER, DE.OWNERSHIP, DE.STATUS " + + "DL.STATE, DL.COUNTRY, DL.UPDATE_TIMESTAMP AS DL_UPDATED_TIMESTAMP, DE.ID AS ENROLLMENT_ID, DE.OWNER, DE.OWNERSHIP, DE.STATUS " + "AS DE_STATUS FROM DM_DEVICE_DETAIL DD INNER JOIN DM_DEVICE D ON D.ID=DD.DEVICE_ID\n" + "LEFT JOIN DM_DEVICE_LOCATION DL ON DL.DEVICE_ID=D.ID \n" + "INNER JOIN DM_DEVICE_TYPE DT ON DT.ID=D.DEVICE_TYPE_ID\n" + @@ -359,7 +359,7 @@ public class QueryBuilderImpl implements QueryBuilder { "DD.SSID, DD.CPU_USAGE, DD.TOTAL_RAM_MEMORY, DD.AVAILABLE_RAM_MEMORY, \n" + "DD.PLUGGED_IN, DD.UPDATE_TIMESTAMP, DL.LATITUDE, DL.LONGITUDE, DL.STREET1, DL.STREET2, DL.CITY, DL.ZIP, \n" + "DL.STATE, DL.COUNTRY, DL.UPDATE_TIMESTAMP AS DL_UPDATED_TIMESTAMP, DI.KEY_FIELD, DI.VALUE_FIELD, \n" + - "DE.OWNER, DE.OWNERSHIP, DE.STATUS AS DE_STATUS " + + "DE.ID ENROLLMENT_ID, DE.OWNER, DE.OWNERSHIP, DE.STATUS AS DE_STATUS " + "FROM DM_DEVICE_DETAIL DD INNER JOIN DM_DEVICE D ON D.ID=DD.DEVICE_ID\n" + "LEFT JOIN DM_DEVICE_LOCATION DL ON DL.DEVICE_ID=D.ID \n" + "INNER JOIN DM_DEVICE_TYPE DT ON DT.ID=D.DEVICE_TYPE_ID\n" + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/impl/ResultSetAggregatorImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/impl/ResultSetAggregatorImpl.java index acc565a9af..cdb6322ca6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/impl/ResultSetAggregatorImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/search/mgt/impl/ResultSetAggregatorImpl.java @@ -19,9 +19,16 @@ package org.wso2.carbon.device.mgt.core.search.mgt.impl; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; +import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionUtils; import org.wso2.carbon.device.mgt.core.search.mgt.Constants; import org.wso2.carbon.device.mgt.core.search.mgt.ResultSetAggregator; +import org.wso2.carbon.user.api.UserRealm; +import org.wso2.carbon.user.api.UserStoreException; import java.util.ArrayList; import java.util.HashMap; @@ -29,16 +36,17 @@ import java.util.List; import java.util.Map; public class ResultSetAggregatorImpl implements ResultSetAggregator { + private static Log log = LogFactory.getLog(ResultSetAggregatorImpl.class); @Override public List aggregate(Map> devices) { - Map generalQueryMap = this.convertToMap(devices.get(Constants.GENERAL)); Map andMap = this.convertToMap(devices.get(Constants.PROP_AND)); Map orMap = this.convertToMap(devices.get(Constants.PROP_OR)); Map locationMap = this.convertToMap(devices.get(Constants.LOCATION)); Map finalMap = new HashMap<>(); List finalResult = new ArrayList<>(); + List ownDevices = new ArrayList<>(); if (andMap.isEmpty()) { finalMap = generalQueryMap; @@ -70,7 +78,23 @@ public class ResultSetAggregatorImpl implements ResultSetAggregator { } } - return finalResult; + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + + try { + if (isPermittedToViewAnyDevice(username)) { + return finalResult; + } + } catch (UserStoreException e) { + log.error("Unable to check permissions of the user: " + username, e); + } + + for (Device device: finalResult) { + if (username.equals(device.getEnrolmentInfo().getOwner())) { + ownDevices.add(device); + } + } + + return ownDevices; } private Map convertToMap(List devices) { @@ -79,7 +103,7 @@ public class ResultSetAggregatorImpl implements ResultSetAggregator { } Map deviceWrapperMap = new HashMap<>(); for (Device device : devices) { - deviceWrapperMap.put(device.getId(), device); + deviceWrapperMap.put(device.getEnrolmentInfo().getId(), device); } return deviceWrapperMap; } @@ -92,4 +116,20 @@ public class ResultSetAggregatorImpl implements ResultSetAggregator { return list; } + /** + * Checks if the user has permissions to view all devices. + * + * @param username username + * @return {@code true} if user is permitted + * @throws UserStoreException If unable to check user permissions + */ + private boolean isPermittedToViewAnyDevice(String username) throws UserStoreException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + UserRealm userRealm = DeviceManagementDataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId); + return userRealm != null && userRealm.getAuthorizationManager() != null && + userRealm.getAuthorizationManager().isUserAuthorized(username, + PermissionUtils.getAbsolutePermissionPath(Constants.ANY_DEVICE_PERMISSION), + Constants.UI_EXECUTE); + } + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java index 9786b8f73d..5e7658ae71 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java @@ -17,16 +17,7 @@ */ package org.wso2.carbon.device.mgt.core.service; -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.FeatureManager; -import org.wso2.carbon.device.mgt.common.InvalidDeviceException; -import org.wso2.carbon.device.mgt.common.MonitoringOperation; -import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig; -import org.wso2.carbon.device.mgt.common.PaginationRequest; -import org.wso2.carbon.device.mgt.common.PaginationResult; +import org.wso2.carbon.device.mgt.common.*; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; import org.wso2.carbon.device.mgt.common.license.mgt.License; @@ -465,6 +456,29 @@ public interface DeviceManagementProviderService { */ int getDeviceCount() throws DeviceManagementException; + /** + * Method to get the count of devices with given status and type. + * + * @param deviceType Device type name + * @param status Device status + * + * @return device count + * @throws DeviceManagementException If some unusual behaviour is observed while counting + * the devices + */ + int getDeviceCount(String deviceType, EnrolmentInfo.Status status) throws DeviceManagementException; + + /** + * Method to get the count of all types of devices with given status. + * + * @param status Device status + * + * @return device count + * @throws DeviceManagementException If some unusual behaviour is observed while counting + * the devices + */ + int getDeviceCount(EnrolmentInfo.Status status) throws DeviceManagementException; + HashMap getTenantedDevice(DeviceIdentifier deviceIdentifier) throws DeviceManagementException; void sendEnrolmentInvitation(String templateName, EmailMetaInfo metaInfo) throws DeviceManagementException, @@ -637,4 +651,10 @@ public interface DeviceManagementProviderService { List findGeoClusters(String deviceType, GeoCoordinate southWest, GeoCoordinate northEast, int geohashLength) throws DeviceManagementException; + + int getDeviceCountOfTypeByStatus(String deviceType, String deviceStatus) throws DeviceManagementException; + + List getDeviceIdentifiersByStatus(String deviceType, String deviceStatus) throws DeviceManagementException; + + boolean bulkUpdateDeviceStatus(String deviceType, List deviceList, String status) throws DeviceManagementException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index 923ed22fb1..37851dbb1c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -1959,6 +1959,57 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } } + @Override + public int getDeviceCount(String deviceType, EnrolmentInfo.Status status) throws DeviceManagementException { + if (log.isDebugEnabled()) { + log.debug("Get devices count for type '" + deviceType + "' and status: " + status.toString()); + } + try { + DeviceManagementDAOFactory.openConnection(); + return deviceDAO.getDeviceCountByStatus(deviceType, status.toString(), this.getTenantId()); + } catch (DeviceManagementDAOException e) { + String msg = "Error occurred while retrieving the device count for type '" + deviceType + + "' and status: " + status.toString(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while opening a connection to the data source"; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (Exception e) { + String msg = "Error occurred in getDeviceCount for type '" + deviceType + "' and status: " + status.toString(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Override + public int getDeviceCount(EnrolmentInfo.Status status) throws DeviceManagementException { + if (log.isDebugEnabled()) { + log.debug("Get devices count status: " + status.toString()); + } + try { + DeviceManagementDAOFactory.openConnection(); + return deviceDAO.getDeviceCountByStatus(status.toString(), this.getTenantId()); + } catch (DeviceManagementDAOException e) { + String msg = "Error occurred while retrieving the device count"; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while opening a connection to the data source"; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (Exception e) { + String msg = "Error occurred in getDeviceCount status: " + status.toString(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + @Override public List getDevicesByNameAndType(PaginationRequest request, boolean requireDeviceInfo) throws DeviceManagementException { @@ -2708,6 +2759,67 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } } + @Override + public int getDeviceCountOfTypeByStatus(String deviceType, String deviceStatus) throws DeviceManagementException { + int tenantId = this.getTenantId(); + try { + DeviceManagementDAOFactory.openConnection(); + return deviceDAO.getDeviceCount(deviceType, deviceStatus, tenantId); + } catch (DeviceManagementDAOException e) { + String msg = "Error occurred in while retrieving device count by status for deviceType :" +deviceType + " status : " + deviceStatus; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while opening a connection to the data source"; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Override + public List getDeviceIdentifiersByStatus(String deviceType, String deviceStatus) throws DeviceManagementException { + int tenantId = this.getTenantId(); + List deviceIds; + try { + DeviceManagementDAOFactory.openConnection(); + deviceIds = deviceDAO.getDeviceIdentifiers(deviceType, deviceStatus, tenantId); + } catch (DeviceManagementDAOException e) { + String msg = "Error occurred in while retrieving devices by status for deviceType :" +deviceType + " status : " + deviceStatus; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while opening a connection to the data source"; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + return deviceIds; + } + + @Override + public boolean bulkUpdateDeviceStatus(String deviceType, List deviceList, String status) throws DeviceManagementException { + int tenantId = this.getTenantId(); + boolean success; + try { + DeviceManagementDAOFactory.openConnection(); + success = deviceDAO.setEnrolmentStatusInBulk(deviceType, status, tenantId, deviceList); + } catch (DeviceManagementDAOException e) { + String msg = "Error occurred in while updating status of devices :" +deviceType + " status : " + deviceList.toString(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while opening a connection to the data source"; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + return success; + } + private void extractDeviceLocationToUpdate(Device device) { List properties = device.getProperties(); if (properties != null) { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/search/ProcessorImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/search/ProcessorImplTest.java index 92f3eac37d..221ed02461 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/search/ProcessorImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/search/ProcessorImplTest.java @@ -17,14 +17,11 @@ */ package org.wso2.carbon.device.mgt.core.search; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; -import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; import org.wso2.carbon.device.mgt.common.search.Condition; import org.wso2.carbon.device.mgt.common.search.SearchContext; import org.wso2.carbon.device.mgt.core.TestDeviceManagementService; @@ -41,7 +38,6 @@ import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl; import org.wso2.carbon.utils.multitenancy.MultitenantConstants; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; @@ -50,16 +46,12 @@ import java.util.List; */ public class ProcessorImplTest extends BaseDeviceManagementTest { - private DeviceAccessAuthorizationService deviceAccessAuthorizationService; - private static final Log log = LogFactory.getLog(SearchManagementServiceTest.class); private static List deviceIdentifiers = new ArrayList<>(); private static final String DEVICE_ID_PREFIX = "SEARCH-DEVICE-ID-"; private static final String DEVICE_TYPE = "SEARCH_TYPE"; @BeforeClass public void init() throws Exception { - deviceAccessAuthorizationService = DeviceManagementDataHolder.getInstance() - .getDeviceAccessAuthorizationService(); for (int i = 0; i < 5; i++) { deviceIdentifiers.add(new DeviceIdentifier(DEVICE_ID_PREFIX + i, DEVICE_TYPE)); } @@ -81,27 +73,59 @@ public class ProcessorImplTest extends BaseDeviceManagementTest { } } - @Test(description = "Test the Search Processor") - public void testWithNoDeviceAccessAuthorization() throws NoSuchFieldException, IllegalAccessException, - SearchMgtException { + @Test (description = "Search for device with and condition") + public void testSearchDevicesWIthAndCondition() throws SearchMgtException { SearchContext context = new SearchContext(); List conditions = new ArrayList<>(); - Condition cond = new Condition(); - cond.setKey("batteryLevel"); - cond.setOperator("="); - cond.setValue("40"); - cond.setState(Condition.State.AND); - conditions.add(cond); + + Condition condition = new Condition(); + condition.setKey("IMEI"); + condition.setOperator("="); + condition.setValue("e6f236ac82537a8e"); + condition.setState(Condition.State.AND); + conditions.add(condition); + + context.setConditions(conditions); + ProcessorImpl processor = new ProcessorImpl(); + List devices = processor.execute(context); + Assert.assertEquals(5, devices.size(), "There should be exactly 5 devices with matching search criteria"); + } + + @Test (description = "Search for device with or condition") + public void testSearchDevicesWIthORCondition() throws SearchMgtException { + SearchContext context = new SearchContext(); + List conditions = new ArrayList<>(); + + Condition condition = new Condition(); + condition.setKey("IMSI"); + condition.setOperator("="); + condition.setValue("432659632123654845"); + condition.setState(Condition.State.OR); + conditions.add(condition); + context.setConditions(conditions); ProcessorImpl processor = new ProcessorImpl(); - Field deviceAccessAuthorizationServiceField = ProcessorImpl.class.getDeclaredField - ("deviceAccessAuthorizationService"); - deviceAccessAuthorizationServiceField.setAccessible(true); - deviceAccessAuthorizationServiceField.set(processor, null); - List searchedDevices = processor.execute(context); - Assert.assertEquals(0, searchedDevices.size()); + List devices = processor.execute(context); + Assert.assertEquals(5, devices.size(), "There should be exactly 5 devices with matching search criteria"); } + @Test (description = "Search for device with wrong condition") + public void testSearchDevicesWIthWrongCondition() throws SearchMgtException { + SearchContext context = new SearchContext(); + List conditions = new ArrayList<>(); + + Condition condition = new Condition(); + condition.setKey("IMSI"); + condition.setOperator("="); + condition.setValue("43265963212378466"); + condition.setState(Condition.State.OR); + conditions.add(condition); + + context.setConditions(conditions); + ProcessorImpl processor = new ProcessorImpl(); + List devices = processor.execute(context); + Assert.assertEquals(0, devices.size(), "There should be no devices with matching search criteria"); + } @Test(description = "Test for invalid state") public void testInvalidState() throws SearchMgtException { @@ -141,16 +165,4 @@ public class ProcessorImplTest extends BaseDeviceManagementTest { } } } - - @Test(description = "Test when Device Access Authorization is null", expectedExceptions = {IllegalStateException - .class}, dependsOnMethods = {"testWithNoDeviceAccessAuthorization", "testInvalidState"}) - public void testProcessorInitializationError() throws ClassNotFoundException, NoSuchMethodException, - NoSuchFieldException, IllegalAccessException, SearchMgtException { - DeviceManagementDataHolder deviceManagementDataHolder = DeviceManagementDataHolder.getInstance(); - Field field = DeviceManagementDataHolder.class.getDeclaredField("deviceAccessAuthorizationService"); - field.setAccessible(true); - field.set(deviceManagementDataHolder, null); - ProcessorImpl processor = new ProcessorImpl(); - processor.execute(null); - } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceTest.java index 22d7098c74..ffff69c6a5 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceTest.java @@ -301,7 +301,7 @@ public class DeviceManagementProviderServiceTest extends BaseDeviceManagementTes @Test(expectedExceptions = DeviceManagementException.class) public void testGetDeviceCountForNullUser() throws DeviceManagementException { - deviceMgtService.getDeviceCount(null); + deviceMgtService.getDeviceCount((String) null); } @Test(dependsOnMethods = {"testSuccessfulDeviceEnrollment"}) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json index d717cdae31..ffe9bcaa86 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json @@ -156,10 +156,12 @@ "perm:admin:device-type", "perm:device:enroll", "perm:geo-service:analytics-view", - "perm:geo-service:alerts-manage" + "perm:geo-service:alerts-manage", + "appm:read" ], "isOAuthEnabled": true, "backendRestEndpoints": { - "deviceMgt": "/api/device-mgt/v1.0" + "deviceMgt": "/api/device-mgt/v1.0", + "appMgt": "/api/appm/store/v1.1" } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/policy.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/policy.js index de106c6ecb..c1be205a63 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/policy.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/policy.js @@ -14,6 +14,23 @@ * either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2018, Entgra (Pvt) Ltd. (http://www.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. */ var policyModule; @@ -180,6 +197,55 @@ policyModule = function () { } }; + /* + Get apps available in the store from backend service. + */ + publicMethods.getStoreAppsForPolicy = function () { + var carbonUser = session.get(constants["USER_SESSION_KEY"]); + if (!carbonUser) { + log.error("User object was not found in the session"); + userModule.logout(function () { + response.sendRedirect(devicemgtProps["appContext"] + "login"); + }); + } + try { + var url = devicemgtProps["managerHTTPSURL"] + devicemgtProps["backendRestEndpoints"]["appMgt"] + + "/apps/mobileapp?field-filter=all"; + return serviceInvokers.XMLHttp.get(url, + function (backendResponse) { + var response = {}; + if (backendResponse.status === 200 && backendResponse.responseText) { + var appListFromRestEndpoint = parse(backendResponse.responseText)["appList"]; + var storeApps = []; + var i, appObjectFromRestEndpoint, appObjectToView; + for (i=0; i