diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/assembly/src.xml b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/assembly/src.xml
index 2797034e0..a73a3edaa 100644
--- a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/assembly/src.xml
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/assembly/src.xml
@@ -29,7 +29,12 @@
${basedir}/src/main/resources/jaggeryapps/devicemgt
- /
+ /devicemgt
+ true
+
+
+ ${basedir}/src/main/resources/jaggeryapps/emm-web-agent
+ /emm-web-agent
true
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/api/invoker-api.jag b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/api/invoker-api.jag
new file mode 100644
index 000000000..191614376
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/api/invoker-api.jag
@@ -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);
+ }
+}
+%>
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/api/user-api.jag b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/api/user-api.jag
new file mode 100644
index 000000000..b038e66ad
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/api/user-api.jag
@@ -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);
+}
+%>
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/conf/app-conf.json b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/conf/app-conf.json
new file mode 100644
index 000000000..5091d70b9
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/conf/app-conf.json
@@ -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"
+ }
+}
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/conf/config.json b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/conf/config.json
new file mode 100644
index 000000000..67df3a79d
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/conf/config.json
@@ -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%/ios/",
+ "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" : "%https.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"]
+}
\ No newline at end of file
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/layouts/mdm.layout.enrollment.hbs b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/layouts/mdm.layout.enrollment.hbs
new file mode 100644
index 000000000..cee58594d
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/layouts/mdm.layout.enrollment.hbs
@@ -0,0 +1,67 @@
+{{!-- 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"~}}
+
+
+
+
+
+ {{defineZone "favicon"}}
+
+ {{defineZone "title"}}
+
+ {{defineZone "topCss"}}
+ {{defineZone "topJs"}}
+
+
+
+
+
+
+
{{defineZone "headerTitle"}}
+
+
+
+ {{defineZone "content"}}
+
+
+ {{!-- {{ defineZone "footer"}} --}}
+
+{{defineZone "bottomJs" }}
+
+
\ No newline at end of file
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/business-controllers/device.js b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/business-controllers/device.js
new file mode 100644
index 000000000..dbc76aabc
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/business-controllers/device.js
@@ -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;
+}();
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/business-controllers/group.js b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/business-controllers/group.js
new file mode 100644
index 000000000..02b2198b4
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/business-controllers/group.js
@@ -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));
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/business-controllers/operation.js b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/business-controllers/operation.js
new file mode 100644
index 000000000..e96ffcdec
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/business-controllers/operation.js
@@ -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;
+}();
\ No newline at end of file
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/business-controllers/policy.js b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/business-controllers/policy.js
new file mode 100644
index 000000000..00b82116c
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/business-controllers/policy.js
@@ -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;
+}();
\ No newline at end of file
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/business-controllers/user.js b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/business-controllers/user.js
new file mode 100644
index 000000000..93f76b3e8
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/business-controllers/user.js
@@ -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 = "";
+ 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;
+}();
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/conf-reader/main.js b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/conf-reader/main.js
new file mode 100644
index 000000000..f81849fe3
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/conf-reader/main.js
@@ -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;
+}();
\ No newline at end of file
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/conf-reader/pinch.min.js b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/conf-reader/pinch.min.js
new file mode 100644
index 000000000..5d22ca0eb
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/conf-reader/pinch.min.js
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 2011 František Hába
+*
+* 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
\ No newline at end of file
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/ios/agent-controller.jag b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/ios/agent-controller.jag
new file mode 100644
index 000000000..f6bafeacd
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/ios/agent-controller.jag
@@ -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");
+ }
+ }
+ );
+ }
+}
+%>
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/ios/agent-enroll.jag b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/ios/agent-enroll.jag
new file mode 100644
index 000000000..eb3e3acbc
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/ios/agent-enroll.jag
@@ -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();
+ }
+ }
+}
+%>
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/ios/agent.jag b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/ios/agent.jag
new file mode 100644
index 000000000..45a08c762
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/ios/agent.jag
@@ -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;
+}
+%>
\ No newline at end of file
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/ios/certificate.jag b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/ios/certificate.jag
new file mode 100644
index 000000000..d3cb1c5d6
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/ios/certificate.jag
@@ -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);
+}
+%>
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/ios/config/ios-manifest-template.hbs b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/ios/config/ios-manifest-template.hbs
new file mode 100644
index 000000000..37deaf50c
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/ios/config/ios-manifest-template.hbs
@@ -0,0 +1,31 @@
+
+
+
+
+ items
+
+
+ assets
+
+
+ kind
+ software-package
+ url
+ {{url}}
+
+
+ metadata
+
+ bundle-identifier
+ {{bundleID}}
+ bundle-version
+ {{bundleVersion}}
+ kind
+ software
+ title
+ {{appName}}
+
+
+
+
+
\ No newline at end of file
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/util/utils.js b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/util/utils.js
new file mode 100644
index 000000000..91175c764
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/util/utils.js
@@ -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;
+}();
\ No newline at end of file
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/windows/agent-controller.jag b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/windows/agent-controller.jag
new file mode 100644
index 000000000..f76bcf925
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/windows/agent-controller.jag
@@ -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;
+ }
+};
+
+%>
\ No newline at end of file
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/windows/agent-enroll.jag b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/windows/agent-enroll.jag
new file mode 100644
index 000000000..1ad693001
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/windows/agent-enroll.jag
@@ -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;
+ }
+}
+%>
\ No newline at end of file
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/windows/config/workplace-switch-request-template.hbs b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/windows/config/workplace-switch-request-template.hbs
new file mode 100644
index 000000000..8911383b5
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/enrollments/windows/config/workplace-switch-request-template.hbs
@@ -0,0 +1,20 @@
+
+
+
+
+ Working...
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/init.js b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/init.js
new file mode 100644
index 000000000..d9f442cdd
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/init.js
@@ -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);
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/login.js b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/login.js
new file mode 100644
index 000000000..87f840d3c
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/login.js
@@ -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);
+ }
+})();
diff --git a/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/oauth/token-handler-utils.js b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/oauth/token-handler-utils.js
new file mode 100644
index 000000000..2ed241d0d
--- /dev/null
+++ b/components/mobile-plugins/mobile-base-plugin/org.wso2.carbon.device.mgt.mobile.ui/src/main/resources/jaggeryapps/emm-web-agent/app/modules/oauth/token-handler-utils.js
@@ -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 = "
+ * Dual licensed under GPLv2 & MIT
+ */
+(function(window,undefined){"use strict";var LIBVERSION="0.7.3",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded";var util={extend:function(regexes,extensions){for(var i in extensions){if("browser cpu device engine os".indexOf(i)!==-1&&extensions[i].length%2===0){regexes[i]=extensions[i].concat(regexes[i])}}return regexes},has:function(str1,str2){if(typeof str1==="string"){return str2.toLowerCase().indexOf(str1.toLowerCase())!==-1}},lowerize:function(str){return str.toLowerCase()}};var mapper={rgx:function(){var result,i=0,j,k,p,q,matches,match,args=arguments;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){result[q[0]]=q[1].call(this,match)}else{result[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){result[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{result[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){result[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{result[q]=match?match:undefined}}}}i+=2}return result},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j