Merge branch 'master' into removeddevicefix

remotes/1725563413541109883/master
Kavin Prathaban 5 months ago
commit 3c31c9d432

@ -546,5 +546,20 @@ public interface ApplicationManager {
* @throws ApplicationManagementException thrown if an error occurs when deleting data
*/
void deleteApplicationDataOfTenant(int tenantId) throws ApplicationManagementException;
/**
* Delete all application related data of a tenant by tenant Domain
*
* @param tenantDomain Domain of the Tenant
* @throws ApplicationManagementException thrown if an error occurs when deleting data
*/
void deleteApplicationDataByTenantDomain(String tenantDomain) throws ApplicationManagementException;
/**
* Delete all Application artifacts related to a tenant by Tenant Domain
*
* @param tenantDomain Domain of the Tenant
* @throws ApplicationManagementException thrown if an error occurs when deleting app folders
*/
void deleteApplicationArtifactsByTenantDomain(String tenantDomain) throws ApplicationManagementException;
}

@ -81,6 +81,7 @@
com.dd.*,
io.entgra.device.mgt.core.identity.jwt.client.extension.*,
io.entgra.device.mgt.core.apimgt.application.extension.*,
io.entgra.device.mgt.core.tenant.mgt.common.*,
org.apache.commons.httpclient,
org.apache.commons.httpclient.methods,
org.apache.commons.validator.routines
@ -389,6 +390,10 @@
<artifactId>org.wso2.carbon.tenant.mgt</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.tenant.mgt.common</artifactId>
</dependency>
</dependencies>
</project>

