From 7b0295ff010cda0cb7077d959491363b8db4ab9f Mon Sep 17 00:00:00 2001 From: Rasika Perera Date: Mon, 29 May 2017 12:58:06 +0530 Subject: [PATCH] Added geo-fencing to the devicemgt app --- .../devicemgt/app/conf/config.json | 3 +- .../modules/business-controllers/device.js | 139 ++++++++---------- .../app/units/cdmf.unit.device.view/view.hbs | 2 + .../app/units/cdmf.unit.device.view/view.js | 1 + .../public/js/invoker-lib.js | 22 ++- .../public/css/custom-common.css | 4 + .../public/css/custom-theme.css | 40 ++--- .../app/units/cdmf.unit.ui.theme/theme.hbs | 38 +++++ .../uuf.unit.theme/public/css/theme-wso2.css | 2 +- .../public/lib/noty_2.3.5/layouts/topRight.js | 2 +- 10 files changed, 143 insertions(+), 110 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json index f6120a5c146..36eda11c066 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json @@ -176,7 +176,8 @@ "perm:ios:get-restrictions", "perm:ios:wipe-data", "perm:admin", - "perm:devicetype:deployment" + "perm:devicetype:deployment", + "perm:geo-service:analytics" ], "isOAuthEnabled": true, "backendRestEndpoints": { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js index 0138c578977..2a2c6335ef0 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js @@ -38,17 +38,17 @@ deviceModule = function () { privateMethods.callBackend = function (url, method) { if (constants["HTTP_GET"] == method) { return serviceInvokers.XMLHttp.get(url, - function (backendResponse) { - var response = {}; - response.content = backendResponse.responseText; - if (backendResponse.status == 200) { - response.status = "success"; - } else if (backendResponse.status == 400 || backendResponse.status == 401 || - backendResponse.status == 404 || backendResponse.status == 500) { - response.status = "error"; - } - return response; - } + function (backendResponse) { + var response = {}; + response.content = backendResponse.responseText; + if (backendResponse.status == 200) { + response.status = "success"; + } else if (backendResponse.status == 400 || backendResponse.status == 401 || + backendResponse.status == 404 || backendResponse.status == 500) { + response.status = "error"; + } + return response; + } ); } else { log.error("Runtime error : This method only support HTTP GET requests."); @@ -69,35 +69,22 @@ deviceModule = function () { throw constants["ERRORS"]["USER_NOT_FOUND"]; } var userName = carbonUser.username + "@" + carbonUser.domain; - - var locationDataSet = []; - switch (deviceType) { - case 'android': - locationDataSet = batchProvider.getData(userName, deviceId, deviceType); - break; - case 'android_sense': - locationDataSet = batchProvider.getData(userName, deviceId, deviceType); - break; - + var locationHistory = []; + try { + var fromDate = new Date(); + fromDate.setHours(fromDate.getHours() - 2); + var toDate = new Date(); + var serviceUrl = devicemgtProps["httpsURL"] + '/api/device-mgt/v1.0/geo-services/stats/' + deviceType + '/' + deviceId; + serviceInvokers.XMLHttp.get(serviceUrl, + function (backendResponse) { + if (backendResponse.status === 200 && backendResponse.responseText) { + locationHistory = JSON.parse(backendResponse.responseText); + } + }); + } catch (e) { + log.error(e.message, e); } - var locationData = []; - var locationTimeData = []; - if (locationDataSet != null) { - for (var i = 0; i < locationDataSet.length; i++) { - var gpsReading = {}; - var gpsReadingTimes = {}; - gpsReading.lat = locationDataSet[i].latitude; - gpsReading.lng = locationDataSet[i].longitude; - if (deviceType == "android") { - gpsReadingTimes.time = locationDataSet[i].timeStamp; - } else { - gpsReadingTimes.time = locationDataSet[i].meta_timestamp; - } - locationData.push(gpsReading); - locationTimeData.push(gpsReadingTimes); - } - } var locationInfo = {}; try { var url = devicemgtProps["httpsURL"] + "/api/device-mgt/v1.0/devices/" + deviceType + "/" + deviceId + "/location"; @@ -110,14 +97,12 @@ deviceModule = function () { locationInfo.latitude = device.latitude; locationInfo.longitude = device.longitude; locationInfo.updatedOn = device.updatedTime; - } }); } catch (e) { log.error(e.message, e); } - var utility = require('/app/modules/utility.js')["utility"]; try { utility.startTenantFlow(carbonUser); @@ -192,27 +177,45 @@ deviceModule = function () { } } } + if (device["deviceInfo"]) { filteredDeviceData["latestDeviceInfo"] = device["deviceInfo"]; + } else { + filteredDeviceData["latestDeviceInfo"] = {}; + filteredDeviceData["latestDeviceInfo"]["location"] = {}; + } - //location related verification and modifications - // adding the location histry for the movement path. - var locationHistory = {}; - locationHistory.locations = locationData; - locationHistory.times = locationTimeData; - filteredDeviceData["locationHistory"] = locationHistory; + //location related verification and modifications + // adding the location histry for the movement path. + filteredDeviceData["locationHistory"] = locationHistory; - //checking for the latest location information. - if (filteredDeviceData.latestDeviceInfo.location && locationInfo) { - var infoDate = new Date(filteredDeviceData.latestDeviceInfo.location.updatedTime); - var locationDate = new Date(locationInfo.updatedOn); - if (infoDate < locationDate) { - filteredDeviceData.latestDeviceInfo.location.longitude = locationInfo.longitude; - filteredDeviceData.latestDeviceInfo.location.latitude = locationInfo.latitude; - } + //checking for the latest location information based on historical data. + if (locationHistory) { + var infoDate; + var locationDate; + var historicalLatestLoc = locationHistory[locationHistory.length - 1]; + if (historicalLatestLoc && filteredDeviceData.latestDeviceInfo && filteredDeviceData.latestDeviceInfo.location) { + infoDate = new Date(filteredDeviceData.latestDeviceInfo.location.updatedTime); + locationDate = new Date(historicalLatestLoc.values.timeStamp); + } + if (infoDate < locationDate || filteredDeviceData.latestDeviceInfo.length === 0) { + filteredDeviceData.latestDeviceInfo.location = {}; + filteredDeviceData.latestDeviceInfo.location.longitude = historicalLatestLoc.values.longitude; + filteredDeviceData.latestDeviceInfo.location.latitude = historicalLatestLoc.values.latitude; + filteredDeviceData.latestDeviceInfo.location.updatedTime = historicalLatestLoc.values.timeStamp; } } + //checking for the latest location information. + if (filteredDeviceData.latestDeviceInfo.location && locationInfo) { + var infoDate = new Date(filteredDeviceData.latestDeviceInfo.location.updatedTime); + var locationDate = new Date(locationInfo.updatedOn); + if (infoDate < locationDate) { + filteredDeviceData.latestDeviceInfo.location.longitude = locationInfo.longitude; + filteredDeviceData.latestDeviceInfo.location.latitude = locationInfo.latitude; + filteredDeviceData.latestDeviceInfo.location.updatedTime = locationInfo.updatedOn; + } + } response["content"] = filteredDeviceData; response["status"] = "success"; @@ -245,10 +248,10 @@ deviceModule = function () { var url; if (uiPermissions.LIST_DEVICES) { url = devicemgtProps["httpsURL"] + - devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/devices?offset=0&limit=1"; + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/devices?offset=0&limit=1"; } else if (uiPermissions.LIST_OWN_DEVICES) { url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + - "/devices?offset=0&limit=1&user=" + carbonUser.username; + "/devices?offset=0&limit=1&user=" + carbonUser.username; } else { log.error("Access denied for user: " + carbonUser.username); return -1; @@ -277,31 +280,9 @@ deviceModule = function () { return response; }; - /* - @Updated - */ - // publicMethods.getLicense = function (deviceType) { - // var url; - // var license; - // if (deviceType == "windows") { - // url = mdmProps["httpURL"] + "/mdm-windows-agent/services/device/license"; - // } else if (deviceType == "ios") { - // url = mdmProps["httpsURL"] + "/ios-enrollment/license/"; - // } - - // if (url != null && url != undefined) { - // serviceInvokers.XMLHttp.get(url, function (responsePayload) { - // license = responsePayload.text; - // }, function (responsePayload) { - // return null; - // }); - // } - // return license; - // }; - publicMethods.getDevices = function (userName) { var url = devicemgtProps["httpsURL"] + - devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/devices"; + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/devices"; return serviceInvokers.XMLHttp.get( url, function (responsePayload) { var devices = JSON.parse(responsePayload.responseText).devices; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/view.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/view.hbs index 903224be543..8a58f285ab3 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/view.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/view.hbs @@ -19,6 +19,8 @@ {{#zone "content"}} {{#if deviceFound}} {{#if isAuthorized}} + {{#defineZone "device-details-header"}}

diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/view.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/view.js index c93097ab791..3f2d34dc87c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/view.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/view.js @@ -34,6 +34,7 @@ function onRequest(context) { var viewModel = {}; if (filteredDeviceData["type"]) { viewModel["deviceType"] = filteredDeviceData["type"]; + viewModel["type"] = filteredDeviceData["type"]; viewModel.isNotWindows = true; if (viewModel["deviceType"] == "windows") { viewModel.isNotWindows = false; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.lib.service-invoker-utility/public/js/invoker-lib.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.lib.service-invoker-utility/public/js/invoker-lib.js index 335050f5aa4..86722a2612a 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.lib.service-invoker-utility/public/js/invoker-lib.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.lib.service-invoker-utility/public/js/invoker-lib.js @@ -37,6 +37,11 @@ var invokerUtil = function () { acceptTypeValue = acceptType; } + var synchronous = false; + if (isSynchronous) { + synchronous = true; + } + if(contentTypeValue == "application/json"){ restAPIRequestDetails["requestPayload"] = JSON.stringify(requestPayload); } @@ -46,6 +51,7 @@ var invokerUtil = function () { contentType: contentTypeValue, data: JSON.stringify(restAPIRequestDetails), accept: acceptTypeValue, + async : synchronous, success: successCallback, error: function (jqXHR) { if (jqXHR.status == 401) { @@ -61,22 +67,22 @@ var invokerUtil = function () { $.ajax(request); }; - publicMethods.get = function (requestURL, successCallback, errorCallback, contentType, acceptType) { + publicMethods.get = function (requestURL, successCallback, errorCallback, contentType, acceptType, isSynchronous) { var requestPayload = null; - privateMethods.execute("GET", requestURL, requestPayload, successCallback, errorCallback, contentType, acceptType); + privateMethods.execute("GET", requestURL, requestPayload, successCallback, errorCallback, contentType, acceptType, isSynchronous); }; - publicMethods.post = function (requestURL, requestPayload, successCallback, errorCallback, contentType, acceptType) { - privateMethods.execute("POST", requestURL, requestPayload, successCallback, errorCallback, contentType, acceptType); + publicMethods.post = function (requestURL, requestPayload, successCallback, errorCallback, contentType, acceptType, isSynchronous) { + privateMethods.execute("POST", requestURL, requestPayload, successCallback, errorCallback, contentType, acceptType, isSynchronous); }; - publicMethods.put = function (requestURL, requestPayload, successCallback, errorCallback, contentType, acceptType) { - privateMethods.execute("PUT", requestURL, requestPayload, successCallback, errorCallback, contentType, acceptType); + publicMethods.put = function (requestURL, requestPayload, successCallback, errorCallback, contentType, acceptType, isSynchronous) { + privateMethods.execute("PUT", requestURL, requestPayload, successCallback, errorCallback, contentType, acceptType, isSynchronous); }; - publicMethods.delete = function (requestURL, successCallback, errorCallback, contentType, acceptType) { + publicMethods.delete = function (requestURL, successCallback, errorCallback, contentType, acceptType, isSynchronous) { var requestPayload = null; - privateMethods.execute("DELETE", requestURL, requestPayload, successCallback, errorCallback, contentType, acceptType); + privateMethods.execute("DELETE", requestURL, requestPayload, successCallback, errorCallback, contentType, acceptType, isSynchronous); }; return publicMethods; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/public/css/custom-common.css b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/public/css/custom-common.css index 1fa92bf5497..96ecf48e6b7 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/public/css/custom-common.css +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/public/css/custom-common.css @@ -265,4 +265,8 @@ header .username { .add-padding-top-3x { padding-top: 15px !important; +} + +ul#noty_topRight_layout_container li{ + margin-bottom: 10px; } \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/public/css/custom-theme.css b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/public/css/custom-theme.css index e7377e780c7..559a522e061 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/public/css/custom-theme.css +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/public/css/custom-theme.css @@ -428,26 +428,26 @@ a.ctrl-filter-category:hover { } .btn { - display: inline-block; - padding: 8px 20px; - margin-bottom: 0; - font-size: 16px; - font-weight: normal; - line-height: 1.42857143; - text-align: center; - white-space: nowrap; - vertical-align: middle; - -ms-touch-action: manipulation; - touch-action: manipulation; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - background-image: none; - border: 1px solid transparent; - border-radius: 0; - transition: background 0.2s; + display: inline-block; + /*padding: 8px 20px;*/ + margin-bottom: 0; + /*font-size: 16px;*/ + font-weight: normal; + /*line-height: 1.42857143;*/ + text-align: center; + white-space: nowrap; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + /*border-radius: 0;*/ + transition: background 0.2s; } .col-centered { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/theme.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/theme.hbs index bd79e7563f6..7ff2a101ef9 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/theme.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/theme.hbs @@ -26,4 +26,42 @@ {{#zone "bottomJs" override=false}} {{!-- Responsive JS Library--}} {{js "js/responsive-text.js"}} + {{/zone}} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/css/theme-wso2.css b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/css/theme-wso2.css index 02283db5950..a220a923a1b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/css/theme-wso2.css +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/css/theme-wso2.css @@ -7837,7 +7837,7 @@ ul.sidebar-messages > li { * noty styles * ======================================================================== */ #noty_topRight_layout_container { - position: absolute !important; + position: fixed !important; } #noty_topRight_layout_container, #noty_topLeft_layout_container { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/noty_2.3.5/layouts/topRight.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/noty_2.3.5/layouts/topRight.js index be637ec048d..c1d72e4b8b7 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/noty_2.3.5/layouts/topRight.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/noty_2.3.5/layouts/topRight.js @@ -8,7 +8,7 @@ $.noty.layouts.topRight = { selector: 'ul#noty_topRight_layout_container', style : function() { $(this).css({ - top : 20, + top : 0, right : 20, position : 'fixed', width : '310px',