package at.asitplus.eidas.specific.modules.auth.eidas.v2.test; import static at.asitplus.eidas.specific.connector.MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE; import java.io.IOException; import java.net.URISyntaxException; import java.util.Arrays; import java.util.Base64; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang3.RandomStringUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import at.asitplus.eidas.specific.connector.test.config.dummy.MsConnectorDummyConfigMap; import at.asitplus.eidas.specific.connector.test.config.dummy.MsConnectorDummySpConfiguration; import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; import at.asitplus.eidas.specific.modules.auth.eidas.v2.EidasSignalServlet; import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.CreateIdentityLinkTask; import at.asitplus.eidas.specific.modules.auth.eidas.v2.test.dummy.DummySpecificCommunicationService; import at.gv.egiz.eaaf.core.api.IRequestStorage; import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants; import at.gv.egiz.eaaf.core.api.data.EaafConstants; import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage; import at.gv.egiz.eaaf.core.exceptions.EaafException; import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; import at.gv.egiz.eaaf.core.impl.idp.module.test.DummyProtocolAuthService; import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl; import at.gv.egiz.eaaf.core.impl.utils.Random; import eu.eidas.auth.commons.EidasParameterKeys; import eu.eidas.auth.commons.protocol.impl.AuthenticationResponse; import eu.eidas.auth.commons.protocol.impl.AuthenticationResponse.Builder; import eu.eidas.auth.commons.tx.BinaryLightToken; import eu.eidas.specificcommunication.exception.SpecificCommunicationException; @RunWith(SpringJUnit4ClassRunner.class) @PrepareForTest(CreateIdentityLinkTask.class) @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) @ContextConfiguration(locations = { "/SpringTest-context_tasks_test.xml", "/SpringTest-context_basic_mapConfig.xml"}) @EnableWebMvc public class EidasSignalServletTest { @Autowired private MsConnectorDummyConfigMap basicConfig; @Autowired private EidasSignalServlet controller; @Autowired private IRequestStorage storage; @Autowired private ITransactionStorage transStore; @Autowired private DummyProtocolAuthService protAuthService; @Autowired private DummySpecificCommunicationService connector; private MockHttpServletRequest httpReq; private MockHttpServletResponse httpResp; private TestRequestImpl pendingReq; private MsConnectorDummySpConfiguration oaParam; /** * jUnit test set-up. */ @Before public void setUp() throws EaafStorageException, URISyntaxException { httpReq = new MockHttpServletRequest("POST", "https://localhost/authhandler"); httpResp = new MockHttpServletResponse(); RequestContextHolder.resetRequestAttributes(); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp)); final Map spConfig = new HashMap<>(); spConfig.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, "testSp"); spConfig.put("target", "urn:publicid:gv.at:cdid+XX"); spConfig.put(PROP_CONFIG_SP_NEW_EID_MODE, "true"); oaParam = new MsConnectorDummySpConfiguration(spConfig, basicConfig); oaParam.setLoa(Arrays.asList(EaafConstants.EIDAS_LOA_HIGH)); pendingReq = new TestRequestImpl(); pendingReq.setSpConfig(oaParam); pendingReq.setPendingReqId(at.gv.egiz.eaaf.core.impl.utils.Random.nextProcessReferenceValue()); pendingReq.setAuthUrl("http://test.com/"); pendingReq.setTransactionId("avaasbav"); pendingReq.setPiiTransactionId(RandomStringUtils.randomAlphanumeric(10)); connector.setiLightResponse(null); } @Test public void noResponsToken() throws IOException, EaafException { //set-up //execute test controller.restoreEidasAuthProcess(httpReq, httpResp); //validate state Assert.assertNull("eIDAS response", httpReq.getAttribute(Constants.DATA_FULL_EIDAS_RESPONSE)); Assert.assertNotNull("missing error", protAuthService.getException()); Assert.assertEquals("Wrong errorId", "auth.26", ((EaafException) protAuthService.getException()).getErrorId()); } @Test public void unknownResponseToken() throws IOException, EaafException { //set-up httpReq.setParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); //execute test controller.restoreEidasAuthProcess(httpReq, httpResp); //validate state Assert.assertNull("eIDAS response", httpReq.getAttribute(Constants.DATA_FULL_EIDAS_RESPONSE)); Assert.assertNotNull("missing error", protAuthService.getException()); Assert.assertEquals("Wrong errorId", "auth.26", ((EaafException) protAuthService.getException()).getErrorId()); } @Test public void withRelayState() throws IOException, EaafException, SpecificCommunicationException { //set-up String relayState = RandomStringUtils.randomAlphanumeric(10); pendingReq.setPendingReqId(relayState); storage.storePendingRequest(pendingReq); Builder iLightResponse = new AuthenticationResponse.Builder(); iLightResponse.id("_".concat(Random.nextHexRandom16())) .issuer(RandomStringUtils.randomAlphabetic(10)) .subject(RandomStringUtils.randomAlphabetic(10)) .statusCode(Constants.SUCCESS_URI) .inResponseTo("_".concat(Random.nextHexRandom16())) .subjectNameIdFormat("afaf") .relayState(relayState); AuthenticationResponse eidasResp = iLightResponse.build(); BinaryLightToken token = connector.putResponse(eidasResp); httpReq.setParameter(EidasParameterKeys.TOKEN.toString(), Base64.getEncoder().encodeToString(token.getTokenBytes())); //execute test controller.restoreEidasAuthProcess(httpReq, httpResp); //validate state Assert.assertNotNull("eIDAS response", httpReq.getAttribute(Constants.DATA_FULL_EIDAS_RESPONSE)); Assert.assertEquals("wrong eIDAS response", eidasResp, httpReq.getAttribute(Constants.DATA_FULL_EIDAS_RESPONSE)); Assert.assertNotNull("missing error", protAuthService.getException()); Assert.assertEquals("Wrong errorId", "PendingRequest object is not of type 'RequestImpl.class'", ((EaafException) protAuthService.getException()).getErrorId()); } @Test public void withOutRelayStateMissingPendingReq() throws IOException, EaafException, SpecificCommunicationException { //set-up String pendingReqId = RandomStringUtils.randomAlphanumeric(10); pendingReq.setPendingReqId(pendingReqId); storage.storePendingRequest(pendingReq); String inResponseTo = "_".concat(Random.nextHexRandom16()); Builder iLightResponse = new AuthenticationResponse.Builder(); iLightResponse.id("_".concat(Random.nextHexRandom16())) .issuer(RandomStringUtils.randomAlphabetic(10)) .subject(RandomStringUtils.randomAlphabetic(10)) .statusCode(Constants.SUCCESS_URI) .inResponseTo(inResponseTo) .subjectNameIdFormat("afaf"); AuthenticationResponse eidasResp = iLightResponse.build(); BinaryLightToken token = connector.putResponse(eidasResp); httpReq.setParameter(EidasParameterKeys.TOKEN.toString(), Base64.getEncoder().encodeToString(token.getTokenBytes())); //execute test controller.restoreEidasAuthProcess(httpReq, httpResp); //validate state Assert.assertNull("eIDAS response", httpReq.getAttribute(Constants.DATA_FULL_EIDAS_RESPONSE)); Assert.assertNotNull("missing error", protAuthService.getException()); Assert.assertEquals("Wrong errorId", "auth.26", ((EaafException) protAuthService.getException()).getErrorId()); } @Test public void withInResponseToElement() throws IOException, EaafException, SpecificCommunicationException { //set-up String pendingReqId = RandomStringUtils.randomAlphanumeric(10); pendingReq.setPendingReqId(pendingReqId); storage.storePendingRequest(pendingReq); String inResponseTo = "_".concat(Random.nextHexRandom16()); transStore.put(inResponseTo, pendingReqId, -1); Builder iLightResponse = new AuthenticationResponse.Builder(); iLightResponse.id("_".concat(Random.nextHexRandom16())) .issuer(RandomStringUtils.randomAlphabetic(10)) .subject(RandomStringUtils.randomAlphabetic(10)) .statusCode(Constants.SUCCESS_URI) .inResponseTo(inResponseTo) .subjectNameIdFormat("afaf"); AuthenticationResponse eidasResp = iLightResponse.build(); BinaryLightToken token = connector.putResponse(eidasResp); httpReq.setParameter(EidasParameterKeys.TOKEN.toString(), Base64.getEncoder().encodeToString(token.getTokenBytes())); //execute test controller.restoreEidasAuthProcess(httpReq, httpResp); //validate state Assert.assertNotNull("eIDAS response", httpReq.getAttribute(Constants.DATA_FULL_EIDAS_RESPONSE)); Assert.assertEquals("wrong eIDAS response", eidasResp, httpReq.getAttribute(Constants.DATA_FULL_EIDAS_RESPONSE)); Assert.assertNotNull("missing error", protAuthService.getException()); Assert.assertEquals("Wrong errorId", "PendingRequest object is not of type 'RequestImpl.class'", ((EaafException) protAuthService.getException()).getErrorId()); } }