Merge branch 'release-3.0.x' of https://github.com/wso2/carbon-device-mgt-plugins into release-3.0.x

revert-dabc3590
Hasunie 8 years ago
commit ad812f2328

@ -56,13 +56,11 @@ hr {
background-color: #f6f4f4; background-color: #f6f4f4;
} }
.doc-link { .doc-link{
background: #11375B; background: none;
padding: 20px; color: #000;
color: white; padding: 10px 0px;
margin-top: 0;
} }
.doc-link a { .doc-link a {
color: white; color: #006eff;
} }

@ -20,17 +20,15 @@
<hr> <hr>
</div> </div>
<div class="col-xs-12 col-sm-4 col-md-4 col-lg-4 padding-top"> <div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 padding-top">
<img src="{{@unit.publicUri}}/images/android-sense-icon.png" class="img-responsive"> <img src="{{@unit.publicUri}}/images/android-sense-icon.png" class="img-responsive">
</div> </div>
<div class="col-xs-12 col-sm-8 col-md-8 col-lg-8 padding-top"> <div class="col-xs-12 col-sm-8 col-md-8 col-lg-8 padding-top">
<h4 class="doc-link">Click <a href="https://docs.wso2.com/display/IoTS100/Android+Sense"
target="_blank">[ here ]</a> for latest instructions and
troubleshooting.</h4>
</div> </div>
<div class="col-xs-12 col-sm-8 col-md-8 col-lg-8 padding-top"> <div class="col-xs-12 col-sm-8 col-md-9 col-lg-9 padding-top">
<h3 class="uppercase">What it Does</h3> <h3 class="uppercase">What it Does</h3>
<hr> <hr>
<p class="grey margin-top">Connect an Android device to WSO2 IoT Server and visualize sensor <p class="grey margin-top">Connect an Android device to WSO2 IoT Server and visualize sensor
@ -41,24 +39,27 @@
<p class="grey margin-top">You should have an Android Device to get started.</p> <p class="grey margin-top">You should have an Android Device to get started.</p>
<ul class="list-unstyled"> <ul class="list-unstyled">
<li class="padding-top-double"> <li class="padding-top-double">
<span class="circle">STEP 01</span> <span class="badge">STEP 01</span>
Go ahead and click [Enroll Device]. Go ahead and click [Enroll Device].
</li> </li>
<li class="padding-top-double"> <li>
<span class="circle">STEP 02</span> <span class="badge">STEP 02</span>
You can either scan the QR code or directly download Android agent. You can either scan the QR code or directly download Android agent.
</li> </li>
<li class="padding-top-double"> <li>
<span class="circle">STEP 03</span> <span class="badge">STEP 03</span>
Install Android agent into your Android Device. Install Android agent into your Android Device.
</li> </li>
<li class="padding-top-double"><span class="circle">STEP 04</span> <li><span class="badge">STEP 04</span>
Proceed to [Prepare] section. Proceed to [Prepare] section.
</ul> </ul>
<br> <br>
<a href="#" class="download-link btn-operations"> <a href="#" class="download-link btn-operations">
<i class="fw fw-mobile fw-inverse fw-lg"></i> Enroll Device</a> <i class="fw fw-mobile fw-inverse fw-lg"></i> Enroll Device</a>
<br/><br/> <br/><br/>
<p class="doc-link">Click <a href="https://docs.wso2.com/display/IoTS100/Android+Sense"
target="_blank">[ here ]</a> for latest instructions and
troubleshooting.</p>
<div id="device-400-content" class="hide"> <div id="device-400-content" class="hide">
<div class="modal-content"> <div class="modal-content">

@ -226,7 +226,8 @@ public class ArduinoServiceImpl implements ArduinoService {
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService(); APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
String[] tags = {ArduinoConstants.DEVICE_TYPE}; String[] tags = {ArduinoConstants.DEVICE_TYPE};
apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
ArduinoConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true); ArduinoConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true,
ArduinoConstants.APIM_APPLICATION_TOKEN_VALIDITY_PERIOD);
} }
JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient(); JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
String scopes = " device_" + deviceId; String scopes = " device_" + deviceId;

@ -25,4 +25,6 @@ public class ArduinoConstants {
//sensor events summerized table name //sensor events summerized table name
public static final String TEMPERATURE_EVENT_TABLE = "DEVICE_TEMPERATURE_SUMMARY"; public static final String TEMPERATURE_EVENT_TABLE = "DEVICE_TEMPERATURE_SUMMARY";
public static final String APIM_APPLICATION_TOKEN_VALIDITY_PERIOD = "3600";
} }

@ -20,7 +20,7 @@
<hr> <hr>
</div> </div>
<div class="col-xs-12 col-sm-4 col-md-4 col-lg-4 padding-top"> <div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 padding-top">
<img src="{{@unit.publicUri}}/images/ardunio-icon.png" class="img-responsive"> <img src="{{@unit.publicUri}}/images/ardunio-icon.png" class="img-responsive">
</div> </div>
@ -28,7 +28,7 @@
</div> </div>
<div class="col-xs-12 col-sm-8 col-md-8 col-lg-8 padding-top"> <div class="col-xs-12 col-sm-8 col-md-9 col-lg-9 padding-top">
<h3 class="uppercase">What it Does</h3> <h3 class="uppercase">What it Does</h3>
<hr> <hr>
<p class="grey margin-top">Connect Arduino UNO board to WSO2 IoT Server and visualize sensor <p class="grey margin-top">Connect Arduino UNO board to WSO2 IoT Server and visualize sensor

@ -210,7 +210,8 @@ public class RaspberryPiServiceImpl implements RaspberryPiService {
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService(); APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
String[] tags = {RaspberrypiConstants.DEVICE_TYPE}; String[] tags = {RaspberrypiConstants.DEVICE_TYPE};
apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
RaspberrypiConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true); RaspberrypiConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true,
RaspberrypiConstants.APIM_APPLICATION_TOKEN_VALIDITY_PERIOD);
} }
JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient(); JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
String scopes = " device_" + deviceId; String scopes = " device_" + deviceId;

@ -31,4 +31,6 @@ public class RaspberrypiConstants {
//mqtt tranport related constants //mqtt tranport related constants
public static final String MQTT_ADAPTER_TOPIC_PROPERTY_NAME = "mqtt.adapter.topic"; public static final String MQTT_ADAPTER_TOPIC_PROPERTY_NAME = "mqtt.adapter.topic";
public static final String APIM_APPLICATION_TOKEN_VALIDITY_PERIOD = "3600";
} }

@ -20,12 +20,12 @@
<hr> <hr>
</div> </div>
<div class="col-xs-12 col-sm-4 col-md-4 col-lg-4 padding-top"> <div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 padding-top">
<img src="{{@unit.publicUri}}/images/respberry-icon.png" class="img-responsive"> <img src="{{@unit.publicUri}}/images/respberry-icon.png" class="img-responsive">
</div> </div>
<div class="col-xs-12 col-sm-8 col-md-8 col-lg-8 padding-top"> <div class="col-xs-12 col-sm-8 col-md-9 col-lg-9 padding-top">
<h3 class="uppercase">What it Does</h3> <h3 class="uppercase">What it Does</h3>
<hr> <hr>
<p class="grey margin-top">Connect a RaspberryPi to WSO2 IoT Server and manage it.</p> <p class="grey margin-top">Connect a RaspberryPi to WSO2 IoT Server and manage it.</p>

@ -309,7 +309,8 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService(); APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
String[] tags = {VirtualFireAlarmConstants.DEVICE_TYPE}; String[] tags = {VirtualFireAlarmConstants.DEVICE_TYPE};
apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
VirtualFireAlarmConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true); VirtualFireAlarmConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true,
VirtualFireAlarmConstants.APIM_APPLICATION_TOKEN_VALIDITY_PERIOD);
} }
JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient(); JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
String scopes = " device_" + deviceId; String scopes = " device_" + deviceId;

@ -83,4 +83,6 @@ public class VirtualFireAlarmConstants {
public static final String SERVER_NAME = "serverName"; public static final String SERVER_NAME = "serverName";
public static final String MQTT_ADAPTER_TOPIC_PROPERTY_NAME = "mqtt.adapter.topic"; public static final String MQTT_ADAPTER_TOPIC_PROPERTY_NAME = "mqtt.adapter.topic";
public static final String APIM_APPLICATION_TOKEN_VALIDITY_PERIOD = "3600";
} }

@ -56,13 +56,11 @@ hr {
background-color: #f6f4f4; background-color: #f6f4f4;
} }
.doc-link { .doc-link{
background: #11375B; background: none;
padding: 20px; color: #000;
color: white; padding: 10px 0px;
margin-top: 0;
} }
.doc-link a { .doc-link a {
color: white; color: #006eff;
} }

@ -19,15 +19,10 @@
<h1 class="grey ">Virtual Firealarm</h1> <h1 class="grey ">Virtual Firealarm</h1>
<hr> <hr>
</div> </div>
<div class="col-xs-12 col-sm-4 col-md-4 col-lg-4 padding-top"> <div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 padding-top">
<img src="{{@unit.publicUri}}/images/firealarm-icon.png" class="img-responsive"> <img src="{{@unit.publicUri}}/images/firealarm-icon.png" class="img-responsive">
</div> </div>
<div class="col-xs-12 col-sm-8 col-md-8 col-lg-8 padding-top"> <div class="col-xs-12 col-sm-8 col-md-9 col-lg-9 padding-top">
<h4 class="doc-link">Click <a href="https://docs.wso2.com/display/IoTS100/Virtual+Firealarm"
target="_blank">[ here ]</a> for latest instructions and
troubleshooting.</h4>
</div>
<div class="col-xs-12 col-sm-8 col-md-8 col-lg-8 padding-top">
<h3 class="uppercase">What it Does</h3> <h3 class="uppercase">What it Does</h3>
<hr> <hr>
<p class="grey margin-top">A Virtual Device that mimics the functionality of a real Firealarm. <p class="grey margin-top">A Virtual Device that mimics the functionality of a real Firealarm.
@ -40,15 +35,15 @@
<hr> <hr>
<ul class="list-unstyled"> <ul class="list-unstyled">
<li class="padding-top-double"> <li class="padding-top-double">
<span class="circle">STEP 01</span> <span class="badge">STEP 01</span>
Go ahead and [Download] the Device. Go ahead and [Download] the Device.
</li> </li>
<li class="padding-top-double"> <li>
<span class="circle">STEP 02</span> <span class="badge">STEP 02</span>
Proceed to [Prepare] section. Proceed to [Prepare] section.
</li> </li>
<li class="padding-top-double"> <li>
<span class="circle">STEP 03</span> <span class="badge">STEP 03</span>
Read [Try Out] section to further experiment with the device. Read [Try Out] section to further experiment with the device.
</li> </li>
</ul> </ul>
@ -59,7 +54,9 @@
</a> </a>
<a href="#" class="download-link btn-operations"> <a href="#" class="download-link btn-operations">
<i class="fw fw-download"></i>Download Agent</a> <i class="fw fw-download"></i>Download Agent</a>
<p class="doc-link">Click <a href="https://docs.wso2.com/display/IoTS100/Virtual+Firealarm"
target="_blank">[ here ]</a> for latest instructions and
troubleshooting.</p>
<div id="download-device-modal-content" class="hide"> <div id="download-device-modal-content" class="hide">
<div class="modal-header"> <div class="modal-header">
<h4 class="pull-left modal-title"> <h4 class="pull-left modal-title">

