sync with upstream apim420

synced-apim420
Dharmakeerthi Lasantha 1 year ago
commit fe58a16d17

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>grafana-mgt</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -295,7 +295,7 @@
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<artifactId>powermock-api-mockito2</artifactId>
<scope>test</scope>
</dependency>
<dependency>

@ -22,17 +22,25 @@ import com.google.gson.JsonObject;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.GrafanaAPIProxyService;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.bean.ErrorResponse;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.exception.RefererNotValid;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.impl.util.GrafanaMgtAPIUtils;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.impl.util.GrafanaRequestHandlerUtil;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.bean.GrafanaPanelIdentifier;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.exception.MaliciousQueryAttempt;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.internal.GrafanaMgtDataHolder;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DBConnectionException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.sql.SQLException;
@ -49,8 +57,8 @@ public class GrafanaAPIProxyServiceImpl implements GrafanaAPIProxyService {
public Response queryDatasource(JsonObject body, @Context HttpHeaders headers, @Context UriInfo requestUriInfo) {
try {
GrafanaPanelIdentifier panelIdentifier = GrafanaRequestHandlerUtil.getPanelIdentifier(headers);
GrafanaMgtDataHolder.getInstance().getGrafanaQueryService().
buildSafeQuery(body, panelIdentifier.getDashboardId(), panelIdentifier.getPanelId(), requestUriInfo.getRequestUri());
GrafanaMgtAPIUtils.getGrafanaQueryService().buildSafeQuery(body, panelIdentifier.getDashboardId(),
panelIdentifier.getPanelId(), requestUriInfo.getRequestUri());
return GrafanaRequestHandlerUtil.proxyPassPostRequest(body, requestUriInfo, panelIdentifier.getOrgId());
} catch (MaliciousQueryAttempt e) {
return Response.status(Response.Status.BAD_REQUEST).entity(

@ -0,0 +1,52 @@
/*
* Copyright (c) 2018 - 2023, 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.analytics.mgt.grafana.proxy.api.impl.util;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.service.GrafanaQueryService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
public class GrafanaMgtAPIUtils {
private static final Log log = LogFactory.getLog(GrafanaMgtAPIUtils.class);
private static volatile GrafanaQueryService grafanaQueryService;
/**
* Accessing GrafanaQueryService from OSGI service context
* @return GrafanaQueryService instance
*/
public static GrafanaQueryService getGrafanaQueryService() {
if (grafanaQueryService == null) {
synchronized (GrafanaMgtAPIUtils.class) {
if (grafanaQueryService == null) {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
grafanaQueryService =
(GrafanaQueryService) ctx.getOSGiService(GrafanaQueryService.class, null);
if (grafanaQueryService == null) {
String msg = "Grafana Query service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
}
}
}
return grafanaQueryService;
}
}

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>grafana-mgt</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>grafana-mgt</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -211,7 +211,7 @@
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<artifactId>powermock-api-mockito2</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>analytics-mgt</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -22,7 +22,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -68,17 +68,18 @@ public class APIApplicationManagerExtensionDataHolder {
public void setRealmService(RealmService realmService) {
this.realmService = realmService;
this.setTenantManager(realmService);
setTenantManager(realmService != null ?
realmService.getTenantManager() : null);
}
private void setTenantManager(RealmService realmService) {
if (realmService == null) {
throw new IllegalStateException("Realm service is not initialized properly");
}
this.tenantManager = realmService.getTenantManager();
private void setTenantManager(TenantManager tenantManager) {
this.tenantManager = tenantManager;
}
public TenantManager getTenantManager() {
if (tenantManager == null) {
throw new IllegalStateException("Tenant manager is not initialized properly");
}
return tenantManager;
}

@ -22,7 +22,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -21,7 +21,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -41,7 +41,7 @@
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<artifactId>powermock-api-mockito2</artifactId>
<scope>test</scope>
</dependency>
<dependency>

@ -75,17 +75,18 @@ public class APIPublisherDataHolder {
public void setRealmService(RealmService realmService) {
this.realmService = realmService;
this.setTenantManager(realmService);
setTenantManager(realmService != null ?
realmService.getTenantManager() : null);
}
private void setTenantManager(RealmService realmService) {
if (realmService == null) {
throw new IllegalStateException("Realm service is not initialized properly");
}
this.tenantManager = realmService.getTenantManager();
private void setTenantManager(TenantManager tenantManager) {
this.tenantManager = tenantManager;
}
public TenantManager getTenantManager() {
if (tenantManager == null) {
throw new IllegalStateException("Tenant manager is not initialized properly");
}
return tenantManager;
}

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>application-mgt</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -17,7 +17,12 @@
*/
package io.entgra.device.mgt.core.application.mgt.common.services;
import io.entgra.device.mgt.core.application.mgt.common.*;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationArtifact;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationList;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationType;
import io.entgra.device.mgt.core.application.mgt.common.Filter;
import io.entgra.device.mgt.core.application.mgt.common.LifecycleChanger;
import io.entgra.device.mgt.core.application.mgt.common.LifecycleState;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException;

@ -21,7 +21,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>application-mgt</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -153,6 +153,10 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
--add-opens=java.xml/jdk.xml.internal=ALL-UNNAMED
--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED
</argLine>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
@ -160,6 +164,9 @@
<jacoco-agent.destfile>${basedir}/target/coverage-reports/jacoco-unit.exec</jacoco-agent.destfile>
<log4j.configuration>file:src/test/resources/log4j.properties</log4j.configuration>
</systemPropertyVariables>
<classpathDependencyExcludes>
<classpathDependencyExclude>org.ops4j.pax.logging</classpathDependencyExclude>
</classpathDependencyExcludes>
</configuration>
</plugin>
</plugins>
@ -404,6 +411,10 @@
<artifactId>org.wso2.carbon.ntask.core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.notification.logger</artifactId>
</dependency>
</dependencies>
</project>

@ -18,21 +18,58 @@
package io.entgra.device.mgt.core.application.mgt.core.impl;
import io.entgra.device.mgt.core.application.mgt.common.*;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationArtifact;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstaller;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationList;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationSubscriptionType;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationType;
import io.entgra.device.mgt.core.application.mgt.common.DeviceTypes;
import io.entgra.device.mgt.core.application.mgt.common.Filter;
import io.entgra.device.mgt.core.application.mgt.common.LifecycleChanger;
import io.entgra.device.mgt.core.application.mgt.common.LifecycleState;
import io.entgra.device.mgt.core.application.mgt.common.Pagination;
import io.entgra.device.mgt.core.application.mgt.common.config.RatingConfiguration;
import io.entgra.device.mgt.core.application.mgt.common.dto.*;
import io.entgra.device.mgt.core.application.mgt.common.exception.*;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.CategoryDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.TagDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationStorageManagementException;
import io.entgra.device.mgt.core.application.mgt.common.exception.DBConnectionException;
import io.entgra.device.mgt.core.application.mgt.common.exception.LifecycleManagementException;
import io.entgra.device.mgt.core.application.mgt.common.exception.RequestValidatingException;
import io.entgra.device.mgt.core.application.mgt.common.exception.ResourceManagementException;
import io.entgra.device.mgt.core.application.mgt.common.exception.TransactionManagementException;
import io.entgra.device.mgt.core.application.mgt.common.response.Application;
import io.entgra.device.mgt.core.application.mgt.common.response.ApplicationRelease;
import io.entgra.device.mgt.core.application.mgt.common.response.Category;
import io.entgra.device.mgt.core.application.mgt.common.response.Tag;
import io.entgra.device.mgt.core.application.mgt.common.services.ApplicationManager;
import io.entgra.device.mgt.core.application.mgt.common.services.ApplicationStorageManager;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.*;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.ApplicationUpdateWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.ApplicationWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.CustomAppReleaseWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.CustomAppWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.EntAppReleaseWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.PublicAppReleaseWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.PublicAppWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.WebAppReleaseWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.WebAppWrapper;
import io.entgra.device.mgt.core.application.mgt.core.config.ConfigurationManager;
import io.entgra.device.mgt.core.application.mgt.core.dao.*;
import io.entgra.device.mgt.core.application.mgt.core.dao.ApplicationDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.ApplicationReleaseDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.LifecycleStateDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.SPApplicationDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.SubscriptionDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.VisibilityDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.common.ApplicationManagementDAOFactory;
import io.entgra.device.mgt.core.application.mgt.core.exception.*;
import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException;
import io.entgra.device.mgt.core.application.mgt.core.exception.BadRequestException;
import io.entgra.device.mgt.core.application.mgt.core.exception.ForbiddenException;
import io.entgra.device.mgt.core.application.mgt.core.exception.LifeCycleManagementDAOException;
import io.entgra.device.mgt.core.application.mgt.core.exception.NotFoundException;
import io.entgra.device.mgt.core.application.mgt.core.exception.VisibilityManagementDAOException;
import io.entgra.device.mgt.core.application.mgt.core.internal.DataHolder;
import io.entgra.device.mgt.core.application.mgt.core.lifecycle.LifecycleStateManager;
import io.entgra.device.mgt.core.application.mgt.core.util.APIUtil;
@ -40,7 +77,9 @@ import io.entgra.device.mgt.core.application.mgt.core.util.ApplicationManagement
import io.entgra.device.mgt.core.application.mgt.core.util.ConnectionManagerUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.Constants;
import io.entgra.device.mgt.core.device.mgt.common.Base64File;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
import io.entgra.device.mgt.core.device.mgt.core.common.exception.StorageManagementException;
import io.entgra.device.mgt.core.device.mgt.core.dto.DeviceType;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
@ -52,15 +91,23 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.validator.routines.UrlValidator;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.json.JSONObject;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@ -1239,13 +1286,13 @@ public class ApplicationManagerImpl implements ApplicationManager {
this.changeLifecycleState(applicationReleaseDTO, lifecycleChanger);
}
}
if (Constants.ENTERPRISE_APP_TYPE.equals(applicationDTO.getType()) || Constants.PUBLIC_APP_TYPE.equals(applicationDTO.getType())) {
persistAppIconInfo(applicationReleaseDTO);
}
applicationReleaseEntities.add(applicationReleaseDTO);
}
applicationDTO.setId(appId);
applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities);
if (applicationDTO.getType().equals("ENTERPRISE") || applicationDTO.getType().equals("PUBLIC") ) {
persistAppIconInfo(applicationReleaseDTO);
}
return APIUtil.appDtoToAppResponse(applicationDTO);
}
} catch (LifeCycleManagementDAOException e) {
@ -1669,6 +1716,30 @@ public class ApplicationManagerImpl implements ApplicationManager {
}
}
/**
* Check whether valid metaData value or not
*
* @return true or false
* @throws MetadataManagementException If it is unable to load metaData
*/
private boolean isUserAbleToViewAllRoles() throws MetadataManagementException {
List<Metadata> allMetadata;
allMetadata = APIUtil.getMetadataManagementService().retrieveAllMetadata();
if (allMetadata != null && !allMetadata.isEmpty()) {
for (Metadata metadata : allMetadata) {
if (Constants.SHOW_ALL_ROLES.equals(metadata.getMetaKey())) {
String metaValue = metadata.getMetaValue();
if (metaValue != null) {
JSONObject jsonObject;
jsonObject = new JSONObject(metaValue);
return jsonObject.getBoolean(Constants.IS_USER_ABLE_TO_VIEW_ALL_ROLES);
}
}
}
}
return false;
}
/**
* Get assigned role list of the given user.
*
@ -3442,7 +3513,8 @@ public class ApplicationManagerImpl implements ApplicationManager {
}
@Override
public <T> void validateAppCreatingRequest(T param) throws ApplicationManagementException, RequestValidatingException {
public <T> void validateAppCreatingRequest(T param)
throws ApplicationManagementException, RequestValidatingException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
int deviceTypeId = -1;
@ -3614,12 +3686,14 @@ public class ApplicationManagerImpl implements ApplicationManager {
log.error(msg);
throw new ApplicationManagementException(msg);
}
if (!hasUserRole(unrestrictedRoles, userName)) {
String msg = "You are trying to restrict the visibility of the application for a role set, but "
+ "in order to perform the action at least one role should be assigned to user: "
+ userName;
log.error(msg);
throw new BadRequestException(msg);
if (!isUserAbleToViewAllRoles()) {
if (!hasUserRole(unrestrictedRoles, userName)) {
String msg = "You are trying to restrict the visibility of the application for a role set, but "
+ "in order to perform the action at least one role should be assigned to user: "
+ userName;
log.error(msg);
throw new BadRequestException(msg);
}
}
}
@ -3672,6 +3746,10 @@ public class ApplicationManagerImpl implements ApplicationManager {
String msg = "Error occurred when validating the unrestricted roles given for the web clip";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (MetadataManagementException e) {
String msg = "Error occurred while retrieving metadata list";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}

@ -21,9 +21,25 @@ package io.entgra.device.mgt.core.application.mgt.core.impl;
import com.google.gson.Gson;
import io.entgra.device.mgt.core.apimgt.application.extension.dto.ApiApplicationKey;
import io.entgra.device.mgt.core.apimgt.application.extension.exception.APIManagerException;
import io.entgra.device.mgt.core.application.mgt.common.*;
import io.entgra.device.mgt.core.application.mgt.common.dto.*;
import io.entgra.device.mgt.core.application.mgt.common.exception.*;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationSubscriptionInfo;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationType;
import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionData;
import io.entgra.device.mgt.core.application.mgt.common.DeviceTypes;
import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus;
import io.entgra.device.mgt.core.application.mgt.common.SubAction;
import io.entgra.device.mgt.core.application.mgt.common.SubscribingDeviceIdHolder;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationPolicyDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.device.mgt.core.application.mgt.common.exception.DBConnectionException;
import io.entgra.device.mgt.core.application.mgt.common.exception.LifecycleManagementException;
import io.entgra.device.mgt.core.application.mgt.common.exception.SubscriptionManagementException;
import io.entgra.device.mgt.core.application.mgt.common.exception.TransactionManagementException;
import io.entgra.device.mgt.core.application.mgt.common.response.Application;
import io.entgra.device.mgt.core.application.mgt.common.services.SubscriptionManager;
import io.entgra.device.mgt.core.application.mgt.core.dao.ApplicationDAO;
@ -35,11 +51,20 @@ import io.entgra.device.mgt.core.application.mgt.core.exception.ForbiddenExcepti
import io.entgra.device.mgt.core.application.mgt.core.exception.NotFoundException;
import io.entgra.device.mgt.core.application.mgt.core.internal.DataHolder;
import io.entgra.device.mgt.core.application.mgt.core.lifecycle.LifecycleStateManager;
import io.entgra.device.mgt.core.application.mgt.core.util.*;
import io.entgra.device.mgt.core.application.mgt.core.util.APIUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.ConnectionManagerUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.Constants;
import io.entgra.device.mgt.core.application.mgt.core.util.HelperUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.OAuthUtils;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.EnrolmentInfo;
import io.entgra.device.mgt.core.device.mgt.common.MDMAppConstants;
import io.entgra.device.mgt.core.device.mgt.common.MDMAppConstants;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
import io.entgra.device.mgt.core.device.mgt.common.*;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
import io.entgra.device.mgt.core.device.mgt.common.app.mgt.App;
import io.entgra.device.mgt.core.device.mgt.common.app.mgt.MobileAppTypes;
import io.entgra.device.mgt.core.device.mgt.common.app.mgt.android.CustomApplication;
@ -57,15 +82,16 @@ import io.entgra.device.mgt.core.device.mgt.core.service.GroupManagementProvider
import io.entgra.device.mgt.core.device.mgt.core.util.MDMAndroidOperationUtil;
import io.entgra.device.mgt.core.device.mgt.core.util.MDMIOSOperationUtil;
import io.entgra.device.mgt.core.device.mgt.core.util.MDMWindowsOperationUtil;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger;
import io.entgra.device.mgt.core.identity.jwt.client.extension.dto.AccessTokenInfo;
import io.entgra.device.mgt.core.notification.logger.AppInstallLogContext;
import io.entgra.device.mgt.core.notification.logger.impl.EntgraAppInstallLoggerImpl;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONObject;
import org.wso2.carbon.context.PrivilegedCarbonContext;
@ -79,7 +105,14 @@ import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
@ -87,8 +120,8 @@ import java.util.stream.Collectors;
* This is the default implementation for the Subscription Manager.
*/
public class SubscriptionManagerImpl implements SubscriptionManager {
private static final Log log = LogFactory.getLog(SubscriptionManagerImpl.class);
AppInstallLogContext.Builder appInstallLogContextBuilder = new AppInstallLogContext.Builder();
private static final EntgraLogger log = new EntgraAppInstallLoggerImpl(SubscriptionManagerImpl.class);
private SubscriptionDAO subscriptionDAO;
private ApplicationDAO applicationDAO;
private LifecycleStateManager lifecycleStateManager;
@ -620,7 +653,9 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
Properties properties,
boolean isOperationReExecutingDisabled)
throws ApplicationManagementException {
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
String tenantId = String.valueOf(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId());
String tenantDomain = String.valueOf(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain());
//Get app subscribing info of each device
SubscribingDeviceIdHolder subscribingDeviceIdHolder = getSubscribingDeviceIdHolder(devices,
applicationDTO.getApplicationReleaseDTOs().get(0).getId());
@ -670,10 +705,36 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
Activity activity = addAppOperationOnDevices(applicationDTO, new ArrayList<>(entry.getValue()),
entry.getKey(), action, properties);
activityList.add(activity);
for (DeviceIdentifier identifier : deviceIdentifiers) {
log.info(String.format("Web app %s triggered", action), appInstallLogContextBuilder
.setAppId(String.valueOf(applicationDTO.getId()))
.setAppName(applicationDTO.getName())
.setAppType(applicationDTO.getType())
.setSubType(subType)
.setTenantId(tenantId)
.setTenantDomain(tenantDomain)
.setDevice(String.valueOf(identifier))
.setUserName(username)
.setAction(action)
.build());
}
}
} else {
Activity activity = addAppOperationOnDevices(applicationDTO, deviceIdentifiers, deviceType, action, properties);
activityList.add(activity);
for (DeviceIdentifier identifier : deviceIdentifiers) {
log.info(String.format("App %s triggered", action), appInstallLogContextBuilder
.setAppId(String.valueOf(applicationDTO.getId()))
.setAppName(applicationDTO.getName())
.setAppType(applicationDTO.getType())
.setSubType(subType)
.setTenantId(tenantId)
.setTenantDomain(tenantDomain)
.setDevice(String.valueOf(identifier))
.setUserName(username)
.setAction(action)
.build());
}
}
ApplicationInstallResponse applicationInstallResponse = new ApplicationInstallResponse();

@ -39,6 +39,7 @@ import io.entgra.device.mgt.core.application.mgt.core.exception.UnexpectedServer
import io.entgra.device.mgt.core.application.mgt.core.internal.DataHolder;
import io.entgra.device.mgt.core.application.mgt.core.serviceprovider.ISServiceProviderApplicationService;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService;
import io.entgra.device.mgt.core.device.mgt.core.dto.DeviceType;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
@ -64,6 +65,7 @@ public class APIUtil {
private static volatile SubscriptionManager subscriptionManager;
private static volatile ReviewManager reviewManager;
private static volatile AppmDataHandler appmDataHandler;
private static volatile MetadataManagementService metadataManagementService;
public static SPApplicationManager getSPApplicationManager() {
if (SPApplicationManager == null) {
@ -514,7 +516,22 @@ public class APIUtil {
public static String createAppIconPath(ApplicationReleaseDTO applicationReleaseDTO, int tenantId) throws ApplicationManagementException {
String basePath = getArtifactDownloadBaseURL() + tenantId + Constants.FORWARD_SLASH + applicationReleaseDTO
.getAppHashValue() + Constants.FORWARD_SLASH;
String iconPath = basePath + Constants.ICON_ARTIFACT + Constants.FORWARD_SLASH + applicationReleaseDTO.getIconName();
return iconPath;
return basePath + Constants.ICON_ARTIFACT + Constants.FORWARD_SLASH + applicationReleaseDTO.getIconName();
}
public static MetadataManagementService getMetadataManagementService() {
if (metadataManagementService == null) {
synchronized (APIUtil.class) {
if (metadataManagementService == null) {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
metadataManagementService = (MetadataManagementService) ctx.getOSGiService(
MetadataManagementService.class, null);
if (metadataManagementService == null) {
throw new IllegalStateException("Metadata Management service not initialized.");
}
}
}
}
return metadataManagementService;
}
}

@ -70,7 +70,8 @@ public class Constants {
public static final String ANY = "ANY";
public static final String DEFAULT_PCK_NAME = "default.app.com";
public static final String ALL = "ALL";
public static final String SHOW_ALL_ROLES = "SHOW_ALL_ROLES";
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";
@ -93,6 +94,9 @@ public class Constants {
public static final String MSI = "MSI";
public static final String APPX = "APPX";
public static final String ENTERPRISE_APP_TYPE = "ENTERPRISE";
public static final String PUBLIC_APP_TYPE = "ENTERPRISE";
private static final Map<String, String> AGENT_DATA = new HashMap<>();
static {
AGENT_DATA.put("android", "android-agent.apk");

@ -27,7 +27,7 @@
<EveryOneRoleName>everyone</EveryOneRoleName>
<ReadOnly>false</ReadOnly>
<MaxUserNameListLength>500</MaxUserNameListLength>
<Property name="url">jdbc:h2:target/databasetest/CARBON_TEST</Property>
<Property name="url">jdbc:h2:./target/databasetest/CARBON_TEST</Property>
<Property name="driverName">org.h2.Driver</Property>
<Property name="maxActive">50</Property>
<Property name="maxWait">60000</Property>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>certificate-mgt</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>certificate-mgt</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>certificate-mgt</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -111,6 +111,10 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
--add-opens=java.xml/jdk.xml.internal=ALL-UNNAMED
--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED
</argLine>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
@ -118,6 +122,9 @@
<jacoco-agent.destfile>${basedir}/target/coverage-reports/jacoco-unit.exec</jacoco-agent.destfile>
<log4j.configuration>file:src/test/resources/log4j.properties</log4j.configuration>
</systemPropertyVariables>
<classpathDependencyExcludes>
<classpathDependencyExclude>org.ops4j.pax.logging</classpathDependencyExclude>
</classpathDependencyExcludes>
</configuration>
</plugin>
<plugin>
@ -175,7 +182,7 @@
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<artifactId>powermock-api-mockito2</artifactId>
<scope>test</scope>
</dependency>
<dependency>

@ -25,6 +25,15 @@ public class Certificate {
X509Certificate certificate;
int tenantId;
String tenantDomain;
String deviceIdentifier;
public String getDeviceIdentifier() {
return deviceIdentifier;
}
public void setDeviceIdentifier(String deviceIdentifier) {
this.deviceIdentifier = deviceIdentifier;
}
public int getTenantId() {
return tenantId;

@ -41,6 +41,17 @@ public interface CertificateDAO {
void addCertificate(List<Certificate> certificate)
throws CertificateManagementDAOException;
/**
* This can be used to store a certificate in the database, where it will be stored against the serial number
* of the certificate.
*
* @param certificate Holds the certificate and relevant details.
* @throws CertificateManagementDAOException
*
*/
void addCertificate(Certificate certificate)
throws CertificateManagementDAOException;
/**
* Usage is to obtain a certificate stored in the database by providing the common name.
*
@ -51,6 +62,16 @@ public interface CertificateDAO {
*/
CertificateResponse retrieveCertificate(String serialNumber) throws CertificateManagementDAOException;
/**
* Obtain a certificated stored in the database by providing the common name and the tenant ID
*
* @param serialNumber Serial number (Common name) of the certificate
* @param tenantId ID of the certificate owning tenant
* @return representation of the certificate.
* @throws CertificateManagementDAOException if fails to read the certificate from the database
*/
CertificateResponse retrieveCertificate(String serialNumber, int tenantId) throws CertificateManagementDAOException;
/**
* Get all the certificates in a paginated manner.
*

@ -81,6 +81,40 @@ public abstract class AbstractCertificateDAOImpl implements CertificateDAO{
}
}
@Override
public void addCertificate(Certificate certificate)
throws CertificateManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
try {
conn = this.getConnection();
stmt = conn.prepareStatement(
"INSERT INTO DM_DEVICE_CERTIFICATE (SERIAL_NUMBER, CERTIFICATE, TENANT_ID," +
" USERNAME, DEVICE_IDENTIFIER) VALUES (?,?,?,?,?)");
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.
getThreadLocalCarbonContext();
String username = threadLocalCarbonContext.getUsername();
// the serial number of the certificate used for its creation is set as its alias.
String serialNumber = certificate.getSerial();
if (serialNumber == null || serialNumber.isEmpty()) {
serialNumber = String.valueOf(certificate.getCertificate().getSerialNumber());
}
byte[] bytes = Serializer.serialize(certificate.getCertificate());
stmt.setString(1, serialNumber);
stmt.setBytes(2, bytes);
stmt.setInt(3, certificate.getTenantId());
stmt.setString(4, username);
stmt.setString(5, certificate.getDeviceIdentifier());
stmt.executeUpdate();
} catch (SQLException | IOException e) {
throw new CertificateManagementDAOException("Error occurred while saving the " +
"certificate. ", e);
} finally {
CertificateManagementDAOUtil.cleanupResources(stmt, null);
}
}
@Override
public CertificateResponse retrieveCertificate(String serialNumber)
throws CertificateManagementDAOException {
@ -119,6 +153,42 @@ public abstract class AbstractCertificateDAOImpl implements CertificateDAO{
return certificateResponse;
}
@Override
public CertificateResponse retrieveCertificate(String serialNumber, int tenantId) throws CertificateManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet resultSet = null;
CertificateResponse certificateResponse = null;
try {
conn = this.getConnection();
String query =
"SELECT CERTIFICATE, SERIAL_NUMBER, TENANT_ID, USERNAME FROM"
+ " DM_DEVICE_CERTIFICATE WHERE SERIAL_NUMBER = ? AND TENANT_ID = ? ";
stmt = conn.prepareStatement(query);
stmt.setString(1, serialNumber);
stmt.setInt(2, tenantId);
resultSet = stmt.executeQuery();
if (resultSet.next()) {
certificateResponse = new CertificateResponse();
byte[] certificateBytes = resultSet.getBytes("CERTIFICATE");
certificateResponse.setCertificate(certificateBytes);
certificateResponse.setSerialNumber(resultSet.getString("SERIAL_NUMBER"));
certificateResponse.setTenantId(resultSet.getInt("TENANT_ID"));
certificateResponse.setUsername(resultSet.getString("USERNAME"));
CertificateGenerator.extractCertificateDetails(certificateBytes, certificateResponse);
}
} catch (SQLException e) {
String errorMsg =
"Unable to get the read the certificate with serial" + serialNumber;
log.error(errorMsg, e);
throw new CertificateManagementDAOException(errorMsg, e);
} finally {
CertificateManagementDAOUtil.cleanupResources(stmt, resultSet);
}
return certificateResponse;
}
@Override
public List<CertificateResponse> searchCertificate(String serialNumber)
throws CertificateManagementDAOException {

@ -336,15 +336,31 @@ public class CertificateGenerator {
CertificateResponse lookUpCertificate = null;
KeyStoreReader keyStoreReader = new KeyStoreReader();
if (distinguishedName != null && !distinguishedName.isEmpty()) {
if (distinguishedName.contains("/CN=")) {
String[] dnSplits = distinguishedName.split("/");
for (String dnPart : dnSplits) {
if (dnPart.contains("CN=")) {
String commonNameExtracted = dnPart.replace("CN=", "");
lookUpCertificate = keyStoreReader.getCertificateBySerial(commonNameExtracted);
break;
if (distinguishedName.contains("CN=")) {
String[] dnSplits = null;
if (distinguishedName.contains("/")) {
dnSplits = distinguishedName.split("/");
} else if (distinguishedName.contains(",")) {
//some older versions of nginx will forward the client certificate subject dn separated with commas
dnSplits = distinguishedName.split(",");
}
String commonNameExtracted = null;
int tenantId = 0;
if (dnSplits != null && dnSplits.length >= 1) {
for (String dnPart : dnSplits) {
if (dnPart.contains("CN=")) {
commonNameExtracted = dnPart.replace("CN=", "");
} else if (dnPart.contains("OU=")) {
//the OU of the certificate will be like OU=tenant_<TENANT_ID> ex: OU=tenant_-1234
//splitting by underscore to extract the tenant domain
String[] orgUnitSplits = dnPart.split("_");
tenantId = Integer.parseInt(orgUnitSplits[1]);
}
}
}
lookUpCertificate = keyStoreReader.getCertificateBySerial(commonNameExtracted, tenantId);
} else {
LdapName ldapName;
try {
@ -672,6 +688,30 @@ public class CertificateGenerator {
}
}
public void saveCertificate(io.entgra.device.mgt.core.certificate.mgt.core.bean.Certificate
certificate) throws KeystoreException {
if (certificate == null) {
return;
}
try {
CertificateDAO certificateDAO = CertificateManagementDAOFactory.getCertificateDAO();
CertificateManagementDAOFactory.beginTransaction();
certificateDAO.addCertificate(certificate);
CertificateManagementDAOFactory.commitTransaction();
} catch (CertificateManagementDAOException e) {
String errorMsg = "Error occurred when saving the generated certificate in database";
log.error(errorMsg);
CertificateManagementDAOFactory.rollbackTransaction();
throw new KeystoreException(errorMsg, e);
} catch (TransactionManagementException e) {
String errorMsg = "Error occurred when saving the generated certificate in database";
log.error(errorMsg);
throw new KeystoreException(errorMsg, e);
}
}
public void saveCertInKeyStore(List<io.entgra.device.mgt.core.certificate.mgt.core.bean.Certificate> certificate)
throws KeystoreException {

@ -271,6 +271,43 @@ public class KeyStoreReader {
return raPrivateKey;
}
public CertificateResponse getCertificateBySerial(String serialNumber, int tenantId) throws KeystoreException {
CertificateResponse certificateResponse = null;
try {
CertificateCacheManager cacheManager = CertificateCacheManagerImpl.getInstance();
certificateResponse = cacheManager.getCertificateBySerial(serialNumber);
if (certificateResponse == null) {
try {
CertificateManagementDAOFactory.openConnection();
certificateResponse = certDao.retrieveCertificate(serialNumber, tenantId);
} catch (SQLException e) {
String errorMsg = "Error when making a connection to the database.";
throw new KeystoreException(errorMsg, e);
} finally {
CertificateManagementDAOFactory.closeConnection();
}
if (certificateResponse != null && certificateResponse.getCertificate() != null) {
Certificate certificate = (Certificate) Serializer.deserialize(certificateResponse.getCertificate());
if (certificate instanceof X509Certificate) {
X509Certificate x509cert = (X509Certificate) certificate;
String commonName = CertificateGenerator.getCommonName(x509cert);
certificateResponse.setCommonName(commonName);
cacheManager.addCertificateBySerial(serialNumber, certificateResponse);
}
}
}
} catch (CertificateManagementDAOException e) {
String errorMsg = "Error when retrieving certificate from the the database for the serial number: " +
serialNumber;
throw new KeystoreException(errorMsg, e);
} catch (ClassNotFoundException | IOException e) {
String errorMsg = "Error when de-serializing saved certificate.";
throw new KeystoreException(errorMsg, e);
}
return certificateResponse;
}
public CertificateResponse getCertificateBySerial(String serialNumber) throws KeystoreException {
CertificateResponse certificateResponse = null;
try {

@ -18,7 +18,7 @@
-->
<DataSourceConfig>
<Url>jdbc:h2:mem:cdm-test-db;DB_CLOSE_ON_EXIT=FALSE;MVCC=true</Url>
<Url>jdbc:h2:mem:cdm-test-db;DB_CLOSE_ON_EXIT=FALSE</Url>
<DriverClassName>org.h2.Driver</DriverClassName>
<User>wso2carbon</User>
<Password>wso2carbon</Password>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -106,13 +106,19 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
--add-opens=java.xml/jdk.xml.internal=ALL-UNNAMED
--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED
</argLine>
<systemPropertyVariables>
<log4j.configuration>file:src/test/resources/carbon-home/repository/conf/log4j.properties
</log4j.configuration>
<log4j.configuration>file:src/test/resources/log4j.properties</log4j.configuration>
</systemPropertyVariables>
<suiteXmlFiles>
<file>src/test/resources/testng.xml</file>
</suiteXmlFiles>
<classpathDependencyExcludes>
<classpathDependencyExclude>org.ops4j.pax.logging</classpathDependencyExclude>
</classpathDependencyExcludes>
</configuration>
</plugin>
</plugins>
@ -207,5 +213,15 @@
<groupId>org.wso2.orbit.javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -104,6 +104,21 @@
<artifactId>io.entgra.device.mgt.core.device.mgt.core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -157,6 +172,25 @@
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
--add-opens=java.xml/jdk.xml.internal=ALL-UNNAMED
--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED
</argLine>
<systemPropertyVariables>
<log4j.configuration>file:src/test/resources/log4j.properties</log4j.configuration>
</systemPropertyVariables>
<suiteXmlFiles>
<file>src/test/resources/testng.xml</file>
</suiteXmlFiles>
<classpathDependencyExcludes>
<classpathDependencyExclude>org.ops4j.pax.logging</classpathDependencyExclude>
</classpathDependencyExcludes>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>

@ -21,7 +21,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -122,6 +122,16 @@
<artifactId>powermock-module-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.securevault</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
@ -189,6 +199,25 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
--add-opens=java.xml/jdk.xml.internal=ALL-UNNAMED
--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED
</argLine>
<systemPropertyVariables>
<log4j.configuration>file:src/test/resources/log4j.properties</log4j.configuration>
</systemPropertyVariables>
<suiteXmlFiles>
<file>src/test/resources/testng.xml</file>
</suiteXmlFiles>
<classpathDependencyExcludes>
<classpathDependencyExclude>org.ops4j.pax.logging</classpathDependencyExclude>
</classpathDependencyExcludes>
</configuration>
</plugin>
</plugins>
</build>

@ -1,658 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
~ Copyright (c) 2018 - 2023, 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.
-->
<!--
This is the main server configuration file
${carbon.home} represents the carbon.home system property.
Other system properties can be specified in a similar manner.
-->
<Server xmlns="http://wso2.org/projects/carbon/carbon.xml">
<!--
Product Name
-->
<Name>${product.name}</Name>
<!--
machine readable unique key to identify each product
-->
<ServerKey>${product.key}</ServerKey>
<!--
Product Version
-->
<Version>${product.version}</Version>
<!--
Host name or IP address of the machine hosting this server
e.g. www.wso2.org, 192.168.1.10
This is will become part of the End Point Reference of the
services deployed on this server instance.
-->
<!--HostName>www.wso2.org</HostName-->
<!--
Host name to be used for the Carbon management console
-->
<!--MgtHostName>mgt.wso2.org</MgtHostName-->
<!--
The URL of the back end server. This is where the admin services are hosted and
will be used by the clients in the front end server.
This is required only for the Front-end server. This is used when seperating BE server from FE server
-->
<ServerURL>local:/${carbon.context}/services/</ServerURL>
<!--
<ServerURL>https://${carbon.local.ip}:${carbon.management.port}${carbon.context}/services/</ServerURL>
-->
<!--
The URL of the index page. This is where the user will be redirected after signing in to the
carbon server.
-->
<!-- IndexPageURL>/carbon/admin/index.jsp</IndexPageURL-->
<!--
For cApp deployment, we have to identify the roles that can be acted by the current server.
The following property is used for that purpose. Any number of roles can be defined here.
Regular expressions can be used in the role.
Ex : <Role>.*</Role> means this server can act any role
-->
<ServerRoles>
<Role>${default.server.role}</Role>
</ServerRoles>
<!-- uncommnet this line to subscribe to a bam instance automatically -->
<!--<BamServerURL>https://bamhost:bamport/services/</BamServerURL>-->
<!--
The fully qualified name of the server
-->
<Package>org.wso2.carbon</Package>
<!--
Webapp context root of WSO2 Carbon management console.
-->
<WebContextRoot>/</WebContextRoot>
<!--
Proxy context path is a useful parameter to add a proxy path when a Carbon server is fronted by reverse proxy. In addtion
to the proxy host and proxy port this parameter allows you add a path component to external URLs. e.g.
URL of the Carbon server -> https://10.100.1.1:9443/carbon
URL of the reverse proxy -> https://prod.abc.com/appserver/carbon
appserver - proxy context path. This specially required whenever you are generating URLs to displace in
Carbon UI components.
-->
<!--
<MgtProxyContextPath></MgtProxyContextPath>
<ProxyContextPath></ProxyContextPath>
-->
<!-- In-order to get the registry http Port from the back-end when the default http transport is not the same-->
<!--RegistryHttpPort>9763</RegistryHttpPort-->
<!--
Number of items to be displayed on a management console page. This is used at the
backend server for pagination of various items.
-->
<ItemsPerPage>15</ItemsPerPage>
<!-- The endpoint URL of the cloud instance management Web service -->
<!--<InstanceMgtWSEndpoint>https://ec2.amazonaws.com/</InstanceMgtWSEndpoint>-->
<!--
Ports used by this server
-->
<Ports>
<!-- Ports offset. This entry will set the value of the ports defined below to
the define value + Offset.
e.g. Offset=2 and HTTPS port=9443 will set the effective HTTPS port to 9445
-->
<Offset>0</Offset>
<!-- The JMX Ports -->
<JMX>
<!--The port RMI registry is exposed-->
<RMIRegistryPort>9999</RMIRegistryPort>
<!--The port RMI server should be exposed-->
<RMIServerPort>11111</RMIServerPort>
</JMX>
<!-- Embedded LDAP server specific ports -->
<EmbeddedLDAP>
<!-- Port which embedded LDAP server runs -->
<LDAPServerPort>10389</LDAPServerPort>
<!-- Port which KDC (Kerberos Key Distribution Center) server runs -->
<KDCServerPort>8000</KDCServerPort>
</EmbeddedLDAP>
<!--
Override datasources JNDIproviderPort defined in bps.xml and datasources.properties files
-->
<!--<JNDIProviderPort>2199</JNDIProviderPort>-->
<!--Override receive port of thrift based entitlement service.-->
<ThriftEntitlementReceivePort>10500</ThriftEntitlementReceivePort>
</Ports>
<!--
JNDI Configuration
-->
<JNDI>
<!--
The fully qualified name of the default initial context factory
-->
<DefaultInitialContextFactory>org.wso2.carbon.tomcat.jndi.CarbonJavaURLContextFactory</DefaultInitialContextFactory>
<!--
The restrictions that are done to various JNDI Contexts in a Multi-tenant environment
-->
<Restrictions>
<!--
Contexts that will be available only to the super-tenant
-->
<!-- <SuperTenantOnly>
<UrlContexts>
<UrlContext>
<Scheme>foo</Scheme>
</UrlContext>
<UrlContext>
<Scheme>bar</Scheme>
</UrlContext>
</UrlContexts>
</SuperTenantOnly> -->
<!--
Contexts that are common to all tenants
-->
<AllTenants>
<UrlContexts>
<UrlContext>
<Scheme>java</Scheme>
</UrlContext>
<!-- <UrlContext>
<Scheme>foo</Scheme>
</UrlContext> -->
</UrlContexts>
</AllTenants>
<!--
All other contexts not mentioned above will be available on a per-tenant basis
(i.e. will not be shared among tenants)
-->
</Restrictions>
</JNDI>
<!--
Property to determine if the server is running an a cloud deployment environment.
This property should only be used to determine deployment specific details that are
applicable only in a cloud deployment, i.e when the server deployed *-as-a-service.
-->
<IsCloudDeployment>false</IsCloudDeployment>
<!--
Property to determine whether usage data should be collected for metering purposes
-->
<EnableMetering>false</EnableMetering>
<!-- The Max time a thread should take for execution in seconds -->
<MaxThreadExecutionTime>600</MaxThreadExecutionTime>
<!--
A flag to enable or disable Ghost Deployer. By default this is set to false. That is
because the Ghost Deployer works only with the HTTP/S transports. If you are using
other transports, don't enable Ghost Deployer.
-->
<GhostDeployment>
<Enabled>false</Enabled>
</GhostDeployment>
<!--
Eager loading or lazy loading is a design pattern commonly used in computer programming which
will initialize an object upon creation or load on-demand. In carbon, lazy loading is used to
load tenant when a request is received only. Similarly Eager loading is used to enable load
existing tenants after carbon server starts up. Using this feature, you will be able to include
or exclude tenants which are to be loaded when server startup.
We can enable only one LoadingPolicy at a given time.
1. Tenant Lazy Loading
This is the default behaviour and enabled by default. With this policy, tenants are not loaded at
server startup, but loaded based on-demand (i.e when a request is received for a tenant).
The default tenant idle time is 30 minutes.
2. Tenant Eager Loading
This is by default not enabled. It can be be enabled by un-commenting the <EagerLoading> section.
The eager loading configurations supported are as below. These configurations can be given as the
value for <Include> element with eager loading.
(i)Load all tenants when server startup - *
(ii)Load all tenants except foo.com & bar.com - *,!foo.com,!bar.com
(iii)Load only foo.com & bar.com to be included - foo.com,bar.com
-->
<Tenant>
<LoadingPolicy>
<LazyLoading>
<IdleTime>30</IdleTime>
</LazyLoading>
<!-- <EagerLoading>
<Include>*,!foo.com,!bar.com</Include>
</EagerLoading>-->
</LoadingPolicy>
</Tenant>
<!--
Caching related configurations
-->
<Cache>
<!-- Default cache timeout in minutes -->
<DefaultCacheTimeout>15</DefaultCacheTimeout>
</Cache>
<!--
Axis2 related configurations
-->
<Axis2Config>
<!--
Location of the Axis2 Services & Modules repository
This can be a directory in the local file system, or a URL.
e.g.
1. /home/wso2wsas/repository/ - An absolute path
2. repository - In this case, the path is relative to CARBON_HOME
3. file:///home/wso2wsas/repository/
4. http://wso2wsas/repository/
-->
<RepositoryLocation>${carbon.home}/repository/deployment/server/</RepositoryLocation>
<!--
Deployment update interval in seconds. This is the interval between repository listener
executions.
-->
<DeploymentUpdateInterval>15</DeploymentUpdateInterval>
<!--
Location of the main Axis2 configuration descriptor file, a.k.a. axis2.xml file
This can be a file on the local file system, or a URL
e.g.
1. /home/repository/axis2.xml - An absolute path
2. conf/axis2.xml - In this case, the path is relative to CARBON_HOME
3. file:///home/carbon/repository/axis2.xml
4. http://repository/conf/axis2.xml
-->
<ConfigurationFile>${carbon.home}/repository/conf/axis2/axis2.xml</ConfigurationFile>
<!--
ServiceGroupContextIdleTime, which will be set in ConfigurationContex
for multiple clients which are going to access the same ServiceGroupContext
Default Value is 30 Sec.
-->
<ServiceGroupContextIdleTime>30000</ServiceGroupContextIdleTime>
<!--
This repository location is used to crete the client side configuration
context used by the server when calling admin services.
-->
<ClientRepositoryLocation>${carbon.home}/repository/deployment/client/</ClientRepositoryLocation>
<!-- This axis2 xml is used in createing the configuration context by the FE server
calling to BE server -->
<clientAxis2XmlLocation>${carbon.home}/repository/conf/axis2/axis2_client.xml</clientAxis2XmlLocation>
<!-- If this parameter is set, the ?wsdl on an admin service will not give the admin service wsdl. -->
<HideAdminServiceWSDLs>true</HideAdminServiceWSDLs>
<!--WARNING-Use With Care! Uncommenting bellow parameter would expose all AdminServices in HTTP transport.
With HTTP transport your credentials and data routed in public channels are vulnerable for sniffing attacks.
Use bellow parameter ONLY if your communication channels are confirmed to be secured by other means -->
<!--HttpAdminServices>*</HttpAdminServices-->
</Axis2Config>
<!--
The default user roles which will be created when the server
is started up for the first time.
-->
<ServiceUserRoles>
<Role>
<Name>admin</Name>
<Description>Default Administrator Role</Description>
</Role>
<Role>
<Name>user</Name>
<Description>Default User Role</Description>
</Role>
</ServiceUserRoles>
<!--
Enable following config to allow Emails as usernames.
-->
<!--EnableEmailUserName>true</EnableEmailUserName-->
<!--
Security configurations
-->
<Security>
<!--
KeyStore which will be used for encrypting/decrypting passwords
and other sensitive information.
-->
<KeyStore>
<!-- Keystore file location-->
<Location>${carbon.home}/repository/resources/security/wso2carbon.jks</Location>
<!-- Keystore type (JKS/PKCS12 etc.)-->
<Type>JKS</Type>
<!-- Keystore password-->
<Password>wso2carbon</Password>
<!-- Private Key alias-->
<KeyAlias>wso2carbon</KeyAlias>
<!-- Private Key password-->
<KeyPassword>wso2carbon</KeyPassword>
</KeyStore>
<!--
System wide trust-store which is used to maintain the certificates of all
the trusted parties.
-->
<TrustStore>
<!-- trust-store file location -->
<Location>${carbon.home}/repository/resources/security/client-truststore.jks</Location>
<!-- trust-store type (JKS/PKCS12 etc.) -->
<Type>JKS</Type>
<!-- trust-store password -->
<Password>wso2carbon</Password>
</TrustStore>
<!--
The Authenticator configuration to be used at the JVM level. We extend the
java.net.Authenticator to make it possible to authenticate to given servers and
proxies.
-->
<NetworkAuthenticatorConfig>
<!--
Below is a sample configuration for a single authenticator. Please note that
all child elements are mandatory. Not having some child elements would lead to
exceptions at runtime.
-->
<!-- <Credential> -->
<!--
the pattern that would match a subset of URLs for which this authenticator
would be used
-->
<!-- <Pattern>regularExpression</Pattern> -->
<!--
the type of this authenticator. Allowed values are:
1. server
2. proxy
-->
<!-- <Type>proxy</Type> -->
<!-- the username used to log in to server/proxy -->
<!-- <Username>username</Username> -->
<!-- the password used to log in to server/proxy -->
<!-- <Password>password</Password> -->
<!-- </Credential> -->
</NetworkAuthenticatorConfig>
<!--
The Tomcat realm to be used for hosted Web applications. Allowed values are;
1. UserManager
2. Memory
If this is set to 'UserManager', the realm will pick users & roles from the system's
WSO2 User Manager. If it is set to 'memory', the realm will pick users & roles from
CARBON_HOME/repository/conf/tomcat/tomcat-users.xml
-->
<TomcatRealm>UserManager</TomcatRealm>
<!--Option to disable storing of tokens issued by STS-->
<DisableTokenStore>false</DisableTokenStore>
<!--
Security token store class name. If this is not set, default class will be
org.wso2.carbon.security.util.SecurityTokenStore
-->
<!--TokenStoreClassName>org.wso2.carbon.identity.sts.store.DBTokenStore</TokenStoreClassName-->
</Security>
<!--
The temporary work directory
-->
<WorkDirectory>${carbon.home}/tmp/work</WorkDirectory>
<!--
House-keeping configuration
-->
<HouseKeeping>
<!--
true - Start House-keeping thread on server startup
false - Do not start House-keeping thread on server startup.
The user will run it manually as and when he wishes.
-->
<AutoStart>true</AutoStart>
<!--
The interval in *minutes*, between house-keeping runs
-->
<Interval>10</Interval>
<!--
The maximum time in *minutes*, temp files are allowed to live
in the system. Files/directories which were modified more than
"MaxTempFileLifetime" minutes ago will be removed by the
house-keeping task
-->
<MaxTempFileLifetime>30</MaxTempFileLifetime>
</HouseKeeping>
<!--
Configuration for handling different types of file upload & other file uploading related
config parameters.
To map all actions to a particular FileUploadExecutor, use
<Action>*</Action>
-->
<FileUploadConfig>
<!--
The total file upload size limit in MB
-->
<TotalFileSizeLimit>100</TotalFileSizeLimit>
<Mapping>
<Actions>
<Action>keystore</Action>
<Action>certificate</Action>
<Action>*</Action>
</Actions>
<Class>org.wso2.carbon.ui.transports.fileupload.AnyFileUploadExecutor</Class>
</Mapping>
<Mapping>
<Actions>
<Action>jarZip</Action>
</Actions>
<Class>org.wso2.carbon.ui.transports.fileupload.JarZipUploadExecutor</Class>
</Mapping>
<Mapping>
<Actions>
<Action>dbs</Action>
</Actions>
<Class>org.wso2.carbon.ui.transports.fileupload.DBSFileUploadExecutor</Class>
</Mapping>
<Mapping>
<Actions>
<Action>tools</Action>
</Actions>
<Class>org.wso2.carbon.ui.transports.fileupload.ToolsFileUploadExecutor</Class>
</Mapping>
<Mapping>
<Actions>
<Action>toolsAny</Action>
</Actions>
<Class>org.wso2.carbon.ui.transports.fileupload.ToolsAnyFileUploadExecutor</Class>
</Mapping>
</FileUploadConfig>
<!--
Processors which process special HTTP GET requests such as ?wsdl, ?policy etc.
In order to plug in a processor to handle a special request, simply add an entry to this
section.
The value of the Item element is the first parameter in the query string(e.g. ?wsdl)
which needs special processing
The value of the Class element is a class which implements
org.wso2.carbon.transport.HttpGetRequestProcessor
-->
<HttpGetRequestProcessors>
<Processor>
<Item>info</Item>
<Class>org.wso2.carbon.core.transports.util.InfoProcessor</Class>
</Processor>
<Processor>
<Item>wsdl</Item>
<Class>org.wso2.carbon.core.transports.util.Wsdl11Processor</Class>
</Processor>
<Processor>
<Item>wsdl2</Item>
<Class>org.wso2.carbon.core.transports.util.Wsdl20Processor</Class>
</Processor>
<Processor>
<Item>xsd</Item>
<Class>org.wso2.carbon.core.transports.util.XsdProcessor</Class>
</Processor>
</HttpGetRequestProcessors>
<!-- Deployment Synchronizer Configuration. t Enabled value to true when running with "svn based" dep sync.
In master nodes you need to set both AutoCommit and AutoCheckout to true
and in worker nodes set only AutoCheckout to true.
-->
<DeploymentSynchronizer>
<Enabled>false</Enabled>
<AutoCommit>false</AutoCommit>
<AutoCheckout>true</AutoCheckout>
<RepositoryType>svn</RepositoryType>
<SvnUrl>http://svnrepo.example.com/repos/</SvnUrl>
<SvnUser>username</SvnUser>
<SvnPassword>password</SvnPassword>
<SvnUrlAppendTenantId>true</SvnUrlAppendTenantId>
</DeploymentSynchronizer>
<!-- Deployment Synchronizer Configuration. Uncomment the following section when running with "registry based" dep sync.
In master nodes you need to set both AutoCommit and AutoCheckout to true
and in worker nodes set only AutoCheckout to true.
-->
<!--<DeploymentSynchronizer>
<Enabled>true</Enabled>
<AutoCommit>false</AutoCommit>
<AutoCheckout>true</AutoCheckout>
</DeploymentSynchronizer>-->
<!-- Mediation persistence configurations. Only valid if mediation features are available i.e. ESB -->
<!--<MediationConfig>
<LoadFromRegistry>false</LoadFromRegistry>
<SaveToFile>false</SaveToFile>
<Persistence>enabled</Persistence>
<RegistryPersistence>enabled</RegistryPersistence>
</MediationConfig>-->
<!--
Server intializing code, specified as implementation classes of org.wso2.carbon.core.ServerInitializer.
This code will be run when the Carbon server is initialized
-->
<ServerInitializers>
<!--<Initializer></Initializer>-->
</ServerInitializers>
<!--
Indicates whether the Carbon Servlet is required by the system, and whether it should be
registered
-->
<RequireCarbonServlet>${require.carbon.servlet}</RequireCarbonServlet>
<!--
Carbon H2 OSGI Configuration
By default non of the servers start.
name="web" - Start the web server with the H2 Console
name="webPort" - The port (default: 8082)
name="webAllowOthers" - Allow other computers to connect
name="webSSL" - Use encrypted (HTTPS) connections
name="tcp" - Start the TCP server
name="tcpPort" - The port (default: 9092)
name="tcpAllowOthers" - Allow other computers to connect
name="tcpSSL" - Use encrypted (SSL) connections
name="pg" - Start the PG server
name="pgPort" - The port (default: 5435)
name="pgAllowOthers" - Allow other computers to connect
name="trace" - Print additional trace information; for all servers
name="baseDir" - The base directory for H2 databases; for all servers
-->
<!--H2DatabaseConfiguration>
<property name="web" />
<property name="webPort">8082</property>
<property name="webAllowOthers" />
<property name="webSSL" />
<property name="tcp" />
<property name="tcpPort">9092</property>
<property name="tcpAllowOthers" />
<property name="tcpSSL" />
<property name="pg" />
<property name="pgPort">5435</property>
<property name="pgAllowOthers" />
<property name="trace" />
<property name="baseDir">${carbon.home}</property>
</H2DatabaseConfiguration-->
<!--Disabling statistics reporter by default-->
<StatisticsReporterDisabled>true</StatisticsReporterDisabled>
<!-- Enable accessing Admin Console via HTTP -->
<!-- EnableHTTPAdminConsole>true</EnableHTTPAdminConsole -->
<!--
Default Feature Repository of WSO2 Carbon.
-->
<FeatureRepository>
<RepositoryName>default repository</RepositoryName>
<RepositoryURL>${p2.repo.url}</RepositoryURL>
</FeatureRepository>
<!--
Configure API Management
-->
<APIManagement>
<!--Uses the embedded API Manager by default. If you want to use an external
API Manager instance to manage APIs, configure below externalAPIManager-->
<Enabled>true</Enabled>
<!--Uncomment and configure API Gateway and
Publisher URLs to use external API Manager instance-->
<!--ExternalAPIManager>
<APIGatewayURL>http://localhost:8281</APIGatewayURL>
<APIPublisherURL>http://localhost:8281/publisher</APIPublisherURL>
</ExternalAPIManager-->
<LoadAPIContextsInServerStartup>true</LoadAPIContextsInServerStartup>
</APIManagement>
</Server>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -364,7 +364,7 @@
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<artifactId>powermock-api-mockito2</artifactId>
<scope>test</scope>
</dependency>
<dependency>

@ -20,15 +20,39 @@ package io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.api;
import io.entgra.device.mgt.core.apimgt.annotations.Scope;
import io.entgra.device.mgt.core.apimgt.annotations.Scopes;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.*;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.DeviceGroupList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.DeviceList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.DeviceToGroupsAssignment;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.ErrorResponse;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.RoleList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.util.Constants;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.swagger.annotations.*;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
import io.swagger.annotations.ResponseHeader;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.apache.axis2.transport.http.HTTPConstants;
import javax.validation.Valid;
import javax.ws.rs.*;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
@ -159,6 +183,13 @@ import java.util.List;
key = "perm:groups:devices-types",
roles = {"Internal/devicemgt-user"},
permissions = {"/device-mgt/groups/devices/types"}
),
@Scope(
name = "View whether the groups has relevant device types",
description = "View whether the groups has relevant device types",
key = "perm:groups:add",
roles = {"Internal/devicemgt-user"},
permissions = {"/device-mgt/groups/device-types"}
)
}
)
@ -1206,4 +1237,77 @@ public interface GroupManagementService {
required = true)
List<String> identifiers);
@POST
@Path("/roles/share")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = HTTPConstants.HEADER_POST,
value = "Consolidated API for Creating a Device Group, Adding Devices, and Sharing",
notes = "This API can be used to create a new device group, add devices to the group, and share the group with user roles.",
tags = "Device Group Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:add")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 201,
message = "Created. \n Device group has successfully been created.",
responseHeaders = {
@ResponseHeader(
name = "Content-Location",
description = "The URL of the created group."),
@ResponseHeader(
name = "Content-Type",
description = "The 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 has been modified the last time.\n" +
"Used by caches, or in conditional requests.")
}
),
@ApiResponse(
code = 303,
message = "See Other. \n Source can be retrieved from the URL specified at the Location " +
"header.",
responseHeaders = {
@ResponseHeader(
name = "Content-Location",
description = "The Source URL of the document.")}),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Current logged in user is not authorized to perform the operation.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Group not found.",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while creating the group or adding devices or sharing the group.",
response = ErrorResponse.class)
})
Response createGroupWithRoles(
@ApiParam(
name = "group",
value = "Define the group object with data.",
required = true)
@Valid DeviceGroupRoleWrapper group
);
}

@ -187,6 +187,104 @@ public interface RoleManagementService {
defaultValue = "5")
@QueryParam("limit") int limit);
@GET
@Path("/visible/{metaKey}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting the List of Visible Roles",
notes = "WSO2 IoTS supports role-based access control (RBAC) and role management. Using this API you can the list of roles that are in WSO2 IoTS.\n" +
"Note: Internal roles, roles created for service-providers, and application related roles will not be given in the output.",
tags = "Role Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:roles:view")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully fetched the list of roles in WSO2 IoTS.",
response = RoleList.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The 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 has been modified the last time.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 304,
message = "Not Modified. \n Empty body because the client already has the latest version of the " +
"requested resource."),
@ApiResponse(
code = 404,
message = "Not Found. \n The specified resource does not exist.\n",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the list of roles" +
" assigned to the specified user.",
response = ErrorResponse.class)
})
Response getVisibleRole(
@ApiParam(
name = "filter",
value = "Provide a character or a few characters in the role name.",
required = false)
@QueryParam("filter") String filter,
@ApiParam(
name = "user-store",
value = "The name of the UserStore you wish to get the list of roles.",
required = false)
@QueryParam("user-store") String userStoreName,
@ApiParam(
name = "If-Modified-Since",
value = "Checks if the requested variant was modified, since the specified date-time." +
"Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" +
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false)
@HeaderParam("If-Modified-Since") String ifModifiedSince,
@ApiParam(
name = "offset",
value = "The starting pagination index for the complete list of qualified items.",
required = false,
defaultValue = "0")
@QueryParam("offset") int offset,
@ApiParam(
name = "limit",
value = "Provide how many role details you require from the starting pagination index/offset.",
required = false,
defaultValue = "5")
@QueryParam("limit") int limit,
@ApiParam(
name = "username",
value = "The username of the user.",
required = true,
defaultValue = "admin")
@QueryParam("username") String username,
@ApiParam(
name = "domain",
value = "The domain name of the user store.",
required = false)
@QueryParam("domain") String domain,
@ApiParam(
name = "metaKey",
value = "Key of the metadata",
required = true)
@PathParam("metaKey") String metaKey);
@GET
@Path("/filter/{prefix}")
@ApiOperation(

@ -20,15 +20,32 @@ package io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.api.admin;
import io.entgra.device.mgt.core.apimgt.annotations.Scope;
import io.entgra.device.mgt.core.apimgt.annotations.Scopes;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.DeviceGroupList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.ErrorResponse;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.util.Constants;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.swagger.annotations.*;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Info;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Extension;
import io.swagger.annotations.Tag;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.ResponseHeader;
import org.apache.axis2.transport.http.HTTPConstants;
import javax.validation.Valid;
import javax.ws.rs.*;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@ -358,4 +375,79 @@ public interface GroupManagementAdminService {
required = true)
@Valid DeviceGroup group);
@POST
@Path("/roles/share")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = HTTPConstants.HEADER_POST,
value = "Consolidated API for Creating a Device Group, Adding Devices, and Sharing",
notes = "This API can be used to create a new device group, add devices to the group, and share the group with user roles.",
tags = "Device Group Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:add")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 201,
message = "Created. \n Device group has successfully been created.",
responseHeaders = {
@ResponseHeader(
name = "Content-Location",
description = "The URL of the created group."),
@ResponseHeader(
name = "Content-Type",
description = "The 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 has been modified the last time.\n" +
"Used by caches, or in conditional requests.")
}
),
@ApiResponse(
code = 303,
message = "See Other. \n Source can be retrieved from the URL specified at the Location " +
"header.",
responseHeaders = {
@ResponseHeader(
name = "Content-Location",
description = "The Source URL of the document.")}),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Current logged in user is not authorized to perform the operation.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Group not found.",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while creating the group or adding devices or sharing the group.",
response = ErrorResponse.class)
})
Response createGroupWithRoles(@ApiParam(
name = "group",
value = "Define the group object with data.",
required = true)
@Valid DeviceGroupRoleWrapper group
);
}

@ -25,7 +25,11 @@ import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.RoleList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.api.GroupManagementService;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.impl.util.RequestValidationUtil;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.util.DeviceMgtAPIUtils;
import io.entgra.device.mgt.core.device.mgt.common.*;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.EnrolmentInfo;
import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceNotFoundException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.*;
@ -36,11 +40,19 @@ import io.entgra.device.mgt.core.policy.mgt.common.PolicyManagementException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException;
import javax.ws.rs.*;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class GroupManagementServiceImpl implements GroupManagementService {
@ -94,8 +106,18 @@ public class GroupManagementServiceImpl implements GroupManagementService {
request.setGroupName(name);
request.setOwner(owner);
request.setDepth(depth);
PaginationResult deviceGroupsResult = DeviceMgtAPIUtils.getGroupManagementProviderService()
.getGroupsWithHierarchy(currentUser, request, requireGroupProps);
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
UserRealm realmService = DeviceMgtAPIUtils.getRealmService().getTenantUserRealm(tenantId);
String[] roles = realmService.getUserStoreManager().getRoleListOfUser(currentUser);
boolean hasAdminRole = Arrays.asList(roles).contains(DEFAULT_ADMIN_ROLE);
PaginationResult deviceGroupsResult;
if (hasAdminRole) {
deviceGroupsResult = DeviceMgtAPIUtils.getGroupManagementProviderService()
.getGroupsWithHierarchy(null, request, requireGroupProps);
} else{
deviceGroupsResult = DeviceMgtAPIUtils.getGroupManagementProviderService()
.getGroupsWithHierarchy(currentUser, request, requireGroupProps);
}
DeviceGroupList deviceGroupList = new DeviceGroupList();
deviceGroupList.setList(deviceGroupsResult.getData());
deviceGroupList.setCount(deviceGroupsResult.getRecordsTotal());
@ -104,6 +126,10 @@ public class GroupManagementServiceImpl implements GroupManagementService {
String error = "Error occurred while retrieving groups with hierarchy.";
log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
} catch (UserStoreException e) {
String msg = "Error occurred while getting user realm.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
@ -416,4 +442,37 @@ public class GroupManagementServiceImpl implements GroupManagementService {
}
}
}
@POST
@Path("/roles/share")
@Override
public Response createGroupWithRoles(DeviceGroupRoleWrapper groups) {
if (groups == null) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
groups.setOwner(PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername());
groups.setStatus(DeviceGroupConstants.GroupStatus.ACTIVE);
try {
DeviceMgtAPIUtils.getGroupManagementProviderService().createGroupWithRoles(groups, DEFAULT_ADMIN_ROLE, DEFAULT_ADMIN_PERMISSIONS);
DeviceGroup group = DeviceMgtAPIUtils.getGroupManagementProviderService().getGroup(groups.getName(),
PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername().isEmpty());
if (group != null) {
DeviceMgtAPIUtils.getGroupManagementProviderService().manageGroupSharing(group.getGroupId(), groups.getUserRoles());
return Response.status(Response.Status.CREATED).entity(group.getGroupId()).build();
} else {
String msg = "Error occurred while retrieving newly created group.";
log.error(msg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
} catch (GroupManagementException e) {
String msg = "Error occurred while adding " + groups.getName() + " group";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (GroupAlreadyExistException e) {
String msg = "Group already exists with name : " + groups.getName() + " Try with another group name.";
log.error(msg, e);
return Response.status(Response.Status.CONFLICT).entity(msg).build();
} catch (RoleDoesNotExistException e) {
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
}
}
}

@ -17,6 +17,10 @@
*/
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.impl;
import com.google.common.base.Strings;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.ErrorResponse;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.RoleInfo;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.RoleList;
@ -28,6 +32,10 @@ import io.entgra.device.mgt.core.device.mgt.api.jaxrs.util.DeviceMgtAPIUtils;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.util.SetReferenceTransformer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.util.StringUtils;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.CarbonContext;
@ -35,21 +43,39 @@ import org.wso2.carbon.context.RegistryType;
import org.wso2.carbon.registry.api.Registry;
import org.wso2.carbon.registry.core.session.UserRegistry;
import org.wso2.carbon.registry.resource.services.utils.ChangeRolePermissionsUtil;
import org.wso2.carbon.user.api.*;
import org.wso2.carbon.user.api.AuthorizationManager;
import org.wso2.carbon.user.api.Permission;
import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.user.core.common.AbstractUserStoreManager;
import org.wso2.carbon.user.core.constants.UserCoreErrorConstants.ErrorMessages;
import org.wso2.carbon.user.mgt.UserRealmProxy;
import org.wso2.carbon.user.mgt.common.UIPermissionNode;
import org.wso2.carbon.user.mgt.common.UserAdminException;
import javax.ws.rs.*;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import static io.entgra.device.mgt.core.device.mgt.api.jaxrs.util.Constants.PRIMARY_USER_STORE;
@ -97,6 +123,96 @@ public class RoleManagementServiceImpl implements RoleManagementService {
}
}
@GET
@Path("/visible/{metaKey}")
@Override
public Response getVisibleRole(
@QueryParam("filter") String filter,
@QueryParam("user-store") String userStore,
@HeaderParam("If-Modified-Since") String ifModifiedSince,
@QueryParam("offset") int offset,
@QueryParam("limit") int limit,
@QueryParam("username") String username,
@QueryParam("domain") String domain,
@PathParam("metaKey") String metaKey) {
RequestValidationUtil.validatePaginationParameters(offset, limit);
if (limit == 0){
limit = Constants.DEFAULT_PAGE_LIMIT;
}
if (!Strings.isNullOrEmpty(domain)) {
username = domain + '/' + username;
}
Metadata metadata;
List<String> visibleRoles;
RoleList visibleRoleList = new RoleList();
try {
metadata = DeviceMgtAPIUtils.getMetadataManagementService().retrieveMetadata(metaKey);
String metaValue = metadata.getMetaValue();
JSONParser parser = new JSONParser();
JSONObject jsonObject = (JSONObject) parser.parse(metaValue);
boolean decision = (boolean) jsonObject.get(Constants.IS_USER_ABLE_TO_VIEW_ALL_ROLES);
if (decision) {
if (Strings.isNullOrEmpty(userStore)){
userStore = PRIMARY_USER_STORE;
}
try {
visibleRoles = getRolesFromUserStore(filter, userStore);
visibleRoleList.setList(visibleRoles);
visibleRoles = FilteringUtil.getFilteredList(getRolesFromUserStore(filter, userStore), offset, limit);
visibleRoleList.setList(visibleRoles);
return Response.status(Response.Status.OK).entity(visibleRoleList).build();
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving roles from the underlying user stores";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
} else {
try {
UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager();
if (!userStoreManager.isExistingUser(username)) {
if (log.isDebugEnabled()) {
log.debug("User by username: " + username + " does not exist for role retrieval.");
}
String msg = "User by username: " + username + " does not exist for role retrieval.";
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
}
visibleRoleList.setList(getFilteredVisibleRoles(userStoreManager, username));
return Response.status(Response.Status.OK).entity(visibleRoleList).build();
} catch (UserStoreException e) {
String msg = "Error occurred while trying to retrieve roles of the user '" + username + "'";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
}
} catch (MetadataManagementException e) {
String msg = "Error occurred while getting the metadata entry for metaKey:" + metaKey;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (ParseException e) {
String msg = "Error occurred while parsing JSON metadata: " + e.getMessage();
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
}
private List<String> getFilteredVisibleRoles(UserStoreManager userStoreManager, String username)
throws UserStoreException {
String[] roleListOfUser;
roleListOfUser = userStoreManager.getRoleListOfUser(username);
List<String> filteredRoles = new ArrayList<>();
for (String role : roleListOfUser) {
if (!(role.startsWith("Internal/") || role.startsWith("Authentication/"))) {
filteredRoles.add(role);
}
}
return filteredRoles;
}
@GET
@Path("/filter/{prefix}")
@Override
@ -542,6 +658,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
@Consumes(MediaType.WILDCARD)
@Override
public Response deleteRole(@PathParam("roleName") String roleName, @QueryParam("user-store") String userStoreName) {
String roleToDelete = roleName;
if (userStoreName != null && !userStoreName.isEmpty()) {
roleName = userStoreName + "/" + roleName;
}
@ -549,6 +666,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
try {
final UserRealm userRealm = DeviceMgtAPIUtils.getUserRealm();
final UserStoreManager userStoreManager = userRealm.getUserStoreManager();
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
if (!userStoreManager.isExistingRole(roleName)) {
String msg = "No role exists with the name : " + roleName ;
return Response.status(404).entity(msg).build();
@ -558,16 +676,18 @@ public class RoleManagementServiceImpl implements RoleManagementService {
if (log.isDebugEnabled()) {
log.debug("Deleting the role in user store");
}
userStoreManager.deleteRole(roleName);
// Delete all authorizations for the current role before deleting
authorizationManager.clearRoleAuthorization(roleName);
DeviceMgtAPIUtils.getGroupManagementProviderService().deleteRoleAndRoleGroupMapping(roleName, roleToDelete, tenantId, userStoreManager, authorizationManager);
return Response.status(Response.Status.OK).build();
} catch (UserStoreException e) {
String msg = "Error occurred while deleting the role '" + roleName + "'";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
} catch (GroupManagementException e) {
String msg = "Error occurred while deleting group-role mapping records";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
}
@ -597,7 +717,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
userStoreManager.updateUserListOfRole(roleName, usersToDelete, usersToAdd);
return Response.status(Response.Status.OK).entity("Role '" + roleName + "' has " +
"successfully been updated with the user list")
"successfully been updated with the user list")
.build();
} catch (UserStoreException e) {
String msg = "Error occurred while updating the users of the role '" + roleName + "'";

@ -424,6 +424,9 @@ public class UserManagementServiceImpl implements UserManagementService {
userList = new ArrayList<>(users.size());
BasicUserInfo user;
for (String username : users) {
if (Constants.APIM_RESERVED_USER.equals(username) || Constants.RESERVED_USER.equals(username)) {
continue;
}
user = getBasicUserInfo(username);
userList.add(user);
}
@ -484,6 +487,10 @@ public class UserManagementServiceImpl implements UserManagementService {
if (StringUtils.isNotEmpty(username)) {
commonUsers = getUserList(null, username);
}
if (commonUsers != null) {
commonUsers.remove(Constants.APIM_RESERVED_USER);
commonUsers.remove(Constants.RESERVED_USER);
}
if (!skipSearch(commonUsers) && StringUtils.isNotEmpty(firstName)) {
tempList = getUserList(Constants.USER_CLAIM_FIRST_NAME, firstName);
@ -658,6 +665,9 @@ public class UserManagementServiceImpl implements UserManagementService {
userList = new ArrayList<>();
UserInfo user;
for (String username : users) {
if (Constants.APIM_RESERVED_USER.equals(username) || Constants.RESERVED_USER.equals(username)) {
continue;
}
user = new UserInfo();
user.setUsername(username);
user.setEmailAddress(getClaimValue(username, Constants.USER_CLAIM_EMAIL_ADDRESS));

@ -21,21 +21,30 @@ import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.DeviceGroupList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.api.admin.GroupManagementAdminService;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.impl.util.RequestValidationUtil;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.util.DeviceMgtAPIUtils;
import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupConstants;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupAlreadyExistException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.RoleDoesNotExistException;
import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.apache.commons.lang.StringUtils;
import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.Arrays;
public class GroupManagementAdminServiceImpl implements GroupManagementAdminService {
@ -90,13 +99,25 @@ public class GroupManagementAdminServiceImpl implements GroupManagementAdminServ
@DefaultValue("5") @QueryParam("limit") int limit) {
try {
RequestValidationUtil.validatePaginationParameters(offset, limit);
String currentUser = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
GroupPaginationRequest request = new GroupPaginationRequest(offset, limit);
request.setGroupName(name);
request.setOwner(owner);
request.setStatus(status);
request.setDepth(depth);
PaginationResult deviceGroupsResult = DeviceMgtAPIUtils.getGroupManagementProviderService()
.getGroupsWithHierarchy(null, request, requireGroupProps);
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
UserRealm realmService = DeviceMgtAPIUtils.getRealmService().getTenantUserRealm(tenantId);
String[] roles = realmService.getUserStoreManager().getRoleListOfUser(currentUser);
boolean isAdmin = DEFAULT_ADMIN_ROLE.equals(currentUser);
boolean hasAdminRole = Arrays.asList(roles).contains(DEFAULT_ADMIN_ROLE);
PaginationResult deviceGroupsResult;
if (StringUtils.isBlank(currentUser) || isAdmin || hasAdminRole) {
deviceGroupsResult = DeviceMgtAPIUtils.getGroupManagementProviderService()
.getGroupsWithHierarchy(null, request, requireGroupProps);
} else {
deviceGroupsResult = DeviceMgtAPIUtils.getGroupManagementProviderService()
.getGroupsWithHierarchy(currentUser, request, requireGroupProps);
}
DeviceGroupList deviceGroupList = new DeviceGroupList();
deviceGroupList.setList(deviceGroupsResult.getData());
deviceGroupList.setCount(deviceGroupsResult.getRecordsTotal());
@ -105,6 +126,10 @@ public class GroupManagementAdminServiceImpl implements GroupManagementAdminServ
String error = "Error occurred while retrieving groups with hierarchy.";
log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
} catch (UserStoreException e) {
String msg = "Error occurred while getting user realm.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
@ -144,4 +169,31 @@ public class GroupManagementAdminServiceImpl implements GroupManagementAdminServ
return Response.status(Response.Status.CONFLICT).entity(msg).build();
}
}
@POST
@Path("/roles/share")
@Override
public Response createGroupWithRoles(DeviceGroupRoleWrapper group) {
if (group == null) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
group.setOwner(PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername());
group.setStatus(DeviceGroupConstants.GroupStatus.ACTIVE);
try {
DeviceMgtAPIUtils.getGroupManagementProviderService().createGroupWithRoles(group, DEFAULT_ADMIN_ROLE, DEFAULT_ADMIN_PERMISSIONS);
DeviceMgtAPIUtils.getGroupManagementProviderService().manageGroupSharing(group.getGroupId(), group.getUserRoles());
return Response.status(Response.Status.CREATED).build();
} catch (GroupManagementException e) {
String msg = "Error occurred while adding " + group.getName() + " group";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (GroupAlreadyExistException e) {
String msg = "Group already exists with name : " + group.getName() + " Try with another group name.";
log.error(msg, e);
return Response.status(Response.Status.CONFLICT).entity(msg).build();
} catch (RoleDoesNotExistException e) {
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
}
}
}

@ -30,13 +30,16 @@ public class Constants {
public static final String USER_CLAIM_MODIFIED = "http://wso2.org/claims/modified";
public static final String USER_CLAIM_DEVICES = "http://wso2.org/claims/devices";
public static final String PRIMARY_USER_STORE = "PRIMARY";
public static final String DEFAULT_STREAM_VERSION = "1.0.0";
public static final String APIM_RESERVED_USER = "apim_reserved_user";
public static final String RESERVED_USER = "reserved_user";
public static final String DEFAULT_STREAM_VERSION = "1.0.0";
public static final String SCOPE = "scope";
public static final String JDBC_USERSTOREMANAGER = "org.wso2.carbon.user.core.jdbc.JDBCUserStoreManager";
public static final String DEFAULT_SIMPLE_DATE_FORMAT = "EEE, d MMM yyyy HH:mm:ss Z";
public static final int DEFAULT_PAGE_LIMIT = 50;
public static final String FORWARD_SLASH = "/";
public static final String ANDROID = "android";
public static final String IS_USER_ABLE_TO_VIEW_ALL_ROLES = "isUserAbleToViewAllRoles";
public static final String ANDROID_POLICY_VALIDATOR = "io.entgra.proprietary.uem.platform.android." +
"core.polcy.AndroidPolicyPayloadValidator";
public static final String IOS = "ios";

@ -21,7 +21,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -134,6 +134,8 @@ public final class DeviceManagementConstants {
public static final String LAST_NAME = "last-name";
public static final String TENANT_ADMIN_USERNAME = "tenant-admin-username";
public static final String TENANT_ADMIN_PASSWORD = "tenant-admin-password";
public static final int OTP_DEFAULT_EXPIRY_SECONDS = 3600;
}
public static final class EventServices {

@ -18,10 +18,22 @@
package io.entgra.device.mgt.core.device.mgt.common.general;
import java.util.Map;
public class QREnrollmentDetails {
String ownershipType;
String username;
String enrollmentMode;
Map<String, String> customValues;
int tokenExpiry;
public Map<String, String> getCustomValues() {
return customValues;
}
public void setCustomValues(Map<String, String> customValues) {
this.customValues = customValues;
}
public String getOwnershipType() { return ownershipType; }
@ -34,4 +46,12 @@ public class QREnrollmentDetails {
public String getEnrollmentMode() { return enrollmentMode; }
public void setEnrollmentMode(String enrollmentMode) { this.enrollmentMode = enrollmentMode; }
public int getTokenExpiry() {
return tokenExpiry;
}
public void setTokenExpiry(int tokenExpiry) {
this.tokenExpiry = tokenExpiry;
}
}

@ -0,0 +1,151 @@
/*
* Copyright (c) 2018 - 2023, 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.group.mgt;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiParam;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* Holds Device Group details and expose to external access
*/
@ApiModel(value = "DeviceGroupRoleWrapper", description = "This class carries all information related to a managed device group.")
public class DeviceGroupRoleWrapper implements Serializable {
private static final long serialVersionUID = 1998121711L;
@ApiModelProperty(name = "id", value = "ID of the device group in the device group information database.")
private int id;
@ApiModelProperty(name = "description", value = "The device group description that can be set on the device group by the user.", required = true)
private String description;
@ApiModelProperty(name = "name", value = "The device group name that can be set on the device group by the user.", required = true)
private String name;
private String owner;
@ApiModelProperty(name = "status", value = "The status of group that needs updating/retrieval.")
private String status;
@ApiModelProperty(name = "parentGroupId", value = "Group ID of parent group")
private int parentGroupId;
@ApiModelProperty(name = "parentPath", value = "Path of parent group")
private String parentPath;
@ApiModelProperty(name = "childrenGroups", value = "Children groups")
private List<DeviceGroup> childrenGroups;
@ApiModelProperty(name = "userRoles", value = "User roles")
private List<String> userRoles;
public DeviceGroupRoleWrapper() {
}
public DeviceGroupRoleWrapper(String name) {
this.name = name;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
private Map<String, String> groupProperties;
public int getGroupId() {
return id;
}
public void setGroupId(int id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public Map<String, String> getGroupProperties() {
return groupProperties;
}
public void setGroupProperties(Map<String, String> groupProperties) {
this.groupProperties = groupProperties;
}
public int getParentGroupId() {
return parentGroupId;
}
public void setParentGroupId(int parentGroupId) {
this.parentGroupId = parentGroupId;
}
public String getParentPath() {
return parentPath;
}
public void setParentPath(String parentPath) {
this.parentPath = parentPath;
}
public List<DeviceGroup> getChildrenGroups() {
return childrenGroups;
}
public void setChildrenGroups(List<DeviceGroup> childrenGroups) {
this.childrenGroups = childrenGroups;
}
public List<String> getUserRoles() {
return userRoles;
}
public void setUserRoles(List<String> userRoles) {
this.userRoles = userRoles;
}
}

@ -19,5 +19,5 @@
package io.entgra.device.mgt.core.device.mgt.common.otp.mgt;
public enum OTPEmailTypes {
USER_VERIFY, DEVICE_ENROLLMENT
USER_VERIFY, DEVICE_ENROLLMENT, USER_INVITE, REMOTE_SESSION
}

@ -35,7 +35,8 @@ public interface OTPManagementService {
* @throws OTPManagementException if error occurred whle verifying validity of the OPT
* @throws BadRequestException if found an null value for OTP
*/
OneTimePinDTO isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException;
OneTimePinDTO isValidOTP(String oneTimeToken, boolean requireRenewal) throws
OTPManagementException, BadRequestException;
/**
* Invalidate the OTP and send welcome mail
@ -59,8 +60,7 @@ public interface OTPManagementService {
boolean hasEmailRegistered(String email, String emailDomain) throws OTPManagementException,
DeviceManagementException;
OneTimePinDTO generateOneTimePin(String email, String emailType, String userName, Object metaDataObj,
int tenantId, boolean persistPin) throws OTPManagementException;
OneTimePinDTO generateOneTimePin(OneTimePinDTO oneTimePinData, boolean persistPin) throws OTPManagementException;
OneTimePinDTO getRenewedOtpByEmailAndMailType(String email, String emailType) throws OTPManagementException;

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -76,12 +76,20 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<log4j.configuration>file:src/test/resources/log4j.properties</log4j.configuration>
</systemPropertyVariables>
<argLine>
--add-opens=java.xml/jdk.xml.internal=ALL-UNNAMED
--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED
</argLine>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
<systemPropertyVariables>
<jacoco-agent.destfile>${basedir}/target/coverage-reports/jacoco-unit.exec</jacoco-agent.destfile>
<log4j.configuration>file:src/test/resources/log4j.properties</log4j.configuration>
</systemPropertyVariables>
<classpathDependencyExcludes>
<classpathDependencyExclude>org.ops4j.pax.logging</classpathDependencyExclude>
</classpathDependencyExcludes>
</configuration>
</plugin>
</plugins>
@ -255,7 +263,7 @@
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<artifactId>powermock-api-mockito2</artifactId>
<scope>test</scope>
</dependency>
<dependency>

@ -139,7 +139,12 @@ public interface DeviceManagementConfigService {
value = "The properties list using for query a device",
required = true)
@QueryParam("properties")
String properties);
String properties,
@ApiParam(
name = "withAccessToken",
value = "Whether to use access token or otp token for device configuration")
@QueryParam("withAccessToken")
boolean withAccessToken);
@PUT
@Path("/device/transfer")

@ -21,6 +21,10 @@ import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import io.entgra.device.mgt.core.device.mgt.common.AppRegistrationCredentials;
import io.entgra.device.mgt.core.device.mgt.common.ApplicationRegistrationException;
import io.entgra.device.mgt.core.device.mgt.common.DeviceTransferRequest;
@ -30,6 +34,10 @@ import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementEx
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceNotFoundException;
import io.entgra.device.mgt.core.device.mgt.common.general.TenantDetail;
import io.entgra.device.mgt.core.device.mgt.common.permission.mgt.PermissionManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.OTPManagementException;
import io.entgra.device.mgt.core.device.mgt.common.otp.mgt.OTPEmailTypes;
import io.entgra.device.mgt.core.device.mgt.common.otp.mgt.dto.OneTimePinDTO;
import io.entgra.device.mgt.core.device.mgt.common.spi.OTPManagementService;
import io.entgra.device.mgt.core.device.mgt.config.api.beans.ErrorResponse;
import io.entgra.device.mgt.core.device.mgt.config.api.service.DeviceManagementConfigService;
import io.entgra.device.mgt.core.device.mgt.config.api.util.DeviceMgtAPIUtils;
@ -44,15 +52,18 @@ import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProvide
import io.entgra.device.mgt.core.device.mgt.core.util.DeviceManagerUtil;
import io.entgra.device.mgt.core.identity.jwt.client.extension.dto.AccessTokenInfo;
import io.entgra.device.mgt.core.identity.jwt.client.extension.exception.JWTClientException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.user.api.Tenant;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.core.service.RealmService;
import javax.ws.rs.*;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
@ -70,7 +81,8 @@ public class DeviceManagementConfigServiceImpl implements DeviceManagementConfig
@Path("/configurations")
@Produces(MediaType.APPLICATION_JSON)
public Response getConfiguration(@HeaderParam("token") String token,
@QueryParam("properties") String properties) {
@QueryParam("properties") String properties,
@QueryParam("withAccessToken") boolean withAccessToken) {
DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService();
try {
if (token == null || token.isEmpty()) {
@ -95,7 +107,8 @@ public class DeviceManagementConfigServiceImpl implements DeviceManagementConfig
deviceProps.put("token", token);
DeviceConfiguration devicesConfiguration =
dms.getDeviceConfiguration(deviceProps);
setAccessTokenToDeviceConfigurations(devicesConfiguration);
if (withAccessToken) setAccessTokenToDeviceConfigurations(devicesConfiguration);
else setOTPTokenToDeviceConfigurations(devicesConfiguration);
return Response.status(Response.Status.OK).entity(devicesConfiguration).build();
} catch (DeviceManagementException e) {
String msg = "Error occurred while retrieving configurations";
@ -207,6 +220,33 @@ public class DeviceManagementConfigServiceImpl implements DeviceManagementConfig
}
}
private void setOTPTokenToDeviceConfigurations(DeviceConfiguration deviceConfiguration)
throws DeviceManagementException {
OneTimePinDTO oneTimePinData = new OneTimePinDTO();
oneTimePinData.setEmail(OTPEmailTypes.DEVICE_ENROLLMENT.toString());
oneTimePinData.setEmailType(OTPEmailTypes.DEVICE_ENROLLMENT.toString());
oneTimePinData.setUsername(deviceConfiguration.getDeviceOwner());
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
deviceConfiguration.getTenantDomain(), true);
oneTimePinData.setTenantId(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId());
PrivilegedCarbonContext.endTenantFlow();
OTPManagementService otpManagementService = DeviceMgtAPIUtils.getOtpManagementService();
try {
OneTimePinDTO oneTimePinDTO = otpManagementService.generateOneTimePin(oneTimePinData, true);
if (oneTimePinDTO == null) {
String msg = "Null value returned when generating OTP token for " + oneTimePinData.getOtpToken();
log.error(msg);
throw new DeviceManagementException(msg);
}
deviceConfiguration.setAccessToken(oneTimePinDTO.getOtpToken());
} catch (OTPManagementException ex) {
String msg = "Error occurred while generating one time pin: " + ex.getMessage();
log.error(msg, ex);
throw new DeviceManagementException(msg, ex);
}
}
@Override
@Path("/tenants")
@GET

@ -18,6 +18,7 @@
package io.entgra.device.mgt.core.device.mgt.config.api.util;
import io.entgra.device.mgt.core.device.mgt.common.spi.OTPManagementService;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -34,6 +35,8 @@ public class DeviceMgtAPIUtils {
private static DeviceManagementProviderService deviceManagementProviderService = null;
private static RealmService realmService = null;
private static OTPManagementService otpManagementService = null;
public static DeviceManagementProviderService getDeviceManagementService() {
if (deviceManagementProviderService == null) {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
@ -48,6 +51,19 @@ public class DeviceMgtAPIUtils {
return deviceManagementProviderService;
}
public static OTPManagementService getOtpManagementService() {
if (otpManagementService == null) {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
otpManagementService = (OTPManagementService) ctx.getOSGiService(OTPManagementService.class, null);
if (otpManagementService == null) {
String msg = "OTP Management Service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
}
return otpManagementService;
}
public static RealmService getRealmService() {
if (realmService == null) {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>device-mgt</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -473,7 +473,7 @@
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<artifactId>powermock-api-mockito2</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.multitenancy</groupId>

@ -22,6 +22,7 @@ import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import java.util.List;
import java.util.Map;
@ -40,6 +41,18 @@ public interface GroupDAO {
*/
int addGroup(DeviceGroup deviceGroup, int tenantId) throws GroupManagementDAOException;
/**
* Add properties for device group.
* Note that groupId parameter is considered seperately due to the groupId parameter passed with
* device group Payload is ignored in the add/update logic instead the internal groupId reference is used.
*
* @param groups to be added.
* @param tenantId of the group.
* @return sql execution result.
* @throws GroupManagementDAOException
*/
int addGroupWithRoles(DeviceGroupRoleWrapper groups, int tenantId) throws GroupManagementDAOException;
/**
* Add properties for device group.
* Note that groupId parameter is considered seperately due to the groupId parameter passed with
@ -52,6 +65,18 @@ public interface GroupDAO {
*/
boolean addGroupProperties(DeviceGroup deviceGroup, int groupId, int tenantId) throws GroupManagementDAOException;
/**
* Update properties for device group.
* Note that groupId parameter is considered seperately due to the groupId parameter passed with
* device group Payload is ignored in the add/update logic instead the internal groupId reference is used.
*
* @param groups to be updated.
* @param tenantId of the group.
* @return sql execution result.
* @throws GroupManagementDAOException
*/
boolean addGroupPropertiesWithRoles(DeviceGroupRoleWrapper groups, int groupId, int tenantId) throws GroupManagementDAOException;
/**
* Update properties for device group.
* Note that groupId parameter is considered seperately due to the groupId parameter passed with
@ -130,6 +155,15 @@ public interface GroupDAO {
*/
void deleteGroupsMapping(List<Integer> groupIds, int tenantId) throws GroupManagementDAOException;
/**
* Delete mappings of Device Groups.
*
* @param role of Device Groups.
* @param tenantId of the role.
* @throws GroupManagementDAOException on error during deletion of mappings of groups
*/
void deleteGroupsMapping(String role, int tenantId) throws GroupManagementDAOException;
/**
* Delete existing Device Groups.
*
@ -186,6 +220,19 @@ public interface GroupDAO {
*/
List<DeviceGroup> getGroups(GroupPaginationRequest paginationRequest, int tenantId) throws GroupManagementDAOException;
/**
* Get paginated list of Device Groups in tenant with specified device group ids.
*
* @param paginationRequest to filter results.
* @param deviceGroupIds of groups required.
* @param tenantId of user's tenant.
* @param isWithParentPath of user's ParentPath.
* @return List of all Device Groups in tenant.
* @throws GroupManagementDAOException
*/
List<DeviceGroup> getGroups(GroupPaginationRequest paginationRequest, List<Integer> deviceGroupIds,
int tenantId, boolean isWithParentPath) throws GroupManagementDAOException;
/**
* Get paginated list of Device Groups in tenant with specified device group ids.
*
@ -412,4 +459,4 @@ public interface GroupDAO {
List<String> groupNames)
throws GroupManagementDAOException;
}
}

@ -22,6 +22,7 @@ import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import io.entgra.device.mgt.core.device.mgt.core.dao.GroupDAO;
import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOException;
import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOFactory;
@ -35,7 +36,11 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
/**
* This class represents implementation of GroupDAO
@ -49,7 +54,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
throws GroupManagementDAOException {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID FROM DM_GROUP "
+ "WHERE TENANT_ID = ?";
if (StringUtils.isNotBlank(request.getGroupName())) {
sql += " AND GROUP_NAME LIKE ?";
@ -103,7 +108,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
@Override
public List<DeviceGroup> getGroups(GroupPaginationRequest request, List<Integer> deviceGroupIds,
int tenantId) throws GroupManagementDAOException {
int tenantId) throws GroupManagementDAOException {
int deviceGroupIdsCount = deviceGroupIds.size();
if (deviceGroupIdsCount == 0) {
return new ArrayList<>();
@ -111,7 +116,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP WHERE TENANT_ID = ?";
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID FROM DM_GROUP WHERE TENANT_ID = ?";
if (StringUtils.isNotBlank(request.getGroupName())) {
sql += " AND GROUP_NAME LIKE ?";
}
@ -164,6 +169,73 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
throw new GroupManagementDAOException(msg, e);
}
}
@Override
public List<DeviceGroup> getGroups(GroupPaginationRequest request, List<Integer> deviceGroupIds,
int tenantId, boolean isWithParentPath) throws GroupManagementDAOException {
int deviceGroupIdsCount = deviceGroupIds.size();
if (deviceGroupIdsCount == 0) {
return new ArrayList<>();
}
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID FROM DM_GROUP WHERE TENANT_ID = ?";
if (StringUtils.isNotBlank(request.getGroupName())) {
sql += " AND GROUP_NAME LIKE ?";
}
if (StringUtils.isNotBlank(request.getOwner())) {
sql += " AND OWNER LIKE ?";
}
if (StringUtils.isNotBlank(request.getParentPath())) {
if(isWithParentPath){
sql += " AND PARENT_PATH LIKE ?";
}
}
sql += " AND ID IN (";
for (int i = 0; i < deviceGroupIdsCount; i++) {
sql += (deviceGroupIdsCount - 1 != i) ? "?," : "?";
}
sql += ")";
if (request.getRowCount() != 0) {
sql += " LIMIT ? OFFSET ?";
}
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
int paramIndex = 1;
stmt.setInt(paramIndex++, tenantId);
if (StringUtils.isNotBlank(request.getGroupName())) {
stmt.setString(paramIndex++, request.getGroupName() + "%");
}
if (StringUtils.isNotBlank(request.getOwner())) {
stmt.setString(paramIndex++, request.getOwner() + "%");
}
if (StringUtils.isNotBlank(request.getParentPath())) {
if(isWithParentPath){
stmt.setString(paramIndex++, request.getParentPath());
}
}
for (Integer deviceGroupId : deviceGroupIds) {
stmt.setInt(paramIndex++, deviceGroupId);
}
if (request.getRowCount() != 0) {
stmt.setInt(paramIndex++, request.getRowCount());
stmt.setInt(paramIndex, request.getStartIndex());
}
List<DeviceGroup> deviceGroupList = new ArrayList<>();
try (ResultSet resultSet = stmt.executeQuery()) {
while (resultSet.next()) {
deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
}
}
return deviceGroupList;
}
} catch (SQLException e) {
String msg = "Error occurred while retrieving groups of groups IDs " + deviceGroupIds.toString()
+ " in tenant: " + tenantId;
log.error(msg);
throw new GroupManagementDAOException(msg, e);
}
}
@Override
public int addGroup(DeviceGroup deviceGroup, int tenantId) throws GroupManagementDAOException {
@ -175,11 +247,11 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql;
if (deviceGroup.getStatus() == null || deviceGroup.getStatus().isEmpty()) {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH) "
+ "VALUES (?, ?, ?, ?, ?)";
} else {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, STATUS) "
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, PARENT_GROUP_ID) "
+ "VALUES (?, ?, ?, ?, ?, ?)";
} else {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, PARENT_GROUP_ID, STATUS) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?)";
hasStatus = true;
}
stmt = conn.prepareStatement(sql, new String[]{"ID"});
@ -188,10 +260,10 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
stmt.setString(3, deviceGroup.getOwner());
stmt.setInt(4, tenantId);
stmt.setString(5, deviceGroup.getParentPath());
stmt.setInt(6, deviceGroup.getParentGroupId());
if (hasStatus) {
stmt.setString(6, deviceGroup.getStatus());
stmt.setString(7, deviceGroup.getStatus());
}
stmt.executeUpdate();
rs = stmt.getGeneratedKeys();
if (rs.next()) {
@ -206,6 +278,47 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
}
}
@Override
public int addGroupWithRoles(DeviceGroupRoleWrapper groups, int tenantId) throws GroupManagementDAOException {
int groupId = -1;
boolean hasStatus = false;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql;
if (groups.getStatus() == null || groups.getStatus().isEmpty()) {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, PARENT_GROUP_ID) "
+ "VALUES (?, ?, ?, ?, ?, ?)";
} else {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, PARENT_GROUP_ID, STATUS) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?)";
hasStatus = true;
}
try (PreparedStatement stmt = conn.prepareStatement(sql, new String[]{"ID"})) {
stmt.setString(1, groups.getDescription());
stmt.setString(2, groups.getName());
stmt.setString(3, groups.getOwner());
stmt.setInt(4, tenantId);
stmt.setString(5, groups.getParentPath());
stmt.setInt(6, groups.getParentGroupId());
if (hasStatus) {
stmt.setString(7, groups.getStatus());
}
stmt.executeUpdate();
try (ResultSet rs = stmt.getGeneratedKeys();) {
if (rs.next()) {
groupId = rs.getInt(1);
}
return groupId;
}
}
} catch (SQLException e) {
String msg = "Error occurred while adding deviceGroup '" +
groups.getName() + "'";
log.error(msg);
throw new GroupManagementDAOException(msg, e);
}
}
public boolean addGroupProperties(DeviceGroup deviceGroup, int groupId, int tenantId)
throws GroupManagementDAOException {
boolean status;
@ -234,6 +347,33 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
return status;
}
public boolean addGroupPropertiesWithRoles(DeviceGroupRoleWrapper groups, int groupId, int tenantId)
throws GroupManagementDAOException {
boolean status;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
try (PreparedStatement stmt = conn.prepareStatement(
"INSERT INTO GROUP_PROPERTIES(GROUP_ID, PROPERTY_NAME, " +
"PROPERTY_VALUE, TENANT_ID) VALUES (?, ?, ?, ?)")) {
for (Map.Entry<String, String> entry : groups.getGroupProperties().entrySet()) {
stmt.setInt(1, groupId);
stmt.setString(2, entry.getKey());
stmt.setString(3, entry.getValue());
stmt.setInt(4, tenantId);
stmt.addBatch();
}
stmt.executeBatch();
status = true;
}
} catch (SQLException e) {
String msg = "Error occurred while adding properties for group '" +
groups.getName() + "' values : " + groups.getGroupProperties();
log.error(msg);
throw new GroupManagementDAOException(msg, e);
}
return status;
}
public boolean updateGroupProperties(DeviceGroup deviceGroup, int groupId, int tenantId)
throws GroupManagementDAOException {
boolean status;
@ -303,7 +443,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "UPDATE DM_GROUP SET DESCRIPTION = ?, GROUP_NAME = ?, OWNER = ?, STATUS = ?, "
+ "PARENT_PATH = ? WHERE ID = ? AND TENANT_ID = ?";
+ "PARENT_PATH = ?, PARENT_GROUP_ID = ? WHERE ID = ? AND TENANT_ID = ?";
try (PreparedStatement stmt = conn.prepareStatement(sql)){
for (DeviceGroup deviceGroup : deviceGroups) {
stmt.setString(1, deviceGroup.getDescription());
@ -311,8 +451,9 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
stmt.setString(3, deviceGroup.getOwner());
stmt.setString(4, deviceGroup.getStatus());
stmt.setString(5, deviceGroup.getParentPath());
stmt.setInt(6, deviceGroup.getGroupId());
stmt.setInt(7, tenantId);
stmt.setInt(6, deviceGroup.getParentGroupId());
stmt.setInt(7, deviceGroup.getGroupId());
stmt.setInt(8, tenantId);
stmt.addBatch();
}
stmt.executeBatch();
@ -403,6 +544,23 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
}
}
@Override
public void deleteGroupsMapping(String role, int tenantId) throws GroupManagementDAOException {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "DELETE FROM DM_ROLE_GROUP_MAP WHERE ROLE = ? AND TENANT_ID = ?";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, role);
stmt.setInt(2, tenantId);
stmt.executeUpdate();
}
} catch (SQLException e) {
String msg = "Error occurred while removing record from group-role mapping.";
log.error(msg);
throw new GroupManagementDAOException(msg, e);
}
}
@Override
public void deleteGroups(List<Integer> groupIds, int tenantId) throws GroupManagementDAOException {
try {
@ -491,7 +649,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
ResultSet resultSet = null;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP WHERE ID = ? "
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID FROM DM_GROUP WHERE ID = ? "
+ "AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, groupId);
@ -514,7 +672,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
public List<DeviceGroup> getChildrenGroups(String parentPath, int tenantId) throws GroupManagementDAOException {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID FROM DM_GROUP "
+ "WHERE PARENT_PATH LIKE ? AND TENANT_ID = ?";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, parentPath + "%");
@ -539,7 +697,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
public List<DeviceGroup> getRootGroups(int tenantId) throws GroupManagementDAOException {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID FROM DM_GROUP "
+ "WHERE PARENT_PATH LIKE ? AND TENANT_ID = ?";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, "/");
@ -567,7 +725,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
List<DeviceGroup> deviceGroupBuilders = new ArrayList<>();
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT G.ID, G.GROUP_NAME, G.DESCRIPTION, G.OWNER, G.STATUS, G.PARENT_PATH FROM DM_GROUP G " +
String sql = "SELECT G.ID, G.GROUP_NAME, G.DESCRIPTION, G.OWNER, G.STATUS, G.PARENT_PATH, G.PARENT_GROUP_ID FROM DM_GROUP G " +
"INNER JOIN DM_DEVICE_GROUP_MAP GM ON G.ID = GM.GROUP_ID " +
"WHERE GM.DEVICE_ID = ? AND GM.TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
@ -705,7 +863,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql =
"SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
"SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID FROM DM_GROUP "
+ "WHERE LOWER(GROUP_NAME) = LOWER(?) AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, groupName);
@ -876,7 +1034,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
List<DeviceGroup> deviceGroupList = null;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP g, " +
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID P FROM DM_GROUP g, " +
"(SELECT GROUP_ID FROM DM_ROLE_GROUP_MAP WHERE ROLE IN (";
int index = 0;
@ -990,7 +1148,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
List<DeviceGroup> deviceGroupList = null;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID FROM DM_GROUP "
+ "WHERE OWNER = ? AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, username);
@ -1128,7 +1286,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
}
@Override
@Override
public List<Device> getAllDevicesOfGroup(String groupName, int tenantId) throws GroupManagementDAOException {
Connection conn;
List<Device> devices;

@ -18,6 +18,7 @@
package io.entgra.device.mgt.core.device.mgt.core.dao.impl.group;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOException;
@ -26,6 +27,8 @@ import io.entgra.device.mgt.core.device.mgt.core.dao.impl.AbstractGroupDAOImpl;
import io.entgra.device.mgt.core.device.mgt.core.dao.util.DeviceManagementDAOUtil;
import io.entgra.device.mgt.core.device.mgt.core.dao.util.GroupManagementDAOUtil;
import org.apache.solr.common.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.sql.Connection;
import java.sql.PreparedStatement;
@ -39,6 +42,8 @@ import java.util.List;
*/
public class PostgreSQLGroupDAOImpl extends AbstractGroupDAOImpl {
private static final Log log = LogFactory.getLog(PostgreSQLGroupDAOImpl.class);
@Override
public int addGroup(DeviceGroup deviceGroup, int tenantId) throws GroupManagementDAOException {
PreparedStatement stmt = null;
@ -49,7 +54,7 @@ public class PostgreSQLGroupDAOImpl extends AbstractGroupDAOImpl {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql;
if(StringUtils.isEmpty(deviceGroup.getStatus())) {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH) " +
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, PARENT_GROUP_ID) " +
"VALUES (?, ?, ?, ?) RETURNING ID";
} else {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, STATUS) " +
@ -79,6 +84,46 @@ public class PostgreSQLGroupDAOImpl extends AbstractGroupDAOImpl {
}
}
@Override
public int addGroupWithRoles(DeviceGroupRoleWrapper groups, int tenantId) throws GroupManagementDAOException {
int groupId = -1;
boolean hasStatus = false;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql;
if (StringUtils.isEmpty(groups.getStatus())) {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH) " +
"VALUES (?, ?, ?, ?) RETURNING ID";
} else {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, STATUS) " +
"VALUES (?, ?, ?, ?, ?) RETURNING ID";
hasStatus = true;
}
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, groups.getDescription());
stmt.setString(2, groups.getName());
stmt.setString(3, groups.getOwner());
stmt.setInt(4, tenantId);
stmt.setString(5, groups.getParentPath());
if (hasStatus) {
stmt.setString(6, groups.getStatus());
}
stmt.execute();
try (ResultSet rs = stmt.getGeneratedKeys()) {
if (rs.next()) {
groupId = rs.getInt(1);
}
return groupId;
}
}
} catch (SQLException e) {
String msg = "Error occurred while adding deviceGroup '" +
groups.getName() + "'";
log.error(msg);
throw new GroupManagementDAOException(msg, e);
}
}
@Override
public List<Device> getDevices(int groupId, int startIndex, int rowCount, int tenantId)
throws GroupManagementDAOException {

@ -87,6 +87,7 @@ public final class GroupManagementDAOUtil {
group.setOwner(resultSet.getString("OWNER"));
group.setStatus(resultSet.getString("STATUS"));
group.setParentPath(resultSet.getString("PARENT_PATH"));
group.setParentGroupId(resultSet.getInt("PARENT_GROUP_ID"));
return group;
}

@ -118,18 +118,18 @@ public class DeviceManagementDataHolder {
public void setRealmService(RealmService realmService) {
this.realmService = realmService;
this.setTenantManager(realmService);
setTenantManager(realmService != null ?
realmService.getTenantManager() : null);
}
public TenantManager getTenantManager() {
return tenantManager;
}
private void setTenantManager(RealmService realmService) {
if (realmService == null) {
throw new IllegalStateException("Realm service is not initialized properly");
if (tenantManager == null) {
throw new IllegalStateException("Tenant manager is not initialized properly");
}
this.tenantManager = realmService.getTenantManager();
return tenantManager; }
private void setTenantManager(TenantManager tenantManager) {
this.tenantManager = tenantManager;
}
public DeviceManagementProviderService getDeviceManagementProvider() {

@ -18,7 +18,15 @@
package io.entgra.device.mgt.core.device.mgt.core.operation.mgt;
import io.entgra.device.mgt.core.device.mgt.common.*;
import io.entgra.device.mgt.core.device.mgt.common.ActivityPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.DynamicTaskContext;
import io.entgra.device.mgt.core.device.mgt.common.EnrolmentInfo;
import io.entgra.device.mgt.core.device.mgt.common.MonitoringOperation;
import io.entgra.device.mgt.core.device.mgt.common.OperationMonitoringTaskConfig;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
import io.entgra.device.mgt.core.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.InvalidDeviceException;
@ -47,15 +55,22 @@ import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProvide
import io.entgra.device.mgt.core.device.mgt.core.task.DeviceTaskManager;
import io.entgra.device.mgt.core.device.mgt.core.task.impl.DeviceTaskManagerImpl;
import io.entgra.device.mgt.core.device.mgt.core.util.DeviceManagerUtil;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger;
import io.entgra.device.mgt.core.notification.logger.DeviceConnectivityLogContext;
import io.entgra.device.mgt.core.notification.logger.impl.EntgraDeviceConnectivityLoggerImpl;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executors;
@ -68,7 +83,8 @@ import java.util.concurrent.ThreadPoolExecutor;
*/
public class OperationManagerImpl implements OperationManager {
private static final Log log = LogFactory.getLog(OperationManagerImpl.class);
DeviceConnectivityLogContext.Builder deviceConnectivityLogContextBuilder = new DeviceConnectivityLogContext.Builder();
private static final EntgraLogger log = new EntgraDeviceConnectivityLoggerImpl(OperationManagerImpl.class);
private static final int CACHE_VALIDITY_PERIOD = 5 * 60 * 1000;
private static final String NOTIFIER_TYPE_LOCAL = "LOCAL";
private static final String SYSTEM = "system";
@ -151,6 +167,8 @@ public class OperationManagerImpl implements OperationManager {
}
}
String tenantId = String.valueOf(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId());
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
DeviceIDHolder deviceValidationResult = DeviceManagerUtil.validateDeviceIdentifiers(deviceIds);
List<DeviceIdentifier> validDeviceIds = deviceValidationResult.getValidDeviceIDList();
if (!validDeviceIds.isEmpty()) {
@ -227,6 +245,10 @@ public class OperationManagerImpl implements OperationManager {
activity.setActivityStatus(
this.getActivityStatus(deviceValidationResult, deviceAuthorizationResult));
}
for (DeviceIdentifier deviceId : authorizedDeviceIds) {
device = getDevice(deviceId);
log.info("Operation added", deviceConnectivityLogContextBuilder.setDeviceId(String.valueOf(device.getId())).setDeviceType(deviceType).setActionTag("ADD_OPERATION").setTenantDomain(tenantDomain).setTenantId(tenantId).setUserName(initiatedBy).setOperationCode(operationCode).build());
}
return activity;
} catch (OperationManagementDAOException e) {
OperationManagementDAOFactory.rollbackTransaction();
@ -448,6 +470,7 @@ public class OperationManagerImpl implements OperationManager {
int failAttempts = 0;
while (true) {
try {
OperationManagementDAOFactory.beginTransaction();
operationMappingDAO.updateOperationMapping(operation.getId(), device.getEnrolmentInfo().getId(),
io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.Operation.PushNotificationStatus.SCHEDULED);
OperationManagementDAOFactory.commitTransaction();
@ -470,6 +493,11 @@ public class OperationManagerImpl implements OperationManager {
} catch (InterruptedException ignore) {
break;
}
} catch (TransactionManagementException ex) {
log.error("Error occurred while initiating the transaction", ex);
break;
} finally {
OperationManagementDAOFactory.closeConnection();
}
}
} catch (Exception e) {
@ -673,7 +701,9 @@ public class OperationManagerImpl implements OperationManager {
if (log.isDebugEnabled()) {
log.debug("Device identifier id:[" + deviceId.getId() + "] type:[" + deviceId.getType() + "]");
}
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
EnrolmentInfo enrolmentInfo = this.getActiveEnrolmentInfo(deviceId);
if (enrolmentInfo == null) {
throw new OperationManagementException("Device not found for the given device Identifier:" +
@ -686,16 +716,25 @@ public class OperationManagerImpl implements OperationManager {
case INACTIVE:
case UNREACHABLE:
this.setEnrolmentStatus(enrolmentId, EnrolmentInfo.Status.ACTIVE);
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
DeviceCacheManagerImpl.getInstance().removeDeviceFromCache(deviceId, tenantId);
break;
}
log.info("Device Connected", deviceConnectivityLogContextBuilder
.setDeviceId(deviceId.getId())
.setDeviceType(deviceId.getType())
.setActionTag("PENDING_OPERATION")
.setTenantDomain(tenantDomain)
.setTenantId(String.valueOf(tenantId))
.setUserName(userName)
.build());
return getOperations(deviceId, Operation.Status.PENDING, enrolmentId);
}
@Override
public List<? extends Operation> getPendingOperations(Device device) throws OperationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
EnrolmentInfo enrolmentInfo = device.getEnrolmentInfo();
if (enrolmentInfo == null) {
throw new OperationManagementException("Device not found for the given device Identifier:" +
@ -713,10 +752,10 @@ public class OperationManagerImpl implements OperationManager {
this.setEnrolmentStatus(enrolmentId, EnrolmentInfo.Status.ACTIVE);
enrolmentInfo.setStatus(EnrolmentInfo.Status.ACTIVE);
device.setEnrolmentInfo(enrolmentInfo);
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
DeviceCacheManagerImpl.getInstance().addDeviceToCache(deviceIdentifier, device, tenantId);
break;
}
log.info("Device Connected", deviceConnectivityLogContextBuilder.setDeviceId(device.getDeviceIdentifier()).setDeviceType(device.getType()).setActionTag("PENDING_OPERATION").setTenantDomain(tenantDomain).setTenantId(String.valueOf(tenantId)).setUserName(userName).build());
return getOperations(deviceIdentifier, Operation.Status.PENDING, enrolmentId);
}

@ -18,15 +18,19 @@
package io.entgra.device.mgt.core.device.mgt.core.otp.mgt.dao.impl;
import io.entgra.device.mgt.core.device.mgt.common.DeviceManagementConstants;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DBConnectionException;
import io.entgra.device.mgt.core.device.mgt.common.otp.mgt.dto.OneTimePinDTO;
import io.entgra.device.mgt.core.device.mgt.core.otp.mgt.dao.AbstractDAOImpl;
import io.entgra.device.mgt.core.device.mgt.core.otp.mgt.dao.OTPManagementDAO;
import io.entgra.device.mgt.core.device.mgt.core.otp.mgt.exception.OTPManagementDAOException;
import org.apache.commons.logging.Log;
import io.entgra.device.mgt.core.device.mgt.core.otp.mgt.exception.OTPManagementDAOException;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.sql.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.List;
@ -51,7 +55,8 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM
+ "META_INFO, "
+ "CREATED_AT,"
+ "TENANT_ID,"
+ "USERNAME) VALUES (?, ?, ?, ?, ?, ?, ?)";
+ "USERNAME, "
+ "EXPIRY_TIME) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
try {
Connection conn = this.getDBConnection();
Calendar calendar = Calendar.getInstance();
@ -65,6 +70,8 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM
stmt.setTimestamp(5, timestamp);
stmt.setInt(6, oneTimePinDTO.getTenantId());
stmt.setString(7, oneTimePinDTO.getUsername());
stmt.setInt(8, oneTimePinDTO.getExpiryTime() == 0
? DeviceManagementConstants.OTPProperties.OTP_DEFAULT_EXPIRY_SECONDS : oneTimePinDTO.getExpiryTime());
stmt.addBatch();
}
stmt.executeBatch();

@ -117,7 +117,8 @@ public class OTPManagementServiceImpl implements OTPManagementService {
}
@Override
public OneTimePinDTO isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException {
public OneTimePinDTO isValidOTP(String oneTimeToken, boolean requireRenewal) throws OTPManagementException,
BadRequestException {
if (StringUtils.isBlank(oneTimeToken)){
String msg = "Received blank OTP to verify. OTP: " + oneTimeToken;
log.error(msg);
@ -141,17 +142,19 @@ public class OTPManagementServiceImpl implements OTPManagementService {
oneTimePinDTO.getCreatedAt().getTime() + oneTimePinDTO.getExpiryTime() * 1000L);
if (currentTimestamp.after(expiredTimestamp)) {
String renewedOTP = UUID.randomUUID().toString();
renewOTP(oneTimePinDTO, renewedOTP);
Gson gson = new Gson();
Tenant tenant = gson.fromJson(oneTimePinDTO.getMetaInfo(), Tenant.class);
if (requireRenewal) {
String renewedOTP = UUID.randomUUID().toString();
renewOTP(oneTimePinDTO, renewedOTP);
Gson gson = new Gson();
Tenant tenant = gson.fromJson(oneTimePinDTO.getMetaInfo(), Tenant.class);
Properties props = new Properties();
props.setProperty("first-name", tenant.getAdminFirstName());
props.setProperty("otp-token", renewedOTP);
props.setProperty("email", oneTimePinDTO.getEmail());
props.setProperty("type", oneTimePinDTO.getEmailType());
sendMail(props, oneTimePinDTO.getEmail(), DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE);
Properties props = new Properties();
props.setProperty("first-name", tenant.getAdminFirstName());
props.setProperty("otp-token", renewedOTP);
props.setProperty("email", oneTimePinDTO.getEmail());
props.setProperty("type", oneTimePinDTO.getEmailType());
sendMail(props, oneTimePinDTO.getEmail(), DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE);
}
return null;
}
return oneTimePinDTO;
@ -224,9 +227,6 @@ public class OTPManagementServiceImpl implements OTPManagementService {
}
}
}
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
OneTimePinDTO oneTimePinDTO;
List<OneTimePinDTO> oneTimePinDTOList = new ArrayList<>();
Properties props = new Properties();
props.setProperty("enrollment-steps", enrollmentSteps.toString());
try {
@ -234,16 +234,11 @@ public class OTPManagementServiceImpl implements OTPManagementService {
for (String username : deviceEnrollmentInvitation.getUsernames()) {
String emailAddress = DeviceManagerUtil.getUserClaimValue(
username, DeviceManagementConstants.User.CLAIM_EMAIL_ADDRESS);
oneTimePinDTO = generateOneTimePin(emailAddress, OTPEmailTypes.DEVICE_ENROLLMENT.toString(), username,
null, tenantId, false);
oneTimePinDTOList.add(oneTimePinDTO);
props.setProperty("first-name", DeviceManagerUtil.
getUserClaimValue(username, DeviceManagementConstants.User.CLAIM_FIRST_NAME));
props.setProperty("username", username);
props.setProperty("otp-token", oneTimePinDTO.getOtpToken());
sendMail(props, emailAddress, DeviceManagementConstants.EmailAttributes.USER_ENROLLMENT_TEMPLATE);
}
this.otpManagementDAO.addOTPData(oneTimePinDTOList);
ConnectionManagerUtil.commitDBTransaction();
} catch (UserStoreException e) {
String msg = "Error occurred while getting claim values to invite user";
@ -257,11 +252,6 @@ public class OTPManagementServiceImpl implements OTPManagementService {
String msg = "SQL Error occurred when adding OPT data to send device enrollment Invitation.";
log.error(msg, e);
throw new OTPManagementException(msg, e);
} catch (OTPManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while saving the OTP data.";
log.error(msg, e);
throw new OTPManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
@ -269,27 +259,17 @@ public class OTPManagementServiceImpl implements OTPManagementService {
/**
* Create One Time Token
* @param email email
* @param emailType email type
* @param userName username
* @param metaDataObj meta data object
* @param tenantId tenant Id
* @param oneTimePinDTO Data related to the one time pin
* @return {@link OneTimePinDTO}
*/
@Override
public OneTimePinDTO generateOneTimePin(String email, String emailType, String userName, Object metaDataObj,
int tenantId, boolean persistPin) throws OTPManagementException {
public OneTimePinDTO generateOneTimePin(OneTimePinDTO oneTimePinDTO, boolean persistPin) throws OTPManagementException {
String otpValue = UUID.randomUUID().toString();
Gson gson = new Gson();
String metaInfo = gson.toJson(metaDataObj);
String metaInfo = gson.toJson(oneTimePinDTO.getMetaInfo());
OneTimePinDTO oneTimePinDTO = new OneTimePinDTO();
oneTimePinDTO.setEmail(email);
oneTimePinDTO.setTenantId(tenantId);
oneTimePinDTO.setUsername(userName);
oneTimePinDTO.setEmailType(emailType);
oneTimePinDTO.setMetaInfo(metaInfo);
oneTimePinDTO.setOtpToken(otpValue);

@ -20,10 +20,34 @@ package io.entgra.device.mgt.core.device.mgt.core.service;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import io.entgra.device.mgt.core.device.mgt.common.*;
import io.entgra.device.mgt.core.device.mgt.common.ActivityPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.DeviceEnrollmentInfoNotification;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.DeviceManager;
import io.entgra.device.mgt.core.device.mgt.common.DeviceNotification;
import io.entgra.device.mgt.core.device.mgt.common.DevicePropertyNotification;
import io.entgra.device.mgt.core.device.mgt.common.DeviceTransferRequest;
import io.entgra.device.mgt.core.device.mgt.common.DynamicTaskContext;
import io.entgra.device.mgt.core.device.mgt.common.EnrolmentInfo;
import io.entgra.device.mgt.core.device.mgt.common.FeatureManager;
import io.entgra.device.mgt.core.device.mgt.common.InitialOperationConfig;
import io.entgra.device.mgt.core.device.mgt.common.MonitoringOperation;
import io.entgra.device.mgt.core.device.mgt.common.OperationMonitoringTaskConfig;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
import io.entgra.device.mgt.core.device.mgt.common.StartupOperationConfig;
import io.entgra.device.mgt.core.device.mgt.common.BillingResponse;
import io.entgra.device.mgt.core.device.mgt.common.app.mgt.Application;
import io.entgra.device.mgt.core.device.mgt.common.app.mgt.ApplicationManagementException;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.*;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.AmbiguousConfigurationException;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.ConfigurationEntry;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.ConfigurationManagementException;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.CorrectiveActionConfig;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.DeviceConfiguration;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.DevicePropertyInfo;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.EnrollmentConfiguration;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.PlatformConfiguration;
import io.entgra.device.mgt.core.device.mgt.common.cost.mgt.Cost;
import io.entgra.device.mgt.core.device.mgt.common.device.details.DeviceData;
import io.entgra.device.mgt.core.device.mgt.common.device.details.DeviceInfo;
@ -32,7 +56,15 @@ import io.entgra.device.mgt.core.device.mgt.common.device.details.DeviceLocation
import io.entgra.device.mgt.core.device.mgt.common.enrollment.notification.EnrollmentNotificationConfiguration;
import io.entgra.device.mgt.core.device.mgt.common.enrollment.notification.EnrollmentNotifier;
import io.entgra.device.mgt.core.device.mgt.common.enrollment.notification.EnrollmentNotifierException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.*;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.BadRequestException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceNotFoundException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceTypeNotFoundException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.InvalidDeviceException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.TransactionManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.UnauthorizedDeviceAccessException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.UserNotFoundException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
import io.entgra.device.mgt.core.device.mgt.common.geo.service.GeoCluster;
import io.entgra.device.mgt.core.device.mgt.common.geo.service.GeoQuery;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
@ -64,7 +96,13 @@ import io.entgra.device.mgt.core.device.mgt.core.cache.impl.DeviceCacheManagerIm
import io.entgra.device.mgt.core.device.mgt.core.common.Constants;
import io.entgra.device.mgt.core.device.mgt.core.config.DeviceConfigurationManager;
import io.entgra.device.mgt.core.device.mgt.core.config.DeviceManagementConfig;
import io.entgra.device.mgt.core.device.mgt.core.dao.*;
import io.entgra.device.mgt.core.device.mgt.core.dao.ApplicationDAO;
import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceDAO;
import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOException;
import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory;
import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceStatusDAO;
import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceTypeDAO;
import io.entgra.device.mgt.core.device.mgt.core.dao.EnrollmentDAO;
import io.entgra.device.mgt.core.device.mgt.core.dao.util.DeviceManagementDAOUtil;
import io.entgra.device.mgt.core.device.mgt.core.device.details.mgt.DeviceDetailsMgtException;
import io.entgra.device.mgt.core.device.mgt.core.device.details.mgt.DeviceInformationManager;
@ -81,12 +119,13 @@ import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.CommandOperation;
import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.ProfileOperation;
import io.entgra.device.mgt.core.device.mgt.core.util.DeviceManagerUtil;
import io.entgra.device.mgt.core.device.mgt.core.util.HttpReportingUtil;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger;
import io.entgra.device.mgt.core.notification.logger.DeviceEnrolmentLogContext;
import io.entgra.device.mgt.core.notification.logger.impl.EntgraDeviceEnrolmentLoggerImpl;
import io.entgra.device.mgt.core.transport.mgt.email.sender.core.*;
import io.entgra.device.mgt.core.transport.mgt.email.sender.core.service.EmailSenderService;
import org.apache.commons.collections.map.SingletonMap;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
@ -110,14 +149,26 @@ import java.lang.reflect.Type;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
public class DeviceManagementProviderServiceImpl implements DeviceManagementProviderService,
PluginInitializationListener {
private static final Log log = LogFactory.getLog(DeviceManagementProviderServiceImpl.class);
DeviceEnrolmentLogContext.Builder deviceEnrolmentLogContextBuilder = new DeviceEnrolmentLogContext.Builder();
private static final EntgraLogger log = new EntgraDeviceEnrolmentLoggerImpl(DeviceManagementProviderServiceImpl.class);
private static final String OPERATION_RESPONSE_EVENT_STREAM_DEFINITION = "org.wso2.iot.OperationResponseStream";
private final DeviceManagementPluginRepository pluginRepository;
@ -205,6 +256,8 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
}
return false;
}
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
EnrollmentConfiguration enrollmentConfiguration = DeviceManagerUtil.getEnrollmentConfigurationEntry();
String deviceSerialNumber = null;
if (enrollmentConfiguration != null) {
@ -291,6 +344,15 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
device.getType() + " upon the user '" + device.getEnrolmentInfo().getOwner() +
"'");
}
log.info("Device enrolled successfully", deviceEnrolmentLogContextBuilder
.setDeviceId(String.valueOf(existingDevice.getId()))
.setDeviceType(String.valueOf(existingDevice.getType()))
.setOwner(newEnrolmentInfo.getOwner())
.setOwnership(String.valueOf(newEnrolmentInfo.getOwnership()))
.setTenantID(String.valueOf(tenantId))
.setTenantDomain(tenantDomain)
.setUserName(userName)
.build());
status = true;
} else {
log.warn("Unable to update device enrollment for device : " + device.getDeviceIdentifier() +
@ -327,6 +389,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
}
device.setEnrolmentInfo(enrollment);
DeviceManagementDAOFactory.commitTransaction();
log.info("Device enrolled successfully", deviceEnrolmentLogContextBuilder.setDeviceId(String.valueOf(device.getId())).setDeviceType(String.valueOf(device.getType())).setOwner(enrollment.getOwner()).setOwnership(String.valueOf(enrollment.getOwnership())).setTenantID(String.valueOf(tenantId)).setTenantDomain(tenantDomain).setUserName(userName).build());
} else {
DeviceManagementDAOFactory.rollbackTransaction();
throw new DeviceManagementException("No device type registered with name - " + device.getType()
@ -404,6 +467,8 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
if (log.isDebugEnabled()) {
log.debug("Modifying enrollment for device: " + device.getId() + " of type '" + device.getType() + "'");
}
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
DeviceManager deviceManager = this.getDeviceManager(device.getType());
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(device.getDeviceIdentifier(), device.getType());
if (deviceManager == null) {
@ -432,6 +497,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
enrollmentDAO.updateEnrollment(device.getEnrolmentInfo(), tenantId);
DeviceManagementDAOFactory.commitTransaction();
log.info("Device enrolled successfully", deviceEnrolmentLogContextBuilder.setDeviceId(String.valueOf(currentDevice.getId())).setDeviceType(String.valueOf(currentDevice.getType())).setOwner(currentDevice.getEnrolmentInfo().getOwner()).setOwnership(String.valueOf(currentDevice.getEnrolmentInfo().getOwnership())).setTenantID(String.valueOf(tenantId)).setTenantDomain(tenantDomain).setUserName(userName).build());
this.removeDeviceFromCache(deviceIdentifier);
} catch (DeviceManagementDAOException e) {
DeviceManagementDAOFactory.rollbackTransaction();
@ -515,7 +581,8 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
}
int tenantId = this.getTenantId();
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
Device device = this.getDevice(deviceId, false);
if (device == null) {
if (log.isDebugEnabled()) {
@ -549,7 +616,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
}
}
//procees to dis-enroll a device from traccar ends
log.info("Device disenrolled successfully", deviceEnrolmentLogContextBuilder.setDeviceId(String.valueOf(device.getId())).setDeviceType(String.valueOf(device.getType())).setOwner(device.getEnrolmentInfo().getOwner()).setOwnership(String.valueOf(device.getEnrolmentInfo().getOwnership())).setTenantID(String.valueOf(tenantId)).setTenantDomain(tenantDomain).setUserName(userName).build());
} catch (DeviceManagementDAOException e) {
DeviceManagementDAOFactory.rollbackTransaction();
String msg = "Error occurred while dis-enrolling '" + deviceId.getType() +
@ -1006,7 +1073,15 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
dateDiff = endDate.getTime() - device.getEnrolmentInfo().getDateOfEnrolment();
}
}
long dateInDays = TimeUnit.DAYS.convert(dateDiff, TimeUnit.MILLISECONDS);
// Convert dateDiff to days as a decimal value
double dateDiffInDays = (double) dateDiff / (24 * 60 * 60 * 1000);
if (dateDiffInDays % 1 >= 0.9) {
dateDiffInDays = Math.ceil(dateDiffInDays);
}
long dateInDays = (long) dateDiffInDays;
double cost = (tenantCost.getCost() / 365) * dateInDays;
totalCost += cost;
device.setCost(Math.round(cost * 100.0) / 100.0);
@ -1073,9 +1148,13 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
long difference_In_Days = (difference_In_Time / (1000 * 60 * 60 * 24)) % 365;
if (difference_In_Time % (1000 * 60 * 60 * 24) >= 0.9 * (1000 * 60 * 60 * 24)) {
difference_In_Days++;
}
for (int i = 1; i <= difference_In_Years; i++) {
List<Device> allDevicesPerYear = new ArrayList<>();
LocalDateTime oneYearAfterStart = startDate.toLocalDateTime().plusYears(1);
LocalDateTime oneYearAfterStart = startDate.toLocalDateTime().plusYears(1).with(LocalTime.of(23, 59, 59));;
Timestamp newStartDate;
Timestamp newEndDate;
@ -1084,14 +1163,12 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
remainingDaysConsidered = true;
oneYearAfterStart = startDate.toLocalDateTime();
newEndDate = endDate;
} else if (Timestamp.valueOf(oneYearAfterStart).getTime() >= endDate.getTime()) {
newEndDate = Timestamp.valueOf(oneYearAfterStart);
} else {
oneYearAfterStart = startDate.toLocalDateTime().plusYears(1);
oneYearAfterStart = startDate.toLocalDateTime().plusYears(1).with(LocalTime.of(23, 59, 59));;
newEndDate = Timestamp.valueOf(oneYearAfterStart);
}
} else {
oneYearAfterStart = startDate.toLocalDateTime().plusYears(1);
oneYearAfterStart = startDate.toLocalDateTime().plusYears(1).with(LocalTime.of(23, 59, 59));;
newEndDate = Timestamp.valueOf(oneYearAfterStart);
}
@ -1114,7 +1191,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
allDevices.addAll(billingResponse.getDevice());
totalCost = totalCost + billingResponse.getTotalCostPerYear();
deviceCount = deviceCount + billingResponse.getDeviceCount();
LocalDateTime nextStartDate = oneYearAfterStart.plusDays(1);
LocalDateTime nextStartDate = oneYearAfterStart.plusDays(1).with(LocalTime.of(00, 00, 00));
startDate = Timestamp.valueOf(nextStartDate);
}

@ -24,6 +24,8 @@ import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceNotFoundException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.*;
import org.wso2.carbon.user.api.AuthorizationManager;
import org.wso2.carbon.user.api.UserStoreManager;
import java.util.List;
@ -43,6 +45,16 @@ public interface GroupManagementProviderService {
void createGroup(DeviceGroup deviceGroup, String defaultRole,
String[] defaultPermissions) throws GroupManagementException, GroupAlreadyExistException;
/**
* Add new device group and create default role with default permissions.
*
* @param groups to add
* @param defaultRole of the deviceGroup
* @param defaultPermissions of the default role
* @throws GroupManagementException
*/
void createGroupWithRoles(DeviceGroupRoleWrapper groups, String defaultRole, String[] defaultPermissions) throws GroupAlreadyExistException,GroupManagementException, RoleDoesNotExistException;
/**
* Update existing device group.
*
@ -63,6 +75,18 @@ public interface GroupManagementProviderService {
*/
boolean deleteGroup(int groupId, boolean isDeleteChildren) throws GroupManagementException;
/**
* Delete existing device group.
*
* @param role to be deleted with the userStore name.
* @param roleToDelete to delete the role.
* @param tenantId to belongs to roles.
* @param userStoreManager with details.
* @param authorizationManager with details.
* @throws GroupManagementException
*/
void deleteRoleAndRoleGroupMapping(String role, String roleToDelete, int tenantId, UserStoreManager userStoreManager, AuthorizationManager authorizationManager) throws GroupManagementException;
/**
* Get the device group provided the device group id.
*

@ -18,7 +18,11 @@
package io.entgra.device.mgt.core.device.mgt.core.service;
import io.entgra.device.mgt.core.device.mgt.common.*;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.DeviceManagementConstants;
import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceNotFoundException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.TransactionManagementException;
@ -35,12 +39,17 @@ import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.user.api.AuthorizationManager;
import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager;
import java.sql.SQLException;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
@ -125,6 +134,59 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
}
}
public void createGroupWithRoles(DeviceGroupRoleWrapper groups, String defaultRole, String[] defaultPermissions) throws GroupAlreadyExistException, GroupManagementException {
if (groups == null) {
String msg = "Received incomplete data for createGroup";
log.error(msg);
throw new GroupManagementException(msg);
}
if (log.isDebugEnabled()) {
log.debug("Creating group '" + groups.getName() + "'");
}
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
GroupManagementDAOFactory.beginTransaction();
DeviceGroup existingGroup = this.groupDAO.getGroup(groups.getName(), tenantId);
if (existingGroup == null) {
if (groups.getParentGroupId() == 0) {
groups.setParentPath(DeviceGroupConstants.HierarchicalGroup.SEPERATOR);
} else {
DeviceGroup immediateParentGroup = groupDAO.getGroup(groups.getParentGroupId(), tenantId);
if (immediateParentGroup == null) {
GroupManagementDAOFactory.rollbackTransaction();
String msg = "Parent group with group ID '" + groups.getParentGroupId() + "' does not exist. Hence creating of group '" + groups.getName() + "' was not success";
log.error(msg);
throw new GroupManagementException(msg);
}
String parentPath = DeviceManagerUtil.createParentPath(immediateParentGroup);
groups.setParentPath(parentPath);
}
int updatedGroupID = this.groupDAO.addGroupWithRoles(groups, tenantId);
if (groups.getGroupProperties() != null && groups.getGroupProperties().size() > 0) {
this.groupDAO.addGroupPropertiesWithRoles(groups, updatedGroupID, tenantId);
}
GroupManagementDAOFactory.commitTransaction();
} else {
throw new GroupAlreadyExistException("Group already exists with name : " + groups.getName() + " Try with another group name.");
}
} catch (GroupManagementDAOException e) {
GroupManagementDAOFactory.rollbackTransaction();
String msg = e.getMessage();
log.error(msg, e);
throw new GroupManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg = "Error occurred while initiating transaction.";
log.error(msg, e);
throw new GroupManagementException(msg, e);
} finally {
GroupManagementDAOFactory.closeConnection();
}
if (log.isDebugEnabled()) {
log.debug("DeviceGroup added: " + groups.getName());
}
}
/**
* {@inheritDoc}
*/
@ -236,6 +298,13 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
newParentPath = DeviceGroupConstants.HierarchicalGroup.SEPERATOR;
}
childrenGroup.setParentPath(newParentPath);
if (!DeviceGroupConstants.HierarchicalGroup.SEPERATOR.equals(newParentPath)) {
String[] groupIds = newParentPath.split(DeviceGroupConstants.HierarchicalGroup.SEPERATOR);
int latestGroupId = Integer.parseInt(groupIds[groupIds.length - 1]);
childrenGroup.setParentGroupId(latestGroupId);
} else {
childrenGroup.setParentGroupId(0);
}
}
}
}
@ -276,6 +345,40 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
}
}
/**
* {@inheritDoc}
*/
@Override
public void deleteRoleAndRoleGroupMapping(String roleName, String roleToDelete, int tenantId, UserStoreManager userStoreManager, AuthorizationManager authorizationManager) throws GroupManagementException {
if (log.isDebugEnabled()) {
log.debug("Delete roles");
}
try {
GroupManagementDAOFactory.beginTransaction();
groupDAO.deleteGroupsMapping(roleToDelete, tenantId);
userStoreManager.deleteRole(roleName);
// Delete all authorizations for the current role before deleting
authorizationManager.clearRoleAuthorization(roleName);
GroupManagementDAOFactory.commitTransaction();
} catch (UserStoreException e) {
GroupManagementDAOFactory.rollbackTransaction();
String msg = "Error occurred while deleting the role '" + roleName + "'";
log.error(msg, e);
throw new GroupManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg = "Error occurred while initiating transaction.";
log.error(msg, e);
throw new GroupManagementException(msg, e);
} catch (GroupManagementDAOException e) {
GroupManagementDAOFactory.rollbackTransaction();
String msg = "Error occurred while deleting the role";
log.error(msg, e);
throw new GroupManagementException(msg, e);
} finally {
GroupManagementDAOFactory.closeConnection();
}
}
/**
* {@inheritDoc}
*/
@ -442,7 +545,7 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
@Override
public PaginationResult getGroupsWithHierarchy(String username, GroupPaginationRequest request,
boolean requireGroupProps) throws GroupManagementException {
boolean requireGroupProps) throws GroupManagementException {
if (request == null) {
String msg = "Received incomplete data for retrieve groups with hierarchy";
log.error(msg);
@ -451,6 +554,7 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
if (log.isDebugEnabled()) {
log.debug("Get groups with hierarchy " + request.toString());
}
boolean isWithParentPath = false;
DeviceManagerUtil.validateGroupListPageSize(request);
List<DeviceGroup> rootGroups;
try {
@ -462,7 +566,7 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
} else {
List<Integer> allDeviceGroupIdsOfUser = getGroupIds(username);
GroupManagementDAOFactory.openConnection();
rootGroups = this.groupDAO.getGroups(request, allDeviceGroupIdsOfUser, tenantId);
rootGroups = this.groupDAO.getGroups(request, allDeviceGroupIdsOfUser, tenantId, isWithParentPath);
}
String parentPath;
List<DeviceGroup> childrenGroups;
@ -1283,7 +1387,7 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
* @throws GroupManagementDAOException on error during population of group properties.
*/
private void createGroupWithChildren(DeviceGroup parentGroup, List<DeviceGroup> childrenGroups,
boolean requireGroupProps, int tenantId, int depth, int counter) throws GroupManagementDAOException {
boolean requireGroupProps, int tenantId, int depth, int counter) throws GroupManagementDAOException {
if (childrenGroups.isEmpty() || depth == counter) {
return;
}

@ -16,6 +16,7 @@ CREATE TABLE IF NOT EXISTS DM_GROUP (
OWNER VARCHAR(45) DEFAULT NULL,
PARENT_PATH VARCHAR(255) DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
PARENT_GROUP_ID INTEGER DEFAULT 0,
PRIMARY KEY (ID)
);

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -78,7 +78,7 @@
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<artifactId>powermock-api-mockito2</artifactId>
<scope>test</scope>
</dependency>
<dependency>

@ -23,7 +23,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>heartbeat-management</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>identity-extensions</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>identity-extensions</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -155,7 +155,12 @@
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<artifactId>powermock-api-mockito2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
@ -253,12 +258,19 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
--add-opens=java.xml/jdk.xml.internal=ALL-UNNAMED
--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED
</argLine>
<systemPropertyVariables>
<log4j.configuration>file:src/test/resources/log4j.properties</log4j.configuration>
</systemPropertyVariables>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
<classpathDependencyExcludes>
<classpathDependencyExclude>org.ops4j.pax.logging</classpathDependencyExclude>
</classpathDependencyExcludes>
</configuration>
</plugin>
</plugins>

@ -74,17 +74,18 @@ public class JWTClientExtensionDataHolder {
public void setRealmService(RealmService realmService) {
this.realmService = realmService;
this.setTenantManager(realmService);
setTenantManager(realmService != null ?
realmService.getTenantManager() : null);
}
private void setTenantManager(RealmService realmService) {
if (realmService == null) {
throw new IllegalStateException("Realm service is not initialized properly");
}
this.tenantManager = realmService.getTenantManager();
private void setTenantManager(TenantManager tenantManager) {
this.tenantManager = tenantManager;
}
public TenantManager getTenantManager() {
if (tenantManager == null) {
throw new IllegalStateException("Tenant manager is not initialized properly");
}
return tenantManager;
}
}

@ -43,9 +43,10 @@ import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.powermock.modules.testng.PowerMockTestCase;
@PrepareForTest(JWTClientUtil.class)
public class JWTClientTest {
public class JWTClientTest extends PowerMockTestCase{
private static final Log log = LogFactory.getLog(JWTClientTest.class);
@ObjectFactory

@ -27,7 +27,7 @@
<EveryOneRoleName>everyone</EveryOneRoleName>
<ReadOnly>false</ReadOnly>
<MaxUserNameListLength>500</MaxUserNameListLength>
<Property name="url">jdbc:h2:target/databasetest/CARBON_TEST</Property>
<Property name="url">jdbc:h2:./target/databasetest/CARBON_TEST</Property>
<Property name="driverName">org.h2.Driver</Property>
<Property name="maxActive">50</Property>
<Property name="maxWait">60000</Property>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>logger</artifactId>
<version>5.0.26-SNAPSHOT</version>
<version>5.0.27-SNAPSHOT</version>
</parent>
<artifactId>io.entgra.device.mgt.core.notification.logger</artifactId>

@ -0,0 +1,181 @@
/*
* Copyright (c) 2018 - 2023, 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.notification.logger;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.LogContext;
public class AppInstallLogContext extends LogContext {
private final String appId;
private final String appName;
private final String appType;
private final String subType;
private final String tenantId;
private final String tenantDomain;
private final String device;
private final String userName;
private final String action;
private AppInstallLogContext(Builder builder) {
this.appId = builder.appId;
this.appName = builder.appName;
this.appType = builder.appType;
this.subType = builder.subType;
this.tenantId = builder.tenantId;
this.tenantDomain = builder.tenantDomain;
this.device = builder.device;
this.userName = builder.userName;
this.action = builder.action;
}
public String getAppId() {
return appId;
}
public String getAppName() {
return appName;
}
public String getAppType() {
return appType;
}
public String getSubType() {
return subType;
}
public String getTenantId() {
return tenantId;
}
public String getTenantDomain() {
return tenantDomain;
}
public String getDevice() {
return device;
}
public String getUserName() {
return userName;
}
public String getAction() {
return action;
}
public static class Builder {
private String appId;
private String appName;
private String appType;
private String subType;
private String tenantId;
private String tenantDomain;
private String device;
private String userName;
private String action;
public Builder() {
}
public String getUserName() {
return userName;
}
public Builder setUserName(String userName) {
this.userName = userName;
return this;
}
public String getAppId() {
return appId;
}
public Builder setAppId(String appId) {
this.appId = appId;
return this;
}
public String getAppName() {
return appName;
}
public Builder setAppName(String appName) {
this.appName = appName;
return this;
}
public String getAppType() {
return appType;
}
public Builder setAppType(String appType) {
this.appType = appType;
return this;
}
public String getSubType() {
return subType;
}
public Builder setSubType(String subType) {
this.subType = subType;
return this;
}
public String getTenantDomain() {
return tenantDomain;
}
public Builder setTenantDomain(String tenantDomain) {
this.tenantDomain = tenantDomain;
return this;
}
public String getTenantId() {
return tenantId;
}
public Builder setTenantId(String tenantId) {
this.tenantId = tenantId;
return this;
}
public String getDevice() {
return device;
}
public Builder setDevice(String device) {
this.device = device;
return this;
}
public String getAction() {
return action;
}
public Builder setAction(String action) {
this.action = action;
return this;
}
public AppInstallLogContext build() {
return new AppInstallLogContext(this);
}
}
}

@ -0,0 +1,150 @@
/*
* Copyright (c) 2018 - 2023, 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.notification.logger;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.LogContext;
public class DeviceConnectivityLogContext extends LogContext {
private final String deviceId;
private final String deviceType;
private final String actionTag;
private final String operationCode;
private final String tenantId;
private final String tenantDomain;
private final String userName;
private DeviceConnectivityLogContext(Builder builder) {
this.deviceId = builder.deviceId;
this.deviceType = builder.deviceType;
this.actionTag = builder.actionTag;
this.operationCode = builder.operationCode;
this.tenantId = builder.tenantId;
this.tenantDomain = builder.tenantDomain;
this.userName = builder.userName;
}
public String getDeviceId() {
return deviceId;
}
public String getDeviceType() {
return deviceType;
}
public String getActionTag() {
return actionTag;
}
public String getOperationCode() {
return operationCode;
}
public String getTenantId() {
return tenantId;
}
public String getTenantDomain() {
return tenantDomain;
}
public String getUserName() {
return userName;
}
public static class Builder {
private String deviceId;
private String deviceType;
private String operationCode;
private String actionTag;
private String tenantId;
private String tenantDomain;
private String userName;
public Builder() {
}
public String getDeviceId() {
return deviceId;
}
public Builder setDeviceId(String deviceId) {
this.deviceId = deviceId;
return this;
}
public String getDeviceType() {
return deviceType;
}
public Builder setDeviceType(String deviceType) {
this.deviceType = deviceType;
return this;
}
public String getOperationCode() {
return operationCode;
}
public Builder setOperationCode(String operationCode) {
this.operationCode = operationCode;
return this;
}
public String getTenantId() {
return tenantId;
}
public Builder setTenantId(String tenantId) {
this.tenantId = tenantId;
return this;
}
public String getTenantDomain() {
return tenantDomain;
}
public Builder setTenantDomain(String tenantDomain) {
this.tenantDomain = tenantDomain;
return this;
}
public String getUserName() {
return userName;
}
public Builder setUserName(String userName) {
this.userName = userName;
return this;
}
public String getActionTag() {
return actionTag;
}
public Builder setActionTag(String actionTag) {
this.actionTag = actionTag;
return this;
}
public DeviceConnectivityLogContext build() {
return new DeviceConnectivityLogContext(this);
}
}
}

@ -0,0 +1,149 @@
/*
* Copyright (c) 2018 - 2023, 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.notification.logger;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.LogContext;
public class DeviceEnrolmentLogContext extends LogContext {
private final String deviceId;
private final String deviceType;
private final String owner;
private final String ownership;
private final String tenantID;
private final String tenantDomain;
private final String userName;
private DeviceEnrolmentLogContext(Builder builder) {
this.deviceId = builder.deviceId;
this.deviceType = builder.deviceType;
this.owner = builder.owner;
this.ownership = builder.ownership;
this.tenantID = builder.tenantID;
this.tenantDomain = builder.tenantDomain;
this.userName = builder.userName;
}
public String getTenantID() {
return tenantID;
}
public String getDeviceId() {
return deviceId;
}
public String getOwner() {
return owner;
}
public String getDeviceType() {
return deviceType;
}
public String getOwnership() {
return ownership;
}
public String getTenantDomain() {
return tenantDomain;
}
public String getUserName() {
return userName;
}
public static class Builder {
private String deviceId;
private String deviceType;
private String owner;
private String ownership;
private String tenantID;
private String tenantDomain;
private String userName;
public Builder() {
}
public String getDeviceType() {
return deviceType;
}
public Builder setDeviceType(String deviceType) {
this.deviceType = deviceType;
return this;
}
public String getTenantID() {
return tenantID;
}
public Builder setTenantID(String tenantID) {
this.tenantID = tenantID;
return this;
}
public String getTenantDomain() {
return tenantDomain;
}
public Builder setTenantDomain(String tenantDomain) {
this.tenantDomain = tenantDomain;
return this;
}
public String getUserName() {
return userName;
}
public Builder setUserName(String userName) {
this.userName = userName;
return this;
}
public String getDeviceId() {
return deviceId;
}
public Builder setDeviceId(String deviceId) {
this.deviceId = deviceId;
return this;
}
public String getOwner() {
return owner;
}
public Builder setOwner(String owner) {
this.owner = owner;
return this;
}
public String getOwnership() {
return ownership;
}
public Builder setOwnership(String ownership) {
this.ownership = ownership;
return this;
}
public DeviceEnrolmentLogContext build() {
return new DeviceEnrolmentLogContext(this);
}
}
}

@ -0,0 +1,133 @@
/*
* Copyright (c) 2018 - 2023, 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.notification.logger;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.LogContext;
public class PolicyLogContext extends LogContext {
private final String policyName;
private final String payload;
private final String actionTag;
private final String userName;
private final String tenantID;
private final String tenantDomain;
private PolicyLogContext(Builder builder) {
this.policyName = builder.policyName;
this.payload = builder.payload;
this.actionTag = builder.actionTag;
this.userName = builder.userName;
this.tenantID = builder.tenantID;
this.tenantDomain = builder.tenantDomain;
}
public String getPolicyName() {
return policyName;
}
public String getPayload() {
return payload;
}
public String getActionTag() {
return actionTag;
}
public String getUserName() {
return userName;
}
public String getTenantID() {
return tenantID;
}
public String getTenantDomain() {
return tenantDomain;
}
public static class Builder {
private String policyName;
private String payload;
private String actionTag;
private String userName;
private String tenantID;
private String tenantDomain;
public Builder() {
}
public String getPolicyName() {
return policyName;
}
public Builder setPolicyName(String policyName) {
this.policyName = policyName;
return this;
}
public String getPayload() {
return payload;
}
public Builder setPayload(String payload) {
this.payload = payload;
return this;
}
public String getActionTag() {
return actionTag;
}
public Builder setActionTag(String actionTag) {
this.actionTag = actionTag;
return this;
}
public String getUserName() {
return userName;
}
public Builder setUserName(String userName) {
this.userName = userName;
return this;
}
public String getTenantID() {
return tenantID;
}
public Builder setTenantID(String tenantID) {
this.tenantID = tenantID;
return this;
}
public String getTenantDomain() {
return tenantDomain;
}
public Builder setTenantDomain(String tenantDomain) {
this.tenantDomain = tenantDomain;
return this;
}
public PolicyLogContext build() {
return new PolicyLogContext(this);
}
}
}

@ -0,0 +1,318 @@
/*
* Copyright (c) 2018 - 2023, 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.notification.logger.impl;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.LogContext;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger;
import io.entgra.device.mgt.core.notification.logger.AppInstallLogContext;
import io.entgra.device.mgt.core.notification.logger.util.MDCContextUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.MDC;
public class EntgraAppInstallLoggerImpl implements EntgraLogger {
private static Log log = null;
public EntgraAppInstallLoggerImpl(Class<?> clazz) {
log = LogFactory.getLog(clazz);
}
public void info(String message) {
log.info(message);
}
public void info(String message, Throwable t) {
log.info(message, t);
}
@Override
public void info(Object o) {
log.info(o);
}
@Override
public void info(Object o, Throwable throwable) {
log.info(o, throwable);
}
@Override
public void info(String message, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.info(message);
}
@Override
public void info(Object object, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.info(object);
}
@Override
public void info(Object object, Throwable t, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.info(object, t);
}
public void debug(String message) {
log.debug(message);
}
public void debug(String message, Throwable t) {
log.debug(message, t);
}
@Override
public void debug(Object o) {
log.debug(o);
}
@Override
public void debug(Object o, Throwable throwable) {
log.debug(o, throwable);
}
@Override
public void debug(String message, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.debug(message);
}
@Override
public void debug(Object object, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.debug(object);
}
@Override
public void debug(Object object, Throwable t, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.debug(object, t);
}
public void error(String message) {
log.error(message);
}
public void error(String message, Throwable t) {
log.error(message, t);
}
@Override
public void error(Object o) {
log.error(o);
}
@Override
public void error(Object o, Throwable throwable) {
log.error(o, throwable);
}
@Override
public void error(String message, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.error(message);
}
@Override
public void error(String message, Throwable t, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.error(message, t);
}
@Override
public void error(Object object, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.error(object);
}
@Override
public void error(Object object, Throwable t, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.error(object, t);
}
public void warn(String message) {
log.warn(message);
}
public void warn(String message, Throwable t) {
log.warn(message, t);
}
@Override
public void warn(Object o) {
log.warn(o);
}
@Override
public void warn(Object o, Throwable throwable) {
log.warn(o, throwable);
}
@Override
public void warn(String message, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.warn(message);
}
@Override
public void warn(String message, Throwable t, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.warn(message, t);
}
@Override
public void warn(Object object, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.warn(object);
}
@Override
public void warn(Object object, Throwable t, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.warn(object, t);
}
public void trace(String message) {
log.trace(message);
}
public void trace(String message, Throwable t) {
log.trace(message, t);
}
@Override
public void trace(Object o) {
log.trace(o);
}
@Override
public void trace(Object o, Throwable throwable) {
log.trace(o, throwable);
}
@Override
public void trace(String message, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.trace(message);
}
@Override
public void trace(Object object, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.trace(object);
}
@Override
public void trace(Object object, Throwable t, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.trace(object, t);
}
public void fatal(String message) {
log.fatal(message);
}
public void fatal(String message, Throwable t) {
log.fatal(message, t);
}
@Override
public void fatal(Object o) {
log.fatal(0);
}
@Override
public void fatal(Object o, Throwable throwable) {
log.fatal(0, throwable);
}
@Override
public void fatal(String message, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.fatal(message);
}
@Override
public void fatal(Object object, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.fatal(object);
}
@Override
public void fatal(Object object, Throwable t, LogContext logContext) {
AppInstallLogContext appInstallLogContext = (AppInstallLogContext) logContext;
MDCContextUtil.populateAppInstallMDCContext(appInstallLogContext);
log.fatal(object, t);
}
@Override
public boolean isDebugEnabled() {
return log.isDebugEnabled();
}
@Override
public boolean isErrorEnabled() {
return log.isErrorEnabled();
}
@Override
public boolean isFatalEnabled() {
return log.isFatalEnabled();
}
@Override
public boolean isInfoEnabled() {
return log.isInfoEnabled();
}
@Override
public boolean isTraceEnabled() {
return log.isTraceEnabled();
}
@Override
public boolean isWarnEnabled() {
return log.isWarnEnabled();
}
@Override
public void clearLogContext() {
MDC.clear();
}
}

@ -0,0 +1,318 @@
/*
* Copyright (c) 2018 - 2023, 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.notification.logger.impl;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.LogContext;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger;
import io.entgra.device.mgt.core.notification.logger.DeviceConnectivityLogContext;
import io.entgra.device.mgt.core.notification.logger.util.MDCContextUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.MDC;
public class EntgraDeviceConnectivityLoggerImpl implements EntgraLogger {
private static Log log = null;
public EntgraDeviceConnectivityLoggerImpl(Class<?> clazz) {
log = LogFactory.getLog(clazz);
}
public void info(String message) {
log.info(message);
}
public void info(String message, Throwable t) {
log.info(message, t);
}
@Override
public void info(Object o) {
log.info(o);
}
@Override
public void info(Object o, Throwable throwable) {
log.info(o, throwable);
}
@Override
public void info(String message, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.info(message);
}
@Override
public void info(Object object, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.info(object);
}
@Override
public void info(Object object, Throwable t, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.info(object, t);
}
public void debug(String message) {
log.debug(message);
}
public void debug(String message, Throwable t) {
log.debug(message, t);
}
@Override
public void debug(Object o) {
log.debug(o);
}
@Override
public void debug(Object o, Throwable throwable) {
log.debug(o, throwable);
}
@Override
public void debug(String message, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.debug(message);
}
@Override
public void debug(Object object, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.debug(object);
}
@Override
public void debug(Object object, Throwable t, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.debug(object, t);
}
public void error(String message) {
log.error(message);
}
public void error(String message, Throwable t) {
log.error(message, t);
}
@Override
public void error(Object o) {
log.error(o);
}
@Override
public void error(Object o, Throwable throwable) {
log.error(o, throwable);
}
@Override
public void error(String message, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.error(message);
}
@Override
public void error(String message, Throwable t, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.error(message, t);
}
@Override
public void error(Object object, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.error(object);
}
@Override
public void error(Object object, Throwable t, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.error(object, t);
}
public void warn(String message) {
log.warn(message);
}
public void warn(String message, Throwable t) {
log.warn(message, t);
}
@Override
public void warn(Object o) {
log.warn(o);
}
@Override
public void warn(Object o, Throwable throwable) {
log.warn(o, throwable);
}
@Override
public void warn(String message, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.warn(message);
}
@Override
public void warn(String message, Throwable t, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.warn(message, t);
}
@Override
public void warn(Object object, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.warn(object);
}
@Override
public void warn(Object object, Throwable t, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.warn(object, t);
}
public void trace(String message) {
log.trace(message);
}
public void trace(String message, Throwable t) {
log.trace(message, t);
}
@Override
public void trace(Object o) {
log.trace(o);
}
@Override
public void trace(Object o, Throwable throwable) {
log.trace(o, throwable);
}
@Override
public void trace(String message, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.trace(message);
}
@Override
public void trace(Object object, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.trace(object);
}
@Override
public void trace(Object object, Throwable t, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.trace(object, t);
}
public void fatal(String message) {
log.fatal(message);
}
public void fatal(String message, Throwable t) {
log.fatal(message, t);
}
@Override
public void fatal(Object o) {
log.fatal(0);
}
@Override
public void fatal(Object o, Throwable throwable) {
log.fatal(0, throwable);
}
@Override
public void fatal(String message, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.fatal(message);
}
@Override
public void fatal(Object object, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.fatal(object);
}
@Override
public void fatal(Object object, Throwable t, LogContext logContext) {
DeviceConnectivityLogContext deviceConnectivityLogContext = (DeviceConnectivityLogContext) logContext;
MDCContextUtil.populateDeviceConnectivityMDCContext(deviceConnectivityLogContext);
log.fatal(object, t);
}
@Override
public boolean isDebugEnabled() {
return log.isDebugEnabled();
}
@Override
public boolean isErrorEnabled() {
return log.isErrorEnabled();
}
@Override
public boolean isFatalEnabled() {
return log.isFatalEnabled();
}
@Override
public boolean isInfoEnabled() {
return log.isInfoEnabled();
}
@Override
public boolean isTraceEnabled() {
return log.isTraceEnabled();
}
@Override
public boolean isWarnEnabled() {
return log.isWarnEnabled();
}
@Override
public void clearLogContext() {
MDC.clear();
}
}

@ -0,0 +1,318 @@
/*
* Copyright (c) 2018 - 2023, 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.notification.logger.impl;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.LogContext;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger;
import io.entgra.device.mgt.core.notification.logger.DeviceEnrolmentLogContext;
import io.entgra.device.mgt.core.notification.logger.util.MDCContextUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.MDC;
public class EntgraDeviceEnrolmentLoggerImpl implements EntgraLogger {
private static Log log = null;
public EntgraDeviceEnrolmentLoggerImpl(Class<?> clazz) {
log = LogFactory.getLog(clazz);
}
public void info(String message) {
log.info(message);
}
public void info(String message, Throwable t) {
log.info(message, t);
}
@Override
public void info(Object o) {
log.info(o);
}
@Override
public void info(Object o, Throwable throwable) {
log.info(o, throwable);
}
@Override
public void info(String message, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.info(message);
}
@Override
public void info(Object object, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.info(object);
}
@Override
public void info(Object object, Throwable t, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.info(object, t);
}
public void debug(String message) {
log.debug(message);
}
public void debug(String message, Throwable t) {
log.debug(message, t);
}
@Override
public void debug(Object o) {
log.debug(o);
}
@Override
public void debug(Object o, Throwable throwable) {
log.debug(o, throwable);
}
@Override
public void debug(String message, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.debug(message);
}
@Override
public void debug(Object object, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.debug(object);
}
@Override
public void debug(Object object, Throwable t, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.debug(object, t);
}
public void error(String message) {
log.error(message);
}
public void error(String message, Throwable t) {
log.error(message, t);
}
@Override
public void error(Object o) {
log.error(o);
}
@Override
public void error(Object o, Throwable throwable) {
log.error(o, throwable);
}
@Override
public void error(String message, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.error(message);
}
@Override
public void error(String message, Throwable t, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.error(message, t);
}
@Override
public void error(Object object, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.error(object);
}
@Override
public void error(Object object, Throwable t, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.error(object, t);
}
public void warn(String message) {
log.warn(message);
}
public void warn(String message, Throwable t) {
log.warn(message, t);
}
@Override
public void warn(Object o) {
log.warn(o);
}
@Override
public void warn(Object o, Throwable throwable) {
log.warn(o, throwable);
}
@Override
public void warn(String message, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.warn(message);
}
@Override
public void warn(String message, Throwable t, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.warn(message, t);
}
@Override
public void warn(Object object, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.warn(object);
}
@Override
public void warn(Object object, Throwable t, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.warn(object, t);
}
public void trace(String message) {
log.trace(message);
}
public void trace(String message, Throwable t) {
log.trace(message, t);
}
@Override
public void trace(Object o) {
log.trace(o);
}
@Override
public void trace(Object o, Throwable throwable) {
log.trace(o, throwable);
}
@Override
public void trace(String message, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.trace(message);
}
@Override
public void trace(Object object, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.trace(object);
}
@Override
public void trace(Object object, Throwable t, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.trace(object, t);
}
public void fatal(String message) {
log.fatal(message);
}
public void fatal(String message, Throwable t) {
log.fatal(message, t);
}
@Override
public void fatal(Object o) {
log.fatal(0);
}
@Override
public void fatal(Object o, Throwable throwable) {
log.fatal(0, throwable);
}
@Override
public void fatal(String message, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.fatal(message);
}
@Override
public void fatal(Object object, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.fatal(object);
}
@Override
public void fatal(Object object, Throwable t, LogContext logContext) {
DeviceEnrolmentLogContext deviceEnrolmentLogContext = (DeviceEnrolmentLogContext) logContext;
MDCContextUtil.populateDeviceEnrolmentMDCContext(deviceEnrolmentLogContext);
log.fatal(object, t);
}
@Override
public boolean isDebugEnabled() {
return log.isDebugEnabled();
}
@Override
public boolean isErrorEnabled() {
return log.isErrorEnabled();
}
@Override
public boolean isFatalEnabled() {
return log.isFatalEnabled();
}
@Override
public boolean isInfoEnabled() {
return log.isInfoEnabled();
}
@Override
public boolean isTraceEnabled() {
return log.isTraceEnabled();
}
@Override
public boolean isWarnEnabled() {
return log.isWarnEnabled();
}
@Override
public void clearLogContext() {
MDC.clear();
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save