package com.fp.general.security.rules; import java.util.List; import com.fp.common.base64.Base64Input; import com.fp.dto.rules.TransactionRule; import com.fp.dto.save.SaveRequest; import com.fp.general.exception.GeneralException; import com.fp.persistence.commondb.PersistenceHelper; import com.fp.persistence.commondb.helper.FormatDates; import com.fp.persistence.pgeneral.safe.TsafePassword; import com.fp.persistence.pgeneral.safe.TsafePasswordKey; import com.fp.persistence.pgeneral.safe.TsafeUserDetail; import com.fp.persistence.pgeneral.safe.TsafeUserDetailKey; /** * Clase que se encarga de validar la politica de seguridad definida en TsafePassword. * * @author Jorge Vaca. * @version 2.1 */ public class Politics extends TransactionRule { /***/ private static final String UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZÁÉÍÓÚÑ"; private static final String LOWER = "abcdefghijklmnopqrstuvwxyzáéíóúñ"; private static final String NUMBERS = "0123456789"; /** Tabla que almnacena politica de seguridad del password. */ private TsafePassword tsafePassword = null; private Integer numeric = 0; private Integer upper = 0; private Integer lower = 0; private Integer special = 0; /** * Metodo que caduca el registro vigente del inicio de sesion * * @param pSaveRequest Datos del request original. * @return SaveRequest * @throws Exception */ @Override public SaveRequest normalProcess(SaveRequest pSaveRequest) throws Exception { TsafeUserDetail tsafeUserDetailForm = (TsafeUserDetail) pSaveRequest.getSaveBeanModifiedObject("TSAFEUSERDETAIL"); TsafeUserDetailKey tsafeUserDetailKey = new TsafeUserDetailKey(tsafeUserDetailForm.getPk().getUsercode(), tsafeUserDetailForm.getPk() .getPersoncode(), FormatDates.getDefaultExpiryTimestamp()); TsafeUserDetail tsafeUserDetail = TsafeUserDetail.find(PersistenceHelper.getEntityManager(), tsafeUserDetailKey); TsafePasswordKey key = new TsafePasswordKey(pSaveRequest.getCompany(), pSaveRequest.getChannelCode()); this.tsafePassword = TsafePassword.find(PersistenceHelper.getEntityManager(), key); String value = tsafeUserDetailForm.get("origination").toString(); String oldpassword = tsafeUserDetailForm.get("oldpassword").toString(); String passindatabase = tsafeUserDetail.getPassword(); if(pSaveRequest.isJsf()){ passindatabase = ((TsafeUserDetail)tsafeUserDetailForm.get("ORIGINALBEAN")).getPassword(); value = tsafeUserDetailForm.get("newpassword").toString(); } if ((oldpassword != null) && (oldpassword.compareTo("") != 0) && (passindatabase.compareTo(oldpassword) != 0)) { throw new GeneralException("GENE-0025", "CONTRASEÑA ANTERIOR INCORRECTA"); } // Valida politica de seguridad this.validate(value, pSaveRequest.isJsf()); // Valida que no se repitan los ultimos n passwords this.validateNotrepeated(tsafeUserDetailForm, tsafeUserDetailForm.get("origination").toString() ); return pSaveRequest; } /** * Metodo que valida la politica de seguridad del password. * * @param value Password en base 64. * @throws Exception */ private void validate(String value, boolean isjsf) throws Exception { // OBTIENE EL PASSWORD EN CARACTER if(!isjsf){ value = Base64Input.decodificar(value); } this.validateLength(value); for (int i = 0; i < value.length(); i++) { String c = value.substring(i, i + 1); this.compute(c); } this.validateNumbers(); this.validateUppercase(); this.validateLowercase(); this.validateSpecial(); } /** * Metodo que valida la longitud del password. * * @param value Datos de la clave a validar. * @return boolean * @throws Exception */ private void validateLength(String value) throws Exception { if ((this.tsafePassword.getMinlength() != null) && (value.length() < this.tsafePassword.getMinlength())) { throw new GeneralException("GENE-0030", "LA LONGITUD MÍNIMA DE LA CONTRASEÑA DEBE SER DE {0} CARACTERES", this.tsafePassword.getMinlength()); } } /** * Metodo que valida numeros minimos en el password. * * @throws Exception */ private void validateNumbers() throws Exception { if ((this.tsafePassword.getMinnumber() != null) && (this.tsafePassword.getMinnumber() > 0) && (this.tsafePassword.getMinnumber() > this.numeric)) { throw new GeneralException("GENE-0029", "LA CONTRASEÑA DEBE TENER POR LO MENOS {0} NÚMEROS", this.tsafePassword.getMinnumber()); } } /** * Metodo que valida letras mayusculas minimas en el password. * * @throws Exception */ private void validateUppercase() throws Exception { if ((this.tsafePassword.getMinuppercase() != null) && (this.tsafePassword.getMinuppercase() > 0) && (this.tsafePassword.getMinuppercase() > this.upper)) { throw new GeneralException("GENE-0028", "LA CONTRASEÑA DEBE TENER POR LO MENOS {0} LETRAS MAYÚSCULAS", this.tsafePassword.getMinuppercase()); } } /** * Metodo que valida letras minusculas minimas en el password. * * @throws Exception */ private void validateLowercase() throws Exception { if ((this.tsafePassword.getMinlowercase() != null) && (this.tsafePassword.getMinlowercase() > 0) && (this.tsafePassword.getMinlowercase() > this.lower)) { throw new GeneralException("GENE-0026", "LA CONTRASEÑA DEBE TENER POR LO MENOS {0} LETRAS MINÚSCULAS", this.tsafePassword.getMinlowercase()); } } /** * Metodo que valida los caracteres especiales. * * @throws Exception */ private void validateSpecial() throws Exception { if ((this.tsafePassword.getMinspecialcharacters() != null) && (this.tsafePassword.getMinspecialcharacters() > 0) && (this.tsafePassword.getMinspecialcharacters() > this.special)) { throw new GeneralException("GENE-0027", "LA CONTRASEÑA DEBE TENER POR LO MENOS {0} CARACTERES ESPECIALES", this.tsafePassword.getMinspecialcharacters()); } } /** * Valida que el password no se repita en las ultimas n veces. * * @param obj Datos del nuevo password. * @throws Exception */ private void validateNotrepeated(TsafeUserDetail useerdetail, String passindatabase) throws Exception { if ((this.tsafePassword.getMinnotrepeated() == null) || (this.tsafePassword.getMinnotrepeated().compareTo(0) == 0)) { return; } List ldata = TsafeUserDetail.find(PersistenceHelper.getEntityManager(), useerdetail.getPk().getUsercode(), this.tsafePassword.getMinnotrepeated()); if ((ldata == null) || ldata.isEmpty()) { return; } for (TsafeUserDetail obj : ldata) { if(obj.get("ORIGINALBEAN") != null){ continue; } PersistenceHelper.detatch(obj); if (obj.getPassword().compareTo(passindatabase) == 0) { throw new GeneralException("GENE-0022", "NO PUEDE REPETIR LAS ÚLTIMAS: {0} CONTRASEÑAS", this.tsafePassword.getMinnotrepeated()); } } } /** * Metodo que se encarga de acumular, numeros, mayusculas y/o minusculas. * * @param c Datoa a verificar. * @throws Exception */ private void compute(String c) throws Exception { if (this.isNumber(c)) { this.numeric++; return; } if (this.isUppercase(c)) { this.upper++; return; } if (this.isLowercase(c)) { this.lower++; return; } // Si no es numero, mayuscula o minuscula es un caractwer especial this.special++; } /** * Metdo que verifica si el caracter es un numero. * * @param value Dato a verificar si es un numero * @return boolean * @throws Exception */ private boolean isNumber(String value) throws Exception { if (Politics.NUMBERS.indexOf(value) >= 0) { return true; } return false; } /** * Metdo que verifica si el caracter es una mayuscula, incluye tildes. * * @param value Dato a verificar si es una mayuscula * @return boolean * @throws Exception */ private boolean isUppercase(String value) throws Exception { if (Politics.UPPER.indexOf(value) >= 0) { return true; } return false; } /** * Metdo que verifica si el caracter es una minuscula incluye tildes. * * @param value Dato a verificar si es una minuscula * @return boolean * @throws Exception */ private boolean isLowercase(String value) throws Exception { if (Politics.LOWER.indexOf(value) >= 0) { return true; } return false; } /** * Metodo que se ejecuta en modo reverso * * @param pSaveRequest * @return SaveRequest * @throws Exception */ @Override public SaveRequest reverseProcess(SaveRequest pSaveRequest) throws Exception { return pSaveRequest; } }