package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.validation; import static at.asitplus.eidas.specific.connector.MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE; import java.net.URISyntaxException; import java.util.Arrays; 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.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.google.common.collect.ImmutableSet; import at.asitplus.eidas.specific.connector.test.config.MsConnectorDummyConfigMap; import at.asitplus.eidas.specific.connector.test.config.MsConnectorDummySpConfiguration; import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasValidationException; import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry; import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.CreateIdentityLinkTask; import at.asitplus.eidas.specific.modules.auth.eidas.v2.validator.EidasResponseValidator; import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants; import at.gv.egiz.eaaf.core.api.data.EaafConstants; import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; 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.attribute.AttributeDefinition; import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; import eu.eidas.auth.commons.attribute.ImmutableAttributeMap.Builder; import eu.eidas.auth.commons.attribute.impl.StringAttributeValue; import eu.eidas.auth.commons.light.ILightResponse; import eu.eidas.auth.commons.protocol.impl.AuthenticationResponse; import lombok.val; @RunWith(SpringJUnit4ClassRunner.class) @PrepareForTest(CreateIdentityLinkTask.class) @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) @ContextConfiguration(locations = { "/SpringTest-context_tasks_test.xml", "/SpringTest-context_basic_mapConfig.xml"}) public class EidasResponseValidatorTest { @Autowired private MsConnectorDummyConfigMap basicConfig; @Autowired protected EidasAttributeRegistry attrRegistry; private TestRequestImpl pendingReq; private MsConnectorDummySpConfiguration oaParam; /** * jUnit test set-up. */ @Before public void setUp() throws EaafStorageException, URISyntaxException { 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)); } @Test public void loaFromResponseToLow() throws URISyntaxException { //set-up ILightResponse eidasResponse = buildDummyAuthResponse( "LU/AT/" + RandomStringUtils.randomNumeric(10), EaafConstants.EIDAS_LOA_LOW, false); String spCountry = "AT"; String citizenCountryCode = "XX"; //execute test try { EidasResponseValidator.validateResponse(pendingReq, eidasResponse, spCountry, citizenCountryCode, attrRegistry); Assert.fail("Wrong eIDAS response not detected"); } catch (EidasValidationException e) { Assert.assertEquals("ErrorId", "eidas.06", e.getErrorId()); Assert.assertEquals("wrong parameter size", 1, e.getParams().length); Assert.assertEquals("wrong errorMsg", "http://eidas.europa.eu/LoA/low", e.getParams()[0]); } } @Test public void noEidasSpCountry() throws URISyntaxException { //set-up ILightResponse eidasResponse = buildDummyAuthResponse( "LU/AT/" + RandomStringUtils.randomNumeric(10), EaafConstants.EIDAS_LOA_SUBSTANTIAL, false); String spCountry = null; String citizenCountryCode = "LU"; oaParam.setLoa(Arrays.asList(EaafConstants.EIDAS_LOA_HIGH, EaafConstants.EIDAS_LOA_SUBSTANTIAL)); //execute test try { EidasResponseValidator.validateResponse(pendingReq, eidasResponse, spCountry, citizenCountryCode, attrRegistry); Assert.fail("Wrong eIDAS response not detected"); } catch (EidasValidationException e) { Assert.assertEquals("ErrorId", "eidas.07", e.getErrorId()); Assert.assertEquals("wrong parameter size", 2, e.getParams().length); Assert.assertEquals("wrong errorMsg", "PersonIdentifier", e.getParams()[0]); Assert.assertEquals("wrong errorMsg", "Destination country does not match to SP country", e.getParams()[1]); } } @Test public void noEidasResponseCountry() throws URISyntaxException { //set-up ILightResponse eidasResponse = buildDummyAuthResponse( "LU/AT/" + RandomStringUtils.randomNumeric(10), EaafConstants.EIDAS_LOA_SUBSTANTIAL, false); String spCountry = "AT"; String citizenCountryCode = null; oaParam.setLoa(Arrays.asList(EaafConstants.EIDAS_LOA_HIGH, EaafConstants.EIDAS_LOA_SUBSTANTIAL)); //execute test try { EidasResponseValidator.validateResponse(pendingReq, eidasResponse, spCountry, citizenCountryCode, attrRegistry); Assert.fail("Wrong eIDAS response not detected"); } catch (EidasValidationException e) { Assert.assertEquals("ErrorId", "eidas.07", e.getErrorId()); Assert.assertEquals("wrong parameter size", 2, e.getParams().length); Assert.assertEquals("wrong errorMsg", "PersonIdentifier", e.getParams()[0]); Assert.assertEquals("wrong errorMsg", "Citizen country does not match to eIDAS-node country that generates the response", e.getParams()[1]); } } @Test public void wrongEidasResponseCountry() throws URISyntaxException { //set-up ILightResponse eidasResponse = buildDummyAuthResponse( "LU/AT/" + RandomStringUtils.randomNumeric(10), EaafConstants.EIDAS_LOA_SUBSTANTIAL, false); String spCountry = "AT"; String citizenCountryCode = "XX"; oaParam.setLoa(Arrays.asList(EaafConstants.EIDAS_LOA_HIGH, EaafConstants.EIDAS_LOA_SUBSTANTIAL)); //execute test try { EidasResponseValidator.validateResponse(pendingReq, eidasResponse, spCountry, citizenCountryCode, attrRegistry); Assert.fail("Wrong eIDAS response not detected"); } catch (EidasValidationException e) { Assert.assertEquals("ErrorId", "eidas.07", e.getErrorId()); Assert.assertEquals("wrong parameter size", 2, e.getParams().length); Assert.assertEquals("wrong errorMsg", "PersonIdentifier", e.getParams()[0]); Assert.assertEquals("wrong errorMsg", "Citizen country does not match to eIDAS-node country that generates the response", e.getParams()[1]); } } @Test public void missingPersonalIdentifier() throws URISyntaxException { //set-up ILightResponse eidasResponse = buildDummyAuthResponse( null, EaafConstants.EIDAS_LOA_SUBSTANTIAL, false); String spCountry = "AT"; String citizenCountryCode = "LU"; oaParam.setLoa(Arrays.asList(EaafConstants.EIDAS_LOA_HIGH, EaafConstants.EIDAS_LOA_SUBSTANTIAL)); //execute test try { EidasResponseValidator.validateResponse(pendingReq, eidasResponse, spCountry, citizenCountryCode, attrRegistry); Assert.fail("Wrong eIDAS response not detected"); } catch (EidasValidationException e) { Assert.assertEquals("ErrorId", "eidas.05", e.getErrorId()); Assert.assertEquals("wrong parameter size", 1, e.getParams().length); Assert.assertEquals("wrong errorMsg", "NO 'PersonalIdentifier' attriubte", e.getParams()[0]); } } @Test public void moreThanOnePersonalIdentifier() throws URISyntaxException { //set-up ILightResponse eidasResponse = buildDummyAuthResponse( null, EaafConstants.EIDAS_LOA_SUBSTANTIAL, true); String spCountry = "AT"; String citizenCountryCode = "LU"; oaParam.setLoa(Arrays.asList(EaafConstants.EIDAS_LOA_HIGH, EaafConstants.EIDAS_LOA_SUBSTANTIAL)); //execute test try { EidasResponseValidator.validateResponse(pendingReq, eidasResponse, spCountry, citizenCountryCode, attrRegistry); Assert.fail("Wrong eIDAS response not detected"); } catch (EidasValidationException e) { Assert.assertEquals("ErrorId", "eidas.05", e.getErrorId()); Assert.assertEquals("wrong parameter size", 1, e.getParams().length); Assert.assertEquals("wrong errorMsg", "NO 'PersonalIdentifier' attriubte", e.getParams()[0]); } } @Test public void emptyPersonalIdentifier() throws URISyntaxException { //set-up ILightResponse eidasResponse = buildDummyAuthResponse( "", EaafConstants.EIDAS_LOA_SUBSTANTIAL, false); String spCountry = "AT"; String citizenCountryCode = "LU"; oaParam.setLoa(Arrays.asList(EaafConstants.EIDAS_LOA_HIGH, EaafConstants.EIDAS_LOA_SUBSTANTIAL)); //execute test try { EidasResponseValidator.validateResponse(pendingReq, eidasResponse, spCountry, citizenCountryCode, attrRegistry); Assert.fail("Wrong eIDAS response not detected"); } catch (EidasValidationException e) { Assert.assertEquals("ErrorId", "eidas.07", e.getErrorId()); Assert.assertEquals("wrong parameter size", 2, e.getParams().length); Assert.assertEquals("wrong errorMsg", "PersonIdentifier", e.getParams()[0]); Assert.assertEquals("wrong errorMsg", "Wrong identifier format", e.getParams()[1]); } } @Test public void validResponse() throws URISyntaxException, EidasValidationException { //set-up String spCountry = RandomStringUtils.randomAlphabetic(2).toUpperCase(); String cCountry = RandomStringUtils.randomAlphabetic(2).toUpperCase(); ILightResponse eidasResponse = buildDummyAuthResponse( cCountry + "/" + spCountry + "/" + RandomStringUtils.randomAlphanumeric(20), EaafConstants.EIDAS_LOA_SUBSTANTIAL, false); oaParam.setLoa(Arrays.asList(EaafConstants.EIDAS_LOA_HIGH, EaafConstants.EIDAS_LOA_SUBSTANTIAL)); //execute test EidasResponseValidator.validateResponse(pendingReq, eidasResponse, spCountry, cCountry, attrRegistry); } private AuthenticationResponse buildDummyAuthResponse(String personalId, String loa, boolean moreThanOnePersonalId) throws URISyntaxException { final AttributeDefinition personIdattributeDef = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first(); final Builder attributeMap = ImmutableAttributeMap.builder(); if (personalId != null) { if (moreThanOnePersonalId) { ImmutableSet values = ImmutableSet.of(new StringAttributeValue(personalId), new StringAttributeValue("XX/YY/" + RandomStringUtils.randomAlphanumeric(10))); attributeMap.put(personIdattributeDef, values); } else { attributeMap.put(personIdattributeDef, personalId); } } val b = new AuthenticationResponse.Builder(); return b.id("_".concat(Random.nextHexRandom16())) .issuer(RandomStringUtils.randomAlphabetic(10)) .subject(RandomStringUtils.randomAlphabetic(10)) .statusCode(Constants.SUCCESS_URI) .inResponseTo("_".concat(Random.nextHexRandom16())) .subjectNameIdFormat("afaf") .levelOfAssurance(loa) .attributes(attributeMap.build()) .build(); } }