Imesh Chandrasiri 9 years ago
commit 32953a8411

@ -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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/operations/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/android/enroll")
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/android/enroll")
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/android/enroll")
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/android/enroll")
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/android/enroll")
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/android/enroll")
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/android/enroll")
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/android/events/manage")
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/android/events/manage")
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();
}

@ -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";
}
}

@ -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,7 +1,24 @@
{{!
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">
@ -12,6 +29,7 @@
<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>
@ -41,6 +59,7 @@
<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 +67,7 @@
</span>
View
</a>
<!--suppress HtmlUnknownTarget -->
{{#if permissions.ADD_POLICY}}
<a href="{{@app.context}}/policy/add">
<span class="fw-stack">
@ -72,6 +92,7 @@
<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 +100,7 @@
</span>
View
</a>
<!--suppress HtmlUnknownTarget -->
{{#if permissions.ADD_USER}}
<a href="{{@app.context}}/user/add">
<span class="fw-stack">
@ -103,6 +125,7 @@
<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 +134,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>
@ -126,9 +150,6 @@
</div>
</div>
{{/if}}
{{else}}
Permission denied
{{/if}}
{{/zone}}
{{#zone "bottomJs"}}
{{js "js/dashboard.js"}}

@ -20,10 +20,16 @@ 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");
viewModel.permissions = permissions;
//TODO: Move enrollment URL into app-conf.json
viewModel.enrollmentURL = mdmProps.generalConfig.host + mdmProps.enrollmentDir;
return viewModel;

@ -28,6 +28,7 @@
</a>
</li>
<li>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/devices">
Devices
</a>
@ -35,132 +36,131 @@
{{/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 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>
<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>
<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="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>
</div>
{{/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"

@ -216,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
@ -269,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

@ -42,6 +42,7 @@
<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>
@ -60,7 +61,7 @@
<hr>
<div class="row">
<div class="col-lg-12">
<h4 class="visible-xs">Step 4: Publish to devices</h4>
<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>
@ -73,6 +74,7 @@
</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
@ -114,7 +116,7 @@
<hr>
<div class="row">
<div class="col-lg-12">
<h4 class="visible-xs">Step 3: Assign to groups</h4>
<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>
@ -125,6 +127,7 @@
</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>
@ -148,6 +151,7 @@
<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>
@ -162,6 +166,7 @@
<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>
@ -174,6 +179,7 @@
</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>
@ -202,7 +208,7 @@
<hr>
<div class="row">
<div class="col-lg-12">
<h4 class="visible-xs">Step 2: Configure profile</h4>
<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>
@ -242,7 +248,7 @@
<!--</div>-->
<div class="row">
<div class="col-lg-12">
<h4 class="visible-xs"> Step 1: Select a platform</h4>
<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>
@ -251,15 +257,16 @@
<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;">
<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"
class="{{name}}-platform wizard-stepper"
data-current="policy-platform"
data-next="policy-profile" data-platform="{{name}}"
data-next="policy-profile"
data-platform="{{name}}"
data-validate="false">
<img src="{{icon}}" width="50px" height="50px" />
<br><br>
<!--<img src="{{icon}}" width="50px" height="50px" />-->
<i class="fw fw-{{deviceTypeIcon}}"></i>
<b>{{label}}</b>
</a>
</li>
@ -277,12 +284,14 @@
</div>
{{/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);
}

@ -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

@ -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;
}

@ -130,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="message message-info message-no-new"><h4><i class="icon fw fw-info"></i>No new notifications found...</h4></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;
}();

@ -0,0 +1,43 @@
/*
* 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 conf = function () {
var conf = application.get("CONF");
if (!conf) {
conf = require("/app/conf/config.json");
var pinch = require("/app/modules/conf-reader/pinch.min.js")["pinch"];
var server = require("carbon")["server"];
pinch(conf, /^/,
function (path, key, value) {
if ((typeof value === "string") && value.indexOf("%https.ip%") > -1) {
//noinspection JSUnresolvedFunction
return value.replace("%https.ip%", server.address("https"));
} else if ((typeof value === "string") && value.indexOf("%http.ip%") > -1) {
//noinspection JSUnresolvedFunction
return value.replace("%http.ip%", server.address("http"));
} else if ((typeof value === "string") && value.indexOf("%date-year%") > -1) {
var year = new Date().getFullYear();
return value.replace("%date-year%", year);
}
return value;
}
);
application.put("CONF", conf);
}
return conf;
}();

@ -0,0 +1,26 @@
/*
* Copyright (c) 2011 František Hába <hello@frantisekhaba.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the 'Software'), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Reference:- https://github.com/Baggz/Pinch
* */
(function(){var k=function(a,c){return a.length!==c.length?!1:a.every(function(a,b){return c[b]===a})},j=function(a,c,d){var b,e;if("[object Array]"===Object.prototype.toString.call(a)){b=0;for(e=a.length;b<e;b++)c.apply(d,[b,a[b],a])}else for(b in a)a.hasOwnProperty(b)&&c.apply(d,[b,a[b],a])},h=function(a){for(var c=[],d=!1,b=0,e=a.length,f="",g=function(){f&&(c.push(f),f="")};b<e;b++)a[b].match(/\[|\]/)?(g(),d="]"===a[b]?!1:!0):'"'!==a[b]&&"'"!==a[b]&&("."===a[b]&&!d?g():f+=a[b]),b===e-1&&g();return c},
g=function(a,c,d){var b=-1!==["string","object"].indexOf(typeof a),e="string"===typeof c||c&&c.test&&c.exec,f=-1!==["string","object","function"].indexOf(typeof d);b&&e&&f&&("string"===typeof a?(this.instance=JSON.parse(a),this.json=!0):this.instance=a,this.pattern="string"===typeof c?c.replace(/'/g,'"'):c,this.replacement=d,this.createIndex(this.instance))};g.prototype.createIndex=function(a,c){var d=this;this.index=this.index||[];c=c||"";j(a,function(a,e){var f,a=a+"";f=a.match(/^[a-zA-Z]+$/)?c?
c+"."+a:a:a.match(/\d+/)?c+"["+a+"]":c+'["'+a+'"]';d.index.push(f);"object"===typeof e&&d.createIndex(e,f)})};g.prototype.replace=function(){var a=this;j(this.index,function(c,d){if(a.pattern&&a.pattern.test&&a.pattern.exec&&d.match(a.pattern))return a.replaceValue(d);if("string"===typeof a.pattern){var b=h(d),e=h(a.pattern);if(k(b,e))return a.replaceValue(d)}});return this.json?JSON.stringify(this.instance):this.instance};g.prototype.replaceValue=function(a){var c=this,d=h(a);d.reduce(function(b,
e,f){if(f===d.length-1)f="function"===typeof c.replacement?c.replacement(a,e,b[e]):c.replacement,b[e]=f;else return b[e]},this.instance)};var i=function(a,c,d,b){a=(new g(a,c,d)).replace();return"function"===typeof b?b(null,a):a};"undefined"!==typeof module&&module.exports?module.exports=i:"undefined"!==typeof define?define(function(){return i}):this.pinch=i})();

@ -0,0 +1,81 @@
/*
* 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 WEB_APP_TITLE = "WSO2 CDM";
var WEB_APP_CONTEXT = "/devicemgt";
var ADMIN_SERVICE_CONTEXT = "/devicemgt_admin";
var USER_SESSION_KEY = "_UUF_USER";
var UNSPECIFIED = "Unspecified";
var httpURL = "httpURL";
var httpsURL = "httpsURL";
var DEVICE_IDENTIFIER = "deviceIdentifier";
var DEVICE_NAME = "name";
var DEVICE_OWNERSHIP = "ownership";
var DEVICE_OWNER = "owner";
var DEVICE_TYPE = "type";
var DEVICE_VENDOR = "vendor";
var DEVICE_MODEL = "model";
var DEVICE_PRODUCT = "PRODUCT";
var DEVICE_OS_VERSION = "osVersion";
var DEVICE_OS_BUILD_DATE = "osBuildDate";
var DEVICE_PROPERTIES = "properties";
var DEVICE_ENROLLMENT_INFO = "enrolmentInfo";
var DEVICE_STATUS = "status";
var FEATURE_NAME = "featureName";
var FEATURE_DESCRIPTION = "featureDescription";
var PLATFORM_ANDROID = "android";
var PLATFORM_WINDOWS = "windows";
var PLATFORM_IOS = "ios";
var LANGUAGE_US = "en_US";
var VENDOR_APPLE = "Apple";
var ERRORS = {
"USER_NOT_FOUND": "USER_NOT_FOUND"
};
var USER_STORES_NOISY_CHAR = "\"";
var USER_STORES_SPLITTING_CHAR = "\\n";
var USER_STORE_CONFIG_ADMIN_SERVICE_END_POINT =
"/services/UserStoreConfigAdminService.UserStoreConfigAdminServiceHttpsSoap12Endpoint/";
var SOAP_VERSION = 1.2;
var WEB_SERVICE_ADDRESSING_VERSION = 1.0;
var TOKEN_PAIR = "tokenPair";
var ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS = "encodedTenantBasedClientAppCredentials";
var CONTENT_TYPE_IDENTIFIER = "Content-Type";
var CONTENT_DISPOSITION_IDENTIFIER = "Content-Disposition";
var APPLICATION_JSON = "application/json";
var APPLICATION_ZIP = "application/zip";
var ACCEPT_IDENTIFIER = "Accept";
var AUTHORIZATION_HEADER= "Authorization";
var BEARER_PREFIX = "Bearer ";
var HTTP_GET = "GET";
var HTTP_POST = "POST";
var HTTP_PUT = "PUT";
var HTTP_DELETE = "DELETE";
var REFERER = "referer";
var HTTP_CONFLICT = 409;
var HTTP_CREATED = 201;
var CACHED_CREDENTIALS = "tenantBasedCredentials";
var ALLOWED_SCOPES = "scopes";

@ -0,0 +1,66 @@
<%
/*
* 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("/modules/enrollments/ios/agent-check.jag");
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
var UAParser = require("/app/modules/ua-parser.min.js")["UAParser"];
var tokenUtil = require("/app/modules/oauth/token-handlers.js")["handlers"];
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
var parser = new UAParser();
var userAgent = request.getHeader("User-Agent");
parser.setUA(userAgent);
parser.getResult();
var os = parser.getOS();
var platform = os.name;
if (platform != "iOS") {
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
} else if (session.get("lastAccessedPage") != "license-agent") {
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
} else {
var enrolledUser = session.get("enrolledUser");
if (!enrolledUser) {
response["status"] = 200;
response["content"] = {"deviceID" : null};
} else {
var deviceCheckURL = mdmProps["iOSAPIRoot"] + "devices/udid";
var challengeToken = session.get("iOSChallengeToken");
var payload = {"challengeToken" : challengeToken};
serviceInvokers.XMLHttp.post(
deviceCheckURL,
stringify(payload),
function (restAPIResponse) {
var status = restAPIResponse["status"];
if (status == 200) {
var responseContent = parse(restAPIResponse.responseText);
response["status"] = 200;
response["content"] = responseContent;
} else {
response["status"] = 200;
response["content"] = {"deviceID" : null};
}
}
);
}
}
%>

@ -0,0 +1,80 @@
<%
/*
* 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("/modules/enrollments/ios/agent-controller.jag");
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
var UAParser = require("/app/modules/ua-parser.min.js")["UAParser"];
var tokenUtil = require("/app/modules/oauth/token-handlers.js")["handlers"];
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
var constants = require("/app/modules/constants.js");
var parser = new UAParser();
var userAgent = request.getHeader("User-Agent");
parser.setUA(userAgent);
parser.getResult();
var os = parser.getOS();
var platform = os.name;
if (platform != "iOS") {
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
} else if (session.get("lastAccessedPage") != "login-agent") {
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
} else {
var username = request.getParameter("username");
var password = request.getParameter("password");
var ownership = request.getParameter("ownership");
var domain = request.getParameter("domain");
if (!username || !password || !ownership) {
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
} else {
var fullyQualifiedUsername = username;
if(domain != null && domain != ''){
fullyQualifiedUsername = username + "@" + domain;
}
tokenUtil.setupTokenPairByPasswordGrantType(fullyQualifiedUsername, password);
var authUrl = mdmProps["iOSConfigRoot"] + "authenticate";
var payload = {
"username": username, "password": password, "ownership": ownership,
"tenantDomain": domain
};
serviceInvokers.XMLHttp.post(
authUrl,
stringify(payload),
function (restAPIResponse) {
var status = restAPIResponse["status"];
if (status == 200) {
var responseContent = parse(restAPIResponse.responseText);
session.put("authenticatedUser", username);
session.put("authenticatedUserPassword", password);
session.put("authenticatedUserDeviceOwnership", ownership);
session.put("authenticatedUserDomain", domain);
session.put("iOSChallengeToken", responseContent["challengeToken"]);
response.sendRedirect(mdmProps["appContext"] + "enrollments/ios/license-agent");
} else if (status == 403) {
response.sendRedirect(mdmProps["appContext"] + "enrollments/ios/login-agent?error=auth-failed");
} else {
// one visible possibility would be server sending 500
response.sendRedirect(mdmProps["appContext"] + "enrollments/ios/login-agent?error=unexpected");
}
}
);
}
}
%>

@ -0,0 +1,85 @@
<%
/*
* 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("/app/modules/enrollments/ios/agent-enroll.jag");
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
var UAParser = require("/app/modules/ua-parser.min.js")["UAParser"];
var parser = new UAParser();
var userAgent = request.getHeader("User-Agent");
parser.setUA(userAgent);
parser.getResult();
var os = parser.getOS();
var platform = os.name;
if (platform != "iOS") {
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
} else if (session.get("lastAccessedPage") != "license-agent") {
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
} else {
var authenticatedUser = session.get("authenticatedUser");
if (!authenticatedUser) {
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
} else {
var HttpClient = Packages.org.apache.commons.httpclient.HttpClient;
var PostMethod = Packages.org.apache.commons.httpclient.methods.PostMethod;
var Header = Packages.org.apache.commons.httpclient.Header;
var StringRequestEntity = Packages.org.apache.commons.httpclient.methods.StringRequestEntity;
var ByteArrayInputStream = Packages.java.io.ByteArrayInputStream;
var client = new HttpClient();
var enrollUrl = mdmProps["iOSConfigRoot"] + "enroll";
var method = new PostMethod(enrollUrl);
var header = new Header();
header.setName("Content-Type");
header.setValue("application/json");
method.addRequestHeader(header);
var username = authenticatedUser;
var password = session.get("authenticatedUserPassword");
var tenantDomain = session.get("authenticatedUserDomain");
var challengeToken = session.get("iOSChallengeToken");
var inputs = {"username": username, "password": password, "challengeToken": challengeToken, "tenantDomain": tenantDomain};
var stringRequestEntity = new StringRequestEntity(stringify(inputs));
method.setRequestEntity(stringRequestEntity);
try {
client.executeMethod(method);
var status = method.getStatusCode();
if (status == 200) {
session.put("enrolledUser", authenticatedUser);
var stream = method.getResponseBody();
var byteArrayInputStream = new ByteArrayInputStream(stream);
response.contentType = "application/x-apple-aspen-config";
print(new Stream(byteArrayInputStream));
} else {
// two visible possibilities would be server sending 401 and 500
response.sendRedirect(mdmProps["appContext"] + "enrollments/ios/login-agent?error=unexpected");
}
} catch (e) {
log.error("Error occurred in enrolling ios device", e);
response.sendRedirect(mdmProps["appContext"] + "enrollments/ios/login-agent?error=unexpected");
} finally {
method.releaseConnection();
}
}
}
%>

@ -0,0 +1,47 @@
<%
/*
* 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("/app/modules/enrollments/ios/agent.jag");
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
var userAgent = request.getHeader("User-Agent");
var userAgentIsiPhone = (userAgent.indexOf("iPhone") > -1);
var userAgentIsiPad = (userAgent.indexOf("iPad") > -1);
var userAgentIsiPodTouch = (userAgent.indexOf("iPod Touch") > -1);
if (!userAgentIsiPhone && !userAgentIsiPad && !userAgentIsiPodTouch) {
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
} else {
var enrollmentUtils = require("/app/modules/enrollments/util/utils.js")["methods"];
var Handlebars = require("/lib/modules/handlebars/handlebars-v2.0.0.js")["Handlebars"];
var template = Handlebars.compile(enrollmentUtils.
getResource("/app/modules/enrollments/ios/config/ios-manifest-template.hbs"));
var iOSManifest = template({
"url" : mdmProps["device"]["ios"]["location"],
"bundleID" : mdmProps["device"]["ios"]["bundleID"],
"bundleVersion" : mdmProps["device"]["ios"]["version"],
"appName" : mdmProps["device"]["ios"]["appName"]
});
response.contentType = "application/xml";
response.content = iOSManifest;
}
%>

@ -0,0 +1,26 @@
<%
var HttpClient = Packages.org.apache.commons.httpclient.HttpClient;
var GetMethod = Packages.org.apache.commons.httpclient.methods.GetMethod;
var StringRequestEntity = Packages.org.apache.commons.httpclient.methods.StringRequestEntity;
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
var caURL = mdmProps["iOSConfigRoot"] + 'ca';
var client = new HttpClient();
var method = new GetMethod(caURL);
try {
client.executeMethod(method);
var status = method.getStatusCode();
if (status == 200) {
var stream = method.getResponseBody();
response.contentType = "application/x-x509-ca-cert";
var byteArrayInputStream = new Packages.java.io.ByteArrayInputStream(stream);
print(new Stream(byteArrayInputStream));
} else {
response.sendRedirect("/errorpage");
}
} catch (e) {
log.error("Error occurred when downloading CA " + e);
}
%>

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>url</key>
<string>{{url}}</string>
</dict>
</array>
<key>metadata</key>
<dict>
<key>bundle-identifier</key>
<string>{{bundleID}}</string>
<key>bundle-version</key>
<string>{{bundleVersion}}</string>
<key>kind</key>
<string>software</string>
<key>title</key>
<string>{{appName}}</string>
</dict>
</dict>
</array>
</dict>
</plist>

@ -0,0 +1,40 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var methods;
methods = function () {
var log = new Log("modules/enrollments/util/utils.js");
var publicMethods = {};
publicMethods.getResource = function (resourcePath) {
var file = new File(resourcePath);
var resource = null;
try {
file.open("r");
resource = file.readAll();
} catch (e) {
log.error("Error in reading resource");
} finally {
file.close();
}
return resource;
};
return publicMethods;
}();

@ -0,0 +1,96 @@
<%
/*
* 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("/app/modules/enrollments/windows/agent-controller.jag");
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
var UAParser = require("/app/modules/ua-parser.min.js")["UAParser"];
var tokenUtil = require("/app/modules/oauth/token-handlers.js")["handlers"];
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
var constants = require("/app/modules/constants.js");
var parser = new UAParser();
var userAgent = request.getHeader("User-Agent");
parser.setUA(userAgent);
parser.getResult();
var os = parser.getOS();
var platform = os.name;
if (platform != "Windows Phone") {
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
} else if (session.get("lastAccessedPage") != "login-agent") {
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
} else {
var username = request.getParameter("username");
var email = session.get("email");
var password = request.getParameter("password");
var domain = request.getParameter("domain");
if (!username || !email || !password) {
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
} else {
var authUrl = mdmProps["windowsConfigRoot"];
var fullyQualifiedUsername = username;
if(domain != null && domain != ''){
fullyQualifiedUsername = username + "@" + domain;
}
tokenUtil.setupTokenPairByPasswordGrantType(fullyQualifiedUsername, password);
var payload = {
"credentials": {
"username": username, "email": email,
"password": password, "token": getAccessToken()
}
};
serviceInvokers.XMLHttp.post(
authUrl,
stringify(payload),
function (restAPIResponse) {
var status = restAPIResponse["status"];
if (status == 200) {
session.put("authenticatedUser", username);
session.put("windowsBinaryToken", parse(xmlHttpRequest["responseText"]).UserToken);
response.sendRedirect(mdmProps["appContext"] + "enrollments/windows/license-agent");
} else if (status == 403) {
response.sendRedirect(mdmProps["appContext"] + "enrollments/windows/login-agent?error=auth-failed");
} else if (status == 409) {
response.sendRedirect(mdmProps["appContext"] + "enrollments/windows/login-agent?" +
"error=auth-failed&message=Provided Workplace email does not match with username. Please check.");
} else {
// one visible possibility would be server sending 500
response.sendRedirect(mdmProps["appContext"] + "enrollments/windows/login-agent?error=unexpected");
}
}
);
}
}
/**
* This method reads the token pair from the session and return the access token.
* If the token pair is not set in the session, this will return null.
*/
function getAccessToken() {
var tokenPair = parse(session.get(constants["TOKEN_PAIR"]));
if (tokenPair) {
return tokenPair["accessToken"];
} else {
return null;
}
};
%>

@ -0,0 +1,55 @@
<%
/*
* 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("/app/modules/enrollments/windows/agent-enroll.jag");
var UAParser = require("/app/modules/ua-parser.min.js")["UAParser"];
var parser = new UAParser();
var userAgent = request.getHeader("User-Agent");
parser.setUA(userAgent);
parser.getResult();
var os = parser.getOS();
var platform = os.name;
if (platform != "Windows Phone") {
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
} else if (session.get("lastAccessedPage") != "license-agent") {
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
} else {
var authenticatedUser = session.get("authenticatedUser");
if (!authenticatedUser) {
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
} else {
var enrollmentUtils = require("/modules/enrollments/util/utils.js")["methods"];
var Handlebars = require("/lib/handlebars-v2.0.0.js")["Handlebars"];
var template = Handlebars.compile(enrollmentUtils.
getResource("/modules/enrollments/windows/config/workplace-switch-request-template.hbs"));
var windowsWorkplaceAppID = session.get("windowsWorkplaceAppID");
var windowsBinaryToken = session.get("windowsBinaryToken");
var workplaceSwitchRequest = template({
"windowsWorkplaceAppID" : windowsWorkplaceAppID,
"windowsBinaryToken" : windowsBinaryToken
});
response.contentType = "text/html";
response.content = workplaceSwitchRequest;
}
}
%>

@ -0,0 +1,20 @@
<!DOCTYPE HTML>
<html>
<head>
<title>
Working...
</title>
<script>
function formSubmit() {
document.forms[0].submit();
}
window.onload=formSubmit;
</script>
</head>
<body>
<form method="post" action="{{windowsWorkplaceAppID}}">
<p><input type="hidden" name="wresult" value="{{windowsBinaryToken}}"/></p>
<input type="submit"/>
</form>
</body>
</html>

@ -0,0 +1,34 @@
/*
* 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 carbonModule = require("carbon");
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var carbonServer = new carbonModule.server.Server({
tenanted: true,
url: devicemgtProps["httpsURL"] + "/admin"
});
application.put("carbonServer", carbonServer);
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var utility = require("/app/modules/utility.js")["utility"];
var permissions = {
'/permission/admin/device-mgt/user': ['ui.execute'],
'/permission/admin/manage/api/subscribe': ['ui.execute']
};
//userModule.addRole("internal/devicemgt-user", ["admin"], permissions);

@ -0,0 +1,42 @@
/*
* 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 onSuccess;
var onFail;
(function () {
var log = new Log("/app/modules/login.js");
var constants = require("/app/modules/constants.js");
onSuccess = function (context) {
var utility = require("/app/modules/utility.js").utility;
var apiWrapperUtil = require("/app/modules/oauth/token-handlers.js")["handlers"];
if (context.input.samlToken) {
apiWrapperUtil.setupTokenPairBySamlGrantType(context.input.username, context.input.samlToken);
} else {
apiWrapperUtil.setupTokenPairByPasswordGrantType(context.input.username, context.input.password);
}
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var carbonServer = require("carbon").server;
(new carbonServer.Server({url: devicemgtProps["adminService"]}))
.login(context.input.username, context.input.password);
};
onFail = function (error) {
log.error(error.message);
}
})();

@ -0,0 +1,295 @@
/*
* 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 utils = function () {
var log = new Log("/app/modules/oauth/token-handler-utils.js");
var deviceMgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var constants = require("/app/modules/constants.js");
var carbon = require("carbon");
//noinspection JSUnresolvedVariable
var Base64 = Packages.org.apache.commons.codec.binary.Base64;
//noinspection JSUnresolvedVariable
var String = Packages.java.lang.String;
var publicMethods = {};
var privateMethods = {};
publicMethods["encode"] = function (payload) {
//noinspection JSUnresolvedFunction
return String(Base64.encodeBase64(String(payload).getBytes()));
};
publicMethods["decode"] = function (payload) {
//noinspection JSUnresolvedFunction
return String(Base64.decodeBase64(String(payload).getBytes()));
};
publicMethods["getDynamicClientAppCredentials"] = function () {
// setting up dynamic client application properties
var dcAppProperties = {
"applicationType": deviceMgtProps["oauthProvider"]["appRegistration"]["appType"],
"clientName": deviceMgtProps["oauthProvider"]["appRegistration"]["clientName"],
"owner": deviceMgtProps["oauthProvider"]["appRegistration"]["owner"],
"tokenScope": deviceMgtProps["oauthProvider"]["appRegistration"]["tokenScope"],
"grantType": deviceMgtProps["oauthProvider"]["appRegistration"]["grantType"],
"callbackUrl": deviceMgtProps["oauthProvider"]["appRegistration"]["callbackUrl"],
"saasApp" : true
};
// calling dynamic client app registration service endpoint
var requestURL = deviceMgtProps["oauthProvider"]["appRegistration"]
["dynamicClientAppRegistrationServiceURL"];
var requestPayload = dcAppProperties;
var xhr = new XMLHttpRequest();
xhr.open("POST", requestURL, false);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(stringify(requestPayload));
var dynamicClientAppCredentials = {};
if (xhr["status"] == 201 && xhr["responseText"]) {
var responsePayload = parse(xhr["responseText"]);
dynamicClientAppCredentials["clientId"] = responsePayload["client_id"];
dynamicClientAppCredentials["clientSecret"] = responsePayload["client_secret"];
} else if (xhr["status"] == 400) {
log.error("{/app/modules/oauth/token-handler-utils.js - getDynamicClientAppCredentials()} " +
"Bad request. Invalid data provided as dynamic client application properties.");
dynamicClientAppCredentials = null;
} else {
log.error("{/app/modules/oauth/token-handler-utils.js - getDynamicClientAppCredentials()} " +
"Error in retrieving dynamic client credentials.");
dynamicClientAppCredentials = null;
}
// returning dynamic client credentials
return dynamicClientAppCredentials;
};
publicMethods["getTenantBasedClientAppCredentials"] = function (username, jwtToken) {
if (!username || !jwtToken) {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
"based client app credentials. No username or jwt token is found " +
"as input - getTenantBasedClientAppCredentials(x, y)");
return null;
} else {
//noinspection JSUnresolvedFunction, JSUnresolvedVariable
var tenantDomain = carbon.server.tenantDomain({username: username});
if (!tenantDomain) {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
"based client application credentials. Unable to obtain a valid tenant domain for provided " +
"username - getTenantBasedClientAppCredentials(x, y)");
return null;
} else {
var cachedTenantBasedClientAppCredentials = privateMethods.
getCachedTenantBasedClientAppCredentials(tenantDomain);
if (cachedTenantBasedClientAppCredentials) {
return cachedTenantBasedClientAppCredentials;
} else {
// register a tenant based client app at API Manager
var applicationName = "webapp_" + tenantDomain;
var requestURL = deviceMgtProps["oauthProvider"]["appRegistration"]
["apiManagerClientAppRegistrationServiceURL"] +
"?tenantDomain=" + tenantDomain + "&applicationName=" + applicationName;
var xhr = new XMLHttpRequest();
xhr.open("POST", requestURL, false);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Authorization", "Bearer " + jwtToken);
xhr.send();
if (xhr["status"] == 201 && xhr["responseText"]) {
var responsePayload = parse(xhr["responseText"]);
var tenantBasedClientAppCredentials = {};
tenantBasedClientAppCredentials["clientId"] = responsePayload["client_id"];
tenantBasedClientAppCredentials["clientSecret"] = responsePayload["client_secret"];
privateMethods.
setCachedTenantBasedClientAppCredentials(tenantDomain, tenantBasedClientAppCredentials);
return tenantBasedClientAppCredentials;
} else {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
"based client application credentials from API " +
"Manager - getTenantBasedClientAppCredentials(x, y)");
return null;
}
}
}
}
};
privateMethods["setCachedTenantBasedClientAppCredentials"] = function (tenantDomain, clientAppCredentials) {
var cachedTenantBasedClientAppCredentialsMap = application.get(constants["CACHED_CREDENTIALS"]);
if (!cachedTenantBasedClientAppCredentialsMap) {
cachedTenantBasedClientAppCredentialsMap = {};
cachedTenantBasedClientAppCredentialsMap[tenantDomain] = clientAppCredentials;
application.put(constants["CACHED_CREDENTIALS"], cachedTenantBasedClientAppCredentialsMap);
} else if (!cachedTenantBasedClientAppCredentialsMap[tenantDomain]) {
cachedTenantBasedClientAppCredentialsMap[tenantDomain] = clientAppCredentials;
}
};
privateMethods["getCachedTenantBasedClientAppCredentials"] = function (tenantDomain) {
var cachedTenantBasedClientAppCredentialsMap = application.get(constants["CACHED_CREDENTIALS"]);
if (!cachedTenantBasedClientAppCredentialsMap ||
!cachedTenantBasedClientAppCredentialsMap[tenantDomain]) {
return null;
} else {
return cachedTenantBasedClientAppCredentialsMap[tenantDomain];
}
};
publicMethods["getTokenPairByPasswordGrantType"] = function (username, password, encodedClientAppCredentials, scopes) {
if (!username || !password || !encodedClientAppCredentials || !scopes) {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access token by password " +
"grant type. No username, password, encoded client app credentials or scopes are " +
"found - getTokenPairByPasswordGrantType(a, b, c, d)");
return null;
} else {
// calling oauth provider token service endpoint
var requestURL = deviceMgtProps["oauthProvider"]["tokenServiceURL"];
var requestPayload = "grant_type=password&username=" +
username + "&password=" + password + "&scope=" + scopes;
var xhr = new XMLHttpRequest();
xhr.open("POST", requestURL, false);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("Authorization", "Basic " + encodedClientAppCredentials);
xhr.send(requestPayload);
if (xhr["status"] == 200 && xhr["responseText"]) {
var responsePayload = parse(xhr["responseText"]);
var tokenData = {};
tokenData["accessToken"] = responsePayload["access_token"];
tokenData["refreshToken"] = responsePayload["refresh_token"];
tokenData["scopes"] = responsePayload["scope"];
return tokenData;
} else {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access token " +
"by password grant type - getTokenPairByPasswordGrantType(a, b, c, d)");
return null;
}
}
};
publicMethods["getTokenPairBySAMLGrantType"] = function (assertion, encodedClientAppCredentials, scopes) {
if (!assertion || !encodedClientAppCredentials || !scopes) {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access token by saml " +
"grant type. No assertion, encoded client app credentials or scopes are " +
"found - getTokenPairBySAMLGrantType(x, y, z)");
return null;
} else {
var assertionXML = publicMethods.decode(assertion);
/*
TODO: make assertion extraction with proper parsing.
Since Jaggery XML parser seem to add formatting which causes signature verification to fail.
*/
var assertionStartMarker = "<saml2:Assertion";
var assertionEndMarker = "<\/saml2:Assertion>";
var assertionStartIndex = assertionXML.indexOf(assertionStartMarker);
var assertionEndIndex = assertionXML.indexOf(assertionEndMarker);
var extractedAssertion;
if (assertionStartIndex == -1 || assertionEndIndex == -1) {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access " +
"token by saml grant type. Issue in assertion format - getTokenPairBySAMLGrantType(x, y, z)");
return null;
} else {
extractedAssertion = assertionXML.
substring(assertionStartIndex, assertionEndIndex) + assertionEndMarker;
var encodedAssertion = publicMethods.encode(extractedAssertion);
// calling oauth provider token service endpoint
var requestURL = deviceMgtProps["oauthProvider"]["tokenServiceURL"];
var requestPayload = "grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&" +
"assertion=" + encodeURIComponent(encodedAssertion) + "&scope=" + scopes;
var xhr = new XMLHttpRequest();
xhr.open("POST", requestURL, false);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("Authorization", "Basic " + encodedClientAppCredentials);
xhr.send(requestPayload);
if (xhr["status"] == 200 && xhr["responseText"]) {
var responsePayload = parse(xhr["responseText"]);
var tokenData = {};
tokenData["accessToken"] = responsePayload["access_token"];
tokenData["refreshToken"] = responsePayload["refresh_token"];
tokenData["scopes"] = responsePayload["scope"];
return tokenData;
} else {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access token " +
"by password grant type - getTokenPairBySAMLGrantType(x, y, z)");
return null;
}
}
}
};
publicMethods["getNewTokenPairByRefreshToken"] = function (refreshToken, encodedClientAppCredentials, scopes) {
if (!refreshToken || !encodedClientAppCredentials) {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving new access token " +
"by current refresh token. No refresh token or encoded client app credentials are " +
"found - getNewTokenPairByRefreshToken(x, y, z)");
return null;
} else {
var requestURL = deviceMgtProps["oauthProvider"]["tokenServiceURL"];
var requestPayload = "grant_type=refresh_token&refresh_token=" + refreshToken;
if (scopes) {
requestPayload = requestPayload + "&scope=" + scopes;
}
var xhr = new XMLHttpRequest();
xhr.open("POST", requestURL, false);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("Authorization", "Basic " + encodedClientAppCredentials);
xhr.send(requestPayload);
if (xhr["status"] == 200 && xhr["responseText"]) {
var responsePayload = parse(xhr["responseText"]);
var tokenPair = {};
tokenPair["accessToken"] = responsePayload["access_token"];
tokenPair["refreshToken"] = responsePayload["refresh_token"];
return tokenPair;
} else {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving new access token by " +
"current refresh token - getNewTokenPairByRefreshToken(x, y, z)");
return null;
}
}
};
publicMethods["getAccessTokenByJWTGrantType"] = function (clientAppCredentials) {
if (!clientAppCredentials) {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving new access token " +
"by current refresh token. No client app credentials are found " +
"as input - getAccessTokenByJWTGrantType(x)");
return null;
} else {
var JWTClientManagerServicePackagePath =
"org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService";
//noinspection JSUnresolvedFunction, JSUnresolvedVariable
var JWTClientManagerService = carbon.server.osgiService(JWTClientManagerServicePackagePath);
//noinspection JSUnresolvedFunction
var jwtClient = JWTClientManagerService.getJWTClient();
// returning access token by JWT grant type
return jwtClient.getAccessToken(clientAppCredentials["clientId"], clientAppCredentials["clientSecret"],
deviceMgtProps["oauthProvider"]["appRegistration"]["owner"], null)["accessToken"];
}
};
return publicMethods;
}();

@ -0,0 +1,171 @@
/*
* 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.
*/
/**
* -----------------------------------------------------
* Following module includes handlers
* at Jaggery Layer for handling OAuth tokens.
* -----------------------------------------------------
*/
var handlers = function () {
var log = new Log("/app/modules/oauth/token-handlers.js");
var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"];
var constants = require("/app/modules/constants.js");
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var publicMethods = {};
var privateMethods = {};
publicMethods["setupTokenPairByPasswordGrantType"] = function (username, password) {
if (!username || !password) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up access token pair by " +
"password grant type. Either username of logged in user, password or both are missing " +
"as input - setupTokenPairByPasswordGrantType(x, y)");
} else {
privateMethods.setUpEncodedTenantBasedClientAppCredentials(username);
var encodedClientAppCredentials = session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"]);
if (!encodedClientAppCredentials) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up access token pair by " +
"password grant type. Encoded client credentials are " +
"missing - setupTokenPairByPasswordGrantType(x, y)");
} else {
var tokenData;
// tokenPair will include current access token as well as current refresh token
var arrayOfScopes = devicemgtProps["scopes"];
var stringOfScopes = "";
arrayOfScopes.forEach(function (entry) {
stringOfScopes += entry + " ";
});
tokenData = tokenUtil.
getTokenPairByPasswordGrantType(username,
encodeURIComponent(password), encodedClientAppCredentials, stringOfScopes);
if (!tokenData) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up " +
"token pair by password grant type. Error in token " +
"retrieval - setupTokenPairByPasswordGrantType(x, y)");
} else {
var tokenPair = {};
tokenPair["accessToken"] = tokenData["accessToken"];
tokenPair["refreshToken"] = tokenData["refreshToken"];
// setting up token pair into session context as a string
session.put(constants["TOKEN_PAIR"], stringify(tokenPair));
var scopes = tokenData.scopes.split(" ");
// adding allowed scopes to the session
session.put(constants["ALLOWED_SCOPES"], scopes);
}
}
}
};
publicMethods["setupTokenPairBySamlGrantType"] = function (username, samlToken) {
if (!username || !samlToken) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up access token pair by " +
"saml grant type. Either username of logged in user, samlToken or both are missing " +
"as input - setupTokenPairByPasswordGrantType(x, y)");
} else {
privateMethods.setUpEncodedTenantBasedClientAppCredentials(username);
var encodedClientAppCredentials = session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"]);
if (!encodedClientAppCredentials) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up access token pair " +
"by saml grant type. Encoded client credentials are " +
"missing - setupTokenPairByPasswordGrantType(x, y)");
} else {
var tokenData;
// accessTokenPair will include current access token as well as current refresh token
tokenData = tokenUtil.
getTokenPairBySAMLGrantType(samlToken, encodedClientAppCredentials, "PRODUCTION");
if (!tokenData) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up token " +
"pair by password grant type. Error in token " +
"retrieval - setupTokenPairByPasswordGrantType(x, y)");
} else {
var tokenPair = {};
tokenPair["accessToken"] = tokenData["accessToken"];
tokenPair["refreshToken"] = tokenData["refreshToken"];
// setting up access token pair into session context as a string
session.put(constants["TOKEN_PAIR"], stringify(tokenPair));
var scopes = tokenData.scopes.split(" ");
// adding allowed scopes to the session
session.put(constants["ALLOWED_SCOPES"], scopes);
}
}
}
};
publicMethods["refreshTokenPair"] = function () {
var currentTokenPair = parse(session.get(constants["TOKEN_PAIR"]));
// currentTokenPair includes current access token as well as current refresh token
var encodedClientAppCredentials = session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"]);
if (!currentTokenPair || !encodedClientAppCredentials) {
throw new Error("{/app/modules/oauth/token-handlers.js} Error in refreshing tokens. Either the " +
"token pair, encoded client app credentials or both input are not found under " +
"session context - refreshTokenPair()");
} else {
var newTokenPair = tokenUtil.
getNewTokenPairByRefreshToken(currentTokenPair["refreshToken"], encodedClientAppCredentials);
if (!newTokenPair) {
log.error("{/app/modules/oauth/token-handlers.js} Error in refreshing token pair. " +
"Unable to update session context with new access token pair - refreshTokenPair()");
} else {
session.put(constants["TOKEN_PAIR"], stringify(newTokenPair));
}
}
};
privateMethods["setUpEncodedTenantBasedClientAppCredentials"] = function (username) {
if (!username) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up encoded tenant based " +
"client credentials to session context. No username of logged in user is found as " +
"input - setUpEncodedTenantBasedClientAppCredentials(x)");
} else {
var dynamicClientAppCredentials = tokenUtil.getDynamicClientAppCredentials();
if (!dynamicClientAppCredentials) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up encoded tenant based " +
"client credentials to session context as the server is unable to obtain " +
"dynamic client credentials - setUpEncodedTenantBasedClientAppCredentials(x)");
} else {
var jwtToken = tokenUtil.getAccessTokenByJWTGrantType(dynamicClientAppCredentials);
if (!jwtToken) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up encoded tenant based " +
"client credentials to session context as the server is unable to obtain " +
"a jwt token - setUpEncodedTenantBasedClientAppCredentials(x)");
} else {
var tenantBasedClientAppCredentials = tokenUtil.
getTenantBasedClientAppCredentials(username, jwtToken);
if (!tenantBasedClientAppCredentials) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up encoded tenant " +
"based client credentials to session context as the server is unable " +
"to obtain such credentials - setUpEncodedTenantBasedClientAppCredentials(x)");
} else {
var encodedTenantBasedClientAppCredentials =
tokenUtil.encode(tenantBasedClientAppCredentials["clientId"] + ":" +
tenantBasedClientAppCredentials["clientSecret"]);
// setting up encoded tenant based client credentials to session context.
session.put(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"],
encodedTenantBasedClientAppCredentials);
}
}
}
}
};
return publicMethods;
}();

