Improve OTP creating functionality

revert-70ac1926
Dharmakeerthi Lasantha 4 years ago
parent 1cbb84345e
commit 3d2f474e75

@ -24,7 +24,7 @@ import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPMailWrapper;
public interface OTPManagementService { public interface OTPManagementService {
/** /**
* Cretae OTP token and store tenant details in the DB * Create OTP token and store tenant details in the DB
* @param otpMailWrapper OTP Mail Wrapper object which contains tenant details of registering user * @param otpMailWrapper OTP Mail Wrapper object which contains tenant details of registering user
* @return OTPToken * @return OTPToken
* @throws OTPManagementException if error occurs while creating OTP token and storing tenant details. * @throws OTPManagementException if error occurs while creating OTP token and storing tenant details.
@ -32,5 +32,12 @@ public interface OTPManagementService {
*/ */
String createOTPToken (OTPMailWrapper otpMailWrapper) throws OTPManagementException, BadRequestException; String createOTPToken (OTPMailWrapper otpMailWrapper) throws OTPManagementException, BadRequestException;
/**
* Check the validity of the OTP
* @param oneTimeToken OTP
* @return Ture if OTP is valid one, otherise returns false
* @throws OTPManagementException if error occurred whle verifying validity of the OPT
* @throws BadRequestException if found an null value for OTP
*/
boolean isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException; boolean isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException;
} }

@ -38,5 +38,19 @@ public interface OTPManagementDAO {
*/ */
OTPMailDTO getOTPDataByToken (String oneTimeToken) throws OTPManagementDAOException; OTPMailDTO getOTPDataByToken (String oneTimeToken) throws OTPManagementDAOException;
void ExpireOneTimeToken (String oneTimeToken); /**
* Expire the OTP
* @param oneTimeToken OTP
* @throws OTPManagementDAOException if error occurred while updating the OTP validity.
*/
void expireOneTimeToken(String oneTimeToken) throws OTPManagementDAOException;
/**
* Update OTP with renewed OTP
* @param id ID
* @param oneTimeToken One Time Token
* @throws OTPManagementDAOException if error occured while updating OTP
*/
void renewOneTimeToken(int id, String oneTimeToken) throws OTPManagementDAOException;
} }

@ -140,7 +140,66 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM
} }
@Override @Override
public void ExpireOneTimeToken (String oneTimeToken) { public void expireOneTimeToken(String oneTimeToken) throws OTPManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to update an OTP data entry for OTP");
log.debug("OTP Details : OTP key : " + oneTimeToken );
}
String sql = "UPDATE DM_OTP_DATA "
+ "SET "
+ "IS_EXPIRED = ? "
+ "WHERE OTP_TOKEN = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setBoolean(1, true);
stmt.setString(2, oneTimeToken);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to update the OTP token validity.";
log.error(msg, e);
throw new OTPManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when obtaining database connection for updating the OTP token validity.";
log.error(msg, e);
throw new OTPManagementDAOException(msg, e);
}
}
@Override
public void renewOneTimeToken(int id, String oneTimeToken) throws OTPManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to update an OTP data entry for OTP");
log.debug("OTP Details : OTP key : " + oneTimeToken );
}
String sql = "UPDATE DM_OTP_DATA "
+ "SET "
+ "OTP_TOKEN = ? "
+ "CREATED_AT = ? "
+ "WHERE ID = ?";
try {
Connection conn = this.getDBConnection();
Calendar calendar = Calendar.getInstance();
Timestamp timestamp = new Timestamp(calendar.getTime().getTime());
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, oneTimeToken);
stmt.setTimestamp(2, timestamp);
stmt.setInt(3, id);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to update the OTP token validity.";
log.error(msg, e);
throw new OTPManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when obtaining database connection for updating the OTP token validity.";
log.error(msg, e);
throw new OTPManagementDAOException(msg, e);
}
} }
} }

