diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.config.api/src/main/java/io/entgra/device/mgt/core/device/mgt/config/api/service/DeviceManagementConfigService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.config.api/src/main/java/io/entgra/device/mgt/core/device/mgt/config/api/service/DeviceManagementConfigService.java index e5d65dd4d3..97627393d5 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.config.api/src/main/java/io/entgra/device/mgt/core/device/mgt/config/api/service/DeviceManagementConfigService.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.config.api/src/main/java/io/entgra/device/mgt/core/device/mgt/config/api/service/DeviceManagementConfigService.java @@ -25,6 +25,7 @@ import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.DeviceConfi import io.entgra.device.mgt.core.device.mgt.common.general.TenantDetail; import io.entgra.device.mgt.core.device.mgt.config.api.beans.ErrorResponse; import io.swagger.annotations.*; +import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.dto.OperationConfig; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; @@ -77,6 +78,13 @@ import java.util.List; key = "admin:permissions:add", roles = {"Internal/devicemgt-user"}, permissions = {"/permissions/add"} + ), + @Scope( + name = "Manage operation configuration", + description = "Add or update operation configuration", + key = "admin:operation_config:manage", + roles = {"Internal/devicemgt-user"}, + permissions = {"/operation-configuration/manage"} ) } ) @@ -319,4 +327,173 @@ public interface DeviceManagementConfigService { }) @Produces(MediaType.APPLICATION_JSON) Response addPermission(List permissions); + + @GET + @Path("/operation-configuration") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HttpMethod.GET, + value = "Getting operation configuration", + notes = "Retrieve the operation configuration", + tags = "Device Management Configuration", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "scope", value = "admin:operation_config:manage") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the operation configuration.", + response = OperationConfig.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 was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 400, + message = "Bad Request.", + response = ErrorResponse.class), + @ApiResponse( + code = 401, + message = "Unauthorized. \n Unauthorized operation! Only admin role can perform this operation."), + @ApiResponse( + code = 404, + message = "Not Found. \n No operation found", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while adding operation configuration.", + response = ErrorResponse.class) + }) + Response getOperationConfiguration(); + + @POST + @Path("/operation-configuration") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HttpMethod.POST, + value = "Add operation configuration", + notes = "Add operation configuration.", + tags = "Device Management Configuration", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "scope", value = + "admin:operation_config:manage") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully added the operation configuration.", + 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 was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 400, + message = "The incoming request has wrong operation configuration.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while adding operation configuration", + response = ErrorResponse.class) + }) + @Produces(MediaType.APPLICATION_JSON) + Response addOperationConfiguration(OperationConfig config); + + @PUT + @Path("/operation-configuration") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HttpMethod.PUT, + value = "Update operation configuration", + notes = "Update operation configuration.", + tags = "Device Management Configuration", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "scope", value = "admin:operation_config:manage") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully Update the operation configuration.", + 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 was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 400, + message = "The incoming request has wrong operation configuration.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while adding operation configuration.", + response = ErrorResponse.class) + }) + @Produces(MediaType.APPLICATION_JSON) + Response updateOperationConfiguration(OperationConfig config); + + @DELETE + @Path("/operation-configuration") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HttpMethod.DELETE, + value = "Delete operation configuration", + notes = "Delete operation configuration", + tags = {"Device Management Configuration"}, + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "scope", value = "admin:operation_config:manage") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully deleted the operation configuration", + response = Response.class), + @ApiResponse( + code = 400, + message = "Bad Request.", + response = Response.class), + @ApiResponse( + code = 404, + message = "Not Found. \n Operation configuration not provided", + response = Response.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while deleting the operation configuration.", + response = Response.class) + } + ) + Response deleteOperationConfiguration(); } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.config.api/src/main/java/io/entgra/device/mgt/core/device/mgt/config/api/service/impl/DeviceManagementConfigServiceImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.config.api/src/main/java/io/entgra/device/mgt/core/device/mgt/config/api/service/impl/DeviceManagementConfigServiceImpl.java index a83bd6cc6f..b394f36b78 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.config.api/src/main/java/io/entgra/device/mgt/core/device/mgt/config/api/service/impl/DeviceManagementConfigServiceImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.config.api/src/main/java/io/entgra/device/mgt/core/device/mgt/config/api/service/impl/DeviceManagementConfigServiceImpl.java @@ -22,6 +22,12 @@ 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 io.entgra.device.mgt.core.device.mgt.common.exceptions.OTPManagementException; +import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.OperationConfigurationService; +import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.dto.OperationConfig; +import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions.OperationConfigAlreadyExistsException; +import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions.OperationConfigException; +import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions.OperationConfigNotFoundException; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.context.PrivilegedCarbonContext; @@ -61,6 +67,7 @@ import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.POST; import javax.ws.rs.PUT; +import javax.ws.rs.DELETE; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; @@ -313,4 +320,89 @@ public class DeviceManagementConfigServiceImpl implements DeviceManagementConfig return Response.status(Response.Status.OK).build(); } + @GET + @Path("/operation-configuration") + @Produces({MediaType.APPLICATION_JSON}) + public Response getOperationConfiguration() { + OperationConfig config; + try { + config = OperationConfigurationService.getOperationConfig(); + } catch (OperationConfigException e) { + String msg = "Error occurred getting operation configuration"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } + if (config == null) { + String msg = "Operation configuration not provided"; + log.error(msg); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } else { + return Response.status(Response.Status.OK).entity(config).build(); + } + } + + @POST + @Path("/operation-configuration") + @Produces({MediaType.APPLICATION_JSON}) + public Response addOperationConfiguration(OperationConfig config) { + try { + if (config != null) { + OperationConfigurationService.addOperationConfiguration(config); + } else { + String msg = "Operation configuration not provided"; + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + } catch (OperationConfigException e) { + String msg = "Error occurred adding operation configuration"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (OperationConfigAlreadyExistsException e) { + String msg = "Operation configuration already exists"; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + return Response.status(Response.Status.OK).entity(config).build(); + } + + @PUT + @Path("/operation-configuration") + @Produces({MediaType.APPLICATION_JSON}) + public Response updateOperationConfiguration(OperationConfig config) { + try { + if (config != null) { + OperationConfigurationService.updateOperationConfiguration(config); + } else { + String msg = "Operation configuration body not provided"; + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + } catch (OperationConfigException e) { + String msg = "Error occurred adding operation configuration"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + return Response.status(Response.Status.OK).entity(config).build(); + } + + @DELETE + @Path("/operation-configuration") + @Produces({MediaType.APPLICATION_JSON}) + public Response deleteOperationConfiguration() { + String msg; + try { + OperationConfigurationService.deleteOperationConfiguration(); + } catch (OperationConfigException e) { + msg = "Error occurred while deleting operation configuration"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (OperationConfigNotFoundException e) { + msg = "Operation configuration not provided"; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } + msg = "Operation configuration deleted successfully"; + log.info(msg); + return Response.status(Response.Status.OK).entity(msg).build(); + } } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/DeviceManagementDataHolder.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/DeviceManagementDataHolder.java index f9ea261793..c9ae912a70 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/DeviceManagementDataHolder.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/DeviceManagementDataHolder.java @@ -100,6 +100,7 @@ public class DeviceManagementDataHolder { private DeviceStatusManagementService deviceStatusManagementService; private APIApplicationServices apiApplicationServices; private PublisherRESTAPIServices publisherRESTAPIServices; + private DeviceManagementStartupHandler deviceManagementStartupHandler; private final Map deviceStatusTaskPluginConfigs = Collections.synchronizedMap( new HashMap<>()); @@ -457,4 +458,12 @@ public class DeviceManagementDataHolder { public void setGroupAccessAuthorizationService(GroupAccessAuthorizationService groupAccessAuthorizationService) { this.groupAccessAuthorizationService = groupAccessAuthorizationService; } + + public DeviceManagementStartupHandler getDeviceManagementStartupHandler() { + return deviceManagementStartupHandler; + } + + public void setDeviceManagementStartupHandler(DeviceManagementStartupHandler deviceManagementStartupHandler) { + this.deviceManagementStartupHandler = deviceManagementStartupHandler; + } } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/DeviceManagementServiceComponent.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/DeviceManagementServiceComponent.java index 4aae43beb0..58e1d34ec8 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/DeviceManagementServiceComponent.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/DeviceManagementServiceComponent.java @@ -259,8 +259,10 @@ public class DeviceManagementServiceComponent { TenantCreateObserver listener = new TenantCreateObserver(); bundleContext.registerService(Axis2ConfigurationContextObserver.class.getName(), listener, null); - UserRoleCreateObserver userRoleCreateObserver = new UserRoleCreateObserver(); - bundleContext.registerService(ServerStartupObserver.class.getName(), userRoleCreateObserver, null); + /* Registering Device Management Startup Handler */ + DeviceManagementStartupHandler deviceManagementStartupHandler = new DeviceManagementStartupHandler(); + DeviceManagementDataHolder.getInstance().setDeviceManagementStartupHandler(deviceManagementStartupHandler); + bundleContext.registerService(ServerStartupObserver.class.getName(), deviceManagementStartupHandler, null); /* Registering Device Management Service */ DeviceManagementProviderService deviceManagementProvider = new DeviceManagementProviderServiceImpl(); diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/DeviceManagementStartupHandler.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/DeviceManagementStartupHandler.java new file mode 100644 index 0000000000..56fabedf6c --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/DeviceManagementStartupHandler.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package io.entgra.device.mgt.core.device.mgt.core.internal; + +import com.google.gson.Gson; +import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException; +import io.entgra.device.mgt.core.device.mgt.common.exceptions.TransactionManagementException; +import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata; +import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService; +import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants; +import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.dto.OperationConfig; +import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationDAO; +import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOException; +import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.core.ServerStartupObserver; +import org.wso2.carbon.user.api.AuthorizationManager; +import org.wso2.carbon.user.api.Permission; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; +import org.wso2.carbon.utils.multitenancy.MultitenantConstants; + +public class DeviceManagementStartupHandler implements ServerStartupObserver { + private static final Log log = LogFactory.getLog(DeviceManagementStartupHandler.class); + private static final Gson gson = new Gson(); + private static final String OPERATION_CONFIG = "OPERATION_CONFIG"; + private static final String tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; + + @Override + public void completingServerStartup() { + + } + + @Override + public void completedServerStartup() { + userRoleCreateObserver(); + operationStatusChangeObserver(); + } + + private void userRoleCreateObserver() { + try { + UserStoreManager userStoreManager = + DeviceManagementDataHolder.getInstance().getRealmService().getTenantUserRealm( + MultitenantConstants.SUPER_TENANT_ID).getUserStoreManager(); + String tenantAdminName = + DeviceManagementDataHolder.getInstance().getRealmService().getTenantUserRealm( + MultitenantConstants.SUPER_TENANT_ID).getRealmConfiguration().getAdminUserName(); + AuthorizationManager authorizationManager = DeviceManagementDataHolder.getInstance().getRealmService() + .getTenantUserRealm(MultitenantConstants.SUPER_TENANT_ID).getAuthorizationManager(); + + if (!userStoreManager.isExistingRole(DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN)) { + userStoreManager.addRole( + DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN, + null, + DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_ADMIN); + } else { + for (Permission permission : DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_ADMIN) { + authorizationManager.authorizeRole(DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN, + permission.getResourceId(), permission.getAction()); + } + } + if (!userStoreManager.isExistingRole(DeviceManagementConstants.User.DEFAULT_DEVICE_USER)) { + userStoreManager.addRole( + DeviceManagementConstants.User.DEFAULT_DEVICE_USER, + null, + DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_USER); + } else { + for (Permission permission : DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_USER) { + authorizationManager.authorizeRole(DeviceManagementConstants.User.DEFAULT_DEVICE_USER, + permission.getResourceId(), permission.getAction()); + } + } + userStoreManager.updateRoleListOfUser(tenantAdminName, null, + new String[]{DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN, + DeviceManagementConstants.User.DEFAULT_DEVICE_USER}); + + if (log.isDebugEnabled()) { + log.debug("Device management roles: " + DeviceManagementConstants.User.DEFAULT_DEVICE_USER + ", " + + DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN + " created for the tenant:" + tenantDomain + "." + ); + log.debug("Tenant administrator: " + tenantAdminName + "@" + tenantDomain + + " is assigned to the role:" + DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN + "." + ); + } + } catch (UserStoreException e) { + log.error("Error occurred while creating roles for the tenant: " + tenantDomain + "."); + } + } + + private void operationStatusChangeObserver () { + MetadataManagementService metadataManagementService = DeviceManagementDataHolder + .getInstance().getMetadataManagementService(); + OperationDAO operationDAO = OperationManagementDAOFactory.getOperationDAO(); + Metadata metadata; + int numOfRecordsUpdated; + try { + metadata = metadataManagementService.retrieveMetadata(OPERATION_CONFIG); + if (metadata != null) { + OperationConfig operationConfiguration = gson.fromJson(metadata.getMetaValue(), OperationConfig.class); + String[] deviceTypes = operationConfiguration.getDeviceTypes(); + String initialOperationStatus = operationConfiguration.getInitialOperationStatus(); + String requiredStatusChange = operationConfiguration.getRequiredStatusChange(); + + for (String deviceType : deviceTypes) { + try { + OperationManagementDAOFactory.beginTransaction(); + try { + numOfRecordsUpdated = operationDAO.updateOperationByDeviceTypeAndInitialStatus(deviceType, + initialOperationStatus, requiredStatusChange); + log.info(numOfRecordsUpdated + " operations updated successfully for the" + deviceType); + OperationManagementDAOFactory.commitTransaction(); + } catch (OperationManagementDAOException e) { + OperationManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while updating operation status. DeviceType : " + deviceType + ", " + + "Initial operation status: " + initialOperationStatus + ", Required status:" + requiredStatusChange; + log.error(msg, e); + } + } catch (TransactionManagementException e) { + String msg = "Transactional error occurred while updating the operation status"; + log.error(msg, e); + } finally { + OperationManagementDAOFactory.closeConnection(); + } + } + } else { + log.info("Operation configuration not provided"); + } + } catch (MetadataManagementException e) { + String msg = "Error occurred while retrieving the operation configuration"; + log.error(msg, e); + } + } +} diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/UserRoleCreateObserver.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/UserRoleCreateObserver.java deleted file mode 100644 index f7b2a27a4b..0000000000 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/UserRoleCreateObserver.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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.core.internal; - -import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.core.ServerStartupObserver; -import org.wso2.carbon.user.api.AuthorizationManager; -import org.wso2.carbon.user.api.Permission; -import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.user.api.UserStoreManager; -import org.wso2.carbon.utils.multitenancy.MultitenantConstants; - -public class UserRoleCreateObserver implements ServerStartupObserver { - private static final Log log = LogFactory.getLog(UserRoleCreateObserver.class); - @Override - public void completingServerStartup() { - - } - - @Override - public void completedServerStartup() { - String tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; - - try { - UserStoreManager userStoreManager = - DeviceManagementDataHolder.getInstance().getRealmService().getTenantUserRealm( - MultitenantConstants.SUPER_TENANT_ID).getUserStoreManager(); - String tenantAdminName = - DeviceManagementDataHolder.getInstance().getRealmService().getTenantUserRealm( - MultitenantConstants.SUPER_TENANT_ID).getRealmConfiguration().getAdminUserName(); - AuthorizationManager authorizationManager = DeviceManagementDataHolder.getInstance().getRealmService() - .getTenantUserRealm(MultitenantConstants.SUPER_TENANT_ID).getAuthorizationManager(); - - if (!userStoreManager.isExistingRole(DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN)) { - userStoreManager.addRole( - DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN, - null, - DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_ADMIN); - } else { - for (Permission permission : DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_ADMIN) { - authorizationManager.authorizeRole(DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN, - permission.getResourceId(), permission.getAction()); - } - } - if (!userStoreManager.isExistingRole(DeviceManagementConstants.User.DEFAULT_DEVICE_USER)) { - userStoreManager.addRole( - DeviceManagementConstants.User.DEFAULT_DEVICE_USER, - null, - DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_USER); - } else { - for (Permission permission : DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_USER) { - authorizationManager.authorizeRole(DeviceManagementConstants.User.DEFAULT_DEVICE_USER, - permission.getResourceId(), permission.getAction()); - } - } - userStoreManager.updateRoleListOfUser(tenantAdminName, null, - new String[] {DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN, - DeviceManagementConstants.User.DEFAULT_DEVICE_USER}); - - if (log.isDebugEnabled()) { - log.debug("Device management roles: " + DeviceManagementConstants.User.DEFAULT_DEVICE_USER + ", " + - DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN + " created for the tenant:" + tenantDomain + "." - ); - log.debug("Tenant administrator: " + tenantAdminName + "@" + tenantDomain + - " is assigned to the role:" + DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN + "." - ); - } - } catch (UserStoreException e) { - log.error("Error occurred while creating roles for the tenant: " + tenantDomain + "."); - } - } -} diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/change/status/task/OperationConfigurationService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/change/status/task/OperationConfigurationService.java new file mode 100644 index 0000000000..fe7baac9fb --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/change/status/task/OperationConfigurationService.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task; + +import com.google.gson.Gson; +import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataKeyAlreadyExistsException; +import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataKeyNotFoundException; +import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException; +import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata; +import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService; +import io.entgra.device.mgt.core.device.mgt.core.internal.DeviceManagementDataHolder; +import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.dto.OperationConfig; +import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions.OperationConfigAlreadyExistsException; +import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions.OperationConfigException; +import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions.OperationConfigNotFoundException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class OperationConfigurationService { + + private static final Log log = LogFactory.getLog(OperationConfigurationService.class); + private static final Gson gson = new Gson(); + private static final String STRING = "STRING"; + private static final String OPERATION_CONFIG = "OPERATION_CONFIG"; + static MetadataManagementService metadataManagementService = DeviceManagementDataHolder.getInstance().getMetadataManagementService(); + + + public static OperationConfig getOperationConfig() throws OperationConfigException { + + Metadata metadata; + try { + metadata = metadataManagementService.retrieveMetadata(OPERATION_CONFIG); + } catch (MetadataManagementException e) { + String msg = "Error occurred while retrieving operation configuration"; + log.error(msg, e); + throw new OperationConfigException(msg, e); + } + if (metadata != null) { + return gson.fromJson(metadata.getMetaValue(), OperationConfig.class); + } else { + return null; + } + } + + public static void addOperationConfiguration(OperationConfig config) throws OperationConfigException, + OperationConfigAlreadyExistsException { + + Metadata metadata = new Metadata(); + metadata.setDataType(STRING); + metadata.setMetaKey(OPERATION_CONFIG); + metadata.setMetaValue(gson.toJson(config)); + + try { + metadataManagementService.createMetadata(metadata); + } catch (MetadataManagementException e) { + String msg = "Error occurred while adding operation configuration"; + log.error(msg, e); + throw new OperationConfigException(msg, e); + } catch (MetadataKeyAlreadyExistsException e) { + String msg = "Operation configuration already exists"; + log.error(msg, e); + throw new OperationConfigAlreadyExistsException(msg, e); + } + } + + public static void updateOperationConfiguration(OperationConfig config) throws OperationConfigException { + + Metadata metadata = new Metadata(); + metadata.setDataType(STRING); + metadata.setMetaKey(OPERATION_CONFIG); + metadata.setMetaValue(gson.toJson(config)); + + try { + metadataManagementService.updateMetadata(metadata); + } catch (MetadataManagementException e) { + String msg = "Error occurred while updating operation configuration"; + log.error(msg, e); + throw new OperationConfigException(msg, e); + } + } + + public static void deleteOperationConfiguration() throws OperationConfigException, OperationConfigNotFoundException { + + try { + metadataManagementService.deleteMetadata(OPERATION_CONFIG); + } catch (MetadataManagementException e) { + String msg = "Error occurred while deleting operation configuration"; + log.error(msg, e); + throw new OperationConfigException(msg, e); + } catch (MetadataKeyNotFoundException e) { + String msg = "Operation configuration already exists"; + log.error(msg, e); + throw new OperationConfigNotFoundException(msg, e); + } + } + +} diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/change/status/task/dto/OperationConfig.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/change/status/task/dto/OperationConfig.java new file mode 100644 index 0000000000..5e54e5f062 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/change/status/task/dto/OperationConfig.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.dto; + +/** + * DTO for Operation configuration. + */ + +public class OperationConfig { + + private String[] deviceTypes; + private String initialOperationStatus; + private String requiredStatusChange; + + public String[] getDeviceTypes() { + return deviceTypes; + } + + public void setDeviceTypes(String[] deviceTypes) { + this.deviceTypes = deviceTypes; + } + + public String getInitialOperationStatus() { + return initialOperationStatus; + } + + public void setInitialOperationStatus(String initialOperationStatus) { + this.initialOperationStatus = initialOperationStatus; + } + + public String getRequiredStatusChange() { + return requiredStatusChange; + } + + public void setRequiredStatusChange(String requiredStatusChange) { + this.requiredStatusChange = requiredStatusChange; + } + +} diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/change/status/task/exceptions/OperationConfigAlreadyExistsException.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/change/status/task/exceptions/OperationConfigAlreadyExistsException.java new file mode 100644 index 0000000000..7bcc3b5f1b --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/change/status/task/exceptions/OperationConfigAlreadyExistsException.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions; + +/** + * Custom exception class to be used in operation configuration service related functionalities. + */ +public class OperationConfigAlreadyExistsException extends Exception { + + private static final long serialVersionUID = -1814347544027733436L; + private String errorMessage; + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public OperationConfigAlreadyExistsException(String msg, Exception nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public OperationConfigAlreadyExistsException(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public OperationConfigAlreadyExistsException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public OperationConfigAlreadyExistsException() { + super(); + } + + public OperationConfigAlreadyExistsException(Throwable cause) { + super(cause); + } + +} diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/change/status/task/exceptions/OperationConfigException.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/change/status/task/exceptions/OperationConfigException.java new file mode 100644 index 0000000000..863de5d48a --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/change/status/task/exceptions/OperationConfigException.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions; + +/** + * Custom exception class to be used in operation configuration related functionalities. + */ +public class OperationConfigException extends Exception { + + private static final long serialVersionUID = -8933146283800122661L; + private String errorMessage; + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public OperationConfigException(String msg, Exception nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public OperationConfigException(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public OperationConfigException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public OperationConfigException() { + super(); + } + + public OperationConfigException(Throwable cause) { + super(cause); + } + +} diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/change/status/task/exceptions/OperationConfigNotFoundException.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/change/status/task/exceptions/OperationConfigNotFoundException.java new file mode 100644 index 0000000000..c3e5cd0dc3 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/change/status/task/exceptions/OperationConfigNotFoundException.java @@ -0,0 +1,60 @@ +/* + * 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.core.operation.change.status.task.exceptions; + +/** + * Custom exception class to be used in Operation configuration related functionalities. + */ +public class OperationConfigNotFoundException extends Exception { + + private static final long serialVersionUID = 5260831982626354815L; + private String errorMessage; + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public OperationConfigNotFoundException(String msg, Exception nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public OperationConfigNotFoundException(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public OperationConfigNotFoundException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public OperationConfigNotFoundException() { + super(); + } + + public OperationConfigNotFoundException(Throwable cause) { + super(cause); + } + +} diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/OperationDAO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/OperationDAO.java index c874283a76..60a64a0521 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/OperationDAO.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/OperationDAO.java @@ -61,6 +61,9 @@ public interface OperationDAO { boolean updateOperationStatus(int enrolmentId, int operationId,Operation.Status status) throws OperationManagementDAOException; + int updateOperationByDeviceTypeAndInitialStatus(String deiceType, String initialStatus, String requiredStatus) + throws OperationManagementDAOException; + void updateEnrollmentOperationsStatus(int enrolmentId, String operationCode, Operation.Status existingStatus, Operation.Status newStatus) throws OperationManagementDAOException; diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java index 50ec3f1071..3df2f41aac 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java @@ -128,6 +128,38 @@ public class GenericOperationDAOImpl implements OperationDAO { return isUpdated; } + public int updateOperationByDeviceTypeAndInitialStatus(String deiceType, String initialStatus, String requiredStatus) + throws OperationManagementDAOException { + int numOfRecordsUpdated; + long time = DeviceManagementDAOUtil.getCurrentUTCTime(); + + String sql = "UPDATE DM_ENROLMENT_OP_MAPPING SET STATUS=?, UPDATED_TIMESTAMP=? WHERE DEVICE_TYPE=?"; + + if (initialStatus == null) { + sql += " AND STATUS IS NULL"; + } else { + sql += " AND STATUS=?"; + } + + try ( + Connection connection = OperationManagementDAOFactory.getConnection(); + PreparedStatement stmt = connection.prepareStatement(sql) + ) { + stmt.setString(1, requiredStatus); + stmt.setLong(2, time); + stmt.setString(3, deiceType); + + if (initialStatus != null) { + stmt.setString(4, initialStatus); + } + numOfRecordsUpdated = stmt.executeUpdate(); + } catch (SQLException e) { + throw new OperationManagementDAOException("Error occurred while update device mapping operation status " + + e.getMessage(), e); + } + return numOfRecordsUpdated; + } + @Override public void updateEnrollmentOperationsStatus(int enrolmentId, String operationCode, Operation.Status existingStatus, Operation.Status newStatus) throws OperationManagementDAOException {