@ -0,0 +1,376 @@
/*
* 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.
*/
/**
* ----------------------------------------------------------------------------
* Following module includes invokers
* at Jaggery Layer for calling Backend Services, protected by OAuth Tokens.
* These Services include both REST and SOAP Services.
* ----------------------------------------------------------------------------
*/
var invokers = function () {
var log = new Log("/app/modules/oauth/token-protected-service-invokers.js");
var publicXMLHTTPInvokers = {};
var publicHTTPClientInvokers = {};
var privateMethods = {};
var publicWSInvokers = {};
var TOKEN_EXPIRED = "Access token expired";
var TOKEN_INVALID = "Invalid input. Access token validation failed";
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var constants = require("/app/modules/constants.js");
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var tokenUtil = require("/app/modules/oauth/token-handlers.js")["handlers"];
/**
* This method reads the token pair from the session and return the access token.
* If the token pair is not set in the session, this will return null.
*/
privateMethods.getAccessToken = function () {
var tokenPair = parse(session.get(constants["TOKEN_PAIR"]));
if (tokenPair) {
return tokenPair["accessToken"];
} else {
return null;
}
};
/**
* ---------------------------------------------------------------------------
* Start of XML-HTTP-REQUEST based Interceptor implementations
* ---------------------------------------------------------------------------
*/
/**
* This method add Oauth authentication header to outgoing XML-HTTP Requests if Oauth authentication is enabled.
* @param httpMethod HTTP request type.
* @param requestPayload payload/data if exists which is needed to be send.
* @param endpoint Backend REST API url.
* @param responseCallback a function to be called with response retrieved.
* @param count a counter which hold the number of recursive execution
*/
privateMethods["execute"] = function (httpMethod, requestPayload, endpoint, responseCallback, count) {
var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open(httpMethod, endpoint);
xmlHttpRequest.setRequestHeader(constants["CONTENT_TYPE_IDENTIFIER"], constants["APPLICATION_JSON"]);
xmlHttpRequest.setRequestHeader(constants["ACCEPT_IDENTIFIER"], constants["APPLICATION_JSON"]);
if (devicemgtProps["isOAuthEnabled"]) {
var accessToken = privateMethods.getAccessToken();
if (!accessToken) {
userModule.logout(function () {
response.sendRedirect(devicemgtProps["appContext"] + "login");
});
} else {
xmlHttpRequest.setRequestHeader(constants["AUTHORIZATION_HEADER"],
constants["BEARER_PREFIX"] + accessToken);
}
}
if (requestPayload) {
xmlHttpRequest.send(requestPayload);
} else {
xmlHttpRequest.send();
}
log.debug("Request : " + httpMethod + " " + endpoint);
log.debug("Request payload if any : " + stringify(requestPayload));
log.debug("Response status : " + xmlHttpRequest.status);
log.debug("Response payload if any : " + xmlHttpRequest.responseText);
if (xmlHttpRequest.status == 401 && (xmlHttpRequest.responseText == TOKEN_EXPIRED ||
xmlHttpRequest.responseText == TOKEN_INVALID ) && count < 5) {
tokenUtil.refreshTokenPair();
return privateMethods.execute(httpMethod, requestPayload, endpoint, responseCallback, ++count);
} else {
return responseCallback(xmlHttpRequest);
}
};
/**
* This method add Oauth authentication header to outgoing XML-HTTP Requests if Oauth authentication is enabled.
* @param httpMethod HTTP request type.
* @param requestPayload payload/data if exists which is needed to be send.
* @param endpoint Backend REST API url.
* @param responseCallback a function to be called with response retrieved.
*/
privateMethods["initiateXMLHTTPRequest"] = function (httpMethod, requestPayload, endpoint, responseCallback) {
return privateMethods.execute(httpMethod, requestPayload, endpoint, responseCallback, 0);
};
/**
* This method invokes return initiateXMLHttpRequest for get calls.
* @param endpoint Backend REST API url.
* @param responseCallback a function to be called with response retrieved.
*/
publicXMLHTTPInvokers["get"] = function (endpoint, responseCallback) {
var requestPayload = null;
return privateMethods.initiateXMLHTTPRequest(constants["HTTP_GET"], requestPayload, endpoint, responseCallback);
};
/**
* This method invokes return initiateXMLHttpRequest for post calls.
* @param endpoint Backend REST API url.
* @param requestPayload payload/data if exists which is needed to be send.
* @param responseCallback a function to be called with response retrieved.
*/
publicXMLHTTPInvokers["post"] = function (endpoint, requestPayload, responseCallback) {
return privateMethods.initiateXMLHTTPRequest(constants["HTTP_POST"], requestPayload, endpoint, responseCallback);
};
/**
* This method invokes return initiateXMLHttpRequest for put calls.
* @param endpoint Backend REST API url.
* @param requestPayload payload/data if exists which is needed to be send.
* @param responseCallback a function to be called with response retrieved.
*/
publicXMLHTTPInvokers["put"] = function (endpoint, requestPayload, responseCallback) {
return privateMethods.initiateXMLHTTPRequest(constants["HTTP_PUT"], requestPayload, endpoint, responseCallback);
};
/**
* This method invokes return initiateXMLHttpRequest for delete calls.
* @param endpoint Backend REST API url.
* @param responseCallback a function to be called with response retrieved.
*/
publicXMLHTTPInvokers["delete"] = function (endpoint, responseCallback) {
var requestPayload = null;
return privateMethods.initiateXMLHTTPRequest(constants["HTTP_DELETE"], requestPayload, endpoint, responseCallback);
};
/**
* ---------------------------------------------------------------------------
* Start of WS-REQUEST based Interceptor implementations
* ---------------------------------------------------------------------------
*/
/**
* This method add Oauth authentication header to outgoing WS Requests if Oauth authentication is enabled.
* @param action
* @param endpoint service end point to be triggered.
* @param payload soap payload which need to be send.
* @param successCallback a function to be called if the respond if successful.
* @param errorCallback a function to be called if en error is reserved.
* @param soapVersion soapVersion which need to used.
*/
privateMethods["initiateWSRequest"] = function (action, endpoint, successCallback,
errorCallback, soapVersion, payload) {
var ws = require("ws");
//noinspection JSUnresolvedFunction
var wsRequest = new ws.WSRequest();
var options = [];
if (devicemgtProps["isOAuthEnabled"]) {
var accessToken = privateMethods.getAccessToken();
if (accessToken) {
var authenticationHeaderName = String(constants["AUTHORIZATION_HEADER"]);
var authenticationHeaderValue = String(constants["BEARER_PREFIX"] + accessToken);
var headers = [];
var oAuthAuthenticationData = {};
oAuthAuthenticationData.name = authenticationHeaderName;
oAuthAuthenticationData.value = authenticationHeaderValue;
headers.push(oAuthAuthenticationData);
options.HTTPHeaders = headers;
} else {
response.sendRedirect(devicemgtProps["appContext"] + "login");
}
}
options.useSOAP = soapVersion;
options.useWSA = constants["WEB_SERVICE_ADDRESSING_VERSION"];
options.action = action;
var wsResponse;
try {
wsRequest.open(options, endpoint, false);
if (payload) {
wsRequest.send(payload);
} else {
wsRequest.send();
}
wsResponse = wsRequest.responseE4X;
} catch (e) {
return errorCallback(e);
}
return successCallback(wsResponse);
};
/**
* This method invokes return initiateWSRequest for soap calls.
* @param action describes particular soap action.
* @param requestPayload SOAP request payload which is needed to be send.
* @param endpoint service end point to be triggered.
* @param successCallback a function to be called if the respond if successful.
* @param errorCallback a function to be called if en error is reserved.
* @param soapVersion soapVersion which need to used.
*/
publicWSInvokers["soapRequest"] = function (action, requestPayload, endpoint,
successCallback, errorCallback, soapVersion) {
return privateMethods.initiateWSRequest(action, endpoint, successCallback,
errorCallback, soapVersion, requestPayload);
};
/**
* ---------------------------------------------------------------------------
* Start of HTTP-CLIENT-REQUEST based Interceptor implementations
* ---------------------------------------------------------------------------
*/
/**
* This method add Oauth authentication header to outgoing HTTPClient Requests if Oauth authentication is enabled.
* @param method HTTP request type.
* @param url target url.
* @param payload payload/data which need to be send.
* @param successCallback a function to be called if the respond if successful.
* @param errorCallback a function to be called if en error is reserved.
*/
privateMethods["initiateHTTPClientRequest"] = function (method, url, successCallback, errorCallback, payload) {
//noinspection JSUnresolvedVariable
var HttpClient = Packages.org.apache.commons.httpclient.HttpClient;
var httpMethodObject;
switch (method) {
case constants["HTTP_GET"]:
//noinspection JSUnresolvedVariable
var GetMethod = Packages.org.apache.commons.httpclient.methods.GetMethod;
httpMethodObject = new GetMethod(url);
break;
case constants["HTTP_POST"]:
//noinspection JSUnresolvedVariable
var PostMethod = Packages.org.apache.commons.httpclient.methods.PostMethod;
httpMethodObject = new PostMethod(url);
break;
case constants["HTTP_PUT"]:
//noinspection JSUnresolvedVariable
var PutMethod = Packages.org.apache.commons.httpclient.methods.PutMethod;
httpMethodObject = new PutMethod(url);
break;
case constants["HTTP_DELETE"]:
//noinspection JSUnresolvedVariable
var DeleteMethod = Packages.org.apache.commons.httpclient.methods.DeleteMethod;
httpMethodObject = new DeleteMethod(url);
break;
default:
//noinspection JSUnresolvedFunction
throw new IllegalArgumentException("Invalid HTTP request method: " + method);
}
//noinspection JSUnresolvedVariable
var Header = Packages.org.apache.commons.httpclient.Header;
var header = new Header();
header.setName(constants["CONTENT_TYPE_IDENTIFIER"]);
header.setValue(constants["APPLICATION_JSON"]);
//noinspection JSUnresolvedFunction
httpMethodObject.addRequestHeader(header);
header = new Header();
header.setName(constants["ACCEPT_IDENTIFIER"]);
header.setValue(constants["APPLICATION_JSON"]);
//noinspection JSUnresolvedFunction
httpMethodObject.addRequestHeader(header);
if (devicemgtProps["isOAuthEnabled"]) {
var accessToken = privateMethods.getAccessToken();
if (accessToken) {
header = new Header();
header.setName(constants["AUTHORIZATION_HEADER"]);
header.setValue(constants["BEARER_PREFIX"] + accessToken);
//noinspection JSUnresolvedFunction
httpMethodObject.addRequestHeader(header);
} else {
response.sendRedirect(devicemgtProps["appContext"] + "login");
}
}
//noinspection JSUnresolvedFunction
var stringRequestEntity = new StringRequestEntity(stringify(payload));
//noinspection JSUnresolvedFunction
httpMethodObject.setRequestEntity(stringRequestEntity);
var client = new HttpClient();
try {
//noinspection JSUnresolvedFunction
client.executeMethod(httpMethodObject);
//noinspection JSUnresolvedFunction
var status = httpMethodObject.getStatusCode();
if (status == 200) {
//noinspection JSUnresolvedFunction
return successCallback(httpMethodObject.getResponseBody());
} else {
//noinspection JSUnresolvedFunction
return errorCallback(httpMethodObject.getResponseBody());
}
} catch (e) {
return errorCallback(response);
} finally {
//noinspection JSUnresolvedFunction
method.releaseConnection();
}
};
/**
* This method invokes return initiateHTTPClientRequest for get calls.
* @param url target url.
* @param successCallback a function to be called if the respond if successful.
* @param errorCallback a function to be called if en error is reserved.
*/
publicHTTPClientInvokers["get"] = function (url, successCallback, errorCallback) {
var requestPayload = null;
return privateMethods.
initiateHTTPClientRequest(constants["HTTP_GET"], url, successCallback, errorCallback, requestPayload);
};
/**
* This method invokes return initiateHTTPClientRequest for post calls.
* @param url target url.
* @param payload payload/data which need to be send.
* @param successCallback a function to be called if the respond if successful.
* @param errorCallback a function to be called if en error is reserved.
*/
publicHTTPClientInvokers["post"] = function (url, payload, successCallback, errorCallback) {
return privateMethods.
initiateHTTPClientRequest(constants["HTTP_POST"], url, successCallback, errorCallback, payload);
};
/**
* This method invokes return initiateHTTPClientRequest for put calls.
* @param url target url.
* @param payload payload/data which need to be send.
* @param successCallback a function to be called if the respond if successful.
* @param errorCallback a function to be called if en error is reserved.
*/
publicHTTPClientInvokers["put"] = function (url, payload, successCallback, errorCallback) {
return privateMethods.
initiateHTTPClientRequest(constants["HTTP_PUT"], url, successCallback, errorCallback, payload);
};
/**
* This method invokes return initiateHTTPClientRequest for delete calls.
* @param url target url.
* @param successCallback a function to be called if the respond if successful.
* @param errorCallback a function to be called if en error is reserved.
*/
publicHTTPClientInvokers["delete"] = function (url, successCallback, errorCallback) {
var requestPayload = null;
return privateMethods.
initiateHTTPClientRequest(constants["HTTP_DELETE"], url, successCallback, errorCallback, requestPayload);
};
var publicMethods = {};
publicMethods.XMLHttp = publicXMLHTTPInvokers;
publicMethods.WS = publicWSInvokers;
publicMethods.HttpClient = publicHTTPClientInvokers;
return publicMethods;
}();