@ -20,21 +20,26 @@ import com.google.gson.Gson;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException; import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException;
import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException; 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.OTPManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException; import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO; import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OTPMailDTO;
import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.device.mgt.common.spi.OTPManagementService;
import org.wso2.carbon.device.mgt.core.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAO; import org.wso2.carbon.device.mgt.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.OTPMailWrapper;
import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAOFactory; 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.exception.OTPManagementDAOException;
import org.wso2.carbon.device.mgt.core.otp.mgt.util.ConnectionManagerUtil; import org.wso2.carbon.device.mgt.core.otp.mgt.util.ConnectionManagerUtil;
import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo;
import java.sql.Time;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.Calendar; import java.util.Calendar;
import java.util.Properties;
import java.util.UUID; import java.util.UUID;
public class OTPManagementServiceImpl implements OTPManagementService { public class OTPManagementServiceImpl implements OTPManagementService {
@ -108,6 +113,11 @@ public class OTPManagementServiceImpl implements OTPManagementService {
} }
if (otpMailDTO.isExpired()) { if (otpMailDTO.isExpired()) {
log.warn("Token is expired. OTP: " + oneTimeToken);
return false;
}
if (otpMailDTO.isTenantCreated()) {
log.warn("Tenant is already created for the token. OTP: " + oneTimeToken);
return false; return false;
} }
@ -117,12 +127,14 @@ public class OTPManagementServiceImpl implements OTPManagementService {
otpMailDTO.getCreatedAt().getTime() + otpMailDTO.getExpiryTime() * 1000); otpMailDTO.getCreatedAt().getTime() + otpMailDTO.getExpiryTime() * 1000);
if (currentTimestamp.after(expiredTimestamp)) { if (currentTimestamp.after(expiredTimestamp)) {
//todo update the DB String renewedOTP = UUID.randomUUID().toString();
renewOTP(otpMailDTO, renewedOTP);
Gson gson = new Gson();
OTPMailWrapper otpMailWrapper = gson.fromJson(otpMailDTO.getMetaInfo(), OTPMailWrapper.class);
resendUserVerifyingMail(otpMailWrapper.getFirstName(), renewedOTP, otpMailDTO.getEmail());
return false; return false;
} }
return true; return true;
} }
/** /**
@ -184,4 +196,58 @@ public class OTPManagementServiceImpl implements OTPManagementService {
} }
return true; return true;
} }
/**
* If OTP expired, resend the user verifying mail with renewed OTP
* @param firstName First Name of the User
* @param renewedOTP Renewed OTP
* @param mailAddress Mail Address of the User
* @throws OTPManagementException if error occurred while resend the user verifying mail
*/
private void resendUserVerifyingMail(String firstName, String renewedOTP, String mailAddress)
throws OTPManagementException {
Properties props = new Properties();
props.setProperty("first-name", firstName);
props.setProperty("otp-token", renewedOTP);
EmailMetaInfo metaInfo = new EmailMetaInfo(mailAddress, props);
try {
DeviceManagementDataHolder.getInstance().getDeviceManagementProvider()
.sendEnrolmentInvitation(DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE, metaInfo);
} catch (DeviceManagementException e) {
e.printStackTrace();
throw new OTPManagementException(e);
} catch (ConfigurationManagementException e) {
throw new OTPManagementException(e);
}
}
/**
* Renew the OTP
* @param otpMailDTO {@link OTPMailDTO}
* @param renewedOTP Renewed OTP
* @throws OTPManagementException if error occurred while renew the OTP
*/
private void renewOTP(OTPMailDTO otpMailDTO, String renewedOTP) throws OTPManagementException {
try {
ConnectionManagerUtil.beginDBTransaction();
this.otpManagementDAO.renewOneTimeToken(otpMailDTO.getId(), renewedOTP);
ConnectionManagerUtil.commitDBTransaction();
} catch (TransactionManagementException e) {
String msg = "Error occurred while disabling AutoCommit to renew the OTP.";
log.error(msg, e);
throw new OTPManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "Error occurred while getting database connection to renew the OTP.";
log.error(msg, e);
throw new OTPManagementException(msg, e);
} catch (OTPManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while renew the OTP. OTP: " + renewedOTP;
log.error(msg, e);
throw new OTPManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
} }

@ -20,7 +20,6 @@ package org.wso2.carbon.webapp.authenticator.framework.authenticator;
import org.apache.catalina.connector.Response; import org.apache.catalina.connector.Response;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.general.OneTimeTokenDetails;
import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.device.mgt.common.spi.OTPManagementService;
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo; import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo;
import org.wso2.carbon.webapp.authenticator.framework.Constants; import org.wso2.carbon.webapp.authenticator.framework.Constants;
@ -45,25 +44,21 @@ public class OneTimeTokenAuthenticator implements WebappAuthenticator {
OTPManagementService otpManagementService = AuthenticatorFrameworkDataHolder.getInstance() OTPManagementService otpManagementService = AuthenticatorFrameworkDataHolder.getInstance()
.getOtpManagementService(); .getOtpManagementService();
String token = request.getHeader(Constants.HTTPHeaders.ONE_TIME_TOKEN_HEADER);
// DeviceMgtAPIUtils.getDeviceManagementService();//TODO: call token validate service in core
OneTimeTokenDetails tokenDetails = new OneTimeTokenDetails();//TODO: use token details
AuthenticationInfo authenticationInfo = new AuthenticationInfo(); AuthenticationInfo authenticationInfo = new AuthenticationInfo();
try { try {
authenticationInfo.setTenantDomain(tokenDetails.getDomain()); if (otpManagementService.isValidOTP(request.getHeader(Constants.HTTPHeaders.ONE_TIME_TOKEN_HEADER))) {
authenticationInfo.setStatus(Status.CONTINUE); authenticationInfo.setStatus(Status.CONTINUE);
//authenticationInfo.setUsername(tokenDetails.get); //TODO: set username authenticationInfo.setTenantId(-1);
//authenticationInfo.setTenantId();//TODO: set tenant Id } else {
} catch (Exception e) { // TODO: remove this if not needed
authenticationInfo.setStatus(Status.FAILURE); authenticationInfo.setStatus(Status.FAILURE);
authenticationInfo.setMessage("Could not identify tenant domain."); authenticationInfo.setMessage("Invalid OTP token.");
} }
} catch (Exception e) {
return null; authenticationInfo.setStatus(Status.FAILURE);
authenticationInfo.setMessage("CToken Validation Failed.");
}
return authenticationInfo;
} }
public String getName() { public String getName() {

Loading…
Cancel
Save