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..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
@@ -232,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/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/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/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..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
@@ -124,4 +124,4 @@
/*
-
\ No newline at end of file
+
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..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
@@ -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.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;
@@ -75,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(
@@ -894,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/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 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 31b9543d08..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
@@ -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;
@@ -52,6 +69,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 +152,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 OTPManagementService otpManagementService;
static {
String keyStorePassword = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Password");
@@ -337,6 +356,25 @@ 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) {
+ 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.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.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/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/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/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;
+ }
+}
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/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/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;
+ }
+}
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/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..72bbea982e
--- /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, DEVICE_ENROLLMENT
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OneTimePinDTO.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
new file mode 100644
index 0000000000..11923947c1
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OneTimePinDTO.java
@@ -0,0 +1,113 @@
+/* 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 OneTimePinDTO {
+
+ int id;
+ String otpToken;
+ int tenantId;
+ String username;
+ String email;
+ String emailType;
+ String metaInfo;
+ Timestamp createdAt;
+ int expiryTime;
+ boolean isExpired;
+
+ 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;
+ }
+
+ 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;
+ }
+
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPWrapper.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
new file mode 100644
index 0000000000..319da774d1
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPWrapper.java
@@ -0,0 +1,53 @@
+/* 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;
+
+import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata;
+
+import java.util.List;
+
+public class OTPWrapper {
+
+ private String email;
+ private String emailType;
+ private String username;
+ private List properties;
+
+ 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 getUsername() { return username; }
+
+ public void setUsername(String username) { this.username = username; }
+
+ public List getProperties() { return properties; }
+
+ 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/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.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..f63a95ca32
--- /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,65 @@
+/* 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.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;
+
+import java.util.Map;
+
+public interface OTPManagementService {
+
+ /**
+ * Create OTP token and store tenant details in the DB
+ * @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.
+ */
+ void sendUserVerifyingMail(OTPWrapper otpWrapper) throws OTPManagementException, DeviceManagementException;
+
+ /**
+ * Check the validity of the OTP
+ * @param oneTimeToken OTP
+ * @return The OTP data
+ * @throws OTPManagementException if error occurred whle verifying validity of the OPT
+ * @throws BadRequestException if found an null value for OTP
+ */
+ OneTimePinDTO isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException;
+
+ /**
+ * Invalidate the OTP and send welcome mail
+ * @param oneTimeToken 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 completeSelfRegistration(String oneTimeToken, String email, Map properties)
+ 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/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/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..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
@@ -116,6 +116,8 @@ 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";
}
@@ -142,6 +144,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/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..4c3690f5d0
--- /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,64 @@
+/* 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.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 oneTimePinDTO OTPMailDTO
+ * @return Primary key of the newly adding data raw
+ * @throws OTPManagementDAOException if error occurred whule storing data
+ */
+ int addOTPData(OneTimePinDTO oneTimePinDTO) throws OTPManagementDAOException;
+
+ /**
+ * Get OTP data for requesting One Time Token
+ * @param oneTimeToken One Time Token
+ * @return {@link OneTimePinDTO}
+ * @throws OTPManagementDAOException if error ocured while getting OTP data for requesting one time token
+ */
+ OneTimePinDTO getOTPDataByToken (String oneTimeToken) throws OTPManagementDAOException;
+
+ /**
+ * Expire the OTP
+ * @param oneTimeToken OTP
+ * @throws OTPManagementDAOException if error occurred while updating the OTP validity.
+ */
+ boolean 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;
+
+ /**
+ * 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/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..273cf6c1a5
--- /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,243 @@
+/* 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.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;
+
+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(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 : " + oneTimePinDTO.getOtpToken() + " Email : " + oneTimePinDTO.getEmail());
+ }
+
+ String sql = "INSERT INTO DM_OTP_DATA "
+ + "(OTP_TOKEN, "
+ + "EMAIL, "
+ + "EMAIL_TYPE, "
+ + "META_INFO, "
+ + "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, oneTimePinDTO.getOtpToken());
+ stmt.setString(2, oneTimePinDTO.getEmail());
+ stmt.setString(3, oneTimePinDTO.getEmailType());
+ stmt.setString(4, oneTimePinDTO.getMetaInfo());
+ stmt.setTimestamp(5, timestamp);
+ stmt.setInt(6, oneTimePinDTO.getTenantId());
+ stmt.setString(7, oneTimePinDTO.getUsername());
+ 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 "
+ + 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 " + oneTimePinDTO.getEmail();
+ log.error(msg, e);
+ throw new OTPManagementDAOException(msg, e);
+ }
+ }
+
+ @Override
+ 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");
+ log.debug("OTP Details : OTP key : " + oneTimeToken );
+ }
+
+ String sql = "SELECT "
+ + "ID, "
+ + "OTP_TOKEN, "
+ + "EMAIL, "
+ + "EMAIL_TYPE, "
+ + "META_INFO, "
+ + "CREATED_AT, "
+ + "EXPIRY_TIME, "
+ + "IS_EXPIRED, "
+ + "TENANT_ID, "
+ + "USERNAME 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()) {
+ 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;
+ }
+ }
+ } 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 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 );
+ }
+
+ 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);
+ return stmt.executeUpdate() == 1;
+ }
+ } 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.";
+ log.error(msg, e);
+ throw new OTPManagementDAOException(msg, e);
+ } catch (SQLException e) {
+ 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/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..9b25987e84
--- /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,461 @@
+/* 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.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;
+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.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;
+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.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;
+
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+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 void sendUserVerifyingMail(OTPWrapper otpWrapper) throws OTPManagementException, DeviceManagementException {
+ Tenant tenant = validateTenantCreatingDetails(otpWrapper);
+ OneTimePinDTO oneTimePinDTO = createOneTimePin(otpWrapper.getEmail(), otpWrapper.getEmailType(),
+ otpWrapper.getUsername(), tenant, -1234);
+ try {
+ ConnectionManagerUtil.beginDBTransaction();
+ if (this.otpManagementDAO.addOTPData(oneTimePinDTO) == -1) {
+ ConnectionManagerUtil.rollbackDBTransaction();
+ String msg = "OTP data saving failed. Please, contact Administrator";
+ log.error(msg);
+ throw new OTPManagementException(msg);
+ }
+ Properties props = new Properties();
+ props.setProperty("first-name", tenant.getAdminFirstName());
+ props.setProperty("otp-token", oneTimePinDTO.getOtpToken());
+ sendMail(props, tenant.getEmail(), DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE);
+ ConnectionManagerUtil.commitDBTransaction();
+ } 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: " + oneTimePinDTO.getEmail();
+ log.error(msg, e);
+ throw new OTPManagementException(msg, e);
+ } finally {
+ ConnectionManagerUtil.closeDBConnection();
+ }
+ }
+
+ @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;
+ }
+
+ Calendar calendar = Calendar.getInstance();
+ Timestamp currentTimestamp = new Timestamp(calendar.getTime().getTime());
+ Timestamp expiredTimestamp = new Timestamp(
+ oneTimePinDTO.getCreatedAt().getTime() + oneTimePinDTO.getExpiryTime() * 1000);
+
+ if (currentTimestamp.after(expiredTimestamp)) {
+ String renewedOTP = UUID.randomUUID().toString();
+ renewOTP(oneTimePinDTO, renewedOTP);
+ Gson gson = new Gson();
+ Tenant tenant = gson.fromJson(oneTimePinDTO.getMetaInfo(), Tenant.class);
+
+ Properties props = new Properties();
+ props.setProperty("first-name", tenant.getAdminFirstName());
+ props.setProperty("otp-token", renewedOTP);
+ sendMail(props, oneTimePinDTO.getEmail(), DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE);
+ return null;
+ }
+ return oneTimePinDTO;
+ }
+
+ @Override
+ 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, DeviceManagementConstants.EmailAttributes.USER_WELCOME_TEMPLATE);
+ } 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)) {
+ 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();
+ }
+ }
+
+
+ @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, OTPEmailTypes.DEVICE_ENROLLMENT.toString(), 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
+ * @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 OneTimePinDTO}
+ * @throws OTPManagementException if error occurred while getting OTP data for given OTP in DB
+ */
+ private OneTimePinDTO 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();
+ }
+ }
+
+ /**
+ * Validate Tenant details
+ * @param otpWrapper OTP-Wrapper
+ * @return {@link Tenant} if its valid payload otherwise throws {@link DeviceManagementException}
+ * @throws DeviceManagementException if invalid payload or unauthorized request received
+ */
+ private Tenant validateTenantCreatingDetails(OTPWrapper otpWrapper) throws DeviceManagementException {
+
+ DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance()
+ .getDeviceManagementConfig();
+ KeyManagerConfigurations kmConfig = deviceManagementConfig.getKeyManagerConfigurations();
+
+ 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[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);
+ }
+
+ 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)) {
+ 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)) {
+ 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_PASSWORD:
+ String pwd = property.getMetaValue();
+ if (StringUtils.isBlank(pwd)) {
+ 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:
+ String msg = "Received invalid key with OTP properties for creating OTP.";
+ log.error(msg);
+ throw new BadRequestException(msg);
+ }
+ }
+
+ if (StringUtils.isBlank(otpWrapper.getEmail())) {
+ String msg = "Received empty or blank email field with OTP creating payload.";
+ 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);
+ }
+
+ 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;
+ }
+
+ /**
+ * 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, String template) throws OTPManagementException {
+ try {
+ EmailMetaInfo metaInfo = new EmailMetaInfo(mailAddress, props);
+ DeviceManagementDataHolder.getInstance().getDeviceManagementProvider()
+ .sendEnrolmentInvitation(template, metaInfo);
+ } catch (DeviceManagementException e) {
+ String msg = "Error occurred while sending email using email template '" + template + "'.";
+ log.error(msg, e);
+ throw new OTPManagementException(msg, e);
+ } catch (ConfigurationManagementException e) {
+ String msg = "Configuration error occurred. Hence mail sending failed.";
+ log.error(msg, e);
+ throw new OTPManagementException(msg, e);
+ }
+ }
+
+ /**
+ * Renew the OTP
+ * @param oneTimePinDTO {@link OneTimePinDTO}
+ * @param renewedOTP Renewed OTP
+ * @throws OTPManagementException if error occurred while renew the OTP
+ */
+ private void renewOTP(OneTimePinDTO oneTimePinDTO, String renewedOTP) throws OTPManagementException {
+ try {
+ ConnectionManagerUtil.beginDBTransaction();
+ this.otpManagementDAO.renewOneTimeToken(oneTimePinDTO.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/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/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..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;
@@ -89,7 +73,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;
@@ -927,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();
+ }
}
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);
+ }
}
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/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;
+ }
}
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;
+ }
}
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..624814f327
--- /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 = "OTPRequestHandlerServlet",
+ 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();
+ }
}
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..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,7 +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.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/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..9d290c51da
--- /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,91 @@
+/*
+ * 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.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;
+import org.wso2.carbon.webapp.authenticator.framework.Utils.Utils;
+import org.wso2.carbon.webapp.authenticator.framework.internal.AuthenticatorFrameworkDataHolder;
+
+import java.util.Properties;
+
+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) {
+
+ AuthenticationInfo authenticationInfo = new AuthenticationInfo();
+
+ try {
+ OTPManagementService otpManagementService = AuthenticatorFrameworkDataHolder.getInstance()
+ .getOtpManagementService();
+ OneTimePinDTO validOTP = otpManagementService.isValidOTP(request.getHeader(Constants.HTTPHeaders
+ .ONE_TIME_TOKEN_HEADER));
+ if (validOTP != null) {
+ authenticationInfo.setStatus(Status.CONTINUE);
+ authenticationInfo.setTenantId(validOTP.getTenantId());
+ authenticationInfo.setTenantDomain(Utils.getTenantDomain(validOTP.getTenantId()));
+ authenticationInfo.setUsername(validOTP.getUsername());
+ } else {
+ authenticationInfo.setStatus(Status.FAILURE);
+ authenticationInfo.setMessage("Invalid OTP token.");
+ }
+ } catch (Exception e) {
+ String msg = "OTP Token Validation Failed.";
+ log.error(msg, e);
+ authenticationInfo.setStatus(Status.FAILURE);
+ authenticationInfo.setMessage(msg);
+ }
+ return authenticationInfo;
+ }
+
+ 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..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,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.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;
@@ -35,6 +36,7 @@ public class AuthenticatorFrameworkDataHolder {
private OAuth2TokenValidationService oAuth2TokenValidationService;
private TenantIndexingLoader tenantIndexingLoader;
private TenantRegistryLoader tenantRegistryLoader;
+ private OTPManagementService otpManagementService;
private static AuthenticatorFrameworkDataHolder
thisInstance = new AuthenticatorFrameworkDataHolder();
@@ -114,4 +116,10 @@ public class AuthenticatorFrameworkDataHolder {
public TenantRegistryLoader getTenantRegistryLoader() {
return tenantRegistryLoader;
}
+
+ public OTPManagementService getOtpManagementService() { return otpManagementService; }
+
+ 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 36dd1c09c6..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
@@ -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.identity.oauth2.OAuth2TokenValidationService;
import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader;
@@ -80,7 +81,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.common.spi.OTPManagementService"
+ * cardinality="1..1"
+ * policy="dynamic"
+ * bind="setOTPManagementService"
+ * unbind="unsetOTPManagementService"
*/
+
public class WebappAuthenticatorFrameworkServiceComponent {
private static final Log log = LogFactory.getLog(WebappAuthenticatorFrameworkServiceComponent.class);
@@ -211,4 +219,18 @@ public class WebappAuthenticatorFrameworkServiceComponent {
protected void unsetTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) {
AuthenticatorFrameworkDataHolder.getInstance().setTenantRegistryLoader(null);
}
+
+ protected void setOTPManagementService(OTPManagementService otpManagementService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Setting OTP Management OSGI Service");
+ }
+ AuthenticatorFrameworkDataHolder.getInstance().setOtpManagementService(otpManagementService);
+ }
+
+ protected void unsetOTPManagementService(OTPManagementService otpManagementService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Removing OTP Management OSGI Service");
+ }
+ AuthenticatorFrameworkDataHolder.getInstance().setOtpManagementService(null);
+ }
}
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/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..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
@@ -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_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,
+ CREATED_AT TIMESTAMP NOT NULL,
+ EXPIRY_TIME INT NOT NULL DEFAULT 3600,
+ IS_EXPIRED 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..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
@@ -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_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,
+ CREATED_AT DATETIME2(0) NOT NULL,
+ EXPIRY_TIME INT NOT NULL DEFAULT 3600,
+ IS_EXPIRED BIT 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..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
@@ -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_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,
+ CREATED_AT TIMESTAMP NOT NULL,
+ EXPIRY_TIME INT NOT NULL DEFAULT 3600,
+ IS_EXPIRED 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..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
@@ -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_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,
+ CREATED_AT TIMESTAMP(0) NOT NULL,
+ EXPIRY_TIME NUMBER(10) DEFAULT 3600 NOT NULL,
+ IS_EXPIRED CHAR(1) 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..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
@@ -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_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,
+ CREATED_AT TIMESTAMP(0) NOT NULL,
+ EXPIRY_TIME INT NOT NULL DEFAULT 3600,
+ IS_EXPIRED 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-enrollment.vm b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-enrollment.vm
index 20bcf6e768..9573061735 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
@@ -37,7 +53,13 @@
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.
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..858503fd8a
--- /dev/null
+++ b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm
@@ -0,0 +1,61 @@
+#*
+ 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.
+*#
+
+ Verify email to register with Entgra IoTS
+
+
+
+ Entgra IoT Server
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+
+
+
+ ]]>
+