@ -16,7 +16,8 @@
under the License. under the License.
}} }}
{{#if control_operations}} {{#if control_operations}}
<div class="wr-operations" style="height: 87px; display: block;"> <div class="wr-operations" style="height: 87px; display: block;"
xmlns="http://www.w3.org/1999/html">
<style> <style>
::-webkit-input-placeholder { ::-webkit-input-placeholder {
color: #B8B8B8; color: #B8B8B8;
@ -55,7 +56,7 @@
<h3> <h3>
<span class="fw-stack"> <span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i> <i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-service fw-stack-1x"></i> <i class="fw {{iconFont}} fw-stack-1x"></i>
</span> </span>
{{name}} {{name}}
<br> <br>
@ -68,7 +69,9 @@
<form action="{{params.0.uri}}" method="{{params.0.method}}" <form action="{{params.0.uri}}" method="{{params.0.method}}"
style="padding-bottom: 20px;" style="padding-bottom: 20px;"
data-payload="{{payload}}" id="form-{{operation}}" data-payload="{{payload}}" id="form-{{operation}}"
data-device-id="{{../device.deviceIdentifier}}"> data-device-id="{{../device.deviceIdentifier}}"
data-content-type="{{params.0.contentType}}"
data-operation-code="{{operation}}">
{{#each params.0.pathParams}} {{#each params.0.pathParams}}
<input type="{{type}}" id="{{name}}" placeholder="{{name}}" class="form-control" data-param-type="path" value="{{value}}" /> <input type="{{type}}" id="{{name}}" placeholder="{{name}}" class="form-control" data-param-type="path" value="{{value}}" />
<br /> <br />
@ -81,8 +84,24 @@
<input type="{{type}}" id="{{name}}" placeholder="{{name}}" class="form-control" data-param-type="query" value="{{value}}" /> <input type="{{type}}" id="{{name}}" placeholder="{{name}}" class="form-control" data-param-type="query" value="{{value}}" />
<br /> <br />
{{/each}} {{/each}}
{{#each uiParams}}
{{#equal this.type "checkbox"}}
<input type="{{this.type}}" id="{{this.id}}"
class="checkbox"
placeholder="{{this.label}}"
data-param-type="form"/>
{{this.label}}
<br/>
{{/equal}}
{{#equal this.type "text"}}
<input type="{{this.type}}" id="{{this.id}}"
placeholder="{{this.label}}" class="form-control"
data-param-type="form" value=""/>
<br/>
{{/equal}}
{{/each}}
<button id="btnSend" type="button" onclick="submitForm('form-{{operation}}')" class="btn btn-default">&nbsp;&nbsp;&nbsp;&nbsp;Send <button id="btnSend" type="button" onclick="submitForm('form-{{operation}}')" class="btn btn-default">&nbsp;&nbsp;&nbsp;&nbsp;Send
to Device&nbsp;&nbsp;&nbsp;&nbsp;</button> to Device&nbsp;&nbsp;&nbsp;&nbsp;</button>
<label id="lblSending" class="wr-input-label hidden"><i <label id="lblSending" class="wr-input-label hidden"><i
class="fw fw-lifecycle fw-spin fw-2x"></i> Sending..</label> class="fw fw-lifecycle fw-spin fw-2x"></i> Sending..</label>
<label id="lblSent" class="wr-input-label hidden"><i <label id="lblSent" class="wr-input-label hidden"><i

@ -28,13 +28,14 @@ function onRequest(context) {
var pathParams = []; var pathParams = [];
for (var i = 0; i < controlOperations.length; i++) { for (var i = 0; i < controlOperations.length; i++) {
var currentParamList = controlOperations[i]["params"]; var currentParamList = controlOperations[i]["params"];
var uiParamList = controlOperations[i]["uiParams"];
for (var j = 0; j < currentParamList.length; j++) { for (var j = 0; j < currentParamList.length; j++) {
var currentParam = currentParamList[j]; var currentParam = currentParamList[j];
currentParamList[j]["formParams"] = processParams(currentParam["formParams"], autoCompleteParams); currentParamList[j]["formParams"] = processParams(currentParam["formParams"], autoCompleteParams);
currentParamList[j]["queryParams"] = processParams(currentParam["queryParams"], autoCompleteParams); currentParamList[j]["queryParams"] = processParams(currentParam["queryParams"], autoCompleteParams);
currentParamList[j]["pathParams"] = processParams(currentParam["pathParams"], autoCompleteParams); currentParamList[j]["pathParams"] = processParams(currentParam["pathParams"], autoCompleteParams);
} }
controlOperations[i]["params"] = currentParamList; controlOperations[i]["uiParams"] = uiParamList;
if (encodedFeaturePayloads) { if (encodedFeaturePayloads) {
controlOperations[i]["payload"] = getPayload(encodedFeaturePayloads, controlOperations[i]["operation"]); controlOperations[i]["payload"] = getPayload(encodedFeaturePayloads, controlOperations[i]["operation"]);
} }

@ -31,6 +31,8 @@ function submitForm(formId) {
var form = $("#" + formId); var form = $("#" + formId);
var uri = form.attr("action"); var uri = form.attr("action");
var deviceId = form.data("device-id"); var deviceId = form.data("device-id");
var contentType = form.data("content-type");
var operationCode = form.data("operation-code");
var uriencodedQueryStr = ""; var uriencodedQueryStr = "";
var uriencodedFormStr = ""; var uriencodedFormStr = "";
var payload = {}; var payload = {};
@ -44,21 +46,18 @@ function submitForm(formId) {
} else if (input.data("param-type") == "form") { } else if (input.data("param-type") == "form") {
var prefix = (uriencodedFormStr == "") ? "" : "&"; var prefix = (uriencodedFormStr == "") ? "" : "&";
uriencodedFormStr += prefix + input.attr("id") + "=" + input.val(); uriencodedFormStr += prefix + input.attr("id") + "=" + input.val();
//payload[input.attr("id")] = input.val(); if(input.attr("type") == "text"){
payload[input.attr("id")] = input.val();
} else if(input.attr("type") == "checkbox"){
payload[input.attr("id")] = input.is(":checked");
}
} }
}); });
uri += uriencodedQueryStr; uri += uriencodedQueryStr;
var httpMethod = form.attr("method").toUpperCase(); var httpMethod = form.attr("method").toUpperCase();
var contentType = form.attr("enctype"); //var contentType = form.attr("enctype");
console.log("URL "+uri);
console.log("Method "+httpMethod);
console.log("Content Type "+contentType);
var featurePayload = form.attr("data-payload");
if (featurePayload) {
contentType = "application/json";
payload = JSON.parse(atob(featurePayload));
} else if (contentType == undefined || contentType.isEmpty()) { if (contentType == undefined || contentType == "") {
contentType = "application/x-www-form-urlencoded"; contentType = "application/x-www-form-urlencoded";
payload = uriencodedFormStr; payload = uriencodedFormStr;
} }
@ -101,9 +100,9 @@ function submitForm(formId) {
if (httpMethod == "GET") { if (httpMethod == "GET") {
invokerUtil.get(uri, successCallBack, errorCallBack, contentType); invokerUtil.get(uri, successCallBack, errorCallBack, contentType);
} else if (httpMethod == "POST") { } else if (httpMethod == "POST") {
console.log("------ cType "+contentType); var deviceList = [deviceId];
var payloadTest = [deviceId]; payload = generatePayload(operationCode, payload, deviceList);
invokerUtil.post(uri, payloadTest, successCallBack, errorCallBack, "application/json"); invokerUtil.post(uri, payload, successCallBack, errorCallBack, contentType);
} else if (httpMethod == "PUT") { } else if (httpMethod == "PUT") {
invokerUtil.put(uri, payload, successCallBack, errorCallBack, contentType); invokerUtil.put(uri, payload, successCallBack, errorCallBack, contentType);
} else if (httpMethod == "DELETE") { } else if (httpMethod == "DELETE") {
@ -120,9 +119,9 @@ $(document).on('submit', 'form', function (e) {
cosole.log("darn!!"); cosole.log("darn!!");
e.preventDefault(); e.preventDefault();
var postOperationRequest = $.ajax({ var postOperationRequest = $.ajax({
url: $(this).attr("action") + '&' + $(this).serialize(), url: $(this).attr("action") + '&' + $(this).serialize(),
method: "post" method: "post"
}); });
var btnSubmit = $('#btnSend', this); var btnSubmit = $('#btnSend', this);
btnSubmit.addClass('hidden'); btnSubmit.addClass('hidden');
@ -144,3 +143,261 @@ $(document).on('submit', 'form', function (e) {
lblSent.addClass('hidden'); lblSent.addClass('hidden');
}); });
}); });
// Constants to define operation types available
var operationTypeConstants = {
"PROFILE": "profile",
"CONFIG": "config",
"COMMAND": "command"
};
var generatePayload = function (operationCode, operationData, deviceList) {
var payload;
var operationType;
switch (operationCode) {
case androidOperationConstants["CAMERA_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"CAMERA" : operationData["cameraEnabled"],
"DISALLOW_ADJUST_VOLUME" : operationData["disallowAdjustVolumeEnabled"],
"DISALLOW_CONFIG_BLUETOOTH" : operationData["disallowConfigBluetooth"],
"DISALLOW_CONFIG_CELL_BROADCASTS" : operationData["disallowConfigCellBroadcasts"],
"DISALLOW_CONFIG_CREDENTIALS" : operationData["disallowConfigCredentials"],
"DISALLOW_CONFIG_MOBILE_NETWORKS" : operationData["disallowConfigMobileNetworks"],
"DISALLOW_CONFIG_TETHERING" : operationData["disallowConfigTethering"],
"DISALLOW_CONFIG_VPN" : operationData["disallowConfigVpn"],
"DISALLOW_CONFIG_WIFI" : operationData["disallowConfigWifi"],
"DISALLOW_APPS_CONTROL" : operationData["disallowAppControl"],
"DISALLOW_CREATE_WINDOWS" : operationData["disallowCreateWindows"],
"DISALLOW_CROSS_PROFILE_COPY_PASTE" : operationData["disallowCrossProfileCopyPaste"],
"DISALLOW_DEBUGGING_FEATURES" : operationData["disallowDebugging"],
"DISALLOW_FACTORY_RESET" : operationData["disallowFactoryReset"],
"DISALLOW_ADD_USER" : operationData["disallowAddUser"],
"DISALLOW_INSTALL_APPS" : operationData["disallowInstallApps"],
"DISALLOW_INSTALL_UNKNOWN_SOURCES" : operationData["disallowInstallUnknownSources"],
"DISALLOW_MODIFY_ACCOUNTS" : operationData["disallowModifyAccounts"],
"DISALLOW_MOUNT_PHYSICAL_MEDIA" : operationData["disallowMountPhysicalMedia"],
"DISALLOW_NETWORK_RESET" : operationData["disallowNetworkReset"],
"DISALLOW_OUTGOING_BEAM" : operationData["disallowOutgoingBeam"],
"DISALLOW_OUTGOING_CALLS" : operationData["disallowOutgoingCalls"],
"DISALLOW_REMOVE_USER" : operationData["disallowRemoveUser"],
"DISALLOW_SAFE_BOOT" : operationData["disallowSafeBoot"],
"DISALLOW_SHARE_LOCATION" : operationData["disallowLocationSharing"],
"DISALLOW_SMS" : operationData["disallowSMS"],
"DISALLOW_UNINSTALL_APPS" : operationData["disallowUninstallApps"],
"DISALLOW_UNMUTE_MICROPHONE" : operationData["disallowUnmuteMicrophone"],
"DISALLOW_USB_FILE_TRANSFER" : operationData["disallowUSBFileTransfer"],
"ALLOW_PARENT_PROFILE_APP_LINKING" : operationData["disallowParentProfileAppLinking"],
"ENSURE_VERIFY_APPS" : operationData["ensureVerifyApps"],
"AUTO_TIME" : operationData["enableAutoTime"],
"SET_SCREEN_CAPTURE_DISABLED" : operationData["disableScreenCapture"],
"SET_STATUS_BAR_DISABLED" : operationData["disableStatusBar"]
}
};
break;
case androidOperationConstants["CHANGE_LOCK_CODE_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"lockCode" : operationData["lockCode"]
}
};
break;
case androidOperationConstants["ENCRYPT_STORAGE_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"encrypted" : operationData["encryptStorageEnabled"]
}
};
break;
case androidOperationConstants["NOTIFICATION_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
//"message" : operationData["message"]
"messageText": operationData["messageText"],
"messageTitle": operationData["messageTitle"]
}
};
break;
case androidOperationConstants["UPGRADE_FIRMWARE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"schedule" : operationData["schedule"],
"server" : operationData["server"]
}
};
break;
case androidOperationConstants["WIPE_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"pin" : operationData["pin"]
}
};
break;
case androidOperationConstants["WIFI_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"ssid": operationData["wifiSSID"],
"type": operationData["wifiType"],
"password" : operationData["wifiPassword"],
"eap" : operationData["wifiEAP"],
"phase2" : operationData["wifiPhase2"],
"provisioning" : operationData["wifiProvisioning"],
"identity" : operationData["wifiIdentity"],
"anonymousIdentity" : operationData["wifiAnoIdentity"],
"cacert" : operationData["wifiCaCert"],
"cacertName" : operationData["wifiCaCertName"]
}
};
break;
case androidOperationConstants["VPN_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"serverAddress": operationData["serverAddress"],
"serverPort": operationData["serverPort"],
"sharedSecret": operationData["sharedSecret"],
"dnsServer": operationData["dnsServer"]
}
};
break;
case androidOperationConstants["LOCK_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"message" : operationData["lock-message"],
"isHardLockEnabled" : operationData["hard-lock"]
}
};
break;
case androidOperationConstants["WORK_PROFILE_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"profileName": operationData["workProfilePolicyProfileName"],
"enableSystemApps": operationData["workProfilePolicyEnableSystemApps"],
"hideSystemApps": operationData["workProfilePolicyHideSystemApps"],
"unhideSystemApps": operationData["workProfilePolicyUnhideSystemApps"],
"enablePlaystoreApps": operationData["workProfilePolicyEnablePlaystoreApps"]
}
};
break;
case androidOperationConstants["PASSCODE_POLICY_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"allowSimple": operationData["passcodePolicyAllowSimple"],
"requireAlphanumeric": operationData["passcodePolicyRequireAlphanumeric"],
"minLength": operationData["passcodePolicyMinLength"],
"minComplexChars": operationData["passcodePolicyMinComplexChars"],
"maxPINAgeInDays": operationData["passcodePolicyMaxPasscodeAgeInDays"],
"pinHistory": operationData["passcodePolicyPasscodeHistory"],
"maxFailedAttempts": operationData["passcodePolicyMaxFailedAttempts"]
}
};
break;
case androidOperationConstants["APPLICATION_OPERATION_CODE"]:
payload = {
"operation": {
"restriction-type": operationData["restrictionType"],
"restricted-applications": operationData["restrictedApplications"]
}
};
break;
case androidOperationConstants["SYSTEM_UPDATE_POLICY_CODE"]:
operationType = operationTypeConstants["PROFILE"];
if (operationData["cosuSystemUpdatePolicyType"] != "window") {
payload = {
"operation": {
"type": operationData["cosuSystemUpdatePolicyType"]
}
};
} else {
payload = {
"operation": {
"type": operationData["cosuSystemUpdatePolicyType"],
"startTime": operationData["cosuSystemUpdatePolicyWindowStartTime"],
"endTime": operationData["cosuSystemUpdatePolicyWindowEndTime"]
}
};
}
break;
case androidOperationConstants["KIOSK_APPS_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"whitelistedApplications": operationData["cosuWhitelistedApplications"]
}
};
break;
default:
// If the operation is neither of above, it is a command operation
operationType = operationTypeConstants["COMMAND"];
// Operation payload of a command operation is simply an array of device IDs
payload = deviceList;
}
if (operationType == operationTypeConstants["PROFILE"] && deviceList) {
payload["deviceIDs"] = deviceList;
}
return payload;
};
// Constants to define Android Operation Constants
var androidOperationConstants = {
"PASSCODE_POLICY_OPERATION_CODE": "PASSCODE_POLICY",
"VPN_OPERATION_CODE": "VPN",
"CAMERA_OPERATION_CODE": "CAMERA",
"ENCRYPT_STORAGE_OPERATION_CODE": "ENCRYPT_STORAGE",
"WIFI_OPERATION_CODE": "WIFI",
"WIPE_OPERATION_CODE": "WIPE_DATA",
"NOTIFICATION_OPERATION_CODE": "NOTIFICATION",
"WORK_PROFILE_CODE": "WORK_PROFILE",
"CHANGE_LOCK_CODE_OPERATION_CODE": "CHANGE_LOCK_CODE",
"LOCK_OPERATION_CODE": "DEVICE_LOCK",
"UPGRADE_FIRMWARE": "UPGRADE_FIRMWARE",
"DISALLOW_ADJUST_VOLUME": "DISALLOW_ADJUST_VOLUME",
"DISALLOW_CONFIG_BLUETOOTH" : "DISALLOW_CONFIG_BLUETOOTH",
"DISALLOW_CONFIG_CELL_BROADCASTS" : "DISALLOW_CONFIG_CELL_BROADCASTS",
"DISALLOW_CONFIG_CREDENTIALS" : "DISALLOW_CONFIG_CREDENTIALS",
"DISALLOW_CONFIG_MOBILE_NETWORKS" : "DISALLOW_CONFIG_MOBILE_NETWORKS",
"DISALLOW_CONFIG_TETHERING" : "DISALLOW_CONFIG_TETHERING",
"DISALLOW_CONFIG_VPN" : "DISALLOW_CONFIG_VPN",
"DISALLOW_CONFIG_WIFI" : "DISALLOW_CONFIG_WIFI",
"DISALLOW_APPS_CONTROL" : "DISALLOW_APPS_CONTROL",
"DISALLOW_CREATE_WINDOWS" : "DISALLOW_CREATE_WINDOWS",
"DISALLOW_CROSS_PROFILE_COPY_PASTE" : "DISALLOW_CROSS_PROFILE_COPY_PASTE",
"DISALLOW_DEBUGGING_FEATURES" : "DISALLOW_DEBUGGING_FEATURES",
"DISALLOW_FACTORY_RESET" : "DISALLOW_FACTORY_RESET",
"DISALLOW_ADD_USER" : "DISALLOW_ADD_USER",
"DISALLOW_INSTALL_APPS" : "DISALLOW_INSTALL_APPS",
"DISALLOW_INSTALL_UNKNOWN_SOURCES" : "DISALLOW_INSTALL_UNKNOWN_SOURCES",
"DISALLOW_MODIFY_ACCOUNTS" : "DISALLOW_MODIFY_ACCOUNTS",
"DISALLOW_MOUNT_PHYSICAL_MEDIA" : "DISALLOW_MOUNT_PHYSICAL_MEDIA",
"DISALLOW_NETWORK_RESET" : "DISALLOW_NETWORK_RESET",
"DISALLOW_OUTGOING_BEAM" : "DISALLOW_OUTGOING_BEAM",
"DISALLOW_OUTGOING_CALLS" : "DISALLOW_OUTGOING_CALLS",
"DISALLOW_REMOVE_USER" : "DISALLOW_REMOVE_USER",
"DISALLOW_SAFE_BOOT" : "DISALLOW_SAFE_BOOT",
"DISALLOW_SHARE_LOCATION" : "DISALLOW_SHARE_LOCATION",
"DISALLOW_SMS" : "DISALLOW_SMS",
"DISALLOW_UNINSTALL_APPS" : "DISALLOW_UNINSTALL_APPS",
"DISALLOW_UNMUTE_MICROPHONE" : "DISALLOW_UNMUTE_MICROPHONE",
"DISALLOW_USB_FILE_TRANSFER" : "DISALLOW_USB_FILE_TRANSFER",
"ALLOW_PARENT_PROFILE_APP_LINKING" : "ALLOW_PARENT_PROFILE_APP_LINKING",
"ENSURE_VERIFY_APPS" : "ENSURE_VERIFY_APPS",
"AUTO_TIME" : "AUTO_TIME",
"SET_SCREEN_CAPTURE_DISABLED" : "SET_SCREEN_CAPTURE_DISABLED",
"SET_STATUS_BAR_DISABLED" : "SET_STATUS_BAR_DISABLED",
"APPLICATION_OPERATION_CODE":"APP-RESTRICTION",
"SYSTEM_UPDATE_POLICY_CODE": "SYSTEM_UPDATE_POLICY",
"KIOSK_APPS_CODE": "KIOSK_APPS"
};

