Merging with master

revert-dabc3590
Ace 8 years ago
commit a05dad6f4d

@ -21,7 +21,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -3,7 +3,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -14,7 +14,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-plugins</artifactId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-plugins</artifactId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-plugins</artifactId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<artifactId>iot-base-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -20,7 +20,7 @@
<parent>
<artifactId>iot-base-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -20,7 +20,7 @@
<parent>
<artifactId>iot-base-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -20,7 +20,7 @@
<parent>
<artifactId>iot-base-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -20,7 +20,7 @@
<parent>
<artifactId>iot-base-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -22,7 +22,7 @@
<parent>
<artifactId>iot-base-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>iot-base-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<artifactId>iot-base-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -23,7 +23,7 @@
<parent>
<artifactId>iot-base-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>iot-base-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-plugins</artifactId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>carbon-device-mgt-plugins-parent</artifactId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-plugins</artifactId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-plugins</artifactId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>android-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -43,9 +43,6 @@ public class ApplicationUninstallation extends AndroidOperation implements Seria
@Pattern(regexp = "^[A-Za-z]*$")
private String type;
@ApiModelProperty(name = "url", value = "The URL of the application.", required = true)
private String url;
@ApiModelProperty(name = "name", value = "The name of the application.", required = true)
@Size(min = 2, max = 45)
private String name;
@ -66,14 +63,6 @@ public class ApplicationUninstallation extends AndroidOperation implements Seria
this.type = type;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getName() {
return name;
}

