package gov.va.med.edp.springframework.security.userdetails.vistalink; import gov.va.med.crypto.VistaKernelHash; import gov.va.med.crypto.VistaKernelHashCountLimitExceededException; import gov.va.med.vistalink.adapter.cci.VistaLinkConnectionSpecImpl; import org.w3c.dom.CDATASection; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; class VistaLinkAccessVerifyConnectionSpec extends VistaLinkConnectionSpecImpl { private static final String TYPE_AV = "av"; private static final String ELEMENT_AV = "AccessVerify"; private static final String ATTRIBUTE_AVCODE = "avCode"; private String accessCode; private String verifyCode; private String clientIp; private String avCode; private static Logger logger = LoggerFactory.getLogger(VistaLinkAccessVerifyConnectionSpec.class); /** * Main constructor for this connection spec. * * @param division station # (external format) of the division to log the user in against * @param accessCode user access code * @param verifyCode user verify code */ public VistaLinkAccessVerifyConnectionSpec( String division, String accessCode, String verifyCode, String clientIp) { super(division); this.accessCode = accessCode; this.verifyCode = verifyCode; this.clientIp = clientIp; this.avCode = ""; try { this.avCode = VistaKernelHash.encrypt( accessCode + ";" + verifyCode + ";" + clientIp, true); } catch (VistaKernelHashCountLimitExceededException e) { logger.error("Could not encrypt access/verify code", e); } } public ArrayList getProprietarySecurityInfo() { ArrayList values = new ArrayList(); values.add(this.avCode); return values; } public void setAuthenticationNodes( Document requestDoc, Node securityNode) { if (logger.isDebugEnabled()) { logger.debug("setAuthenticationNodes -> Re Auth type is 'av'"); } //AC/OAK OIFO - Next line commented out and replaced by following line as required for upgrading to VL 1.5 dev17: // setSecurityDivision(securityNode, this.getDivision()); setSecurityDivisionAttr(securityNode); //AC/OAK OIFO - Next line commented out and replaced by following line as required for upgrading to VL 1.5 dev17: // setSecurityType(securityNode, TYPE_AV); setSecurityTypeAttr(securityNode); Element elemAV = requestDoc.createElement(ELEMENT_AV); /* add CDATA section for encoded AV code */ CDATASection cdata = requestDoc.createCDATASection(this.avCode); Node currentAvCdataNode = elemAV.getFirstChild(); if (currentAvCdataNode != null) { elemAV.removeChild(currentAvCdataNode); } elemAV.appendChild(cdata); securityNode.appendChild(elemAV); } /** * checks equality with any object */ public boolean isConnSpecEqual(Object obj) { return equals(obj); } /** * @return whether the object is equal */ public boolean equals(Object obj) { if (obj instanceof VistaLinkAccessVerifyConnectionSpec) { VistaLinkAccessVerifyConnectionSpec connSpec = (VistaLinkAccessVerifyConnectionSpec) obj; if ((connSpec.getDivision().equals(this.getDivision())) && (connSpec.getAccessCode().equals(this.getAccessCode())) && (connSpec.getVerifyCode().equals(this.getVerifyCode())) && (connSpec.getClientIp().equals(this.getClientIp()))) { return true; } } return false; } /** * @return the hashCode */ public int hashCode() { // algorithm taken from "Effective Java" item #8. int HASHCODE_SEED = 17; int returnVal = HASHCODE_SEED; // division contribution to hashcode int divisionHashCode = this.getDivision().hashCode(); returnVal = 37 * returnVal + divisionHashCode; // Access code contribution to hashcode int accessHashCode = this.getAccessCode().hashCode(); returnVal = 37 * returnVal + accessHashCode; // Verify code contribution to hashcode int verifyHashCode = this.getVerifyCode().hashCode(); returnVal = 37 * returnVal + verifyHashCode; // Client IP contribution to hashcode int clientIPHashCode = this.getClientIp().hashCode(); returnVal = 37 * returnVal + clientIPHashCode; return returnVal; } /** * @return the client ip address */ public String getClientIp() { return this.clientIp; } /** * @return the internal access code */ public String getAccessCode() { return accessCode; } /** * @return the internal verify code */ public String getVerifyCode() { return verifyCode; } /** * returns the security type. */ public String getSecurityType() { return TYPE_AV; } }