@ -0,0 +1,140 @@
/*
* 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 utility;
utility = function () {
var constants = require('/app/modules/constants.js');
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var log = new Log("/app/modules/utility.js");
var JavaClass = Packages.java.lang.Class;
var PrivilegedCarbonContext = Packages.org.wso2.carbon.context.PrivilegedCarbonContext;
var getOsgiService = function (className) {
return PrivilegedCarbonContext.getThreadLocalCarbonContext().getOSGiService(JavaClass.forName(className));
};
var deviceTypeConfigMap = {};
var publicMethods = {};
publicMethods.startTenantFlow = function (userInfo) {
var context, carbon = require('carbon');
PrivilegedCarbonContext.startTenantFlow();
context = PrivilegedCarbonContext.getThreadLocalCarbonContext();
context.setTenantDomain(carbon.server.tenantDomain({
tenantId: userInfo.tenantId
}));
context.setTenantId(userInfo.tenantId);
context.setUsername(userInfo.username || null);
};
publicMethods.endTenantFlow = function () {
PrivilegedCarbonContext.endTenantFlow();
};
publicMethods.getDeviceManagementService = function () {
return getOsgiService('org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService');
};
publicMethods.getUserManagementService = function () {
return getOsgiService("org.wso2.carbon.device.mgt.user.core.UserManager");
};
publicMethods.getPolicyManagementService = function () {
return getOsgiService("org.wso2.carbon.policy.mgt.core.PolicyManagerService");
};
publicMethods.getIoTServerConfig = function (configName) {
var path = "/config/iot-config.json";
var file = new File(path);
try {
file.open("r");
var content = file.readAll();
} catch (err) {
log.error("Error while reading IoT server config file `" + path + "`: " + err);
} finally {
file.close();
}
var json = parse(content);
return json[configName];
};
publicMethods.getDeviceTypeConfig = function (deviceType) {
var unitName = publicMethods.getTenantedDeviceUnitName(deviceType, "type-view");
if (deviceType in deviceTypeConfigMap) {
return deviceTypeConfigMap[deviceType];
}
var deviceTypeConfig;
var deviceTypeConfigFile = new File("/app/units/" + unitName + "/private/config.json");
if (deviceTypeConfigFile.isExists()) {
try {
deviceTypeConfigFile.open("r");
deviceTypeConfig = parse(deviceTypeConfigFile.readAll());
} catch (err) {
log.error("Error while reading device config file for `" + deviceType + "`: " + err);
} finally {
deviceTypeConfigFile.close();
}
}
deviceTypeConfigMap[deviceType] = deviceTypeConfig;
return deviceTypeConfig;
};
publicMethods.getOperationIcon = function (deviceType, operation) {
var unitName = publicMethods.getTenantedDeviceUnitName(deviceType, "type-view");
var iconPath = "/app/units/" + unitName + "/public/images/operations/" + operation + ".png";
var icon = new File(iconPath);
if (icon.isExists()) {
return devicemgtProps["appContext"] + "public/" + unitName + "/images/operations/" + operation + ".png";
} else {
return null;
}
};
publicMethods.getDeviceThumb = function (deviceType) {
var unitName = publicMethods.getTenantedDeviceUnitName(deviceType, "type-view");
var iconPath = "/app/units/" + unitName + "/public/images/thumb.png";
var icon = new File(iconPath);
if (icon.isExists()) {
return devicemgtProps["appContext"] + "public/" + unitName + "/images/thumb.png";
} else {
return null;
}
};
publicMethods.getTenantedDeviceUnitName = function (deviceType, unitPostfix) {
var user = session.get(constants.USER_SESSION_KEY);
if (!user) {
log.error("User object was not found in the session");
throw constants.ERRORS.USER_NOT_FOUND;
}
var unitName = user.domain + ".cdmf.unit.device.type." + deviceType + "." + unitPostfix;
if (new File("/app/units/" + unitName).isExists()) {
return unitName;
}
unitName = "cdmf.unit.device.type." + deviceType + "." + unitPostfix;
if (new File("/app/units/" + unitName).isExists()) {
return unitName;
}
return null;
};
return publicMethods;
}();

@ -0,0 +1,47 @@
{{!-- 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. --}}
{{!-- defining controlled access parameters --}}
{{#zone "accessControl"}}
{{
unit "mdm.unit.enrollments.access-control"
allowedPlatform = "Android"
currentPage = "download-agent"
}}
{{/zone}}
{{!-- Inputting content into defined zones in enrollment layout --}}
{{unit "mdm.unit.ui.title" pageTitle = "Android Enrollment | Download and Install Agent"}}
{{#zone "headerTitle"}}
Android Enrollment
{{/zone}}
{{#zone "content"}}
{{
unit "mdm.unit.wizard-stepper"
steps = "Download and Install Agent"
currentStep = "Download and Install Agent"
currentStepIndex = 0
}}
<div class="row">
<div class="col-md-4 wr-text">
If you have not already enrolled this device with {{companyName}},
Download and install following EMM Agent to continue.
<div class="wr-buttons">
<a href="{{agentDownloadURL}}" class="btn-download-agent">Download EMM Agent</a>
</div>
</div>
</div>
{{/zone}}

@ -0,0 +1,36 @@
/*
* 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.page.enrollments.android.agent.download");
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
var viewModel = {};
// setting android agent download URL
// Needs host=>http:9763 since self-signed certificates won't allow downloads in android
//TODO: try to retrieve page name from UUF
viewModel.agentDownloadURL = mdmProps["generalConfig"]["host"] + mdmProps["appContext"] + "public/mdm.page.enrollments.android.download-agent/asset/" + mdmProps["androidAgentApp"];
var companyProps = session.get("COMPANY_DETAILS");
if (!companyProps) {
viewModel.companyName = mdmProps.generalConfig.companyName;
} else {
viewModel.companyName = companyProps.companyName;
}
return viewModel;
}

@ -0,0 +1,17 @@
{{!-- 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 page will route into relevant download url based on User-Agent --}}

@ -0,0 +1,39 @@
/*
* 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.page.enrollments.default");
var UAParser = require("/app/modules/ua-parser.min.js")["UAParser"];
var parser = new UAParser();
var userAgent = request.getHeader("User-Agent");
parser.setUA(userAgent);
parser.getResult();
var os = parser.getOS();
var platform = os.name;
if (platform == "Android") {
response.sendRedirect(context.app.context + "/enrollments/android/download-agent");
} else if (platform == "iOS") {
response.sendRedirect(context.app.context + "/enrollments/ios/download-agent");
} else if (platform == "Windows Phone") {
response.sendRedirect(context.app.context + "/enrollments/windows/invoke-agent");
} else {
response.sendRedirect(context.app.context + "/enrollments/error/unintentional-request");
}
}

@ -0,0 +1,33 @@
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
WSO2 Inc. licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file except
in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
either express or implied. See the License for the
specific language governing permissions and limitations
under the License. --}}
{{!-- Inputting content into defined zones in enrollment layout --}}
{{unit "mdm.unit.ui.title" pageTitle="Device Enrollment"}}
{{#zone "headerTitle"}}
Unintentional Request
{{/zone}}
{{#zone "content"}}
<div class="wr-head">
<h3>Possible Causes :</h3>
</div>
[1] You have tried making a request call intended to be made by a different Platform. <br />
[2] You have tried accessing enrollment steps out of order. <br />
<div class="row">
<div class="container col-md-4 wr-buttons">
<a href="{{@app.context}}/enrollment" class="btn-download-agent">Redirect</a>
</div>
</div>
{{/zone}}

@ -0,0 +1,34 @@
{{!-- 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. --}}
{{!-- Inputting content into defined zones in enrollment layout --}}
{{unit "mdm.unit.ui.title" pageTitle="iOS Enrollment | Certificate Download Failure"}}
{{#zone "headerTitle"}}
iOS Certificate Download Failure
{{/zone}}
{{#zone "content"}}
<div class="wr-head">
<h3>Possible Causes :</h3>
</div>
[1] Network Issue. <br/>
[2] Bad Request Call to Server. <br/>
[3] Internal Server Error. <br/>
<div class="row">
<div class="container col-md-4 wr-buttons">
<a href="{{@app.context}}/enrollment" class="btn-download-agent">Redirect</a>
</div>
</div>
{{/zone}}

@ -0,0 +1,6 @@
{
"version": "1.0.0",
"uri": "/enrollments/error/ios/certificate-download-failure",
"layout": "mdm.layout.enrollment",
"isAnonymous": true
}

@ -0,0 +1,55 @@
{{!-- 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. --}}
{{!-- defining controlled access parameters --}}
{{#zone "accessControl"}}
{{
unit "mdm.unit.enrollments.access-control"
allowedPlatform = "iOS"
currentPage = "download-agent"
nextPage = "login-agent"
}}
{{/zone}}
{{!-- Inputting content into defined zones in enrollment layout --}}
{{unit "mdm.unit.ui.title" pageTitle="iOS Enrollment | Install Certificate and Agent"}}
{{#zone "headerTitle"}}
iOS Enrollment
{{/zone}}
{{#zone "content"}}
{{
unit "mdm.unit.wizard-stepper"
steps = "Install Certificate and Agent,
Login to Enterprise Mobility Manager,
Accept End User License Agreement"
currentStep = "Install Certificate and Agent"
currentStepIndex = 0
}}
<div class="row">
<div class="col-md-4 wr-text">
If you have not already enrolled this device with {{companyName}},
Install following EMM Certificate and Agent to continue.
<div class="wr-buttons">
<a href="{{emmCertificateDownloadURL}}" class="btn-download-agent">Install EMM Certificate</a>
</div>
<br class="c-both" />
Also note : EMM certificate should be first installed on the device for a
successful installation of the agent.
<div class="wr-buttons">
<a href="{{agentDownloadURL}}" class="btn-download-agent">Install EMM Agent</a>
</div>
</div>
</div>
{{/zone}}

@ -0,0 +1,37 @@
/*
* 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("asset-download-agent-ios-unit");
log.debug("calling asset-download-agent-ios-unit backend js");
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
var viewModel = {};
// setting iOS certificate download URL
viewModel.emmCertificateDownloadURL = context.app.context + "/enrollment/ios/download-certificate";
// setting iOS agent download URL
viewModel.agentDownloadURL = "itms-services://?action=download-manifest&url=" +
mdmProps["httpsURL"] + context.app.context + "/enrollment/ios/download-agent";
var companyProps = session.get("COMPANY_DETAILS");
if (!companyProps) {
viewModel.companyName = mdmProps.generalConfig.companyName;
} else {
viewModel.companyName = companyProps.companyName;
}
return viewModel;
}

@ -0,0 +1,59 @@
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
WSO2 Inc. licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file except
in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
either express or implied. See the License for the
specific language governing permissions and limitations
under the License. --}}
{{!-- defining controlled access parameters --}}
{{#zone "accessControl"}}
{{
unit "mdm.unit.enrollments.access-control"
allowedPlatform = "iOS"
currentPage = "license-agent"
lastPage = "login-agent"
nextPage = "thank-you-agent"
}}
{{/zone}}
{{!-- Inputting content into defined zones in enrollment layout --}}
{{unit "mdm.unit.ui.title" pageTitle="iOS Enrollment | Accept End User License Agreement"}}
{{#zone "headerTitle"}}
iOS Enrollment
{{/zone}}
{{#zone "content"}}
{{
unit "mdm.unit.wizard-stepper"
steps = "Install Certificate and Agent,
Login to Enterprise Mobility Manager,
Accept End User License Agreement"
currentStep = "Accept End User License Agreement"
currentStepIndex = 2
}}
{{
unit "mdm.unit.enrollments.license-box"
platform = "ios"
languageCode = "en_US"
licenseAcceptActionURL = iosLicenseAcceptURL
}}
{{/zone}}
{{#zone "topJs"}}
<script type="text/javascript">
var contextPath = "{{@app.context}}";
</script>
{{/zone}}
{{#zone "bottomJs"}}
{{js "/js/enrollment-completion-checker-ios.js"}}
{{/zone}}

@ -0,0 +1,24 @@
/*
* 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 viewModel = {};
// setting iOS license download URL
viewModel.iosLicenseAcceptURL = context.app.context + "/enrollment/ios/enroll";
return viewModel;
}

@ -0,0 +1,6 @@
{
"version": "1.0.0",
"uri": "/enrollments/ios/license-agent",
"layout": "mdm.layout.enrollment",
"isAnonymous": true
}

@ -0,0 +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.
*/
$(document).ready(function () {
var iOSCheckUrl = contextPath + "/enrollment/ios/check";
setInterval(function () {
$.post(iOSCheckUrl, function (data, status) {
var parsedData = JSON.parse(data);
var deviceId = parsedData["deviceID"];
var refreshToken = parsedData["refreshToken"];
var accessToken = parsedData["accessToken"];
var clientCredentials = parsedData["clientCredentials"];
if (deviceId) {
window.location = contextPath + "/enrollments/ios/thank-you-agent?device-id=" + encodeURI(deviceId) +
"&accessToken=" + encodeURI(accessToken) + "&refreshToken=" + encodeURI(refreshToken)
+ "&clientCredentials=" + encodeURI(clientCredentials);
}
});
}, 1000);
});

