diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/common/PluginConstants.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/common/PluginConstants.java index e2959baf0..92573902d 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/common/PluginConstants.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/common/PluginConstants.java @@ -31,6 +31,8 @@ public final class PluginConstants { "org.wso2.carbon.device.mgt.mobile.windows.api.services.wstep.CertificateEnrollmentService"; public static final String CERTIFICATE_ENROLLMENT_POLICY_SERVICE_ENDPOINT = "org.wso2.carbon.device.mgt.mobile.windows.api.services.xcep.CertificateEnrollmentPolicyService"; + public static final String ENROLLMENT_SERVICE_ENDPOINT = + "org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.EnrollmentService"; //Services' target namespaces public static final String DISCOVERY_SERVICE_TARGET_NAMESPACE = @@ -81,10 +83,8 @@ public final class PluginConstants { "/ENROLLMENTSERVER/PolicyEnrollmentWebservice.svc"; public static final String CERTIFICATE_ENROLLMENT_SERVICE_URL = "/ENROLLMENTSERVER/DeviceEnrollmentWebservice.svc"; - public static final String ONPREMISE_CERTIFICATE_ENROLLMENT_POLICY = - "/ENROLLMENTSERVER/ONPREMISE/PolicyEnrollmentWebservice.svc"; - public static final String ONPREMISE_CERTIFICATE_ENROLLMENT_SERVICE_URL = - "/ENROLLMENTSERVER/ONPREMISE/DeviceEnrollmentWebservice.svc"; + public static final String ENROLLMENT_SERVICE_URL = + "/ENROLLMENTSERVER/Win10DeviceEnrollmentWebservice.svc"; public static final String WAB_URL = "/windows-web-agent/enrollments/windows/login-agent"; } @@ -125,7 +125,6 @@ public final class PluginConstants { "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#base64binary"; public static final String CA_CERT = "cacert"; public static final String X_509 = "X.509"; - public static final String PROPERTIES_XML = "properties.xml"; public static final String WAP_PROVISIONING_XML = "wap-provisioning.xml"; public static final String PROVIDER = "BC"; public static final String ALGORITHM = "SHA1withRSA"; @@ -153,6 +152,9 @@ public final class PluginConstants { public static final int DOMAIN_POSITION = 7; public static final String ENROLL_SUBDOMAIN = "https://EnterpriseEnrollment."; public static final String SYNCML_PROVISIONING_SERVICE_URL = "/Syncml/initialquery"; + public static final String SYNCML_PROVISIONING_WIN10_SERVICE_URL = "/devicemgt"; + public static final String ENROLLMENT_DISPOSITION_MESSAGE = "http://schemas.microsoft.com/windows/pki/" + + "2009/01/enrollment"; } /** @@ -205,6 +207,18 @@ public final class PluginConstants { public static final String MANUFACTURER = "MANUFACTURER"; public static final String LANGUAGE = "LANGUAGE"; public static final String RESOLUTION = "RESOLUTION"; + + // windows 10 codes + public static final String TOTAL_RAM = "TOTAL_RAM";// available ram in MB + public static final String TOTAL_STORAGE = "TOTAL_STORAGE"; + public static final String OS_PLATFORM = "OS_PLATFORM"; + public static final String DEVICE_TYPE = "DEVICE_TYPE"; + public static final String BATTERY_QUERY = "BATTERY_QUERY"; + public static final String BATTERY_STATUS = "BATTERY_STATUS"; + public static final String BATTERY_CHARGE_REMAINING = "BATTERY_CHARGE_REMAINING"; + public static final String BATTERY_ESTIMATED_RUNTIME = "BATTERY_ESTIMATED_RUNTIME"; + public static final String MOBILE_ID = "MOBILE_ID"; + } /** @@ -252,6 +266,7 @@ public final class PluginConstants { public static final String ENCRYPT_STORAGE_STATUS = "ENCRYPT_STORAGE_STATUS"; public static final String DEVICE_PASSWORD_STATUS = "DEVICE_PASSWORD_STATUS"; public static final String DEVICE_PASSCODE_DELETE = "DEVICE_PASSCODE_DELETE"; + public static final String DEVICE_INFO = "DEVICE_INFO"; } /** @@ -289,7 +304,6 @@ public final class PluginConstants { public static final String DEFAULT_AUTH_POLICY = "Federated"; } - /** * Policy Configuration related constants. */ @@ -311,4 +325,31 @@ public final class PluginConstants { public static final String MAX_CONNECTION_PER_HOST = "MaxConnectionsPerHost"; public static final String MAX_TOTAL_CONNECTIONS = "MaxTotalConnections"; } + + /** + * Windows version(8.1/10) related constants. + */ + public final class WindowsVersionProperties { + private WindowsVersionProperties() { + throw new AssertionError(); + } + public static final String REQUESTED_WIN10_VERSION = "3.0"; + public static final String REQUESTED_WIN81_VERSION = "2.0"; + } + + /** + * Windows enrollment property constants. + */ + + public final class WindowsEnrollmentProperties { + private WindowsEnrollmentProperties() { + throw new AssertionError(); + } + + public static final int WIN_DEVICE_ID = 12; + public static final int WIN_DEVICE_NAME = 2; + public static final int WIN_DEVICE_VERSION = 15; + public static final int WIN_DEVICE_IMEI = 3; + + } } diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/common/util/WindowsAPIUtils.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/common/util/WindowsAPIUtils.java index a20d9ba53..274c7ffae 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/common/util/WindowsAPIUtils.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/common/util/WindowsAPIUtils.java @@ -28,10 +28,13 @@ import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.InvalidDeviceException; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; +import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; +import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceDetailsMgtException; +import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; import org.wso2.carbon.device.mgt.mobile.windows.api.common.beans.ErrorResponse; @@ -222,4 +225,18 @@ public class WindowsAPIUtils { return null; } } + + /** + * This method is used to update Device Information. + * @param deviceId DeviceID to need to update. + * @param deviceInfo Device Info to be update/ + * @throws DeviceDetailsMgtException Error occurs while updating Device Info. + */ + public static void updateDeviceInfo(DeviceIdentifier deviceId, DeviceInfo deviceInfo) + throws DeviceDetailsMgtException { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + DeviceInformationManager informationManager = + (DeviceInformationManager) ctx.getOSGiService(DeviceInformationManager.class, null); + informationManager.addDeviceInfo(deviceId, deviceInfo); + } } diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/Constants.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/Constants.java index 0d9a40592..b68bca44c 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/Constants.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/Constants.java @@ -27,6 +27,7 @@ public class Constants { public static final String INITIAL_NONCE = "ZHVtbXk="; public static final String DISENROLL_ALERT_DATA = "1226"; public static final String INITIAL_ALERT_DATA = "1201"; + public static final String INITIAL_WIN10_ALERT_DATA = "1224"; public static final int EMPTY = 0; public static final String SYNCML_ROOT_ELEMENT_NAME = "SyncML"; diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/HeartBeatDeviceInfo.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/HeartBeatDeviceInfo.java new file mode 100644 index 000000000..2bbf1c08d --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/HeartBeatDeviceInfo.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.mobile.windows.api.operations.util; + +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; + +import java.util.ArrayList; +import java.util.List; + +public class HeartBeatDeviceInfo { + public List getDeviceInfo() { + + List deviceInfoOperations = new ArrayList<>(); + + Operation osVersion = new Operation(); + osVersion.setCode(PluginConstants.SyncML.SOFTWARE_VERSION); + deviceInfoOperations.add(osVersion); + + Operation imsi = new Operation(); + imsi.setCode(PluginConstants.SyncML.IMSI); + deviceInfoOperations.add(imsi); + + Operation imei = new Operation(); + imei.setCode(PluginConstants.SyncML.IMEI); + deviceInfoOperations.add(imei); + + Operation deviceID = new Operation(); + deviceID.setCode(PluginConstants.SyncML.DEV_ID); + deviceInfoOperations.add(deviceID); + + Operation manufacturer = new Operation(); + manufacturer.setCode(PluginConstants.SyncML.MANUFACTURER); + deviceInfoOperations.add(manufacturer); + + Operation model = new Operation(); + model.setCode(PluginConstants.SyncML.MODEL); + deviceInfoOperations.add(model); + + Operation language = new Operation(); + language.setCode(PluginConstants.SyncML.LANGUAGE); + deviceInfoOperations.add(language); + + Operation vendor = new Operation(); + vendor.setCode(PluginConstants.SyncML.VENDOR); + deviceInfoOperations.add(vendor); + + Operation macaddress = new Operation(); + macaddress.setCode(PluginConstants.SyncML.MAC_ADDRESS); + deviceInfoOperations.add(macaddress); + + Operation resolution = new Operation(); + resolution.setCode(PluginConstants.SyncML.RESOLUTION); + deviceInfoOperations.add(resolution); + + Operation deviceName = new Operation(); + deviceName.setCode(PluginConstants.SyncML.DEVICE_NAME); + deviceInfoOperations.add(deviceName); + + Operation totalRam = new Operation(); + totalRam.setCode(PluginConstants.SyncML.TOTAL_RAM); + deviceInfoOperations.add(totalRam); + + Operation availableStorage = new Operation(); + availableStorage.setCode(PluginConstants.SyncML.TOTAL_STORAGE); + deviceInfoOperations.add(availableStorage); + + Operation remainingBattery = new Operation(); + remainingBattery.setCode(PluginConstants.SyncML.BATTERY_CHARGE_REMAINING); + deviceInfoOperations.add(remainingBattery); + + return deviceInfoOperations; + } +} diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/OperationCode.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/OperationCode.java index 90a9327a8..8ba4b4416 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/OperationCode.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/OperationCode.java @@ -44,8 +44,19 @@ public class OperationCode { DEVICE_PASSWORD_STATUS("./Vendor/MSFT/PolicyManager/Device/DeviceLock/DevicePasswordEnabled"), DEVICE_PASSCODE_DELETE("./Vendor/MSFT/PolicyManager/My/DeviceLock"), LONGITUDE("./Vendor/MSFT/RemoteFind/Location/Longitude"), - LATITUDE("./Vendor/MSFT/RemoteFind/Location/Latitude"); - + LATITUDE("./Vendor/MSFT/RemoteFind/Location/Latitude"), + + // Windows10 operation codes + TOTAL_RAM("./DevDetail/Ext/Microsoft/TotalRAM"), + TOTAL_STORAGE("./DevDetail/Ext/Microsoft/TotalStorage"), + OS_PLATFORM("./DevDetail/Ext/Microsoft/OSPlatform"), + MOBILE_ID("./DevDetail/Ext/Microsoft/MobileID"), + DEVICE_TYPE("./DevDetail/DevTyp"), + BATTERY_QUERY("./Vendor/MSFT/DeviceStatus/Battery"), + BATTERY_STATUS("./Vendor/MSFT/DeviceStatus/Battery/Status"), + BATTERY_CHARGE_REMAINING("./Vendor/MSFT/DeviceStatus/Battery/EstimatedChargeRemaining"), + BATTERY_ESTIMATED_RUNTIME("./Vendor/MSFT/DeviceStatus/Battery/EstimatedRuntime"), + TEST("./Vendor/MSFT/DiagnosticLog/EtwLog/Collectors"); private final String code; Info(String code) { @@ -69,7 +80,18 @@ public class OperationCode { CAMERA_STATUS("./Vendor/MSFT/PolicyManager/Device/Camera/AllowCamera"), ENCRYPT_STORAGE_STATUS("./Vendor/MSFT/PolicyManager/Device/Security/RequireDeviceEncryption"), DEVICE_PASSWORD_ENABLE("./Vendor/MSFT/PolicyManager/My/DeviceLock/DevicePasswordEnabled"), - DEVICE_PASSCODE_DELETE("./Vendor/MSFT/PolicyManager/My/DeviceLock"); + DEVICE_PASSCODE_DELETE("./Vendor/MSFT/PolicyManager/My/DeviceLock"), + // Windows10 operation codes + TOTAL_RAM("./DevDetail/Ext/Microsoft/TotalRAM"), + TOTAL_STORAGE("./DevDetail/Ext/Microsoft/TotalStorage"), + OS_PLATFORM("./DevDetail/Ext/Microsoft/OSPlatform"), + MOBILE_ID("./DevDetail/Ext/Microsoft/MobileID"), + DEVICE_TYPE("./DevDetail/DevTyp"), + BATTERY_QUERY("./Vendor/MSFT/DeviceStatus/Battery"), + BATTERY_STATUS("./Vendor/MSFT/DeviceStatus/Battery/Status"), + BATTERY_CHARGE_REMAINING("./Vendor/MSFT/DeviceStatus/Battery/EstimatedChargeRemaining"), + BATTERY_ESTIMATED_RUNTIME("./Vendor/MSFT/DeviceStatus/Battery/EstimatedRuntime"), + TEST("./Vendor/MSFT/DiagnosticLog/EtwLog/Collectors"); private final String code; diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/OperationHandler.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/OperationHandler.java index 9c0417fb5..8b0db0222 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/OperationHandler.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/OperationHandler.java @@ -24,6 +24,7 @@ import org.json.JSONException; import org.json.JSONObject; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; import org.wso2.carbon.device.mgt.common.notification.mgt.Notification; import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementException; import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService; @@ -87,7 +88,7 @@ public class OperationHandler { Notification lockResetNotification = new Notification(); lockResetNotification.setOperationId(status.getCommandReference()); lockResetNotification.setStatus(String.valueOf(Notification.Status.NEW)); -// lockResetNotification.setDeviceIdentifier(deviceIdentifier); + lockResetNotification.setDescription( Constants.SyncMLResponseCodes.LOCK_RESET_NOTIFICATION); nmService.addNotification(deviceIdentifier, lockResetNotification); @@ -152,7 +153,6 @@ public class OperationHandler { Notification lockResetNotification = new Notification(); lockResetNotification.setOperationId(status.getCommandReference()); lockResetNotification.setStatus(String.valueOf(Notification.Status.NEW)); -// lockResetNotification.setDeviceIdentifier(deviceIdentifier); lockResetNotification.setDescription(Constants.SyncMLResponseCodes.LOCK_RESET_NOTIFICATION); nmService.addNotification(deviceIdentifier, lockResetNotification); @@ -166,7 +166,7 @@ public class OperationHandler { } } - /*** + /** * Update status of the ring operation. * * @param status Ring status of the device. @@ -194,7 +194,7 @@ public class OperationHandler { } } - /*** + /** * Update the status of the DataWipe operation. * * @param status Status of the data wipe. @@ -223,6 +223,23 @@ public class OperationHandler { } } + + public void updateDeviceInfoStatus(DeviceIdentifier deviceIdentifier) throws OperationManagementException { + List pendingDeviceInfoOperations; + try { + pendingDeviceInfoOperations = WindowsAPIUtils.getPendingOperations(deviceIdentifier); + } catch (DeviceManagementException e) { + throw new OperationManagementException("Error occurred while getting pending operations."); + } + for (Operation operation : pendingDeviceInfoOperations) { + if (PluginConstants.OperationCodes.DEVICE_INFO.equals(operation.getCode())) { + operation.setStatus(Operation.Status.COMPLETED); + updateStatus(deviceIdentifier.getId(), pendingDeviceInfoOperations); + } + } + } + + /** * Get pending operations. * @@ -232,13 +249,20 @@ public class OperationHandler { */ public List getPendingOperations(SyncmlDocument syncmlDocument) throws OperationManagementException, WindowsOperationException { - + SyncmlHeader syncmlHeader = syncmlDocument.getHeader(); + SyncmlBody syncmlBody = syncmlDocument.getBody(); List pendingOperations; - DeviceIdentifier deviceIdentifier = convertToDeviceIdentifierObject( - syncmlDocument.getHeader().getSource().getLocURI()); + DeviceIdentifier deviceIdentifier = convertToDeviceIdentifierObject(syncmlHeader.getSource().getLocURI()); + int sessionId = syncmlHeader.getSessionId(); + int msgId = syncmlHeader.getMsgID(); + if (!(PluginConstants.SyncML.SYNCML_FIRST_MESSAGE_ID == msgId && + PluginConstants.SyncML.SYNCML_FIRST_SESSION_ID == sessionId)) { + if ((syncmlBody.getResults() != null)) { + updateDeviceInfo(syncmlDocument); + } + } UpdateUriOperations(syncmlDocument); generateComplianceFeatureStatus(syncmlDocument); - pendingOperations = WindowsAPIUtils.getDeviceManagementService().getPendingOperations(deviceIdentifier); return pendingOperations; } @@ -487,4 +511,61 @@ public class OperationHandler { } } + + public void updateDeviceInfo(SyncmlDocument syncmlDocument) throws WindowsOperationException { + String softwareVersion; + String imsi; + String imei; + String model; + String vendor; + String totalRAM; + String deviceID = null; + String totalStorage; + + List deviceInformations = syncmlDocument.getBody().getResults().getItem(); + DeviceInfo deviceInfo = new DeviceInfo(); + for (ItemTag item : deviceInformations) { + String source = item.getSource().getLocURI(); + if (OperationCode.Info.SOFTWARE_VERSION.getCode().equals(source)) { + softwareVersion = item.getData(); + deviceInfo.setOsVersion(softwareVersion); + } + if (OperationCode.Info.IMSI.getCode().equals(source)) { + imsi = item.getData(); + deviceInfo.setIMSI(imsi); + } + if (OperationCode.Info.IMEI.getCode().equals(source)) { + imei = item.getData(); + deviceInfo.setIMEI(imei); + } + if (OperationCode.Info.DEVICE_MODEL.getCode().equals(source)) { + model = item.getData(); + deviceInfo.setDeviceModel(model); + } + if (OperationCode.Info.VENDOR.getCode().equals(source)) { + vendor = item.getData(); + deviceInfo.setVendor(vendor); + } + if (OperationCode.Info.TOTAL_RAM.getCode().equals(source)) { + totalRAM = item.getData(); + deviceInfo.setAvailableRAMMemory(Double.parseDouble(totalRAM)); + } + if (OperationCode.Info.TOTAL_STORAGE.getCode().equals(source)) { + totalStorage = item.getData(); + deviceInfo.setInternalAvailableMemory(Double.parseDouble(totalStorage)); + } + if (OperationCode.Info.DEV_ID.getCode().equals(source)) { + deviceID = item.getData(); + } + } + DeviceIdentifier deviceIdentifier = convertToDeviceIdentifierObject(deviceID); + try { + WindowsAPIUtils.updateDeviceInfo(deviceIdentifier, deviceInfo); + updateDeviceInfoStatus(deviceIdentifier); + } catch (org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceDetailsMgtException e) { + throw new WindowsOperationException("Error occurred while adding Device info."); + } catch (OperationManagementException e) { + throw new WindowsOperationException("Error occurred while updating Device info operation status."); + } + } } diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/OperationReply.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/OperationReply.java index 104ffa3c0..658e7dc13 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/OperationReply.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/operations/util/OperationReply.java @@ -70,6 +70,36 @@ public class OperationReply { replySyncmlDocument = new SyncmlDocument(); } + public OperationReply() { + + } + + /** + * Generate Device payloads. + * + * @param syncmlDocument Parsed syncml payload from the syncml engine. + * @param operations Operations for generate payload. + * @return String type syncml payload. + * @throws WindowsOperationException + * @throws PolicyManagementException + * @throws org.wso2.carbon.policy.mgt.common.FeatureManagementException + */ + public String generateReply(SyncmlDocument syncmlDocument, List operations) + throws SyncmlMessageFormatException, SyncmlOperationException { + + OperationReply operationReply; + SyncmlGenerator generator; + SyncmlDocument syncmlResponse; + if (operations == null) { + operationReply = new OperationReply(syncmlDocument); + } else { + operationReply = new OperationReply(syncmlDocument, operations); + } + syncmlResponse = operationReply.generateReply(); + generator = new SyncmlGenerator(); + return generator.generatePayload(syncmlResponse); + } + public SyncmlDocument generateReply() throws SyncmlMessageFormatException, SyncmlOperationException { generateHeader(); generateBody(); @@ -199,8 +229,8 @@ public class OperationReply { } private void appendOperations(SyncmlBody syncmlBody) throws PolicyManagementException, - FeatureManagementException, JSONException, - SyncmlOperationException { + FeatureManagementException, JSONException, SyncmlOperationException { + GetTag getElement = new GetTag(); List getElements = new ArrayList<>(); List executeElements = new ArrayList<>(); @@ -209,6 +239,7 @@ public class OperationReply { ReplaceTag replaceElement = new ReplaceTag(); List replaceItems = new ArrayList<>(); SequenceTag monitorSequence = new SequenceTag(); + List deviceInfoOperations; if (operations != null) { for (Operation operation : operations) { @@ -216,8 +247,10 @@ public class OperationReply { switch (type) { case POLICY: if (this.syncmlDocument.getBody().getAlert() != null) { - if ((Constants.INITIAL_ALERT_DATA.equals(this.syncmlDocument.getBody() - .getAlert().getData()))) { + if ((Constants.INITIAL_ALERT_DATA.equals(this.syncmlDocument.getBody().getAlert() + .getData())) || Constants.INITIAL_WIN10_ALERT_DATA. + equals(this.syncmlDocument.getBody() + .getAlert().getData())) { SequenceTag policySequence = new SequenceTag(); policySequence = buildSequence(operation, policySequence); syncmlBody.setSequence(policySequence); @@ -288,26 +321,41 @@ public class OperationReply { } } } - break; + if (PluginConstants.OperationCodes.DEVICE_INFO.equals(operation.getCode())) { + if (this.syncmlDocument.getBody().getAlert() != null) { + if ((Constants.INITIAL_ALERT_DATA.equals(this.syncmlDocument.getBody().getAlert() + .getData())) || Constants.INITIAL_WIN10_ALERT_DATA. + equals(this.syncmlDocument.getBody() + .getAlert().getData())) { + HeartBeatDeviceInfo heartBeatDeviceInfo = new HeartBeatDeviceInfo(); + deviceInfoOperations = heartBeatDeviceInfo.getDeviceInfo(); + for (Operation infoOperation : deviceInfoOperations) { + ItemTag deviceInfo = appendGetInfo(infoOperation); + getElements.add(deviceInfo); + } + } + } + break; + } } } + if (!replaceItems.isEmpty()) { + replaceElement.setCommandId(Constants.SyncmlMessageCodes.replaceCommandId); + replaceElement.setItems(replaceItems); + } + if (!getElements.isEmpty()) { + getElement.setCommandId(Constants.SyncmlMessageCodes.elementCommandId); + getElement.setItems(getElements); + } + if (!addElements.isEmpty()) { + atomicTagElement.setCommandId(Constants.SyncmlMessageCodes.atomicCommandId); + atomicTagElement.setAdds(addElements); + } + syncmlBody.setGet(getElement); + syncmlBody.setExec(executeElements); + syncmlBody.setAtomicTag(atomicTagElement); + syncmlBody.setReplace(replaceElement); } - if (!replaceItems.isEmpty()) { - replaceElement.setCommandId(Constants.SyncmlMessageCodes.replaceCommandId); - replaceElement.setItems(replaceItems); - } - if (!getElements.isEmpty()) { - getElement.setCommandId(Constants.SyncmlMessageCodes.elementCommandId); - getElement.setItems(getElements); - } - if (!addElements.isEmpty()) { - atomicTagElement.setCommandId(Constants.SyncmlMessageCodes.atomicCommandId); - atomicTagElement.setAdds(addElements); - } - syncmlBody.setGet(getElement); - syncmlBody.setExec(executeElements); - syncmlBody.setAtomicTag(atomicTagElement); - syncmlBody.setReplace(replaceElement); } private ItemTag appendExecInfo(Operation operation) { @@ -341,7 +389,7 @@ public class OperationReply { } } if ((operationCode != null) && - PluginConstants.OperationCodes.LOCK_RESET.equals(operationCode)) { + PluginConstants.OperationCodes.LOCK_RESET.equals(operationCode)) { operation.setCode(PluginConstants.OperationCodes.PIN_CODE); for (Info getInfo : Info.values()) { if (operation.getCode().equals(getInfo.name())) { @@ -514,8 +562,8 @@ public class OperationReply { } public SequenceTag buildSequence(Operation operation, SequenceTag sequenceElement) throws - JSONException, - SyncmlOperationException { + JSONException, + SyncmlOperationException { sequenceElement.setCommandId(operation.getId()); List replaceItems = new ArrayList<>(); diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/ConfigurationMgtService.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/ConfigurationMgtService.java index a5f207595..1796a637c 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/ConfigurationMgtService.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/ConfigurationMgtService.java @@ -66,8 +66,8 @@ import javax.ws.rs.core.Response; description = "This carries all the resources related to Windows configurations management functionalities") @WebService @Path("/configuration") -@Produces({"application/json", "application/xml"}) -@Consumes({"application/json", "application/xml"}) +@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) +@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public interface ConfigurationMgtService { @GET diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/DeviceManagementAdminService.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/DeviceManagementAdminService.java index 8ff15ea34..0b1b0995c 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/DeviceManagementAdminService.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/DeviceManagementAdminService.java @@ -36,8 +36,7 @@ import java.util.List; /** * Interface for Admin operations persisting. This interface accepts operations added via UI. */ -@Api(value = "Windows Device Management Administrative Service", - description = "Device management related admin APIs.") + @SwaggerDefinition( info = @Info( @@ -56,10 +55,12 @@ import java.util.List; @Tag(name = "devicemgt_windows", description = "") } ) +@Api(value = "Windows Device Management Administrative Service", + description = "Device management related admin APIs.") @WebService -@Path("/admin/devices") -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) +@Path("/operation/admin/devices") +@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) +@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public interface DeviceManagementAdminService { @POST @@ -367,7 +368,6 @@ public interface DeviceManagementAdminService { message = "Internal Server Error. \n " + "Server error occurred while adding adding a lock-reset operation.") }) - // Response lockReset(@HeaderParam("Accept") String acceptHeader, @ApiParam( name = "deviceIDs", value = "Provide the ID of the A Windows device. Multiple device IDs can be added by " + diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/DeviceManagementService.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/DeviceManagementService.java new file mode 100644 index 000000000..2b3dd6ae6 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/DeviceManagementService.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.mobile.windows.api.services; + + +import io.swagger.annotations.*; +import org.w3c.dom.Document; +import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsConfigurationException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsDeviceEnrolmentException; +import org.wso2.carbon.device.mgt.mobile.windows.api.operations.WindowsOperationException; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + + +/** + * Interface for Syncml message flow. + */ +@SwaggerDefinition( + info = @Info( + version = "1.0.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "Syncml Endpoint"), + @ExtensionProperty(name = "context", + value = "/api/device-mgt/windows/v1.0/syncmlmgt"), + }) + } + ), + tags = { + @Tag(name = "devicemgt_windows", description = "") + } +) +@Api(value = "Windows syncml service to initialize management session", + description = "This carries all the resources related to Windows syncml message flow.") +@Path("/devicemgt") +public interface DeviceManagementService { + @Path("/pending-operations") + @POST + @Consumes({PluginConstants.SYNCML_MEDIA_TYPE, MediaType.APPLICATION_XML}) + @Produces(PluginConstants.SYNCML_MEDIA_TYPE) + @ApiOperation( + httpMethod = "POST", + value = "Getting pending operations for Windows device.", + notes = "Using this API to fetching more information to enroll the Device and " + + "getting pending operations.", + tags = "Windows Device Management Administrative Service", + authorizations = { + @Authorization( + value = "permission", + scopes = {@AuthorizationScope( + scope = "/device-mgt/devices/enroll/windows", + description = "Getting pending operations and " + + "device information to enroll the device")} + ) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 201, + message = "Ok. \n Successfully getting pending operations.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "URL of the activity instance that refers to the scheduled operation."), + @ResponseHeader( + name = "Content-Type", + description = "Content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified. \n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 303, + message = "See Other. \n The source can be retrieved from the URL specified in the location header.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error."), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported.\n"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while getting pending operations.") + }) + Response getResponse(Document request) throws WindowsDeviceEnrolmentException, WindowsOperationException, + NotificationManagementException, WindowsConfigurationException; + +} + diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryRequest.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryRequest.java index e5f123d01..2c8260fb9 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryRequest.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryRequest.java @@ -18,47 +18,46 @@ package org.wso2.carbon.device.mgt.mobile.windows.api.services.discovery.beans; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.*; import java.io.Serializable; +import java.util.List; @XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "DiscoveryRequest") -@ApiModel(value = "DiscoveryRequest", - description = "Discover request related information.") +@XmlType(name = "DiscoveryRequest", namespace = "http://schemas.microsoft.com/windows/management/2012/01/enrollment") @SuppressWarnings("unused") public class DiscoveryRequest implements Serializable { - @ApiModelProperty(name = "emailId", value = "User email address which is submitted to the workplace app" + - " once sign in .", required = true) @XmlElement(name = "EmailAddress", required = true) private String emailId; - @ApiModelProperty(name = "version", value = "OS version on the Windows Device.", required = true) @XmlElement(name = "RequestVersion") private String version; - @ApiModelProperty(name = "deviceType", value = "Type of the Device(LapTop/Mobile Device).", required = true) @XmlElement(name = "DeviceType") private String deviceType; + @XmlElement(name = "OSEdition") + private String osEdition; + + @XmlElement(name = "ApplicationVersion") + private String applicationVersion; + + @XmlElementWrapper(name = "AuthPolicies") + @XmlElement(name = "AuthPolicy", required = true) + private List authenticationPolicies; + public String getEmailId() { return emailId; } - public String getVersion() { - return version; - } - public void setEmailId(String emailId) { this.emailId = emailId; } + public String getVersion() { + return version; + } + public void setVersion(String version) { this.version = version; } @@ -70,4 +69,21 @@ public class DiscoveryRequest implements Serializable { public void setDeviceType(String deviceType) { this.deviceType = deviceType; } + + public List getAuthenticationPolicies() { + return authenticationPolicies; + } + + public void setAuthenticationPolicies(List authenticationPolicies) { + this.authenticationPolicies = authenticationPolicies; + } + + public String getOsEdition() { + return osEdition; + } + + public void setOsEdition(String osEdition) { + this.osEdition = osEdition; + } + } \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryResponse.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryResponse.java index 7bfea5d37..10a124b06 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryResponse.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryResponse.java @@ -41,6 +41,9 @@ public class DiscoveryResponse implements Serializable { @XmlElement(name = "AuthenticationServiceUrl") private String authenticationServiceUrl; + @XmlElement(name = "EnrollmentVersion") + private String enrollmentVersion; + public void setAuthenticationServiceUrl(String authenticationServiceUrl) { this.authenticationServiceUrl = authenticationServiceUrl; } @@ -73,4 +76,12 @@ public class DiscoveryResponse implements Serializable { this.enrollmentServiceUrl = enrollmentServiceUrl; } + public String getEnrollmentVersion() { + return enrollmentVersion; + } + + public void setEnrollmentVersion(String enrollmentVersion) { + this.enrollmentVersion = enrollmentVersion; + } + } \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/impl/DiscoveryServiceImpl.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/impl/DiscoveryServiceImpl.java index 7d08082a4..6b7d57fac 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/impl/DiscoveryServiceImpl.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/impl/DiscoveryServiceImpl.java @@ -68,18 +68,32 @@ public class DiscoveryServiceImpl implements DiscoveryService { String emailId = discoveryRequest.getEmailId(); String[] userDomains = emailId.split(DELIMITER); String domain = userDomains[DOMAIN_SEGMENT]; + DiscoveryResponse discoveryResponse; + if (PluginConstants.WindowsVersionProperties.REQUESTED_WIN10_VERSION.equals(discoveryRequest.getVersion()) && + FEDERATED.equals(getAuthPolicy())) { + discoveryResponse = new DiscoveryResponse(); - DiscoveryResponse discoveryResponse = new DiscoveryResponse(); - if (FEDERATED.equals(getAuthPolicy())) { discoveryResponse.setAuthPolicy(FEDERATED); + discoveryResponse.setEnrollmentVersion(PluginConstants.WindowsVersionProperties.REQUESTED_WIN10_VERSION); discoveryResponse.setEnrollmentPolicyServiceUrl(PluginConstants.Discovery.DEVICE_ENROLLMENT_SUBDOMAIN + - domain + PluginConstants.Discovery. + domain + PluginConstants.Discovery. CERTIFICATE_ENROLLMENT_POLICY_SERVICE_URL); discoveryResponse.setEnrollmentServiceUrl(PluginConstants.Discovery.DEVICE_ENROLLMENT_SUBDOMAIN + - domain + PluginConstants.Discovery. + domain + PluginConstants.Discovery. + ENROLLMENT_SERVICE_URL); + discoveryResponse.setAuthenticationServiceUrl(PluginConstants.Discovery.DEVICE_ENROLLMENT_SUBDOMAIN + + domain + PluginConstants.Discovery.WAB_URL); + } else { + discoveryResponse = new DiscoveryResponse(); + discoveryResponse.setAuthPolicy(FEDERATED); + discoveryResponse.setEnrollmentPolicyServiceUrl(PluginConstants.Discovery.DEVICE_ENROLLMENT_SUBDOMAIN + + domain + PluginConstants.Discovery. + CERTIFICATE_ENROLLMENT_POLICY_SERVICE_URL); + discoveryResponse.setEnrollmentServiceUrl(PluginConstants.Discovery.DEVICE_ENROLLMENT_SUBDOMAIN + + domain + PluginConstants.Discovery. CERTIFICATE_ENROLLMENT_SERVICE_URL); discoveryResponse.setAuthenticationServiceUrl(PluginConstants.Discovery.DEVICE_ENROLLMENT_SUBDOMAIN + - domain + PluginConstants.Discovery.WAB_URL); + domain + PluginConstants.Discovery.WAB_URL); } response.value = discoveryResponse; if (log.isDebugEnabled()) { diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/EnrollmentService.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/EnrollmentService.java new file mode 100644 index 000000000..74390a031 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/EnrollmentService.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment; + +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WAPProvisioningException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsDeviceEnrolmentException; +import org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.AdditionalContext; +import org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.RequestSecurityTokenResponse; + +import javax.jws.WebMethod; +import javax.jws.WebParam; +import javax.jws.WebService; +import javax.xml.ws.BindingType; +import javax.xml.ws.RequestWrapper; +import javax.xml.ws.ResponseWrapper; +import javax.xml.ws.soap.SOAPBinding; +import java.io.UnsupportedEncodingException; + +@WebService(targetNamespace = PluginConstants.DEVICE_ENROLLMENT_SERVICE_TARGET_NAMESPACE, name = "enrollment") +@BindingType(value = SOAPBinding.SOAP12HTTP_BINDING) +public interface EnrollmentService { + + @RequestWrapper(localName = "RequestSecurityToken", targetNamespace = PluginConstants + .WS_TRUST_TARGET_NAMESPACE) + @WebMethod(operationName = "RequestSecurityToken") + @ResponseWrapper(localName = "RequestSecurityTokenResponseCollection", targetNamespace = + PluginConstants.WS_TRUST_TARGET_NAMESPACE) + void requestSecurityToken( + @WebParam(name = "TokenType", targetNamespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE) + String tokenType, + @WebParam(name = "RequestType", targetNamespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE) + String requestType, + @WebParam(name = "BinarySecurityToken", targetNamespace = PluginConstants + .WS_SECURITY_TARGET_NAMESPACE) + String binarySecurityToken, + @WebParam(name = "AdditionalContext", targetNamespace = PluginConstants + .SOAP_AUTHORIZATION_TARGET_NAMESPACE) + AdditionalContext additionalContext, + @WebParam(mode = WebParam.Mode.OUT, name = "RequestSecurityTokenResponse", + targetNamespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE) + javax.xml.ws.Holder response) throws + WindowsDeviceEnrolmentException, UnsupportedEncodingException, + WAPProvisioningException; +} diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/AdditionalContext.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/AdditionalContext.java new file mode 100644 index 000000000..fd62ef2ca --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/AdditionalContext.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans; + +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.util.ArrayList; +import java.util.List; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "OIDCollection", namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE, + propOrder = {"contextitem"}) +@SuppressWarnings("unused") +public class AdditionalContext { + + @XmlElement(name = "ContextItem", required = true, + namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE) + + protected List contextitem; + + public List getcontextitem() { + if (contextitem == null) { + contextitem = new ArrayList(); + } + return this.contextitem; + } +} + diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/BinarySecurityToken.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/BinarySecurityToken.java new file mode 100644 index 000000000..cf3d3bd5f --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/BinarySecurityToken.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans; + +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; + +import javax.xml.bind.annotation.*; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "BinarySecurityToken", namespace = PluginConstants.WS_SECURITY_TARGET_NAMESPACE, + propOrder = {"ValueType", "EncodingType"}) +@SuppressWarnings("unused") +public class BinarySecurityToken { + + @XmlAttribute(name = "ValueType") + protected String ValueType; + @XmlAttribute(name = "EncodingType") + protected String EncodingType; + @XmlValue + protected String Token; + + public void setValueType(String valuetype) { + this.ValueType = valuetype; + } + + public String getValueType() { + return this.ValueType; + } + + public void setEncodingType(String encodingtype) { + this.EncodingType = encodingtype; + } + + public String getEncodingType() { + return this.EncodingType; + } + + public void setToken(String token) { + this.Token = token; + } + + public String getToken() { + return this.Token; + } + +} + diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/ContextItem.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/ContextItem.java new file mode 100644 index 000000000..bbbdbd09c --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/ContextItem.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans; + +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "ContextItem", namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE, + propOrder = {"Name" , "Value"}) +public class ContextItem { + + @XmlElement(required = true, namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE) + protected String Name; + @XmlElement(required = true, namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE) + protected String Value; + + public String getValue() { + return Value; + } + + public void setValue(String value) { + Value = value; + } + + public String getName() { + return Name; + } + + public void setName(String name) { + Name = name; + } + +} diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestSecurityToken.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestSecurityToken.java new file mode 100644 index 000000000..ebd90792d --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestSecurityToken.java @@ -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. + */ + +package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans; + +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "RequestedSecurityToken", namespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE, + propOrder = {"binarySecurityToken"}) +@SuppressWarnings("unused") +public class RequestSecurityToken { + + @XmlElement(name = "BinarySecurityToken", required = true, + namespace = PluginConstants.WS_SECURITY_TARGET_NAMESPACE) + + protected BinarySecurityToken binarySecurityToken; + + public void setBinarySecurityToken(BinarySecurityToken binarysecuritytoken) { + this.binarySecurityToken = binarysecuritytoken; + } +} \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestSecurityTokenResponse.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestSecurityTokenResponse.java new file mode 100644 index 000000000..9f1b0c3c8 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestSecurityTokenResponse.java @@ -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. + */ + +package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans; + +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.io.Serializable; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "RequestSecurityTokenResponse", namespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE, + propOrder = {"TokenType", "DispositionMessage", "RequestedSecurityToken", "RequestID"}) +@SuppressWarnings("unused") +public class RequestSecurityTokenResponse implements Serializable { + + @XmlElement(name = "TokenType", namespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE) + private String TokenType; + + // Windows 10 property + @XmlElement(name = "DispositionMessage", namespace = PluginConstants.ENROLLMENT_POLICY_TARGET_NAMESPACE) + private String DispositionMessage; + + @XmlElement(name = "RequestedSecurityToken", required = true, + namespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE) + private org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.RequestedSecurityToken RequestedSecurityToken; + + @XmlElement(name = "RequestID", namespace = PluginConstants.ENROLLMENT_POLICY_TARGET_NAMESPACE) + private int RequestID; + + public String getTokenType() { + return TokenType; + } + + public void setTokenType(String tokenType) { + TokenType = tokenType; + } + + public org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.RequestedSecurityToken getRequestedSecurityToken() { + return RequestedSecurityToken; + } + + public void setRequestedSecurityToken(org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.RequestedSecurityToken + requestedSecurityToken) { + RequestedSecurityToken = requestedSecurityToken; + } + + public int getRequestID() { + return RequestID; + } + + public void setRequestID(int requestID) { + RequestID = requestID; + } + + public String getDispositionMessage() { + return DispositionMessage; + } + + public void setDispositionMessage(String dispositionMessage) { + DispositionMessage = dispositionMessage; + } + +} \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestedSecurityToken.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestedSecurityToken.java new file mode 100644 index 000000000..56f1ec571 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestedSecurityToken.java @@ -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. + */ + +package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans; + +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "RequestedSecurityToken", namespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE, + propOrder = {"binarySecurityToken"}) +public class RequestedSecurityToken { + + @XmlElement(name = "BinarySecurityToken", required = true, + namespace = PluginConstants.WS_SECURITY_TARGET_NAMESPACE) + + protected BinarySecurityToken binarySecurityToken; + + public void setBinarySecurityToken(BinarySecurityToken binarysecuritytoken) { + this.binarySecurityToken = binarysecuritytoken; + } +} + diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/package-info.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/package-info.java new file mode 100644 index 000000000..3ad6ec1b2 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/package-info.java @@ -0,0 +1,27 @@ +/* + * 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. + */ + +@XmlSchema(namespace = "http://www.w3.org/2003/05/soap-envelope", + xmlns = { + @XmlNs(prefix = "", namespaceURI = "http://www.w3.org/2003/05/soap-envelope") + }, elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) + +package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans; + +import javax.xml.bind.annotation.XmlNs; +import javax.xml.bind.annotation.XmlSchema; \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/impl/EnrollmentServiceImpl.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/impl/EnrollmentServiceImpl.java new file mode 100644 index 000000000..7cd57a495 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/impl/EnrollmentServiceImpl.java @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.impl; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.cxf.headers.Header; +import org.apache.cxf.helpers.CastUtils; +import org.apache.cxf.jaxws.context.WrappedMessageContext; +import org.apache.cxf.message.Message; +import org.w3c.dom.*; +import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException; +import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementServiceImpl; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.*; +import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.beans.CacheEntry; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.CertificateGenerationException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.SyncmlMessageFormatException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WAPProvisioningException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsDeviceEnrolmentException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.DeviceUtil; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.WindowsAPIUtils; +import org.wso2.carbon.device.mgt.mobile.windows.api.operations.util.SyncmlCredentialUtil; +import org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.EnrollmentService; +import org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.*; +import org.wso2.carbon.device.mgt.mobile.windows.api.services.syncml.beans.WindowsDevice; +import org.wso2.carbon.policy.mgt.common.PolicyManagementException; +import org.wso2.carbon.policy.mgt.core.PolicyManagerService; +import org.xml.sax.SAXException; + +import javax.annotation.Resource; +import javax.jws.WebService; +import javax.servlet.ServletContext; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.ws.BindingType; +import javax.xml.ws.Holder; +import javax.xml.ws.WebServiceContext; +import javax.xml.ws.handler.MessageContext; +import javax.xml.ws.soap.Addressing; +import javax.xml.ws.soap.SOAPBinding; +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + + +/** + * Implementation class of Windows10 Enrollment process. + */ +@WebService(endpointInterface = PluginConstants.ENROLLMENT_SERVICE_ENDPOINT, + targetNamespace = PluginConstants.DEVICE_ENROLLMENT_SERVICE_TARGET_NAMESPACE) +@Addressing(enabled = true, required = true) +@BindingType(value = SOAPBinding.SOAP12HTTP_BINDING) +public class EnrollmentServiceImpl implements EnrollmentService { + private static Log log = LogFactory.getLog(EnrollmentServiceImpl.class); + private X509Certificate rootCACertificate; + private String pollingFrequency; + private String provisioningURL; + private String domain; + + @Resource + private WebServiceContext context; + + @Override + public void requestSecurityToken(String tokenType, String requestType, String binarySecurityToken, + AdditionalContext additionalContext, + Holder response) + throws WindowsDeviceEnrolmentException, UnsupportedEncodingException, WAPProvisioningException { + + String headerBinarySecurityToken = null; + String headerTo = null; + String encodedWap; + List
headers = getHeaders(); + for (Header headerElement : headers != null ? headers : null) { + String nodeName = headerElement.getName().getLocalPart(); + if (PluginConstants.SECURITY.equals(nodeName)) { + Element element = (Element) headerElement.getObject(); + headerBinarySecurityToken = element.getFirstChild().getFirstChild().getTextContent(); + } + if (PluginConstants.TO.equals(nodeName)) { + Element toElement = (Element) headerElement.getObject(); + headerTo = toElement.getFirstChild().getTextContent(); + } + } + try { + enrollDevice(additionalContext, headerBinarySecurityToken); + } catch (DeviceManagementException e) { + throw new WindowsDeviceEnrolmentException("Error occurred while enrolling the device."); + } catch (PolicyManagementException e) { + throw new WindowsDeviceEnrolmentException("Error occurred while enforcing windows policies."); + } + String[] splitEmail = headerTo.split("(/ENROLLMENTSERVER)"); + String email = splitEmail[PluginConstants.CertificateEnrolment.EMAIL_SEGMENT]; + + String[] splitDomain = email.split("(EnterpriseEnrollment.)"); + domain = splitDomain[PluginConstants.CertificateEnrolment.DOMAIN_SEGMENT]; + provisioningURL = PluginConstants.CertificateEnrolment.ENROLL_SUBDOMAIN + domain + + PluginConstants.CertificateEnrolment.SYNCML_PROVISIONING_WIN10_SERVICE_URL; + + List tenantConfigurations; + try { + if ((tenantConfigurations = WindowsAPIUtils.getTenantConfigurationData()) != null) { + for (ConfigurationEntry configurationEntry : tenantConfigurations) { + if ((PluginConstants.TenantConfigProperties.NOTIFIER_FREQUENCY.equals( + configurationEntry.getName()))) { + pollingFrequency = configurationEntry.getValue().toString(); + } else { + pollingFrequency = PluginConstants.TenantConfigProperties.DEFAULT_FREQUENCY; + } + } + } else { + pollingFrequency = PluginConstants.TenantConfigProperties.DEFAULT_FREQUENCY; + String msg = "Tenant configurations are not initialized yet."; + log.error(msg); + } + ServletContext ctx = (ServletContext) context.getMessageContext(). + get(MessageContext.SERVLET_CONTEXT); + File wapProvisioningFile = (File) ctx.getAttribute(PluginConstants.CONTEXT_WAP_PROVISIONING_FILE); + if (log.isDebugEnabled()) { + log.debug("Received CSR from Device:" + binarySecurityToken); + } + + String wapProvisioningFilePath = wapProvisioningFile.getPath(); + RequestSecurityTokenResponse requestSecurityTokenResponse = new RequestSecurityTokenResponse(); + requestSecurityTokenResponse.setTokenType(PluginConstants.CertificateEnrolment.TOKEN_TYPE); + + encodedWap = prepareWapProvisioningXML(binarySecurityToken, wapProvisioningFilePath, + headerBinarySecurityToken); + RequestedSecurityToken requestedSecurityToken = new RequestedSecurityToken(); + BinarySecurityToken binarySecToken = new BinarySecurityToken(); + binarySecToken.setValueType(PluginConstants.CertificateEnrolment.VALUE_TYPE); + binarySecToken.setEncodingType(PluginConstants.CertificateEnrolment.ENCODING_TYPE); + binarySecToken.setToken(encodedWap); + requestedSecurityToken.setBinarySecurityToken(binarySecToken); + requestSecurityTokenResponse.setRequestedSecurityToken(requestedSecurityToken); + requestSecurityTokenResponse.setRequestID(PluginConstants.CertificateEnrolment.REQUEST_ID); + response.value = requestSecurityTokenResponse; + } catch (CertificateGenerationException e) { + String msg = "Problem occurred while generating certificate."; + log.error(msg, e); + throw new WindowsDeviceEnrolmentException(msg, e); + } catch (WAPProvisioningException e) { + String msg = "Problem occurred while generating wap-provisioning file."; + log.error(msg, e); + throw new WindowsDeviceEnrolmentException(msg, e); + } catch (DeviceManagementException e) { + String msg = "Error occurred while getting tenant configurations."; + log.error(msg); + throw new WindowsDeviceEnrolmentException(msg, e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + + } + } + + /** + * Method used to Convert the Document object into a String. + * + * @param document - Wap provisioning XML document + * @return - String representation of wap provisioning XML document + * @throws TransformerException + */ + private String convertDocumentToString(Document document) throws TransformerException { + DOMSource DOMSource = new DOMSource(document); + StringWriter stringWriter = new StringWriter(); + StreamResult streamResult = new StreamResult(stringWriter); + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.transform(DOMSource, streamResult); + + return stringWriter.toString(); + } + + /** + * This method prepares the wap-provisioning file by including relevant certificates etc. + * + * @param binarySecurityToken - CSR from device + * @param wapProvisioningFilePath - File path of wap-provisioning file + * @return - base64 encoded final wap-provisioning file as a String + * @throws CertificateGenerationException + * @throws org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WAPProvisioningException + */ + private String prepareWapProvisioningXML(String binarySecurityToken, String wapProvisioningFilePath, + String headerBst) throws CertificateGenerationException, + WAPProvisioningException, + WindowsDeviceEnrolmentException { + String rootCertEncodedString; + String signedCertEncodedString; + X509Certificate signedCertificate; + String provisioningXmlString; + + CertificateManagementServiceImpl certMgtServiceImpl = CertificateManagementServiceImpl.getInstance(); + Base64 base64Encoder = new Base64(); + try { + rootCACertificate = (X509Certificate) certMgtServiceImpl.getCACertificate(); + rootCertEncodedString = base64Encoder.encodeAsString(rootCACertificate.getEncoded()); + + + signedCertificate = certMgtServiceImpl.getSignedCertificateFromCSR(binarySecurityToken); + signedCertEncodedString = base64Encoder.encodeAsString(signedCertificate.getEncoded()); + + DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder; + + builder = domFactory.newDocumentBuilder(); + Document document = builder.parse(wapProvisioningFilePath); + NodeList wapParm = document.getElementsByTagName(PluginConstants.CertificateEnrolment.PARM); + Node caCertificatePosition = wapParm.item(PluginConstants.CertificateEnrolment.CA_CERTIFICATE_POSITION); + + //Adding SHA1 CA certificate finger print to wap-provisioning xml. + caCertificatePosition.getParentNode().getAttributes().getNamedItem(PluginConstants. + CertificateEnrolment.TYPE).setTextContent(String.valueOf( + DigestUtils.sha1Hex(rootCACertificate.getEncoded())).toUpperCase()); + //Adding encoded CA certificate to wap-provisioning file after removing new line + // characters. + NamedNodeMap rootCertAttributes = caCertificatePosition.getAttributes(); + Node rootCertNode = + rootCertAttributes.getNamedItem(PluginConstants.CertificateEnrolment.VALUE); + rootCertEncodedString = rootCertEncodedString.replaceAll("\n", ""); + rootCertNode.setTextContent(rootCertEncodedString); + + if (log.isDebugEnabled()) { + log.debug("Root certificate: " + rootCertEncodedString); + } + + Node signedCertificatePosition = wapParm.item(PluginConstants.CertificateEnrolment. + SIGNED_CERTIFICATE_POSITION); + + //Adding SHA1 signed certificate finger print to wap-provisioning xml. + signedCertificatePosition.getParentNode().getAttributes().getNamedItem(PluginConstants. + CertificateEnrolment.TYPE).setTextContent(String.valueOf( + DigestUtils.sha1Hex(signedCertificate.getEncoded())).toUpperCase()); + + //Adding encoded signed certificate to wap-provisioning file after removing new line + // characters. + NamedNodeMap clientCertAttributes = signedCertificatePosition.getAttributes(); + Node clientEncodedNode = + clientCertAttributes.getNamedItem(PluginConstants.CertificateEnrolment.VALUE); + signedCertEncodedString = signedCertEncodedString.replaceAll("\n", ""); + + clientEncodedNode.setTextContent(signedCertEncodedString); + if (log.isDebugEnabled()) { + log.debug("Signed certificate: " + signedCertEncodedString); + } + + //Adding domainName to wap-provisioning xml. + Node domainPosition = wapParm.item(PluginConstants.CertificateEnrolment.DOMAIN_POSITION); + NamedNodeMap domainAttribute = domainPosition.getAttributes(); + Node domainNode = domainAttribute.getNamedItem(PluginConstants.CertificateEnrolment.VALUE); + domainNode.setTextContent(domain); + + //Adding Next provisioning service URL to wap-provisioning xml. + Node syncmlServicePosition = wapParm.item(PluginConstants.CertificateEnrolment. + SYNCML_PROVISIONING_ADDR_POSITION); + NamedNodeMap syncmlServiceAttribute = syncmlServicePosition.getAttributes(); + Node syncmlServiceNode = syncmlServiceAttribute.getNamedItem(PluginConstants.CertificateEnrolment.VALUE); + syncmlServiceNode.setTextContent(provisioningURL); + + // Adding user name auth token to wap-provisioning xml. + Node userNameAuthPosition = wapParm.item(PluginConstants.CertificateEnrolment.APPAUTH_USERNAME_POSITION); + NamedNodeMap appServerAttribute = userNameAuthPosition.getAttributes(); + Node authNameNode = appServerAttribute.getNamedItem(PluginConstants.CertificateEnrolment.VALUE); + String userName = getRequestedUser(headerBst); + //CacheEntry cacheEntry = (CacheEntry) DeviceUtil.getCacheEntry(headerBst); + // String userName = cacheEntry.getUsername(); + authNameNode.setTextContent(userName); + DeviceUtil.removeToken(headerBst); + String password = DeviceUtil.generateRandomToken(); + Node passwordAuthPosition = wapParm.item(PluginConstants.CertificateEnrolment.APPAUTH_PASSWORD_POSITION); + NamedNodeMap appSrvPasswordAttribute = passwordAuthPosition.getAttributes(); + Node authPasswordNode = appSrvPasswordAttribute.getNamedItem(PluginConstants.CertificateEnrolment.VALUE); + authPasswordNode.setTextContent(password); + String requestSecurityTokenResponse = SyncmlCredentialUtil.generateRST(userName, password); + DeviceUtil.persistChallengeToken(requestSecurityTokenResponse, null, userName); + + // Get device polling frequency from the tenant Configurations. + Node numberOfFirstRetries = wapParm.item(PluginConstants.CertificateEnrolment.POLLING_FREQUENCY_POSITION); + NamedNodeMap pollingAttributes = numberOfFirstRetries.getAttributes(); + Node pollValue = pollingAttributes.getNamedItem(PluginConstants.CertificateEnrolment.VALUE); + pollValue.setTextContent(pollingFrequency); + provisioningXmlString = convertDocumentToString(document); + + } catch (ParserConfigurationException e) { + throw new WAPProvisioningException("Problem occurred while creating configuration request", e); + } catch (CertificateEncodingException e) { + throw new WindowsDeviceEnrolmentException("Error occurred while encoding certificates.", e); + } catch (SAXException e) { + throw new WAPProvisioningException("Error occurred while parsing wap-provisioning.xml file.", e); + } catch (TransformerException e) { + throw new WAPProvisioningException("Error occurred while transforming wap-provisioning.xml file.", e); + } catch (IOException e) { + throw new WAPProvisioningException("Error occurred while getting wap-provisioning.xml file.", e); + } catch (SyncmlMessageFormatException e) { + throw new WindowsDeviceEnrolmentException("Error occurred while generating password hash value.", e); + } catch (KeystoreException e) { + throw new CertificateGenerationException("CA certificate cannot be generated.", e); + } + return base64Encoder.encodeAsString(provisioningXmlString.getBytes()); + } + + /** + * This method get the soap request header contents. + * + * @return List of SOAP headers. + */ + private List
getHeaders() { + MessageContext messageContext = context.getMessageContext(); + if (messageContext == null || !(messageContext instanceof WrappedMessageContext)) { + return null; + } + Message message = ((WrappedMessageContext) messageContext).getWrappedMessage(); + return CastUtils.cast((List) message.get(Header.HEADER_LIST)); + } + + /** + * This method to getting RSTR requested user from the Cache. + * + * @param bst Binary Security token which has given from BST Endpoint. + * @return User for given token. + */ + private String getRequestedUser(String bst) { + CacheEntry cacheEntry = (CacheEntry) DeviceUtil.getCacheEntry(bst); + String userName = cacheEntry.getUsername(); + return userName; + } + + /** + * This Method to generate windows device. + * + * @param windowsDevice Requested Device with properties. + * @return Value added Device. + */ + private Device generateDevice(WindowsDevice windowsDevice) { + + Device generatedDevice = new Device(); + + Device.Property OSVersionProperty = new Device.Property(); + OSVersionProperty.setName(PluginConstants.SyncML.OS_VERSION); + OSVersionProperty.setValue(windowsDevice.getOsVersion()); + + Device.Property IMSEIProperty = new Device.Property(); + IMSEIProperty.setName(PluginConstants.SyncML.IMSI); + IMSEIProperty.setValue(windowsDevice.getImsi()); + + Device.Property IMEIProperty = new Device.Property(); + IMEIProperty.setName(PluginConstants.SyncML.IMEI); + IMEIProperty.setValue(windowsDevice.getImei()); + + List propertyList = new ArrayList<>(); + propertyList.add(OSVersionProperty); + propertyList.add(IMSEIProperty); + propertyList.add(IMEIProperty); + + EnrolmentInfo enrolmentInfo = new EnrolmentInfo(); + enrolmentInfo.setOwner(windowsDevice.getUser()); + enrolmentInfo.setOwnership(EnrolmentInfo.OwnerShip.BYOD); + enrolmentInfo.setStatus(EnrolmentInfo.Status.ACTIVE); + + generatedDevice.setEnrolmentInfo(enrolmentInfo); + generatedDevice.setDeviceIdentifier(windowsDevice.getDeviceId()); + generatedDevice.setProperties(propertyList); + generatedDevice.setType(windowsDevice.getDeviceType()); + generatedDevice.setName(windowsDevice.getDeviceName()); + + return generatedDevice; + } + + /** + * This method to enroll windows10 Device. + * + * @param requestContextItems Context values to enroll the device. + * @param headerBinarySecurityToken SOAP request header value to identify the user. + * @throws DeviceManagementException Exception occurs while enrolling the Device. + * @throws PolicyManagementException Exception occurs while getting effective policies. + */ + private void enrollDevice(AdditionalContext requestContextItems, String headerBinarySecurityToken) + throws DeviceManagementException, PolicyManagementException { + WindowsDevice windowsDevice = new WindowsDevice(); + windowsDevice.setDeviceType(DeviceManagementConstants.MobileDeviceTypes. + MOBILE_DEVICE_TYPE_WINDOWS); + windowsDevice.setUser(getRequestedUser(headerBinarySecurityToken)); + List contextItems = requestContextItems.getcontextitem(); + for (int x = 0; x < contextItems.size(); x++) { + switch (x) { + case PluginConstants.WindowsEnrollmentProperties.WIN_DEVICE_NAME: + windowsDevice.setDeviceName(contextItems.get(x).getValue()); + case PluginConstants.WindowsEnrollmentProperties.WIN_DEVICE_IMEI: + windowsDevice.setImei(contextItems.get(x).getValue()); + case PluginConstants.WindowsEnrollmentProperties.WIN_DEVICE_ID: + windowsDevice.setDeviceId(contextItems.get(x).getValue()); + case PluginConstants.WindowsEnrollmentProperties.WIN_DEVICE_VERSION: + windowsDevice.setOsVersion(contextItems.get(x).getValue()); + } + } + Device device = generateDevice(windowsDevice); + WindowsAPIUtils.getDeviceManagementService().enrollDevice(device); + PolicyManagerService policyManagerService = WindowsAPIUtils.getPolicyManagerService(); + policyManagerService.getEffectivePolicy(new DeviceIdentifier(windowsDevice.getDeviceId(), device.getType())); + + } +} + diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/CertificateSigningService.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/CertificateSigningService.java new file mode 100644 index 000000000..e4eeaf665 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/CertificateSigningService.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bouncycastle.asn1.x509.*; +import org.bouncycastle.cert.CertIOException; +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.CertificateGenerationException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WAPProvisioningException; + +import javax.security.auth.x500.X500Principal; +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.List; + +/** + * Class for generating signed certificate for CSR form device. + */ +public class CertificateSigningService { + + private static final long MILLI_SECONDS = 1000L * 60 * 60 * 24; + + private enum PropertyIndex { + COMMON_NAME_INDEX(0), + NOT_BEFORE_DAYS_INDEX(1), + NOT_AFTER_DAYS_INDEX(2); + + private final int itemPosition; + private PropertyIndex(final int itemPosition) { + this.itemPosition = itemPosition; + } + public int getValue() { + return this.itemPosition; + } + } + + private static Log log = LogFactory.getLog( + CertificateSigningService.class); + + /** + * Implement certificate signing task using CSR received from the device and the MDM server key + * store. + * @param jcaRequest - CSR from the device + * @param privateKey - Private key of CA certificate in MDM server + * @param caCert - CA certificate in MDM server + * @param certParameterList - Parameter list for Signed certificate generation + * @return - Signed certificate for CSR from device + * @throws CertificateGenerationException + * @throws WAPProvisioningException + */ + public static X509Certificate signCSR(JcaPKCS10CertificationRequest jcaRequest, + PrivateKey privateKey, X509Certificate caCert, + List certParameterList) throws + CertificateGenerationException, + WAPProvisioningException { + + String commonName = + (String) certParameterList.get(PropertyIndex.COMMON_NAME_INDEX.getValue()); + int notBeforeDays = + (Integer) certParameterList.get(PropertyIndex.NOT_BEFORE_DAYS_INDEX.getValue()); + int notAfterDays = + (Integer) certParameterList.get(PropertyIndex.NOT_AFTER_DAYS_INDEX.getValue()); + X509v3CertificateBuilder certificateBuilder; + X509Certificate signedCertificate; + + try { + ContentSigner signer; + BigInteger serialNumber = BigInteger.valueOf(new SecureRandom(). + nextInt(Integer.MAX_VALUE)); + Date notBeforeDate = new Date(System.currentTimeMillis() - + (MILLI_SECONDS * notBeforeDays)); + Date notAfterDate = new Date(System.currentTimeMillis() + + (MILLI_SECONDS * notAfterDays)); + certificateBuilder = + new JcaX509v3CertificateBuilder(caCert, serialNumber, notBeforeDate, notAfterDate, + new X500Principal(commonName), + jcaRequest.getPublicKey()); + + //Adding extensions to the signed certificate. + certificateBuilder.addExtension(Extension.keyUsage, true, + new KeyUsage(KeyUsage.digitalSignature)); + certificateBuilder.addExtension(Extension.extendedKeyUsage, false, + new ExtendedKeyUsage(KeyPurposeId.id_kp_clientAuth)); + certificateBuilder.addExtension(Extension.basicConstraints, true, + new BasicConstraints(false)); + + signer = new JcaContentSignerBuilder(PluginConstants.CertificateEnrolment.ALGORITHM). + setProvider(PluginConstants.CertificateEnrolment.PROVIDER).build(privateKey); + + signedCertificate = new JcaX509CertificateConverter().setProvider( + PluginConstants.CertificateEnrolment.PROVIDER).getCertificate( + certificateBuilder.build(signer)); + } catch (InvalidKeyException e) { + throw new CertificateGenerationException("CSR's public key is invalid", e); + } catch (NoSuchAlgorithmException e) { + throw new CertificateGenerationException("Certificate cannot be generated", e); + } + catch (CertIOException e) { + throw new CertificateGenerationException( + "Cannot add extension(s) to signed certificate", e); + } + catch (OperatorCreationException e) { + throw new CertificateGenerationException("Content signer cannot be created", e); + } + catch (CertificateException e) { + throw new CertificateGenerationException("Signed certificate cannot be generated", e); + } + return signedCertificate; + } +} diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/KeyStoreGenerator.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/KeyStoreGenerator.java new file mode 100644 index 000000000..ba966f80e --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/KeyStoreGenerator.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.KeyStoreGenerationException; + +import java.io.FileInputStream; +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; + +/** + * Class for MDM Keystore operations. + */ +public class KeyStoreGenerator { + + private static final Log log = LogFactory.getLog( + KeyStoreGenerator.class); + + /** + * This method loads the MDM keystore. + * @param keyStore - MDM Keystore + * @param keyStorePassword - Keystore Password + * @param keyStorePath - Keystore path + * @throws KeyStoreGenerationException + */ + public static void loadToStore(KeyStore keyStore, + char[] keyStorePassword, + String keyStorePath) throws KeyStoreGenerationException { + + FileInputStream fileInputStream = null; + + try { + if (keyStorePath != null) { + fileInputStream = new FileInputStream(keyStorePath); + keyStore.load(fileInputStream, keyStorePassword); + } + } catch (NoSuchAlgorithmException e) { + throw new KeyStoreGenerationException( + "Requested cryptographic algorithm is not available in the environment.", e); + } catch (CertificateException e) { + throw new KeyStoreGenerationException("Error working with certificate related to, " + + keyStorePath, e); + } catch (IOException e) { + throw new KeyStoreGenerationException("File error while working with file, " + + keyStorePath, e); + } finally { + try { + if (fileInputStream != null) { + fileInputStream.close(); + } + } catch (IOException e) { + throw new KeyStoreGenerationException("File error while closing the file, " + + keyStorePath, e); + } + } + } + + /** + * This method is for retrieving instance of Key Store. + * @return Keystore object + * @throws KeyStoreGenerationException + */ + public static KeyStore getKeyStore() throws KeyStoreGenerationException { + try { + return KeyStore.getInstance(PluginConstants.CertificateEnrolment.JKS); + } catch (KeyStoreException e) { + String msg = "KeyStore error while creating new JKS."; + log.error(msg, e); + throw new KeyStoreGenerationException(msg, e); + } + } +} diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/MessageHandler.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/MessageHandler.java new file mode 100644 index 000000000..616e3db08 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/MessageHandler.java @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.joda.time.DateTime; +import org.joda.time.format.ISODateTimeFormat; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; + +import javax.ws.rs.core.Response; +import javax.xml.namespace.QName; +import javax.xml.soap.*; +import javax.xml.ws.handler.MessageContext; +import javax.xml.ws.handler.soap.SOAPHandler; +import javax.xml.ws.handler.soap.SOAPMessageContext; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.*; + +/** + * Class responsible for adding Timestamp security header in SOAP message and adding Content-length + * in the HTTP header for avoiding HTTP chunking. + */ +public class MessageHandler implements SOAPHandler { + + public static final String TIME_ZONE = "Z"; + public static final int VALIDITY_TIME = 5; + public static final int TIMESTAMP_END_INDEX = 6; + public static final int TIMESTAMP_BEGIN_INDEX = 0; + private static Log log = LogFactory.getLog( + MessageHandler.class); + + /** + * This method resolves the security header coming in the SOAP message. + * @return - Security Header + */ + @Override + public Set getHeaders() { + QName securityHeader = new QName(PluginConstants.WS_SECURITY_TARGET_NAMESPACE, PluginConstants.SECURITY); + HashSet headers = new HashSet(); + headers.add(securityHeader); + return headers; + } + + /** + * This method adds Timestamp for SOAP header, and adds Content-length for HTTP header for + * avoiding HTTP chunking. + * + * @param context - Context of the SOAP Message + */ + @Override + public boolean handleMessage(SOAPMessageContext context) { + + Boolean outBoundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); + + if (outBoundProperty) { + SOAPMessage message = context.getMessage(); + SOAPHeader header = null; + SOAPEnvelope envelope = null; + try { + header = message.getSOAPHeader(); + envelope = message.getSOAPPart().getEnvelope(); + } catch (SOAPException e) { + Response.serverError().entity("SOAP message content cannot be read.").build(); + } + try { + if ((header == null) && (envelope != null)) { + header = envelope.addHeader(); + } + } catch (SOAPException e) { + Response.serverError().entity("SOAP header cannot be added.").build(); + } + + SOAPFactory soapFactory = null; + try { + soapFactory = SOAPFactory.newInstance(); + } catch (SOAPException e) { + Response.serverError().entity("Cannot get an instance of SOAP factory.").build(); + } + + QName qNamesSecurity = new QName(PluginConstants.WS_SECURITY_TARGET_NAMESPACE, + PluginConstants.CertificateEnrolment.SECURITY); + SOAPHeaderElement Security = null; + Name attributeName = null; + try { + if (header != null) { + Security = header.addHeaderElement(qNamesSecurity); + } + if (soapFactory != null) { + attributeName = + soapFactory.createName(PluginConstants.CertificateEnrolment.TIMESTAMP_ID, + PluginConstants.CertificateEnrolment.TIMESTAMP_U, + PluginConstants.CertificateEnrolment + .WSS_SECURITY_UTILITY); + } + } catch (SOAPException e) { + Response.serverError().entity("Security header cannot be added.").build(); + } + + QName qNameTimestamp = new QName(PluginConstants.CertificateEnrolment.WSS_SECURITY_UTILITY, + PluginConstants.CertificateEnrolment.TIMESTAMP); + SOAPHeaderElement timestamp = null; + try { + if (header != null) { + timestamp = header.addHeaderElement(qNameTimestamp); + timestamp.addAttribute(attributeName, + PluginConstants.CertificateEnrolment.TIMESTAMP_0); + } + } catch (SOAPException e) { + Response.serverError().entity("Exception while adding timestamp header.").build(); + } + DateTime dateTime = new DateTime(); + DateTime expiredDateTime = dateTime.plusMinutes(VALIDITY_TIME); + String createdISOTime = dateTime.toString(ISODateTimeFormat.dateTime()); + String expiredISOTime = expiredDateTime.toString(ISODateTimeFormat.dateTime()); + createdISOTime = createdISOTime.substring(TIMESTAMP_BEGIN_INDEX, + createdISOTime.length() - + TIMESTAMP_END_INDEX); + createdISOTime = createdISOTime + TIME_ZONE; + expiredISOTime = expiredISOTime.substring(TIMESTAMP_BEGIN_INDEX, + expiredISOTime.length() - + TIMESTAMP_END_INDEX); + expiredISOTime = expiredISOTime + TIME_ZONE; + QName qNameCreated = new QName(PluginConstants.CertificateEnrolment.WSS_SECURITY_UTILITY, + PluginConstants.CertificateEnrolment.CREATED); + SOAPHeaderElement SOAPHeaderCreated = null; + + try { + if (header != null) { + SOAPHeaderCreated = header.addHeaderElement(qNameCreated); + SOAPHeaderCreated.addTextNode(createdISOTime); + } + } catch (SOAPException e) { + Response.serverError().entity("Exception while creating SOAP header.").build(); + } + QName qNameExpires = new QName(PluginConstants.CertificateEnrolment.WSS_SECURITY_UTILITY, + PluginConstants.CertificateEnrolment.EXPIRES); + SOAPHeaderElement SOAPHeaderExpires = null; + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + String messageString = null; + try { + if (header != null) { + SOAPHeaderExpires = header.addHeaderElement(qNameExpires); + SOAPHeaderExpires.addTextNode(expiredISOTime); + } + if ((timestamp != null) && (Security != null)) { + timestamp.addChildElement(SOAPHeaderCreated); + timestamp.addChildElement(SOAPHeaderExpires); + Security.addChildElement(timestamp); + } + message.saveChanges(); + message.writeTo(outputStream); + messageString = new String(outputStream.toByteArray(), + PluginConstants.CertificateEnrolment.UTF_8); + } catch (SOAPException e) { + Response.serverError().entity("Exception while creating timestamp SOAP header.") + .build(); + } catch (IOException e) { + Response.serverError().entity("Exception while writing message to output stream.") + .build(); + } + + Map> headers = + (Map>) context.get(MessageContext.HTTP_REQUEST_HEADERS); + headers = new HashMap>(); + if (messageString != null) { + headers.put(PluginConstants.CONTENT_LENGTH, Arrays.asList(String.valueOf( + messageString.length()))); + } + context.put(MessageContext.HTTP_REQUEST_HEADERS, headers); + } + return true; + } + + @Override + public boolean handleFault(SOAPMessageContext context) { + return true; + } + + @Override + public void close(MessageContext context) { + } +} diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/impl/ConfigurationMgtServiceImpl.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/impl/ConfigurationMgtServiceImpl.java index c2a6607b3..f4829183e 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/impl/ConfigurationMgtServiceImpl.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/impl/ConfigurationMgtServiceImpl.java @@ -31,6 +31,7 @@ import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.Unexpecte import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsConfigurationException; import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.WindowsAPIUtils; import org.wso2.carbon.device.mgt.mobile.windows.api.services.ConfigurationMgtService; +import javax.ws.rs.core.MediaType; import javax.jws.WebService; import javax.ws.rs.*; @@ -39,9 +40,9 @@ import java.util.ArrayList; import java.util.List; @WebService -@Produces({"application/json", "application/xml"}) -@Consumes({"application/json", "application/xml"}) -@Path("/") +@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) +@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) +@Path("/configuration") public class ConfigurationMgtServiceImpl implements ConfigurationMgtService { private static Log log = LogFactory.getLog( diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/impl/DeviceManagementAdminServiceImpl.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/impl/DeviceManagementAdminServiceImpl.java index 5f6e4e082..1bcd6da0a 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/impl/DeviceManagementAdminServiceImpl.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/impl/DeviceManagementAdminServiceImpl.java @@ -35,9 +35,7 @@ import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.Message; import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.WindowsAPIUtils; import org.wso2.carbon.device.mgt.mobile.windows.api.services.DeviceManagementAdminService; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.Path; +import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.List; @@ -46,6 +44,9 @@ import java.util.List; * Implementation class of operations interface. Each method in this class receives the operations comes via UI * and persists those in the correct format. */ +@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) +@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) +@Path("/admin/devices") public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminService { private static Log log = LogFactory.getLog(OperationImpl.class); @@ -102,7 +103,7 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe * @throws WindowsDeviceEnrolmentException */ @POST - @Path("/disenroll") + @Path("/disenroll-devices") public Response disenroll(@HeaderParam("Accept") String acceptHeader, List deviceIDs) throws WindowsDeviceEnrolmentException { @@ -127,11 +128,11 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe log.error(errorMessage, e); throw new WindowsOperationsException(message, responseMediaType); } catch (InvalidDeviceException e) { - String errorMessage = "Invalid Device Identifiers found."; - log.error(errorMessage, e); - throw new BadRequestException( - new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build()); - } + String errorMessage = "Invalid Device Identifiers found."; + log.error(errorMessage, e); + throw new BadRequestException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build()); + } } /** @@ -143,7 +144,7 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe * @throws WindowsDeviceEnrolmentException */ @POST - @Path("/wipe-data") + @Path("/wipe-devices") public Response wipe(@HeaderParam("Accept") String acceptHeader, List deviceids) throws WindowsDeviceEnrolmentException { @@ -186,7 +187,7 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe * @throws WindowsDeviceEnrolmentException */ @POST - @Path("/ring-device") + @Path("/ring-devices") public Response ring(@HeaderParam("Accept") String acceptHeader, List deviceIDs) throws WindowsDeviceEnrolmentException { @@ -234,7 +235,7 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe * @throws WindowsDeviceEnrolmentException */ @POST - @Path("/lock-reset") + @Path("/lock-reset-devices") public Response lockReset(@HeaderParam("Accept") String acceptHeader, List deviceIDs) throws WindowsDeviceEnrolmentException { diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/impl/DeviceManagementServiceImpl.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/impl/DeviceManagementServiceImpl.java new file mode 100644 index 000000000..f754ff80c --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/impl/DeviceManagementServiceImpl.java @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.mobile.windows.api.services.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Document; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.device.details.*; +import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementException; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.beans.CacheEntry; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.SyncmlMessageFormatException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.SyncmlOperationException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsConfigurationException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsDeviceEnrolmentException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.AuthenticationInfo; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.DeviceUtil; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.WindowsAPIUtils; +import org.wso2.carbon.device.mgt.mobile.windows.api.operations.*; +import org.wso2.carbon.device.mgt.mobile.windows.api.operations.util.*; +import org.wso2.carbon.device.mgt.mobile.windows.api.operations.util.DeviceInfo; +import org.wso2.carbon.device.mgt.mobile.windows.api.services.DeviceManagementService; +import org.wso2.carbon.policy.mgt.common.PolicyManagementException; +import org.wso2.carbon.policy.mgt.core.PolicyManagerService; + +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.List; + +import static org.wso2.carbon.device.mgt.mobile.windows.api.common.util.WindowsAPIUtils.convertToDeviceIdentifierObject; + + +public class DeviceManagementServiceImpl implements DeviceManagementService { + private static Log log = LogFactory.getLog( + org.wso2.carbon.device.mgt.mobile.windows.api.services.syncml.impl.SyncmlServiceImpl.class); + + @Override + public Response getResponse(Document request) throws WindowsDeviceEnrolmentException, WindowsOperationException, + NotificationManagementException, WindowsConfigurationException { + + int msgId; + int sessionId; + String user; + String token; + String response; + SyncmlDocument syncmlDocument; + List pendingOperations; + OperationHandler operationHandler = new OperationHandler(); + OperationReply operationReply = new OperationReply(); + + try { + if (SyncmlParser.parseSyncmlPayload(request) != null) { + syncmlDocument = SyncmlParser.parseSyncmlPayload(request); + SyncmlHeader syncmlHeader = syncmlDocument.getHeader(); + sessionId = syncmlHeader.getSessionId(); + user = syncmlHeader.getSource().getLocName(); + DeviceIdentifier deviceIdentifier = convertToDeviceIdentifierObject(syncmlHeader.getSource(). + getLocURI()); + msgId = syncmlHeader.getMsgID(); + if ((PluginConstants.SyncML.SYNCML_FIRST_MESSAGE_ID == msgId) && + (PluginConstants.SyncML.SYNCML_FIRST_SESSION_ID == sessionId)) { + token = syncmlHeader.getCredential().getData(); + CacheEntry cacheToken = (CacheEntry) DeviceUtil.getCacheEntry(token); + + if ((cacheToken.getUsername() != null) && (cacheToken.getUsername().equals(user))) { + + if (modifyEnrollWithMoreDetail(request)) { + pendingOperations = operationHandler.getPendingOperations(syncmlDocument); + response = operationReply.generateReply(syncmlDocument,pendingOperations); + return Response.status(Response.Status.OK).entity(response).build(); + } else { + String msg = "Error occurred in while modify the enrollment."; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } else { + String msg = "Authentication failure due to incorrect credentials."; + log.error(msg); + return Response.status(Response.Status.UNAUTHORIZED).entity(msg).build(); + } + } else { + if ((syncmlDocument.getBody().getAlert() != null)) { + if (!syncmlDocument.getBody().getAlert().getData().equals(Constants.DISENROLL_ALERT_DATA)) { + pendingOperations = operationHandler.getPendingOperations(syncmlDocument); + return Response.ok().entity(operationReply.generateReply( + syncmlDocument, pendingOperations)).build(); + } else { + if (WindowsAPIUtils.getDeviceManagementService().getDevice(deviceIdentifier) != null) { + WindowsAPIUtils.getDeviceManagementService().disenrollDevice(deviceIdentifier); + return Response.ok().entity(operationReply.generateReply(syncmlDocument, null)).build(); + } else { + String msg = "Enrolled device can not be found in the server."; + log.error(msg); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } + } + } else { + pendingOperations = operationHandler.getPendingOperations(syncmlDocument); + return Response.ok().entity(operationReply.generateReply( + syncmlDocument, pendingOperations)).build(); + } + } + } + } catch (SyncmlMessageFormatException e) { + String msg = "Error occurred while parsing syncml request."; + log.error(msg, e); + throw new WindowsOperationException(msg, e); + } catch (OperationManagementException e) { + String msg = "Cannot access operation management service."; + log.error(msg, e); + throw new WindowsOperationException(msg, e); + } catch (SyncmlOperationException e) { + String msg = "Error occurred while getting effective feature."; + log.error(msg, e); + throw new WindowsConfigurationException(msg, e); + } catch (DeviceManagementException e) { + String msg = "Failure occurred in dis-enrollment flow."; + log.error(msg, e); + throw new WindowsOperationException(msg, e); + } + return null; + } + + /** + * Enroll phone device + * + * @param request Device syncml request for the server side. + * @return enroll state + * @throws WindowsDeviceEnrolmentException + * @throws WindowsOperationException + */ + private boolean modifyEnrollWithMoreDetail(Document request) throws WindowsDeviceEnrolmentException, + WindowsOperationException { + + String devMan; + String devMod; + boolean status = false; + String user; + SyncmlDocument syncmlDocument; + + try { + syncmlDocument = SyncmlParser.parseSyncmlPayload(request); + ReplaceTag replace = syncmlDocument.getBody().getReplace(); + List itemList = replace.getItems(); + devMan = itemList.get(PluginConstants.SyncML.DEVICE_MAN_POSITION).getData(); + devMod = itemList.get(PluginConstants.SyncML.DEVICE_MODEL_POSITION).getData(); + user = syncmlDocument.getHeader().getSource().getLocName(); + AuthenticationInfo authenticationInfo = new AuthenticationInfo(); + authenticationInfo.setUsername(user); + WindowsAPIUtils.startTenantFlow(authenticationInfo); + DeviceIdentifier deviceIdentifier = convertToDeviceIdentifierObject(syncmlDocument. + getHeader().getSource().getLocURI()); + Device existingDevice = WindowsAPIUtils.getDeviceManagementService().getDevice(deviceIdentifier); + if (!existingDevice.getProperties().isEmpty()) { + List existingProperties = new ArrayList<>(); + + Device.Property vendorProperty = new Device.Property(); + vendorProperty.setName(PluginConstants.SyncML.VENDOR); + vendorProperty.setValue(devMan); + existingProperties.add(vendorProperty); + + Device.Property deviceModelProperty = new Device.Property(); + deviceModelProperty.setName(PluginConstants.SyncML.MODEL); + deviceModelProperty.setValue(devMod); + existingProperties.add(deviceModelProperty); + + existingDevice.setProperties(existingProperties); + existingDevice.setDeviceIdentifier(syncmlDocument.getHeader().getSource().getLocURI()); + existingDevice.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_WINDOWS); + status = WindowsAPIUtils.getDeviceManagementService().modifyEnrollment(existingDevice); + return status; + } + } catch (DeviceManagementException e) { + throw new WindowsDeviceEnrolmentException("Failure occurred while enrolling device.", e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + return status; + } +} diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/beans/WindowsDevice.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/beans/WindowsDevice.java index c531a45df..272b7875a 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/beans/WindowsDevice.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/beans/WindowsDevice.java @@ -31,6 +31,7 @@ public class WindowsDevice { private String manufacturer; private String model; private String user; + private String deviceName; public String getImei() { return imei; @@ -96,5 +97,13 @@ public class WindowsDevice { this.user = user; } + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + } diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/impl/SyncmlServiceImpl.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/impl/SyncmlServiceImpl.java index 1bd6c827a..3dfcb4461 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/impl/SyncmlServiceImpl.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/impl/SyncmlServiceImpl.java @@ -235,6 +235,7 @@ public class SyncmlServiceImpl implements SyncmlService { String devLang; String vendor; String macAddress; + String resolution; String modVersion; boolean status = false; String user; @@ -323,11 +324,10 @@ public class SyncmlServiceImpl implements SyncmlService { deviceModelProperty.setValue(devMod); existingProperties.add(deviceModelProperty); - existingDevice.setName(deviceName); existingDevice.setProperties(existingProperties); + existingDevice.setName(deviceName); existingDevice.setDeviceIdentifier(syncmlDocument.getHeader().getSource().getLocURI()); existingDevice.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_WINDOWS); - status = WindowsAPIUtils.getDeviceManagementService().modifyEnrollment(existingDevice); // call effective policy for the enrolling device. PolicyManagerService policyManagerService = WindowsAPIUtils.getPolicyManagerService(); diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/resources/properties.xml b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/resources/properties.xml deleted file mode 100644 index f06c1da23..000000000 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/resources/properties.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - Federated - wso2carbon - cacert - CN=mdmcn - 3 - 300 - wso2.com - \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/resources/win10-wap-provisioning.xml b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/resources/win10-wap-provisioning.xml new file mode 100644 index 000000000..5d305a243 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/resources/win10-wap-provisioning.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/resources/wso2mdm.jks b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/resources/wso2mdm.jks deleted file mode 100644 index 66b68ea39..000000000 Binary files a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/resources/wso2mdm.jks and /dev/null differ diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/cxf-servlet.xml index a81ccfd47..cebd427bb 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/cxf-servlet.xml +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -64,24 +64,27 @@ - + + id="CertificateEnrollmentService" + implementor="org.wso2.carbon.device.mgt.mobile.windows.api.services.wstep.impl.CertificateEnrollmentServiceImpl" + address="/deviceenrolment/wstep"> - + - + + + + - + + id="EnrollmentService" + implementor="org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.impl.EnrollmentServiceImpl" + address="/deviceenrolment/enrollment"> @@ -97,51 +100,41 @@ - - - - - - - + + - - + - - - - - - + + - - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + nonSecuredEndPoints /discovery/get,/discovery/post,/certificatepolicy/xcep, - ,/deviceenrolment/wstep,/syncml/devicemanagement/request + ,/deviceenrolment/wstep,/syncml/devicemanagement/request,/deviceenrolment/enrollment,/management/devicemgt/pending-operations + \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.device-view/device-view.hbs b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.device-view/device-view.hbs index d220367f3..6030939ef 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.device-view/device-view.hbs +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.device-view/device-view.hbs @@ -1,485 +1,380 @@ {{unit "cdmf.unit.device.type.windows.leaflet"}} {{unit "cdmf.unit.lib.qrcode"}} {{unit "cdmf.unit.device.type.windows.qr-modal"}} -{{unit "cdmf.unit.device.type.windows.operation-bar"}} {{#if deviceFound}} {{#if isAuthorized}} {{#zone "device-details-header"}} -

- Device {{deviceView.name}} - {{#if deviceView.model}} - - ( {{deviceView.vendor}} {{deviceView.model}} ) +

+ Device {{device.name}} + {{#if device.model}} + + ( {{device.vendor}} {{device.model}} ) - {{/if}} -

+ {{/if}} +

{{/zone}} - {{#zone "overview-section"}} -
-
Device - Overview -
- - - {{#if deviceView.deviceIdentifier}} - - - - - {{/if}} - {{#if deviceView.name}} - - - - - {{/if}} - {{#if deviceView.vendor}} - {{#if deviceView.model}} - - - - - {{/if}} - {{/if}} - {{#if deviceView.status}} - - - - - {{/if}} - {{#if deviceView.owner}} - - - - - {{/if}} - {{#if deviceView.ownership}} - - - - - {{/if}} - {{#if deviceView.imei}} - - - - - {{/if}} - {{#if deviceView.udid}} - - - - - {{/if}} - {{#if deviceView.osBuildDate}} - - - - - {{/if}} - {{#if deviceView.phoneNumber}} - - - - - {{/if}} - {{#if deviceView.lastUpdatedTime}} - - - - - {{/if}} - -
Device ID{{deviceView.deviceIdentifier}}
Name{{deviceView.name}}
Model{{deviceView.vendor}} {{deviceView.model}}
Status - {{#equal deviceView.status "ACTIVE"}}Active{{/equal}} - {{#equal deviceView.status "INACTIVE"}}Inactive{{/equal}} - {{#equal deviceView.status "BLOCKED"}}Blocked{{/equal}} - {{#equal deviceView.status "REMOVED"}}Removed{{/equal}} -
Owner{{deviceView.owner}}
Ownership{{deviceView.ownership}}
IMEI{{deviceView.imei}}
UDID{{deviceView.udid}}
Firmware Build - Date - {{deviceView.osBuildDate}}
Phone Number{{deviceView.phoneNumber}}
Last Update{{deviceView.lastUpdatedTime}}
-
- {{/zone}} - - {{#zone "device-opetations"}} - {{#if deviceView.isNotRemoved}} -
- Operations -
-
- {{unit "cdmf.unit.device.operation-bar" device=deviceView backendApiUri=backendApiUri autoCompleteParams=autoCompleteParams}} -
+ {{#zone "overview-section"}} +
+
Device + Overview +
+ + + {{#if device.deviceIdentifier}} + + + + {{/if}} - {{/zone}} - + {{#if device.name}} + + + + + {{/if}} + {{#if device.vendor}} + {{#if device.model}} + + + + + {{/if}} + {{/if}} + {{#if device.status}} + + + + + {{/if}} + {{#if device.owner}} + + + + + {{/if}} + {{#if device.ownership}} + + + + + {{/if}} + {{#if device.imei}} + + + + + {{/if}} + {{#if device.udid}} + + + + + {{/if}} + {{#if device.osBuildDate}} + + + + + {{/if}} + {{#if device.phoneNumber}} + + + + + {{/if}} + {{#if device.lastUpdatedTime}} + + + + + {{/if}} + +
Device ID{{device.deviceIdentifier}}
Name{{device.name}}
Model{{device.vendor}} + {{device.model}}
Status + {{#equal device.status "ACTIVE"}}Active{{/equal}} + {{#equal device.status "INACTIVE"}}Inactive{{/equal}} + {{#equal device.status "BLOCKED"}}Blocked{{/equal}} + {{#equal device.status "REMOVED"}}Removed{{/equal}} +
Owner{{device.owner}}
Ownership{{device.ownership}}
IMEI{{device.imei}}
UDID{{device.udid}}
Firmware Build + Date + {{device.osBuildDate}}
Phone Number{{device.phoneNumber}}
Last Update{{device.lastUpdatedTime}}
+ {{/zone}} - {{#zone "device-detail-properties"}} -
-