diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceSubscriptionData.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceSubscriptionData.java index 3afac36acd..550c1c98fc 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceSubscriptionData.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceSubscriptionData.java @@ -24,7 +24,7 @@ import java.sql.Timestamp; public class DeviceSubscriptionData { private String action; - private Timestamp actionTriggeredTimestamp; + private long actionTriggeredTimestamp; private String actionTriggeredBy; private String actionType; private String status; @@ -38,11 +38,11 @@ public class DeviceSubscriptionData { this.action = action; } - public Timestamp getActionTriggeredTimestamp() { + public long getActionTriggeredTimestamp() { return actionTriggeredTimestamp; } - public void setActionTriggeredTimestamp(Timestamp actionTriggeredTimestamp) { + public void setActionTriggeredTimestamp(long actionTriggeredTimestamp) { this.actionTriggeredTimestamp = actionTriggeredTimestamp; } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ScheduledSubscriptionDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ScheduledSubscriptionDTO.java index 65801e9415..da3e1e01e0 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ScheduledSubscriptionDTO.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ScheduledSubscriptionDTO.java @@ -69,7 +69,7 @@ public class ScheduledSubscriptionDTO { /** * Scheduled time of subscription. */ - private LocalDateTime scheduledAt; + private long scheduledAt; /** * Username of the scheduler. @@ -86,7 +86,7 @@ public class ScheduledSubscriptionDTO { } - public ScheduledSubscriptionDTO(String taskName, String applicationUUID, LocalDateTime scheduledAt, + public ScheduledSubscriptionDTO(String taskName, String applicationUUID, long scheduledAt, List subscriberList, String scheduledBy) { this.taskName = taskName; this.applicationUUID = applicationUUID; @@ -135,11 +135,11 @@ public class ScheduledSubscriptionDTO { this.status = status; } - public LocalDateTime getScheduledAt() { + public long getScheduledAt() { return scheduledAt; } - public void setScheduledAt(LocalDateTime scheduledAt) { + public void setScheduledAt(long scheduledAt) { this.scheduledAt = scheduledAt; } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java index 9d9e94c183..a535ffd389 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java @@ -22,6 +22,7 @@ import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDT import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationResult; import java.util.List; @@ -127,14 +128,11 @@ public interface SubscriptionManager { * This method used to get the app id ,device ids and pass them to DM service method. * * @param appUUID UUID of the application release. - * @param offsetValue offset value for get paginated request. - * @param limitValue limit value for get paginated request. - * @param status status of the devices. + * @param request paginated request object. * @return deviceDetails - device details for given application release. * @throws {@link ApplicationManagementException} Exception of the application management */ - PaginationResult getAppInstalledDevices(int offsetValue, int limitValue, String appUUID, - List status) throws ApplicationManagementException; + PaginationResult getAppInstalledDevices(PaginationRequest request, String appUUID) throws ApplicationManagementException; /*** * This method used to get category details. @@ -152,14 +150,15 @@ public interface SubscriptionManager { /** * This method is responsible to provide application subscription data for given application release UUID. * - * @param offsetValue offset - * @param limitValue limit + * @param request paginated request object. + * @param actionStatus status of the operation. + * @param action action related to the device. * @param appUUID application release UUID * @return {@link PaginationResult} * @throws ApplicationManagementException if offset or limit contains incorrect values, if it couldn't find an * application release for given UUID, if an error occurred while getting device details of subscribed device ids, * if an error occurred while getting subscription details of given application release UUID. */ - PaginationResult getAppSubscriptionDetails(int offsetValue, int limitValue, String appUUID) + PaginationResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, String action) throws ApplicationManagementException; } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/SubscriptionDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/SubscriptionDAO.java index 4b99420e50..ce8780a6a2 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/SubscriptionDAO.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/SubscriptionDAO.java @@ -81,7 +81,7 @@ public interface SubscriptionDAO { void addGroupSubscriptions(int tenantId, String subscribedBy, List groups, int releaseId, String action) throws ApplicationManagementDAOException; - List getDeviceSubscriptions(int appReleaseId, int tenantId) throws + List getDeviceSubscriptions(int appReleaseId, int tenantId, String actionStatus, String action) throws ApplicationManagementDAOException; Map getDeviceSubscriptions(List deviceIds, int appReleaseId, int tenantId) @@ -124,7 +124,7 @@ public interface SubscriptionDAO { * @param scheduledBy username of the user who scheduled the subscription * @throws ApplicationManagementDAOException if error occurred while updating the entry */ - boolean updateScheduledSubscription(int id, LocalDateTime scheduledAt, String scheduledBy) + boolean updateScheduledSubscription(int id, long scheduledAt, String scheduledBy) throws ApplicationManagementDAOException; /** diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java index a4d9d4a87a..dd8880c6fc 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java @@ -134,7 +134,8 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " - + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT, " + + "NEW_AP_APP_LIFECYCLE_STATE.UPDATED_AT AS LATEST_UPDATE " + "FROM AP_APP " + "INNER JOIN AP_APP_RELEASE ON " + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " @@ -181,7 +182,17 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic if (filter.getLimit() != -1) { sql += "LIMIT ? OFFSET ? "; } - sql += ") AS app_data ON app_data.ID = AP_APP.ID WHERE AP_APP.TENANT_ID = ? ORDER BY AP_APP.ID"; + sql += ") AS app_data ON app_data.ID = AP_APP.ID " + + "INNER JOIN (" + + "SELECT AP_APP_LIFECYCLE_STATE.UPDATED_AT, AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID " + + "FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_LIFECYCLE_STATE.ID " + + "IN(SELECT MAX(AP_APP_LIFECYCLE_STATE.ID) " + + "FROM AP_APP_LIFECYCLE_STATE " + + "GROUP BY AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID)) AS NEW_AP_APP_LIFECYCLE_STATE " + + "ON AP_APP_RELEASE.ID = NEW_AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID " + + "WHERE AP_APP.TENANT_ID = ? " + + "ORDER BY AP_APP.ID, LATEST_UPDATE DESC"; + try { Connection conn = this.getDBConnection(); try (PreparedStatement stmt = conn.prepareStatement(sql)) { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/OracleApplicationDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/OracleApplicationDAOImpl.java index c57ef8a07d..bb705d7f82 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/OracleApplicationDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/OracleApplicationDAOImpl.java @@ -80,7 +80,8 @@ public class OracleApplicationDAOImpl extends GenericApplicationDAOImpl { + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " - + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT, " + + "NEW_AP_APP_LIFECYCLE_STATE.UPDATED_AT AS LATEST_UPDATE " + "FROM AP_APP " + "INNER JOIN AP_APP_RELEASE ON " + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " @@ -125,7 +126,17 @@ public class OracleApplicationDAOImpl extends GenericApplicationDAOImpl { if (filter.getLimit() != -1) { sql += "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY "; } - sql += ") AS app_data ON app_data.ID = AP_APP.ID WHERE AP_APP.TENANT_ID = ? ORDER BY AP_APP.ID"; + sql += ") AS app_data ON app_data.ID = AP_APP.ID " + + "INNER JOIN (" + + "SELECT AP_APP_LIFECYCLE_STATE.UPDATED_AT, AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID " + + "FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_LIFECYCLE_STATE.ID " + + "IN(SELECT MAX(AP_APP_LIFECYCLE_STATE.ID) " + + "FROM AP_APP_LIFECYCLE_STATE " + + "GROUP BY AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID)) AS NEW_AP_APP_LIFECYCLE_STATE " + + "ON AP_APP_RELEASE.ID = NEW_AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID " + + "WHERE AP_APP.TENANT_ID = ? " + + "ORDER BY AP_APP.ID, LATEST_UPDATE DESC"; + try { Connection conn = this.getDBConnection(); try (PreparedStatement stmt = conn.prepareStatement(sql)) { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/SQLServerApplicationDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/SQLServerApplicationDAOImpl.java index ee7c78f8ba..d27e55aa9b 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/SQLServerApplicationDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/SQLServerApplicationDAOImpl.java @@ -79,7 +79,8 @@ public class SQLServerApplicationDAOImpl extends GenericApplicationDAOImpl { + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " - + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT, " + + "NEW_AP_APP_LIFECYCLE_STATE.UPDATED_AT AS LATEST_UPDATE " + "FROM AP_APP " + "INNER JOIN AP_APP_RELEASE ON " + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " @@ -124,7 +125,17 @@ public class SQLServerApplicationDAOImpl extends GenericApplicationDAOImpl { if (filter.getLimit() != -1) { sql += "ORDER BY ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY "; } - sql += ") AS app_data ON app_data.ID = AP_APP.ID WHERE AP_APP.TENANT_ID = ? ORDER BY AP_APP.ID"; + sql += ") AS app_data ON app_data.ID = AP_APP.ID " + + "INNER JOIN (" + + "SELECT AP_APP_LIFECYCLE_STATE.UPDATED_AT, AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID " + + "FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_LIFECYCLE_STATE.ID " + + "IN(SELECT MAX(AP_APP_LIFECYCLE_STATE.ID) " + + "FROM AP_APP_LIFECYCLE_STATE " + + "GROUP BY AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID)) AS NEW_AP_APP_LIFECYCLE_STATE " + + "ON AP_APP_RELEASE.ID = NEW_AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID " + + "WHERE AP_APP.TENANT_ID = ? " + + "ORDER BY AP_APP.ID, LATEST_UPDATE DESC"; + try { Connection conn = this.getDBConnection(); try (PreparedStatement stmt = conn.prepareStatement(sql)) { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java index c2f559e96b..c2fd7f240a 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java @@ -332,12 +332,15 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public List getDeviceSubscriptions(int appReleaseId, int tenantId) throws + public List getDeviceSubscriptions(int appReleaseId, int tenantId, String actionStatus, String action) throws ApplicationManagementDAOException { if (log.isDebugEnabled()) { log.debug("Getting device subscriptions for the application release id " + appReleaseId + " from the database"); } + boolean isActionStatusProvided = false; + boolean isActionProvided = false; + int index = 1; String sql = "SELECT " + "DS.ID AS ID, " + "DS.SUBSCRIBED_BY AS SUBSCRIBED_BY, " @@ -350,11 +353,30 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc + "DS.DM_DEVICE_ID AS DEVICE_ID " + "FROM AP_DEVICE_SUBSCRIPTION DS " + "WHERE DS.AP_APP_RELEASE_ID = ? AND DS.TENANT_ID=?"; + + if (actionStatus != null && !actionStatus.isEmpty()) { + sql += " AND DS.STATUS= ?"; + isActionStatusProvided = true; + } + if (action != null && !action.isEmpty()) { + sql += " AND DS.UNSUBSCRIBED= ?"; + isActionProvided = true; + } try { Connection conn = this.getDBConnection(); try (PreparedStatement stmt = conn.prepareStatement(sql)) { - stmt.setInt(1, appReleaseId); - stmt.setInt(2, tenantId); + stmt.setInt(index++, appReleaseId); + stmt.setInt(index++, tenantId); + if (isActionStatusProvided) { + stmt.setString(index++, actionStatus); + } + if (isActionProvided) { + if (action.equals("SUBSCRIBED")) { + stmt.setString(index, "FALSE"); + } else { + stmt.setString(index, "TRUE"); + } + } try (ResultSet rs = stmt.executeQuery()) { if (log.isDebugEnabled()) { log.debug("Successfully retrieved device subscriptions for application release id " @@ -765,7 +787,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc stmt.setString(2, subscriptionDTO.getApplicationUUID()); stmt.setString(3, subscriptionDTO.getSubscribersString()); stmt.setString(4, ExecutionStatus.PENDING.toString()); - stmt.setTimestamp(5, Timestamp.valueOf(subscriptionDTO.getScheduledAt())); + stmt.setLong(5, subscriptionDTO.getScheduledAt()); stmt.setTimestamp(6, new Timestamp(calendar.getTime().getTime())); stmt.setString(7, subscriptionDTO.getScheduledBy()); stmt.setBoolean(8, false); @@ -785,7 +807,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public boolean updateScheduledSubscription(int id, LocalDateTime scheduledAt, String scheduledBy) + public boolean updateScheduledSubscription(int id, long scheduledAt, String scheduledBy) throws ApplicationManagementDAOException { String sql = "UPDATE AP_SCHEDULED_SUBSCRIPTION " + "SET " @@ -797,7 +819,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc Connection conn = this.getDBConnection(); try (PreparedStatement stmt = conn.prepareStatement(sql)) { Calendar calendar = Calendar.getInstance(); - stmt.setTimestamp(1, Timestamp.valueOf(scheduledAt)); + stmt.setLong(1, scheduledAt); stmt.setString(2, scheduledBy); stmt.setTimestamp(3, new Timestamp(calendar.getTime().getTime())); stmt.setInt(4, id); @@ -1037,7 +1059,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc try (PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, ExecutionStatus.PENDING.toString()); stmt.setBoolean(2, false); - stmt.setTimestamp(3, new Timestamp(Calendar.getInstance().getTime().getTime())); + stmt.setLong(3, Calendar.getInstance().getTime().getTime() / 1000); try (ResultSet rs = stmt.executeQuery()) { return DAOUtil.loadScheduledSubscriptions(rs); } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java index 2cebd98c61..05b757ba45 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java @@ -1445,7 +1445,7 @@ ApplicationManagerImpl implements ApplicationManager { log.error(msg); throw new ForbiddenException(msg); } - if (!subscriptionDAO.getDeviceSubscriptions(applicationReleaseDTO.getId(), tenantId).isEmpty()) { + if (!subscriptionDAO.getDeviceSubscriptions(applicationReleaseDTO.getId(), tenantId, null, null).isEmpty()) { String msg = "Application release which has UUID: " + applicationReleaseDTO.getUuid() + " either subscribed to device/s or it had subscribed to device/s. Therefore you are not " + "permitted to delete the application release."; @@ -1580,7 +1580,7 @@ ApplicationManagerImpl implements ApplicationManager { try { ConnectionManagerUtil.beginDBTransaction(); List deviceSubscriptionDTOS = subscriptionDAO - .getDeviceSubscriptions(applicationReleaseDTO.getId(), tenantId); + .getDeviceSubscriptions(applicationReleaseDTO.getId(), tenantId, null, null); if (!deviceSubscriptionDTOS.isEmpty()) { String msg = "Application release which has UUID: " + applicationReleaseDTO.getUuid() + " either subscribed to device/s or it had subscribed to device/s. Therefore you " diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java index 19008cbb0d..5aa222ce13 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java @@ -65,10 +65,7 @@ import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; import org.wso2.carbon.device.application.mgt.core.util.Constants; import org.wso2.carbon.device.application.mgt.core.util.HelperUtil; import org.wso2.carbon.device.application.mgt.core.util.OAuthUtils; -import org.wso2.carbon.device.mgt.common.Device; -import org.wso2.carbon.device.mgt.common.DeviceIdentifier; -import org.wso2.carbon.device.mgt.common.EnrolmentInfo; -import org.wso2.carbon.device.mgt.common.MDMAppConstants; +import org.wso2.carbon.device.mgt.common.*; import org.wso2.carbon.device.mgt.common.app.mgt.App; import org.wso2.carbon.device.mgt.common.app.mgt.MobileAppTypes; import org.wso2.carbon.device.mgt.common.app.mgt.android.CustomApplication; @@ -88,7 +85,6 @@ import org.wso2.carbon.device.mgt.core.util.MDMIOSOperationUtil; import org.wso2.carbon.device.mgt.core.util.MDMWindowsOperationUtil; import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.device.mgt.common.PaginationResult; import javax.ws.rs.core.MediaType; import java.io.BufferedReader; @@ -381,7 +377,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { if (applicationDTO != null) { List deviceSubscriptionDTOS = this.subscriptionDAO .getDeviceSubscriptions(applicationDTO.getApplicationReleaseDTOs().get(0).getId(), - tenantId); + tenantId, null, null); AtomicBoolean isAppSubscribable = new AtomicBoolean(true); for (DeviceSubscriptionDTO deviceSubscriptionDTO : deviceSubscriptionDTOS) { @@ -1223,7 +1219,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public PaginationResult getAppInstalledDevices(int offsetValue, int limitValue, String appUUID, List status) + public PaginationResult getAppInstalledDevices(PaginationRequest request, String appUUID) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); DeviceManagementProviderService deviceManagementProviderService = HelperUtil @@ -1235,7 +1231,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { int applicationReleaseId = applicationDTO.getApplicationReleaseDTOs().get(0).getId(); List deviceSubscriptionDTOS = subscriptionDAO - .getDeviceSubscriptions(applicationReleaseId, tenantId); + .getDeviceSubscriptions(applicationReleaseId, tenantId, null, null); if (deviceSubscriptionDTOS.isEmpty()) { PaginationResult paginationResult = new PaginationResult(); paginationResult.setData(new ArrayList<>()); @@ -1262,8 +1258,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } //pass the device id list to device manager service method try { - PaginationResult deviceDetails = deviceManagementProviderService - .getAppSubscribedDevices(offsetValue, limitValue, deviceIdList, status); + PaginationResult deviceDetails = deviceManagementProviderService.getAppSubscribedDevices + (request, deviceIdList); if (deviceDetails == null) { String msg = "Couldn't found an subscribed devices details for device ids: " + deviceIdList; @@ -1342,8 +1338,10 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public PaginationResult getAppSubscriptionDetails(int offsetValue, int limitValue, String appUUID) - throws ApplicationManagementException { + public PaginationResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, + String action) throws ApplicationManagementException { + int limitValue = request.getRowCount(); + int offsetValue = request.getStartIndex(); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); DeviceManagementProviderService deviceManagementProviderService = HelperUtil .getDeviceManagementProviderService(); @@ -1365,7 +1363,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { int applicationReleaseId = applicationDTO.getApplicationReleaseDTOs().get(0).getId(); List deviceSubscriptionDTOS = subscriptionDAO - .getDeviceSubscriptions(applicationReleaseId, tenantId); + .getDeviceSubscriptions(applicationReleaseId, tenantId, actionStatus, action); if (deviceSubscriptionDTOS.isEmpty()) { PaginationResult paginationResult = new PaginationResult(); paginationResult.setData(new ArrayList<>()); @@ -1377,8 +1375,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { .collect(Collectors.toList()); try { //pass the device id list to device manager service method - PaginationResult paginationResult = deviceManagementProviderService - .getAppSubscribedDevices(offsetValue, limitValue, deviceIdList, null); + PaginationResult paginationResult = deviceManagementProviderService.getAppSubscribedDevices + (request, deviceIdList); List deviceSubscriptionDataList = new ArrayList<>(); if (!paginationResult.getData().isEmpty()) { @@ -1392,12 +1390,12 @@ public class SubscriptionManagerImpl implements SubscriptionManager { deviceSubscriptionData.setAction(Constants.UNSUBSCRIBED); deviceSubscriptionData.setActionTriggeredBy(subscription.getUnsubscribedBy()); deviceSubscriptionData - .setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp()); + .setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp().getTime() / 1000); } else { deviceSubscriptionData.setAction(Constants.SUBSCRIBED); deviceSubscriptionData.setActionTriggeredBy(subscription.getSubscribedBy()); deviceSubscriptionData - .setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); + .setActionTriggeredTimestamp(subscription.getSubscribedTimestamp().getTime() / 1000); } deviceSubscriptionData.setActionType(subscription.getActionTriggeredFrom()); deviceSubscriptionData.setStatus(subscription.getStatus()); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionCleanupTask.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionCleanupTask.java index 113b16cf3f..351a4477b2 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionCleanupTask.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionCleanupTask.java @@ -40,7 +40,7 @@ public class ScheduledAppSubscriptionCleanupTask extends RandomlyAssignedSchedul @Override public void executeRandomlyAssignedTask() { try { - if(super.isQualifiedToExecuteTask()) { + if(isQualifiedToExecuteTask()) { subscriptionManager.cleanScheduledSubscriptions(); } } catch (SubscriptionManagementException e) { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTask.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTask.java index caff4ec460..8a95efc0aa 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTask.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTask.java @@ -68,7 +68,7 @@ public class ScheduledAppSubscriptionTask extends RandomlyAssignedScheduleTask { @Override public void executeRandomlyAssignedTask() { - if(super.isQualifiedToExecuteTask()) { + if(isQualifiedToExecuteTask()) { try { ScheduledSubscriptionDTO subscriptionDTO = subscriptionManager.getPendingScheduledSubscription( this.taskName); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTaskManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTaskManager.java index c07053f3d5..326a358e1b 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTaskManager.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTaskManager.java @@ -40,6 +40,8 @@ import org.wso2.carbon.ntask.core.service.TaskService; import java.time.LocalDateTime; import java.time.format.TextStyle; +import java.util.Calendar; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -64,24 +66,27 @@ public class ScheduledAppSubscriptionTaskManager { * either {@link org.wso2.carbon.device.mgt.common.DeviceIdentifier} if {@param subType} is * equal to DEVICE or {@link String} if {@param subType} is USER, ROLE or GROUP * @param subscriptionType subscription type. E.g. DEVICE, USER, ROLE, GROUP - * {@see {@link org.wso2.carbon.device.application.mgt.common.SubscriptionType}} + * {@see {@link SubscriptionType}} * @param action action subscription action. E.g. {@code INSTALL/UNINSTALL} - * {@see {@link org.wso2.carbon.device.application.mgt.common.SubAction}} + * {@see {@link SubAction}} * @param timestamp timestamp to schedule the application subscription * @throws ApplicationOperationTaskException if error occurred while scheduling the subscription */ public void scheduleAppSubscriptionTask(String applicationUUID, List subscribers, - SubscriptionType subscriptionType, SubAction action, LocalDateTime timestamp) + SubscriptionType subscriptionType, SubAction action, long timestamp) throws ApplicationOperationTaskException { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date(timestamp * 1000)); String space = " "; String cronExpression = - String.valueOf(timestamp.getSecond()) + space + timestamp.getMinute() + space + timestamp.getHour() - + space + timestamp.getDayOfMonth() + space + timestamp.getMonth().getDisplayName(TextStyle.SHORT, - Locale.getDefault()).toUpperCase() + " ? " + timestamp.getYear(); + calendar.get(Calendar.SECOND) + space + calendar.get(Calendar.MINUTE) + space + + calendar.get(Calendar.HOUR_OF_DAY) + space + calendar.get(Calendar.DAY_OF_MONTH) + space + + calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.getDefault()).toUpperCase() + " ? " + + calendar.get(Calendar.YEAR); if (!CronExpression.isValidExpression(cronExpression)) { String msg = "The cron expression [" + cronExpression + "] generated by the" + " timestamp [" + timestamp - .toString() + "] is invalid"; + + "] is invalid"; log.error(msg); throw new ApplicationOperationTaskException(msg); } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/DAOUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/DAOUtil.java index c56df53109..4950fe3c6e 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/DAOUtil.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/DAOUtil.java @@ -274,7 +274,7 @@ public class DAOUtil { } subscription.setStatus(ExecutionStatus.valueOf(rs.getString("STATUS"))); - subscription.setScheduledAt(rs.getTimestamp("SCHEDULED_AT").toLocalDateTime()); + subscription.setScheduledAt(rs.getLong("SCHEDULED_AT")); subscription.setScheduledBy(rs.getString("SCHEDULED_BY")); subscription.setDeleted(rs.getBoolean("DELETED")); subscriptionDTOS.add(subscription); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/SubscriptionManagementAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/SubscriptionManagementAPI.java index 75a4522d68..be55b64639 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/SubscriptionManagementAPI.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/SubscriptionManagementAPI.java @@ -32,6 +32,7 @@ import org.wso2.carbon.device.application.mgt.common.ErrorResponse; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import javax.validation.Valid; +import javax.validation.constraints.Size; import javax.ws.rs.Path; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; @@ -129,7 +130,7 @@ public interface SubscriptionManagementAPI { name = "timestamp", value = "Timestamp of scheduled install/uninstall operation" ) - @QueryParam("timestamp") String timestamp + @QueryParam("timestamp") long timestamp ); @POST @@ -182,7 +183,7 @@ public interface SubscriptionManagementAPI { name = "timestamp", value = "Timestamp of scheduled install/uninstall operation" ) - @QueryParam("timestamp") String timestamp + @QueryParam("timestamp") long timestamp ); @POST @@ -229,7 +230,7 @@ public interface SubscriptionManagementAPI { name = "timestamp", value = "Timestamp of scheduled ent. install operation" ) - @QueryParam("timestamp") String timestamp, + @QueryParam("timestamp") long timestamp, @ApiParam( name = "requiresUpdatingExternal", value = "Should external system such as Google EMM APIs need to be updated." @@ -287,7 +288,7 @@ public interface SubscriptionManagementAPI { name = "timestamp", value = "Timestamp of scheduled ent app install operation" ) - @QueryParam("timestamp") String timestamp, + @QueryParam("timestamp") long timestamp, @ApiParam( name = "requiresUpdatingExternal", value = "Should external system such as Google EMM APIs need to be updated." @@ -337,6 +338,28 @@ public interface SubscriptionManagementAPI { response = ErrorResponse.class) }) Response getAppInstalledDevices( + @ApiParam( + name = "name", + value = "The device name. For example, Nexus devices can have names, suhc as shamu, bullhead or angler.", + required = false) + @Size(max = 45) + String name, + @ApiParam( + name = "user", + value = "The username of the owner of the device.", + required = false) + @QueryParam("user") + String user, + @ApiParam( + name = "ownership", + allowableValues = "BYOD, COPE", + value = "Provide the ownership status of the device. The following values can be assigned:\n" + + "- BYOD: Bring Your Own Device\n" + + "- COPE: Corporate-Owned, Personally-Enabled", + required = false) + @QueryParam("ownership") + @Size(max = 45) + String ownership, @ApiParam( name="uuid", value="uuid of the application release.", diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/admin/SubscriptionManagementAdminAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/admin/SubscriptionManagementAdminAPI.java index 7c47b1f7cf..97f6f6851e 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/admin/SubscriptionManagementAdminAPI.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/admin/SubscriptionManagementAdminAPI.java @@ -31,6 +31,7 @@ import org.wso2.carbon.apimgt.annotations.api.Scope; import org.wso2.carbon.apimgt.annotations.api.Scopes; import org.wso2.carbon.device.application.mgt.common.ErrorResponse; +import javax.validation.constraints.Size; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -111,6 +112,32 @@ public interface SubscriptionManagementAdminAPI { response = ErrorResponse.class) }) Response getAppInstalledDevices( + @ApiParam( + name = "name", + value = "The device name. For example, Nexus devices can have names, suhc as shamu, bullhead or angler.", + required = false) + @Size(max = 45) + String name, + @ApiParam( + name = "user", + value = "The username of the owner of the device.", + required = false) + @QueryParam("user") + String user, + @ApiParam( + name = "action", + value = "The action, subscribed or unsubscribed.", + required = false) + @Size(max = 45) + @QueryParam("action") String action, + @ApiParam( + name = "actionStatus", + value = "Provide the action status details") + @QueryParam("actionStatus") String actionStatus, + @ApiParam( + name = "status", + value = "Provide the device status details, such as active or inactive.") + @QueryParam("status") List status, @ApiParam( name = "uuid", value = "uuid of the application release.", diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/SubscriptionManagementAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/SubscriptionManagementAPIImpl.java index 984f689d07..acf9662cb9 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/SubscriptionManagementAPIImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/SubscriptionManagementAPIImpl.java @@ -33,6 +33,8 @@ import org.wso2.carbon.device.application.mgt.common.BasicUserInfo; import org.wso2.carbon.device.application.mgt.common.BasicUserInfoList; import org.wso2.carbon.device.application.mgt.common.RoleList; import org.wso2.carbon.device.application.mgt.common.DeviceGroupList; +import org.wso2.carbon.device.application.mgt.store.api.services.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationResult; import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException; @@ -73,9 +75,9 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{ @PathParam("uuid") String uuid, @PathParam("action") String action, @Valid List deviceIdentifiers, - @QueryParam("timestamp") String timestamp) { + @QueryParam("timestamp") long timestamp) { try { - if (StringUtils.isEmpty(timestamp)) { + if (0 == timestamp) { SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); ApplicationInstallResponse response = subscriptionManager .performBulkAppOperation(uuid, deviceIdentifiers, SubscriptionType.DEVICE.toString(), action); @@ -114,9 +116,9 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{ @PathParam("subType") String subType, @PathParam("action") String action, @Valid List subscribers, - @QueryParam("timestamp") String timestamp) { + @QueryParam("timestamp") long timestamp) { try { - if (StringUtils.isEmpty(timestamp)) { + if (0 == timestamp) { SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); ApplicationInstallResponse response = subscriptionManager .performBulkAppOperation(uuid, subscribers, subType, action); @@ -155,10 +157,10 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{ @PathParam("uuid") String uuid, @PathParam("action") String action, @Valid List deviceIdentifiers, - @QueryParam("timestamp") String timestamp, + @QueryParam("timestamp") long timestamp, @QueryParam("requiresUpdatingExternal") boolean requiresUpdatingExternal) { try { - if (StringUtils.isEmpty(timestamp)) { + if (0 == timestamp) { SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); subscriptionManager .performEntAppSubscription(uuid, deviceIdentifiers, SubscriptionType.DEVICE.toString(), @@ -202,10 +204,10 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{ @PathParam("subType") String subType, @PathParam("action") String action, @Valid List subscribers, - @QueryParam("timestamp") String timestamp, + @QueryParam("timestamp") long timestamp, @QueryParam("requiresUpdatingExternal") boolean requiresUpdatingExternal) { try { - if (StringUtils.isEmpty(timestamp)) { + if (0 == timestamp) { SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); subscriptionManager.performEntAppSubscription(uuid, subscribers, subType, action, requiresUpdatingExternal); String msg = "Application release which has UUID " + uuid + " is installed to subscriber's valid device" @@ -253,11 +255,11 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{ * @return {@link Response} of the operation */ private Response scheduleApplicationOperationTask(String applicationUUID, List subscribers, - SubscriptionType subType, SubAction subAction, String timestamp) { + SubscriptionType subType, SubAction subAction, long timestamp) { try { ScheduledAppSubscriptionTaskManager subscriptionTaskManager = new ScheduledAppSubscriptionTaskManager(); subscriptionTaskManager.scheduleAppSubscriptionTask(applicationUUID, subscribers, subType, subAction, - LocalDateTime.parse(timestamp, DateTimeFormatter.ISO_LOCAL_DATE_TIME)); + timestamp); } catch (ApplicationOperationTaskException e) { String msg = "Error occurred while scheduling the application install operation"; log.error(msg, e); @@ -273,6 +275,9 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{ @Produces("application/json") @Path("/{uuid}/devices") public Response getAppInstalledDevices( + @QueryParam("name") String name, + @QueryParam("user") String user, + @QueryParam("ownership") String ownership, @PathParam("uuid") String uuid, @DefaultValue("0") @QueryParam("offset") int offset, @@ -281,8 +286,31 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{ @QueryParam("status") List status) { try { SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); - PaginationResult subscribedDeviceDetails = subscriptionManager - .getAppInstalledDevices(offset, limit, uuid, status); + PaginationRequest request = new PaginationRequest(offset, limit); + if (name != null && !name.isEmpty()) { + request.setDeviceName(name); + } + if (user != null && !user.isEmpty()) { + request.setOwner(user); + } + if (ownership != null && !ownership.isEmpty()) { + RequestValidationUtil.validateOwnershipType(ownership); + request.setOwnership(ownership); + } + if (status != null && !status.isEmpty()) { + boolean isStatusEmpty = true; + for (String statusString : status) { + if (StringUtils.isNotBlank(statusString)) { + isStatusEmpty = false; + break; + } + } + if (!isStatusEmpty) { + RequestValidationUtil.validateStatus(status); + request.setStatusList(status); + } + } + PaginationResult subscribedDeviceDetails = subscriptionManager.getAppInstalledDevices(request, uuid); DeviceList devices = new DeviceList(); devices.setList((List) subscribedDeviceDetails.getData()); devices.setCount(subscribedDeviceDetails.getRecordsTotal()); @@ -292,8 +320,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{ log.error(msg, e); return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); } catch (BadRequestException e) { - String msg = "Found invalid payload for getting application which has UUID: " + uuid - + ". Hence verify the payload"; + String msg = "User requested details are not valid"; log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } catch (ForbiddenException e) { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/admin/SubscriptionManagementAdminAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/admin/SubscriptionManagementAdminAPIImpl.java index 2462556570..681b3b5f38 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/admin/SubscriptionManagementAdminAPIImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/admin/SubscriptionManagementAdminAPIImpl.java @@ -18,6 +18,7 @@ package org.wso2.carbon.device.application.mgt.store.api.services.impl.admin; +import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; @@ -26,6 +27,8 @@ import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException; import org.wso2.carbon.device.application.mgt.core.util.APIUtil; import org.wso2.carbon.device.application.mgt.store.api.services.admin.SubscriptionManagementAdminAPI; +import org.wso2.carbon.device.application.mgt.store.api.services.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationResult; import javax.ws.rs.Consumes; @@ -36,6 +39,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; +import java.util.List; /** * Implementation of Subscription Management related APIs. @@ -51,6 +55,11 @@ public class SubscriptionManagementAdminAPIImpl implements SubscriptionManagemen @Produces("application/json") @Path("/{uuid}") public Response getAppInstalledDevices( + @QueryParam("name") String name, + @QueryParam("user") String user, + @QueryParam("action") String action, + @QueryParam("actionStatus") String actionStatus, + @QueryParam("status") List status, @PathParam("uuid") String uuid, @DefaultValue("0") @QueryParam("offset") int offset, @@ -58,22 +67,49 @@ public class SubscriptionManagementAdminAPIImpl implements SubscriptionManagemen @QueryParam("limit") int limit) { try { + PaginationRequest request = new PaginationRequest(offset, limit); + if (name != null && !name.isEmpty()) { + request.setDeviceName(name); + } + if (user != null && !user.isEmpty()) { + request.setOwner(user); + } + if (action != null && !action.isEmpty()) { + RequestValidationUtil.validateAction(action); + } + if (status != null && !status.isEmpty()) { + boolean isStatusEmpty = true; + for (String statusString : status) { + if (StringUtils.isNotBlank(statusString)) { + isStatusEmpty = false; + break; + } + } + if (!isStatusEmpty) { + RequestValidationUtil.validateStatus(status); + request.setStatusList(status); + } + } + if (actionStatus != null && !actionStatus.isEmpty()) { + if (StringUtils.isNotBlank(actionStatus)) { + RequestValidationUtil.validateStatusFiltering(actionStatus); + } + } SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); - PaginationResult subscriptionData = subscriptionManager - .getAppSubscriptionDetails(offset, limit, uuid); + PaginationResult subscriptionData = subscriptionManager.getAppSubscriptionDetails + (request, uuid, actionStatus, action); return Response.status(Response.Status.OK).entity(subscriptionData).build(); } catch (NotFoundException e) { String msg = "Application with application release UUID: " + uuid + " is not found"; log.error(msg, e); return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); } catch (BadRequestException e) { - String msg = "Found invalid payload for getting application which has UUID: " + uuid - + ". Hence verify the payload"; + String msg = "User requested details are not valid"; log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } catch (ApplicationManagementException e) { String msg = "Error occurred while getting app installed devices which has application release UUID of: " - + uuid; + + uuid; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/util/RequestValidationUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/util/RequestValidationUtil.java new file mode 100644 index 0000000000..2a59d220a4 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/util/RequestValidationUtil.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.application.mgt.store.api.services.impl.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; +import org.wso2.carbon.device.application.mgt.store.api.util.Constants; + +import java.util.List; + +public class RequestValidationUtil { + + private static final Log log = LogFactory.getLog(RequestValidationUtil.class); + + /** + * Checks if user requested status codes are valid. + * + * @param statusList status codes upon to filter operation logs using status + */ + public static void validateStatus(List statusList) throws BadRequestException { + for (String status : statusList) { + switch (status) { + case "ACTIVE": + case "INACTIVE": + case "UNCLAIMED": + case "UNREACHABLE": + case "SUSPENDED": + case "DISENROLLMENT_REQUESTED": + case "REMOVED": + case "BLOCKED": + case "CREATED": + break; + default: + String msg = "Invalid enrollment status type: " + status + ". \nValid status types " + + "are ACTIVE | INACTIVE | UNCLAIMED | UNREACHABLE | SUSPENDED | " + + "DISENROLLMENT_REQUESTED | REMOVED | BLOCKED | CREATED"; + log.error(msg); + throw new BadRequestException(msg); + } + } + } + + /** + * Checks if user requested action is valid. + * + * @param action action upon to filter devices using action + */ + public static void validateAction(String action) throws BadRequestException { + if (action.equals("SUBSCRIBED") || action.equals("UNSUBSCRIBED")) { + } else { + String msg = "Invalid action type received.Valid action types are SUBSCRIBED | UNSUBSCRIBED"; + log.error(msg); + throw new BadRequestException(msg); + } + } + + /** + * Checks if user requested ownerships are valid. + * + * @param ownership ownerships upon to filter devices using ownership + */ + public static void validateOwnershipType(String ownership) throws BadRequestException { + switch (ownership) { + case "BYOD": + case "COPE": + case "WORK_PROFILE": + case "GOOGLE_ENTERPRISE": + case "COSU": + case "FULLY_MANAGED": + case "DEDICATED_DEVICE": + break; + default: + String msg = "Invalid ownership type received.Valid ownership types are BYOD | COPE | WORK_PROFILE |" + + "GOOGLE_ENTERPRISE | COSU | FULLY_MANAGED | DEDICATED_DEVICE"; + log.error(msg); + throw new BadRequestException(msg); + } + } + + /** + * Checks if user requested Action status codes are valid. + * + * @param status status codes upon to filter operation logs using status + */ + public static void validateStatusFiltering(String status) throws BadRequestException { + if (Constants.OperationStatus.COMPLETED.toUpperCase().equals(status) + || Constants.OperationStatus.ERROR.toUpperCase().equals(status) + || Constants.OperationStatus.NOTNOW.toUpperCase().equals(status) + || Constants.OperationStatus.REPEATED.toUpperCase().equals(status) + || Constants.OperationStatus.PENDING.toUpperCase().equals(status) + || Constants.OperationStatus.IN_PROGRESS.toUpperCase().equals(status)) { + } else { + String msg = "Invalid status type: " + status + ". \nValid status types are COMPLETED | ERROR | " + + "IN_PROGRESS | NOTNOW | PENDING | REPEATED"; + log.error(msg); + throw new BadRequestException(msg); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/util/Constants.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/util/Constants.java new file mode 100644 index 0000000000..a78c16077f --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/util/Constants.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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. + * + * + * Copyright (c) 2019, 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.application.mgt.store.api.util; + +/** + * Holds the constants used by DeviceImpl Management Admin web application. + */ +public class Constants { + + public static final String USER_CLAIM_EMAIL_ADDRESS = "http://wso2.org/claims/emailaddress"; + public static final String USER_CLAIM_FIRST_NAME = "http://wso2.org/claims/givenname"; + public static final String USER_CLAIM_LAST_NAME = "http://wso2.org/claims/lastname"; + public static final String USER_CLAIM_CREATED = "http://wso2.org/claims/created"; + public static final String USER_CLAIM_MODIFIED = "http://wso2.org/claims/modified"; + public static final String USER_CLAIM_DEVICES = "http://wso2.org/claims/devices"; + public static final String PRIMARY_USER_STORE = "PRIMARY"; + public static final String DEFAULT_STREAM_VERSION = "1.0.0"; + public static final String SCOPE = "scope"; + public static final String JDBC_USERSTOREMANAGER = "org.wso2.carbon.user.core.jdbc.JDBCUserStoreManager"; + public static final String DEFAULT_SIMPLE_DATE_FORMAT = "EEE, d MMM yyyy HH:mm:ss Z"; + public static final int DEFAULT_PAGE_LIMIT = 50; + public static final String FORWARD_SLASH = "/"; + public static final String ANDROID = "android"; + public static final String ANDROID_POLICY_VALIDATOR = "io.entgra.proprietary.platform.android." + + "core.polcy.AndroidPolicyPayloadValidator"; + public static final String IOS = "ios"; + public static final String WINDOWS = "windows"; + + + public final class OperationStatus { + private OperationStatus () { throw new AssertionError(); } + public static final String COMPLETED = "completed"; + public static final String ERROR = "error"; + public static final String IN_PROGRESS = "in_progress"; + public static final String PENDING = "pending"; + public static final String NOTNOW = "notnow"; + public static final String REPEATED = "repeated"; + } + public static final String DEVICES = "devices"; + public static final String ATTRIBUTE_DISPLAY_NAME = "DisplayName"; + public static final String ATTRIBUTE_DESCRIPTION = "Description"; + public static final String EXTERNAL_DEVICE_CLAIM_DISPLAY_NAME = "Devices"; + public static final String EXTERNAL_DEVICE_CLAIM_DESCRIPTION = "Device list"; + + public final class ErrorMessages { + private ErrorMessages () { throw new AssertionError(); } + + public static final String STATUS_BAD_REQUEST_MESSAGE_DEFAULT = "Bad Request"; + + } + + public final class DeviceConstants { + private DeviceConstants () { throw new AssertionError(); } + + public static final String APPLICATION_JSON = "application/json"; + public static final String HEADER_CONTENT_TYPE = "Content-Type"; + } + + public final class Permission { + private Permission() { throw new AssertionError(); } + + public static final String ADMIN = "/permission/admin"; + public static final String LOGIN = "/permission/admin/login"; + public static final String DEVICE_MGT = "/permission/admin/device-mgt"; + public static final String APP_MGT = "/permission/admin/app-mgt"; + } + +} 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 f90a205c0a..01145b05ec 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 @@ -269,6 +269,12 @@ public interface DeviceManagementService { @QueryParam("ownership") @Size(max = 45) String ownership, + @ApiParam( + name = "serialNumber", + value = "The serial number of the device.", + required = false) + @QueryParam("serialNumber") + String serialNumber, @ApiParam( name = "status", value = "Provide the device status details, such as active or inactive.", 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 b2f2d1ab11..7648a102b8 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 @@ -172,6 +172,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { @QueryParam("userPattern") String userPattern, @QueryParam("role") String role, @QueryParam("ownership") String ownership, + @QueryParam("serialNumber") String serialNumber, @QueryParam("status") List status, @QueryParam("groupId") int groupId, @QueryParam("since") String since, @@ -205,6 +206,9 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { RequestValidationUtil.validateOwnershipType(ownership); request.setOwnership(ownership); } + if (StringUtils.isNotBlank(serialNumber)) { + request.setSerialNumber(serialNumber); + } if (status != null && !status.isEmpty()) { boolean isStatusEmpty = true; for (String statusString : status){ diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java index bb9de05c1f..7b995660ad 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java @@ -175,7 +175,8 @@ public class DeviceManagementServiceImplTest { .toReturn(this.deviceAccessAuthorizationService); Response response = this.deviceManagementService .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); + null, DEFAULT_STATUS_LIST, 1, null, null, false, + 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); } @@ -194,19 +195,23 @@ public class DeviceManagementServiceImplTest { Response response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); + null, DEFAULT_STATUS_LIST, 1, null, null, false, + 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); response = this.deviceManagementService .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, null, DEFAULT_OWNERSHIP, - DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); + null, DEFAULT_STATUS_LIST, 1, null, null, false, + 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); response = this.deviceManagementService .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, null, null, null, DEFAULT_OWNERSHIP, - DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); + null, DEFAULT_STATUS_LIST, 1, null, null, false, + 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); response = this.deviceManagementService .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, null, null, null, DEFAULT_OWNERSHIP, - DEFAULT_STATUS_LIST, 1, null, null, true, 10, 5); + null, DEFAULT_STATUS_LIST, 1, null, null, true, + 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); } @@ -319,7 +324,7 @@ public class DeviceManagementServiceImplTest { .toReturn(this.deviceManagementProviderService); Mockito.when(deviceAccessAuthorizationService.isDeviceAdminUser()).thenReturn(true); deviceManagementService.getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, - DEFAULT_ROLE, DEFAULT_OWNERSHIP, DEFAULT_STATUS_LIST, 1, + DEFAULT_ROLE, DEFAULT_OWNERSHIP, null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); } @@ -339,11 +344,11 @@ public class DeviceManagementServiceImplTest { Response response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP - , DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); + , null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, null, DEFAULT_USERNAME, DEFAULT_ROLE, DEFAULT_OWNERSHIP - , DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); + , null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); } @@ -365,7 +370,8 @@ public class DeviceManagementServiceImplTest { Response response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, "newuser", null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - DEFAULT_STATUS_LIST, 0, null, null, false, 10, 5); + null, DEFAULT_STATUS_LIST, 0, null, null, false, + 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode()); Mockito.reset(this.deviceAccessAuthorizationService); } @@ -386,15 +392,18 @@ public class DeviceManagementServiceImplTest { Response response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - DEFAULT_STATUS_LIST, 0, null, ifModifiedSince, false, 10, 5); + null, DEFAULT_STATUS_LIST, 0, null, ifModifiedSince, false, + 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.NOT_MODIFIED.getStatusCode()); response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - DEFAULT_STATUS_LIST, 0, null, ifModifiedSince, true, 10, 5); + null, DEFAULT_STATUS_LIST, 0, null, ifModifiedSince, true, + 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.NOT_MODIFIED.getStatusCode()); response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - DEFAULT_STATUS_LIST, 0, null, "ErrorModifiedSince", false, 10, 5); + null, DEFAULT_STATUS_LIST, 0, null, "ErrorModifiedSince", + false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); } @@ -414,15 +423,18 @@ public class DeviceManagementServiceImplTest { Response response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - DEFAULT_STATUS_LIST, 0, since, null, false, 10, 5); + null, DEFAULT_STATUS_LIST, 0, since, null, false, + 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - DEFAULT_STATUS_LIST, 0, since, null, true, 10, 5); + null, DEFAULT_STATUS_LIST, 0, since, null, true, + 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - DEFAULT_STATUS_LIST, 0, "ErrorSince", null, false, 10, 5); + null, DEFAULT_STATUS_LIST, 0, "ErrorSince", null, false, + 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); } @@ -444,7 +456,8 @@ public class DeviceManagementServiceImplTest { Response response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); + null, DEFAULT_STATUS_LIST, 1, null, null, false, + 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); Mockito.reset(this.deviceManagementProviderService); } @@ -466,7 +479,8 @@ public class DeviceManagementServiceImplTest { Response response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); + null, DEFAULT_STATUS_LIST, 1, null, null, false, + 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); Mockito.reset(this.deviceAccessAuthorizationService); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/PaginationRequest.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/PaginationRequest.java index 94cf5c5272..29bb7922e9 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/PaginationRequest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/PaginationRequest.java @@ -40,6 +40,7 @@ public class PaginationRequest { private String ownerRole; private Date since; private String filter; + private String serialNumber; private Map property = new HashMap<>(); private List statusList = new ArrayList<>(); private OperationLogFilters operationLogFilters = new OperationLogFilters(); @@ -153,6 +154,10 @@ public class PaginationRequest { return this.property.get(key); } + public String getSerialNumber() { return serialNumber; } + + public void setSerialNumber(String serialNumber) { this.serialNumber = serialNumber; } + public Map getProperties() { Map temp = new HashMap<>(); temp.putAll(property); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/operation/mgt/ActivityStatus.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/operation/mgt/ActivityStatus.java index 1007c18058..234aa084c2 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/operation/mgt/ActivityStatus.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/operation/mgt/ActivityStatus.java @@ -30,7 +30,7 @@ import java.util.List; public class ActivityStatus { public enum Status { - IN_PROGRESS, PENDING, COMPLETED, ERROR, REPEATED, INVALID, UNAUTHORIZED + IN_PROGRESS, PENDING, COMPLETED, ERROR, REPEATED, INVALID, UNAUTHORIZED, NOTNOW } @ApiModelProperty( diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/ui/Item.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/ui/Item.java index faf97d7e11..43927eb876 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/ui/Item.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/ui/Item.java @@ -27,6 +27,7 @@ public class Item { private String label; private String tooltip; + private String docLink; private String key; private String value; private boolean isRequired; @@ -65,6 +66,16 @@ public class Item { this.tooltip = tooltip; } + @XmlElement(name = "DocLink") + public String getDocLink() { + return docLink; + } + + public void setDocLink(String docLink) { + this.docLink = docLink; + } + + @XmlElement(name = "Key", required = true) public String getKey() { return key; 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 38ef50a923..82aded2490 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 @@ -651,16 +651,14 @@ public interface DeviceDAO { /** * This method is used to get the details of subscribed devices. * - * @param deviceIds device ids of the subscribed devices. - * @param tenantId Id of the current tenant. - * @param offsetValue offset value for get paginated request. - * @param limitValue limit value for get paginated request. - * @param status status of the devices. + * @param deviceIds device ids of the subscribed devices. + * @param tenantId Id of the current tenant. + * @param request paginated request object. * @return devices - subscribed device details list * @throws DeviceManagementDAOException if connections establishment fails. */ - List getSubscribedDevices(int offsetValue, int limitValue, List deviceIds, - int tenantId, List status) throws DeviceManagementDAOException; + List getSubscribedDevices(PaginationRequest request, List deviceIds, int tenantId) + throws DeviceManagementDAOException; /** * @param deviceIds device ids of the subscribed devices. diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java index 83615eb056..eb3fa87f54 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java @@ -67,6 +67,9 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { boolean isStatusProvided = false; Date since = request.getSince(); boolean isSinceProvided = false; + String serial = request.getSerialNumber(); + boolean isSerialProvided = false; + try { Connection conn = getConnection(); @@ -87,10 +90,19 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { "d.DESCRIPTION, " + "d.NAME, " + "d.DEVICE_IDENTIFICATION, " + - "t.NAME AS DEVICE_TYPE " + - "FROM DM_DEVICE d, DM_DEVICE_TYPE t "; - - sql = sql + " WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?"; + "t.NAME AS DEVICE_TYPE "; + + if (serial != null) { + sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_INFO i " + + "WHERE DEVICE_TYPE_ID = t.ID " + + "AND d.ID= i.DEVICE_ID " + + "AND i.KEY_FIELD = 'serial' " + + "AND i.VALUE_FIELD = ? " + + "AND d.TENANT_ID = ? "; + isSerialProvided = true; + } else { + sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ? "; + } //Add query for last updated timestamp if (since != null) { sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?"; @@ -128,6 +140,9 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { try (PreparedStatement stmt = conn.prepareStatement(sql)) { int paramIdx = 1; + if (isSerialProvided) { + stmt.setString(paramIdx++, serial); + } stmt.setInt(paramIdx++, tenantId); if (isSinceProvided) { stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime())); @@ -877,11 +892,15 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { } @Override - public List getSubscribedDevices(int offsetValue, int limitValue, - List deviceIds, int tenantId, List status) + public List getSubscribedDevices(PaginationRequest request, List deviceIds, int tenantId) throws DeviceManagementDAOException { Connection conn; - + int limitValue = request.getRowCount(); + int offsetValue = request.getStartIndex(); + List status = request.getStatusList(); + String name = request.getDeviceName(); + String user = request.getOwner(); + String ownership = request.getOwnership(); try { List devices = new ArrayList<>(); if (deviceIds.isEmpty()) { @@ -891,6 +910,10 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { int index = 1; boolean isStatusProvided = false; + boolean isDeviceNameProvided = false; + boolean isOwnerProvided = false; + boolean isOwnershipProvided = false; + StringJoiner joiner = new StringJoiner(",", "SELECT " + "DM_DEVICE.ID AS DEVICE_ID, " @@ -918,6 +941,18 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { deviceIds.stream().map(ignored -> "?").forEach(joiner::add); String query = joiner.toString(); + if (name != null && !name.isEmpty()) { + query += " AND DM_DEVICE.NAME LIKE ?"; + isDeviceNameProvided = true; + } + if (ownership != null && !ownership.isEmpty()) { + query += " AND e.OWNERSHIP = ?"; + isOwnershipProvided = true; + } + if (user != null && !user.isEmpty()) { + query += " AND e.OWNER = ?"; + isOwnerProvided = true; + } if (status != null && !status.isEmpty()) { query += buildStatusQuery(status); isStatusProvided = true; @@ -930,8 +965,16 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { for (Integer deviceId : deviceIds) { ps.setObject(index++, deviceId); } - ps.setInt(index++, tenantId); + if (isDeviceNameProvided) { + ps.setString(index++, name + "%"); + } + if (isOwnershipProvided) { + ps.setString(index++, ownership); + } + if (isOwnerProvided) { + ps.setString(index++, user); + } if (isStatusProvided) { for (String deviceStatus : status) { ps.setString(index++, deviceStatus); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java index ed5a8c843c..4393a4546e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java @@ -68,6 +68,8 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { boolean isStatusProvided = false; Date since = request.getSince(); boolean isSinceProvided = false; + String serial = request.getSerialNumber(); + boolean isSerialProvided = false; try { conn = getConnection(); @@ -88,9 +90,19 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { "d.DESCRIPTION, " + "d.NAME, " + "d.DEVICE_IDENTIFICATION, " + - "t.NAME AS DEVICE_TYPE " + - "FROM DM_DEVICE d, " + - "DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?"; + "t.NAME AS DEVICE_TYPE "; + + if (serial != null) { + sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_INFO i " + + "WHERE DEVICE_TYPE_ID = t.ID " + + "AND d.ID= i.DEVICE_ID " + + "AND i.KEY_FIELD = 'serial' " + + "AND i.VALUE_FIELD = ? " + + "AND d.TENANT_ID = ? "; + isSerialProvided = true; + } else { + sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ? "; + } //Add query for last updated timestamp if (since != null) { sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?"; @@ -128,6 +140,9 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { try (PreparedStatement stmt = conn.prepareStatement(sql)) { int paramIdx = 1; + if (isSerialProvided) { + stmt.setString(paramIdx++, serial); + } stmt.setInt(paramIdx++, tenantId); if (isSinceProvided) { stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime())); @@ -847,11 +862,15 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { } @Override - public List getSubscribedDevices(int offsetValue, int limitValue, - List deviceIds, int tenantId, List status) + public List getSubscribedDevices(PaginationRequest request, List deviceIds, int tenantId) throws DeviceManagementDAOException { Connection conn; - + int limitValue = request.getRowCount(); + int offsetValue = request.getStartIndex(); + List status = request.getStatusList(); + String name = request.getDeviceName(); + String user = request.getOwner(); + String ownership = request.getOwnership(); try { List devices = new ArrayList<>(); if (deviceIds.isEmpty()) { @@ -861,6 +880,9 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { int index = 1; boolean isStatusProvided = false; + boolean isDeviceNameProvided = false; + boolean isOwnerProvided = false; + boolean isOwnershipProvided = false; StringJoiner joiner = new StringJoiner(",", "SELECT " + "DM_DEVICE.ID AS DEVICE_ID, " @@ -888,6 +910,18 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { deviceIds.stream().map(ignored -> "?").forEach(joiner::add); String query = joiner.toString(); + if (name != null && !name.isEmpty()) { + query += " AND DM_DEVICE.NAME LIKE ?"; + isDeviceNameProvided = true; + } + if (ownership != null && !ownership.isEmpty()) { + query += " AND e.OWNERSHIP = ?"; + isOwnershipProvided = true; + } + if (user != null && !user.isEmpty()) { + query += " AND e.OWNER = ?"; + isOwnerProvided = true; + } if (status != null && !status.isEmpty()) { query += buildStatusQuery(status); isStatusProvided = true; @@ -902,6 +936,15 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { } ps.setInt(index++, tenantId); + if (isDeviceNameProvided) { + ps.setString(index++, name + "%"); + } + if (isOwnershipProvided) { + ps.setString(index++, ownership); + } + if (isOwnerProvided) { + ps.setString(index++, user); + } if (isStatusProvided) { for (String deviceStatus : status) { ps.setString(index++, deviceStatus); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java index cfefbb8b3f..66313603cb 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java @@ -67,6 +67,8 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { boolean isStatusProvided = false; Date since = request.getSince(); boolean isSinceProvided = false; + String serial = request.getSerialNumber(); + boolean isSerialProvided = false; try { conn = getConnection(); @@ -87,11 +89,19 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { "d.DESCRIPTION, " + "d.NAME, " + "d.DEVICE_IDENTIFICATION, " + - "t.NAME AS DEVICE_TYPE " + - "FROM DM_DEVICE d, " + - "DM_DEVICE_TYPE t " + - "WHERE DEVICE_TYPE_ID = t.ID " + - "AND d.TENANT_ID = ?"; + "t.NAME AS DEVICE_TYPE "; + + if (serial != null) { + sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_INFO i " + + "WHERE DEVICE_TYPE_ID = t.ID " + + "AND d.ID= i.DEVICE_ID " + + "AND i.KEY_FIELD = 'serial' " + + "AND i.VALUE_FIELD = ? " + + "AND d.TENANT_ID = ? "; + isSerialProvided = true; + } else { + sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ? "; + } //Add the query for device-type if (deviceType != null && !deviceType.isEmpty()) { sql = sql + " AND t.NAME = ?"; @@ -124,6 +134,9 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { try (PreparedStatement stmt = conn.prepareStatement(sql)) { int paramIdx = 1; + if (isSerialProvided) { + stmt.setString(paramIdx++, serial); + } stmt.setInt(paramIdx++, tenantId); if (isDeviceTypeProvided) { stmt.setString(paramIdx++, deviceType); @@ -827,11 +840,15 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { } @Override - public List getSubscribedDevices(int offsetValue, int limitValue, - List deviceIds, int tenantId, List status) + public List getSubscribedDevices(PaginationRequest request, List deviceIds, int tenantId) throws DeviceManagementDAOException { Connection conn; - + int limitValue = request.getRowCount(); + int offsetValue = request.getStartIndex(); + List status = request.getStatusList(); + String name = request.getDeviceName(); + String user = request.getOwner(); + String ownership = request.getOwnership(); try { List devices = new ArrayList<>(); if (deviceIds.isEmpty()) { @@ -841,6 +858,9 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { int index = 1; boolean isStatusProvided = false; + boolean isDeviceNameProvided = false; + boolean isOwnerProvided = false; + boolean isOwnershipProvided = false; StringJoiner joiner = new StringJoiner(",", "SELECT " + "DM_DEVICE.ID AS DEVICE_ID, " @@ -868,6 +888,18 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { deviceIds.stream().map(ignored -> "?").forEach(joiner::add); String query = joiner.toString(); + if (name != null && !name.isEmpty()) { + query += " AND DM_DEVICE.NAME LIKE ?"; + isDeviceNameProvided = true; + } + if (ownership != null && !ownership.isEmpty()) { + query += " AND e.OWNERSHIP = ?"; + isOwnershipProvided = true; + } + if (user != null && !user.isEmpty()) { + query += " AND e.OWNER = ?"; + isOwnerProvided = true; + } if (status != null && !status.isEmpty()) { query += buildStatusQuery(status); isStatusProvided = true; @@ -882,6 +914,15 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { } ps.setInt(index++, tenantId); + if (isDeviceNameProvided) { + ps.setString(index++, name + "%"); + } + if (isOwnershipProvided) { + ps.setString(index++, ownership); + } + if (isOwnerProvided) { + ps.setString(index++, user); + } if (isStatusProvided) { for (String deviceStatus : status) { ps.setString(index++, deviceStatus); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java index 755f882a46..4e87d8ab61 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java @@ -69,6 +69,8 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { boolean isStatusProvided = false; Date since = request.getSince(); boolean isSinceProvided = false; + String serial = request.getSerialNumber(); + boolean isSerialProvided = false; try { conn = getConnection(); @@ -89,8 +91,19 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { "d.DESCRIPTION, " + "d.NAME, " + "d.DEVICE_IDENTIFICATION, " + - "t.NAME AS DEVICE_TYPE " + - "FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?"; + "t.NAME AS DEVICE_TYPE "; + + if (serial != null) { + sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_INFO i " + + "WHERE DEVICE_TYPE_ID = t.ID " + + "AND d.ID= i.DEVICE_ID " + + "AND i.KEY_FIELD = 'serial' " + + "AND i.VALUE_FIELD = ? " + + "AND d.TENANT_ID = ? "; + isSerialProvided = true; + } else { + sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ? "; + } //Add query for last updated timestamp if (since != null) { sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?"; @@ -128,6 +141,9 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { try (PreparedStatement stmt = conn.prepareStatement(sql)) { int paramIdx = 1; + if (isSerialProvided) { + stmt.setString(paramIdx++, serial); + } stmt.setInt(paramIdx++, tenantId); if (isSinceProvided) { stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime())); @@ -693,11 +709,15 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { } @Override - public List getSubscribedDevices(int offsetValue, int limitValue, - List deviceIds, int tenantId, List status) + public List getSubscribedDevices(PaginationRequest request, List deviceIds, int tenantId) throws DeviceManagementDAOException { Connection conn; - + int limitValue = request.getRowCount(); + int offsetValue = request.getStartIndex(); + List status = request.getStatusList(); + String name = request.getDeviceName(); + String user = request.getOwner(); + String ownership = request.getOwnership(); try { List devices = new ArrayList<>(); if (deviceIds.isEmpty()) { @@ -707,6 +727,9 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { int index = 1; boolean isStatusProvided = false; + boolean isDeviceNameProvided = false; + boolean isOwnerProvided = false; + boolean isOwnershipProvided = false; StringJoiner joiner = new StringJoiner(",", "SELECT " + "DM_DEVICE.ID AS DEVICE_ID, " @@ -734,6 +757,18 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { deviceIds.stream().map(ignored -> "?").forEach(joiner::add); String query = joiner.toString(); + if (name != null && !name.isEmpty()) { + query += " AND DM_DEVICE.NAME LIKE ?"; + isDeviceNameProvided = true; + } + if (ownership != null && !ownership.isEmpty()) { + query += " AND e.OWNERSHIP = ?"; + isOwnershipProvided = true; + } + if (user != null && !user.isEmpty()) { + query += " AND e.OWNER = ?"; + isOwnerProvided = true; + } if (status != null && !status.isEmpty()) { query += buildStatusQuery(status); isStatusProvided = true; @@ -748,6 +783,15 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { } ps.setInt(index++, tenantId); + if (isDeviceNameProvided) { + ps.setString(index++, name + "%"); + } + if (isOwnershipProvided) { + ps.setString(index++, ownership); + } + if (isOwnerProvided) { + ps.setString(index++, user); + } if (isStatusProvided) { for (String deviceStatus : status) { ps.setString(index++, deviceStatus); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/CommandOperation.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/CommandOperation.java index bc132a9b20..c7eb730c4e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/CommandOperation.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/CommandOperation.java @@ -22,6 +22,10 @@ public class CommandOperation extends Operation { private boolean enabled; + public CommandOperation() { + setControl(Control.NO_REPEAT); + } + public boolean isEnabled() { return enabled; } @@ -34,8 +38,4 @@ public class CommandOperation extends Operation { return Type.COMMAND; } - public Control getControl(){ - return Control.NO_REPEAT; - } - } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/ConfigOperation.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/ConfigOperation.java index c2be65a372..28116d5dc6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/ConfigOperation.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/ConfigOperation.java @@ -23,10 +23,11 @@ import java.util.List; public class ConfigOperation extends Operation { - private List properties; + private final List properties; public ConfigOperation() { - properties = new ArrayList(); + properties = new ArrayList<>(); + setControl(Control.REPEAT); } public List getConfigProperties() { @@ -37,6 +38,10 @@ public class ConfigOperation extends Operation { properties.add(new Property(name, value, type)); } + public Type getType() { + return Type.CONFIG; + } + public static class Property { private String name; private Object value; @@ -73,13 +78,4 @@ public class ConfigOperation extends Operation { } } - public Type getType() { - return Type.CONFIG; - } - - - public Control getControl(){ - return Control.REPEAT; - } - } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/PolicyOperation.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/PolicyOperation.java index dc6ae4dd78..bc93bcf0f8 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/PolicyOperation.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/PolicyOperation.java @@ -19,7 +19,13 @@ package org.wso2.carbon.device.mgt.core.dto.operation.mgt; import java.util.List; -public class PolicyOperation extends Operation{ +public class PolicyOperation extends Operation { + + private List profileOperations; + + public PolicyOperation() { + setControl(Control.REPEAT); + } public List getProfileOperations() { return profileOperations; @@ -29,10 +35,4 @@ public class PolicyOperation extends Operation{ this.profileOperations = profileOperations; } - private List profileOperations; - - public Control getControl(){ - return Control.REPEAT; - } - } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/ProfileOperation.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/ProfileOperation.java index 107cf091d7..9e3db16f2e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/ProfileOperation.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dto/operation/mgt/ProfileOperation.java @@ -22,13 +22,12 @@ import java.io.Serializable; public class ProfileOperation extends ConfigOperation implements Serializable { - public Type getType() { - return Type.PROFILE; + public ProfileOperation() { + super(); } - - public Control getControl(){ - return Control.REPEAT; + public Type getType() { + return Type.PROFILE; } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/CommandOperation.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/CommandOperation.java index 3a9ecefca3..618c05adf3 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/CommandOperation.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/CommandOperation.java @@ -24,6 +24,10 @@ public class CommandOperation extends Operation { private boolean enabled; + public CommandOperation() { + setControl(Control.NO_REPEAT); + } + public boolean isEnabled() { return enabled; } @@ -35,8 +39,5 @@ public class CommandOperation extends Operation { public Type getType() { return Type.COMMAND; } - public Control getControl(){ - return Control.NO_REPEAT; - } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/ConfigOperation.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/ConfigOperation.java index 69d8aafc4a..753b170a1b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/ConfigOperation.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/ConfigOperation.java @@ -21,8 +21,6 @@ package org.wso2.carbon.device.mgt.core.operation.mgt; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; public class ConfigOperation extends Operation { @@ -38,6 +36,15 @@ public class ConfigOperation extends Operation { properties.add(new Property(name, value, type)); }*/ + public ConfigOperation() { + //properties = new ArrayList<>(); + setControl(Control.REPEAT); + } + + public Type getType() { + return Type.CONFIG; + } + public static class Property implements Serializable { private String name; private Object value; @@ -74,12 +81,4 @@ public class ConfigOperation extends Operation { } } - public Type getType() { - return Type.CONFIG; - } - - public Control getControl(){ - return Control.REPEAT; - } - } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/PolicyOperation.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/PolicyOperation.java index 6b36492a83..47ca55f95e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/PolicyOperation.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/PolicyOperation.java @@ -18,6 +18,7 @@ package org.wso2.carbon.device.mgt.core.operation.mgt; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; + import java.util.List; public class PolicyOperation extends Operation { @@ -25,6 +26,10 @@ public class PolicyOperation extends Operation { public static final String POLICY_OPERATION_CODE = "POLICY_BUNDLE"; private List profileOperations; + public PolicyOperation() { + setControl(Control.REPEAT); + } + public List getProfileOperations() { return profileOperations; } @@ -33,8 +38,4 @@ public class PolicyOperation extends Operation { this.profileOperations = profileOperations; } - public Control getControl(){ - return Control.REPEAT; - } - } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/ProfileOperation.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/ProfileOperation.java index 3423524666..ac1082317b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/ProfileOperation.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/ProfileOperation.java @@ -19,21 +19,21 @@ package org.wso2.carbon.device.mgt.core.operation.mgt; import java.io.Serializable; -import java.util.ArrayList; import java.util.List; public class ProfileOperation extends ConfigOperation implements Serializable { + private static final long serialVersionUID = -3322674908775087365L; private List correctiveActionIds; private List reactiveActionIds; - public Type getType() { - return Type.PROFILE; + public ProfileOperation() { + super(); } - public Control getControl(){ - return Control.REPEAT; + public Type getType() { + return Type.PROFILE; } public List getCorrectiveActionIds() { @@ -51,4 +51,5 @@ public class ProfileOperation extends ConfigOperation implements Serializable { public void setReactiveActionIds(List reactiveActionIds) { this.reactiveActionIds = reactiveActionIds; } + } 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 fb3dd19527..f084e35c3a 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 @@ -905,14 +905,12 @@ public interface DeviceManagementProviderService { * This method retrieves a list of subscribed devices. * * @param devicesIds devices ids of the subscribed devices. - * @param offsetValue offset value for get paginated request. - * @param limitValue limit value for get paginated request. - * @param status status of the devices. + * @param request paginated request object. * @return {@link PaginationResult} * @throws DeviceManagementException if any service level or DAO level error occurs. */ - PaginationResult getAppSubscribedDevices(int offsetValue, int limitValue, - List devicesIds, List status) throws DeviceManagementException; + PaginationResult getAppSubscribedDevices(PaginationRequest request, List devicesIds) + throws DeviceManagementException; /** * This method is used to get a list of applications installed in all enrolled devices 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 dba8d2b88e..e9082f4010 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 @@ -4161,9 +4161,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } @Override - public PaginationResult getAppSubscribedDevices(int offsetValue, int limitValue, List devicesIds, - List status) throws DeviceManagementException { - + public PaginationResult getAppSubscribedDevices(PaginationRequest request, List devicesIds) throws DeviceManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); if (log.isDebugEnabled()) { log.debug("Getting all devices details for device ids: " + devicesIds); @@ -4172,15 +4170,14 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv List subscribedDeviceDetails; try { DeviceManagementDAOFactory.openConnection(); - subscribedDeviceDetails = deviceDAO - .getSubscribedDevices(offsetValue, limitValue, devicesIds, tenantId, status); + subscribedDeviceDetails = deviceDAO.getSubscribedDevices(request, devicesIds, tenantId); if (subscribedDeviceDetails.isEmpty()) { paginationResult.setData(new ArrayList<>()); paginationResult.setRecordsFiltered(0); paginationResult.setRecordsTotal(0); return paginationResult; } - int count = deviceDAO.getSubscribedDeviceCount(devicesIds, tenantId, status); + int count = deviceDAO.getSubscribedDeviceCount(devicesIds, tenantId, request.getStatusList()); paginationResult.setRecordsFiltered(count); paginationResult.setRecordsTotal(count); } catch (DeviceManagementDAOException e) { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/status/task/impl/DeviceStatusMonitoringTask.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/status/task/impl/DeviceStatusMonitoringTask.java index 7bc831c313..5182fc3651 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/status/task/impl/DeviceStatusMonitoringTask.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/status/task/impl/DeviceStatusMonitoringTask.java @@ -52,6 +52,7 @@ public class DeviceStatusMonitoringTask extends DynamicPartitionedScheduleTask { @Override public void setProperties(Map properties) { + super.setProperties(properties); deviceType = properties.get(DeviceStatusTaskManagerServiceImpl.DEVICE_TYPE); deviceTypeId = Integer.parseInt(properties.get(DeviceStatusTaskManagerServiceImpl.DEVICE_TYPE_ID)); String deviceStatusTaskConfigStr = properties.get(DeviceStatusTaskManagerServiceImpl.DEVICE_STATUS_TASK_CONFIG); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/task/impl/DeviceDetailsRetrieverTask.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/task/impl/DeviceDetailsRetrieverTask.java index 360325e9ab..0c6f77c15d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/task/impl/DeviceDetailsRetrieverTask.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/task/impl/DeviceDetailsRetrieverTask.java @@ -39,28 +39,26 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.device.mgt.common.DynamicTaskContext; -import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig; import org.wso2.carbon.device.mgt.common.StartupOperationConfig; +import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.task.DeviceMgtTaskException; import org.wso2.carbon.device.mgt.core.task.DeviceTaskManager; -import org.wso2.carbon.ntask.core.Task; -import org.wso2.carbon.user.api.UserStoreException; import java.util.List; import java.util.Map; public class DeviceDetailsRetrieverTask extends DynamicPartitionedScheduleTask { - private static Log log = LogFactory.getLog(DeviceDetailsRetrieverTask.class); + private static final Log log = LogFactory.getLog(DeviceDetailsRetrieverTask.class); private String deviceType; private DeviceManagementProviderService deviceManagementProviderService; @Override public void setProperties(Map map) { + super.setProperties(map); deviceType = map.get("DEVICE_TYPE"); } @@ -122,7 +120,7 @@ public class DeviceDetailsRetrieverTask extends DynamicPartitionedScheduleTask { //pass the configurations also from here, monitoring tasks try { if (deviceManagementProviderService.isDeviceMonitoringEnabled(deviceType)) { - deviceTaskManager.addOperations(super.getTaskContext()); + deviceTaskManager.addOperations(getTaskContext()); } } catch (DeviceMgtTaskException e) { log.error("Error occurred while trying to add the operations to " + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/task/impl/DynamicPartitionedScheduleTask.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/task/impl/DynamicPartitionedScheduleTask.java index ef11b3bda2..0bbb59d2bd 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/task/impl/DynamicPartitionedScheduleTask.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/task/impl/DynamicPartitionedScheduleTask.java @@ -26,12 +26,27 @@ import org.wso2.carbon.device.mgt.common.DynamicTaskContext; import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; import org.wso2.carbon.ntask.core.Task; +import java.util.Map; + public abstract class DynamicPartitionedScheduleTask implements Task { private static final Log log = LogFactory.getLog(DynamicPartitionedScheduleTask.class); private static DynamicTaskContext taskContext = null; + private Map properties; + + @Override + public void setProperties(Map properties) { + this.properties = properties; + } + + public String getProperty(String name) { + if (properties == null) { + return null; + } + return properties.get(name); + } @Override public final void init() { @@ -97,11 +112,7 @@ public abstract class DynamicPartitionedScheduleTask implements Task { } public static boolean isDynamicTaskEligible(){ - if(taskContext != null && taskContext.isPartitioningEnabled()) { - return true; - } else { - return false; - } + return taskContext != null && taskContext.isPartitioningEnabled(); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/task/impl/RandomlyAssignedScheduleTask.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/task/impl/RandomlyAssignedScheduleTask.java index 56a1c498a0..fb8a5b9235 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/task/impl/RandomlyAssignedScheduleTask.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/task/impl/RandomlyAssignedScheduleTask.java @@ -61,6 +61,8 @@ public abstract class RandomlyAssignedScheduleTask implements Task { log.error("Error refreshing Variables necessary for Randomly Assigned Scheduled Task. " + "Dynamic Tasks will not function.", e); } + } else { + qualifiedToExecuteTask = true; } } diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/enforcement/DelegationTask.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/enforcement/DelegationTask.java index b24e84f029..ba4cfd971c 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/enforcement/DelegationTask.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/enforcement/DelegationTask.java @@ -21,8 +21,8 @@ package org.wso2.carbon.policy.mgt.core.enforcement; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.common.Device; -import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; import org.wso2.carbon.device.mgt.core.config.policy.PolicyConfiguration; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; @@ -36,19 +36,13 @@ import org.wso2.carbon.policy.mgt.core.mgt.impl.PolicyManagerImpl; import java.util.ArrayList; import java.util.List; -import java.util.Map; public class DelegationTask extends DynamicPartitionedScheduleTask { private static final Log log = LogFactory.getLog(DelegationTask.class); - private PolicyConfiguration policyConfiguration = DeviceConfigurationManager.getInstance() + private final PolicyConfiguration policyConfiguration = DeviceConfigurationManager.getInstance() .getDeviceManagementConfig().getPolicyConfiguration(); - @Override - public void setProperties(Map map) { - - } - @Override public void executeDynamicTask() { try { @@ -70,10 +64,10 @@ public class DelegationTask extends DynamicPartitionedScheduleTask { try { devices = new ArrayList<>(); toBeNotified = new ArrayList<>(); - if (super.isDynamicTaskEligible()) { + if (isDynamicTaskEligible()) { devices.addAll(service.getAllocatedDevices(deviceType, - super.getTaskContext().getActiveServerCount(), - super.getTaskContext().getServerHashIndex())); + getTaskContext().getActiveServerCount(), + getTaskContext().getServerHashIndex())); } else { devices.addAll(service.getAllDevices(deviceType, false)); } @@ -81,9 +75,9 @@ public class DelegationTask extends DynamicPartitionedScheduleTask { if (device != null && device.getEnrolmentInfo() != null && device.getEnrolmentInfo().getStatus() != EnrolmentInfo.Status.REMOVED) { toBeNotified.add(device); - } - if (log.isDebugEnabled()) { - log.debug("Adding policy operation to device : " + device.getDeviceIdentifier()); + if (log.isDebugEnabled()) { + log.debug("Adding policy operation to device : " + device.getDeviceIdentifier()); + } } } if (!toBeNotified.isEmpty()) { diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/task/MonitoringTask.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/task/MonitoringTask.java index d51f283a8e..c93ff3d563 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/task/MonitoringTask.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/task/MonitoringTask.java @@ -24,33 +24,22 @@ import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; -import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager; import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.task.impl.DynamicPartitionedScheduleTask; import org.wso2.carbon.policy.mgt.core.internal.PolicyManagementDataHolder; import org.wso2.carbon.policy.mgt.core.mgt.MonitoringManager; +import org.wso2.carbon.policy.mgt.core.util.PolicyManagementConstants; import java.util.ArrayList; import java.util.List; -import java.util.Map; public class MonitoringTask extends DynamicPartitionedScheduleTask { private static final Log log = LogFactory.getLog(MonitoringTask.class); - @Override - public void setProperties(Map map) { - } - - @Override - public void executeDynamicTask() { - if (log.isDebugEnabled()) { - log.debug("Monitoring task started to run."); - } - this.executeforAllTenants(); - } + private String tenant; /** * Check whether Device platform (ex: android) is exist in the cdm-config.xml file before adding a @@ -66,30 +55,27 @@ public class MonitoringTask extends DynamicPartitionedScheduleTask { return policyMonitoringManager != null; } - private void executeforAllTenants() { - + @Override + public void executeDynamicTask() { + tenant = getProperty(PolicyManagementConstants.TENANT_ID); + if (tenant == null) { + log.warn("Tenant id of the Monitoring Task got null"); + return; + } + int tenantId = Integer.parseInt(tenant); if (log.isDebugEnabled()) { - log.debug("Monitoring task started to run for all tenants."); + log.debug("Monitoring task started to run for tenant: " + tenant); + } + if (MultitenantConstants.SUPER_TENANT_ID == tenantId) { + this.executeTask(); + return; } try { - DeviceManagementProviderService deviceManagementService = PolicyManagementDataHolder - .getInstance().getDeviceManagementService(); - List tenants = deviceManagementService.getDeviceEnrolledTenants(); - for (Integer tenant : tenants) { - if (MultitenantConstants.SUPER_TENANT_ID == tenant) { - this.executeTask(); - continue; - } - try { - PrivilegedCarbonContext.startTenantFlow(); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenant, true); - this.executeTask(); - } finally { - PrivilegedCarbonContext.endTenantFlow(); - } - } - } catch (DeviceManagementException e) { - log.error("Error occurred while trying to get the available tenants from device manager service ", e); + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true); + this.executeTask(); + } finally { + PrivilegedCarbonContext.endTenantFlow(); } } @@ -105,7 +91,7 @@ public class MonitoringTask extends DynamicPartitionedScheduleTask { } } } catch (PolicyComplianceException e) { - log.error("Error occurred while getting the device types."); + log.error("TID:[" + tenant + "] Error occurred while getting the device types."); } if (!deviceTypes.isEmpty()) { try { @@ -113,42 +99,42 @@ public class MonitoringTask extends DynamicPartitionedScheduleTask { PolicyManagementDataHolder.getInstance().getDeviceManagementService(); for (String deviceType : configDeviceTypes) { if (log.isDebugEnabled()) { - log.debug("Running task for device type : " + deviceType); + log.debug("TID:[" + tenant + "] Running task for device type : " + deviceType); } PolicyMonitoringManager monitoringService = PolicyManagementDataHolder.getInstance().getDeviceManagementService() .getPolicyMonitoringManager(deviceType); List devices; - if(super.isDynamicTaskEligible()){ - devices = deviceManagementProviderService.getAllocatedDevices(deviceType, - super.getTaskContext().getActiveServerCount(), - super.getTaskContext().getServerHashIndex()); + if(isDynamicTaskEligible()){ + devices = deviceManagementProviderService + .getAllocatedDevices(deviceType, getTaskContext().getActiveServerCount(), + getTaskContext().getServerHashIndex()); } else { devices = deviceManagementProviderService.getAllDevices(deviceType, false); } if (monitoringService != null && !devices.isEmpty()) { List notifiableDevices = new ArrayList<>(); if (log.isDebugEnabled()) { - log.debug("Removing inactive and blocked devices from the list for the device type : " + - deviceType); + log.debug("TID:[" + tenant + "] Removing inactive and blocked devices from " + + "the list for the device type : " + deviceType); } + StringBuilder sb = new StringBuilder(); for (Device device : devices) { EnrolmentInfo.Status status = device.getEnrolmentInfo().getStatus(); if (status.equals(EnrolmentInfo.Status.ACTIVE) || - status.equals(EnrolmentInfo.Status.INACTIVE) || status.equals(EnrolmentInfo.Status.UNREACHABLE)) { notifiableDevices.add(device); - } - if (log.isDebugEnabled()) { - log.debug("Adding monitoring operation to device : " + device.getDeviceIdentifier()); + if (log.isDebugEnabled()) { + if (sb.length() > 0) { + sb.append(", "); + } + sb.append(device.getDeviceIdentifier()); + } } } if (log.isDebugEnabled()) { - log.debug("Following '" + deviceType + "' devices selected to send the notification " + - "for policy monitoring"); - for (Device device : notifiableDevices) { - log.debug(device.getDeviceIdentifier()); - } + log.debug("TID:[" + tenant + "] Sending monitoring to '" + deviceType + + "' devices with ids [" + sb + "]"); } if (!notifiableDevices.isEmpty()) { monitoringManager.addMonitoringOperation(deviceType, notifiableDevices); @@ -156,13 +142,14 @@ public class MonitoringTask extends DynamicPartitionedScheduleTask { } } if (log.isDebugEnabled()) { - log.debug("Monitoring task running completed."); + log.debug("TID:[" + tenant + "] Monitoring task running completed."); } } catch (Exception e) { - log.error("Error occurred while trying to run a task.", e); + log.error("TID:[" + tenant + "] Error occurred while trying to run a task.", e); } } else { - log.info("No device types registered currently. So did not run the monitoring task."); + log.info("TID:[" + tenant + "] No device types registered currently. " + + "So did not run the monitoring task."); } } @@ -170,4 +157,5 @@ public class MonitoringTask extends DynamicPartitionedScheduleTask { protected void setup() { } + } diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/task/TaskScheduleServiceImpl.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/task/TaskScheduleServiceImpl.java index b4b358bc32..d6aefcee11 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/task/TaskScheduleServiceImpl.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/task/TaskScheduleServiceImpl.java @@ -39,7 +39,7 @@ import java.util.Map; public class TaskScheduleServiceImpl implements TaskScheduleService { private static final Log log = LogFactory.getLog(TaskScheduleServiceImpl.class); - private PolicyConfiguration policyConfiguration; + private final PolicyConfiguration policyConfiguration; public TaskScheduleServiceImpl() { @@ -72,7 +72,7 @@ public class TaskScheduleServiceImpl implements TaskScheduleService { Map properties = new HashMap<>(); properties.put(PolicyManagementConstants.TENANT_ID, String.valueOf(tenantId)); - String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + String.valueOf(tenantId); + String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + tenantId; if (!taskManager.isTaskScheduled(taskName)) { @@ -101,7 +101,7 @@ public class TaskScheduleServiceImpl implements TaskScheduleService { public void stopTask() throws PolicyMonitoringTaskException { int tenantId = getTenantId(); try { - String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + String.valueOf(tenantId); + String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + tenantId; TaskService taskService = PolicyManagementDataHolder.getInstance().getTaskService(); if (taskService.isServerInit()) { TaskManager taskManager = taskService.getTaskManager(PolicyManagementConstants.MONITORING_TASK_TYPE); @@ -117,7 +117,7 @@ public class TaskScheduleServiceImpl implements TaskScheduleService { public void updateTask(int monitoringFrequency) throws PolicyMonitoringTaskException { int tenantId = getTenantId(); try { - String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + String.valueOf(tenantId); + String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + tenantId; TaskService taskService = PolicyManagementDataHolder.getInstance().getTaskService(); TaskManager taskManager = taskService.getTaskManager(PolicyManagementConstants.MONITORING_TASK_TYPE); @@ -129,7 +129,7 @@ public class TaskScheduleServiceImpl implements TaskScheduleService { triggerInfo.setRepeatCount(-1); Map properties = new HashMap<>(); - properties.put("tenantId", String.valueOf(tenantId)); + properties.put(PolicyManagementConstants.TENANT_ID, String.valueOf(tenantId)); TaskInfo taskInfo = new TaskInfo(taskName, PolicyManagementConstants.MONITORING_TASK_CLAZZ, properties, triggerInfo); @@ -150,7 +150,7 @@ public class TaskScheduleServiceImpl implements TaskScheduleService { @Override public boolean isTaskScheduled() throws PolicyMonitoringTaskException { int tenantId = getTenantId(); - String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + String.valueOf(tenantId); + String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + tenantId; TaskService taskService = PolicyManagementDataHolder.getInstance().getTaskService(); TaskManager taskManager; try { diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/DefaultTokenHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/DefaultTokenHandler.java index 1079e78b27..7aaae1ca70 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/DefaultTokenHandler.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/DefaultTokenHandler.java @@ -132,7 +132,7 @@ public class DefaultTokenHandler extends HttpServlet { URIBuilder ub = new URIBuilder(); ub.setScheme(HandlerConstants.WSS_PROTOCOL); ub.setHost(System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)); - ub.setPort(Integer.parseInt(System.getProperty(HandlerConstants.IOT_CORE_PORT_ENV_VAR))); + ub.setPort(Integer.parseInt(System.getProperty(HandlerConstants.IOT_CORE_HTTPS_PORT_ENV_VAR))); ub.setPath(HandlerConstants.REMOTE_SESSION_CONTEXT); JsonObject responseJsonObj = new JsonObject(); diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/InvokerHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/InvokerHandler.java index 7bf0861f72..1bc5de7831 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/InvokerHandler.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/InvokerHandler.java @@ -48,6 +48,7 @@ import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.InputStreamBody; import io.entgra.ui.request.interceptor.beans.ProxyResponse; +import org.wso2.carbon.context.CarbonContext; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; @@ -111,6 +112,11 @@ public class InvokerHandler extends HttpServlet { HttpGet getRequest = new HttpGet(generateBackendRequestURL(req)); copyRequestHeaders(req, getRequest, false); getRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BEARER + authData.getAccessToken()); + if (apiEndpoint.equals(System.getProperty("iot.reporting.webapp.host"))) { + getRequest.setHeader("Tenant-Id", String.valueOf( + CarbonContext.getThreadLocalCarbonContext().getTenantId() + )); + } ProxyResponse proxyResponse = HandlerUtil.execute(getRequest); if (HandlerConstants.TOKEN_IS_EXPIRED.equals(proxyResponse.getExecutorResponse())) { proxyResponse = retryRequestWithRefreshedToken(req, resp, getRequest); diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java index ed106923b5..6042f66031 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java @@ -24,6 +24,9 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; import io.entgra.ui.request.interceptor.beans.AuthData; +import io.entgra.ui.request.interceptor.cache.LoginCacheManager; +import io.entgra.ui.request.interceptor.cache.OAuthApp; +import io.entgra.ui.request.interceptor.cache.OAuthAppCacheKey; import io.entgra.ui.request.interceptor.exceptions.LoginException; import io.entgra.ui.request.interceptor.util.HandlerConstants; import io.entgra.ui.request.interceptor.util.HandlerUtil; @@ -56,7 +59,7 @@ public class LoginHandler extends HttpServlet { private static String password; private static String gatewayUrl; private static String uiConfigUrl; - private static String keyManagerUrl; + private static String iotsCoreUrl; @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) { @@ -70,33 +73,66 @@ public class LoginHandler extends HttpServlet { //setting session to expiry in 5 minutes httpSession.setMaxInactiveInterval(Math.toIntExact(HandlerConstants.TIMEOUT)); - JsonObject uiConfigJsonObject = HandlerUtil.getUIConfigAndPersistInSession( - uiConfigUrl, gatewayUrl, httpSession, resp); + JsonObject uiConfigJsonObject = HandlerUtil.getUIConfigAndPersistInSession(uiConfigUrl, gatewayUrl, httpSession, resp); JsonArray tags = uiConfigJsonObject.get("appRegistration").getAsJsonObject().get("tags").getAsJsonArray(); JsonArray scopes = uiConfigJsonObject.get("scopes").getAsJsonArray(); - HttpPost apiRegEndpoint = new HttpPost(gatewayUrl + HandlerConstants.APP_REG_ENDPOINT); - apiRegEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + Base64.getEncoder() - .encodeToString((username + HandlerConstants.COLON + password).getBytes())); - apiRegEndpoint.setHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()); - apiRegEndpoint.setEntity(HandlerUtil.constructAppRegPayload( - tags, HandlerConstants.PUBLISHER_APPLICATION_NAME, username, password)); + // Check if OAuth app cache exists. If not create a new application. + LoginCacheManager loginCacheManager = new LoginCacheManager(); + loginCacheManager.initializeCacheManager(); + OAuthAppCacheKey oAuthAppCacheKey = new OAuthAppCacheKey(HandlerConstants.PUBLISHER_APPLICATION_NAME, username); + OAuthApp oAuthApp = loginCacheManager.getOAuthAppCache(oAuthAppCacheKey); - ProxyResponse clientAppResponse = HandlerUtil.execute(apiRegEndpoint); + if (oAuthApp == null) { + HttpPost apiRegEndpoint = new HttpPost(gatewayUrl + HandlerConstants.APP_REG_ENDPOINT); + apiRegEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + Base64.getEncoder() + .encodeToString((username + HandlerConstants.COLON + password).getBytes())); + apiRegEndpoint.setHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()); + apiRegEndpoint.setEntity(HandlerUtil.constructAppRegPayload(tags, HandlerConstants.PUBLISHER_APPLICATION_NAME, username, password)); - if (clientAppResponse.getCode() == HttpStatus.SC_UNAUTHORIZED) { - HandlerUtil.handleError(resp, clientAppResponse); - return; - } - if (clientAppResponse.getCode() == HttpStatus.SC_CREATED && getTokenAndPersistInSession(req, resp, - clientAppResponse.getData(), scopes)) { - ProxyResponse proxyResponse = new ProxyResponse(); - proxyResponse.setCode(HttpStatus.SC_OK); - HandlerUtil.handleSuccess(resp, proxyResponse); - return; + ProxyResponse clientAppResponse = HandlerUtil.execute(apiRegEndpoint); + + if (clientAppResponse.getCode() == HttpStatus.SC_UNAUTHORIZED) { + HandlerUtil.handleError(resp, clientAppResponse); + return; + } + + if (clientAppResponse.getCode() == HttpStatus.SC_CREATED) { + JsonParser jsonParser = new JsonParser(); + JsonElement jClientAppResult = jsonParser.parse(clientAppResponse.getData()); + String clientId = null; + String clientSecret = null; + String encodedClientApp = null; + if (jClientAppResult.isJsonObject()) { + JsonObject jClientAppResultAsJsonObject = jClientAppResult.getAsJsonObject(); + clientId = jClientAppResultAsJsonObject.get("client_id").getAsString(); + clientSecret = jClientAppResultAsJsonObject.get("client_secret").getAsString(); + encodedClientApp = Base64.getEncoder() + .encodeToString((clientId + HandlerConstants.COLON + clientSecret).getBytes()); + + oAuthAppCacheKey = new OAuthAppCacheKey(HandlerConstants.PUBLISHER_APPLICATION_NAME, username); + oAuthApp = new OAuthApp( + HandlerConstants.PUBLISHER_APPLICATION_NAME, + username, + clientId, + clientSecret, + encodedClientApp + ); + loginCacheManager.addOAuthAppToCache(oAuthAppCacheKey, oAuthApp); + } + + if (getTokenAndPersistInSession(req, resp, clientId, clientSecret, encodedClientApp, scopes)) { + ProxyResponse proxyResponse = new ProxyResponse(); + proxyResponse.setCode(HttpStatus.SC_OK); + HandlerUtil.handleSuccess(resp, proxyResponse); + return; + } + } + HandlerUtil.handleError(resp, null); + } else { + getTokenAndPersistInSession(req, resp, oAuthApp.getClientId(), oAuthApp.getClientSecret(), oAuthApp.getEncodedClientApp(), scopes); } - HandlerUtil.handleError(resp, null); } catch (IOException e) { log.error("Error occurred while sending the response into the socket. ", e); } catch (JsonSyntaxException e) { @@ -106,57 +142,54 @@ public class LoginHandler extends HttpServlet { } } - /*** + /** * Generates token from token endpoint and persists them inside the session * - * @param req - {@link HttpServletRequest} - * @param clientAppResult - clientAppResult - * @param scopes - scopes defied in the application-mgt.xml - * @throws LoginException - login exception throws when getting token result + * @param req - {@link HttpServletRequest} + * @param resp - {@link HttpServletResponse} + * @param clientId - clientId of the OAuth app + * @param clientSecret - clientSecret of the OAuth app + * @param encodedClientApp - Base64 encoded clientId:clientSecret. + * @param scopes - User scopes JSON Array + * @return boolean response + * @throws LoginException - Throws if any error occurs while getting login response */ private boolean getTokenAndPersistInSession(HttpServletRequest req, HttpServletResponse resp, - String clientAppResult, JsonArray scopes) throws LoginException { + String clientId, String clientSecret, String encodedClientApp, + JsonArray scopes) throws LoginException { JsonParser jsonParser = new JsonParser(); try { - JsonElement jClientAppResult = jsonParser.parse(clientAppResult); - if (jClientAppResult.isJsonObject()) { - JsonObject jClientAppResultAsJsonObject = jClientAppResult.getAsJsonObject(); - String clientId = jClientAppResultAsJsonObject.get("client_id").getAsString(); - String clientSecret = jClientAppResultAsJsonObject.get("client_secret").getAsString(); - String encodedClientApp = Base64.getEncoder() - .encodeToString((clientId + HandlerConstants.COLON + clientSecret).getBytes()); - - ProxyResponse tokenResultResponse = getTokenResult(encodedClientApp, scopes); - - if (tokenResultResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { - log.error("Error occurred while invoking the API to get token data."); - HandlerUtil.handleError(resp, tokenResultResponse); - return false; - } - String tokenResult = tokenResultResponse.getData(); - if (tokenResult == null) { - log.error("Invalid token response is received."); - HandlerUtil.handleError(resp, tokenResultResponse); - return false; - } - JsonElement jTokenResult = jsonParser.parse(tokenResult); - if (jTokenResult.isJsonObject()) { - JsonObject jTokenResultAsJsonObject = jTokenResult.getAsJsonObject(); - HttpSession session = req.getSession(false); - if (session == null) { - return false; - } - AuthData authData = new AuthData(); - authData.setClientId(clientId); - authData.setClientSecret(clientSecret); - authData.setEncodedClientApp(encodedClientApp); - authData.setAccessToken(jTokenResultAsJsonObject.get("access_token").getAsString()); - authData.setRefreshToken(jTokenResultAsJsonObject.get("refresh_token").getAsString()); - authData.setScope(jTokenResultAsJsonObject.get("scope").getAsString()); - session.setAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY, authData); - return true; + ProxyResponse tokenResultResponse = getTokenResult(encodedClientApp, scopes); + + if (tokenResultResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { + log.error("Error occurred while invoking the API to get token data."); + HandlerUtil.handleError(resp, tokenResultResponse); + return false; + } + String tokenResult = tokenResultResponse.getData(); + if (tokenResult == null) { + log.error("Invalid token response is received."); + HandlerUtil.handleError(resp, tokenResultResponse); + return false; + } + + JsonElement jTokenResult = jsonParser.parse(tokenResult); + if (jTokenResult.isJsonObject()) { + JsonObject jTokenResultAsJsonObject = jTokenResult.getAsJsonObject(); + HttpSession session = req.getSession(false); + if (session == null) { + return false; } + AuthData authData = new AuthData(); + authData.setClientId(clientId); + authData.setClientSecret(clientSecret); + authData.setEncodedClientApp(encodedClientApp); + authData.setAccessToken(jTokenResultAsJsonObject.get("access_token").getAsString()); + authData.setRefreshToken(jTokenResultAsJsonObject.get("refresh_token").getAsString()); + authData.setScope(jTokenResultAsJsonObject.get("scope").getAsString()); + session.setAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY, authData); + return true; } return false; } catch (IOException e) { @@ -170,19 +203,18 @@ public class LoginHandler extends HttpServlet { * Define username and password static parameters. */ private static void validateLoginRequest(HttpServletRequest req) throws LoginException { - String iotsCorePort = System.getProperty("iot.core.https.port"); + String iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTPS_PORT_ENV_VAR); if (HandlerConstants.HTTP_PROTOCOL.equals(req.getScheme())) { - iotsCorePort = System.getProperty("iot.core.http.port"); + iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTP_PORT_ENV_VAR); } username = req.getParameter("username"); password = req.getParameter("password"); - gatewayUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.gateway.host") + gatewayUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_GW_HOST_ENV_VAR) + HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme()); - uiConfigUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.core.host") + uiConfigUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR) + HandlerConstants.COLON + iotsCorePort + HandlerConstants.UI_CONFIG_ENDPOINT; - keyManagerUrl = HandlerConstants.HTTPS_PROTOCOL + HandlerConstants.SCHEME_SEPARATOR + - System.getProperty("iot.keymanager.host") + HandlerConstants.COLON - + System.getProperty("iot.keymanager.https.port"); + iotsCoreUrl = HandlerConstants.HTTPS_PROTOCOL + HandlerConstants.SCHEME_SEPARATOR + + System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR) + HandlerConstants.COLON + iotsCorePort; if (username == null || password == null) { String msg = "Invalid login request. Username or Password is not received for login request."; log.error(msg); @@ -199,7 +231,7 @@ public class LoginHandler extends HttpServlet { * @throws IOException IO exception throws if an error occurred when invoking token endpoint */ private ProxyResponse getTokenResult(String encodedClientApp, JsonArray scopes) throws IOException { - HttpPost tokenEndpoint = new HttpPost(keyManagerUrl + HandlerConstants.TOKEN_ENDPOINT); + HttpPost tokenEndpoint = new HttpPost(iotsCoreUrl+ HandlerConstants.TOKEN_ENDPOINT); tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + encodedClientApp); tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString()); String scopeString = HandlerUtil.getScopeString(scopes); diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/OTPInvokerHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/OTPInvokerHandler.java index a97d8be7c5..7194001cca 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/OTPInvokerHandler.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/OTPInvokerHandler.java @@ -241,7 +241,7 @@ public class OTPInvokerHandler extends HttpServlet { private static boolean validateRequest(HttpServletRequest req, HttpServletResponse resp) throws IOException { String schema = req.getScheme(); - apiEndpoint = schema + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.core.host") + apiEndpoint = schema + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR) + HandlerConstants.COLON + HandlerUtil.getCorePort(schema); if (StringUtils.isBlank(req.getHeader(HandlerConstants.OTP_HEADER))) { diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/PermissionScopeHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/PermissionScopeHandler.java new file mode 100644 index 0000000000..96d1d1151f --- /dev/null +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/PermissionScopeHandler.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019, 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. + */ + +package io.entgra.ui.request.interceptor; + +import io.entgra.ui.request.interceptor.beans.AuthData; +import io.entgra.ui.request.interceptor.beans.ProxyResponse; +import io.entgra.ui.request.interceptor.util.HandlerConstants; +import io.entgra.ui.request.interceptor.util.HandlerUtil; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpStatus; +import org.json.JSONObject; + +import javax.servlet.ServletException; +import javax.servlet.annotation.MultipartConfig; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; + +@MultipartConfig +@WebServlet("/login-user/scopes") +public class PermissionScopeHandler extends HttpServlet { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + HttpSession httpSession = req.getSession(false); + if (httpSession == null) { + HandlerUtil.sendUnAuthorizeResponse(resp); + return; + } + + AuthData authData = (AuthData) httpSession.getAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY); + if (authData == null) { + HandlerUtil.sendUnAuthorizeResponse(resp); + return; + } + + if (!StringUtils.isEmpty(authData.getScope())) { + ProxyResponse proxyResponse = new ProxyResponse(); + JSONObject jsonObject = new JSONObject(); + jsonObject.put(HandlerConstants.USER_SCOPES, authData.getScope()); + proxyResponse.setCode(HttpStatus.SC_OK); + proxyResponse.setData(jsonObject.toString()); + HandlerUtil.handleSuccess(resp, proxyResponse); + } + HandlerUtil.handleError(resp, null); + } +} diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginCallbackHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginCallbackHandler.java index e047b5ba73..e77137ff1c 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginCallbackHandler.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginCallbackHandler.java @@ -27,6 +27,7 @@ import io.entgra.ui.request.interceptor.util.HandlerUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpHeaders; +import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; @@ -50,21 +51,18 @@ public class SsoLoginCallbackHandler extends HttpServlet { String code = req.getParameter("code"); HttpSession session = req.getSession(false); String scope = session.getAttribute("scope").toString(); - String iotsCorePort = System.getProperty("iot.core.https.port"); + String iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTPS_PORT_ENV_VAR); if (HandlerConstants.HTTP_PROTOCOL.equals(req.getScheme())) { - iotsCorePort = System.getProperty("iot.core.http.port"); + iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTP_PORT_ENV_VAR); } - String gatewayUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.gateway.host") + String gatewayUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_GW_HOST_ENV_VAR) + HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme()); - String iotsCoreUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.core.host") + String iotsCoreUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR) + HandlerConstants.COLON + iotsCorePort; - String keyManagerUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR - + System.getProperty("iot.keymanager.host") + HandlerConstants.COLON - + System.getProperty("iot.keymanager.https.port"); - HttpPost tokenEndpoint = new HttpPost(keyManagerUrl + HandlerConstants.TOKEN_ENDPOINT); + HttpPost tokenEndpoint = new HttpPost(iotsCoreUrl + HandlerConstants.TOKEN_ENDPOINT); tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + session.getAttribute("encodedClientApp")); tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString()); diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginHandler.java index 78b874ac68..15358ad362 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginHandler.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginHandler.java @@ -23,6 +23,9 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; +import io.entgra.ui.request.interceptor.cache.LoginCacheManager; +import io.entgra.ui.request.interceptor.cache.OAuthApp; +import io.entgra.ui.request.interceptor.cache.OAuthAppCacheKey; import io.entgra.ui.request.interceptor.util.HandlerConstants; import io.entgra.ui.request.interceptor.util.HandlerUtil; import org.apache.commons.lang.text.StrSubstitutor; @@ -69,28 +72,65 @@ public class SsoLoginHandler extends HttpServlet { private static String adminPassword; private static String gatewayUrl; private static String iotsCoreUrl; - private static String keyManagerUrl; private static String encodedAdminCredentials; private static String encodedClientApp; private static String applicationId; + private static String applicationName; private static String baseContextPath; private JsonObject uiConfigJsonObject; private HttpSession httpSession; + private LoginCacheManager loginCacheManager; + private OAuthApp oAuthApp; + @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { - dynamicClientRegistration(req, resp); - String clientId = httpSession.getAttribute("clientId").toString(); - JsonArray scopesSsoJson = uiConfigJsonObject.get("scopes").getAsJsonArray(); - String scopesSsoString = HandlerUtil.getScopeString(scopesSsoJson); - String loginCallbackUrl = iotsCoreUrl + baseContextPath + HandlerConstants.SSO_LOGIN_CALLBACK; - resp.sendRedirect(iotsCoreUrl + HandlerConstants.AUTHORIZATION_ENDPOINT + - "?response_type=code" + - "&client_id=" + clientId + - "&state=" + - "&scope=openid " + scopesSsoString + - "&redirect_uri=" + loginCallbackUrl); + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { + try { + httpSession = req.getSession(false); + + if (httpSession != null) { + httpSession.invalidate(); + } + + httpSession = req.getSession(true); + initializeAdminCredentials(); + baseContextPath = req.getContextPath(); + applicationName = baseContextPath.substring(1, baseContextPath.indexOf("-ui-request-handler")); + + // Check if oauth app cache is available + loginCacheManager = new LoginCacheManager(); + loginCacheManager.initializeCacheManager(); + oAuthApp = loginCacheManager.getOAuthAppCache( + new OAuthAppCacheKey(applicationName, adminUsername) + ); + + if (oAuthApp == null) { + dynamicClientRegistration(req, resp); + } + + String clientId = oAuthApp.getClientId(); + JsonArray scopesSsoJson = uiConfigJsonObject.get("scopes").getAsJsonArray(); + String scopesSsoString = HandlerUtil.getScopeString(scopesSsoJson); + String loginCallbackUrl = iotsCoreUrl + baseContextPath + HandlerConstants.SSO_LOGIN_CALLBACK; + persistAuthSessionData(req, oAuthApp.getClientId(), oAuthApp.getClientSecret(), + oAuthApp.getEncodedClientApp(), scopesSsoString); + + resp.sendRedirect(iotsCoreUrl + HandlerConstants.AUTHORIZATION_ENDPOINT + + "?response_type=code" + + "&client_id=" + clientId + + "&state=" + + "&scope=openid " + scopesSsoString + + "&redirect_uri=" + loginCallbackUrl); + } catch (IOException e) { + log.error("Error occurred while sending the response into the socket. ", e); + } catch (JsonSyntaxException e) { + log.error("Error occurred while parsing the response. ", e); + } catch (ParserConfigurationException e) { + log.error("Error while creating the document builder."); + } catch (SAXException e) { + log.error("Error while parsing xml file.", e); + } } /*** @@ -102,40 +142,19 @@ public class SsoLoginHandler extends HttpServlet { */ private void dynamicClientRegistration(HttpServletRequest req, HttpServletResponse resp) { try { - File userMgtConf = new File("repository/conf/user-mgt.xml"); - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - Document doc = dBuilder.parse(userMgtConf); - - adminUsername = doc.getElementsByTagName("UserName").item(0).getTextContent(); - adminPassword = doc.getElementsByTagName("Password").item(0).getTextContent(); - - baseContextPath = req.getContextPath(); - String applicationName = baseContextPath.substring(1, baseContextPath.indexOf("-ui-request-handler")); - - String iotsCorePort = System.getProperty("iot.core.https.port"); + String iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTPS_PORT_ENV_VAR); if (HandlerConstants.HTTP_PROTOCOL.equals(req.getScheme())) { - iotsCorePort = System.getProperty("iot.core.http.port"); + iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTP_PORT_ENV_VAR); } - gatewayUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.gateway.host") + gatewayUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_GW_HOST_ENV_VAR) + HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme()); - iotsCoreUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.core.host") + iotsCoreUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR) + HandlerConstants.COLON + iotsCorePort; String uiConfigUrl = iotsCoreUrl + HandlerConstants.UI_CONFIG_ENDPOINT; - keyManagerUrl = HandlerConstants.HTTPS_PROTOCOL + HandlerConstants.SCHEME_SEPARATOR + - System.getProperty("iot.keymanager.host") + HandlerConstants.COLON - + System.getProperty("iot.keymanager.https.port"); - - httpSession = req.getSession(false); - if (httpSession != null) { - httpSession.invalidate(); - } - httpSession = req.getSession(true); uiConfigJsonObject = HandlerUtil.getUIConfigAndPersistInSession(uiConfigUrl, gatewayUrl, httpSession, resp); - JsonArray tags = uiConfigJsonObject.get("appRegistration").getAsJsonObject().get("tags").getAsJsonArray(); JsonArray scopes = uiConfigJsonObject.get("scopes").getAsJsonArray(); @@ -157,19 +176,22 @@ public class SsoLoginHandler extends HttpServlet { if (clientAppResponse.getCode() == HttpStatus.SC_CREATED) { JsonParser jsonParser = new JsonParser(); JsonElement jClientAppResult = jsonParser.parse(clientAppResponse.getData()); + String clientId = null; + String clientSecret = null; + if (jClientAppResult.isJsonObject()) { JsonObject jClientAppResultAsJsonObject = jClientAppResult.getAsJsonObject(); - String clientId = jClientAppResultAsJsonObject.get("client_id").getAsString(); - String clientSecret = jClientAppResultAsJsonObject.get("client_secret").getAsString(); + clientId = jClientAppResultAsJsonObject.get("client_id").getAsString(); + clientSecret = jClientAppResultAsJsonObject.get("client_secret").getAsString(); encodedClientApp = Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes()); - String redirectUrl = req.getParameter("redirect"); - httpSession = req.getSession(false); - httpSession.setAttribute("clientId", clientId); - httpSession.setAttribute("clientSecret", clientSecret); - httpSession.setAttribute("encodedClientApp", encodedClientApp); - httpSession.setAttribute("scope", HandlerUtil.getScopeString(scopes)); - httpSession.setAttribute("redirectUrl", redirectUrl); + String scopesString = HandlerUtil.getScopeString(scopes); + persistAuthSessionData(req, clientId, clientSecret, encodedClientApp, scopesString); } + + // cache the oauth app credentials + OAuthAppCacheKey oAuthAppCacheKey = new OAuthAppCacheKey(applicationName, adminUsername); + oAuthApp = new OAuthApp(applicationName, adminUsername, clientId, clientSecret, encodedClientApp); + loginCacheManager.addOAuthAppToCache(oAuthAppCacheKey, oAuthApp); } // Get the details of the registered application @@ -225,7 +247,6 @@ public class SsoLoginHandler extends HttpServlet { if (updateApplicationGrantTypesEndpointResponse.getCode() == HttpStatus.SC_OK) { return; } - HandlerUtil.handleError(resp, null); } catch (IOException e) { log.error("Error occurred while sending the response into the socket. ", e); @@ -233,11 +254,48 @@ public class SsoLoginHandler extends HttpServlet { log.error("Error occurred while parsing the response. ", e); } catch (ParserConfigurationException e) { log.error("Error while creating the document builder."); - } catch ( SAXException e) { + } catch (SAXException e) { log.error("Error while parsing xml file.", e); } } + /** + * Initialize the admin credential variables + * + * @throws ParserConfigurationException - Throws when error occur during initializing the document builder + * @throws IOException - Throws when error occur during document parsing + * @throws SAXException - Throws when error occur during document parsing + */ + private void initializeAdminCredentials() throws ParserConfigurationException, IOException, SAXException { + File userMgtConf = new File("repository/conf/user-mgt.xml"); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(userMgtConf); + + adminUsername = doc.getElementsByTagName("UserName").item(0).getTextContent(); + adminPassword = doc.getElementsByTagName("Password").item(0).getTextContent(); + } + + + /** + * Persist the Auth data inside the session + * + * @param req - Http Servlet request + * @param clientId - Client ID of the SP + * @param clientSecret - Client secret of the SP + * @param encodedClientApp - Base64 encoded clientId:clientSecret. + * @param scopes - User scopes + */ + private void persistAuthSessionData(HttpServletRequest req, String clientId, String clientSecret, + String encodedClientApp, String scopes) { + httpSession = req.getSession(false); + httpSession.setAttribute("clientId", clientId); + httpSession.setAttribute("clientSecret", clientSecret); + httpSession.setAttribute("encodedClientApp", encodedClientApp); + httpSession.setAttribute("scope", scopes); + httpSession.setAttribute("redirectUrl", req.getParameter("redirect")); + } + /*** * Generates payload for application grant_type update payload * @@ -266,7 +324,7 @@ public class SsoLoginHandler extends HttpServlet { * @throws IOException IO exception throws if an error occurred when invoking token endpoint */ private ProxyResponse getTokenResult(String encodedClientApp) throws IOException { - HttpPost tokenEndpoint = new HttpPost(keyManagerUrl + HandlerConstants.TOKEN_ENDPOINT); + HttpPost tokenEndpoint = new HttpPost(iotsCoreUrl + HandlerConstants.TOKEN_ENDPOINT); tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + encodedClientApp); tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString()); @@ -315,7 +373,7 @@ public class SsoLoginHandler extends HttpServlet { */ private void updateSaasApp(String appName) throws ParserConfigurationException, IOException, SAXException { File getAppRequestXmlFile = new File(HandlerConstants.PAYLOADS_DIR + "/get-app-request.xml"); - String identityAppMgtUrl = iotsCoreUrl + HandlerConstants.IDENTITY_APP_MGT_ENDPOINT;; + String identityAppMgtUrl = iotsCoreUrl + HandlerConstants.IDENTITY_APP_MGT_ENDPOINT; HttpPost getApplicationEndpoint = new HttpPost(identityAppMgtUrl); getApplicationEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/UserHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/UserHandler.java index d6ef958a5c..c545567ed8 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/UserHandler.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/UserHandler.java @@ -55,7 +55,8 @@ public class UserHandler extends HttpServlet { protected void doPost(HttpServletRequest req, HttpServletResponse resp) { try { String serverUrl = - req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.core.host") + req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + + System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR) + HandlerConstants.COLON + HandlerUtil.getCorePort(req.getScheme()); HttpSession httpSession = req.getSession(false); if (httpSession == null) { @@ -71,32 +72,31 @@ public class UserHandler extends HttpServlet { String accessToken = authData.getAccessToken(); - HttpPost introspectionEndpoint = new HttpPost(serverUrl + HandlerConstants.INTROSPECT_ENDPOINT); - introspectionEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, - ContentType.APPLICATION_FORM_URLENCODED.toString()); + HttpPost tokenEndpoint = new HttpPost(serverUrl + HandlerConstants.INTROSPECT_ENDPOINT); + tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString()); DeviceManagementConfig dmc = DeviceConfigurationManager.getInstance().getDeviceManagementConfig(); - String username = dmc.getKeyManagerConfigurations().getAdminUsername(); - String password = dmc.getKeyManagerConfigurations().getAdminPassword(); - introspectionEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + Base64.getEncoder() - .encodeToString((username + HandlerConstants.COLON + password).getBytes())); - StringEntity introspectionPayload = new StringEntity("token=" + accessToken, + String adminUsername = dmc.getKeyManagerConfigurations().getAdminUsername(); + String adminPassword = dmc.getKeyManagerConfigurations().getAdminPassword(); + tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + Base64.getEncoder() + .encodeToString((adminUsername + HandlerConstants.COLON + adminPassword).getBytes())); + StringEntity tokenEPPayload = new StringEntity("token=" + accessToken, ContentType.APPLICATION_FORM_URLENCODED); - introspectionEndpoint.setEntity(introspectionPayload); - ProxyResponse introspectionStatus = HandlerUtil.execute(introspectionEndpoint); + tokenEndpoint.setEntity(tokenEPPayload); + ProxyResponse tokenStatus = HandlerUtil.execute(tokenEndpoint); - if (introspectionStatus.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { + if (tokenStatus.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { log.error("Error occurred while invoking the API to get token status."); - HandlerUtil.handleError(resp, introspectionStatus); + HandlerUtil.handleError(resp, tokenStatus); return; } - String introspectionData = introspectionStatus.getData(); - if (introspectionData == null) { + String tokenData = tokenStatus.getData(); + if (tokenData == null) { log.error("Invalid token data is received."); - HandlerUtil.handleError(resp, introspectionStatus); + HandlerUtil.handleError(resp, tokenStatus); return; } JsonParser jsonParser = new JsonParser(); - JsonElement jTokenResult = jsonParser.parse(introspectionData); + JsonElement jTokenResult = jsonParser.parse(tokenData); if (jTokenResult.isJsonObject()) { JsonObject jTokenResultAsJsonObject = jTokenResult.getAsJsonObject(); if (!jTokenResultAsJsonObject.get("active").getAsBoolean()) { diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/cache/LoginCacheManager.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/cache/LoginCacheManager.java new file mode 100644 index 0000000000..3ecd741350 --- /dev/null +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/cache/LoginCacheManager.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021, 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. + */ + +package io.entgra.ui.request.interceptor.cache; + +import io.entgra.ui.request.interceptor.util.HandlerConstants; + +import javax.cache.Cache; +import javax.cache.CacheManager; +import javax.cache.Caching; + +/** + * Contains necessary functions to manage oAuth app cache during login handling + */ +public class LoginCacheManager { + + private CacheManager cacheManager = null; + private Cache cache = null; + + /** + * Initialize the cache manager if it is not already initialized + */ + public void initializeCacheManager() { + cacheManager = Caching.getCacheManagerFactory().getCacheManager(HandlerConstants.LOGIN_CACHE); + } + + /** + * Persists OAuth app cache if it is not already persisted + * + * @param oAuthAppCacheKey - The identifier key of the cache + * @param oAuthApp - The value of the cache which contains OAuth app data + */ + public void addOAuthAppToCache(OAuthAppCacheKey oAuthAppCacheKey, OAuthApp oAuthApp) { + cache = cacheManager.getCache(HandlerConstants.LOGIN_CACHE); + cache.put(oAuthAppCacheKey, oAuthApp); + } + + /** + * Retrieves the OAuth app cache + * + * @param oAuthAppCacheKey - The key to identify the cache + * @return - Returns OAuthApp object + */ + public OAuthApp getOAuthAppCache(OAuthAppCacheKey oAuthAppCacheKey) { + cache = cacheManager.getCache(HandlerConstants.LOGIN_CACHE); + return cache.get(oAuthAppCacheKey); + } +} diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/cache/OAuthApp.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/cache/OAuthApp.java new file mode 100644 index 0000000000..db721ea992 --- /dev/null +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/cache/OAuthApp.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2021, 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. + */ + +package io.entgra.ui.request.interceptor.cache; + +/** + * The data object used for Login Cache + */ +public class OAuthApp { + + private String appName; + private String appOwner; + private String clientId; + private String clientSecret; + private String encodedClientApp; + + public OAuthApp(String appName, String appOwner, String clientId, String clientSecret, String encodedClientApp) { + this.appName = appName; + this.appOwner = appOwner; + this.clientId = clientId; + this.clientSecret = clientSecret; + this.encodedClientApp = encodedClientApp; + } + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + } + + public String getAppOwner() { + return appOwner; + } + + public void setAppOwner(String appOwner) { + this.appOwner = appOwner; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getClientSecret() { + return clientSecret; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + public String getEncodedClientApp() { + return encodedClientApp; + } + + public void setEncodedClientApp(String encodedClientApp) { + this.encodedClientApp = encodedClientApp; + } +} diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/cache/OAuthAppCacheKey.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/cache/OAuthAppCacheKey.java new file mode 100644 index 0000000000..aa03eade5a --- /dev/null +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/cache/OAuthAppCacheKey.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021, 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. + */ + +package io.entgra.ui.request.interceptor.cache; + +import java.util.Objects; + +/** + * The key object used for Login Cache + */ +public class OAuthAppCacheKey { + + private String appName; + private String appOwner; + private volatile int hashCode; + + public OAuthAppCacheKey(String appName, String appOwner) { + this.appName = appName; + this.appOwner = appOwner; + } + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + } + + public String getAppOwner() { + return appOwner; + } + + public void setAppOwner(String appOwner) { + this.appOwner = appOwner; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj instanceof OAuthAppCacheKey) { + final OAuthAppCacheKey other = (OAuthAppCacheKey) obj; + String thisId = this.appName + "-" + this.appOwner; + String otherId = other.appName + "-" + other.appOwner; + return thisId.equals(otherId); + } + return false; + } + + @Override + public int hashCode() { + if (hashCode == 0) { + hashCode = Objects.hash(appName, appOwner); + } + return hashCode; + } +} diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java index 636c5aceeb..fa7020ac6d 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java @@ -55,6 +55,7 @@ public class HandlerConstants { public static final String PASSWORD_GRANT_TYPE = "password"; public static final String JWT_BEARER_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer"; public static final String PRODUCTION_KEY = "PRODUCTION"; + public static final String LOGIN_CACHE = "LOGIN_CACHE"; public static final String SCHEME_SEPARATOR = "://"; public static final String COLON = ":"; @@ -75,6 +76,10 @@ public class HandlerConstants { public static final String REMOTE_SESSION_CONTEXT = "/remote/session/clients"; public static final String IOT_CORE_HOST_ENV_VAR = "iot.core.host"; - public static final String IOT_CORE_PORT_ENV_VAR = "iot.core.https.port"; - + public static final String IOT_CORE_HTTP_PORT_ENV_VAR = "iot.core.http.port"; + public static final String IOT_CORE_HTTPS_PORT_ENV_VAR = "iot.core.https.port"; + public static final String IOT_GW_HOST_ENV_VAR = "iot.gateway.host"; + public static final String IOT_GW_HTTP_PORT_ENV_VAR = "iot.gateway.http.port"; + public static final String IOT_GW_HTTPS_PORT_ENV_VAR = "iot.gateway.https.port"; + public static final String USER_SCOPES = "user-scopes"; } diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java index 4582468a0c..5acec832ce 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java @@ -226,9 +226,9 @@ public class HandlerUtil { * @return {@link String} gateway port */ public static String getGatewayPort(String scheme) { - String gatewayPort = System.getProperty("iot.gateway.https.port"); + String gatewayPort = System.getProperty(HandlerConstants.IOT_GW_HTTPS_PORT_ENV_VAR); if (HandlerConstants.HTTP_PROTOCOL.equals(scheme)) { - gatewayPort = System.getProperty("iot.gateway.http.port"); + gatewayPort = System.getProperty(HandlerConstants.IOT_GW_HTTP_PORT_ENV_VAR); } return gatewayPort; } @@ -240,9 +240,9 @@ public class HandlerUtil { * @return {@link String} gateway port */ public static String getCorePort(String scheme) { - String productCorePort = System.getProperty("iot.core.https.port"); + String productCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTPS_PORT_ENV_VAR); if (HandlerConstants.HTTP_PROTOCOL.equals(scheme)) { - productCorePort = System.getProperty("iot.core.https.por"); + productCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTP_PORT_ENV_VAR); } return productCorePort; } diff --git a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql index f16927301b..dcbebd74b4 100644 --- a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql +++ b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql @@ -269,7 +269,7 @@ CREATE TABLE IF NOT EXISTS AP_SCHEDULED_SUBSCRIPTION( APPLICATION_UUID VARCHAR(36) NOT NULL, SUBSCRIBER_LIST LONGVARCHAR NOT NULL, STATUS VARCHAR(15) NOT NULL, - SCHEDULED_AT TIMESTAMP NOT NULL, + SCHEDULED_AT BIGINT NOT NULL, SCHEDULED_BY VARCHAR(100) NOT NULL, SCHEDULED_TIMESTAMP TIMESTAMP NOT NULL, DELETED BOOLEAN, diff --git a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mssql.sql b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mssql.sql index 78e05c1371..25fc47e38e 100644 --- a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mssql.sql +++ b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mssql.sql @@ -270,7 +270,7 @@ CREATE TABLE AP_SCHEDULED_SUBSCRIPTION( APPLICATION_UUID VARCHAR(200) NOT NULL, SUBSCRIBER_LIST VARCHAR(MAX) NOT NULL, STATUS VARCHAR(15) NOT NULL, - SCHEDULED_AT DATETIME2(0) NOT NULL, + SCHEDULED_AT BIGINT NOT NULL, SCHEDULED_BY VARCHAR(100) NOT NULL, SCHEDULED_TIMESTAMP DATETIME2(0) NOT NULL, DELETED BIT, diff --git a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql index 1daa796858..5d5db38b2d 100644 --- a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql +++ b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql @@ -269,7 +269,7 @@ CREATE TABLE IF NOT EXISTS AP_SCHEDULED_SUBSCRIPTION( APPLICATION_UUID VARCHAR(36) NOT NULL, SUBSCRIBER_LIST TEXT NOT NULL, STATUS VARCHAR(15) NOT NULL, - SCHEDULED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, + SCHEDULED_AT BIGINT NOT NULL, SCHEDULED_BY VARCHAR(100) NOT NULL, SCHEDULED_TIMESTAMP TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, DELETED BOOLEAN, diff --git a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/oracle.sql b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/oracle.sql index c4f2c99f06..edbc277ab2 100644 --- a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/oracle.sql +++ b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/oracle.sql @@ -372,7 +372,7 @@ CREATE TABLE AP_SCHEDULED_SUBSCRIPTION ( APPLICATION_UUID VARCHAR(36) NOT NULL, SUBSCRIBER_LIST VARCHAR(4000) NOT NULL, STATUS VARCHAR(15) NOT NULL, - SCHEDULED_AT TIMESTAMP NOT NULL, + SCHEDULED_AT NUMBER(19) NOT NULL, SCHEDULED_BY VARCHAR(100) NOT NULL, SCHEDULED_TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, DELETED NUMBER(1) NOT_NULL DEFAULT 0, diff --git a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/postgresql.sql b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/postgresql.sql index 5c20aa4a75..d871549d89 100644 --- a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/postgresql.sql +++ b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/postgresql.sql @@ -299,7 +299,7 @@ CREATE TABLE IF NOT EXISTS AP_SCHEDULED_SUBSCRIPTION( APPLICATION_UUID VARCHAR(36) NOT NULL, SUBSCRIBER_LIST TEXT NOT NULL, STATUS VARCHAR(15) NOT NULL, - SCHEDULED_AT TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP NOT NULL, + SCHEDULED_AT BIGINT NOT NULL, SCHEDULED_BY VARCHAR(100) NOT NULL, SCHEDULED_TIMESTAMP TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP NOT NULL, DELETED BOOLEAN, diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/license-config.xml.j2 b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/etc/license-config.xml.j2 similarity index 100% rename from features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/license-config.xml.j2 rename to features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/etc/license-config.xml.j2 diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/remote-appmanager-config.xml.j2 b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/etc/remote-appmanager-config.xml.j2 similarity index 100% rename from features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/remote-appmanager-config.xml.j2 rename to features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/etc/remote-appmanager-config.xml.j2 diff --git a/features/transport-mgt/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/conf_templates/templates/repository/conf/email-sender-config.xml.j2 b/features/transport-mgt/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/conf_templates/templates/repository/conf/etc/email-sender-config.xml.j2 similarity index 100% rename from features/transport-mgt/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/conf_templates/templates/repository/conf/email-sender-config.xml.j2 rename to features/transport-mgt/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/conf_templates/templates/repository/conf/etc/email-sender-config.xml.j2 diff --git a/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf_templates/templates/repository/conf/webapp-authenticator-config.xml.j2 b/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf_templates/templates/repository/conf/etc/webapp-authenticator-config.xml.j2 similarity index 100% rename from features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf_templates/templates/repository/conf/webapp-authenticator-config.xml.j2 rename to features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf_templates/templates/repository/conf/etc/webapp-authenticator-config.xml.j2 diff --git a/pom.xml b/pom.xml index afa35d50db..885f41e130 100644 --- a/pom.xml +++ b/pom.xml @@ -2258,6 +2258,8 @@ [1.6.0, 2.0.0) [1.2.0,1.3.0) + + true