@ -0,0 +1,45 @@
{{!-- 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. --}}
{{!-- defining controlled access parameters --}}
{{#zone "accessControl"}}
{{
unit "mdm.unit.enrollments.access-control"
allowedPlatform = "iOS"
currentPage = "login-agent"
lastPage = "download-agent"
nextPage = "license-agent"
}}
{{/zone}}
{{!-- Inputting content into defined zones in enrollment layout --}}
{{unit "mdm.unit.ui.title" pageTitle="iOS Enrollment | Login to Enterprise Mobility Manager"}}
{{#zone "headerTitle"}}
iOS Enrollment
{{/zone}}
{{#zone "content"}}
{{
unit "mdm.unit.wizard-stepper"
steps = "Install Certificate and Agent,
Login to Enterprise Mobility Manager,
Accept End User License Agreement"
currentStep = "Login to Enterprise Mobility Manager"
currentStepIndex = 1
}}
{{
unit "mdm.unit.enrollments.login-box"
loginActionURL = iosLoginActionURL
}}
{{/zone}}

@ -0,0 +1,24 @@
/*
* 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 viewModel = {};
// setting iOS login URL
viewModel.iosLoginActionURL = context.app.context + "/enrollment/ios/login";
return viewModel;
}

@ -0,0 +1,6 @@
{
"version": "1.0.0",
"uri": "/enrollments/ios/login-agent",
"layout": "mdm.layout.enrollment",
"isAnonymous": true
}

@ -0,0 +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.
*/
var getParameterByName = function (name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
};
$(document).ready(function () {
setTimeout(function () {
var deviceID = getParameterByName("device-id");
var accessToken = getParameterByName("accessToken");
var refreshToken = getParameterByName("refreshToken");
var clientCredentials = getParameterByName("clientCredentials");
// window.location.href = "wso2agent://" + deviceID;
window.location.href = "wso2agent://" + deviceID + "?accessToken=" +
accessToken +"&refreshToken=" + refreshToken + "&clientCredentials=" + clientCredentials;
}, 1000);
});

@ -0,0 +1,52 @@
{{!-- 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. --}}
{{!-- defining controlled access parameters --}}
{{#zone "accessControl"}}
{{
unit "mdm.unit.enrollments.access-control"
allowedPlatform = "iOS"
currentPage = "thank-you-agent"
lastPage = "license-agent"
}}
{{/zone}}
{{!-- Inputting content into defined zones in enrollment layout --}}
{{unit "mdm.unit.ui.title" pageTitle="iOS Enrollment | Success Note"}}
{{#zone "headerTitle"}}
iOS Enrollment
{{/zone}}
{{#zone "content"}}
<div class="wr-head">
<h3>DEVICE ADDED</h3>
</div>
You have successfully enrolled your iOS device with {{companyName}}.
<br class="c-both" />
<br class="c-both" />
Device Owner : {{deviceOwner}}
<br class="c-both" />
<br class="c-both" />
Changes related to your company device policy will usually be applied
on your phone with in the next couple of minutes.
<br class="c-both" />
<br class="c-both" />
Thank You.
<br class="c-both" />
<a href="{{serverURL}}">{{companyName}}</a>
{{/zone}}
{{#zone "bottomJs"}}
{{js "/js/enrollment-success-note-ios.js"}}
{{/zone}}

@ -0,0 +1,31 @@
/*
* 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 viewModel = {};
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
viewModel.deviceOwner = session.get("enrolledUser");
viewModel.serverURL = mdmProps["httpsURL"] + context.app.context;
var companyProps = session.get("COMPANY_DETAILS");
if (!companyProps) {
viewModel.companyName = mdmProps.generalConfig.companyName;
} else {
viewModel.companyName = companyProps.companyName;
}
return viewModel;
}

@ -0,0 +1,6 @@
{
"version": "1.0.0",
"uri": "/enrollments/ios/thank-you-agent",
"layout": "mdm.layout.enrollment",
"isAnonymous": true
}

@ -0,0 +1,53 @@
{{!-- 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. --}}
{{!-- defining controlled access parameters --}}
{{#zone "accessControl"}}
{{
unit "mdm.unit.enrollments.access-control"
allowedPlatform = "Windows Phone"
currentPage = "invoke-agent"
nextPage = "login-agent"
}}
{{/zone}}
{{!-- Inputting content into defined zones in enrollment layout --}}
{{unit "mdm.unit.ui.title" pageTitle="Windows Phone Enrollment | Start Workplace"}}
{{#zone "headerTitle"}}
Windows Phone Enrollment
{{/zone}}
{{#zone "content"}}
{{
unit "mdm.unit.wizard-stepper"
steps = "Start Workplace,
Login to Enterprise Mobility Manager,
Accept End User License Agreement"
currentStep = "Start Workplace"
currentStepIndex = 0
}}
Start the Workplace app to continue device enrollment.
<br class="c-both" />
<br class="c-both" />
Setting up a Workplace account with WSO2 Enterprise Mobility Manager
will offer you company policies, certificates and apps that help you connect
to your business.
<br class="c-both" />
<br class="c-both" />
<div class="row">
<div class="container col-md-4 wr-buttons">
<a href="ms-settings-workplace://" class="btn-download-agent">Start Workplace</a>
</div>
</div>
{{/zone}}

@ -0,0 +1,46 @@
{{!-- 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. --}}
{{!-- defining controlled access parameters --}}
{{#zone "accessControl"}}
{{
unit "mdm.unit.enrollments.access-control"
allowedPlatform = "Windows Phone"
currentPage = "license-agent"
lastPage = "login-agent"
}}
{{/zone}}
{{!-- Inputting content into defined zones in enrollment layout --}}
{{unit "mdm.unit.ui.title" pageTitle="Windows Phone Enrollment | Accept End User License Agreement"}}
{{#zone "headerTitle"}}
Windows Phone Enrollment
{{/zone}}
{{#zone "content"}}
{{
unit "mdm.unit.wizard-stepper"
steps = "Start Workplace,
Login to Enterprise Mobility Manager,
Accept End User License Agreement"
currentStep = "Accept End User License Agreement"
currentStepIndex = 2
}}
{{
unit "mdm.unit.enrollments.license-box"
platform = "windows"
languageCode = "en_US"
licenseAcceptActionURL = windowsLicenseAcceptURL
}}
{{/zone}}

@ -0,0 +1,24 @@
/*
* 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 viewModel = {};
// setting iOS license download URL
viewModel.windowsLicenseAcceptURL = context.app.context + "/enrollment/windows/enroll";
return viewModel;
}

@ -0,0 +1,6 @@
{
"version": "1.0.0",
"uri": "/enrollments/windows/license-agent",
"layout": "mdm.layout.enrollment",
"isAnonymous": true
}

@ -0,0 +1,45 @@
{{!-- 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. --}}
{{!-- defining controlled access parameters --}}
{{#zone "accessControl"}}
{{
unit "mdm.unit.enrollments.access-control"
allowedPlatform = "Windows Phone"
currentPage = "login-agent"
lastPage = "invoke-agent"
nextPage = "license-agent"
}}
{{/zone}}
{{!-- Inputting content into defined zones in enrollment layout --}}
{{unit "mdm.unit.ui.title" pageTitle="Windows Phone Enrollment | Login to Enterprise Mobility Manager"}}
{{#zone "headerTitle"}}
Windows Phone Enrollment
{{/zone}}
{{#zone "content"}}
{{
unit "mdm.unit.wizard-stepper"
steps = "Start Workplace,
Login to Enterprise Mobility Manager,
Accept End User License Agreement"
currentStep = "Login to Enterprise Mobility Manager"
currentStepIndex = 1
}}
{{
unit "mdm.unit.enrollments.login-box"
loginActionURL = windowsLoginActionURL
}}
{{/zone}}

@ -0,0 +1,50 @@
/*
* 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("agent-to-web-context-mapper-windows-unit backend js");
log.debug("calling agent-to-web-context-mapper-windows-unit");
var viewModel = {};
if (!(session.get("email") && session.get("windowsWorkplaceAppID"))) {
// if both email and windowsWorkplaceAppID session values are not set
// this means either shifting to the page from agent or directly accessing the page out-of-order
// checking if user is actually shifting to the page from agent
// login_hint passes the user email value entered in Windows workplace app
var userEmail = request.getParameter("login_hint");
// appru passes app ID of the Windows workplace app
var windowsWorkplaceAppID = request.getParameter("appru");
if (!userEmail || !windowsWorkplaceAppID) {
response.sendRedirect(context.app.context + "/enrollments/error/unintentional-request");
} else {
/* allowing to skip first step of windows enrollment by
setting session.put("lastAccessedPage", "invoke-agent")...
This update was proposed to overcome following problem:
First step of enrollment and second step of enrollment being linked with two sessions as
first step is initiated by Internet explorer and the second by an internal web-view */
session.put("lastAccessedPage", "invoke-agent");
session.put("email", userEmail);
session.put("windowsWorkplaceAppID", windowsWorkplaceAppID);
}
}
// setting windows login URL
viewModel.windowsLoginActionURL = context.app.context + "/enrollment/windows/login";
return viewModel;
}

@ -0,0 +1,6 @@
{
"version": "1.0.0",
"uri": "/enrollments/windows/login-agent",
"layout": "mdm.layout.enrollment",
"isAnonymous": true
}

@ -0,0 +1,32 @@
{{!-- 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. --}}
{{!-- Inputting content into defined zones in enrollment layout --}}
{{unit "mdm.unit.ui.title" pageTitle="Page Error"}}
{{#zone "headerTitle"}}
404 - Resource Not Found
{{/zone}}
{{#zone "content"}}
<div class="wr-head">
<h3>Possible Causes :</h3>
</div>
You are seen this page since the resource you are trying to access is not available.<br/>
<div class="row">
<div class="container col-md-4 wr-buttons">
<a href="{{@app.context}}/enrollment" class="btn-download-agent">Goto Enroll Page</a>
</div>
</div>
{{/zone}}

@ -0,0 +1,15 @@
{{!-- 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. --}}

@ -0,0 +1,79 @@
/*
* 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("enrollment-access-control-unit backend js");
log.debug("calling enrollment-access-control-unit");
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
var UAParser = require("/app/modules/ua-parser.min.js")["UAParser"];
var parser = new UAParser();
var userAgent = request.getHeader("User-Agent");
parser.setUA(userAgent);
parser.getResult();
var userAgentPlatform = parser.getOS()["name"];
if (userAgentPlatform != context.unit.params["allowedPlatform"]) {
// if userAgentPlatform is not allowed
log.error("platform not allowed");
response.sendRedirect(context.app.context + "/enrollments/error/unintentional-request");
} else {
var lastPage = context.unit.params["lastPage"];
var nextPage = context.unit.params["nextPage"];
var currentPage = context.unit.params["currentPage"];
// if userAgentPlatform is allowed,
// restricting unordered intermediate page access
if (lastPage && currentPage && nextPage) {
// meaning it's not first page, but a middle page
if (!session.get("lastAccessedPage")) {
// meaning a middle page is accessed at first
response.sendRedirect(context.app.context + "/enrollments/error/unintentional-request");
} else if (!(session.get("lastAccessedPage") == currentPage) &&
!(session.get("lastAccessedPage") == lastPage) &&
!(session.get("lastAccessedPage") == nextPage)) {
response.sendRedirect(context.app.context + "/enrollments/error/unintentional-request");
} else if (currentPage) {
// if currentPage is set, update lastAccessedPage as currentPage
session.put("lastAccessedPage", currentPage);
}
} else if (lastPage && currentPage && !nextPage) {
// meaning it's not first page, not a middle page, but the last page in wizard
if (!session.get("lastAccessedPage")) {
// this means the last page is accessed at first
response.sendRedirect(context.app.context + "/enrollments/error/unintentional-request");
} else if (!(session.get("lastAccessedPage") == currentPage) &&
!(session.get("lastAccessedPage") == lastPage)) {
response.sendRedirect(context.app.context + "/enrollments/error/unintentional-request");
} else if (currentPage) {
// if currentPage is set, update lastAccessedPage as currentPage
session.put("lastAccessedPage", currentPage);
}
} else if (currentPage) {
// meaning it's the first page
// if currentPage is set, update lastAccessedPage as currentPage
session.put("lastAccessedPage", currentPage);
}
}
if (log.isDebugEnabled()) {
log.debug("last-accessed-page = " + session.get("lastAccessedPage") +
" : " + "session-id = " + session.getId());
}
return context;
}

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

Loading…
Cancel
Save