@ -30,6 +30,7 @@ import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.app.mgt.App;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata;
import io.entgra.device.mgt.core.tenant.mgt.common.exception.TenantMgtException;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringEscapeUtils;
@ -96,8 +97,6 @@ import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementEx
import io.entgra.device.mgt.core.device.mgt.core.dto.DeviceType;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.stratos.common.beans.TenantInfoBean;
import org.wso2.carbon.tenant.mgt.services.TenantMgtAdminService;
import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException;
@ -778,6 +777,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);
}
@ -4416,7 +4417,6 @@ public class ApplicationManagerImpl implements ApplicationManager {
spApplicationDAO.deleteSPApplicationMappingByTenant(tenantId);
spApplicationDAO.deleteIdentityServerByTenant(tenantId);
applicationDAO.deleteApplicationsByTenant(tenantId);
APIUtil.getApplicationStorageManager().deleteAppFolderOfTenant(tenantId);
ConnectionManagerUtil.commitDBTransaction();
} catch (DBConnectionException e) {
@ -4441,12 +4441,6 @@ public class ApplicationManagerImpl implements ApplicationManager {
+ " of tenant ID: " + tenantId ;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationStorageManagementException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while deleting App folder of tenant"
+ " of tenant ID: " + tenantId ;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
@ -4455,19 +4449,9 @@ public class ApplicationManagerImpl implements ApplicationManager {
@Override
public void deleteApplicationDataByTenantDomain(String tenantDomain) throws ApplicationManagementException {
int tenantId;
try{
TenantMgtAdminService tenantMgtAdminService = new TenantMgtAdminService();
TenantInfoBean tenantInfoBean = tenantMgtAdminService.getTenant(tenantDomain);
tenantId = tenantInfoBean.getTenantId();
} catch (Exception e) {
String msg = "Error getting tenant ID from domain: "
+ tenantDomain;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
try {
tenantId = DataHolder.getInstance().getTenantManagerAdminService().getTenantId(tenantDomain);
ConnectionManagerUtil.beginDBTransaction();
vppApplicationDAO.deleteAssociationByTenant(tenantId);
@ -4491,40 +4475,54 @@ public class ApplicationManagerImpl implements ApplicationManager {
spApplicationDAO.deleteSPApplicationMappingByTenant(tenantId);
spApplicationDAO.deleteIdentityServerByTenant(tenantId);
applicationDAO.deleteApplicationsByTenant(tenantId);
APIUtil.getApplicationStorageManager().deleteAppFolderOfTenant(tenantId);
ConnectionManagerUtil.commitDBTransaction();
} catch (DBConnectionException e) {
String msg = "Error occurred while observing the database connection to delete applications for tenant with ID: "
+ tenantId;
String msg = "Error occurred while observing the database connection to delete applications for tenant with " +
"domain: " + tenantDomain;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Database access error is occurred when getting applications for tenant with ID: " + tenantId;
String msg = "Database access error is occurred when getting applications for tenant with domain: "
+ tenantDomain;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (LifeCycleManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while deleting life-cycle state data of application releases of the tenant"
+ " of ID: " + tenantId ;
+ " of domain: " + tenantDomain ;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ReviewManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while deleting reviews of application releases of the applications"
+ " of tenant ID: " + tenantId ;
+ " of tenant of domain: " + tenantDomain ;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationStorageManagementException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while deleting App folder of tenant"
+ " of tenant ID: " + tenantId ;
} catch (Exception e) {
String msg = "Error getting tenant ID from domain: "
+ tenantDomain;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public void deleteApplicationArtifactsByTenantDomain(String tenantDomain) throws ApplicationManagementException {
int tenantId;
try {
tenantId = DataHolder.getInstance().getTenantManagerAdminService().getTenantId(tenantDomain);
DataHolder.getInstance().getApplicationStorageManager().deleteAppFolderOfTenant(tenantId);
} catch (ApplicationStorageManagementException e) {
String msg = "Error deleting app artifacts of tenant of domain: " + tenantDomain ;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (TenantMgtException e) {
String msg = "Error getting tenant ID from domain: "
+ tenantDomain + " when trying to delete application artifacts of tenant";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
}
}

@ -33,7 +33,9 @@ import io.entgra.device.mgt.core.application.mgt.core.impl.FileTransferServiceIm
import io.entgra.device.mgt.core.application.mgt.core.lifecycle.LifecycleStateManager;
import io.entgra.device.mgt.core.application.mgt.core.task.ScheduledAppSubscriptionTaskManager;
import io.entgra.device.mgt.core.application.mgt.core.util.ApplicationManagementUtil;
import io.entgra.device.mgt.core.device.mgt.core.internal.DeviceManagementDataHolder;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import io.entgra.device.mgt.core.tenant.mgt.common.spi.TenantManagerAdminService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext;
@ -71,6 +73,12 @@ import java.util.List;
* policy="dynamic"
* bind="setTaskService"
* unbind="unsetTaskService"
* @scr.reference name="io.entgra.device.mgt.core.tenant.manager"
* interface="io.entgra.device.mgt.core.tenant.mgt.common.spi.TenantManagerAdminService"
* cardinality="0..1"
* policy="dynamic"
* bind="setTenantManagementAdminService"
* unbind="unsetTenantManagementAdminService"
*/
@SuppressWarnings("unused")
public class ApplicationManagementServiceComponent {
@ -196,4 +204,20 @@ public class ApplicationManagementServiceComponent {
}
DataHolder.getInstance().setTaskService(null);
}
@SuppressWarnings("unused")
protected void setTenantManagementAdminService(TenantManagerAdminService tenantManagerAdminService) {
if (log.isDebugEnabled()) {
log.debug("Setting Tenant management admin Service");
}
DataHolder.getInstance().setTenantManagerAdminService(tenantManagerAdminService);
}
@SuppressWarnings("unused")
protected void unsetTenantManagementAdminService(TenantManagerAdminService tenantManagerAdminService) {
if (log.isDebugEnabled()) {
log.debug("Un setting Tenant management admin service");
}
DataHolder.getInstance().setTenantManagerAdminService(null);
}
}

@ -27,6 +27,8 @@ import io.entgra.device.mgt.core.application.mgt.common.services.SubscriptionMan
import io.entgra.device.mgt.core.application.mgt.common.services.VPPApplicationManager;
import io.entgra.device.mgt.core.application.mgt.core.lifecycle.LifecycleStateManager;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import io.entgra.device.mgt.core.tenant.mgt.common.spi.TenantManagerAdminService;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.ntask.core.service.TaskService;
import org.wso2.carbon.user.core.service.RealmService;
@ -57,6 +59,7 @@ public class DataHolder {
private TaskService taskService;
private FileTransferService fileTransferService;
private TenantManagerAdminService tenantManagerAdminService;
private static final DataHolder applicationMgtDataHolder = new DataHolder();
@ -163,4 +166,12 @@ public class DataHolder {
public void setFileTransferService(FileTransferService fileTransferService) {
this.fileTransferService = fileTransferService;
}
public TenantManagerAdminService getTenantManagerAdminService() {
return tenantManagerAdminService;
}
public void setTenantManagerAdminService(TenantManagerAdminService tenantManagerAdminService) {
this.tenantManagerAdminService = tenantManagerAdminService;
}
}

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

@ -298,8 +298,13 @@ public interface UserManagementAdminService {
name = "tenantDomain",
value = "The domain of the tenant to be deleted.",
required = true)
@PathParam("tenantDomain")
String tenantDomain);
String tenantDomain,
@ApiParam(
name = "deleteAppArtifacts",
value = "Flag to indicate whether to delete application artifacts.",
required = false)
@QueryParam("deleteAppArtifacts")
@DefaultValue("false")
boolean deleteAppArtifacts);
}

@ -19,6 +19,7 @@ package io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.impl.admin;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.tenant.mgt.common.exception.TenantMgtException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
@ -29,9 +30,6 @@ import io.entgra.device.mgt.core.device.mgt.api.jaxrs.util.CredentialManagementR
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.util.DeviceMgtAPIUtils;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.stratos.common.exception.StratosException;
import org.wso2.carbon.tenant.mgt.services.TenantMgtAdminService;
import org.wso2.carbon.user.api.UserStoreException;
import javax.validation.constraints.Size;
import javax.ws.rs.*;
@ -91,7 +89,7 @@ public class UserManagementAdminServiceImpl implements UserManagementAdminServic
@DELETE
@Path("/domain/{tenantDomain}")
@Override
public Response deleteTenantByDomain(@PathParam("tenantDomain") String tenantDomain) {
public Response deleteTenantByDomain(@PathParam("tenantDomain") String tenantDomain, @QueryParam("deleteAppArtifacts") boolean deleteAppArtifacts) {
try {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
if (tenantId != MultitenantConstants.SUPER_TENANT_ID){
@ -99,15 +97,20 @@ public class UserManagementAdminServiceImpl implements UserManagementAdminServic
log.error(msg);
return Response.status(Response.Status.UNAUTHORIZED).entity(msg).build();
} else {
if (deleteAppArtifacts) {
DeviceMgtAPIUtils.getApplicationManager().deleteApplicationArtifactsByTenantDomain(tenantDomain);
}
DeviceMgtAPIUtils.getApplicationManager().deleteApplicationDataByTenantDomain(tenantDomain);
DeviceMgtAPIUtils.getDeviceManagementService().deleteDeviceDataByTenantDomain(tenantDomain);
TenantMgtAdminService tenantMgtAdminService = new TenantMgtAdminService();
tenantMgtAdminService.deleteTenant(tenantDomain);
DeviceMgtAPIUtils.getTenantManagerAdminService().deleteTenant(tenantDomain);
String msg = "Tenant Deletion process has been initiated for tenant:" + tenantDomain;
if (log.isDebugEnabled()) {
log.debug(msg);
}
return Response.status(Response.Status.OK).entity(msg).build();
}
} catch (StratosException | UserStoreException e) {
} catch (TenantMgtException e) {
String msg = "Error deleting tenant: " + tenantDomain;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();

@ -24,6 +24,7 @@ import io.entgra.device.mgt.core.application.mgt.common.services.SubscriptionMan
import io.entgra.device.mgt.core.device.mgt.common.authorization.GroupAccessAuthorizationService;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.DeviceStatusManagementService;
import io.entgra.device.mgt.core.device.mgt.core.permission.mgt.PermissionManagerServiceImpl;
import io.entgra.device.mgt.core.tenant.mgt.common.spi.TenantManagerAdminService;
import org.apache.axis2.AxisFault;
import org.apache.axis2.client.Options;
import org.apache.axis2.java.security.SSLProtocolSocketFactory;
@ -163,6 +164,7 @@ public class DeviceMgtAPIUtils {
private static volatile ApplicationManager applicationManager;
private static volatile APIPublisherService apiPublisher;
private static volatile TenantManagerAdminService tenantManagerAdminService;
static {
String keyStorePassword = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Password");
@ -1243,4 +1245,21 @@ public class DeviceMgtAPIUtils {
}
return isPermitted;
}
public static TenantManagerAdminService getTenantManagerAdminService(){
if(tenantManagerAdminService == null) {
synchronized (DeviceMgtAPIUtils.class) {
if (tenantManagerAdminService == null) {
tenantManagerAdminService = (TenantManagerAdminService) PrivilegedCarbonContext.getThreadLocalCarbonContext().
getOSGiService(TenantManagerAdminService.class, null);
if (tenantManagerAdminService == null) {
String msg = "Tenant Manager Admin Service is null";
log.error(msg);
throw new IllegalStateException(msg);
}
}
}
}
return tenantManagerAdminService;
}
}

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

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

@ -982,7 +982,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
+ "e.TENANT_ID = ? AND "
+ "LOWER(e.OWNER) = LOWER(?) AND "
+ "e.STATUS IN (",
")) e1 ORDER BY e1.DATE_OF_LAST_UPDATE DESC");
")) e1 WHERE d.ID = e1.DEVICE_ID ORDER BY e1.DATE_OF_LAST_UPDATE DESC");
deviceStatuses.stream().map(ignored -> "?").forEach(joiner::add);
String query = joiner.toString();

@ -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<String> 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<String> 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<String> 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();
}

@ -0,0 +1,27 @@
/*
* 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.tenant.mgt.common.spi;
import io.entgra.device.mgt.core.tenant.mgt.common.exception.TenantMgtException;
public interface TenantManagerAdminService {
void deleteTenant(String tenantDomain) throws TenantMgtException;
int getTenantId(String tenantDomain) throws TenantMgtException;
}

@ -60,6 +60,7 @@
org.wso2.carbon.stratos.common.beans,
org.wso2.carbon.stratos.common.exception,
org.wso2.carbon.stratos.common.listeners,
org.wso2.carbon.tenant.mgt.services,
io.entgra.device.mgt.core.device.mgt.common.metadata.mgt,
io.entgra.device.mgt.core.device.mgt.common.exceptions,
io.entgra.device.mgt.core.device.mgt.common.permission.mgt,

@ -57,4 +57,5 @@ public interface TenantManager {
* @throws TenantMgtException Throws when deleting Tenant related device data
*/
void deleteTenantDeviceData(int tenantId) throws TenantMgtException;
}

@ -0,0 +1,57 @@
/*
* 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.tenant.mgt.core.impl;
import io.entgra.device.mgt.core.tenant.mgt.common.exception.TenantMgtException;
import io.entgra.device.mgt.core.tenant.mgt.common.spi.TenantManagerAdminService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.stratos.common.exception.StratosException;
import org.wso2.carbon.tenant.mgt.services.TenantMgtAdminService;
import org.wso2.carbon.user.api.UserStoreException;
public class TenantManagerAdminServiceImpl implements TenantManagerAdminService {
private static final Log log = LogFactory.getLog(TenantManagerAdminServiceImpl.class);
private static final TenantMgtAdminService tenantMgtAdminService = new TenantMgtAdminService();
@Override
public void deleteTenant(String tenantDomain) throws TenantMgtException {
try {
tenantMgtAdminService.deleteTenant(tenantDomain);
} catch (StratosException | UserStoreException e) {
String msg = "Error occurred while deleting tenant of domain: " + tenantDomain;
log.error(msg, e);
throw new TenantMgtException(msg, e);
}
}
@Override
public int getTenantId(String tenantDomain) throws TenantMgtException {
try {
return tenantMgtAdminService.getTenant(tenantDomain).getTenantId();
} catch (Exception e){
String msg = "Error occurred while getting tenant ID of domain: " + tenantDomain;
log.error(msg, e);
throw new TenantMgtException(msg, e);
}
}
}

@ -20,8 +20,10 @@ package io.entgra.device.mgt.core.tenant.mgt.core.internal;
import io.entgra.device.mgt.core.application.mgt.common.services.ApplicationManager;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.DeviceStatusManagementService;
import io.entgra.device.mgt.core.device.mgt.core.metadata.mgt.DeviceStatusManagementServiceImpl;
import io.entgra.device.mgt.core.tenant.mgt.common.spi.TenantManagerAdminService;
import io.entgra.device.mgt.core.tenant.mgt.common.spi.TenantManagerService;
import io.entgra.device.mgt.core.tenant.mgt.core.TenantManager;
import io.entgra.device.mgt.core.tenant.mgt.core.impl.TenantManagerAdminServiceImpl;
import io.entgra.device.mgt.core.tenant.mgt.core.impl.TenantManagerImpl;
import io.entgra.device.mgt.core.tenant.mgt.core.impl.TenantManagerServiceImpl;
import io.entgra.device.mgt.core.tenant.mgt.core.listener.DeviceMgtTenantListener;
@ -59,11 +61,14 @@ public class TenantMgtServiceComponent {
try {
TenantManagerService tenantManagerService = new TenantManagerServiceImpl();
componentContext.getBundleContext().
registerService(TenantManagerServiceImpl.class.getName(), tenantManagerService, null);
registerService(TenantManagerService.class.getName(), tenantManagerService, null);
TenantManagerAdminService tenantManagerAdminService = new TenantManagerAdminServiceImpl();
componentContext.getBundleContext().
registerService(TenantManagerAdminService.class.getName(), tenantManagerAdminService, null);
TenantManager tenantManager = new TenantManagerImpl();
TenantMgtDataHolder.getInstance().setTenantManager(tenantManager);
WhiteLabelManagementService whiteLabelManagementService = new WhiteLabelManagementServiceImpl();
componentContext.getBundleContext().registerService(WhiteLabelManagementServiceImpl.class.getName(),
componentContext.getBundleContext().registerService(WhiteLabelManagementService.class.getName(),
whiteLabelManagementService, null);
TenantMgtDataHolder.getInstance().setWhiteLabelManagementService(whiteLabelManagementService);
DeviceStatusManagementService deviceStatusManagementService = new DeviceStatusManagementServiceImpl();

@ -88,13 +88,5 @@ public class DeviceMgtTenantListener implements TenantMgtListener {
@Override
public void onPreDelete(int i) throws StratosException {
// Any work to be performed before a tenant is deleted
TenantManager tenantManager = TenantMgtDataHolder.getInstance().getTenantManager();
try{
tenantManager.deleteTenantDeviceData(i);
tenantManager.deleteTenantApplicationData(i);
} catch (TenantMgtException e) {
String msg = "Error occurred while deleting tenant data";
log.error(msg, e);
}
}
}

@ -387,6 +387,7 @@
<Scope>win:ops:device-info</Scope>
<Scope>win:ops:security-info</Scope>
<Scope>win:ops:firewall-info</Scope>
<Scope>win:microsoft-store:search</Scope>
<Scope>admin:tenant:view</Scope>
<Scope>dm:admin:devices:usage:view</Scope>
<Scope>and:ops:clear-app</Scope>

Loading…
Cancel
Save