merged with origin

revert-dabc3590
ayyoob 9 years ago
commit 38b9f017c3

@ -19,17 +19,11 @@
package org.wso2.carbon.device.mgt.iot.androidsense.service.impl;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
@DeviceType(value = "android_sense")
@ -45,7 +39,7 @@ public interface AndroidSenseService {
@Path("device/{deviceId}/words")
@POST
@Feature(code = "keywords", name = "Add Keywords", description = "Send keywords to the device")
@Permission(scope = "android_sense_user", permissions = {"/permission/admin/device-mgt/user/operations"})
@Scope(key = "device:android-sense:enroll", name = "", description = "")
Response sendKeyWords(@PathParam("deviceId") String deviceId, @QueryParam("keywords") String keywords);
/**
@ -57,13 +51,13 @@ public interface AndroidSenseService {
@Path("device/{deviceId}/words/threshold")
@POST
@Feature(code = "threshold", name = "Add a Threshold", description = "Set a threshold for word in the device")
@Permission(scope = "android_sense_user", permissions = {"/permission/admin/device-mgt/user/operations"})
@Scope(key = "device:android-sense:enroll", name = "", description = "")
Response sendThreshold(@PathParam("deviceId") String deviceId, @QueryParam("threshold") String threshold);
@Path("device/{deviceId}/words")
@DELETE
@Feature(code = "remove", name = "Remove Keywords", description = "Remove the keywords")
@Permission(scope = "android_sense_user", permissions = {"/permission/admin/device-mgt/user/operations"})
@Scope(key = "device:android-sense:enroll", name = "", description = "")
Response removeKeyWords(@PathParam("deviceId") String deviceId, @QueryParam("words") String words);
/**
@ -72,7 +66,7 @@ public interface AndroidSenseService {
@Path("stats/{deviceId}/sensors/{sensorName}")
@GET
@Consumes("application/json")
@Permission(scope = "android_sense_user", permissions = {"/permission/admin/device-mgt/user/stats"})
@Scope(key = "device:android-sense:enroll", name = "", description = "")
@Produces("application/json")
Response getAndroidSenseDeviceStats(@PathParam("deviceId") String deviceId, @PathParam("sensorName") String sensor,
@QueryParam("from") long from, @QueryParam("to") long to);
@ -82,7 +76,7 @@ public interface AndroidSenseService {
*/
@Path("device/{device_id}/register")
@POST
@Permission(scope = "android_sense_user", permissions = {"/permission/admin/device-mgt/user/devices"})
@Scope(key = "device:android-sense:enroll", name = "", description = "")
Response register(@PathParam("device_id") String deviceId, @QueryParam("deviceName") String deviceName);
}

