From 32088708407c7eadca1a02495e86b7df4d19bf50 Mon Sep 17 00:00:00 2001 From: inoshperera Date: Wed, 22 Jul 2020 21:27:56 +0530 Subject: [PATCH 01/33] Add one time token bean --- .../common/general/OneTimeTokenDetails.java | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/general/OneTimeTokenDetails.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/general/OneTimeTokenDetails.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/general/OneTimeTokenDetails.java new file mode 100644 index 0000000000..f204a1f390 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/general/OneTimeTokenDetails.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.common.general; + +import java.util.Map; + +public class OneTimeTokenDetails extends TenantDetail { + + String password; + String token; + long createdDate; + long updatedDate; + boolean isExpired; + String metaInfo; + Map replaceValue; + String emailType; + + public long getCreatedDate() { + return createdDate; + } + + public void setCreatedDate(long createdDate) { + this.createdDate = createdDate; + } + + public long getUpdatedDate() { + return updatedDate; + } + + public void setUpdatedDate(long updatedDate) { + this.updatedDate = updatedDate; + } + + public boolean isExpired() { + return isExpired; + } + + public void setExpired(boolean expired) { + isExpired = expired; + } + + public String getMetaInfo() { + return metaInfo; + } + + public void setMetaInfo(String metaInfo) { + this.metaInfo = metaInfo; + } + + public Map getReplaceValue() { + return replaceValue; + } + + public void setReplaceValue(Map replaceValue) { + this.replaceValue = replaceValue; + } + + public String getEmailType() { + return emailType; + } + + public void setEmailType(String emailType) { + this.emailType = emailType; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } +} From a7af88396247f39a603533df30cd235e203cf29f Mon Sep 17 00:00:00 2001 From: inoshperera Date: Thu, 23 Jul 2020 20:45:30 +0530 Subject: [PATCH 02/33] Add tenant create API --- .../pom.xml | 4 + .../DeviceManagementConfigServiceImpl.java | 90 +++++++++++++++++++ .../src/main/webapp/WEB-INF/web.xml | 3 +- 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/pom.xml b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/pom.xml index 8ffc22a4ec..fe1ff78a87 100644 --- a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/pom.xml +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/pom.xml @@ -273,5 +273,9 @@ + + org.wso2.carbon.multitenancy + org.wso2.carbon.tenant.mgt + diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java index 9ccbecda3d..bb1a04bba7 100644 --- a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java @@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.entgra.carbon.device.mgt.config.jaxrs.beans.ErrorResponse; import io.entgra.carbon.device.mgt.config.jaxrs.service.DeviceManagementConfigService; import io.entgra.carbon.device.mgt.config.jaxrs.util.DeviceMgtAPIUtils; +import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.base.MultitenantConstants; @@ -35,6 +36,7 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.AmbiguousConfiguratio import org.wso2.carbon.device.mgt.common.configuration.mgt.DeviceConfiguration; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceNotFoundException; +import org.wso2.carbon.device.mgt.common.general.OneTimeTokenDetails; import org.wso2.carbon.device.mgt.common.general.TenantDetail; import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagementException; import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService; @@ -48,22 +50,29 @@ import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.stratos.common.beans.TenantInfoBean; +import org.wso2.carbon.tenant.mgt.services.TenantMgtAdminService; import org.wso2.carbon.user.api.Tenant; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.core.service.RealmService; +import javax.validation.constraints.Size; 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.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.IOException; import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; import java.util.List; import java.util.Map; @@ -270,6 +279,87 @@ public class DeviceManagementConfigServiceImpl implements DeviceManagementConfig return tenantDetail; } + /** + * This API will add a tenant to the system and can be called by the super tenant only. + * @return Returns the + */ + @Path("/tenant") + @POST + @Produces(MediaType.APPLICATION_JSON) + public Response addTenant(@HeaderParam("one-time-token") String token) { + + TenantMgtAdminService tenantMgtAdminService = null; + OneTimeTokenDetails tenantWrapper = null; + + // Request validation + String errorMsg = null; + Response.Status errorStatus = Response.Status.BAD_REQUEST; + if (StringUtils.isEmpty(token)) { + errorMsg = "Authentication failure when creating tenant"; + } else { + tenantWrapper = new OneTimeTokenDetails(); //TODO: Call one time token validation API + if (tenantWrapper == null) { + errorMsg = "One time token is not present in the database"; + } else { + try { + tenantMgtAdminService = new TenantMgtAdminService(); + if (tenantMgtAdminService == null) { + errorMsg = "Request can only be made by super admin"; + errorStatus = Response.Status.INTERNAL_SERVER_ERROR; + } else { + TenantInfoBean[] tenant = tenantMgtAdminService.retrievePartialSearchTenants(tenantWrapper.getDomain()); + if (!PrivilegedCarbonContext.getThreadLocalCarbonContext() + .getTenantDomain().equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) { + errorMsg = "Request can only be made by super admin"; + } else if (tenant != null && tenant.length > 0) { + for (TenantInfoBean tenantInfoBean : tenant) { + if (tenantInfoBean.getTenantDomain().equals(tenantWrapper.getDomain())) { + errorMsg = "Tenant domain is already in use"; + break; + } + } + } + } + + } catch (Exception e) { // Carbon multi-tenancy is throwing generic exceptions. + errorMsg = "Could not create tenant domain " + tenantWrapper.getDomain(); + errorStatus = Response.Status.INTERNAL_SERVER_ERROR; + } + } + } + + if (errorMsg != null) { + log.error(errorMsg); + return Response.status(errorStatus).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMsg).build() + ).build(); + } + + try { + TenantInfoBean tenantInfoBean = new TenantInfoBean(); + tenantInfoBean.setActive(true); + tenantInfoBean.setAdminPassword(tenantWrapper.getPassword()); + tenantInfoBean.setAdmin(tenantWrapper.getAdminName()); + tenantInfoBean.setFirstname(tenantWrapper.getAdminFirstName()); + tenantInfoBean.setLastname(tenantWrapper.getAdminLastName()); + tenantInfoBean.setEmail(tenantWrapper.getEmail()); + Calendar calendar = new GregorianCalendar(); + calendar.setTime(new Date()); + tenantInfoBean.setCreatedDate(calendar); + tenantInfoBean.setTenantDomain(tenantWrapper.getDomain()); + + String response = tenantMgtAdminService.addTenant(tenantInfoBean); + return Response.status(Response.Status.OK).entity(response).build(); + + } catch (Exception e) { // The underlying API is throwing a generic exception. + String msg = "Error while adding tenant"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + + } + @POST @Path("/permissions") @Produces({MediaType.APPLICATION_JSON}) diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml index 6b397c9fbe..3b97a83bbc 100644 --- a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml @@ -49,7 +49,8 @@ nonSecuredEndPoints /api/device-mgt-config/v1.0/configurations, - /api/device-mgt-config/v1.0/configurations/ui-config + /api/device-mgt-config/v1.0/configurations/ui-config, + /api/device-mgt-config/v1.0/tenant From 709a7ab5924dc4ada2d19f83ce2955363a60d412 Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Fri, 24 Jul 2020 01:07:59 +0530 Subject: [PATCH 03/33] Add OTP managing functionality --- .../service/api/UserManagementService.java | 48 +++- .../impl/UserManagementServiceImpl.java | 50 ++++ .../mgt/jaxrs/util/DeviceMgtAPIUtils.java | 27 +- .../src/main/webapp/WEB-INF/web.xml | 3 +- .../exceptions/DBConnectionException.java | 33 +++ .../exceptions/OTPManagementException.java | 44 ++++ .../mgt/common/otp/mgt/dto/OTPMailDTO.java | 104 ++++++++ .../otp/mgt/wrapper/OTPMailWrapper.java | 84 +++++++ .../mgt/common/spi/OTPManagementService.java | 34 +++ .../mgt/core/DeviceManagementConstants.java | 1 + .../DeviceManagementServiceComponent.java | 9 +- .../mgt/core/otp/mgt/dao/AbstractDAOImpl.java | 33 +++ .../core/otp/mgt/dao/OTPManagementDAO.java | 32 +++ .../otp/mgt/dao/OTPManagementDAOFactory.java | 76 ++++++ .../dao/impl/GenericOTPManagementDAOImpl.java | 85 +++++++ .../dao/impl/OracleOTPManagementDAOImpl.java | 24 ++ .../impl/PostgreSQLOTPManagementDAOImpl.java | 25 ++ .../impl/SQLServerOTPManagementDAOImpl.java | 24 ++ .../exception/OTPManagementDAOException.java | 31 +++ .../mgt/service/OTPManagementServiceImpl.java | 132 ++++++++++ .../otp/mgt/util/ConnectionManagerUtil.java | 211 ++++++++++++++++ .../src/main/resources/dbscripts/cdm/h2.sql | 17 ++ .../main/resources/dbscripts/cdm/mssql.sql | 17 ++ .../main/resources/dbscripts/cdm/mysql.sql | 17 ++ .../main/resources/dbscripts/cdm/oracle.sql | 28 +++ .../resources/dbscripts/cdm/postgresql.sql | 20 ++ .../resources/email/templates/user-verify.vm | 230 ++++++++++++++++++ 27 files changed, 1435 insertions(+), 4 deletions(-) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/DBConnectionException.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/OTPManagementException.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OTPMailDTO.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPMailWrapper.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/AbstractDAOImpl.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAOFactory.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/OracleOTPManagementDAOImpl.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/PostgreSQLOTPManagementDAOImpl.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/SQLServerOTPManagementDAOImpl.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/exception/OTPManagementDAOException.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/util/ConnectionManagerUtil.java create mode 100644 features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java index 397c35b336..a133ffd4ec 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java @@ -35,7 +35,6 @@ package org.wso2.carbon.device.mgt.jaxrs.service.api; import com.google.gson.JsonArray; -import com.google.gson.JsonObject; import io.swagger.annotations.SwaggerDefinition; import io.swagger.annotations.Info; import io.swagger.annotations.ExtensionProperty; @@ -50,6 +49,7 @@ import io.swagger.annotations.ResponseHeader; import org.apache.axis2.transport.http.HTTPConstants; import org.wso2.carbon.apimgt.annotations.api.Scopes; import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper; import org.wso2.carbon.device.mgt.jaxrs.beans.ActivityList; import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfo; import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfoList; @@ -1221,4 +1221,50 @@ public interface UserManagementService { response = ErrorResponse.class) }) Response getPermissionsOfUser(); + + @POST + @Path("/one-time-pin") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting the permission details of the current user", + notes = "A user may granted more than one permission in IoTS. Using this REST API " + + "you can get the permission/permission the current user has granted. ", + tags = "User Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:user:permission-view") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of permissions the user " + + "has granted.", + response = PermissionList.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 = 404, + message = "Not Found. \n The specified resource does not exist.\n", + 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 sendEmailVerifyingMail(OTPMailWrapper otpMailWrapper); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java index 81233092f3..8b9dbe6e65 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java @@ -45,8 +45,11 @@ import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; +import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper; import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo; @@ -1115,6 +1118,53 @@ public class UserManagementServiceImpl implements UserManagementService { } } + /** + * Method used to send an invitation email to a existing user to enroll a device. + * + * @param otpMailWrapper Username list of the users to be invited + */ + @POST + @Path("/one-time-pin") + @Produces({MediaType.APPLICATION_JSON}) + public Response sendEmailVerifyingMail(OTPMailWrapper otpMailWrapper) { + if (log.isDebugEnabled()) { + log.debug("Sending enrollment invitation mail to existing user."); + } + DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + OTPManagementService oms = DeviceMgtAPIUtils.getOTPManagementService(); + try { + String otpToken = oms.createOTPToken(otpMailWrapper); + Properties props = new Properties(); + props.setProperty("first-name", otpMailWrapper.getFirstName()); + props.setProperty("otp-token", otpToken); + + EmailMetaInfo metaInfo = new EmailMetaInfo(otpMailWrapper.getEmail(), props); + dms.sendEnrolmentInvitation(DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE, + metaInfo); + } catch (DeviceManagementException e) { + String msg = "Error occurred while inviting user to enrol their device"; + if (e.getMessage() != null && !e.getMessage().isEmpty()) { + msg = e.getMessage(); + } + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (ConfigurationManagementException e) { + String msg = "Error occurred while sending the email invitations. Mail server not configured."; + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (OTPManagementException e) { + String msg = "Error occurred while generating and storing the OTP data"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (org.wso2.carbon.device.mgt.common.exceptions.BadRequestException e) { + String msg = "Bad Request : Found invalid request payload to create OTP toke."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + return Response.status(Response.Status.OK).entity("Invitation mails have been sent.").build(); + } + private Map buildDefaultUserClaims(String firstName, String lastName, String emailAddress, boolean isFresh) { Map defaultUserClaims = new HashMap<>(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java index 31b9543d08..fa5eeaf2c7 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java @@ -52,6 +52,7 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService; import org.wso2.carbon.device.mgt.common.report.mgt.ReportManagementService; import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService; import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager; import org.wso2.carbon.device.mgt.core.dto.DeviceTypeVersion; @@ -134,13 +135,14 @@ public class DeviceMgtAPIUtils { public static final String DAS_ADMIN_SERVICE_EP = "https://" + DAS_HOST_NAME + ":" + DAS_PORT + "/services/"; private static SSLContext sslContext; - private static Log log = LogFactory.getLog(DeviceMgtAPIUtils.class); + private static final Log log = LogFactory.getLog(DeviceMgtAPIUtils.class); private static KeyStore keyStore; private static KeyStore trustStore; private static char[] keyStorePassword; private static IntegrationClientService integrationClientService; private static MetadataManagementService metadataManagementService; + private static volatile OTPManagementService otpManagementService; static { String keyStorePassword = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Password"); @@ -459,6 +461,29 @@ public class DeviceMgtAPIUtils { return metadataManagementService; } + /** + * Initializing and accessing method for OTPManagementService. + * + * @return OTPManagementService instance + * @throws IllegalStateException if OTPManagementService cannot be initialized + */ + public static OTPManagementService getOTPManagementService() { + if (otpManagementService == null) { + synchronized (DeviceMgtAPIUtils.class) { + if (otpManagementService == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + otpManagementService = (OTPManagementService) ctx.getOSGiService(OTPManagementService.class, null); + if (otpManagementService == null) { + String msg = "OTP Management service not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + return otpManagementService; + } + /** * Method for initializing ReportManagementService * @return ReportManagementServie Instance diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/web.xml b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/web.xml index fffbfbdb24..4d7c9c915f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/web.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/web.xml @@ -48,7 +48,8 @@ nonSecuredEndPoints - /api/device-mgt/v1.0/users/validate + /api/device-mgt/v1.0/users/validate, + /api/device-mgt/v1.0/users/one-time-pin, diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/DBConnectionException.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/DBConnectionException.java new file mode 100644 index 0000000000..a47449c060 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/DBConnectionException.java @@ -0,0 +1,33 @@ +/* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.common.exceptions; + +/** + * Exception thrown due to Database Connection issues. + */ +public class DBConnectionException extends Exception { + + private static final long serialVersionUID = -6779125067467878014L; + + public DBConnectionException(String message, Throwable cause) { + super(message, cause); + } + + public DBConnectionException(String msg) { + super(msg); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/OTPManagementException.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/OTPManagementException.java new file mode 100644 index 0000000000..3dd3bee07f --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/OTPManagementException.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.common.exceptions; + +public class OTPManagementException extends Exception { + + private static final long serialVersionUID = 397485329551276175L; + + public OTPManagementException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public OTPManagementException(String message, Throwable cause) { + super(message, cause); + } + + public OTPManagementException(String msg) { + super(msg); + } + + public OTPManagementException() { + super(); + } + + public OTPManagementException(Throwable cause) { + super(cause); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OTPMailDTO.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OTPMailDTO.java new file mode 100644 index 0000000000..ee582b8288 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OTPMailDTO.java @@ -0,0 +1,104 @@ +/* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.common.otp.mgt.dto; + +import java.sql.Timestamp; + +public class OTPMailDTO { + + int id; + String otpToken; + String tenantDomain; + String email; + String emailType; + String metaInfo; + Timestamp createdAt; + int expiryTime; + boolean isExpired; + boolean isTenantCreated; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getOtpToken() { + return otpToken; + } + + public void setOtpToken(String otpToken) { + this.otpToken = otpToken; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getEmailType() { + return emailType; + } + + public void setEmailType(String emailType) { + this.emailType = emailType; + } + + public String getMetaInfo() { return metaInfo; } + + public void setMetaInfo(String metaInfo) { + this.metaInfo = metaInfo; + } + + public Timestamp getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Timestamp createdAt) { + this.createdAt = createdAt; + } + + public int getExpiryTime() { + return expiryTime; + } + + public void setExpiryTime(int expiryTime) { + this.expiryTime = expiryTime; + } + + public boolean isExpired() { + return isExpired; + } + + public void setExpired(boolean expired) { + isExpired = expired; + } + + public String getTenantDomain() { return tenantDomain; } + + public void setTenantDomain(String tenantDomain) { this.tenantDomain = tenantDomain; } + + public boolean isTenantCreated() { return isTenantCreated; } + + public void setTenantCreated(boolean tenantCreated) { isTenantCreated = tenantCreated; } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPMailWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPMailWrapper.java new file mode 100644 index 0000000000..35f255ef6b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPMailWrapper.java @@ -0,0 +1,84 @@ +/* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.common.otp.mgt.wrapper; + +public class OTPMailWrapper { + + private String firstName; + private String lastName; + private String tenantDomain; + private String adminUsername; + private String adminPassword; + private String email; + private String emailType; + + public String getTenantDomain() { + return tenantDomain; + } + + public void setTenantDomain(String tenantDomain) { + this.tenantDomain = tenantDomain; + } + + public String getAdminUsername() { + return adminUsername; + } + + public void setAdminUsername(String adminUsername) { + this.adminUsername = adminUsername; + } + + public String getAdminPassword() { + return adminPassword; + } + + public void setAdminPassword(String adminPassword) { + this.adminPassword = adminPassword; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getEmailType() { + return emailType; + } + + public void setEmailType(String emailType) { + this.emailType = emailType; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java new file mode 100644 index 0000000000..a8d5737963 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java @@ -0,0 +1,34 @@ +/* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.common.spi; + +import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException; +import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; +import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper; + +public interface OTPManagementService { + + /** + * Cretae OTP token and store tenant details in the DB + * @param otpMailWrapper OTP Mail Wrapper object which contains tenant details of registering user + * @return OTPToken + * @throws OTPManagementException if error occurs while creating OTP token and storing tenant details. + * @throws BadRequestException if found and incompatible payload to create OTP token. + */ + String createOTPToken (OTPMailWrapper otpMailWrapper) throws OTPManagementException, BadRequestException; +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java index 1b402560b7..21b19b7a83 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java @@ -116,6 +116,7 @@ public final class DeviceManagementConstants { public static final String USER_REGISTRATION_TEMPLATE = "user-registration"; public static final String USER_ENROLLMENT_TEMPLATE = "user-enrollment"; + public static final String USER_VERIFY_TEMPLATE = "user-verify"; public static final String DEFAULT_ENROLLMENT_TEMPLATE = "default-enrollment-invitation"; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java index daf740fa60..60b309ad76 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java @@ -35,6 +35,7 @@ import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService import org.wso2.carbon.device.mgt.common.report.mgt.ReportManagementService; import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService; import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagerProviderServiceImpl; @@ -56,6 +57,8 @@ import org.wso2.carbon.device.mgt.core.notification.mgt.NotificationManagementSe import org.wso2.carbon.device.mgt.core.notification.mgt.dao.NotificationManagementDAOFactory; import org.wso2.carbon.device.mgt.core.operation.mgt.OperationManagerImpl; import org.wso2.carbon.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAOFactory; +import org.wso2.carbon.device.mgt.core.otp.mgt.service.OTPManagementServiceImpl; import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionManagerServiceImpl; import org.wso2.carbon.device.mgt.core.privacy.PrivacyComplianceProvider; import org.wso2.carbon.device.mgt.core.privacy.impl.PrivacyComplianceProviderImpl; @@ -178,6 +181,7 @@ public class DeviceManagementServiceComponent { NotificationManagementDAOFactory.init(dsConfig); OperationManagementDAOFactory.init(dsConfig); MetadataManagementDAOFactory.init(dsConfig); + OTPManagementDAOFactory.init(dsConfig.getJndiLookupDefinition().getJndiName()); /*Initialize the device cache*/ DeviceManagerUtil.initializeDeviceCache(); @@ -330,7 +334,10 @@ public class DeviceManagementServiceComponent { MetadataManagementService metadataManagementService = new MetadataManagementServiceImpl(); bundleContext.registerService(MetadataManagementService.class.getName(), metadataManagementService, null); - /* Registering App Management service */ + OTPManagementService otpManagementService = new OTPManagementServiceImpl(); + bundleContext.registerService(OTPManagementService.class.getName(), otpManagementService, null); + + /* Registering App Management service */ try { AppManagementConfigurationManager.getInstance().initConfig(); AppManagementConfig appConfig = diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/AbstractDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/AbstractDAOImpl.java new file mode 100644 index 0000000000..ea9faf7ee0 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/AbstractDAOImpl.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.core.otp.mgt.dao; + +import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException; +import org.wso2.carbon.device.mgt.core.otp.mgt.util.ConnectionManagerUtil; + +import java.sql.Connection; + +/** + * This class deals with getting the DB connection. + */ +public abstract class AbstractDAOImpl { + + protected Connection getDBConnection() throws DBConnectionException { + return ConnectionManagerUtil.getDBConnection(); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java new file mode 100644 index 0000000000..5d92d435c8 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java @@ -0,0 +1,32 @@ +/* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.core.otp.mgt.dao; + +import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO; +import org.wso2.carbon.device.mgt.core.otp.mgt.exception.OTPManagementDAOException; + +public interface OTPManagementDAO { + + /** + * Save OTP token data and tenant details of registering user + * @param otpMailDTO OTPMailDTO + * @return Primary key of the newly adding data raw + * @throws OTPManagementDAOException if error occurred whule storing data + */ + int addOTPData(OTPMailDTO otpMailDTO) throws OTPManagementDAOException; +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAOFactory.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAOFactory.java new file mode 100644 index 0000000000..5d7ca6c585 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAOFactory.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.core.otp.mgt.dao; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; +import org.wso2.carbon.device.mgt.common.exceptions.UnsupportedDatabaseEngineException; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.impl.GenericOTPManagementDAOImpl; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.impl.OracleOTPManagementDAOImpl; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.impl.PostgreSQLOTPManagementDAOImpl; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.impl.SQLServerOTPManagementDAOImpl; +import org.wso2.carbon.device.mgt.core.otp.mgt.util.ConnectionManagerUtil; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; + +/** + * This class intends to act as the primary entity that hides all DAO instantiation related complexities and logic so + * that the business objection handling layer doesn't need to be aware of the same providing seamless plug-ability of + * different data sources, connection acquisition mechanisms as well as different forms of DAO implementations to the + * high-level implementations that require Application management related metadata persistence. + */ +public class OTPManagementDAOFactory { + + private static String databaseEngine; + private static final Log log = LogFactory.getLog(OTPManagementDAOFactory.class); + + public static void init(String datasourceName) { + ConnectionManagerUtil.resolveDataSource(datasourceName); + databaseEngine = ConnectionManagerUtil.getDatabaseType(); + } + + public static void init(DataSource dtSource) { + try (Connection connection = dtSource.getConnection()) { + databaseEngine = connection.getMetaData().getDatabaseProductName(); + } catch (SQLException e) { + log.error("Error occurred while retrieving config.datasource connection", e); + } + } + + public static OTPManagementDAO getOTPManagementDAO() { + if (databaseEngine != null) { + switch (databaseEngine) { + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_H2: + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_MYSQL: + return new GenericOTPManagementDAOImpl(); + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_POSTGRESQL: + return new PostgreSQLOTPManagementDAOImpl(); + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_MSSQL: + return new SQLServerOTPManagementDAOImpl(); + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_ORACLE: + return new OracleOTPManagementDAOImpl(); + default: + throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine); + } + } + throw new IllegalStateException("Database engine has not initialized properly."); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java new file mode 100644 index 0000000000..9149a7450b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java @@ -0,0 +1,85 @@ +/* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.core.otp.mgt.dao.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException; +import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.AbstractDAOImpl; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAO; +import org.wso2.carbon.device.mgt.core.otp.mgt.exception.OTPManagementDAOException; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Timestamp; +import java.util.Calendar; + +public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPManagementDAO { + + private static final Log log = LogFactory.getLog(GenericOTPManagementDAOImpl.class); + + @Override + public int addOTPData(OTPMailDTO otpMailDTO) throws OTPManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to create an OTP data entry"); + log.debug("OTP Details : "); + log.debug("OTP key : " + otpMailDTO.getOtpToken() + " Email : " + otpMailDTO.getEmail()); + } + + String sql = "INSERT INTO DM_OTP_DATA " + + "(OTP_TOKEN, " + + "TENANT_DOMAIN," + + "EMAIL, " + + "EMAIL_TYPE, " + + "META_INFO, " + + "CREATED_AT) VALUES (?, ?, ?, ?, ?, ?)"; + try { + Connection conn = this.getDBConnection(); + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setString(1, otpMailDTO.getOtpToken()); + stmt.setString(2, otpMailDTO.getTenantDomain()); + stmt.setString(3, otpMailDTO.getEmail()); + stmt.setString(4, otpMailDTO.getEmailType()); + stmt.setString(5, otpMailDTO.getMetaInfo()); + stmt.setTimestamp(6, timestamp); + stmt.executeUpdate(); + try (ResultSet rs = stmt.getGeneratedKeys()) { + if (rs.next()) { + return rs.getInt(1); + } + return -1; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to create an opt entry for email " + + otpMailDTO.getEmail(); + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to create an otp entry for email " + otpMailDTO.getEmail(); + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/OracleOTPManagementDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/OracleOTPManagementDAOImpl.java new file mode 100644 index 0000000000..c3feb1262d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/OracleOTPManagementDAOImpl.java @@ -0,0 +1,24 @@ +/* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.core.otp.mgt.dao.impl; + +/** + * This handles OTP managing DAO methods which are specific to Oracle. + */ +public class OracleOTPManagementDAOImpl extends GenericOTPManagementDAOImpl{ +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/PostgreSQLOTPManagementDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/PostgreSQLOTPManagementDAOImpl.java new file mode 100644 index 0000000000..52d705736b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/PostgreSQLOTPManagementDAOImpl.java @@ -0,0 +1,25 @@ +/* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.core.otp.mgt.dao.impl; + +/** + * This handles OTP managing DAO methods which are specific to PostgreSQL. + */ +public class PostgreSQLOTPManagementDAOImpl extends GenericOTPManagementDAOImpl{ + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/SQLServerOTPManagementDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/SQLServerOTPManagementDAOImpl.java new file mode 100644 index 0000000000..222fc9fd7c --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/SQLServerOTPManagementDAOImpl.java @@ -0,0 +1,24 @@ +/* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.core.otp.mgt.dao.impl; + +/** + * This handles OTP managing DAO methods which are specific to MSSQL. + */ +public class SQLServerOTPManagementDAOImpl extends GenericOTPManagementDAOImpl{ +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/exception/OTPManagementDAOException.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/exception/OTPManagementDAOException.java new file mode 100644 index 0000000000..6815823bab --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/exception/OTPManagementDAOException.java @@ -0,0 +1,31 @@ +/* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.core.otp.mgt.exception; + +/** + * Exception thrown during the ApplicationDTO Management DAO operations. + */ +public class OTPManagementDAOException extends Exception { + + public OTPManagementDAOException(String message, Throwable throwable) { + super(message, throwable); + } + + public OTPManagementDAOException(String message) { + super(message, new Exception()); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java new file mode 100644 index 0000000000..16c21396a8 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -0,0 +1,132 @@ +/* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.core.otp.mgt.service; + +import com.google.gson.Gson; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException; +import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException; +import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException; +import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAO; +import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAOFactory; +import org.wso2.carbon.device.mgt.core.otp.mgt.exception.OTPManagementDAOException; +import org.wso2.carbon.device.mgt.core.otp.mgt.util.ConnectionManagerUtil; + +import java.util.UUID; + +public class OTPManagementServiceImpl implements OTPManagementService { + + private static final Log log = LogFactory.getLog(OTPManagementServiceImpl.class); + private OTPManagementDAO otpManagementDAO; + + public OTPManagementServiceImpl() { + initDataAccessObjects(); + } + + private void initDataAccessObjects() { + otpManagementDAO = OTPManagementDAOFactory.getOTPManagementDAO(); + } + + @Override + public String createOTPToken(OTPMailWrapper otpMailWrapper) throws OTPManagementException, BadRequestException { + + if (!isValidOTPTokenCreatingRequest(otpMailWrapper)){ + String msg = "Found invalid payload with OTP creating request"; + log.error(msg); + throw new BadRequestException(msg); + } + + Gson gson = new Gson(); + String metaInfo = gson.toJson(otpMailWrapper); + String otpValue = UUID.randomUUID().toString(); + + OTPMailDTO otpMailDTO = new OTPMailDTO(); + otpMailDTO.setEmail(otpMailWrapper.getEmail()); + otpMailDTO.setTenantDomain(otpMailWrapper.getTenantDomain()); + otpMailDTO.setEmailType(otpMailWrapper.getEmailType()); + otpMailDTO.setMetaInfo(metaInfo); + otpMailDTO.setOtpToken(otpValue); + + try { + ConnectionManagerUtil.beginDBTransaction(); + if (this.otpManagementDAO.addOTPData(otpMailDTO) == -1) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "OTP data saving failed. Please, contact Administrator"; + log.error(msg); + throw new OTPManagementException(msg); + } + ConnectionManagerUtil.commitDBTransaction(); + return otpValue; + } catch (TransactionManagementException e) { + String msg = "Error occurred while disabling AutoCommit."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } catch (OTPManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while saving the OTP data. Email address: " + otpMailDTO.getEmail(); + log.error(msg, e); + throw new OTPManagementException(msg, e); + } + } + + /** + * Validate OTP token creating payload + * @param otpMailWrapper OTPMailWrapper + * @return true if its valid payload otherwise returns false + */ + private boolean isValidOTPTokenCreatingRequest(OTPMailWrapper otpMailWrapper) { + if (StringUtils.isBlank(otpMailWrapper.getFirstName())) { + log.error("Received empty or blank first name field with OTP creating payload."); + return false; + } + if (StringUtils.isBlank(otpMailWrapper.getLastName())) { + log.error("Received empty or blank last name field with OTP creating payload."); + return false; + } + if (StringUtils.isBlank(otpMailWrapper.getAdminUsername())) { + log.error("Received empty or blank admin username field with OTP creating payload."); + return false; + } + if (StringUtils.isBlank(otpMailWrapper.getAdminPassword())) { + log.error("Received empty or blank admin password field with OTP creating payload."); + return false; + } + if (StringUtils.isBlank(otpMailWrapper.getEmail())) { + log.error("Received empty or blank email field with OTP creating payload."); + return false; + } + if (StringUtils.isBlank(otpMailWrapper.getEmailType())) { + log.error("Received empty or blank email type field with OTP creating payload."); + return false; + } + if (StringUtils.isBlank(otpMailWrapper.getTenantDomain())) { + log.error("Received empty or blank tenant domain field with OTP creating payload."); + return false; + } + return true; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/util/ConnectionManagerUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/util/ConnectionManagerUtil.java new file mode 100644 index 0000000000..9db3784dd5 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/util/ConnectionManagerUtil.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.core.otp.mgt.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException; +import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.IllegalTransactionStateException; + +import javax.naming.InitialContext; +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; + +/** + * ConnectionManagerUtil is responsible for handling all the datasource connections utilities. + */ +public class ConnectionManagerUtil { + + private static final Log log = LogFactory.getLog(ConnectionManagerUtil.class); + private static final ThreadLocal currentConnection = new ThreadLocal<>(); + private static DataSource dataSource; + + public static void openDBConnection() throws DBConnectionException { + Connection conn = currentConnection.get(); + if (conn != null) { + String msg = "Database connection has already been obtained."; + log.error(msg); + throw new IllegalTransactionStateException(msg); + } + try { + conn = dataSource.getConnection(); + } catch (SQLException e) { + String msg = "Failed to get a database connection."; + log.error(msg, e); + throw new DBConnectionException(msg, e); + } + currentConnection.set(conn); + } + + public static Connection getDBConnection() throws DBConnectionException { + Connection conn = currentConnection.get(); + if (conn == null) { + try { + conn = dataSource.getConnection(); + currentConnection.set(conn); + } catch (SQLException e) { + throw new DBConnectionException("Failed to get database connection.", e); + } + } + return conn; + } + + public static void beginDBTransaction() throws TransactionManagementException, DBConnectionException { + Connection conn = currentConnection.get(); + if (conn == null) { + conn = getDBConnection(); + } else if (inTransaction(conn)) { + String msg = "Transaction has already been started."; + log.error(msg); + throw new IllegalTransactionStateException(msg); + } + + try { + conn.setAutoCommit(false); + } catch (SQLException e) { + String msg = "Error occurred while starting a database transaction."; + log.error(msg, e); + throw new TransactionManagementException(msg, e); + } + } + + public static void endDBTransaction() throws TransactionManagementException { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("Database connection is not active."); + } + + if (!inTransaction(conn)) { + throw new IllegalTransactionStateException("Transaction has not been started."); + } + + try { + conn.setAutoCommit(true); + } catch (SQLException e) { + throw new TransactionManagementException("Error occurred while ending database transaction.", e); + } + } + + public static void commitDBTransaction() { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("Database connection is not active."); + } + + if (!inTransaction(conn)) { + throw new IllegalTransactionStateException("Transaction has not been started."); + } + + try { + conn.commit(); + } catch (SQLException e) { + log.error("Error occurred while committing the transaction", e); + } + } + + public static void rollbackDBTransaction() { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("Database connection is not active."); + } + + if (!inTransaction(conn)) { + throw new IllegalTransactionStateException("Transaction has not been started."); + } + + try { + conn.rollback(); + } catch (SQLException e) { + log.warn("Error occurred while roll-backing the transaction", e); + } + } + + public static void closeDBConnection() { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("Database connection is not active."); + } + try { + conn.close(); + } catch (SQLException e) { + log.error("Error occurred while closing the connection", e); + } + currentConnection.remove(); + } + + private static boolean inTransaction(Connection conn) { + boolean inTransaction = true; + try { + if (conn.getAutoCommit()) { + inTransaction = false; + } + } catch (SQLException e) { + throw new IllegalTransactionStateException("Failed to get transaction state."); + } + return inTransaction; + } + + public static boolean isTransactionStarted() throws DBConnectionException { + Connection connection = getDBConnection(); + return inTransaction(connection); + } + + /** + * Resolve the datasource from the datasource definition. + * + * @param dataSourceName Name of the datasource + * @return DataSource resolved by the datasource name + */ + public static DataSource resolveDataSource(String dataSourceName) { + try { + dataSource = InitialContext.doLookup(dataSourceName); + } catch (Exception e) { + throw new RuntimeException("Error in looking up data source: " + e.getMessage(), e); + } + return dataSource; + } + + public static String getDatabaseType() { + try (Connection connection = dataSource.getConnection()) { + return connection.getMetaData().getDatabaseProductName(); + } catch (SQLException e) { + log.error("Error occurred while retrieving config.datasource connection", e); + } + return null; + } + + /** + * To check whether particular database that is used for application management supports batch query execution. + * + * @return true if batch query is supported, otherwise false. + */ + public static boolean isBatchQuerySupported() { + try (Connection connection = dataSource.getConnection()) { + return connection.getMetaData().supportsBatchUpdates(); + } catch (SQLException e) { + log.error("Error occurred while checking whether database supports batch updates", e); + } + return false; + } + + public static void init(DataSource dtSource) { + dataSource = dtSource; + } +} diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql index 4d16db5abe..adf4044962 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql @@ -572,6 +572,23 @@ CREATE TABLE IF NOT EXISTS DM_METADATA ( ); -- END OF METADATA TABLE -- +-- DM_OTP_DATA TABLE -- +CREATE TABLE IF NOT EXISTS DM_OTP_DATA ( + ID INT AUTO_INCREMENT NOT NULL, + OTP_TOKEN VARCHAR(100) NOT NULL, + TENANT_DOMAIN VARCHAR(20) NOT NULL, + EMAIL VARCHAR(100) NOT NULL, + EMAIL_TYPE VARCHAR(20) NOT NULL, + META_INFO VARCHAR(20000) NOT NULL, + CREATED_AT TIMESTAMP NOT NULL, + EXPIRY_TIME INT NOT NULL DEFAULT 3600, + IS_EXPIRED BOOLEAN DEFAULT false, + TENANT_CREATED BOOLEAN DEFAULT false, + PRIMARY KEY (ID), + CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE) +); +-- END OF DM_OTP_DATA TABLE -- + -- DASHBOARD RELATED VIEWS -- CREATE VIEW POLICY_COMPLIANCE_INFO AS SELECT diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql index 8739701915..cbed63388d 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql @@ -614,6 +614,23 @@ CREATE TABLE DM_METADATA ( ); -- END OF METADATA TABLE -- +-- DM_OTP_DATA TABLE -- +CREATE TABLE DM_OTP_DATA ( + ID INT IDENTITY NOT NULL, + OTP_TOKEN VARCHAR(100) NOT NULL, + TENANT_DOMAIN VARCHAR(20) NOT NULL, + EMAIL VARCHAR(100) NOT NULL, + EMAIL_TYPE VARCHAR(20) NOT NULL, + META_INFO VARCHAR(20000) NOT NULL, + CREATED_AT DATETIME2(0) NOT NULL, + EXPIRY_TIME INT NOT NULL DEFAULT 3600, + IS_EXPIRED BIT DEFAULT false, + TENANT_CREATED BOOLEAN DEFAULT false, + PRIMARY KEY (ID), + CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE) +); +-- END OF DM_OTP_DATA TABLE -- + -- DASHBOARD RELATED VIEWS -- IF NOT EXISTS (SELECT * FROM SYS.VIEWS WHERE NAME = 'POLICY_COMPLIANCE_INFO') diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql index ba57c26757..a3dff752c3 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql @@ -630,6 +630,23 @@ CREATE TABLE IF NOT EXISTS DM_METADATA ( ) ENGINE=InnoDB; -- END OF METADATA TABLE -- +-- DM_OTP_DATA TABLE -- +CREATE TABLE IF NOT EXISTS DM_OTP_DATA ( + ID INT AUTO_INCREMENT NOT NULL, + OTP_TOKEN VARCHAR(100) NOT NULL, + TENANT_DOMAIN VARCHAR(20) NOT NULL, + EMAIL VARCHAR(100) NOT NULL, + EMAIL_TYPE VARCHAR(20) NOT NULL, + META_INFO VARCHAR(20000) NOT NULL, + CREATED_AT TIMESTAMP NOT NULL, + EXPIRY_TIME INT NOT NULL DEFAULT 3600, + IS_EXPIRED BOOLEAN DEFAULT false, + TENANT_CREATED BOOLEAN DEFAULT false, + PRIMARY KEY (ID), + CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE) +); +-- END OF DM_OTP_DATA TABLE -- + -- DASHBOARD RELATED VIEWS -- CREATE VIEW DEVICE_INFO_VIEW AS diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql index 3ca15d3f38..41a10d8ffe 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql @@ -978,6 +978,34 @@ END; / -- END OF METADATA TABLE -- +-- OPT-DATA TABLE -- +CREATE TABLE DM_OTP_DATA ( + ID NUMBER(10) NOT NULL, + OTP_TOKEN VARCHAR2(100) NOT NULL, + TENANT_DOMAIN VARCHAR(20) NOT NULL, + EMAIL VARCHAR2(100) NOT NULL, + EMAIL_TYPE VARCHAR2(20) NOT NULL, + META_INFO VARCHAR2(20000) NOT NULL, + CREATED_AT TIMESTAMP(0) NOT NULL, + EXPIRY_TIME NUMBER(10) DEFAULT 3600 NOT NULL, + IS_EXPIRED CHAR(1) DEFAULT false, + TENANT_CREATED BOOLEAN DEFAULT false, + PRIMARY KEY (ID), + CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE) +); + +-- Generate ID using sequence and trigger +CREATE SEQUENCE DM_OTP_DATA_seq START WITH 1 INCREMENT BY 1; + +CREATE OR REPLACE TRIGGER DM_OTP_DATA_seq_tr + BEFORE INSERT ON DM_OTP_DATA FOR EACH ROW + WHEN (NEW.ID IS NULL) +BEGIN +SELECT DM_OTP_DATA_seq.NEXTVAL INTO :NEW.ID FROM DUAL; +END; +/ +-- END OF OTP-DATA TABLE -- + -- DASHBOARD RELATED VIEWS -- CREATE VIEW POLICY_COMPLIANCE_INFO AS diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql index dc3d264cfd..c8c25534ae 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql @@ -617,6 +617,26 @@ CREATE TABLE IF NOT EXISTS DM_METADATA ( ); -- END OF METADATA TABLE -- +-- OPT-DATA TABLE -- +CREATE SEQUENCE DM_OTP_DATA_seq; + +CREATE TABLE IF NOT EXISTS DM_OTP_DATA ( + ID INT DEFAULT NEXTVAL ('DM_OTP_DATA_seq') NOT NULL, + OTP_TOKEN VARCHAR(100) NOT NULL, + TENANT_DOMAIN VARCHAR(20) NOT NULL, + EMAIL VARCHAR(100) NOT NULL, + EMAIL_TYPE VARCHAR(20) NOT NULL, + META_INFO VARCHAR(20000) NOT NULL, + CREATED_AT TIMESTAMP(0) NOT NULL, + EXPIRY_TIME INT NOT NULL DEFAULT 3600, + IS_EXPIRED BOOLEAN DEFAULT false, + TENANT_CREATED BOOLEAN DEFAULT false, + PRIMARY KEY (ID), + CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE) +); + +-- END OF OPT-DATA TABLE -- + -- DASHBOARD RELATED VIEWS -- CREATE VIEW DEVICE_INFO_VIEW AS diff --git a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm new file mode 100644 index 0000000000..ee0747c64d --- /dev/null +++ b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm @@ -0,0 +1,230 @@ +#* + Copyright (c) 2020, 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. +*# + + You have been invited to enroll your device in Entgra IoT + + + + Entgra IoT Server + + +
+
+
+
+ entgra.io +
+
+
+

+ Hi $first-name, +

+

+ Congratulations!!! Thank you for registering with Entgra cloud. Please click and log in to the + following link to complete your registration with us. Click here. +

+ +

+ If you need further assistance, please contact your administrator. +

+ +

+ Regards, +

+ +

+ Entgra IoT Administrator +

+
+
+
+ + + ]]> + +
From 160c463672034ff3978795234fecd9f695391879 Mon Sep 17 00:00:00 2001 From: inoshperera Date: Sun, 26 Jul 2020 23:05:01 +0530 Subject: [PATCH 04/33] Add token validation with one time token This is to validate one time tokens in the APIM handlers and in the valve --- .../handlers/AuthenticationHandler.java | 9 ++ .../apimgt/handlers/utils/AuthConstants.java | 1 + .../authenticator/framework/Constants.java | 1 + .../OneTimeTokenAuthenticator.java | 93 +++++++++++++++++++ .../AuthenticatorFrameworkDataHolder.java | 11 +++ ...uthenticatorFrameworkServiceComponent.java | 23 +++++ 6 files changed, 138 insertions(+) create mode 100644 components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java index c9873629b7..415ec06304 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java @@ -182,6 +182,15 @@ public class AuthenticationHandler extends AbstractHandler { if (log.isDebugEnabled()) { log.debug("Verify response:" + response.getContent()); } + } else if (headers.containsKey(AuthConstants.ONE_TIME_TOKEN_HEADER)) { + String token = headers.get(AuthConstants.ONE_TIME_TOKEN_HEADER); + //TODO: validate token service. Since this is getting validated in the valve, + // this may not even be necessery +// if (log.isDebugEnabled()) { +// log.debug("One time time :" + token + ", status : " + ); +// } + return true; + } else { log.warn("Unauthorized request for api: " + ctxPath); return false; diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/AuthConstants.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/AuthConstants.java index f2a9f7a42b..d9a9ef8a7b 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/AuthConstants.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/AuthConstants.java @@ -24,6 +24,7 @@ public class AuthConstants { public static final String MDM_SIGNATURE = "mdm-signature"; public static final String PROXY_MUTUAL_AUTH_HEADER = "proxy-mutual-auth-header"; public static final String MUTUAL_AUTH_HEADER = "mutual-auth-header"; + public static final String ONE_TIME_TOKEN_HEADER = "one-time-token"; public static final String ENCODED_PEM = "encoded-pem"; public static final String CALLBACK_URL = ""; public static final String CLIENT_NAME = "IOT-API-MANAGER"; diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java index 2694ea069a..6426c53f47 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java @@ -31,6 +31,7 @@ public final class Constants { public static final String HEADER_HTTP_ACCEPT = "Accept"; public static final String HEADER_HTTP_AUTHORIZATION = "Authorization"; + public static final String ONE_TIME_TOKEN_HEADER = "one-time-token"; } public static final class ContentTypes { diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java new file mode 100644 index 0000000000..7b207aa034 --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.webapp.authenticator.framework.authenticator; + +import org.apache.catalina.connector.Response; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tomcat.util.buf.ByteChunk; +import org.apache.tomcat.util.buf.MessageBytes; +import org.wso2.carbon.device.mgt.common.general.OneTimeTokenDetails; +import org.wso2.carbon.webapp.authenticator.framework.AuthenticationException; +import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo; +import org.wso2.carbon.webapp.authenticator.framework.Constants; +import org.wso2.carbon.webapp.authenticator.framework.Utils.Utils; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuth2TokenValidator; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthTokenValidationException; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthValidationResponse; + +import java.util.Properties; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class OneTimeTokenAuthenticator implements WebappAuthenticator { + private static final Log log = LogFactory.getLog(OneTimeTokenAuthenticator.class); + + + @Override + public void init() { + + } + + public boolean canHandle(org.apache.catalina.connector.Request request) { + return request.getHeader(Constants.HTTPHeaders.ONE_TIME_TOKEN_HEADER) != null; + } + + public AuthenticationInfo authenticate(org.apache.catalina.connector.Request request, Response response) { + + String token = request.getHeader(Constants.HTTPHeaders.ONE_TIME_TOKEN_HEADER); +// DeviceMgtAPIUtils.getDeviceManagementService();//TODO: call token validate service in core + OneTimeTokenDetails tokenDetails = new OneTimeTokenDetails();//TODO: use token details + + AuthenticationInfo authenticationInfo = new AuthenticationInfo(); + + try { + authenticationInfo.setTenantDomain(tokenDetails.getDomain()); + authenticationInfo.setStatus(Status.CONTINUE); + //authenticationInfo.setUsername(tokenDetails.get); //TODO: set username + //authenticationInfo.setTenantId();//TODO: set tenant Id + } catch (Exception e) { // TODO: remove this if not needed + authenticationInfo.setStatus(Status.FAILURE); + authenticationInfo.setMessage("Could not identify tenant domain."); + } + + return null; + } + + public String getName() { + return "One-Time-Token"; + } + + @Override + public void setProperties(Properties properties) { + + } + + @Override + public Properties getProperties() { + return null; + } + + @Override + public String getProperty(String name) { + return null; + } + + +} diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/AuthenticatorFrameworkDataHolder.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/AuthenticatorFrameworkDataHolder.java index 8607d02239..0bfbcc8f43 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/AuthenticatorFrameworkDataHolder.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/AuthenticatorFrameworkDataHolder.java @@ -20,6 +20,7 @@ package org.wso2.carbon.webapp.authenticator.framework.internal; import org.wso2.carbon.certificate.mgt.core.scep.SCEPManager; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; @@ -35,6 +36,7 @@ public class AuthenticatorFrameworkDataHolder { private OAuth2TokenValidationService oAuth2TokenValidationService; private TenantIndexingLoader tenantIndexingLoader; private TenantRegistryLoader tenantRegistryLoader; + private DeviceManagementProviderService deviceManagementService; private static AuthenticatorFrameworkDataHolder thisInstance = new AuthenticatorFrameworkDataHolder(); @@ -114,4 +116,13 @@ public class AuthenticatorFrameworkDataHolder { public TenantRegistryLoader getTenantRegistryLoader() { return tenantRegistryLoader; } + + + public DeviceManagementProviderService getDeviceManagementService() { + return deviceManagementService; + } + + public void setDeviceManagementService(DeviceManagementProviderService deviceManagementService) { + this.deviceManagementService = deviceManagementService; + } } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java index 36dd1c09c6..1fc7ba2bb9 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java @@ -25,6 +25,7 @@ import org.osgi.framework.BundleContext; import org.osgi.service.component.ComponentContext; import org.wso2.carbon.certificate.mgt.core.scep.SCEPManager; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; @@ -80,6 +81,12 @@ import java.util.Properties; * cardinality="1..1" policy="dynamic" * bind="setTenantRegistryLoader" * unbind="unsetTenantRegistryLoader" + * @scr.reference name="org.wso2.carbon.device.manager" + * interface="org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService" + * cardinality="1..1" + * policy="dynamic" + * bind="setDeviceManagementService" + * unbind="unsetDeviceManagementService" */ public class WebappAuthenticatorFrameworkServiceComponent { private static final Log log = LogFactory.getLog(WebappAuthenticatorFrameworkServiceComponent.class); @@ -211,4 +218,20 @@ public class WebappAuthenticatorFrameworkServiceComponent { protected void unsetTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) { AuthenticatorFrameworkDataHolder.getInstance().setTenantRegistryLoader(null); } + + @SuppressWarnings("unused") + protected void setDeviceManagementService(DeviceManagementProviderService deviceManagementProviderService) { + if (log.isDebugEnabled()) { + log.debug("Setting ApplicationDTO Management OSGI Manager"); + } + AuthenticatorFrameworkDataHolder.getInstance().setDeviceManagementService(deviceManagementProviderService); + } + + @SuppressWarnings("unused") + protected void unsetDeviceManagementService(DeviceManagementProviderService deviceManagementProviderService) { + if (log.isDebugEnabled()) { + log.debug("Removing ApplicationDTO Management OSGI Manager"); + } + AuthenticatorFrameworkDataHolder.getInstance().setDeviceManagementService(null); + } } From 0d48f9d38c4bb3657d9f3ff124ea8433bb2be7c0 Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Thu, 30 Jul 2020 03:06:57 +0530 Subject: [PATCH 05/33] Improve One Time Token Authenticator --- .../handlers/AuthenticationHandler.java | 11 +--- .../DeviceManagementConfigServiceImpl.java | 2 - .../src/main/webapp/WEB-INF/web.xml | 2 +- .../mgt/common/spi/OTPManagementService.java | 2 + .../core/otp/mgt/dao/OTPManagementDAO.java | 10 +++ .../dao/impl/GenericOTPManagementDAOImpl.java | 61 +++++++++++++++++++ .../mgt/service/OTPManagementServiceImpl.java | 55 +++++++++++++++++ .../DeviceManagementProviderService.java | 1 - .../OneTimeTokenAuthenticator.java | 16 ++--- .../AuthenticatorFrameworkDataHolder.java | 13 ++-- ...uthenticatorFrameworkServiceComponent.java | 24 ++++---- 11 files changed, 153 insertions(+), 44 deletions(-) diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java index 415ec06304..464dfc248d 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java @@ -182,15 +182,6 @@ public class AuthenticationHandler extends AbstractHandler { if (log.isDebugEnabled()) { log.debug("Verify response:" + response.getContent()); } - } else if (headers.containsKey(AuthConstants.ONE_TIME_TOKEN_HEADER)) { - String token = headers.get(AuthConstants.ONE_TIME_TOKEN_HEADER); - //TODO: validate token service. Since this is getting validated in the valve, - // this may not even be necessery -// if (log.isDebugEnabled()) { -// log.debug("One time time :" + token + ", status : " + ); -// } - return true; - } else { log.warn("Unauthorized request for api: " + ctxPath); return false; @@ -241,4 +232,4 @@ public class AuthenticationHandler extends AbstractHandler { map.put(CONTENT_TYPE, "application/json"); return map; } -} \ No newline at end of file +} diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java index bb1a04bba7..2541577698 100644 --- a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java @@ -56,14 +56,12 @@ import org.wso2.carbon.user.api.Tenant; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.core.service.RealmService; -import javax.validation.constraints.Size; 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.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/web.xml b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/web.xml index 4d7c9c915f..d24eeb72b3 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/web.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/web.xml @@ -49,7 +49,7 @@ nonSecuredEndPoints /api/device-mgt/v1.0/users/validate, - /api/device-mgt/v1.0/users/one-time-pin, + /api/device-mgt/v1.0/users/one-time-pin diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java index a8d5737963..24ec41d229 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java @@ -31,4 +31,6 @@ public interface OTPManagementService { * @throws BadRequestException if found and incompatible payload to create OTP token. */ String createOTPToken (OTPMailWrapper otpMailWrapper) throws OTPManagementException, BadRequestException; + + boolean isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java index 5d92d435c8..64288ced22 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java @@ -29,4 +29,14 @@ public interface OTPManagementDAO { * @throws OTPManagementDAOException if error occurred whule storing data */ int addOTPData(OTPMailDTO otpMailDTO) throws OTPManagementDAOException; + + /** + * Get OTP data for requesting One Time Token + * @param oneTimeToken One Time Token + * @return {@link OTPMailDTO} + * @throws OTPManagementDAOException if error ocured while getting OTP data for requesting one time token + */ + OTPMailDTO getOTPDataByToken (String oneTimeToken) throws OTPManagementDAOException; + + void ExpireOneTimeToken (String oneTimeToken); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java index 9149a7450b..b8ec791faf 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java @@ -82,4 +82,65 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM throw new OTPManagementDAOException(msg, e); } } + + @Override + public OTPMailDTO getOTPDataByToken (String oneTimeToken) throws OTPManagementDAOException { + + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get an OTP data entry for OTP"); + log.debug("OTP Details : OTP key : " + oneTimeToken ); + } + + String sql = "SELECT " + + "ID, " + + "OTP_TOKEN, " + + "TENANT_DOMAIN," + + "EMAIL, " + + "EMAIL_TYPE, " + + "META_INFO, " + + "CREATED_AT, " + + "EXPIRY_TIME, " + + "IS_EXPIRED, " + + "TENANT_CREATED FROM DM_OTP_DATA " + + "WHERE OTP_TOKEN = ?"; + + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, oneTimeToken); + + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + OTPMailDTO otpMailDTO = new OTPMailDTO(); + otpMailDTO.setId(rs.getInt("ID")); + otpMailDTO.setOtpToken(rs.getString("OTP_TOKEN")); + otpMailDTO.setTenantDomain(rs.getString("TENANT_DOMAIN")); + otpMailDTO.setEmail(rs.getString("EMAIL")); + otpMailDTO.setEmailType(rs.getString("EMAIL_TYPE")); + otpMailDTO.setMetaInfo(rs.getString("META_INFO")); + otpMailDTO.setCreatedAt(rs.getTimestamp("CREATED_AT")); + otpMailDTO.setExpiryTime(rs.getInt("EXPIRY_TIME")); + otpMailDTO.setExpired(rs.getBoolean("IS_EXPIRED")); + otpMailDTO.setTenantCreated(rs.getBoolean("TENANT_CREATED")); + return otpMailDTO; + } + return null; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get OPT data for given OTP. OTP: " + + oneTimeToken; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to get OTP data for OTP. One time token: " + oneTimeToken; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } + } + + @Override + public void ExpireOneTimeToken (String oneTimeToken) { + + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java index 16c21396a8..464c2da922 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -32,6 +32,9 @@ import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAOFactory; import org.wso2.carbon.device.mgt.core.otp.mgt.exception.OTPManagementDAOException; import org.wso2.carbon.device.mgt.core.otp.mgt.util.ConnectionManagerUtil; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; import java.util.UUID; public class OTPManagementServiceImpl implements OTPManagementService { @@ -90,6 +93,58 @@ public class OTPManagementServiceImpl implements OTPManagementService { String msg = "Error occurred while saving the OTP data. Email address: " + otpMailDTO.getEmail(); log.error(msg, e); throw new OTPManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public boolean isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException { + OTPMailDTO otpMailDTO = getOTPDataByToken(oneTimeToken); + if (otpMailDTO == null) { + String msg = "Couldn't found OTP data for the requesting OTP " + oneTimeToken + " In the system."; + log.error(msg); + throw new BadRequestException(msg); + } + + if (otpMailDTO.isExpired()) { + return false; + } + + Calendar calendar = Calendar.getInstance(); + Timestamp currentTimestamp = new Timestamp(calendar.getTime().getTime()); + Timestamp expiredTimestamp = new Timestamp( + otpMailDTO.getCreatedAt().getTime() + otpMailDTO.getExpiryTime() * 1000); + + if (currentTimestamp.after(expiredTimestamp)) { + //todo update the DB + return false; + } + + return true; + + } + + /** + * Get OTPData from DB + * @param oneTimeToken One Time Token + * @return {@link OTPMailDTO} + * @throws OTPManagementException if error occurred while getting OTP data for given OTP in DB + */ + private OTPMailDTO getOTPDataByToken ( String oneTimeToken) throws OTPManagementException { + try { + ConnectionManagerUtil.openDBConnection(); + return otpManagementDAO.getOTPDataByToken(oneTimeToken); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection to validate the given OTP."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } catch (OTPManagementDAOException e) { + String msg = "Error occurred while getting OTP data from DB. OTP: " + oneTimeToken; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java index 54c7c04805..ad677b1bf0 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java @@ -89,7 +89,6 @@ import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceTypeVersion; import org.wso2.carbon.device.mgt.core.geo.GeoCluster; import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; -import org.wso2.carbon.device.mgt.core.operation.mgt.CommandOperation; import java.sql.SQLException; import java.util.Date; diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java index 7b207aa034..636b0052a4 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java @@ -20,21 +20,13 @@ package org.wso2.carbon.webapp.authenticator.framework.authenticator; import org.apache.catalina.connector.Response; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.tomcat.util.buf.ByteChunk; -import org.apache.tomcat.util.buf.MessageBytes; import org.wso2.carbon.device.mgt.common.general.OneTimeTokenDetails; -import org.wso2.carbon.webapp.authenticator.framework.AuthenticationException; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo; import org.wso2.carbon.webapp.authenticator.framework.Constants; -import org.wso2.carbon.webapp.authenticator.framework.Utils.Utils; -import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuth2TokenValidator; -import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthTokenValidationException; -import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthValidationResponse; +import org.wso2.carbon.webapp.authenticator.framework.internal.AuthenticatorFrameworkDataHolder; import java.util.Properties; -import java.util.StringTokenizer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class OneTimeTokenAuthenticator implements WebappAuthenticator { private static final Log log = LogFactory.getLog(OneTimeTokenAuthenticator.class); @@ -51,6 +43,10 @@ public class OneTimeTokenAuthenticator implements WebappAuthenticator { public AuthenticationInfo authenticate(org.apache.catalina.connector.Request request, Response response) { + OTPManagementService otpManagementService = AuthenticatorFrameworkDataHolder.getInstance() + .getOtpManagementService(); + + String token = request.getHeader(Constants.HTTPHeaders.ONE_TIME_TOKEN_HEADER); // DeviceMgtAPIUtils.getDeviceManagementService();//TODO: call token validate service in core OneTimeTokenDetails tokenDetails = new OneTimeTokenDetails();//TODO: use token details diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/AuthenticatorFrameworkDataHolder.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/AuthenticatorFrameworkDataHolder.java index 0bfbcc8f43..a95b4fadb6 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/AuthenticatorFrameworkDataHolder.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/AuthenticatorFrameworkDataHolder.java @@ -20,7 +20,7 @@ package org.wso2.carbon.webapp.authenticator.framework.internal; import org.wso2.carbon.certificate.mgt.core.scep.SCEPManager; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; -import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; @@ -36,7 +36,7 @@ public class AuthenticatorFrameworkDataHolder { private OAuth2TokenValidationService oAuth2TokenValidationService; private TenantIndexingLoader tenantIndexingLoader; private TenantRegistryLoader tenantRegistryLoader; - private DeviceManagementProviderService deviceManagementService; + private OTPManagementService otpManagementService; private static AuthenticatorFrameworkDataHolder thisInstance = new AuthenticatorFrameworkDataHolder(); @@ -117,12 +117,9 @@ public class AuthenticatorFrameworkDataHolder { return tenantRegistryLoader; } + public OTPManagementService getOtpManagementService() { return otpManagementService; } - public DeviceManagementProviderService getDeviceManagementService() { - return deviceManagementService; - } - - public void setDeviceManagementService(DeviceManagementProviderService deviceManagementService) { - this.deviceManagementService = deviceManagementService; + public void setOtpManagementService(OTPManagementService otpManagementService) { + this.otpManagementService = otpManagementService; } } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java index 1fc7ba2bb9..ef71b78718 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java @@ -25,6 +25,7 @@ import org.osgi.framework.BundleContext; import org.osgi.service.component.ComponentContext; import org.wso2.carbon.certificate.mgt.core.scep.SCEPManager; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; import org.wso2.carbon.registry.core.service.TenantRegistryLoader; @@ -81,13 +82,14 @@ import java.util.Properties; * cardinality="1..1" policy="dynamic" * bind="setTenantRegistryLoader" * unbind="unsetTenantRegistryLoader" - * @scr.reference name="org.wso2.carbon.device.manager" - * interface="org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService" + * @scr.reference name="org.wso2.carbon.otp.manager" + * interface="org.wso2.carbon.device.mgt.common.spi.OTPManagementService" * cardinality="1..1" * policy="dynamic" - * bind="setDeviceManagementService" - * unbind="unsetDeviceManagementService" + * bind="setOTPManagementService" + * unbind="unsetOTPManagementService" */ + public class WebappAuthenticatorFrameworkServiceComponent { private static final Log log = LogFactory.getLog(WebappAuthenticatorFrameworkServiceComponent.class); @@ -219,19 +221,17 @@ public class WebappAuthenticatorFrameworkServiceComponent { AuthenticatorFrameworkDataHolder.getInstance().setTenantRegistryLoader(null); } - @SuppressWarnings("unused") - protected void setDeviceManagementService(DeviceManagementProviderService deviceManagementProviderService) { + protected void setOTPManagementService(OTPManagementService otpManagementService) { if (log.isDebugEnabled()) { - log.debug("Setting ApplicationDTO Management OSGI Manager"); + log.debug("Setting OTP Management OSGI Service"); } - AuthenticatorFrameworkDataHolder.getInstance().setDeviceManagementService(deviceManagementProviderService); + AuthenticatorFrameworkDataHolder.getInstance().setOtpManagementService(otpManagementService); } - @SuppressWarnings("unused") - protected void unsetDeviceManagementService(DeviceManagementProviderService deviceManagementProviderService) { + protected void unsetOTPManagementService(OTPManagementService otpManagementService) { if (log.isDebugEnabled()) { - log.debug("Removing ApplicationDTO Management OSGI Manager"); + log.debug("Removing OTP Management OSGI Service"); } - AuthenticatorFrameworkDataHolder.getInstance().setDeviceManagementService(null); + AuthenticatorFrameworkDataHolder.getInstance().setOtpManagementService(null); } } From 3d2f474e75b5fb539fba4206b7508eaf9f05953b Mon Sep 17 00:00:00 2001 From: Dharmakeerthi Lasantha Date: Thu, 30 Jul 2020 12:54:35 +0000 Subject: [PATCH 06/33] Improve OTP creating functionality --- .../mgt/common/spi/OTPManagementService.java | 9 ++- .../core/otp/mgt/dao/OTPManagementDAO.java | 16 +++- .../dao/impl/GenericOTPManagementDAOImpl.java | 61 ++++++++++++++- .../mgt/service/OTPManagementServiceImpl.java | 74 ++++++++++++++++++- .../OneTimeTokenAuthenticator.java | 25 +++---- 5 files changed, 163 insertions(+), 22 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java index 24ec41d229..6ce92c27c9 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java @@ -24,7 +24,7 @@ import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper; public interface OTPManagementService { /** - * Cretae OTP token and store tenant details in the DB + * Create OTP token and store tenant details in the DB * @param otpMailWrapper OTP Mail Wrapper object which contains tenant details of registering user * @return OTPToken * @throws OTPManagementException if error occurs while creating OTP token and storing tenant details. @@ -32,5 +32,12 @@ public interface OTPManagementService { */ String createOTPToken (OTPMailWrapper otpMailWrapper) throws OTPManagementException, BadRequestException; + /** + * Check the validity of the OTP + * @param oneTimeToken OTP + * @return Ture if OTP is valid one, otherise returns false + * @throws OTPManagementException if error occurred whle verifying validity of the OPT + * @throws BadRequestException if found an null value for OTP + */ boolean isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java index 64288ced22..9a9ae3eefb 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java @@ -38,5 +38,19 @@ public interface OTPManagementDAO { */ OTPMailDTO getOTPDataByToken (String oneTimeToken) throws OTPManagementDAOException; - void ExpireOneTimeToken (String oneTimeToken); + /** + * Expire the OTP + * @param oneTimeToken OTP + * @throws OTPManagementDAOException if error occurred while updating the OTP validity. + */ + void expireOneTimeToken(String oneTimeToken) throws OTPManagementDAOException; + + /** + * Update OTP with renewed OTP + * @param id ID + * @param oneTimeToken One Time Token + * @throws OTPManagementDAOException if error occured while updating OTP + */ + void renewOneTimeToken(int id, String oneTimeToken) throws OTPManagementDAOException; + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java index b8ec791faf..7cc27618a1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java @@ -140,7 +140,66 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM } @Override - public void ExpireOneTimeToken (String oneTimeToken) { + public void expireOneTimeToken(String oneTimeToken) throws OTPManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to update an OTP data entry for OTP"); + log.debug("OTP Details : OTP key : " + oneTimeToken ); + } + + String sql = "UPDATE DM_OTP_DATA " + + "SET " + + "IS_EXPIRED = ? " + + "WHERE OTP_TOKEN = ?"; + + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setBoolean(1, true); + stmt.setString(2, oneTimeToken); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to update the OTP token validity."; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when obtaining database connection for updating the OTP token validity."; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } + } + + @Override + public void renewOneTimeToken(int id, String oneTimeToken) throws OTPManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to update an OTP data entry for OTP"); + log.debug("OTP Details : OTP key : " + oneTimeToken ); + } + + String sql = "UPDATE DM_OTP_DATA " + + "SET " + + "OTP_TOKEN = ? " + + "CREATED_AT = ? " + + "WHERE ID = ?"; + try { + Connection conn = this.getDBConnection(); + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, oneTimeToken); + stmt.setTimestamp(2, timestamp); + stmt.setInt(3, id); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to update the OTP token validity."; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when obtaining database connection for updating the OTP token validity."; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java index 464c2da922..47ef466114 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -20,21 +20,26 @@ import com.google.gson.Gson; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException; import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException; +import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException; import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO; import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; +import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; +import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAO; import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper; import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAOFactory; import org.wso2.carbon.device.mgt.core.otp.mgt.exception.OTPManagementDAOException; import org.wso2.carbon.device.mgt.core.otp.mgt.util.ConnectionManagerUtil; +import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo; -import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; +import java.util.Properties; import java.util.UUID; public class OTPManagementServiceImpl implements OTPManagementService { @@ -108,6 +113,11 @@ public class OTPManagementServiceImpl implements OTPManagementService { } if (otpMailDTO.isExpired()) { + log.warn("Token is expired. OTP: " + oneTimeToken); + return false; + } + if (otpMailDTO.isTenantCreated()) { + log.warn("Tenant is already created for the token. OTP: " + oneTimeToken); return false; } @@ -117,12 +127,14 @@ public class OTPManagementServiceImpl implements OTPManagementService { otpMailDTO.getCreatedAt().getTime() + otpMailDTO.getExpiryTime() * 1000); if (currentTimestamp.after(expiredTimestamp)) { - //todo update the DB + String renewedOTP = UUID.randomUUID().toString(); + renewOTP(otpMailDTO, renewedOTP); + Gson gson = new Gson(); + OTPMailWrapper otpMailWrapper = gson.fromJson(otpMailDTO.getMetaInfo(), OTPMailWrapper.class); + resendUserVerifyingMail(otpMailWrapper.getFirstName(), renewedOTP, otpMailDTO.getEmail()); return false; } - return true; - } /** @@ -184,4 +196,58 @@ public class OTPManagementServiceImpl implements OTPManagementService { } return true; } + + /** + * If OTP expired, resend the user verifying mail with renewed OTP + * @param firstName First Name of the User + * @param renewedOTP Renewed OTP + * @param mailAddress Mail Address of the User + * @throws OTPManagementException if error occurred while resend the user verifying mail + */ + private void resendUserVerifyingMail(String firstName, String renewedOTP, String mailAddress) + throws OTPManagementException { + Properties props = new Properties(); + props.setProperty("first-name", firstName); + props.setProperty("otp-token", renewedOTP); + + EmailMetaInfo metaInfo = new EmailMetaInfo(mailAddress, props); + try { + DeviceManagementDataHolder.getInstance().getDeviceManagementProvider() + .sendEnrolmentInvitation(DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE, metaInfo); + } catch (DeviceManagementException e) { + e.printStackTrace(); + throw new OTPManagementException(e); + } catch (ConfigurationManagementException e) { + throw new OTPManagementException(e); + } + } + + /** + * Renew the OTP + * @param otpMailDTO {@link OTPMailDTO} + * @param renewedOTP Renewed OTP + * @throws OTPManagementException if error occurred while renew the OTP + */ + private void renewOTP(OTPMailDTO otpMailDTO, String renewedOTP) throws OTPManagementException { + try { + ConnectionManagerUtil.beginDBTransaction(); + this.otpManagementDAO.renewOneTimeToken(otpMailDTO.getId(), renewedOTP); + ConnectionManagerUtil.commitDBTransaction(); + } catch (TransactionManagementException e) { + String msg = "Error occurred while disabling AutoCommit to renew the OTP."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection to renew the OTP."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } catch (OTPManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while renew the OTP. OTP: " + renewedOTP; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java index 636b0052a4..d150f6ee3f 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java @@ -20,7 +20,6 @@ package org.wso2.carbon.webapp.authenticator.framework.authenticator; import org.apache.catalina.connector.Response; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.device.mgt.common.general.OneTimeTokenDetails; import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo; import org.wso2.carbon.webapp.authenticator.framework.Constants; @@ -45,25 +44,21 @@ public class OneTimeTokenAuthenticator implements WebappAuthenticator { OTPManagementService otpManagementService = AuthenticatorFrameworkDataHolder.getInstance() .getOtpManagementService(); - - - String token = request.getHeader(Constants.HTTPHeaders.ONE_TIME_TOKEN_HEADER); -// DeviceMgtAPIUtils.getDeviceManagementService();//TODO: call token validate service in core - OneTimeTokenDetails tokenDetails = new OneTimeTokenDetails();//TODO: use token details - AuthenticationInfo authenticationInfo = new AuthenticationInfo(); try { - authenticationInfo.setTenantDomain(tokenDetails.getDomain()); - authenticationInfo.setStatus(Status.CONTINUE); - //authenticationInfo.setUsername(tokenDetails.get); //TODO: set username - //authenticationInfo.setTenantId();//TODO: set tenant Id - } catch (Exception e) { // TODO: remove this if not needed + if (otpManagementService.isValidOTP(request.getHeader(Constants.HTTPHeaders.ONE_TIME_TOKEN_HEADER))) { + authenticationInfo.setStatus(Status.CONTINUE); + authenticationInfo.setTenantId(-1); + } else { + authenticationInfo.setStatus(Status.FAILURE); + authenticationInfo.setMessage("Invalid OTP token."); + } + } catch (Exception e) { authenticationInfo.setStatus(Status.FAILURE); - authenticationInfo.setMessage("Could not identify tenant domain."); + authenticationInfo.setMessage("CToken Validation Failed."); } - - return null; + return authenticationInfo; } public String getName() { From efee2b01bf6f602007ba14f10460a56fb512ab35 Mon Sep 17 00:00:00 2001 From: Dharmakeerthi Lasantha Date: Thu, 30 Jul 2020 12:54:35 +0000 Subject: [PATCH 07/33] Improve OTP creating functionality --- .../service/api/UserManagementService.java | 46 ------------------ .../impl/UserManagementServiceImpl.java | 47 ------------------- .../mgt/jaxrs/util/DeviceMgtAPIUtils.java | 24 ---------- .../src/main/webapp/WEB-INF/web.xml | 3 +- .../pom.xml | 1 + .../OneTimeTokenAuthenticator.java | 8 ++-- .../etc/webapp-authenticator-config.xml | 4 ++ .../conf/webapp-authenticator-config.xml | 4 ++ 8 files changed, 15 insertions(+), 122 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java index a133ffd4ec..d68ba8fc09 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java @@ -1221,50 +1221,4 @@ public interface UserManagementService { response = ErrorResponse.class) }) Response getPermissionsOfUser(); - - @POST - @Path("/one-time-pin") - @ApiOperation( - produces = MediaType.APPLICATION_JSON, - httpMethod = "GET", - value = "Getting the permission details of the current user", - notes = "A user may granted more than one permission in IoTS. Using this REST API " - + "you can get the permission/permission the current user has granted. ", - tags = "User Management", - extensions = { - @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:user:permission-view") - }) - } - ) - @ApiResponses(value = { - @ApiResponse( - code = 200, - message = "OK. \n Successfully fetched the list of permissions the user " - + "has granted.", - response = PermissionList.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 = 404, - message = "Not Found. \n The specified resource does not exist.\n", - 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 sendEmailVerifyingMail(OTPMailWrapper otpMailWrapper); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java index 8b9dbe6e65..ec28453188 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java @@ -1118,53 +1118,6 @@ public class UserManagementServiceImpl implements UserManagementService { } } - /** - * Method used to send an invitation email to a existing user to enroll a device. - * - * @param otpMailWrapper Username list of the users to be invited - */ - @POST - @Path("/one-time-pin") - @Produces({MediaType.APPLICATION_JSON}) - public Response sendEmailVerifyingMail(OTPMailWrapper otpMailWrapper) { - if (log.isDebugEnabled()) { - log.debug("Sending enrollment invitation mail to existing user."); - } - DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); - OTPManagementService oms = DeviceMgtAPIUtils.getOTPManagementService(); - try { - String otpToken = oms.createOTPToken(otpMailWrapper); - Properties props = new Properties(); - props.setProperty("first-name", otpMailWrapper.getFirstName()); - props.setProperty("otp-token", otpToken); - - EmailMetaInfo metaInfo = new EmailMetaInfo(otpMailWrapper.getEmail(), props); - dms.sendEnrolmentInvitation(DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE, - metaInfo); - } catch (DeviceManagementException e) { - String msg = "Error occurred while inviting user to enrol their device"; - if (e.getMessage() != null && !e.getMessage().isEmpty()) { - msg = e.getMessage(); - } - log.error(msg, e); - return Response.serverError().entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); - } catch (ConfigurationManagementException e) { - String msg = "Error occurred while sending the email invitations. Mail server not configured."; - return Response.serverError().entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); - } catch (OTPManagementException e) { - String msg = "Error occurred while generating and storing the OTP data"; - log.error(msg, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); - } catch (org.wso2.carbon.device.mgt.common.exceptions.BadRequestException e) { - String msg = "Bad Request : Found invalid request payload to create OTP toke."; - log.error(msg, e); - return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); - } - return Response.status(Response.Status.OK).entity("Invitation mails have been sent.").build(); - } - private Map buildDefaultUserClaims(String firstName, String lastName, String emailAddress, boolean isFresh) { Map defaultUserClaims = new HashMap<>(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java index fa5eeaf2c7..91161ced0d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java @@ -142,7 +142,6 @@ public class DeviceMgtAPIUtils { private static IntegrationClientService integrationClientService; private static MetadataManagementService metadataManagementService; - private static volatile OTPManagementService otpManagementService; static { String keyStorePassword = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Password"); @@ -461,29 +460,6 @@ public class DeviceMgtAPIUtils { return metadataManagementService; } - /** - * Initializing and accessing method for OTPManagementService. - * - * @return OTPManagementService instance - * @throws IllegalStateException if OTPManagementService cannot be initialized - */ - public static OTPManagementService getOTPManagementService() { - if (otpManagementService == null) { - synchronized (DeviceMgtAPIUtils.class) { - if (otpManagementService == null) { - PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); - otpManagementService = (OTPManagementService) ctx.getOSGiService(OTPManagementService.class, null); - if (otpManagementService == null) { - String msg = "OTP Management service not initialized."; - log.error(msg); - throw new IllegalStateException(msg); - } - } - } - } - return otpManagementService; - } - /** * Method for initializing ReportManagementService * @return ReportManagementServie Instance diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/web.xml b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/web.xml index d24eeb72b3..fffbfbdb24 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/web.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/web.xml @@ -48,8 +48,7 @@ nonSecuredEndPoints - /api/device-mgt/v1.0/users/validate, - /api/device-mgt/v1.0/users/one-time-pin + /api/device-mgt/v1.0/users/validate diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml index d2c8bb4dec..ee7fd305f2 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml @@ -94,6 +94,7 @@ org.wso2.carbon.certificate.mgt.core.*, org.wso2.carbon.device.mgt.core.permission.mgt, org.wso2.carbon.device.mgt.common, + org.wso2.carbon.device.mgt.core.*, org.wso2.carbon.device.mgt.common.permission.mgt, org.apache.axis2, org.apache.axis2.client, diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java index d150f6ee3f..41f43eea9d 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java @@ -42,11 +42,11 @@ public class OneTimeTokenAuthenticator implements WebappAuthenticator { public AuthenticationInfo authenticate(org.apache.catalina.connector.Request request, Response response) { - OTPManagementService otpManagementService = AuthenticatorFrameworkDataHolder.getInstance() - .getOtpManagementService(); AuthenticationInfo authenticationInfo = new AuthenticationInfo(); try { + OTPManagementService otpManagementService = AuthenticatorFrameworkDataHolder.getInstance() + .getOtpManagementService(); if (otpManagementService.isValidOTP(request.getHeader(Constants.HTTPHeaders.ONE_TIME_TOKEN_HEADER))) { authenticationInfo.setStatus(Status.CONTINUE); authenticationInfo.setTenantId(-1); @@ -55,8 +55,10 @@ public class OneTimeTokenAuthenticator implements WebappAuthenticator { authenticationInfo.setMessage("Invalid OTP token."); } } catch (Exception e) { + String msg = "OTP Token Validation Failed."; + log.error(msg, e); authenticationInfo.setStatus(Status.FAILURE); - authenticationInfo.setMessage("CToken Validation Failed."); + authenticationInfo.setMessage(msg); } return authenticationInfo; } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/config/etc/webapp-authenticator-config.xml b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/config/etc/webapp-authenticator-config.xml index 5099328df7..93830ca169 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/config/etc/webapp-authenticator-config.xml +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/config/etc/webapp-authenticator-config.xml @@ -24,5 +24,9 @@ CertificateAuth org.wso2.carbon.webapp.authenticator.framework.authenticator.CertificateAuthenticator + + OTPAuth + org.wso2.carbon.webapp.authenticator.framework.authenticator.OneTimeTokenAuthenticator + diff --git a/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml b/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml index 4b727a28c2..dfea5c07ac 100644 --- a/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml +++ b/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml @@ -31,6 +31,10 @@ CertificateAuth org.wso2.carbon.webapp.authenticator.framework.authenticator.CertificateAuthenticator + + OTPAuth + org.wso2.carbon.webapp.authenticator.framework.authenticator.OneTimeTokenAuthenticator + BST org.wso2.carbon.webapp.authenticator.framework.authenticator.BSTAuthenticator From f86837996f97a51828e6c381ebe11754f134cffd Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Mon, 3 Aug 2020 09:08:32 +0530 Subject: [PATCH 08/33] Add OTP authenticator into config --- .../src/main/resources/conf/webapp-authenticator-config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml b/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml index dfea5c07ac..cd376469ef 100644 --- a/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml +++ b/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml @@ -29,7 +29,7 @@ CertificateAuth - org.wso2.carbon.webapp.authenticator.framework.authenticator.CertificateAuthenticator + org.wso2.carbon.webapp.authenticator.framework.authenticator.gitCertificateAuthenticator OTPAuth From 59eeec55d6f05fb388fdffe07e88055502c808a0 Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Tue, 4 Aug 2020 07:47:53 +0530 Subject: [PATCH 09/33] Fix OSGI loading issue in web app authenticator --- .../DeviceManagementConfigServiceImpl.java | 88 ------------------- .../pom.xml | 3 +- ...uthenticatorFrameworkServiceComponent.java | 3 +- 3 files changed, 2 insertions(+), 92 deletions(-) diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java index 2541577698..9ccbecda3d 100644 --- a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java @@ -24,7 +24,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.entgra.carbon.device.mgt.config.jaxrs.beans.ErrorResponse; import io.entgra.carbon.device.mgt.config.jaxrs.service.DeviceManagementConfigService; import io.entgra.carbon.device.mgt.config.jaxrs.util.DeviceMgtAPIUtils; -import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.base.MultitenantConstants; @@ -36,7 +35,6 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.AmbiguousConfiguratio import org.wso2.carbon.device.mgt.common.configuration.mgt.DeviceConfiguration; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceNotFoundException; -import org.wso2.carbon.device.mgt.common.general.OneTimeTokenDetails; import org.wso2.carbon.device.mgt.common.general.TenantDetail; import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagementException; import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService; @@ -50,8 +48,6 @@ import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; -import org.wso2.carbon.stratos.common.beans.TenantInfoBean; -import org.wso2.carbon.tenant.mgt.services.TenantMgtAdminService; import org.wso2.carbon.user.api.Tenant; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.core.service.RealmService; @@ -68,9 +64,6 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.IOException; import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; import java.util.List; import java.util.Map; @@ -277,87 +270,6 @@ public class DeviceManagementConfigServiceImpl implements DeviceManagementConfig return tenantDetail; } - /** - * This API will add a tenant to the system and can be called by the super tenant only. - * @return Returns the - */ - @Path("/tenant") - @POST - @Produces(MediaType.APPLICATION_JSON) - public Response addTenant(@HeaderParam("one-time-token") String token) { - - TenantMgtAdminService tenantMgtAdminService = null; - OneTimeTokenDetails tenantWrapper = null; - - // Request validation - String errorMsg = null; - Response.Status errorStatus = Response.Status.BAD_REQUEST; - if (StringUtils.isEmpty(token)) { - errorMsg = "Authentication failure when creating tenant"; - } else { - tenantWrapper = new OneTimeTokenDetails(); //TODO: Call one time token validation API - if (tenantWrapper == null) { - errorMsg = "One time token is not present in the database"; - } else { - try { - tenantMgtAdminService = new TenantMgtAdminService(); - if (tenantMgtAdminService == null) { - errorMsg = "Request can only be made by super admin"; - errorStatus = Response.Status.INTERNAL_SERVER_ERROR; - } else { - TenantInfoBean[] tenant = tenantMgtAdminService.retrievePartialSearchTenants(tenantWrapper.getDomain()); - if (!PrivilegedCarbonContext.getThreadLocalCarbonContext() - .getTenantDomain().equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) { - errorMsg = "Request can only be made by super admin"; - } else if (tenant != null && tenant.length > 0) { - for (TenantInfoBean tenantInfoBean : tenant) { - if (tenantInfoBean.getTenantDomain().equals(tenantWrapper.getDomain())) { - errorMsg = "Tenant domain is already in use"; - break; - } - } - } - } - - } catch (Exception e) { // Carbon multi-tenancy is throwing generic exceptions. - errorMsg = "Could not create tenant domain " + tenantWrapper.getDomain(); - errorStatus = Response.Status.INTERNAL_SERVER_ERROR; - } - } - } - - if (errorMsg != null) { - log.error(errorMsg); - return Response.status(errorStatus).entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(errorMsg).build() - ).build(); - } - - try { - TenantInfoBean tenantInfoBean = new TenantInfoBean(); - tenantInfoBean.setActive(true); - tenantInfoBean.setAdminPassword(tenantWrapper.getPassword()); - tenantInfoBean.setAdmin(tenantWrapper.getAdminName()); - tenantInfoBean.setFirstname(tenantWrapper.getAdminFirstName()); - tenantInfoBean.setLastname(tenantWrapper.getAdminLastName()); - tenantInfoBean.setEmail(tenantWrapper.getEmail()); - Calendar calendar = new GregorianCalendar(); - calendar.setTime(new Date()); - tenantInfoBean.setCreatedDate(calendar); - tenantInfoBean.setTenantDomain(tenantWrapper.getDomain()); - - String response = tenantMgtAdminService.addTenant(tenantInfoBean); - return Response.status(Response.Status.OK).entity(response).build(); - - } catch (Exception e) { // The underlying API is throwing a generic exception. - String msg = "Error while adding tenant"; - log.error(msg, e); - return Response.serverError().entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); - } - - } - @POST @Path("/permissions") @Produces({MediaType.APPLICATION_JSON}) diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml index ee7fd305f2..24cbfecefb 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml @@ -93,8 +93,7 @@ org.apache.axis2.transport.http, org.wso2.carbon.certificate.mgt.core.*, org.wso2.carbon.device.mgt.core.permission.mgt, - org.wso2.carbon.device.mgt.common, - org.wso2.carbon.device.mgt.core.*, + org.wso2.carbon.device.mgt.common.*, org.wso2.carbon.device.mgt.common.permission.mgt, org.apache.axis2, org.apache.axis2.client, diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java index ef71b78718..49eff0503b 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java @@ -26,7 +26,6 @@ import org.osgi.service.component.ComponentContext; import org.wso2.carbon.certificate.mgt.core.scep.SCEPManager; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; -import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; @@ -82,7 +81,7 @@ import java.util.Properties; * cardinality="1..1" policy="dynamic" * bind="setTenantRegistryLoader" * unbind="unsetTenantRegistryLoader" - * @scr.reference name="org.wso2.carbon.otp.manager" + * @scr.reference name="org.wso2.carbon.device.manager" * interface="org.wso2.carbon.device.mgt.common.spi.OTPManagementService" * cardinality="1..1" * policy="dynamic" From b91dcdbfc9622e4f4b5773fcb7624dcdeb52684d Mon Sep 17 00:00:00 2001 From: inoshperera Date: Tue, 4 Aug 2020 19:00:14 +0530 Subject: [PATCH 10/33] Add Db changes for tenant ID and username --- .../src/main/resources/dbscripts/cdm/h2.sql | 2 ++ .../src/main/resources/dbscripts/cdm/mssql.sql | 2 ++ .../src/main/resources/dbscripts/cdm/mysql.sql | 2 ++ .../src/main/resources/dbscripts/cdm/oracle.sql | 2 ++ .../src/main/resources/dbscripts/cdm/postgresql.sql | 2 ++ 5 files changed, 10 insertions(+) diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql index adf4044962..b75cbd2295 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql @@ -577,6 +577,8 @@ CREATE TABLE IF NOT EXISTS DM_OTP_DATA ( ID INT AUTO_INCREMENT NOT NULL, OTP_TOKEN VARCHAR(100) NOT NULL, TENANT_DOMAIN VARCHAR(20) NOT NULL, + TENANT_ID INT NOT NULL, + USERNAME VARCHAR(500) DEFAULT NOT NULL, EMAIL VARCHAR(100) NOT NULL, EMAIL_TYPE VARCHAR(20) NOT NULL, META_INFO VARCHAR(20000) NOT NULL, diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql index cbed63388d..90171e6735 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql @@ -619,6 +619,8 @@ CREATE TABLE DM_OTP_DATA ( ID INT IDENTITY NOT NULL, OTP_TOKEN VARCHAR(100) NOT NULL, TENANT_DOMAIN VARCHAR(20) NOT NULL, + TENANT_ID INTEGER NOT NULL, + USERNAME VARCHAR(500) NOT NULL, EMAIL VARCHAR(100) NOT NULL, EMAIL_TYPE VARCHAR(20) NOT NULL, META_INFO VARCHAR(20000) NOT NULL, diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql index a3dff752c3..42e103963b 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql @@ -635,6 +635,8 @@ CREATE TABLE IF NOT EXISTS DM_OTP_DATA ( ID INT AUTO_INCREMENT NOT NULL, OTP_TOKEN VARCHAR(100) NOT NULL, TENANT_DOMAIN VARCHAR(20) NOT NULL, + TENANT_ID INT NOT NULL, + USERNAME VARCHAR(500) NOT NULL, EMAIL VARCHAR(100) NOT NULL, EMAIL_TYPE VARCHAR(20) NOT NULL, META_INFO VARCHAR(20000) NOT NULL, diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql index 41a10d8ffe..da01528e68 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql @@ -983,6 +983,8 @@ CREATE TABLE DM_OTP_DATA ( ID NUMBER(10) NOT NULL, OTP_TOKEN VARCHAR2(100) NOT NULL, TENANT_DOMAIN VARCHAR(20) NOT NULL, + TENANT_ID INTEGER NOT NULL, + USERNAME VARCHAR(500) NOT NULL, EMAIL VARCHAR2(100) NOT NULL, EMAIL_TYPE VARCHAR2(20) NOT NULL, META_INFO VARCHAR2(20000) NOT NULL, diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql index c8c25534ae..279494c5da 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql @@ -624,6 +624,8 @@ CREATE TABLE IF NOT EXISTS DM_OTP_DATA ( ID INT DEFAULT NEXTVAL ('DM_OTP_DATA_seq') NOT NULL, OTP_TOKEN VARCHAR(100) NOT NULL, TENANT_DOMAIN VARCHAR(20) NOT NULL, + TENANT_ID INTEGER NOT NULL, + USERNAME VARCHAR(500) NOT NULL, EMAIL VARCHAR(100) NOT NULL, EMAIL_TYPE VARCHAR(20) NOT NULL, META_INFO VARCHAR(20000) NOT NULL, From 18531d0500221e2d1072d314c9a850bd554fc893 Mon Sep 17 00:00:00 2001 From: inoshperera Date: Tue, 4 Aug 2020 19:39:05 +0530 Subject: [PATCH 11/33] Add tenant ID and username to all layers --- .../mgt/common/otp/mgt/dto/OTPMailDTO.java | 23 ++++++++++++++---- .../otp/mgt/wrapper/OTPMailWrapper.java | 10 ++++---- .../dao/impl/GenericOTPManagementDAOImpl.java | 24 +++++++++++-------- .../mgt/service/OTPManagementServiceImpl.java | 7 +++--- .../src/main/resources/dbscripts/cdm/h2.sql | 1 - .../main/resources/dbscripts/cdm/mssql.sql | 1 - .../main/resources/dbscripts/cdm/mysql.sql | 1 - .../main/resources/dbscripts/cdm/oracle.sql | 1 - .../resources/dbscripts/cdm/postgresql.sql | 1 - 9 files changed, 41 insertions(+), 28 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OTPMailDTO.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OTPMailDTO.java index ee582b8288..87c347419e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OTPMailDTO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OTPMailDTO.java @@ -23,7 +23,8 @@ public class OTPMailDTO { int id; String otpToken; - String tenantDomain; + int tenantId; + String username; String email; String emailType; String metaInfo; @@ -32,6 +33,22 @@ public class OTPMailDTO { boolean isExpired; boolean isTenantCreated; + public int getTenantId() { + return tenantId; + } + + public void setTenantId(int tenantId) { + this.tenantId = tenantId; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + public int getId() { return id; } @@ -94,10 +111,6 @@ public class OTPMailDTO { isExpired = expired; } - public String getTenantDomain() { return tenantDomain; } - - public void setTenantDomain(String tenantDomain) { this.tenantDomain = tenantDomain; } - public boolean isTenantCreated() { return isTenantCreated; } public void setTenantCreated(boolean tenantCreated) { isTenantCreated = tenantCreated; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPMailWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPMailWrapper.java index 35f255ef6b..176e899a86 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPMailWrapper.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPMailWrapper.java @@ -20,18 +20,18 @@ public class OTPMailWrapper { private String firstName; private String lastName; - private String tenantDomain; private String adminUsername; + int tenantId; private String adminPassword; private String email; private String emailType; - public String getTenantDomain() { - return tenantDomain; + public int getTenantId() { + return tenantId; } - public void setTenantDomain(String tenantDomain) { - this.tenantDomain = tenantDomain; + public void setTenantId(int tenantId) { + this.tenantId = tenantId; } public String getAdminUsername() { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java index 7cc27618a1..076f5f820f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java @@ -47,22 +47,24 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM String sql = "INSERT INTO DM_OTP_DATA " + "(OTP_TOKEN, " - + "TENANT_DOMAIN," + "EMAIL, " + "EMAIL_TYPE, " + "META_INFO, " - + "CREATED_AT) VALUES (?, ?, ?, ?, ?, ?)"; + + "CREATED_AT," + + "TENANT_ID," + + "USERNAME) VALUES (?, ?, ?, ?, ?, ?, ?)"; try { Connection conn = this.getDBConnection(); Calendar calendar = Calendar.getInstance(); Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { stmt.setString(1, otpMailDTO.getOtpToken()); - stmt.setString(2, otpMailDTO.getTenantDomain()); - stmt.setString(3, otpMailDTO.getEmail()); - stmt.setString(4, otpMailDTO.getEmailType()); - stmt.setString(5, otpMailDTO.getMetaInfo()); - stmt.setTimestamp(6, timestamp); + stmt.setString(2, otpMailDTO.getEmail()); + stmt.setString(3, otpMailDTO.getEmailType()); + stmt.setString(4, otpMailDTO.getMetaInfo()); + stmt.setTimestamp(5, timestamp); + stmt.setInt(6, otpMailDTO.getTenantId()); + stmt.setString(7, otpMailDTO.getUsername()); stmt.executeUpdate(); try (ResultSet rs = stmt.getGeneratedKeys()) { if (rs.next()) { @@ -94,14 +96,15 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM String sql = "SELECT " + "ID, " + "OTP_TOKEN, " - + "TENANT_DOMAIN," + "EMAIL, " + "EMAIL_TYPE, " + "META_INFO, " + "CREATED_AT, " + "EXPIRY_TIME, " + "IS_EXPIRED, " - + "TENANT_CREATED FROM DM_OTP_DATA " + + "TENANT_CREATED," + + "TENANT_ID, " + + "USERNAME FROM DM_OTP_DATA " + "WHERE OTP_TOKEN = ?"; try { @@ -114,7 +117,6 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM OTPMailDTO otpMailDTO = new OTPMailDTO(); otpMailDTO.setId(rs.getInt("ID")); otpMailDTO.setOtpToken(rs.getString("OTP_TOKEN")); - otpMailDTO.setTenantDomain(rs.getString("TENANT_DOMAIN")); otpMailDTO.setEmail(rs.getString("EMAIL")); otpMailDTO.setEmailType(rs.getString("EMAIL_TYPE")); otpMailDTO.setMetaInfo(rs.getString("META_INFO")); @@ -122,6 +124,8 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM otpMailDTO.setExpiryTime(rs.getInt("EXPIRY_TIME")); otpMailDTO.setExpired(rs.getBoolean("IS_EXPIRED")); otpMailDTO.setTenantCreated(rs.getBoolean("TENANT_CREATED")); + otpMailDTO.setTenantId(rs.getInt("TENANT_ID")); + otpMailDTO.setUsername(rs.getString("USERNAME")); return otpMailDTO; } return null; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java index 47ef466114..1df9b13b32 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -70,7 +70,8 @@ public class OTPManagementServiceImpl implements OTPManagementService { OTPMailDTO otpMailDTO = new OTPMailDTO(); otpMailDTO.setEmail(otpMailWrapper.getEmail()); - otpMailDTO.setTenantDomain(otpMailWrapper.getTenantDomain()); + otpMailDTO.setTenantId(otpMailDTO.getTenantId()); + otpMailDTO.setUsername(otpMailWrapper.getAdminUsername()); otpMailDTO.setEmailType(otpMailWrapper.getEmailType()); otpMailDTO.setMetaInfo(metaInfo); otpMailDTO.setOtpToken(otpValue); @@ -190,8 +191,8 @@ public class OTPManagementServiceImpl implements OTPManagementService { log.error("Received empty or blank email type field with OTP creating payload."); return false; } - if (StringUtils.isBlank(otpMailWrapper.getTenantDomain())) { - log.error("Received empty or blank tenant domain field with OTP creating payload."); + if (otpMailWrapper.getTenantId() != -1234 && otpMailWrapper.getTenantId() < 1) { + log.error("Invalid tenant Id field with OTP creating payload."); return false; } return true; diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql index b75cbd2295..5ff3b1c08c 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql @@ -576,7 +576,6 @@ CREATE TABLE IF NOT EXISTS DM_METADATA ( CREATE TABLE IF NOT EXISTS DM_OTP_DATA ( ID INT AUTO_INCREMENT NOT NULL, OTP_TOKEN VARCHAR(100) NOT NULL, - TENANT_DOMAIN VARCHAR(20) NOT NULL, TENANT_ID INT NOT NULL, USERNAME VARCHAR(500) DEFAULT NOT NULL, EMAIL VARCHAR(100) NOT NULL, diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql index 90171e6735..5c82436ff1 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql @@ -618,7 +618,6 @@ CREATE TABLE DM_METADATA ( CREATE TABLE DM_OTP_DATA ( ID INT IDENTITY NOT NULL, OTP_TOKEN VARCHAR(100) NOT NULL, - TENANT_DOMAIN VARCHAR(20) NOT NULL, TENANT_ID INTEGER NOT NULL, USERNAME VARCHAR(500) NOT NULL, EMAIL VARCHAR(100) NOT NULL, diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql index 42e103963b..b2c64ebb3a 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql @@ -634,7 +634,6 @@ CREATE TABLE IF NOT EXISTS DM_METADATA ( CREATE TABLE IF NOT EXISTS DM_OTP_DATA ( ID INT AUTO_INCREMENT NOT NULL, OTP_TOKEN VARCHAR(100) NOT NULL, - TENANT_DOMAIN VARCHAR(20) NOT NULL, TENANT_ID INT NOT NULL, USERNAME VARCHAR(500) NOT NULL, EMAIL VARCHAR(100) NOT NULL, diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql index da01528e68..16139722fb 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql @@ -982,7 +982,6 @@ END; CREATE TABLE DM_OTP_DATA ( ID NUMBER(10) NOT NULL, OTP_TOKEN VARCHAR2(100) NOT NULL, - TENANT_DOMAIN VARCHAR(20) NOT NULL, TENANT_ID INTEGER NOT NULL, USERNAME VARCHAR(500) NOT NULL, EMAIL VARCHAR2(100) NOT NULL, diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql index 279494c5da..d5db624796 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql @@ -623,7 +623,6 @@ CREATE SEQUENCE DM_OTP_DATA_seq; CREATE TABLE IF NOT EXISTS DM_OTP_DATA ( ID INT DEFAULT NEXTVAL ('DM_OTP_DATA_seq') NOT NULL, OTP_TOKEN VARCHAR(100) NOT NULL, - TENANT_DOMAIN VARCHAR(20) NOT NULL, TENANT_ID INTEGER NOT NULL, USERNAME VARCHAR(500) NOT NULL, EMAIL VARCHAR(100) NOT NULL, From b61e9a667b389f2f045e0d1bc0a5a1ac1e2b7dd3 Mon Sep 17 00:00:00 2001 From: inoshperera Date: Tue, 4 Aug 2020 20:12:37 +0530 Subject: [PATCH 12/33] Improve token validation login in valve --- .../device/mgt/common/spi/OTPManagementService.java | 5 +++-- .../core/otp/mgt/service/OTPManagementServiceImpl.java | 10 +++++----- .../authenticator/OneTimeTokenAuthenticator.java | 10 ++++++++-- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java index 6ce92c27c9..1d23b20b03 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java @@ -19,6 +19,7 @@ package org.wso2.carbon.device.mgt.common.spi; import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException; import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; +import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO; import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper; public interface OTPManagementService { @@ -35,9 +36,9 @@ public interface OTPManagementService { /** * Check the validity of the OTP * @param oneTimeToken OTP - * @return Ture if OTP is valid one, otherise returns false + * @return The OTP data * @throws OTPManagementException if error occurred whle verifying validity of the OPT * @throws BadRequestException if found an null value for OTP */ - boolean isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException; + OTPMailDTO isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java index 1df9b13b32..78276c45b5 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -105,7 +105,7 @@ public class OTPManagementServiceImpl implements OTPManagementService { } @Override - public boolean isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException { + public OTPMailDTO isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException { OTPMailDTO otpMailDTO = getOTPDataByToken(oneTimeToken); if (otpMailDTO == null) { String msg = "Couldn't found OTP data for the requesting OTP " + oneTimeToken + " In the system."; @@ -115,11 +115,11 @@ public class OTPManagementServiceImpl implements OTPManagementService { if (otpMailDTO.isExpired()) { log.warn("Token is expired. OTP: " + oneTimeToken); - return false; + return null; } if (otpMailDTO.isTenantCreated()) { log.warn("Tenant is already created for the token. OTP: " + oneTimeToken); - return false; + return null; } Calendar calendar = Calendar.getInstance(); @@ -133,9 +133,9 @@ public class OTPManagementServiceImpl implements OTPManagementService { Gson gson = new Gson(); OTPMailWrapper otpMailWrapper = gson.fromJson(otpMailDTO.getMetaInfo(), OTPMailWrapper.class); resendUserVerifyingMail(otpMailWrapper.getFirstName(), renewedOTP, otpMailDTO.getEmail()); - return false; + return null; } - return true; + return otpMailDTO; } /** diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java index 41f43eea9d..c5e9d90824 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java @@ -20,9 +20,11 @@ package org.wso2.carbon.webapp.authenticator.framework.authenticator; import org.apache.catalina.connector.Response; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO; import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo; import org.wso2.carbon.webapp.authenticator.framework.Constants; +import org.wso2.carbon.webapp.authenticator.framework.Utils.Utils; import org.wso2.carbon.webapp.authenticator.framework.internal.AuthenticatorFrameworkDataHolder; import java.util.Properties; @@ -47,9 +49,13 @@ public class OneTimeTokenAuthenticator implements WebappAuthenticator { try { OTPManagementService otpManagementService = AuthenticatorFrameworkDataHolder.getInstance() .getOtpManagementService(); - if (otpManagementService.isValidOTP(request.getHeader(Constants.HTTPHeaders.ONE_TIME_TOKEN_HEADER))) { + OTPMailDTO validOTP = otpManagementService.isValidOTP(request.getHeader(Constants.HTTPHeaders + .ONE_TIME_TOKEN_HEADER)); + if (validOTP != null) { authenticationInfo.setStatus(Status.CONTINUE); - authenticationInfo.setTenantId(-1); + authenticationInfo.setTenantId(validOTP.getTenantId()); + authenticationInfo.setTenantDomain(Utils.getTenantDomain(validOTP.getTenantId())); + authenticationInfo.setUsername(validOTP.getUsername()); } else { authenticationInfo.setStatus(Status.FAILURE); authenticationInfo.setMessage("Invalid OTP token."); From 8494f0bc58d06c6f55d00150b845581099a9af3e Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Mon, 10 Aug 2020 02:38:51 +0530 Subject: [PATCH 13/33] Improve OTP creating logic --- .../service/api/UserManagementService.java | 1 - .../impl/DeviceManagementServiceImpl.java | 8 +- .../impl/UserManagementServiceImpl.java | 3 - .../mgt/common/DeviceManagementConstants.java | 10 ++ .../exceptions/BadRequestException.java | 2 +- .../exceptions/UnAuthorizedException.java | 45 ++++++ .../mgt/common/otp/mgt/dto/OTPMailDTO.java | 4 - .../{OTPMailWrapper.java => OTPWrapper.java} | 53 ++----- .../mgt/common/spi/OTPManagementService.java | 8 +- .../dao/impl/GenericOTPManagementDAOImpl.java | 2 - .../mgt/service/OTPManagementServiceImpl.java | 130 ++++++++++++------ .../src/main/resources/dbscripts/cdm/h2.sql | 1 - .../main/resources/dbscripts/cdm/mssql.sql | 1 - .../main/resources/dbscripts/cdm/mysql.sql | 1 - .../main/resources/dbscripts/cdm/oracle.sql | 1 - .../resources/dbscripts/cdm/postgresql.sql | 1 - .../conf/webapp-authenticator-config.xml | 2 +- 17 files changed, 162 insertions(+), 111 deletions(-) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/UnAuthorizedException.java rename components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/{OTPMailWrapper.java => OTPWrapper.java} (52%) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java index d68ba8fc09..432b752a66 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java @@ -49,7 +49,6 @@ import io.swagger.annotations.ResponseHeader; import org.apache.axis2.transport.http.HTTPConstants; import org.wso2.carbon.apimgt.annotations.api.Scopes; import org.wso2.carbon.apimgt.annotations.api.Scope; -import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper; import org.wso2.carbon.device.mgt.jaxrs.beans.ActivityList; import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfo; import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfoList; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java index a4ca3f026d..73a07b7aad 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -1288,6 +1288,10 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { operation.setId(operationStatusBean.getOperationId()); DeviceMgtAPIUtils.getDeviceManagementService().updateOperation(device, operation); return Response.status(Response.Status.OK).entity("OperationStatus updated successfully.").build(); + } catch (BadRequestException e) { + String msg = "Error occured due to invalid request"; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } catch (DeviceManagementException e) { String msg = "Error occurred when fetching device " + deviceIdentifier.toString(); log.error(msg, e); @@ -1296,10 +1300,6 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { String msg = "Error occurred when updating operation of device " + deviceIdentifier; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); - } catch (BadRequestException e) { - String msg = "Error occured due to invalid request"; - log.error(msg, e); - return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java index ec28453188..81233092f3 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java @@ -45,11 +45,8 @@ import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; -import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; -import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; -import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper; import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManagementConstants.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManagementConstants.java index 20b4f5b626..492288febb 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManagementConstants.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManagementConstants.java @@ -125,4 +125,14 @@ public final class DeviceManagementConstants { public static final String DEFAULT_HTTP_PROTOCOL = "https"; public static final String DAS_URL = DEFAULT_HTTP_PROTOCOL + "://" + DAS_HOST_NAME + ":" + DAS_PORT; } + + public static final class OTPProperties { + private OTPProperties() { throw new AssertionError(); } + + public static final String FIRST_NAME = "first-name"; + 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"; + } + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/BadRequestException.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/BadRequestException.java index b7d99da0e0..ed681b8140 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/BadRequestException.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/BadRequestException.java @@ -19,7 +19,7 @@ package org.wso2.carbon.device.mgt.common.exceptions; -public class BadRequestException extends Exception { +public class BadRequestException extends DeviceManagementException { private static final long serialVersionUID = 2304023531260840549L; public BadRequestException() { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/UnAuthorizedException.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/UnAuthorizedException.java new file mode 100644 index 0000000000..6c3d5c6346 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/UnAuthorizedException.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.wso2.carbon.device.mgt.common.exceptions; + +public class UnAuthorizedException extends DeviceManagementException { + private static final long serialVersionUID = 2304023531260840549L; + + public UnAuthorizedException() { + super(); + } + + public UnAuthorizedException(String msg) { + super(msg); + } + + public UnAuthorizedException(Throwable cause) { + super(cause); + } + + public UnAuthorizedException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public UnAuthorizedException(String message, Throwable cause) { + super(message, cause); + } +} + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OTPMailDTO.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OTPMailDTO.java index 87c347419e..bd8698206c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OTPMailDTO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OTPMailDTO.java @@ -31,7 +31,6 @@ public class OTPMailDTO { Timestamp createdAt; int expiryTime; boolean isExpired; - boolean isTenantCreated; public int getTenantId() { return tenantId; @@ -111,7 +110,4 @@ public class OTPMailDTO { isExpired = expired; } - public boolean isTenantCreated() { return isTenantCreated; } - - public void setTenantCreated(boolean tenantCreated) { isTenantCreated = tenantCreated; } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPMailWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPWrapper.java similarity index 52% rename from components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPMailWrapper.java rename to components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPWrapper.java index 176e899a86..319da774d1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPMailWrapper.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPWrapper.java @@ -16,39 +16,16 @@ */ package org.wso2.carbon.device.mgt.common.otp.mgt.wrapper; -public class OTPMailWrapper { +import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata; - private String firstName; - private String lastName; - private String adminUsername; - int tenantId; - private String adminPassword; - private String email; - private String emailType; - - public int getTenantId() { - return tenantId; - } - - public void setTenantId(int tenantId) { - this.tenantId = tenantId; - } - - public String getAdminUsername() { - return adminUsername; - } - - public void setAdminUsername(String adminUsername) { - this.adminUsername = adminUsername; - } +import java.util.List; - public String getAdminPassword() { - return adminPassword; - } +public class OTPWrapper { - public void setAdminPassword(String adminPassword) { - this.adminPassword = adminPassword; - } + private String email; + private String emailType; + private String username; + private List properties; public String getEmail() { return email; @@ -66,19 +43,11 @@ public class OTPMailWrapper { this.emailType = emailType; } - public String getFirstName() { - return firstName; - } + public String getUsername() { return username; } - public void setFirstName(String firstName) { - this.firstName = firstName; - } + public void setUsername(String username) { this.username = username; } - public String getLastName() { - return lastName; - } + public List getProperties() { return properties; } - public void setLastName(String lastName) { - this.lastName = lastName; - } + public void setProperties(List properties) { this.properties = properties; } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java index 1d23b20b03..00e6ce3d93 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java @@ -18,20 +18,20 @@ package org.wso2.carbon.device.mgt.common.spi; import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException; +import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO; -import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper; +import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPWrapper; public interface OTPManagementService { /** * Create OTP token and store tenant details in the DB - * @param otpMailWrapper OTP Mail Wrapper object which contains tenant details of registering user - * @return OTPToken + * @param otpWrapper OTP Mail Wrapper object which contains tenant details of registering user * @throws OTPManagementException if error occurs while creating OTP token and storing tenant details. * @throws BadRequestException if found and incompatible payload to create OTP token. */ - String createOTPToken (OTPMailWrapper otpMailWrapper) throws OTPManagementException, BadRequestException; + void sendUserVerifyingMail(OTPWrapper otpWrapper) throws OTPManagementException, DeviceManagementException; /** * Check the validity of the OTP diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java index 076f5f820f..a923756c88 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java @@ -102,7 +102,6 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM + "CREATED_AT, " + "EXPIRY_TIME, " + "IS_EXPIRED, " - + "TENANT_CREATED," + "TENANT_ID, " + "USERNAME FROM DM_OTP_DATA " + "WHERE OTP_TOKEN = ?"; @@ -123,7 +122,6 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM otpMailDTO.setCreatedAt(rs.getTimestamp("CREATED_AT")); otpMailDTO.setExpiryTime(rs.getInt("EXPIRY_TIME")); otpMailDTO.setExpired(rs.getBoolean("IS_EXPIRED")); - otpMailDTO.setTenantCreated(rs.getBoolean("TENANT_CREATED")); otpMailDTO.setTenantId(rs.getInt("TENANT_ID")); otpMailDTO.setUsername(rs.getString("USERNAME")); return otpMailDTO; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java index 78276c45b5..de013ce4ae 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -26,19 +26,28 @@ import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.UnAuthorizedException; +import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata; import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO; import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; +import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; +import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig; +import org.wso2.carbon.device.mgt.core.config.keymanager.KeyManagerConfigurations; import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAO; -import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper; +import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPWrapper; import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAOFactory; import org.wso2.carbon.device.mgt.core.otp.mgt.exception.OTPManagementDAOException; import org.wso2.carbon.device.mgt.core.otp.mgt.util.ConnectionManagerUtil; import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo; +import org.wso2.carbon.user.api.Tenant; + +import static org.wso2.carbon.device.mgt.common.DeviceManagementConstants.OTPProperties; import java.sql.Timestamp; import java.util.Calendar; +import java.util.List; import java.util.Properties; import java.util.UUID; @@ -56,23 +65,35 @@ public class OTPManagementServiceImpl implements OTPManagementService { } @Override - public String createOTPToken(OTPMailWrapper otpMailWrapper) throws OTPManagementException, BadRequestException { + public void sendUserVerifyingMail(OTPWrapper otpWrapper) throws OTPManagementException, DeviceManagementException { - if (!isValidOTPTokenCreatingRequest(otpMailWrapper)){ + Tenant tenant = validateOTPTokenCreatingRequest(otpWrapper); + if (tenant == null){ String msg = "Found invalid payload with OTP creating request"; log.error(msg); throw new BadRequestException(msg); } + DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance() + .getDeviceManagementConfig(); + KeyManagerConfigurations kmConfig = deviceManagementConfig.getKeyManagerConfigurations(); + String superTenantUsername = kmConfig.getAdminUsername(); + + if (!otpWrapper.getUsername().equals(superTenantUsername)) { + String msg = "You don't have required permission to create OTP"; + log.error(msg); + throw new UnAuthorizedException(msg); + } + Gson gson = new Gson(); - String metaInfo = gson.toJson(otpMailWrapper); + String metaInfo = gson.toJson(tenant); String otpValue = UUID.randomUUID().toString(); OTPMailDTO otpMailDTO = new OTPMailDTO(); - otpMailDTO.setEmail(otpMailWrapper.getEmail()); - otpMailDTO.setTenantId(otpMailDTO.getTenantId()); - otpMailDTO.setUsername(otpMailWrapper.getAdminUsername()); - otpMailDTO.setEmailType(otpMailWrapper.getEmailType()); + otpMailDTO.setEmail(otpWrapper.getEmail()); + otpMailDTO.setTenantId(-1234); + otpMailDTO.setUsername(otpWrapper.getUsername()); + otpMailDTO.setEmailType(otpWrapper.getEmailType()); otpMailDTO.setMetaInfo(metaInfo); otpMailDTO.setOtpToken(otpValue); @@ -84,8 +105,8 @@ public class OTPManagementServiceImpl implements OTPManagementService { log.error(msg); throw new OTPManagementException(msg); } + sendMail(tenant.getAdminFirstName(), otpValue, tenant.getEmail()); ConnectionManagerUtil.commitDBTransaction(); - return otpValue; } catch (TransactionManagementException e) { String msg = "Error occurred while disabling AutoCommit."; log.error(msg, e); @@ -117,10 +138,6 @@ public class OTPManagementServiceImpl implements OTPManagementService { log.warn("Token is expired. OTP: " + oneTimeToken); return null; } - if (otpMailDTO.isTenantCreated()) { - log.warn("Tenant is already created for the token. OTP: " + oneTimeToken); - return null; - } Calendar calendar = Calendar.getInstance(); Timestamp currentTimestamp = new Timestamp(calendar.getTime().getTime()); @@ -131,8 +148,8 @@ public class OTPManagementServiceImpl implements OTPManagementService { String renewedOTP = UUID.randomUUID().toString(); renewOTP(otpMailDTO, renewedOTP); Gson gson = new Gson(); - OTPMailWrapper otpMailWrapper = gson.fromJson(otpMailDTO.getMetaInfo(), OTPMailWrapper.class); - resendUserVerifyingMail(otpMailWrapper.getFirstName(), renewedOTP, otpMailDTO.getEmail()); + Tenant tenant = gson.fromJson(otpMailDTO.getMetaInfo(), Tenant.class); + sendMail(tenant.getAdminFirstName(), renewedOTP, otpMailDTO.getEmail()); return null; } return otpMailDTO; @@ -163,39 +180,63 @@ public class OTPManagementServiceImpl implements OTPManagementService { /** * Validate OTP token creating payload - * @param otpMailWrapper OTPMailWrapper + * @param otpWrapper OTP-Wrapper * @return true if its valid payload otherwise returns false */ - private boolean isValidOTPTokenCreatingRequest(OTPMailWrapper otpMailWrapper) { - if (StringUtils.isBlank(otpMailWrapper.getFirstName())) { - log.error("Received empty or blank first name field with OTP creating payload."); - return false; - } - if (StringUtils.isBlank(otpMailWrapper.getLastName())) { - log.error("Received empty or blank last name field with OTP creating payload."); - return false; - } - if (StringUtils.isBlank(otpMailWrapper.getAdminUsername())) { - log.error("Received empty or blank admin username field with OTP creating payload."); - return false; - } - if (StringUtils.isBlank(otpMailWrapper.getAdminPassword())) { - log.error("Received empty or blank admin password field with OTP creating payload."); - return false; + private Tenant validateOTPTokenCreatingRequest(OTPWrapper otpWrapper) { + + Tenant tenant = new Tenant(); + List properties = otpWrapper.getProperties(); + for (Metadata property : properties) { + switch (property.getMetaKey()) { + case OTPProperties.FIRST_NAME: + String firstName = property.getMetaValue(); + if (StringUtils.isBlank(firstName)) { + log.error("Received empty or blank first name field with OTP creating payload."); + return null; + } + tenant.setAdminFirstName(firstName); + break; + case OTPProperties.LAST_NAME: + String lastName = property.getMetaValue(); + if (StringUtils.isBlank(lastName)) { + log.error("Received empty or blank last name field with OTP creating payload."); + return null; + } + tenant.setAdminLastName(lastName); + break; + case OTPProperties.TENANT_ADMIN_USERNAME: + String username = property.getMetaValue(); + if (StringUtils.isBlank(username)) { + log.error("Received empty or blank admin username field with OTP creating payload."); + return null; + } + tenant.setAdminName(username); + break; + case OTPProperties.TENANT_ADMIN_PASSWORD: + String pwd = property.getMetaValue(); + if (StringUtils.isBlank(pwd)) { + log.error("Received empty or blank admin password field with OTP creating payload."); + return null; + } + tenant.setAdminPassword(pwd); + break; + default: + log.error("Received invalid key with OTP properties for creating OTP."); + return null; + } } - if (StringUtils.isBlank(otpMailWrapper.getEmail())) { + + if (StringUtils.isBlank(otpWrapper.getEmail())) { log.error("Received empty or blank email field with OTP creating payload."); - return false; + return null; } - if (StringUtils.isBlank(otpMailWrapper.getEmailType())) { + if (StringUtils.isBlank(otpWrapper.getEmailType())) { log.error("Received empty or blank email type field with OTP creating payload."); - return false; - } - if (otpMailWrapper.getTenantId() != -1234 && otpMailWrapper.getTenantId() < 1) { - log.error("Invalid tenant Id field with OTP creating payload."); - return false; + return null; } - return true; + tenant.setEmail(otpWrapper.getEmail()); + return tenant; } /** @@ -205,7 +246,7 @@ public class OTPManagementServiceImpl implements OTPManagementService { * @param mailAddress Mail Address of the User * @throws OTPManagementException if error occurred while resend the user verifying mail */ - private void resendUserVerifyingMail(String firstName, String renewedOTP, String mailAddress) + private void sendMail(String firstName, String renewedOTP, String mailAddress) throws OTPManagementException { Properties props = new Properties(); props.setProperty("first-name", firstName); @@ -216,8 +257,9 @@ public class OTPManagementServiceImpl implements OTPManagementService { DeviceManagementDataHolder.getInstance().getDeviceManagementProvider() .sendEnrolmentInvitation(DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE, metaInfo); } catch (DeviceManagementException e) { - e.printStackTrace(); - throw new OTPManagementException(e); + String msg = "Error occurred while inviting user to enrol their device"; + log.error(msg, e); + throw new OTPManagementException(msg, e); } catch (ConfigurationManagementException e) { throw new OTPManagementException(e); } diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql index 5ff3b1c08c..623bd6b374 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql @@ -584,7 +584,6 @@ CREATE TABLE IF NOT EXISTS DM_OTP_DATA ( CREATED_AT TIMESTAMP NOT NULL, EXPIRY_TIME INT NOT NULL DEFAULT 3600, IS_EXPIRED BOOLEAN DEFAULT false, - TENANT_CREATED BOOLEAN DEFAULT false, PRIMARY KEY (ID), CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE) ); diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql index 5c82436ff1..058bceb53b 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql @@ -626,7 +626,6 @@ CREATE TABLE DM_OTP_DATA ( CREATED_AT DATETIME2(0) NOT NULL, EXPIRY_TIME INT NOT NULL DEFAULT 3600, IS_EXPIRED BIT DEFAULT false, - TENANT_CREATED BOOLEAN DEFAULT false, PRIMARY KEY (ID), CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE) ); diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql index b2c64ebb3a..f1244dd87e 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql @@ -642,7 +642,6 @@ CREATE TABLE IF NOT EXISTS DM_OTP_DATA ( CREATED_AT TIMESTAMP NOT NULL, EXPIRY_TIME INT NOT NULL DEFAULT 3600, IS_EXPIRED BOOLEAN DEFAULT false, - TENANT_CREATED BOOLEAN DEFAULT false, PRIMARY KEY (ID), CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE) ); diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql index 16139722fb..325bb770b3 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql @@ -990,7 +990,6 @@ CREATE TABLE DM_OTP_DATA ( CREATED_AT TIMESTAMP(0) NOT NULL, EXPIRY_TIME NUMBER(10) DEFAULT 3600 NOT NULL, IS_EXPIRED CHAR(1) DEFAULT false, - TENANT_CREATED BOOLEAN DEFAULT false, PRIMARY KEY (ID), CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE) ); diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql index d5db624796..d695625575 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql @@ -631,7 +631,6 @@ CREATE TABLE IF NOT EXISTS DM_OTP_DATA ( CREATED_AT TIMESTAMP(0) NOT NULL, EXPIRY_TIME INT NOT NULL DEFAULT 3600, IS_EXPIRED BOOLEAN DEFAULT false, - TENANT_CREATED BOOLEAN DEFAULT false, PRIMARY KEY (ID), CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE) ); diff --git a/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml b/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml index cd376469ef..dfea5c07ac 100644 --- a/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml +++ b/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml @@ -29,7 +29,7 @@ CertificateAuth - org.wso2.carbon.webapp.authenticator.framework.authenticator.gitCertificateAuthenticator + org.wso2.carbon.webapp.authenticator.framework.authenticator.CertificateAuthenticator OTPAuth From 648cffaa172633ea6604f8ec0fa28a21c0979d19 Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Mon, 10 Aug 2020 13:23:28 +0530 Subject: [PATCH 14/33] Generalize OTP creation --- .../{OTPMailDTO.java => OneTimePinDTO.java} | 2 +- .../mgt/common/spi/OTPManagementService.java | 4 +- .../core/otp/mgt/dao/OTPManagementDAO.java | 10 +- .../dao/impl/GenericOTPManagementDAOImpl.java | 48 ++--- .../mgt/service/OTPManagementServiceImpl.java | 180 ++++++++++-------- .../OneTimeTokenAuthenticator.java | 4 +- 6 files changed, 138 insertions(+), 110 deletions(-) rename components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/{OTPMailDTO.java => OneTimePinDTO.java} (98%) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OTPMailDTO.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OneTimePinDTO.java similarity index 98% rename from components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OTPMailDTO.java rename to components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OneTimePinDTO.java index bd8698206c..11923947c1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OTPMailDTO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OneTimePinDTO.java @@ -19,7 +19,7 @@ package org.wso2.carbon.device.mgt.common.otp.mgt.dto; import java.sql.Timestamp; -public class OTPMailDTO { +public class OneTimePinDTO { int id; String otpToken; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java index 00e6ce3d93..2844be1f07 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java @@ -20,7 +20,7 @@ package org.wso2.carbon.device.mgt.common.spi; import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; -import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO; +import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OneTimePinDTO; import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPWrapper; public interface OTPManagementService { @@ -40,5 +40,5 @@ public interface OTPManagementService { * @throws OTPManagementException if error occurred whle verifying validity of the OPT * @throws BadRequestException if found an null value for OTP */ - OTPMailDTO isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException; + OneTimePinDTO isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java index 9a9ae3eefb..86eb5e4ccf 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java @@ -17,26 +17,26 @@ package org.wso2.carbon.device.mgt.core.otp.mgt.dao; -import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO; +import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OneTimePinDTO; import org.wso2.carbon.device.mgt.core.otp.mgt.exception.OTPManagementDAOException; public interface OTPManagementDAO { /** * Save OTP token data and tenant details of registering user - * @param otpMailDTO OTPMailDTO + * @param oneTimePinDTO OTPMailDTO * @return Primary key of the newly adding data raw * @throws OTPManagementDAOException if error occurred whule storing data */ - int addOTPData(OTPMailDTO otpMailDTO) throws OTPManagementDAOException; + int addOTPData(OneTimePinDTO oneTimePinDTO) throws OTPManagementDAOException; /** * Get OTP data for requesting One Time Token * @param oneTimeToken One Time Token - * @return {@link OTPMailDTO} + * @return {@link OneTimePinDTO} * @throws OTPManagementDAOException if error ocured while getting OTP data for requesting one time token */ - OTPMailDTO getOTPDataByToken (String oneTimeToken) throws OTPManagementDAOException; + OneTimePinDTO getOTPDataByToken (String oneTimeToken) throws OTPManagementDAOException; /** * Expire the OTP diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java index a923756c88..515b2fc727 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java @@ -20,7 +20,7 @@ package org.wso2.carbon.device.mgt.core.otp.mgt.dao.impl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException; -import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO; +import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OneTimePinDTO; import org.wso2.carbon.device.mgt.core.otp.mgt.dao.AbstractDAOImpl; import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAO; import org.wso2.carbon.device.mgt.core.otp.mgt.exception.OTPManagementDAOException; @@ -38,11 +38,11 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM private static final Log log = LogFactory.getLog(GenericOTPManagementDAOImpl.class); @Override - public int addOTPData(OTPMailDTO otpMailDTO) throws OTPManagementDAOException { + public int addOTPData(OneTimePinDTO oneTimePinDTO) throws OTPManagementDAOException { if (log.isDebugEnabled()) { log.debug("Request received in DAO Layer to create an OTP data entry"); log.debug("OTP Details : "); - log.debug("OTP key : " + otpMailDTO.getOtpToken() + " Email : " + otpMailDTO.getEmail()); + log.debug("OTP key : " + oneTimePinDTO.getOtpToken() + " Email : " + oneTimePinDTO.getEmail()); } String sql = "INSERT INTO DM_OTP_DATA " @@ -58,13 +58,13 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM Calendar calendar = Calendar.getInstance(); Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { - stmt.setString(1, otpMailDTO.getOtpToken()); - stmt.setString(2, otpMailDTO.getEmail()); - stmt.setString(3, otpMailDTO.getEmailType()); - stmt.setString(4, otpMailDTO.getMetaInfo()); + stmt.setString(1, oneTimePinDTO.getOtpToken()); + stmt.setString(2, oneTimePinDTO.getEmail()); + stmt.setString(3, oneTimePinDTO.getEmailType()); + stmt.setString(4, oneTimePinDTO.getMetaInfo()); stmt.setTimestamp(5, timestamp); - stmt.setInt(6, otpMailDTO.getTenantId()); - stmt.setString(7, otpMailDTO.getUsername()); + stmt.setInt(6, oneTimePinDTO.getTenantId()); + stmt.setString(7, oneTimePinDTO.getUsername()); stmt.executeUpdate(); try (ResultSet rs = stmt.getGeneratedKeys()) { if (rs.next()) { @@ -75,18 +75,18 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM } } catch (DBConnectionException e) { String msg = "Error occurred while obtaining the DB connection to create an opt entry for email " - + otpMailDTO.getEmail(); + + oneTimePinDTO.getEmail(); log.error(msg, e); throw new OTPManagementDAOException(msg, e); } catch (SQLException e) { - String msg = "Error occurred while executing SQL to create an otp entry for email " + otpMailDTO.getEmail(); + String msg = "Error occurred while executing SQL to create an otp entry for email " + oneTimePinDTO.getEmail(); log.error(msg, e); throw new OTPManagementDAOException(msg, e); } } @Override - public OTPMailDTO getOTPDataByToken (String oneTimeToken) throws OTPManagementDAOException { + public OneTimePinDTO getOTPDataByToken (String oneTimeToken) throws OTPManagementDAOException { if (log.isDebugEnabled()) { log.debug("Request received in DAO Layer to get an OTP data entry for OTP"); @@ -113,18 +113,18 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM try (ResultSet rs = stmt.executeQuery()) { if (rs.next()) { - OTPMailDTO otpMailDTO = new OTPMailDTO(); - otpMailDTO.setId(rs.getInt("ID")); - otpMailDTO.setOtpToken(rs.getString("OTP_TOKEN")); - otpMailDTO.setEmail(rs.getString("EMAIL")); - otpMailDTO.setEmailType(rs.getString("EMAIL_TYPE")); - otpMailDTO.setMetaInfo(rs.getString("META_INFO")); - otpMailDTO.setCreatedAt(rs.getTimestamp("CREATED_AT")); - otpMailDTO.setExpiryTime(rs.getInt("EXPIRY_TIME")); - otpMailDTO.setExpired(rs.getBoolean("IS_EXPIRED")); - otpMailDTO.setTenantId(rs.getInt("TENANT_ID")); - otpMailDTO.setUsername(rs.getString("USERNAME")); - return otpMailDTO; + OneTimePinDTO oneTimePinDTO = new OneTimePinDTO(); + oneTimePinDTO.setId(rs.getInt("ID")); + oneTimePinDTO.setOtpToken(rs.getString("OTP_TOKEN")); + oneTimePinDTO.setEmail(rs.getString("EMAIL")); + oneTimePinDTO.setEmailType(rs.getString("EMAIL_TYPE")); + oneTimePinDTO.setMetaInfo(rs.getString("META_INFO")); + oneTimePinDTO.setCreatedAt(rs.getTimestamp("CREATED_AT")); + oneTimePinDTO.setExpiryTime(rs.getInt("EXPIRY_TIME")); + oneTimePinDTO.setExpired(rs.getBoolean("IS_EXPIRED")); + oneTimePinDTO.setTenantId(rs.getInt("TENANT_ID")); + oneTimePinDTO.setUsername(rs.getString("USERNAME")); + return oneTimePinDTO; } return null; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java index de013ce4ae..68297a5554 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -28,7 +28,7 @@ import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException; import org.wso2.carbon.device.mgt.common.exceptions.UnAuthorizedException; import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata; -import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO; +import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OneTimePinDTO; import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; @@ -66,46 +66,21 @@ public class OTPManagementServiceImpl implements OTPManagementService { @Override public void sendUserVerifyingMail(OTPWrapper otpWrapper) throws OTPManagementException, DeviceManagementException { - - Tenant tenant = validateOTPTokenCreatingRequest(otpWrapper); - if (tenant == null){ - String msg = "Found invalid payload with OTP creating request"; - log.error(msg); - throw new BadRequestException(msg); - } - - DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance() - .getDeviceManagementConfig(); - KeyManagerConfigurations kmConfig = deviceManagementConfig.getKeyManagerConfigurations(); - String superTenantUsername = kmConfig.getAdminUsername(); - - if (!otpWrapper.getUsername().equals(superTenantUsername)) { - String msg = "You don't have required permission to create OTP"; - log.error(msg); - throw new UnAuthorizedException(msg); - } - - Gson gson = new Gson(); - String metaInfo = gson.toJson(tenant); - String otpValue = UUID.randomUUID().toString(); - - OTPMailDTO otpMailDTO = new OTPMailDTO(); - otpMailDTO.setEmail(otpWrapper.getEmail()); - otpMailDTO.setTenantId(-1234); - otpMailDTO.setUsername(otpWrapper.getUsername()); - otpMailDTO.setEmailType(otpWrapper.getEmailType()); - otpMailDTO.setMetaInfo(metaInfo); - otpMailDTO.setOtpToken(otpValue); - + Tenant tenant = validateTenantCreatingDetails(otpWrapper); + OneTimePinDTO oneTimePinDTO = createOneTimePin(otpWrapper.getEmail(), otpWrapper.getEmailType(), + otpWrapper.getUsername(), tenant, -1234); try { ConnectionManagerUtil.beginDBTransaction(); - if (this.otpManagementDAO.addOTPData(otpMailDTO) == -1) { + if (this.otpManagementDAO.addOTPData(oneTimePinDTO) == -1) { ConnectionManagerUtil.rollbackDBTransaction(); String msg = "OTP data saving failed. Please, contact Administrator"; log.error(msg); throw new OTPManagementException(msg); } - sendMail(tenant.getAdminFirstName(), otpValue, tenant.getEmail()); + Properties props = new Properties(); + props.setProperty("first-name", tenant.getAdminFirstName()); + props.setProperty("otp-token", oneTimePinDTO.getOtpToken()); + sendMail(props, tenant.getEmail()); ConnectionManagerUtil.commitDBTransaction(); } catch (TransactionManagementException e) { String msg = "Error occurred while disabling AutoCommit."; @@ -117,7 +92,7 @@ public class OTPManagementServiceImpl implements OTPManagementService { throw new OTPManagementException(msg, e); } catch (OTPManagementDAOException e) { ConnectionManagerUtil.rollbackDBTransaction(); - String msg = "Error occurred while saving the OTP data. Email address: " + otpMailDTO.getEmail(); + String msg = "Error occurred while saving the OTP data. Email address: " + oneTimePinDTO.getEmail(); log.error(msg, e); throw new OTPManagementException(msg, e); } finally { @@ -126,15 +101,15 @@ public class OTPManagementServiceImpl implements OTPManagementService { } @Override - public OTPMailDTO isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException { - OTPMailDTO otpMailDTO = getOTPDataByToken(oneTimeToken); - if (otpMailDTO == null) { + public OneTimePinDTO isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException { + OneTimePinDTO oneTimePinDTO = getOTPDataByToken(oneTimeToken); + if (oneTimePinDTO == null) { String msg = "Couldn't found OTP data for the requesting OTP " + oneTimeToken + " In the system."; log.error(msg); throw new BadRequestException(msg); } - if (otpMailDTO.isExpired()) { + if (oneTimePinDTO.isExpired()) { log.warn("Token is expired. OTP: " + oneTimeToken); return null; } @@ -142,26 +117,59 @@ public class OTPManagementServiceImpl implements OTPManagementService { Calendar calendar = Calendar.getInstance(); Timestamp currentTimestamp = new Timestamp(calendar.getTime().getTime()); Timestamp expiredTimestamp = new Timestamp( - otpMailDTO.getCreatedAt().getTime() + otpMailDTO.getExpiryTime() * 1000); + oneTimePinDTO.getCreatedAt().getTime() + oneTimePinDTO.getExpiryTime() * 1000); if (currentTimestamp.after(expiredTimestamp)) { String renewedOTP = UUID.randomUUID().toString(); - renewOTP(otpMailDTO, renewedOTP); + renewOTP(oneTimePinDTO, renewedOTP); Gson gson = new Gson(); - Tenant tenant = gson.fromJson(otpMailDTO.getMetaInfo(), Tenant.class); - sendMail(tenant.getAdminFirstName(), renewedOTP, otpMailDTO.getEmail()); + Tenant tenant = gson.fromJson(oneTimePinDTO.getMetaInfo(), Tenant.class); + + Properties props = new Properties(); + props.setProperty("first-name", tenant.getAdminFirstName()); + props.setProperty("otp-token", renewedOTP); + sendMail(props, oneTimePinDTO.getEmail()); return null; } - return otpMailDTO; + return oneTimePinDTO; + } + + + /** + * Create One Time Token + * @param email email + * @param emailType email type + * @param userName username + * @param metaDataObj meta data object + * @param tenantId tenant Id + * @return {@link OneTimePinDTO} + */ + private OneTimePinDTO createOneTimePin(String email, String emailType, String userName, Object metaDataObj, + int tenantId) { + + String otpValue = UUID.randomUUID().toString(); + + Gson gson = new Gson(); + String metaInfo = gson.toJson(metaDataObj); + + OneTimePinDTO oneTimePinDTO = new OneTimePinDTO(); + oneTimePinDTO.setEmail(email); + oneTimePinDTO.setTenantId(tenantId); + oneTimePinDTO.setUsername(userName); + oneTimePinDTO.setEmailType(emailType); + oneTimePinDTO.setMetaInfo(metaInfo); + oneTimePinDTO.setOtpToken(otpValue); + + return oneTimePinDTO; } /** * Get OTPData from DB * @param oneTimeToken One Time Token - * @return {@link OTPMailDTO} + * @return {@link OneTimePinDTO} * @throws OTPManagementException if error occurred while getting OTP data for given OTP in DB */ - private OTPMailDTO getOTPDataByToken ( String oneTimeToken) throws OTPManagementException { + private OneTimePinDTO getOTPDataByToken ( String oneTimeToken) throws OTPManagementException { try { ConnectionManagerUtil.openDBConnection(); return otpManagementDAO.getOTPDataByToken(oneTimeToken); @@ -179,61 +187,85 @@ public class OTPManagementServiceImpl implements OTPManagementService { } /** - * Validate OTP token creating payload + * Validate Tenant details * @param otpWrapper OTP-Wrapper - * @return true if its valid payload otherwise returns false + * @return {@link Tenant} if its valid payload otherwise throws {@link DeviceManagementException} + * @throws DeviceManagementException if invalid payload or unauthorized request received */ - private Tenant validateOTPTokenCreatingRequest(OTPWrapper otpWrapper) { + private Tenant validateTenantCreatingDetails(OTPWrapper otpWrapper) throws DeviceManagementException { + + DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance() + .getDeviceManagementConfig(); + KeyManagerConfigurations kmConfig = deviceManagementConfig.getKeyManagerConfigurations(); + String superTenantUsername = kmConfig.getAdminUsername(); + + if (!otpWrapper.getUsername().equals(superTenantUsername)) { + String msg = "You don't have required permission to create OTP"; + log.error(msg); + throw new UnAuthorizedException(msg); + } Tenant tenant = new Tenant(); List properties = otpWrapper.getProperties(); for (Metadata property : properties) { + if (property == null) { + String msg = "Received invalid property to create OTP."; + log.error(msg); + throw new BadRequestException(msg); + } switch (property.getMetaKey()) { case OTPProperties.FIRST_NAME: String firstName = property.getMetaValue(); if (StringUtils.isBlank(firstName)) { - log.error("Received empty or blank first name field with OTP creating payload."); - return null; + String msg = "Received empty or blank first name field with OTP creating payload."; + log.error(msg); + throw new BadRequestException(msg); } tenant.setAdminFirstName(firstName); break; case OTPProperties.LAST_NAME: String lastName = property.getMetaValue(); if (StringUtils.isBlank(lastName)) { - log.error("Received empty or blank last name field with OTP creating payload."); - return null; + String msg = "Received empty or blank last name field with OTP creating payload."; + log.error(msg); + throw new BadRequestException(msg); } tenant.setAdminLastName(lastName); break; case OTPProperties.TENANT_ADMIN_USERNAME: String username = property.getMetaValue(); if (StringUtils.isBlank(username)) { - log.error("Received empty or blank admin username field with OTP creating payload."); - return null; + String msg = "Received empty or blank admin username field with OTP creating payload."; + log.error(msg); + throw new BadRequestException(msg); } tenant.setAdminName(username); break; case OTPProperties.TENANT_ADMIN_PASSWORD: String pwd = property.getMetaValue(); if (StringUtils.isBlank(pwd)) { - log.error("Received empty or blank admin password field with OTP creating payload."); - return null; + String msg = "Received empty or blank admin password field with OTP creating payload."; + log.error(msg); + throw new BadRequestException(msg); } tenant.setAdminPassword(pwd); break; default: - log.error("Received invalid key with OTP properties for creating OTP."); - return null; + String msg = "Received invalid key with OTP properties for creating OTP."; + log.error(msg); + throw new BadRequestException(msg); } } if (StringUtils.isBlank(otpWrapper.getEmail())) { - log.error("Received empty or blank email field with OTP creating payload."); - return null; + String msg = "Received empty or blank email field with OTP creating payload."; + log.error(msg); + throw new BadRequestException(msg); } if (StringUtils.isBlank(otpWrapper.getEmailType())) { - log.error("Received empty or blank email type field with OTP creating payload."); - return null; + String msg = "Received empty or blank email type field with OTP creating payload."; + log.error(msg); + throw new BadRequestException(msg); } tenant.setEmail(otpWrapper.getEmail()); return tenant; @@ -241,19 +273,13 @@ public class OTPManagementServiceImpl implements OTPManagementService { /** * If OTP expired, resend the user verifying mail with renewed OTP - * @param firstName First Name of the User - * @param renewedOTP Renewed OTP + * @param props Mail body properties * @param mailAddress Mail Address of the User * @throws OTPManagementException if error occurred while resend the user verifying mail */ - private void sendMail(String firstName, String renewedOTP, String mailAddress) - throws OTPManagementException { - Properties props = new Properties(); - props.setProperty("first-name", firstName); - props.setProperty("otp-token", renewedOTP); - - EmailMetaInfo metaInfo = new EmailMetaInfo(mailAddress, props); + private void sendMail(Properties props, String mailAddress) throws OTPManagementException { try { + EmailMetaInfo metaInfo = new EmailMetaInfo(mailAddress, props); DeviceManagementDataHolder.getInstance().getDeviceManagementProvider() .sendEnrolmentInvitation(DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE, metaInfo); } catch (DeviceManagementException e) { @@ -261,20 +287,22 @@ public class OTPManagementServiceImpl implements OTPManagementService { log.error(msg, e); throw new OTPManagementException(msg, e); } catch (ConfigurationManagementException e) { - throw new OTPManagementException(e); + String msg = "Configuration error occurred. Hence mail sending failed."; + log.error(msg, e); + throw new OTPManagementException(msg, e); } } /** * Renew the OTP - * @param otpMailDTO {@link OTPMailDTO} + * @param oneTimePinDTO {@link OneTimePinDTO} * @param renewedOTP Renewed OTP * @throws OTPManagementException if error occurred while renew the OTP */ - private void renewOTP(OTPMailDTO otpMailDTO, String renewedOTP) throws OTPManagementException { + private void renewOTP(OneTimePinDTO oneTimePinDTO, String renewedOTP) throws OTPManagementException { try { ConnectionManagerUtil.beginDBTransaction(); - this.otpManagementDAO.renewOneTimeToken(otpMailDTO.getId(), renewedOTP); + this.otpManagementDAO.renewOneTimeToken(oneTimePinDTO.getId(), renewedOTP); ConnectionManagerUtil.commitDBTransaction(); } catch (TransactionManagementException e) { String msg = "Error occurred while disabling AutoCommit to renew the OTP."; diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java index c5e9d90824..472fb6d302 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java @@ -20,7 +20,7 @@ package org.wso2.carbon.webapp.authenticator.framework.authenticator; import org.apache.catalina.connector.Response; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO; +import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OneTimePinDTO; import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo; import org.wso2.carbon.webapp.authenticator.framework.Constants; @@ -49,7 +49,7 @@ public class OneTimeTokenAuthenticator implements WebappAuthenticator { try { OTPManagementService otpManagementService = AuthenticatorFrameworkDataHolder.getInstance() .getOtpManagementService(); - OTPMailDTO validOTP = otpManagementService.isValidOTP(request.getHeader(Constants.HTTPHeaders + OneTimePinDTO validOTP = otpManagementService.isValidOTP(request.getHeader(Constants.HTTPHeaders .ONE_TIME_TOKEN_HEADER)); if (validOTP != null) { authenticationInfo.setStatus(Status.CONTINUE); From 0a2836c59942a49b5d607ba639f114b488b040a6 Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Tue, 11 Aug 2020 13:32:17 +0530 Subject: [PATCH 15/33] Add OTP invoker --- .../interceptor/OTPInvokerHandler.java | 270 ++++++++++++++++++ .../interceptor/util/HandlerConstants.java | 2 + .../request/interceptor/util/HandlerUtil.java | 33 ++- 3 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/OTPInvokerHandler.java diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/OTPInvokerHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/OTPInvokerHandler.java new file mode 100644 index 0000000000..1378f5af4c --- /dev/null +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/OTPInvokerHandler.java @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2020, 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.ui.request.interceptor; + +import io.entgra.ui.request.interceptor.util.HandlerConstants; +import io.entgra.ui.request.interceptor.util.HandlerUtil; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpHeaders; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpHead; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.cookie.SM; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.InputStreamEntity; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.InputStreamBody; +import org.wso2.carbon.device.application.mgt.common.ProxyResponse; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Enumeration; +import java.util.List; + +@WebServlet( + name = "RequestHandlerServlet", + description = "This servlet intercepts the otp-api requests initiated from the user interface and validate " + + "before forwarding to the backend", + urlPatterns = { + "/otp-invoke/*" + } +) +public class OTPInvokerHandler extends HttpServlet { + private static final Log log = LogFactory.getLog(OTPInvokerHandler.class); + private static final long serialVersionUID = 3109569827313066220L; + private static String apiEndpoint; + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) { + try { + if (validateRequest(req, resp)) { + HttpPost postRequest = new HttpPost(HandlerUtil.generateBackendRequestURL(req, apiEndpoint)); + generateRequestEntity(req, postRequest); + ProxyResponse proxyResponse = HandlerUtil.execute(postRequest); + + if (proxyResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { + log.error("Error occurred while invoking the POST API endpoint."); + HandlerUtil.handleError(resp, proxyResponse); + return; + } + HandlerUtil.handleSuccess(resp, proxyResponse); + } + } catch (FileUploadException e) { + log.error("Error occurred when processing Multipart POST request.", e); + } catch (IOException e) { + log.error("Error occurred when processing POST request.", e); + } + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { + try { + if (validateRequest(req, resp)) { + HttpGet getRequest = new HttpGet(HandlerUtil.generateBackendRequestURL(req, apiEndpoint)); + copyRequestHeaders(req, getRequest, false); + ProxyResponse proxyResponse = HandlerUtil.execute(getRequest); + + if (proxyResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { + log.error("Error occurred while invoking the GET API endpoint."); + HandlerUtil.handleError(resp, proxyResponse); + return; + } + HandlerUtil.handleSuccess(resp, proxyResponse); + } + } catch (IOException e) { + log.error("Error occurred when processing GET request.", e); + } + } + + @Override + protected void doHead(HttpServletRequest req, HttpServletResponse resp) { + try { + if (validateRequest(req, resp)) { + HttpHead headRequest = new HttpHead(HandlerUtil.generateBackendRequestURL(req, apiEndpoint)); + copyRequestHeaders(req, headRequest, false); + ProxyResponse proxyResponse = HandlerUtil.execute(headRequest); + + if (proxyResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { + log.error("Error occurred while invoking the HEAD API endpoint."); + HandlerUtil.handleError(resp, proxyResponse); + return; + } + HandlerUtil.handleSuccess(resp, proxyResponse); + } + } catch (IOException e) { + log.error("Error occurred when processing HEAD request.", e); + } + } + + @Override + protected void doPut(HttpServletRequest req, HttpServletResponse resp) { + try { + if (validateRequest(req, resp)) { + HttpPut putRequest = new HttpPut(HandlerUtil.generateBackendRequestURL(req, apiEndpoint)); + generateRequestEntity(req, putRequest); + ProxyResponse proxyResponse = HandlerUtil.execute(putRequest); + + if (proxyResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { + log.error("Error occurred while invoking the PUT API endpoint."); + HandlerUtil.handleError(resp, proxyResponse); + return; + } + HandlerUtil.handleSuccess(resp, proxyResponse); + } + } catch (FileUploadException e) { + log.error("Error occurred when processing Multipart PUT request.", e); + } catch (IOException e) { + log.error("Error occurred when processing PUT request.", e); + } + } + + @Override + protected void doDelete(HttpServletRequest req, HttpServletResponse resp) { + try { + if (validateRequest(req, resp)) { + HttpDelete deleteRequest = new HttpDelete(HandlerUtil.generateBackendRequestURL(req, apiEndpoint)); + copyRequestHeaders(req, deleteRequest, false); + ProxyResponse proxyResponse = HandlerUtil.execute(deleteRequest); + + if (proxyResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { + log.error("Error occurred while invoking the DELETE API endpoint."); + HandlerUtil.handleError(resp, proxyResponse); + return; + } + HandlerUtil.handleSuccess(resp, proxyResponse); + } + } catch (IOException e) { + log.error("Error occurred when processing DELETE request.", e); + } + } + + /** + * Generate te request entity for POST and PUT requests from the incoming request. + * + * @param req incoming {@link HttpServletRequest}. + * @param proxyRequest proxy request instance. + * @throws FileUploadException If unable to parse the incoming request for multipart content extraction. + * @throws IOException If error occurred while generating the request body. + */ + private void generateRequestEntity(HttpServletRequest req, HttpEntityEnclosingRequestBase proxyRequest) + throws FileUploadException, IOException { + if (ServletFileUpload.isMultipartContent(req)) { + ServletFileUpload servletFileUpload = new ServletFileUpload(new DiskFileItemFactory()); + List fileItemList = servletFileUpload.parseRequest(req); + MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create(); + entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); + for (FileItem item: fileItemList) { + if (!item.isFormField()) { + entityBuilder.addPart(item.getFieldName(), new InputStreamBody(item.getInputStream(), + ContentType.create(item.getContentType()), item.getName())); + } else { + entityBuilder.addTextBody(item.getFieldName(), item.getString()); + } + } + proxyRequest.setEntity(entityBuilder.build()); + copyRequestHeaders(req, proxyRequest, false); + } else { + if (StringUtils.isNotEmpty(req.getHeader(HttpHeaders.CONTENT_LENGTH)) || + StringUtils.isNotEmpty(req.getHeader(HttpHeaders.TRANSFER_ENCODING))) { + InputStreamEntity entity = new InputStreamEntity(req.getInputStream(), + Long.parseLong(req.getHeader(HttpHeaders.CONTENT_LENGTH))); + proxyRequest.setEntity(entity); + } + copyRequestHeaders(req, proxyRequest, true); + } + } + + /** + * Copy incoming request headers to the proxy request. + * + * @param req incoming {@link HttpServletRequest} + * @param httpRequest proxy request instance. + * @param preserveContentType true if content type header needs to be preserved. + * This should be set to false when handling multipart requests as Http + * client will generate the Content-Type header automatically. + */ + private void copyRequestHeaders(HttpServletRequest req, HttpRequestBase httpRequest, boolean preserveContentType) { + Enumeration headerNames = req.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String headerName = headerNames.nextElement(); + if (headerName.equalsIgnoreCase(HttpHeaders.CONTENT_LENGTH) || + headerName.equalsIgnoreCase(SM.COOKIE) || + (!preserveContentType && headerName.equalsIgnoreCase(HttpHeaders.CONTENT_TYPE))) { + continue; + } + Enumeration headerValues = req.getHeaders(headerName); + while (headerValues.hasMoreElements()) { + httpRequest.setHeader(headerName, headerValues.nextElement()); + } + } + } + + /*** + * Validates the incoming request. + * + * @param req {@link HttpServletRequest} + * @param resp {@link HttpServletResponse} + * @return If request is a valid one, returns TRUE, otherwise return FALSE + * @throws IOException If and error occurs while witting error response to client side + */ + private static boolean validateRequest(HttpServletRequest req, HttpServletResponse resp) + throws IOException { + String schema = req.getScheme(); + apiEndpoint = schema + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.core.host") + + HandlerConstants.COLON + HandlerUtil.getCorePort(schema); + + if (StringUtils.isBlank(req.getHeader(HandlerConstants.OTP_HEADER))) { + log.error("Unauthorized, Please provide OTP token."); + handleError(resp, HttpStatus.SC_UNAUTHORIZED); + return false; + } + return true; + } + + /** + * Handle error requests + * + * @param resp {@link HttpServletResponse} + * @param errorCode HTTP error status code + * @throws IOException If error occurred when trying to send the error response. + */ + private static void handleError(HttpServletResponse resp, int errorCode) + throws IOException { + ProxyResponse proxyResponse = new ProxyResponse(); + proxyResponse.setCode(errorCode); + proxyResponse.setExecutorResponse( + HandlerConstants.EXECUTOR_EXCEPTION_PREFIX + HandlerUtil.getStatusKey(errorCode)); + HandlerUtil.handleError(resp, proxyResponse); + } +} diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java index a335f224c7..b691eaa315 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java @@ -47,4 +47,6 @@ public class HandlerConstants { public static final int INTERNAL_ERROR_CODE = 500; public static final long TIMEOUT = 1200; + + public static final String OTP_HEADER = "one-time-token"; } diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java index 82685daa43..592806f338 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java @@ -34,6 +34,7 @@ import org.json.JSONException; import org.json.JSONObject; import org.wso2.carbon.device.application.mgt.common.ProxyResponse; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; @@ -203,7 +204,7 @@ public class HandlerUtil { } /** - * Get gatway port according to request recieved scheme + * Get gateway port according to request received scheme * @param scheme https or https * @return {@link String} gateway port */ @@ -215,6 +216,19 @@ public class HandlerUtil { return gatewayPort; } + /** + * Get core port according to request received scheme + * @param scheme https or https + * @return {@link String} gateway port + */ + public static String getCorePort(String scheme) { + String productCorePort = System.getProperty("iot.core.https.port"); + if (HandlerConstants.HTTP_PROTOCOL.equals(scheme)) { + productCorePort = System.getProperty("iot.core.https.por"); + } + return productCorePort; + } + /** * Retrieve Http client based on hostname verification. * @return {@link CloseableHttpClient} http client @@ -242,4 +256,21 @@ public class HandlerUtil { HandlerConstants.EXECUTOR_EXCEPTION_PREFIX + HandlerUtil.getStatusKey(HttpStatus.SC_UNAUTHORIZED)); handleError(resp, proxyResponse); } + + /** + * Generates the target URL for the proxy request. + * + * @param req incoming {@link HttpServletRequest} + * @param apiEndpoint API Endpoint URL + * @return Target URL + */ + public static String generateBackendRequestURL(HttpServletRequest req, String apiEndpoint) { + StringBuilder urlBuilder = new StringBuilder(); + urlBuilder.append(apiEndpoint).append(HandlerConstants.API_COMMON_CONTEXT) + .append(req.getPathInfo().replace(" ", "%20")); + if (StringUtils.isNotEmpty(req.getQueryString())) { + urlBuilder.append("?").append(req.getQueryString()); + } + return urlBuilder.toString(); + } } From d8e234c6daf08fb436d552a8e8497f6c379a5d85 Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Tue, 11 Aug 2020 14:03:44 +0530 Subject: [PATCH 16/33] Change user verifying mail body --- .../src/main/resources/email/templates/user-verify.vm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm index ee0747c64d..7b0d617fc6 100644 --- a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm +++ b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm @@ -206,7 +206,7 @@ TkSuQmCC"

Congratulations!!! Thank you for registering with Entgra cloud. Please click and log in to the - following link to complete your registration with us. Click here. + following link to complete your registration with us. Click here.

From e2a143cde09694ef27c6b6b365c6e229bdb0db20 Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Wed, 12 Aug 2020 12:21:58 +0530 Subject: [PATCH 17/33] Improve user verifying mail sending logic --- .../org.wso2.carbon.device.mgt.core/pom.xml | 4 +++ .../mgt/service/OTPManagementServiceImpl.java | 31 +++++++++++++++++-- pom.xml | 10 +++++- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml b/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml index 4d1c23ba6c..347c710be6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml @@ -360,6 +360,10 @@ org.wso2.carbon.multitenancy org.wso2.carbon.tenant.mgt + + commons-validator + commons-validator + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java index 68297a5554..ee649baf1d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -20,6 +20,7 @@ import com.google.gson.Gson; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException; import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException; @@ -41,6 +42,7 @@ import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAOFactory; import org.wso2.carbon.device.mgt.core.otp.mgt.exception.OTPManagementDAOException; import org.wso2.carbon.device.mgt.core.otp.mgt.util.ConnectionManagerUtil; import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo; +import org.apache.commons.validator.routines.EmailValidator; import org.wso2.carbon.user.api.Tenant; import static org.wso2.carbon.device.mgt.common.DeviceManagementConstants.OTPProperties; @@ -102,13 +104,18 @@ public class OTPManagementServiceImpl implements OTPManagementService { @Override public OneTimePinDTO isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException { + if (StringUtils.isBlank(oneTimeToken)){ + String msg = "Received blank OTP to verify. OTP: " + oneTimeToken; + log.error(msg); + throw new BadRequestException(msg); + } + OneTimePinDTO oneTimePinDTO = getOTPDataByToken(oneTimeToken); if (oneTimePinDTO == null) { String msg = "Couldn't found OTP data for the requesting OTP " + oneTimeToken + " In the system."; log.error(msg); throw new BadRequestException(msg); } - if (oneTimePinDTO.isExpired()) { log.warn("Token is expired. OTP: " + oneTimeToken); return null; @@ -197,9 +204,17 @@ public class OTPManagementServiceImpl implements OTPManagementService { DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance() .getDeviceManagementConfig(); KeyManagerConfigurations kmConfig = deviceManagementConfig.getKeyManagerConfigurations(); - String superTenantUsername = kmConfig.getAdminUsername(); - if (!otpWrapper.getUsername().equals(superTenantUsername)) { + if (StringUtils.isBlank(otpWrapper.getUsername())) { + String msg = "Received Blank username to create OTP. Username: " + otpWrapper.getUsername(); + log.error(msg); + throw new BadRequestException(msg); + } + + String[] superTenantDetails = otpWrapper.getUsername().split("@"); + + if (MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(superTenantDetails[1]) || !superTenantDetails[0] + .equals(kmConfig.getAdminUsername())) { String msg = "You don't have required permission to create OTP"; log.error(msg); throw new UnAuthorizedException(msg); @@ -262,11 +277,21 @@ public class OTPManagementServiceImpl implements OTPManagementService { log.error(msg); throw new BadRequestException(msg); } + + EmailValidator validator = EmailValidator.getInstance(); + if (!validator.isValid(otpWrapper.getEmail())) { + String msg = "Found invalid email. Hence please verify the email address and re-try. Email: " + otpWrapper + .getEmail(); + log.error(msg); + throw new BadRequestException(msg); + } + if (StringUtils.isBlank(otpWrapper.getEmailType())) { String msg = "Received empty or blank email type field with OTP creating payload."; log.error(msg); throw new BadRequestException(msg); } + tenant.setDomain(otpWrapper.getEmail().split("@")[1]); tenant.setEmail(otpWrapper.getEmail()); return tenant; } diff --git a/pom.xml b/pom.xml index d522b61dab..d12b76d9f4 100644 --- a/pom.xml +++ b/pom.xml @@ -1772,6 +1772,11 @@ maven-checkstyle-plugin ${maven.checkstyle.vesion} + + commons-validator + commons-validator + ${apache.validator.version} + @@ -2219,6 +2224,9 @@ 2.3.2 + + 1.7 + 2.1.7-wso2v7 1.5.11.wso2v15 @@ -2252,7 +2260,7 @@ v12.18.1 3.1.0 - + 7.0.85 1.0 From 86912915fd2a26b6c5a3aa74e0661b3b67acdc09 Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Wed, 12 Aug 2020 20:17:17 +0530 Subject: [PATCH 18/33] Fix user verifying functionality in OTP --- .../mgt/core/otp/mgt/service/OTPManagementServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java index ee649baf1d..1ec1bb3dce 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -213,8 +213,8 @@ public class OTPManagementServiceImpl implements OTPManagementService { String[] superTenantDetails = otpWrapper.getUsername().split("@"); - if (MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(superTenantDetails[1]) || !superTenantDetails[0] - .equals(kmConfig.getAdminUsername())) { + if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(superTenantDetails[superTenantDetails.length - 1]) + || !superTenantDetails[0].equals(kmConfig.getAdminUsername())) { String msg = "You don't have required permission to create OTP"; log.error(msg); throw new UnAuthorizedException(msg); From a3510cbee12e92d615add10a291edb870149c368 Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Thu, 13 Aug 2020 12:15:06 +0530 Subject: [PATCH 19/33] Add email enum --- .../mgt/common/otp/mgt/OTPEmailTypes.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/OTPEmailTypes.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/OTPEmailTypes.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/OTPEmailTypes.java new file mode 100644 index 0000000000..c4f7ef0689 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/OTPEmailTypes.java @@ -0,0 +1,22 @@ +/* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.common.otp.mgt; + +public enum OTPEmailTypes { + USER_VERIFY, ENROLLMENT +} From a55a3b6ebd2936726c0752164c46b3224dd1129d Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Thu, 13 Aug 2020 23:46:53 +0530 Subject: [PATCH 20/33] Improve OTP service --- .../mgt/common/spi/OTPManagementService.java | 7 + .../core/otp/mgt/dao/OTPManagementDAO.java | 10 +- .../dao/impl/GenericOTPManagementDAOImpl.java | 46 ++++- .../mgt/service/OTPManagementServiceImpl.java | 63 +++++-- .../resources/email/templates/user-verify.vm | 171 +----------------- 5 files changed, 110 insertions(+), 187 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java index 2844be1f07..31948772e2 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java @@ -41,4 +41,11 @@ public interface OTPManagementService { * @throws BadRequestException if found an null value for OTP */ OneTimePinDTO isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException; + + /** + * Invalidate the OTP + * @param oneTimeToken OTP + * @throws OTPManagementException If error occurred while invalidating the OTP + */ + void invalidateOTP(String oneTimeToken) throws OTPManagementException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java index 86eb5e4ccf..4c3690f5d0 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java @@ -43,7 +43,7 @@ public interface OTPManagementDAO { * @param oneTimeToken OTP * @throws OTPManagementDAOException if error occurred while updating the OTP validity. */ - void expireOneTimeToken(String oneTimeToken) throws OTPManagementDAOException; + boolean expireOneTimeToken(String oneTimeToken) throws OTPManagementDAOException; /** * Update OTP with renewed OTP @@ -53,4 +53,12 @@ public interface OTPManagementDAO { */ void renewOneTimeToken(int id, String oneTimeToken) throws OTPManagementDAOException; + /** + * To veify whether email and email type exists or not + * @param email email + * @param emailType email type + * @return true if email and email type exists otherwise returns false + * @throws OTPManagementDAOException if error occurred while verify existance of the email and email type + */ + boolean isEmailExist (String email, String emailType) throws OTPManagementDAOException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java index 515b2fc727..273cf6c1a5 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java @@ -142,7 +142,7 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM } @Override - public void expireOneTimeToken(String oneTimeToken) throws OTPManagementDAOException { + public boolean expireOneTimeToken(String oneTimeToken) throws OTPManagementDAOException { if (log.isDebugEnabled()) { log.debug("Request received in DAO Layer to update an OTP data entry for OTP"); log.debug("OTP Details : OTP key : " + oneTimeToken ); @@ -158,7 +158,7 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM try (PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setBoolean(1, true); stmt.setString(2, oneTimeToken); - stmt.executeUpdate(); + return stmt.executeUpdate() == 1; } } catch (DBConnectionException e) { String msg = "Error occurred while obtaining the DB connection to update the OTP token validity."; @@ -180,7 +180,7 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM String sql = "UPDATE DM_OTP_DATA " + "SET " - + "OTP_TOKEN = ? " + + "OTP_TOKEN = ?, " + "CREATED_AT = ? " + "WHERE ID = ?"; @@ -195,11 +195,47 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM stmt.executeUpdate(); } } catch (DBConnectionException e) { - String msg = "Error occurred while obtaining the DB connection to update the OTP token validity."; + String msg = "Error occurred while obtaining the DB connection to update the OTP token."; log.error(msg, e); throw new OTPManagementDAOException(msg, e); } catch (SQLException e) { - String msg = "Error occurred when obtaining database connection for updating the OTP token validity."; + String msg = "Error occurred when executing sql query to update the OTP token."; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } + } + + @Override + public boolean isEmailExist (String email, String emailType) throws OTPManagementDAOException { + + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to verify whether email was registed with emai type in OTP"); + log.debug("OTP Details : email : " + email + " email type: " + emailType ); + } + + String sql = "SELECT " + + "ID " + + "FROM DM_OTP_DATA " + + "WHERE EMAIL = ? AND " + + "EMAIL_TYPE = ?"; + + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, email); + stmt.setString(2, emailType); + try (ResultSet rs = stmt.executeQuery()) { + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to verify email and email type exist in OTP." + + " Email: " + email + "Email Type: " + emailType; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to verify email and email type exist in OTP. Email: " + + email + "Email Type: " + emailType; log.error(msg, e); throw new OTPManagementDAOException(msg, e); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java index 1ec1bb3dce..b326f141cc 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -141,6 +141,35 @@ public class OTPManagementServiceImpl implements OTPManagementService { return oneTimePinDTO; } + @Override + public void invalidateOTP(String oneTimeToken) throws OTPManagementException { + try { + ConnectionManagerUtil.beginDBTransaction(); + if (!otpManagementDAO.expireOneTimeToken(oneTimeToken)) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Couldn't find OTP entry for OTP: " + oneTimeToken; + log.error(msg); + throw new OTPManagementException(msg); + } + ConnectionManagerUtil.commitDBTransaction(); + } catch (OTPManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while invalidate the OTP: " + oneTimeToken; + log.error(msg); + throw new OTPManagementException(msg); + } catch (TransactionManagementException e) { + String msg = "Error occurred while disabling AutoCommit to invalidate OTP."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection to invalidate OPT."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + /** * Create One Time Token @@ -212,7 +241,6 @@ public class OTPManagementServiceImpl implements OTPManagementService { } String[] superTenantDetails = otpWrapper.getUsername().split("@"); - if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(superTenantDetails[superTenantDetails.length - 1]) || !superTenantDetails[0].equals(kmConfig.getAdminUsername())) { String msg = "You don't have required permission to create OTP"; @@ -247,15 +275,6 @@ public class OTPManagementServiceImpl implements OTPManagementService { } tenant.setAdminLastName(lastName); break; - case OTPProperties.TENANT_ADMIN_USERNAME: - String username = property.getMetaValue(); - if (StringUtils.isBlank(username)) { - String msg = "Received empty or blank admin username field with OTP creating payload."; - log.error(msg); - throw new BadRequestException(msg); - } - tenant.setAdminName(username); - break; case OTPProperties.TENANT_ADMIN_PASSWORD: String pwd = property.getMetaValue(); if (StringUtils.isBlank(pwd)) { @@ -291,7 +310,29 @@ public class OTPManagementServiceImpl implements OTPManagementService { log.error(msg); throw new BadRequestException(msg); } - tenant.setDomain(otpWrapper.getEmail().split("@")[1]); + + try { + ConnectionManagerUtil.openDBConnection(); + if (otpManagementDAO.isEmailExist(otpWrapper.getEmail(), otpWrapper.getEmailType())) { + String msg = "Email is registered to execute the same action. Hence can't proceed."; + log.error(msg); + throw new BadRequestException(msg); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection to validate the given email and email type."; + log.error(msg); + throw new DeviceManagementException(msg); + } catch (OTPManagementDAOException e) { + String msg = "Error occurred while executing SQL query to validate the given email and email type."; + log.error(msg); + throw new DeviceManagementException(msg); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + + String[] tenantUsernameDetails = otpWrapper.getEmail().split("@"); + tenant.setAdminName(tenantUsernameDetails[0]); + tenant.setDomain(tenantUsernameDetails[tenantUsernameDetails.length - 1]); tenant.setEmail(otpWrapper.getEmail()); return tenant; } diff --git a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm index 7b0d617fc6..18e3a66a01 100644 --- a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm +++ b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm @@ -28,176 +28,7 @@

- entgra.io + entgra
From ea6b8c753681ae3626f7913b4ddd5f4abf094b36 Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Mon, 17 Aug 2020 01:03:55 +0530 Subject: [PATCH 21/33] Fix invoker loading issue --- .../src/main/webapp/WEB-INF/web.xml | 5 ++--- .../io/entgra/ui/request/interceptor/OTPInvokerHandler.java | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml index 3b97a83bbc..aafbcec0e0 100644 --- a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml @@ -49,8 +49,7 @@ nonSecuredEndPoints /api/device-mgt-config/v1.0/configurations, - /api/device-mgt-config/v1.0/configurations/ui-config, - /api/device-mgt-config/v1.0/tenant + /api/device-mgt-config/v1.0/configurations/ui-config @@ -125,4 +124,4 @@ /* - \ No newline at end of file + diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/OTPInvokerHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/OTPInvokerHandler.java index 1378f5af4c..624814f327 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/OTPInvokerHandler.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/OTPInvokerHandler.java @@ -53,7 +53,7 @@ import java.util.Enumeration; import java.util.List; @WebServlet( - name = "RequestHandlerServlet", + name = "OTPRequestHandlerServlet", description = "This servlet intercepts the otp-api requests initiated from the user interface and validate " + "before forwarding to the backend", urlPatterns = { From 58217ac77a35820f9d544755ad3729f605cd35c8 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Wed, 12 Aug 2020 18:22:59 +0530 Subject: [PATCH 22/33] Implement service to create OTP and to send device enrollment invitation --- .../mgt/common/spi/OTPManagementService.java | 9 +++ .../mgt/core/DeviceManagementConstants.java | 3 + .../mgt/service/OTPManagementServiceImpl.java | 59 +++++++++++++++++-- 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java index 31948772e2..8ecb4de4fd 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java @@ -20,6 +20,7 @@ package org.wso2.carbon.device.mgt.common.spi; import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitation; import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OneTimePinDTO; import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPWrapper; @@ -48,4 +49,12 @@ public interface OTPManagementService { * @throws OTPManagementException If error occurred while invalidating the OTP */ void invalidateOTP(String oneTimeToken) throws OTPManagementException; + + /** + * Create OTP token and send device enrollment invitation + * @param deviceEnrollmentInvitation object which contains device enrollment invitation related details + * @throws OTPManagementException if error occurred while creating OTP token &/ sending mail + */ + void sendDeviceEnrollmentInvitationMail(DeviceEnrollmentInvitation deviceEnrollmentInvitation) + throws OTPManagementException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java index 21b19b7a83..afa9dfd767 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java @@ -143,6 +143,9 @@ public final class DeviceManagementConstants { public static final String DEFAULT_DEVICE_USER = "Internal/devicemgt-user"; public static final String DEFAULT_DEVICE_ADMIN = "Internal/devicemgt-admin"; + public static final String CLAIM_EMAIL_ADDRESS = "http://wso2.org/claims/emailaddress"; + public static final String CLAIM_FIRST_NAME = "http://wso2.org/claims/givenname"; + // Permissions that are given for a normal device user. public static final Permission[] PERMISSIONS_FOR_DEVICE_USER = { new Permission("/permission/admin/Login", "ui.execute"), diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java index b326f141cc..8be27f0ec2 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -21,6 +21,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException; import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException; @@ -28,6 +29,9 @@ import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException; import org.wso2.carbon.device.mgt.common.exceptions.UnAuthorizedException; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitation; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentType; import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata; import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OneTimePinDTO; import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; @@ -41,9 +45,12 @@ import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPWrapper; import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAOFactory; import org.wso2.carbon.device.mgt.core.otp.mgt.exception.OTPManagementDAOException; import org.wso2.carbon.device.mgt.core.otp.mgt.util.ConnectionManagerUtil; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo; import org.apache.commons.validator.routines.EmailValidator; +import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; import org.wso2.carbon.user.api.Tenant; +import org.wso2.carbon.user.api.UserStoreException; import static org.wso2.carbon.device.mgt.common.DeviceManagementConstants.OTPProperties; @@ -82,7 +89,7 @@ public class OTPManagementServiceImpl implements OTPManagementService { Properties props = new Properties(); props.setProperty("first-name", tenant.getAdminFirstName()); props.setProperty("otp-token", oneTimePinDTO.getOtpToken()); - sendMail(props, tenant.getEmail()); + sendMail(props, tenant.getEmail(), DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE); ConnectionManagerUtil.commitDBTransaction(); } catch (TransactionManagementException e) { String msg = "Error occurred while disabling AutoCommit."; @@ -135,7 +142,7 @@ public class OTPManagementServiceImpl implements OTPManagementService { Properties props = new Properties(); props.setProperty("first-name", tenant.getAdminFirstName()); props.setProperty("otp-token", renewedOTP); - sendMail(props, oneTimePinDTO.getEmail()); + sendMail(props, oneTimePinDTO.getEmail(), DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE); return null; } return oneTimePinDTO; @@ -171,6 +178,47 @@ public class OTPManagementServiceImpl implements OTPManagementService { } + @Override + public void sendDeviceEnrollmentInvitationMail(DeviceEnrollmentInvitation deviceEnrollmentInvitation) + throws OTPManagementException { + DeviceManagementProviderService dms = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider(); + StringBuilder enrollmentSteps = new StringBuilder(); + DeviceEnrollmentInvitationDetails deviceEnrollmentInvitationDetails; + for (DeviceEnrollmentType deviceEnrollmentType : deviceEnrollmentInvitation.getDeviceEnrollmentTypes()) { + deviceEnrollmentInvitationDetails = dms.getDeviceEnrollmentInvitationDetails( + deviceEnrollmentType.getDeviceType()); + if (deviceEnrollmentInvitationDetails != null && + deviceEnrollmentInvitationDetails.getEnrollmentDetails() != null) { + for (String enrollmentType : deviceEnrollmentType.getEnrollmentType()) { + deviceEnrollmentInvitationDetails.getEnrollmentDetails().stream() + .filter(details -> enrollmentType.equals(details.getEnrollmentType())).findFirst() + .ifPresent(details -> enrollmentSteps.append(details.getEnrollmentSteps())); + } + } + } + int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); + OneTimePinDTO oneTimePinDTO; + Properties props = new Properties(); + props.setProperty("enrollment-steps", enrollmentSteps.toString()); + try { + for (String username : deviceEnrollmentInvitation.getUsernames()) { + String emailAddress = DeviceManagerUtil.getUserClaimValue( + username, DeviceManagementConstants.User.CLAIM_EMAIL_ADDRESS); + oneTimePinDTO = createOneTimePin(emailAddress, "test-type", username, null, tenantId); + 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); + } + } catch (UserStoreException e) { + String msg = "Error occurred while getting claim values to invite user"; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } + } + + /** * Create One Time Token * @param email email @@ -341,15 +389,16 @@ public class OTPManagementServiceImpl implements OTPManagementService { * If OTP expired, resend the user verifying mail with renewed OTP * @param props Mail body properties * @param mailAddress Mail Address of the User + * @param template Mail template to be used * @throws OTPManagementException if error occurred while resend the user verifying mail */ - private void sendMail(Properties props, String mailAddress) throws OTPManagementException { + private void sendMail(Properties props, String mailAddress, String template) throws OTPManagementException { try { EmailMetaInfo metaInfo = new EmailMetaInfo(mailAddress, props); DeviceManagementDataHolder.getInstance().getDeviceManagementProvider() - .sendEnrolmentInvitation(DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE, metaInfo); + .sendEnrolmentInvitation(template, metaInfo); } catch (DeviceManagementException e) { - String msg = "Error occurred while inviting user to enrol their device"; + String msg = "Error occurred while sending email using email template '" + template + "'."; log.error(msg, e); throw new OTPManagementException(msg, e); } catch (ConfigurationManagementException e) { From d97de23ece9c757210e4072b7e0dd05cb8014477 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Wed, 12 Aug 2020 18:25:26 +0530 Subject: [PATCH 23/33] Modify send-invitation API to send enrollment steps and OTP token --- .../service/api/UserManagementService.java | 5 +- .../impl/UserManagementServiceImpl.java | 50 +++++++------------ .../mgt/jaxrs/util/DeviceMgtAPIUtils.java | 41 +++++++++++++++ .../mgt/core/util/DeviceManagerUtil.java | 31 ++++++++++++ 4 files changed, 92 insertions(+), 35 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java index 432b752a66..5e580f6a06 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java @@ -49,6 +49,7 @@ import io.swagger.annotations.ResponseHeader; import org.apache.axis2.transport.http.HTTPConstants; import org.wso2.carbon.apimgt.annotations.api.Scopes; import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitation; import org.wso2.carbon.device.mgt.jaxrs.beans.ActivityList; import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfo; import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfoList; @@ -74,7 +75,6 @@ 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; @SwaggerDefinition( info = @Info( @@ -893,7 +893,8 @@ public interface UserManagementService { @ApiParam( name = "users", value = "List of users", - required = true) List usernames); + required = true) + @Valid DeviceEnrollmentInvitation deviceEnrollmentInvitation); @POST @Path("/enrollment-invite") diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java index 81233092f3..6f240093ec 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java @@ -45,8 +45,11 @@ import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitation; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo; @@ -716,48 +719,29 @@ public class UserManagementServiceImpl implements UserManagementService { return CredentialManagementResponseBuilder.buildChangePasswordResponse(credentials); } - /** - * Method used to send an invitation email to a existing user to enroll a device. - * - * @param usernames Username list of the users to be invited - */ + @POST @Path("/send-invitation") @Produces({MediaType.APPLICATION_JSON}) - public Response inviteExistingUsersToEnrollDevice(List usernames) { + public Response inviteExistingUsersToEnrollDevice(DeviceEnrollmentInvitation deviceEnrollmentInvitation) { + if (deviceEnrollmentInvitation.getUsernames() == null || deviceEnrollmentInvitation.getUsernames().isEmpty()) { + String msg = "Error occurred while validating list of user-names. User-names cannot be empty."; + log.error(msg); + throw new BadRequestException( + new ErrorResponse.ErrorResponseBuilder().setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg) + .build()); + } if (log.isDebugEnabled()) { - log.debug("Sending enrollment invitation mail to existing user."); + log.debug("Sending device enrollment invitation mail to existing user/s."); } - DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + OTPManagementService oms = DeviceMgtAPIUtils.getOTPManagementService(); try { - for (String username : usernames) { - String recipient = getClaimValue(username, Constants.USER_CLAIM_EMAIL_ADDRESS); - - Properties props = new Properties(); - props.setProperty("first-name", getClaimValue(username, Constants.USER_CLAIM_FIRST_NAME)); - props.setProperty("username", username); - - EmailMetaInfo metaInfo = new EmailMetaInfo(recipient, props); - dms.sendEnrolmentInvitation(DeviceManagementConstants.EmailAttributes.USER_ENROLLMENT_TEMPLATE, - metaInfo); - } - } catch (DeviceManagementException e) { - String msg = "Error occurred while inviting user to enrol their device"; - if (e.getMessage() != null && !e.getMessage().isEmpty()) { - msg = e.getMessage(); - } + oms.sendDeviceEnrollmentInvitationMail(deviceEnrollmentInvitation); + } catch (OTPManagementException e) { + String msg = "Error occurred while generating OTP and inviting user/s to enroll their device/s."; log.error(msg, e); return Response.serverError().entity( new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); - } catch (UserStoreException e) { - String msg = "Error occurred while getting claim values to invite user"; - log.error(msg, e); - return Response.serverError().entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); - } catch (ConfigurationManagementException e) { - String msg = "Error occurred while sending the email invitations. Mail server not configured."; - return Response.serverError().entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); } return Response.status(Response.Status.OK).entity("Invitation mails have been sent.").build(); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java index 91161ced0d..e3a166dc2b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java @@ -14,6 +14,23 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ package org.wso2.carbon.device.mgt.jaxrs.util; @@ -142,6 +159,7 @@ public class DeviceMgtAPIUtils { private static IntegrationClientService integrationClientService; private static MetadataManagementService metadataManagementService; + private static OTPManagementService otpManagementService; static { String keyStorePassword = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Password"); @@ -338,6 +356,29 @@ public class DeviceMgtAPIUtils { return integrationClientService; } + /** + * Initializing and accessing method for OTPManagementService. + * + * @return OTPManagementService instance + * @throws IllegalStateException if OTPManagementService cannot be initialized + */ + public static synchronized OTPManagementService getOTPManagementService() { + if (otpManagementService == null) { + synchronized (DeviceMgtAPIUtils.class) { + 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 RegistryService getRegistryService() { RegistryService registryService; PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java index cb5d305aef..9404e5de86 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java @@ -14,6 +14,23 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ package org.wso2.carbon.device.mgt.core.util; @@ -79,6 +96,7 @@ import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerSer import org.wso2.carbon.user.api.TenantManager; 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.utils.CarbonUtils; import org.wso2.carbon.utils.ConfigurationContextService; import org.wso2.carbon.utils.NetworkUtils; @@ -1047,4 +1065,17 @@ public final class DeviceManagerUtil { } return roleList; } + + /** + * Retrieve the value of the user property from the user profile + * @param username of the user + * @param claimUri name of the claim + * @return value for the claim uri of user + * @throws UserStoreException when there is error in retrieving the user store manager + */ + public static String getUserClaimValue(String username, String claimUri) throws UserStoreException { + UserStoreManager userStoreManager = CarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getUserStoreManager(); + return userStoreManager.getUserClaimValue(username, claimUri, null); + } } From d2ab4c67100b3425b52377b95599ad0b88102d3d Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Wed, 12 Aug 2020 18:30:06 +0530 Subject: [PATCH 24/33] Implement retrieval of DeviceEnrollmentInvitationDetails from device type xml files --- .../DeviceEnrollmentInvitationDetails.java | 25 +++++++++++++ .../invitation/mgt/EnrollmentDetails.java | 36 +++++++++++++++++++ .../common/spi/DeviceManagementService.java | 3 ++ .../template/DeviceTypeManagerService.java | 18 ++++++++++ .../config/DeviceTypeConfiguration.java | 20 +++++++++++ 5 files changed, 102 insertions(+) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentInvitationDetails.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/EnrollmentDetails.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentInvitationDetails.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentInvitationDetails.java new file mode 100644 index 0000000000..3882d47293 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentInvitationDetails.java @@ -0,0 +1,25 @@ +package org.wso2.carbon.device.mgt.common.invitation.mgt; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.util.List; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "DeviceEnrollmentInvitationDetails", propOrder = { + "enrollmentDetails" +}) +public class DeviceEnrollmentInvitationDetails { + + @XmlElement(name = "EnrollmentDetails") + private List enrollmentDetails; + + public List getEnrollmentDetails() { + return enrollmentDetails; + } + + public void setEnrollmentDetails(List enrollmentDetails) { + this.enrollmentDetails = enrollmentDetails; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/EnrollmentDetails.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/EnrollmentDetails.java new file mode 100644 index 0000000000..905022440b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/EnrollmentDetails.java @@ -0,0 +1,36 @@ +package org.wso2.carbon.device.mgt.common.invitation.mgt; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "EnrollmentDetails", propOrder = { + "enrollmentType", + "enrollmentSteps" +}) +public class EnrollmentDetails { + + @XmlElement(name = "EnrollmentType") + private String enrollmentType; + + @XmlElement(name = "EnrollmentSteps") + private String enrollmentSteps; + + public String getEnrollmentType() { + return enrollmentType; + } + + public void setEnrollmentType(String enrollmentType) { + this.enrollmentType = enrollmentType; + } + + public String getEnrollmentSteps() { + return enrollmentSteps; + } + + public void setEnrollmentSteps(String enrollmentSteps) { + this.enrollmentSteps = enrollmentSteps; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/DeviceManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/DeviceManagementService.java index 25303cf966..e6f33f85de 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/DeviceManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/DeviceManagementService.java @@ -38,6 +38,7 @@ import org.wso2.carbon.device.mgt.common.*; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.general.GeneralConfig; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager; import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber; import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig; @@ -77,4 +78,6 @@ public interface DeviceManagementService { DeviceTypePlatformDetails getDeviceTypePlatformDetails(); + DeviceEnrollmentInvitationDetails getDeviceEnrollmentInvitationDetails(); + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManagerService.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManagerService.java index 67b79bfeb4..5896039d99 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManagerService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManagerService.java @@ -48,6 +48,7 @@ import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; import org.wso2.carbon.device.mgt.common.general.GeneralConfig; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager; import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber; import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig; @@ -92,6 +93,7 @@ public class DeviceTypeManagerService implements DeviceManagementService { private PullNotificationSubscriber pullNotificationSubscriber; private final DeviceStatusTaskPluginConfig deviceStatusTaskPluginConfig; private DeviceTypePlatformDetails deviceTypePlatformDetails; + private DeviceEnrollmentInvitationDetails deviceEnrollmentInvitationDetails; private GeneralConfig generalConfig; private boolean isRegistryBasedConfigs = false; private boolean isScheduled = false; @@ -116,6 +118,8 @@ public class DeviceTypeManagerService implements DeviceManagementService { this.setPolicyMonitoringManager(deviceTypeConfiguration.getPolicyMonitoring()); this.setPullNotificationSubscriber(deviceTypeConfiguration.getPullNotificationSubscriberConfig()); this.setGeneralConfig(deviceTypeConfiguration); + this.deviceEnrollmentInvitationDetails = new DeviceEnrollmentInvitationDetails(); + this.setDeviceEnrollmentInvitationDetails(deviceTypeConfiguration); } @Override @@ -259,6 +263,11 @@ public class DeviceTypeManagerService implements DeviceManagementService { return generalConfig; } + @Override + public DeviceEnrollmentInvitationDetails getDeviceEnrollmentInvitationDetails() { + return deviceEnrollmentInvitationDetails; + } + private void setProvisioningConfig(String tenantDomain, DeviceTypeConfiguration deviceTypeConfiguration) { if (deviceTypeConfiguration.getProvisioningConfig() != null) { boolean sharedWithAllTenants = deviceTypeConfiguration.getProvisioningConfig().isSharedWithAllTenants(); @@ -354,4 +363,13 @@ public class DeviceTypeManagerService implements DeviceManagementService { deviceTypePlatformDetails.setDeviceTypePlatformVersion(deviceTypeVersions.getDeviceTypePlatformVersion()); } } + + public void setDeviceEnrollmentInvitationDetails(DeviceTypeConfiguration deviceTypeConfiguration) { + DeviceEnrollmentInvitationDetails deviceEnrollmentInvitationDetailsFromConfig = deviceTypeConfiguration + .getDeviceEnrollmentInvitationDetails(); + if (deviceEnrollmentInvitationDetailsFromConfig != null) { + deviceEnrollmentInvitationDetails.setEnrollmentDetails( + deviceEnrollmentInvitationDetailsFromConfig.getEnrollmentDetails()); + } + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java index f1c470829e..098baec3e3 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java @@ -34,6 +34,7 @@ */ package org.wso2.carbon.device.mgt.extensions.device.type.template.config; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypePlatformDetails; import javax.xml.bind.annotation.XmlElement; @@ -107,6 +108,8 @@ public class DeviceTypeConfiguration { protected List operations; @XmlElement(name = "DeviceTypePlatformDetails", required = true) protected DeviceTypePlatformDetails deviceTypePlatformDetails; + @XmlElement(name = "DeviceEnrollmentInvitationDetails", required = true) + protected DeviceEnrollmentInvitationDetails deviceEnrollmentInvitationDetails; public DeviceTypePlatformDetails getDeviceTypePlatformDetails() { return deviceTypePlatformDetails; @@ -414,4 +417,21 @@ public class DeviceTypeConfiguration { public void setStartupOperations(List startupOperations) { this.startupOperations = startupOperations; } + + /** + * Gets the value of device enrollment invitation details which has enrollment steps of enrollment types + * @return device enrollment invitation details + */ + public DeviceEnrollmentInvitationDetails getDeviceEnrollmentInvitationDetails() { + return deviceEnrollmentInvitationDetails; + } + + /** + * Sets the value of device enrollment invitation details from the relevant device type xml file + * @param deviceEnrollmentInvitationDetails {@link DeviceEnrollmentInvitationDetails} object + */ + public void setDeviceEnrollmentInvitationDetails( + DeviceEnrollmentInvitationDetails deviceEnrollmentInvitationDetails) { + this.deviceEnrollmentInvitationDetails = deviceEnrollmentInvitationDetails; + } } From ff00f26c8382d568e106db98c2613e437842127a Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Wed, 12 Aug 2020 18:32:04 +0530 Subject: [PATCH 25/33] Implement retrieval of DeviceEnrollmentInvitationDetails from the device management service --- .../DeviceManagementProviderService.java | 30 +++++++------------ .../DeviceManagementProviderServiceImpl.java | 25 ++++++++++++++++ 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java index ad677b1bf0..3a79a9cd42 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java @@ -14,8 +14,8 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - */ -/* + * + * * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. * * Entgra (pvt) Ltd. licenses this file to you under the Apache License, @@ -32,23 +32,6 @@ * specific language governing permissions and limitations * under the License. */ -/* - * Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. - * - * Entgra (pvt) Ltd. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ package org.wso2.carbon.device.mgt.core.service; @@ -76,6 +59,7 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManageme import org.wso2.carbon.device.mgt.common.configuration.mgt.DeviceConfiguration; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; import org.wso2.carbon.device.mgt.common.device.details.DeviceData; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.license.mgt.License; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; @@ -926,4 +910,12 @@ public interface DeviceManagementProviderService { */ List getDeviceByIdList(List deviceIdentifiers) throws DeviceManagementException; + + /** + * Retrieve device enrollment details to be sent device enrollment invitation. + * This has the relevant enrollment steps of each enrollment types. + * @param deviceType Device type of the required device enrollment details + * @return enrollment steps of each enrollment types which are provided in the device type xml file + */ + DeviceEnrollmentInvitationDetails getDeviceEnrollmentInvitationDetails(String deviceType); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index 55787e37fc..5e28129390 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -14,6 +14,23 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ package org.wso2.carbon.device.mgt.core.service; @@ -74,6 +91,7 @@ import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.license.mgt.License; import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManagementException; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; @@ -4187,4 +4205,11 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv DeviceManagementDAOFactory.closeConnection(); } } + + @Override + public DeviceEnrollmentInvitationDetails getDeviceEnrollmentInvitationDetails(String deviceType) { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + DeviceManagementService dms = pluginRepository.getDeviceManagementService(deviceType, tenantId); + return dms.getDeviceEnrollmentInvitationDetails(); + } } From 1b0c19cb0201f6120e0901ea62352268ab966262 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Wed, 12 Aug 2020 18:32:29 +0530 Subject: [PATCH 26/33] Add device enrollment invitation beans --- .../mgt/DeviceEnrollmentInvitation.java | 59 +++++++++++++++++++ .../invitation/mgt/DeviceEnrollmentType.java | 59 +++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentInvitation.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentType.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentInvitation.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentInvitation.java new file mode 100644 index 0000000000..0bdb03e921 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentInvitation.java @@ -0,0 +1,59 @@ +/* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.common.invitation.mgt; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; +import java.util.List; + +@ApiModel( + value = "DeviceEnrollmentInvitation", + description = "Holds data to send device enrollment invitation to list of existing users.") +public class DeviceEnrollmentInvitation implements Serializable { + + private static final long serialVersionUID = 6933837278652532052L; + + @ApiModelProperty( + name = "usernames", + value = "List of usernames of users.", + required = true) + private List usernames; + + @ApiModelProperty( + name = "deviceEnrollmentTypes", + value = "List of enrollment types against device types.") + private List deviceEnrollmentTypes; + + public List getUsernames() { + return usernames; + } + + public void setUsernames(List usernames) { + this.usernames = usernames; + } + + public List getDeviceEnrollmentTypes() { + return deviceEnrollmentTypes; + } + + public void setDeviceEnrollmentTypes( + List deviceEnrollmentTypes) { + this.deviceEnrollmentTypes = deviceEnrollmentTypes; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentType.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentType.java new file mode 100644 index 0000000000..0124fde36d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentType.java @@ -0,0 +1,59 @@ +/* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.common.invitation.mgt; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; +import java.util.List; + +@ApiModel( + value = "DeviceEnrollmentType", + description = "Holds data of enrollment types against device types.") +public class DeviceEnrollmentType implements Serializable { + + private static final long serialVersionUID = 6563596191450032613L; + + @ApiModelProperty( + name = "deviceType", + value = "Device type (i.e: android, ios, windows)", + required = true) + private String deviceType; + + @ApiModelProperty( + name = "enrollmentType", + value = "Enrollment type (i.e: BYOD, COPE, COSU)", + required = true) + private List enrollmentType; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public List getEnrollmentType() { + return enrollmentType; + } + + public void setEnrollmentType(List enrollmentType) { + this.enrollmentType = enrollmentType; + } +} From 0e018679b8734d4081f11a2d63544bd311e67982 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Wed, 12 Aug 2020 18:34:20 +0530 Subject: [PATCH 27/33] Modify test cases related to device enrollment invitation --- .../impl/UserManagementServiceImplTest.java | 55 +++++++++++++++---- .../mgt/core/TestDeviceManagementService.java | 6 ++ .../mock/TypeXDeviceManagementService.java | 6 ++ 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImplTest.java index 13942afb25..aa2f84733f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImplTest.java @@ -15,6 +15,23 @@ * specific language governing permissions and limitations * under the License. * + * + * Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * */ package org.wso2.carbon.device.mgt.jaxrs.service.impl; @@ -34,6 +51,10 @@ import org.testng.annotations.Test; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitation; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; +import org.wso2.carbon.device.mgt.core.otp.mgt.service.OTPManagementServiceImpl; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl; import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfo; @@ -66,9 +87,11 @@ public class UserManagementServiceImplTest { private UserStoreManager userStoreManager; private UserManagementService userManagementService; private DeviceManagementProviderService deviceManagementProviderService; + private OTPManagementService otpManagementService; private static final String DEFAULT_DEVICE_USER = "Internal/devicemgt-user"; private UserRealm userRealm; private EnrollmentInvitation enrollmentInvitation; + private DeviceEnrollmentInvitation deviceEnrollmentInvitation; private List userList; private static final String TEST_USERNAME = "test"; private static final String TEST2_USERNAME = "test2"; @@ -86,6 +109,7 @@ public class UserManagementServiceImplTest { userStoreManager = Mockito.mock(UserStoreManager.class, Mockito.RETURNS_MOCKS); deviceManagementProviderService = Mockito .mock(DeviceManagementProviderServiceImpl.class, Mockito.CALLS_REAL_METHODS); + otpManagementService = Mockito.mock(OTPManagementServiceImpl.class, Mockito.CALLS_REAL_METHODS); userRealm = Mockito.mock(UserRealm.class); RealmConfiguration realmConfiguration = Mockito.mock(RealmConfiguration.class); Mockito.doReturn(null).when(realmConfiguration).getSecondaryRealmConfig(); @@ -97,6 +121,8 @@ public class UserManagementServiceImplTest { enrollmentInvitation.setRecipients(recipients); userList = new ArrayList<>(); userList.add(TEST_USERNAME); + deviceEnrollmentInvitation = new DeviceEnrollmentInvitation(); + deviceEnrollmentInvitation.setUsernames(userList); } @Test(description = "This method tests the addUser method of UserManagementService") @@ -205,13 +231,11 @@ public class UserManagementServiceImplTest { @Test(description = "This method tests the send invitation method of UserManagementService", dependsOnMethods = {"testIsUserExists"}) - public void testSendInvitation() throws ConfigurationManagementException, DeviceManagementException { - PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) - .toReturn(this.userStoreManager); - PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) - .toReturn(this.deviceManagementProviderService); - Mockito.doNothing().when(deviceManagementProviderService).sendEnrolmentInvitation(Mockito.any(), Mockito.any()); - Response response = userManagementService.inviteExistingUsersToEnrollDevice(userList); + public void testSendInvitation() throws OTPManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getOTPManagementService")) + .toReturn(this.otpManagementService); + Mockito.doNothing().when(otpManagementService).sendDeviceEnrollmentInvitationMail(Mockito.any()); + Response response = userManagementService.inviteExistingUsersToEnrollDevice(deviceEnrollmentInvitation); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "Inviting existing users to enroll device failed"); } @@ -240,7 +264,7 @@ public class UserManagementServiceImplTest { @Test(description = "This method tests the inviteToEnrollDevice method of UserManagementService", dependsOnMethods = "testGetUsers") - public void testInviteToEnrollDevice() { + public void testInviteToEnrollDevice() throws ConfigurationManagementException, DeviceManagementException { URL resourceUrl = ClassLoader.getSystemResource("testng.xml"); System.setProperty("carbon.home", resourceUrl.getPath()); PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) @@ -248,6 +272,7 @@ public class UserManagementServiceImplTest { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser")).toReturn(TEST_USERNAME); PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); + Mockito.doNothing().when(deviceManagementProviderService).sendEnrolmentInvitation(Mockito.any(), Mockito.any()); EnrollmentInvitation enrollmentInvitation = new EnrollmentInvitation(); List recipients = new ArrayList<>(); recipients.add(TEST_USERNAME); @@ -289,16 +314,22 @@ public class UserManagementServiceImplTest { @Test(description = "This method tests the behaviour of methods when there is an issue with " + "DeviceManagementProviderService", dependsOnMethods = {"testGetUserCount"}) - public void testNegativeScenarios1() throws ConfigurationManagementException, DeviceManagementException { + public void testNegativeScenarios1() + throws ConfigurationManagementException, DeviceManagementException, OTPManagementException { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) .toReturn(this.userStoreManager); PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser")).toReturn(TEST_USERNAME); Mockito.reset(deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getOTPManagementService")) + .toReturn(this.otpManagementService); + Mockito.reset(otpManagementService); Mockito.doThrow(new DeviceManagementException()).when(deviceManagementProviderService) .sendEnrolmentInvitation(Mockito.any(), Mockito.any()); - Response response = userManagementService.inviteExistingUsersToEnrollDevice(userList); + Mockito.doThrow(new OTPManagementException()).when(otpManagementService) + .sendDeviceEnrollmentInvitationMail(Mockito.any()); + Response response = userManagementService.inviteExistingUsersToEnrollDevice(deviceEnrollmentInvitation); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), "Invite existing users to enroll device succeeded under erroneous conditions"); response = userManagementService.inviteToEnrollDevice(enrollmentInvitation); @@ -346,6 +377,8 @@ public class UserManagementServiceImplTest { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); Mockito.reset(this.userStoreManager); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getOTPManagementService")) + .toReturn(this.otpManagementService); Mockito.doThrow(new UserStoreException()).when(userStoreManager) .getUserClaimValue(Mockito.any(), Mockito.any(), Mockito.any()); Mockito.doThrow(new UserStoreException()).when(userStoreManager) @@ -362,7 +395,7 @@ public class UserManagementServiceImplTest { response = userManagementService.inviteToEnrollDevice(enrollmentInvitation); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), "Invite existing users to enroll device succeeded under erroneous conditions"); - response = userManagementService.inviteExistingUsersToEnrollDevice(userList); + response = userManagementService.inviteExistingUsersToEnrollDevice(deviceEnrollmentInvitation); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), "Invite existing users to enroll device succeeded under erroneous conditions"); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/TestDeviceManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/TestDeviceManagementService.java index 580ed77161..c3789d47fa 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/TestDeviceManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/TestDeviceManagementService.java @@ -37,6 +37,7 @@ import org.wso2.carbon.device.mgt.common.*; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.general.GeneralConfig; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager; import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber; import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig; @@ -142,4 +143,9 @@ public class TestDeviceManagementService implements DeviceManagementService { public DeviceTypePlatformDetails getDeviceTypePlatformDetails() { return null; } + + @Override + public DeviceEnrollmentInvitationDetails getDeviceEnrollmentInvitationDetails() { + return null; + } } diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeXDeviceManagementService.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeXDeviceManagementService.java index 9bcd089eb0..de7a16c0b1 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeXDeviceManagementService.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeXDeviceManagementService.java @@ -44,6 +44,7 @@ import org.wso2.carbon.device.mgt.common.ProvisioningConfig; import org.wso2.carbon.device.mgt.common.StartupOperationConfig; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager; import org.wso2.carbon.device.mgt.common.general.GeneralConfig; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager; import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber; import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig; @@ -131,4 +132,9 @@ public class TypeXDeviceManagementService implements DeviceManagementService { public DeviceTypePlatformDetails getDeviceTypePlatformDetails() { return null; } + + @Override + public DeviceEnrollmentInvitationDetails getDeviceEnrollmentInvitationDetails() { + return null; + } } From 322981fe5a92bb49c423cb554a9a92ea52c63743 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Thu, 13 Aug 2020 12:37:22 +0530 Subject: [PATCH 28/33] Use DEVICE_ENROLLMENT email type to create OTP --- .../device/mgt/jaxrs/util/DeviceMgtAPIUtils.java | 16 ++++++---------- .../device/mgt/common/otp/mgt/OTPEmailTypes.java | 2 +- .../mgt/service/OTPManagementServiceImpl.java | 4 +++- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java index e3a166dc2b..56f2a76e36 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java @@ -364,16 +364,12 @@ public class DeviceMgtAPIUtils { */ public static synchronized OTPManagementService getOTPManagementService() { if (otpManagementService == null) { - synchronized (DeviceMgtAPIUtils.class) { - 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); - } - } + 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; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/OTPEmailTypes.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/OTPEmailTypes.java index c4f7ef0689..72bbea982e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/OTPEmailTypes.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/OTPEmailTypes.java @@ -18,5 +18,5 @@ package org.wso2.carbon.device.mgt.common.otp.mgt; public enum OTPEmailTypes { - USER_VERIFY, ENROLLMENT + USER_VERIFY, DEVICE_ENROLLMENT } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java index 8be27f0ec2..ee7db06f15 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -33,6 +33,7 @@ import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitati import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentType; import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata; +import org.wso2.carbon.device.mgt.common.otp.mgt.OTPEmailTypes; import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OneTimePinDTO; import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; @@ -204,7 +205,8 @@ public class OTPManagementServiceImpl implements OTPManagementService { for (String username : deviceEnrollmentInvitation.getUsernames()) { String emailAddress = DeviceManagerUtil.getUserClaimValue( username, DeviceManagementConstants.User.CLAIM_EMAIL_ADDRESS); - oneTimePinDTO = createOneTimePin(emailAddress, "test-type", username, null, tenantId); + oneTimePinDTO = createOneTimePin(emailAddress, OTPEmailTypes.DEVICE_ENROLLMENT.toString(), username, + null, tenantId); props.setProperty("first-name", DeviceManagerUtil. getUserClaimValue(username, DeviceManagementConstants.User.CLAIM_FIRST_NAME)); props.setProperty("username", username); From d1c894abfe799e2905dcae5e3fdf1aabee85683b Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Thu, 13 Aug 2020 13:03:43 +0530 Subject: [PATCH 29/33] Modify user enrollment mail template to have enrollment steps --- .../email/templates/user-enrollment.vm | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-enrollment.vm b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-enrollment.vm index 0c29e86b4b..1093bad675 100644 --- a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-enrollment.vm +++ b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-enrollment.vm @@ -14,6 +14,22 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + + Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + Version 2.0 (the "License"); you may not use this file except + in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. *# You have been invited to enroll your device in Entgra IoT @@ -206,7 +222,13 @@ TkSuQmCC"

You have been invited to enrol your device in Entgra IoT Server. - Click here to begin device enrolment.

+ Click here to begin device enrolment.

+ +

+ Enrollment Steps are as below, +

+ + $enrollment-steps

Should you need assistance, please contact your administrator. From d53f56c96b2323c396c9c85b3b93574a42ed4b9a Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Tue, 18 Aug 2020 08:09:39 +0530 Subject: [PATCH 30/33] Complete self registration via OTP service --- .../mgt/common/spi/OTPManagementService.java | 11 +- .../mgt/service/OTPManagementServiceImpl.java | 22 +++- .../resources/email/templates/user-verify.vm | 2 +- .../resources/email/templates/user-welcome.vm | 101 ++++++++++++++++++ 4 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-welcome.vm diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java index 8ecb4de4fd..f63a95ca32 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java @@ -24,6 +24,8 @@ import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitati import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OneTimePinDTO; import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPWrapper; +import java.util.Map; + public interface OTPManagementService { /** @@ -44,11 +46,14 @@ public interface OTPManagementService { OneTimePinDTO isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException; /** - * Invalidate the OTP + * Invalidate the OTP and send welcome mail * @param oneTimeToken OTP - * @throws OTPManagementException If error occurred while invalidating the OTP + * @param email email address + * @param properties email properties to add to email body + * @throws OTPManagementException if error occurred while invalidate the OTP or send welcome email */ - void invalidateOTP(String oneTimeToken) throws OTPManagementException; + void completeSelfRegistration(String oneTimeToken, String email, Map properties) + throws OTPManagementException; /** * Create OTP token and send device enrollment invitation diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java index ee7db06f15..111f9e3591 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -58,6 +58,7 @@ import static org.wso2.carbon.device.mgt.common.DeviceManagementConstants.OTPPro import java.sql.Timestamp; import java.util.Calendar; import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.UUID; @@ -150,7 +151,26 @@ public class OTPManagementServiceImpl implements OTPManagementService { } @Override - public void invalidateOTP(String oneTimeToken) throws OTPManagementException { + public void completeSelfRegistration(String oneTimeToken, String email, Map properties) + throws OTPManagementException { + try { + invalidateOTP(oneTimeToken); + Properties props = new Properties(); + properties.forEach(props::setProperty); + sendMail(props, email); + } catch (OTPManagementException e) { + String msg = "Error occurred while completing the self registration via OTP"; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } + } + + /** + * Invalidate the OTP + * @param oneTimeToken OTP + * @throws OTPManagementException If error occurred while invalidating the OTP + */ + private void invalidateOTP(String oneTimeToken) throws OTPManagementException { try { ConnectionManagerUtil.beginDBTransaction(); if (!otpManagementDAO.expireOneTimeToken(oneTimeToken)) { diff --git a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm index 18e3a66a01..858503fd8a 100644 --- a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm +++ b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm @@ -16,7 +16,7 @@ under the License. *# - You have been invited to enroll your device in Entgra IoT + Verify email to register with Entgra IoTS diff --git a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-welcome.vm b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-welcome.vm new file mode 100644 index 0000000000..dfaab5c559 --- /dev/null +++ b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-welcome.vm @@ -0,0 +1,101 @@ +#* + Copyright (c) 2020, 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. +*# + + Welcome to Entgra Evaluation Cloud + + + + Entgra IoT Server + + +

+
+
+
+ entgra +
+
+
+

+ Hi $first-name, +

+
+

+ Welcome to Entgra Evaluation Cloud!! Entgra server support offers managing Android, iOS and Windows + devices along with a wide range of features that support cooperate (COPE) or personal device (BYOD) + enrollments. +

+
+
+

Access different portals

+

+ Your log-in credentials to any of our portals(endpoint-mgt, store, publisher) are the same as the + email (username) and password you provided during the registration for an evaluation account. +

+

Endpoint management portal URL: $base-url-https/endpoint-mgt/

+

+ This is the portal used to send operations and policies to devices and overall management of + the server. +

+

Application store portal URL: $base-url-https/store

+

+ This is an in-house corporate app store where you can host all your corporate applications. + Users may browse apps and install them to their devices if the administrator has made the apps + publicly visible to users. Administrator can install, uninstall and update apps in the user + device or device groups. +

+

Application publishing portal URL: $base-url-https/publisher

+

+ The portal for publishing new applications for internal use. This is the developer view of the + enterprise application store that comes with the product. +

+
+
+

Enroll a device

+

+ Please find here a set of videos on how to enroll and onboard devices to our Cloud platform. + [Cloud Enrollment Guide] + When enrolling a device, Make sure to use the following log-in format: +

+

+ Organisation: $tenant-domain + Username: $email-address + Password: password provided at registration. +

+
+
+

+ If you have any further questions, please reach out to us using your registered mail to + bizdev-group@entgra.io. Looking forward to working with you. +

+

+ Best Regards, +

+

+ Entgra Cloud Team +

+
+
+
+
+ + + ]]> + +
From d0b90dba5eca9eed3432e9b0d0840057bed6f487 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Wed, 19 Aug 2020 12:22:56 +0530 Subject: [PATCH 31/33] Update user enrollment email template --- .../email/templates/user-enrollment.vm | 173 +----------------- 1 file changed, 2 insertions(+), 171 deletions(-) diff --git a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-enrollment.vm b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-enrollment.vm index 1093bad675..ee2c0382ef 100644 --- a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-enrollment.vm +++ b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-enrollment.vm @@ -44,176 +44,7 @@
- entgra.io + entgra
@@ -222,7 +53,7 @@ TkSuQmCC"

You have been invited to enrol your device in Entgra IoT Server. - Click here to begin device enrolment.

+ Click here to begin device enrolment.

Enrollment Steps are as below, From b1845d9b42afd020679c7b3cc9845d7bb9bdbc50 Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Wed, 19 Aug 2020 08:24:55 +0530 Subject: [PATCH 32/33] Update user welcome mail body --- .../mgt/core/DeviceManagementConstants.java | 1 + .../mgt/service/OTPManagementServiceImpl.java | 2 +- .../resources/email/templates/user-welcome.vm | 25 ++++++++----------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java index afa9dfd767..b09d6fad9d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java @@ -117,6 +117,7 @@ public final class DeviceManagementConstants { public static final String USER_REGISTRATION_TEMPLATE = "user-registration"; public static final String USER_ENROLLMENT_TEMPLATE = "user-enrollment"; public static final String USER_VERIFY_TEMPLATE = "user-verify"; + public static final String USER_WELCOME_TEMPLATE = "user-welcome"; public static final String DEFAULT_ENROLLMENT_TEMPLATE = "default-enrollment-invitation"; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java index 111f9e3591..9b25987e84 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -157,7 +157,7 @@ public class OTPManagementServiceImpl implements OTPManagementService { invalidateOTP(oneTimeToken); Properties props = new Properties(); properties.forEach(props::setProperty); - sendMail(props, email); + sendMail(props, email, DeviceManagementConstants.EmailAttributes.USER_WELCOME_TEMPLATE); } catch (OTPManagementException e) { String msg = "Error occurred while completing the self registration via OTP"; log.error(msg, e); diff --git a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-welcome.vm b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-welcome.vm index dfaab5c559..5ce4611964 100644 --- a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-welcome.vm +++ b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-welcome.vm @@ -43,41 +43,38 @@

-

Access different portals

-

- Your log-in credentials to any of our portals(endpoint-mgt, store, publisher) are the same as the - email (username) and password you provided during the registration for an evaluation account. -

-

Endpoint management portal URL: $base-url-https/endpoint-mgt/

+

Access different portals

+

Your log-in credentials to any of our portals(endpoint-mgt, store, publisher) are,

+

Username: $portal-username

+

Password: password provided at registration for an evaluation account.

+

Endpoint management portal URL: $base-url-https/endpoint-mgt/

This is the portal used to send operations and policies to devices and overall management of the server.

-

Application store portal URL: $base-url-https/store

+

Application store portal URL: $base-url-https/store

This is an in-house corporate app store where you can host all your corporate applications. Users may browse apps and install them to their devices if the administrator has made the apps publicly visible to users. Administrator can install, uninstall and update apps in the user device or device groups.

-

Application publishing portal URL: $base-url-https/publisher

+

Application publishing portal URL: $base-url-https/publisher

The portal for publishing new applications for internal use. This is the developer view of the enterprise application store that comes with the product.

-

Enroll a device

+

Enroll a device

Please find here a set of videos on how to enroll and onboard devices to our Cloud platform. [Cloud Enrollment Guide] When enrolling a device, Make sure to use the following log-in format:

-

- Organisation: $tenant-domain - Username: $email-address - Password: password provided at registration. -

+

Organisation: $tenant-domain

+

Username: $agent-username

+

Password: password provided at registration.

From 8aeb4d22eabf6e5329b569022138c7f6fc5ca148 Mon Sep 17 00:00:00 2001 From: "tcdlpds@gmail.com" Date: Fri, 21 Aug 2020 09:18:55 +0530 Subject: [PATCH 33/33] Improve code formatting --- .../framework/authenticator/OneTimeTokenAuthenticator.java | 1 - 1 file changed, 1 deletion(-) diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java index 472fb6d302..9d290c51da 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java @@ -88,5 +88,4 @@ public class OneTimeTokenAuthenticator implements WebappAuthenticator { return null; } - }