diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/ApplicationManagerImpl.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/ApplicationManagerImpl.java index f560d8ce82..ec7ed25190 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/ApplicationManagerImpl.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/ApplicationManagerImpl.java @@ -778,6 +778,8 @@ public class ApplicationManagerImpl implements ApplicationManager { return Constants.GOOGLE_PLAY_STORE_URL; } else if (DeviceTypes.IOS.toString().equalsIgnoreCase(deviceType)) { return Constants.APPLE_STORE_URL; + } else if (DeviceTypes.WINDOWS.toString().equalsIgnoreCase(deviceType)) { + return Constants.MICROSOFT_STORE_URL; } else { throw new IllegalArgumentException("No such device with the name " + deviceType); } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/util/Constants.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/util/Constants.java index b5b5fd5154..0b22db0668 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/util/Constants.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/util/Constants.java @@ -74,6 +74,7 @@ public class Constants { public static final String IS_USER_ABLE_TO_VIEW_ALL_ROLES = "isUserAbleToViewAllRoles"; public static final String GOOGLE_PLAY_STORE_URL = "https://play.google.com/store/apps/details?id="; public static final String APPLE_STORE_URL = "https://itunes.apple.com/country/app/app-name/id"; + public static final String MICROSOFT_STORE_URL = "https://apps.microsoft.com/detail/"; public static final String GOOGLE_PLAY_SYNCED_APP = "GooglePlaySyncedApp"; // Subscription task related constants diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/MDMAppConstants.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/MDMAppConstants.java index 60d9503c97..da1714ede0 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/MDMAppConstants.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/MDMAppConstants.java @@ -58,6 +58,8 @@ public class MDMAppConstants { } public static final String INSTALL_ENTERPRISE_APPLICATION = "INSTALL_ENTERPRISE_APPLICATION"; public static final String UNINSTALL_ENTERPRISE_APPLICATION = "UNINSTALL_ENTERPRISE_APPLICATION"; + public static final String INSTALL_STORE_APPLICATION = "INSTALL_STORE_APPLICATION"; + public static final String UNINSTALL_STORE_APPLICATION = "UNINSTALL_STORE_APPLICATION"; public static final String INSTALL_WEB_CLIP_APPLICATION = "INSTALL_WEB_CLIP"; public static final String UNINSTALL_WEB_CLIP_APPLICATION = "UNINSTALL_WEB_CLIP"; //App type constants related to window device type diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/app/mgt/windows/AppStoreApplication.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/app/mgt/windows/AppStoreApplication.java new file mode 100644 index 0000000000..85a6cbd9a1 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/app/mgt/windows/AppStoreApplication.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018 - 2024, 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 io.entgra.device.mgt.core.device.mgt.common.app.mgt.windows; + +import com.google.gson.Gson; +import java.io.Serializable; + +public class AppStoreApplication implements Serializable { + + private String type; + private String packageIdentifier; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getPackageIdentifier() { + return packageIdentifier; + } + + public void setPackageIdentifier(String packageIdentifier) { + this.packageIdentifier = packageIdentifier; + } + + public String toJSON() { + Gson gson = new Gson(); + return gson.toJson(this); + } +} diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/util/MDMWindowsOperationUtil.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/util/MDMWindowsOperationUtil.java index a1f0e0e31d..14050b6ea4 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/util/MDMWindowsOperationUtil.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/util/MDMWindowsOperationUtil.java @@ -27,6 +27,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import io.entgra.device.mgt.core.device.mgt.common.MDMAppConstants; import io.entgra.device.mgt.core.device.mgt.common.app.mgt.App; +import io.entgra.device.mgt.core.device.mgt.common.app.mgt.windows.AppStoreApplication; import io.entgra.device.mgt.core.device.mgt.common.app.mgt.windows.EnterpriseApplication; import io.entgra.device.mgt.core.device.mgt.common.app.mgt.windows.HostedAppxApplication; import io.entgra.device.mgt.core.device.mgt.common.app.mgt.windows.HostedMSIApplication; @@ -62,64 +63,26 @@ public class MDMWindowsOperationUtil { switch (application.getType()) { case ENTERPRISE: - operation.setCode(MDMAppConstants.WindowsConstants.INSTALL_ENTERPRISE_APPLICATION); EnterpriseApplication enterpriseApplication = new EnterpriseApplication(); - if (appType.equalsIgnoreCase(MDMAppConstants.WindowsConstants.APPX)) { - HostedAppxApplication hostedAppxApplication = new HostedAppxApplication(); - List dependencyPackageList = new ArrayList<>(); - for (int i = 0; i < metaJsonArray.size(); i++) { - JsonElement metaElement = metaJsonArray.get(i); - JsonObject metaObject = metaElement.getAsJsonObject(); - - if (MDMAppConstants.WindowsConstants.APPX_PACKAGE_URI.equals(metaObject.get("key").getAsString())) { - hostedAppxApplication.setPackageUri(metaObject.get("value").getAsString().trim()); - } - else if (MDMAppConstants.WindowsConstants.APPX_PACKAGE_FAMILY_NAME.equals(metaObject.get("key").getAsString())) { - hostedAppxApplication.setPackageFamilyName(metaObject.get("value").getAsString().trim()); - } - else if (MDMAppConstants.WindowsConstants.APPX_DEPENDENCY_PACKAGE_URL.equals(metaObject.get("key").getAsString()) - && metaObject.has("value")) { - dependencyPackageList.add(metaObject.get("value").getAsString().trim()); - hostedAppxApplication.setDependencyPackageUri(dependencyPackageList); - } - else if (MDMAppConstants.WindowsConstants.APPX_CERTIFICATE_HASH.equals(metaObject.get("key").getAsString()) - && metaObject.has("value")) { - hostedAppxApplication.setCertificateHash(metaObject.get("value").getAsString().trim()); - } - else if (MDMAppConstants.WindowsConstants.APPX_ENCODED_CERT_CONTENT.equals(metaObject.get("key").getAsString()) - && metaObject.has("value")) { - hostedAppxApplication.setEncodedCertificate(metaObject.get("value").getAsString().trim()); - } - } - enterpriseApplication.setHostedAppxApplication(hostedAppxApplication); - - } else if (appType.equalsIgnoreCase(MDMAppConstants.WindowsConstants.MSI)) { - HostedMSIApplication hostedMSIApplication = new HostedMSIApplication(); - for (int i = 0; i < metaJsonArray.size(); i++) { - JsonElement metaElement = metaJsonArray.get(i); - JsonObject metaObject = metaElement.getAsJsonObject(); - if (MDMAppConstants.WindowsConstants.MSI_PRODUCT_ID.equals(metaObject.get("key").getAsString())) { - hostedMSIApplication.setProductId(metaObject.get("value").getAsString().trim()); - } - else if (MDMAppConstants.WindowsConstants.MSI_CONTENT_URI.equals(metaObject.get("key").getAsString())) { - hostedMSIApplication.setContentUrl(metaObject.get("value").getAsString().trim()); - } - else if (MDMAppConstants.WindowsConstants.MSI_FILE_HASH.equals(metaObject.get("key").getAsString())) { - hostedMSIApplication.setFileHash(metaObject.get("value").getAsString().trim()); - } - } - enterpriseApplication.setHostedMSIApplication(hostedMSIApplication); - } + createEnterpriseAppPayload(appType, metaJsonArray, enterpriseApplication); + operation.setCode(MDMAppConstants.WindowsConstants.INSTALL_ENTERPRISE_APPLICATION); operation.setPayLoad(enterpriseApplication.toJSON()); break; + case PUBLIC: + AppStoreApplication appStoreApplication = new AppStoreApplication(); + appStoreApplication.setType(application.getType().toString()); + appStoreApplication.setPackageIdentifier(application.getIdentifier()); + operation.setCode(MDMAppConstants.WindowsConstants.INSTALL_STORE_APPLICATION); + operation.setPayLoad(appStoreApplication.toJSON()); + break; case WEB_CLIP: - operation.setCode(MDMAppConstants.WindowsConstants.INSTALL_WEB_CLIP_APPLICATION); WebClipApplication webClipApplication = new WebClipApplication(); webClipApplication.setUrl(application.getLocation()); webClipApplication.setName(application.getName()); webClipApplication.setIcon(application.getIconImage()); webClipApplication.setProperties(application.getProperties()); webClipApplication.setType(application.getType().toString()); + operation.setCode(MDMAppConstants.WindowsConstants.INSTALL_WEB_CLIP_APPLICATION); operation.setPayLoad(webClipApplication.toJSON()); break; default: @@ -148,64 +111,26 @@ public class MDMWindowsOperationUtil { switch (application.getType()) { case ENTERPRISE: - operation.setCode(MDMAppConstants.WindowsConstants.UNINSTALL_ENTERPRISE_APPLICATION); EnterpriseApplication enterpriseApplication = new EnterpriseApplication(); - if (appType.equalsIgnoreCase(MDMAppConstants.WindowsConstants.APPX)) { - HostedAppxApplication hostedAppxApplication = new HostedAppxApplication(); - List dependencyPackageList = new ArrayList<>(); - for (int i = 0; i < metaJsonArray.size(); i++) { - JsonElement metaElement = metaJsonArray.get(i); - JsonObject metaObject = metaElement.getAsJsonObject(); - - if (MDMAppConstants.WindowsConstants.APPX_PACKAGE_URI.equals(metaObject.get("key").getAsString())) { - hostedAppxApplication.setPackageUri(metaObject.get("value").getAsString().trim()); - } - else if (MDMAppConstants.WindowsConstants.APPX_PACKAGE_FAMILY_NAME.equals(metaObject.get("key").getAsString())) { - hostedAppxApplication.setPackageFamilyName(metaObject.get("value").getAsString().trim()); - } - else if (MDMAppConstants.WindowsConstants.APPX_DEPENDENCY_PACKAGE_URL.equals(metaObject.get("key").getAsString()) - && metaObject.has("value")) { - dependencyPackageList.add(metaObject.get("value").getAsString().trim()); - hostedAppxApplication.setDependencyPackageUri(dependencyPackageList); - } - else if (MDMAppConstants.WindowsConstants.APPX_CERTIFICATE_HASH.equals(metaObject.get("key").getAsString()) - && metaObject.has("value")) { - hostedAppxApplication.setCertificateHash(metaObject.get("value").getAsString().trim()); - } - else if (MDMAppConstants.WindowsConstants.APPX_ENCODED_CERT_CONTENT.equals(metaObject.get("key").getAsString()) - && metaObject.has("value")) { - hostedAppxApplication.setEncodedCertificate(metaObject.get("value").getAsString().trim()); - } - } - enterpriseApplication.setHostedAppxApplication(hostedAppxApplication); - - } else if (appType.equalsIgnoreCase(MDMAppConstants.WindowsConstants.MSI)) { - HostedMSIApplication hostedMSIApplication = new HostedMSIApplication(); - for (int i = 0; i < metaJsonArray.size(); i++) { - JsonElement metaElement = metaJsonArray.get(i); - JsonObject metaObject = metaElement.getAsJsonObject(); - if (MDMAppConstants.WindowsConstants.MSI_PRODUCT_ID.equals(metaObject.get("key").getAsString())) { - hostedMSIApplication.setProductId(metaObject.get("value").getAsString().trim()); - } - else if (MDMAppConstants.WindowsConstants.MSI_CONTENT_URI.equals(metaObject.get("key").getAsString())) { - hostedMSIApplication.setContentUrl(metaObject.get("value").getAsString().trim()); - } - else if (MDMAppConstants.WindowsConstants.MSI_FILE_HASH.equals(metaObject.get("key").getAsString())) { - hostedMSIApplication.setFileHash(metaObject.get("value").getAsString().trim()); - } - } - enterpriseApplication.setHostedMSIApplication(hostedMSIApplication); - } + createEnterpriseAppPayload(appType, metaJsonArray, enterpriseApplication); + operation.setCode(MDMAppConstants.WindowsConstants.UNINSTALL_ENTERPRISE_APPLICATION); operation.setPayLoad(enterpriseApplication.toJSON()); break; + case PUBLIC: + AppStoreApplication appStoreApplication = new AppStoreApplication(); + appStoreApplication.setType(application.getType().toString()); + appStoreApplication.setPackageIdentifier(application.getIdentifier()); + operation.setCode(MDMAppConstants.WindowsConstants.UNINSTALL_STORE_APPLICATION); + operation.setPayLoad(appStoreApplication.toJSON()); + break; case WEB_CLIP: - operation.setCode(MDMAppConstants.WindowsConstants.UNINSTALL_WEB_CLIP_APPLICATION); WebClipApplication webClipApplication = new WebClipApplication(); webClipApplication.setUrl(application.getLocation()); webClipApplication.setName(application.getName()); webClipApplication.setIcon(application.getIconImage()); webClipApplication.setProperties(application.getProperties()); webClipApplication.setType(application.getType().toString()); + operation.setCode(MDMAppConstants.WindowsConstants.UNINSTALL_WEB_CLIP_APPLICATION); operation.setPayLoad(webClipApplication.toJSON()); default: String msg = "Application type " + application.getType() + " is not supported"; @@ -216,6 +141,67 @@ public class MDMWindowsOperationUtil { return operation; } + /** + * Helper method to create enterprise APPX and MSI app payloads for both install and uninstall operations + * @param appType contains whether the app type is APPX or MSI + * @param metaJsonArray JSON array containing metadata of APPX and MSI apps + * @param enterpriseApplication {@link EnterpriseApplication} contains operation payload content that will be sent to the device + */ + private static void createEnterpriseAppPayload(String appType, JsonArray metaJsonArray, EnterpriseApplication enterpriseApplication) { + + JsonElement metaElement; + JsonObject metaObject; + if (MDMAppConstants.WindowsConstants.APPX.equalsIgnoreCase(appType)) { + HostedAppxApplication hostedAppxApplication = new HostedAppxApplication(); + List dependencyPackageList = new ArrayList<>(); + + for (int i = 0; i < metaJsonArray.size(); i++) { + metaElement = metaJsonArray.get(i); + metaObject = metaElement.getAsJsonObject(); + + if (MDMAppConstants.WindowsConstants.APPX_PACKAGE_URI.equals(metaObject.get("key").getAsString())) { + hostedAppxApplication.setPackageUri(metaObject.get("value").getAsString().trim()); + } + else if (MDMAppConstants.WindowsConstants.APPX_PACKAGE_FAMILY_NAME.equals(metaObject.get("key").getAsString())) { + hostedAppxApplication.setPackageFamilyName(metaObject.get("value").getAsString().trim()); + } + else if (MDMAppConstants.WindowsConstants.APPX_DEPENDENCY_PACKAGE_URL.equals(metaObject.get("key").getAsString()) + && metaObject.has("value")) { + dependencyPackageList.add(metaObject.get("value").getAsString().trim()); + hostedAppxApplication.setDependencyPackageUri(dependencyPackageList); + } + else if (MDMAppConstants.WindowsConstants.APPX_CERTIFICATE_HASH.equals(metaObject.get("key").getAsString()) + && metaObject.has("value")) { + hostedAppxApplication.setCertificateHash(metaObject.get("value").getAsString().trim()); + } + else if (MDMAppConstants.WindowsConstants.APPX_ENCODED_CERT_CONTENT.equals(metaObject.get("key").getAsString()) + && metaObject.has("value")) { + hostedAppxApplication.setEncodedCertificate(metaObject.get("value").getAsString().trim()); + } + } + enterpriseApplication.setHostedAppxApplication(hostedAppxApplication); + + } else if (MDMAppConstants.WindowsConstants.MSI.equalsIgnoreCase(appType)) { + HostedMSIApplication hostedMSIApplication = new HostedMSIApplication(); + + for (int i = 0; i < metaJsonArray.size(); i++) { + metaElement = metaJsonArray.get(i); + metaObject = metaElement.getAsJsonObject(); + + if (MDMAppConstants.WindowsConstants.MSI_PRODUCT_ID.equals(metaObject.get("key").getAsString())) { + hostedMSIApplication.setProductId(metaObject.get("value").getAsString().trim()); + } + else if (MDMAppConstants.WindowsConstants.MSI_CONTENT_URI.equals(metaObject.get("key").getAsString())) { + hostedMSIApplication.setContentUrl(metaObject.get("value").getAsString().trim()); + } + else if (MDMAppConstants.WindowsConstants.MSI_FILE_HASH.equals(metaObject.get("key").getAsString())) { + hostedMSIApplication.setFileHash(metaObject.get("value").getAsString().trim()); + } + } + enterpriseApplication.setHostedMSIApplication(hostedMSIApplication); + } + } + /** * Method to get the installer file extension type for windows type apps(either appx or msi) * @@ -223,8 +209,7 @@ public class MDMWindowsOperationUtil { * @return string extension of the windows app types(either appx or msi) */ public static String windowsAppType(String installerName) { - String extension = installerName.substring(installerName.lastIndexOf(".") + 1); - return extension; + return installerName.substring(installerName.lastIndexOf(".") + 1); } /** @@ -234,8 +219,7 @@ public class MDMWindowsOperationUtil { * @return the metaData Json String as Json Array */ public static JsonArray jsonStringToArray(String metaData) { - JsonArray metaJsonArray = new JsonParser().parse(metaData).getAsJsonArray(); - return metaJsonArray; + return new JsonParser().parse(metaData).getAsJsonArray(); } diff --git a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml index 32dc388789..65ffa660c8 100644 --- a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml +++ b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml @@ -387,6 +387,7 @@ win:ops:device-info win:ops:security-info win:ops:firewall-info + win:microsoft-store:search admin:tenant:view dm:admin:devices:usage:view and:ops:clear-app