@ -20,6 +20,7 @@ package org.wso2.carbon.mdm.services.android.services;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import org.wso2.carbon.mdm.services.android.bean.wrapper.*;
@ -92,7 +93,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new lock operation.")
})
@Scope(key = "device:android:operation:lock", name = "Lock device", description = "")
@Permission(name = "Lock Device", permission = "/device-mgt/devices/owning/operations/android/lock")
Response configureDeviceLock(
@ApiParam(name = "deviceLockBeanWrapper",
value = "Device lock configurations with device IDs") DeviceLockBeanWrapper deviceLockBeanWrapper);
@ -146,7 +147,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new un-lock operation.")
})
@Scope(key = "device:android:operation:unlock", name = "Unlock device", description = "")
@Permission(name = "Unlock Device", permission = "/device-mgt/devices/owning/operations/android/unlock")
Response configureDeviceUnlock(
@ApiParam(name = "deviceIDs", value = "DeviceIds to be enable device unlock operation")
List<String> deviceIDs);
@ -199,7 +200,7 @@ public interface DeviceManagementAdminService {
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while adding a new get-location operation.")})
@Scope(key = "device:android:operation:location", name = "Get device location", description = "")
@Permission(name = "Get Device Location", permission = "/device-mgt/devices/owning/operations/android/location")
Response getDeviceLocation(
@ApiParam(name = "deviceIDs", value = "DeviceIDs to be requested to get device location")
List<String> deviceIDs);
@ -252,7 +253,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new clear password operation.")
})
@Scope(key = "device:android:operation:clear-password", name = "Clear password of device", description = "")
@Permission(name = "Clear Password of Device", permission = "/device-mgt/devices/owning/operations/android/clear-password")
Response removePassword(
@ApiParam(name = "deviceIDs",
value = "DeviceIds to be requested to remove password") List<String> deviceIDs);
@ -305,7 +306,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new control camera operation.")
})
@Scope(key = "device:android:operation:camera", name = "Enable/Disable camera", description = "")
@Permission(name = "Manage Camera", permission = "/device-mgt/devices/owning/operations/android/camera")
Response configureCamera(
@ApiParam(name = "cameraBeanWrapper", value = "Camera enable/disable configurations with device IDs")
CameraBeanWrapper cameraBeanWrapper);
@ -361,19 +362,19 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new device info operation.")
})
@Scope(key = "device:android:operation:info", name = "Get device information", description = "")
@Permission(name = "Get Device Information", permission = "/device-mgt/devices/owning/operations/android/info")
Response getDeviceInformation(
@ApiParam(name = "deviceIds", value = "Device IDs to be requested to get device information")
List<String> deviceIDs);
@POST
@Path("/info")
@Path("/logcat")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Requesting Information from Android Devices",
notes = "Using this REST API you are able to request for Android device details. Once this REST API is" +
value = "Requesting logcat from Android Devices",
notes = "Using this REST API you are able to request for Android device log details. Once this REST API is" +
" executed it will be in the Android operation queue until the device calls the server to retrieve " +
"the list of operations that needs to be executed on the device",
response = Activity.class,
@ -417,6 +418,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new device logcat operation.")
})
@Permission(name = "Get Logs", permission = "/device-mgt/devices/owning/operations/android/logcat")
Response getDeviceLogcat(
@ApiParam(name = "deviceIds", value = "Device IDs to be requested to get device logcat")
List<String> deviceIDs);
@ -470,7 +472,7 @@ public interface DeviceManagementAdminService {
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while adding a enterprise wipe operation.")})
@Scope(key = "device:android:operation:enterprise-wipe", name = "Enterprise wipe", description = "")
@Permission(name = "Enterprise Wipe", permission = "/device-mgt/devices/owning/operations/android/enterprise-wipe")
Response wipeDevice(@ApiParam(name = "deviceIDs", value = "Device IDs to be requested to do enterprise-wipe")
List<String> deviceIDs);
@ -522,7 +524,7 @@ public interface DeviceManagementAdminService {
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while adding a device wipe operation.")})
@Scope(key = "device:android:operation:wipe", name = "Factory reset device", description = "")
@Permission(name = "Factory Reset", permission = "/device-mgt/devices/owning/operations/android/wipe")
Response wipeData(
@ApiParam(name = "wipeDataBeanWrapper", value = "Configurations and DeviceIds needed to do wipe-data")
WipeDataBeanWrapper wipeDataBeanWrapper);
@ -579,7 +581,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new get-applications operation.")
})
@Scope(key = "device:android:operation:applications", name = "Get installed applications", description = "")
@Permission(name = "Get Installed Application", permission = "/device-mgt/devices/owning/operations/android/applications")
Response getApplications(
@ApiParam(name = "deviceIDs", value = "Device Ids needed to get applications that are already installed")
List<String> deviceIDs);
@ -632,7 +634,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new device ring operation.")
})
@Scope(key = "device:android:operation:ring", name = "Ring device", description = "")
@Permission(name = "Ring Device", permission = "/device-mgt/devices/owning/operations/android/ring")
Response ringDevice(
@ApiParam(name = "deviceIDs", value = "Device Ids needed for ring")
List<String> deviceIDs);
@ -685,7 +687,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new device reboot operation.")
})
@Scope(key = "device:android:operation:reboot", name = "Reboot device", description = "")
@Permission(name = "Reboot Device", permission = "/device-mgt/devices/owning/operations/android/reboot")
Response rebootDevice(
@ApiParam(name = "deviceIDs", value = "Device Ids needed for reboot.")
List<String> deviceIDs);
@ -738,7 +740,7 @@ public interface DeviceManagementAdminService {
"Server error occurred while adding a new device mute operation.")
})
@Path("/mute")
@Scope(key = "device:android:operation:mute", name = "Mute device", description = "")
@Permission(name = "Mute Device", permission = "/device-mgt/devices/owning/operations/android/mute")
Response muteDevice(
@ApiParam(name = "deviceIDs", value = "DeviceIDs need to be muted")
List<String> deviceIDs);
@ -794,7 +796,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new install-application operation.")
})
@Scope(key = "device:android:operation:install-app", name = "Install applications", description = "")
@Permission(name = "Install Applications", permission = "/device-mgt/devices/owning/operations/android/install-app")
Response installApplication(
@ApiParam(name = "applicationInstallationBeanWrapper", value = "Properties of installed apps and device IDs")
ApplicationInstallationBeanWrapper applicationInstallationBeanWrapper);
@ -850,7 +852,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new update-application operation.")
})
@Scope(key = "device:android:operation:update-app", name = "Update installed applications", description = "")
@Permission(name = "Update installed applications", permission = "/device-mgt/devices/owning/operations/android/update-app")
Response updateApplication(
@ApiParam(name = "applicationUpdateBeanWrapper", value = "Properties of updated apps and device IDs")
ApplicationUpdateBeanWrapper applicationUpdateBeanWrapper);
@ -903,7 +905,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new uninstall-application operation.")
})
@Scope(key = "device:android:operation:uninstall-app", name = "Uninstall applications", description = "")
@Permission(name = "Uninstall Applications", permission = "/device-mgt/devices/owning/operations/android/uninstall-app")
Response uninstallApplication(
@ApiParam(name = "applicationUninstallationBeanWrapper",
value = "applicationUninstallationConfigs and Device Ids")
@ -958,7 +960,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new blacklist-applications operation.")
})
@Scope(key = "device:android:operation:blacklist-app", name = "Blacklist applications", description = "")
@Permission(name = "Blacklist Applications", permission = "/device-mgt/devices/owning/operations/android/blacklist-app")
Response blacklistApplications(
@ApiParam(name = "blacklistApplicationsBeanWrapper", value = "BlacklistApplications " +
"Configuration and DeviceIds")
@ -1013,7 +1015,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new upgrade firmware operation.")
})
@Scope(key = "device:android:operation:upgrade", name = "Upgrade firmware", description = "")
@Permission(name = "Upgrade Firmware", permission = "/device-mgt/devices/owning/operations/android/upgrade")
Response upgradeFirmware(
@ApiParam(name = "upgradeFirmwareBeanWrapper",
value = "Firmware upgrade configuration and DeviceIds")
@ -1068,7 +1070,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new configure VPN operation.")
})
@Scope(key = "device:android:operation:vpn", name = "Add VPN profiles", description = "")
@Permission(name = "Add VPN", permission = "/device-mgt/devices/owning/operations/android/vpn")
Response configureVPN(
@ApiParam(name = "vpnBeanWrapper",
value = "VPN configuration and DeviceIds")
@ -1122,7 +1124,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new send notification operation.")
})
@Scope(key = "device:android:operation:notification", name = "Send notifications", description = "")
@Permission(name = "Send Notifications", permission = "/device-mgt/devices/owning/operations/android/notification")
Response sendNotification(
@ApiParam(name = "notificationBeanWrapper",
value = "Notification Configurations and device Ids")
@ -1176,7 +1178,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new configure wifi operation.")
})
@Scope(key = "device:android:operation:wifi", name = "Add WiFi configurations", description = "")
@Permission(name = "Add Wifi Configuration", permission = "/device-mgt/devices/owning/operations/android/wifi")
Response configureWifi(
@ApiParam(name = "wifiBeanWrapper",
value = "WifiConfigurations and Device Ids") WifiBeanWrapper wifiBeanWrapper);
@ -1229,7 +1231,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new encrypt storage operation.")
})
@Scope(key = "device:android:operation:encrypt", name = "Encrypt device", description = "")
@Permission(name = "Encrypt Device", permission = "/device-mgt/devices/owning/operations/android/encrypt")
Response encryptStorage(
@ApiParam(name = "encryptionBeanWrapper",
value = "Configurations and deviceIds need to be done data encryption")
@ -1283,7 +1285,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new change lock code operation.")
})
@Scope(key = "device:android:operation:change-lock", name = "Change password of device", description = "")
@Permission(name = "Change Password of Device", permission = "/device-mgt/devices/owning/operations/android/change-lock")
Response changeLockCode(
@ApiParam(name = "lockCodeBeanWrapper",
value = "Configurations and device Ids need to be done change lock code")
@ -1337,7 +1339,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new set password policy operation.")
})
@Scope(key = "device:android:operation:password-policy", name = "Set password policy", description = "")
@Permission(name = "Set Password Policy", permission = "/device-mgt/devices/owning/operations/android/password-policy")
Response setPasswordPolicy(
@ApiParam(name = "passwordPolicyBeanWrapper",
value = "Password Policy Configurations and Device Ids")
@ -1391,7 +1393,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new set webclip operation.")
})
@Scope(key = "device:android:operation:webclip", name = "Add webclips", description = "")
@Permission(name = "Add Webclips", permission = "/device-mgt/devices/owning/operations/android/webclip")
Response setWebClip(
@ApiParam(name = "webClipBeanWrapper",
value = "Configurations to need set web clip on device and device Ids")

@ -20,6 +20,7 @@ package org.wso2.carbon.mdm.services.android.services;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.mdm.services.android.bean.wrapper.AndroidApplication;
@ -87,7 +88,7 @@ public interface DeviceManagementService {
message = "Internal Server Error. \n " +
"Server error occurred while updating the application list.")
})
@Scope(key = "device:android:enroll", name = "Enroll Android device", description = "")
@Permission(name = "Enroll Device", permission = "/device-mgt/devices/enroll/android")
Response updateApplicationList(
@ApiParam(
name = "id",
@ -141,7 +142,7 @@ public interface DeviceManagementService {
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching policies.")
})
@Scope(key = "device:android:enroll", name = "Enroll Android device", description = "")
@Permission(name = "Enroll Device", permission = "/device-mgt/devices/enroll/android")
Response getPendingOperations(
@ApiParam(
name = "id",
@ -206,7 +207,7 @@ public interface DeviceManagementService {
message = "Internal Server Error. \n " +
"Server error occurred while adding a new policy.")
})
@Permission(name = "Enroll Device", permission = "/device-mgt/devices/enroll/android")
Response enrollDevice(@ApiParam(name = "device", value = "Device Information to be enroll")
@Valid AndroidDevice device);
@ -245,7 +246,7 @@ public interface DeviceManagementService {
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the enrollment status of the Android device.")
})
@Scope(key = "device:android:enroll", name = "Enroll Android device", description = "")
@Permission(name = "Enroll Device", permission = "/device-mgt/devices/enroll/android")
Response isEnrolled(
@ApiParam(
name = "id",
@ -299,7 +300,7 @@ public interface DeviceManagementService {
message = "Internal Server Error. \n " +
"Server error occurred while updating the device enrollment.")
})
@Scope(key = "device:android:enroll", name = "Enroll Android device", description = "")
@Permission(name = "Enroll Device", permission = "/device-mgt/devices/enroll/android")
Response modifyEnrollment(
@ApiParam(
name = "id",
@ -329,7 +330,7 @@ public interface DeviceManagementService {
message = "Internal Server Error. \n " +
"Server error occurred while dis-enrolling the device.")
})
@Scope(key = "device:android:disenroll", name = "Enroll Android device", description = "")
@Permission(name = "Enroll Device", permission = "/device-mgt/devices/enroll/android")
Response disEnrollDevice(
@ApiParam(
name = "id",

@ -20,6 +20,7 @@ package org.wso2.carbon.mdm.services.android.services;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.mdm.services.android.bean.AndroidPlatformConfiguration;
@ -81,7 +82,7 @@ public interface DeviceTypeConfigurationService {
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching Android platform configuration.")
})
@Scope(key = "configuration:view", name = "View configurations", description = "")
@Permission(name = "View Configurations", permission = "/device-mgt/configurations/view")
Response getConfiguration(
@ApiParam(
name = "If-Modified-Since",
@ -131,7 +132,7 @@ public interface DeviceTypeConfigurationService {
message = "Internal Server Error. \n " +
"Server error occurred while modifying Android platform configuration.")
})
@Scope(key = "configuration:manage", name = "Add configurations", description = "")
@Permission(name = "Manage Configurations", permission = "/device-mgt/configurations/manage")
Response updateConfiguration(
@ApiParam(name = "configuration",
value = "AndroidPlatformConfiguration")
@ -152,7 +153,7 @@ public interface DeviceTypeConfigurationService {
@ApiResponse(
code = 200,
message = "OK. \n Successfully fetched Android license configuration.",
response = PlatformConfiguration.class,
response = String.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
@ -179,7 +180,7 @@ public interface DeviceTypeConfigurationService {
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching Android license configuration.")
})
@Scope(key = "device:android:enroll", name = "Enroll Android device", description = "")
@Permission(name = "Enroll Device", permission = "/device-mgt/devices/enroll/android")
Response getLicense(
@ApiParam(
name = "If-Modified-Since",

@ -20,6 +20,7 @@ package org.wso2.carbon.mdm.services.android.services;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.mdm.services.android.bean.DeviceState;
import org.wso2.carbon.mdm.services.android.bean.wrapper.EventBeanWrapper;
@ -90,7 +91,7 @@ public interface EventReceiverService {
message = "Internal Server Error. \n " +
"Server error occurred while publishing events.")
})
@Scope(key = "device:android:event:manage", name = "Publish events to DAS", description = "")
@Permission(name = "Publish Events to DAS", permission = "/device-mgt/devices/enroll/android")
Response publishEvents(
@ApiParam(
name = "eventBeanWrapper",
@ -140,7 +141,7 @@ public interface EventReceiverService {
code = 500,
message = "Error occurred while getting published events for specific device.")
})
@Scope(key = "device:android:event:read", name = "View events", description = "")
@Permission(name = "Publish Events to DAS", permission = "/device-mgt/devices/enroll/android")
Response retrieveAlerts(
@ApiParam(
name = "id",

@ -20,14 +20,45 @@ package org.wso2.carbon.mdm.services.android.services.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.json.JSONObject;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.core.operation.mgt.CommandOperation;
import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation;
import org.wso2.carbon.mdm.services.android.bean.*;
import org.wso2.carbon.mdm.services.android.bean.wrapper.*;
import org.wso2.carbon.mdm.services.android.bean.ApplicationInstallation;
import org.wso2.carbon.mdm.services.android.bean.ApplicationUninstallation;
import org.wso2.carbon.mdm.services.android.bean.ApplicationUpdate;
import org.wso2.carbon.mdm.services.android.bean.BlacklistApplications;
import org.wso2.carbon.mdm.services.android.bean.Camera;
import org.wso2.carbon.mdm.services.android.bean.DeviceEncryption;
import org.wso2.carbon.mdm.services.android.bean.DeviceLock;
import org.wso2.carbon.mdm.services.android.bean.ErrorResponse;
import org.wso2.carbon.mdm.services.android.bean.LockCode;
import org.wso2.carbon.mdm.services.android.bean.Notification;
import org.wso2.carbon.mdm.services.android.bean.PasscodePolicy;
import org.wso2.carbon.mdm.services.android.bean.UpgradeFirmware;
import org.wso2.carbon.mdm.services.android.bean.Vpn;
import org.wso2.carbon.mdm.services.android.bean.WebClip;
import org.wso2.carbon.mdm.services.android.bean.Wifi;
import org.wso2.carbon.mdm.services.android.bean.WipeData;
import org.wso2.carbon.mdm.services.android.bean.wrapper.ApplicationInstallationBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.ApplicationUninstallationBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.ApplicationUpdateBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.BlacklistApplicationsBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.CameraBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.DeviceLockBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.EncryptionBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.LockCodeBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.NotificationBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.PasswordPolicyBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.UpgradeFirmwareBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.VpnBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.WebClipBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.WifiBeanWrapper;
import org.wso2.carbon.mdm.services.android.bean.wrapper.WipeDataBeanWrapper;
import org.wso2.carbon.mdm.services.android.exception.BadRequestException;
import org.wso2.carbon.mdm.services.android.exception.UnexpectedServerErrorException;
import org.wso2.carbon.mdm.services.android.services.DeviceManagementAdminService;
@ -41,10 +72,15 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Path("/admin/devices")
@Produces(MediaType.APPLICATION_JSON)
@ -492,19 +528,60 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe
try {
if (applicationInstallationBeanWrapper == null || applicationInstallationBeanWrapper.getOperation() ==
null) {
null) {
String errorMessage = "The payload of the application installing operation is incorrect";
log.error(errorMessage);
throw new BadRequestException(
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
}
ApplicationInstallation applicationInstallation = applicationInstallationBeanWrapper.getOperation();
JSONObject payload = new JSONObject(applicationInstallation.toJSON());
try {
URL url = new URL(payload.getString("url"));
URLConnection conn = url.openConnection();
//get all headers
Map<String, List<String>> headerFields = conn.getHeaderFields();
boolean isFile = false;
for (Map.Entry<String, List<String>> entry : headerFields.entrySet()) {
if ("Content-Type".equals(entry.getKey()) && entry.getValue() != null
&& entry.getValue().size() > 0 && "application/octet-stream".equals(entry.getValue().get(0))) {
isFile = true;
break;
}
}
if (!isFile) {
String errorMessage = "URL is not pointed to a downloadable file.";
log.error(errorMessage);
throw new BadRequestException(
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
}
validateType(payload);
} catch (MalformedURLException e) {
String errorMessage = "Malformed application url.";
log.error(errorMessage);
throw new BadRequestException(
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
} catch (IOException e) {
String errorMessage = "Invalid application url.";
log.error(errorMessage);
throw new BadRequestException(
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
}
ProfileOperation operation = new ProfileOperation();
operation.setCode(AndroidConstants.OperationCodes.INSTALL_APPLICATION);
operation.setType(Operation.Type.PROFILE);
operation.setPayLoad(applicationInstallation.toJSON());
operation.setPayLoad(payload.toString());
return AndroidAPIUtils.getOperationResponse(applicationInstallationBeanWrapper.getDeviceIDs(),
operation);
operation);
} catch (JSONException e) {
String errorMessage = "Invalid payload for the operation.";
log.error(errorMessage);
throw new BadRequestException(
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
} catch (InvalidDeviceException e) {
String errorMessage = "Invalid Device Identifiers found.";
log.error(errorMessage, e);
@ -581,6 +658,9 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
}
ApplicationUninstallation applicationUninstallation = applicationUninstallationBeanWrapper.getOperation();
JSONObject payload = new JSONObject(applicationUninstallation.toJSON());
validateType(payload);
ProfileOperation operation = new ProfileOperation();
operation.setCode(AndroidConstants.OperationCodes.UNINSTALL_APPLICATION);
operation.setType(Operation.Type.PROFILE);
@ -606,6 +686,25 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe
}
}
private void validateType(JSONObject payload) {
if (payload.has("type")) {
String type = payload.getString("type");
if (!"enterprise".equalsIgnoreCase(type)
&& !"public".equalsIgnoreCase(type)
&& !"webapp".equalsIgnoreCase(type)) {
String errorMessage = "Invalid application type.";
log.error(errorMessage);
throw new BadRequestException(
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
}
} else {
String errorMessage = "Application type is missing.";
log.error(errorMessage);
throw new BadRequestException(
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
}
}
@POST
@Path("/blacklist-applications")
@Override

@ -52,15 +52,15 @@ public class DeviceTypeConfigurationServiceImpl implements DeviceTypeConfigurati
public Response getConfiguration(
@HeaderParam("If-Modified-Since") String ifModifiedSince) {
String msg;
PlatformConfiguration PlatformConfiguration;
PlatformConfiguration platformConfiguration;
List<ConfigurationEntry> configs;
try {
PlatformConfiguration = AndroidAPIUtils.getDeviceManagementService().
platformConfiguration = AndroidAPIUtils.getDeviceManagementService().
getConfiguration(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
if (PlatformConfiguration != null) {
configs = PlatformConfiguration.getConfiguration();
if (platformConfiguration != null) {
configs = platformConfiguration.getConfiguration();
} else {
PlatformConfiguration = new PlatformConfiguration();
platformConfiguration = new PlatformConfiguration();
configs = new ArrayList<>();
}
ConfigurationEntry entry = new ConfigurationEntry();
@ -73,7 +73,7 @@ public class DeviceTypeConfigurationServiceImpl implements DeviceTypeConfigurati
entry.setName(AndroidConstants.TenantConfigProperties.LICENSE_KEY);
entry.setValue(license.getText());
configs.add(entry);
PlatformConfiguration.setConfiguration(configs);
platformConfiguration.setConfiguration(configs);
}
} catch (DeviceManagementException e) {
msg = "Error occurred while retrieving the Android tenant configuration";
@ -81,14 +81,13 @@ public class DeviceTypeConfigurationServiceImpl implements DeviceTypeConfigurati
throw new UnexpectedServerErrorException(
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
}
return Response.status(Response.Status.OK).entity(PlatformConfiguration).build();
return Response.status(Response.Status.OK).entity(platformConfiguration).build();
}
@PUT
@Override
public Response updateConfiguration(@Valid AndroidPlatformConfiguration androidPlatformConfiguration) {
String msg;
Message responseMsg = new Message();
ConfigurationEntry licenseEntry = null;
PlatformConfiguration configuration = new PlatformConfiguration();
if (androidPlatformConfiguration == null) {
@ -120,16 +119,13 @@ public class DeviceTypeConfigurationServiceImpl implements DeviceTypeConfigurati
configuration.setConfiguration(configs);
AndroidAPIUtils.getDeviceManagementService().saveConfiguration(configuration);
//AndroidAPIUtils.getGCMService().resetTenantConfigCache();
Response.status(Response.Status.ACCEPTED);
responseMsg.setResponseMessage("Android platform configuration has been updated successfully.");
responseMsg.setResponseCode(Response.Status.ACCEPTED.toString());
} catch (DeviceManagementException e) {
msg = "Error occurred while modifying configuration settings of Android platform";
log.error(msg, e);
throw new UnexpectedServerErrorException(
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
}
return Response.status(Response.Status.CREATED).entity(responseMsg).build();
return Response.status(Response.Status.OK).entity("Android platform configuration has been updated successfully.").build();
}

@ -122,17 +122,16 @@ public class AndroidAPIUtils {
throw new BadRequestException(
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
}
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
List<DeviceIdentifier> deviceids = new ArrayList<>();
DeviceIdentifier deviceIdentifier;
List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>();
for (String deviceId : deviceIDs) {
deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(deviceId);
deviceIdentifier.setType(AndroidConstants.DEVICE_TYPE_ANDROID);
deviceids.add(deviceIdentifier);
deviceIdentifiers.add(deviceIdentifier);
}
Activity activity = null;
activity = getDeviceManagementService().addOperation(
DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID, operation, deviceids);
Activity activity = getDeviceManagementService().addOperation(
DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID, operation, deviceIdentifiers);
// if (activity != null) {
// GCMService gcmService = getGCMService();
// if (gcmService.isGCMEnabled()) {
@ -144,7 +143,6 @@ public class AndroidAPIUtils {
// getGCMService().sendNotification(operation.getCode(), devices);
// }
// }
return Response.status(Response.Status.CREATED).entity(activity).build();
}

@ -55,7 +55,7 @@
<Permission>
<name>Enroll</name>
<path>/device-mgt/user/device/android/enroll</path>
<path>/device-mgt/user/device/enroll/android</path>
<url>/configuration/license</url>
<method>GET</method>
</Permission>
@ -66,42 +66,42 @@
<Permission>
<name>Enroll</name>
<path>/device-mgt/user/device/android/enroll</path>
<path>/device-mgt/user/device/enroll/android</path>
<url>/devices</url>
<method>POST</method>
</Permission>
<Permission>
<name>Enroll</name>
<path>/device-mgt/user/device/android/enroll</path>
<path>/device-mgt/user/device/enroll/android</path>
<url>/devices/*</url>
<method>DELETE</method>
</Permission>
<Permission>
<name>Enroll</name>
<path>/device-mgt/user/device/android/enroll</path>
<path>/device-mgt/user/device/enroll/android</path>
<url>/devices/*</url>
<method>PUT</method>
</Permission>
<Permission>
<name>Enroll</name>
<path>/device-mgt/user/device/android/enroll</path>
<path>/device-mgt/user/device/enroll/android</path>
<url>/devices/*/applications</url>
<method>PUT</method>
</Permission>
<Permission>
<name>Enroll</name>
<path>/device-mgt/user/device/android/enroll</path>
<path>/device-mgt/user/device/enroll/android</path>
<url>/devices/*/pending-operations</url>
<method>PUT</method>
</Permission>
<Permission>
<name>Enroll</name>
<path>/device-mgt/user/device/android/enroll</path>
<path>/device-mgt/user/device/enroll/android</path>
<url>/devices/*/status</url>
<method>GET</method>
</Permission>
@ -112,7 +112,7 @@
<Permission>
<name>Enroll</name>
<path>/device-mgt/user/device/android/enroll</path>
<path>/device-mgt/user/device/enroll/android</path>
<url>/events/publish</url>
<method>POST</method>
</Permission>

@ -23,13 +23,13 @@
<parent>
<artifactId>android-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.mobile.android.ui</artifactId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<name>WSO2 Carbon - Mobile Android UI</name>
<packaging>pom</packaging>

@ -22,7 +22,7 @@
<parent>
<artifactId>android-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -18,17 +18,20 @@
package org.wso2.carbon.device.mgt.mobile.android.impl;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceManager;
import org.wso2.carbon.device.mgt.common.ProvisioningConfig;
import org.wso2.carbon.device.mgt.common.app.mgt.Application;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.mobile.android.impl.util.AndroidPluginConstants;
import org.wso2.carbon.device.mgt.mobile.android.internal.AndroidDeviceManagementDataHolder;
import java.util.HashMap;
import java.util.List;
/**
@ -36,9 +39,13 @@ import java.util.List;
*/
public class AndroidDeviceManagementService implements DeviceManagementService {
private static final Log log = LogFactory.getLog(AndroidDeviceManagementService.class);
private DeviceManager deviceManager;
public static final String DEVICE_TYPE_ANDROID = "android";
private static final String SUPER_TENANT_DOMAIN = "carbon.super";
private static final String NOTIFIER_PROPERTY = "notifierType";
private static final String GCM_API_KEY = "gcmAPIKey";
private static final String GCM_SENDER_ID = "gcmSenderId";
@Override
public String getType() {
@ -67,7 +74,37 @@ public class AndroidDeviceManagementService implements DeviceManagementService {
@Override
public PushNotificationConfig getPushNotificationConfig() {
try {
DeviceManagementService deviceManagementService = AndroidDeviceManagementDataHolder.getInstance().
getAndroidDeviceManagementService();
if (deviceManagementService != null && deviceManagementService.getDeviceManager() != null) {
PlatformConfiguration androidConfig = deviceManagementService.getDeviceManager().getConfiguration();
if (androidConfig != null) {
List<ConfigurationEntry> configuration = androidConfig.getConfiguration();
String notifierValue = this.getConfigProperty(configuration, NOTIFIER_PROPERTY);
if (notifierValue != null && !notifierValue.isEmpty()) {
int notifierType = Integer.parseInt(notifierValue);
if (notifierType == 2) {
HashMap<String, String> config = new HashMap<>();
config.put(GCM_API_KEY, this.getConfigProperty(configuration, GCM_API_KEY));
config.put(GCM_SENDER_ID, this.getConfigProperty(configuration, GCM_SENDER_ID));
return new PushNotificationConfig(AndroidPluginConstants.NotifierType.GCM, config);
}
}
}
}
} catch (DeviceManagementException e) {
log.error("Unable to get the Android platform configuration from registry.");
}
return null;
}
private String getConfigProperty(List<ConfigurationEntry> configs, String propertyName) {
for (ConfigurationEntry entry : configs) {
if (propertyName.equals(entry.getName())) {
return entry.getValue().toString();
}
}
return null;
}
}

@ -21,7 +21,7 @@ package org.wso2.carbon.device.mgt.mobile.android.impl.util;
/**
* Defines constants used by android plugin.
*/
public class AndroidPluginConstants {
public final class AndroidPluginConstants {
//Properties related to AD_DEVICE table
public static final String DEVICE_ID = "DEVICE_ID";
@ -45,4 +45,12 @@ public class AndroidPluginConstants {
public static final String ANDROID_FEATURE_NAME = "NAME";
public static final String ANDROID_FEATURE_DESCRIPTION = "DESCRIPTION";
}
public static final class NotifierType {
private NotifierType() {
throw new AssertionError();
}
public static final String GCM = "GCM";
public static final String LOCAL = "LOCAL";
}
}

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>mobile-plugins</artifactId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>mobile-base-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.3-SNAPSHOT</version>
<version>2.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -29,7 +29,12 @@
<fileSets>
<fileSet>
<directory>${basedir}/src/main/resources/jaggeryapps/devicemgt</directory>
<outputDirectory>/</outputDirectory>
<outputDirectory>/devicemgt</outputDirectory>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
<fileSet>
<directory>${basedir}/src/main/resources/jaggeryapps/emm-web-agent</directory>
<outputDirectory>/emm-web-agent</outputDirectory>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>

@ -1,17 +1,35 @@
{{!
Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
WSO2 Inc. licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file except
in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
}}
{{unit "cdmf.unit.lib.qrcode"}}
{{unit "mdm.unit.device.qr-modal"}}
{{#zone "content"}}
{{#if permissions.VIEW_DASHBOARD}}
{{#if permissions.LIST_DEVICES}}
<div class="row ">
<div class="col-md-3 wr-stats-board">
<div class="wr-stats-board-tile">
<div class="tile-name">Devices</div>
<div>
<div class="tile-icon"><i class="fw fw-mobile"></i></div>
<div class="tile-stats">
<span id="device-count" data-device-count="true">Loading...</span>
{{#if permissions.LIST_DEVICES}}
<div class="row ">
<div class="col-md-3 wr-stats-board">
<div class="wr-stats-board-tile">
<div class="tile-name">Devices</div>
<div>
<div class="tile-icon"><i class="fw fw-mobile"></i></div>
<div class="tile-stats">
<span id="device-count" data-device-count="true">Loading...</span>
<span class="tile-stats-free">
<!--suppress HtmlUnknownTarget -->
<a id="device-count-view-btn" href="{{@app.context}}/devices">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
@ -19,28 +37,31 @@
</span>
View
</a>
<a href="javascript:toggleEnrollment()">
{{#if permissions.ENROLL_DEVICE}}
<a href="javascript:toggleEnrollment()">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
Add
</a>
{{/if}}
</span>
</div>
</div>
</div>
</div>
{{/if}}
{{# if permissions.LIST_POLICIES}}
<div class="col-md-3 wr-stats-board">
<div class="wr-stats-board-tile">
<div class="tile-name">Policies</div>
<div>
<div class="tile-icon"><i class="fw fw-policy"></i></div>
<div class="tile-stats">
<span id="policy-count" data-policy-count="true">Loading...</span>
</div>
{{/if}}
{{# if permissions.LIST_POLICIES}}
<div class="col-md-3 wr-stats-board">
<div class="wr-stats-board-tile">
<div class="tile-name">Policies</div>
<div>
<div class="tile-icon"><i class="fw fw-policy"></i></div>
<div class="tile-stats">
<span id="policy-count" data-policy-count="true">Loading...</span>
<span class="tile-stats-free">
<!--suppress HtmlUnknownTarget -->
<a id="policy-count-view-btn" href="{{@app.context}}/policies/">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
@ -48,6 +69,7 @@
</span>
View
</a>
<!--suppress HtmlUnknownTarget -->
{{#if permissions.ADD_POLICY}}
<a href="{{@app.context}}/policy/add">
<span class="fw-stack">
@ -58,20 +80,21 @@
</a>
{{/if}}
</span>
</div>
</div>
</div>
</div>
{{/if}}
{{# if permissions.LIST_USERS}}
<div class="col-md-3 wr-stats-board">
<div class="wr-stats-board-tile">
<div class="tile-name">Users</div>
<div>
<div class="tile-icon"><i class="fw fw-user"></i></div>
<div class="tile-stats">
<span id="user-count" data-user-count="true">Loading...</span>
</div>
{{/if}}
{{# if permissions.LIST_USERS}}
<div class="col-md-3 wr-stats-board">
<div class="wr-stats-board-tile">
<div class="tile-name">Users</div>
<div>
<div class="tile-icon"><i class="fw fw-user"></i></div>
<div class="tile-stats">
<span id="user-count" data-user-count="true">Loading...</span>
<span class="tile-stats-free">
<!--suppress HtmlUnknownTarget -->
<a id="user-count-view-btn" href="{{@app.context}}/users/">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
@ -79,6 +102,7 @@
</span>
View
</a>
<!--suppress HtmlUnknownTarget -->
{{#if permissions.ADD_USER}}
<a href="{{@app.context}}/user/add">
<span class="fw-stack">
@ -89,20 +113,21 @@
</a>
{{/if}}
</span>
</div>
</div>
</div>
</div>
{{/if}}
{{# if permissions.LIST_ROLES}}
<div class="col-md-3 wr-stats-board">
<div class="wr-stats-board-tile">
<div class="tile-name">Roles</div>
<div>
<div class="tile-icon"><i class="fw fw-bookmark"></i></div>
<div class="tile-stats">
<span id="role-count" data-role-count="true">Loading...</span>
</div>
{{/if}}
{{# if permissions.LIST_ROLES}}
<div class="col-md-3 wr-stats-board">
<div class="wr-stats-board-tile">
<div class="tile-name">Roles</div>
<div>
<div class="tile-icon"><i class="fw fw-bookmark"></i></div>
<div class="tile-stats">
<span id="role-count" data-role-count="true">Loading...</span>
<span class="tile-stats-free">
<!--suppress HtmlUnknownTarget -->
<a id="device-count-view-btn" href="{{@app.context}}/roles">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
@ -111,6 +136,7 @@
View
</a>
{{#if permissions.ADD_ROLE}}
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/role/add">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
@ -120,14 +146,11 @@
</a>
{{/if}}
</span>
</div>
</div>
</div>
</div>
</div>
{{/if}}
{{else}}
Permission denied
</div>
{{/if}}
{{/zone}}
{{#zone "bottomJs"}}

@ -20,10 +20,19 @@ function onRequest(context) {
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var generalConfig = context.app.conf["generalConfig"];
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
var viewModel = {};
viewModel.permissions = userModule.getUIPermissions();
new Log().debug("## Permissions : " + stringify(userModule.getUIPermissions()));
var permissions = {};
permissions.LIST_DEVICES = userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/view");
permissions.LIST_POLICIES = userModule.isAuthorized("/permission/admin/device-mgt/policies/view");
permissions.LIST_ROLES = userModule.isAuthorized("/permission/admin/device-mgt/roles/view");
permissions.LIST_USERS = userModule.isAuthorized("/permission/admin/device-mgt/users/view");
permissions.ADD_POLICY = userModule.isAuthorized("/permission/admin/device-mgt/policies/manage");
permissions.ADD_ROLE = userModule.isAuthorized("/permission/admin/device-mgt/roles/manage");
permissions.ADD_USER = userModule.isAuthorized("/permission/admin/device-mgt/users/manage");
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/enroll/ios") | userModule.isAuthorized("/permission/admin/devices/enroll/android") | userModule.isAuthorized("/permission/admin/device-mgt/devices/enroll/windows") ){
permissions.ENROLL_DEVICE = true;
}
viewModel.permissions = permissions;
//TODO: Move enrollment URL into app-conf.json
viewModel.enrollmentURL = mdmProps.generalConfig.host + mdmProps.enrollmentDir;
return viewModel;

@ -26,6 +26,7 @@
</a>
</li>
<li>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/devices">
Devices
</a>
@ -38,7 +39,15 @@
{{/zone}}
{{#zone "content"}}
{{unit "cdmf.unit.lib.data-table"}}
{{unit "cdmf.unit.device.operation-mod"}}
{{unit "cdmf.unit.device.view"}}
{{#if isAuthorized}}
{{unit "cdmf.unit.lib.data-table"}}
{{unit "cdmf.unit.device.operation-mod"}}
{{unit "cdmf.unit.device.view"}}
{{else}}
<h1 class="page-sub-title">
Permission Denied
</h1>
<br>
You are not authorized to view any enrolled device in the system.
{{/if}}
{{/zone}}

@ -17,17 +17,24 @@
*/
function onRequest(context){
var utility = require("/app/modules/utility.js").utility;
context.handlebars.registerHelper('equal', function (lvalue, rvalue, options) {
if (arguments.length < 3)
throw new Error("Handlebars Helper equal needs 2 parameters");
if( lvalue!=rvalue ) {
return options.inverse(this);
} else {
return options.fn(this);
}
});
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var viewModel = {};
var deviceType = context.uriParams.deviceType;
return {"deviceViewUnitName": utility.getTenantedDeviceUnitName(deviceType, "device-view")};
// permission checks
// [1] checking viewing devices permission
viewModel["isAuthorized"] = userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/view");
if (viewModel["isAuthorized"]) {
context.handlebars.registerHelper('equal', function (lvalue, rvalue, options) {
if (arguments.length < 3)
throw new Error("Handlebars Helper equal needs 2 parameters");
if( lvalue!=rvalue ) {
return options.inverse(this);
} else {
return options.fn(this);
}
});
}
return viewModel;
}

@ -28,6 +28,7 @@
</a>
</li>
<li>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/devices">
Devices
</a>
@ -35,132 +36,137 @@
{{/zone}}
{{#zone "navbarActions"}}
{{!-- #if permissions.enroll --}}
<li>
<a href="javascript:toggleEnrollment()">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-mobile fw-stack-1x"></i>
<span class="fw-stack fw-move-right fw-move-bottom">
<i class="fw fw-circle fw-stack-2x fw-stroke fw-inverse"></i>
<i class="fw fw-circle fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
</span>
Enroll Device
</a>
</li>
{{!-- /if --}}
<li>
<a href="{{appContext}}devices/search">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-mobile fw-stack-1x"></i>
<span class="fw-stack fw-move-right fw-move-bottom">
<i class="fw fw-circle fw-stack-2x fw-stroke fw-inverse"></i>
<i class="fw fw-circle fw-stack-2x"></i>
<i class="fw fw-search fw-stack-1x"></i>
</span>
</span>
Advanced Search
</a>
</li>
{{#if permissions.ENROLL_DEVICE}}
<li id = "enroll-btn">
<a href="javascript:toggleEnrollment()">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-mobile fw-stack-1x"></i>
<span class="fw-stack fw-move-right fw-move-top">
<i class="fw fw-circle fw-stack-2x fw-stroke fw-inverse"></i>
<i class="fw fw-circle fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
</span>
&nbsp;&nbsp;Enroll Device
</a>
</li>
{{/if}}
{{#if permissions.ADVANCED_SEARCH}}
<li id = "advanced-search-btn">
<a href="{{appContext}}devices/search">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-mobile fw-stack-1x"></i>
<span class="fw-stack fw-move-right fw-move-top">
<i class="fw fw-circle fw-stack-2x fw-stroke fw-inverse"></i>
<i class="fw fw-circle fw-stack-2x"></i>
<i class="fw fw-search fw-stack-1x"></i>
</span>
</span>
&nbsp;&nbsp;Advanced Search
</a>
</li>
{{/if}}
{{/zone}}
{{#zone "content"}}
<span id="permission" data-permission="{{permissions}}"></span>
<div id="loading-content" class="col-centered">
<i class="fw fw-settings fw-spin fw-2x"></i>
&nbsp;&nbsp;&nbsp;
Loading devices . . .
<br>
</div>
<div id="device-listing-status" class="raw hidden">
<ul style="list-style-type: none;">
<li class="message message-info">
<h4>
<i class="icon fw fw-info"></i>
<a id="device-listing-status-msg"></a>
</h4>
</li>
</ul>
</div>
<div id="device-table">
<table class="table table-striped table-hover list-table display responsive nowrap data-table grid-view"
id="device-grid">
<thead>
<tr class="sort-row">
<th class="no-sort"></th>
<th>By Device Name</th>
<th>By Owner</th>
<th>By Status</th>
<th>By Platform</th>
<th>By Ownership</th>
<th class="no-sort"></th>
</tr>
<tr class="filter-row filter-box">
<th class="no-sort"></th>
<th data-for="By Device Name"></th>
<th data-for="By Owner" class="text-filter"></th>
<th data-for="By Status" class="select-filter"></th>
<th data-for="By Platform" class="select-filter data-platform"></th>
<th data-for="By Ownership" class="select-filter"></th>
<th class="no-sort"></th>
</tr>
<tr class="bulk-action-row hidden">
<th colspan="7">
<div id="operation-bar">
{{unit "mdm.unit.device.operation-bar"}}
</div>
<div id="operation-guide" class="bs-callout bs-callout-info">
<h4>Enabling Device Operations</h4>
<p>To enable device operations, select the desired platform from above filter.</p>
</div>
</th>
</tr>
</thead>
<tbody id="ast-container">
<br class="c-both"/>
</tbody>
</table>
</div>
<br class="c-both"/>
<div id="content-filter-types" style="display: none">
<div class="sort-title">Sort By</div>
<div class="sort-options">
<a href="#">By Device Name<span class="ico-sort-asc"></span></a>
<a href="#">By Owner</a>
<a href="#">By Status</a>
<a href="#">By Platform</a>
<a href="#">By Ownership</a>
{{#if permissions.VIEW_DEVICES}}
<div id="loading-content" class="col-centered">
<i class="fw fw-settings fw-spin fw-2x"></i>
&nbsp;&nbsp;&nbsp;
Loading devices . . .
<br>
</div>
<div id="device-listing-status" class="raw hidden">
<ul style="list-style-type: none;">
<li class="message message-info">
<h4>
<i class="icon fw fw-info"></i>
<a id="device-listing-status-msg"></a>
</h4>
</li>
</ul>
</div>
</div>
<div id="no-device-view" class="ast-container list-view hidden">
<div class="ctrl-info-panel col-centered text-center wr-login">
<h2>You don't have any device registered at the moment.</h2>
<br/>
<p class="text-center">
<a href="javascript:toggleEnrollment()" class="wr-btn">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-mobile fw-stack-1x"></i>
<span class="fw-stack fw-move-right fw-move-bottom">
<i class="fw fw-circle fw-stack-2x fw-stroke fw-inverse"></i>
<i class="fw fw-circle fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
</span>
Enroll New Device
</a>
</p>
<div id="device-table">
<table class="table table-striped table-hover list-table display responsive nowrap data-table grid-view"
id="device-grid">
<thead>
<tr class="sort-row">
<th class="no-sort"></th>
<th>By Device Name</th>
<th>By Owner</th>
<th>By Status</th>
<th>By Platform</th>
<th>By Ownership</th>
<th class="no-sort"></th>
</tr>
<tr class="filter-row filter-box">
<th class="no-sort"></th>
<th data-for="By Device Name"></th>
<th data-for="By Owner" class="text-filter"></th>
<th data-for="By Status" class="select-filter"></th>
<th data-for="By Platform" class="select-filter data-platform"></th>
<th data-for="By Ownership" class="select-filter"></th>
<th class="no-sort"></th>
</tr>
<tr class="bulk-action-row hidden">
<th colspan="7">
<div id="operation-bar">
{{unit "mdm.unit.device.operation-bar"}}
</div>
<div id="operation-guide" class="bs-callout bs-callout-info">
<h4>Enabling Device Operations</h4>
<p>To enable device operations, select the desired platform from above filter.</p>
</div>
</th>
</tr>
</thead>
<tbody id="ast-container"></tbody>
</table>
</div>
</div>
<br class="c-both"/>
<div id="content-filter-types" style="display: none">
<div class="sort-title">Sort By</div>
<div class="sort-options">
<a href="#">By Device Name<span class="ico-sort-asc"></span></a>
<a href="#">By Owner</a>
<a href="#">By Status</a>
<a href="#">By Platform</a>
<a href="#">By Ownership</a>
</div>
</div>
<div id="no-device-view" class="ast-container list-view hidden">
<div class="ctrl-info-panel col-centered text-center wr-login">
<h2>You don't have any device registered at the moment.</h2>
<br/>
<p class="text-center">
<a href="javascript:toggleEnrollment()" class="wr-btn">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-mobile fw-stack-1x"></i>
<span class="fw-stack fw-move-right fw-move-bottom">
<i class="fw fw-circle fw-stack-2x fw-stroke fw-inverse"></i>
<i class="fw fw-circle fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
</span>
Enroll New Device
</a>
</p>
</div>
</div>
{{else}}
<h1 class="page-sub-title">
Permission Denied
</h1>
<br>
You are not authorized to view any enrolled device in the system.
{{/if}}
{{/zone}}
{{#zone "bottomJs"}}
<script id="device-listing" data-current-user="{{currentUser.username}}"
data-image-resource="{{self.publicURL}}/images/"
src="{{self.publicURL}}/templates/device-listing.hbs" type="text/x-handlebars-template"></script>
{{js "js/device-listing.js"}}
{{#if permissions.VIEW_DEVICES}}
{{js "js/device-listing.js"}}
{{/if}}
{{/zone}}

@ -15,26 +15,29 @@
* specific language governing permissions and limitations
* under the License.
*/
function onRequest(context){
var userModule = require("/app/modules/business-controllers/user.js").userModule;
function onRequest() {
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var constants = require("/app/modules/constants.js");
var viewModel = {};
var permissions = [];
if(userModule.isAuthorized("/permission/admin/device-mgt/emm-admin/devices/list")){
permissions.push("LIST_DEVICES");
if (userModule.isAuthorized("/permission/admin/device-mgt/emm-admin/devices/view")) {
permissions.push("VIEW_DEVICES");
}
}else if(userModule.isAuthorized("/permission/admin/device-mgt/user/devices/list")){
permissions.push("LIST_OWN_DEVICES");
if (userModule.isAuthorized("/permission/admin/device-mgt/user/devices/view")) {
permissions.push("VIEW_OWN_DEVICES");
}
}else if(userModule.isAuthorized("/permission/admin/device-mgt/emm-admin/policies/list")){
permissions.push("LIST_POLICIES");
}
var currentUser = session.get(constants.USER_SESSION_KEY);
viewModel.permissions = stringify(permissions);
viewModel.currentUser = currentUser;
var permissions = {};
// permission checks
// [1] checking enrollment permissions
permissions["ENROLL_DEVICE"] = userModule.isAuthorized("/permission/admin/device-mgt/devices/enroll/android") ||
userModule.isAuthorized("/permission/admin/device-mgt/devices/enroll/ios") ||
userModule.isAuthorized("/permission/admin/device-mgt/devices/enroll/windows");
// [2] checking advanced device search permissions
permissions["ADVANCED_SEARCH"] = userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/view");
// [3] checking device viewing permission
permissions["VIEW_DEVICES"] = userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/view");
var currentUser = session.get(constants["USER_SESSION_KEY"]);
viewModel["permissions"] = permissions;
viewModel["currentUser"] = currentUser;
return viewModel;
}

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

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

@ -174,8 +174,8 @@
<tr data-type="selectable" data-id="{{id}}" data-status="{{status}}">
<td class="remove-padding icon-only content-fill viewEnabledIcon"
data-url="{{@app.context}}/policy/view?id={{id}}" data-id="{{id}}">
<div class="thumbnail icon">
<img src="{{icon}}"/>
<div class="thumbnail icon" style="padding-top: 30px; padding-bottom: 30px;">
<i class="fw fw-{{deviceTypeIcon}}" style="font-size: 59px"></i>
</div>
</td>
<td class="fade-edge"
@ -261,378 +261,388 @@
</div>
<div id="remove-policy-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Do you really want to remove the selected policy(s)?</h3>
<div class="buttons">
<a href="#" id="remove-policy-yes-link" class="btn-operations">
Remove
</a>
<div class="modal-header">
<h3 class="pull-left modal-title">
Do you really want to remove the selected policy(s)?
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<a href="#" id="remove-policy-cancel-link" class="btn-operations">
Cancel
</a>
</div>
</div>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="remove-policy-yes-link" class="btn-operations">Remove</a>
<a href="#" id="remove-policy-cancel-link" class="btn-operations">Cancel</a>
</div>
</div>
</div>
<div id="remove-policy-success-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Done. Selected policy was successfully removed.</h3>
<div class="modal-header">
<h3 class="pull-left modal-title">
Done. Selected policy was successfully removed.
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<div class="buttons">
<a href="#" id="remove-policy-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="remove-policy-success-link" class="btn-operations">Ok</a>
</div>
</div>
</div>
<div id="remove-policy-error-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>An unexpected error occurred. Please try again later.</h3>
<div class="modal-header">
<h3 class="pull-left modal-title">
An unexpected error occurred. Please try again later
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<div class="buttons">
<a href="#" id="remove-policy-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="remove-policy-error-link" class="btn-operations">Ok</a>
</div>
</div>
</div>
<div id="remove-active-policy-error-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
You cannot remove policies that have been already applied to devices.
Please deselect active policies from your selection and try again.
</h3>
<div class="buttons">
<a href="#" id="remove-active-policy-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
<div class="modal-header">
<h3 class="pull-left modal-title">
Please Try again.
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>You cannot remove policies that have been already applied to devices.
Please deselect active policies from your selection and try again.</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="remove-active-policy-error-link" class="btn-operations">Ok</a>
</div>
</div>
</div>
<div id="publish-policy-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Do you really want to publish the selected policy(s)?</h3>
<div class="buttons">
<a href="#" id="publish-policy-yes-link" class="btn-operations">Yes</a>
<a href="#" id="publish-policy-cancel-link" class="btn-operations">No</a>
</div>
</div>
<div class="modal-header">
<h3 class="pull-left modal-title">
Do you really want to publish the selected policy(s)?
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="publish-policy-yes-link" class="btn-operations">Yes</a>
<a href="#" id="publish-policy-cancel-link" class="btn-operations">No</a>
</div>
</div>
</div>
<div id="publish-policy-success-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Done. Selected policy was successfully published.</h3>
<div class="buttons">
<a href="#" id="publish-policy-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
<div class="modal-header">
<h3 class="pull-left modal-title">
Done. Selected policy was successfully published.
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="publish-policy-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
<div id="publish-policy-error-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>An unexpected error occurred. Please try again later.</h3>
<div class="buttons">
<a href="#" id="publish-policy-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
<div class="modal-header">
<h3 class="pull-left modal-title">
An unexpected error occurred. Please try again later.
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="publish-policy-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
<div id="unpublish-policy-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Do you really want to unpublish the selected policy(s)?</h3>
<div class="buttons">
<a href="#" id="unpublish-policy-yes-link" class="btn-operations">
Yes
</a>
<div class="modal-header">
<h3 class="pull-left modal-title">
Do you really want to unpublish the selected policy(s)?
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="unpublish-policy-yes-link" class="btn-operations">
Yes
</a>
<a href="#" id="unpublish-policy-cancel-link" class="btn-operations">
No
</a>
</div>
</div>
<a href="#" id="unpublish-policy-cancel-link" class="btn-operations">
No
</a>
</div>
</div>
</div>
<div id="unpublish-policy-success-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Done. Selected policy was successfully unpublished.</h3>
<div class="buttons">
<a href="#" id="unpublish-policy-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
<div class="modal-header">
<h3 class="pull-left modal-title">
Done. Selected policy was successfully unpublished.
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="unpublish-policy-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
<div id="unpublish-policy-error-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>An unexpected error occurred. Please try again later.</h3>
<div class="buttons">
<a href="#" id="unpublish-policy-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
<div class="modal-header">
<h3 class="pull-left modal-title">
An unexpected error occurred. Please try again later.
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="unpublish-policy-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
<div id="save-policy-priorities-success-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Done. New Policy priorities were successfully updated.</h3>
<div class="buttons">
<a href="#" id="save-policy-priorities-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
<div class="modal-header">
<h3 class="pull-left modal-title">
Done. New Policy priorities were successfully updated.
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="save-policy-priorities-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
<div id="save-policy-priorities-error-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>An unexpected error occurred. Please try again later.</h3>
<h4 class="message-from-server"></h4>
<div class="buttons">
<a href="#" id="save-policy-priorities-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
<div class="modal-header">
<h3 class="pull-left modal-title">
An unexpected error occurred. Please try again later.
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="save-policy-priorities-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
<div id="change-policy-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Do you really want to apply changes to all policies?</h3>
<div class="buttons">
<a href="#" id="change-policy-yes-link" class="btn-operations">
Yes
</a>
<div class="modal-header">
<h3 class="pull-left modal-title">
Do you really want to apply changes to all policies?
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="change-policy-yes-link" class="btn-operations">
Yes
</a>
<a href="#" id="change-policy-cancel-link" class="btn-operations">
No
</a>
</div>
</div>
<a href="#" id="change-policy-cancel-link" class="btn-operations">
No
</a>
</div>
</div>
</div>
<div id="change-policy-success-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Done. Changes applied successfully.</h3>
<div class="buttons">
<a href="#" id="change-policy-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
<div class="modal-header">
<h3 class="pull-left modal-title">
Done. Changes applied successfully.
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="change-policy-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
<div id="change-policy-error-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>An unexpected error occurred. Please try again later.</h3>
<div class="buttons">
<a href="#" id="change-policy-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
<div class="modal-header">
<h3 class="pull-left modal-title">
An unexpected error occurred. Please try again later.
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="change-policy-error-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
<div id="errorPolicyUnPublish" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<div class="modal-header">
<h3 class="pull-left modal-title">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Action cannot be performed !
</h3>
<h4>
Please select a policy or a list of policies to un-publish.
</h4>
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">
Ok
</a>
</div>
</div>
Action cannot be performed !
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>Please select a policy or a list of policies to un-publish.</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
<div id="errorPolicyUnPublishSelection" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<div class="modal-header">
<h3 class="pull-left modal-title">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Action cannot be performed !
</h3>
<h4>
You cannot select already inactive policies to be unpublished.
Please deselect inactive policies and try again.
</h4>
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">
Ok
</a>
</div>
</div>
Action cannot be performed !
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>You cannot select already inactive policies to be unpublished.
Please deselect inactive policies and try again.</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
<div id="active-policy-selection-error" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<div class="modal-header">
<h3 class="pull-left modal-title">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Action cannot be performed !
</h3>
<h4>
You cannot select already active policies. Please deselect active policies and try again.
</h4>
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">
Ok
</a>
</div>
</div>
Action cannot be performed !
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>You cannot select already active policies. Please deselect active policies and try again.</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
<div id="policy-publish-error" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<div class="modal-header">
<h3 class="pull-left modal-title">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Action cannot be performed !
</h3>
<h4>
Please select a policy or a list of policies to publish.
</h4>
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">
Ok
</a>
</div>
</div>
Action cannot be performed !
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>Please select a policy or a list of policies to publish.</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
<div id="policy-remove-error" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<div class="modal-header">
<h3 class="pull-left modal-title">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Action cannot be performed !
</h3>
<h4>
Please select a policy or a list of policies to remove.
</h4>
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">
Ok
</a>
</div>
</div>
Action cannot be performed !
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>Please select a policy or a list of policies to remove.</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">
Ok
</a>
</div>
</div>
</div>

@ -61,9 +61,9 @@ function InitiateViewOption() {
* Modal related stuff are as follows.
*/
var modalPopup = ".wr-modalpopup";
var modalPopupContainer = modalPopup + " .modalpopup-container";
var modalPopupContent = modalPopup + " .modalpopup-content";
var modalPopup = ".modal";
var modalPopupContainer = modalPopup + " .modal-content";
var modalPopupContent = modalPopup + " .modal-content";
var body = "body";
/*
@ -81,8 +81,7 @@ function setPopupMaxHeight() {
* show popup function.
*/
function showPopup() {
$(modalPopup).show();
setPopupMaxHeight();
$(modalPopup).modal('show');
}
/*
@ -90,7 +89,9 @@ function showPopup() {
*/
function hidePopup() {
$(modalPopupContent).html('');
$(modalPopup).hide();
$(modalPopup).modal('hide');
$('body').removeClass('modal-open').css('padding-right','0px');
$('.modal-backdrop').remove();
}
/*
@ -215,7 +216,7 @@ $(document).ready(function () {
// on-click function for policy un-publishing "yes" button
$("a#unpublish-policy-yes-link").click(function () {
invokerUtil.put(
invokerUtil.post(
serviceURL,
policyList,
// on success
@ -268,7 +269,7 @@ $(document).ready(function () {
// on-click function for policy removing "yes" button
$("a#publish-policy-yes-link").click(function () {
invokerUtil.put(
invokerUtil.post(
serviceURL,
policyList,
// on success

@ -15,13 +15,15 @@
specific language governing permissions and limitations
under the License.
}}
{{#zone "content"}}
<div id = "operations-mod">
<div id = "operations-mod" data-permissions="{{permissions}}">
{{unit "mdm.unit.device.operation-mod"}}
</div>
{{/zone}}
{{#zone "bottomJs"}}
<!--suppress HtmlUnknownTarget -->
<script id="operations-bar" src="{{@unit.publicUri}}/templates/operations.hbs"
type="text/x-handlebars-template"></script>
{{js "js/operation-bar.js"}}

@ -0,0 +1,71 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
function onRequest(context) {
// var log = new Log("mdm.unit.device.operation-bar");
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var viewModel = {};
var permissions = {};
// adding android operations related permission checks
permissions["android"] = [];
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/android/ring")) {
permissions["android"].push("DEVICE_RING");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/android/lock-devices")) {
permissions["android"].push("DEVICE_LOCK");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/android/unlock-devices")) {
permissions["android"].push("DEVICE_UNLOCK");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/android/location")) {
permissions["android"].push("DEVICE_LOCATION");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/android/clear-password")) {
permissions["android"].push("CLEAR_PASSWORD");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/android/reboot")) {
permissions["android"].push("DEVICE_REBOOT");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/android/upgrade-firmware")) {
permissions["android"].push("UPGRADE_FIRMWARE");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/android/mute")) {
permissions["android"].push("DEVICE_MUTE");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/android/send-notification")) {
permissions["android"].push("NOTIFICATION");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/android/change-lock-code")) {
permissions["android"].push("CHANGE_LOCK_CODE");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/android/enterprise-wipe")) {
permissions["android"].push("ENTERPRISE_WIPE");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/android/wipe")) {
permissions["android"].push("WIPE_DATA");
}
// adding ios operations related permission checks
// adding windows operations related permission checks
viewModel["permissions"] = stringify(permissions);
return viewModel;
}

@ -108,8 +108,21 @@ function loadOperationBar(deviceType) {
//var serviceURL = "/mdm-admin/features/" + platformType;
var serviceURL = "/api/device-mgt/v1.0/devices/" + platformType + "/*/features";
var successCallback = function (data) {
var permittedOperations = [];
var i;
var permissionList = $("#operations-mod").data("permissions");
var totalFeatures = JSON.parse(data);
for (i = 0; i < permissionList[deviceType].length; i++) {
var j;
for (j = 0; j < totalFeatures.length; j++) {
if (permissionList[deviceType][i] == totalFeatures[j]["code"]) {
permittedOperations.push(totalFeatures[j]);
}
}
}
var viewModel = {};
data = JSON.parse(data).filter(function (current) {
permittedOperations = permittedOperations.filter(function (current) {
var iconName;
switch (deviceType) {
case platformTypeConstants.ANDROID:
@ -129,7 +142,8 @@ function loadOperationBar(deviceType) {
return current;
}
});
viewModel.features = data;
viewModel.features = permittedOperations;
var content = template(viewModel);
$(".wr-operations").html(content);
};

@ -1,85 +1,87 @@
<div id="errorOperations" class="operation">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Operation cannot be performed !
</h3>
<h4>
Please select a device or a list of devices to perform an operation.
</h4>
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">Ok</a>
</div>
</div>
<div class="modal-header">
<h3 class="pull-left modal-title">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Operation cannot be performed !
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>
Please select a device or a list of devices to perform an operation.
</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">Ok</a>
</div>
</div>
</div>
<div id="errorOperationUnexpected" class="operation">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Operation cannot be performed !
</h3>
<h4>
Unexpected error occurred. Please Try again later.
</h4>
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">Ok</a>
</div>
</div>
<div class="modal-header">
<h3 class="pull-left modal-title">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Operation cannot be performed !
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>
Unexpected error occurred. Please Try again later.
</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">Ok</a>
</div>
</div>
</div>
<div id="operationSuccess" class="operation">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-check fw-stack-1x"></i>
</span>
Operation queued successfully !
</h3>
<h4>
Operation has been queued successfully to be sent to the device.
</h4>
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">Ok</a>
</div>
</div>
<div class="modal-header">
<h3 class="pull-left modal-title">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-check fw-stack-1x"></i>
</span>
Operation queued successfully !
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>
Operation has been queued successfully to be sent to the device.
</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">Ok</a>
</div>
</div>
</div>
<div id="messageSuccess" class="operation">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<div class="modal-header">
<h3 class="pull-left modal-title">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-check fw-stack-1x"></i>
</span>
Message sent successfully !
</h3>
<h4>
Message has been queued to be sent to the device.
</h4>
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">Ok</a>
</div>
</div>
Message sent successfully !
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>Message has been queued to be sent to the device.</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">Ok</a>
</div>
</div>
</div>
@ -89,107 +91,127 @@
<span>{{name}}</span>
</a>
<div class="operation" data-operation-code="{{code}}">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw {{icon}} fw-stack-1x"></i>
</span>
{{name}}
<br>
</h3>
<h4>
{{#equal code "WIPE_DATA"}}
{{#equal type "android"}}
Enter PIN code (Optional - This is required only if the device type is BYOD).
<br><br>
<div>
<input type="password" class="form-control modal-input operationDataKeys" id="pin"
data-key="pin">
</div>
<br>
{{/equal}}
{{/equal}}
{{#equal code "NOTIFICATION"}}
Type your message below.
<div class="modal-content clearfix">
<div class="modal-header">
<h3 class="pull-left modal-title">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw {{icon}} fw-stack-1x"></i>
</span>
{{name}}
<br>
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>
{{#equal code "WIPE_DATA"}}
{{#equal type "android"}}
Enter PIN code (Optional - This is required only if the device type is BYOD).
<br><br>
<div id="notification-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="form-group">
<input class="form-control modal-input operationDataKeys"
id="messageTitle" data-key="messageTitle" placeholder="Title here..." />
</div>
<div class="form-group">
<textarea class="form-control modal-input operationDataKeys"
id="messageText" data-key="messageText" placeholder="Message here..."></textarea>
<div>
<input type="password" class="form-control modal-input operationDataKeys" id="pin"
data-key="pin">
</div>
<br>
{{/equal}}
{{#equal code "CHANGE_LOCK_CODE"}}
Type new lock-code below.
{{/equal}}
{{#equal code "NOTIFICATION"}}
Type your message below.
<br><br>
<div id="notification-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="form-group">
<input class="form-control modal-input operationDataKeys"
id="messageTitle" data-key="messageTitle" placeholder="Title here..." />
</div>
<div class="form-group">
<textarea class="form-control modal-input operationDataKeys"
id="messageText" data-key="messageText" placeholder="Message here..."></textarea>
</div>
<br>
{{/equal}}
{{#equal code "CHANGE_LOCK_CODE"}}
Type new lock-code below.
<br><br>
<input type="password" class="form-control modal-input operationDataKeys" id="lockcode"
data-key="lockCode" placeholder="Enter Lockcode"/>
<br>
{{/equal}}
{{#equal code "DEVICE_LOCK"}}
{{#equal type "android"}}
Type your message to be shown in the lock screen (Optional).
<br><br>
<input type="password" class="form-control modal-input operationDataKeys" id="lockcode"
data-key="lockCode" placeholder="Enter Lockcode"/>
<br>
{{/equal}}
{{#equal code "DEVICE_LOCK"}}
{{#equal type "android"}}
Type your message to be shown in the lock screen (Optional).
<br><br>
<div>
<div>
<textarea class="form-control modal-input operationDataKeys" id="lock-message"
data-key="lock-message"></textarea>
</div>
<br>
<label class="wr-input-control checkbox">
<input id="hard-lock" type="checkbox" class="form-control operationDataKeys"
data-key="hard-lock"/>
</div>
<br>
<label class="wr-input-control checkbox">
<input id="hard-lock" type="checkbox" class="form-control operationDataKeys"
data-key="hard-lock"/>
<span class="helper" title="Once it enables, device will be blocked permanently.">
&nbsp;&nbsp;&nbsp;Enable Permanent Lock
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
{{/equal}}
</label>
{{/equal}}
{{#equal code "UPGRADE_FIRMWARE"}}
{{#equal type "android"}}
Enter firmware upgrade scheduling information.
<br><br>
<label class="wr-input-control checkbox">
<input id="instant-upgrade" type="checkbox" class="form-control operationDataKeys"
data-key="instant-upgrade"/>
{{/equal}}
{{#equal code "UPGRADE_FIRMWARE"}}
{{#equal type "android"}}
Enter firmware upgrade scheduling information.
<br><br>
<label class="wr-input-control checkbox">
<input id="instant-upgrade" type="checkbox" class="form-control operationDataKeys"
data-key="instant-upgrade"/>
<span class="helper"
title="Once enabled, device firmware upgrade process will start instantly.">
&nbsp;&nbsp;&nbsp;Instant Upgrade
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</label>
<br><br>
<div class='input-group date' id='dateTimePicker'>
Enter the date and time to schedule firmware upgrade.
<br><br>
<div class='input-group date' id='dateTimePicker'>
Enter the date and time to schedule firmware upgrade.
<br><br>
<div id="firmware-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<input type='text' class="form-control modal-input operationDataKeys"
style="z-index : 900;" name="daterange" id="schedule" data-key="schedule"/>
<div id="firmware-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<input type='text' class="form-control modal-input operationDataKeys"
style="z-index : 900;" name="daterange" id="schedule" data-key="schedule"/>
</div>
<br><br>
<div class='wr-input-control' id='firmwareServerInfo'>
Enter firmware upgrade server URL (ie. http://abc.com or http://abc.com/ota)
(Optional).
<br><br>
<div class='wr-input-control' id='firmwareServerInfo'>
Enter firmware upgrade server URL (ie. http://abc.com or http://abc.com/ota)
(Optional).
<br><br>
<input type='text' class="form-control modal-input operationDataKeys" id="server"
data-key="server"/>
</div>
<script type="text/javascript">
$(function () {
$('.modalpopup-bg').css('z-index', '1000');
$('.modalpopup-container').css('z-index', '1200');
<input type='text' class="form-control modal-input operationDataKeys" id="server"
data-key="server"/>
</div>
<script type="text/javascript">
$(function () {
$('.modalpopup-bg').css('z-index', '1000');
$('.modalpopup-container').css('z-index', '1200');
$('input[name="daterange"]').daterangepicker({
singleDatePicker: true,
timePicker: true,
showDropdowns: true,
timePickerIncrement: 1,
locale: {
format: 'MM-DD-YYYY hh:mm a'
}
});
});
$('#instant-upgrade').change(function () {
if ($(this).is(":checked")) {
$('#dateTimePicker').addClass("hidden");
$("#schedule").val('');
} else {
$('#dateTimePicker').removeClass("hidden");
$('input[name="daterange"]').daterangepicker({
singleDatePicker: true,
timePicker: true,
@ -199,40 +221,25 @@
format: 'MM-DD-YYYY hh:mm a'
}
});
});
$('#instant-upgrade').change(function () {
if ($(this).is(":checked")) {
$('#dateTimePicker').addClass("hidden");
$("#schedule").val('');
} else {
$('#dateTimePicker').removeClass("hidden");
$('input[name="daterange"]').daterangepicker({
singleDatePicker: true,
timePicker: true,
showDropdowns: true,
timePickerIncrement: 1,
locale: {
format: 'MM-DD-YYYY hh:mm a'
}
});
}
});
</script>
<br>
{{/equal}}
}
});
</script>
<br>
{{/equal}}
<br><br>
Do you want to perform this operation on selected device(s) ?
<br>
</h4>
<div class="buttons">
<a href="javascript:runOperation('{{code}}')" class="btn-operations">Yes</a>
<a href="javascript:hidePopup()" class="btn-operations">No</a>
</div>
{{/equal}}
<br><br>
Do you want to perform this operation on selected device(s) ?
<br>
</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="javascript:runOperation('{{code}}')" class="btn-operations">Yes</a>
<a href="javascript:hidePopup()" class="btn-operations">No</a>
</div>
</div>
</div>
</div>
{{/each}}
<br class="c-both"/>

@ -80,7 +80,9 @@ var operationModule = function () {
"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"
"APPLICATION_OPERATION_CODE":"APP-RESTRICTION",
"SYSTEM_UPDATE_POLICY_CODE": "SYSTEM_UPDATE_POLICY",
"KIOSK_APPS_CODE": "KIOSK_APPS"
};
// Constants to define Windows Operation Constants
@ -115,8 +117,8 @@ var operationModule = function () {
var featureMap = {
"DEVICE_LOCK": "lock",
"VPN": "vpn",
"PER_APP_VPN": "perappvpn",
"APP_TO_PER_APP_VPN_MAPPING": "apptoperappvpnmapping",
"PER_APP_VPN": "per-app-vpn",
"APP_TO_PER_APP_VPN_MAPPING": "app-to-per-app-vpn-mapping",
"RING": "ring",
"LOCATION": "location",
"NOTIFICATION": "notification",
@ -124,12 +126,12 @@ var operationModule = function () {
"RESTRICTION": "restriction",
"CELLULAR": "cellular",
"WIFI": "wifi",
"INSTALL_STORE_APPLICATION": "storeapplication",
"INSTALL_ENTERPRISE_APPLICATION": "enterpriseapplication",
"REMOVE_APPLICATION": "removeapplication",
"ENTERPRISE_WIPE": "enterprisewipe"
"INSTALL_STORE_APPLICATION": "store-application",
"INSTALL_ENTERPRISE_APPLICATION": "enterprise-application",
"REMOVE_APPLICATION": "remove-application",
"ENTERPRISE_WIPE": "enterprise-wipe"
};
return "/ios/operation/" + featureMap[operationCode];
return "/api/device-mgt/ios/v1.0/admin/devices/" + featureMap[operationCode];
};
/**
@ -1012,6 +1014,24 @@ var operationModule = function () {
}
};
break;
case androidOperationConstants["SYSTEM_UPDATE_POLICY_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"type": operationData["cosuSystemUpdateType"],
"startTime": operationData["cosuWindowStartTime"],
"endTime": operationData["cosuWindowEndTime"]
}
};
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"];
@ -1276,6 +1296,8 @@ var operationModule = function () {
value = operationDataObj.val();
} else if (operationDataObj.is(":checkbox")) {
value = operationDataObj.is(":checked");
} else if (operationDataObj.is(":radio") && operationDataObj.is(":checked")) {
value = operationDataObj.val();
} else if (operationDataObj.is("select")) {
value = operationDataObj.find("option:selected").attr("value");
} else if (operationDataObj.hasClass("grouped-array-input")) {

@ -17,20 +17,27 @@
}}
{{#zone "content"}}
<div id="qr-code-modal" data-enrollment-url="{{enrollmentURL}}" class="hidden">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Scan QR code to start enrollment</h3>
<h4>
Please scan the QR code using your mobile device to retrieve enrollment URL.
</h4>
<div class="panel panel-default">
<div class="panel-body col-centered text-center">
<div class="qr-code"></div>
</div>
<div class="modal-header">
<h3 class="pull-left modal-title">
Scan QR code to start enrollment
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<div>
<h4>
Please scan the QR code using your mobile device to retrieve enrollment URL.
</h4>
<div class="panel panel-default">
<div class="panel-body col-centered text-center">
<div class="qr-code"></div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<div class="buttons">
</div>
</div>
</div>
{{/zone}}

@ -50,49 +50,61 @@ var InitiateViewOption = null;
);
}
$(".media.tab-responsive [data-toggle=tab]").on("shown.bs.tab", function (e) {
var activeTabPane = $(e.target).attr("href"),
activeCollapsePane = $(activeTabPane).find("[data-toggle=collapse]").data("target"),
activeCollapsePaneSiblings = $(activeTabPane).siblings().find("[data-toggle=collapse]").data("target"),
activeListGroupItem = $(".media .list-group-item.active");
var activeTabPane = $(e.target).attr("href");
var activeListGroupItem = $(".media .list-group-item.active");
$(activeCollapsePaneSiblings).collapse("hide");
$(activeCollapsePane).collapse("show");
$(activeTabPane).removeClass("visible-xs-block");
$(activeTabPane).siblings().not(".arrow-left").addClass("visible-xs-block");
positionArrow(activeListGroupItem);
$(".panel-heading .caret-updown").removeClass("fw-sort-down");
$(".panel-heading.collapsed .caret-updown").addClass("fw-sort-up");
});
$(".media.tab-responsive .tab-content").on("shown.bs.collapse", function (e) {
var activeTabPane = $(e.target).parent().attr("id");
$(".media.tab-responsive [data-toggle=tab][href=#" + activeTabPane + "]").tab("show");
$(".panel-heading .caret-updown").removeClass("fw-sort-up");
$(".panel-heading.collapsed .caret-updown").addClass("fw-sort-down");
var thisParent = $(e.target).parent();
var activeTabPaneCaret = thisParent.find('.caret-updown');
var activeTabPaneCaretSiblings = thisParent.siblings().find('.caret-updown');
activeTabPaneCaret.removeClass("fw-up").addClass("fw-down");
activeTabPaneCaretSiblings.removeClass("fw-down").addClass("fw-up");
});
$('.media.tab-responsive a[data-toggle="collapse"]').on('click',function(){
var clickedPanel = $(this).attr('href');
if($(clickedPanel).hasClass('in')){
$(clickedPanel).collapse('hide');
}else{
$(clickedPanel).collapse('show');
}
});
function positionArrow(selectedTab) {
var selectedTabHeight = $(selectedTab).outerHeight();
var selectedTabHeight = $(selectedTab).innerHeight();
var arrowPosition = 0;
var totalHeight = 0;
var arrow = $(".media .panel-group.tab-content .arrow-left");
var parentHeight = $(arrow).parent().outerHeight();
var parentHeight = $(arrow).parent().innerHeight();
// if($(selectedTab).prev().length){
// $(selectedTab).prevAll().each(function() {
// totalHeight += $(this).outerHeight();
// });
// arrowPosition = totalHeight + (selectedTabHeight / 2);
// }else{
// arrowPosition = selectedTabHeight / 2;
// }
if($(selectedTab).prev().length){
$(selectedTab).prevAll().each(function() {
totalHeight += $(this).innerHeight();
});
arrowPosition = totalHeight + (selectedTabHeight / 2);
}else{
arrowPosition = selectedTabHeight / 2;
}
if(arrowPosition >= parentHeight){
parentHeight = arrowPosition + 10;
$(arrow).parent().height(parentHeight);
parentHeight = arrowPosition + 50;
$(arrow).siblings(".panel.active").height(parentHeight);
}else{
$(arrow).parent().removeAttr("style");
}
$(arrow).css("top", arrowPosition - 10);
}
@ -228,8 +240,8 @@ var InitiateViewOption = null;
$("#applications-list-container").html(content);
} else {
$("#applications-list-container").
html("<div class='panel-body'><br><p class='fw-warning'>&nbsp;No applications found. " +
"please try refreshing the list in a while.<p></div>");
html("<div class='message message-info'><h4><i class='icon fw fw-info'></i>No applications found.</h4>" +
"<p>Please try refreshing the list in a while.</p></div>");
}
}
},
@ -315,4 +327,5 @@ var InitiateViewOption = null;
}
);
}
}());

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

@ -17,7 +17,7 @@
*/
function onRequest(context) {
var log = new Log("view.js");
// var log = new Log("view.js");
var deviceType = context.uriParams.deviceType;
var deviceId = request.getParameter("id");
var deviceData = {};
@ -26,6 +26,8 @@ function onRequest(context) {
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var response = deviceModule.viewDevice(deviceType, deviceId);
if (response["status"] == "success") {
deviceData["isAuthorized"] = true;
var device = response["content"];
var viewModel = {};
var deviceInfo = device["properties"]["DEVICE_INFO"];
@ -54,8 +56,7 @@ function onRequest(context) {
viewModel["vendor"] = device["properties"]["VENDOR"];
var osBuildDate = device["properties"]["OS_BUILD_DATE"];
if (osBuildDate != null && osBuildDate != "0") {
var formattedDate = new Date(osBuildDate * 1000);
viewModel["os_build_date"] = formattedDate;
viewModel["os_build_date"] = new Date(osBuildDate * 1000);
}
viewModel["internal_memory"] = {};
viewModel["external_memory"] = {};
@ -96,6 +97,8 @@ function onRequest(context) {
device["viewModel"] = viewModel;
}
deviceData["device"] = device;
} else if (response["status"] == "unauthorized") {
deviceData["isAuthorized"] = false;
}
return deviceData;
}

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

@ -17,7 +17,7 @@
*/
function onRequest() {
var log = new Log("/app/units/mdm.unit.policy.create");
// var log = new Log("/app/units/mdm.unit.policy.create");
var CONF_DEVICE_TYPE_KEY = "deviceType";
var CONF_DEVICE_TYPE_LABEL_KEY = "label";
@ -35,6 +35,11 @@ function onRequest() {
var content = {};
var deviceType = deviceTypes[i];
content["name"] = deviceType;
if (deviceType == "ios") {
content["deviceTypeIcon"] = "apple";
} else {
content["deviceTypeIcon"] = deviceType;
}
var configs = utility.getDeviceTypeConfig(deviceType);
var deviceTypeLabel = deviceType;
if (configs && configs[CONF_DEVICE_TYPE_KEY][CONF_DEVICE_TYPE_LABEL_KEY]) {
@ -43,7 +48,7 @@ function onRequest() {
var policyWizard = new File("/app/units/" + utility.getTenantedDeviceUnitName(deviceType, "policy-wizard"));
if (policyWizard.isExists()) {
content["icon"] = utility.getDeviceThumb(deviceType);
// content["icon"] = utility.getDeviceThumb(deviceType);
content["label"] = deviceTypeLabel;
viewModelData["types"].push(content);
}
@ -54,6 +59,9 @@ function onRequest() {
if (result["status"] == "success") {
viewModelData["roles"] = result["content"];
}
viewModelData.isAuthorized = userModule.isAuthorized("/permission/admin/device-mgt/policies/manage");
viewModelData.isAuthorizedViewUsers = userModule.isAuthorized("/permission/admin/device-mgt/roles/view");
viewModelData.isAuthorizedViewRoles = userModule.isAuthorized("/permission/admin/device-mgt/users/view");
return viewModelData;
}

@ -2441,6 +2441,24 @@ var slideDownPaneAgainstValueSet = function (selectElement, paneID, valueSet) {
);
}
};
var slideDownPaneAgainstValueSetForRadioButtons = function (selectElement, paneID, valueSet) {
var selectedValueOnChange = selectElement.value;
var i, slideDownVotes = 0;
for (i = 0; i < valueSet.length; i++) {
if (selectedValueOnChange == valueSet[i]) {
slideDownVotes++;
}
}
var paneSelector = "#" + paneID;
if(slideDownVotes > 0) {
$(paneSelector).removeClass("hidden");
} else {
$(paneSelector).addClass("hidden");
}
};
// End of HTML embedded invoke methods

@ -57,6 +57,17 @@
<span id="work-profile-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="work-profile-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<!--COSU-->
<a href="javascript:void(0)" onclick="showAdvanceOperation('android-for-work-cosu', this)">
<span class="wr-hidden-operation-icon fw-stack">
<i class="fw fw-service fw-stack-2x"></i>
</span>
&nbsp;&nbsp;COSU Configuration
<span id="android-for-work-cosu-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="android-for-work-cosu-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="android-for-work-cosu-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<!--/COSU-->
<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>
@ -1268,6 +1279,249 @@
</div>
</div>
<!--android-for-work-cosu-->
<div class="wr-hidden-operation" data-operation="android-for-work-cosu">
<!--system-update-policy-->
<div class="panel panel-default operation-data" data-operation="system-update-policy"
data-operation-code="SYSTEM_UPDATE_POLICY">
<div id="system-update-policy-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
System Update Policy
<label id="system-update-policy-lbl" class="wr-input-control switch" data-toggle="collapse"
data-target="#system-update-policy-body">
<input type="checkbox"/>
<span class="helper"></span>
<span class="text"></span>
</label>
</h2>
</div>
<div id="system-update-policy-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="android-for-work-cosu-policy-body">
<div id="system-update-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-label" for="android-for-work-cosu-policy-system-update">
System Update
<span class="helper" title="Type of the System Update to be set by the Device Owner">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
</label>
<br>
<div class="wr-input-control">
<label class="wr-input-control radio light">
<input id="automatic-system-update-radio-btn" type="radio" name="android-for-work-cosu-policy-system-update"
class="form-control operationDataKeys" data-key="cosuSystemUpdateType"
value="automatic" onclick="slideDownPaneAgainstValueSetForRadioButtons(this, 'android-for-work-cosu-window-select', ['window'])" checked/>
<span class="helper" title="Installs system update automatically as soon as one is available">
&nbsp;Automatic
</span>
</span>
</label>
<label class="wr-input-control radio light">
<input id="postpone-system-update-radio-btn" type="radio" name="android-for-work-cosu-policy-system-update"
class="form-control operationDataKeys" data-key="cosuSystemUpdateType"
value="postpone" onclick="slideDownPaneAgainstValueSetForRadioButtons(this, 'android-for-work-cosu-window-select', ['window'])"/>
<span class="helper" title="Incoming system update will be blocked for a maximum of 30 days">
&nbsp;Postpone
</span>
</label>
<label class="wr-input-control radio light">
<input id="window-system-update-radio-btn" type="radio" name="android-for-work-cosu-policy-system-update"
class="form-control operationDataKeys" data-key="cosuSystemUpdateType"
value="window" onclick="slideDownPaneAgainstValueSetForRadioButtons(this, 'android-for-work-cosu-window-select', ['window'])"/>
<span class="helper" title="Install system update automatically within a daily maintenance window, for a maximum of 30 days">
&nbsp;Window
</span>
</label>
</div>
</div>
<div id="android-for-work-cosu-window-select" class="hidden">
<div>
<ul class="message message-info">
<i class="icon fw fw-info"></i>
<a id="android-for-work-cosu-window-select-msg"> Below configuration of start time and end time are valid only when
<b>window</b> option is selected.</a>
</ul>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="android-for-work-cosu-window-start-time">
Start Time
<span class="helper" title="Window start time for system update">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="android-for-work-cosu-start-time" class="form-control operationDataKeys"
data-key="cosuWindowStartTime" data-default="0">
<option value="1440" selected="selected">
12 AM
</option>
<option value="60">1 AM</option>
<option value="120">2 AM</option>
<option value="180">3 AM</option>
<option value="240">4 AM</option>
<option value="300">5 AM</option>
<option value="360">6 AM</option>
<option value="420">7 AM</option>
<option value="480">8 AM</option>
<option value="540">9 AM</option>
<option value="600">10 AM</option>
<option value="660">11 AM</option>
<option value="720">12 noon</option>
<option value="780">1 PM</option>
<option value="840">2 PM</option>
<option value="900">3 PM</option>
<option value="960">4 PM</option>
<option value="1020">5 PM</option>
<option value="1080">6 PM</option>
<option value="1140">7 PM</option>
<option value="1200">8 PM</option>
<option value="1260">9 PM</option>
<option value="1320">10 PM</option>
<option value="1380">11 PM</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="android-for-work-cosu-window-end-time">
Start Time
<span class="helper" title="Window end time for system update">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="android-for-work-cosu-end-time" class="form-control operationDataKeys"
data-key="cosuWindowEndTime" data-default="0">
<option value="1440" selected="selected">
12 AM
</option>
<option value="60">1 AM</option>
<option value="120">2 AM</option>
<option value="180">3 AM</option>
<option value="240">4 AM</option>
<option value="300">5 AM</option>
<option value="360">6 AM</option>
<option value="420">7 AM</option>
<option value="480">8 AM</option>
<option value="540">9 AM</option>
<option value="600">10 AM</option>
<option value="660">11 AM</option>
<option value="720">12 noon</option>
<option value="780">1 PM</option>
<option value="840">2 PM</option>
<option value="900">3 PM</option>
<option value="960">4 PM</option>
<option value="1020">5 PM</option>
<option value="1080">6 PM</option>
<option value="1140">7 PM</option>
<option value="1200">8 PM</option>
<option value="1260">9 PM</option>
<option value="1320">10 PM</option>
<option value="1380">11 PM</option>
</select>
</div>
</div>
</div>
</div>
<!--system-update-policy-->
<!--whitelisted-applications-->
<div class="panel panel-default operation-data" data-operation="whitelisted-applications"
data-operation-code="KIOSK_APPS">
<div id="whitelisted-applications-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Whitelisted Applications
<label id="whitelisted-applications-lbl" class="wr-input-control switch" data-toggle="collapse"
data-target="#whitelisted-applications-body">
<input type="checkbox"/>
<span class="helper"></span>
<span class="text"></span>
</label>
</h2>
</div>
<div id="whitelisted-applications-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="whitelisted-applications-body">
<div id="whitelisted-applications-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="whitelisted-application">
<br><br>Whitelisted Application List to enter Lock Task Mode
<span class="helper" title="Add an application to whitelist.">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
<a href="#whitelisted-applications-grid" class="grid-input-add" data-click-event="add-form">
<span class="icon fw-stack">
<i class="fw fw-add fw-stack-1x"></i>
<i class="fw fw-ring fw-stack-2x"></i>
</span>
&nbsp;
Add Application
</a>
</label>
<div id="whitelisted-applications"
class="operationDataKeys grouped-array-input multi-column-key-value-pair-array"
data-key="cosuWhitelistedApplications" 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="#whitelisted-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="#whitelisted-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="[ Gmail ]"/>
</td>
<td data-title="Package Name">
<input type="text" class="form-control grid-input-text"
data-child-key="packageName" maxlength="100" data-default=""
placeholder="[ com.google.android.gm ]"/>
</td>
<td>
<span class="list-group-item-actions">
<a href="#whitelisted-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>
<!--/whitelisted-applications-->
</div>
<!--/android-for-work-cosu-->
</div>
</div>

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

@ -32,5 +32,9 @@ function onRequest(context) {
context.users = usersResult.content;
}
context.isAuthorized = userModule.isAuthorized("/permission/admin/device-mgt/policies/manage");
context.isAuthorizedViewUsers = userModule.isAuthorized("/permission/admin/device-mgt/roles/view");
context.isAuthorizedViewRoles = userModule.isAuthorized("/permission/admin/device-mgt/users/view");
return context;
}

@ -2038,7 +2038,7 @@ var updatePolicy = function (policy, state) {
policyList.push(getParameterByName("id"));
if (state == "save") {
serviceURL = "/api/device-mgt/v1.0/policies/deactivate-policy";
invokerUtil.put(
invokerUtil.post(
serviceURL,
policyList,
// on success
@ -2055,7 +2055,7 @@ var updatePolicy = function (policy, state) {
);
} else if (state == "publish") {
serviceURL = "/api/device-mgt/v1.0/policies/activate-policy";
invokerUtil.put(
invokerUtil.post(
serviceURL,
policyList,
// on success

@ -1824,7 +1824,7 @@ var updatePolicy = function (policy, state) {
var policyList = [];
policyList.push(getParameterByName("id"));
serviceURL = base_api_url + "/policies/deactivate-policy";
invokerUtil.put(
invokerUtil.post(
serviceURL,
policyList,
// on success
@ -1841,7 +1841,7 @@ var updatePolicy = function (policy, state) {
var policyList = [];
policyList.push(getParameterByName("id"));
serviceURL = base_api_url + "/policies/activate-policy";
invokerUtil.put(
invokerUtil.post(
serviceURL,
policyList,
// on success

@ -50,7 +50,7 @@
</div>
</div>
<div class="container col-centered wr-content policy-message hidden">
<div class="col-centered wr-content policy-message hidden">
<div class="wr-form">
<h1 id="policy-message-page-wizard-title" class="page-sub-title">Policy creation is
successful.</h1>
@ -72,7 +72,7 @@
</div>
</div>
<div class="container col-centered wr-content policy-naming hidden">
<div class="col-centered wr-content policy-naming hidden">
<div class="wr-form">
<h1 id="policy-naming-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
@ -135,7 +135,7 @@
</div>
</div>
<div class="container col-centered wr-content policy-criteria hidden">
<div class="col-centered wr-content policy-criteria hidden">
<div class="wr-form">
<h1 id="policy-criteria-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
@ -236,7 +236,7 @@
</div>
</div>
<div class="container col-centered wr-content policy-profile">
<div class="col-centered wr-content policy-profile">
<div class="wr-form">
<h1 id="policy-profile-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>

@ -17,35 +17,25 @@
}}
{{#zone "navMenu-icon"}}
<span class="icon fw-stack">
<i class="fw fw-tiles fw-stack-1x toggle-icon-up"></i>
<i class="fw fw-menu fw-stack-1x toggle-icon-down"></i>
</span>
{{/zone}}
{{#zone "navMenu-items"}}
{{#if permissions.VIEW_DASHBOARD}}
<li>
<a href="{{@app.context}}">
<i class="fw fw-dashboard"></i>
Admin Dashboard
</a>
</li>
{{/if}}
{{#if permissions.LIST_DEVICES_ADMIN}}
{{#if permissions.LIST_DEVICES}}
<li>
<a href="{{@app.context}}/devices">
<i class="fw fw-mobile"></i>
Device Management
</a>
</li>
{{else}}
{{#if permissions.LIST_OWN_DEVICES}}
<li>
<a href="{{@app.context}}/devices">
<i class="fw fw-mobile"></i>
Device Management
</a>
</li>
{{/if}}
{{/if}}
<li><a><i class="fw fw-user"></i>User Management</a>
@ -64,12 +54,12 @@
{{/if}}
<li><a><i class="fw fw-settings"></i>Configuration Management</a>
<ul>
{{#if permissions.TENANT_CONFIGURATION}}
{{#if permissions.LIST_CONFIGURATION}}
<li><a href="{{@app.context}}/platform-configuration"><i class="fw fw-service"></i>Platform Configurations</a>
</li>
{{/if}}
<!-- todo change the permission and get the related permission -->
{{#if permissions.TENANT_CONFIGURATION}}
{{#if permissions.LIST_CONFIGURATION}}
<li><a href="{{@app.context}}/certificates"><i class="fw fw-security-policy"></i>Certificate Configurations</a>
</li>
{{/if}}
@ -93,13 +83,12 @@
</ul>
{{/zone}}
{{#zone "sidePanes"}}
<div class="sidebar-wrapper" id="right-sidebar" is-authorized="{{isAuthorizedForNotifications}}"
<div class="sidebar-wrapper" id="right-sidebar" is-authorized="{{permissions.LIST_NOTIFICATIONS}}"
data-side="right" data-width="320" data-sidebar-fixed="true" data-fixed-offset="50" data-spy="affix"
data-offset-top="80">
<ul class="sidebar-messages">
</ul>
<h4 class="text-center"><a href="{{appContext}}notification-listing" class="text-center">Show all notifications</a>
</h4>
<div class="text-center"><a href="{{appContext}}notification-listing" class="btn btn-primary">Show all notifications</a></div>
</div>
{{/zone}}
{{#zone "bottomJs"}}

@ -30,27 +30,30 @@ function onRequest(context) {
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
var constants = require("/app/modules/constants.js");
var uiPermissions = userModule.getUIPermissions();
context["permissions"] = uiPermissions;
var links = {
"user-mgt": [],
"role-mgt": [],
"policy-mgt": [],
"device-mgt": []
};
var viewModel = {};
// following context.link value comes here based on the value passed at the point
// following viewModel.link value comes here based on the value passed at the point
// where units are attached to a page zone.
// eg: {{unit "appbar" pageLink="users" title="User Management"}}
context["currentActions"] = links[context["pageLink"]];
context["enrollmentURL"] = mdmProps["generalConfig"]["host"] + mdmProps["enrollmentDir"];
var isAuthorizedForNotifications =
userModule.isAuthorized("/permission/admin/device-mgt/emm-admin/notifications/view");
viewModel["currentActions"] = links[viewModel["pageLink"]];
viewModel["enrollmentURL"] = mdmProps["generalConfig"]["host"] + mdmProps["enrollmentDir"];
var currentUser = session.get(constants["USER_SESSION_KEY"]);
context["isAuthorizedForNotifications"] = isAuthorizedForNotifications;
context["currentUser"] = currentUser;
context["appContext"] = mdmProps["appContext"];
var permissions = {};
permissions.LIST_DEVICES = userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/view");
permissions.LIST_POLICIES = userModule.isAuthorized("/permission/admin/device-mgt/policies/view");
permissions.LIST_ROLES = userModule.isAuthorized("/permission/admin/device-mgt/roles/view");
permissions.LIST_USERS = userModule.isAuthorized("/permission/admin/device-mgt/users/view");
permissions.LIST_NOTIFICATIONS = userModule.isAuthorized("/permission/admin/device-mgt/notifications/view");
permissions.LIST_CONFIGURATION = userModule.isAuthorized("/permission/admin/device-mgt/configurations/view");
viewModel.permissions = permissions;
viewModel["currentUser"] = currentUser;
viewModel["appContext"] = mdmProps["appContext"];
return context;
return viewModel;
}

@ -16,9 +16,9 @@
* under the License.
*/
var modalPopup = ".wr-modalpopup",
modalPopupContainer = modalPopup + " .modalpopup-container",
modalPopupContent = modalPopup + " .modalpopup-content";
var modalPopup = ".modal",
modalPopupContainer = modalPopup + " .modal-content",
modalPopupContent = modalPopup + " .modal-content";
var emmAdminBasePath = "/api/device-mgt/v1.0";
@ -46,8 +46,7 @@ function setPopupMaxHeight() {
* show popup function.
*/
function showPopup() {
$(modalPopup).show();
setPopupMaxHeight();
$(modalPopup).modal('show');
}
/*
@ -56,7 +55,9 @@ function showPopup() {
function hidePopup() {
$(modalPopupContent).html("");
$(modalPopupContent).removeClass("operation-data");
$(modalPopup).hide();
$(modalPopup).modal('hide');
$('body').removeClass('modal-open').css('padding-right','0px');
$('.modal-backdrop').remove();
}
/*
@ -72,8 +73,8 @@ function generateQRCode(qrCodeClass) {
}
function toggleEnrollment() {
$(".modalpopup-content").html($("#qr-code-modal").html());
generateQRCode(".modalpopup-content .qr-code");
$(".modal-content").html($("#qr-code-modal").html());
generateQRCode(".modal-content .qr-code");
showPopup();
}
@ -129,7 +130,7 @@ function loadNewNotifications() {
viewModel["notifications"] = responsePayload["notifications"];
$(messageSideBar).html(template(viewModel));
} else {
$(messageSideBar).html("<h4 class='text-center'>No new notifications found...</h4>");
$(messageSideBar).html('<div class="alert alert-info" role="alert"><i class="icon fw fw-info"></i>No new notifications found...</div>');
}
} else {
$(messageSideBar).html("<h4 class ='message-danger'>Unexpected error " +

@ -0,0 +1,104 @@
<%
/*
* 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 log = new Log("api/invoker-api.jag");
var uri = request.getRequestURI();
var uriMatcher = new URIMatcher(String(uri));
var constants = require("/app/modules/constants.js");
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
if (uriMatcher.match("/{context}/api/invoker/execute/")) {
var restAPIRequestDetails = request.getContent();
var requestMethod = restAPIRequestDetails["requestMethod"];
var requestURL = restAPIRequestDetails["requestURL"];
var requestPayload = restAPIRequestDetails["requestPayload"];
if (!requestMethod) {
requestMethod = parse(restAPIRequestDetails)["requestMethod"];
}
if (!requestURL) {
requestURL = parse(restAPIRequestDetails)["requestURL"];
}
if (!requestPayload) {
requestPayload = parse(restAPIRequestDetails)["requestPayload"];
}
var restAPIEndpoint = devicemgtProps["httpsURL"] + requestURL;
try {
switch (requestMethod) {
case constants["HTTP_GET"]:
serviceInvokers.XMLHttp.get(
restAPIEndpoint,
function (restAPIResponse) {
response["status"] = restAPIResponse["status"];
if (restAPIResponse["responseText"]) {
response["content"] = restAPIResponse["responseText"];
}
}
);
break;
case constants["HTTP_POST"]:
serviceInvokers.XMLHttp.post(
restAPIEndpoint,
requestPayload,
function (restAPIResponse) {
response["status"] = restAPIResponse["status"];
if (restAPIResponse["responseText"]) {
response["content"] = restAPIResponse["responseText"];
}
}
);
break;
case constants["HTTP_PUT"]:
serviceInvokers.XMLHttp.put(
restAPIEndpoint,
requestPayload,
function (restAPIResponse) {
response["status"] = restAPIResponse["status"];
if (restAPIResponse["responseText"]) {
response["content"] = restAPIResponse["responseText"];
}
}
);
break;
case constants["HTTP_DELETE"]:
serviceInvokers.XMLHttp.delete(
restAPIEndpoint,
function (restAPIResponse) {
response["status"] = restAPIResponse["status"];
if (restAPIResponse["responseText"]) {
response["content"] = restAPIResponse["responseText"];
}
}
);
break;
}
} catch (e) {
throw new Error("Exception occurred while trying to access " +
"backend REST API services from Jaggery API invoker layer", e);
}
}
%>

@ -0,0 +1,185 @@
<%
/*
* 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 uri = request.getRequestURI();
var uriMatcher = new URIMatcher(String(uri));
var log = new Log("api/user-api.jag");
var constants = require("/app/modules/constants.js");
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var utility = require("/app/modules/utility.js").utility;
var apiWrapperUtil = require("/app/modules/oauth/token-handlers.js")["handlers"];
var util = require("/app/modules/oauth/token-handler-utils.js")["utils"];
var responseProcessor = require('utils').response;
var result;
if (uriMatcher.match("/{context}/api/user/authenticate")) {
var username = request.getParameter("username");
var password = request.getParameter("password");
//Check if a username and password is provided
if ((!username) || (!password)) {
response = responseProcessor.buildErrorResponse(response, 400, 'Username and Password must be provided');
} else {
try {
userModule.login(username, password, function (user) {
if (log.isDebugEnabled()) {
log.debug("User Logged In : " + user);
}
apiWrapperUtil.setupTokenPairByPasswordGrantType(username, password);
}, function () {
response = responseProcessor.buildSuccessResponse(response, 200, {'sessionId': session.getId()});
});
} catch (e) {
log.error("Exception occurred while a user tried to login to MDM", e);
response = responseProcessor.buildErrorResponse(response, 401, 'username/password is incorrect');
}
}
} else if (uriMatcher.match("/{context}/api/user/login/")) {
username = request.getParameter("username");
password = request.getParameter("password");
username = util.decode(username);
password = util.decode(password);
try {
userModule.login(username, password, function (user) {
if (log.isDebugEnabled()) {
log.debug("User Logged In : " + user);
}
apiWrapperUtil.setupTokenPairByPasswordGrantType(username, password);
var permissions = userModule.getUIPermissions();
if (permissions.VIEW_DASHBOARD) {
response.sendRedirect(constants.WEB_APP_CONTEXT);
} else {
response.sendRedirect(constants.WEB_APP_CONTEXT + "/devices");
}
}, function () {
response.sendRedirect(devicemgtProps.appContext + "login?#auth-failed");
});
} catch (e) {
log.error("Exception occurred while a user tried to login to MDM", e);
response.sendRedirect(devicemgtProps.appContext + "login?#error");
}
} else if (uriMatcher.match("/{context}/api/user/logout/")) {
userModule.logout(function () {
response.sendRedirect(devicemgtProps.appContext + "login");
});
} else if (uriMatcher.match("/{context}/api/user/devices/")) {
/*
@Deprecated
*/
if (userModule.isAuthorized("/permission/admin/device-mgt/user/devices/list")) {
carbonUser = session.get(constants.USER_SESSION_KEY);
result = deviceModule.listDevicesForUser(carbonUser.username);
} else {
response.sendError(403);
}
} else if (uriMatcher.match("/{context}/api/user/{username}/invite")) {
/*
@Deprecated
*/
if (userModule.isAuthorized("/permission/admin/device-mgt/admin/user/invite")) {
elements = uriMatcher.elements();
username = elements.username;
userModule.inviteUser(username);
} else {
response.sendError(403);
}
} else if (uriMatcher.match("/{context}/api/user/add")) {
/*
@Deprecated
*/
if (userModule.isAuthorized("/permission/admin/device-mgt/admin/user/add")) {
addUserFormData = request.getContent();
username = addUserFormData.username;
firstname = addUserFormData.firstname;
lastname = addUserFormData.lastname;
emailAddress = addUserFormData.emailAddress;
if (!addUserFormData.userRoles) {
userRoles = null;
} else {
userRoles = String(addUserFormData.userRoles).split(",");
}
if (username.length < devicemgtProps.usernameLength) {
log.error("Username Must be between 1 and " + devicemgtProps.usernameLength + " characters long");
result = "Username Must be between 1 and " + devicemgtProps.usernameLength + " characters long";
} else {
try {
result = userModule.addUser(username, firstname, lastname, emailAddress, userRoles);
} catch (e) {
log.error("Exception occurred while trying to add a user to MDM User Store", e);
// http status code 400 refers to - Bad request.
result = 400;
}
}
} else {
// http status code 403 refers to - forbidden.
result = 403;
}
} else if (uriMatcher.match("/{context}/api/user/register")) {
addUserFormData = request.getContent();
username = addUserFormData.username;
firstname = addUserFormData.firstname;
lastname = addUserFormData.lastname;
emailAddress = addUserFormData.emailAddress;
password = addUserFormData.password;
userRoles = ["internal/devicemgt-user"];
try {
result = userModule.registerUser(username, firstname, lastname, emailAddress, password,
userRoles);
} catch (e) {
log.error("Exception occurred while trying to registering a new user to DC User Store", e);
// http status code 400 refers to - Bad request.
result = 400;
}
} else if (uriMatcher.match("/{context}/api/user/{username}/remove")) {
/*
@Deprecated
*/
if (userModule.isAuthorized("/permission/admin/device-mgt/admin/user/remove")) {
elements = uriMatcher.elements();
username = elements.username;
try {
result = userModule.removeUser(username);
} catch (e) {
log.error("Exception occurred while trying to remove a user from MDM User Store", e);
// http status code 400 refers to - Bad request.
result = 400;
}
} else {
// http status code 403 refers to - forbidden.
result = 403;
}
} else if (uriMatcher.match("/{context}/api/user/all")) {
result = userModule.getUsers();
}
// returning the result.
if (result) {
print(result);
}
%>

@ -0,0 +1,52 @@
{
"appName": "WSO2 Enterprise Mobility Manager",
"cachingEnabled": true,
"debuggingEnabled": false,
"permissionRoot": "/",
"loginPage": "cdmf.page.sign-in",
"adminServicesUrl": "https://${server.ip}:${server.https_port}/admin/services/",
"authModule": {
"enabled": true,
"login": {
"onSuccess": {
"script": "/app/modules/login.js",
"page": "mdm.page.dashboard"
},
"onFail": {
"script": "/app/modules/login.js",
"page": "cdmf.page.sign-in"
}
},
"logout": {
"onSuccess": {
"page": "cdmf.page.sign-in"
},
"onFail": {
"page": "mdm.page.dashboard"
}
},
"sso": {
"enabled": false,
"issuer" : "emm",
"appName" : "emm",
"identityProviderUrl" : "https://localhost:9443/samlsso",
"acs": "https://localhost:9443/emm/uuf/sso/acs",
"identityAlias": "wso2carbon",
"responseSigningEnabled" : "true",
"useTenantKey": false
}
},
"generalConfig" : {
"host" : "https://localhost:9443",
"companyName" : "WSO2 Enterprise Mobility Manager",
"browserTitle" : "WSO2 EMM",
"copyrightPrefix" : "\u00A9 %date-year%, ",
"copyrightOwner" : "WSO2 Inc.",
"copyrightOwnersSite" : "http://www.wso2.org",
"copyrightSuffix" : ""
},
"errorPages": {
"404": "mdm.page.error",
"default": "uuf.page.error"
}
}

@ -0,0 +1,108 @@
{
"appContext" : "/emm-web-agent/",
"apiContext" : "api",
"httpsURL" : "%https.ip%",
"httpURL" : "%http.ip%",
"enrollmentDir": "/emm-web-agent/enrollment",
"iOSConfigRoot" : "%https.ip%/ios-enrollment/",
"iOSAPIRoot" : "%https.ip%/api/device-mgt/ios/v1.0/",
"dynamicClientRegistrationEndPoint" : "%https.ip%/dynamic-client-web/register/",
"adminService":"%https.ip%",
"idPServer":"%https.ip%",
"callBackUrl":"%https.ip%/mdm-admin",
"oauthProvider": {
"appRegistration": {
"appType": "webapp",
"clientName": "emm-web-agent",
"owner": "admin@carbon.super",
"dynamicClientAppRegistrationServiceURL": "%https.ip%/dynamic-client-web/register",
"apiManagerClientAppRegistrationServiceURL": "%https.ip%/api-application-registration/register/tenants",
"grantType": "password refresh_token urn:ietf:params:oauth:grant-type:saml2-bearer",
"tokenScope": "admin",
"callbackUrl": "%https.ip%/api/device-mgt/v1.0"
},
"tokenServiceURL": "%https.ip%/oauth2/token"
},
"adminUser":"admin",
"usernameLength":30,
"device" : {
"ios" : {
"location" : "%http.ip%/emm-web-agent/public/mdm.page.enrollments.ios.download-agent/asset/ios-agent.ipa",
"bundleID" : "org.wso2.carbon.emm.iOSMDMAgent",
"version" : "1.0",
"appName" : "EMM iOS Agent"
}
},
"androidAgentApp" : "android-agent.apk",
"windowsConfigRoot" : "%http.ip%/api/device-mgt/windows/v1.0/services/federated/bst/authentication",
"ssoConfiguration" : {
"enabled" : false,
"issuer" : "mdm",
"appName" : "admin_emm-web-agent",
"identityProviderURL" : "%https.ip%/sso/samlsso.jag",
"responseSigningEnabled" : "true",
"keyStorePassword" : "wso2carbon",
"identityAlias" : "wso2carbon",
"keyStoreName" : "/repository/resources/security/wso2carbon.jks"
},
"generalConfig" : {
"host" : "%http.ip%",
"companyName" : "WSO2 Enterprise Mobility Manager",
"browserTitle" : "WSO2 EMM",
"copyrightText" : "\u00A9 %date-year%, WSO2 Inc. (http://www.wso2.org) All Rights Reserved."
},
"isOAuthEnabled" : true,
"scopes" : ["activity:view",
"application:install",
"application:uninstall",
"device:view",
"user:modify",
"configuration:view",
"configuration:modify",
"device:list",
"device:search",
"notification:view",
"policy:list",
"policy:add",
"polciy:modify",
"policy:view",
"role:list",
"role:add",
"role:view",
"role:modify",
"user:list",
"user:add",
"user:view",
"certificate:view",
"certificate:add",
"certificate:modify",
"device:android:get-applications",
"device:android:blacklist-applications",
"device:android:change-lock-code",
"device:android:clear-password",
"device:android:vpn",
"device:android:wifi",
"device:android:camera",
"device:android:encrypt",
"device:android:enterprise-wipe",
"device:android:info",
"device:android:install-application",
"device:android:location",
"device:android:lock",
"device:android:mute",
"device:android:reboot",
"device:android:ring",
"device:android:send-notification",
"device:android:set-password-policy",
"device:android:webclip",
"device:android:uninstall-application",
"device:android:unlock",
"device:android:update-application",
"device:android:upgrade-firmware",
"device:android:wipe",
"device:configuration:view",
"device:android:configuration:modify",
"device:android:enroll",
"device:android:event:publish",
"device:android:event:view"]
}

@ -0,0 +1,76 @@
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
WSO2 Inc. licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file except
in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
either express or implied. See the License for the
specific language governing permissions and limitations
under the License. --}}
{{!-- Copyright (c) 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. --}}
{{~defineZone "accessControl"~}}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{{defineZone "favicon"}}
<title>
{{defineZone "title"}}
</title>
{{defineZone "topCss"}}
{{defineZone "topJs"}}
</head>
<body>
<header class="header header-default">
<div class="container-fluid ">
<div class="col-sm-8 app-logo">
{{defineZone "brand"}}
</div>
</div>
</header>
<div class="page-content-wrapper">
<div class="container-fluid ">
<div class="body-wrapper">
<div class="wr-head">
<h2>{{defineZone "headerTitle" }}</h2>
<hr>
</div>
<!-- start: zone-content-->
{{defineZone "content"}}
<!-- end: zone-content-->
{{!-- {{ defineZone "footer"}} --}}
</div>
</div>
</div>
<footer class="footer">
<div class="container-fluid">
{{defineZone "footer"}}
</div>
</footer>
{{defineZone "bottomJs" }}
</body>
</html>

@ -0,0 +1,348 @@
/*
* 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 deviceModule;
deviceModule = function () {
var log = new Log("/app/modules/business-controllers/device.js");
var utility = require('/app/modules/utility.js').utility;
var constants = require('/app/modules/constants.js');
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
// var ArrayList = Packages.java.util.ArrayList;
// var Properties = Packages.java.util.Properties;
// var DeviceIdentifier = Packages.org.wso2.carbon.device.mgt.common.DeviceIdentifier;
// var DeviceManagerUtil = Packages.org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
// var SimpleOperation = Packages.org.wso2.carbon.device.mgt.core.operation.mgt.SimpleOperation;
// var ConfigOperation = Packages.org.wso2.carbon.device.mgt.core.operation.mgt.ConfigOperation;
// var CommandOperation = Packages.org.wso2.carbon.device.mgt.core.operation.mgt.CommandOperation;
var publicMethods = {};
var privateMethods = {};
// var deviceCloudService = devicemgtProps["httpsURL"] + "/common/device_manager";
privateMethods.validateAndReturn = function (value) {
return (value == undefined || value == null) ? constants.UNSPECIFIED : value;
};
/*
@Deprecated
*/
// publicMethods.listDevices = function () {
// var carbonUser = session.get(constants.USER_SESSION_KEY);
// var utility = require('/app/modules/utility.js').utility;
// if (!carbonUser) {
// log.error("User object was not found in the session");
// throw constants.ERRORS.USER_NOT_FOUND;
// }
// try {
// utility.startTenantFlow(carbonUser);
// var deviceManagementService = utility.getDeviceManagementService();
// var devices = deviceManagementService.getAllDevices();
// var deviceList = [];
// var i, device, propertiesList, deviceObject;
// for (i = 0; i < devices.size(); i++) {
// device = devices.get(i);
// propertiesList = DeviceManagerUtil.convertDevicePropertiesToMap(device.getProperties());
//
// deviceObject = {};
// deviceObject[constants.DEVICE_IDENTIFIER] =
// privateMethods.validateAndReturn(device.getDeviceIdentifier());
// deviceObject[constants.DEVICE_NAME] =
// privateMethods.validateAndReturn(device.getName());
// deviceObject[constants.DEVICE_OWNERSHIP] =
// privateMethods.validateAndReturn(device.getEnrolmentInfo().getOwnership());
// deviceObject[constants.DEVICE_OWNER] =
// privateMethods.validateAndReturn(device.getEnrolmentInfo().getOwner());
// deviceObject[constants.DEVICE_TYPE] =
// privateMethods.validateAndReturn(device.getType());
// deviceObject[constants.DEVICE_PROPERTIES] = {};
// if (device.getType() == constants.PLATFORM_IOS) {
// deviceObject[constants.DEVICE_PROPERTIES][constants.DEVICE_MODEL] =
// privateMethods.validateAndReturn(propertiesList.get(constants.DEVICE_PRODUCT));
// deviceObject[constants.DEVICE_PROPERTIES][constants.DEVICE_VENDOR] = constants.VENDOR_APPLE;
// } else {
// deviceObject[constants.DEVICE_PROPERTIES][constants.DEVICE_MODEL] =
// privateMethods.validateAndReturn(propertiesList.get(constants.DEVICE_MODEL));
// deviceObject[constants.DEVICE_PROPERTIES][constants.DEVICE_VENDOR] =
// privateMethods.validateAndReturn(propertiesList.get(constants.DEVICE_VENDOR));
// }
// deviceObject[constants.DEVICE_PROPERTIES][constants.DEVICE_OS_VERSION] =
// privateMethods.validateAndReturn(propertiesList.get(constants.DEVICE_OS_VERSION));
//
// deviceList.push(deviceObject);
// }
// return deviceList;
// } catch (e) {
// throw e;
// } finally {
// utility.endTenantFlow();
// }
// };
/*
@Deprecated
*/
/*
Get the supported features by the device type
*/
// publicMethods.getFeatures = function (deviceType) {
// var carbonUser = session.get(constants.USER_SESSION_KEY);
// var utility = require('/app/modules/utility.js').utility;
// if (!carbonUser) {
// log.error("User object was not found in the session");
// throw constants.ERRORS.USER_NOT_FOUND;
// }
// try {
// utility.startTenantFlow(carbonUser);
// var deviceManagementService = utility.getDeviceManagementService();
// var features = deviceManagementService.getFeatureManager(deviceType).getFeatures();
// var featuresConverted = {};
// if (features) {
// var i, feature, featureObject;
// for (i = 0; i < features.size(); i++) {
// feature = features.get(i);
// featureObject = {};
// featureObject[constants.FEATURE_NAME] = feature.getName();
// featureObject[constants.FEATURE_DESCRIPTION] = feature.getDescription();
// featuresConverted[feature.getName()] = featureObject;
// }
// }
// return featuresConverted;
// } catch (e) {
// throw e;
// } finally {
// utility.endTenantFlow();
// }
// };
/*
@Deprecated
*/
// publicMethods.performOperation = function (devices, operation) {
// var carbonUser = session.get(constants.USER_SESSION_KEY);
// var utility = require('/app/modules/utility.js').utility;
// if (!carbonUser) {
// log.error("User object was not found in the session");
// throw constants.ERRORS.USER_NOT_FOUND;
// }
// try {
// utility.startTenantFlow(carbonUser);
// var deviceManagementService = utility.getDeviceManagementService();
// var operationInstance;
// if (operation.type == "COMMAND") {
// operationInstance = new CommandOperation();
// } else if (operation.type == "CONFIG") {
// operationInstance = new ConfigOperation();
// } else {
// operationInstance = new SimpleOperation();
// }
// operationInstance.setCode(operation.featureName);
// var props = new Properties();
// var i, object;
// for (i = 0; i < operation.properties.length; i++) {
// object = properties[i];
// props.setProperty(object.key, object.value);
// }
// operationInstance.setProperties(props);
// var deviceList = new ArrayList();
// var j, device, deviceIdentifier;
// for (j = 0; j < devices.length; i++) {
// device = devices[j];
// deviceIdentifier = new DeviceIdentifier();
// deviceIdentifier.setId(device.id);
// deviceIdentifier.setType(device.type);
// deviceList.add(deviceIdentifier);
// }
// deviceManagementService.addOperation(operationInstance, deviceList);
// } catch (e) {
// throw e;
// } finally {
// utility.endTenantFlow();
// }
// };
/*
@Deprecated
*/
// privateMethods.getDevice = function (type, deviceId) {
// var carbonUser = session.get(constants.USER_SESSION_KEY);
// var utility = require('/app/modules/utility.js').utility;
// if (!carbonUser) {
// log.error("User object was not found in the session");
// throw constants.ERRORS.USER_NOT_FOUND;
// }
// try {
// utility.startTenantFlow(carbonUser);
// var deviceManagementService = utility.getDeviceManagementService();
// var deviceIdentifier = new DeviceIdentifier();
// deviceIdentifier.setType(type);
// deviceIdentifier.setId(deviceId);
// return deviceManagementService.getDevice(deviceIdentifier);
// } catch (e) {
// throw e;
// } finally {
// utility.endTenantFlow();
// }
// };
/*
@Updated
*/
publicMethods.viewDevice = function (deviceType, deviceId) {
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
if (!carbonUser) {
log.error("User object was not found in the session");
throw constants["ERRORS"]["USER_NOT_FOUND"];
}
var utility = require('/app/modules/utility.js')["utility"];
try {
utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + constants.ADMIN_SERVICE_CONTEXT + "/devices/view?type=" + deviceType
+ "&id=" + deviceId;
return serviceInvokers.XMLHttp.get(
url, function (responsePayload) {
var device = responsePayload.responseContent;
if (device) {
var propertiesList = device["properties"];
var properties = {};
if (propertiesList) {
for (var i = 0; i < propertiesList.length; i++) {
properties[propertiesList[i]["name"]] = propertiesList[i]["value"];
}
}
var deviceObject = {};
deviceObject[constants["DEVICE_IDENTIFIER"]] = device["deviceIdentifier"];
deviceObject[constants["DEVICE_NAME"]] = device["name"];
deviceObject[constants["DEVICE_OWNERSHIP"]] = device["enrolmentInfo"]["ownership"];
deviceObject[constants["DEVICE_OWNER"]] = device["enrolmentInfo"]["owner"];
deviceObject[constants["DEVICE_STATUS"]] = device["enrolmentInfo"]["status"];
deviceObject[constants["DEVICE_TYPE"]] = device["type"];
if (device["type"] == constants["PLATFORM_IOS"]) {
properties[constants["DEVICE_MODEL"]] = properties[constants["DEVICE_PRODUCT"]];
delete properties[constants["DEVICE_PRODUCT"]];
properties[constants["DEVICE_VENDOR"]] = constants["VENDOR_APPLE"];
}
deviceObject[constants["DEVICE_PROPERTIES"]] = properties;
return deviceObject;
}
},
function (responsePayload) {
var response = {};
response["status"] = "error";
return response;
}
);
} catch (e) {
throw e;
} finally {
utility.endTenantFlow();
}
};
// Refactored methods
publicMethods.getDevicesCount = function () {
var carbonUser = session.get(constants.USER_SESSION_KEY);
if (carbonUser) {
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var uiPermissions = userModule.getUIPermissions();
var url;
if (uiPermissions.LIST_DEVICES) {
url = devicemgtProps["httpsURL"] + constants.ADMIN_SERVICE_CONTEXT + "/devices/count";
} else if (uiPermissions.LIST_OWN_DEVICES) {
url = devicemgtProps["httpsURL"] + constants.ADMIN_SERVICE_CONTEXT + "/devices/user/"
+ carbonUser.username
+ "/count";
} else {
log.error("Access denied for user: " + carbonUser.username);
return -1;
}
return serviceInvokers.XMLHttp.get(
url, function (responsePayload) {
return responsePayload;
},
function (responsePayload) {
log.error(responsePayload);
return -1;
}
);
} else {
log.error("User object was not found in the session");
throw constants["ERRORS"]["USER_NOT_FOUND"];
}
};
publicMethods.getDeviceTypes = function () {
var url = devicemgtProps["httpsURL"] + constants.ADMIN_SERVICE_CONTEXT + "/devices/types";
return serviceInvokers.XMLHttp.get(
url, function (responsePayload) {
return responsePayload;
},
function (responsePayload) {
log.error(responsePayload);
return -1;
}
);
};
//Old methods
//TODO: make sure these methods are updated
/*
@Updated
*/
publicMethods.getLicense = function (deviceType) {
var url;
var license;
if (deviceType == "windows") {
url = devicemgtProps["httpURL"] + "/mdm-windows-agent/services/device/license";
} else if (deviceType == "ios") {
url = devicemgtProps["httpsURL"] + "/ios-enrollment/license/";
}
if (url != null && url != undefined) {
return serviceInvokers.XMLHttp.get(
url, function (responsePayload) {
return "" + parse(responsePayload.responseText).text;
},
function (responsePayload) {
return null;
}
);
}
return null;
};
publicMethods.getDevices = function (userName) {
var url = devicemgtProps["httpsURL"] + constants.ADMIN_SERVICE_CONTEXT + "/devices/user/" + userName;
return serviceInvokers.XMLHttp.get(
url, function (responsePayload) {
for (var i = 0; i < responsePayload.length; i++) {
responsePayload[i].thumb = utility.getDeviceThumb(responsePayload[i].type);
}
return responsePayload;
},
function (responsePayload) {
log.error(responsePayload);
return -1;
}
);
};
return publicMethods;
}();

@ -0,0 +1,82 @@
/*
* 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 groupModule = {};
(function (groupModule) {
var log = new Log("/app/modules/business-controllers/group.js");
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var constants = require('/app/modules/constants.js');
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var utility = require("/app/modules/utility.js").utility;
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
var groupServiceEndpoint = devicemgtProps["httpsURL"] + constants.ADMIN_SERVICE_CONTEXT + "/groups";
var user = session.get(constants.USER_SESSION_KEY);
var endPoint;
groupModule.getGroupCount = function () {
var permissions = userModule.getUIPermissions();
if (permissions.LIST_ALL_GROUPS) {
endPoint = groupServiceEndpoint + "/count";
} else if (permissions.LIST_GROUPS) {
endPoint = groupServiceEndpoint + "/user/" + user.username + "/count";
} else {
log.error("Access denied for user: " + carbonUser.username);
return -1;
}
return serviceInvokers.XMLHttp.get(
endPoint, function (responsePayload) {
return responsePayload;
},
function (responsePayload) {
log.error(responsePayload);
return -1;
}
);
};
groupModule.getGroupDeviceCount = function (groupName, owner) {
endPoint = groupServiceEndpoint + "/owner/" + owner + "/name/" + groupName + "/devices/count";
return serviceInvokers.XMLHttp.get(
endPoint, function (responsePayload) {
return responsePayload;
},
function (responsePayload) {
log.error(responsePayload);
return -1;
}
);
};
groupModule.getGroupDevices = function (groupName, owner) {
endPoint = groupServiceEndpoint + "/owner/" + owner + "/name/" + groupName + "/devices";
return serviceInvokers.XMLHttp.get(
endPoint, function (responsePayload) {
return responsePayload;
},
function (responsePayload) {
log.error(responsePayload);
return responsePayload;
}
);
};
}(groupModule));

@ -0,0 +1,134 @@
/*
* 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 operationModule = function () {
var log = new Log("/app/modules/business-controllers/operation.js");
var utility = require('/app/modules/utility.js').utility;
var constants = require('/app/modules/constants.js');
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
var publicMethods = {};
var privateMethods = {};
/**
* This method reads the token from the Token client and return the access token.
* If the token pair s not set in the session this will send a redirect to the login page.
*/
function getAccessToken(deviceType, owner, deviceId) {
var TokenClient = Packages.org.wso2.carbon.device.mgt.iot.apimgt.TokenClient;
var accessTokenClient = new TokenClient(deviceType);
var accessTokenInfo = accessTokenClient.getAccessToken(owner, deviceId);
return accessTokenInfo.getAccess_token();
}
privateMethods.getOperationsFromFeatures = function (deviceType, operationType) {
var url = devicemgtProps["httpsURL"] + constants.ADMIN_SERVICE_CONTEXT + "/features/" + deviceType;
var featuresList = serviceInvokers.XMLHttp.get(url, function (responsePayload) {
var features = responsePayload;
var featureList = [];
var feature;
for (var i = 0; i < features.length; i++) {
feature = {};
var analyticStreams = utility.getDeviceTypeConfig(deviceType)["analyticStreams"];
if (analyticStreams) {
for (var stream in analyticStreams) {
if (analyticStreams[stream].name == features[i].name) {
feature.ui_unit = analyticStreams[stream].ui_unit;
break;
}
}
}
feature["operation"] = features[i].code;
feature["name"] = features[i].name;
feature["description"] = features[i].description;
feature["deviceType"] = deviceType;
feature["params"] = [];
var metaData = features[i].metadataEntries;
if (metaData) {
for (var j = 0; j < metaData.length; j++) {
feature["params"].push(metaData[j].value);
}
featureList.push(feature);
}
}
return featureList;
}, function (responsePayload) {
var response = {};
response["status"] = "error";
return response;
}
);
return featuresList;
};
publicMethods.getControlOperations = function (deviceType) {
var operations = privateMethods.getOperationsFromFeatures(deviceType, "operation");
for (var op in operations) {
var iconPath = utility.getOperationIcon(deviceType, operations[op].operation);
if (iconPath) {
operations[op]["icon"] = iconPath;
}
}
return operations;
};
publicMethods.getMonitorOperations = function (deviceType) {
return privateMethods.getOperationsFromFeatures(deviceType, "monitor");
};
publicMethods.handlePOSTOperation = function (deviceType, operation, deviceId, params) {
var user = session.get(constants.USER_SESSION_KEY);
var endPoint = devicemgtProps["httpsURL"] + '/' + deviceType + "/controller/" + operation;
var header = '{"owner":"' + user.username + '","deviceId":"' + deviceId +
'","protocol":"mqtt", "sessionId":"' + session.getId() + '", "' +
constants.AUTHORIZATION_HEADER + '":"' + constants.BEARER_PREFIX +
getAccessToken(deviceType, user.username, deviceId) + '"}';
return post(endPoint, params, JSON.parse(header), "json");
};
publicMethods.handleGETOperation = function (deviceType, operation, operationName, deviceId) {
var user = session.get(constants.USER_SESSION_KEY);
var endPoint = devicemgtProps["httpsURL"] + '/' + deviceType + "/controller/" + operation;
var header = '{"owner":"' + user.username + '","deviceId":"' + deviceId +
'","protocol":"mqtt", "' + constants.AUTHORIZATION_HEADER + '":"' +
constants.BEARER_PREFIX + getAccessToken(deviceType, user.username, deviceId) +
'"}';
var result = get(endPoint, {}, JSON.parse(header), "json");
if (result.data) {
var values = result.data.sensorValue.split(',');
if (operationName == 'gps') {
result.data.map = {
lat: parseFloat(values[0]),
lng: parseFloat(values[1])
}
} else {
var sqSum = 0;
for (var v in values) {
sqSum += Math.pow(values[v], 2);
}
result.data[operationName] = Math.sqrt(sqSum);
}
delete result.data['sensorValue'];
}
return result;
};
return publicMethods;
}();

@ -0,0 +1,152 @@
/*
* 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 policyModule;
policyModule = function () {
var log = new Log("/app/modules/business-controllers/policy.js");
var constants = require('/app/modules/constants.js');
var utility = require("/app/modules/utility.js")["utility"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
var publicMethods = {};
var privateMethods = {};
privateMethods.handleGetAllPoliciesResponse = function (backendResponse) {
var response = {};
if (backendResponse.status == 200 && backendResponse.responseText) {
var isUpdated = false;
var policyListFromRestEndpoint = parse(backendResponse.responseText)["policies"];
var policyListToView = [];
var i, policyObjectFromRestEndpoint, policyObjectToView;
for (i = 0; i < policyListFromRestEndpoint.length; i++) {
// get list object
policyObjectFromRestEndpoint = policyListFromRestEndpoint[i];
// populate list object values to view-object
policyObjectToView = {};
policyObjectToView["id"] = policyObjectFromRestEndpoint["id"];
policyObjectToView["priorityId"] = policyObjectFromRestEndpoint["priorityId"];
policyObjectToView["name"] = policyObjectFromRestEndpoint["policyName"];
policyObjectToView["platform"] = policyObjectFromRestEndpoint["profile"]["deviceType"];
policyObjectToView["icon"] = utility.getDeviceThumb(policyObjectToView["platform"]);
policyObjectToView["ownershipType"] = policyObjectFromRestEndpoint["ownershipType"];
var assignedRoleCount = policyObjectFromRestEndpoint["roles"].length;
var assignedUserCount = policyObjectFromRestEndpoint["users"].length;
if (assignedRoleCount == 0) {
policyObjectToView["roles"] = "None";
} else if (assignedRoleCount == 1) {
policyObjectToView["roles"] = policyObjectFromRestEndpoint["roles"][0];
} else if (assignedRoleCount > 1) {
policyObjectToView["roles"] = policyObjectFromRestEndpoint["roles"][0] + ", ...";
}
if (assignedUserCount == 0) {
policyObjectToView["users"] = "None";
} else if (assignedUserCount == 1) {
policyObjectToView["users"] = policyObjectFromRestEndpoint["users"][0];
} else if (assignedUserCount > 1) {
policyObjectToView["users"] = policyObjectFromRestEndpoint["users"][0] + ", ...";
}
policyObjectToView["compliance"] = policyObjectFromRestEndpoint["compliance"];
if (policyObjectFromRestEndpoint["active"] == true &&
policyObjectFromRestEndpoint["updated"] == true) {
policyObjectToView["status"] = "Active/Updated";
isUpdated = true;
} else if (policyObjectFromRestEndpoint["active"] == true &&
policyObjectFromRestEndpoint["updated"] == false) {
policyObjectToView["status"] = "Active";
} else if (policyObjectFromRestEndpoint["active"] == false &&
policyObjectFromRestEndpoint["updated"] == true) {
policyObjectToView["status"] = "Inactive/Updated";
isUpdated = true;
} else if (policyObjectFromRestEndpoint["active"] == false &&
policyObjectFromRestEndpoint["updated"] == false) {
policyObjectToView["status"] = "Inactive";
}
// push view-objects to list
policyListToView.push(policyObjectToView);
}
// generate response
response.updated = isUpdated;
response.status = "success";
response.content = policyListToView;
return response;
} else {
response.status = "error";
/* backendResponse.responseText == "Scope validation failed"
Here the response.context("Scope validation failed") is used other then response.status(401).
Reason for this is IDP return 401 as the status in 4 different situations such as,
1. UnAuthorized.
2. Scope Validation Failed.
3. Permission Denied.
4. Access Token Expired.
5. Access Token Invalid.
In these cases in order to identify the correct situation we have to compare the unique value from status and
context which is context.
*/
if (backendResponse.responseText == "Scope validation failed") {
response.content = "Permission Denied";
} else {
response.content = backendResponse.responseText;
}
return response;
}
};
/*
@Updated
*/
publicMethods.getAllPolicies = function () {
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
if (!carbonUser) {
log.error("User object was not found in the session");
throw constants["ERRORS"]["USER_NOT_FOUND"];
}
try {
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] +
"/policies?offset=0&limit=100";
return serviceInvokers.XMLHttp.get(url, privateMethods.handleGetAllPoliciesResponse);
} catch (e) {
throw e;
}
};
/*
@Updated - used by getAllPolicies
*/
privateMethods.getElementsInAString = function (elementList) {
var i, elementsInAString = "";
for (i = 0; i < elementList.length; i++) {
if (i == elementList.length - 1) {
elementsInAString += elementList[i];
} else {
elementsInAString += elementList[i] + ", ";
}
}
return elementsInAString;
};
return publicMethods;
}();

@ -0,0 +1,540 @@
/*
* 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.
*/
/*
* This module contains user and roles related functionality.
*/
var userModule = function () {
var log = new Log("/app/modules/business-controllers/user.js");
var constants = require("/app/modules/constants.js");
var utility = require("/app/modules/utility.js")["utility"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
/* Initializing user manager */
var carbon = require("carbon");
var url = carbon.server.address("https") + "/admin/services";
var server = new carbon.server.Server(url);
var publicMethods = {};
var privateMethods = {};
/**
* Get the carbon user object from the session. If not found - it will throw a user not found error.
* @returns {object} carbon user object
*/
privateMethods.getCarbonUser = function () {
var carbon = require("carbon");
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
var utility = require("/modules/utility.js")["utility"];
if (!carbonUser) {
log.error("User object was not found in the session");
throw constants["ERRORS"]["USER_NOT_FOUND"];
}
return carbonUser;
};
/**
* Only GET method is implemented for now since there are no other type of methods used this method.
* @param url - URL to call the backend without the host
* @param method - HTTP Method (GET, POST)
* @returns An object with 'status': 'success'|'error', 'content': {}
*/
privateMethods.callBackend = function (url, method) {
if (constants["HTTP_GET"] == method) {
return serviceInvokers.XMLHttp.get(url,
function (backendResponse) {
var response = {};
response.content = backendResponse.responseText;
if (backendResponse.status == 200) {
response.status = "success";
} else if (backendResponse.status == 400 || backendResponse.status == 401 ||
backendResponse.status == 404 || backendResponse.status == 500) {
response.status = "error";
}
return response;
}
);
} else {
log.error("Runtime error : This method only support HTTP GET requests.");
}
};
/**
* Register user to dc-user-store.
*
* @param username Username of the user
* @param firstname First name of the user
* @param lastname Last name of the user
* @param emailAddress Email address of the user
* @param password Password of the user
* @param userRoles Roles assigned to the user
*
* @returns {number} HTTP Status code 201 if succeeded, 409 if user already exists
*/
publicMethods.registerUser = function (username, firstname, lastname, emailAddress, password, userRoles) {
var carbon = require('carbon');
var tenantId = carbon.server.tenantId();
var url = carbon.server.address('https') + "/admin/services";
var server = new carbon.server.Server(url);
var userManager = new carbon.user.UserManager(server, tenantId);
try {
if (userManager.userExists(username)) {
if (log.isDebugEnabled()) {
log.debug("A user with name '" + username + "' already exists.");
}
// http status code 409 refers to - conflict.
return constants.HTTP_CONFLICT;
} else {
var defaultUserClaims = privateMethods.buildDefaultUserClaims(firstname, lastname, emailAddress);
userManager.addUser(username, password, userRoles, defaultUserClaims, "default");
if (log.isDebugEnabled()) {
log.debug("A new user with name '" + username + "' was created.");
}
// http status code 201 refers to - created.
return constants.HTTP_CREATED;
}
} catch (e) {
throw e;
}
};
/*
@Updated
*/
publicMethods.getUsers = function () {
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
var utility = require("/app/modules/utility.js")["utility"];
if (!carbonUser) {
log.error("User object was not found in the session");
throw constants["ERRORS"]["USER_NOT_FOUND"];
}
try {
utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/users?offset=0&limit=100";
var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
if (response.status == "success") {
response.content = parse(response.content).users;
}
return response;
} catch (e) {
throw e;
} finally {
utility.endTenantFlow();
}
};
/**
* Return a User object from the backend by calling the JAX-RS
* @param username
* @returns {object} a response object with status and content on success.
*/
publicMethods.getUser = function (username) {
var carbonUser = privateMethods.getCarbonUser();
try {
utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/users/" +
encodeURIComponent(username);
var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
response["content"] = parse(response.content);
response["userDomain"] = carbonUser.domain;
return response;
} catch (e) {
throw e;
} finally {
utility.endTenantFlow();
}
};
/**
* Returns a set of roles assigned to a particular user
* @param username
* @returns {object} a response object with status and content on success.
*/
publicMethods.getRolesByUsername = function (username) {
var carbonUser = privateMethods.getCarbonUser();
try {
utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/users/" +
encodeURIComponent(username) + "/roles";
return privateMethods.callBackend(url, constants["HTTP_GET"]);
} catch (e) {
throw e;
} finally {
utility.endTenantFlow();
}
};
/*
@NewlyAdded
*/
publicMethods.getUsersByUsername = function () {
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
var utility = require("/app/modules/utility.js")["utility"];
if (!carbonUser) {
log.error("User object was not found in the session");
throw constants["ERRORS"]["USER_NOT_FOUND"];
}
try {
utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + "/mdm-admin/users/users-by-username";
return privateMethods.callBackend(url, constants["HTTP_GET"]);
} catch (e) {
throw e;
} finally {
utility.endTenantFlow();
}
};
/*
@Updated
*/
/**
* Get User Roles from user store (Internal roles not included).
*/
publicMethods.getRoles = function () {
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
var utility = require("/app/modules/utility.js")["utility"];
if (!carbonUser) {
log.error("User object was not found in the session");
throw constants["ERRORS"]["USER_NOT_FOUND"];
}
try {
utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] +
"/roles?offset=0&limit=100";
var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
if (response.status == "success") {
response.content = parse(response.content).roles;
}
return response;
} catch (e) {
throw e;
} finally {
utility.endTenantFlow();
}
};
/*
@Updated
*/
/**
* Get User Roles from user store (Internal roles not included).
* @returns {object} a response object with status and content on success.
*/
publicMethods.getRolesByUserStore = function () {
var ROLE_LIMIT = devicemgtProps["pageSize"];
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
var utility = require("/app/modules/utility.js")["utility"];
if (!carbonUser) {
log.error("User object was not found in the session");
throw constants["ERRORS"]["USER_NOT_FOUND"];
}
try {
utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/roles?limit=" + ROLE_LIMIT;
var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
if (response.status == "success") {
response.content = parse(response.content).roles;
}
return response;
} catch (e) {
throw e;
} finally {
utility.endTenantFlow();
}
};
/**
* Get Platforms.
*/
//TODO Move this piece of logic out of user.js to somewhere else appropriate.
publicMethods.getPlatforms = function () {
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
var utility = require("/app/modules/utility.js")["utility"];
if (!carbonUser) {
log.error("User object was not found in the session");
throw constants["ERRORS"]["USER_NOT_FOUND"];
}
try {
utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/admin/device-types";
var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
if (response.status == "success") {
response.content = parse(response.content);
}
return response;
} catch (e) {
throw e;
} finally {
utility.endTenantFlow();
}
};
/**
* Get role
*/
publicMethods.getRole = function (roleName) {
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
var utility = require("/app/modules/utility.js")["utility"];
if (!carbonUser) {
log.error("User object was not found in the session");
throw constants["ERRORS"]["USER_NOT_FOUND"];
}
try {
utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] +
"/roles/" + encodeURIComponent(roleName);
var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
response.content = parse(response.content);
return response;
} catch (e) {
throw e;
} finally {
utility.endTenantFlow();
}
};
/**
* Authenticate a user when he or she attempts to login to MDM.
*
* @param username Username of the user
* @param password Password of the user
* @param successCallback Function to be called at the event of successful authentication
* @param failureCallback Function to be called at the event of failed authentication
*/
publicMethods.login = function (username, password, successCallback, failureCallback) {
var carbonModule = require("carbon");
var carbonServer = application.get("carbonServer");
try {
// check if the user is an authenticated user.
var isAuthenticated = carbonServer.authenticate(username, password);
if (!isAuthenticated) {
failureCallback("authentication");
return;
}
var tenantUser = carbonModule.server.tenantUser(username);
var isAuthorizedToLogin = privateMethods.isAuthorizedToLogin(tenantUser);
if (!isAuthorizedToLogin) {
failureCallback("authorization");
return;
}
session.put(constants.USER_SESSION_KEY, tenantUser);
successCallback(tenantUser);
} catch (e) {
throw e;
}
};
publicMethods.logout = function (successCallback) {
session.invalidate();
successCallback();
};
publicMethods.isAuthorized = function (permission) {
var carbon = require("carbon");
var carbonServer = application.get("carbonServer");
var carbonUser = session.get(constants.USER_SESSION_KEY);
var utility = require('/app/modules/utility.js').utility;
if (!carbonUser) {
log.error("User object was not found in the session");
response.sendError(401, constants.ERRORS.USER_NOT_FOUND);
exit();
}
try {
utility.startTenantFlow(carbonUser);
var tenantId = carbon.server.tenantId();
var userManager = new carbon.user.UserManager(server, tenantId);
var user = new carbon.user.User(userManager, carbonUser.username);
return user.isAuthorized(permission, "ui.execute");
} catch (e) {
throw e;
} finally {
utility.endTenantFlow();
}
};
privateMethods.isAuthorizedToLogin = function(carbonUser) {
var utility = require('/app/modules/utility.js').utility;
try {
utility.startTenantFlow(carbonUser);
var tenantId = carbon.server.tenantId();
var userManager = new carbon.user.UserManager(server, tenantId);
var user = new carbon.user.User(userManager, carbonUser.username);
return user.isAuthorized("/permission/admin/login", "ui.execute");
} catch (e) {
throw e;
} finally {
utility.endTenantFlow();
}
};
publicMethods.getUIPermissions = function () {
var permissions = {};
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/devices/list")) {
permissions["LIST_DEVICES"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/devices/list")) {
permissions["LIST_OWN_DEVICES"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/groups/list")) {
permissions["LIST_ALL_GROUPS"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/groups/list")) {
permissions["LIST_GROUPS"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/users/list")) {
permissions["LIST_USERS"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/roles/list")) {
permissions["LIST_ROLES"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/policies/list")) {
permissions["LIST_ALL_POLICIES"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/policies/list")) {
permissions["LIST_POLICIES"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/devices/add")) {
permissions["ADD_DEVICE"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/groups/add")) {
permissions["ADD_GROUP"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/users/add")) {
permissions["ADD_USER"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/users/remove")) {
permissions["REMOVE_USER"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/roles/add")) {
permissions["ADD_ROLE"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/policies/add")) {
permissions["ADD_ADMIN_POLICY"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/policies/add")) {
permissions["ADD_POLICY"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/policies/priority")) {
permissions["CHANGE_POLICY_PRIORITY"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/dashboard/view")) {
permissions["VIEW_DASHBOARD"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/platform-configs/view")) {
permissions["TENANT_CONFIGURATION"] = true;
}
return permissions;
};
publicMethods.addPermissions = function (permissionList, path, init) {
var registry, carbon = require("carbon");
var carbonServer = application.get("carbonServer");
var utility = require('/app/modules/utility.js').utility;
var options = {system: true};
if (init == "login") {
try {
var carbonUser = session.get(constants.USER_SESSION_KEY);
if (!carbonUser) {
log.error("User object was not found in the session");
throw constants.ERRORS.USER_NOT_FOUND;
}
utility.startTenantFlow(carbonUser);
var tenantId = carbon.server.tenantId();
if (carbonUser) {
options.tenantId = tenantId;
}
registry = new carbon.registry.Registry(carbonServer, options);
var i, permission, resource;
for (i = 0; i < permissionList.length; i++) {
permission = permissionList[i];
resource = {
collection: true,
name: permission.name,
properties: {
name: permission.name
}
};
if (path != "") {
registry.put("/_system/governance/permission/admin/" + path + "/" + permission.key, resource);
} else {
registry.put("/_system/governance/permission/admin/" + permission.key, resource);
}
}
} catch (e) {
throw e;
} finally {
utility.endTenantFlow();
}
} else {
registry = new carbon.registry.Registry(carbonServer, options);
var i, permission, resource;
for (i = 0; i < permissionList.length; i++) {
permission = permissionList[i];
resource = {
collection: true,
name: permission.name,
properties: {
name: permission.name
}
};
if (path != "") {
registry.put("/_system/governance/permission/admin/" + path + "/" + permission.key, resource);
} else {
registry.put("/_system/governance/permission/admin/" + permission.key, resource);
}
}
}
};
/**
* Private method to be used by addUser() to
* retrieve secondary user stores.
* This needs Authentication since the method access admin services.
*
* @returns Array of secondary user stores.
*/
publicMethods.getSecondaryUserStores = function () {
var returnVal = [];
var endpoint = devicemgtProps["adminService"] + constants["USER_STORE_CONFIG_ADMIN_SERVICE_END_POINT"];
var wsPayload = "<xsd:getSecondaryRealmConfigurations xmlns:xsd='http://org.apache.axis2/xsd'/>";
serviceInvokers.WS.soapRequest(
"urn:getSecondaryRealmConfigurations",
wsPayload,
endpoint,
function (wsResponse) {
var domainIDs = stringify(wsResponse.*::['return']. *::domainId.text());
if (domainIDs != "\"\"") {
var regExpForSearch = new RegExp(constants["USER_STORES_NOISY_CHAR"], "g");
domainIDs = domainIDs.replace(regExpForSearch, "");
returnVal = domainIDs.split(constants["USER_STORES_SPLITTING_CHAR"]);
}
}, function (e) {
log.error("Error retrieving secondary user stores", e);
},
constants["SOAP_VERSION"]);
return returnVal;
};
return publicMethods;
}();

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

Loading…
Cancel
Save