@ -27,7 +27,7 @@ function onRequest(context) {
"backendApiUri": devicemgtProps["httpsURL"] + "/android_sense/stats/"
};
} else if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
var deviceModule = require("/app/modules/device.js").deviceModule;
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device && device.status != "error") {
return {

@ -25,7 +25,7 @@ function onRequest(context) {
];
if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
var deviceModule = require("/app/modules/device.js").deviceModule;
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device && device.status != "error") {
return {

@ -18,7 +18,7 @@
function onRequest(context) {
var device = context.unit.params.device;
var devicemgtProps = require("/app/conf/reader/main.js")["conf"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var constants = require("/app/modules/constants.js");
var websocketEndpoint = devicemgtProps["httpsURL"].replace("https", "wss");
var tokenPair = session.get(constants.ACCESS_TOKEN_PAIR_IDENTIFIER);

@ -18,7 +18,7 @@
function onRequest(context){
var viewModel = {};
var devicemgtProps = require("/app/conf/reader/main.js")["conf"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
viewModel.hostName = devicemgtProps["httpsWebURL"];
return viewModel;
}

@ -19,16 +19,11 @@
package org.wso2.carbon.device.mgt.iot.arduino.service.impl;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
@API(name = "arduino", version = "1.0.0", context = "/arduino", tags = {"arduino"})
@ -38,12 +33,12 @@ public interface ArduinoService {
@Path("device/{deviceId}/bulb")
@POST
@Feature(code = "bulb", name = "Control Bulb", description = "Control Bulb on Arduino Uno")
@Permission(scope = "arduino_user", permissions = {"/permission/admin/device-mgt/user/operations"})
@Scope(key = "device:arduino:enroll", name = "", description = "")
Response switchBulb(@PathParam("deviceId") String deviceId, @QueryParam("state") String state);
@Path("device/{deviceId}/controls")
@GET
@Permission(scope = "arduino_device", permissions = {"/permission/admin/device-mgt/user/operations"})
@Scope(key = "device:arduino:enroll", name = "", description = "")
Response readControls(@PathParam("deviceId") String deviceId);
/**
@ -53,7 +48,7 @@ public interface ArduinoService {
@GET
@Consumes("application/json")
@Produces("application/json")
@Permission(scope = "arduino_user", permissions = {"/permission/admin/device-mgt/user/stats"})
@Scope(key = "device:arduino:enroll", name = "", description = "")
Response getArduinoTemperatureStats(@PathParam("deviceId") String deviceId, @QueryParam("from") long from,
@QueryParam("to") long to);
@ -63,7 +58,7 @@ public interface ArduinoService {
@Path("device/download")
@GET
@Produces("application/octet-stream")
@Permission(scope = "arduino_user", permissions = {"/permission/admin/device-mgt/user/devices"})
@Scope(key = "device:arduino:enroll", name = "", description = "")
Response downloadSketch(@QueryParam("deviceName") String customDeviceName);
}

@ -17,7 +17,7 @@
*/
function onRequest(context) {
var devicemgtProps = require("/app/conf/reader/main.js")["conf"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var devices = context.unit.params.devices;
var deviceType = context.uriParams.deviceType;
@ -29,7 +29,7 @@ function onRequest(context) {
"backendApiUri": devicemgtProps["httpsURL"] + "/arduino/device/stats/"
};
} else if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
var deviceModule = require("/app/modules/device.js").deviceModule;
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device && device.status != "error") {
return {

@ -25,7 +25,7 @@ function onRequest(context) {
];
if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
var deviceModule = require("/app/modules/device.js").deviceModule;
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device && device.status != "error") {
return {"device": device, "backendApiUri" : devicemgtProps["httpsURL"] + "/arduino/", "autoCompleteParams" : autoCompleteParams};

@ -19,7 +19,7 @@
function onRequest(context) {
var log = new Log("stats.js");
var device = context.unit.params.device;
var devicemgtProps = require("/app/conf/reader/main.js")["conf"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var constants = require("/app/modules/constants.js");
var websocketEndpoint = devicemgtProps["wssURL"].replace("https", "wss");
var tokenPair = session.get(constants.ACCESS_TOKEN_PAIR_IDENTIFIER);

@ -23,7 +23,7 @@ var uriMatcher = new URIMatcher(String(uri));
var log = new Log("api/policy-api.jag");
var constants = require("/app/modules/constants.js");
var policyModule = require("/app/modules/policy.js").policyModule;
var policyModule = require("/app/modules/business-controllers/policy.js")["policyModule"];
var deviceType, deviceId;

@ -23,7 +23,7 @@
* @returns {*} A context object that returns the dynamic state of this page to be presented
*/
function onRequest(context) {
var devicemgtProps = require("/app/conf/reader/main.js")["conf"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var page = {};
page["usernameJSRegEx"] = devicemgtProps.userValidationConfig.usernameJSRegEx;
page["usernameHelpText"] = devicemgtProps.userValidationConfig.usernameHelpMsg;

@ -18,7 +18,7 @@
function onRequest(context) {
var log = new Log("operation.js");
var operationModule = require("/app/modules/operation.js").operationModule;
var operationModule = require("/app/modules/business-controllers/operation.js")["operationModule"];
var device = context.unit.params.device;
var autoCompleteParams = context.unit.params.autoCompleteParams;
var controlOperations = operationModule.getControlOperations(device.type);

@ -19,7 +19,7 @@
function onRequest(context) {
var log = new Log("policy-view-edit-unit backend js");
log.debug("calling policy-view-edit-unit");
var userModule = require("/app/modules/user.js").userModule;
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
context.roles = userModule.getRoles().content;
return context;
}

@ -19,7 +19,7 @@
function onRequest(context) {
var log = new Log("policy-view-edit-unit backend js");
log.debug("calling policy-view-edit-unit");
var userModule = require("/app/modules/user.js").userModule;
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
context.roles = userModule.getRoles().content;
return context;
}

@ -22,8 +22,8 @@ function onRequest(context) {
var DTYPE_CONF_DEVICE_TYPE_KEY = "deviceType";
var DTYPE_CONF_DEVICE_TYPE_LABEL_KEY = "label";
var userModule = require("/app/modules/user.js")["userModule"];
var deviceModule = require("/app/modules/device.js").deviceModule;
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var deviceModule = require("/app/modules/business-controllers/device.js").deviceModule;
var utility = require('/app/modules/utility.js').utility;
var response = userModule.getRoles();
var wizardPage = {};

@ -192,7 +192,7 @@
<artifactId>smackx</artifactId>
</dependency>
<dependency>
<groupId>commons-codec.wso2</groupId>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
</dependencies>

@ -0,0 +1,108 @@
/*
* 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.
*/
package org.wso2.carbon.device.mgt.iot.devicetype.config;
import org.wso2.carbon.device.mgt.iot.devicetype.util.DeviceTypeConfigUtil;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Class for holding CertificateKeystore data.
*/
@XmlRootElement(name = "CertificateKeystore")
public class CertificateKeystoreConfig {
private String certificateKeystoreLocation;
private String certificateKeystoreType;
private String certificateKeystorePassword;
private String caCertAlias;
private String caPrivateKeyPassword;
private String raCertAlias;
private String raPrivateKeyPassword;
@XmlElement(name = "CertificateKeystoreLocation", required = true)
public String getCertificateKeystoreLocation() {
return certificateKeystoreLocation;
}
public void setCertificateKeystoreLocation(String certificateKeystoreLocation) {
if (certificateKeystoreLocation != null && certificateKeystoreLocation.toLowerCase().
contains(DeviceTypeConfigUtil.CARBON_HOME_ENTRY)) {
certificateKeystoreLocation = certificateKeystoreLocation.replace(DeviceTypeConfigUtil.CARBON_HOME_ENTRY,
System.getProperty(DeviceTypeConfigUtil.CARBON_HOME));
}
this.certificateKeystoreLocation = certificateKeystoreLocation;
}
@XmlElement(name = "CertificateKeystoreType", required = true)
public String getCertificateKeystoreType() {
return certificateKeystoreType;
}
public void setCertificateKeystoreType(String certificateKeystoreType) {
this.certificateKeystoreType = certificateKeystoreType;
}
@XmlElement(name = "CertificateKeystorePassword", required = true)
public String getCertificateKeystorePassword() {
return certificateKeystorePassword;
}
public void setCertificateKeystorePassword(String certificateKeystorePassword) {
this.certificateKeystorePassword = certificateKeystorePassword;
}
@XmlElement(name = "CACertAlias", required = true)
public String getCACertAlias() {
return caCertAlias;
}
public void setCACertAlias(String caCertAlias) {
this.caCertAlias = caCertAlias;
}
@XmlElement(name = "CAPrivateKeyPassword", required = true)
public String getCAPrivateKeyPassword() {
return caPrivateKeyPassword;
}
public void setCAPrivateKeyPassword(String caPrivateKeyPassword) {
this.caPrivateKeyPassword = caPrivateKeyPassword;
}
@XmlElement(name = "RACertAlias", required = true)
public String getRACertAlias() {
return raCertAlias;
}
public void setRACertAlias(String raCertAlias) {
this.raCertAlias = raCertAlias;
}
@XmlElement(name = "RAPrivateKeyPassword", required = true)
public String getRAPrivateKeyPassword() {
return raPrivateKeyPassword;
}
public void setRAPrivateKeyPassword(String raPrivateKeyPassword) {
this.raPrivateKeyPassword = raPrivateKeyPassword;
}
}

@ -30,6 +30,7 @@ public class DeviceManagementConfiguration {
private DeviceManagementConfigRepository deviceManagementConfigRepository;
private PushNotificationConfig pushNotificationConfig;
private String deviceType;
private CertificateKeystoreConfig certificateKeystoreConfig;
private static final Log log = LogFactory.getLog(DeviceManagementConfiguration.class);
@ -63,4 +64,13 @@ public class DeviceManagementConfiguration {
this.pushNotificationConfig = pushNotificationConfig;
}
@XmlElement(name = "CertificateKeystore", required = false)
public CertificateKeystoreConfig getCertificateKeystoreConfig() {
return certificateKeystoreConfig;
}
public void setCertificateKeystoreConfig(
CertificateKeystoreConfig certificateKeystoreConfig) {
this.certificateKeystoreConfig = certificateKeystoreConfig;
}
}

@ -31,6 +31,9 @@ import java.io.File;
public class DeviceTypeConfigUtil {
public static final String CARBON_HOME = "carbon.home";
public static final String CARBON_HOME_ENTRY = "${carbon.home}";
public static Document convertToDocument(File file) throws DeviceTypeConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);

@ -19,16 +19,11 @@
package org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@ -39,7 +34,7 @@ public interface RaspberryPiService {
@Path("device/{deviceId}/bulb")
@POST
@Feature(code = "bulb", name = "Bulb On / Off", description = "Switch on/off Raspberry Pi agent's bulb. (On / Off)")
@Permission(scope = "raspberrypi_user", permissions = {"/permission/admin/device-mgt/user/operations"})
@Scope(key = "device:raspberrypi:enroll", name = "", description = "")
Response switchBulb(@PathParam("deviceId") String deviceId, @QueryParam("state") String state);
/**
@ -49,7 +44,7 @@ public interface RaspberryPiService {
@GET
@Consumes("application/json")
@Produces("application/json")
@Permission(scope = "raspberrypi_user", permissions = {"/permission/admin/device-mgt/user/stats"})
@Scope(key = "device:raspberrypi:enroll", name = "", description = "")
Response getRaspberryPiTemperatureStats(@PathParam("deviceId") String deviceId,
@QueryParam("from") long from, @QueryParam("to") long to);
@ -59,7 +54,7 @@ public interface RaspberryPiService {
@Path("device/download")
@GET
@Produces(MediaType.APPLICATION_JSON)
@Permission(scope = "raspberrypi_user", permissions = {"/permission/admin/device-mgt/user/devices"})
@Scope(key = "device:raspberrypi:enroll", name = "", description = "")
Response downloadSketch(@QueryParam("deviceName") String deviceName, @QueryParam("sketch_type") String sketchType);
}

@ -17,7 +17,7 @@
*/
function onRequest(context) {
var devicemgtProps = require("/app/conf/reader/main.js")["conf"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var devices = context.unit.params.devices;
var deviceType = context.uriParams.deviceType;
@ -29,7 +29,7 @@ function onRequest(context) {
"backendApiUri": devicemgtProps["httpsURL"] + "/raspberrypi/device/stats/"
};
} else if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
var deviceModule = require("/app/modules/device.js").deviceModule;
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device && device.status != "error") {
return {

@ -25,7 +25,7 @@ function onRequest(context) {
];
if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
var deviceModule = require("/app/modules/device.js").deviceModule;
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device && device.status != "error") {
return {"device": device, "backendApiUri" : devicemgtProps["httpsURL"] + "/raspberrypi/", "autoCompleteParams" : autoCompleteParams};

@ -19,7 +19,7 @@
function onRequest(context) {
var log = new Log("stats.js");
var device = context.unit.params.device;
var devicemgtProps = require("/app/conf/reader/main.js")["conf"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var constants = require("/app/modules/constants.js");
var websocketEndpoint = devicemgtProps["wssURL"].replace("https", "wss");
var tokenPair = session.get(constants.ACCESS_TOKEN_PAIR_IDENTIFIER);

@ -125,7 +125,7 @@
</dependency>
<dependency>
<groupId>commons-codec.wso2</groupId>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>

@ -134,7 +134,7 @@
</dependency>
<dependency>
<groupId>commons-codec.wso2</groupId>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>

@ -69,7 +69,7 @@
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>commons-codec.wso2</groupId>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</exclusion>
</exclusions>
@ -208,7 +208,7 @@
</dependency>
<dependency>
<groupId>commons-codec.wso2</groupId>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>

@ -19,7 +19,7 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature;
@ -48,7 +48,7 @@ public interface VirtualFireAlarmService {
*/
@POST
@Path("device/{deviceId}/buzz")
@Permission(scope = "virtual_firealarm_user", permissions = {"/permission/admin/device-mgt/user/operations"})
@Scope(key = "device:firealarm:enroll", name = "", description = "")
@Feature(code = "buzz", name = "Buzzer On / Off", description = "Switch on/off Virtual Fire Alarm Buzzer. (On / Off)")
Response switchBuzzer(@PathParam("deviceId") String deviceId,
@FormParam("state") String state);
@ -58,7 +58,7 @@ public interface VirtualFireAlarmService {
*/
@Path("device/stats/{deviceId}")
@GET
@Permission(scope = "virtual_firealarm_user", permissions = {"/permission/admin/device-mgt/user/stats"})
@Scope(key = "device:firealarm:enroll", name = "", description = "")
@Consumes("application/json")
@Produces("application/json")
Response getVirtualFirealarmStats(@PathParam("deviceId") String deviceId, @QueryParam("from") long from,
@ -67,7 +67,7 @@ public interface VirtualFireAlarmService {
@Path("device/download")
@GET
@Produces("application/zip")
@Permission(scope = "virtual_firealarm_user", permissions = {"/permission/admin/device-mgt/user/devices"})
@Scope(key = "device:firealarm:enroll", name = "", description = "")
Response downloadSketch(@QueryParam("deviceName") String deviceName, @QueryParam("sketchType") String sketchType);
}

@ -98,7 +98,7 @@
<dependencies>
<dependency>
<groupId>commons-codec.wso2</groupId>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>

@ -22,8 +22,11 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
import org.wso2.carbon.certificate.mgt.core.util.ConfigurationUtil;
import org.wso2.carbon.device.mgt.iot.devicetype.config.CertificateKeystoreConfig;
import org.wso2.carbon.device.mgt.iot.devicetype.config.DeviceManagementConfiguration;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.internal.VirtualFirealarmManagementDataHolder;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
@ -46,11 +49,11 @@ import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
public class VirtualFirealarmSecurityManager {
private static final Log log = LogFactory.getLog(VirtualFirealarmSecurityManager.class);
private static PrivateKey serverPrivateKey;
private static CertificateKeystoreConfig certificateKeystoreConfig;
private static final String SIGNATURE_ALG = "SHA1withRSA";
private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding";
@ -58,26 +61,34 @@ public class VirtualFirealarmSecurityManager {
}
private static CertificateKeystoreConfig getCertKeyStoreConfig() {
if (certificateKeystoreConfig == null) {
DeviceManagementConfiguration deviceManagementConfiguration = VirtualFirealarmManagementDataHolder.getInstance().
getDeviceTypeConfigService().getConfiguration(
VirtualFireAlarmConstants.DEVICE_TYPE,
VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN);
certificateKeystoreConfig = deviceManagementConfiguration.getCertificateKeystoreConfig();
}
return certificateKeystoreConfig;
}
public static void initVerificationManager() {
serverPrivateKey = retrievePrivateKey(ConfigurationUtil.CA_CERT_ALIAS,
ConfigurationUtil.KEYSTORE_CA_CERT_PRIV_PASSWORD);
serverPrivateKey = retrievePrivateKey();
}
public static PrivateKey retrievePrivateKey(String alias, String password){
public static PrivateKey retrievePrivateKey() {
PrivateKey privateKey = null;
InputStream inputStream = null;
KeyStore keyStore;
CertificateKeystoreConfig certificateKeystoreConfig = getCertKeyStoreConfig();
try {
keyStore = KeyStore.getInstance(ConfigurationUtil.getConfigEntry(ConfigurationUtil.CERTIFICATE_KEYSTORE));
inputStream = new FileInputStream(ConfigurationUtil.getConfigEntry(
ConfigurationUtil.PATH_CERTIFICATE_KEYSTORE));
keyStore = KeyStore.getInstance(certificateKeystoreConfig.getCertificateKeystoreType());
inputStream = new FileInputStream(certificateKeystoreConfig.getCertificateKeystoreLocation());
keyStore.load(inputStream, ConfigurationUtil.getConfigEntry(ConfigurationUtil.CERTIFICATE_KEYSTORE_PASSWORD)
.toCharArray());
keyStore.load(inputStream, certificateKeystoreConfig.getCertificateKeystorePassword().toCharArray());
privateKey = (PrivateKey) (keyStore.getKey(ConfigurationUtil.getConfigEntry(alias),
ConfigurationUtil.getConfigEntry(password).toCharArray()));
privateKey = (PrivateKey) (keyStore.getKey(certificateKeystoreConfig.getCACertAlias(),
certificateKeystoreConfig.getCAPrivateKeyPassword().toCharArray()));
} catch (KeyStoreException e) {
String errorMsg = "Could not load KeyStore of given type in [certificate-config.xml] file." ;
@ -94,9 +105,6 @@ public class VirtualFirealarmSecurityManager {
} catch (IOException e) {
String errorMsg = "Input output issue occurred when loading KeyStore";
log.error(errorMsg, e);
} catch (KeystoreException e) {
String errorMsg = "An error occurred whilst trying load Configs for KeyStoreReader";
log.error(errorMsg, e);
} catch (UnrecoverableKeyException e) {
String errorMsg = "Key is unrecoverable when retrieving CA private key";
log.error(errorMsg, e);

@ -57,7 +57,7 @@
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>commons-codec.wso2</groupId>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</exclusion>
</exclusions>
@ -171,7 +171,7 @@
</dependency>
<dependency>
<groupId>commons-codec.wso2</groupId>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
</dependencies>

@ -17,7 +17,7 @@
*/
function onRequest(context) {
var devicemgtProps = require("/app/conf/reader/main.js")["conf"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var devices = context.unit.params.devices;
var deviceType = context.uriParams.deviceType;
@ -29,7 +29,7 @@ function onRequest(context) {
"backendApiUri": devicemgtProps["httpsURL"] + "/virtual_firealarm/device/stats/"
};
} else if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
var deviceModule = require("/app/modules/device.js").deviceModule;
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device && device.status != "error") {
return {

@ -25,7 +25,7 @@ function onRequest(context) {
];
if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
var deviceModule = require("/app/modules/device.js").deviceModule;
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device && device.status != "error") {
return {"device": device, "backendApiUri" : devicemgtProps["httpsURL"] + "/virtual_firealarm/", "autoCompleteParams" : autoCompleteParams};

@ -19,7 +19,7 @@
function onRequest(context) {
var log = new Log("stats.js");
var device = context.unit.params.device;
var devicemgtProps = require("/app/conf/reader/main.js")["conf"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var constants = require("/app/modules/constants.js");
var websocketEndpoint = devicemgtProps["wssURL"].replace("https", "wss");
var jwtService = carbon.server.osgiService('org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService');

@ -23,7 +23,6 @@ import io.swagger.annotations.ApiModelProperty;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@ -52,7 +51,6 @@ public class AndroidPlatformConfiguration implements Serializable {
)
@NotNull
@Size(min = 2, max = 10)
@Pattern(regexp = "^[A-Za-z0-9]*$")
private String type;
@ApiModelProperty(
name = "configuration",

@ -21,7 +21,6 @@ package org.wso2.carbon.mdm.services.android.bean.wrapper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
/**
@ -33,7 +32,6 @@ public class EventBeanWrapper {
@ApiModelProperty(name = "deviceIdentifier", value = "DeviceIdentifier to be need to retrieve/publish Event.", required = true)
@Size(min = 2, max = 45)
@Pattern(regexp = "^[A-Za-z0-9]*$")
private String deviceIdentifier;
@ApiModelProperty(name = "payload", value = "Event payload.", required = true)
private String payload;

@ -50,32 +50,41 @@ public class GlobalThrowableMapper implements ExceptionMapper {
if (e instanceof JsonParseException) {
String errorMessage = "Malformed request body.";
log.error(errorMessage);
if (log.isDebugEnabled()) {
log.error(errorMessage, e);
}
return AndroidDeviceUtils.buildBadRequestException(errorMessage).getResponse();
}
if (e instanceof NotFoundException) {
return ((NotFoundException) e).getResponse();
}
if (e instanceof ConstraintViolationException) {
log.error("Constraint violation", e);
return Response.status(Response.Status.BAD_REQUEST).header("Content-Type", "application/json")
.entity(400l).build();
if (e instanceof BadRequestException) {
return ((BadRequestException) e).getResponse();
}
if (e instanceof UnexpectedServerErrorException) {
log.error("Unexpected server error", e);
if (log.isDebugEnabled()) {
log.error("Unexpected server error", e);
}
return ((UnexpectedServerErrorException) e).getResponse();
}
if (e instanceof ConstraintViolationException) {
return ((ParameterValidationException) e).getResponse();
}
if (e instanceof IllegalArgumentException) {
log.error("Illegal exception.", e);
return Response.status(Response.Status.BAD_REQUEST).header("Content-Type", "application/json")
.entity(400l).build();
ErrorDTO errorDetail = new ErrorDTO();
errorDetail.setCode((long) 400);
errorDetail.setMoreInfo("");
errorDetail.setMessage("");
errorDetail.setDescription(e.getMessage());
return Response
.status(Response.Status.BAD_REQUEST)
.entity(errorDetail)
.build();
}
if (e instanceof ClientErrorException) {
log.error("Client error", e);
if (log.isDebugEnabled()) {
log.error("Client error", e);
}
return ((ClientErrorException) e).getResponse();
}
if (e instanceof AuthenticationException) {
@ -90,11 +99,15 @@ public class GlobalThrowableMapper implements ExceptionMapper {
.build();
}
if (e instanceof ForbiddenException) {
log.error("Resource forbidden", e);
if (log.isDebugEnabled()) {
log.error("Resource forbidden", e);
}
return ((ForbiddenException) e).getResponse();
}
//unknown exception log and return
log.error("An Unknown exception has been captured by global exception mapper.", e);
if (log.isDebugEnabled()) {
log.error("An Unknown exception has been captured by global exception mapper.", e);
}
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).header("Content-Type", "application/json")
.entity(e500).build();
}

@ -19,6 +19,8 @@
package org.wso2.carbon.mdm.services.android.services;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import org.wso2.carbon.mdm.services.android.bean.wrapper.*;
@ -30,6 +32,10 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
@API(name = "Android Device Management Administrative Service", version = "1.0.0",
context = "api/device-mgt/android/v1.0/admin/devices",
tags = {"devicemgt_android"})
@Path("/admin/devices")
@Api(value = "Android Device Management Administrative Service", description = "Device management related admin APIs.")
@Produces(MediaType.APPLICATION_JSON)
@ -85,6 +91,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new lock operation.")
})
@Scope(key = "device:android:operation:lock", name = "Lock device", description = "")
Response configureDeviceLock(
@ApiParam(name = "deviceLockBeanWrapper",
value = "Device lock configurations with device IDs") DeviceLockBeanWrapper deviceLockBeanWrapper);
@ -138,6 +145,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new un-lock operation.")
})
@Scope(key = "device:android:operation:unlock", name = "Unlock device", description = "")
Response configureDeviceUnlock(
@ApiParam(name = "deviceIDs", value = "DeviceIds to be enable device unlock operation")
List<String> deviceIDs);
@ -190,6 +198,7 @@ public interface DeviceManagementAdminService {
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while adding a new get-location operation.")})
@Scope(key = "device:android:operation:location", name = "Get device location", description = "")
Response getDeviceLocation(
@ApiParam(name = "deviceIDs", value = "DeviceIDs to be requested to get device location")
List<String> deviceIDs);
@ -242,6 +251,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new clear password operation.")
})
@Scope(key = "device:android:operation:clear-password", name = "Clear password of device", description = "")
Response removePassword(
@ApiParam(name = "deviceIDs",
value = "DeviceIds to be requested to remove password") List<String> deviceIDs);
@ -294,6 +304,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new control camera operation.")
})
@Scope(key = "device:android:operation:camera", name = "Enable/Disable camera", description = "")
Response configureCamera(
@ApiParam(name = "cameraBeanWrapper", value = "Camera enable/disable configurations with device IDs")
CameraBeanWrapper cameraBeanWrapper);
@ -349,6 +360,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new device info operation.")
})
@Scope(key = "device:android:operation:info", name = "Get device information", description = "")
Response getDeviceInformation(
@ApiParam(name = "deviceIds", value = "Device IDs to be requested to get device information")
List<String> deviceIDs);
@ -457,6 +469,7 @@ public interface DeviceManagementAdminService {
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while adding a enterprise wipe operation.")})
@Scope(key = "device:android:operation:enterprise-wipe", name = "Enterprise wipe", description = "")
Response wipeDevice(@ApiParam(name = "deviceIDs", value = "Device IDs to be requested to do enterprise-wipe")
List<String> deviceIDs);
@ -508,6 +521,7 @@ public interface DeviceManagementAdminService {
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while adding a device wipe operation.")})
@Scope(key = "device:android:operation:wipe", name = "Factory reset device", description = "")
Response wipeData(
@ApiParam(name = "wipeDataBeanWrapper", value = "Configurations and DeviceIds needed to do wipe-data")
WipeDataBeanWrapper wipeDataBeanWrapper);
@ -564,6 +578,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new get-applications operation.")
})
@Scope(key = "device:android:operation:applications", name = "Get installed applications", description = "")
Response getApplications(
@ApiParam(name = "deviceIDs", value = "Device Ids needed to get applications that are already installed")
List<String> deviceIDs);
@ -616,6 +631,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new device ring operation.")
})
@Scope(key = "device:android:operation:ring", name = "Ring device", description = "")
Response ringDevice(
@ApiParam(name = "deviceIDs", value = "Device Ids needed for ring")
List<String> deviceIDs);
@ -668,6 +684,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new device reboot operation.")
})
@Scope(key = "device:android:operation:reboot", name = "Reboot device", description = "")
Response rebootDevice(
@ApiParam(name = "deviceIDs", value = "Device Ids needed for reboot.")
List<String> deviceIDs);
@ -720,6 +737,7 @@ public interface DeviceManagementAdminService {
"Server error occurred while adding a new device mute operation.")
})
@Path("/mute")
@Scope(key = "device:android:operation:mute", name = "Mute device", description = "")
Response muteDevice(
@ApiParam(name = "deviceIDs", value = "DeviceIDs need to be muted")
List<String> deviceIDs);
@ -775,6 +793,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new install-application operation.")
})
@Scope(key = "device:android:operation:install-app", name = "Install applications", description = "")
Response installApplication(
@ApiParam(name = "applicationInstallationBeanWrapper", value = "Properties of installed apps and device IDs")
ApplicationInstallationBeanWrapper applicationInstallationBeanWrapper);
@ -830,6 +849,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new update-application operation.")
})
@Scope(key = "device:android:operation:update-app", name = "Update installed applications", description = "")
Response updateApplication(
@ApiParam(name = "applicationUpdateBeanWrapper", value = "Properties of updated apps and device IDs")
ApplicationUpdateBeanWrapper applicationUpdateBeanWrapper);
@ -882,6 +902,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new uninstall-application operation.")
})
@Scope(key = "device:android:operation:uninstall-app", name = "Uninstall applications", description = "")
Response uninstallApplication(
@ApiParam(name = "applicationUninstallationBeanWrapper",
value = "applicationUninstallationConfigs and Device Ids")
@ -936,6 +957,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new blacklist-applications operation.")
})
@Scope(key = "device:android:operation:blacklist-app", name = "Blacklist applications", description = "")
Response blacklistApplications(
@ApiParam(name = "blacklistApplicationsBeanWrapper", value = "BlacklistApplications " +
"Configuration and DeviceIds")
@ -990,6 +1012,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new upgrade firmware operation.")
})
@Scope(key = "device:android:operation:upgrade", name = "Upgrade firmware", description = "")
Response upgradeFirmware(
@ApiParam(name = "upgradeFirmwareBeanWrapper",
value = "Firmware upgrade configuration and DeviceIds")
@ -1044,6 +1067,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new configure VPN operation.")
})
@Scope(key = "device:android:operation:vpn", name = "Add VPN profiles", description = "")
Response configureVPN(
@ApiParam(name = "vpnBeanWrapper",
value = "VPN configuration and DeviceIds")
@ -1097,6 +1121,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new send notification operation.")
})
@Scope(key = "device:android:operation:notification", name = "Send notifications", description = "")
Response sendNotification(
@ApiParam(name = "notificationBeanWrapper",
value = "Notification Configurations and device Ids")
@ -1150,6 +1175,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new configure wifi operation.")
})
@Scope(key = "device:android:operation:wifi", name = "Add WiFi configurations", description = "")
Response configureWifi(
@ApiParam(name = "wifiBeanWrapper",
value = "WifiConfigurations and Device Ids") WifiBeanWrapper wifiBeanWrapper);
@ -1202,6 +1228,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new encrypt storage operation.")
})
@Scope(key = "device:android:operation:encrypt", name = "Encrypt device", description = "")
Response encryptStorage(
@ApiParam(name = "encryptionBeanWrapper",
value = "Configurations and deviceIds need to be done data encryption")
@ -1255,6 +1282,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new change lock code operation.")
})
@Scope(key = "device:android:operation:change-lock", name = "Change password of device", description = "")
Response changeLockCode(
@ApiParam(name = "lockCodeBeanWrapper",
value = "Configurations and device Ids need to be done change lock code")
@ -1308,6 +1336,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new set password policy operation.")
})
@Scope(key = "device:android:operation:password-policy", name = "Set password policy", description = "")
Response setPasswordPolicy(
@ApiParam(name = "passwordPolicyBeanWrapper",
value = "Password Policy Configurations and Device Ids")
@ -1361,6 +1390,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new set webclip operation.")
})
@Scope(key = "device:android:operation:webclip", name = "Add webclips", description = "")
Response setWebClip(
@ApiParam(name = "webClipBeanWrapper",
value = "Configurations to need set web clip on device and device Ids")

@ -19,6 +19,8 @@
package org.wso2.carbon.mdm.services.android.services;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.mdm.services.android.bean.wrapper.AndroidApplication;
import org.wso2.carbon.mdm.services.android.bean.wrapper.AndroidDevice;
@ -32,6 +34,10 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
@API(name = "Android Device Management", version = "1.0.0",
context = "api/device-mgt/android/v1.0/devices",
tags = {"devicemgt_android"})
@Api(value = "Android Device Management",
description = "This carries all the resources related to Android device management functionalities")
@Path("/devices")
@ -81,6 +87,7 @@ public interface DeviceManagementService {
message = "Internal Server Error. \n " +
"Server error occurred while updating the application list.")
})
@Scope(key = "device:android:enroll", name = "Enroll Android device", description = "")
Response updateApplicationList(
@ApiParam(
name = "id",
@ -134,6 +141,7 @@ public interface DeviceManagementService {
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching policies.")
})
@Scope(key = "device:android:enroll", name = "Enroll Android device", description = "")
Response getPendingOperations(
@ApiParam(
name = "id",
@ -198,6 +206,7 @@ public interface DeviceManagementService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new policy.")
})
Response enrollDevice(@ApiParam(name = "device", value = "Device Information to be enroll")
@Valid AndroidDevice device);
@ -236,6 +245,7 @@ public interface DeviceManagementService {
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the enrollment status of the Android device.")
})
@Scope(key = "device:android:enroll", name = "Enroll Android device", description = "")
Response isEnrolled(
@ApiParam(
name = "id",
@ -289,6 +299,7 @@ public interface DeviceManagementService {
message = "Internal Server Error. \n " +
"Server error occurred while updating the device enrollment.")
})
@Scope(key = "device:android:enroll", name = "Enroll Android device", description = "")
Response modifyEnrollment(
@ApiParam(
name = "id",
@ -318,6 +329,7 @@ public interface DeviceManagementService {
message = "Internal Server Error. \n " +
"Server error occurred while dis-enrolling the device.")
})
@Scope(key = "device:android:disenroll", name = "Enroll Android device", description = "")
Response disEnrollDevice(
@ApiParam(
name = "id",

@ -19,6 +19,8 @@
package org.wso2.carbon.mdm.services.android.services;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.mdm.services.android.bean.AndroidPlatformConfiguration;
import org.wso2.carbon.mdm.services.android.exception.AndroidAgentException;
@ -28,6 +30,10 @@ import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@API(name = "Android Configuration Management", version = "1.0.0",
context = "api/device-mgt/android/v1.0/configuration",
tags = {"devicemgt_android"})
@Api(value = "Android Configuration Management", description = "This API carries all resource associated with " +
"manipulating the general configurations of Android platform")
@Path("/configuration")
@ -75,6 +81,7 @@ public interface DeviceTypeConfigurationService {
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching Android platform configuration.")
})
@Scope(key = "configuration:view", name = "View configurations", description = "")
Response getConfiguration(
@ApiParam(
name = "If-Modified-Since",
@ -124,6 +131,7 @@ public interface DeviceTypeConfigurationService {
message = "Internal Server Error. \n " +
"Server error occurred while modifying Android platform configuration.")
})
@Scope(key = "configuration:manage", name = "Add configurations", description = "")
Response updateConfiguration(
@ApiParam(name = "configuration",
value = "AndroidPlatformConfiguration")
@ -171,6 +179,7 @@ public interface DeviceTypeConfigurationService {
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching Android license configuration.")
})
@Scope(key = "device:android:enroll", name = "Enroll Android device", description = "")
Response getLicense(
@ApiParam(
name = "If-Modified-Since",

@ -19,16 +19,21 @@
package org.wso2.carbon.mdm.services.android.services;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.mdm.services.android.bean.DeviceState;
import org.wso2.carbon.mdm.services.android.bean.wrapper.EventBeanWrapper;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@API(name = "Android Event Receiver", version = "1.0.0",
context = "api/device-mgt/android/v1.0/events",
tags = {"devicemgt_android"})
@Api(value = "Event Receiver", description = "Event publishing/retrieving related APIs.To enable Eventing need to" +
" configure as ref-https://docs.wso2.com/display/EMM210/Managing+Event+Publishing+with+WSO2+Data+Analytics+Server, " +
"https://docs.wso2.com/display/EMM210/Creating+a+New+Event+Stream+and+Receiver")
@ -85,6 +90,7 @@ public interface EventReceiverService {
message = "Internal Server Error. \n " +
"Server error occurred while publishing events.")
})
@Scope(key = "device:android:event:write", name = "Publish events to DAS", description = "")
Response publishEvents(
@ApiParam(
name = "eventBeanWrapper",
@ -134,14 +140,13 @@ public interface EventReceiverService {
code = 500,
message = "Error occurred while getting published events for specific device.")
})
@Scope(key = "device:android:event:read", name = "View events", description = "")
Response retrieveAlerts(
@ApiParam(
name = "id",
value = "Device Identifier to be need to retrieve events.",
required = true)
@Size(min = 2, max = 45)
@Pattern(regexp = "^[A-Za-z0-9]*$")
@QueryParam("id") String deviceId,
@ApiParam(
name = "from",
@ -155,7 +160,6 @@ public interface EventReceiverService {
name = "type",
value = "Type of the Alert to be need to retrieve events.")
@Size(min = 2, max = 45)
@Pattern(regexp = "^[A-Za-z0-9]*$")
@QueryParam("type") String type,
@ApiParam(
name = "If-Modified-Since",

@ -25,21 +25,52 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.core.operation.mgt.CommandOperation;
import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation;
import org.wso2.carbon.mdm.services.android.bean.*;
import org.wso2.carbon.mdm.services.android.bean.wrapper.*;
import org.wso2.carbon.mdm.services.android.bean.ApplicationInstallation;
import org.wso2.carbon.mdm.services.android.bean.ApplicationUninstallation;
import org.wso2.carbon.mdm.services.android.bean.ApplicationUpdate;
import org.wso2.carbon.mdm.services.android.bean.BlacklistApplications;
import org.wso2.carbon.mdm.services.android.bean.Camera;
import org.wso2.carbon.mdm.services.android.bean.DeviceEncryption;
import org.wso2.carbon.mdm.services.android.bean.DeviceLock;
import org.wso2.carbon.mdm.services.android.bean.ErrorResponse;
import org.wso2.carbon.mdm.services.android.bean.LockCode;
import org.wso2.carbon.mdm.services.android.bean.Notification;
import org.wso2.carbon.mdm.services.android.bean.PasscodePolicy;
import org.wso2.carbon.mdm.services.android.bean.UpgradeFirmware;
import org.wso2.carbon.mdm.services.android.bean.Vpn;
import org.wso2.carbon.mdm.services.android.bean.WebClip;
import org.wso2.carbon.mdm.services.android.bean.Wifi;
import org.wso2.carbon.mdm.services.android.bean.WipeData;
import org.wso2.carbon.mdm.services.android.bean.wrapper.ApplicationInstallationBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.ApplicationUninstallationBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.ApplicationUpdateBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.BlacklistApplicationsBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.CameraBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.DeviceLockBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.EncryptionBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.LockCodeBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.NotificationBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.PasswordPolicyBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.UpgradeFirmwareBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.VpnBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.WebClipBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.WifiBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.WipeDataBeanWrapper;
import org.wso2.carbon.mdm.services.android.exception.BadRequestException;
import org.wso2.carbon.mdm.services.android.exception.UnexpectedServerErrorException;
import org.wso2.carbon.mdm.services.android.services.DeviceManagementAdminService;
import org.wso2.carbon.mdm.services.android.util.AndroidAPIUtils;
import org.wso2.carbon.mdm.services.android.util.AndroidConstants;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@Path("/admin/devices")
@ -48,6 +79,7 @@ import java.util.List;
public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminService {
private static final Log log = LogFactory.getLog(DeviceManagementAdminServiceImpl.class);
private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX";
@POST
@Path("/lock-devices")
@ -573,6 +605,14 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
}
UpgradeFirmware upgradeFirmware = upgradeFirmwareBeanWrapper.getOperation();
//validate date
if(upgradeFirmware != null && upgradeFirmware.getSchedule() != null){
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
sdf.setLenient(false);
Date date = sdf.parse(upgradeFirmware.getSchedule());
}
ProfileOperation operation = new ProfileOperation();
operation.setCode(AndroidConstants.OperationCodes.UPGRADE_FIRMWARE);
operation.setType(Operation.Type.PROFILE);
@ -588,6 +628,11 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe
log.error(errorMessage, e);
throw new UnexpectedServerErrorException(
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(errorMessage).build());
} catch (ParseException e) {
String errorMessage = "Issue in validating the schedule date";
log.error(errorMessage);
throw new BadRequestException(
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
}
}

@ -260,7 +260,16 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
@Override
public Response modifyEnrollment(@PathParam("id") String id, @Valid AndroidDevice androidDevice) {
Device device = new Device();
String msg = "";
device.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
if(androidDevice.getEnrolmentInfo().getDateOfEnrolment() <= 0){
msg = "Invalid Enrollment date.";
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
if(androidDevice.getEnrolmentInfo().getDateOfLastUpdate() <= 0){
msg = "Invalid Last Updated date.";
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
device.setEnrolmentInfo(androidDevice.getEnrolmentInfo());
device.getEnrolmentInfo().setOwner(AndroidAPIUtils.getAuthenticatedUser());
device.setDeviceInfo(androidDevice.getDeviceInfo());
@ -281,7 +290,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
"carries the id '" + id + "' has not been updated").build();
}
} catch (DeviceManagementException e) {
String msg = "Error occurred while modifying enrollment of the Android device that carries the id '" +
msg = "Error occurred while modifying enrollment of the Android device that carries the id '" +
id + "'";
log.error(msg, e);
throw new UnexpectedServerErrorException(

@ -33,7 +33,6 @@ import org.wso2.carbon.mdm.services.android.util.AndroidAPIUtils;
import org.wso2.carbon.mdm.services.android.util.Message;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
@ -78,11 +77,10 @@ public class EventReceiverServiceImpl implements EventReceiverService {
@Override
public Response retrieveAlerts(@QueryParam("id")
@Size(min = 2, max = 45)
@Pattern(regexp = "^[A-Za-z0-9]*$") String deviceId,
String deviceId,
@QueryParam("from") long from,
@QueryParam("to") long to,
@Size(min = 2, max = 45)
@Pattern(regexp = "^[A-Za-z0-9]*$")
@QueryParam("type") String type,
@HeaderParam("If-Modified-Since") String ifModifiedSince) {

@ -129,8 +129,14 @@ public class AndroidAPIUtils {
DeviceIDHolder deviceIDHolder = deviceUtils.validateDeviceIdentifiers(deviceIDs);
List<DeviceIdentifier> validDeviceIds = deviceIDHolder.getValidDeviceIDList();
Activity activity = getDeviceManagementService().addOperation(
DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID, operation, validDeviceIds);
Activity activity = null;
if(validDeviceIds.size() > 0) {
activity = getDeviceManagementService().addOperation(
DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID, operation, validDeviceIds);
} else {
throw new IllegalArgumentException("Invalid device Identifiers found");
}
// if (activity != null) {
// GCMService gcmService = getGCMService();
// if (gcmService.isGCMEnabled()) {
@ -142,11 +148,7 @@ public class AndroidAPIUtils {
// getGCMService().sendNotification(operation.getCode(), devices);
// }
// }
if (!deviceIDHolder.getErrorDeviceIdList().isEmpty()) {
throw new BadRequestException(
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(deviceUtils.
convertErrorMapIntoErrorMessage(deviceIDHolder.getErrorDeviceIdList())).build());
}
return Response.status(Response.Status.CREATED).entity(activity).build();
}
@ -283,6 +285,9 @@ public class AndroidAPIUtils {
OperationCodes.DEVICE_INFO.equals(operation.getCode())) {
try {
if (log.isDebugEnabled()){
log.debug("Operation response: " + operation.getOperationResponse());
}
Device device = new Gson().fromJson(operation.getOperationResponse(), Device.class);
org.wso2.carbon.device.mgt.common.device.details.DeviceInfo deviceInfo = convertDeviceToInfo(device);
updateDeviceInfo(deviceIdentifier, deviceInfo);
@ -401,8 +406,6 @@ public class AndroidAPIUtils {
}
} else {
if (prop.getName().equalsIgnoreCase("CPU_INFO")) {
deviceInfo.setTotalRAMMemory(Double.parseDouble(getProperty(prop.getValue(), "User")));
deviceInfo.getDeviceDetailsMap().put("cpuUser",
getProperty(prop.getValue(), "User"));
deviceInfo.getDeviceDetailsMap().put("cpuSystem",

@ -39,6 +39,13 @@
<method>GET</method>
</Permission>
<Permission>
<name>Modify Tenant configuration</name>
<path>/device-mgt/admin/platform-configs/add</path>
<url>/configuration</url>
<method>PUT</method>
</Permission>
<Permission>
<name>Add Tenant configuration</name>
<path>/device-mgt/admin/platform-configs/add</path>

@ -51,7 +51,7 @@
<property name="version" value="1.0"/>
<property name="host" value="localhost:9443"/>
<property name="schemes" value="https" />
<property name="basePath" value="/api/device-mgt/android/v1.0"/>
<property name="basePath" value="/api-device-mgt-android-v1.0"/>
<property name="title" value="Android Device Management API Definitions"/>
<property name="contact" value="dev@wso2.org"/>
<property name="license" value="Apache 2.0"/>

@ -49,7 +49,7 @@
</context-param>
<context-param>
<param-name>managed-api-enabled</param-name>
<param-value>false</param-value>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>managed-api-owner</param-name>

@ -22,7 +22,7 @@ function onRequest(context) {
var deviceId = request.getParameter("id");
if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
var deviceModule = require("/app/modules/device.js").deviceModule;
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device) {

@ -1 +1,29 @@
{{unit "mdm.unit.policy.wizard"}}
<div class="container col-centered wr-content policy-profile">
<div class="wr-form">
<h1 id="policy-profile-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
<div id="policy-profile-wizard-steps" class="row wr-wizard"></div>
<hr>
<div class="row">
<div class="col-lg-12">
<h4 class="visible-xs">Step 2: Configure profile</h4>
<br>
<div id="policy-profile-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="wr-advance-operations">
<div class="wr-advance-operations-init">
<br>
&nbsp;&nbsp;&nbsp;&nbsp;<i class="fw fw-settings fw-spin fw-2x"></i>
&nbsp;&nbsp;&nbsp;Loading platform features . . .
<br><br>
</div>
</div>
<div class="wr-input-control wr-btn-grp">
<a href="javascript:void(0)" class="wr-btn wizard-stepper" data-is-back-btn="true" data-current="policy-profile" data-next="policy-platform">Back</a>
<a href="javascript:void(0)" class="wr-btn wizard-stepper" data-current="policy-profile" data-next="policy-criteria" data-validate="true">Continue</a>
</div>
</div>
</div>
</div>
</div>

@ -18,7 +18,7 @@
function onRequest(context){
var viewModel = {};
var devicemgtProps = require("/app/conf/reader/main.js")["conf"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
viewModel.hostName = devicemgtProps["httpsURL"];
return viewModel;
}

@ -1,5 +1,5 @@
{
"appName": "Enterprise Mobility Manager",
"appName": "WSO2 Enterprise Mobility Manager",
"cachingEnabled": true,
"debuggingEnabled": false,
"permissionRoot": "/",

@ -1,6 +1,5 @@
{
"appContext": "/emm/",
"clientName": "emm",
"webAgentContext" : "/emm-web-agent/",
"apiContext": "api",
"httpsURL" : "%https.ip%",
@ -12,13 +11,23 @@
"enrollmentDir": "/emm-web-agent/enrollment",
"iOSConfigRoot" : "%https.ip%/ios-enrollment/",
"iOSAPIRoot" : "%https.ip%/ios/",
"dynamicClientRegistrationEndPoint" : "https://localhost:9443/dynamic-client-web/register/",
"adminService": "%https.ip%",
"idPServer":"%https.ip%/oauth2/token",
"callBackUrl":"%https.ip%/api/device-mgt/v1.0",
"adminUser":"admin@carbon.super",
"adminRole":"admin",
"usernameLength":30,
"oauthProvider": {
"appRegistration": {
"appType": "webapp",
"clientName": "emm",
"owner": "admin@carbon.super",
"dynamicClientAppRegistrationServiceURL": "%https.ip%/dynamic-client-web/register",
"apiManagerClientAppRegistrationServiceURL": "%https.ip%/api-application-registration/register/tenants",
"grantType": "password refresh_token urn:ietf:params:oauth:grant-type:saml2-bearer",
"tokenScope": "admin",
"callbackUrl": "%https.ip%/api/device-mgt/v1.0"
},
"tokenServiceURL": "%https.ip%/oauth2/token"
},
"adminUser": "admin@carbon.super",
"adminRole": "admin",
"usernameLength": 30,
"pageSize":10,
"ssoConfiguration" : {
"enabled" : false,
@ -52,7 +61,7 @@
"roleNameHelpMsg" : "should be in minimum 3 characters long and do not include any whitespaces."
},
"generalConfig" : {
"host" : "https://localhost:9443",
"host" : "%https.ip%",
"companyName" : "WSO2 Carbon Device Manager",
"browserTitle" : "WSO2 Device Manager",
"copyrightPrefix" : "\u00A9 %date-year%, ",
@ -61,17 +70,53 @@
"copyrightSuffix" : " All Rights Reserved."
},
"scopes" : [
"license-add", "license-view", "device-view",
"device-info", "device-list", "device-view-own", "device-modify", "device-search",
"operation-install", "operation-view", "operation-modify", "operation-uninstall",
"group-add", "group-share", "group-modify", "group-view", "group-remove",
"certificate-modify", "certificate-view",
"configuration-view", "configuration-modify",
"policy-view", "policy-modify",
"device-notification-view", "device-notification-modify",
"feature-view",
"roles-view", "roles-modify", "roles-remove", "roles-add",
"user-password-reset", "user-password-modify", "user-modify", "user-view", "user-invite", "user-remove", "user-add"
"user:manage",
"user:view",
"device-type:admin:view",
"device:view",
"notification:view",
"device:admin:view",
"application:manage",
"activity:view",
"user:admin:reset-password",
"policy:manage",
"policy:view",
"role:manage",
"role:view",
"configuration:view",
"configuration:modify",
"device:android:operation:reboot",
"device:android:operation:camera",
"device:android:operation:vpn",
"device:android:operation:lock",
"device:android:operation:ring",
"device:android:operation:update-app",
"device:android:operation:wipe",
"device:android:operation:encrypt",
"device:android:operation:blacklist-app",
"device:android:operation:applications",
"device:android:operation:enterprise-wipe",
"device:android:operation:info",
"device:android:operation:wifi",
"device:android:operation:uninstall-app",
"device:android:operation:change-lock",
"device:android:operation:notification",
"device:android:operation:upgrade",
"device:android:operation:unlock",
"device:android:operation:mute",
"device:android:operation:location",
"device:android:operation:webclip",
"device:android:operation:clear-password",
"device:android:operation:password-policy",
"device:android:operation:install-app",
"device:android:event:write",
"device:android:event:read",
"device:android:enroll",
"configuration:manage",
"configuration:view",
"device:android:enroll",
"certificate:view",
"certificate:manage"
],
"isOAuthEnabled" : true,
"backendRestEndpoints" : {

@ -48,7 +48,7 @@
View
</a>
{{#if permissions.ADD_POLICY}}
<a href="/emm/policies/add-policy">
<a href="/emm/policy/add">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
@ -79,7 +79,7 @@
View
</a>
{{#if permissions.ADD_USER}}
<a href="/emm/users/add-user">
<a href="/emm/user/add">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
@ -110,7 +110,7 @@
View
</a>
{{#if permissions.ADD_ROLE}}
<a href="/emm/roles/add-role">
<a href="/emm/role/add">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>

@ -17,12 +17,14 @@
*/
function onRequest(context) {
var userModule = require("/app/modules/user.js")["userModule"];
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var generalConfig = context.app.conf["generalConfig"];
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
context["permissions"] = userModule.getUIPermissions();
new Log().info("## Permissions : "+ stringify(userModule.getUIPermissions()));
context["enrollmentURL"] = generalConfig["host"] + generalConfig["enrollmentDir"];
return context;
var viewModel = {};
viewModel.permissions = userModule.getUIPermissions();
new Log().debug("## Permissions : " + stringify(userModule.getUIPermissions()));
//TODO: Move enrollment URL into app-conf.json
viewModel.enrollmentURL = mdmProps.generalConfig.host + mdmProps.enrollmentDir;
return viewModel;
}

@ -0,0 +1,44 @@
{{!
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.
}}
{{unit "cdmf.unit.ui.title" pageTitle="Device Details"}}
{{unit "cdmf.unit.lib.service-invoker-utility"}}
{{unit "cdmf.unit.lib.handlebars"}}
{{#zone "breadcrumbs"}}
<li>
<a href="{{@app.context}}/">
<i class="icon fw fw-home"></i>
</a>
</li>
<li>
<a href="{{@app.context}}/devices">
Devices
</a>
</li>
<li>
<a href="#">
Device Details
</a>
</li>
{{/zone}}
{{#zone "content"}}
{{unit "cdmf.unit.lib.data-table"}}
{{unit "cdmf.unit.device.operation-mod"}}
{{unit "cdmf.unit.device.view"}}
{{/zone}}

@ -0,0 +1,33 @@
/*
* 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.
*/
function onRequest(context){
var utility = require("/app/modules/utility.js").utility;
context.handlebars.registerHelper('equal', function (lvalue, rvalue, options) {
if (arguments.length < 3)
throw new Error("Handlebars Helper equal needs 2 parameters");
if( lvalue!=rvalue ) {
return options.inverse(this);
} else {
return options.fn(this);
}
});
var deviceType = context.uriParams.deviceType;
return {"deviceViewUnitName": utility.getTenantedDeviceUnitName(deviceType, "device-view")};
}

@ -0,0 +1,123 @@
{{!
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.
}}
{{unit "cdmf.unit.ui.title" pageTitle="Device Management"}}
{{unit "cdmf.unit.data-tables-extended"}}
{{#zone "breadcrumbs"}}
<li>
<a href="{{@app.context}}/">
<i class="icon fw fw-home"></i>
</a>
</li>
<li>
<a href="{{@app.context}}/devices">
Devices
</a>
</li>
{{/zone}}
{{#zone "navbarActions"}}
{{#if permissions.enroll}}
<li>
<a href="{{@app.context}}/device/enroll" class="cu-btn">
<span class="icon fw-stack">
<i class="fw fw-add fw-stack-1x"></i>
<i class="fw fw-ring fw-stack-2x"></i>
</span>
Enroll Device
</a>
</li>
{{/if}}
{{/zone}}
{{#zone "content"}}
<span id="permission" data-permission="{{permissions}}"></span>
<div id="loading-content" class="col-centered">
<i class="fw fw-settings fw-spin fw-2x"></i>
&nbsp;&nbsp;&nbsp;
Loading devices . . .
<br>
</div>
<div id="device-listing-status" class="raw hidden">
<ul style="list-style-type: none;">
<li class="message message-info" >
<h4>
<i class="icon fw fw-info"></i>
<a id="device-listing-status-msg"></a>
</h4>
</li>
</ul>
</div>
<div id="device-table">
<table class="table table-striped table-hover list-table display responsive nowrap data-table grid-view" id="device-grid">
<thead>
<tr class="sort-row">
<th class="no-sort"></th>
<th>By Device Name</th>
<th>By Owner</th>
<th>By Status</th>
<th>By Platform</th>
<th>By Ownership</th>
<th class="no-sort"></th>
</tr>
<tr class="filter-row filter-box">
<th class="no-sort"></th>
<th data-for="By Device Name"></th>
<th data-for="By Owner" class="text-filter"></th>
<th data-for="By Status" class="select-filter"></th>
<th data-for="By Platform" class="select-filter data-platform"></th>
<th data-for="By Ownership" class="select-filter"></th>
<th class="no-sort"></th>
</tr>
<tr class="bulk-action-row">
<th colspan="7">
<div id = "operation-bar">
{{unit "mdm.unit.device.operation-bar"}}
</div>
<div id="operation-guide" class="bs-callout bs-callout-info">
<h4>Enabling Device Operations</h4>
<p>To enable device operations, select the desired platform from above filter.</p>
</div>
</th>
</tr>
</thead>
<tbody id="ast-container">
<br class="c-both" />
</tbody>
</table>
</div>
<br class="c-both"/>
<div id="content-filter-types" style="display: none">
<div class="sort-title">Sort By</div>
<div class="sort-options">
<a href="#">By Device Name<span class="ico-sort-asc"></span></a>
<a href="#">By Owner</a>
<a href="#">By Status</a>
<a href="#">By Platform</a>
<a href="#">By Ownership</a>
</div>
</div>
{{/zone}}
{{#zone "bottomJs"}}
<script id="device-listing" data-current-user="{{currentUser.username}}" data-image-resource="{{self.publicURL}}/images/"
src="{{self.publicURL}}/templates/device-listing.hbs" type="text/x-handlebars-template" ></script>
{{js "js/device-listing.js"}}
{{/zone}}

@ -0,0 +1,40 @@
/*
* 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.
*/
function onRequest(context){
var userModule = require("/app/modules/business-controllers/user.js").userModule;
var constants = require("/app/modules/constants.js");
var viewModel = {};
var permissions = [];
if(userModule.isAuthorized("/permission/admin/device-mgt/emm-admin/devices/list")){
permissions.push("LIST_DEVICES");
if (userModule.isAuthorized("/permission/admin/device-mgt/emm-admin/devices/view")) {
permissions.push("VIEW_DEVICES");
}
}else if(userModule.isAuthorized("/permission/admin/device-mgt/user/devices/list")){
permissions.push("LIST_OWN_DEVICES");
if (userModule.isAuthorized("/permission/admin/device-mgt/user/devices/view")) {
permissions.push("VIEW_OWN_DEVICES");
}
}else if(userModule.isAuthorized("/permission/admin/device-mgt/emm-admin/policies/list")){
permissions.push("LIST_POLICIES");
}
var currentUser = session.get(constants.USER_SESSION_KEY);
viewModel.permissions = stringify(permissions);
viewModel.currentUser = currentUser;
return viewModel;
}

@ -0,0 +1,520 @@
/*
* Copyright (c) 2015, 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.
*/
/**
* Following function would execute
* when a user clicks on the list item
* initial mode and with out select mode.
*/
function InitiateViewOption(url) {
if ($(".select-enable-btn").text() == "Select") {
$(location).attr('href', url);
}
}
(function () {
var cache = {};
var permissionSet = {};
var validateAndReturn = function (value) {
return (value == undefined || value == null) ? "Unspecified" : value;
};
Handlebars.registerHelper("deviceMap", function (device) {
device.owner = validateAndReturn(device.owner);
device.ownership = validateAndReturn(device.ownership);
var arr = device.properties;
if (arr){
device.properties = arr.reduce(function (total, current) {
total[current.name] = validateAndReturn(current.value);
return total;
}, {});
}
});
//This method is used to setup permission for device listing
$.setPermission = function (permission) {
permissionSet[permission] = true;
};
$.hasPermission = function (permission) {
return permissionSet[permission];
};
})();
/*
* Setting-up global variables.
*/
var deviceCheckbox = "#ast-container .ctrl-wr-asset .itm-select input[type='checkbox']";
var assetContainer = "#ast-container";
/*
* DOM ready functions.
*/
$(document).ready(function () {
/* Adding selected class for selected devices */
$(deviceCheckbox).each(function () {
addDeviceSelectedClass(this);
});
var i;
var permissionList = $("#permission").data("permission");
for (i = 0; i < permissionList.length; i++) {
$.setPermission(permissionList[i]);
}
/* for device list sorting drop down */
$(".ctrl-filter-type-switcher").popover({
html : true,
content : function () {
return $("#content-filter-types").html();
}
});
$(".ast-container").on("click", ".claim-btn", function(e){
e.stopPropagation();
var deviceId = $(this).data("deviceid");
var deviceListing = $("#device-listing");
var currentUser = deviceListing.data("current-user");
var serviceURL = "/temp-controller-agent/enrollment/claim?username=" + currentUser;
var deviceIdentifier = {id: deviceId, type: "TemperatureController"};
invokerUtil.put(serviceURL, deviceIdentifier, function(message){
console.log(message);
}, function(message){
console.log(message.content);
});
});
});
/*
* On Select All Device button click function.
*
* @param button: Select All Device button
*/
function selectAllDevices(button) {
if(!$(button).data('select')){
$(deviceCheckbox).each(function(index){
$(this).prop('checked', true);
addDeviceSelectedClass(this);
});
$(button).data('select', true);
$(button).html('Deselect All Devices');
}else{
$(deviceCheckbox).each(function(index){
$(this).prop('checked', false);
addDeviceSelectedClass(this);
});
$(button).data('select', false);
$(button).html('Select All Devices');
}
}
/*
* On listing layout toggle buttons click function.
*
* @param view: Selected view type
* @param selection: Selection button
*/
function changeDeviceView(view, selection) {
$(".view-toggle").each(function() {
$(this).removeClass("selected");
});
$(selection).addClass("selected");
if (view == "list") {
$(assetContainer).addClass("list-view");
} else {
$(assetContainer).removeClass("list-view");
}
}
/*
* Add selected style class to the parent element function.
*
* @param checkbox: Selected checkbox
*/
function addDeviceSelectedClass(checkbox) {
if ($(checkbox).is(":checked")) {
$(checkbox).closest(".ctrl-wr-asset").addClass("selected device-select");
} else {
$(checkbox).closest(".ctrl-wr-asset").removeClass("selected device-select");
}
}
function toTitleCase(str) {
return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}
function loadDevices(searchType, searchParam){
var deviceListing = $("#device-listing");
var currentUser = deviceListing.data("currentUser");
var serviceURL;
if ($.hasPermission("LIST_DEVICES")) {
//serviceURL = "/mdm-admin/devices";
serviceURL = "/api/device-mgt/v1.0/devices";
} else if ($.hasPermission("LIST_OWN_DEVICES")) {
//Get authenticated users devices
serviceURL = "/api/device-mgt/v1.0/devices?user="+currentUser;
//serviceURL = "/mdm-admin/users/devices?username="+currentUser;
} else {
$("#loading-content").remove();
$('#device-table').addClass('hidden');
$('#device-listing-status-msg').text('Permission denied.');
$("#device-listing-status").removeClass(' hidden');
return;
}
function getPropertyValue(deviceProperties, propertyName) {
var property;
for (var i =0; i < deviceProperties.length; i++) {
property = deviceProperties[i];
if (property.name == propertyName) {
return property.value;
}
}
return {};
}
var fnCreatedRow = function( nRow, aData, iDataIndex ) {
$(nRow).attr('data-type', 'selectable');
$(nRow).attr('data-deviceid', aData.deviceIdentifier);
$(nRow).attr('data-devicetype', aData.deviceType);
}
var columns = [
{
class : 'remove-padding icon-only content-fill viewEnabledIcon',
data : 'icon',
render: function (data, type, row, meta) {
var deviceType = row.deviceType;
var deviceIdentifier = row.deviceIdentifier;
var url = "#";
if (status != 'REMOVED') {
url = "device/" + deviceType + "?id=" + deviceIdentifier;
}
return '<div onclick="javascript:InitiateViewOption(\'' + url + '\')" class="thumbnail icon"><i class="square-element text fw fw-mobile"></i></div>'
}
},{
class: 'fade-edge',
data: 'name',
render: function ( name, type, row, meta ) {
var model = row.model;
var vendor = row.vendor;
var html = '<h4>Device ' + name + '</h4>';
if (model) {
html += '<div>(' + vendor + '-' + model + ')</div>';
}
return html;
}
},{
class: 'fade-edge remove-padding-top',
data: 'user',
render: function ( user, type, row, meta ) {
return '<div><label class="label-bold">Owner</label>' + user + '</div>';
}
},{
class: 'fade-edge remove-padding-top',
data: 'status',
render: function ( status, type, row, meta ) {
var html;
switch (status) {
case 'ACTIVE' :
html = '<span><i class="fw fw-ok icon-success"></i> Active</span>';
break;
case 'INACTIVE' :
html = '<span><i class="fw fw-warning icon-warning"></i> Inactive</span>';
break;
case 'BLOCKED' :
html = '<span><i class="fw fw-remove icon-danger"></i> Blocked</span>';
break;
case 'REMOVED' :
html = '<span><i class="fw fw-delete icon-danger"></i> Removed</span>';
break;
}
return '<div><label class="label-bold">Status</label>'+html+'</div>';
}
},{
className: 'fade-edge remove-padding-top',
data: 'deviceType',
render: function ( deviceType, type, row, meta ) {
return '<div><label class="label-bold">Type</label>' + deviceType + '</div>';
}
},{
className: 'fade-edge remove-padding-top',
data: 'ownership',
render: function ( ownership, type, row, meta ) {
return '<div><label class="label-bold">Ownership</label>' + ownership + '</div>';
}
}
];
var dataFilter = function(data){
data = JSON.parse(data);
var objects = [];
$(data.devices).each(function( index ) {
objects.push(
{
model: getPropertyValue(data.devices[index].properties, 'DEVICE_MODEL'),
vendor: getPropertyValue(data.devices[index].properties, 'VENDOR'),
owner: data.devices[index].enrolmentInfo.owner,
status: data.devices[index].enrolmentInfo.status,
ownership: data.devices[index].enrolmentInfo.ownership,
deviceType: data.devices[index].type,
deviceIdentifier: data.devices[index].deviceIdentifier,
name : data.devices[index].name
}
);
});
json = {
"recordsTotal": data.count,
"recordsFiltered": data.count,
"data": objects
};
return JSON.stringify( json );
};
$('#device-grid').datatables_extended_serverside_paging(null, '/api/device-mgt/v1.0/devices', dataFilter, columns, fnCreatedRow,
function( oSettings ) {
$(".icon .text").res_text(0.2);
$('#device-grid').removeClass('hidden');
$("#loading-content").remove();
}, {
"placeholder": "Search By Device Name",
"searchKey" : "name"
});
// $('#device-grid').datatables_extended({
// serverSide: true,
// processing: false,
// searching: true,
// ordering: false,
// filter: false,
// pageLength : 16,
// ajax: { url : '/emm/api/devices', data : {url : serviceURL},
// dataSrc: function (json) {
// $('#device-grid').removeClass('hidden');
// $("#loading-content").remove();
// var $list = $("#device-table :input[type='search']");
// $list.each(function(){
// $(this).addClass("hidden");
// });
// return json.devices;
// }
// },
// columnDefs: [
// { targets: 0, data: 'name', className: 'remove-padding icon-only content-fill viewEnabledIcon' , render: function ( data, type, row, meta ) {
// var deviceType = row.type;
// var deviceIdentifier = row.deviceIdentifier;
// var url = "#";
// if (status != 'REMOVED') {
// url = "devices/view?type=" + deviceType + "&id=" + deviceIdentifier;
// }
// return '<div onclick="javascript:InitiateViewOption(\'' + url + '\')" class="thumbnail icon"><i class="square-element text fw fw-mobile"></i></div>';
// }},
// { targets: 1, data: 'name', className: 'fade-edge' , render: function ( name, type, row, meta ) {
// var model = getPropertyValue(row.properties, 'DEVICE_MODEL');
// var vendor = getPropertyValue(row.properties, 'VENDOR');
// var html = '<h4>Device ' + name + '</h4>';
// if (model) {
// html += '<div>(' + vendor + '-' + model + ')</div>';
// }
// return html;
// }},
// { targets: 2, data: 'enrolmentInfo.owner', className: 'fade-edge remove-padding-top'},
// { targets: 3, data: 'enrolmentInfo.status', className: 'fade-edge remove-padding-top' ,
// render: function ( status, type, row, meta ) {
// var html;
// switch (status) {
// case 'ACTIVE' :
// html = '<span><i class="fw fw-ok icon-success"></i> Active</span>';
// break;
// case 'INACTIVE' :
// html = '<span><i class="fw fw-warning icon-warning"></i> Inactive</span>';
// break;
// case 'BLOCKED' :
// html = '<span><i class="fw fw-remove icon-danger"></i> Blocked</span>';
// break;
// case 'REMOVED' :
// html = '<span><i class="fw fw-delete icon-danger"></i> Removed</span>';
// break;
// }
// return html;
// }},
// { targets: 4, data: 'type' , className: 'fade-edge remove-padding-top' },
// { targets: 5, data: 'enrolmentInfo.ownership' , className: 'fade-edge remove-padding-top' },
// { targets: 6, data: 'enrolmentInfo.status' , className: 'text-right content-fill text-left-on-grid-view no-wrap' ,
// render: function ( status, type, row, meta ) {
// var deviceType = row.type;
// var deviceIdentifier = row.deviceIdentifier;
// var html = '<span></span>';
// return html;
// }}
// ],
// "createdRow": function( row, data, dataIndex ) {
// $(row).attr('data-type', 'selectable');
// $(row).attr('data-deviceid', data.deviceIdentifier);
// $(row).attr('data-devicetype', data.type);
// var model = getPropertyValue(data.properties, 'DEVICE_MODEL');
// var vendor = getPropertyValue(data.properties, 'VENDOR');
// var owner = data.enrolmentInfo.owner;
// var status = data.enrolmentInfo.status;
// var ownership = data.enrolmentInfo.ownership;
// var deviceType = data.type;
// $.each($('td', row), function (colIndex) {
// switch(colIndex) {
// case 1:
// $(this).attr('data-search', model + ',' + vendor);
// $(this).attr('data-display', model);
// break;
// case 2:
// $(this).attr('data-grid-label', "Owner");
// $(this).attr('data-search', owner);
// $(this).attr('data-display', owner);
// break;
// case 3:
// $(this).attr('data-grid-label', "Status");
// $(this).attr('data-search', status);
// $(this).attr('data-display', status);
// break;
// case 4:
// $(this).attr('data-grid-label', "Type");
// $(this).attr('data-search', deviceType);
// $(this).attr('data-display', deviceType);
// break;
// case 5:
// $(this).attr('data-grid-label', "Ownership");
// $(this).attr('data-search', ownership);
// $(this).attr('data-display', ownership);
// break;
// }
// });
// },
// "fnDrawCallback": function( oSettings ) {
// $(".icon .text").res_text(0.2);
// }
// });
$(deviceCheckbox).click(function () {
addDeviceSelectedClass(this);
});
}
/*
* Setting-up global variables.
*/
var deviceCheckbox = "#ast-container .ctrl-wr-asset .itm-select input[type='checkbox']";
var assetContainer = "#ast-container";
function openCollapsedNav(){
$('.wr-hidden-nav-toggle-btn').addClass('active');
$('#hiddenNav').slideToggle('slideDown', function(){
if($(this).css('display') == 'none'){
$('.wr-hidden-nav-toggle-btn').removeClass('active');
}
});
}
function initPage() {
var currentUser = $("#device-listing").data("currentUser");
var serviceURL;
if ($.hasPermission("LIST_DEVICES")) {
serviceURL ="/api/device-mgt/v1.0/devices"
} else if ($.hasPermission("LIST_OWN_DEVICES")) {
//Get authenticated users devices
serviceURL = "/api/device-mgt/v1.0/devices?user=" + currentUser;
}
invokerUtil.get(
serviceURL,
function (data) {
if (data) {
data = JSON.parse(data);
if (data.devices.length > 0) {
loadDevices();
} else {
$("#loading-content").remove();
$("#device-listing-status-msg").text("No enrolled device is found.");
$("#device-listing-status").removeClass(' hidden');
}
}
}, function (message) {
initPage();
}
);
}
/*
* DOM ready functions.
*/
$(document).ready(function () {
initPage();
/* Adding selected class for selected devices */
$(deviceCheckbox).each(function () {
addDeviceSelectedClass(this);
});
var i;
var permissionList = $("#permission").data("permission");
for (i = 0; i < permissionList.length; i++) {
$.setPermission(permissionList[i]);
}
/* for device list sorting drop down */
$(".ctrl-filter-type-switcher").popover({
html : true,
content : function () {
return $("#content-filter-types").html();
}
});
$(".ast-container").on("click", ".claim-btn", function(e){
e.stopPropagation();
var deviceId = $(this).data("deviceid");
var deviceListing = $("#device-listing");
var currentUser = deviceListing.data("current-user");
var serviceURL = "/temp-controller-agent/enrollment/claim?username=" + currentUser;
var deviceIdentifier = {id: deviceId, type: "TemperatureController"};
invokerUtil.put(serviceURL, deviceIdentifier, function(message){
console.log(message);
}, function(message){
console.log(message.content);
});
});
/* for data tables*/
$('[data-toggle="tooltip"]').tooltip();
$("[data-toggle=popover]").popover();
$(".ctrl-filter-type-switcher").popover({
html : true,
content: function() {
return $('#content-filter-types').html();
}
});
$('#nav').affix({
offset: {
top: $('header').height()
}
});
});

@ -0,0 +1,42 @@
{{#each devices}}
{{deviceMap this}}
<tr data-type="selectable" data-deviceid="{{deviceIdentifier}}" data-devicetype="{{type}}">
<td class="remove-padding icon-only content-fill viewEnabledIcon"
{{#unequal enrolmentInfo.status "REMOVED"}}
data-url="device?type={{type}}&id={{deviceIdentifier}}"
{{/unequal}}
>
<div class="thumbnail icon">
<i class="square-element text fw fw-mobile"></i>
</div>
</td>
<td class="fade-edge" data-search="{{properties.DEVICE_MODEL}},{{properties.VENDOR}}" data-display="{{properties.DEVICE_MODEL}}">
<h4>Device {{name}}</h4>
{{#if properties.DEVICE_MODEL}}
<div>({{properties.VENDOR}} - {{properties.DEVICE_MODEL}})</div>
{{/if}}
</td>
<td class="fade-edge remove-padding-top" data-search="{{enrolmentInfo.owner}}" data-display="{{enrolmentInfo.owner}}" data-grid-label="Owner">{{enrolmentInfo.owner}}</td>
<td class="fade-edge remove-padding-top" data-search="{{enrolmentInfo.status}}" data-display="{{enrolmentInfo.status}}" data-grid-label="Status">
{{#equal enrolmentInfo.status "ACTIVE"}}<span><i class="fw fw-ok icon-success"></i> Active</span>{{/equal}}
{{#equal enrolmentInfo.status "INACTIVE"}}<span><i class="fw fw-warning icon-warning"></i> Inactive</span>{{/equal}}
{{#equal enrolmentInfo.status "BLOCKED"}}<span><i class="fw fw-remove icon-danger"></i> Blocked</span>{{/equal}}
{{#equal enrolmentInfo.status "REMOVED"}}<span><i class="fw fw-delete icon-danger"></i> Removed</span>{{/equal}}
</td>
<td class="fade-edge remove-padding-top" data-search="{{type}}" data-display="{{type}}" data-grid-label="Type">{{type}}</td>
<td class="fade-edge remove-padding-top" data-search="{{enrolmentInfo.ownership}}" data-display="{{enrolmentInfo.ownership}}" data-grid-label="Ownership">{{enrolmentInfo.ownership}}</td>
<td class="text-right content-fill text-left-on-grid-view no-wrap">
<!--{{#equal type "TemperatureController"}}
{{#equal status "INACTIVE"}}
<a href="#" data-click-event="remove-form" class="btn padding-reduce-on-grid-view claim-btn" data-deviceid="{{deviceIdentifier}}">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-edit fw-stack-1x"></i>
</span>
<span class="hidden-xs hidden-on-grid-view">Claim</span>
</a>
{{/equal}}
{{/equal}}-->
</td>
</tr>
{{/each}}

@ -0,0 +1,643 @@
{{!
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.
}}
{{unit "cdmf.unit.ui.title" pageTitle="Policy Management"}}
{{unit "cdmf.unit.data-tables-extended"}}
{{#zone "topCss"}}
<style>
.thumbnail.icon:before {
padding-top: 0;
}
</style>
{{/zone}}
{{#zone "breadcrumbs"}}
<li>
<a href="{{@app.context}}/">
<i class="icon fw fw-home"></i>
</a>
</li>
<li>
<a href="{{@app.context}}/policies">
Policies
</a>
</li>
{{/zone}}
{{#zone "navbarActions"}}
{{#if permissions.ADD_ADMIN_POLICY}}
<li>
<a href="{{@app.context}}/policy/add" class="cu-btn">
<span class="icon fw-stack">
<i class="fw fw-add fw-stack-1x"></i>
<i class="fw fw-ring fw-stack-2x"></i>
</span>
Add Policy
</a>
</li>
{{/if}}
{{#if permissions.CHANGE_POLICY_PRIORITY}}
{{#equal noPolicy false}}
<li>
<a href="{{@app.context}}/policy/priority" class="cu-btn">
<span class="icon fw-stack">
<i class="fw fw-throttling-policy fw-stack-1x"></i>
<i class="fw fw-ring fw-stack-2x"></i>
</span>
Policy Priority
</a>
</li>
{{/equal}}
{{/if}}
<li>
<a href="#" class="cu-btn" id="appbar-btn-apply-changes">
<span class="icon fw-stack">
<i class="fw fw-check fw-stack-1x"></i>
<i class="fw fw-ring fw-stack-2x"></i>
</span>
Apply Changes To Devices
</a>
</li>
{{/zone}}
{{#zone "content"}}
{{#equal isUpdated true}}
<input type="hidden" id="is-updated" value="UPDATED">
{{/equal}}
{{#equal noPolicy true}}
<div id="ast-container" class="ast-container list-view">
<div class="ctrl-info-panel col-centered text-center wr-login">
<h2>You don't have any policy at the moment.</h2>
<br/>
{{#if permissions.ADD_ADMIN_POLICY}}
<p class="text-center">
<a href="{{@app.context}}/policy/add" class="wr-btn">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
Add New Policy
</a>
</p>
{{/if}}
</div>
</div>
{{/equal}}
{{#equal noPolicy false}}
<div id="loading-content" class="col-centered">
<i class="fw fw-settings fw-spin fw-2x"></i>
Loading policies . . .
<br>
</div>
<table class="table table-striped table-hover list-table display responsive nowrap data-table grid-view hidden"
id="policy-grid">
<thead>
<tr class="sort-row">
<th class="no-sort"></th>
<th class="no-sort"></th>
<th>By Platform</th>
<th>By Ownership Type</th>
<th>By Role</th>
<th>By User</th>
<th>By Compliance Type</th>
<th>By Status</th>
<th class="no-sort"></th>
</tr>
<tr class="filter-row filter-box">
<th class="no-sort"></th>
<th class="no-sort"></th>
<th data-for="By Platform" class="select-filter"></th>
<th data-for="By Ownership Type" class="select-filter"></th>
<th data-for="By Role" class="text-filter"></th>
<th data-for="By User" class="text-filter"></th>
<th data-for="By Compliance Type" class="select-filter"></th>
<th data-for="By Status" class="select-filter"></th>
<th class="no-sort"></th>
</tr>
<tr class="bulk-action-row">
<th colspan="9">
<ul class="tiles">
{{#if removePermitted}}
<li class="square">
<a href="#" data-click-event="remove-form" class="btn square-element policy-remove-link"
data-toggle="modal" data-target="#modalDemo">
<span class="icon fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-delete fw-stack-1x"></i>
</span>
Remove
</a>
</li>
{{/if}}
<li class="square">
<a href="#" data-click-event="remove-form" class="btn square-element policy-publish-link"
data-toggle="modal" data-target="#modalDemo">
<span class="icon fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="glyphicon glyphicon-floppy-saved"></i>
</span>
Publish
</a>
</li>
<li class="square">
<a href="#" data-click-event="remove-form" class="btn square-element policy-unpublish-link"
data-toggle="modal" data-target="#modalDemo">
<span class="icon fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="glyphicon glyphicon-floppy-remove"></i>
</span>
Unpublish
</a>
</li>
</ul>
</th>
</tr>
</thead>
<tbody>
{{#each policyListToView}}
<tr data-type="selectable" data-id="{{id}}" data-status="{{status}}">
<td class="remove-padding icon-only content-fill viewEnabledIcon"
data-url="{{@app.context}}/policy/view?id={{id}}" data-id="{{id}}">
<div class="thumbnail icon">
<img src="{{icon}}"/>
</div>
</td>
<td class="fade-edge"
data-search="{{name}}"
data-display="{{name}}">
<h4>{{name}}</h4>
<div>({{platform}})</div>
{{#equal status "Active/Updated"}}
<span><i class="fw fw-warning icon-success"></i> Active/Updated</span>
{{/equal}}
{{#equal status "Active"}}
<span><i class="fw fw-ok icon-success"></i> Active</span>
{{/equal}}
{{#equal status "Inactive/Updated"}}
<span><i class="fw fw-warning icon-warning"></i> Inactive/Updated</span>
{{/equal}}
{{#equal status "Inactive"}}
<span><i class="fw fw-error icon-danger"></i> Inactive</span>
{{/equal}}
</td>
<td class="fade-edge remove-padding-top"
data-search="{{platform}}"
data-display="{{platform}}">
</td>
<td class="fade-edge remove-padding-top"
data-search="{{ownershipType}}"
data-display="{{ownershipType}}"
data-grid-label="Ownership">
{{ownershipType}}
</td>
<td id="policy-roles" class="fade-edge remove-padding-top"
data-search="{{roles}}"
data-display="{{roles}}"
data-grid-label="Role(s)">
{{roles}}
</td>
<td id="policy-users" class="fade-edge remove-padding-top"
data-search="{{users}}"
data-display="{{users}}"
data-grid-label="User(s)">
{{users}}
</td>
<td class="fade-edge remove-padding-top"
data-search="{{compliance}}"
data-display="{{compliance}}"
data-grid-label="Compliance">
{{compliance}}
</td>
<td id="policy-status" class="fade-edge remove-padding-top"
data-search="{{status}}"
data-display="{{status}}">
</td>
<td class="text-right content-fill text-left-on-grid-view no-wrap">
<a href="{{@app.context}}/policy/edit?id={{id}}"
data-id="{{id}}"
data-click-event="remove-form"
class="btn padding-reduce-on-grid-view policy-update-link">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-edit fw-stack-1x"></i>
</span>
<span class="hidden-xs hidden-on-grid-view">Re-Configure</span>
</a>
</td>
</tr>
{{/each}}
<br class="c-both"/>
</tbody>
</table>
{{/equal}}
<br class="c-both"/>
<div id="content-filter-types" style="display: none">
<div class="sort-title">Sort By</div>
<div class="sort-options">
<a href="#">By Platform<span class="ico-sort-asc"></span></a>
<a href="#">By Ownership Type</a>
<a href="#">By Role</a>
<a href="#">By User</a>
<a href="#">By Compliance Type</a>
<a href="#">By Status</a>
</div>
</div>
<div id="remove-policy-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Do you really want to remove the selected policy(s)?</h3>
<div class="buttons">
<a href="#" id="remove-policy-yes-link" class="btn-operations">
Remove
</a>
<a href="#" id="remove-policy-cancel-link" class="btn-operations">
Cancel
</a>
</div>
</div>
</div>
</div>
</div>
<div id="remove-policy-success-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Done. Selected policy was successfully removed.</h3>
<div class="buttons">
<a href="#" id="remove-policy-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="remove-policy-error-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>An unexpected error occurred. Please try again later.</h3>
<div class="buttons">
<a href="#" id="remove-policy-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="remove-active-policy-error-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
You cannot remove policies that have been already applied to devices.
Please deselect active policies from your selection and try again.
</h3>
<div class="buttons">
<a href="#" id="remove-active-policy-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="publish-policy-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Do you really want to publish the selected policy(s)?</h3>
<div class="buttons">
<a href="#" id="publish-policy-yes-link" class="btn-operations">Yes</a>
<a href="#" id="publish-policy-cancel-link" class="btn-operations">No</a>
</div>
</div>
</div>
</div>
</div>
<div id="publish-policy-success-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Done. Selected policy was successfully published.</h3>
<div class="buttons">
<a href="#" id="publish-policy-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="publish-policy-error-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>An unexpected error occurred. Please try again later.</h3>
<div class="buttons">
<a href="#" id="publish-policy-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="unpublish-policy-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Do you really want to unpublish the selected policy(s)?</h3>
<div class="buttons">
<a href="#" id="unpublish-policy-yes-link" class="btn-operations">
Yes
</a>
<a href="#" id="unpublish-policy-cancel-link" class="btn-operations">
No
</a>
</div>
</div>
</div>
</div>
</div>
<div id="unpublish-policy-success-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Done. Selected policy was successfully unpublished.</h3>
<div class="buttons">
<a href="#" id="unpublish-policy-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="unpublish-policy-error-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>An unexpected error occurred. Please try again later.</h3>
<div class="buttons">
<a href="#" id="unpublish-policy-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="save-policy-priorities-success-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Done. New Policy priorities were successfully updated.</h3>
<div class="buttons">
<a href="#" id="save-policy-priorities-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="save-policy-priorities-error-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>An unexpected error occurred. Please try again later.</h3>
<h4 class="message-from-server"></h4>
<div class="buttons">
<a href="#" id="save-policy-priorities-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="change-policy-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Do you really want to apply changes to all policies?</h3>
<div class="buttons">
<a href="#" id="change-policy-yes-link" class="btn-operations">
Yes
</a>
<a href="#" id="change-policy-cancel-link" class="btn-operations">
No
</a>
</div>
</div>
</div>
</div>
</div>
<div id="change-policy-success-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Done. Changes applied successfully.</h3>
<div class="buttons">
<a href="#" id="change-policy-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="change-policy-error-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>An unexpected error occurred. Please try again later.</h3>
<div class="buttons">
<a href="#" id="change-policy-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="errorPolicyUnPublish" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Action cannot be performed !
</h3>
<h4>
Please select a policy or a list of policies to un-publish.
</h4>
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="errorPolicyUnPublishSelection" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Action cannot be performed !
</h3>
<h4>
You cannot select already inactive policies to be unpublished.
Please deselect inactive policies and try again.
</h4>
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="active-policy-selection-error" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Action cannot be performed !
</h3>
<h4>
You cannot select already active policies. Please deselect active policies and try again.
</h4>
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="policy-publish-error" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Action cannot be performed !
</h3>
<h4>
Please select a policy or a list of policies to publish.
</h4>
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
<div id="policy-remove-error" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Action cannot be performed !
</h3>
<h4>
Please select a policy or a list of policies to remove.
</h4>
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
</div>
</div>
{{/zone}}
{{#zone "bottomJs"}}
{{js "js/policy-list.js"}}
{{/zone}}

@ -0,0 +1,59 @@
/*
* 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.
*/
function onRequest(context) {
context.handlebars.registerHelper('equal', function (lvalue, rvalue, options) {
if (arguments.length < 3) {
throw new Error("Handlebars Helper equal needs 2 parameters");
}
if (lvalue != rvalue) {
return options.inverse(this);
} else {
return options.fn(this);
}
});
var page = {};
var policyModule = require("/app/modules/business-controllers/policy.js")["policyModule"];
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var response = policyModule.getAllPolicies();
if (response["status"] == "success") {
var policyListToView = response["content"];
page["policyListToView"] = policyListToView;
var policyCount = policyListToView.length;
if (policyCount == 0) {
page["policyListingStatusMsg"] = "No policy is available to be displayed.";
page["noPolicy"] = true;
} else {
page["noPolicy"] = false;
page["isUpdated"] = response["updated"];
}
} else {
// here, response["status"] == "error"
page["policyListingStatusMsg"] = "An unexpected error occurred. Please try again later.";
page["noPolicy"] = true;
}
if (userModule.isAuthorized("/permission/admin/device-mgt/policies/remove")) {
page["removePermitted"] = true;
}
if (userModule.isAuthorized("/permission/admin/device-mgt/policies/update")) {
page["editPermitted"] = true;
}
page.permissions = userModule.getUIPermissions();
return page;
}

@ -0,0 +1,6 @@
{
"version": "1.0.0",
"uri": "/policies",
"extends": "cdmf.page.policies",
"layout": "cdmf.layout.default"
}

@ -0,0 +1,361 @@
/*
* Copyright (c) 2015, 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.
*/
/* sorting function */
var sortUpdateBtn = "#sortUpdateBtn";
// var sortedIDs;
// var dataTableSelection = ".DTTT_selected";
$('#policy-grid').datatables_extended();
// $(".icon .text").res_text(0.2);
var saveNewPrioritiesButton = "#save-new-priorities-button";
var saveNewPrioritiesButtonEnabled = Boolean($(saveNewPrioritiesButton).data("enabled"));
if (saveNewPrioritiesButtonEnabled) {
$(saveNewPrioritiesButton).removeClass("hide");
}
/**
* Following function would execute
* when a user clicks on the list item
* initial mode and with out select mode.
*/
function InitiateViewOption() {
$(location).attr('href', $(this).data("url"));
}
//var addSortableIndexNumbers = function () {
// $(".wr-sortable .list-group-item").not(".ui-sortable-placeholder").each(function (i) {
// $(".wr-sort-index", this).html(i + 1);
// });
//};
//var sortElements = function () {
// addSortableIndexNumbers();
// var sortableElem = ".wr-sortable";
// $(sortableElem).sortable({
// beforeStop: function () {
// sortedIDs = $(this).sortable("toArray");
// addSortableIndexNumbers();
// $(sortUpdateBtn).prop("disabled", false);
// }
// });
// $(sortableElem).disableSelection();
//};
/**
* Modal related stuff are as follows.
*/
var modalPopup = ".wr-modalpopup";
var modalPopupContainer = modalPopup + " .modalpopup-container";
var modalPopupContent = modalPopup + " .modalpopup-content";
var body = "body";
/*
* set popup maximum height function.
*/
function setPopupMaxHeight() {
var maxHeight = "max-height";
var marginTop = "margin-top";
var body = "body";
$(modalPopupContent).css(maxHeight, ($(body).height() - ($(body).height() / 100 * 30)));
$(modalPopupContainer).css(marginTop, (-($(modalPopupContainer).height() / 2)));
}
/*
* show popup function.
*/
function showPopup() {
$(modalPopup).show();
setPopupMaxHeight();
}
/*
* hide popup function.
*/
function hidePopup() {
$(modalPopupContent).html('');
$(modalPopup).hide();
}
/*
* Function to get selected policies.
*/
function getSelectedPolicyStates() {
var policyList = [];
var thisTable = $(".DTTT_selected").closest('.dataTables_wrapper').find('.dataTable').dataTable();
thisTable.api().rows().every(function () {
if ($(this.node()).hasClass('DTTT_selected')) {
policyList.push($(thisTable.api().row(this).node()).data('status'));
}
});
return policyList;
}
/*
* Function to get selected policies.
*/
function getSelectedPolicies() {
var policyList = [];
var thisTable = $(".DTTT_selected").closest('.dataTables_wrapper').find('.dataTable').dataTable();
thisTable.api().rows().every(function () {
if ($(this.node()).hasClass('DTTT_selected')) {
policyList.push($(thisTable.api().row(this).node()).data('id'));
}
});
return policyList;
}
$(document).ready(function () {
// sortElements();
// var policyRoles = $("#policy-roles").text();
// var policyUsers = $("#policy-users").text();
//
// if (!policyRoles) {
// $("#policy-roles").hide();
// }
// if (!policyUsers) {
// $("#policy-users").hide();
// }
/**
* ********************************************
* Click functions related to Policy Listing
* ********************************************
*/
// [1] logic for running apply-changes-for-devices use-case
var applyChangesButtonId = "#appbar-btn-apply-changes";
var isUpdated = $("#is-updated").val();
if (!isUpdated) {
// if no updated policies found, hide button from app bar
$(applyChangesButtonId).addClass("hidden");
} else {
// if updated policies found, show button from app bar
$(applyChangesButtonId).removeClass("hidden");
}
// click-event function for applyChangesButton
$(applyChangesButtonId).click(function () {
var serviceURL = "/api/device-mgt/v1.0/policies/apply-changes";
$(modalPopupContent).html($('#change-policy-modal-content').html());
showPopup();
$("a#change-policy-yes-link").click(function () {
invokerUtil.put(
serviceURL,
null,
// on success
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200) {
$(modalPopupContent).html($('#change-policy-success-content').html());
showPopup();
$("a#change-policy-success-link").click(function () {
hidePopup();
location.reload();
});
}
},
// on error
function (jqXHR) {
console.log(stringify(jqXHR.data));
$(modalPopupContent).html($("#change-policy-error-content").html());
showPopup();
$("a#change-policy-error-link").click(function () {
hidePopup();
});
}
);
});
$("a#change-policy-cancel-link").click(function () {
hidePopup();
});
});
// [2] logic for un-publishing a selected set of Active, Active/Updated policies
$(".policy-unpublish-link").click(function () {
var policyList = getSelectedPolicies();
var statusList = getSelectedPolicyStates();
if (($.inArray("Inactive/Updated", statusList) > -1) || ($.inArray("Inactive", statusList) > -1)) {
// if policies found in Inactive or Inactive/Updated states with in the selection,
// pop-up an error saying
// "You cannot select already inactive policies. Please deselect inactive policies and try again."
$(modalPopupContent).html($("#errorPolicyUnPublishSelection").html());
showPopup();
} else {
var serviceURL = "/api/device-mgt/v1.0/policies/deactivate-policy";
if (policyList.length == 0) {
$(modalPopupContent).html($("#errorPolicyUnPublish").html());
} else {
$(modalPopupContent).html($("#unpublish-policy-modal-content").html());
}
showPopup();
// on-click function for policy un-publishing "yes" button
$("a#unpublish-policy-yes-link").click(function () {
invokerUtil.put(
serviceURL,
policyList,
// on success
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200 && data) {
$(modalPopupContent).html($("#unpublish-policy-success-content").html());
$("a#unpublish-policy-success-link").click(function () {
hidePopup();
location.reload();
});
}
},
// on error
function (jqXHR) {
console.log(stringify(jqXHR.data));
$(modalPopupContent).html($("#unpublish-policy-error-content").html());
$("a#unpublish-policy-error-link").click(function () {
hidePopup();
});
}
);
});
// on-click function for policy un-publishing "cancel" button
$("a#unpublish-policy-cancel-link").click(function () {
hidePopup();
});
}
});
// [3] logic for publishing a selected set of Inactive, Inactive/Updated policies
$(".policy-publish-link").click(function () {
var policyList = getSelectedPolicies();
var statusList = getSelectedPolicyStates();
if (($.inArray("Active/Updated", statusList) > -1) || ($.inArray("Active", statusList) > -1)) {
// if policies found in Active or Active/Updated states with in the selection,
// pop-up an error saying
// "You cannot select already active policies. Please deselect active policies and try again."
$(modalPopupContent).html($("#active-policy-selection-error").html());
showPopup();
} else {
var serviceURL = "/api/device-mgt/v1.0/policies/activate-policy";
if (policyList.length == 0) {
$(modalPopupContent).html($("#policy-publish-error").html());
} else {
$(modalPopupContent).html($("#publish-policy-modal-content").html());
}
showPopup();
// on-click function for policy removing "yes" button
$("a#publish-policy-yes-link").click(function () {
invokerUtil.put(
serviceURL,
policyList,
// on success
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200 && data) {
$(modalPopupContent).html($("#publish-policy-success-content").html());
$("a#publish-policy-success-link").click(function () {
hidePopup();
location.reload();
});
}
},
// on error
function (jqXHR) {
console.log(stringify(jqXHR.data));
$(modalPopupContent).html($("#publish-policy-error-content").html());
$("a#publish-policy-error-link").click(function () {
hidePopup();
});
}
);
});
// on-click function for policy removing "cancel" button
$("a#publish-policy-cancel-link").click(function () {
hidePopup();
});
}
});
// [4] logic for removing a selected set of policies
$(".policy-remove-link").click(function () {
var policyList = getSelectedPolicies();
var statusList = getSelectedPolicyStates();
if (($.inArray("Active/Updated", statusList) > -1) || ($.inArray("Active", statusList) > -1)) {
// if policies found in Active or Active/Updated states with in the selection,
// pop-up an error saying
// "You cannot remove already active policies. Please deselect active policies and try again."
$(modalPopupContent).html($("#active-policy-selection-error").html());
showPopup();
} else {
var serviceURL = "/api/device-mgt/v1.0/policies/remove-policy";
if (policyList.length == 0) {
$(modalPopupContent).html($("#policy-remove-error").html());
} else {
$(modalPopupContent).html($("#remove-policy-modal-content").html());
}
showPopup();
// on-click function for policy removing "yes" button
$("a#remove-policy-yes-link").click(function () {
invokerUtil.post(
serviceURL,
policyList,
// on success
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200 && data) {
$(modalPopupContent).html($("#remove-policy-success-content").html());
$("a#remove-policy-success-link").click(function () {
hidePopup();
location.reload();
});
}
},
// on error
function (jqXHR) {
console.log(stringify(jqXHR.data));
$(modalPopupContent).html($("#remove-policy-error-content").html());
$("a#remove-policy-error-link").click(function () {
hidePopup();
});
}
);
});
// on-click function for policy removing "cancel" button
$("a#remove-policy-cancel-link").click(function () {
hidePopup();
});
}
});
$("#loading-content").remove();
if ($("#policy-listing-status-msg").text()) {
$("#policy-listing-status").removeClass("hidden");
}
$("#policy-grid").removeClass("hidden");
// $(".icon .text").res_text(0.2);
});

@ -15,10 +15,14 @@
specific language governing permissions and limitations
under the License.
}}
<div class="wr-operations" style="height: 87px;"></div>
{{#zone "content"}}
<div id = "operations-mod">
{{unit "mdm.unit.device.operation-mod"}}
</div>
{{/zone}}
{{#zone "bottomJs"}}
<script id="operations-bar" src="{{@unit.publicUri}}/templates/operations.hbs"
type="text/x-handlebars-template"></script>
{{js "js/operation-bar.js"}}
{{js "js/operation-bar.js"}}
{{/zone}}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* Copyright (c) 2015, 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
@ -103,13 +103,15 @@ function loadOperationBar(deviceType) {
var operationBar = $("#operations-bar");
var operationBarSrc = operationBar.attr("src");
var platformType = deviceType;
//var selectedDeviceID = deviceId;
$.template("operations-bar", operationBarSrc, function (template) {
var serviceURL = "/devicemgt_admin/features/" + platformType;
//var serviceURL = "/mdm-admin/features/" + platformType;
var serviceURL = "/api/device-mgt/v1.0/devices/"+platformType+"/*/features";
var successCallback = function (data) {
var viewModel = {};
data = JSON.parse(data).filter(function (current) {
var iconName;
switch (deviceType) {
switch(deviceType) {
case platformTypeConstants.ANDROID:
iconName = operationModule.getAndroidIconForFeature(current.code);
current.type = deviceType;
@ -140,6 +142,7 @@ function loadOperationBar(deviceType) {
function runOperation(operationName) {
var deviceIdList = getSelectedDeviceIds();
var list = getDevicesByTypes(deviceIdList);
console.log(list);
var successCallback = function (data) {
if (operationName == "NOTIFICATION") {
@ -157,7 +160,7 @@ function runOperation(operationName) {
var payload, serviceEndPoint;
if (list[platformTypeConstants.IOS]) {
payload = operationModule.
generatePayload(platformTypeConstants.IOS, operationName, list[platformTypeConstants.IOS]);
generatePayload(platformTypeConstants.IOS, operationName, list[platformTypeConstants.IOS]);
serviceEndPoint = operationModule.getIOSServiceEndpoint(operationName);
} else if (list[platformTypeConstants.ANDROID]) {
payload = operationModule
@ -165,14 +168,15 @@ function runOperation(operationName) {
serviceEndPoint = operationModule.getAndroidServiceEndpoint(operationName);
} else if (list[platformTypeConstants.WINDOWS]) {
payload = operationModule.
generatePayload(platformTypeConstants.WINDOWS, operationName, list[platformTypeConstants.WINDOWS]);
generatePayload(platformTypeConstants.WINDOWS, operationName, list[platformTypeConstants.WINDOWS]);
serviceEndPoint = operationModule.getWindowsServiceEndpoint(operationName);
}
if (operationName == "NOTIFICATION") {
var errorMsgWrapper = "#notification-error-msg";
var errorMsg = "#notification-error-msg span";
var message = $("#message").val();
if (!message) {
var messageTitle = $("#messageTitle").val();
var messageText = $("#messageText").val();
if (!(messageTitle && messageText)) {
$(errorMsg).text("Enter a message. It cannot be empty.");
$(errorMsgWrapper).removeClass("hidden");
} else {
@ -181,6 +185,7 @@ function runOperation(operationName) {
hidePopup();
}
} else {
console.log(serviceEndPoint);
invokerUtil.post(serviceEndPoint, payload, successCallback, errorCallback);
$(modalPopupContent).removeData();
hidePopup();

@ -0,0 +1,318 @@
/*
* Copyright (c) 2015, 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.
*/
var InitiateViewOption = null;
(function () {
var deviceId = $(".device-id");
var deviceIdentifier = deviceId.data("deviceid");
var deviceType = deviceId.data("type");
var payload = [deviceIdentifier];
var operationTable;
var serviceUrl;
if (deviceType == "ios") {
serviceUrl = "/ios/operation/deviceinfo";
} else if (deviceType == "android") {
//var serviceUrl = "/mdm-android-agent/operation/device-info";
serviceUrl = "/api/device-mgt/android/v1.0/admin/devices/info";
}
if (serviceUrl) {
invokerUtil.post(
serviceUrl,
payload,
// success-callback
function () {
$(".panel-body").show();
},
// error-callback
function () {
var defaultInnerHTML =
"<br><p class='fw-warning'>Device data may not have been updated. Please refresh to try again.<p>";
$(".panel-body").append(defaultInnerHTML);
}
);
}
$(".media.tab-responsive [data-toggle=tab]").on("shown.bs.tab", function (e) {
var activeTabPane = $(e.target).attr("href"),
activeCollapsePane = $(activeTabPane).find("[data-toggle=collapse]").data("target"),
activeCollapsePaneSiblings = $(activeTabPane).siblings().find("[data-toggle=collapse]").data("target"),
activeListGroupItem = $(".media .list-group-item.active");
$(activeCollapsePaneSiblings).collapse("hide");
$(activeCollapsePane).collapse("show");
positionArrow(activeListGroupItem);
$(".panel-heading .caret-updown").removeClass("fw-sort-down");
$(".panel-heading.collapsed .caret-updown").addClass("fw-sort-up");
});
$(".media.tab-responsive .tab-content").on("shown.bs.collapse", function (e) {
var activeTabPane = $(e.target).parent().attr("id");
$(".media.tab-responsive [data-toggle=tab][href=#" + activeTabPane + "]").tab("show");
$(".panel-heading .caret-updown").removeClass("fw-sort-up");
$(".panel-heading.collapsed .caret-updown").addClass("fw-sort-down");
});
function positionArrow(selectedTab) {
var selectedTabHeight = $(selectedTab).outerHeight();
var arrowPosition = 0;
var totalHeight = 0;
var arrow = $(".media .panel-group.tab-content .arrow-left");
var parentHeight = $(arrow).parent().outerHeight();
// if($(selectedTab).prev().length){
// $(selectedTab).prevAll().each(function() {
// totalHeight += $(this).outerHeight();
// });
// arrowPosition = totalHeight + (selectedTabHeight / 2);
// }else{
// arrowPosition = selectedTabHeight / 2;
// }
if(arrowPosition >= parentHeight){
parentHeight = arrowPosition + 10;
$(arrow).parent().height(parentHeight);
}else{
$(arrow).parent().removeAttr("style");
}
$(arrow).css("top", arrowPosition - 10);
}
$(document).ready(function() {
$(".device-detail-body").removeClass("hidden");
$("#loading-content").remove();
loadOperationBar(deviceType);
loadOperationsLog(false);
loadApplicationsList();
loadPolicyCompliance();
$("#refresh-policy").click(function () {
$("#policy-spinner").removeClass("hidden");
loadPolicyCompliance();
});
$("#refresh-apps").click(function () {
$("#apps-spinner").removeClass("hidden");
loadApplicationsList();
});
$("#refresh-operations").click(function () {
$("#operations-spinner").removeClass("hidden");
loadOperationsLog(true);
});
});
function loadOperationsLog(update) {
var operationsLogTable = "#operations-log-table";
if (update) {
operationTable = $(operationsLogTable).DataTable();
operationTable.ajax.reload(false);
return;
}
operationTable = $(operationsLogTable).datatables_extended({
serverSide: true,
processing: false,
searching: false,
ordering: false,
pageLength : 10,
order: [],
ajax: {
url: "/emm/api/operation/paginate",
data: {deviceId : deviceIdentifier, deviceType: deviceType},
dataSrc: function (json) {
$("#operations-spinner").addClass("hidden");
$("#operations-log-container").empty();
return json.data;
}
},
columnDefs: [
{targets: 0, data: "code" },
{targets: 1, data: "status", render:
function (status) {
var html;
switch (status) {
case "COMPLETED" :
html = "<span><i class='fw fw-ok icon-success'></i> Completed</span>";
break;
case "PENDING" :
html = "<span><i class='fw fw-warning icon-warning'></i> Pending</span>";
break;
case "ERROR" :
html = "<span><i class='fw fw-error icon-danger'></i> Error</span>";
break;
case "IN_PROGRESS" :
html = "<span><i class='fw fw-ok icon-warning'></i> In Progress</span>";
break;
case "REPEATED" :
html = "<span><i class='fw fw-ok icon-warning'></i> Repeated</span>";
break;
}
return html;
}
},
{targets: 2, data: "createdTimeStamp", render:
function (date) {
var value = String(date);
return value.slice(0, 16);
}
}
],
"createdRow": function(row, data) {
$(row).attr("data-type", "selectable");
$(row).attr("data-id", data["id"]);
$.each($("td", row),
function(colIndex) {
switch(colIndex) {
case 1:
$(this).attr("data-grid-label", "Code");
$(this).attr("data-display", data["code"]);
break;
case 2:
$(this).attr("data-grid-label", "Status");
$(this).attr("data-display", data["status"]);
break;
case 3:
$(this).attr("data-grid-label", "Created Timestamp");
$(this).attr("data-display", data["createdTimeStamp"]);
break;
}
}
);
}
});
}
function loadApplicationsList() {
var applicationsList = $("#applications-list");
var applicationListingTemplate = applicationsList.attr("src");
var deviceId = applicationsList.data("device-id");
var deviceType = applicationsList.data("device-type");
$.template("application-list", applicationListingTemplate, function (template) {
var serviceURL = "/api/device-mgt/v1.0/devices/" + deviceType + "/" + deviceId + "/applications";
invokerUtil.get(
serviceURL,
// success-callback
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200 && data) {
data = JSON.parse(data);
$("#apps-spinner").addClass("hidden");
if (data.length > 0) {
for (var i = 0; i < data.length; i++) {
data[i]["name"] = decodeURIComponent(data[i]["name"]);
data[i]["platform"] = deviceType;
}
var viewModel = {};
viewModel["applications"] = data;
viewModel["deviceType"] = deviceType;
var content = template(viewModel);
$("#applications-list-container").html(content);
} else {
$("#applications-list-container").
html("<div class='panel-body'><br><p class='fw-warning'>&nbsp;No applications found. " +
"please try refreshing the list in a while.<p></div>");
}
}
},
// error-callback
function () {
$("#applications-list-container").
html("<div class='panel-body'><br><p class='fw-warning'>&nbsp;Loading application list " +
"was not successful. please try refreshing the list in a while.<p></div>");
});
});
}
function loadPolicyCompliance() {
var policyCompliance = $("#policy-view");
var policyComplianceTemplate = policyCompliance.attr("src");
var deviceId = policyCompliance.data("device-id");
var deviceType = policyCompliance.data("device-type");
var activePolicy = null;
$.template(
"policy-view",
policyComplianceTemplate,
function (template) {
var getEffectivePolicyURL = "/api/device-mgt/v1.0/devices/" + deviceType + "/" + deviceId + "/effective-policy";
var getDeviceComplianceURL = "/api/device-mgt/v1.0/devices/" + deviceType + "/" + deviceId + "/compliance-data";
invokerUtil.get(
getEffectivePolicyURL,
// success-callback
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200 && data) {
data = JSON.parse(data);
$("#policy-spinner").addClass("hidden");
if (data["active"] == true) {
activePolicy = data;
invokerUtil.get(
getDeviceComplianceURL,
// success-callback
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200 && data) {
var viewModel = {};
viewModel["policy"] = activePolicy;
viewModel["deviceType"] = deviceType;
data = JSON.parse(data);
var content;
if (data["complianceData"]) {
if (data["complianceData"]["complianceFeatures"] &&
data["complianceData"]["complianceFeatures"].length > 0) {
viewModel["compliance"] = "NON-COMPLIANT";
viewModel["complianceFeatures"] = data["complianceData"]["complianceFeatures"];
content = template(viewModel);
$("#policy-list-container").html(content);
} else {
viewModel["compliance"] = "COMPLIANT";
content = template(viewModel);
$("#policy-list-container").html(content);
$("#policy-compliance-table").addClass("hidden");
}
} else {
$("#policy-list-container").
html("<div class='panel-body'><br><p class='fw-warning'> This device " +
"has no policy applied.<p></div>");
}
}
},
// error-callback
function () {
$("#policy-list-container").
html("<div class='panel-body'><br><p class='fw-warning'> Loading policy compliance related data " +
"was not successful. please try refreshing data in a while.<p></div>");
}
);
}
}
},
// error-callback
function () {
$("#policy-list-container").
html("<div class='panel-body'><br><p class='fw-warning'> Loading policy compliance related data " +
"was not successful. please try refreshing data in a while.<p></div>");
}
);
}
);
}
}());

@ -0,0 +1,54 @@
/*
* Copyright (c) 2015, 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.
*/
var map;
function loadLeafletMap() {
var deviceLocationID = "#device-location",
lat = $(deviceLocationID).data("lat"),
long = $(deviceLocationID).data("long"),
container = "device-location",
zoomLevel = 13,
tileSet = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
attribution = "&copy; <a href='https://openstreetmap.org/copyright'>OpenStreetMap</a> contributors";
if (lat && long) {
map = L.map(container).setView([lat, long], zoomLevel);
L.tileLayer(tileSet, {attribution: attribution}).addTo(map);
L.marker([lat, long]).addTo(map).bindPopup("Device is here...").openPopup();
$("#map-error").hide();
$("#device-location").show();
} else {
$("#device-location").hide();
$("#map-error").show();
}
}
$(document).ready(function () {
$("a[data-toggle='tab']").on("shown.bs.tab", function() {
var url = $(this).prop("href");
var hash = url.substring(url.indexOf("#") + 1);
if (hash == "device_location") {
if (!map) {
loadLeafletMap();
}
}
});
});

@ -0,0 +1,31 @@
<div class="wr-app-listing">
<div class="wr-applist">
{{#each applications}}
<a style="text-align: center; width: 110px; height: 140px;">
{{#equal platform "android"}}<i class="icon fw fw-android"></i>{{/equal}}
{{#equal platform "ios"}}<i class="icon fw fw-apple"></i>{{/equal}}
{{#equal platform "windows"}}<i class="icon fw fw-windows"></i>{{/equal}}
{{#equal isActive true}}
<span style="word-wrap: break-word;">
<i class="fw fw-ok icon-success" style="font-size: 14px;"></i>
&nbsp;Active
</span>
<span style="word-wrap: break-word;"><b>{{name}}</b></span>
<span style="word-wrap: break-word;"><b>V:{{version}}</b></span>
{{#if memoryUsage}}
<span style="word-wrap: break-word;">
Memory Usage
</span>
<span style="word-wrap: break-word;">
( {{memoryUsage}} Bytes )
</span>
{{/if}}
{{/equal}}
{{#equal isActive false}}
<span style="word-wrap: break-word;">{{name}}</span>
<span style="word-wrap: break-word;"><b>V:{{version}}</b></span>
{{/equal}}
</a>
{{/each}}
</div>
</div>

@ -0,0 +1,24 @@
<table class="table table-striped table-hover table-bordered display data-table" id="operations-log-table">
<thead>
<tr class="sort-row">
<th>Operation Code</th>
<th>Status</th>
<th>Request created at</th>
</tr>
</thead>
<tbody>
{{#each operations}}
<tr data-type="selectable" data-id="{{id}}">
<td data-display="{{code}}" data-grid-label="Code">{{code}}</td>
<td data-display="{{status}}" data-grid-label="Status">
{{#equal status "COMPLETED"}}<span><i class="fw fw-ok icon-success"></i> Completed</span>{{/equal}}
{{#equal status "PENDING"}}<span><i class="fw fw-warning icon-warning"></i> Pending</span>{{/equal}}
{{#equal status "ERROR"}}<span><i class="fw fw-error icon-danger"></i> Error</span>{{/equal}}
{{#equal status "IN_PROGRESS"}}<span><i class="fw fw-ok icon-warning"></i> In Progress</span>{{/equal}}
</td>
<td data-display="{{createdTimeStamp}}" data-grid-label="Created Timestamp">{{createdTimeStamp}}</td>
</tr>
{{/each}}
<br class="c-both" />
</tbody>
</table>

@ -0,0 +1,79 @@
<div class="wr-list-group wr-sortable policy-list">
<span class="list-group-item" id="{{id}}">
<div class="row">
<div class="col-lg-3 clearfix">
<span class="wr-list-icon">
{{#equal deviceType "android"}}
<i class=" fw fw-android"></i>
{{/equal}}
{{#equal deviceType "ios"}}
<i class=" fw fw-apple"></i>
{{/equal}}
{{#equal deviceType "windows"}}
<i class=" fw fw-windows"></i>
{{/equal}}
</span>
<span class="wr-list-desc">
<h3 class="wr-list-name">{{policy.policyName}}</h3>
<span class="wr-list-username">{{deviceType}}</span>
</span>
</div>
<div class="col-lg-6">
<div class="row no-gutter">
<div class="wr-desc-list-configs col-lg-4">
<div>
<b>Ownership Type : </b> {{policy.ownershipType}}
</div>
</div>
<div class="wr-desc-list-configs col-lg-4">
<div>
<b>Compliance Type :</b> {{policy.compliance}}
</div>
</div>
<div class="wr-desc-list-configs col-lg-4">
<div>
<b>Compliance :</b>
{{#equal compliance "COMPLIANT"}}
<span><i class="fw fw-ok icon-success"></i> Compliant</span>
{{/equal}}
{{#equal compliance "NON-COMPLIANT"}}
<span><i class="fw fw-warning icon-danger"></i> Not Compliant</span>
{{/equal}}
</div>
</div>
</div>
</div>
<div class="col-lg-3">
<span class="list-group-item-actions">
<a href="/emm/policies/view?id={{policy.id}}" class="cu-btn-inner policy-view-link" data-id="{{id}}">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-view fw-stack-1x"></i>
</span>
View
</a>
</span>
</div>
</div>
</span>
</div>
<table class="table table-striped table-hover table-bordered display data-table" id="policy-compliance-table">
<thead>
<tr class="sort-row">
<th>Feature</th>
<th>Compliance</th>
</tr>
</thead>
<tbody>
{{#each complianceFeatures}}
<tr data-type="selectable">
<td data-display="{{featureCode}}" data-grid-label="Feature Code">{{featureCode}}</td>
<td data-display="{{compliance}}" data-grid-label="Status">
{{#equal compliance true}}<span><i class="fw fw-ok icon-success"></i> Compliant</span>{{/equal}}
{{#equal compliance false}}<span><i class="fw fw-warning icon-danger"></i> Not Compliant</span>{{/equal}}
</td>
</tr>
{{/each}}
<br class="c-both" />
</tbody>
</table>

@ -0,0 +1,378 @@
{{#zone "content"}}
{{#defineZone "device-detail-top"}}
<div class="row wr-device-board">
<div class="col-lg-12 wr-secondary-bar">
<label class="device-id device-select" data-deviceid="{{device.deviceIdentifier}}"
data-type="{{device.type}}">
Device {{device.name}}
{{#if device.viewModel.model}}
<span class="lbl-device">
( {{device.viewModel.vendor}} {{device.viewModel.model}} )
</span>
{{/if}}
</label>
</div>
</div>
{{/defineZone}}
<div class="row no-gutter add-padding-5x add-margin-top-5x" style="border: 1px solid #e4e4e4;">
<div class="media">
<div class="media-left media-middle asset-image col-xs-2 col-sm-2 col-md-2 col-lg-2">
<div class="thumbnail icon"><i class="square-element text fw fw-mobile"></i></div>
</div>
<div class="media-body asset-desc add-padding-left-5x">
<div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">Device Overview</div>
{{#defineZone "device-detail-properties"}}
<table class="table table-responsive table-striped" id="members">
<tbody>
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px; width: 1%;">Device</td>
<td style="padding:10px 15px;">{{device.viewModel.vendor}} {{device.properties.model}}</td>
</tr>
{{#if device.viewModel.model}}
<tr role="row" class="odd">
<td class="sorting_1" style="padding:10px 15px;">Model</td>
<td style="padding:10px 15px;">{{device.viewModel.model}}</td>
</tr>
{{/if}}
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px;">IMEI</td>
<td style="padding:10px 15px;">{{device.viewModel.imei}}</td>
</tr>
{{#if device.viewModel.udid}}
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px;">UDID</td>
<td style="padding:10px 15px;">{{device.viewModel.udid}}</td>
</tr>
{{/if}}
{{#if device.viewModel.os_build_date}}
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px;">Firmware Build Date</td>
<td style="padding:10px 15px;">{{device.viewModel.os_build_date}}</td>
</tr>
{{/if}}
{{#if device.viewModel.phoneNumber}}
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px;">Phone Number</td>
<td style="padding:10px 15px;">{{device.viewModel.phoneNumber}}</td>
</tr>
{{/if}}
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px;">Status</td>
<td style="padding:10px 15px;">
{{#equal device.status "ACTIVE"}}<span><i class="fw fw-ok icon-success"></i>&nbsp;&nbsp;Active</span>{{/equal}}
{{#equal device.status "INACTIVE"}}<span><i class="fw fw-warning icon-warning"></i>&nbsp;&nbsp;Inactive</span>{{/equal}}
{{#equal device.status "BLOCKED"}}<span><i class="fw fw-remove icon-danger"></i>&nbsp;&nbsp;Blocked</span>{{/equal}}
{{#equal device.status "REMOVED"}}<span><i class="fw fw-delete icon-danger"></i>&nbsp;&nbsp;Removed</span>{{/equal}}
</td>
</tr>
</tbody>
</table>
{{/defineZone}}
<div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">Operations</div>
<div class="add-margin-top-4x">
{{unit "mdm.unit.device.operation-bar" deviceType=device.type}}
</div>
</div>
</div>
<div class="media tab-responsive">
<div class="media-left col-xs-1 col-sm-1 col-md-2 col-lg-2 hidden-xs">
<ul class="list-group nav nav-pills nav-stacked" role="tablist">
<li class="list-group-item active">
<a href="#device_details" role="tab" data-toggle="tab" aria-controls="device_details">
<i class="icon fw fw-mobile"></i>Device Details
</a>
</li>
<li class="list-group-item">
<a href="#policy_compliance" role="tab" data-toggle="tab" aria-controls="policy_compliance">
<i class="icon fw fw-policy"></i>Policy Compliance
</a>
</li>
<li class="list-group-item">
<a href="#device_location" role="tab" data-toggle="tab"
data-lat="{{device.viewModel.location.latitude}}"
data-long="{{device.viewModel.location.longitude}}"
aria-controls="device_location">
<i class="icon fw fw-map-location"></i> Device Location
</a>
</li>
<li class="list-group-item">
<a href="#installed_applications" role="tab" data-toggle="tab" aria-controls="installed_applications">
<i class="icon fw fw-application"></i> Installed Applications
</a>
</li>
<li class="list-group-item">
<a href="#event_log" role="tab" data-toggle="tab" aria-controls="event_log">
<i class="icon fw fw-text"></i> Operations Log
</a>
</li>
</ul>
</div>
<div class="media-body remove-padding-xs">
{{#defineZone "device-detail-properties"}}
<div class="media-body add-padding-left-5x remove-padding-xs">
<div class="panel-group tab-content" id="tabs">
<div class="arrow-left hidden-xs"></div>
<div class="panel panel-default tab-pane fade in active fade-in-xs visible-block"
id="device_details" role="tabpanel"
aria-labelledby="device_details">
<div class="panel-heading dropup visible-xs" role="tab" id="tab1" data-toggle="collapse"
data-target="#tabContent1" aria-expanded="false" data-parent="#tabs">
<h4 class="panel-title">
<i class="fw fw-map-location fw-2x"></i>
Device Details
<i class="caret-updown fw fw-sort-up"></i>
</h4>
</div>
<div class="panel-heading display-none-xs">Device Details</div>
<div id="loading-content" class="col-centered">
<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<i class="fw fw-settings fw-spin fw-2x"></i>&nbsp;&nbsp;&nbsp;Loading Device Details . . .<br>
</div>
<div class="panel-body collapse display-block-sm display-block-md display-block-lg in"
id="tabContent1">
<div class="device-detail-body hidden">
<!-- device summary -->
{{#equal device.type "windows"}}
<div class="panel-body">
Not available yet
</div>
<br class="c-both"/>
{{/equal}}
{{#if device.viewModel.BatteryLevel}}
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
<div class="col-md-12">
<div class="wr-stats-board-tile">
<div class="tile-name">BATTERY</div>
<div>
<div class="tile-icon"><i class="fw fw-battery"></i></div>
<div class="tile-stats">
{{device.viewModel.BatteryLevel}} %
</div>
</div>
</div>
</div>
</div>
{{/if}}
{{#if device.viewModel.DeviceCapacity}}
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
<div class="col-md-12">
<div class="wr-stats-board-tile">
<div class="tile-name">STORAGE</div>
<div>
<div class="tile-icon"><i class="fw fw-hdd"></i></div>
<div class="tile-stats">
{{device.viewModel.DeviceCapacityPercentage}} %
<span class="tile-stats-free">
{{device.viewModel.AvailableDeviceCapacity}} GB Free
</span>
</div>
</div>
</div>
</div>
</div>
{{/if}}
{{#if device.viewModel.internal_memory.FreeCapacity}}
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
<div class="col-md-12">
<div class="wr-stats-board-tile">
<div class="tile-name">LOCAL STORAGE</div>
<div>
<div class="tile-icon"><i class="fw fw-hdd"></i></div>
<div class="tile-stats">
{{device.viewModel.internal_memory.DeviceCapacityPercentage}} %
<span class="tile-stats-free">
{{device.viewModel.internal_memory.FreeCapacity}} GB Free
</span>
</div>
</div>
</div>
</div>
</div>
{{/if}}
{{#if device.viewModel.external_memory.FreeCapacity}}
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
<div class="col-md-12">
<div class="wr-stats-board-tile">
<div class="tile-name">EXTERNAL STORAGE</div>
<div>
<div class="tile-icon"><i class="fw fw-usb-drive"></i></div>
<div class="tile-stats">
{{device.viewModel.external_memory.DeviceCapacityPercentage}} %
<span class="tile-stats-free">
{{device.viewModel.external_memory.FreeCapacity}} GB Free
</span>
</div>
</div>
</div>
</div>
</div>
{{/if}}
</div>
</div>
</div>
<div class="panel panel-default tab-pane fade fade-in-xs visible-block"
id="policy_compliance">
<div class="panel-heading dropdown visible-xs collapsed" role="tab" id="tab2"
data-toggle="collapse" data-target="#tabContent2" aria-expanded="false"
data-parent="#tabs">
<h4 class="panel-title"><i class="fw fw-text fw-2x"></i>
Policy Compliance
<i class="caret-updown fw fw-sort-down"></i>
</h4>
</div>
<div class="panel-heading display-none-xs">
Policy Compliance
&nbsp;&nbsp;
<span>
<a href="#" id="refresh-policy">
<i class="fw fw-refresh"></i>
</a>
</span>
</div>
<div id="policy-spinner" class="wr-advance-operations-init hidden">
<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;
<i class="fw fw-settings fw-spin fw-2x"></i>
&nbsp;&nbsp;&nbsp;
Loading Policy Compliance . . .
<br>
<br>
</div>
<div class="panel-body collapse display-block-sm display-block-md display-block-lg" id="tabContent2">
<div id="policy-list-container">
<div class="panel-body">
There is no active policy for this device.
</div>
<br class="c-both"/>
</div>
</div>
</div>
<div class="panel panel-default tab-pane fade fade-in-xs visible-block"
id="device_location">
<div class="panel-heading dropdown visible-xs collapsed" role="tab" id="tab3"
data-toggle="collapse" data-target="#tabContent3" aria-expanded="false"
data-parent="#tabs">
<h4 class="panel-title">
<i class="fw fw-text fw-2x"></i>
Device Location
<i class="caret-updown fw fw-sort-down"></i>
</h4>
</div>
<div class="panel-heading display-none-xs">Device Location</div>
<div class="panel-body collapse display-block-sm display-block-md display-block-lg"
id="tabContent3">
<div id="device-location"
data-lat="{{device.viewModel.location.latitude}}"
data-long="{{device.viewModel.location.longitude}}"
class="panel-body">
</div>
<div id="map-error" class="panel-body" style="margin: auto;">
Device location cannot be retrieved.
</div>
<br class="c-both"/>
</div>
</div>
<div class="panel panel-default tab-pane fade fade-in-xs visible-block"
id="installed_applications">
<div class="panel-heading dropdown visible-xs collapsed" role="tab" id="tab4"
data-toggle="collapse" data-target="#tabContent4" aria-expanded="false"
data-parent="#tabs">
<h4 class="panel-title">
<i class="fw fw-text fw-2x"></i>
Installed Applications
<i class="caret-updown fw fw-sort-down"></i></h4>
</div>
<div class="panel-heading display-none-xs">
Installed Applications
&nbsp;&nbsp;
<span>
<a href="#" id="refresh-apps">
<i class="fw fw-refresh"></i>
</a>
</span>
</div>
<div class="panel-body collapse display-block-sm display-block-md display-block-lg"
id="tabContent4">
<div id="apps-spinner" class="wr-advance-operations-init hidden">
<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;<i class="fw fw-settings fw-spin fw-2x"></i>
&nbsp;&nbsp;&nbsp;Loading Applications List . . .<br><br>
</div>
<div id="applications-list-container">
<div class="panel-body">
<br>
<p class="fw-warning">
No applications found. please try refreshing the list in a while.
<p>
</div>
<br class="c-both"/>
</div>
</div>
</div>
<div class="panel panel-default tab-pane fade fade-in-xs visible-block" id="event_log">
<div class="panel-heading dropdown visible-xs collapsed" role="tab" id="tab5"
data-toggle="collapse" data-target="#tabContent5" aria-expanded="false"
data-parent="#tabs">
<h4 class="panel-title">
<i class="fw fw-text fw-2x"></i>
Operations Logs
<i class="caret-updown fw fw-sort-down"></i>
</h4>
</div>
<div class="panel-heading display-none-xs">
Operations Logs
&nbsp;&nbsp;
<span>
<a href="#" id="refresh-operations">
<i class="fw fw-refresh"></i>
</a>
</span>
</div>
<div class="panel-body collapse display-block-sm display-block-md display-block-lg"
id="tabContent5">
<div id="operations-spinner" class="wr-advance-operations-init hidden">
<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<i class="fw fw-settings fw-spin fw-2x"></i>&nbsp;&nbsp;&nbsp;
Loading Operations Log . . .
<br><br>
</div>
<div id="operations-log-container">
<div class="panel-body">
There are no operations, performed yet on this device.
</div>
<br class="c-both"/>
</div>
<table class="table table-striped table-hover table-bordered display data-table"
id="operations-log-table">
<thead>
<tr class="sort-row">
<th>Operation Code</th>
<th>Status</th>
<th>Request created at</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{{/defineZone}}
</div>
</div>
{{/zone}}
{{#zone "bottomJs"}}
<script id="policy-view" src="{{@unit.publicUri}}/templates/policy-compliance.hbs"
data-device-id="{{device.deviceIdentifier}}" data-device-type="{{device.type}}"
type="text/x-handlebars-template"></script>
<script id="applications-list" src="{{@unit.publicUri}}/templates/applications-list.hbs"
data-device-id="{{device.deviceIdentifier}}" data-device-type="{{device.type}}"
type="text/x-handlebars-template"></script>
<script id="operations-log" src="{{@unit.publicUri}}/templates/operations-log.hbs"
data-device-id="{{device.deviceIdentifier}}" data-device-type="{{device.type}}"
type="text/x-handlebars-template"></script>
{{js "js/device-detail.js"}}
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
{{js "js/load-map.js"}}
{{/zone}}

@ -0,0 +1,102 @@
/*
* Copyright (c) 2015, 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.
*/
function onRequest(context) {
var log = new Log("view.js");
var deviceType = context.uriParams.deviceType;
var deviceId = request.getParameter("id");
var deviceData = {};
if (deviceType && deviceId) {
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var response = deviceModule.viewDevice(deviceType, deviceId);
if (response["status"] == "success") {
var device = response["content"];
var viewModel = {};
var deviceInfo = device["properties"]["DEVICE_INFO"];
if (deviceInfo && String(deviceInfo.toString()).length > 0) {
deviceInfo = parse(stringify(deviceInfo));
if (device["type"] == "ios") {
deviceInfo = parse(deviceInfo);
viewModel["imei"] = device["properties"]["IMEI"];
viewModel["phoneNumber"] = deviceInfo["PhoneNumber"];
viewModel["udid"] = deviceInfo["UDID"];
viewModel["BatteryLevel"] = Math.round(deviceInfo["BatteryLevel"] * 100);
viewModel["DeviceCapacity"] = Math.round(deviceInfo["DeviceCapacity"] * 100) / 100;
viewModel["AvailableDeviceCapacity"] = Math.
round(deviceInfo["AvailableDeviceCapacity"] * 100) / 100;
viewModel["DeviceCapacityUsed"] = Math.
round((viewModel["DeviceCapacity"] - viewModel["AvailableDeviceCapacity"]) * 100) / 100;
viewModel["DeviceCapacityPercentage"] = Math.
round(viewModel["AvailableDeviceCapacity"] / viewModel["DeviceCapacity"] * 10000) / 100;
viewModel["location"] = {
latitude: device["properties"]["LATITUDE"],
longitude: device["properties"]["LONGITUDE"]
};
} else if (device["type"] == "android") {
viewModel["imei"] = device["properties"]["IMEI"];
viewModel["model"] = device["properties"]["DEVICE_MODEL"];
viewModel["vendor"] = device["properties"]["VENDOR"];
var osBuildDate = device["properties"]["OS_BUILD_DATE"];
if (osBuildDate != null && osBuildDate != "0") {
var formattedDate = new Date(osBuildDate * 1000);
viewModel["os_build_date"] = formattedDate;
}
viewModel["internal_memory"] = {};
viewModel["external_memory"] = {};
viewModel["location"] = {
latitude: device["properties"]["LATITUDE"],
longitude: device["properties"]["LONGITUDE"]
};
var info = {};
var infoList = parse(deviceInfo);
if (infoList != null && infoList != undefined) {
for (var j = 0; j < infoList.length; j++) {
info[infoList[j].name] = infoList[j].value;
}
}
deviceInfo = info;
viewModel["BatteryLevel"] = deviceInfo["BATTERY_LEVEL"];
viewModel["internal_memory"]["FreeCapacity"] = Math.
round(deviceInfo["INTERNAL_AVAILABLE_MEMORY"] * 100)/100;
viewModel["internal_memory"]["DeviceCapacityPercentage"] = Math.
round(deviceInfo["INTERNAL_AVAILABLE_MEMORY"]
/ deviceInfo["INTERNAL_TOTAL_MEMORY"] * 10000) / 100;
viewModel["external_memory"]["FreeCapacity"] = Math.
round(deviceInfo["EXTERNAL_AVAILABLE_MEMORY"] * 100) / 100;
viewModel["external_memory"]["DeviceCapacityPercentage"] = Math.
round(deviceInfo["EXTERNAL_AVAILABLE_MEMORY"]
/ deviceInfo["EXTERNAL_TOTAL_MEMORY"] * 10000) / 100;
} else if (device["type"] == "windows") {
viewModel["imei"] = device["properties"]["IMEI"];
viewModel["model"] = device["properties"]["DEVICE_MODEL"];
viewModel["vendor"] = device["properties"]["VENDOR"];
viewModel["internal_memory"] = {};
viewModel["external_memory"] = {};
viewModel["location"] = {
latitude: device["properties"]["LATITUDE"],
longitude: device["properties"]["LONGITUDE"]
};
}
device["viewModel"] = viewModel;
}
deviceData["device"] = device;
}
return deviceData;
}
}

@ -0,0 +1,288 @@
{{#zone "content"}}
<div class="row">
<div class="col-md-12">
<div class="wr-steps hidden">
<div class="col-md-3 col-xs-3">
<div class="itm-wiz itm-wiz-current" data-step="policy-platform">
<div class="wiz-no">1</div>
<div class="wiz-lbl hidden-xs"><span>Select a platform</span></div>
</div>
<br class="c-both" />
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-profile">
<div class="wiz-no">2</div>
<div class="wiz-lbl hidden-xs"><span>Configure profile</span></div>
</div>
<br class="c-both" />
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-criteria">
<div class="wiz-no">3</div>
<div class="wiz-lbl hidden-xs"><span>Assign to groups</span></div>
</div>
<br class="c-both" />
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-naming">
<div class="wiz-no">4</div>
<div class="wiz-lbl hidden-xs"><span>Publish to devices</span></div>
</div>
<br class="c-both" />
</div>
</div>
<div class="container col-centered policy-message hidden">
<div class="wr-form">
<h1 id="policy-message-page-wizard-title" class="page-sub-title">Policy creation is successful.</h1>
<br>Please click <b>"Add Another Policy"</b>, if you wish to add another policy or click
<b>"View policy list"</b> to complete the process and go back to the policy list.
<hr>
<button class="wr-btn wizard-stepper" data-current="policy-message" data-direct="/emm/policies/">
View policy list
</button>
<a href="/emm/policy/add" class="cu-btn-inner">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
Add another policy
</a>
</div>
</div>
<div class="container col-centered wr-content policy-naming hidden">
<div class="wr-form">
<h1 id="policy-naming-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
<div id="policy-naming-wizard-steps" class="row wr-wizard"></div>
<hr>
<div class="row">
<div class="col-lg-12">
<h4 class="visible-xs">Step 4: Publish to devices</h4>
<br>
<div id="policy-naming-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div>
<label class="wr-input-label">Set a Name for your Policy *</label>
<br />
<label class="wr-input-label">
(Policy name should be 1-to-30 characters long)
</label>
<div id="policyNameField" class="wr-input-control">
<div class="cus-col-50 form-group wr-input-control">
<input id="policy-name-input" class="form-control" type="text" value="" />
<label class="error nameEmpty hidden" for="summary">Policy name is required &
Should be be 1-to-30
characters long.</label>
</div>
<br class="c-both" />
</div>
<label class="wr-input-label">
Add a description
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<textarea id="policy-description-input" class="form-control" rows="10"
placeholder="[ Summary about the policy ]"></textarea>
</div>
<br class="c-both" />
</div>
</div>
<div class="wr-input-control wr-btn-grp">
<a href="javascript:void(0)" class="wr-btn wizard-stepper" data-is-back-btn="true"
data-current="policy-naming" data-next="policy-criteria">Back</a>
<a href="javascript:void(0)" class="wr-btn wizard-stepper"
data-current="policy-naming-publish" data-next="policy-message" data-validate="true">Publish
to
Devices</a>
<a href="javascript:void(0)" class="wr-btn wizard-stepper" data-current="policy-naming"
data-next="policy-message" data-validate="true">Save</a>
</div>
</div>
</div>
</div>
</div>
<div class="container col-centered wr-content policy-criteria hidden">
<div class="wr-form">
<h1 id="policy-criteria-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
<div id="policy-criteria-wizard-steps" class="row wr-wizard"></div>
<hr>
<div class="row">
<div class="col-lg-12">
<h4 class="visible-xs">Step 3: Assign to groups</h4>
<br>
<div id="policy-criteria-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div>
<label class="wr-input-label">
Set device ownership type
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<select id="ownership-input" class="form-control">
<option value="ANY" selected>ANY</option>
<option value="BYOD">BYOD (Bring Your Own Device)</option>
<option value="COPE">COPE (Corporate-Owned, Personally Enabled)</option>
</select>
</div>
<br class="c-both" />
</div>
<div class="wr-input-control">
<label class="wr-input-control radio light">
<input id="user-roles-radio-btn" type="radio" name="select-users-radio-btn"
class="select-users-radio" checked />
<span class="helper">&nbsp;Set user role(s)</span>
</label>
<label class="wr-input-control radio light" rel="assetfilter">
<input id="users-radio-btn" type="radio" name="select-users-radio-btn"
class="select-users-radio" />
<span class="helper">&nbsp;Set user(s)</span>
</label>
</div>
<div id="user-roles-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<select id="user-roles-input" class="form-control select2"
multiple="multiple">
<option value="ANY" selected>ANY</option>
{{#each roles}}
<option>{{this}}</option>
{{/each}}
</select>
</div>
<br class="c-both" />
</div>
</div>
<div id="users-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<select id="users-input" class="form-control select2" multiple="multiple">
</select>
</div>
<br class="c-both" />
</div>
</div>
<br>
<label class="wr-input-label" title="">
Set an action upon non-compliance
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<select id="action-input" class="form-control">
<option data-action="enforce" selected>Enforce</option>
<option data-action="warn">Warn</option>
<option data-action="monitor">Monitor</option>
</select>
</div>
<br class="c-both" />
</div>
</div>
<div class="wr-input-control wr-btn-grp">
<a href="javascript:void(0)" class="wr-btn wizard-stepper" data-is-back-btn="true"
data-current="policy-criteria" data-next="policy-profile">Back</a>
<a href="javascript:void(0)" class="wr-btn wizard-stepper"
data-current="policy-criteria" data-next="policy-naming" data-validate="true">Continue</a>
</div>
</div>
</div>
</div>
</div>
<div class="container col-centered wr-content policy-profile hidden">
<div class="wr-form">
<h1 id="policy-profile-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
<div id="policy-profile-wizard-steps" class="row wr-wizard"></div>
<hr>
<div class="row">
<div class="col-lg-12">
<h4 class="visible-xs">Step 2: Configure profile</h4>
<br>
<div id="policy-profile-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="wr-advance-operations">
<div class="wr-advance-operations-init">
<br>
&nbsp;&nbsp;&nbsp;&nbsp;<i class="fw fw-settings fw-spin fw-2x"></i>
&nbsp;&nbsp;&nbsp;Loading platform features . . .
<br><br>
</div>
</div>
<div class="wr-input-control wr-btn-grp">
<a href="javascript:void(0)" class="wr-btn wizard-stepper" data-is-back-btn="true"
data-current="policy-profile" data-next="policy-platform">Back</a>
<a href="javascript:void(0)" class="wr-btn wizard-stepper" data-current="policy-profile"
data-next="policy-criteria" data-validate="true">Continue</a>
</div>
</div>
</div>
</div>
</div>
<div id="loading-content" class="col-centered">
<br><br>
&nbsp;&nbsp;<i class="fw fw-settings fw-spin fw-2x"></i>
&nbsp;&nbsp;&nbsp;Loading policy creation wizard . . .
<br><br>
</div>
<div class="container col-centered wr-content policy-platform hidden">
<div class="wr-form">
<h1 id="policy-platform-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
<div id="policy-platform-wizard-steps" class="row wr-wizard"></div>
<hr>
<!--<div id="policy-platform-main-error-msg" class="alert alert-danger hidden" role="alert">-->
<!--<i class="icon fw fw-error"></i><span></span>-->
<!--</div>-->
<div class="row">
<div class="col-lg-12">
<h4 class="visible-xs"> Step 1: Select a platform</h4>
<br>
<div id="policy-platform-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="row wr-tile-buttons-list">
<div class="wr-input-control">
<ul class="tile-buttons row">
{{#each types}}
<li class="col-xs-12 col-sm-12 col-md- 4 col-lg-4"
style="margin-top: 5px;margin-bottom: 5px;">
<a href="javascript:void(0)"
class="wizard-stepper {{name}}-platform"
data-current="policy-platform"
data-next="policy-profile" data-platform="{{name}}"
data-validate="false">
<img src="{{icon}}" width="50px" height="50px" />
<br><br>
<b>{{label}}</b>
</a>
</li>
{{/each}}
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- content -->
</div>
</div>
{{/zone}}
{{#zone "bottomJs"}}
<script id="hidden-operations-ios" src="{{@unit.publicUri}}/templates/hidden-operations-ios.hbs"
type="text/x-handlebars-template"></script>
<script id="hidden-operations-android" src="{{@unit.publicUri}}/templates/hidden-operations-android.hbs"
type="text/x-handlebars-template"></script>
<script id="hidden-operations-windows" src="{{@unit.publicUri}}/templates/hidden-operations-windows.hbs"
type="text/x-handlebars-template"></script>
{{js "/js/policy-create.js"}}
{{/zone}}

@ -0,0 +1,61 @@
/*
* 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.
*/
function onRequest() {
var log = new Log("/app/units/mdm.unit.policy.create");
var CONF_DEVICE_TYPE_KEY = "deviceType";
var CONF_DEVICE_TYPE_LABEL_KEY = "label";
var utility = require("/app/modules/utility.js")["utility"];
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var viewModelData = {};
viewModelData["types"] = [];
var typesListResponse = userModule.getPlatforms();
var deviceTypes = typesListResponse["content"]["deviceTypes"];
if (typesListResponse["status"] == "success") {
for (var i = 0; i < deviceTypes.length; i++) {
var content = {};
var deviceType = deviceTypes[i];
content["name"] = deviceType;
var configs = utility.getDeviceTypeConfig(deviceType);
var deviceTypeLabel = deviceType;
if (configs && configs[CONF_DEVICE_TYPE_KEY][CONF_DEVICE_TYPE_LABEL_KEY]) {
deviceTypeLabel = configs[CONF_DEVICE_TYPE_KEY][CONF_DEVICE_TYPE_LABEL_KEY];
}
var policyWizard = new File("/app/units/" + utility.getTenantedDeviceUnitName(deviceType, "policy-wizard"));
log.error("/app/units/" + utility.getTenantedDeviceUnitName(deviceType, "policy-wizard"));
if (policyWizard.isExists()) {
content["icon"] = utility.getDeviceThumb(deviceType);
content["label"] = deviceTypeLabel;
viewModelData["types"].push(content);
}
}
}
var result = userModule.getRolesByUserStore();
if (result["status"] == "success") {
viewModelData["roles"] = result["content"];
}
return viewModelData;
}

@ -0,0 +1,566 @@
<div class="row no-gutter">
<div class="wr-hidden-operations-nav col-lg-4">
<a href="javascript:void(0)" onclick="showAdvanceOperation('passcode-policy', this)" class="selected">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-key fw-stack-2x"></i>
</span>
Passcode Policy
<span id="passcode-policy-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="passcode-policy-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="passcode-policy-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('camera', this)">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-block fw-stack-2x"></i>
</span>
Restrictions on Camera
<span id="camera-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="camera-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span class="camera-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('encrypt-storage', this)">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-security fw-stack-2x"></i>
</span>
Encryption Settings
<span id="encrypt-storage-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="encrypt-storage-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="encrypt-storage-error" class="encryption-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('app-restriction', this)">
<span class="fw-stack fw-lg">
<i class="fw fw-application fw-stack-1x"></i>
<i class="fw fw-block fw-stack-2x"></i>
</span>
Applications Restrictions
<span id="app-restriction-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="app-restriction-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="app-restriction-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<!--<a href="javascript:void(0)" onclick="showAdvanceOperation('wifi', this)">-->
<!--<span class="wr-hidden-operations-icon fw-stack">-->
<!--<i class="fw fw-wifi fw-stack-2x"></i>-->
<!--</span>-->
<!--Wi-Fi Settings-->
<!--<span id="wifi-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>-->
<!--<span id="wifi-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>-->
<!--<span id="wifi-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>-->
<!--</a>-->
<!--<a href="javascript:void(0)" onclick="showAdvanceOperation('install-apps', this)">-->
<!--<span class="wr-hidden-operations-icon fw-stack">-->
<!--<i class="fw fw-application fw-stack-2x"></i>-->
<!--</span>-->
<!--App Installations-->
<!--</a>-->
<!--<a href="javascript:void(0)" onclick="showAdvanceOperation('blacklist-apps', this)">-->
<!--<span class="wr-hidden-operations-icon fw-stack">-->
<!--<i class="fw fw-block fw-stack-2x"></i>-->
<!--</span>-->
<!--App Blacklisting-->
<!--</a>-->
<!--<a href="javascript:void(0)" onclick="showAdvanceOperation('web-clips', this)">-->
<!--<span class="wr-hidden-operations-icon fw-stack">-->
<!--<i class="fw fw-website fw-stack-2x"></i>-->
<!--</span>-->
<!--Web clips-->
<!--</a>-->
</div>
<div class="wr-hidden-operations-content col-lg-8">
<!-- passcode-policy -->
<div class="wr-hidden-operation" data-operation="passcode-policy" style="display: block">
<div class="panel panel-default operation-data" data-operation="passcode-policy" data-operation-code="PASSCODE_POLICY">
<div id="passcode-policy-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Passcode Policy
<label id="passcode-policy-lbl" class="wr-input-control switch" data-toggle="collapse" data-target="#passcode-policy-body">
<input type="checkbox" />
<span class="helper"></span>
<span class="text"></span>
</label>
<hr>
<div class="panel-title-description">
This configuration can be used to set a passcode policy to an Windows Device.
Once this configuration profile is installed on a device, corresponding users will not be able
to modify these settings on their devices.
</div>
</h2>
</div>
<div id="passcode-policy-body" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="passcode-policy-body">
<div id="passcode-policy-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="passcode-policy-allow-simple" type="checkbox" class="form-control operationDataKeys" data-key="passcodePolicyAllowSimple" checked="checked" />
<span class="helper" title="Permit the use of repeating, ascending and descending character sequences">
&nbsp;&nbsp;&nbsp;Allow simple value
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="passcode-policy-require-alphanumeric" type="checkbox" class="form-control operationDataKeys" data-key="passcodePolicyRequireAlphanumeric" checked="checked" />
<span class="helper" title="Require passcode to contain both letters and numbers">
&nbsp;&nbsp;&nbsp;Require alphanumeric value
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-min-length">
Minimum passcode length
<span class="helper" title="Minimum number of characters allowed in a passcode">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="passcode-policy-min-length" class="form-control operationDataKeys" data-key="passcodePolicyMinLength" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-min-complex-chars">
Minimum number of complex characters
<span class="helper" title="Minimum number of complex or non-alphanumeric characters allowed in a passcode">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="passcode-policy-min-complex-chars" class="form-control operationDataKeys" data-key="passcodePolicyMinComplexChars" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="1">01</option>
<option value="2">02</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-max-passcode-age-in-days">
Maximum passcode age in days
<span class="helper" title="Number of days after which a passcode must be changed">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
( Should be in between 1-to-730 days or none )
</label>
<input id="passcode-policy-max-passcode-age-in-days" type="text" class="form-control operationDataKeys" data-key="passcodePolicyMaxPasscodeAgeInDays" maxlength="3" placeholder="[ Requires Number Input ]">
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-passcode-history">
Passcode history
<span class="helper" title="Number of consequent unique passcodes to be used before reuse">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
( Should be in between 1-to-50 passcodes or none )
</label>
<input id="passcode-policy-passcode-history" type="text" class="form-control operationDataKeys" data-key="passcodePolicyPasscodeHistory" maxlength="2" placeholder="[ Requires Number Input ]">
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcodePolicyMaxFailedAttempts">
Maximum number of failed attempts
<span class="helper" title="Maximum number of passcode entry attempts allowed before all data on a device will be erased">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="passcode-policy-max-failed-attempts" class="form-control operationDataKeys" data-key="passcodePolicyMaxFailedAttempts" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
</select>
</div>
</div>
</div>
</div>
<!-- /passcode-policy -->
<!-- camera -->
<div class="wr-hidden-operation" data-operation="camera">
<div class="panel panel-default operation-data" data-operation="camera" data-operation-code="CAMERA">
<div id="camera-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Restrictions on Camera
<label class="wr-input-control switch" data-toggle="collapse" data-target="#camera-body">
<input type="checkbox" />
<span class="helper"></span>
<span class="text"></span>
</label>
<hr>
<div class="panel-title-description">
This configuration can be used to restrict the usage of camera on an Windows device together with all the applications using the camera.
Once this configuration profile is installed on a device, corresponding users will not be able
to modify these settings on their devices.
</div>
</h2>
</div>
<div id="camera-body" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="camera-body">
<div id="camera-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
Un-check following checkbox in case you need to disable camera.
<br>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="camera-enabled" type="checkbox" class="operationDataKeys" data-key="cameraEnabled" checked="checked" />
<span class="helper" title="Having this checked would enable Usage of phone camera in the device.">
&nbsp;&nbsp;&nbsp;Allow use of camera
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
</div>
</div>
</div>
<!-- /camera -->
<!-- encrypt-storage -->
<div class="wr-hidden-operation" data-operation="encrypt-storage">
<div class="panel panel-default operation-data" data-operation="encrypt-storage" data-operation-code="ENCRYPT_STORAGE">
<div id="encrypt-storage-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Encryption Settings
<label class="wr-input-control switch" data-toggle="collapse" data-target="#encrypt-storage-body">
<input type="checkbox" />
<span class="helper"></span>
<span class="text"></span>
</label>
<hr>
<div class="panel-title-description">
This configuration can be used to encrypt data on an Windows device, when the device is locked and
make it readable when the passcode is entered. Once this configuration profile is installed on a device,
corresponding users will not be able to modify these settings on their devices.
</div>
</h2>
</div>
<div id="encrypt-storage-body" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="encrypt-storage-body">
<div id="encrypt-storage-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
Un-check following checkbox in case you need to disable storage-encryption.
<br>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="encrypt-storage-enabled" type="checkbox" class="operationDataKeys" data-key="encryptStorageEnabled" checked="checked" />
<span class="helper" title="Having this checked would enable Storage-encryption in the device">
&nbsp;&nbsp;&nbsp;Enable storage-encryption
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
</div>
</div>
</div>
<!-- /encrypt-storage -->
<!--app-restriction-->
<div class="wr-hidden-operation" data-operation="app-restriction">
<div class="panel panel-default operation-data" data-operation="app-restriction" data-operation-code="APP-RESTRICTION">
<div id="app-restriction-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Application Restriction Settings
<label class="wr-input-control switch" data-toggle="collapse" data-target="#app-restriction-body">
<input type="checkbox" />
<span class="helper"></span>
<span class="text"></span>
</label>
<hr>
<div class="panel-title-description">
This configuration can be used to create a black list or white list of applications.
</div>
</h2>
</div>
<div id="app-restriction-body" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="app-restriction-body">
<div id="app-restriction-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<select id="app-restriction-type" class="form-control operationDataKeys" data-key="restrictionType">
<option value="" selected="selected">
None
</option>
<option value="black-list">Black List</option>
<option value="white-list">White List</option>
</select>
<div class="wr-input-control">
<label class="wr-input-label" for="restricted-applications">
Restricted Application List
<span class="helper" title="Add an application to restrict.">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
<a href="#restricted-applications-grid" class="grid-input-add" data-click-event="add-form">
<span class="icon fw-stack">
<i class="fw fw-add fw-stack-1x"></i>
<i class="fw fw-ring fw-stack-2x"></i>
</span>
&nbsp;
Add Application
</a>
</label>
<div id="restricted-applications" class="operationDataKeys grouped-array-input multi-column-key-value-pair-array" data-key="restrictedApplications" data-column-count="2">
<table class="table table-responsive table-striped">
<thead>
<tr>
<th>No:</th>
<th>Application Name/Description</th>
<th>Package Name</th>
<th></th>
</tr>
</thead>
<tbody data-add-form-container="#restricted-applications-grid">
<tr data-help-text="add-form">
<td colspan="4">
No entries added yet .
</td>
</tr>
</tbody>
</table>
<table class="template hidden">
<tbody data-add-form="#restricted-applications-grid">
<tr data-add-form-element="clone">
<td data-title="No:">
<span class="index"></span>
</td>
<td data-title="App Name">
<input type="text" class="form-control grid-input-text" data-child-key="appName" maxlength="100" data-default="" placeholder="[ Application Name or Description ]" />
</td>
<td data-title="Package Name">
<input type="text" class="form-control grid-input-text" data-child-key="packageName" maxlength="100" data-default="" placeholder="[ Package Name of Application ]" />
</td>
<td>
<span class="list-group-item-actions">
<a href="#restricted-applications-grid" class="grid-input-remove" data-click-event="remove-form">
<span class="fw-stack helper" title="Remove Entry">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-delete fw-stack-1x"></i>
</span>
</a>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!--/app-restriction-->
<!-- wi-fi -->
<!--<div class="wr-hidden-operation" data-operation="wifi">-->
<!--<div class="panel panel-default operation-data" data-operation="wifi" data-operation-code="WIFI">-->
<!--<div id="wifi-heading" class="panel-heading" role="tab">-->
<!--<h2 class="sub-title panel-title">-->
<!--Wi-Fi Settings-->
<!--<label class="wr-input-control switch" data-toggle="collapse" data-target="#wifi-body">-->
<!--<input type="checkbox" />-->
<!--<span class="helper"></span>-->
<!--<span class="text"></span>-->
<!--</label>-->
<!--<hr>-->
<!--<div class="panel-title-description">-->
<!--This configurations can be used to configure Wi-Fi access on an Android device.-->
<!--Once this configuration profile is installed on a device, corresponding users will not be able-->
<!--to modify these settings on their devices.-->
<!--</div>-->
<!--</h2>-->
<!--</div>-->
<!--<div id="wifi-body" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="wifi-body">-->
<!--&lt;!&ndash;<div class="cloneable">&ndash;&gt;-->
<!--&lt;!&ndash;<a href="#" class="multi-view add enabled">&ndash;&gt;-->
<!--&lt;!&ndash;<span class="icon fw-stack">&ndash;&gt;-->
<!--&lt;!&ndash;<i class="fw fw-add fw-stack-1x"></i>&ndash;&gt;-->
<!--&lt;!&ndash;<i class="fw fw-ring fw-stack-2x"></i>&ndash;&gt;-->
<!--&lt;!&ndash;</span>&ndash;&gt;-->
<!--&lt;!&ndash;</a>&ndash;&gt;-->
<!--&lt;!&ndash;<a href="#" class="multi-view remove disabled">&ndash;&gt;-->
<!--&lt;!&ndash;<span class="icon fw-stack">&ndash;&gt;-->
<!--&lt;!&ndash;<i class="fw fw-minus fw-stack-1x"></i>&ndash;&gt;-->
<!--&lt;!&ndash;<i class="fw fw-ring fw-stack-2x"></i>&ndash;&gt;-->
<!--&lt;!&ndash;</span>&ndash;&gt;-->
<!--&lt;!&ndash;</a>&ndash;&gt;-->
<!--&lt;!&ndash;Wi-Fi Setting :&ndash;&gt;-->
<!--&lt;!&ndash;<br>&ndash;&gt;-->
<!--&lt;!&ndash;<br>&ndash;&gt;-->
<!--Please note that * sign represents required fields of data.-->
<!--<br>-->
<!--<br>-->
<!--<div id="wifi-feature-error-msg" class="alert alert-danger hidden" role="alert">-->
<!--<i class="icon fw fw-error"></i><span></span>-->
<!--</div>-->
<!--<div class="wr-input-control">-->
<!--<label class="wr-input-label" for="wifi-ssid">-->
<!--Service Set Identifier (SSID) *-->
<!--<span class="helper" title="Identification of the wireless network to be configured.">-->
<!--<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>-->
<!--</span>-->
<!--<br>-->
<!--( should be 1-to-30 characters long )-->
<!--</label>-->
<!--<input id="wifi-ssid" type="text" class="form-control operationDataKeys" data-key="wifiSSID" maxlength="100" placeholder="[ Required field ]"/>-->
<!--</div>-->
<!--<div class="wr-input-control">-->
<!--<label class="wr-input-label" for="wifi-password">-->
<!--Password-->
<!--<span class="helper" title="Password for the wireless network.">-->
<!--<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>-->
<!--</span>-->
<!--</label>-->
<!--<input id="wifi-password" type="text" class="form-control operationDataKeys" data-key="wifiPassword" maxlength="100" placeholder="[ Optional field ]"/>-->
<!--</div>-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!-- /wi-fi -->
<!-- install-applications -->
<!--<div class="wr-hidden-operation" data-operation="install-apps">-->
<!--<div class="panel panel-default operation-data" data-operation="INSTALL_APPLICATION">-->
<!--<div class="panel-heading" role="tab">-->
<!--<h2 class="sub-title panel-title">-->
<!--<br>-->
<!--&nbsp;&nbsp;&nbsp;App Installations-->
<!--<label class="wr-input-control switch" data-toggle="collapse" data-target="#installApp">-->
<!--<input type="checkbox" />-->
<!--<span class="helper"></span>-->
<!--<span class="text"></span>-->
<!--</label>-->
<!--<br>-->
<!--<br>-->
<!--</h2>-->
<!--</div>-->
<!--<div id="installApp" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="installApp">-->
<!--<div id="install-app-feature-error-msg" class="alert alert-danger hidden" role="alert">-->
<!--<i class="icon fw fw-error"></i><span></span>-->
<!--</div>-->
<!--<label class="wr-input-label" title="Application Identifier">App Identifier<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>-->
<!--<div class="wr-input-control">-->
<!--<input type="text" class="form-control operationDataKeys" id="package-name" data-key="packageName" placeholder="Enter App Identifier"/>-->
<!--</div>-->
<!--<div class="wr-input-control">-->
<!--<label class="wr-input-control dropdown">-->
<!--<span class="helper" title="App Type">App Type<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></span>-->
<!--<select class="form-control col-sm-8 operationDataKeys appTypesInput" id="type" data-key="type">-->
<!--<option>Public</option>-->
<!--<option>Enterprise</option>-->
<!--</select>-->
<!--</label>-->
<!--</div>-->
<!--<label class="wr-input-label" title="URL">URL<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>-->
<!--<div class="wr-input-control">-->
<!--<input type="text" class="form-control operationDataKeys" id="url" data-key="url" placeholder="Enter URL"/>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!-- /install-applications -->
<!-- /uninstall-applications -->
<!--<div class="wr-hidden-operation" data-operation="uninstall-apps">-->
<!--<div class="panel panel-default operation-data" data-operation="UNINSTALL_APPLICATION">-->
<!--<div class="panel-heading" role="tab">-->
<!--<h2 class="sub-title panel-title">-->
<!--<br>-->
<!--&nbsp;&nbsp;&nbsp;App Uninstallations-->
<!--<label class="wr-input-control switch" data-toggle="collapse" data-target="#uninstallApp">-->
<!--<input type="checkbox" />-->
<!--<span class="helper"></span>-->
<!--<span class="text"></span>-->
<!--</label>-->
<!--<br>-->
<!--<br>-->
<!--</h2>-->
<!--</div>-->
<!--<div id="uninstallApp" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="uninstallApp">-->
<!--<div id="uninstall-app-feature-error-msg" class="alert alert-danger hidden" role="alert">-->
<!--<i class="icon fw fw-error"></i><span></span>-->
<!--</div>-->
<!--<label class="wr-input-label" title="Application Identifier">App Identifier<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>-->
<!--<!--span>Identification of the wireless network to connect to</span-->
<!--<div class="wr-input-control">-->
<!--<input type="text" class="form-control operationDataKeys" id="package-name" data-key="packageName" placeholder="Enter App Identifier"/>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!-- /uninstall-applications -->
<!-- /web-clips -->
<!--<div class="wr-hidden-operation" data-operation="web-clips">-->
<!--<div class="panel panel-default operation-data" data-operation="WEBCLIP">-->
<!--<div class="panel-heading" role="tab">-->
<!--<h2 class="sub-title panel-title">-->
<!--<br>-->
<!--&nbsp;&nbsp;&nbsp;Web clips-->
<!--<label class="wr-input-control switch" data-toggle="collapse" data-target="#installWebClip">-->
<!--<input type="checkbox" />-->
<!--<span class="helper"></span>-->
<!--<span class="text"></span>-->
<!--</label>-->
<!--<br>-->
<!--<br>-->
<!--</h2>-->
<!--</div>-->
<!--<div id="installWebClip" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="installWebClip">-->
<!--<div id="install-webclip-feature-error-msg" class="alert alert-danger hidden" role="alert">-->
<!--<i class="icon fw fw-error"></i><span></span>-->
<!--</div>-->
<!--<label class="wr-input-label" title="Title of the web clip">Title<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>-->
<!--<div class="wr-input-control">-->
<!--<input type="text" class="form-control operationDataKeys" id="title" data-key="title" placeholder="Enter Title"/>-->
<!--</div>-->
<!--<label class="wr-input-label" title="URL">URL<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>-->
<!--<div class="wr-input-control">-->
<!--<input type="text" class="form-control operationDataKeys" id="url" data-key="url" placeholder="Enter URL"/>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!-- /web-clips -->
</div>
</div>

@ -1,239 +1,233 @@
{{!
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.
}}
{{#zone "content"}}
<div class="row">
<div class="col-md-12">
<div class="col-md-12">
<div class="wr-steps hidden">
<div class="col-md-3 col-xs-3">
<div class="itm-wiz itm-wiz-current" data-step="policy-profile"><div class="wiz-no">1</div><div class="wiz-lbl hidden-xs"><span>Edit current profile</span></div></div>
<br class="c-both" />
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-criteria"><div class="wiz-no">2</div><div class="wiz-lbl hidden-xs"><span>Edit assignment groups</span></div></div>
<br class="c-both" />
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-naming"><div class="wiz-no">3</div><div class="wiz-lbl hidden-xs"><span>Republish to devices</span></div></div>
<br class="c-both" />
</div>
</div>
<div class="wr-steps hidden">
<div class="col-md-3 col-xs-3">
<div class="itm-wiz itm-wiz-current" data-step="policy-profile"><div class="wiz-no">1</div><div class="wiz-lbl hidden-xs"><span>Edit current profile</span></div></div>
<br class="c-both" />
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-criteria"><div class="wiz-no">2</div><div class="wiz-lbl hidden-xs"><span>Edit assignment groups</span></div></div>
<br class="c-both" />
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-naming"><div class="wiz-no">3</div><div class="wiz-lbl hidden-xs"><span>Republish to devices</span></div></div>
<br class="c-both" />
</div>
</div>
<div class="container col-centered wr-content policy-message hidden">
<div class="wr-form">
<h1 id="policy-message-page-wizard-title" class="page-sub-title">Policy is successfully re-configured.</h1>
<br>Please click <b>"Add Another Policy"</b>, if you wish to add another policy or click
<b>"View policy list"</b> to complete the process and go back to the policy list.
<hr>
<button class="wr-btn wizard-stepper" data-current="policy-message" data-direct="{{@app.context}}/policies/">
View policy list
</button>
<a href="{{@app.context}}/policy/add" class="cu-btn-inner">
<div class="container col-centered wr-content policy-message hidden">
<div class="wr-form">
<h1 id="policy-message-page-wizard-title" class="page-sub-title">Policy is successfully re-configured.</h1>
<br>Please click <b>"Add Another Policy"</b>, if you wish to add another policy or click
<b>"View policy list"</b> to complete the process and go back to the policy list.
<hr>
<button class="wr-btn wizard-stepper" data-current="policy-message" data-direct="/emm/policies/">
View policy list
</button>
<a href="/emm/policies/add-policy" class="cu-btn-inner">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
Add another policy
</a>
</div>
</div>
Add another policy
</a>
</div>
</div>
<div class="container col-centered wr-content policy-naming hidden">
<div class="wr-form">
<h1 id="policy-naming-page-wizard-title" class="page-sub-title">EDIT POLICY</h1>
<hr>
<div id="policy-naming-wizard-steps" class="row wr-wizard"></div>
<hr>
<div class="row">
<div class="col-lg-12">
<h4>Step 3: Republish to devices</h4>
<br>
<div id="policy-naming-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div>
<label class="wr-input-label">
Set a name * to your policy<br>
( should be 1-to-30 characters long )
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<input id="policy-name-input" class="form-control" type="text" value="" placeholder="[ Required field ]"/>
</div>
<br class="c-both" />
</div>
<label class="wr-input-label">
Add a description
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<textarea id="policy-description-input" class="form-control" rows="10" placeholder="[ Optional field ]"></textarea>
</div>
<br class="c-both" />
</div>
<div class="container col-centered wr-content policy-naming hidden">
<div class="wr-form">
<h1 id="policy-naming-page-wizard-title" class="page-sub-title">EDIT POLICY</h1>
<hr>
<div id="policy-naming-wizard-steps" class="row wr-wizard"></div>
<hr>
<div class="row">
<div class="col-lg-12">
<h4 class="visible-xs">Step 3: Republish to devices</h4>
<br>
<div id="policy-naming-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div>
<label class="wr-input-label">
Set a name * to your policy<br>
( should be 1-to-30 characters long )
</label>
<div id="policy-name-field" class="form-group wr-input-control">
<div class="cus-col-50">
<input id="policy-name-input" class="form-control" type="text" value="" placeholder="[ Required field ]"/>
</div>
<div class="wr-input-control wr-btn-grp">
<a href="#" class="wr-btn wizard-stepper" data-is-back-btn="true" data-current="policy-naming" data-next="policy-criteria">
Back
</a>
<a href="#" class="wr-btn wizard-stepper" data-current="policy-naming-publish" data-next="policy-message" data-validate="true">
Save & Publish
</a>
<a href="#" class="wr-btn wizard-stepper" data-current="policy-naming" data-next="policy-message" data-validate="true">
Save
</a>
<br class="c-both"/>
<span class=" nameError hidden glyphicon glyphicon-remove form-control-feedback"></span>
<label class="error nameEmpty hidden" for="summary">Policy name is required & Should be be 1-to-30 characters long.</label>
</div>
<label class="wr-input-label">
Add a description
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<textarea id="policy-description-input" class="form-control" rows="10" placeholder="[ Optional field ]"></textarea>
</div>
<br class="c-both" />
</div>
</div>
<div class="wr-input-control wr-btn-grp">
<a href="#" class="wr-btn wizard-stepper" data-is-back-btn="true" data-current="policy-naming" data-next="policy-criteria">
Back
</a>
<a href="#" class="wr-btn wizard-stepper" data-current="policy-naming-publish" data-next="policy-message" data-validate="true">
Save & Publish
</a>
<a href="#" class="wr-btn wizard-stepper" data-current="policy-naming" data-next="policy-message" data-validate="true">
Save
</a>
</div>
</div>
</div>
</div>
</div>
<div class="container col-centered wr-content policy-criteria hidden">
<div class="wr-form">
<h1 id="policy-criteria-page-wizard-title" class="page-sub-title">EDIT POLICY</h1>
<hr>
<div id="policy-criteria-wizard-steps" class="row wr-wizard"></div>
<hr>
<div class="row">
<div class="col-lg-12">
<h4>Step 2: Edit assignment groups</h4>
<br>
<div id="policy-criteria-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
<div class="container col-centered wr-content policy-criteria hidden">
<div class="wr-form">
<h1 id="policy-criteria-page-wizard-title" class="page-sub-title">EDIT POLICY</h1>
<hr>
<div id="policy-criteria-wizard-steps" class="row wr-wizard"></div>
<hr>
<div class="row">
<div class="col-lg-12">
<h4 class="visible-xs">Step 2: Edit assignment groups</h4>
<br>
<div id="policy-criteria-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div>
<label class="wr-input-label">
Set device ownership type
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<select id="ownership-input" class="form-control">
<option value="ANY" selected>ANY</option>
<option value="BYOD">BYOD (Bring Your Own Device) </option>
<option value="COPE">COPE (Corporate-Owned, Personally Enabled)</option>
</select>
</div>
<div>
<label class="wr-input-label">
Set device ownership type
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<select id="ownership-input" class="form-control">
<option value="ANY" selected>ANY</option>
<option value="BYOD">BYOD (Bring Your Own Device) </option>
<option value="COPE">COPE (Corporate-Owned, Personally Enabled)</option>
</select>
</div>
<br class="c-both" />
</div>
<div class="wr-input-control">
<label class="wr-input-control radio light">
<input id="user-roles-radio-btn" type="radio" name="select-users-radio-btn" class="select-users-radio" checked/>
<span class="helper">&nbsp;Set user role(s)</span>
</label>
<label class="wr-input-control radio light" rel="assetfilter">
<input id="users-radio-btn" type="radio" name="select-users-radio-btn" class="select-users-radio" />
<span class="helper">&nbsp;Set user(s)</span>
</label>
</div>
<div id="user-roles-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<select id="user-roles-input" class="form-control select2" multiple="multiple">
<option value="ANY" selected>ANY</option>
{{#each roles}}
<option>{{this}}</option>
{{/each}}
</select>
</div>
<br class="c-both" />
</div>
</div>
<div id="users-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<select id="users-input" class="form-control select2" multiple="multiple">
<option value="ANY" selected>ANY</option>
{{#each users}}
<option>{{this}}</option>
{{/each}}
</select>
</div>
<br class="c-both" />
</div>
<br class="c-both" />
</div>
<div class="wr-input-control">
<label class="wr-input-control radio light">
<input id="user-roles-radio-btn" type="radio" name="select-users-radio-btn" class="select-users-radio" checked/>
<span class="helper">&nbsp;Set user role(s)</span>
</label>
<label class="wr-input-control radio light" rel="assetfilter">
<input id="users-radio-btn" type="radio" name="select-users-radio-btn" class="select-users-radio" />
<span class="helper">&nbsp;Set user(s)</span>
</label>
</div>
<div id="user-roles-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<select id="user-roles-input" class="form-control select2" multiple="multiple">
<option value="ANY" selected>ANY</option>
{{#each roles}}
<option>{{this}}</option>
{{/each}}
</select>
</div>
<br>
<label class="wr-input-label" title="">
Set an action upon non-compliance
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<select id="action-input" class="form-control">
<option value="enforce" data-action="enforce" selected>Enforce</option>
<option value="warn" data-action="warn">Warn</option>
<option value="monitor" data-action="monitor">Monitor</option>
</select>
</div>
<br class="c-both" />
<br class="c-both" />
</div>
</div>
<div id="users-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<select id="users-input" class="form-control select2" multiple="multiple">
<option value="ANY" selected>ANY</option>
{{#each users}}
<option>{{username}}</option>
{{/each}}
</select>
</div>
<br class="c-both" />
</div>
<div class="wr-input-control wr-btn-grp">
<a href="#" class="wr-btn wizard-stepper" data-is-back-btn="true" data-current="policy-criteria" data-next="policy-profile">
Back
</a>
<a href="#" class="wr-btn wizard-stepper" data-current="policy-criteria" data-next="policy-naming" data-validate="true">
Continue
</a>
</div>
<br>
<label class="wr-input-label" title="">
Set an action upon non-compliance
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<select id="action-input" class="form-control">
<option value="enforce" data-action="enforce" selected>Enforce</option>
<option value="warn" data-action="warn">Warn</option>
<option value="monitor" data-action="monitor">Monitor</option>
</select>
</div>
<br class="c-both" />
</div>
</div>
<div class="wr-input-control wr-btn-grp">
<a href="#" class="wr-btn wizard-stepper" data-is-back-btn="true" data-current="policy-criteria" data-next="policy-profile">
Back
</a>
<a href="#" class="wr-btn wizard-stepper" data-current="policy-criteria" data-next="policy-naming" data-validate="true">
Continue
</a>
</div>
</div>
</div>
</div>
</div>
<div class="container col-centered wr-content policy-profile">
<div class="wr-form">
<h1 id="policy-profile-page-wizard-title" class="page-sub-title">EDIT POLICY</h1>
<hr>
<div id="policy-profile-wizard-steps" class="row wr-wizard"></div>
<hr>
<div class="row">
<div class="col-lg-12">
<h4>Step 1: Edit current profile</h4>
<div class="container col-centered wr-content policy-profile">
<div class="wr-form">
<h1 id="policy-profile-page-wizard-title" class="page-sub-title">EDIT POLICY</h1>
<hr>
<div id="policy-profile-wizard-steps" class="row wr-wizard"></div>
<hr>
<div class="row">
<div class="col-lg-12">
<h4 class="visible-xs">Step 1: Edit current profile</h4>
<br>
<div id="policy-profile-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="wr-advance-operations">
<div class="wr-advance-operations-init">
<br>
&nbsp;&nbsp;
<i class="fw fw-settings fw-spin fw-2x"></i>
&nbsp;Loading platform features . . .
<br>
<br>
<div id="policy-profile-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="wr-advance-operations">
<div class="wr-advance-operations-init">
<br>
<i class="fw fw-settings fw-spin fw-2x"></i>
Loading platform features . . .
<br>
<br>
</div>
</div>
<div class="wr-input-control wr-btn-grp">
<a href="#" class="wr-btn wizard-stepper" data-current="policy-profile" data-next="policy-criteria" data-validate="true">
Continue
</a>
</div>
</div>
</div>
<div class="wr-input-control wr-btn-grp">
<a href="#" class="wr-btn wizard-stepper" data-current="policy-profile" data-next="policy-criteria" data-validate="true">
Continue
</a>
</div>
</div>
</div>
</div>
</div>
<!-- content -->
<!-- content -->
</div>
</div>
</div>
{{/zone}}
{{#zone "bottomJs"}}
<script id="hidden-operations-ios" src="{{@unit.publicUri}}/templates/hidden-operations-ios.hbs" type="text/x-handlebars-template" ></script>
<script id="hidden-operations-android" src="{{@unit.publicUri}}/templates/hidden-operations-android.hbs" type="text/x-handlebars-template" ></script>
<script id="hidden-operations-windows" src="{{@unit.publicUri}}/templates/hidden-operations-windows.hbs" type="text/x-handlebars-template" ></script>
{{js "js/policy-create.js"}}
<!--suppress HtmlUnknownTarget -->
<script id="hidden-operations-ios" src="{{@unit.publicUri}}/templates/hidden-operations-ios.hbs"
type="text/x-handlebars-template"></script>
<!--suppress HtmlUnknownTarget -->
<script id="hidden-operations-android" src="{{@unit.publicUri}}/templates/hidden-operations-android.hbs"
type="text/x-handlebars-template"></script>
<!--suppress HtmlUnknownTarget -->
<script id="hidden-operations-windows" src="{{@unit.publicUri}}/templates/hidden-operations-windows.hbs"
type="text/x-handlebars-template"></script>
{{js "js/edit.js"}}
{{/zone}}

@ -1,17 +1,17 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* Copyright (c) 2015, 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
* 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
* "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.
*/
@ -19,8 +19,18 @@
function onRequest(context) {
var log = new Log("policy-view-edit-unit backend js");
log.debug("calling policy-view-edit-unit");
var userModule = require("/app/modules/user.js").userModule;
context.roles = userModule.getRoles().content;
context.users = userModule.getUsersByUsername().content;
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var rolesResult = userModule.getRoles();
if (rolesResult.status == "success") {
context.roles = rolesResult.content;
}
var usersResult = userModule.getUsers();
if (usersResult.status == "success") {
context.users = usersResult.content;
}
return context;
}

@ -1,460 +1,568 @@
<div class="row no-gutter">
<div class="wr-hidden-operations-nav col-lg-4">
<a href="javascript:void(0)" onclick="showAdvanceOperation('passcode-policy', this)" class="selected">
<div class="wr-hidden-operations-nav col-lg-4">
<a href="javascript:void(0)" onclick="showAdvanceOperation('passcode-policy', this)" class="selected">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-key fw-stack-2x"></i>
</span>
Passcode Policy
<span id="passcode-policy-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="passcode-policy-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="passcode-policy-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('camera', this)">
Passcode Policy
<span id="passcode-policy-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="passcode-policy-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="passcode-policy-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('camera', this)">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-block fw-stack-2x"></i>
</span>
Restrictions on Camera
<span id="camera-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="camera-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span class="camera-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('encrypt-storage', this)">
Restrictions on Camera
<span id="camera-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="camera-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span class="camera-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('encrypt-storage', this)">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-security fw-stack-2x"></i>
</span>
Encryption Settings
<span id="encrypt-storage-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="encrypt-storage-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="encrypt-storage-error" class="encryption-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<!--<a href="javascript:void(0)" onclick="showAdvanceOperation('wifi', this)">-->
<!--<span class="wr-hidden-operations-icon fw-stack">-->
<!--<i class="fw fw-wifi fw-stack-2x"></i>-->
<!--</span>-->
<!--Wi-Fi Settings-->
<!--<span id="wifi-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>-->
<!--<span id="wifi-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>-->
<!--<span id="wifi-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>-->
<!--</a>-->
<!--<a href="javascript:void(0)" onclick="showAdvanceOperation('install-apps', this)">-->
<!--<span class="wr-hidden-operations-icon fw-stack">-->
<!--<i class="fw fw-application fw-stack-2x"></i>-->
<!--</span>-->
<!--App Installations-->
<!--</a>-->
<!--<a href="javascript:void(0)" onclick="showAdvanceOperation('blacklist-apps', this)">-->
<!--<span class="wr-hidden-operations-icon fw-stack">-->
<!--<i class="fw fw-block fw-stack-2x"></i>-->
<!--</span>-->
<!--App Blacklisting-->
<!--</a>-->
<!--<a href="javascript:void(0)" onclick="showAdvanceOperation('web-clips', this)">-->
<!--<span class="wr-hidden-operations-icon fw-stack">-->
<!--<i class="fw fw-website fw-stack-2x"></i>-->
<!--</span>-->
<!--Web clips-->
<!--</a>-->
</div>
Encryption Settings
<span id="encrypt-storage-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="encrypt-storage-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="encrypt-storage-error" class="encryption-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('app-restriction', this)">
<span class="fw-stack fw-lg">
<i class="fw fw-application fw-stack-1x"></i>
<i class="fw fw-block fw-stack-2x"></i>
</span>
Applications Restrictions
<span id="app-restriction-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="app-restriction-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="app-restriction-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<!--<a href="javascript:void(0)" onclick="showAdvanceOperation('wifi', this)">-->
<!--<span class="wr-hidden-operations-icon fw-stack">-->
<!--<i class="fw fw-wifi fw-stack-2x"></i>-->
<!--</span>-->
<!--Wi-Fi Settings-->
<!--<span id="wifi-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>-->
<!--<span id="wifi-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>-->
<!--<span id="wifi-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>-->
<!--</a>-->
<!--<a href="javascript:void(0)" onclick="showAdvanceOperation('install-apps', this)">-->
<!--<span class="wr-hidden-operations-icon fw-stack">-->
<!--<i class="fw fw-application fw-stack-2x"></i>-->
<!--</span>-->
<!--App Installations-->
<!--</a>-->
<!--<a href="javascript:void(0)" onclick="showAdvanceOperation('blacklist-apps', this)">-->
<!--<span class="wr-hidden-operations-icon fw-stack">-->
<!--<i class="fw fw-block fw-stack-2x"></i>-->
<!--</span>-->
<!--App Blacklisting-->
<!--</a>-->
<!--<a href="javascript:void(0)" onclick="showAdvanceOperation('web-clips', this)">-->
<!--<span class="wr-hidden-operations-icon fw-stack">-->
<!--<i class="fw fw-website fw-stack-2x"></i>-->
<!--</span>-->
<!--Web clips-->
<!--</a>-->
</div>
<div class="wr-hidden-operations-content col-lg-8">
<!-- passcode-policy -->
<div class="wr-hidden-operation" data-operation="passcode-policy" style="display: block">
<div class="panel panel-default operation-data" data-operation="passcode-policy" data-operation-code="PASSCODE_POLICY">
<div id="passcode-policy-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Passcode Policy
<label id="passcode-policy-lbl" class="wr-input-control switch" data-toggle="collapse" data-target="#passcode-policy-body">
<input type="checkbox" />
<span class="helper"></span>
<span class="text"></span>
</label>
<hr>
<div class="panel-title-description">
This configuration can be used to set a passcode policy to an Windows Device.
Once this configuration profile is installed on a device, corresponding users will not be able
to modify these settings on their devices.
</div>
</h2>
<div class="wr-hidden-operations-content col-lg-8">
<!-- passcode-policy -->
<div class="wr-hidden-operation" data-operation="passcode-policy" style="display: block">
<div class="panel panel-default operation-data" data-operation="passcode-policy" data-operation-code="PASSCODE_POLICY">
<div id="passcode-policy-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Passcode Policy
<label id="passcode-policy-lbl" class="wr-input-control switch" data-toggle="collapse" data-target="#passcode-policy-body">
<input type="checkbox" />
<span class="helper"></span>
<span class="text"></span>
</label>
<hr>
<div class="panel-title-description">
This configuration can be used to set a passcode policy to an Windows Device.
Once this configuration profile is installed on a device, corresponding users will not be able
to modify these settings on their devices.
</div>
<div id="passcode-policy-body" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="passcode-policy-body">
</h2>
</div>
<div id="passcode-policy-body" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="passcode-policy-body">
<div id="passcode-policy-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div id="passcode-policy-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="passcode-policy-allow-simple" type="checkbox" class="form-control operationDataKeys" data-key="passcodePolicyAllowSimple" checked="checked" />
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="passcode-policy-allow-simple" type="checkbox" class="form-control operationDataKeys" data-key="passcodePolicyAllowSimple" checked="checked" />
<span class="helper" title="Permit the use of repeating, ascending and descending character sequences">
&nbsp;&nbsp;&nbsp;Allow simple value
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
</label>
</div>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="passcode-policy-require-alphanumeric" type="checkbox" class="form-control operationDataKeys" data-key="passcodePolicyRequireAlphanumeric" checked="checked" />
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="passcode-policy-require-alphanumeric" type="checkbox" class="form-control operationDataKeys" data-key="passcodePolicyRequireAlphanumeric" checked="checked" />
<span class="helper" title="Require passcode to contain both letters and numbers">
&nbsp;&nbsp;&nbsp;Require alphanumeric value
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
</label>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-min-length">
Minimum passcode length
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-min-length">
Minimum passcode length
<span class="helper" title="Minimum number of characters allowed in a passcode">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="passcode-policy-min-length" class="form-control operationDataKeys" data-key="passcodePolicyMinLength" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
</select>
</div>
</label>
<select id="passcode-policy-min-length" class="form-control operationDataKeys" data-key="passcodePolicyMinLength" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-min-complex-chars">
Minimum number of complex characters
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-min-complex-chars">
Minimum number of complex characters
<span class="helper" title="Minimum number of complex or non-alphanumeric characters allowed in a passcode">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="passcode-policy-min-complex-chars" class="form-control operationDataKeys" data-key="passcodePolicyMinComplexChars" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="1">01</option>
<option value="2">02</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
</select>
</div>
</label>
<select id="passcode-policy-min-complex-chars" class="form-control operationDataKeys" data-key="passcodePolicyMinComplexChars" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="1">01</option>
<option value="2">02</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-max-passcode-age-in-days">
Maximum passcode age in days
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-max-passcode-age-in-days">
Maximum passcode age in days
<span class="helper" title="Number of days after which a passcode must be changed">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
( Should be in between 1-to-730 days or none )
</label>
<input id="passcode-policy-max-passcode-age-in-days" type="text" class="form-control operationDataKeys" data-key="passcodePolicyMaxPasscodeAgeInDays" maxlength="3" placeholder="[ Requires Number Input ]">
</div>
<br>
( Should be in between 1-to-730 days or none )
</label>
<input id="passcode-policy-max-passcode-age-in-days" type="text" class="form-control operationDataKeys" data-key="passcodePolicyMaxPasscodeAgeInDays" maxlength="3" placeholder="[ Requires Number Input ]">
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-passcode-history">
Passcode history
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-passcode-history">
Passcode history
<span class="helper" title="Number of consequent unique passcodes to be used before reuse">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
( Should be in between 1-to-50 passcodes or none )
</label>
<input id="passcode-policy-passcode-history" type="text" class="form-control operationDataKeys" data-key="passcodePolicyPasscodeHistory" maxlength="2" placeholder="[ Requires Number Input ]">
</div>
<br>
( Should be in between 1-to-50 passcodes or none )
</label>
<input id="passcode-policy-passcode-history" type="text" class="form-control operationDataKeys" data-key="passcodePolicyPasscodeHistory" maxlength="2" placeholder="[ Requires Number Input ]">
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcodePolicyMaxFailedAttempts">
Maximum number of failed attempts
<div class="wr-input-control">
<label class="wr-input-label" for="passcodePolicyMaxFailedAttempts">
Maximum number of failed attempts
<span class="helper" title="Maximum number of passcode entry attempts allowed before all data on a device will be erased">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="passcode-policy-max-failed-attempts" class="form-control operationDataKeys" data-key="passcodePolicyMaxFailedAttempts" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
</select>
</div>
</div>
</label>
<select id="passcode-policy-max-failed-attempts" class="form-control operationDataKeys" data-key="passcodePolicyMaxFailedAttempts" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
</select>
</div>
</div>
<!-- /passcode-policy -->
</div>
</div>
<!-- /passcode-policy -->
<!-- camera -->
<div class="wr-hidden-operation" data-operation="camera">
<div class="panel panel-default operation-data" data-operation="camera" data-operation-code="CAMERA">
<div id="camera-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Restrictions on Camera
<label class="wr-input-control switch" data-toggle="collapse" data-target="#camera-body">
<input type="checkbox" />
<span class="helper"></span>
<span class="text"></span>
</label>
<hr>
<div class="panel-title-description">
This configuration can be used to restrict the usage of camera on an Windows device together with all the applications using the camera.
Once this configuration profile is installed on a device, corresponding users will not be able
to modify these settings on their devices.
</div>
</h2>
<!-- camera -->
<div class="wr-hidden-operation" data-operation="camera">
<div class="panel panel-default operation-data" data-operation="camera" data-operation-code="CAMERA">
<div id="camera-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Restrictions on Camera
<label class="wr-input-control switch" data-toggle="collapse" data-target="#camera-body">
<input type="checkbox" />
<span class="helper"></span>
<span class="text"></span>
</label>
<hr>
<div class="panel-title-description">
This configuration can be used to restrict the usage of camera on an Windows device together with all the applications using the camera.
Once this configuration profile is installed on a device, corresponding users will not be able
to modify these settings on their devices.
</div>
<div id="camera-body" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="camera-body">
<div id="camera-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
Un-check following checkbox in case you need to disable camera.
<br>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="camera-enabled" type="checkbox" class="operationDataKeys" data-key="cameraEnabled" checked="checked" />
</h2>
</div>
<div id="camera-body" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="camera-body">
<div id="camera-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
Un-check following checkbox in case you need to disable camera.
<br>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="camera-enabled" type="checkbox" class="operationDataKeys" data-key="cameraEnabled" checked="checked" />
<span class="helper" title="Having this checked would enable Usage of phone camera in the device.">
&nbsp;&nbsp;&nbsp;Allow use of camera
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
</div>
</label>
</div>
<br>
</div>
<!-- /camera -->
</div>
</div>
<!-- /camera -->
<!-- encrypt-storage -->
<div class="wr-hidden-operation" data-operation="encrypt-storage">
<div class="panel panel-default operation-data" data-operation="encrypt-storage" data-operation-code="ENCRYPT_STORAGE">
<div id="encrypt-storage-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Encryption Settings
<label class="wr-input-control switch" data-toggle="collapse" data-target="#encrypt-storage-body">
<input type="checkbox" />
<span class="helper"></span>
<span class="text"></span>
</label>
<hr>
<div class="panel-title-description">
This configuration can be used to encrypt data on an Windows device, when the device is locked and
make it readable when the passcode is entered. Once this configuration profile is installed on a device,
corresponding users will not be able to modify these settings on their devices.
</div>
</h2>
<!-- encrypt-storage -->
<div class="wr-hidden-operation" data-operation="encrypt-storage">
<div class="panel panel-default operation-data" data-operation="encrypt-storage" data-operation-code="ENCRYPT_STORAGE">
<div id="encrypt-storage-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Encryption Settings
<label class="wr-input-control switch" data-toggle="collapse" data-target="#encrypt-storage-body">
<input type="checkbox" />
<span class="helper"></span>
<span class="text"></span>
</label>
<hr>
<div class="panel-title-description">
This configuration can be used to encrypt data on an Windows device, when the device is locked and
make it readable when the passcode is entered. Once this configuration profile is installed on a device,
corresponding users will not be able to modify these settings on their devices.
</div>
<div id="encrypt-storage-body" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="encrypt-storage-body">
<div id="encrypt-storage-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
Un-check following checkbox in case you need to disable storage-encryption.
<br>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="encrypt-storage-enabled" type="checkbox" class="operationDataKeys" data-key="encryptStorageEnabled" checked="checked" />
</h2>
</div>
<div id="encrypt-storage-body" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="encrypt-storage-body">
<div id="encrypt-storage-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
Un-check following checkbox in case you need to disable storage-encryption.
<br>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="encrypt-storage-enabled" type="checkbox" class="operationDataKeys" data-key="encryptStorageEnabled" checked="checked" />
<span class="helper" title="Having this checked would enable Storage-encryption in the device">
&nbsp;&nbsp;&nbsp;Enable storage-encryption
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
</label>
</div>
<br>
</div>
</div>
</div>
<!-- /encrypt-storage -->
<!--app-restriction-->
<div class="wr-hidden-operation" data-operation="app-restriction">
<div class="panel panel-default operation-data" data-operation="app-restriction" data-operation-code="APP-RESTRICTION">
<div id="app-restriction-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Application Restriction Settings
<label class="wr-input-control switch" data-toggle="collapse" data-target="#app-restriction-body">
<input type="checkbox" />
<span class="helper"></span>
<span class="text"></span>
</label>
<hr>
<div class="panel-title-description">
This configuration can be used to create a black list or white list of applications.
</div>
</h2>
</div>
<div id="app-restriction-body" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="app-restriction-body">
<div id="app-restriction-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<select id="app-restriction-type" class="form-control operationDataKeys" data-key="restrictionType">
<option value="" selected="selected">
None
</option>
<option value="black-list">Black List</option>
<option value="white-list">White List</option>
</select>
<div class="wr-input-control">
<label class="wr-input-label" for="restricted-applications">
Restricted Application List
<span class="helper" title="Add an application to restrict.">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
<a href="#restricted-applications-grid" class="grid-input-add" data-click-event="add-form">
<span class="icon fw-stack">
<i class="fw fw-add fw-stack-1x"></i>
<i class="fw fw-ring fw-stack-2x"></i>
</span>
&nbsp;
Add Application
</a>
</label>
<div id="restricted-applications" class="operationDataKeys grouped-array-input multi-column-key-value-pair-array" data-key="restrictedApplications" data-column-count="2">
<table class="table table-responsive table-striped">
<thead>
<tr>
<th>No:</th>
<th>Application Name/Description</th>
<th>Package Name</th>
<th></th>
</tr>
</thead>
<tbody data-add-form-container="#restricted-applications-grid">
<tr data-help-text="add-form">
<td colspan="4">
No entries added yet .
</td>
</tr>
</tbody>
</table>
<table class="template hidden">
<tbody data-add-form="#restricted-applications-grid">
<tr data-add-form-element="clone">
<td data-title="No:">
<span class="index"></span>
</td>
<td data-title="App Name">
<input type="text" class="form-control grid-input-text" data-child-key="appName" maxlength="100" data-default="" placeholder="[ Application Name or Description ]" />
</td>
<td data-title="Package Name">
<input type="text" class="form-control grid-input-text" data-child-key="packageName" maxlength="100" data-default="" placeholder="[ Package Name of Application ]" />
</td>
<td>
<span class="list-group-item-actions">
<a href="#restricted-applications-grid" class="grid-input-remove" data-click-event="remove-form">
<span class="fw-stack helper" title="Remove Entry">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-delete fw-stack-1x"></i>
</span>
</a>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- /encrypt-storage -->
</div>
</div>
<!--/app-restriction-->
<!-- wi-fi -->
<!--<div class="wr-hidden-operation" data-operation="wifi">-->
<!--<div class="panel panel-default operation-data" data-operation="wifi" data-operation-code="WIFI">-->
<!--<div id="wifi-heading" class="panel-heading" role="tab">-->
<!--<h2 class="sub-title panel-title">-->
<!--Wi-Fi Settings-->
<!--<label class="wr-input-control switch" data-toggle="collapse" data-target="#wifi-body">-->
<!--<input type="checkbox" />-->
<!--<span class="helper"></span>-->
<!--<span class="text"></span>-->
<!--</label>-->
<!--<hr>-->
<!--<div class="panel-title-description">-->
<!--This configurations can be used to configure Wi-Fi access on an Android device.-->
<!--Once this configuration profile is installed on a device, corresponding users will not be able-->
<!--to modify these settings on their devices.-->
<!--</div>-->
<!--</h2>-->
<!--</div>-->
<!--<div id="wifi-body" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="wifi-body">-->
<!--&lt;!&ndash;<div class="cloneable">&ndash;&gt;-->
<!--&lt;!&ndash;<a href="#" class="multi-view add enabled">&ndash;&gt;-->
<!--&lt;!&ndash;<span class="icon fw-stack">&ndash;&gt;-->
<!--&lt;!&ndash;<i class="fw fw-add fw-stack-1x"></i>&ndash;&gt;-->
<!--&lt;!&ndash;<i class="fw fw-ring fw-stack-2x"></i>&ndash;&gt;-->
<!--&lt;!&ndash;</span>&ndash;&gt;-->
<!--&lt;!&ndash;</a>&ndash;&gt;-->
<!--&lt;!&ndash;<a href="#" class="multi-view remove disabled">&ndash;&gt;-->
<!--&lt;!&ndash;<span class="icon fw-stack">&ndash;&gt;-->
<!--&lt;!&ndash;<i class="fw fw-minus fw-stack-1x"></i>&ndash;&gt;-->
<!--&lt;!&ndash;<i class="fw fw-ring fw-stack-2x"></i>&ndash;&gt;-->
<!--&lt;!&ndash;</span>&ndash;&gt;-->
<!--&lt;!&ndash;</a>&ndash;&gt;-->
<!--&lt;!&ndash;Wi-Fi Setting :&ndash;&gt;-->
<!--&lt;!&ndash;<br>&ndash;&gt;-->
<!--&lt;!&ndash;<br>&ndash;&gt;-->
<!--Please note that * sign represents required fields of data.-->
<!--<br>-->
<!--<br>-->
<!--<div id="wifi-feature-error-msg" class="alert alert-danger hidden" role="alert">-->
<!--<i class="icon fw fw-error"></i><span></span>-->
<!--</div>-->
<!--<div class="wr-input-control">-->
<!--<label class="wr-input-label" for="wifi-ssid">-->
<!--Service Set Identifier (SSID) *-->
<!--<span class="helper" title="Identification of the wireless network to be configured.">-->
<!--<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>-->
<!--</span>-->
<!--<br>-->
<!--( should be 1-to-30 characters long )-->
<!--</label>-->
<!--<input id="wifi-ssid" type="text" class="form-control operationDataKeys" data-key="wifiSSID" maxlength="100" placeholder="[ Required field ]"/>-->
<!--</div>-->
<!--<div class="wr-input-control">-->
<!--<label class="wr-input-label" for="wifi-password">-->
<!--Password-->
<!--<span class="helper" title="Password for the wireless network.">-->
<!--<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>-->
<!--</span>-->
<!--</label>-->
<!--<input id="wifi-password" type="text" class="form-control operationDataKeys" data-key="wifiPassword" maxlength="100" placeholder="[ Optional field ]"/>-->
<!--</div>-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!-- /wi-fi -->
<!-- install-applications -->
<!--<div class="wr-hidden-operation" data-operation="install-apps">-->
<!--<div class="panel panel-default operation-data" data-operation="INSTALL_APPLICATION">-->
<!--<div class="panel-heading" role="tab">-->
<!--<h2 class="sub-title panel-title">-->
<!--<br>-->
<!--&nbsp;&nbsp;&nbsp;App Installations-->
<!--<label class="wr-input-control switch" data-toggle="collapse" data-target="#installApp">-->
<!--<input type="checkbox" />-->
<!--<span class="helper"></span>-->
<!--<span class="text"></span>-->
<!--</label>-->
<!--<br>-->
<!--<br>-->
<!--</h2>-->
<!--</div>-->
<!--<div id="installApp" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="installApp">-->
<!--<div id="install-app-feature-error-msg" class="alert alert-danger hidden" role="alert">-->
<!--<i class="icon fw fw-error"></i><span></span>-->
<!--</div>-->
<!--<label class="wr-input-label" title="Application Identifier">App Identifier<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>-->
<!-- wi-fi -->
<!--<div class="wr-hidden-operation" data-operation="wifi">-->
<!--<div class="panel panel-default operation-data" data-operation="wifi" data-operation-code="WIFI">-->
<!--<div id="wifi-heading" class="panel-heading" role="tab">-->
<!--<h2 class="sub-title panel-title">-->
<!--Wi-Fi Settings-->
<!--<label class="wr-input-control switch" data-toggle="collapse" data-target="#wifi-body">-->
<!--<input type="checkbox" />-->
<!--<span class="helper"></span>-->
<!--<span class="text"></span>-->
<!--</label>-->
<!--<hr>-->
<!--<div class="panel-title-description">-->
<!--This configurations can be used to configure Wi-Fi access on an Android device.-->
<!--Once this configuration profile is installed on a device, corresponding users will not be able-->
<!--to modify these settings on their devices.-->
<!--</div>-->
<!--</h2>-->
<!--</div>-->
<!--<div id="wifi-body" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="wifi-body">-->
<!--&lt;!&ndash;<div class="cloneable">&ndash;&gt;-->
<!--&lt;!&ndash;<a href="#" class="multi-view add enabled">&ndash;&gt;-->
<!--&lt;!&ndash;<span class="icon fw-stack">&ndash;&gt;-->
<!--&lt;!&ndash;<i class="fw fw-add fw-stack-1x"></i>&ndash;&gt;-->
<!--&lt;!&ndash;<i class="fw fw-ring fw-stack-2x"></i>&ndash;&gt;-->
<!--&lt;!&ndash;</span>&ndash;&gt;-->
<!--&lt;!&ndash;</a>&ndash;&gt;-->
<!--&lt;!&ndash;<a href="#" class="multi-view remove disabled">&ndash;&gt;-->
<!--&lt;!&ndash;<span class="icon fw-stack">&ndash;&gt;-->
<!--&lt;!&ndash;<i class="fw fw-minus fw-stack-1x"></i>&ndash;&gt;-->
<!--&lt;!&ndash;<i class="fw fw-ring fw-stack-2x"></i>&ndash;&gt;-->
<!--&lt;!&ndash;</span>&ndash;&gt;-->
<!--&lt;!&ndash;</a>&ndash;&gt;-->
<!--&lt;!&ndash;Wi-Fi Setting :&ndash;&gt;-->
<!--&lt;!&ndash;<br>&ndash;&gt;-->
<!--&lt;!&ndash;<br>&ndash;&gt;-->
<!--Please note that * sign represents required fields of data.-->
<!--<br>-->
<!--<br>-->
<!--<div id="wifi-feature-error-msg" class="alert alert-danger hidden" role="alert">-->
<!--<i class="icon fw fw-error"></i><span></span>-->
<!--</div>-->
<!--<div class="wr-input-control">-->
<!--<label class="wr-input-label" for="wifi-ssid">-->
<!--Service Set Identifier (SSID) *-->
<!--<span class="helper" title="Identification of the wireless network to be configured.">-->
<!--<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>-->
<!--</span>-->
<!--<br>-->
<!--( should be 1-to-30 characters long )-->
<!--</label>-->
<!--<input id="wifi-ssid" type="text" class="form-control operationDataKeys" data-key="wifiSSID" maxlength="100" placeholder="[ Required field ]"/>-->
<!--</div>-->
<!--<div class="wr-input-control">-->
<!--<label class="wr-input-label" for="wifi-password">-->
<!--Password-->
<!--<span class="helper" title="Password for the wireless network.">-->
<!--<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>-->
<!--</span>-->
<!--</label>-->
<!--<input id="wifi-password" type="text" class="form-control operationDataKeys" data-key="wifiPassword" maxlength="100" placeholder="[ Optional field ]"/>-->
<!--</div>-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!-- /wi-fi -->
<!--<div class="wr-input-control">-->
<!--<input type="text" class="form-control operationDataKeys" id="package-name" data-key="packageName" placeholder="Enter App Identifier"/>-->
<!--</div>-->
<!--<div class="wr-input-control">-->
<!--<label class="wr-input-control dropdown">-->
<!--<span class="helper" title="App Type">App Type<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></span>-->
<!--<select class="form-control col-sm-8 operationDataKeys appTypesInput" id="type" data-key="type">-->
<!--<option>Public</option>-->
<!--<option>Enterprise</option>-->
<!--</select>-->
<!--</label>-->
<!--</div>-->
<!--<label class="wr-input-label" title="URL">URL<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>-->
<!-- install-applications -->
<!--<div class="wr-hidden-operation" data-operation="install-apps">-->
<!--<div class="panel panel-default operation-data" data-operation="INSTALL_APPLICATION">-->
<!--<div class="panel-heading" role="tab">-->
<!--<h2 class="sub-title panel-title">-->
<!--<br>-->
<!--&nbsp;&nbsp;&nbsp;App Installations-->
<!--<label class="wr-input-control switch" data-toggle="collapse" data-target="#installApp">-->
<!--<input type="checkbox" />-->
<!--<span class="helper"></span>-->
<!--<span class="text"></span>-->
<!--</label>-->
<!--<br>-->
<!--<br>-->
<!--</h2>-->
<!--</div>-->
<!--<div id="installApp" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="installApp">-->
<!--<div id="install-app-feature-error-msg" class="alert alert-danger hidden" role="alert">-->
<!--<i class="icon fw fw-error"></i><span></span>-->
<!--</div>-->
<!--<label class="wr-input-label" title="Application Identifier">App Identifier<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>-->
<!--<div class="wr-input-control">-->
<!--<input type="text" class="form-control operationDataKeys" id="url" data-key="url" placeholder="Enter URL"/>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!-- /install-applications -->
<!--<div class="wr-input-control">-->
<!--<input type="text" class="form-control operationDataKeys" id="package-name" data-key="packageName" placeholder="Enter App Identifier"/>-->
<!--</div>-->
<!--<div class="wr-input-control">-->
<!--<label class="wr-input-control dropdown">-->
<!--<span class="helper" title="App Type">App Type<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></span>-->
<!--<select class="form-control col-sm-8 operationDataKeys appTypesInput" id="type" data-key="type">-->
<!--<option>Public</option>-->
<!--<option>Enterprise</option>-->
<!--</select>-->
<!--</label>-->
<!--</div>-->
<!--<label class="wr-input-label" title="URL">URL<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>-->
<!-- /uninstall-applications -->
<!--<div class="wr-hidden-operation" data-operation="uninstall-apps">-->
<!--<div class="panel panel-default operation-data" data-operation="UNINSTALL_APPLICATION">-->
<!--<div class="panel-heading" role="tab">-->
<!--<h2 class="sub-title panel-title">-->
<!--<br>-->
<!--&nbsp;&nbsp;&nbsp;App Uninstallations-->
<!--<label class="wr-input-control switch" data-toggle="collapse" data-target="#uninstallApp">-->
<!--<input type="checkbox" />-->
<!--<span class="helper"></span>-->
<!--<span class="text"></span>-->
<!--</label>-->
<!--<br>-->
<!--<br>-->
<!--</h2>-->
<!--</div>-->
<!--<div id="uninstallApp" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="uninstallApp">-->
<!--<div id="uninstall-app-feature-error-msg" class="alert alert-danger hidden" role="alert">-->
<!--<i class="icon fw fw-error"></i><span></span>-->
<!--</div>-->
<!--<label class="wr-input-label" title="Application Identifier">App Identifier<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>-->
<!--<!--span>Identification of the wireless network to connect to</span-->
<!--<div class="wr-input-control">-->
<!--<input type="text" class="form-control operationDataKeys" id="package-name" data-key="packageName" placeholder="Enter App Identifier"/>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!-- /uninstall-applications -->
<!--<div class="wr-input-control">-->
<!--<input type="text" class="form-control operationDataKeys" id="url" data-key="url" placeholder="Enter URL"/>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!-- /install-applications -->
<!-- /web-clips -->
<!--<div class="wr-hidden-operation" data-operation="web-clips">-->
<!--<div class="panel panel-default operation-data" data-operation="WEBCLIP">-->
<!--<div class="panel-heading" role="tab">-->
<!--<h2 class="sub-title panel-title">-->
<!--<br>-->
<!--&nbsp;&nbsp;&nbsp;Web clips-->
<!--<label class="wr-input-control switch" data-toggle="collapse" data-target="#installWebClip">-->
<!--<input type="checkbox" />-->
<!--<span class="helper"></span>-->
<!--<span class="text"></span>-->
<!--</label>-->
<!--<br>-->
<!--<br>-->
<!--</h2>-->
<!--</div>-->
<!--<div id="installWebClip" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="installWebClip">-->
<!--<div id="install-webclip-feature-error-msg" class="alert alert-danger hidden" role="alert">-->
<!--<i class="icon fw fw-error"></i><span></span>-->
<!--</div>-->
<!--<label class="wr-input-label" title="Title of the web clip">Title<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>-->
<!--<div class="wr-input-control">-->
<!--<input type="text" class="form-control operationDataKeys" id="title" data-key="title" placeholder="Enter Title"/>-->
<!--</div>-->
<!--<label class="wr-input-label" title="URL">URL<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>-->
<!--<div class="wr-input-control">-->
<!--<input type="text" class="form-control operationDataKeys" id="url" data-key="url" placeholder="Enter URL"/>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!-- /web-clips -->
</div>
<!-- /uninstall-applications -->
<!--<div class="wr-hidden-operation" data-operation="uninstall-apps">-->
<!--<div class="panel panel-default operation-data" data-operation="UNINSTALL_APPLICATION">-->
<!--<div class="panel-heading" role="tab">-->
<!--<h2 class="sub-title panel-title">-->
<!--<br>-->
<!--&nbsp;&nbsp;&nbsp;App Uninstallations-->
<!--<label class="wr-input-control switch" data-toggle="collapse" data-target="#uninstallApp">-->
<!--<input type="checkbox" />-->
<!--<span class="helper"></span>-->
<!--<span class="text"></span>-->
<!--</label>-->
<!--<br>-->
<!--<br>-->
<!--</h2>-->
<!--</div>-->
<!--<div id="uninstallApp" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="uninstallApp">-->
<!--<div id="uninstall-app-feature-error-msg" class="alert alert-danger hidden" role="alert">-->
<!--<i class="icon fw fw-error"></i><span></span>-->
<!--</div>-->
<!--<label class="wr-input-label" title="Application Identifier">App Identifier<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>-->
<!--<!--span>Identification of the wireless network to connect to</span-->
<!--<div class="wr-input-control">-->
<!--<input type="text" class="form-control operationDataKeys" id="package-name" data-key="packageName" placeholder="Enter App Identifier"/>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!-- /uninstall-applications -->
<!-- /web-clips -->
<!--<div class="wr-hidden-operation" data-operation="web-clips">-->
<!--<div class="panel panel-default operation-data" data-operation="WEBCLIP">-->
<!--<div class="panel-heading" role="tab">-->
<!--<h2 class="sub-title panel-title">-->
<!--<br>-->
<!--&nbsp;&nbsp;&nbsp;Web clips-->
<!--<label class="wr-input-control switch" data-toggle="collapse" data-target="#installWebClip">-->
<!--<input type="checkbox" />-->
<!--<span class="helper"></span>-->
<!--<span class="text"></span>-->
<!--</label>-->
<!--<br>-->
<!--<br>-->
<!--</h2>-->
<!--</div>-->
<!--<div id="installWebClip" class="panel-collapse panel-body collapse" role="tabpanel" aria-labelledby="installWebClip">-->
<!--<div id="install-webclip-feature-error-msg" class="alert alert-danger hidden" role="alert">-->
<!--<i class="icon fw fw-error"></i><span></span>-->
<!--</div>-->
<!--<label class="wr-input-label" title="Title of the web clip">Title<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>-->
<!--<div class="wr-input-control">-->
<!--<input type="text" class="form-control operationDataKeys" id="title" data-key="title" placeholder="Enter Title"/>-->
<!--</div>-->
<!--<label class="wr-input-label" title="URL">URL<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>-->
<!--<div class="wr-input-control">-->
<!--<input type="text" class="form-control operationDataKeys" id="url" data-key="url" placeholder="Enter URL"/>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!-- /web-clips -->
</div>
</div>

@ -1,17 +1,17 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* Copyright (c) 2015, 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
* 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
* "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.
*/
@ -23,6 +23,8 @@ var stepBackFrom = {};
var policy = {};
var configuredOperations = [];
var base_api_url = "/api/device-mgt/v1.0";
// Constants to define platform types available
var platformTypeConstants = {
"ANDROID": "android",
@ -102,8 +104,7 @@ var updateGroupedInputVisibility = function (domElement) {
skipStep["policy-platform"] = function (policyPayloadObj) {
policy["name"] = policyPayloadObj["policyName"];
policy["platform"] = policyPayloadObj["profile"]["deviceType"]["name"];
policy["platformId"] = policyPayloadObj["profile"]["deviceType"]["id"];
policy["platform"] = policyPayloadObj["profile"]["deviceType"];
var userRoleInput = $("#user-roles-input");
var ownershipInput = $("#ownership-input");
var userInput = $("#users-select-field");
@ -1788,7 +1789,7 @@ var updatePolicy = function (policy, state) {
if (policy["profile"].hasOwnProperty(key)) {
profilePayloads.push({
"featureCode": key,
"deviceTypeId": policy["platformId"],
"deviceType": policy["platform"],
"content": policy["profile"][key]
});
}
@ -1800,9 +1801,7 @@ var updatePolicy = function (policy, state) {
"ownershipType": policy["selectedOwnership"],
"profile": {
"profileName": policy["policyName"],
"deviceType": {
"id": policy["platformId"]
},
"deviceType": policy["platform"],
"profileFeaturesList": profilePayloads
}
};
@ -1815,7 +1814,7 @@ var updatePolicy = function (policy, state) {
payload["users"] = [];
payload["roles"] = [];
}
var serviceURL = "/devicemgt_admin/policies/" + getParameterByName("id");
var serviceURL = base_api_url + "/policies/" + getParameterByName("id");
invokerUtil.put(
serviceURL,
payload,
@ -1824,7 +1823,7 @@ var updatePolicy = function (policy, state) {
if (state == "save") {
var policyList = [];
policyList.push(getParameterByName("id"));
serviceURL = "/devicemgt_admin/policies/inactivate";
serviceURL = base_api_url + "/policies/deactivate-policy";
invokerUtil.put(
serviceURL,
policyList,
@ -1841,7 +1840,7 @@ var updatePolicy = function (policy, state) {
} else if (state == "publish") {
var policyList = [];
policyList.push(getParameterByName("id"));
serviceURL = "/devicemgt_admin/policies/activate";
serviceURL = base_api_url + "/policies/activate-policy";
invokerUtil.put(
serviceURL,
policyList,
@ -1882,6 +1881,10 @@ var showAdvanceOperation = function (operation, button) {
*/
var slideDownPaneAgainstValueSet = function (selectElement, paneID, valueSet) {
var selectedValueOnChange = $(selectElement).find("option:selected").val();
if ($(selectElement).is("input:checkbox")) {
selectedValueOnChange = $(selectElement).is(":checked").toString();
}
var i, slideDownVotes = 0;
for (i = 0; i < valueSet.length; i++) {
if (selectedValueOnChange == valueSet[i]) {
@ -1979,6 +1982,36 @@ var showHideHelpText = function (addFormContainer) {
}
};
/**
* This method will display appropriate fields based on wifi type
* @param {object} wifi type select object
*/
var changeAndroidWifiPolicy = function (select) {
slideDownPaneAgainstValueSet(select, 'control-wifi-password', ['wep', 'wpa', '802eap']);
slideDownPaneAgainstValueSet(select, 'control-wifi-eap', ['802eap']);
slideDownPaneAgainstValueSet(select, 'control-wifi-phase2', ['802eap']);
slideDownPaneAgainstValueSet(select, 'control-wifi-identity', ['802eap']);
slideDownPaneAgainstValueSet(select, 'control-wifi-anoidentity', ['802eap']);
slideDownPaneAgainstValueSet(select, 'control-wifi-cacert', ['802eap']);
};
/**
* This method will display appropriate fields based on wifi EAP type
* @param {object} wifi eap select object
* @param {object} wifi type select object
*/
var changeAndroidWifiPolicyEAP = function (select, superSelect) {
slideDownPaneAgainstValueSet(select, 'control-wifi-password', ['peap', 'ttls', 'pwd' , 'fast', 'leap']);
slideDownPaneAgainstValueSet(select, 'control-wifi-phase2', ['peap', 'ttls', 'fast']);
slideDownPaneAgainstValueSet(select, 'control-wifi-provisioning', ['fast']);
slideDownPaneAgainstValueSet(select, 'control-wifi-identity', ['peap', 'tls', 'ttls', 'pwd', 'fast', 'leap']);
slideDownPaneAgainstValueSet(select, 'control-wifi-anoidentity', ['peap', 'ttls']);
slideDownPaneAgainstValueSet(select, 'control-wifi-cacert', ['peap', 'tls', 'ttls']);
if (superSelect.value != '802eap') {
changeAndroidWifiPolicy(superSelect);
}
};
// End of functions related to grid-input-view
/**
@ -2000,17 +2033,17 @@ $(document).ready(function () {
var policyPayloadObj;
invokerUtil.get(
"/devicemgt_admin/policies/" + getParameterByName("id"),
base_api_url + "/policies/" + getParameterByName("id"),
// on success
function (data) {
// console.log("success: " + JSON.stringify(data));
data = JSON.parse(data);
policyPayloadObj = data["responseContent"];
skipStep["policy-platform"](policyPayloadObj);
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200 && data) {
policyPayloadObj = JSON.parse(data);
skipStep["policy-platform"](policyPayloadObj);
}
},
// on error
function (data) {
console.log(data);
function (jqXHR) {
console.log(jqXHR);
// should be redirected to an error page
}
);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save