Improve OTP creating logic

4.x.x
tcdlpds@gmail.com 4 years ago
parent 1d465c2909
commit 8494f0bc58

@ -49,7 +49,6 @@ import io.swagger.annotations.ResponseHeader;
import org.apache.axis2.transport.http.HTTPConstants;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper;
import org.wso2.carbon.device.mgt.jaxrs.beans.ActivityList;
import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfo;
import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfoList;

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

@ -45,11 +45,8 @@ import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.spi.OTPManagementService;
import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper;
import org.wso2.carbon.device.mgt.core.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo;

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

@ -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() {

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

@ -31,7 +31,6 @@ public class OTPMailDTO {
Timestamp createdAt;
int expiryTime;
boolean isExpired;
boolean isTenantCreated;
public int getTenantId() {
return tenantId;
@ -111,7 +110,4 @@ public class OTPMailDTO {
isExpired = expired;
}
public boolean isTenantCreated() { return isTenantCreated; }
public void setTenantCreated(boolean tenantCreated) { isTenantCreated = tenantCreated; }
}

@ -16,39 +16,16 @@
*/
package org.wso2.carbon.device.mgt.common.otp.mgt.wrapper;
public class OTPMailWrapper {
import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata;
private String firstName;
private String lastName;
private String adminUsername;
int tenantId;
private String adminPassword;
private String email;
private String emailType;
public int getTenantId() {
return tenantId;
}
public void setTenantId(int tenantId) {
this.tenantId = tenantId;
}
public String getAdminUsername() {
return adminUsername;
}
public void setAdminUsername(String adminUsername) {
this.adminUsername = adminUsername;
}
import java.util.List;
public String getAdminPassword() {
return adminPassword;
}
public class OTPWrapper {
public void setAdminPassword(String adminPassword) {
this.adminPassword = adminPassword;
}
private String email;
private String emailType;
private String username;
private List<Metadata> properties;
public String getEmail() {
return email;
@ -66,19 +43,11 @@ public class OTPMailWrapper {
this.emailType = emailType;
}
public String getFirstName() {
return firstName;
}
public String getUsername() { return username; }
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setUsername(String username) { this.username = username; }
public String getLastName() {
return lastName;
}
public List<Metadata> getProperties() { return properties; }
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setProperties(List<Metadata> properties) { this.properties = properties; }
}

@ -18,20 +18,20 @@
package org.wso2.carbon.device.mgt.common.spi;
import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException;
import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO;
import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper;
import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPWrapper;
public interface OTPManagementService {
/**
* Create OTP token and store tenant details in the DB
* @param otpMailWrapper OTP Mail Wrapper object which contains tenant details of registering user
* @return OTPToken
* @param otpWrapper OTP Mail Wrapper object which contains tenant details of registering user
* @throws OTPManagementException if error occurs while creating OTP token and storing tenant details.
* @throws BadRequestException if found and incompatible payload to create OTP token.
*/
String createOTPToken (OTPMailWrapper otpMailWrapper) throws OTPManagementException, BadRequestException;
void sendUserVerifyingMail(OTPWrapper otpWrapper) throws OTPManagementException, DeviceManagementException;
/**
* Check the validity of the OTP

@ -102,7 +102,6 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM
+ "CREATED_AT, "
+ "EXPIRY_TIME, "
+ "IS_EXPIRED, "
+ "TENANT_CREATED,"
+ "TENANT_ID, "
+ "USERNAME FROM DM_OTP_DATA "
+ "WHERE OTP_TOKEN = ?";
@ -123,7 +122,6 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM
otpMailDTO.setCreatedAt(rs.getTimestamp("CREATED_AT"));
otpMailDTO.setExpiryTime(rs.getInt("EXPIRY_TIME"));
otpMailDTO.setExpired(rs.getBoolean("IS_EXPIRED"));
otpMailDTO.setTenantCreated(rs.getBoolean("TENANT_CREATED"));
otpMailDTO.setTenantId(rs.getInt("TENANT_ID"));
otpMailDTO.setUsername(rs.getString("USERNAME"));
return otpMailDTO;

@ -26,19 +26,28 @@ import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.UnAuthorizedException;
import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata;
import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO;
import org.wso2.carbon.device.mgt.common.spi.OTPManagementService;
import org.wso2.carbon.device.mgt.core.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig;
import org.wso2.carbon.device.mgt.core.config.keymanager.KeyManagerConfigurations;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAO;
import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper;
import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPWrapper;
import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.otp.mgt.exception.OTPManagementDAOException;
import org.wso2.carbon.device.mgt.core.otp.mgt.util.ConnectionManagerUtil;
import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo;
import org.wso2.carbon.user.api.Tenant;
import static org.wso2.carbon.device.mgt.common.DeviceManagementConstants.OTPProperties;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.List;
import java.util.Properties;
import java.util.UUID;
@ -56,23 +65,35 @@ public class OTPManagementServiceImpl implements OTPManagementService {
}
@Override
public String createOTPToken(OTPMailWrapper otpMailWrapper) throws OTPManagementException, BadRequestException {
public void sendUserVerifyingMail(OTPWrapper otpWrapper) throws OTPManagementException, DeviceManagementException {
if (!isValidOTPTokenCreatingRequest(otpMailWrapper)){
Tenant tenant = validateOTPTokenCreatingRequest(otpWrapper);
if (tenant == null){
String msg = "Found invalid payload with OTP creating request";
log.error(msg);
throw new BadRequestException(msg);
}
DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance()
.getDeviceManagementConfig();
KeyManagerConfigurations kmConfig = deviceManagementConfig.getKeyManagerConfigurations();
String superTenantUsername = kmConfig.getAdminUsername();
if (!otpWrapper.getUsername().equals(superTenantUsername)) {
String msg = "You don't have required permission to create OTP";
log.error(msg);
throw new UnAuthorizedException(msg);
}
Gson gson = new Gson();
String metaInfo = gson.toJson(otpMailWrapper);
String metaInfo = gson.toJson(tenant);
String otpValue = UUID.randomUUID().toString();
OTPMailDTO otpMailDTO = new OTPMailDTO();
otpMailDTO.setEmail(otpMailWrapper.getEmail());
otpMailDTO.setTenantId(otpMailDTO.getTenantId());
otpMailDTO.setUsername(otpMailWrapper.getAdminUsername());
otpMailDTO.setEmailType(otpMailWrapper.getEmailType());
otpMailDTO.setEmail(otpWrapper.getEmail());
otpMailDTO.setTenantId(-1234);
otpMailDTO.setUsername(otpWrapper.getUsername());
otpMailDTO.setEmailType(otpWrapper.getEmailType());
otpMailDTO.setMetaInfo(metaInfo);
otpMailDTO.setOtpToken(otpValue);
@ -84,8 +105,8 @@ public class OTPManagementServiceImpl implements OTPManagementService {
log.error(msg);
throw new OTPManagementException(msg);
}
sendMail(tenant.getAdminFirstName(), otpValue, tenant.getEmail());
ConnectionManagerUtil.commitDBTransaction();
return otpValue;
} catch (TransactionManagementException e) {
String msg = "Error occurred while disabling AutoCommit.";
log.error(msg, e);
@ -117,10 +138,6 @@ public class OTPManagementServiceImpl implements OTPManagementService {
log.warn("Token is expired. OTP: " + oneTimeToken);
return null;
}
if (otpMailDTO.isTenantCreated()) {
log.warn("Tenant is already created for the token. OTP: " + oneTimeToken);
return null;
}
Calendar calendar = Calendar.getInstance();
Timestamp currentTimestamp = new Timestamp(calendar.getTime().getTime());
@ -131,8 +148,8 @@ public class OTPManagementServiceImpl implements OTPManagementService {
String renewedOTP = UUID.randomUUID().toString();
renewOTP(otpMailDTO, renewedOTP);
Gson gson = new Gson();
OTPMailWrapper otpMailWrapper = gson.fromJson(otpMailDTO.getMetaInfo(), OTPMailWrapper.class);
resendUserVerifyingMail(otpMailWrapper.getFirstName(), renewedOTP, otpMailDTO.getEmail());
Tenant tenant = gson.fromJson(otpMailDTO.getMetaInfo(), Tenant.class);
sendMail(tenant.getAdminFirstName(), renewedOTP, otpMailDTO.getEmail());
return null;
}
return otpMailDTO;
@ -163,39 +180,63 @@ public class OTPManagementServiceImpl implements OTPManagementService {
/**
* Validate OTP token creating payload
* @param otpMailWrapper OTPMailWrapper
* @param otpWrapper OTP-Wrapper
* @return true if its valid payload otherwise returns false
*/
private boolean isValidOTPTokenCreatingRequest(OTPMailWrapper otpMailWrapper) {
if (StringUtils.isBlank(otpMailWrapper.getFirstName())) {
log.error("Received empty or blank first name field with OTP creating payload.");
return false;
}
if (StringUtils.isBlank(otpMailWrapper.getLastName())) {
log.error("Received empty or blank last name field with OTP creating payload.");
return false;
}
if (StringUtils.isBlank(otpMailWrapper.getAdminUsername())) {
log.error("Received empty or blank admin username field with OTP creating payload.");
return false;
}
if (StringUtils.isBlank(otpMailWrapper.getAdminPassword())) {
log.error("Received empty or blank admin password field with OTP creating payload.");
return false;
private Tenant validateOTPTokenCreatingRequest(OTPWrapper otpWrapper) {
Tenant tenant = new Tenant();
List<Metadata> properties = otpWrapper.getProperties();
for (Metadata property : properties) {
switch (property.getMetaKey()) {
case OTPProperties.FIRST_NAME:
String firstName = property.getMetaValue();
if (StringUtils.isBlank(firstName)) {
log.error("Received empty or blank first name field with OTP creating payload.");
return null;
}
tenant.setAdminFirstName(firstName);
break;
case OTPProperties.LAST_NAME:
String lastName = property.getMetaValue();
if (StringUtils.isBlank(lastName)) {
log.error("Received empty or blank last name field with OTP creating payload.");
return null;
}
tenant.setAdminLastName(lastName);
break;
case OTPProperties.TENANT_ADMIN_USERNAME:
String username = property.getMetaValue();
if (StringUtils.isBlank(username)) {
log.error("Received empty or blank admin username field with OTP creating payload.");
return null;
}
tenant.setAdminName(username);
break;
case OTPProperties.TENANT_ADMIN_PASSWORD:
String pwd = property.getMetaValue();
if (StringUtils.isBlank(pwd)) {
log.error("Received empty or blank admin password field with OTP creating payload.");
return null;
}
tenant.setAdminPassword(pwd);
break;
default:
log.error("Received invalid key with OTP properties for creating OTP.");
return null;
}
}
if (StringUtils.isBlank(otpMailWrapper.getEmail())) {
if (StringUtils.isBlank(otpWrapper.getEmail())) {
log.error("Received empty or blank email field with OTP creating payload.");
return false;
return null;
}
if (StringUtils.isBlank(otpMailWrapper.getEmailType())) {
if (StringUtils.isBlank(otpWrapper.getEmailType())) {
log.error("Received empty or blank email type field with OTP creating payload.");
return false;
}
if (otpMailWrapper.getTenantId() != -1234 && otpMailWrapper.getTenantId() < 1) {
log.error("Invalid tenant Id field with OTP creating payload.");
return false;
return null;
}
return true;
tenant.setEmail(otpWrapper.getEmail());
return tenant;
}
/**
@ -205,7 +246,7 @@ public class OTPManagementServiceImpl implements OTPManagementService {
* @param mailAddress Mail Address of the User
* @throws OTPManagementException if error occurred while resend the user verifying mail
*/
private void resendUserVerifyingMail(String firstName, String renewedOTP, String mailAddress)
private void sendMail(String firstName, String renewedOTP, String mailAddress)
throws OTPManagementException {
Properties props = new Properties();
props.setProperty("first-name", firstName);
@ -216,8 +257,9 @@ public class OTPManagementServiceImpl implements OTPManagementService {
DeviceManagementDataHolder.getInstance().getDeviceManagementProvider()
.sendEnrolmentInvitation(DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE, metaInfo);
} catch (DeviceManagementException e) {
e.printStackTrace();
throw new OTPManagementException(e);
String msg = "Error occurred while inviting user to enrol their device";
log.error(msg, e);
throw new OTPManagementException(msg, e);
} catch (ConfigurationManagementException e) {
throw new OTPManagementException(e);
}

@ -584,7 +584,6 @@ CREATE TABLE IF NOT EXISTS DM_OTP_DATA (
CREATED_AT TIMESTAMP NOT NULL,
EXPIRY_TIME INT NOT NULL DEFAULT 3600,
IS_EXPIRED BOOLEAN DEFAULT false,
TENANT_CREATED BOOLEAN DEFAULT false,
PRIMARY KEY (ID),
CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE)
);

@ -626,7 +626,6 @@ CREATE TABLE DM_OTP_DATA (
CREATED_AT DATETIME2(0) NOT NULL,
EXPIRY_TIME INT NOT NULL DEFAULT 3600,
IS_EXPIRED BIT DEFAULT false,
TENANT_CREATED BOOLEAN DEFAULT false,
PRIMARY KEY (ID),
CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE)
);

@ -642,7 +642,6 @@ CREATE TABLE IF NOT EXISTS DM_OTP_DATA (
CREATED_AT TIMESTAMP NOT NULL,
EXPIRY_TIME INT NOT NULL DEFAULT 3600,
IS_EXPIRED BOOLEAN DEFAULT false,
TENANT_CREATED BOOLEAN DEFAULT false,
PRIMARY KEY (ID),
CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE)
);

@ -990,7 +990,6 @@ CREATE TABLE DM_OTP_DATA (
CREATED_AT TIMESTAMP(0) NOT NULL,
EXPIRY_TIME NUMBER(10) DEFAULT 3600 NOT NULL,
IS_EXPIRED CHAR(1) DEFAULT false,
TENANT_CREATED BOOLEAN DEFAULT false,
PRIMARY KEY (ID),
CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE)
);

@ -631,7 +631,6 @@ CREATE TABLE IF NOT EXISTS DM_OTP_DATA (
CREATED_AT TIMESTAMP(0) NOT NULL,
EXPIRY_TIME INT NOT NULL DEFAULT 3600,
IS_EXPIRED BOOLEAN DEFAULT false,
TENANT_CREATED BOOLEAN DEFAULT false,
PRIMARY KEY (ID),
CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE)
);

@ -29,7 +29,7 @@
</Authenticator>
<Authenticator>
<Name>CertificateAuth</Name>
<ClassName>org.wso2.carbon.webapp.authenticator.framework.authenticator.gitCertificateAuthenticator</ClassName>
<ClassName>org.wso2.carbon.webapp.authenticator.framework.authenticator.CertificateAuthenticator</ClassName>
</Authenticator>
<Authenticator>
<Name>OTPAuth</Name>

Loading…
Cancel
Save