package gov.va.med.edp.springframework.security.userdetails.vistalink; import gov.va.med.edp.springframework.security.userdetails.VistaUserDetails; import gov.va.med.edp.springframework.security.userdetails.VistaUserDetailsService; import gov.va.med.edp.vistalink.ConnectionFactoryLocator; import gov.va.med.edp.vistalink.VistaLinkDaoSupport; import gov.va.med.edp.vistalink.VistaLinkTemplate; import org.springframework.security.BadCredentialsException; import org.springframework.security.GrantedAuthority; import org.springframework.security.GrantedAuthorityImpl; import org.springframework.dao.DataAccessException; import org.springframework.util.StringUtils; import org.springframework.util.Assert; import java.util.ArrayList; import java.util.List; public class VistaLinkUserDetailService extends VistaLinkDaoSupport implements VistaUserDetailsService { static final int DEFAULT_TIMEOUT = 600; static final String RPC_CONTEXT = "XUS KAAJEE WEB LOGON"; static final String GET_USER_INFO_RPC = "XUS KAAJEE GET USER INFO"; static final String LOGOUT_RPC_NAME = "XUS KAAJEE LOGOUT"; private String applicationName; protected void checkDaoConfig() throws IllegalArgumentException { Assert.hasText(applicationName, "''applicationName' must not be empty"); super.checkDaoConfig(); } protected VistaLinkTemplate createRpcTemplate(ConnectionFactoryLocator connectionFactoryLocator) { VistaLinkTemplate template = super.createRpcTemplate(connectionFactoryLocator); template.setTimeOut(DEFAULT_TIMEOUT); return template; } public VistaUserDetails login(String stationNumber, String accessCode, String verifyCode, String remoteAddress) throws BadCredentialsException, DataAccessException { if (!StringUtils.hasLength(stationNumber)) throw new BadCredentialsException("missing station number"); if (!StringUtils.hasLength(accessCode)) throw new BadCredentialsException("missing access code"); if (!StringUtils.hasLength(verifyCode)) throw new BadCredentialsException("missing verify code"); if (!StringUtils.hasLength(remoteAddress)) throw new BadCredentialsException("missing remote address"); try { String result = getRpcTemplate().rpc(new VistaLinkAccessVerifyConnectionSpec(stationNumber, accessCode, verifyCode, remoteAddress), stationNumber, null, RPC_CONTEXT, GET_USER_INFO_RPC, createLoginParams(remoteAddress)); return createVistaUserDetails(result, accessCode, verifyCode); } catch (DataAccessException e) { throw new BadCredentialsException("couldn't log in", e); } } public void logout(VistaUserDetails user) throws DataAccessException { getRpcTemplate().rpcAsUser(user.getLoginStationNumber(), user.getDuz(), RPC_CONTEXT, LOGOUT_RPC_NAME, createLogoutParams(user)); } private List createLoginParams(String remoteAddress) { List params = new ArrayList(); params.add(remoteAddress); params.add(getApplicationName()); return params; } private List createLogoutParams(VistaUserDetails user) { List params = new ArrayList(); params.add(user.getSignonLogInternalEntryNumber()); return params; } /* * Result(0) is the users DUZ. * Result(1) is the user name from the .01 field. * Result(2) is the users full name from the name standard file. * Result(3) is the FAMILY (LAST) NAME (or ^ if null) * Result(4) is the GIVEN (FIRST) NAME (or ^ if null) * Result(5) is the MIDDLE NAME (or ^ if null) * Result(6) is the PREFIX (or ^ if null) * Result(7) is the SUFFIX (or ^ if null) * Result(8) is the DEGREE (or ^ if null) * Result(9) is station # of the division that the user is working in. * Result(10) is the station # of the parent facility for the login division * Result(11) is the station # of the computer system "parent" from the KSP file. * Result(12) is the IEN of the signon log entry * Result(13) = # of permissible divisions * Result(14-n) are the permissible divisions for user login, in the format: * IEN of file 4^Station Name^Station Number^default? (1 or 0) */ protected VistaUserDetails createVistaUserDetails(String result, String accessCode, String verifyCode) { String[] results = result.split("\n"); VistaUser u = new VistaUser(results[12], results[9], results[0], accessCode, verifyCode, true, true, true, true, new GrantedAuthority[]{new GrantedAuthorityImpl("ROLE_USER")}); u.setPersonName(results[1]); u.setDisplayName(results[2]); u.setFamilyName(nullSafeGet(results[3])); u.setGivenName(nullSafeGet(results[4])); u.setMiddleName(nullSafeGet(results[5])); u.setPrefix(nullSafeGet(results[6])); u.setSuffix(nullSafeGet(results[7])); u.setDegree(nullSafeGet(results[8])); return u; } private String nullSafeGet(String value) { if (value.equals("^")) return null; return value; } public String getApplicationName() { return applicationName; } public void setApplicationName(String applicationName) { this.applicationName = applicationName; } }