@ -55,6 +55,13 @@ var updateGroupedInputVisibility = function (domElement) {
} }
}; };
/**
* Populates policy configuration to the ui elements.
*
* This method will be invoked from the relevant cdmf unit when the edit page gets loaded.
*
* @param configuredOperations selected configurations.
*/
var polulateProfileOperations = function (configuredOperations) { var polulateProfileOperations = function (configuredOperations) {
$(".wr-advance-operations li.grouped-input").each(function () { $(".wr-advance-operations li.grouped-input").each(function () {
updateGroupedInputVisibility(this); updateGroupedInputVisibility(this);
@ -80,6 +87,13 @@ var inputIsValidAgainstRange = function (numberInput, min, max) {
return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max); return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max);
}; };
/**
* Validates policy profile operations for the windows platform.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {boolean} whether validation is successful.
*/
var validatePolicyProfile = function () { var validatePolicyProfile = function () {
var validationStatusArray = []; var validationStatusArray = [];
var validationStatus; var validationStatus;
@ -528,6 +542,30 @@ var validatePolicyProfile = function () {
return wizardIsToBeContinued; return wizardIsToBeContinued;
}; };
/**
* Generates policy profile object which will be saved with the profile.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {Array} profile payloads
*/
var generatePolicyProfile = function () {
var profilePayloads = [];
// traverses key by key in policy["profile"]
var key;
for (key in policy["profile"]) {
if (policy["profile"].hasOwnProperty(key)) {
profilePayloads.push({
"featureCode": key,
"deviceType": policy["platform"],
"content": policy["profile"][key]
});
}
}
return profilePayloads;
};
// Start of HTML embedded invoke methods // Start of HTML embedded invoke methods
var showAdvanceOperation = function (operation, button) { var showAdvanceOperation = function (operation, button) {
$(button).addClass('selected'); $(button).addClass('selected');

@ -67,6 +67,13 @@ var inputIsValidAgainstRange = function (numberInput, min, max) {
return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max); return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max);
}; };
/**
* Validates policy profile operations for the windows platform.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {boolean} whether validation is successful.
*/
var validatePolicyProfile = function () { var validatePolicyProfile = function () {
var validationStatusArray = []; var validationStatusArray = [];
var validationStatus; var validationStatus;
@ -515,6 +522,30 @@ var validatePolicyProfile = function () {
return wizardIsToBeContinued; return wizardIsToBeContinued;
}; };
/**
* Generates policy profile object which will be saved with the profile.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {Array} profile payloads
*/
var generatePolicyProfile = function () {
var profilePayloads = [];
// traverses key by key in policy["profile"]
var key;
for (key in policy["profile"]) {
if (policy["profile"].hasOwnProperty(key)) {
profilePayloads.push({
"featureCode": key,
"deviceType": policy["platform"],
"content": policy["profile"][key]
});
}
}
return profilePayloads;
};
// Start of HTML embedded invoke methods // Start of HTML embedded invoke methods
var showAdvanceOperation = function (operation, button) { var showAdvanceOperation = function (operation, button) {
$(button).addClass('selected'); $(button).addClass('selected');

@ -6,40 +6,102 @@
"groupingEnabled": "false", "groupingEnabled": "false",
"features": { "features": {
"DEVICE_RING": { "DEVICE_RING": {
"icon" : "fw-dial-up" "icon": "fw-dial-up"
}, },
"DEVICE_LOCK": { "DEVICE_LOCK": {
"icon" : "fw-lock" "icon": "fw-lock",
"formParams": [
{
"type": "text",
"id": "lock-message",
"optional": true,
"label": "Message to be sent to the device"
},{
"type": "checkbox",
"id": "hard-lock",
"optional": true,
"label": "Hard lock enabled"
}
]
}, },
"DEVICE_LOCATION": { "DEVICE_LOCATION": {
"icon" : "fw-map-location" "icon": "fw-map-location"
}, },
"CLEAR_PASSWORD": { "CLEAR_PASSWORD": {
"icon" : "fw-clear" "icon": "fw-clear"
}, },
"DEVICE_REBOOT": { "DEVICE_REBOOT": {
"icon" : "fw-refresh" "icon": "fw-refresh"
}, },
"UPGRADE_FIRMWARE": { "UPGRADE_FIRMWARE": {
"icon" : "fw-hardware" "icon": "fw-hardware",
"formParams": [
{
"type": "checkbox",
"id": "immediate",
"optional": true,
"label": "Instant Upgrade",
"helper": "Once enabled, device firmware upgrade process will start instantly."
},
{
"type": "text",
"id": "schedule",
"optional": false,
"label": "Enter the date and time to schedule firmware upgrade."
},
{
"type": "text",
"id": "server",
"optional": true,
"label": "Enter firmware upgrade server URL (ie. http://abc.com or http://abc.com/ota)"
}
]
}, },
"DEVICE_MUTE": { "DEVICE_MUTE": {
"icon" : "fw-mute" "icon": "fw-mute"
}, },
"NOTIFICATION": { "NOTIFICATION": {
"icon" : "fw-message" "icon": "fw-message",
"formParams": [
{
"type": "text",
"id": "messageText",
"optional": false,
"label": "Title Here..."
},
{
"type": "text",
"id": "messageTitle",
"optional": false,
"label": "Message Here..."
}
]
}, },
"CHANGE_LOCK_CODE": { "CHANGE_LOCK_CODE": {
"icon" : "fw-security" "icon": "fw-security",
"formParams": [
{
"type": "text",
"id": "lockCode",
"optional": false,
"label": "Lock Code"
}
]
}, },
"ENTERPRISE_WIPE": { "ENTERPRISE_WIPE": {
"icon" : "fw-block" "icon": "fw-block"
}, },
"WIPE_DATA": { "WIPE_DATA": {
"icon" : "fw-delete" "icon": "fw-delete",
"formParams": [
{
"type": "text",
"id": "pin",
"optional": false,
"label": "Enter PIN code* of the device."
}
]
} }
} }
} }
} }

@ -5,12 +5,12 @@
<h1 class="grey ">Android Mobile</h1> <h1 class="grey ">Android Mobile</h1>
<hr> <hr>
</div> </div>
<div class="col-xs-12 col-sm-4 col-md-4 col-lg-4 padding-top"> <div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 padding-top">
<img src="{{@unit.publicUri}}/images/android-icon.png" class="img-responsive"> <img src="{{@unit.publicUri}}/images/android-icon.png" class="img-responsive">
</div> </div>
<div class="col-xs-12 col-sm-8 col-md-8 col-lg-8 padding-top"> <div class="col-xs-12 col-sm-8 col-md-9 col-lg-9 padding-top">
<h3 class="uppercase">What it Does</h3> <h3 class="uppercase">What it Does</h3>
<hr> <hr>

@ -0,0 +1,578 @@
/*
* 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.
*/
var windowsOperationConstants = {
"PASSCODE_POLICY_OPERATION": "passcode-policy",
"PASSCODE_POLICY_OPERATION_CODE": "PASSCODE_POLICY",
"CAMERA_OPERATION": "camera",
"CAMERA_OPERATION_CODE": "CAMERA",
"ENCRYPT_STORAGE_OPERATION": "encrypt-storage",
"ENCRYPT_STORAGE_OPERATION_CODE": "ENCRYPT_STORAGE"
};
/**
* Method to update the visibility of grouped input.
* @param domElement HTML grouped-input element with class name "grouped-input"
*/
var updateGroupedInputVisibility = function (domElement) {
if ($(".parent-input:first", domElement).is(":checked")) {
if ($(".grouped-child-input:first", domElement).hasClass("disabled")) {
$(".grouped-child-input:first", domElement).removeClass("disabled");
}
$(".child-input", domElement).each(function () {
$(this).prop('disabled', false);
});
} else {
if (!$(".grouped-child-input:first", domElement).hasClass("disabled")) {
$(".grouped-child-input:first", domElement).addClass("disabled");
}
$(".child-input", domElement).each(function () {
$(this).prop('disabled', true);
});
}
};
/**
* Populates policy configuration to the ui elements.
*
* This method will be invoked from the relevant cdmf unit when the edit page gets loaded.
*
* @param configuredOperations selected configurations.
*/
var polulateProfileOperations = function (configuredOperations) {
$(".wr-advance-operations li.grouped-input").each(function () {
updateGroupedInputVisibility(this);
});
for (var i = 0; i < configuredOperations.length; ++i) {
var configuredOperation = configuredOperations[i];
$(".operation-data").filterByData("operation-code", configuredOperation)
.find(".panel-title .wr-input-control.switch input[type=checkbox]").each(function () {
$(this).click();
});
}
};
/**
* Checks if provided number is valid against a range.
*
* @param numberInput Number Input
* @param min Minimum Limit
* @param max Maximum Limit
* @returns {boolean} Returns true if input is within the specified range
*/
var inputIsValidAgainstRange = function (numberInput, min, max) {
return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max);
};
/**
* Validates policy profile operations for the windows platform.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {boolean} whether validation is successful.
*/
var validatePolicyProfile = function () {
var validationStatusArray = [];
var validationStatus;
var operation;
// starting validation process and updating validationStatus
if (configuredOperations.length == 0) {
// updating validationStatus
validationStatus = {
"error": true,
"mainErrorMsg": "You cannot continue. Zero configured features."
};
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
} else {
// validating each and every configured Operation
// Validating PASSCODE_POLICY
if ($.inArray(windowsOperationConstants["PASSCODE_POLICY_OPERATION_CODE"], configuredOperations) != -1) {
// if PASSCODE_POLICY is configured
operation = windowsOperationConstants["PASSCODE_POLICY_OPERATION"];
// initializing continueToCheckNextInputs to true
var continueToCheckNextInputs = true;
// validating first input: passcodePolicyMaxPasscodeAgeInDays
var passcodePolicyMaxPasscodeAgeInDays = $("input#passcode-policy-max-passcode-age-in-days").val();
if (passcodePolicyMaxPasscodeAgeInDays) {
if (!$.isNumeric(passcodePolicyMaxPasscodeAgeInDays)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode age is not a number.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
} else if (!inputIsValidAgainstRange(passcodePolicyMaxPasscodeAgeInDays, 1, 730)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode age is not with in the range of 1-to-730.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
}
}
// validating second and last input: passcodePolicyPasscodeHistory
if (continueToCheckNextInputs) {
var passcodePolicyPasscodeHistory = $("input#passcode-policy-passcode-history").val();
if (passcodePolicyPasscodeHistory) {
if (!$.isNumeric(passcodePolicyPasscodeHistory)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode history is not a number.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
} else if (!inputIsValidAgainstRange(passcodePolicyPasscodeHistory, 1, 50)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode history is not with in the range of 1-to-50.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
}
}
}
// at-last, if the value of continueToCheckNextInputs is still true
// this means that no error is found
if (continueToCheckNextInputs) {
validationStatus = {
"error": false,
"okFeature": operation
};
}
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
}
// Validating CAMERA
if ($.inArray(windowsOperationConstants["CAMERA_OPERATION_CODE"], configuredOperations) != -1) {
// if CAMERA is configured
operation = windowsOperationConstants["CAMERA_OPERATION"];
// updating validationStatus
validationStatus = {
"error": false,
"okFeature": operation
};
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
}
// Validating ENCRYPT_STORAGE
if ($.inArray(windowsOperationConstants["ENCRYPT_STORAGE_OPERATION_CODE"], configuredOperations) != -1) {
// if ENCRYPT_STORAGE is configured
operation = windowsOperationConstants["ENCRYPT_STORAGE_OPERATION"];
// updating validationStatus
validationStatus = {
"error": false,
"okFeature": operation
};
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
}
}
// ending validation process
// start taking specific notifying actions upon validation
var wizardIsToBeContinued;
var errorCount = 0;
var mainErrorMsgWrapper, mainErrorMsg,
subErrorMsgWrapper, subErrorMsg, subErrorIcon, subOkIcon, featureConfiguredIcon;
var i;
for (i = 0; i < validationStatusArray.length; i++) {
validationStatus = validationStatusArray[i];
if (validationStatus["error"]) {
errorCount++;
if (validationStatus["mainErrorMsg"]) {
mainErrorMsgWrapper = "#policy-profile-main-error-msg";
mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else if (validationStatus["subErrorMsg"]) {
subErrorMsgWrapper = "#" + validationStatus["erroneousFeature"] + "-feature-error-msg";
subErrorMsg = subErrorMsgWrapper + " span";
subErrorIcon = "#" + validationStatus["erroneousFeature"] + "-error";
subOkIcon = "#" + validationStatus["erroneousFeature"] + "-ok";
featureConfiguredIcon = "#" + validationStatus["erroneousFeature"] + "-configured";
// hiding featureConfiguredState as the first step
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
// updating error state and corresponding messages
$(subErrorMsg).text(validationStatus["subErrorMsg"]);
if ($(subErrorMsgWrapper).hasClass("hidden")) {
$(subErrorMsgWrapper).removeClass("hidden");
}
if (!$(subOkIcon).hasClass("hidden")) {
$(subOkIcon).addClass("hidden");
}
if ($(subErrorIcon).hasClass("hidden")) {
$(subErrorIcon).removeClass("hidden");
}
}
} else {
if (validationStatus["okFeature"]) {
subErrorMsgWrapper = "#" + validationStatus["okFeature"] + "-feature-error-msg";
subErrorIcon = "#" + validationStatus["okFeature"] + "-error";
subOkIcon = "#" + validationStatus["okFeature"] + "-ok";
featureConfiguredIcon = "#" + validationStatus["okFeature"] + "-configured";
// hiding featureConfiguredState as the first step
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
// updating success state and corresponding messages
if (!$(subErrorMsgWrapper).hasClass("hidden")) {
$(subErrorMsgWrapper).addClass("hidden");
}
if (!$(subErrorIcon).hasClass("hidden")) {
$(subErrorIcon).addClass("hidden");
}
if ($(subOkIcon).hasClass("hidden")) {
$(subOkIcon).removeClass("hidden");
}
}
}
}
wizardIsToBeContinued = (errorCount == 0);
return wizardIsToBeContinued;
};
/**
* Generates policy profile object which will be saved with the profile.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {Array} profile payloads
*/
var generatePolicyProfile = function () {
var profilePayloads = [];
// traverses key by key in policy["profile"]
var key;
for (key in policy["profile"]) {
if (key == windowsOperationConstants["PASSCODE_POLICY_OPERATION_CODE"]) {
policy["profile"][key].enablePassword = true;
}
if (policy["profile"].hasOwnProperty(key)) {
profilePayloads.push({
"featureCode": key,
"deviceType": policy["platform"],
"content": policy["profile"][key]
});
}
}
return profilePayloads;
};
// Start of HTML embedded invoke methods
var showAdvanceOperation = function (operation, button) {
$(button).addClass('selected');
$(button).siblings().removeClass('selected');
var hiddenOperation = ".wr-hidden-operations-content > div";
$(hiddenOperation + '[data-operation="' + operation + '"]').show();
$(hiddenOperation + '[data-operation="' + operation + '"]').siblings().hide();
};
/**
* Method to slide down a provided pane upon provided value set.
*
* @param selectElement Select HTML Element to consider
* @param paneID HTML ID of div element to slide down
* @param valueSet Applicable Value Set
*/
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]) {
slideDownVotes++;
}
}
var paneSelector = "#" + paneID;
if (slideDownVotes > 0) {
if (!$(paneSelector).hasClass("expanded")) {
$(paneSelector).addClass("expanded");
}
$(paneSelector).slideDown();
} else {
if ($(paneSelector).hasClass("expanded")) {
$(paneSelector).removeClass("expanded");
}
$(paneSelector).slideUp();
/* now follows the code to reinitialize all inputs of the slidable pane */
// reinitializing input fields into the defaults
$(paneSelector + " input").each(
function () {
if ($(this).is("input:text")) {
$(this).val($(this).data("default"));
} else if ($(this).is("input:password")) {
$(this).val("");
} else if ($(this).is("input:checkbox")) {
$(this).prop("checked", $(this).data("default"));
// if this checkbox is the parent input of a grouped-input
if ($(this).hasClass("parent-input")) {
var groupedInput = $(this).parent().parent().parent();
updateGroupedInputVisibility(groupedInput);
}
}
}
);
// reinitializing select fields into the defaults
$(paneSelector + " select").each(
function () {
var defaultOption = $(this).data("default");
$("option:eq(" + defaultOption + ")", this).prop("selected", "selected");
}
);
// collapsing expanded-panes (upon the selection of html-select-options) if any
$(paneSelector + " .expanded").each(
function () {
if ($(this).hasClass("expanded")) {
$(this).removeClass("expanded");
}
$(this).slideUp();
}
);
// removing all entries of grid-input elements if exist
$(paneSelector + " .grouped-array-input").each(
function () {
var gridInputs = $(this).find("[data-add-form-clone]");
if (gridInputs.length > 0) {
gridInputs.remove();
}
var helpTexts = $(this).find("[data-help-text=add-form]");
if (helpTexts.length > 0) {
helpTexts.show();
}
}
);
}
};
// End of HTML embedded invoke methods
// Start of functions related to grid-input-view
/**
* Method to set count id to cloned elements.
* @param {object} addFormContainer
*/
var setId = function (addFormContainer) {
$(addFormContainer).find("[data-add-form-clone]").each(function (i) {
$(this).attr("id", $(this).attr("data-add-form-clone").slice(1) + "-" + (i + 1));
if ($(this).find(".index").length > 0) {
$(this).find(".index").html(i + 1);
}
});
};
/**
* Method to set count id to cloned elements.
* @param {object} addFormContainer
*/
var showHideHelpText = function (addFormContainer) {
var helpText = "[data-help-text=add-form]";
if ($(addFormContainer).find("[data-add-form-clone]").length > 0) {
$(addFormContainer).find(helpText).hide();
} else {
$(addFormContainer).find(helpText).show();
}
};
$(document).ready(function () {
// Maintains an array of configured features of the profile
var advanceOperations = ".wr-advance-operations";
$(advanceOperations).on("click", ".wr-input-control.switch", function (event) {
var operationCode = $(this).parents(".operation-data").data("operation-code");
var operation = $(this).parents(".operation-data").data("operation");
var operationDataWrapper = $(this).data("target");
// prevents event bubbling by figuring out what element it's being called from.
if (event.target.tagName == "INPUT") {
var featureConfiguredIcon;
if ($("input[type='checkbox']", this).is(":checked")) {
configuredOperations.push(operationCode);
// when a feature is enabled, if "zero-configured-features" msg is available, hide that.
var zeroConfiguredOperationsErrorMsg = "#policy-profile-main-error-msg";
if (!$(zeroConfiguredOperationsErrorMsg).hasClass("hidden")) {
$(zeroConfiguredOperationsErrorMsg).addClass("hidden");
}
// add configured-state-icon to the feature
featureConfiguredIcon = "#" + operation + "-configured";
if ($(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).removeClass("hidden");
}
} else {
//splicing the array if operation is present.
var index = $.inArray(operationCode, configuredOperations);
if (index != -1) {
configuredOperations.splice(index, 1);
}
// when a feature is disabled, clearing all its current configured, error or success states
var subErrorMsgWrapper = "#" + operation + "-feature-error-msg";
var subErrorIcon = "#" + operation + "-error";
var subOkIcon = "#" + operation + "-ok";
featureConfiguredIcon = "#" + operation + "-configured";
if (!$(subErrorMsgWrapper).hasClass("hidden")) {
$(subErrorMsgWrapper).addClass("hidden");
}
if (!$(subErrorIcon).hasClass("hidden")) {
$(subErrorIcon).addClass("hidden");
}
if (!$(subOkIcon).hasClass("hidden")) {
$(subOkIcon).addClass("hidden");
}
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
// reinitializing input fields into the defaults
$(operationDataWrapper + " input").each(
function () {
if ($(this).is("input:text")) {
$(this).val($(this).data("default"));
} else if ($(this).is("input:password")) {
$(this).val("");
} else if ($(this).is("input:checkbox")) {
$(this).prop("checked", $(this).data("default"));
// if this checkbox is the parent input of a grouped-input
if ($(this).hasClass("parent-input")) {
var groupedInput = $(this).parent().parent().parent();
updateGroupedInputVisibility(groupedInput);
}
}
}
);
// reinitializing select fields into the defaults
$(operationDataWrapper + " select").each(
function () {
var defaultOption = $(this).data("default");
$("option:eq(" + defaultOption + ")", this).prop("selected", "selected");
}
);
// collapsing expanded-panes (upon the selection of html-select-options) if any
$(operationDataWrapper + " .expanded").each(
function () {
if ($(this).hasClass("expanded")) {
$(this).removeClass("expanded");
}
$(this).slideUp();
}
);
// removing all entries of grid-input elements if exist
$(operationDataWrapper + " .grouped-array-input").each(
function () {
var gridInputs = $(this).find("[data-add-form-clone]");
if (gridInputs.length > 0) {
gridInputs.remove();
}
var helpTexts = $(this).find("[data-help-text=add-form]");
if (helpTexts.length > 0) {
helpTexts.show();
}
}
);
}
}
});
// <start - fixing feature-configuring switch double-click issue>
$(advanceOperations).on('hidden.bs.collapse', function (event) {
var collapsedFeatureBody = event.target.id;
var operation = collapsedFeatureBody.substr(0, collapsedFeatureBody.lastIndexOf("-"));
var featureConfiguringSwitch = "#" + operation + "-heading input[type=checkbox]";
var featureConfiguredIcon = "#" + operation + "-configured";
if ($(featureConfiguringSwitch).prop("checked") == true) {
$(featureConfiguringSwitch).prop("checked", false);
}
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
});
$(advanceOperations).on('shown.bs.collapse', function (event) {
var expandedFeatureBody = event.target.id;
var operation = expandedFeatureBody.substr(0, expandedFeatureBody.lastIndexOf("-"));
var featureConfiguringSwitch = "#" + operation + "-heading input[type=checkbox]";
var featureConfiguredIcon = "#" + operation + "-configured";
if ($(featureConfiguringSwitch).prop("checked") == false) {
$(featureConfiguringSwitch).prop("checked", true);
}
if ($(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).removeClass("hidden");
}
});
// <end - fixing feature-configuring switch double-click issue>
// adding support for cloning multiple profiles per feature with cloneable class definitions
$(advanceOperations).on("click", ".multi-view.add.enabled", function () {
// get a copy of .cloneable and create new .cloned div element
var cloned = "<div class='cloned'><hr>" + $(".cloneable", $(this).parent().parent()).html() + "</div>";
// append newly created .cloned div element to panel-body
$(this).parent().parent().append(cloned);
// enable remove action of newly cloned div element
$(".cloned", $(this).parent().parent()).each(
function () {
if ($(".multi-view.remove", this).hasClass("disabled")) {
$(".multi-view.remove", this).removeClass("disabled");
}
if (!$(".multi-view.remove", this).hasClass("enabled")) {
$(".multi-view.remove", this).addClass("enabled");
}
}
);
});
$(advanceOperations).on("click", ".multi-view.remove.enabled", function () {
$(this).parent().remove();
});
// enabling or disabling grouped-input based on the status of a parent check-box
$(advanceOperations).on("click", ".grouped-input", function () {
updateGroupedInputVisibility(this);
});
// add form entry click function for grid inputs
$(advanceOperations).on("click", "[data-click-event=add-form]", function () {
var addFormContainer = $("[data-add-form-container=" + $(this).attr("href") + "]");
var clonedForm = $("[data-add-form=" + $(this).attr("href") + "]").clone().find("[data-add-form-element=clone]")
.attr("data-add-form-clone", $(this).attr("href"));
// adding class .child-input to capture text-input-array-values
$("input, select", clonedForm).addClass("child-input");
$(addFormContainer).append(clonedForm);
setId(addFormContainer);
showHideHelpText(addFormContainer);
});
// remove form entry click function for grid inputs
$(advanceOperations).on("click", "[data-click-event=remove-form]", function () {
var addFormContainer = $("[data-add-form-container=" + $(this).attr("href") + "]");
$(this).closest("[data-add-form-element=clone]").remove();
setId(addFormContainer);
showHideHelpText(addFormContainer);
});
});

