package at.gv.egovernment.moa.id.auth.modules.ehvd.service; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import javax.annotation.Nonnull; import javax.annotation.PostConstruct; import javax.xml.ws.BindingProvider; import javax.xml.ws.handler.Handler; import javax.xml.ws.soap.SOAPFaultException; import org.apache.commons.lang3.StringUtils; import org.apache.cxf.endpoint.Client; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.transport.http.HTTPConduit; import org.apache.cxf.transports.http.configuration.ProxyServerType; import org.springframework.beans.factory.annotation.Autowired; import at.gv.egiz.eaaf.core.api.data.PVPAttributeDefinitions; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; import at.gv.egiz.eaaf.core.exceptions.EAAFBuilderException; import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException; import at.gv.egiz.eaaf.core.impl.data.Pair; import at.gv.egiz.eaaf.core.impl.idp.auth.builder.BPKBuilder; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.auth.modules.ehvd.ConfigurationProperties; import at.gv.egovernment.moa.id.auth.modules.ehvd.client.wsdl.EHVD; import at.gv.egovernment.moa.id.auth.modules.ehvd.client.wsdl.EHVDService; import at.gv.egovernment.moa.id.auth.modules.ehvd.client.wsdl.GdaDescriptor; import at.gv.egovernment.moa.id.auth.modules.ehvd.client.wsdl.GdaIndexResponse; import at.gv.egovernment.moa.id.auth.modules.ehvd.client.wsdl.GetGdaDescriptors; import at.gv.egovernment.moa.id.auth.modules.ehvd.client.wsdl.InstanceIdentifier; import at.gv.egovernment.moa.id.auth.modules.ehvd.exception.EhvdException; import at.gv.egovernment.moa.logging.Logger; import at.gv.util.LoggingHandler; /** * Implement interaction with EHVD service to get GDA information. * * @author tlenz * */ public class EhvdCommunicationService implements IEhvdCommunication { private static final String GDA_RESP_STATUS_ACTIVE = "Aktiv"; private static final String ERROR_EHVD_00 = "ehvd.00"; private static final String ERROR_EHVD_01 = "ehvd.01"; private static final String ERROR_EHVD_02 = "ehvd.02"; private static final String ERROR_CONFIG_05 = "config.05"; @Autowired IConfiguration config; private String ehvdBpkTarget; private EHVD ehvdClient; /** * Get user's GDA roles from EHVD Service. * * @param identityLink IdentityLink of the user * @return {@link List} of Roles that are received from EHVD * @throws AuthenticationException In case of an EHVD communication error * @throws EAAFBuilderException In case of a bPK generation error */ @Override @Nonnull public List getRoles(IIdentityLink identityLink) throws AuthenticationException, EAAFBuilderException { // get bPK for EHVD request final Pair ehvdBpk = BPKBuilder.generateAreaSpecificPersonIdentifier( identityLink.getIdentificationValue(), identityLink.getIdentificationType(), ehvdBpkTarget); // request EHVD and handle errors final GdaIndexResponse gdaResp = requestingGda(ehvdBpk.getFirst()); // parse roles from response return parseGdaResponse(gdaResp); } @Nonnull private GdaIndexResponse requestingGda(String bpk) throws EhvdException { try { final GetGdaDescriptors gdaReq = buildGdaRequest(bpk); Logger.debug("Requesting EHVD to get GDA status ... "); final GdaIndexResponse gdaResp = ehvdClient.getGDA(gdaReq); Logger.debug("Receive GDA status. Starting response validation ... "); return gdaResp; } catch (final SOAPFaultException e) { // extract reason for this error String errorMsg = e.getFault() != null ? StringUtils.isNotEmpty(e.getFault().getFaultString()) ? e.getFault().getFaultString() : e.getMessage() : e.getMessage(); Logger.warn("EHVD communication failed with SOAP response: " + errorMsg, e); throw new EhvdException(ERROR_EHVD_02, new Object[] {errorMsg}, e); } catch (final Exception e) { Logger.error("EHVD communication failed with generic error: " + e.getMessage(), e); throw new EhvdException(ERROR_EHVD_01, new Object[] {}, e); } } private List parseGdaResponse(GdaIndexResponse ehvdResp) throws EhvdException { if (ehvdResp.getGda() != null) { final GdaDescriptor gdaInfo = ehvdResp.getGda(); if (GDA_RESP_STATUS_ACTIVE.equals(gdaInfo.getStatus().getEhvdstatus())) { Logger.debug("Find #" + gdaInfo.getRoles().getRole().size() + " roles"); return gdaInfo.getRoles().getRole(); } else { Logger.info("GDA is marked as 'inactive'. Stopping process with an error ... "); throw new EhvdException(ERROR_EHVD_00, null); } } else { Logger.debug("Receive empty GDA response"); // TODO: what we to in case of empty response? } return Collections.emptyList(); } private GetGdaDescriptors buildGdaRequest(String bPK) { final GetGdaDescriptors req = new GetGdaDescriptors(); final InstanceIdentifier gdaIdentifier = new InstanceIdentifier(); gdaIdentifier.setOidIssuingAuthority(PVPAttributeDefinitions.BPK_OID); gdaIdentifier.setId(bPK); req.setHcIdentifier(gdaIdentifier); return req; } @PostConstruct private void initialize() throws EAAFConfigurationException { if (config.getBasicConfigurationBoolean(ConfigurationProperties.PROP_MODULE_ENABLED, false)) { initializeEhvdClient(); ehvdBpkTarget = config.getBasicConfiguration( ConfigurationProperties.PROP_MODULE_SERVICE_TARGET, ConfigurationProperties.DEFAULT_EHVD_SERVICE_TARGET); Logger.info("Set-up EHVD Client with bPK target: " + ehvdBpkTarget); } else { Logger.info("Skipping EHVD client because it's not active"); } } private void initializeEhvdClient() throws EAAFConfigurationException { Logger.debug("Initializing EHVD client ... "); final URL url = EhvdCommunicationService.class.getResource("/wsdl/eHVD.wsdl"); final EHVDService service = new EHVDService(url); ehvdClient = service.getEHVDPort12(); // load service end-point URL from configuration final String ehvdEndpointUrl = config.getBasicConfiguration( ConfigurationProperties.PROP_MODULE_SERVICE_ENDPOINT); if (StringUtils.isEmpty(ehvdEndpointUrl)) { Logger.error("Missing configuration for EHVD WebService endpoint. " + "(Property: " + ConfigurationProperties.PROP_MODULE_SERVICE_ENDPOINT + ")"); throw new EAAFConfigurationException(ERROR_CONFIG_05, new Object[] { ConfigurationProperties.PROP_MODULE_SERVICE_ENDPOINT }); } // inject service end-point URL final Map requestContext = ((BindingProvider) ehvdClient).getRequestContext(); requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, ehvdEndpointUrl); // inject Logging handler List handlerList = ((BindingProvider) ehvdClient).getBinding().getHandlerChain(); if (handlerList == null) { handlerList = new ArrayList<>(); } handlerList.add(new LoggingHandler()); ((BindingProvider) ehvdClient).getBinding().setHandlerChain(handlerList); Logger.info("Initialize EHVD Client with service end-point: " + ehvdEndpointUrl); // these code is only for local testing String socksPort = config.getBasicConfiguration(ConfigurationProperties.PROP_MODULE_PROXY_SOCKS_PORT); if (StringUtils.isNotEmpty(socksPort)) { Logger.warn("Injecting SOCKS5 Proxy for service communication!"); final Client client = ClientProxy.getClient(ehvdClient); final HTTPConduit http = (HTTPConduit) client.getConduit(); http.getClient().setProxyServerType(ProxyServerType.SOCKS); http.getClient().setProxyServer("127.0.0.1"); http.getClient().setProxyServerPort(Integer.valueOf(socksPort)); } } }