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/bean/EnterpriseApplication.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/bean/EnterpriseApplication.java new file mode 100644 index 0000000000..2d3a45b909 --- /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/bean/EnterpriseApplication.java @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.bean; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.SyncmlOperationException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.ProfileConfigurationException; +import org.wso2.carbon.device.mgt.mobile.windows.api.operations.*; +import org.wso2.carbon.device.mgt.mobile.windows.api.operations.util.Constants; +import org.wso2.carbon.device.mgt.mobile.windows.api.operations.util.OperationCode; +import org.wso2.carbon.device.mgt.mobile.windows.api.operations.util.SyncmlGenerator; + +import java.util.ArrayList; +import java.util.List; + +@ApiModel(value = "EnterpriseApplication", description = "Information related to Enterprise Application.") +public class EnterpriseApplication extends WindowsOperation { + + private static Log log = LogFactory.getLog(EnterpriseApplication.class); + + @ApiModelProperty(name = "packageURL", value = "Package URL.") + private HostedAppxApplication hostedAppxApplication; + @ApiModelProperty(name = "packageFamilyName", value = "Package family name.") + private HostedMSIApplication hostedMSIApplication; + + public HostedAppxApplication getHostedAppxApplication() { + return hostedAppxApplication; + } + + public void setHostedAppxApplication(HostedAppxApplication hostedAppxApplication) { + this.hostedAppxApplication = hostedAppxApplication; + } + + public HostedMSIApplication getHostedMSIApplication() { + return hostedMSIApplication; + } + + public void setHostedMSIApplication(HostedMSIApplication hostedMSIApplication) { + this.hostedMSIApplication = hostedMSIApplication; + } + + public void validateRequest() throws ProfileConfigurationException { + if (getHostedAppxApplication() != null) { + if (isNullOrEmpty(getHostedAppxApplication().getpackageUri())) { + throw new ProfileConfigurationException( + "Appx package URL is not found for enterprise app installation"); + } + if (isNullOrEmpty(getHostedAppxApplication().getpackageFamilyName())) { + throw new ProfileConfigurationException( + "Appx package Family Name is not found for enterprise app installation"); + } + } else if (getHostedMSIApplication() != null) { + if (isNullOrEmpty(getHostedMSIApplication().getProductId())) { + throw new ProfileConfigurationException( + "MSI product ID is not found for enterprise app installation"); + } + if (isNullOrEmpty(getHostedMSIApplication().getContentUrl())) { + throw new ProfileConfigurationException( + "MSI product content download URL is not found for enterprise app installation"); + } + if (isNullOrEmpty(getHostedMSIApplication().getFileHash())) { + throw new ProfileConfigurationException( + "MSI product file hash is not found for enterprise app installation"); + } + } else { + throw new ProfileConfigurationException("MSI or APPX payload is not found for enterprise app installation"); + } + } + + @Override + public List createOperationContent(Operation operation) throws WindowsOperationException { + List enterpriseApplicationContent = new ArrayList<>(); + if (getHostedAppxApplication() != null) { + enterpriseApplicationContent.addAll(createAddTag(operation.getId(), + OperationCode.Command.INSTALL_ENTERPRISE_APPX_APPLICATION.getCode(), + PluginConstants.ApplicationInstallProperties.PACKAGE_FAMILY_NAME, + getHostedAppxApplication().getpackageFamilyName(), + PluginConstants.ApplicationInstallProperties.TYPE_APPX)); + enterpriseApplicationContent.addAll(createExecuteTag(operation.getId(), + OperationCode.Command.INSTALL_ENTERPRISE_APPX_APPLICATION.getCode(), + PluginConstants.ApplicationInstallProperties.PACKAGE_FAMILY_NAME, + getHostedAppxApplication().getpackageFamilyName() + + PluginConstants.ApplicationInstallProperties.HOSTED_INSTALL, + PluginConstants.ApplicationInstallProperties.TYPE_APPX)); + } else if (getHostedMSIApplication() != null) { + enterpriseApplicationContent.addAll(createAddTag(operation.getId(), + OperationCode.Command.INSTALL_ENTERPRISE_MSI_APPLICATION.getCode(), + PluginConstants.ApplicationInstallProperties.PRODUCT_ID, getHostedMSIApplication().getProductId(), + PluginConstants.ApplicationInstallProperties.TYPE_MSI)); + enterpriseApplicationContent.addAll(createExecuteTag(operation.getId(), + OperationCode.Command.INSTALL_ENTERPRISE_MSI_APPLICATION.getCode(), + PluginConstants.ApplicationInstallProperties.PRODUCT_ID, getHostedMSIApplication().getProductId(), + PluginConstants.ApplicationInstallProperties.TYPE_MSI)); + } + return enterpriseApplicationContent; + } + + /*** + * Create add objects required for APPX or MSI application installation which then will be converted as AddTag + * elements to add in SyncML XML. + * + * @param operationId used to set as command ID + * @param operationCode is the LocURI + * @param replaceOld operation code placeholder + * @param replaceNew replace value of operation code placeholder + * @param appType APPX or MSI + * @return list of AddTag objects + */ + private List createAddTag(int operationId, String operationCode, String replaceOld, String replaceNew, + String appType) { + List addTagList = new ArrayList<>(); + List itemTagList = new ArrayList<>(); + AddTag addTag = new AddTag(); + ItemTag itemTag = new ItemTag(); + TargetTag targetTag = new TargetTag(); + String locUri = operationCode.replace(replaceOld, replaceNew); + targetTag.setLocURI(locUri); + itemTag.setTarget(targetTag); + itemTagList.add(itemTag); + addTag.setCommandId(operationId); + addTag.setItems(itemTagList); + addTagList.add(addTag); + if (PluginConstants.ApplicationInstallProperties.TYPE_APPX.equals(appType)) { + if (!isNullOrEmpty(getHostedAppxApplication().getCertificateHash()) && !isNullOrEmpty( + getHostedAppxApplication().getEncodedCertificate())) { + List certItemTagList = new ArrayList<>(); + AddTag certAddTag = new AddTag(); + ItemTag certItemTag = new ItemTag(); + MetaTag certMetaTag = new MetaTag(); + TargetTag certTargetTag = new TargetTag(); + certTargetTag.setLocURI(OperationCode.Command.INSTALL_ENTERPRISE_APPX_CERTIFICATE.getCode() + .replace(PluginConstants.ApplicationInstallProperties.CERT_HASH, + getHostedAppxApplication().getCertificateHash())); + certMetaTag.setFormat(Constants.META_FORMAT_B64); + certItemTag.setTarget(certTargetTag); + certItemTag.setMeta(certMetaTag); + certItemTag.setData(getHostedAppxApplication().getEncodedCertificate()); + certItemTagList.add(certItemTag); + certAddTag.setCommandId(operationId); + certAddTag.setItems(certItemTagList); + addTagList.add(certAddTag); + } + } + return addTagList; + } + + /*** + * Create execute objects required for APPX or MSI application installation which then will be converted as + * ExecuteTag elements to add in SyncML XML. + * + * @param operationId used to set as command ID + * @param operationCode is the LocURI + * @param replaceOld operation code placeholder + * @param replaceNew replace value of operation code placeholder + * @param appType APPX or MSI + * @return list of ExecuteTag objects + * @throws WindowsOperationException + */ + private List createExecuteTag(int operationId, String operationCode, String replaceOld, + String replaceNew, String appType) throws WindowsOperationException { + List executeTagList = new ArrayList<>(); + List itemTagList = new ArrayList<>(); + ExecuteTag executeTag = new ExecuteTag(); + ItemTag itemTag = new ItemTag(); + MetaTag metaTag = new MetaTag(); + TargetTag targetTag = new TargetTag(); + Document document; + Element dependencyElement; + targetTag.setLocURI(operationCode.replace(replaceOld, replaceNew)); + metaTag.setFormat(Constants.META_FORMAT_XML); + try { + if (PluginConstants.ApplicationInstallProperties.TYPE_APPX.equals(appType)) { + document = SyncmlGenerator.generateDocument(); + Element applicationElement = document + .createElement(PluginConstants.ApplicationInstallProperties.APPLICATION); + applicationElement.setAttribute(PluginConstants.ApplicationInstallProperties.PACKAGE_URI, + getHostedAppxApplication().getpackageUri()); + if (!isNullOrEmpty(getHostedAppxApplication().getDependencyPackageUri())) { + Element dependenciesElement = document + .createElement(PluginConstants.ApplicationInstallProperties.DEPENDENCIES); + for (String dependency : getHostedAppxApplication().getDependencyPackageUri()) { + dependencyElement = document + .createElement(PluginConstants.ApplicationInstallProperties.DEPENDENCY); + dependencyElement + .setAttribute(PluginConstants.ApplicationInstallProperties.PACKAGE_URI, dependency); + dependenciesElement.appendChild(dependencyElement); + } + applicationElement.appendChild(dependenciesElement); + } + itemTag.setElementData(applicationElement); + } else if (PluginConstants.ApplicationInstallProperties.TYPE_MSI.equals(appType)) { + metaTag.setType(Constants.META_TYPE_TEXT_PLAIN); + document = SyncmlGenerator.generateDocument(); + Element contentURLElement = document + .createElement(PluginConstants.ApplicationInstallProperties.CONTENT_URL); + contentURLElement.setTextContent(getHostedMSIApplication().getContentUrl()); + Element contentURLListElement = document + .createElement(PluginConstants.ApplicationInstallProperties.CONTENT_URL_LIST); + contentURLListElement.appendChild(contentURLElement); + Element downloadElement = document.createElement(PluginConstants.ApplicationInstallProperties.DOWNLOAD); + downloadElement.appendChild(contentURLListElement); + Element fileHashElement = document + .createElement(PluginConstants.ApplicationInstallProperties.FILE_HASH); + fileHashElement.setTextContent(getHostedMSIApplication().getFileHash()); + Element validationElement = document + .createElement(PluginConstants.ApplicationInstallProperties.VALIDATION); + validationElement.appendChild(fileHashElement); + Element enforcementElement = document + .createElement(PluginConstants.ApplicationInstallProperties.ENFORCEMENT); + Element commandLineElement = document + .createElement(PluginConstants.ApplicationInstallProperties.COMMAND_LINE); + commandLineElement.setTextContent(PluginConstants.ApplicationInstallProperties.COMMAND_LINE_VALUE); + enforcementElement.appendChild(commandLineElement); + Element timeOutElement = document.createElement(PluginConstants.ApplicationInstallProperties.TIMEOUT); + timeOutElement.setTextContent(PluginConstants.ApplicationInstallProperties.TIMEOUT_VALUE); + enforcementElement.appendChild(timeOutElement); + Element retryCountElement = document + .createElement(PluginConstants.ApplicationInstallProperties.RETRY_COUNT); + retryCountElement.setTextContent(PluginConstants.ApplicationInstallProperties.RETRY_COUNT_VALUE); + enforcementElement.appendChild(retryCountElement); + Element retryIntervalElement = document + .createElement(PluginConstants.ApplicationInstallProperties.RETRY_INTERVAL); + retryIntervalElement.setTextContent(PluginConstants.ApplicationInstallProperties.RETRY_INTERVAL_VALUE); + enforcementElement.appendChild(retryIntervalElement); + Element productElement = document.createElement(PluginConstants.ApplicationInstallProperties.PRODUCT); + productElement.setAttribute(PluginConstants.ApplicationInstallProperties.VERSION, + PluginConstants.ApplicationInstallProperties.VERSION_VALUE); + productElement.appendChild(downloadElement); + productElement.appendChild(validationElement); + productElement.appendChild(enforcementElement); + Element msiInstallJobElement = document + .createElement(PluginConstants.ApplicationInstallProperties.MSI_INSTALL_JOB); + msiInstallJobElement.setAttribute(PluginConstants.ApplicationInstallProperties.ID, + PluginConstants.ApplicationInstallProperties.URL_ESCAPED_OPEN_CURLY + getHostedMSIApplication() + .getProductId() + PluginConstants.ApplicationInstallProperties.URL_ESCAPED_CLOSE_CURLY); + msiInstallJobElement.appendChild(productElement); + itemTag.setElementData(msiInstallJobElement); + } + } catch (SyncmlOperationException e) { + String errorMsg = "Error occurred while generating a document to add as a node to Data element of Execute " + + "command which is required to Install " + appType + " application."; + log.error(errorMsg); + throw new WindowsOperationException(errorMsg, e); + } + itemTag.setTarget(targetTag); + itemTag.setMeta(metaTag); + itemTagList.add(itemTag); + executeTag.setCommandId(operationId); + executeTag.setItems(itemTagList); + executeTagList.add(executeTag); + return executeTagList; + } + +} 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/bean/HostedAppxApplication.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/bean/HostedAppxApplication.java new file mode 100644 index 0000000000..61220059d3 --- /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/bean/HostedAppxApplication.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.bean; + +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +public class HostedAppxApplication { + + @ApiModelProperty(name = "packageUri", value = "Package URL.", required = true) + private String packageUri; + @ApiModelProperty(name = "packageFamilyName", value = "Package family name.", required = true) + private String packageFamilyName; + @ApiModelProperty(name = "dependencyPackageURLs", value = "Dependency Package URLs.") + private List dependencyPackageUri; + @ApiModelProperty(name = "certificateHash", value = "Application signed SHA1 certificate hash.") + private String certificateHash; + @ApiModelProperty(name = "encodedCertificate", value = "Application signed Base64 encoded certificate.") + private String encodedCertificate; + + public String getpackageUri() { + return packageUri; + } + + public void setpackageUri (String packageUri) { + this.packageUri = packageUri; + } + + public String getpackageFamilyName() { + return packageFamilyName; + } + + public void setpackageFamilyName(String packageFamilyName) { + this.packageFamilyName = packageFamilyName; + } + + public List getDependencyPackageUri() { + return dependencyPackageUri; + } + + public void setDependencyPackageUri(List dependencyPackageUri) { + this.dependencyPackageUri = dependencyPackageUri; + } + + public String getCertificateHash() { + return certificateHash; + } + + public void setCertificateHash(String certificateHash) { + this.certificateHash = certificateHash; + } + + public String getEncodedCertificate() { + return encodedCertificate; + } + + public void setEncodedCertificate(String encodedCertificate) { + this.encodedCertificate = encodedCertificate; + } +} 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/bean/HostedMSIApplication.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/bean/HostedMSIApplication.java new file mode 100644 index 0000000000..75e80f5819 --- /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/bean/HostedMSIApplication.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.bean; + +import io.swagger.annotations.ApiModelProperty; + +public class HostedMSIApplication { + + @ApiModelProperty(name = "productId", value = "Product ID.", required = true) + private String productId; + @ApiModelProperty(name = "contentUrl", value = "Content URL.", required = true) + private String contentUrl; + @ApiModelProperty(name = "fileHash", value = "File Hash.", required = true) + private String fileHash; + + public String getProductId() { + return productId; + } + + public void setProductId(String productId) { + this.productId = productId; + } + + public String getContentUrl() { + return contentUrl; + } + + public void setContentUrl(String contentUrl) { + this.contentUrl = contentUrl; + } + + public String getFileHash() { + return fileHash; + } + + public void setFileHash(String fileHash) { + this.fileHash = fileHash; + } +} 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/bean/WindowsOperation.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/bean/WindowsOperation.java new file mode 100644 index 0000000000..0466f818c6 --- /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/bean/WindowsOperation.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.bean; + +import com.google.gson.Gson; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.mobile.windows.api.operations.WindowsOperationException; + +import java.util.List; + +/*** + * This abstract class is used for extending generic functions with regard to operation. + */ +public abstract class WindowsOperation { + + public abstract List createOperationContent(Operation operation) throws WindowsOperationException; + + /*** + * Converts operation object to a json format. + * + * @return JSON formatted String + */ + public String toJSON() { + Gson gson = new Gson(); + return gson.toJson(this); + } + + /** + * Checks if the given string is null or empty + * + * @param value string value to check + * @return boolean value of null or empty + */ + public boolean isNullOrEmpty(String value) { + return value == null || value.trim().isEmpty(); + } + + /*** + * Checks if the given list is null or empty + * + * @param value string list value to check + * @return boolean value of null or empty + */ + public boolean isNullOrEmpty(List value) { + return value == null || value.isEmpty(); + } +} 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/bean/wrapper/EnterpriseApplicationBeanWrapper.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/bean/wrapper/EnterpriseApplicationBeanWrapper.java new file mode 100644 index 0000000000..cd39830834 --- /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/bean/wrapper/EnterpriseApplicationBeanWrapper.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.bean.wrapper; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.mobile.windows.api.bean.EnterpriseApplication; + +import java.util.List; + +@ApiModel(value = "EnterpriseApplicationBeanWrapper", + description = "Information related to Enterprise Application.") +public class EnterpriseApplicationBeanWrapper { + + @ApiModelProperty(name = "deviceIDs", + value = "List of device Ids to be need to execute operation.", required = true) + private List deviceIDs; + @ApiModelProperty(name = "operation", + value = "Enterprise Application.", required = true) + private EnterpriseApplication operation; + + public List getDeviceIDs() { + return deviceIDs; + } + + public void setDeviceIDs(List deviceIDs) { + this.deviceIDs = deviceIDs; + } + + public EnterpriseApplication getOperation() { + return operation; + } + + public void setOperation(EnterpriseApplication operation) { + this.operation = operation; + } +} 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 897a7d2bba..bbe2c7f54b 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 @@ -14,6 +14,23 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.common; @@ -167,6 +184,7 @@ public final class PluginConstants { public static final String SYNCML_SOURCE = "Source"; public static final String SYNCML_DATA = "Data"; + public static final String SYNCML_META = "Meta"; public static final String SYNCML_CMD = "Cmd"; public static final String SYNCML_CHAL = "ChallengeTag"; public static final String SYNCML_CMD_ID = "CmdID"; @@ -221,6 +239,7 @@ public final class PluginConstants { public static final String LONGITUDE = "LONGITUDE"; public static final String LATITUDE = "LATITUDE"; + public static final String DEVICE_UNENROLL_META_TYPE = "com.microsoft:mdm.unenrollment.userrequest"; } /** @@ -274,6 +293,7 @@ public final class PluginConstants { public static final String LONGITUDE = "LONGITUDE"; public static final String LATITUDE = "LATITUDE"; public static final String DEVICE_REBOOT = "DEVICE_REBOOT"; + public static final String INSTALL_ENTERPRISE_APPLICATION = "INSTALL_ENTERPRISE_APPLICATION"; } /** @@ -358,4 +378,45 @@ public final class PluginConstants { public static final String IMEI = "MobileEquipmentId"; public static final String TYPE = "DeviceType"; } + + public final class ApplicationInstallProperties { + private ApplicationInstallProperties() { + throw new AssertionError(); + } + public static final String APPLICATION = "Application"; + public static final String TYPE_APPX = "APPX"; + public static final String TYPE_MSI = "MSI"; + public static final String PACKAGE_FAMILY_NAME = "{PackageFamilyName}"; + public static final String PRODUCT_ID = "{ProductId}"; + public static final String CERT_HASH = "{CertHash}"; + public static final String HOSTED_INSTALL = "/HostedInstall"; + + //XML Related Constants + public static final String ID = "id"; + public static final String PACKAGE_URI = "PackageUri"; + public static final String DEPENDENCIES = "Dependencies"; + public static final String DEPENDENCY = "Dependency"; + public static final String CONTENT_URL = "ContentURL"; + public static final String CONTENT_URL_LIST = "ContentURLList"; + public static final String DOWNLOAD = "Download"; + public static final String COMMAND_LINE = "CommandLine"; + public static final String COMMAND_LINE_VALUE = "/quiet"; + public static final String FILE_HASH = "FileHash"; + public static final String VALIDATION = "Validation"; + public static final String ENFORCEMENT = "Enforcement"; + public static final String TIMEOUT = "TimeOut"; + public static final String RETRY_COUNT = "RetryCount"; + public static final String RETRY_INTERVAL = "RetryInterval"; + public static final String PRODUCT = "Product"; + public static final String MSI_INSTALL_JOB = "MsiInstallJob"; + public static final String VERSION = "version"; + public static final String VERSION_VALUE = "1.0.0"; + public static final String TIMEOUT_VALUE = "5"; + public static final String RETRY_COUNT_VALUE = "3"; + public static final String RETRY_INTERVAL_VALUE = "5"; + public static final String LICENSE = "License"; + public static final String CONTENT = "Content"; + public static final String URL_ESCAPED_OPEN_CURLY = "%7B"; + public static final String URL_ESCAPED_CLOSE_CURLY = "%7D"; + } } 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/exceptions/ProfileConfigurationException.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/exceptions/ProfileConfigurationException.java new file mode 100644 index 0000000000..62dcc0ae00 --- /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/common/exceptions/ProfileConfigurationException.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.common.exceptions; + +public class ProfileConfigurationException extends Exception { + + private static final long serialVersionUID = 8025559931927889261L; + + public ProfileConfigurationException(String errorMsg) { + super(errorMsg); + } + + public ProfileConfigurationException(String errorMsg, Throwable throwable) { + super(errorMsg, throwable); + } +} 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/AlertTag.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/AlertTag.java index f4dce70d38..26b4140a57 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/AlertTag.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/AlertTag.java @@ -14,6 +14,23 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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; @@ -22,6 +39,9 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.wso2.carbon.device.mgt.mobile.windows.api.operations.util.Constants; +import java.util.Iterator; +import java.util.List; + /** * Inform an event occurred from device to server. */ @@ -29,6 +49,7 @@ public class AlertTag { int commandId = -1; String data; + List items; public int getCommandId() { return commandId; @@ -46,6 +67,14 @@ public class AlertTag { this.data = data; } + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + public void buildAlertElement(Document doc, Element rootElement) { Element alert = doc.createElement(Constants.ALERT); rootElement.appendChild(alert); @@ -59,5 +88,13 @@ public class AlertTag { data.appendChild(doc.createTextNode(getData())); alert.appendChild(data); } + if (getItems() != null) { + for (Iterator itemIterator = getItems().iterator(); itemIterator.hasNext();) { + ItemTag item = itemIterator.next(); + if (item != null) { + item.buildItemElement(doc, alert); + } + } + } } } 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/ItemTag.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/ItemTag.java index 41081af725..571d62c970 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/ItemTag.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/ItemTag.java @@ -14,12 +14,30 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.Node; import org.wso2.carbon.device.mgt.mobile.windows.api.operations.util.Constants; /** @@ -31,6 +49,7 @@ public class ItemTag { SourceTag source; String data; MetaTag meta; + Element elementData; public MetaTag getMeta() { return meta; @@ -64,6 +83,14 @@ public class ItemTag { this.target = target; } + public Element getElementData() { + return elementData; + } + + public void setElementData(Element elementData) { + this.elementData = elementData; + } + public void buildItemElement(Document doc, Element rootElement) { Element item = doc.createElement(Constants.ITEM); rootElement.appendChild(item); @@ -77,14 +104,19 @@ public class ItemTag { getSource().buildSourceElement(doc, item); } } - if (getData() != null) { - Element data = doc.createElement(Constants.DATA); - data.appendChild(doc.createTextNode(getData())); - item.appendChild(data); - } if (getMeta() != null) { getMeta().buildMetaElement(doc, item); } - + if (getData() != null || getElementData()!= null) { + Element data = doc.createElement(Constants.DATA); + if (getData() != null) { + data.appendChild(doc.createTextNode(getData())); + } + if (getElementData() != null) { + Node node = doc.importNode(getElementData(), true); + data.appendChild(node); + } + item.appendChild(data); + } } } 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 b0d3fb85d6..78a7c5dee9 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 @@ -14,6 +14,23 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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; @@ -78,9 +95,14 @@ public class Constants { public static final String SEQUENCE = "Sequence"; public static final String META_FORMAT_INT = "int"; public static final String META_FORMAT_CHARACTER = "chr"; + public static final String META_FORMAT_XML = "xml"; + public static final String META_FORMAT_B64 = "b64"; + public static final String META_TYPE_TEXT_PLAIN = "text/plain"; public static final String SCOPE = "scope"; + public static final String FORWARD_SLASH = "/"; + /** * SynclML service related constants. */ 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 2f22c8ae77..448375a7e9 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 @@ -14,6 +14,23 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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; @@ -94,7 +111,10 @@ public class OperationCode { LONGITUDE("./Vendor/MSFT/RemoteFind/Location/Longitude"), LATITUDE("./Vendor/MSFT/RemoteFind/Location/Latitude"), TEST("./Vendor/MSFT/DiagnosticLog/EtwLog/Collectors"), - DEVICE_REBOOT("./Vendor/MSFT/Reboot/RebootNow"); + DEVICE_REBOOT("./Vendor/MSFT/Reboot/RebootNow"), + INSTALL_ENTERPRISE_APPX_APPLICATION("./Device/Vendor/MSFT/EnterpriseModernAppManagement/AppInstallation/{PackageFamilyName}"), + INSTALL_ENTERPRISE_APPX_CERTIFICATE("./Device/Vendor/MSFT/RootCATrustedCertificates/Root/{CertHash}/EncodedCertificate"), + INSTALL_ENTERPRISE_MSI_APPLICATION("./Device/Vendor/MSFT/EnterpriseDesktopAppManagement/MSI/%7B{ProductId}%7D/DownloadInstall"); 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/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 389dd0cdcf..8d9a7cb4d0 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 @@ -14,6 +14,23 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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; @@ -21,10 +38,9 @@ package org.wso2.carbon.device.mgt.mobile.windows.api.operations.util; import com.google.gson.Gson; import org.json.JSONException; import org.json.JSONObject; -import org.w3c.dom.Document; -import org.w3c.dom.Element; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.mobile.windows.api.bean.EnterpriseApplication; import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; import org.wso2.carbon.device.mgt.mobile.windows.api.common.SyncmlCommandType; import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.SyncmlMessageFormatException; @@ -87,7 +103,7 @@ public class OperationReply { * @throws org.wso2.carbon.policy.mgt.common.FeatureManagementException */ public String generateReply(SyncmlDocument syncmlDocument, List operations) - throws SyncmlMessageFormatException, SyncmlOperationException { + throws SyncmlMessageFormatException, SyncmlOperationException, WindowsOperationException { OperationReply operationReply; SyncmlGenerator generator; @@ -102,7 +118,8 @@ public class OperationReply { return generator.generatePayload(syncmlResponse); } - public SyncmlDocument generateReply() throws SyncmlMessageFormatException, SyncmlOperationException { + public SyncmlDocument generateReply() + throws SyncmlMessageFormatException, SyncmlOperationException, WindowsOperationException { generateHeader(); generateBody(); return replySyncmlDocument; @@ -146,14 +163,11 @@ public class OperationReply { replySyncmlDocument.setHeader(header); } - private void generateBody() throws SyncmlMessageFormatException, SyncmlOperationException { + private void generateBody() + throws SyncmlMessageFormatException, SyncmlOperationException, WindowsOperationException { SyncmlBody syncmlBody = generateStatuses(); try { appendOperations(syncmlBody); - } catch (PolicyManagementException e) { - throw new SyncmlOperationException("Error occurred while retrieving policy operations.", e); - } catch (FeatureManagementException e) { - throw new SyncmlOperationException("Error occurred while retrieving effective policy operations.", e); } catch (JSONException e) { throw new SyncmlMessageFormatException("Error Occurred while parsing operation object.", e); } @@ -235,8 +249,8 @@ public class OperationReply { return syncmlBodyReply; } - private void appendOperations(SyncmlBody syncmlBody) throws PolicyManagementException, - FeatureManagementException, JSONException, SyncmlOperationException { + private void appendOperations(SyncmlBody syncmlBody) + throws JSONException, SyncmlOperationException, WindowsOperationException { GetTag getElement = new GetTag(); List getElements = new ArrayList<>(); List executeElements = new ArrayList<>(); @@ -359,8 +373,23 @@ public class OperationReply { } } } - break; } + break; + case PROFILE: + if (PluginConstants.OperationCodes.INSTALL_ENTERPRISE_APPLICATION.equals(operation.getCode())) { + EnterpriseApplication enterpriseApplication = gson + .fromJson((String) operation.getPayLoad(), EnterpriseApplication.class); + List enterpriseApplicationContent = enterpriseApplication + .createOperationContent(operation); + for (Object object : enterpriseApplicationContent) { + if (object instanceof AddTag) { + addElements.add((AddTag) object); + } else if (object instanceof ExecuteTag) { + executeElements.add((ExecuteTag) object); + } + } + } + break; } } if (!replaceItems.isEmpty()) { 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/SyncmlGenerator.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/SyncmlGenerator.java index 1bdc5062ea..926ef528b6 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/SyncmlGenerator.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/SyncmlGenerator.java @@ -14,6 +14,23 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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; @@ -48,7 +65,7 @@ public class SyncmlGenerator { return transformDocument(doc); } - private static Document generateDocument() throws SyncmlOperationException { + public static Document generateDocument() throws SyncmlOperationException { DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder; try { 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/SyncmlParser.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/SyncmlParser.java index f0737ca68f..af5b339774 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/SyncmlParser.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/SyncmlParser.java @@ -14,13 +14,33 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import org.wso2.carbon.device.mgt.mobile.windows.api.bean.EnterpriseApplication; import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; import org.wso2.carbon.device.mgt.mobile.windows.api.operations.*; @@ -375,8 +395,15 @@ public class SyncmlParser { AlertTag alert = new AlertTag(); String commandID = node.getChildNodes().item(0).getTextContent().trim(); String data = node.getChildNodes().item(1).getTextContent().trim(); + List items = new ArrayList<>(); + for (int i = 1; i < node.getChildNodes().getLength() - 1; i++) { + items.add(generateItem(node.getChildNodes().item(i + 1))); + } alert.setCommandId(Integer.valueOf(commandID)); alert.setData(data); + if (!items.isEmpty()) { + alert.setItems(items); + } return alert; } @@ -423,6 +450,15 @@ public class SyncmlParser { throw new IllegalStateException(); } item.setData(data); + } else if (PluginConstants.SyncML.SYNCML_META.equals(nodeName)) { + MetaTag metaTag = new MetaTag(); + if (itemNode.getChildNodes().item(0) != null) { + metaTag.setType(itemNode.getChildNodes().item(0).getTextContent().trim()); + } + if (itemNode.getChildNodes().item(1) != null) { + metaTag.setFormat(itemNode.getChildNodes().item(1).getTextContent().trim()); + } + item.setMeta(metaTag); } } return item; 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 2109462899..4d9f40e0db 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 @@ -14,6 +14,23 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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; @@ -23,6 +40,7 @@ import io.swagger.annotations.*; import org.wso2.carbon.apimgt.annotations.api.Scope; import org.wso2.carbon.apimgt.annotations.api.Scopes; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; +import org.wso2.carbon.device.mgt.mobile.windows.api.bean.wrapper.EnterpriseApplicationBeanWrapper; import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsDeviceEnrolmentException; import org.wso2.carbon.device.mgt.mobile.windows.api.operations.util.Constants; @@ -107,6 +125,12 @@ import java.util.List; description = "Lock reset on Windows devices", key = "perm:windows:location", permissions = {"/device-mgt/devices/owning-device/operations/windows/location"} + ), + @Scope( + name = "Install Enterprise Application", + description = "Installing an Enterprise Application", + key = "perm:windows:enterprise-app", + permissions = {"/device-mgt/devices/owning-device/operations/windows/enterprise-application"} ) } ) @@ -536,5 +560,65 @@ public interface DeviceManagementAdminService { required = true) List deviceIDs); + + @POST + @Path("/enterprise-application") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Installing an Enterprise Application", + notes = "Install an enterprise application on Windows devices.", + response = Activity.class, + tags = "Windows Device Management Administrative Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:windows:enterprise-app") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 201, + message = "Created. \n Successfully added Enterprise application operation.", + response = Activity.class, + 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.\n", + 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 adding the enterprise application operation.") + }) + Response installEnterpriseApplication( + @ApiParam( + name = "enterpriseApplicationBeanWrapper", + value = "Enterprise application configuration and Device IDs", + required = true) + EnterpriseApplicationBeanWrapper enterpriseApplicationBeanWrapper); } 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 56e9334962..078b1199e0 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 @@ -14,19 +14,39 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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 com.ibm.wsdl.OperationImpl; import io.swagger.annotations.ApiParam; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpStatus; import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.InvalidDeviceException; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; import org.wso2.carbon.device.mgt.core.operation.mgt.CommandOperation; +import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation; +import org.wso2.carbon.device.mgt.mobile.windows.api.bean.EnterpriseApplication; +import org.wso2.carbon.device.mgt.mobile.windows.api.bean.wrapper.EnterpriseApplicationBeanWrapper; import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; import org.wso2.carbon.device.mgt.mobile.windows.api.common.beans.ErrorResponse; import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.BadRequestException; @@ -35,6 +55,7 @@ import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsDe import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsOperationsException; 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.common.exceptions.ProfileConfigurationException; import org.wso2.carbon.device.mgt.mobile.windows.api.services.DeviceManagementAdminService; import javax.ws.rs.*; @@ -51,7 +72,7 @@ import java.util.List; @Path("/admin/devices") public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminService { - private static Log log = LogFactory.getLog(OperationImpl.class); + private static Log log = LogFactory.getLog(DeviceManagementAdminServiceImpl.class); /** * REST endpoint for the Device Lock operation @@ -336,4 +357,58 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(errorMessage).build()); } } + + /** + * Rest endpoint for Enterprise Application (MSI or APPX) installation + * + * @param enterpriseApplicationBeanWrapper Enterprise application installation payload object + * @return Response object for client. + */ + @POST + @Path("/enterprise-application") + public Response installEnterpriseApplication(@ApiParam( + name = "enterpriseApplicationBeanWrapper", + value = "Enterprise application configuration and Device IDs", + required = true) EnterpriseApplicationBeanWrapper enterpriseApplicationBeanWrapper) { + if (log.isDebugEnabled()) { + log.debug("Invoking Windows install enterprise application device operation"); + } + if (enterpriseApplicationBeanWrapper == null || enterpriseApplicationBeanWrapper.getOperation() == null) { + String errorMessage = "The payload of the application installing operation is incorrect"; + log.error(errorMessage); + throw new BadRequestException( + new ErrorResponse.ErrorResponseBuilder().setCode(HttpStatus.SC_BAD_REQUEST).setMessage(errorMessage) + .build()); + } + try { + EnterpriseApplication enterpriseApplication = enterpriseApplicationBeanWrapper.getOperation(); + enterpriseApplication.validateRequest(); + ProfileOperation operation = new ProfileOperation(); + operation.setCode(PluginConstants.OperationCodes.INSTALL_ENTERPRISE_APPLICATION); + operation.setType(Operation.Type.PROFILE); + operation.setPayLoad(enterpriseApplication.toJSON()); + return WindowsAPIUtils.getOperationResponse(enterpriseApplicationBeanWrapper.getDeviceIDs(), operation); + } catch (ProfileConfigurationException e) { + throw new BadRequestException(new ErrorResponse.ErrorResponseBuilder().setCode(HttpStatus.SC_BAD_REQUEST) + .setMessage(e.getMessage()).build()); + } catch (OperationManagementException e) { + String errorMessage = "Issue in retrieving operation management service instance"; + log.error(errorMessage, e); + throw new UnexpectedServerErrorException( + new ErrorResponse.ErrorResponseBuilder().setCode(HttpStatus.SC_INTERNAL_SERVER_ERROR) + .setMessage(errorMessage).build()); + } catch (DeviceManagementException e) { + String errorMessage = "Issue in retrieving device management service instance"; + log.error(errorMessage, e); + throw new UnexpectedServerErrorException( + new ErrorResponse.ErrorResponseBuilder().setCode(HttpStatus.SC_INTERNAL_SERVER_ERROR) + .setMessage(errorMessage).build()); + } catch (InvalidDeviceException e) { + String errorMessage = "Invalid Device Identifiers found."; + log.error(errorMessage, e); + throw new BadRequestException( + new ErrorResponse.ErrorResponseBuilder().setCode(HttpStatus.SC_BAD_REQUEST).setMessage(errorMessage) + .build()); + } + } } 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 index 5b8d52a44b..796e4759a9 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/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 @@ -14,6 +14,23 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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; @@ -26,7 +43,6 @@ 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.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; @@ -38,6 +54,7 @@ import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.AuthenticationI 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.ItemTag; +import org.wso2.carbon.device.mgt.mobile.windows.api.operations.MetaTag; import org.wso2.carbon.device.mgt.mobile.windows.api.operations.ReplaceTag; import org.wso2.carbon.device.mgt.mobile.windows.api.operations.SyncmlDocument; import org.wso2.carbon.device.mgt.mobile.windows.api.operations.SyncmlHeader; @@ -61,10 +78,8 @@ 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 { - + @Override public Response getResponse(Document request) + throws WindowsDeviceEnrolmentException, WindowsOperationException, WindowsConfigurationException { int msgId; int sessionId; String user; @@ -127,12 +142,17 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { carbonCtx.setTenantId(cacheToken.getTenanatID()); } if ((syncmlDocument.getBody().getAlert() != null)) { - if (!syncmlDocument.getBody().getAlert().getData().equals(Constants.DISENROLL_ALERT_DATA)) { - pendingOperations = operationHandler.getPendingOperations(syncmlDocument); - operationHandler.checkForDeviceWipe(pendingOperations, deviceIdentifier); - return Response.ok().entity(operationReply.generateReply( - syncmlDocument, pendingOperations)).build(); - } else { + List disEnrollItemList = syncmlDocument.getBody().getAlert().getItems(); + String disEnrollMetaType = null; + if (disEnrollItemList != null && !disEnrollItemList.isEmpty()) { + MetaTag disEnrollMetaTag = disEnrollItemList.get(0).getMeta(); + if (disEnrollMetaTag != null) { + disEnrollMetaType = disEnrollMetaTag.getType(); + } + } + if (syncmlDocument.getBody().getAlert().getData().equals(Constants.DISENROLL_ALERT_DATA) + && disEnrollMetaType != null && PluginConstants.SyncML.DEVICE_UNENROLL_META_TYPE + .equals(disEnrollMetaType.trim())) { if (WindowsAPIUtils.getDeviceManagementService().getDevice(deviceIdentifier, false) != null) { operationHandler.updateDisenrollOperationStatus(deviceIdentifier); WindowsAPIUtils.getDeviceManagementService().disenrollDevice(deviceIdentifier); @@ -142,12 +162,17 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { log.error(msg); return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); } + } else { + pendingOperations = operationHandler.getPendingOperations(syncmlDocument); + operationHandler.checkForDeviceWipe(pendingOperations, deviceIdentifier); + return Response.ok().entity(operationReply.generateReply(syncmlDocument, pendingOperations)) + .build(); } } else { pendingOperations = operationHandler.getPendingOperations(syncmlDocument); operationHandler.checkForDeviceWipe(pendingOperations, deviceIdentifier); - return Response.ok().entity(operationReply.generateReply( - syncmlDocument, pendingOperations)).build(); + return Response.ok().entity(operationReply.generateReply(syncmlDocument, pendingOperations)) + .build(); } } } 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 9add9bf172..547e3def91 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 @@ -14,6 +14,22 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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 go */ package org.wso2.carbon.device.mgt.mobile.windows.api.services.syncml.impl; @@ -371,7 +387,7 @@ public class SyncmlServiceImpl implements SyncmlService { * @throws org.wso2.carbon.policy.mgt.common.FeatureManagementException */ public String generateReply(SyncmlDocument syncmlDocument, List operations) - throws SyncmlMessageFormatException, SyncmlOperationException { + throws SyncmlMessageFormatException, SyncmlOperationException, WindowsOperationException { OperationReply operationReply; SyncmlGenerator generator;