@ -0,0 +1,402 @@
<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>
</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>
</h2>
<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>
<div id="passcode-policy-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="passcode-policy-body">
<hr/>
<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">
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">
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>
</h2>
<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>
<div id="camera-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="camera-body">
<hr/>
<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.">
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>
</h2>
<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>
<div id="encrypt-storage-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="encrypt-storage-body">
<hr/>
<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">
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>
</h2>
<div class="panel-title-description">
This configuration can be used to create a black list or white list of applications.
</div>
</div>
<div id="app-restriction-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="app-restriction-body">
<hr/>
<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="btn btn-secondary 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>
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>
</div>
</div>

@ -0,0 +1,590 @@
/*
* 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.
*/
var windowsOperationConstants = {
"PASSCODE_POLICY_OPERATION": "passcode-policy",
"PASSCODE_POLICY_OPERATION_CODE": "PASSCODE_POLICY",
"CAMERA_OPERATION": "camera",
"CAMERA_OPERATION_CODE": "CAMERA",
"ENCRYPT_STORAGE_OPERATION": "encrypt-storage",
"ENCRYPT_STORAGE_OPERATION_CODE": "ENCRYPT_STORAGE"
};
/**
* Method to update the visibility of grouped input.
* @param domElement HTML grouped-input element with class name "grouped-input"
*/
var updateGroupedInputVisibility = function (domElement) {
if ($(".parent-input:first", domElement).is(":checked")) {
if ($(".grouped-child-input:first", domElement).hasClass("disabled")) {
$(".grouped-child-input:first", domElement).removeClass("disabled");
}
$(".child-input", domElement).each(function () {
$(this).prop('disabled', false);
});
} else {
if (!$(".grouped-child-input:first", domElement).hasClass("disabled")) {
$(".grouped-child-input:first", domElement).addClass("disabled");
}
$(".child-input", domElement).each(function () {
$(this).prop('disabled', true);
});
}
};
/**
* Checks if provided number is valid against a range.
*
* @param numberInput Number Input
* @param min Minimum Limit
* @param max Maximum Limit
* @returns {boolean} Returns true if input is within the specified range
*/
var inputIsValidAgainstRange = function (numberInput, min, max) {
return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max);
};
/**
* Validates policy profile operations for the windows platform.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {boolean} whether validation is successful.
*/
var validatePolicyProfile = function () {
var validationStatusArray = [];
var validationStatus;
var operation;
// starting validation process and updating validationStatus
if (configuredOperations.length == 0) {
// updating validationStatus
validationStatus = {
"error": true,
"mainErrorMsg": "You cannot continue. Zero configured features."
};
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
} else {
// validating each and every configured Operation
// Validating PASSCODE_POLICY
if ($.inArray(windowsOperationConstants["PASSCODE_POLICY_OPERATION_CODE"], configuredOperations) != -1) {
// if PASSCODE_POLICY is configured
operation = windowsOperationConstants["PASSCODE_POLICY_OPERATION"];
// initializing continueToCheckNextInputs to true
var continueToCheckNextInputs = true;
// validating first input: passcodePolicyMaxPasscodeAgeInDays
var passcodePolicyMaxPasscodeAgeInDays = $("input#passcode-policy-max-passcode-age-in-days").val();
if (passcodePolicyMaxPasscodeAgeInDays) {
if (!$.isNumeric(passcodePolicyMaxPasscodeAgeInDays)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode age is not a number.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
} else if (!inputIsValidAgainstRange(passcodePolicyMaxPasscodeAgeInDays, 1, 730)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode age is not with in the range of 1-to-730.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
}
}
// validating second and last input: passcodePolicyPasscodeHistory
if (continueToCheckNextInputs) {
var passcodePolicyPasscodeHistory = $("input#passcode-policy-passcode-history").val();
if (passcodePolicyPasscodeHistory) {
if (!$.isNumeric(passcodePolicyPasscodeHistory)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode history is not a number.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
} else if (!inputIsValidAgainstRange(passcodePolicyPasscodeHistory, 1, 50)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode history is not with in the range of 1-to-50.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
}
}
}
// at-last, if the value of continueToCheckNextInputs is still true
// this means that no error is found
if (continueToCheckNextInputs) {
validationStatus = {
"error": false,
"okFeature": operation
};
}
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
}
// Validating CAMERA
if ($.inArray(windowsOperationConstants["CAMERA_OPERATION_CODE"], configuredOperations) != -1) {
// if CAMERA is configured
operation = windowsOperationConstants["CAMERA_OPERATION"];
// updating validationStatus
validationStatus = {
"error": false,
"okFeature": operation
};
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
}
// Validating ENCRYPT_STORAGE
if ($.inArray(windowsOperationConstants["ENCRYPT_STORAGE_OPERATION_CODE"], configuredOperations) != -1) {
// if ENCRYPT_STORAGE is configured
operation = windowsOperationConstants["ENCRYPT_STORAGE_OPERATION"];
// updating validationStatus
validationStatus = {
"error": false,
"okFeature": operation
};
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
}
}
// ending validation process
// start taking specific notifying actions upon validation
var wizardIsToBeContinued;
var errorCount = 0;
var mainErrorMsgWrapper, mainErrorMsg,
subErrorMsgWrapper, subErrorMsg, subErrorIcon, subOkIcon, featureConfiguredIcon;
var i;
for (i = 0; i < validationStatusArray.length; i++) {
validationStatus = validationStatusArray[i];
if (validationStatus["error"]) {
errorCount++;
if (validationStatus["mainErrorMsg"]) {
mainErrorMsgWrapper = "#policy-profile-main-error-msg";
mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else if (validationStatus["subErrorMsg"]) {
subErrorMsgWrapper = "#" + validationStatus["erroneousFeature"] + "-feature-error-msg";
subErrorMsg = subErrorMsgWrapper + " span";
subErrorIcon = "#" + validationStatus["erroneousFeature"] + "-error";
subOkIcon = "#" + validationStatus["erroneousFeature"] + "-ok";
featureConfiguredIcon = "#" + validationStatus["erroneousFeature"] + "-configured";
// hiding featureConfiguredState as the first step
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
// updating error state and corresponding messages
$(subErrorMsg).text(validationStatus["subErrorMsg"]);
if ($(subErrorMsgWrapper).hasClass("hidden")) {
$(subErrorMsgWrapper).removeClass("hidden");
}
if (!$(subOkIcon).hasClass("hidden")) {
$(subOkIcon).addClass("hidden");
}
if ($(subErrorIcon).hasClass("hidden")) {
$(subErrorIcon).removeClass("hidden");
}
}
} else {
if (validationStatus["okFeature"]) {
subErrorMsgWrapper = "#" + validationStatus["okFeature"] + "-feature-error-msg";
subErrorIcon = "#" + validationStatus["okFeature"] + "-error";
subOkIcon = "#" + validationStatus["okFeature"] + "-ok";
featureConfiguredIcon = "#" + validationStatus["okFeature"] + "-configured";
// hiding featureConfiguredState as the first step
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
// updating success state and corresponding messages
if (!$(subErrorMsgWrapper).hasClass("hidden")) {
$(subErrorMsgWrapper).addClass("hidden");
}
if (!$(subErrorIcon).hasClass("hidden")) {
$(subErrorIcon).addClass("hidden");
}
if ($(subOkIcon).hasClass("hidden")) {
$(subOkIcon).removeClass("hidden");
}
}
}
}
wizardIsToBeContinued = (errorCount == 0);
return wizardIsToBeContinued;
};
/**
* Generates policy profile object which will be saved with the profile.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {Array} profile payloads
*/
var generatePolicyProfile = function () {
var profilePayloads = [];
// traverses key by key in policy["profile"]
var key;
for (key in policy["profile"]) {
if (key == windowsOperationConstants["PASSCODE_POLICY_OPERATION_CODE"]) {
policy["profile"][key].enablePassword = true;
}
if (policy["profile"].hasOwnProperty(key)) {
profilePayloads.push({
"featureCode": key,
"deviceType": policy["platform"],
"content": policy["profile"][key]
});
}
}
return profilePayloads;
};
// Start of HTML embedded invoke methods
var showAdvanceOperation = function (operation, button) {
$(button).addClass('selected');
$(button).siblings().removeClass('selected');
var hiddenOperation = ".wr-hidden-operations-content > div";
$(hiddenOperation + '[data-operation="' + operation + '"]').show();
$(hiddenOperation + '[data-operation="' + operation + '"]').siblings().hide();
};
/**
* This method will display appropriate fields based on wifi type
* @param select
*/
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 select
* @param superSelect
*/
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);
}
};
/**
* Method to slide down a provided pane upon provided value set.
*
* @param selectElement Select HTML Element to consider
* @param paneID HTML ID of div element to slide down
* @param valueSet Applicable Value Set
*/
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]) {
slideDownVotes++;
}
}
var paneSelector = "#" + paneID;
if (slideDownVotes > 0) {
if (!$(paneSelector).hasClass("expanded")) {
$(paneSelector).addClass("expanded");
}
$(paneSelector).slideDown();
} else {
if ($(paneSelector).hasClass("expanded")) {
$(paneSelector).removeClass("expanded");
}
$(paneSelector).slideUp();
/** now follows the code to reinitialize all inputs of the slidable pane */
// reinitializing input fields into the defaults
$(paneSelector + " input").each(
function () {
if ($(this).is("input:text")) {
$(this).val($(this).data("default"));
} else if ($(this).is("input:password")) {
$(this).val("");
} else if ($(this).is("input:checkbox")) {
$(this).prop("checked", $(this).data("default"));
// if this checkbox is the parent input of a grouped-input
if ($(this).hasClass("parent-input")) {
var groupedInput = $(this).parent().parent().parent();
updateGroupedInputVisibility(groupedInput);
}
}
}
);
// reinitializing select fields into the defaults
$(paneSelector + " select").each(
function () {
var defaultOption = $(this).data("default");
$("option:eq(" + defaultOption + ")", this).prop("selected", "selected");
}
);
// collapsing expanded-panes (upon the selection of html-select-options) if any
$(paneSelector + " .expanded").each(
function () {
if ($(this).hasClass("expanded")) {
$(this).removeClass("expanded");
}
$(this).slideUp();
}
);
// removing all entries of grid-input elements if exist
$(paneSelector + " .grouped-array-input").each(
function () {
var gridInputs = $(this).find("[data-add-form-clone]");
if (gridInputs.length > 0) {
gridInputs.remove();
}
var helpTexts = $(this).find("[data-help-text=add-form]");
if (helpTexts.length > 0) {
helpTexts.show();
}
}
);
}
};
// End of HTML embedded invoke methods
// Start of functions related to grid-input-view
/**
* Method to set count id to cloned elements.
* @param {object} addFormContainer
*/
var setId = function (addFormContainer) {
$(addFormContainer).find("[data-add-form-clone]").each(function (i) {
$(this).attr("id", $(this).attr("data-add-form-clone").slice(1) + "-" + (i + 1));
if ($(this).find(".index").length > 0) {
$(this).find(".index").html(i + 1);
}
});
};
/**
* Method to set count id to cloned elements.
* @param {object} addFormContainer
*/
var showHideHelpText = function (addFormContainer) {
var helpText = "[data-help-text=add-form]";
if ($(addFormContainer).find("[data-add-form-clone]").length > 0) {
$(addFormContainer).find(helpText).hide();
} else {
$(addFormContainer).find(helpText).show();
}
};
$(document).ready(function () {
// Maintains an array of configured features of the profile
var advanceOperations = ".wr-advance-operations";
$(advanceOperations).on("click", ".wr-input-control.switch", function (event) {
var operationCode = $(this).parents(".operation-data").data("operation-code");
var operation = $(this).parents(".operation-data").data("operation");
var operationDataWrapper = $(this).data("target");
// prevents event bubbling by figuring out what element it's being called from.
if (event.target.tagName == "INPUT") {
var featureConfiguredIcon;
if ($("input[type='checkbox']", this).is(":checked")) {
configuredOperations.push(operationCode);
// when a feature is enabled, if "zero-configured-features" msg is available, hide that.
var zeroConfiguredOperationsErrorMsg = "#policy-profile-main-error-msg";
if (!$(zeroConfiguredOperationsErrorMsg).hasClass("hidden")) {
$(zeroConfiguredOperationsErrorMsg).addClass("hidden");
}
// add configured-state-icon to the feature
featureConfiguredIcon = "#" + operation + "-configured";
if ($(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).removeClass("hidden");
}
} else {
//splicing the array if operation is present.
var index = $.inArray(operationCode, configuredOperations);
if (index != -1) {
configuredOperations.splice(index, 1);
}
// when a feature is disabled, clearing all its current configured, error or success states
var subErrorMsgWrapper = "#" + operation + "-feature-error-msg";
var subErrorIcon = "#" + operation + "-error";
var subOkIcon = "#" + operation + "-ok";
featureConfiguredIcon = "#" + operation + "-configured";
if (!$(subErrorMsgWrapper).hasClass("hidden")) {
$(subErrorMsgWrapper).addClass("hidden");
}
if (!$(subErrorIcon).hasClass("hidden")) {
$(subErrorIcon).addClass("hidden");
}
if (!$(subOkIcon).hasClass("hidden")) {
$(subOkIcon).addClass("hidden");
}
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
// reinitializing input fields into the defaults
$(operationDataWrapper + " input").each(
function () {
if ($(this).is("input:text")) {
$(this).val($(this).data("default"));
} else if ($(this).is("input:password")) {
$(this).val("");
} else if ($(this).is("input:checkbox")) {
$(this).prop("checked", $(this).data("default"));
// if this checkbox is the parent input of a grouped-input
if ($(this).hasClass("parent-input")) {
var groupedInput = $(this).parent().parent().parent();
updateGroupedInputVisibility(groupedInput);
}
}
}
);
// reinitializing select fields into the defaults
$(operationDataWrapper + " select").each(
function () {
var defaultOption = $(this).data("default");
$("option:eq(" + defaultOption + ")", this).prop("selected", "selected");
}
);
// collapsing expanded-panes (upon the selection of html-select-options) if any
$(operationDataWrapper + " .expanded").each(
function () {
if ($(this).hasClass("expanded")) {
$(this).removeClass("expanded");
}
$(this).slideUp();
}
);
// removing all entries of grid-input elements if exist
$(operationDataWrapper + " .grouped-array-input").each(
function () {
var gridInputs = $(this).find("[data-add-form-clone]");
if (gridInputs.length > 0) {
gridInputs.remove();
}
var helpTexts = $(this).find("[data-help-text=add-form]");
if (helpTexts.length > 0) {
helpTexts.show();
}
}
);
}
}
});
// <start - fixing feature-configuring switch double-click issue>
$(advanceOperations).on('hidden.bs.collapse', function (event) {
var collapsedFeatureBody = event.target.id;
var operation = collapsedFeatureBody.substr(0, collapsedFeatureBody.lastIndexOf("-"));
var featureConfiguringSwitch = "#" + operation + "-heading input[type=checkbox]";
var featureConfiguredIcon = "#" + operation + "-configured";
if ($(featureConfiguringSwitch).prop("checked") == true) {
$(featureConfiguringSwitch).prop("checked", false);
}
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
});
$(advanceOperations).on('shown.bs.collapse', function (event) {
var expandedFeatureBody = event.target.id;
var operation = expandedFeatureBody.substr(0, expandedFeatureBody.lastIndexOf("-"));
var featureConfiguringSwitch = "#" + operation + "-heading input[type=checkbox]";
var featureConfiguredIcon = "#" + operation + "-configured";
if ($(featureConfiguringSwitch).prop("checked") == false) {
$(featureConfiguringSwitch).prop("checked", true);
}
if ($(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).removeClass("hidden");
}
});
// <end - fixing feature-configuring switch double-click issue>
// adding support for cloning multiple profiles per feature with cloneable class definitions
$(advanceOperations).on("click", ".multi-view.add.enabled", function () {
// get a copy of .cloneable and create new .cloned div element
var cloned = "<div class='cloned'><hr>" + $(".cloneable", $(this).parent().parent()).html() + "</div>";
// append newly created .cloned div element to panel-body
$(this).parent().parent().append(cloned);
// enable remove action of newly cloned div element
$(".cloned", $(this).parent().parent()).each(
function () {
if ($(".multi-view.remove", this).hasClass("disabled")) {
$(".multi-view.remove", this).removeClass("disabled");
}
if (!$(".multi-view.remove", this).hasClass("enabled")) {
$(".multi-view.remove", this).addClass("enabled");
}
}
);
});
$(advanceOperations).on("click", ".multi-view.remove.enabled", function () {
$(this).parent().remove();
});
// enabling or disabling grouped-input based on the status of a parent check-box
$(advanceOperations).on("click", ".grouped-input", function () {
updateGroupedInputVisibility(this);
});
// add form entry click function for grid inputs
$(advanceOperations).on("click", "[data-click-event=add-form]", function () {
var addFormContainer = $("[data-add-form-container=" + $(this).attr("href") + "]");
var clonedForm = $("[data-add-form=" + $(this).attr("href") + "]").clone().find("[data-add-form-element=clone]")
.attr("data-add-form-clone", $(this).attr("href"));
// adding class .child-input to capture text-input-array-values
$("input, select", clonedForm).addClass("child-input");
$(addFormContainer).append(clonedForm);
setId(addFormContainer);
showHideHelpText(addFormContainer);
});
// remove form entry click function for grid inputs
$(advanceOperations).on("click", "[data-click-event=remove-form]", function () {
var addFormContainer = $("[data-add-form-container=" + $(this).attr("href") + "]");
$(this).closest("[data-add-form-element=clone]").remove();
setId(addFormContainer);
showHideHelpText(addFormContainer);
});
});

@ -0,0 +1,402 @@
<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>
</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>
</h2>
<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>
<div id="passcode-policy-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="passcode-policy-body">
<hr/>
<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">
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">
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>
</h2>
<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>
<div id="camera-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="camera-body">
<hr/>
<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.">
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>
</h2>
<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>
<div id="encrypt-storage-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="encrypt-storage-body">
<hr/>
<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">
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>
</h2>
<div class="panel-title-description">
This configuration can be used to create a black list or white list of applications.
</div>
</div>
<div id="app-restriction-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="app-restriction-body">
<hr/>
<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="btn btn-secondary 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>
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>
</div>
</div>

@ -61,86 +61,67 @@
<Feature code="DEVICE_RING"> <Feature code="DEVICE_RING">
<Name>Ring</Name> <Name>Ring</Name>
<Description>Ring the device</Description> <Description>Ring the device</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/ring" method="POST"> <Operation context="/api/device-mgt/android/v1.0/admin/devices/ring" method="POST" type="application/json">
</Operation> </Operation>
</Feature> </Feature>
<Feature code="DEVICE_LOCK"> <Feature code="DEVICE_LOCK">
<Name>Device Lock</Name> <Name>Device Lock</Name>
<Description>Lock the device</Description> <Description>Lock the device</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/lock-devices" method="POST" conent-type="application/json"> <Operation context="/api/device-mgt/android/v1.0/admin/devices/lock-devices" method="POST" type="application/json">
<FormParameters>
<Parameter id="message" optional="true" type="text">Message to be sent to the device</Parameter>
</FormParameters>
</Operation> </Operation>
</Feature> </Feature>
<Feature code="DEVICE_LOCATION"> <Feature code="DEVICE_LOCATION">
<Name>Location</Name> <Name>Location</Name>
<Description>Request coordinates of device location</Description> <Description>Request coordinates of device location</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/location" method="POST" conent-type="application/json"> <Operation context="/api/device-mgt/android/v1.0/admin/devices/location" method="POST" type="application/json">
</Operation> </Operation>
</Feature> </Feature>
<Feature code="CLEAR_PASSWORD"> <Feature code="CLEAR_PASSWORD">
<Name>Clear Password</Name> <Name>Clear Password</Name>
<Description>Clear current password</Description> <Description>Clear current password</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/clear-password" method="POST" conent-type="application/json"> <Operation context="/api/device-mgt/android/v1.0/admin/devices/clear-password" method="POST" type="application/json">
</Operation> </Operation>
</Feature> </Feature>
<Feature code="DEVICE_REBOOT"> <Feature code="DEVICE_REBOOT">
<Name>Reboot</Name> <Name>Reboot</Name>
<Description>Reboot the device</Description> <Description>Reboot the device</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/reboot" method="POST" conent-type="application/json"> <Operation context="/api/device-mgt/android/v1.0/admin/devices/reboot" method="POST" type="application/json">
</Operation> </Operation>
</Feature> </Feature>
<Feature code="UPGRADE_FIRMWARE"> <Feature code="UPGRADE_FIRMWARE">
<Name>Upgrade Firmware</Name> <Name>Upgrade Firmware</Name>
<Description>Upgrade Firmware</Description> <Description>Upgrade Firmware</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/upgrade-firmware" method="POST" conent-type="application/json"> <Operation context="/api/device-mgt/android/v1.0/admin/devices/upgrade-firmware" method="POST" type="application/json">
<FormParameters>
<Parameter id="immediate" optional="true" type="check" helper-text="Once enabled, device firmware upgrade process will start instantly.">Instant Upgrade</Parameter>
<Parameter id="schedule" optional="false" type="text">Enter the date and time to schedule firmware upgrade.</Parameter>
<Parameter id="server" optional="true" type="text">Enter firmware upgrade server URL (ie. http://abc.com or http://abc.com/ota) (Optional).</Parameter>
</FormParameters>
</Operation> </Operation>
</Feature> </Feature>
<Feature code="DEVICE_MUTE"> <Feature code="DEVICE_MUTE">
<Name>Mute</Name> <Name>Mute</Name>
<Description>Enable mute in the device</Description> <Description>Enable mute in the device</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/mute" method="POST" conent-type="application/json"> <Operation context="/api/device-mgt/android/v1.0/admin/devices/mute" method="POST" type="application/json">
</Operation> </Operation>
</Feature> </Feature>
<Feature code="NOTIFICATION"> <Feature code="NOTIFICATION">
<Name>Message</Name> <Name>Message</Name>
<Description>Send message</Description> <Description>Send message</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/send-notification" method="POST" conent-type="application/json"> <Operation context="/api/device-mgt/android/v1.0/admin/devices/send-notification" method="POST" type="application/json">
<FormParameters>
<Parameter id="messageText" optional="false" type="text">Title Here...</Parameter>
<Parameter id="messageTitle" optional="false" type="text-area">Message Here...</Parameter>
</FormParameters>
</Operation> </Operation>
</Feature> </Feature>
<Feature code="CHANGE_LOCK_CODE"> <Feature code="CHANGE_LOCK_CODE">
<Name>Change Lock-code</Name> <Name>Change Lock-code</Name>
<Description>Change current lock code</Description> <Description>Change current lock code</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/change-lock-code" method="POST" conent-type="application/json"> <Operation context="/api/device-mgt/android/v1.0/admin/devices/change-lock-code" method="POST" type="application/json">
<FormParameters>
<Parameter id="lockCode" optional="false" type="text">Lock Code</Parameter>
</FormParameters>
</Operation> </Operation>
</Feature> </Feature>
<Feature code="ENTERPRISE_WIPE"> <Feature code="ENTERPRISE_WIPE">
<Name>Enterprise Wipe</Name> <Name>Enterprise Wipe</Name>
<Description>Remove enterprise applications</Description> <Description>Remove enterprise applications</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/enterprise-wipe" method="POST" conent-type="application/json"> <Operation context="/api/device-mgt/android/v1.0/admin/devices/enterprise-wipe" method="POST" type="application/json">
</Operation> </Operation>
</Feature> </Feature>
<Feature code="WIPE_DATA"> <Feature code="WIPE_DATA">
<Name>Wipe Data</Name> <Name>Wipe Data</Name>
<Description>Factory reset the device</Description> <Description>Factory reset the device</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/wipe" method="POST" conent-type="application/json"> <Operation context="/api/device-mgt/android/v1.0/admin/devices/wipe" method="POST" type="application/json">
<FormParameters>
<!-- Needs to be converted to a unit -->
<Parameter id="pin" optional="false" type="text">Enter PIN code* of the device.</Parameter>
</FormParameters>
</Operation> </Operation>
</Feature> </Feature>
<Feature code="WIFI"> <Feature code="WIFI">

@ -1232,7 +1232,7 @@
<carbon.devicemgt.version.range>[2.0.0, 3.0.0)</carbon.devicemgt.version.range> <carbon.devicemgt.version.range>[2.0.0, 3.0.0)</carbon.devicemgt.version.range>
<!-- Carbon App Management --> <!-- Carbon App Management -->
<carbon.appmgt.version>1.2.5</carbon.appmgt.version> <carbon.appmgt.version>1.2.8-SNAPSHOT</carbon.appmgt.version>
<!-- Carbon Device Management Plugins --> <!-- Carbon Device Management Plugins -->
<carbon.devicemgt.plugins.version>3.0.3-SNAPSHOT</carbon.devicemgt.plugins.version> <carbon.devicemgt.plugins.version>3.0.3-SNAPSHOT</carbon.devicemgt.plugins.version>
@ -1346,7 +1346,7 @@
<javax.xml.parsers.import.pkg.version>[0.0.0,1.0.0)</javax.xml.parsers.import.pkg.version> <javax.xml.parsers.import.pkg.version>[0.0.0,1.0.0)</javax.xml.parsers.import.pkg.version>
<!-- MB Features --> <!-- MB Features -->
<carbon.messaging.version>3.1.11</carbon.messaging.version> <carbon.messaging.version>3.1.3</carbon.messaging.version>
<!--Feign Version--> <!--Feign Version-->
<io.github.openfeign.version>9.3.1</io.github.openfeign.version> <io.github.openfeign.version>9.3.1</io.github.openfeign.version>

Loading…
Cancel
Save