From 7bf7c3c03fd3a1efeaf3f8e3dd75922e2f5f9921 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 8 Mar 2022 19:06:10 +0100 Subject: refactor(core): move all project libs into sub-project 'modules' --- .../msproxyservice/EidasProxyMessageSource.java | 22 + .../msproxyservice/MsProxyServiceConstants.java | 54 ++ .../MsProxyServiceSpringResourceProvider.java | 52 ++ .../exception/EidasProxyServiceException.java | 19 + .../protocol/EidasProxyServiceController.java | 443 ++++++++++++++ .../protocol/ProxyServiceAuthenticationAction.java | 374 ++++++++++++ .../protocol/ProxyServicePendingRequest.java | 28 + .../utils/EidasProxyServiceUtils.java | 45 ++ ...iz.components.spring.api.SpringResourceProvider | 1 + .../messages/eidasproxy_messages.properties | 14 + .../resources/spring/eidas_proxy-service.beans.xml | 28 + .../test/EidasProxyMessageSourceTest.java | 50 ++ .../MsProxyServiceSpringResourceProviderTest.java | 56 ++ .../protocol/EidasProxyServiceControllerTest.java | 666 +++++++++++++++++++++ .../ProxyServiceAuthenticationActionTest.java | 637 ++++++++++++++++++++ .../resources/config/additional-attributes.xml | 39 ++ .../src/test/resources/config/eidas-attributes.xml | 376 ++++++++++++ .../resources/config/junit_config_1.properties | 6 + .../spring/SpringTest-context_basic_mapConfig.xml | 20 + .../spring/SpringTest-context_basic_test.xml | 42 ++ 20 files changed, 2972 insertions(+) create mode 100644 modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/EidasProxyMessageSource.java create mode 100644 modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java create mode 100644 modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceSpringResourceProvider.java create mode 100644 modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/exception/EidasProxyServiceException.java create mode 100644 modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java create mode 100644 modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java create mode 100644 modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServicePendingRequest.java create mode 100644 modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/utils/EidasProxyServiceUtils.java create mode 100644 modules/eidas_proxy-sevice/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider create mode 100644 modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties create mode 100644 modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml create mode 100644 modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/EidasProxyMessageSourceTest.java create mode 100644 modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/MsProxyServiceSpringResourceProviderTest.java create mode 100644 modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java create mode 100644 modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java create mode 100644 modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml create mode 100644 modules/eidas_proxy-sevice/src/test/resources/config/eidas-attributes.xml create mode 100644 modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties create mode 100644 modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig.xml create mode 100644 modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/EidasProxyMessageSource.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/EidasProxyMessageSource.java new file mode 100644 index 00000000..23390da8 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/EidasProxyMessageSource.java @@ -0,0 +1,22 @@ +package at.asitplus.eidas.specific.modules.msproxyservice; + +import java.util.Arrays; +import java.util.List; + +import at.gv.egiz.eaaf.core.api.logging.IMessageSourceLocation; + +/** + * i18n Message-Source for eIDAS Proxy-Service messages. + * + * @author tlenz + * + */ +public class EidasProxyMessageSource implements IMessageSourceLocation { + + @Override + public List getMessageSourceLocation() { + return Arrays.asList("classpath:messages/eidasproxy_messages"); + + } + +} diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java new file mode 100644 index 00000000..f6a88aa3 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java @@ -0,0 +1,54 @@ +package at.asitplus.eidas.specific.modules.msproxyservice; + +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants; + +/** + * Constants for MS-specific eIDAS Proxy-Service. + * + * @author tlenz + * + */ +public class MsProxyServiceConstants { + + // general constants + public static final String TEMPLATE_SP_UNIQUE_ID = "eidasProxyAuth_from_{0}_type_{1}"; + + // configuration constants + public static final String CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID = Constants.CONIG_PROPS_EIDAS_NODE + + ".proxy.entityId"; + public static final String CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL = Constants.CONIG_PROPS_EIDAS_NODE + + ".proxy.forward.endpoint"; + + // mandate configuration + public static final String CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED = + Constants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.mandates.enabled"; + public static final String CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL = + Constants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.mandates.profiles.natural.default"; + public static final String CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL = + Constants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.mandates.profiles.legal.default"; + + + public static final String CONIG_PROPS_EIDAS_PROXY_WORKAROUND_MANDATES_LEGAL_PERSON = + Constants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.workaround.mandates.legalperson"; + + // specific eIDAS-Connector configuration + public static final String CONIG_PROPS_CONNECTOR_PREFIX = "connector"; + public static final String CONIG_PROPS_CONNECTOR_UNIQUEID = EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER; + public static final String CONIG_PROPS_CONNECTOR_COUNTRYCODE = "countryCode"; + public static final String CONIG_PROPS_CONNECTOR_MANDATES_ENABLED = "mandates.enabled"; + public static final String CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL = "mandates.natural"; + public static final String CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL = "mandates.legal"; + public static final String CONIG_PROPS_CONNECTOR_VALIDATION_ATTR_MDS = "validation.attributes.mds"; + + + //http end-points + public static final String EIDAS_HTTP_ENDPOINT_IDP_POST = "/eidas/light/idp/post"; + public static final String EIDAS_HTTP_ENDPOINT_IDP_REDIRECT = "/eidas/light/idp/redirect"; + + private MsProxyServiceConstants() { + //private constructor for class with only constant values + + } + +} diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceSpringResourceProvider.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceSpringResourceProvider.java new file mode 100644 index 00000000..d36e4712 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceSpringResourceProvider.java @@ -0,0 +1,52 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.asitplus.eidas.specific.modules.msproxyservice; + +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import at.gv.egiz.components.spring.api.SpringResourceProvider; + +public class MsProxyServiceSpringResourceProvider implements SpringResourceProvider { + + @Override + public String getName() { + return "MS-specific eIDAS Proxy-Service module"; + } + + @Override + public String[] getPackagesToScan() { + return null; + + } + + @Override + public Resource[] getResourcesToLoad() { + final ClassPathResource eidasProxyServiceConfig = + new ClassPathResource("/spring/eidas_proxy-service.beans.xml", MsProxyServiceSpringResourceProvider.class); + + return new Resource[] { eidasProxyServiceConfig }; + } + +} diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/exception/EidasProxyServiceException.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/exception/EidasProxyServiceException.java new file mode 100644 index 00000000..43592a28 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/exception/EidasProxyServiceException.java @@ -0,0 +1,19 @@ +package at.asitplus.eidas.specific.modules.msproxyservice.exception; + +import at.gv.egiz.eaaf.core.exceptions.EaafException; + +public class EidasProxyServiceException extends EaafException { + + private static final long serialVersionUID = 1L; + + public EidasProxyServiceException(String errorId, Object[] params) { + super(errorId, params); + + } + + public EidasProxyServiceException(String errorId, Object[] params, Throwable e) { + super(errorId, params, e); + + } + +} diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java new file mode 100644 index 00000000..e24c753e --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java @@ -0,0 +1,443 @@ +package at.asitplus.eidas.specific.modules.msproxyservice.protocol; + +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang3.StringUtils; +import org.opensaml.saml.saml2.core.NameIDType; +import org.opensaml.saml.saml2.core.StatusCode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import com.google.common.collect.ImmutableSortedSet; + +import at.asitplus.eidas.specific.core.MsEidasNodeConstants; +import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry; +import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; +import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException; +import at.asitplus.eidas.specific.modules.msproxyservice.utils.EidasProxyServiceUtils; +import at.gv.egiz.components.eventlog.api.EventConstants; +import at.gv.egiz.eaaf.core.api.IRequest; +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.data.ExtendedPvpAttributeDefinitions.SpMandateModes; +import at.gv.egiz.eaaf.core.api.idp.IModulInfo; +import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.exceptions.GuiBuildException; +import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractController; +import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; +import eu.eidas.auth.commons.EIDASSubStatusCode; +import eu.eidas.auth.commons.EidasParameterKeys; +import eu.eidas.auth.commons.light.ILightRequest; +import eu.eidas.auth.commons.light.impl.LightResponse; +import eu.eidas.auth.commons.light.impl.LightResponse.Builder; +import eu.eidas.auth.commons.light.impl.ResponseStatus; +import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames; +import eu.eidas.specificcommunication.exception.SpecificCommunicationException; +import eu.eidas.specificcommunication.protocol.SpecificCommunicationService; +import lombok.extern.slf4j.Slf4j; + +/** + * End-point implementation for authentication requests from eIDAS Proxy-Service + * to MS-specific eIDAS Proxy-Service. + * + * @author tlenz + * + */ +@Slf4j +@Controller +public class EidasProxyServiceController extends AbstractController implements IModulInfo { + + private static final String ERROR_01 = "eidas.proxyservice.01"; + private static final String ERROR_02 = "eidas.proxyservice.02"; + private static final String ERROR_03 = "eidas.proxyservice.03"; + private static final String ERROR_04 = "eidas.proxyservice.04"; + private static final String ERROR_05 = "eidas.proxyservice.05"; + private static final String ERROR_07 = "eidas.proxyservice.07"; + private static final String ERROR_08 = "eidas.proxyservice.08"; + private static final String ERROR_09 = "eidas.proxyservice.09"; + private static final String ERROR_10 = "eidas.proxyservice.10"; + private static final String ERROR_11 = "eidas.proxyservice.11"; + + public static final String PROTOCOL_ID = "eidasProxy"; + + @Autowired EidasAttributeRegistry attrRegistry; + @Autowired ProxyServiceAuthenticationAction responseAction; + + /** + * End-point that receives authentication requests from eIDAS Node. + * + * @param httpReq Http request + * @param httpResp Http response + * @throws IOException In case of general error + * @throws EaafException In case of a validation or processing error + */ + @RequestMapping(value = { + MsProxyServiceConstants.EIDAS_HTTP_ENDPOINT_IDP_POST, + MsProxyServiceConstants.EIDAS_HTTP_ENDPOINT_IDP_REDIRECT + }, + method = { RequestMethod.POST, RequestMethod.GET }) + public void receiveEidasAuthnRequest(HttpServletRequest httpReq, HttpServletResponse httpResp) + throws IOException, + EaafException { + log.trace("Receive request on eidas proxy-service end-points"); + ProxyServicePendingRequest pendingReq = null; + try { + // get token from Request + final String tokenBase64 = httpReq.getParameter(EidasParameterKeys.TOKEN.toString()); + if (StringUtils.isEmpty(tokenBase64)) { + log.warn("NO eIDAS message token found."); + throw new EidasProxyServiceException(ERROR_02, null); + + } + log.trace("Receive eIDAS-node token: {}. Searching authentication request from eIDAS Proxy-Service ...", + tokenBase64); + + // read authentication request from shared cache + final SpecificCommunicationService specificProxyCommunicationService = + (SpecificCommunicationService) applicationContext.getBean( + SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE + .toString()); + final ILightRequest eidasRequest = specificProxyCommunicationService.getAndRemoveRequest( + tokenBase64, + ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes())); + if (eidasRequest == null) { + log.info("Find no eIDAS Authn. Request with stated token."); + throw new EidasProxyServiceException(ERROR_11, null); + + } + + log.debug("Received eIDAS auth. request from: {}, Initializing authentication environment ... ", + eidasRequest.getSpCountryCode() != null ? eidasRequest.getSpCountryCode() : "'missing SP-country'"); + log.trace("Received eIDAS requst: {}", eidasRequest); + + // create pendingRequest object + pendingReq = applicationContext.getBean(ProxyServicePendingRequest.class); + pendingReq.initialize(httpReq, authConfig); + pendingReq.setModule(getName()); + + // log 'transaction created' event + revisionsLogger.logEvent(EventConstants.TRANSACTION_CREATED, + pendingReq.getUniqueTransactionIdentifier()); + revisionsLogger.logEvent(pendingReq.getUniqueSessionIdentifier(), + pendingReq.getUniqueTransactionIdentifier(), EventConstants.TRANSACTION_IP, + httpReq.getRemoteAddr()); + + // validate eIDAS Authn. request and set into pending-request + validateEidasAuthnRequest(eidasRequest); + pendingReq.setEidasRequest(eidasRequest); + + // generate Service-Provider configuration from eIDAS request + final ISpConfiguration spConfig = generateSpConfigurationFromEidasRequest(eidasRequest); + + // validate eIDAS Authn. request by using eIDAS Connector specifc parameters + validateEidasAuthnRequest(spConfig, eidasRequest); + + // populate pendingRequest with parameters + pendingReq.setOnlineApplicationConfiguration(spConfig); + pendingReq.setSpEntityId(spConfig.getUniqueIdentifier()); + pendingReq.setPassiv(false); + pendingReq.setForce(true); + + // AuthnRequest needs authentication + pendingReq.setNeedAuthentication(true); + + // set protocol action, which should be executed after authentication + pendingReq.setAction(ProxyServiceAuthenticationAction.class.getName()); + + // switch to session authentication + protAuthService.performAuthentication(httpReq, httpResp, pendingReq); + + } catch (final EidasProxyServiceException e) { + throw e; + + } catch (final SpecificCommunicationException e) { + log.error("Can not read eIDAS Authn request from shared cache. Reason: {}", e.getMessage()); + throw new EidasProxyServiceException(ERROR_03, new Object[] { e.getMessage() }, e); + + } catch (final Throwable e) { + // write revision log entries + if (pendingReq != null) { + revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, + pendingReq.getUniqueTransactionIdentifier()); + } + + throw new EidasProxyServiceException(ERROR_01, new Object[] { e.getMessage() }, e); + } + + } + + @Override + public boolean generateErrorMessage(Throwable e, HttpServletRequest httpReq, HttpServletResponse httpResp, + IRequest pendingReq) throws Throwable { + if (pendingReq instanceof ProxyServicePendingRequest) { + try { + ILightRequest eidasReq = ((ProxyServicePendingRequest) pendingReq).getEidasRequest(); + + //build eIDAS response + Builder lightRespBuilder = LightResponse.builder(); + lightRespBuilder.id(UUID.randomUUID().toString()); + lightRespBuilder.inResponseToId(eidasReq.getId()); + lightRespBuilder.relayState(eidasReq.getRelayState()); + lightRespBuilder.issuer(authConfig.getBasicConfiguration( + MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID)); + lightRespBuilder.subject(UUID.randomUUID().toString()); + lightRespBuilder.subjectNameIdFormat(NameIDType.TRANSIENT); + lightRespBuilder.status(ResponseStatus.builder() + .statusCode(StatusCode.RESPONDER) + .subStatusCode(EIDASSubStatusCode.AUTHN_FAILED_URI.getValue()) + .statusMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage())) + .build()); + + // forward to eIDAS Proxy-Service + responseAction.forwardToEidasProxy(pendingReq, httpReq, httpResp, lightRespBuilder.build()); + + return true; + + } catch (ServletException | IOException | GuiBuildException e1) { + log.warn("Forward error to eIDAS Proxy-Service FAILED. Handle error localy ... ", e1); + + } + + } else { + log.error("eIDAS Proxy-Service authentication requires PendingRequest of Type: {}", + ProxyServicePendingRequest.class.getName()); + + } + + return false; + + } + + @Override + public String getName() { + return EidasProxyServiceController.class.getName(); + + } + + @Override + public String getAuthProtocolIdentifier() { + return PROTOCOL_ID; + + } + + @Override + public boolean validate(HttpServletRequest request, HttpServletResponse response, IRequest pending) { + return true; + + } + + /** + * Generic validation of incoming eIDAS request. + * + * @param eidasRequest Incoming eIDAS authentication request + * @throws EidasProxyServiceException In case of a validation error + */ + private void validateEidasAuthnRequest(ILightRequest eidasRequest) throws EidasProxyServiceException { + if (StringUtils.isEmpty(eidasRequest.getIssuer())) { + throw new EidasProxyServiceException(ERROR_05, null); + + } + + // TODO: validate some other stuff + + } + + /** + * eIDAS Connector specific validation of incoming eIDAS request. + * + * @param eidasRequest Incoming eIDAS authentication request + * @param spConfig eIDAS Connector configuration + * @throws EidasProxyServiceException In case of a validation error + */ + private void validateEidasAuthnRequest(ISpConfiguration spConfig, ILightRequest eidasRequest) + throws EidasProxyServiceException { + // check if natural-person and legal-person attributes requested in parallel + if (spConfig.isConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_VALIDATION_ATTR_MDS, true) + && EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest) + && EidasProxyServiceUtils.isNaturalPersonRequested(eidasRequest)) { + throw new EidasProxyServiceException(ERROR_08, null); + + } + + // TODO: validate some other stuff + + } + + /** + * Generate a dummy Service-Provider configuration for processing. + * + * @param eidasRequest Incoming eIDAS authentication request + * @return Service-Provider configuration that can be used for authentication + * @throws EidasProxyServiceException In case of a configuration error + */ + private ISpConfiguration generateSpConfigurationFromEidasRequest(ILightRequest eidasRequest) + throws EidasProxyServiceException { + try { + + Map connectorConfigMap = extractRawConnectorConfiguration(eidasRequest); + + // check if country-code is available + String spCountry = connectorConfigMap.get(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE); + if (StringUtils.isEmpty(spCountry)) { + throw new EidasProxyServiceException(ERROR_07, null); + + } + + // build FriendyName from CountryCode and SPType + connectorConfigMap.put(MsEidasNodeConstants.PROP_CONFIG_SP_FRIENDLYNAME, + MessageFormat.format(MsProxyServiceConstants.TEMPLATE_SP_UNIQUE_ID, + spCountry, eidasRequest.getSpType())); + + // build Service-Provider configuration object + final ServiceProviderConfiguration spConfig = new ServiceProviderConfiguration(connectorConfigMap, authConfig); + + // build bPK target from Country-Code + final String ccCountry = authConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, + Constants.DEFAULT_MS_NODE_COUNTRY_CODE); + spConfig.setBpkTargetIdentifier( + EaafConstants.URN_PREFIX_EIDAS + ccCountry + "+" + spCountry); + + // set required LoA from eIDAS request + spConfig.setRequiredLoA( + eidasRequest.getLevelsOfAssurance().stream().map(el -> el.getValue()).collect(Collectors.toList())); + + //build mandate profiles for this specific request + buildMandateProfileConfiguration(spConfig, eidasRequest); + + return spConfig; + + } catch (EidasProxyServiceException e) { + throw e; + + } catch (final EaafException e) { + throw new EidasProxyServiceException(ERROR_04, new Object[] { e.getMessage() }, e); + + } + } + + + private Map extractRawConnectorConfiguration(ILightRequest eidasRequest) { + Map allConnectorConfigs = authConfig.getBasicConfigurationWithPrefix( + MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_PREFIX); + if (log.isTraceEnabled()) { + log.trace("Full-connector configuration:"); + allConnectorConfigs.entrySet().stream().forEach( + el -> log.trace("Key: {} -> Value: {}", el.getKey(), el.getValue())); + + } + + + Map connectorConfig = allConnectorConfigs.entrySet().stream() + .filter(el -> el.getKey().endsWith(MsEidasNodeConstants.PROP_CONFIG_SP_UNIQUEIDENTIFIER) + && el.getValue().equals(eidasRequest.getIssuer())) + .findFirst() + .map(el -> KeyValueUtils.getSubSetWithPrefix(allConnectorConfigs, + KeyValueUtils.getParentKey(el.getKey()) + KeyValueUtils.KEY_DELIMITER)) + .orElse(new HashMap<>()); + + + if (connectorConfig.isEmpty()) { + log.debug("No specific configuration for eIDAS Connector: {} Using default configuration ... ", + eidasRequest.getIssuer()); + + // set EntityId of the requesting eIDAS Connector + connectorConfig.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, eidasRequest.getIssuer()); + + // set country-code from eIDAS request + connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, + eidasRequest.getSpCountryCode()); + + // set default mandate configuration + connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, + String.valueOf(authConfig.getBasicConfigurationBoolean( + MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, false))); + connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL, + authConfig.getBasicConfiguration( + MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL)); + connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL, + authConfig.getBasicConfiguration( + MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL)); + + } else { + log.debug("Find specific configuration for eIDAS Connector: {}", eidasRequest.getIssuer()); + + } + + return connectorConfig; + + } + + + private void buildMandateProfileConfiguration(ServiceProviderConfiguration spConfig, ILightRequest eidasRequest) + throws EidasProxyServiceException { + // check if mandates are enabled + if (spConfig.isConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, false)) { + injectMandateInfosIntoSpConfig(spConfig, eidasRequest); + + } else { + if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)) { + throw new EidasProxyServiceException(ERROR_09, null); + + } + + spConfig.setMandateProfiles(Collections.emptyList()); + spConfig.setMandateMode(SpMandateModes.NONE); + + } + + } + + private void injectMandateInfosIntoSpConfig(ServiceProviderConfiguration spConfig, + ILightRequest eidasRequest) throws EidasProxyServiceException { + log.trace("eIDAS Proxy-Service allows mandates for Connector: {}. Selecting profiles ... ", + spConfig.getUniqueIdentifier()); + + //check if legal person is requested + if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)) { + spConfig.setMandateProfiles(KeyValueUtils.getListOfCsvValues( + spConfig.getConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL))); + spConfig.setMandateMode(SpMandateModes.LEGAL_FORCE); + + if (spConfig.getMandateProfiles().isEmpty()) { + throw new EidasProxyServiceException(ERROR_10, null); + + } + + } else if (EidasProxyServiceUtils.isNaturalPersonRequested(eidasRequest)) { + spConfig.setMandateProfiles(KeyValueUtils.getListOfCsvValues( + spConfig.getConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL))); + + spConfig.setMandateMode(SpMandateModes.NATURAL); + + } + + + if (spConfig.getMandateProfiles().isEmpty()) { + log.debug("No mandate-profiles for issure: {}. Set mandate-mode to 'none'", + spConfig.getUniqueIdentifier()); + spConfig.setMandateMode(SpMandateModes.NONE); + + } else { + log.debug("Set mandate-profiles: {} to request from issuer: {}", + spConfig.getMandateProfiles(), spConfig.getUniqueIdentifier()); + + } + + } +} diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java new file mode 100644 index 00000000..15524005 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java @@ -0,0 +1,374 @@ +package at.asitplus.eidas.specific.modules.msproxyservice.protocol; + +import java.io.IOException; +import java.util.UUID; + +import javax.annotation.PostConstruct; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.opensaml.saml.saml2.core.NameIDType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.ResourceLoader; +import org.springframework.web.util.UriComponentsBuilder; + +import at.asitplus.eidas.specific.core.MsEidasNodeConstants; +import at.asitplus.eidas.specific.core.gui.StaticGuiBuilderConfiguration; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry; +import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; +import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException; +import at.asitplus.eidas.specific.modules.msproxyservice.utils.EidasProxyServiceUtils; +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions; +import at.gv.egiz.eaaf.core.api.gui.ISpringMvcGuiFormBuilder; +import at.gv.egiz.eaaf.core.api.idp.IAction; +import at.gv.egiz.eaaf.core.api.idp.IAuthData; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.api.idp.IEidAuthData; +import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.exceptions.GuiBuildException; +import at.gv.egiz.eaaf.core.impl.data.SloInformationImpl; +import eu.eidas.auth.commons.EidasParameterKeys; +import eu.eidas.auth.commons.attribute.AttributeDefinition; +import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; +import eu.eidas.auth.commons.light.ILightRequest; +import eu.eidas.auth.commons.light.ILightResponse; +import eu.eidas.auth.commons.light.impl.LightResponse; +import eu.eidas.auth.commons.light.impl.LightResponse.Builder; +import eu.eidas.auth.commons.light.impl.ResponseStatus; +import eu.eidas.auth.commons.tx.BinaryLightToken; +import eu.eidas.specificcommunication.BinaryLightTokenHelper; +import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames; +import eu.eidas.specificcommunication.exception.SpecificCommunicationException; +import eu.eidas.specificcommunication.protocol.SpecificCommunicationService; +import lombok.extern.slf4j.Slf4j; + +/** + * Result action of a successfully performed eIDAS Proxy-Service authentication. + * + * @author tlenz + * + */ +@Slf4j +public class ProxyServiceAuthenticationAction implements IAction { + + private static final String PROXYSERVICE_AUTH_ACTION_NAME = "MS-specific eIDAS-Proxy action"; + + @Autowired + ApplicationContext context; + @Autowired + IConfiguration basicConfig; + @Autowired + ResourceLoader resourceLoader; + @Autowired + ISpringMvcGuiFormBuilder guiBuilder; + @Autowired + EidasAttributeRegistry attrRegistry; + + @Override + public SloInformationInterface processRequest(IRequest pendingReq, HttpServletRequest httpReq, + HttpServletResponse httpResp, IAuthData authData) throws EaafException { + if (pendingReq instanceof ProxyServicePendingRequest) { + try { + ILightRequest eidasReq = ((ProxyServicePendingRequest) pendingReq).getEidasRequest(); + + //build eIDAS response + Builder lightRespBuilder = LightResponse.builder(); + lightRespBuilder.id(UUID.randomUUID().toString()); + lightRespBuilder.inResponseToId(eidasReq.getId()); + lightRespBuilder.relayState(eidasReq.getRelayState()); + + lightRespBuilder.status(ResponseStatus.builder() + .statusCode(Constants.SUCCESS_URI) + .build()); + + //TODO: check if we can use transient subjectNameIds + lightRespBuilder.subject(UUID.randomUUID().toString()); + lightRespBuilder.subjectNameIdFormat(NameIDType.TRANSIENT); + + //TODO: + lightRespBuilder.issuer(basicConfig.getBasicConfiguration( + MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID)); + lightRespBuilder.levelOfAssurance(authData.getEidasQaaLevel()); + lightRespBuilder.attributes(buildAttributesFromAuthData(authData, eidasReq)); + + // set SLO response object of EAAF framework + final SloInformationImpl sloInformation = new SloInformationImpl(); + sloInformation.setProtocolType(pendingReq.requestedModule()); + sloInformation + .setSpEntityID(pendingReq.getServiceProviderConfiguration().getUniqueIdentifier()); + + // forward to eIDAS Proxy-Service + forwardToEidasProxy(pendingReq, httpReq, httpResp, lightRespBuilder.build()); + + return sloInformation; + + } catch (ServletException | IOException | GuiBuildException e) { + throw new EidasProxyServiceException("eidas.proxyservice.06", null, e); + + } + + } else { + log.error("eIDAS Proxy-Service authentication requires PendingRequest of Type: {}", + ProxyServicePendingRequest.class.getName()); + throw new EaafException("eidas.proxyservice.99"); + + } + } + + @Override + public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) { + return true; + + } + + @Override + public String getDefaultActionName() { + return PROXYSERVICE_AUTH_ACTION_NAME; + + } + + + /** + * Forward eIDAS Light response to eIDAS node. + * + * @param pendingReq Current pending request. + * @param httpReq Current HTTP request + * @param httpResp Current HTTP response + * @param lightResponse eIDAS LightResponse + * @throws EaafConfigurationException In case of a configuration error + * @throws IOException In case of a general error + * @throws GuiBuildException In case of a GUI rendering error, if http POST binding is used + * @throws ServletException In case of a general error + */ + public void forwardToEidasProxy(IRequest pendingReq, HttpServletRequest httpReq, + HttpServletResponse httpResp, LightResponse lightResponse) throws EaafConfigurationException, IOException, + GuiBuildException, ServletException { + + // put request into shared cache + final BinaryLightToken token = putResponseInCommunicationCache(lightResponse); + final String tokenBase64 = BinaryLightTokenHelper.encodeBinaryLightTokenBase64(token); + + // select forward URL regarding the selected environment + final String forwardUrl = basicConfig.getBasicConfiguration( + MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL); + + if (StringUtils.isEmpty(forwardUrl)) { + log.warn("NO ForwardURL defined in configuration. Can NOT forward to eIDAS node! Process stops"); + throw new EaafConfigurationException("config.08", + new Object[] { MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL }); + + } + log.debug("ForwardURL: " + forwardUrl + " selected to forward eIDAS request"); + + if (basicConfig.getBasicConfiguration( + Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD, + Constants.FORWARD_METHOD_GET).equals(Constants.FORWARD_METHOD_GET)) { + + log.debug("Use http-redirect for eIDAS node forwarding ... "); + // send redirect + final UriComponentsBuilder redirectUrl = UriComponentsBuilder.fromHttpUrl(forwardUrl); + redirectUrl.queryParam(EidasParameterKeys.TOKEN.toString(), tokenBase64); + httpResp.sendRedirect(redirectUrl.build().encode().toString()); + + } else { + log.debug("Use http-post for eIDAS node forwarding ... "); + final StaticGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration( + basicConfig, + pendingReq, + Constants.TEMPLATE_POST_FORWARD_NAME, + null, + resourceLoader); + + config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_ENDPOINT, forwardUrl); + config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_TOKEN_NAME, + EidasParameterKeys.TOKEN.toString()); + config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_TOKEN_VALUE, + tokenBase64); + + guiBuilder.build(httpReq, httpResp, config, "Forward to eIDASNode form"); + + } + } + + @PostConstruct + private void checkConfiguration() { + //TODO: validate configuration on start-up + + } + + + private ImmutableAttributeMap buildAttributesFromAuthData(IAuthData authData, + ILightRequest eidasReq) { + IEidAuthData eidAuthData = (IEidAuthData) authData; + if (eidAuthData.isUseMandate()) { + log.debug("Building eIDAS Proxy-Service response with mandate ... "); + final ImmutableAttributeMap.Builder attributeMap = ImmutableAttributeMap.builder(); + injectRepesentativeInformation(attributeMap, eidAuthData); + injectMandatorInformation(attributeMap, eidAuthData); + + // work-around that injects nat. person subject to bypass validation on eIDAS Node + injectJurPersonWorkaroundIfRequired(attributeMap, eidasReq, authData); + + return attributeMap.build(); + + } else { + log.debug("Building eIDAS Proxy-Service response without mandates ... "); + return buildAttributesWithoutMandate(eidAuthData); + + } + } + + private void injectMandatorInformation( + ImmutableAttributeMap.Builder attributeMap, IEidAuthData eidAuthData) { + String natMandatorId = eidAuthData.getGenericData( + MsEidasNodeConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER, String.class); + + if (StringUtils.isNotEmpty(natMandatorId)) { + log.debug("Injecting natural mandator informations ... "); + final AttributeDefinition attrDefPersonalId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first(); + final AttributeDefinition attrDefFamilyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_CURRENTFAMILYNAME).first(); + final AttributeDefinition attrDefGivenName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_CURRENTGIVENNAME).first(); + final AttributeDefinition attrDefDateOfBirth = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_DATEOFBIRTH).first(); + + attributeMap.put(attrDefPersonalId, natMandatorId); + attributeMap.put(attrDefFamilyName, eidAuthData.getGenericData( + PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, String.class)); + attributeMap.put(attrDefGivenName, eidAuthData.getGenericData( + PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, String.class)); + attributeMap.put(attrDefDateOfBirth, eidAuthData.getGenericData( + PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, String.class)); + + } else { + log.debug("Injecting legal mandator informations ... "); + final AttributeDefinition commonName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_LEGALNAME).first(); + final AttributeDefinition legalPersonId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first(); + + attributeMap.put(commonName, eidAuthData.getGenericData( + PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, String.class)); + attributeMap.put(legalPersonId, eidAuthData.getGenericData( + MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, String.class)); + + } + } + + private void injectRepesentativeInformation( + ImmutableAttributeMap.Builder attributeMap, IEidAuthData eidAuthData) { + final AttributeDefinition attrDefPersonalId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER).first(); + final AttributeDefinition attrDefFamilyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME).first(); + final AttributeDefinition attrDefGivenName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME).first(); + final AttributeDefinition attrDefDateOfBirth = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH).first(); + + attributeMap.put(attrDefPersonalId, + eidAuthData.getGenericData(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, String.class)); + attributeMap.put(attrDefFamilyName, eidAuthData.getFamilyName()); + attributeMap.put(attrDefGivenName, eidAuthData.getGivenName()); + + //TODO: throw an error in case of SZR Date with month or day = "00" + attributeMap.put(attrDefDateOfBirth, eidAuthData.getDateOfBirth()); + + } + + /** + * Work-around to inject representative information as nat. person subject to bypass eIDAS Node validation. + * + *

Injection will only be done if this work-around is enabled by configuration, + * the mandator is a legal person, and both legal and natural person subject's is requested.

+ * + * @param attributeMap Attribute set for eIDAS response + * @param eidasReq Incoming eIDAS request + * @param authData Authentication data + */ + private void injectJurPersonWorkaroundIfRequired( + ImmutableAttributeMap.Builder attributeMap, ILightRequest eidasReq, IAuthData authData) { + if (isLegalPersonWorkaroundActive() && isLegalPersonMandateAvailable(authData) + && EidasProxyServiceUtils.isNaturalPersonRequested(eidasReq) + && EidasProxyServiceUtils.isLegalPersonRequested(eidasReq)) { + log.debug("Injecting representative information as nat. person subject to bypass eIDAS Node validation"); + attributeMap.putAll(buildAttributesWithoutMandate(authData)); + + } + } + + private ImmutableAttributeMap buildAttributesWithoutMandate(IAuthData eidAuthData) { + //TODO: throw an error in case of SZR Date with month or day = "00" + return buildAttributesWithoutMandate( + eidAuthData.getGenericData(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, String.class), + eidAuthData.getFamilyName(), + eidAuthData.getGivenName(), + eidAuthData.getDateOfBirth()); + + } + + private ImmutableAttributeMap buildAttributesWithoutMandate(String personalIdentifier, String familyName, + String givenName, String dateOfBirth) { + final AttributeDefinition attrDefPersonalId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first(); + final AttributeDefinition attrDefFamilyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_CURRENTFAMILYNAME).first(); + final AttributeDefinition attrDefGivenName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_CURRENTGIVENNAME).first(); + final AttributeDefinition attrDefDateOfBirth = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_DATEOFBIRTH).first(); + + final ImmutableAttributeMap.Builder attributeMap = + ImmutableAttributeMap.builder() + .put(attrDefPersonalId, personalIdentifier) + .put(attrDefFamilyName, familyName) + .put(attrDefGivenName, givenName) + .put(attrDefDateOfBirth, dateOfBirth); + + return attributeMap.build(); + + } + + private BinaryLightToken putResponseInCommunicationCache(ILightResponse lightResponse) + throws ServletException { + final BinaryLightToken binaryLightToken; + try { + final SpecificCommunicationService springManagedSpecificConnectorCommunicationService = + (SpecificCommunicationService) context.getBean( + SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE + .toString()); + + binaryLightToken = springManagedSpecificConnectorCommunicationService.putResponse(lightResponse); + + } catch (final SpecificCommunicationException e) { + log.error("Unable to process specific request"); + throw new ServletException(e); + + } + + return binaryLightToken; + } + + private boolean isLegalPersonWorkaroundActive() { + return basicConfig.getBasicConfigurationBoolean( + MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_WORKAROUND_MANDATES_LEGAL_PERSON, + false); + + } + + private boolean isLegalPersonMandateAvailable(IAuthData authData) { + return StringUtils.isNoneEmpty(authData.getGenericData( + MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, String.class)); + + } + +} diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServicePendingRequest.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServicePendingRequest.java new file mode 100644 index 00000000..a3b5007a --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServicePendingRequest.java @@ -0,0 +1,28 @@ +package at.asitplus.eidas.specific.modules.msproxyservice.protocol; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl; +import eu.eidas.auth.commons.light.ILightRequest; +import lombok.Getter; +import lombok.Setter; + +/** + * Pending-request of an authentication process from eIDAS Proxy-Service. + * + * @author tlenz + * + */ +@Component("ProxyServicePendingRequest") +@Scope(value = BeanDefinition.SCOPE_PROTOTYPE) +public class ProxyServicePendingRequest extends RequestImpl { + + private static final long serialVersionUID = 4227378344716277935L; + + @Getter + @Setter + ILightRequest eidasRequest; + +} diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/utils/EidasProxyServiceUtils.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/utils/EidasProxyServiceUtils.java new file mode 100644 index 00000000..4cd7ba6c --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/utils/EidasProxyServiceUtils.java @@ -0,0 +1,45 @@ +package at.asitplus.eidas.specific.modules.msproxyservice.utils; + +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import eu.eidas.auth.commons.light.ILightRequest; + +/** + * Common utils for eIDAS Proxy-Service implementation. + * + * @author tlenz + * + */ +public class EidasProxyServiceUtils { + + /** + * Check if legal person subject is requested by eIDAS Connector. + * + * @param eidasRequest Authentication request from eIDAS Connector. + * @return true if LegalPersonIdentifier is requested, otherwise falselse + */ + public static boolean isLegalPersonRequested(ILightRequest eidasRequest) { + return eidasRequest.getRequestedAttributes().entrySet().stream() + .filter(el -> el.getKey().getFriendlyName().equals(Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER)) + .findFirst() + .isPresent(); + + } + + /** + * Check if natural person subject is requested by eIDAS Connector. + * + * @param eidasRequest Authentication request from eIDAS Connector. + * @return true if PersonIdentifier is requested, otherwise falselse + */ + public static boolean isNaturalPersonRequested(ILightRequest eidasRequest) { + return eidasRequest.getRequestedAttributes().entrySet().stream() + .filter(el -> el.getKey().getFriendlyName().equals(Constants.eIDAS_ATTR_PERSONALIDENTIFIER)) + .findFirst() + .isPresent(); + + } + + private EidasProxyServiceUtils() { + //hide constructor for class with static methods only + } +} diff --git a/modules/eidas_proxy-sevice/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider b/modules/eidas_proxy-sevice/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider new file mode 100644 index 00000000..9158d2e6 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider @@ -0,0 +1 @@ +at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceSpringResourceProvider \ No newline at end of file diff --git a/modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties b/modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties new file mode 100644 index 00000000..3f92d58a --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties @@ -0,0 +1,14 @@ +eidas.proxyservice.01=General error on request-validation from national eIDAS Proxy-Service +eidas.proxyservice.02=Authentication request contains not communication token. +eidas.proxyservice.03=General error during eIDAS-Node communication. Reason: {} +eidas.proxyservice.04=Validation of eIDAS Authn request failed. Reason: {} +eidas.proxyservice.05=No eIDAS-Connector Issuer in Authn. request. Authentication not possible +eidas.proxyservice.06=Can not build eIDAS Proxy-Service response. Authentication FAILED. +eidas.proxyservice.07=Can not determine eIDAS-Connector CountryCode. Authentication not possible +eidas.proxyservice.08=Validation of eIDAS Authn request failed. Reason: Legal person and natural person can not be requested at once. +eidas.proxyservice.09=eIDAS authentication not possible, because legal person is requested but mandates are disabled in general +eidas.proxyservice.10=eIDAS authentication not possible, because legal person is requested but not mandate profiles are defined +eidas.proxyservice.11=No Authentication request with stated communication token. + + +eidas.proxyservice.99=Internal error during eIDAS Proxy-Service authentication \ No newline at end of file diff --git a/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml b/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml new file mode 100644 index 00000000..2055b5a9 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/EidasProxyMessageSourceTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/EidasProxyMessageSourceTest.java new file mode 100644 index 00000000..efe572b5 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/EidasProxyMessageSourceTest.java @@ -0,0 +1,50 @@ +package at.asitplus.eidas.specific.modules.auth.idaustria.test; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import at.asitplus.eidas.specific.modules.msproxyservice.EidasProxyMessageSource; +import at.gv.egiz.eaaf.core.api.logging.IMessageSourceLocation; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { + "/spring/SpringTest-context_basic_test.xml", + "/spring/SpringTest-context_basic_mapConfig.xml", + }) +public class EidasProxyMessageSourceTest { + + @Autowired + private ResourceLoader loader; + @Autowired(required = false) + private List messageSources; + + @Test + public void checkMessageSources() { + Assert.assertNotNull("No messageSource", messageSources); + Assert.assertFalse("No message source", messageSources.isEmpty()); + + boolean found = false; + + for (final IMessageSourceLocation messageSource : messageSources) { + found = found ? found : messageSource instanceof EidasProxyMessageSource; + + Assert.assertNotNull("No sourcePath", messageSource.getMessageSourceLocation()); + for (final String el : messageSource.getMessageSourceLocation()) { + final Resource messages = loader.getResource(el + ".properties"); + Assert.assertTrue("Source not exist", messages.exists()); + + } + } + + Assert.assertTrue("Internal messagesource not found", found); + + } +} diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/MsProxyServiceSpringResourceProviderTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/MsProxyServiceSpringResourceProviderTest.java new file mode 100644 index 00000000..8c6da366 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/MsProxyServiceSpringResourceProviderTest.java @@ -0,0 +1,56 @@ +package at.asitplus.eidas.specific.modules.auth.idaustria.test; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.io.IOUtils; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.springframework.core.io.Resource; + +import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceSpringResourceProvider; +import at.gv.egiz.eaaf.core.test.TestConstants; + + + +@RunWith(BlockJUnit4ClassRunner.class) +public class MsProxyServiceSpringResourceProviderTest { + + @Test + public void testSpringConfig() { + final MsProxyServiceSpringResourceProvider test = + new MsProxyServiceSpringResourceProvider(); + for (final Resource el : test.getResourcesToLoad()) { + try { + IOUtils.toByteArray(el.getInputStream()); + + } catch (final IOException e) { + Assert.fail("Ressouce: " + el.getFilename() + " not found"); + } + + } + + Assert.assertNotNull("no Name", test.getName()); + Assert.assertNull("Find package definitions", test.getPackagesToScan()); + + } + + @Test + public void testSpILoaderConfig() { + final InputStream el = this.getClass().getResourceAsStream(TestConstants.TEST_SPI_LOADER_PATH); + try { + final String spiFile = IOUtils.toString(el, "UTF-8"); + + Assert.assertEquals("Wrong classpath in SPI file", + MsProxyServiceSpringResourceProvider.class.getName(), spiFile); + + + } catch (final IOException e) { + Assert.fail("Ressouce: " + TestConstants.TEST_SPI_LOADER_PATH + " not found"); + + } + } + +} diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java new file mode 100644 index 00000000..55958d9e --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java @@ -0,0 +1,666 @@ +package at.asitplus.eidas.specific.modules.auth.idaustria.test.protocol; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URLDecoder; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opensaml.saml.saml2.core.NameIDType; +import org.opensaml.saml.saml2.core.StatusCode; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +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 com.google.common.collect.ImmutableSortedSet; + +import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration; +import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +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.test.dummy.DummySpecificCommunicationService; +import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; +import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException; +import at.asitplus.eidas.specific.modules.msproxyservice.protocol.EidasProxyServiceController; +import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest; +import at.gv.egiz.eaaf.core.api.data.EaafConstants; +import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes; +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 eu.eidas.auth.commons.EidasParameterKeys; +import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; +import eu.eidas.auth.commons.light.ILightResponse; +import eu.eidas.auth.commons.light.impl.LightRequest; +import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames; +import eu.eidas.specificcommunication.exception.SpecificCommunicationException; +import eu.eidas.specificcommunication.protocol.SpecificCommunicationService; + +@RunWith(SpringJUnit4ClassRunner.class) +@PrepareForTest(CreateIdentityLinkTask.class) +@ContextConfiguration(locations = { + "/spring/SpringTest-context_basic_test.xml", + "/spring/SpringTest-context_basic_mapConfig.xml", + }) +@EnableWebMvc +public class EidasProxyServiceControllerTest { + + @Autowired private EidasProxyServiceController controller; + + @Autowired private DummySpecificCommunicationService proxyService; + @Autowired private DummyProtocolAuthService authService; + @Autowired private EidasAttributeRegistry attrRegistry; + @Autowired private ApplicationContext context; + + @Autowired MsConnectorDummyConfigMap config; + + private MockHttpServletRequest httpReq; + private MockHttpServletResponse httpResp; + + private SpecificCommunicationService springManagedSpecificConnectorCommunicationService; + + /** + * jUnit test set-up. + */ + @Before + public void setUp() throws EaafStorageException, URISyntaxException { + httpReq = new MockHttpServletRequest("POST", "http://localhost/ms_connector/eidas/light/idp/redirect"); + httpResp = new MockHttpServletResponse(); + RequestContextHolder.resetRequestAttributes(); + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp)); + + proxyService.setiLightRequest(null); + proxyService.setError(null); + + config.putConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint", + "http://eidas.proxy/endpoint"); + + springManagedSpecificConnectorCommunicationService = + (SpecificCommunicationService) context.getBean( + SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE + .toString()); + + } + + @Test + public void generateErrorResponseWrongPendingReq() throws Throwable { + Assert.assertFalse("wrong statusCode", controller.generateErrorMessage( + new EaafException("1000"), + httpReq, httpResp, null)); + + } + + @Test + public void generateErrorResponse() throws Throwable { + ProxyServicePendingRequest pendingReq = new ProxyServicePendingRequest(); + pendingReq.initialize(httpReq, config); + + LightRequest.Builder eidasRequestBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .spType("public") + .requesterId(RandomStringUtils.randomAlphanumeric(10)) + .providerName(RandomStringUtils.randomAlphanumeric(10)); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + + // execute test + Assert.assertTrue("wrong statusCode", controller.generateErrorMessage( + new EaafException("1000"), + httpReq, httpResp, + pendingReq)); + + // validate state + assertNotNull("not redirct Header", httpResp.getHeader("Location")); + assertTrue("wrong redirect URL", httpResp.getHeader("Location").startsWith("http://eidas.proxy/endpoint?token=")); + String token = httpResp.getHeader("Location").substring("http://eidas.proxy/endpoint?token=".length()); + + ILightResponse resp = springManagedSpecificConnectorCommunicationService.getAndRemoveResponse(URLDecoder.decode(token, "UTF-8"), + ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes())); + + assertNotNull("responseId", resp.getId()); + assertEquals("inResponseTo", pendingReq.getEidasRequest().getId(), resp.getInResponseToId()); + assertEquals("relayState", pendingReq.getEidasRequest().getRelayState(), resp.getRelayState()); + + assertNotNull("subjectNameId", resp.getSubject()); + assertEquals("subjectNameIdFormat", NameIDType.TRANSIENT, resp.getSubjectNameIdFormat()); + assertTrue("not attributes", resp.getAttributes().isEmpty()); + + assertEquals("StatusCode", StatusCode.RESPONDER, resp.getStatus().getStatusCode()); + //assertEquals("SubStatusCode", "", resp.getStatus().getSubStatusCode()); + //assertEquals("StatusMsg", "", resp.getStatus().getStatusMessage()); + + } + + @Test + public void missingEidasToken() { + EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, + () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.02", exception.getErrorId()); + + } + + @Test + public void wrongEidasTokenWithNullpointerException() { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + + //validate state + EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, + () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.11", exception.getErrorId()); + + } + + @Test + public void wrongEidasTokenCacheCommunicationError() { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + proxyService.setError(new SpecificCommunicationException(RandomStringUtils.randomAlphanumeric(10))); + + //validate state + EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, + () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.03", exception.getErrorId()); + Assert.assertTrue("Wrong exception", (exception.getCause() instanceof SpecificCommunicationException)); + + } + + @Test + public void missingServiceProviderCountry() { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + //validate state + EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, + () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.07", exception.getErrorId()); + + } + + @Test + public void requestingLegalAndNaturalPerson() { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + //validate state + EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, + () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.08", exception.getErrorId()); + + } + + @Test + public void requestLegalPersonButNoMandates() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "false"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + //validate state + EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, + () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.09", exception.getErrorId()); + + } + + @Test + public void validAuthnRequest() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "false"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + Assert.assertNotNull("pendingRequest", authService.getPendingReq()); + Assert.assertTrue("wrong pendingRequest", authService.getPendingReq() instanceof ProxyServicePendingRequest); + ProxyServicePendingRequest pendingReq = (ProxyServicePendingRequest) authService.getPendingReq(); + Assert.assertNotNull("missing uniqueSpId", pendingReq.getSpEntityId()); + Assert.assertNotNull("missing eidasReq", pendingReq.getEidasRequest()); + + Assert.assertFalse("isPassive", pendingReq.isPassiv()); + Assert.assertTrue("isPassive", pendingReq.forceAuth()); + Assert.assertFalse("isPassive", pendingReq.isAuthenticated()); + Assert.assertFalse("isPassive", pendingReq.isAbortedByUser()); + Assert.assertTrue("isPassive", pendingReq.isNeedAuthentication()); + + Assert.assertNotNull("missing spConfig", pendingReq.getServiceProviderConfiguration()); + ServiceProviderConfiguration spConfig = + pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class); + Assert.assertNotNull("uniqueId", spConfig.getUniqueIdentifier()); + Assert.assertEquals("uniqueId wrong pattern", + authnReqBuilder.build().getIssuer(), + spConfig.getUniqueIdentifier()); + Assert.assertEquals("friendlyName wrong pattern", + MessageFormat.format(MsProxyServiceConstants.TEMPLATE_SP_UNIQUE_ID, spCountryCode, "public"), + spConfig.getFriendlyName()); + + Assert.assertEquals("uniqueId not match to pendingReq", + pendingReq.getSpEntityId(), spConfig.getUniqueIdentifier()); + Assert.assertNotNull("bpkTarget", spConfig.getAreaSpecificTargetIdentifier()); + Assert.assertEquals("wrong bPK Target", + EaafConstants.URN_PREFIX_EIDAS + "AT+" + spCountryCode, + spConfig.getAreaSpecificTargetIdentifier()); + + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode()); + + } + + @Test + public void validAuthnRequestWithMandatesDefaultProfilesNat() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + + + proxyService.setiLightRequest(authnReqBuilder.build()); + + List mandateProfilesNat = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + List mandateProfilesJur = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(mandateProfilesNat, ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, + StringUtils.join(mandateProfilesJur, ",")); + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("mandateprofile size", mandateProfilesNat.size(), spConfig.getMandateProfiles().size()); + spConfig.getMandateProfiles().stream() + .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfilesNat.contains(el))); + assertEquals("MandateMode", SpMandateModes.NATURAL, spConfig.getMandateMode()); + + } + + @Test + public void validAuthnRequestWithMandatesDefaultProfilesJur() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); + + + proxyService.setiLightRequest(authnReqBuilder.build()); + + List mandateProfilesNat = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + List mandateProfilesJur = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(mandateProfilesNat, ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, + StringUtils.join(mandateProfilesJur, ",")); + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("mandateprofile size", mandateProfilesJur.size(), spConfig.getMandateProfiles().size()); + spConfig.getMandateProfiles().stream() + .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfilesJur.contains(el))); + assertEquals("MandateMode", SpMandateModes.LEGAL_FORCE, spConfig.getMandateMode()); + + } + + @Test + public void validAuthnRequestWithMandatesDefaultNoJurProfiles() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); + + + proxyService.setiLightRequest(authnReqBuilder.build()); + + List mandateProfilesNat = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(mandateProfilesNat, ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, ""); + + //validate state + EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, + () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.10", exception.getErrorId()); + + } + + @Test + public void validAuthnRequestWithMandatesDefaultNoNatProfiles() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + + + proxyService.setiLightRequest(authnReqBuilder.build()); + + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, ""); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, ""); + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode()); + + } + + @Test + public void validAuthnRequestIssueSpecificNoMandates() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + + String issuer = RandomStringUtils.randomAlphabetic(10); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(issuer) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + + // set default mandate configuration + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + // set specific mandate configuration + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "false"); + + List mandateProfiles = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL, + StringUtils.join(mandateProfiles, ",")); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL, + StringUtils.join(Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode()); + + } + + @Test + public void validAuthnRequestIssueSpecificMandatesNat() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + + String issuer = "https://apps.egiz.gv.at/EidasNode//ConnectorMetadata"; + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(issuer) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + + // set default mandate configuration + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "false"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + // set specific mandate configuration + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "true"); + + List mandateProfiles = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL, + StringUtils.join(mandateProfiles, ",")); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL, + StringUtils.join(Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("mandateprofile size", mandateProfiles.size(), spConfig.getMandateProfiles().size()); + spConfig.getMandateProfiles().stream() + .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfiles.contains(el))); + assertEquals("MandateMode", SpMandateModes.NATURAL, spConfig.getMandateMode()); + + } + + @Test + public void validAuthnRequestIssueSpecificMandatesJur() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + + String issuer = RandomStringUtils.randomAlphabetic(10); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(issuer) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + + // set default mandate configuration + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + // set specific mandate configuration + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "true"); + + List mandateProfiles = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL, + StringUtils.join(mandateProfiles, ",")); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL, + StringUtils.join(Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("mandateprofile size", mandateProfiles.size(), spConfig.getMandateProfiles().size()); + spConfig.getMandateProfiles().stream() + .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfiles.contains(el))); + assertEquals("MandateMode", SpMandateModes.LEGAL_FORCE, spConfig.getMandateMode()); + + } + + private void addConnectorConfig(int i, String key, String value) { + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_PREFIX + String.valueOf(i) + "." + key, + value); + + } + +} + + diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java new file mode 100644 index 00000000..52cc01d4 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java @@ -0,0 +1,637 @@ +package at.asitplus.eidas.specific.modules.auth.idaustria.test.protocol; + +import static at.asitplus.eidas.specific.core.MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import java.net.URISyntaxException; +import java.net.URLDecoder; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.commons.lang3.RandomStringUtils; +import org.joda.time.DateTime; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opensaml.saml.saml2.core.NameIDType; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +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 com.google.common.collect.ImmutableSortedSet; + +import at.asitplus.eidas.specific.core.MsEidasNodeConstants; +import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap; +import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummySpConfiguration; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +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.msproxyservice.protocol.ProxyServiceAuthenticationAction; +import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest; +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.data.PvpAttributeDefinitions; +import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions.EidIdentityStatusLevelValues; +import at.gv.egiz.eaaf.core.api.idp.IAuthData; +import at.gv.egiz.eaaf.core.api.idp.IEidAuthData; +import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; +import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl; +import eu.eidas.auth.commons.attribute.AttributeDefinition; +import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; +import eu.eidas.auth.commons.light.ILightResponse; +import eu.eidas.auth.commons.light.impl.LightRequest; +import eu.eidas.auth.commons.light.impl.LightRequest.Builder; +import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames; +import eu.eidas.specificcommunication.exception.SpecificCommunicationException; +import eu.eidas.specificcommunication.protocol.SpecificCommunicationService; + +@RunWith(SpringJUnit4ClassRunner.class) +@PrepareForTest(CreateIdentityLinkTask.class) +@ContextConfiguration(locations = { + "/spring/SpringTest-context_basic_test.xml", + "/spring/SpringTest-context_basic_mapConfig.xml", + }) +public class ProxyServiceAuthenticationActionTest { + + @Autowired private MsConnectorDummyConfigMap basicConfig; + @Autowired private ProxyServiceAuthenticationAction action; + @Autowired private ApplicationContext context; + @Autowired EidasAttributeRegistry attrRegistry; + + private MockHttpServletRequest httpReq; + private MockHttpServletResponse httpResp; + private ProxyServicePendingRequest pendingReq; + private MsConnectorDummySpConfiguration oaParam; + private SpecificCommunicationService springManagedSpecificConnectorCommunicationService; + + + /** + * jUnit test set-up. + * @throws EaafException In case of an error + */ + @Before + public void setUp() throws URISyntaxException, EaafException { + httpReq = new MockHttpServletRequest("POST", "https://localhost/authhandler"); + httpResp = new MockHttpServletResponse(); + RequestContextHolder.resetRequestAttributes(); + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp)); + + basicConfig.putConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint", + "http://eidas.proxy/endpoint"); + basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson", + "false"); + + 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 ProxyServicePendingRequest(); + pendingReq.initialize(httpReq, basicConfig); + pendingReq.setOnlineApplicationConfiguration(oaParam); + + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + + springManagedSpecificConnectorCommunicationService = + (SpecificCommunicationService) context.getBean( + SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE + .toString()); + + } + + @Test + public void wrongPendingRequestType() { + IAuthData authData = generateDummyAuthData(); + TestRequestImpl internalPendingReq = new TestRequestImpl(); + + EaafException exception = assertThrows(EaafException.class, + () -> action.processRequest(internalPendingReq, httpReq, httpResp, authData)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.99", exception.getErrorId()); + + } + + @Test + public void missingForwardUrl() { + Map attr = new HashMap<>(); + attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false); + basicConfig.removeConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint"); + + EaafException exception = assertThrows(EaafException.class, + () -> action.processRequest(pendingReq, httpReq, httpResp, authData)); + Assert.assertEquals("wrong errorCode", "config.08", exception.getErrorId()); + + } + + @Test + public void responseWithoutMandate() throws EaafException, SpecificCommunicationException { + Map attr = new HashMap<>(); + attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false); + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 4, respAttr.size()); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_DATEOFBIRTH, + authData.getDateOfBirth()); + + } + + @Test + public void responseWithNatMandate() throws EaafException, SpecificCommunicationException { + Map attr = new HashMap<>(); + attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + + attr.put(MsEidasNodeConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, + "1985-11-15"); + + + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 8, respAttr.size()); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, + (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); + + checkAttrValue(respAttr, Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER)); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTFAMILYNAME, + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME)); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTGIVENNAME, + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME)); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_DATEOFBIRTH, + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME)); + + } + + @Test + public void responseWithJurMandate() throws EaafException, SpecificCommunicationException { + Map attr = new HashMap<>(); + attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + attr.put(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 6, respAttr.size()); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, + (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); + + checkAttrValue(respAttr, Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER, + (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER)); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_LEGALNAME, + (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME)); + + assertNull("find nat. person subject: personalId", + getAttrValue(respAttr, Constants.eIDAS_ATTR_PERSONALIDENTIFIER)); + assertNull("find nat. person subject: familyName", + getAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTFAMILYNAME)); + assertNull("find nat. person subject: givenName", + getAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTGIVENNAME)); + assertNull("find nat. person subject: dateOfBirth", + getAttrValue(respAttr, Constants.eIDAS_ATTR_DATEOFBIRTH)); + + } + + @Test + public void responseWithNatMandateWithWorkAround() throws EaafException, SpecificCommunicationException { + basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson", + "true"); + + //request natural person subject only + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder().put( + attrRegistry.getCoreAttributeRegistry().getByFriendlyName(Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + + Map attr = new HashMap<>(); + attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + + attr.put(MsEidasNodeConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, + "1985-11-15"); + + + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 8, respAttr.size()); + + } + + @Test + public void responseWithJurMandateWithWorkAround() throws EaafException, SpecificCommunicationException { + basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson", + "true"); + + //request natural person subject only + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + Map attr = new HashMap<>(); + attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + attr.put(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 10, respAttr.size()); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, Constants.eIDAS_ATTR_DATEOFBIRTH, authData.getDateOfBirth()); + + } + + @Test + public void responseWithJurMandateWithWorkAroundNoNatSubject() throws EaafException, SpecificCommunicationException { + basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson", + "true"); + + //request natural person subject only + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + Map attr = new HashMap<>(); + attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + attr.put(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 6, respAttr.size()); + assertNull("find nat. person subject: personalId", + getAttrValue(respAttr, Constants.eIDAS_ATTR_PERSONALIDENTIFIER)); + assertNull("find nat. person subject: familyName", + getAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTFAMILYNAME)); + assertNull("find nat. person subject: givenName", + getAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTGIVENNAME)); + assertNull("find nat. person subject: dateOfBirth", + getAttrValue(respAttr, Constants.eIDAS_ATTR_DATEOFBIRTH)); + + } + + @Test + public void checkBasicConstrainsInAction() { + + Assert.assertTrue("Wrong NeedAuthentication", action.needAuthentication(pendingReq, httpReq, httpResp)); + Assert.assertNotNull("Missing ActionName", action.getDefaultActionName()); + + Assert.assertNotNull("missing ActionBean", context.getBean(ProxyServiceAuthenticationAction.class)); + + } + + private IAuthData generateDummyAuthData() { + return generateDummyAuthData(Collections.emptyMap(), EaafConstants.EIDAS_LOA_LOW, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1940-01-01", false); + + } + + private Object getAttrValue(ImmutableAttributeMap respAttr, String attrName) { + final AttributeDefinition attrDef = + attrRegistry.getCoreAttributeRegistry().getByFriendlyName(attrName).first(); + return respAttr.getFirstValue(attrDef); + + } + + private void checkAttrValue(ImmutableAttributeMap respAttr, String attrName, String expected) { + Object value = getAttrValue(respAttr, attrName); + assertNotNull("not attr value: " + attrName, value); + + if (value instanceof String) { + assertEquals("wrong attr. value: " + attrName, expected, value); + + } else if ( value instanceof DateTime) { + assertEquals("wrong attr. value: " + attrName, expected, ((DateTime)value).toString("yyyy-MM-dd")); + + } + } + + private ImmutableAttributeMap validateBasicEidasResponse(IAuthData authData) throws SpecificCommunicationException { + assertNotNull("not redirct Header", httpResp.getHeader("Location")); + assertTrue("wrong redirect URL", httpResp.getHeader("Location").startsWith("http://eidas.proxy/endpoint?token=")); + String token = httpResp.getHeader("Location").substring("http://eidas.proxy/endpoint?token=".length()); + + ILightResponse resp = springManagedSpecificConnectorCommunicationService.getAndRemoveResponse(URLDecoder.decode(token), + ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes())); + + assertNotNull("responseId", resp.getId()); + assertEquals("inResponseTo", pendingReq.getEidasRequest().getId(), resp.getInResponseToId()); + assertEquals("relayState", pendingReq.getEidasRequest().getRelayState(), resp.getRelayState()); + assertEquals("LoA", authData.getEidasQaaLevel(), resp.getLevelOfAssurance()); + + assertNotNull("subjectNameId", resp.getSubject()); + assertEquals("subjectNameIdFormat", NameIDType.TRANSIENT, resp.getSubjectNameIdFormat()); + + assertFalse("not attributes", resp.getAttributes().isEmpty()); + return resp.getAttributes(); + + } + + private Builder generateBasicLightRequest() { + return LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .spType("public") + .requesterId(RandomStringUtils.randomAlphanumeric(10)) + .providerName(RandomStringUtils.randomAlphanumeric(10)); + + } + + private IAuthData generateDummyAuthData(Map attrs, String loa, String familyName, String givenName, String dateOfBirth, + boolean useMandates) { + return new IEidAuthData() { + + @Override + public boolean isSsoSession() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isForeigner() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isBaseIdTransferRestrication() { + // TODO Auto-generated method stub + return false; + } + + @Override + public Date getSsoSessionValidTo() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getSessionIndex() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getNameIdFormat() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getNameID() { + // TODO Auto-generated method stub + return null; + } + + @Override + public IIdentityLink getIdentityLink() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getIdentificationValue() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getIdentificationType() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getGivenName() { + return givenName; + } + + @Override + public T getGenericData(String key, Class clazz) { + if (attrs.containsKey(key)) { + return (T) attrs.get(key); + + } else { + return null; + } + + } + + @Override + public String getDateOfBirth() { + return dateOfBirth; + } + + @Override + public String getFamilyName() { + return familyName; + } + + @Override + public String getEncryptedSourceIdType() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getEncryptedSourceId() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getEidasQaaLevel() { + return loa; + + } + + + @Override + public String getCiticenCountryCode() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getBpkType() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getBpk() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getAuthenticationIssuer() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getAuthenticationIssueInstantString() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Date getAuthenticationIssueInstant() { + // TODO Auto-generated method stub + return null; + } + + @Override + public byte[] getSignerCertificate() { + // TODO Auto-generated method stub + return null; + } + + @Override + public byte[] getEidToken() { + // TODO Auto-generated method stub + return null; + } + + @Override + public EidIdentityStatusLevelValues getEidStatus() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getVdaEndPointUrl() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isUseMandate() { + return useMandates; + + } + + @Override + public String getDateOfBirthFormated(String pattern) { + // TODO Auto-generated method stub + return null; + } + }; + + } +} diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml b/modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml new file mode 100644 index 00000000..6510546e --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml @@ -0,0 +1,39 @@ + + + + + + Dynamic attributes + + http://eidas.europa.eu/attributes/naturalperson/AdditionalAttribute + AdditionalAttribute + NaturalPerson + false + http://www.w3.org/2001/XMLSchema + string + xs + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/LegalAdditionalAttribute + LegalAdditionalAttribute + LegalPerson + false + http://www.w3.org/2001/XMLSchema + string + xs + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/eidas-attributes.xml b/modules/eidas_proxy-sevice/src/test/resources/config/eidas-attributes.xml new file mode 100644 index 00000000..cbae35db --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/resources/config/eidas-attributes.xml @@ -0,0 +1,376 @@ + + + + + + eIDAS attributes + + http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier + PersonIdentifier + NaturalPerson + true + true + http://eidas.europa.eu/attributes/naturalperson + PersonIdentifierType + eidas-natural + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/naturalperson/CurrentFamilyName + FamilyName + NaturalPerson + true + true + http://eidas.europa.eu/attributes/naturalperson + CurrentFamilyNameType + eidas-natural + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/naturalperson/CurrentGivenName + FirstName + NaturalPerson + true + true + http://eidas.europa.eu/attributes/naturalperson + CurrentGivenNameType + eidas-natural + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/naturalperson/DateOfBirth + DateOfBirth + NaturalPerson + true + http://eidas.europa.eu/attributes/naturalperson + DateOfBirthType + eidas-natural + eu.eidas.auth.commons.attribute.impl.DateTimeAttributeValueMarshaller + + http://eidas.europa.eu/attributes/naturalperson/BirthName + BirthName + NaturalPerson + false + true + http://eidas.europa.eu/attributes/naturalperson + BirthNameType + eidas-natural + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth + PlaceOfBirth + NaturalPerson + false + http://eidas.europa.eu/attributes/naturalperson + PlaceOfBirthType + eidas-natural + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/naturalperson/CurrentAddress + CurrentAddress + NaturalPerson + false + http://eidas.europa.eu/attributes/naturalperson + CurrentAddressType + eidas-natural + eu.eidas.auth.commons.protocol.eidas.impl.CurrentAddressAttributeValueMarshaller + + http://eidas.europa.eu/attributes/naturalperson/Gender + Gender + NaturalPerson + false + http://eidas.europa.eu/attributes/naturalperson + GenderType + eidas-natural + eu.eidas.auth.commons.protocol.eidas.impl.GenderAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/LegalPersonIdentifier + LegalPersonIdentifier + LegalPerson + true + true + http://eidas.europa.eu/attributes/legalperson + LegalPersonIdentifierType + eidas-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/LegalName + LegalName + LegalPerson + true + true + http://eidas.europa.eu/attributes/legalperson + LegalNameType + eidas-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/LegalPersonAddress + LegalAddress + LegalPerson + false + http://eidas.europa.eu/attributes/legalperson + LegalPersonAddressType + eidas-legal + eu.eidas.auth.commons.protocol.eidas.impl.LegalAddressAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/VATRegistrationNumber + VATRegistration + LegalPerson + false + http://eidas.europa.eu/attributes/legalperson + VATRegistrationNumberType + eidas-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/TaxReference + TaxReference + LegalPerson + false + http://eidas.europa.eu/attributes/legalperson + TaxReferenceType + eidas-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/D-2012-17-EUIdentifier + D-2012-17-EUIdentifier + LegalPerson + false + http://eidas.europa.eu/attributes/legalperson + D-2012-17-EUIdentifierType + eidas-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/LEI + LEI + LegalPerson + false + http://eidas.europa.eu/attributes/legalperson + LEIType + eidas-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/EORI + EORI + LegalPerson + false + http://eidas.europa.eu/attributes/legalperson + EORIType + eidas-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/SEED + SEED + LegalPerson + false + http://eidas.europa.eu/attributes/legalperson + SEEDType + eidas-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/SIC + SIC + LegalPerson + false + http://eidas.europa.eu/attributes/legalperson + SICType + eidas-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/naturalperson/representative/PersonIdentifier + RepresentativePersonIdentifier + RepresentativeNaturalPerson + false + true + http://eidas.europa.eu/attributes/naturalperson/representative + PersonIdentifierType + eidas-natural + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/naturalperson/representative/CurrentFamilyName + RepresentativeFamilyName + RepresentativeNaturalPerson + false + true + http://eidas.europa.eu/attributes/naturalperson/representative + CurrentFamilyNameType + eidas-reprentative-natural + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/naturalperson/representative/CurrentGivenName + RepresentativeFirstName + RepresentativeNaturalPerson + false + true + http://eidas.europa.eu/attributes/naturalperson/representative + CurrentGivenNameType + eidas-reprentative-natural + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/naturalperson/representative/DateOfBirth + RepresentativeDateOfBirth + RepresentativeNaturalPerson + false + http://eidas.europa.eu/attributes/naturalperson/representative + DateOfBirthType + eidas-reprentative-natural + eu.eidas.auth.commons.attribute.impl.DateTimeAttributeValueMarshaller + + http://eidas.europa.eu/attributes/naturalperson/representative/BirthName + RepresentativeBirthName + RepresentativeNaturalPerson + false + true + http://eidas.europa.eu/attributes/naturalperson/representative + BirthNameType + eidas-reprentative-natural + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/naturalperson/representative/PlaceOfBirth + RepresentativePlaceOfBirth + RepresentativeNaturalPerson + false + http://eidas.europa.eu/attributes/naturalperson/representative + PlaceOfBirthType + eidas-reprentative-natural + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/naturalperson/representative/CurrentAddress + RepresentativeCurrentAddress + RepresentativeNaturalPerson + false + http://eidas.europa.eu/attributes/naturalperson/representative + CurrentAddressType + eidas-reprentative-natural + eu.eidas.auth.commons.protocol.eidas.impl.RepvCurrentAddressAttributeValueMarshaller + + http://eidas.europa.eu/attributes/naturalperson/representative/Gender + RepresentativeGender + RepresentativeNaturalPerson + false + http://eidas.europa.eu/attributes/naturalperson/representative + GenderType + eidas-reprentative-natural + eu.eidas.auth.commons.protocol.eidas.impl.GenderAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/representative/LegalPersonIdentifier + RepresentativeLegalPersonIdentifier + RepresentativeLegalPerson + false + true + http://eidas.europa.eu/attributes/legalperson/representative + LegalPersonIdentifierType + eidas-reprentative-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/representative/LegalName + RepresentativeLegalName + RepresentativeLegalPerson + false + true + http://eidas.europa.eu/attributes/legalperson/representative + LegalNameType + eidas-reprentative-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/representative/LegalPersonAddress + RepresentativeLegalAddress + RepresentativeLegalPerson + false + http://eidas.europa.eu/attributes/legalperson/representative + LegalPersonAddressType + eidas-reprentative-legal + eu.eidas.auth.commons.protocol.eidas.impl.RepvLegalAddressAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/representative/VATRegistrationNumber + RepresentativeVATRegistration + RepresentativeLegalPerson + false + http://eidas.europa.eu/attributes/legalperson/representative + VATRegistrationNumberType + eidas-reprentative-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/representative/TaxReference + RepresentativeTaxReference + RepresentativeLegalPerson + false + http://eidas.europa.eu/attributes/legalperson/representative + TaxReferenceType + eidas-reprentative-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/representative/D-2012-17-EUIdentifier + RepresentativeD-2012-17-EUIdentifier + RepresentativeLegalPerson + false + http://eidas.europa.eu/attributes/legalperson/representative + D-2012-17-EUIdentifierType + eidas-reprentative-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/representative/LEI + RepresentativeLEI + RepresentativeLegalPerson + false + http://eidas.europa.eu/attributes/legalperson/representative + LEIType + eidas-reprentative-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/representative/EORI + RepresentativeEORI + RepresentativeLegalPerson + false + http://eidas.europa.eu/attributes/legalperson/representative + EORIType + eidas-reprentative-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/representative/SEED + RepresentativeSEED + RepresentativeLegalPerson + false + http://eidas.europa.eu/attributes/legalperson/representative + SEEDType + eidas-reprentative-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/representative/SIC + RepresentativeSIC + RepresentativeLegalPerson + false + http://eidas.europa.eu/attributes/legalperson/representative + SICType + eidas-reprentative-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/representative/LegalPersonAddress + RepresentativeLegalAddress + RepresentativeLegalPerson + false + http://eidas.europa.eu/attributes/legalperson/representative + LegalPersonAddressType + eidas-reprentative-legal + eu.eidas.auth.commons.protocol.eidas.impl.RepvLegalAddressAttributeValueMarshaller + + http://eidas.europa.eu/attributes/legalperson/representative/VATRegistrationNumber + RepresentativeVATRegistration + RepresentativeLegalPerson + false + http://eidas.europa.eu/attributes/legalperson/representative + VATRegistrationNumberType + eidas-reprentative-legal + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + + diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties new file mode 100644 index 00000000..4f3b82b5 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties @@ -0,0 +1,6 @@ +## Basic service configuration +eidas.ms.context.url.prefix=http://localhost +eidas.ms.context.url.request.validation=false + +eidas.ms.auth.eIDAS.node_v2.proxy.entityId=ownSpecificProxy +eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint=http://eidas.proxy/endpoint \ No newline at end of file diff --git a/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig.xml b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig.xml new file mode 100644 index 00000000..fe9ff441 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml new file mode 100644 index 00000000..9870d22a --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file -- cgit v1.2.3 From ce7e30f92356f602b65a0608b8224dd93b271f5e Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Fri, 13 May 2022 09:00:52 +0200 Subject: refact(core): switch to eaaf-components 1.3.x and replace 'java.util.Date' by 'java.time.Instant' --- .../test/protocol/ProxyServiceAuthenticationActionTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java index 52cc01d4..21d2f3b7 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java @@ -10,9 +10,9 @@ import static org.junit.Assert.assertTrue; import java.net.URISyntaxException; import java.net.URLDecoder; +import java.time.Instant; import java.util.Arrays; import java.util.Collections; -import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -474,7 +474,7 @@ public class ProxyServiceAuthenticationActionTest { } @Override - public Date getSsoSessionValidTo() { + public Instant getSsoSessionValidTo() { // TODO Auto-generated method stub return null; } @@ -591,7 +591,7 @@ public class ProxyServiceAuthenticationActionTest { } @Override - public Date getAuthenticationIssueInstant() { + public Instant getAuthenticationIssueInstant() { // TODO Auto-generated method stub return null; } -- cgit v1.2.3 From 38d7758281b9cb8ba0f1a7e8a8d10098bcf2dcb8 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Fri, 3 Jun 2022 11:40:52 +0200 Subject: refactor(eidas): split 'authmodule-eIDAS-v2' into 'common-eidas' code and connector-specific elements --- .../msproxyservice/MsProxyServiceConstants.java | 14 ++-- .../protocol/EidasProxyServiceController.java | 8 +-- .../protocol/ProxyServiceAuthenticationAction.java | 46 ++++++------- .../utils/EidasProxyServiceUtils.java | 6 +- .../protocol/EidasProxyServiceControllerTest.java | 31 ++++----- .../ProxyServiceAuthenticationActionTest.java | 76 +++++++++++----------- .../spring/SpringTest-context_basic_test.xml | 4 +- 7 files changed, 90 insertions(+), 95 deletions(-) (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java index f6a88aa3..fd6b45bb 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java @@ -1,6 +1,6 @@ package at.asitplus.eidas.specific.modules.msproxyservice; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants; import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants; /** @@ -15,22 +15,22 @@ public class MsProxyServiceConstants { public static final String TEMPLATE_SP_UNIQUE_ID = "eidasProxyAuth_from_{0}_type_{1}"; // configuration constants - public static final String CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID = Constants.CONIG_PROPS_EIDAS_NODE + public static final String CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID = EidasConstants.CONIG_PROPS_EIDAS_NODE + ".proxy.entityId"; - public static final String CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL = Constants.CONIG_PROPS_EIDAS_NODE + public static final String CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL = EidasConstants.CONIG_PROPS_EIDAS_NODE + ".proxy.forward.endpoint"; // mandate configuration public static final String CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED = - Constants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.mandates.enabled"; + EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.mandates.enabled"; public static final String CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL = - Constants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.mandates.profiles.natural.default"; + EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.mandates.profiles.natural.default"; public static final String CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL = - Constants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.mandates.profiles.legal.default"; + EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.mandates.profiles.legal.default"; public static final String CONIG_PROPS_EIDAS_PROXY_WORKAROUND_MANDATES_LEGAL_PERSON = - Constants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.workaround.mandates.legalperson"; + EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.workaround.mandates.legalperson"; // specific eIDAS-Connector configuration public static final String CONIG_PROPS_CONNECTOR_PREFIX = "connector"; diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java index e24c753e..cd404cee 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java @@ -25,8 +25,8 @@ import com.google.common.collect.ImmutableSortedSet; import at.asitplus.eidas.specific.core.MsEidasNodeConstants; import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry; +import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants; +import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry; import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException; import at.asitplus.eidas.specific.modules.msproxyservice.utils.EidasProxyServiceUtils; @@ -308,8 +308,8 @@ public class EidasProxyServiceController extends AbstractController implements I final ServiceProviderConfiguration spConfig = new ServiceProviderConfiguration(connectorConfigMap, authConfig); // build bPK target from Country-Code - final String ccCountry = authConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, - Constants.DEFAULT_MS_NODE_COUNTRY_CODE); + final String ccCountry = authConfig.getBasicConfiguration(EidasConstants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, + EidasConstants.DEFAULT_MS_NODE_COUNTRY_CODE); spConfig.setBpkTargetIdentifier( EaafConstants.URN_PREFIX_EIDAS + ccCountry + "+" + spCountry); diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java index 15524005..92165412 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java @@ -17,8 +17,8 @@ import org.springframework.web.util.UriComponentsBuilder; import at.asitplus.eidas.specific.core.MsEidasNodeConstants; import at.asitplus.eidas.specific.core.gui.StaticGuiBuilderConfiguration; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry; +import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants; +import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry; import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException; import at.asitplus.eidas.specific.modules.msproxyservice.utils.EidasProxyServiceUtils; @@ -85,7 +85,7 @@ public class ProxyServiceAuthenticationAction implements IAction { lightRespBuilder.relayState(eidasReq.getRelayState()); lightRespBuilder.status(ResponseStatus.builder() - .statusCode(Constants.SUCCESS_URI) + .statusCode(EidasConstants.SUCCESS_URI) .build()); //TODO: check if we can use transient subjectNameIds @@ -168,8 +168,8 @@ public class ProxyServiceAuthenticationAction implements IAction { log.debug("ForwardURL: " + forwardUrl + " selected to forward eIDAS request"); if (basicConfig.getBasicConfiguration( - Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD, - Constants.FORWARD_METHOD_GET).equals(Constants.FORWARD_METHOD_GET)) { + EidasConstants.CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD, + EidasConstants.FORWARD_METHOD_GET).equals(EidasConstants.FORWARD_METHOD_GET)) { log.debug("Use http-redirect for eIDAS node forwarding ... "); // send redirect @@ -182,14 +182,14 @@ public class ProxyServiceAuthenticationAction implements IAction { final StaticGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration( basicConfig, pendingReq, - Constants.TEMPLATE_POST_FORWARD_NAME, + EidasConstants.TEMPLATE_POST_FORWARD_NAME, null, resourceLoader); - config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_ENDPOINT, forwardUrl); - config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_TOKEN_NAME, + config.putCustomParameter(null, EidasConstants.TEMPLATE_POST_FORWARD_ENDPOINT, forwardUrl); + config.putCustomParameter(null, EidasConstants.TEMPLATE_POST_FORWARD_TOKEN_NAME, EidasParameterKeys.TOKEN.toString()); - config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_TOKEN_VALUE, + config.putCustomParameter(null, EidasConstants.TEMPLATE_POST_FORWARD_TOKEN_VALUE, tokenBase64); guiBuilder.build(httpReq, httpResp, config, "Forward to eIDASNode form"); @@ -233,13 +233,13 @@ public class ProxyServiceAuthenticationAction implements IAction { if (StringUtils.isNotEmpty(natMandatorId)) { log.debug("Injecting natural mandator informations ... "); final AttributeDefinition attrDefPersonalId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first(); + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first(); final AttributeDefinition attrDefFamilyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_CURRENTFAMILYNAME).first(); + EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first(); final AttributeDefinition attrDefGivenName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_CURRENTGIVENNAME).first(); + EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first(); final AttributeDefinition attrDefDateOfBirth = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_DATEOFBIRTH).first(); + EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first(); attributeMap.put(attrDefPersonalId, natMandatorId); attributeMap.put(attrDefFamilyName, eidAuthData.getGenericData( @@ -252,9 +252,9 @@ public class ProxyServiceAuthenticationAction implements IAction { } else { log.debug("Injecting legal mandator informations ... "); final AttributeDefinition commonName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_LEGALNAME).first(); + EidasConstants.eIDAS_ATTR_LEGALNAME).first(); final AttributeDefinition legalPersonId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first(); + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first(); attributeMap.put(commonName, eidAuthData.getGenericData( PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, String.class)); @@ -267,13 +267,13 @@ public class ProxyServiceAuthenticationAction implements IAction { private void injectRepesentativeInformation( ImmutableAttributeMap.Builder attributeMap, IEidAuthData eidAuthData) { final AttributeDefinition attrDefPersonalId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER).first(); + EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER).first(); final AttributeDefinition attrDefFamilyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME).first(); + EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME).first(); final AttributeDefinition attrDefGivenName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME).first(); + EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME).first(); final AttributeDefinition attrDefDateOfBirth = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH).first(); + EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH).first(); attributeMap.put(attrDefPersonalId, eidAuthData.getGenericData(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, String.class)); @@ -319,13 +319,13 @@ public class ProxyServiceAuthenticationAction implements IAction { private ImmutableAttributeMap buildAttributesWithoutMandate(String personalIdentifier, String familyName, String givenName, String dateOfBirth) { final AttributeDefinition attrDefPersonalId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first(); + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first(); final AttributeDefinition attrDefFamilyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_CURRENTFAMILYNAME).first(); + EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first(); final AttributeDefinition attrDefGivenName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_CURRENTGIVENNAME).first(); + EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first(); final AttributeDefinition attrDefDateOfBirth = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_DATEOFBIRTH).first(); + EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first(); final ImmutableAttributeMap.Builder attributeMap = ImmutableAttributeMap.builder() diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/utils/EidasProxyServiceUtils.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/utils/EidasProxyServiceUtils.java index 4cd7ba6c..b8a4c598 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/utils/EidasProxyServiceUtils.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/utils/EidasProxyServiceUtils.java @@ -1,6 +1,6 @@ package at.asitplus.eidas.specific.modules.msproxyservice.utils; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants; import eu.eidas.auth.commons.light.ILightRequest; /** @@ -19,7 +19,7 @@ public class EidasProxyServiceUtils { */ public static boolean isLegalPersonRequested(ILightRequest eidasRequest) { return eidasRequest.getRequestedAttributes().entrySet().stream() - .filter(el -> el.getKey().getFriendlyName().equals(Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER)) + .filter(el -> el.getKey().getFriendlyName().equals(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER)) .findFirst() .isPresent(); @@ -33,7 +33,7 @@ public class EidasProxyServiceUtils { */ public static boolean isNaturalPersonRequested(ILightRequest eidasRequest) { return eidasRequest.getRequestedAttributes().entrySet().stream() - .filter(el -> el.getKey().getFriendlyName().equals(Constants.eIDAS_ATTR_PERSONALIDENTIFIER)) + .filter(el -> el.getKey().getFriendlyName().equals(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER)) .findFirst() .isPresent(); diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java index 55958d9e..2b652f79 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java @@ -22,7 +22,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.opensaml.saml.saml2.core.NameIDType; import org.opensaml.saml.saml2.core.StatusCode; -import org.powermock.core.classloader.annotations.PrepareForTest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.mock.web.MockHttpServletRequest; @@ -37,10 +36,9 @@ import com.google.common.collect.ImmutableSortedSet; import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration; import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; -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.test.dummy.DummySpecificCommunicationService; +import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants; +import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry; +import at.asitplus.eidas.specific.modules.core.eidas.test.dummy.DummySpecificCommunicationService; import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException; import at.asitplus.eidas.specific.modules.msproxyservice.protocol.EidasProxyServiceController; @@ -59,7 +57,6 @@ import eu.eidas.specificcommunication.exception.SpecificCommunicationException; import eu.eidas.specificcommunication.protocol.SpecificCommunicationService; @RunWith(SpringJUnit4ClassRunner.class) -@PrepareForTest(CreateIdentityLinkTask.class) @ContextConfiguration(locations = { "/spring/SpringTest-context_basic_test.xml", "/spring/SpringTest-context_basic_mapConfig.xml", @@ -222,9 +219,9 @@ public class EidasProxyServiceControllerTest { .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) .requestedAttributes(ImmutableAttributeMap.builder() .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) .build()); proxyService.setiLightRequest(authnReqBuilder.build()); @@ -250,7 +247,7 @@ public class EidasProxyServiceControllerTest { .spType("public") .requestedAttributes(ImmutableAttributeMap.builder() .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); proxyService.setiLightRequest(authnReqBuilder.build()); @@ -280,7 +277,7 @@ public class EidasProxyServiceControllerTest { .spType("public") .requestedAttributes(ImmutableAttributeMap.builder() .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); proxyService.setiLightRequest(authnReqBuilder.build()); @@ -345,7 +342,7 @@ public class EidasProxyServiceControllerTest { .spType("public") .requestedAttributes(ImmutableAttributeMap.builder() .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); proxyService.setiLightRequest(authnReqBuilder.build()); @@ -389,7 +386,7 @@ public class EidasProxyServiceControllerTest { .spType("public") .requestedAttributes(ImmutableAttributeMap.builder() .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); proxyService.setiLightRequest(authnReqBuilder.build()); @@ -433,7 +430,7 @@ public class EidasProxyServiceControllerTest { .spType("public") .requestedAttributes(ImmutableAttributeMap.builder() .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); proxyService.setiLightRequest(authnReqBuilder.build()); @@ -466,7 +463,7 @@ public class EidasProxyServiceControllerTest { .spType("public") .requestedAttributes(ImmutableAttributeMap.builder() .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); proxyService.setiLightRequest(authnReqBuilder.build()); @@ -502,7 +499,7 @@ public class EidasProxyServiceControllerTest { .spType("public") .requestedAttributes(ImmutableAttributeMap.builder() .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); proxyService.setiLightRequest(authnReqBuilder.build()); @@ -556,7 +553,7 @@ public class EidasProxyServiceControllerTest { .spType("public") .requestedAttributes(ImmutableAttributeMap.builder() .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); proxyService.setiLightRequest(authnReqBuilder.build()); @@ -613,7 +610,7 @@ public class EidasProxyServiceControllerTest { .spType("public") .requestedAttributes(ImmutableAttributeMap.builder() .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); proxyService.setiLightRequest(authnReqBuilder.build()); diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java index 21d2f3b7..97b5bc03 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java @@ -24,7 +24,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.opensaml.saml.saml2.core.NameIDType; -import org.powermock.core.classloader.annotations.PrepareForTest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.mock.web.MockHttpServletRequest; @@ -39,9 +38,8 @@ import com.google.common.collect.ImmutableSortedSet; import at.asitplus.eidas.specific.core.MsEidasNodeConstants; import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap; import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummySpConfiguration; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; -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.core.eidas.EidasConstants; +import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry; import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServiceAuthenticationAction; import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest; import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants; @@ -64,7 +62,6 @@ import eu.eidas.specificcommunication.exception.SpecificCommunicationException; import eu.eidas.specificcommunication.protocol.SpecificCommunicationService; @RunWith(SpringJUnit4ClassRunner.class) -@PrepareForTest(CreateIdentityLinkTask.class) @ContextConfiguration(locations = { "/spring/SpringTest-context_basic_test.xml", "/spring/SpringTest-context_basic_mapConfig.xml", @@ -163,11 +160,11 @@ public class ProxyServiceAuthenticationActionTest { ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); assertEquals("wrong attr. size", 4, respAttr.size()); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName()); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName()); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_DATEOFBIRTH, + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, authData.getDateOfBirth()); } @@ -199,19 +196,19 @@ public class ProxyServiceAuthenticationActionTest { ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); assertEquals("wrong attr. size", 8, respAttr.size()); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName()); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName()); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER)); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTFAMILYNAME, + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME)); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTGIVENNAME, + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME)); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_DATEOFBIRTH, + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME)); } @@ -237,25 +234,25 @@ public class ProxyServiceAuthenticationActionTest { ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); assertEquals("wrong attr. size", 6, respAttr.size()); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName()); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName()); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER, + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER, (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER)); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_LEGALNAME, + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALNAME, (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME)); assertNull("find nat. person subject: personalId", - getAttrValue(respAttr, Constants.eIDAS_ATTR_PERSONALIDENTIFIER)); + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER)); assertNull("find nat. person subject: familyName", - getAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTFAMILYNAME)); + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME)); assertNull("find nat. person subject: givenName", - getAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTGIVENNAME)); + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME)); assertNull("find nat. person subject: dateOfBirth", - getAttrValue(respAttr, Constants.eIDAS_ATTR_DATEOFBIRTH)); + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH)); } @@ -267,7 +264,7 @@ public class ProxyServiceAuthenticationActionTest { //request natural person subject only LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder().put( - attrRegistry.getCoreAttributeRegistry().getByFriendlyName(Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); pendingReq.setEidasRequest(eidasRequestBuilder.build()); @@ -307,8 +304,8 @@ public class ProxyServiceAuthenticationActionTest { //request natural person subject only LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) .build()); pendingReq.setEidasRequest(eidasRequestBuilder.build()); @@ -331,11 +328,11 @@ public class ProxyServiceAuthenticationActionTest { ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); assertEquals("wrong attr. size", 10, respAttr.size()); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName()); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName()); - checkAttrValue(respAttr, Constants.eIDAS_ATTR_DATEOFBIRTH, authData.getDateOfBirth()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, authData.getDateOfBirth()); } @@ -347,7 +344,8 @@ public class ProxyServiceAuthenticationActionTest { //request natural person subject only LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) .build()); pendingReq.setEidasRequest(eidasRequestBuilder.build()); @@ -371,13 +369,13 @@ public class ProxyServiceAuthenticationActionTest { ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); assertEquals("wrong attr. size", 6, respAttr.size()); assertNull("find nat. person subject: personalId", - getAttrValue(respAttr, Constants.eIDAS_ATTR_PERSONALIDENTIFIER)); + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER)); assertNull("find nat. person subject: familyName", - getAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTFAMILYNAME)); + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME)); assertNull("find nat. person subject: givenName", - getAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTGIVENNAME)); + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME)); assertNull("find nat. person subject: dateOfBirth", - getAttrValue(respAttr, Constants.eIDAS_ATTR_DATEOFBIRTH)); + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH)); } diff --git a/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml index 9870d22a..08b25f0f 100644 --- a/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml +++ b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml @@ -14,7 +14,7 @@ + class="at.asitplus.eidas.specific.modules.core.eidas.test.dummy.DummySpecificCommunicationService" /> @@ -32,7 +32,7 @@ + class="at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry"> Date: Fri, 3 Jun 2022 15:24:01 +0200 Subject: test(core): add smoke test with full eIDAS OutGoing login and error-handling --- .../msproxyservice/MsProxyServiceSpringResourceProvider.java | 5 ++++- .../src/main/resources/spring/eidas_proxy-service.beans.xml | 7 +++++++ .../src/test/resources/spring/SpringTest-context_basic_test.xml | 8 -------- 3 files changed, 11 insertions(+), 9 deletions(-) (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceSpringResourceProvider.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceSpringResourceProvider.java index d36e4712..571ad8ab 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceSpringResourceProvider.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceSpringResourceProvider.java @@ -45,8 +45,11 @@ public class MsProxyServiceSpringResourceProvider implements SpringResourceProvi public Resource[] getResourcesToLoad() { final ClassPathResource eidasProxyServiceConfig = new ClassPathResource("/spring/eidas_proxy-service.beans.xml", MsProxyServiceSpringResourceProvider.class); + final ClassPathResource eidasRefImplConfig = new ClassPathResource("/eidas_v2_auth_ref_impl_config.beans.xml", + MsProxyServiceSpringResourceProvider.class); + - return new Resource[] { eidasProxyServiceConfig }; + return new Resource[] { eidasProxyServiceConfig, eidasRefImplConfig }; } } diff --git a/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml b/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml index 2055b5a9..1eb33e93 100644 --- a/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml +++ b/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml @@ -24,5 +24,12 @@ + + + + \ No newline at end of file diff --git a/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml index 08b25f0f..0b7540f5 100644 --- a/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml +++ b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml @@ -31,12 +31,4 @@ value="src/test/resources/config/additional-attributes.xml" /> - - - - - \ No newline at end of file -- cgit v1.2.3 From 968ba90c987ad1df6aa6434dfe9e43e6c5b6a2a3 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 7 Jun 2022 12:18:46 +0200 Subject: refact(eidas): rename package names, because there was a copy&past mistake --- .../test/EidasProxyMessageSourceTest.java | 50 -- .../MsProxyServiceSpringResourceProviderTest.java | 56 -- .../protocol/EidasProxyServiceControllerTest.java | 663 --------------------- .../ProxyServiceAuthenticationActionTest.java | 635 -------------------- .../test/EidasProxyMessageSourceTest.java | 50 ++ .../MsProxyServiceSpringResourceProviderTest.java | 56 ++ .../protocol/EidasProxyServiceControllerTest.java | 663 +++++++++++++++++++++ .../ProxyServiceAuthenticationActionTest.java | 635 ++++++++++++++++++++ 8 files changed, 1404 insertions(+), 1404 deletions(-) delete mode 100644 modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/EidasProxyMessageSourceTest.java delete mode 100644 modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/MsProxyServiceSpringResourceProviderTest.java delete mode 100644 modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java delete mode 100644 modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java create mode 100644 modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/EidasProxyMessageSourceTest.java create mode 100644 modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/MsProxyServiceSpringResourceProviderTest.java create mode 100644 modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java create mode 100644 modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/EidasProxyMessageSourceTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/EidasProxyMessageSourceTest.java deleted file mode 100644 index efe572b5..00000000 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/EidasProxyMessageSourceTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package at.asitplus.eidas.specific.modules.auth.idaustria.test; - -import java.util.List; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import at.asitplus.eidas.specific.modules.msproxyservice.EidasProxyMessageSource; -import at.gv.egiz.eaaf.core.api.logging.IMessageSourceLocation; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations = { - "/spring/SpringTest-context_basic_test.xml", - "/spring/SpringTest-context_basic_mapConfig.xml", - }) -public class EidasProxyMessageSourceTest { - - @Autowired - private ResourceLoader loader; - @Autowired(required = false) - private List messageSources; - - @Test - public void checkMessageSources() { - Assert.assertNotNull("No messageSource", messageSources); - Assert.assertFalse("No message source", messageSources.isEmpty()); - - boolean found = false; - - for (final IMessageSourceLocation messageSource : messageSources) { - found = found ? found : messageSource instanceof EidasProxyMessageSource; - - Assert.assertNotNull("No sourcePath", messageSource.getMessageSourceLocation()); - for (final String el : messageSource.getMessageSourceLocation()) { - final Resource messages = loader.getResource(el + ".properties"); - Assert.assertTrue("Source not exist", messages.exists()); - - } - } - - Assert.assertTrue("Internal messagesource not found", found); - - } -} diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/MsProxyServiceSpringResourceProviderTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/MsProxyServiceSpringResourceProviderTest.java deleted file mode 100644 index 8c6da366..00000000 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/MsProxyServiceSpringResourceProviderTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package at.asitplus.eidas.specific.modules.auth.idaustria.test; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.BlockJUnit4ClassRunner; -import org.springframework.core.io.Resource; - -import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceSpringResourceProvider; -import at.gv.egiz.eaaf.core.test.TestConstants; - - - -@RunWith(BlockJUnit4ClassRunner.class) -public class MsProxyServiceSpringResourceProviderTest { - - @Test - public void testSpringConfig() { - final MsProxyServiceSpringResourceProvider test = - new MsProxyServiceSpringResourceProvider(); - for (final Resource el : test.getResourcesToLoad()) { - try { - IOUtils.toByteArray(el.getInputStream()); - - } catch (final IOException e) { - Assert.fail("Ressouce: " + el.getFilename() + " not found"); - } - - } - - Assert.assertNotNull("no Name", test.getName()); - Assert.assertNull("Find package definitions", test.getPackagesToScan()); - - } - - @Test - public void testSpILoaderConfig() { - final InputStream el = this.getClass().getResourceAsStream(TestConstants.TEST_SPI_LOADER_PATH); - try { - final String spiFile = IOUtils.toString(el, "UTF-8"); - - Assert.assertEquals("Wrong classpath in SPI file", - MsProxyServiceSpringResourceProvider.class.getName(), spiFile); - - - } catch (final IOException e) { - Assert.fail("Ressouce: " + TestConstants.TEST_SPI_LOADER_PATH + " not found"); - - } - } - -} diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java deleted file mode 100644 index 2b652f79..00000000 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java +++ /dev/null @@ -1,663 +0,0 @@ -package at.asitplus.eidas.specific.modules.auth.idaustria.test.protocol; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URLDecoder; -import java.text.MessageFormat; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; - -import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.StringUtils; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.opensaml.saml.saml2.core.NameIDType; -import org.opensaml.saml.saml2.core.StatusCode; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -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 com.google.common.collect.ImmutableSortedSet; - -import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration; -import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap; -import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants; -import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry; -import at.asitplus.eidas.specific.modules.core.eidas.test.dummy.DummySpecificCommunicationService; -import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; -import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException; -import at.asitplus.eidas.specific.modules.msproxyservice.protocol.EidasProxyServiceController; -import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest; -import at.gv.egiz.eaaf.core.api.data.EaafConstants; -import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes; -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 eu.eidas.auth.commons.EidasParameterKeys; -import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; -import eu.eidas.auth.commons.light.ILightResponse; -import eu.eidas.auth.commons.light.impl.LightRequest; -import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames; -import eu.eidas.specificcommunication.exception.SpecificCommunicationException; -import eu.eidas.specificcommunication.protocol.SpecificCommunicationService; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations = { - "/spring/SpringTest-context_basic_test.xml", - "/spring/SpringTest-context_basic_mapConfig.xml", - }) -@EnableWebMvc -public class EidasProxyServiceControllerTest { - - @Autowired private EidasProxyServiceController controller; - - @Autowired private DummySpecificCommunicationService proxyService; - @Autowired private DummyProtocolAuthService authService; - @Autowired private EidasAttributeRegistry attrRegistry; - @Autowired private ApplicationContext context; - - @Autowired MsConnectorDummyConfigMap config; - - private MockHttpServletRequest httpReq; - private MockHttpServletResponse httpResp; - - private SpecificCommunicationService springManagedSpecificConnectorCommunicationService; - - /** - * jUnit test set-up. - */ - @Before - public void setUp() throws EaafStorageException, URISyntaxException { - httpReq = new MockHttpServletRequest("POST", "http://localhost/ms_connector/eidas/light/idp/redirect"); - httpResp = new MockHttpServletResponse(); - RequestContextHolder.resetRequestAttributes(); - RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp)); - - proxyService.setiLightRequest(null); - proxyService.setError(null); - - config.putConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint", - "http://eidas.proxy/endpoint"); - - springManagedSpecificConnectorCommunicationService = - (SpecificCommunicationService) context.getBean( - SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE - .toString()); - - } - - @Test - public void generateErrorResponseWrongPendingReq() throws Throwable { - Assert.assertFalse("wrong statusCode", controller.generateErrorMessage( - new EaafException("1000"), - httpReq, httpResp, null)); - - } - - @Test - public void generateErrorResponse() throws Throwable { - ProxyServicePendingRequest pendingReq = new ProxyServicePendingRequest(); - pendingReq.initialize(httpReq, config); - - LightRequest.Builder eidasRequestBuilder = LightRequest.builder() - .id(UUID.randomUUID().toString()) - .issuer(RandomStringUtils.randomAlphabetic(10)) - .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) - .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .spType("public") - .requesterId(RandomStringUtils.randomAlphanumeric(10)) - .providerName(RandomStringUtils.randomAlphanumeric(10)); - pendingReq.setEidasRequest(eidasRequestBuilder.build()); - - - // execute test - Assert.assertTrue("wrong statusCode", controller.generateErrorMessage( - new EaafException("1000"), - httpReq, httpResp, - pendingReq)); - - // validate state - assertNotNull("not redirct Header", httpResp.getHeader("Location")); - assertTrue("wrong redirect URL", httpResp.getHeader("Location").startsWith("http://eidas.proxy/endpoint?token=")); - String token = httpResp.getHeader("Location").substring("http://eidas.proxy/endpoint?token=".length()); - - ILightResponse resp = springManagedSpecificConnectorCommunicationService.getAndRemoveResponse(URLDecoder.decode(token, "UTF-8"), - ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes())); - - assertNotNull("responseId", resp.getId()); - assertEquals("inResponseTo", pendingReq.getEidasRequest().getId(), resp.getInResponseToId()); - assertEquals("relayState", pendingReq.getEidasRequest().getRelayState(), resp.getRelayState()); - - assertNotNull("subjectNameId", resp.getSubject()); - assertEquals("subjectNameIdFormat", NameIDType.TRANSIENT, resp.getSubjectNameIdFormat()); - assertTrue("not attributes", resp.getAttributes().isEmpty()); - - assertEquals("StatusCode", StatusCode.RESPONDER, resp.getStatus().getStatusCode()); - //assertEquals("SubStatusCode", "", resp.getStatus().getSubStatusCode()); - //assertEquals("StatusMsg", "", resp.getStatus().getStatusMessage()); - - } - - @Test - public void missingEidasToken() { - EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, - () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); - Assert.assertEquals("wrong errorCode", "eidas.proxyservice.02", exception.getErrorId()); - - } - - @Test - public void wrongEidasTokenWithNullpointerException() { - //initialize state - httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); - - //validate state - EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, - () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); - Assert.assertEquals("wrong errorCode", "eidas.proxyservice.11", exception.getErrorId()); - - } - - @Test - public void wrongEidasTokenCacheCommunicationError() { - //initialize state - httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); - proxyService.setError(new SpecificCommunicationException(RandomStringUtils.randomAlphanumeric(10))); - - //validate state - EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, - () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); - Assert.assertEquals("wrong errorCode", "eidas.proxyservice.03", exception.getErrorId()); - Assert.assertTrue("Wrong exception", (exception.getCause() instanceof SpecificCommunicationException)); - - } - - @Test - public void missingServiceProviderCountry() { - //initialize state - httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); - LightRequest.Builder authnReqBuilder = LightRequest.builder() - .id(UUID.randomUUID().toString()) - .issuer(RandomStringUtils.randomAlphabetic(10)) - .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH); - - proxyService.setiLightRequest(authnReqBuilder.build()); - - //validate state - EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, - () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); - Assert.assertEquals("wrong errorCode", "eidas.proxyservice.07", exception.getErrorId()); - - } - - @Test - public void requestingLegalAndNaturalPerson() { - //initialize state - httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); - LightRequest.Builder authnReqBuilder = LightRequest.builder() - .id(UUID.randomUUID().toString()) - .issuer(RandomStringUtils.randomAlphabetic(10)) - .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) - .requestedAttributes(ImmutableAttributeMap.builder() - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) - .build()); - - proxyService.setiLightRequest(authnReqBuilder.build()); - - //validate state - EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, - () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); - Assert.assertEquals("wrong errorCode", "eidas.proxyservice.08", exception.getErrorId()); - - } - - @Test - public void requestLegalPersonButNoMandates() throws IOException, EaafException { - //initialize state - httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); - String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); - LightRequest.Builder authnReqBuilder = LightRequest.builder() - .id(UUID.randomUUID().toString()) - .issuer(RandomStringUtils.randomAlphabetic(10)) - .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) - .spCountryCode(spCountryCode) - .spType("public") - .requestedAttributes(ImmutableAttributeMap.builder() - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); - - proxyService.setiLightRequest(authnReqBuilder.build()); - - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "false"); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, - StringUtils.join(Arrays.asList( - RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); - - //validate state - EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, - () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); - Assert.assertEquals("wrong errorCode", "eidas.proxyservice.09", exception.getErrorId()); - - } - - @Test - public void validAuthnRequest() throws IOException, EaafException { - //initialize state - httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); - String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); - LightRequest.Builder authnReqBuilder = LightRequest.builder() - .id(UUID.randomUUID().toString()) - .issuer(RandomStringUtils.randomAlphabetic(10)) - .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) - .spCountryCode(spCountryCode) - .spType("public") - .requestedAttributes(ImmutableAttributeMap.builder() - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); - - proxyService.setiLightRequest(authnReqBuilder.build()); - - - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "false"); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, - StringUtils.join(Arrays.asList( - RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); - - - //execute - controller.receiveEidasAuthnRequest(httpReq, httpResp); - - //validate state - Assert.assertNotNull("pendingRequest", authService.getPendingReq()); - Assert.assertTrue("wrong pendingRequest", authService.getPendingReq() instanceof ProxyServicePendingRequest); - ProxyServicePendingRequest pendingReq = (ProxyServicePendingRequest) authService.getPendingReq(); - Assert.assertNotNull("missing uniqueSpId", pendingReq.getSpEntityId()); - Assert.assertNotNull("missing eidasReq", pendingReq.getEidasRequest()); - - Assert.assertFalse("isPassive", pendingReq.isPassiv()); - Assert.assertTrue("isPassive", pendingReq.forceAuth()); - Assert.assertFalse("isPassive", pendingReq.isAuthenticated()); - Assert.assertFalse("isPassive", pendingReq.isAbortedByUser()); - Assert.assertTrue("isPassive", pendingReq.isNeedAuthentication()); - - Assert.assertNotNull("missing spConfig", pendingReq.getServiceProviderConfiguration()); - ServiceProviderConfiguration spConfig = - pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class); - Assert.assertNotNull("uniqueId", spConfig.getUniqueIdentifier()); - Assert.assertEquals("uniqueId wrong pattern", - authnReqBuilder.build().getIssuer(), - spConfig.getUniqueIdentifier()); - Assert.assertEquals("friendlyName wrong pattern", - MessageFormat.format(MsProxyServiceConstants.TEMPLATE_SP_UNIQUE_ID, spCountryCode, "public"), - spConfig.getFriendlyName()); - - Assert.assertEquals("uniqueId not match to pendingReq", - pendingReq.getSpEntityId(), spConfig.getUniqueIdentifier()); - Assert.assertNotNull("bpkTarget", spConfig.getAreaSpecificTargetIdentifier()); - Assert.assertEquals("wrong bPK Target", - EaafConstants.URN_PREFIX_EIDAS + "AT+" + spCountryCode, - spConfig.getAreaSpecificTargetIdentifier()); - - assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); - assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); - assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode()); - - } - - @Test - public void validAuthnRequestWithMandatesDefaultProfilesNat() throws IOException, EaafException { - //initialize state - httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); - String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); - LightRequest.Builder authnReqBuilder = LightRequest.builder() - .id(UUID.randomUUID().toString()) - .issuer(RandomStringUtils.randomAlphabetic(10)) - .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) - .spCountryCode(spCountryCode) - .spType("public") - .requestedAttributes(ImmutableAttributeMap.builder() - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); - - - proxyService.setiLightRequest(authnReqBuilder.build()); - - List mandateProfilesNat = - Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); - List mandateProfilesJur = - Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, - StringUtils.join(mandateProfilesNat, ",")); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, - StringUtils.join(mandateProfilesJur, ",")); - - //execute - controller.receiveEidasAuthnRequest(httpReq, httpResp); - - //validate state - ServiceProviderConfiguration spConfig = - authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); - assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); - assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); - assertEquals("mandateprofile size", mandateProfilesNat.size(), spConfig.getMandateProfiles().size()); - spConfig.getMandateProfiles().stream() - .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfilesNat.contains(el))); - assertEquals("MandateMode", SpMandateModes.NATURAL, spConfig.getMandateMode()); - - } - - @Test - public void validAuthnRequestWithMandatesDefaultProfilesJur() throws IOException, EaafException { - //initialize state - httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); - String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); - LightRequest.Builder authnReqBuilder = LightRequest.builder() - .id(UUID.randomUUID().toString()) - .issuer(RandomStringUtils.randomAlphabetic(10)) - .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) - .spCountryCode(spCountryCode) - .spType("public") - .requestedAttributes(ImmutableAttributeMap.builder() - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); - - - proxyService.setiLightRequest(authnReqBuilder.build()); - - List mandateProfilesNat = - Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); - List mandateProfilesJur = - Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, - StringUtils.join(mandateProfilesNat, ",")); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, - StringUtils.join(mandateProfilesJur, ",")); - - //execute - controller.receiveEidasAuthnRequest(httpReq, httpResp); - - //validate state - ServiceProviderConfiguration spConfig = - authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); - assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); - assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); - assertEquals("mandateprofile size", mandateProfilesJur.size(), spConfig.getMandateProfiles().size()); - spConfig.getMandateProfiles().stream() - .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfilesJur.contains(el))); - assertEquals("MandateMode", SpMandateModes.LEGAL_FORCE, spConfig.getMandateMode()); - - } - - @Test - public void validAuthnRequestWithMandatesDefaultNoJurProfiles() throws IOException, EaafException { - //initialize state - httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); - String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); - LightRequest.Builder authnReqBuilder = LightRequest.builder() - .id(UUID.randomUUID().toString()) - .issuer(RandomStringUtils.randomAlphabetic(10)) - .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) - .spCountryCode(spCountryCode) - .spType("public") - .requestedAttributes(ImmutableAttributeMap.builder() - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); - - - proxyService.setiLightRequest(authnReqBuilder.build()); - - List mandateProfilesNat = - Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, - StringUtils.join(mandateProfilesNat, ",")); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, ""); - - //validate state - EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, - () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); - Assert.assertEquals("wrong errorCode", "eidas.proxyservice.10", exception.getErrorId()); - - } - - @Test - public void validAuthnRequestWithMandatesDefaultNoNatProfiles() throws IOException, EaafException { - //initialize state - httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); - String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); - LightRequest.Builder authnReqBuilder = LightRequest.builder() - .id(UUID.randomUUID().toString()) - .issuer(RandomStringUtils.randomAlphabetic(10)) - .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) - .spCountryCode(spCountryCode) - .spType("public") - .requestedAttributes(ImmutableAttributeMap.builder() - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); - - - proxyService.setiLightRequest(authnReqBuilder.build()); - - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, ""); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, ""); - - //execute - controller.receiveEidasAuthnRequest(httpReq, httpResp); - - //validate state - ServiceProviderConfiguration spConfig = - authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); - assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); - assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); - assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode()); - - } - - @Test - public void validAuthnRequestIssueSpecificNoMandates() throws IOException, EaafException { - //initialize state - httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); - - String issuer = RandomStringUtils.randomAlphabetic(10); - LightRequest.Builder authnReqBuilder = LightRequest.builder() - .id(UUID.randomUUID().toString()) - .issuer(issuer) - .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) - .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .spType("public") - .requestedAttributes(ImmutableAttributeMap.builder() - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); - - proxyService.setiLightRequest(authnReqBuilder.build()); - - - // set default mandate configuration - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, - StringUtils.join(Arrays.asList( - RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, - StringUtils.join(Arrays.asList( - RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); - - // set specific mandate configuration - String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); - addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer); - addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode); - addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "false"); - - List mandateProfiles = - Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); - addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL, - StringUtils.join(mandateProfiles, ",")); - addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL, - StringUtils.join(Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); - - //execute - controller.receiveEidasAuthnRequest(httpReq, httpResp); - - //validate state - ServiceProviderConfiguration spConfig = - authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); - assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); - assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); - assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode()); - - } - - @Test - public void validAuthnRequestIssueSpecificMandatesNat() throws IOException, EaafException { - //initialize state - httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); - - String issuer = "https://apps.egiz.gv.at/EidasNode//ConnectorMetadata"; - LightRequest.Builder authnReqBuilder = LightRequest.builder() - .id(UUID.randomUUID().toString()) - .issuer(issuer) - .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) - .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .spType("public") - .requestedAttributes(ImmutableAttributeMap.builder() - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); - - proxyService.setiLightRequest(authnReqBuilder.build()); - - - // set default mandate configuration - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "false"); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, - StringUtils.join(Arrays.asList( - RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, - StringUtils.join(Arrays.asList( - RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); - - // set specific mandate configuration - String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); - addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer); - addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode); - addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "true"); - - List mandateProfiles = - Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); - addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL, - StringUtils.join(mandateProfiles, ",")); - addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL, - StringUtils.join(Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); - - //execute - controller.receiveEidasAuthnRequest(httpReq, httpResp); - - //validate state - ServiceProviderConfiguration spConfig = - authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); - assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); - assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); - assertEquals("mandateprofile size", mandateProfiles.size(), spConfig.getMandateProfiles().size()); - spConfig.getMandateProfiles().stream() - .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfiles.contains(el))); - assertEquals("MandateMode", SpMandateModes.NATURAL, spConfig.getMandateMode()); - - } - - @Test - public void validAuthnRequestIssueSpecificMandatesJur() throws IOException, EaafException { - //initialize state - httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); - - String issuer = RandomStringUtils.randomAlphabetic(10); - LightRequest.Builder authnReqBuilder = LightRequest.builder() - .id(UUID.randomUUID().toString()) - .issuer(issuer) - .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) - .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .spType("public") - .requestedAttributes(ImmutableAttributeMap.builder() - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); - - proxyService.setiLightRequest(authnReqBuilder.build()); - - - // set default mandate configuration - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, - StringUtils.join(Arrays.asList( - RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, - StringUtils.join(Arrays.asList( - RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); - - // set specific mandate configuration - String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); - addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer); - addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode); - addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "true"); - - List mandateProfiles = - Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); - addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL, - StringUtils.join(mandateProfiles, ",")); - addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL, - StringUtils.join(Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); - - //execute - controller.receiveEidasAuthnRequest(httpReq, httpResp); - - //validate state - ServiceProviderConfiguration spConfig = - authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); - assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); - assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); - assertEquals("mandateprofile size", mandateProfiles.size(), spConfig.getMandateProfiles().size()); - spConfig.getMandateProfiles().stream() - .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfiles.contains(el))); - assertEquals("MandateMode", SpMandateModes.LEGAL_FORCE, spConfig.getMandateMode()); - - } - - private void addConnectorConfig(int i, String key, String value) { - config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_PREFIX + String.valueOf(i) + "." + key, - value); - - } - -} - - diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java deleted file mode 100644 index 97b5bc03..00000000 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java +++ /dev/null @@ -1,635 +0,0 @@ -package at.asitplus.eidas.specific.modules.auth.idaustria.test.protocol; - -import static at.asitplus.eidas.specific.core.MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; - -import java.net.URISyntaxException; -import java.net.URLDecoder; -import java.time.Instant; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import org.apache.commons.lang3.RandomStringUtils; -import org.joda.time.DateTime; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.opensaml.saml.saml2.core.NameIDType; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -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 com.google.common.collect.ImmutableSortedSet; - -import at.asitplus.eidas.specific.core.MsEidasNodeConstants; -import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap; -import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummySpConfiguration; -import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants; -import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry; -import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServiceAuthenticationAction; -import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest; -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.data.PvpAttributeDefinitions; -import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions.EidIdentityStatusLevelValues; -import at.gv.egiz.eaaf.core.api.idp.IAuthData; -import at.gv.egiz.eaaf.core.api.idp.IEidAuthData; -import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; -import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface; -import at.gv.egiz.eaaf.core.exceptions.EaafException; -import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl; -import eu.eidas.auth.commons.attribute.AttributeDefinition; -import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; -import eu.eidas.auth.commons.light.ILightResponse; -import eu.eidas.auth.commons.light.impl.LightRequest; -import eu.eidas.auth.commons.light.impl.LightRequest.Builder; -import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames; -import eu.eidas.specificcommunication.exception.SpecificCommunicationException; -import eu.eidas.specificcommunication.protocol.SpecificCommunicationService; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations = { - "/spring/SpringTest-context_basic_test.xml", - "/spring/SpringTest-context_basic_mapConfig.xml", - }) -public class ProxyServiceAuthenticationActionTest { - - @Autowired private MsConnectorDummyConfigMap basicConfig; - @Autowired private ProxyServiceAuthenticationAction action; - @Autowired private ApplicationContext context; - @Autowired EidasAttributeRegistry attrRegistry; - - private MockHttpServletRequest httpReq; - private MockHttpServletResponse httpResp; - private ProxyServicePendingRequest pendingReq; - private MsConnectorDummySpConfiguration oaParam; - private SpecificCommunicationService springManagedSpecificConnectorCommunicationService; - - - /** - * jUnit test set-up. - * @throws EaafException In case of an error - */ - @Before - public void setUp() throws URISyntaxException, EaafException { - httpReq = new MockHttpServletRequest("POST", "https://localhost/authhandler"); - httpResp = new MockHttpServletResponse(); - RequestContextHolder.resetRequestAttributes(); - RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp)); - - basicConfig.putConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint", - "http://eidas.proxy/endpoint"); - basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson", - "false"); - - 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 ProxyServicePendingRequest(); - pendingReq.initialize(httpReq, basicConfig); - pendingReq.setOnlineApplicationConfiguration(oaParam); - - LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); - pendingReq.setEidasRequest(eidasRequestBuilder.build()); - - - springManagedSpecificConnectorCommunicationService = - (SpecificCommunicationService) context.getBean( - SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE - .toString()); - - } - - @Test - public void wrongPendingRequestType() { - IAuthData authData = generateDummyAuthData(); - TestRequestImpl internalPendingReq = new TestRequestImpl(); - - EaafException exception = assertThrows(EaafException.class, - () -> action.processRequest(internalPendingReq, httpReq, httpResp, authData)); - Assert.assertEquals("wrong errorCode", "eidas.proxyservice.99", exception.getErrorId()); - - } - - @Test - public void missingForwardUrl() { - Map attr = new HashMap<>(); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, - "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); - IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, - RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false); - basicConfig.removeConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint"); - - EaafException exception = assertThrows(EaafException.class, - () -> action.processRequest(pendingReq, httpReq, httpResp, authData)); - Assert.assertEquals("wrong errorCode", "config.08", exception.getErrorId()); - - } - - @Test - public void responseWithoutMandate() throws EaafException, SpecificCommunicationException { - Map attr = new HashMap<>(); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, - "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); - IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, - RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false); - - //perform test - SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); - - //validate state - Assert.assertNotNull("Result should be not null", result); - - ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); - assertEquals("wrong attr. size", 4, respAttr.size()); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, - (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName()); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName()); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, - authData.getDateOfBirth()); - - } - - @Test - public void responseWithNatMandate() throws EaafException, SpecificCommunicationException { - Map attr = new HashMap<>(); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, - "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); - - attr.put(MsEidasNodeConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER, - RandomStringUtils.randomAlphabetic(10)); - attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, - RandomStringUtils.randomAlphabetic(10)); - attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, - RandomStringUtils.randomAlphabetic(10)); - attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, - "1985-11-15"); - - - IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, - RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); - - //perform test - SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); - - //validate state - Assert.assertNotNull("Result should be not null", result); - - ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); - assertEquals("wrong attr. size", 8, respAttr.size()); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, - (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName()); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName()); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); - - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, - (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER)); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, - (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME)); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, - (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME)); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, - (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME)); - - } - - @Test - public void responseWithJurMandate() throws EaafException, SpecificCommunicationException { - Map attr = new HashMap<>(); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, - "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); - IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, - RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); - - attr.put(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, - RandomStringUtils.randomAlphabetic(10)); - attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, - RandomStringUtils.randomAlphabetic(10)); - - //perform test - SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); - - //validate state - Assert.assertNotNull("Result should be not null", result); - - ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); - assertEquals("wrong attr. size", 6, respAttr.size()); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, - (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName()); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName()); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); - - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER, - (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER)); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALNAME, - (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME)); - - assertNull("find nat. person subject: personalId", - getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER)); - assertNull("find nat. person subject: familyName", - getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME)); - assertNull("find nat. person subject: givenName", - getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME)); - assertNull("find nat. person subject: dateOfBirth", - getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH)); - - } - - @Test - public void responseWithNatMandateWithWorkAround() throws EaafException, SpecificCommunicationException { - basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson", - "true"); - - //request natural person subject only - LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); - eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder().put( - attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); - pendingReq.setEidasRequest(eidasRequestBuilder.build()); - - - Map attr = new HashMap<>(); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, - "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); - - attr.put(MsEidasNodeConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER, - RandomStringUtils.randomAlphabetic(10)); - attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, - RandomStringUtils.randomAlphabetic(10)); - attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, - RandomStringUtils.randomAlphabetic(10)); - attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, - "1985-11-15"); - - - IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, - RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); - - //perform test - SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); - - //validate state - Assert.assertNotNull("Result should be not null", result); - - ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); - assertEquals("wrong attr. size", 8, respAttr.size()); - - } - - @Test - public void responseWithJurMandateWithWorkAround() throws EaafException, SpecificCommunicationException { - basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson", - "true"); - - //request natural person subject only - LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); - eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) - .build()); - pendingReq.setEidasRequest(eidasRequestBuilder.build()); - - Map attr = new HashMap<>(); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, - "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); - IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, - RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); - - attr.put(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, - RandomStringUtils.randomAlphabetic(10)); - attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, - RandomStringUtils.randomAlphabetic(10)); - - //perform test - SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); - - //validate state - Assert.assertNotNull("Result should be not null", result); - - ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); - assertEquals("wrong attr. size", 10, respAttr.size()); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, - (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName()); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName()); - checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, authData.getDateOfBirth()); - - } - - @Test - public void responseWithJurMandateWithWorkAroundNoNatSubject() throws EaafException, SpecificCommunicationException { - basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson", - "true"); - - //request natural person subject only - LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); - eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) - .build()); - pendingReq.setEidasRequest(eidasRequestBuilder.build()); - - Map attr = new HashMap<>(); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, - "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); - IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, - RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); - - attr.put(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, - RandomStringUtils.randomAlphabetic(10)); - attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, - RandomStringUtils.randomAlphabetic(10)); - - //perform test - SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); - - //validate state - Assert.assertNotNull("Result should be not null", result); - - ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); - assertEquals("wrong attr. size", 6, respAttr.size()); - assertNull("find nat. person subject: personalId", - getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER)); - assertNull("find nat. person subject: familyName", - getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME)); - assertNull("find nat. person subject: givenName", - getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME)); - assertNull("find nat. person subject: dateOfBirth", - getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH)); - - } - - @Test - public void checkBasicConstrainsInAction() { - - Assert.assertTrue("Wrong NeedAuthentication", action.needAuthentication(pendingReq, httpReq, httpResp)); - Assert.assertNotNull("Missing ActionName", action.getDefaultActionName()); - - Assert.assertNotNull("missing ActionBean", context.getBean(ProxyServiceAuthenticationAction.class)); - - } - - private IAuthData generateDummyAuthData() { - return generateDummyAuthData(Collections.emptyMap(), EaafConstants.EIDAS_LOA_LOW, - RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1940-01-01", false); - - } - - private Object getAttrValue(ImmutableAttributeMap respAttr, String attrName) { - final AttributeDefinition attrDef = - attrRegistry.getCoreAttributeRegistry().getByFriendlyName(attrName).first(); - return respAttr.getFirstValue(attrDef); - - } - - private void checkAttrValue(ImmutableAttributeMap respAttr, String attrName, String expected) { - Object value = getAttrValue(respAttr, attrName); - assertNotNull("not attr value: " + attrName, value); - - if (value instanceof String) { - assertEquals("wrong attr. value: " + attrName, expected, value); - - } else if ( value instanceof DateTime) { - assertEquals("wrong attr. value: " + attrName, expected, ((DateTime)value).toString("yyyy-MM-dd")); - - } - } - - private ImmutableAttributeMap validateBasicEidasResponse(IAuthData authData) throws SpecificCommunicationException { - assertNotNull("not redirct Header", httpResp.getHeader("Location")); - assertTrue("wrong redirect URL", httpResp.getHeader("Location").startsWith("http://eidas.proxy/endpoint?token=")); - String token = httpResp.getHeader("Location").substring("http://eidas.proxy/endpoint?token=".length()); - - ILightResponse resp = springManagedSpecificConnectorCommunicationService.getAndRemoveResponse(URLDecoder.decode(token), - ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes())); - - assertNotNull("responseId", resp.getId()); - assertEquals("inResponseTo", pendingReq.getEidasRequest().getId(), resp.getInResponseToId()); - assertEquals("relayState", pendingReq.getEidasRequest().getRelayState(), resp.getRelayState()); - assertEquals("LoA", authData.getEidasQaaLevel(), resp.getLevelOfAssurance()); - - assertNotNull("subjectNameId", resp.getSubject()); - assertEquals("subjectNameIdFormat", NameIDType.TRANSIENT, resp.getSubjectNameIdFormat()); - - assertFalse("not attributes", resp.getAttributes().isEmpty()); - return resp.getAttributes(); - - } - - private Builder generateBasicLightRequest() { - return LightRequest.builder() - .id(UUID.randomUUID().toString()) - .issuer(RandomStringUtils.randomAlphabetic(10)) - .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) - .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .spType("public") - .requesterId(RandomStringUtils.randomAlphanumeric(10)) - .providerName(RandomStringUtils.randomAlphanumeric(10)); - - } - - private IAuthData generateDummyAuthData(Map attrs, String loa, String familyName, String givenName, String dateOfBirth, - boolean useMandates) { - return new IEidAuthData() { - - @Override - public boolean isSsoSession() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isForeigner() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isBaseIdTransferRestrication() { - // TODO Auto-generated method stub - return false; - } - - @Override - public Instant getSsoSessionValidTo() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getSessionIndex() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getNameIdFormat() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getNameID() { - // TODO Auto-generated method stub - return null; - } - - @Override - public IIdentityLink getIdentityLink() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getIdentificationValue() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getIdentificationType() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getGivenName() { - return givenName; - } - - @Override - public T getGenericData(String key, Class clazz) { - if (attrs.containsKey(key)) { - return (T) attrs.get(key); - - } else { - return null; - } - - } - - @Override - public String getDateOfBirth() { - return dateOfBirth; - } - - @Override - public String getFamilyName() { - return familyName; - } - - @Override - public String getEncryptedSourceIdType() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getEncryptedSourceId() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getEidasQaaLevel() { - return loa; - - } - - - @Override - public String getCiticenCountryCode() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getBpkType() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getBpk() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getAuthenticationIssuer() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getAuthenticationIssueInstantString() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Instant getAuthenticationIssueInstant() { - // TODO Auto-generated method stub - return null; - } - - @Override - public byte[] getSignerCertificate() { - // TODO Auto-generated method stub - return null; - } - - @Override - public byte[] getEidToken() { - // TODO Auto-generated method stub - return null; - } - - @Override - public EidIdentityStatusLevelValues getEidStatus() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getVdaEndPointUrl() { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean isUseMandate() { - return useMandates; - - } - - @Override - public String getDateOfBirthFormated(String pattern) { - // TODO Auto-generated method stub - return null; - } - }; - - } -} diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/EidasProxyMessageSourceTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/EidasProxyMessageSourceTest.java new file mode 100644 index 00000000..efe572b5 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/EidasProxyMessageSourceTest.java @@ -0,0 +1,50 @@ +package at.asitplus.eidas.specific.modules.auth.idaustria.test; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import at.asitplus.eidas.specific.modules.msproxyservice.EidasProxyMessageSource; +import at.gv.egiz.eaaf.core.api.logging.IMessageSourceLocation; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { + "/spring/SpringTest-context_basic_test.xml", + "/spring/SpringTest-context_basic_mapConfig.xml", + }) +public class EidasProxyMessageSourceTest { + + @Autowired + private ResourceLoader loader; + @Autowired(required = false) + private List messageSources; + + @Test + public void checkMessageSources() { + Assert.assertNotNull("No messageSource", messageSources); + Assert.assertFalse("No message source", messageSources.isEmpty()); + + boolean found = false; + + for (final IMessageSourceLocation messageSource : messageSources) { + found = found ? found : messageSource instanceof EidasProxyMessageSource; + + Assert.assertNotNull("No sourcePath", messageSource.getMessageSourceLocation()); + for (final String el : messageSource.getMessageSourceLocation()) { + final Resource messages = loader.getResource(el + ".properties"); + Assert.assertTrue("Source not exist", messages.exists()); + + } + } + + Assert.assertTrue("Internal messagesource not found", found); + + } +} diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/MsProxyServiceSpringResourceProviderTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/MsProxyServiceSpringResourceProviderTest.java new file mode 100644 index 00000000..8c6da366 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/MsProxyServiceSpringResourceProviderTest.java @@ -0,0 +1,56 @@ +package at.asitplus.eidas.specific.modules.auth.idaustria.test; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.io.IOUtils; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.springframework.core.io.Resource; + +import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceSpringResourceProvider; +import at.gv.egiz.eaaf.core.test.TestConstants; + + + +@RunWith(BlockJUnit4ClassRunner.class) +public class MsProxyServiceSpringResourceProviderTest { + + @Test + public void testSpringConfig() { + final MsProxyServiceSpringResourceProvider test = + new MsProxyServiceSpringResourceProvider(); + for (final Resource el : test.getResourcesToLoad()) { + try { + IOUtils.toByteArray(el.getInputStream()); + + } catch (final IOException e) { + Assert.fail("Ressouce: " + el.getFilename() + " not found"); + } + + } + + Assert.assertNotNull("no Name", test.getName()); + Assert.assertNull("Find package definitions", test.getPackagesToScan()); + + } + + @Test + public void testSpILoaderConfig() { + final InputStream el = this.getClass().getResourceAsStream(TestConstants.TEST_SPI_LOADER_PATH); + try { + final String spiFile = IOUtils.toString(el, "UTF-8"); + + Assert.assertEquals("Wrong classpath in SPI file", + MsProxyServiceSpringResourceProvider.class.getName(), spiFile); + + + } catch (final IOException e) { + Assert.fail("Ressouce: " + TestConstants.TEST_SPI_LOADER_PATH + " not found"); + + } + } + +} diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java new file mode 100644 index 00000000..2b652f79 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java @@ -0,0 +1,663 @@ +package at.asitplus.eidas.specific.modules.auth.idaustria.test.protocol; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URLDecoder; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opensaml.saml.saml2.core.NameIDType; +import org.opensaml.saml.saml2.core.StatusCode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +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 com.google.common.collect.ImmutableSortedSet; + +import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration; +import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap; +import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants; +import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry; +import at.asitplus.eidas.specific.modules.core.eidas.test.dummy.DummySpecificCommunicationService; +import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; +import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException; +import at.asitplus.eidas.specific.modules.msproxyservice.protocol.EidasProxyServiceController; +import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest; +import at.gv.egiz.eaaf.core.api.data.EaafConstants; +import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes; +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 eu.eidas.auth.commons.EidasParameterKeys; +import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; +import eu.eidas.auth.commons.light.ILightResponse; +import eu.eidas.auth.commons.light.impl.LightRequest; +import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames; +import eu.eidas.specificcommunication.exception.SpecificCommunicationException; +import eu.eidas.specificcommunication.protocol.SpecificCommunicationService; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { + "/spring/SpringTest-context_basic_test.xml", + "/spring/SpringTest-context_basic_mapConfig.xml", + }) +@EnableWebMvc +public class EidasProxyServiceControllerTest { + + @Autowired private EidasProxyServiceController controller; + + @Autowired private DummySpecificCommunicationService proxyService; + @Autowired private DummyProtocolAuthService authService; + @Autowired private EidasAttributeRegistry attrRegistry; + @Autowired private ApplicationContext context; + + @Autowired MsConnectorDummyConfigMap config; + + private MockHttpServletRequest httpReq; + private MockHttpServletResponse httpResp; + + private SpecificCommunicationService springManagedSpecificConnectorCommunicationService; + + /** + * jUnit test set-up. + */ + @Before + public void setUp() throws EaafStorageException, URISyntaxException { + httpReq = new MockHttpServletRequest("POST", "http://localhost/ms_connector/eidas/light/idp/redirect"); + httpResp = new MockHttpServletResponse(); + RequestContextHolder.resetRequestAttributes(); + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp)); + + proxyService.setiLightRequest(null); + proxyService.setError(null); + + config.putConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint", + "http://eidas.proxy/endpoint"); + + springManagedSpecificConnectorCommunicationService = + (SpecificCommunicationService) context.getBean( + SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE + .toString()); + + } + + @Test + public void generateErrorResponseWrongPendingReq() throws Throwable { + Assert.assertFalse("wrong statusCode", controller.generateErrorMessage( + new EaafException("1000"), + httpReq, httpResp, null)); + + } + + @Test + public void generateErrorResponse() throws Throwable { + ProxyServicePendingRequest pendingReq = new ProxyServicePendingRequest(); + pendingReq.initialize(httpReq, config); + + LightRequest.Builder eidasRequestBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .spType("public") + .requesterId(RandomStringUtils.randomAlphanumeric(10)) + .providerName(RandomStringUtils.randomAlphanumeric(10)); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + + // execute test + Assert.assertTrue("wrong statusCode", controller.generateErrorMessage( + new EaafException("1000"), + httpReq, httpResp, + pendingReq)); + + // validate state + assertNotNull("not redirct Header", httpResp.getHeader("Location")); + assertTrue("wrong redirect URL", httpResp.getHeader("Location").startsWith("http://eidas.proxy/endpoint?token=")); + String token = httpResp.getHeader("Location").substring("http://eidas.proxy/endpoint?token=".length()); + + ILightResponse resp = springManagedSpecificConnectorCommunicationService.getAndRemoveResponse(URLDecoder.decode(token, "UTF-8"), + ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes())); + + assertNotNull("responseId", resp.getId()); + assertEquals("inResponseTo", pendingReq.getEidasRequest().getId(), resp.getInResponseToId()); + assertEquals("relayState", pendingReq.getEidasRequest().getRelayState(), resp.getRelayState()); + + assertNotNull("subjectNameId", resp.getSubject()); + assertEquals("subjectNameIdFormat", NameIDType.TRANSIENT, resp.getSubjectNameIdFormat()); + assertTrue("not attributes", resp.getAttributes().isEmpty()); + + assertEquals("StatusCode", StatusCode.RESPONDER, resp.getStatus().getStatusCode()); + //assertEquals("SubStatusCode", "", resp.getStatus().getSubStatusCode()); + //assertEquals("StatusMsg", "", resp.getStatus().getStatusMessage()); + + } + + @Test + public void missingEidasToken() { + EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, + () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.02", exception.getErrorId()); + + } + + @Test + public void wrongEidasTokenWithNullpointerException() { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + + //validate state + EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, + () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.11", exception.getErrorId()); + + } + + @Test + public void wrongEidasTokenCacheCommunicationError() { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + proxyService.setError(new SpecificCommunicationException(RandomStringUtils.randomAlphanumeric(10))); + + //validate state + EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, + () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.03", exception.getErrorId()); + Assert.assertTrue("Wrong exception", (exception.getCause() instanceof SpecificCommunicationException)); + + } + + @Test + public void missingServiceProviderCountry() { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + //validate state + EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, + () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.07", exception.getErrorId()); + + } + + @Test + public void requestingLegalAndNaturalPerson() { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + //validate state + EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, + () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.08", exception.getErrorId()); + + } + + @Test + public void requestLegalPersonButNoMandates() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "false"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + //validate state + EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, + () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.09", exception.getErrorId()); + + } + + @Test + public void validAuthnRequest() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "false"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + Assert.assertNotNull("pendingRequest", authService.getPendingReq()); + Assert.assertTrue("wrong pendingRequest", authService.getPendingReq() instanceof ProxyServicePendingRequest); + ProxyServicePendingRequest pendingReq = (ProxyServicePendingRequest) authService.getPendingReq(); + Assert.assertNotNull("missing uniqueSpId", pendingReq.getSpEntityId()); + Assert.assertNotNull("missing eidasReq", pendingReq.getEidasRequest()); + + Assert.assertFalse("isPassive", pendingReq.isPassiv()); + Assert.assertTrue("isPassive", pendingReq.forceAuth()); + Assert.assertFalse("isPassive", pendingReq.isAuthenticated()); + Assert.assertFalse("isPassive", pendingReq.isAbortedByUser()); + Assert.assertTrue("isPassive", pendingReq.isNeedAuthentication()); + + Assert.assertNotNull("missing spConfig", pendingReq.getServiceProviderConfiguration()); + ServiceProviderConfiguration spConfig = + pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class); + Assert.assertNotNull("uniqueId", spConfig.getUniqueIdentifier()); + Assert.assertEquals("uniqueId wrong pattern", + authnReqBuilder.build().getIssuer(), + spConfig.getUniqueIdentifier()); + Assert.assertEquals("friendlyName wrong pattern", + MessageFormat.format(MsProxyServiceConstants.TEMPLATE_SP_UNIQUE_ID, spCountryCode, "public"), + spConfig.getFriendlyName()); + + Assert.assertEquals("uniqueId not match to pendingReq", + pendingReq.getSpEntityId(), spConfig.getUniqueIdentifier()); + Assert.assertNotNull("bpkTarget", spConfig.getAreaSpecificTargetIdentifier()); + Assert.assertEquals("wrong bPK Target", + EaafConstants.URN_PREFIX_EIDAS + "AT+" + spCountryCode, + spConfig.getAreaSpecificTargetIdentifier()); + + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode()); + + } + + @Test + public void validAuthnRequestWithMandatesDefaultProfilesNat() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + + + proxyService.setiLightRequest(authnReqBuilder.build()); + + List mandateProfilesNat = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + List mandateProfilesJur = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(mandateProfilesNat, ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, + StringUtils.join(mandateProfilesJur, ",")); + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("mandateprofile size", mandateProfilesNat.size(), spConfig.getMandateProfiles().size()); + spConfig.getMandateProfiles().stream() + .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfilesNat.contains(el))); + assertEquals("MandateMode", SpMandateModes.NATURAL, spConfig.getMandateMode()); + + } + + @Test + public void validAuthnRequestWithMandatesDefaultProfilesJur() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); + + + proxyService.setiLightRequest(authnReqBuilder.build()); + + List mandateProfilesNat = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + List mandateProfilesJur = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(mandateProfilesNat, ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, + StringUtils.join(mandateProfilesJur, ",")); + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("mandateprofile size", mandateProfilesJur.size(), spConfig.getMandateProfiles().size()); + spConfig.getMandateProfiles().stream() + .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfilesJur.contains(el))); + assertEquals("MandateMode", SpMandateModes.LEGAL_FORCE, spConfig.getMandateMode()); + + } + + @Test + public void validAuthnRequestWithMandatesDefaultNoJurProfiles() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); + + + proxyService.setiLightRequest(authnReqBuilder.build()); + + List mandateProfilesNat = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(mandateProfilesNat, ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, ""); + + //validate state + EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class, + () -> controller.receiveEidasAuthnRequest(httpReq, httpResp)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.10", exception.getErrorId()); + + } + + @Test + public void validAuthnRequestWithMandatesDefaultNoNatProfiles() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + + + proxyService.setiLightRequest(authnReqBuilder.build()); + + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, ""); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, ""); + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode()); + + } + + @Test + public void validAuthnRequestIssueSpecificNoMandates() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + + String issuer = RandomStringUtils.randomAlphabetic(10); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(issuer) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + + // set default mandate configuration + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + // set specific mandate configuration + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "false"); + + List mandateProfiles = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL, + StringUtils.join(mandateProfiles, ",")); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL, + StringUtils.join(Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode()); + + } + + @Test + public void validAuthnRequestIssueSpecificMandatesNat() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + + String issuer = "https://apps.egiz.gv.at/EidasNode//ConnectorMetadata"; + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(issuer) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + + // set default mandate configuration + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "false"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + // set specific mandate configuration + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "true"); + + List mandateProfiles = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL, + StringUtils.join(mandateProfiles, ",")); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL, + StringUtils.join(Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("mandateprofile size", mandateProfiles.size(), spConfig.getMandateProfiles().size()); + spConfig.getMandateProfiles().stream() + .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfiles.contains(el))); + assertEquals("MandateMode", SpMandateModes.NATURAL, spConfig.getMandateMode()); + + } + + @Test + public void validAuthnRequestIssueSpecificMandatesJur() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + + String issuer = RandomStringUtils.randomAlphabetic(10); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(issuer) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + + // set default mandate configuration + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + // set specific mandate configuration + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "true"); + + List mandateProfiles = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL, + StringUtils.join(mandateProfiles, ",")); + addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL, + StringUtils.join(Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("mandateprofile size", mandateProfiles.size(), spConfig.getMandateProfiles().size()); + spConfig.getMandateProfiles().stream() + .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfiles.contains(el))); + assertEquals("MandateMode", SpMandateModes.LEGAL_FORCE, spConfig.getMandateMode()); + + } + + private void addConnectorConfig(int i, String key, String value) { + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_PREFIX + String.valueOf(i) + "." + key, + value); + + } + +} + + diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java new file mode 100644 index 00000000..97b5bc03 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java @@ -0,0 +1,635 @@ +package at.asitplus.eidas.specific.modules.auth.idaustria.test.protocol; + +import static at.asitplus.eidas.specific.core.MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import java.net.URISyntaxException; +import java.net.URLDecoder; +import java.time.Instant; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.commons.lang3.RandomStringUtils; +import org.joda.time.DateTime; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opensaml.saml.saml2.core.NameIDType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +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 com.google.common.collect.ImmutableSortedSet; + +import at.asitplus.eidas.specific.core.MsEidasNodeConstants; +import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap; +import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummySpConfiguration; +import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants; +import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry; +import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServiceAuthenticationAction; +import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest; +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.data.PvpAttributeDefinitions; +import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions.EidIdentityStatusLevelValues; +import at.gv.egiz.eaaf.core.api.idp.IAuthData; +import at.gv.egiz.eaaf.core.api.idp.IEidAuthData; +import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; +import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl; +import eu.eidas.auth.commons.attribute.AttributeDefinition; +import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; +import eu.eidas.auth.commons.light.ILightResponse; +import eu.eidas.auth.commons.light.impl.LightRequest; +import eu.eidas.auth.commons.light.impl.LightRequest.Builder; +import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames; +import eu.eidas.specificcommunication.exception.SpecificCommunicationException; +import eu.eidas.specificcommunication.protocol.SpecificCommunicationService; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { + "/spring/SpringTest-context_basic_test.xml", + "/spring/SpringTest-context_basic_mapConfig.xml", + }) +public class ProxyServiceAuthenticationActionTest { + + @Autowired private MsConnectorDummyConfigMap basicConfig; + @Autowired private ProxyServiceAuthenticationAction action; + @Autowired private ApplicationContext context; + @Autowired EidasAttributeRegistry attrRegistry; + + private MockHttpServletRequest httpReq; + private MockHttpServletResponse httpResp; + private ProxyServicePendingRequest pendingReq; + private MsConnectorDummySpConfiguration oaParam; + private SpecificCommunicationService springManagedSpecificConnectorCommunicationService; + + + /** + * jUnit test set-up. + * @throws EaafException In case of an error + */ + @Before + public void setUp() throws URISyntaxException, EaafException { + httpReq = new MockHttpServletRequest("POST", "https://localhost/authhandler"); + httpResp = new MockHttpServletResponse(); + RequestContextHolder.resetRequestAttributes(); + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp)); + + basicConfig.putConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint", + "http://eidas.proxy/endpoint"); + basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson", + "false"); + + 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 ProxyServicePendingRequest(); + pendingReq.initialize(httpReq, basicConfig); + pendingReq.setOnlineApplicationConfiguration(oaParam); + + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + + springManagedSpecificConnectorCommunicationService = + (SpecificCommunicationService) context.getBean( + SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE + .toString()); + + } + + @Test + public void wrongPendingRequestType() { + IAuthData authData = generateDummyAuthData(); + TestRequestImpl internalPendingReq = new TestRequestImpl(); + + EaafException exception = assertThrows(EaafException.class, + () -> action.processRequest(internalPendingReq, httpReq, httpResp, authData)); + Assert.assertEquals("wrong errorCode", "eidas.proxyservice.99", exception.getErrorId()); + + } + + @Test + public void missingForwardUrl() { + Map attr = new HashMap<>(); + attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false); + basicConfig.removeConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint"); + + EaafException exception = assertThrows(EaafException.class, + () -> action.processRequest(pendingReq, httpReq, httpResp, authData)); + Assert.assertEquals("wrong errorCode", "config.08", exception.getErrorId()); + + } + + @Test + public void responseWithoutMandate() throws EaafException, SpecificCommunicationException { + Map attr = new HashMap<>(); + attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false); + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 4, respAttr.size()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, + (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, + authData.getDateOfBirth()); + + } + + @Test + public void responseWithNatMandate() throws EaafException, SpecificCommunicationException { + Map attr = new HashMap<>(); + attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + + attr.put(MsEidasNodeConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, + "1985-11-15"); + + + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 8, respAttr.size()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, + (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); + + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, + (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME)); + + } + + @Test + public void responseWithJurMandate() throws EaafException, SpecificCommunicationException { + Map attr = new HashMap<>(); + attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + attr.put(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 6, respAttr.size()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, + (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); + + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER, + (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALNAME, + (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME)); + + assertNull("find nat. person subject: personalId", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER)); + assertNull("find nat. person subject: familyName", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME)); + assertNull("find nat. person subject: givenName", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME)); + assertNull("find nat. person subject: dateOfBirth", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH)); + + } + + @Test + public void responseWithNatMandateWithWorkAround() throws EaafException, SpecificCommunicationException { + basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson", + "true"); + + //request natural person subject only + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder().put( + attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + + Map attr = new HashMap<>(); + attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + + attr.put(MsEidasNodeConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, + "1985-11-15"); + + + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 8, respAttr.size()); + + } + + @Test + public void responseWithJurMandateWithWorkAround() throws EaafException, SpecificCommunicationException { + basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson", + "true"); + + //request natural person subject only + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + Map attr = new HashMap<>(); + attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + attr.put(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 10, respAttr.size()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, + (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, authData.getDateOfBirth()); + + } + + @Test + public void responseWithJurMandateWithWorkAroundNoNatSubject() throws EaafException, SpecificCommunicationException { + basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson", + "true"); + + //request natural person subject only + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + Map attr = new HashMap<>(); + attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + attr.put(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 6, respAttr.size()); + assertNull("find nat. person subject: personalId", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER)); + assertNull("find nat. person subject: familyName", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME)); + assertNull("find nat. person subject: givenName", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME)); + assertNull("find nat. person subject: dateOfBirth", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH)); + + } + + @Test + public void checkBasicConstrainsInAction() { + + Assert.assertTrue("Wrong NeedAuthentication", action.needAuthentication(pendingReq, httpReq, httpResp)); + Assert.assertNotNull("Missing ActionName", action.getDefaultActionName()); + + Assert.assertNotNull("missing ActionBean", context.getBean(ProxyServiceAuthenticationAction.class)); + + } + + private IAuthData generateDummyAuthData() { + return generateDummyAuthData(Collections.emptyMap(), EaafConstants.EIDAS_LOA_LOW, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1940-01-01", false); + + } + + private Object getAttrValue(ImmutableAttributeMap respAttr, String attrName) { + final AttributeDefinition attrDef = + attrRegistry.getCoreAttributeRegistry().getByFriendlyName(attrName).first(); + return respAttr.getFirstValue(attrDef); + + } + + private void checkAttrValue(ImmutableAttributeMap respAttr, String attrName, String expected) { + Object value = getAttrValue(respAttr, attrName); + assertNotNull("not attr value: " + attrName, value); + + if (value instanceof String) { + assertEquals("wrong attr. value: " + attrName, expected, value); + + } else if ( value instanceof DateTime) { + assertEquals("wrong attr. value: " + attrName, expected, ((DateTime)value).toString("yyyy-MM-dd")); + + } + } + + private ImmutableAttributeMap validateBasicEidasResponse(IAuthData authData) throws SpecificCommunicationException { + assertNotNull("not redirct Header", httpResp.getHeader("Location")); + assertTrue("wrong redirect URL", httpResp.getHeader("Location").startsWith("http://eidas.proxy/endpoint?token=")); + String token = httpResp.getHeader("Location").substring("http://eidas.proxy/endpoint?token=".length()); + + ILightResponse resp = springManagedSpecificConnectorCommunicationService.getAndRemoveResponse(URLDecoder.decode(token), + ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes())); + + assertNotNull("responseId", resp.getId()); + assertEquals("inResponseTo", pendingReq.getEidasRequest().getId(), resp.getInResponseToId()); + assertEquals("relayState", pendingReq.getEidasRequest().getRelayState(), resp.getRelayState()); + assertEquals("LoA", authData.getEidasQaaLevel(), resp.getLevelOfAssurance()); + + assertNotNull("subjectNameId", resp.getSubject()); + assertEquals("subjectNameIdFormat", NameIDType.TRANSIENT, resp.getSubjectNameIdFormat()); + + assertFalse("not attributes", resp.getAttributes().isEmpty()); + return resp.getAttributes(); + + } + + private Builder generateBasicLightRequest() { + return LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(RandomStringUtils.randomAlphabetic(10)) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .spType("public") + .requesterId(RandomStringUtils.randomAlphanumeric(10)) + .providerName(RandomStringUtils.randomAlphanumeric(10)); + + } + + private IAuthData generateDummyAuthData(Map attrs, String loa, String familyName, String givenName, String dateOfBirth, + boolean useMandates) { + return new IEidAuthData() { + + @Override + public boolean isSsoSession() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isForeigner() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isBaseIdTransferRestrication() { + // TODO Auto-generated method stub + return false; + } + + @Override + public Instant getSsoSessionValidTo() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getSessionIndex() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getNameIdFormat() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getNameID() { + // TODO Auto-generated method stub + return null; + } + + @Override + public IIdentityLink getIdentityLink() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getIdentificationValue() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getIdentificationType() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getGivenName() { + return givenName; + } + + @Override + public T getGenericData(String key, Class clazz) { + if (attrs.containsKey(key)) { + return (T) attrs.get(key); + + } else { + return null; + } + + } + + @Override + public String getDateOfBirth() { + return dateOfBirth; + } + + @Override + public String getFamilyName() { + return familyName; + } + + @Override + public String getEncryptedSourceIdType() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getEncryptedSourceId() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getEidasQaaLevel() { + return loa; + + } + + + @Override + public String getCiticenCountryCode() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getBpkType() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getBpk() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getAuthenticationIssuer() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getAuthenticationIssueInstantString() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Instant getAuthenticationIssueInstant() { + // TODO Auto-generated method stub + return null; + } + + @Override + public byte[] getSignerCertificate() { + // TODO Auto-generated method stub + return null; + } + + @Override + public byte[] getEidToken() { + // TODO Auto-generated method stub + return null; + } + + @Override + public EidIdentityStatusLevelValues getEidStatus() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getVdaEndPointUrl() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isUseMandate() { + return useMandates; + + } + + @Override + public String getDateOfBirthFormated(String pattern) { + // TODO Auto-generated method stub + return null; + } + }; + + } +} -- cgit v1.2.3 From b3bbdc754025246c3de2a8e04a7ed2f085c5d19e Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 7 Jun 2022 13:21:48 +0200 Subject: feat(eidas): add attribute-mapping service to map eIDAS attributs to IDA attributes --- .../msproxyservice/MsProxyServiceConstants.java | 5 + .../dto/attributes/AttrMappingElement.java | 37 +++++ .../dto/attributes/IdaAttribute.java | 29 ++++ .../msproxyservice/dto/attributes/Type.java | 79 +++++++++ .../service/ProxyEidasAttributeRegistry.java | 176 +++++++++++++++++++++ .../resources/spring/eidas_proxy-service.beans.xml | 3 + .../services/ProxyEidasAttributeRegistryTest.java | 95 +++++++++++ .../test/resources/config/idaAttributeMapping.json | 157 ++++++++++++++++++ .../resources/config/junit_config_1.properties | 4 +- 9 files changed, 584 insertions(+), 1 deletion(-) create mode 100644 modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java create mode 100644 modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/IdaAttribute.java create mode 100644 modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java create mode 100644 modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java create mode 100644 modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java create mode 100644 modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java index fd6b45bb..a2a2e78f 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java @@ -20,6 +20,11 @@ public class MsProxyServiceConstants { public static final String CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL = EidasConstants.CONIG_PROPS_EIDAS_NODE + ".proxy.forward.endpoint"; + + public static final String CONIG_PROPS_EIDAS_PROXY_ATTIBUTE_CONFIGURATION = + EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.attribute.mapping.config"; + + // mandate configuration public static final String CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED = EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.mandates.enabled"; diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java new file mode 100644 index 00000000..d6ed1147 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java @@ -0,0 +1,37 @@ + +package at.asitplus.eidas.specific.modules.msproxyservice.dto.attributes; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import lombok.Data; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "eidasAttribute", + "idaAttribute", + "type" +}) +@Data +public class AttrMappingElement { + + /** + * eIDAS specific attribute name. + */ + @JsonProperty("eidasAttribute") + private String eidasAttributeName; + + /** + * IDA specific attribute name. + */ + @JsonProperty("idaAttribute") + private IdaAttribute idaAttribute; + + /** + * attribute characteristics. + */ + @JsonProperty("type") + private Type type; + +} diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/IdaAttribute.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/IdaAttribute.java new file mode 100644 index 00000000..ee5fc810 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/IdaAttribute.java @@ -0,0 +1,29 @@ +package at.asitplus.eidas.specific.modules.msproxyservice.dto.attributes; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import lombok.Data; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "basic", + "withMandates" +}) +@Data +public class IdaAttribute { + + /** + * IDA attribute name, in case of simple process without mandates. + */ + @JsonProperty("basic") + private String basic; + + /** + * IDA attribute name, in case of mandate process. + */ + @JsonProperty("withMandates") + private String withMandates; + +} diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java new file mode 100644 index 00000000..86ca49fa --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java @@ -0,0 +1,79 @@ + +package at.asitplus.eidas.specific.modules.msproxyservice.dto.attributes; + +import java.util.HashMap; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonValue; + +import lombok.Data; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "mds", + "mandator" +}) +@Data +public class Type { + + /** + * true if this attribute is part of MDS, otherwise + * false + */ + @JsonProperty("mds") + private Boolean mds; + + /** + * Classifie that attribute to specific mandate modes. + */ + @JsonProperty("mandator") + private Type.Mandator mandator; + + /** + * Mandate type in case of a mandate attriute. + */ + public enum Mandator { + BOTH("both"), + LEGAL("legal"), + NATURAL("natural"), + NONE("none"); + + private final String value; + private final static Map CONSTANTS = new HashMap<>(); + + static { + for (final Type.Mandator c : values()) { + CONSTANTS.put(c.value, c); + } + } + + Mandator(String value) { + this.value = value; + } + + @Override + public String toString() { + return this.value; + } + + @JsonValue + public String value() { + return this.value; + } + + @JsonCreator + public static Type.Mandator fromValue(String value) { + final Type.Mandator constant = CONSTANTS.get(value); + if (constant == null) { + throw new IllegalArgumentException(value); + } else { + return constant; + } + } + + } +} diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java new file mode 100644 index 00000000..ea561c1d --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java @@ -0,0 +1,176 @@ +package at.asitplus.eidas.specific.modules.msproxyservice.service; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.annotation.PostConstruct; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.CollectionType; +import com.google.common.collect.Sets; + +import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry; +import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; +import at.asitplus.eidas.specific.modules.msproxyservice.dto.attributes.AttrMappingElement; +import at.asitplus.eidas.specific.modules.msproxyservice.dto.attributes.IdaAttribute; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +import at.gv.egiz.eaaf.core.impl.utils.FileUtils; +import lombok.Getter; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ProxyEidasAttributeRegistry { + + private static final String ATTR_CONFIG_ALL = "*"; + + private static ObjectMapper mapper = new ObjectMapper(); + + @Autowired IConfiguration basicConfig; + @Autowired ResourceLoader resourceLoader; + + + @Getter + private EidasAttributeRegistry coreRegistry; + + private Set attributeConfiguration; + + + /** + * Attribute Registry for eIDAS Proxy-Service implementation. + * @param registry Core attribute registry + */ + public ProxyEidasAttributeRegistry(@Autowired EidasAttributeRegistry registry) { + this.coreRegistry = registry; + + } + + + /** + * Get all attributes that requested from IDA by default. + * + * @param withMandates true if mandates are supported, otherwise false + * @return {@link Stream} of IDA specific attribute names + */ + @NonNull + public Stream getAlwaysRequestedAttributes(boolean withMandates) { + return attributeConfiguration.stream() + .filter(el -> ATTR_CONFIG_ALL.equals(el.getEidasAttributeName())) + .map(el -> getReleadedIdaAttribute(el.getIdaAttribute(), withMandates)) + .flatMap(Collection::stream) + .filter(Objects::nonNull); + + } + + /** + * Get IDA attributes for a specific eIDAS attribute. + * + * @param eidasAttributeName Name of the eIDAS attribute. + * @param withMandates true if mandates are supported, otherwise false + * @return {@link Set} of IDA specific attribute names + */ + @NonNull + public Set getIdaAttributesForEidasAttribute(String eidasAttributeName, boolean withMandates) { + return attributeConfiguration.stream() + .filter(el -> el.getEidasAttributeName().equals(eidasAttributeName)) + .findFirst() + .map(el -> getReleadedIdaAttribute(el.getIdaAttribute(), withMandates)) + .orElse(Collections.emptySet()) + .stream() + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + } + + + @PostConstruct + private void initialize() throws EaafConfigurationException { + final String attrConfPath = basicConfig.getBasicConfiguration( + MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_ATTIBUTE_CONFIGURATION); + + log.debug("Initializing eIDAS <--> IDA attribute mapping from: {} ... ", attrConfPath); + + if (StringUtils.isEmpty(attrConfPath)) { + log.error("Error: Path to attribute-mapping config is unknown"); + throw new EaafConfigurationException("internal.configuration.00", + new Object[]{MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_ATTIBUTE_CONFIGURATION}); + + } + + try { + // reading attribute-configuration file + final CollectionType javaType = + mapper.getTypeFactory().constructCollectionType(List.class, AttrMappingElement.class); + List internalAttributeConfiguration = + mapper.readValue(readFromFile(attrConfPath), javaType); + log.debug("Found #{} eIDAS <--> IDA attribute-mappings . Starting import process ... ", + internalAttributeConfiguration.size()); + + // post-validation of attribute configuration + attributeConfiguration = internalAttributeConfiguration.stream() + .filter(el -> checkEidasAttributeName(el)) + .collect(Collectors.toSet()); + log.info("Load {} eIDAS <--> IDA attribute-mappings into attribute-registry", attributeConfiguration.size()); + + } catch (Exception e) { + log.error("Error reading eIDAS <--> IDA attribute-mapping configuration file", e); + throw new EaafConfigurationException("internal.configuration.01", + new Object[]{MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_ATTIBUTE_CONFIGURATION, + "Error reading Configurations file"}, e); + + } + } + + private Set getReleadedIdaAttribute(IdaAttribute el, boolean withMandates) { + return withMandates + ? Sets.newHashSet(el.getBasic(), el.getWithMandates()) + : Sets.newHashSet(el.getBasic()); + + } + + private boolean checkEidasAttributeName(AttrMappingElement el) { + if (StringUtils.isNotEmpty(el.getEidasAttributeName())) { + if (ATTR_CONFIG_ALL.equals(el.getEidasAttributeName()) + || coreRegistry.getCoreAttributeRegistry().getByName(el.getEidasAttributeName()) != null) { + return true; + + } else { + log.warn("eIDAS attribute: {} is UNKNOWN by eIDAS node. Ignore it!", el.getEidasAttributeName()); + + } + + } else { + log.warn("Find attribute-mapping element WITHOUT eIDAS attribute-name. Ignore it!"); + + } + + return false; + } + + private byte[] readFromFile(final String filePath) throws URISyntaxException, IOException { + final String fullFilePath = FileUtils.makeAbsoluteUrl(filePath, basicConfig.getConfigurationRootDirectory()); + final Resource ressource = resourceLoader.getResource(fullFilePath); + final InputStream is = ressource.getInputStream(); + final byte[] result = IOUtils.toByteArray(is); + is.close(); + return result; + + } + + +} diff --git a/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml b/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml index 1eb33e93..78b7640a 100644 --- a/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml +++ b/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml @@ -32,4 +32,7 @@ ref="specificConnectorAdditionalAttributesFileWithPath" /> + + \ No newline at end of file diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java new file mode 100644 index 00000000..6034c92a --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java @@ -0,0 +1,95 @@ +package at.asitplus.eidas.specific.modules.msproxyservice.test.services; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +import at.asitplus.eidas.specific.modules.msproxyservice.service.ProxyEidasAttributeRegistry; +import lombok.NonNull; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { + "/spring/SpringTest-context_basic_test.xml", + "/spring/SpringTest-context_basic_mapConfig.xml", + }) +@EnableWebMvc +public class ProxyEidasAttributeRegistryTest { + + @Autowired ProxyEidasAttributeRegistry attrRegistry; + + @Test + public void checkDefaultAttributes() { + assertEquals("default attributes without mandates", 2, + attrRegistry.getAlwaysRequestedAttributes(false).count()); + assertEquals("default attributes with mandates", 4, + attrRegistry.getAlwaysRequestedAttributes(true).count()); + + } + + @Test + public void eidasAttributeMapping() { + checkAttributeMapping("http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", false, + Arrays.asList("urn:oid:1.2.40.0.10.2.1.1.149")); + checkAttributeMapping("http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", true, + Arrays.asList("urn:oid:1.2.40.0.10.2.1.1.149", "urn:oid:1.2.40.0.10.2.1.1.261.98")); + + } + + @Test + public void eidasAttributeMappingMandateOnly() { + checkAttributeMapping("http://eidas.europa.eu/attributes/legalperson/LegalPersonIdentifier", false, + Collections.emptyList()); + checkAttributeMapping("http://eidas.europa.eu/attributes/legalperson/LegalPersonIdentifier", true, + Arrays.asList("urn:oid:1.2.40.0.10.2.1.1.261.100")); + + } + + @Test + public void eidasAttributeMappingWithNoIdaAttribute() { + checkAttributeMapping("http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", false, + Collections.emptyList()); + checkAttributeMapping("http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", true, + Collections.emptyList()); + + } + + @Test + public void unknownEidasAttribute() { + checkAttributeMapping("http://eidas.europa.eu/attributes/jUnit/not/exits", false, + Collections.emptyList()); + checkAttributeMapping("http://eidas.europa.eu/attributes/jUnit/not/exits", true, + Collections.emptyList()); + + } + + @Test + public void unknownEidasAttribute2() { + checkAttributeMapping(RandomStringUtils.randomAlphabetic(10), false, + Collections.emptyList()); + checkAttributeMapping(RandomStringUtils.randomAlphabetic(10), true, + Collections.emptyList()); + + } + + private void checkAttributeMapping(String eidasAttr, boolean withMandates, List idaAttributes) { + @NonNull + Set idaAttrResult = attrRegistry.getIdaAttributesForEidasAttribute(eidasAttr, withMandates); + assertEquals("wrong number of IDA attributes", idaAttributes.size(), idaAttrResult.size()); + idaAttributes.forEach( + el -> assertTrue("missing: " + el, idaAttrResult.contains(el))); + + } + +} diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json b/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json new file mode 100644 index 00000000..4f059876 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json @@ -0,0 +1,157 @@ +[ + { + "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "idaAttribute": { + "basic": "urn:oid:1.2.40.0.10.2.1.1.149", + "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.98" + }, + "type": { + "mds": true + } + }, + { + "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/CurrentGivenName", + "idaAttribute": { + "basic": "urn:oid:2.5.4.42", + "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.78" + }, + "type": { + "mds": true + } + }, + { + "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/CurrentFamilyName", + "idaAttribute": { + "basic": "urn:oid:1.2.40.0.10.2.1.1.261.20", + "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.80" + }, + "type": { + "mds": true + } + }, + { + "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/DateOfBirth", + "idaAttribute": { + "basic": "urn:oid:1.2.40.0.10.2.1.1.55", + "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.82" + }, + "type": { + "mds": true + } + }, + { + "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", + "idaAttribute": {}, + "type": { + "mds": false + } + }, + { + "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/BirthName", + "idaAttribute": {}, + "type": { + "mds": false + } + }, + { + "eidasAttribute": "http://eidas.europa.eu/attributes/legalperson/LegalPersonIdentifier", + "idaAttribute": { + "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.100" + }, + "type": { + "mds": true + } + }, + { + "eidasAttribute": "http://eidas.europa.eu/attributes/legalperson/LegalName", + "idaAttribute": { + "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.84" + }, + "type": { + "mds": true + } + }, + { + "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/representative/PersonIdentifier", + "idaAttribute": { + "withMandates": "urn:oid:1.2.40.0.10.2.1.1.149" + }, + "type": { + "mds": true + } + }, + { + "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/representative/CurrentFamilyName", + "idaAttribute": { + "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.20" + }, + "type": { + "mds": true + } + }, + { + "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/representative/CurrentGivenName", + "idaAttribute": { + "withMandates": "urn:oid:2.5.4.42" + }, + "type": { + "mds": true + } + }, + { + "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/representative/DateOfBirth", + "idaAttribute": { + "withMandates": "urn:oid:1.2.40.0.10.2.1.1.55" + }, + "type": { + "mds": true + } + }, + { + "eidasAttribute": "*", + "idaAttribute": { + "basic": "urn:oid:1.2.40.0.10.2.1.1.261.32", + "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.32" + }, + "type": { + "mds": false + } + }, + { + "eidasAttribute": "*", + "idaAttribute": { + "basic": "urn:oid:1.2.40.0.10.2.1.1.261.108", + "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.108" + }, + "type": { + "mds": false + } + }, + { + "eidasAttribute": "*", + "idaAttribute": { + "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.68" + }, + "type": { + "mds": false + } + }, + { + "eidasAttribute": "*", + "idaAttribute": { + "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.106" + }, + "type": { + "mds": false + } + }, + { + "eidasAttribute": "http://eidas.europa.eu/attributes/jUnit/not/exits", + "idaAttribute": { + "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.106" + }, + "type": { + "mds": false + } + } +] \ No newline at end of file diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties index 4f3b82b5..bd4575c3 100644 --- a/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties +++ b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties @@ -3,4 +3,6 @@ eidas.ms.context.url.prefix=http://localhost eidas.ms.context.url.request.validation=false eidas.ms.auth.eIDAS.node_v2.proxy.entityId=ownSpecificProxy -eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint=http://eidas.proxy/endpoint \ No newline at end of file +eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint=http://eidas.proxy/endpoint + +eidas.ms.auth.eIDAS.proxy.attribute.mapping.config=idaAttributeMapping.json \ No newline at end of file -- cgit v1.2.3 From 4c6a80097a041135b96dd1bccac5d3887d63865c Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 7 Jun 2022 13:22:24 +0200 Subject: test(eidas): move jUnit tests into other package --- .../modules/msproxyservice/test/EidasProxyMessageSourceTest.java | 2 +- .../msproxyservice/test/MsProxyServiceSpringResourceProviderTest.java | 2 +- .../msproxyservice/test/protocol/EidasProxyServiceControllerTest.java | 2 +- .../test/protocol/ProxyServiceAuthenticationActionTest.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/EidasProxyMessageSourceTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/EidasProxyMessageSourceTest.java index efe572b5..fc4ad2b6 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/EidasProxyMessageSourceTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/EidasProxyMessageSourceTest.java @@ -1,4 +1,4 @@ -package at.asitplus.eidas.specific.modules.auth.idaustria.test; +package at.asitplus.eidas.specific.modules.msproxyservice.test; import java.util.List; diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/MsProxyServiceSpringResourceProviderTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/MsProxyServiceSpringResourceProviderTest.java index 8c6da366..9a690664 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/MsProxyServiceSpringResourceProviderTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/MsProxyServiceSpringResourceProviderTest.java @@ -1,4 +1,4 @@ -package at.asitplus.eidas.specific.modules.auth.idaustria.test; +package at.asitplus.eidas.specific.modules.msproxyservice.test; import java.io.IOException; import java.io.InputStream; diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java index 2b652f79..189378e0 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java @@ -1,4 +1,4 @@ -package at.asitplus.eidas.specific.modules.auth.idaustria.test.protocol; +package at.asitplus.eidas.specific.modules.msproxyservice.test.protocol; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java index 97b5bc03..c41d6c99 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java @@ -1,4 +1,4 @@ -package at.asitplus.eidas.specific.modules.auth.idaustria.test.protocol; +package at.asitplus.eidas.specific.modules.msproxyservice.test.protocol; import static at.asitplus.eidas.specific.core.MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE; import static org.junit.Assert.assertEquals; -- cgit v1.2.3 From 9c9463d593014292a4b19fbad2fca779e56e33cf Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 7 Jun 2022 13:47:42 +0200 Subject: feat(eidas): update proxy-service attribute registry to request releated attributes --- .../dto/attributes/AttrMappingElement.java | 6 +++++ .../service/ProxyEidasAttributeRegistry.java | 27 +++++++++++++++------- .../services/ProxyEidasAttributeRegistryTest.java | 13 +++++++++-- .../test/resources/config/idaAttributeMapping.json | 6 +++++ 4 files changed, 42 insertions(+), 10 deletions(-) (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java index d6ed1147..cf106bad 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java @@ -1,6 +1,8 @@ package at.asitplus.eidas.specific.modules.msproxyservice.dto.attributes; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; @@ -28,6 +30,10 @@ public class AttrMappingElement { @JsonProperty("idaAttribute") private IdaAttribute idaAttribute; + + @JsonProperty("addionalRequiredAttributes") + private List addionalRequiredAttributes; + /** * attribute characteristics. */ diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java index ea561c1d..b9e0c488 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java @@ -26,7 +26,6 @@ import com.google.common.collect.Sets; import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry; import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; import at.asitplus.eidas.specific.modules.msproxyservice.dto.attributes.AttrMappingElement; -import at.asitplus.eidas.specific.modules.msproxyservice.dto.attributes.IdaAttribute; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; import at.gv.egiz.eaaf.core.impl.utils.FileUtils; @@ -71,7 +70,7 @@ public class ProxyEidasAttributeRegistry { public Stream getAlwaysRequestedAttributes(boolean withMandates) { return attributeConfiguration.stream() .filter(el -> ATTR_CONFIG_ALL.equals(el.getEidasAttributeName())) - .map(el -> getReleadedIdaAttribute(el.getIdaAttribute(), withMandates)) + .map(el -> getReleadedIdaAttribute(el, withMandates)) .flatMap(Collection::stream) .filter(Objects::nonNull); @@ -89,7 +88,7 @@ public class ProxyEidasAttributeRegistry { return attributeConfiguration.stream() .filter(el -> el.getEidasAttributeName().equals(eidasAttributeName)) .findFirst() - .map(el -> getReleadedIdaAttribute(el.getIdaAttribute(), withMandates)) + .map(el -> getReleadedIdaAttribute(el, withMandates)) .orElse(Collections.emptySet()) .stream() .filter(Objects::nonNull) @@ -136,11 +135,23 @@ public class ProxyEidasAttributeRegistry { } } - private Set getReleadedIdaAttribute(IdaAttribute el, boolean withMandates) { - return withMandates - ? Sets.newHashSet(el.getBasic(), el.getWithMandates()) - : Sets.newHashSet(el.getBasic()); - + private Set getReleadedIdaAttribute(AttrMappingElement el, boolean withMandates) { + if (el.getIdaAttribute() != null) { + Set directMapping = withMandates + ? Sets.newHashSet(el.getIdaAttribute().getBasic(), el.getIdaAttribute().getWithMandates()) + : Sets.newHashSet(el.getIdaAttribute().getBasic()); + + if (el.getAddionalRequiredAttributes() != null) { + el.getAddionalRequiredAttributes().forEach( + attr -> directMapping.add(attr)); + + } + return directMapping; + + } else { + return Collections.emptySet(); + + } } private boolean checkEidasAttributeName(AttrMappingElement el) { diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java index 6034c92a..d3e787bb 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java @@ -50,9 +50,18 @@ public class ProxyEidasAttributeRegistryTest { @Test public void eidasAttributeMappingMandateOnly() { checkAttributeMapping("http://eidas.europa.eu/attributes/legalperson/LegalPersonIdentifier", false, - Collections.emptyList()); + Arrays.asList( + "urn:oid:1.2.40.0.10.2.1.1.149", + "urn:oid:2.5.4.42", + "urn:oid:1.2.40.0.10.2.1.1.261.20", + "urn:oid:1.2.40.0.10.2.1.1.55")); checkAttributeMapping("http://eidas.europa.eu/attributes/legalperson/LegalPersonIdentifier", true, - Arrays.asList("urn:oid:1.2.40.0.10.2.1.1.261.100")); + Arrays.asList( + "urn:oid:1.2.40.0.10.2.1.1.261.100", + "urn:oid:1.2.40.0.10.2.1.1.149", + "urn:oid:2.5.4.42", + "urn:oid:1.2.40.0.10.2.1.1.261.20", + "urn:oid:1.2.40.0.10.2.1.1.55")); } diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json b/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json index 4f059876..2d375acb 100644 --- a/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json +++ b/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json @@ -58,6 +58,12 @@ "idaAttribute": { "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.100" }, + "addionalRequiredAttributes" : [ + "urn:oid:1.2.40.0.10.2.1.1.149", + "urn:oid:2.5.4.42", + "urn:oid:1.2.40.0.10.2.1.1.261.20", + "urn:oid:1.2.40.0.10.2.1.1.55" + ], "type": { "mds": true } -- cgit v1.2.3 From db3af28b79296b6f5650a85c5a41ad5015c57222 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 7 Jun 2022 13:48:34 +0200 Subject: feat(eidas): include IDA releated requested attributes into service-provider configuration --- .../protocol/EidasProxyServiceController.java | 35 +++++++++++++++++----- .../protocol/EidasProxyServiceControllerTest.java | 14 ++++++++- 2 files changed, 41 insertions(+), 8 deletions(-) (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java index cd404cee..26cc51ee 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java @@ -2,9 +2,11 @@ package at.asitplus.eidas.specific.modules.msproxyservice.protocol; import java.io.IOException; import java.text.MessageFormat; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.UUID; import java.util.stream.Collectors; @@ -22,13 +24,14 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.Streams; import at.asitplus.eidas.specific.core.MsEidasNodeConstants; import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration; import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants; -import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry; import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException; +import at.asitplus.eidas.specific.modules.msproxyservice.service.ProxyEidasAttributeRegistry; import at.asitplus.eidas.specific.modules.msproxyservice.utils.EidasProxyServiceUtils; import at.gv.egiz.components.eventlog.api.EventConstants; import at.gv.egiz.eaaf.core.api.IRequest; @@ -76,7 +79,7 @@ public class EidasProxyServiceController extends AbstractController implements I public static final String PROTOCOL_ID = "eidasProxy"; - @Autowired EidasAttributeRegistry attrRegistry; + @Autowired ProxyEidasAttributeRegistry attrRegistry; @Autowired ProxyServiceAuthenticationAction responseAction; /** @@ -115,7 +118,7 @@ public class EidasProxyServiceController extends AbstractController implements I .toString()); final ILightRequest eidasRequest = specificProxyCommunicationService.getAndRemoveRequest( tokenBase64, - ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes())); + ImmutableSortedSet.copyOf(attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getAttributes())); if (eidasRequest == null) { log.info("Find no eIDAS Authn. Request with stated token."); throw new EidasProxyServiceException(ERROR_11, null); @@ -317,9 +320,12 @@ public class EidasProxyServiceController extends AbstractController implements I spConfig.setRequiredLoA( eidasRequest.getLevelsOfAssurance().stream().map(el -> el.getValue()).collect(Collectors.toList())); - //build mandate profiles for this specific request + // build mandate profiles for this specific request buildMandateProfileConfiguration(spConfig, eidasRequest); - + + // map eIDAS attributes to national attributes + buildNationalRequestedAttributes(spConfig, eidasRequest); + return spConfig; } catch (EidasProxyServiceException e) { @@ -332,6 +338,22 @@ public class EidasProxyServiceController extends AbstractController implements I } + private void buildNationalRequestedAttributes( + ServiceProviderConfiguration spConfig, ILightRequest eidasRequest) { + boolean mandatesEnabled = !SpMandateModes.NONE.equals(spConfig.getMandateMode()); + spConfig.setRequestedAttributes( + Streams.concat( + eidasRequest.getRequestedAttributes().getAttributeMap().keySet().stream() + .map(el -> attrRegistry.getIdaAttributesForEidasAttribute( + el.getNameUri().toString(), mandatesEnabled)) + .flatMap(Collection::stream) + .filter(Objects::nonNull), + attrRegistry.getAlwaysRequestedAttributes(mandatesEnabled)) + .collect(Collectors.toSet())); + log.debug("Inject #{} attributes to request from IDA system", spConfig.getRequestedAttributes().size()); + + } + private Map extractRawConnectorConfiguration(ILightRequest eidasRequest) { Map allConnectorConfigs = authConfig.getBasicConfigurationWithPrefix( MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_PREFIX); @@ -341,8 +363,7 @@ public class EidasProxyServiceController extends AbstractController implements I el -> log.trace("Key: {} -> Value: {}", el.getKey(), el.getValue())); } - - + Map connectorConfig = allConnectorConfigs.entrySet().stream() .filter(el -> el.getKey().endsWith(MsEidasNodeConstants.PROP_CONFIG_SP_UNIQUEIDENTIFIER) && el.getValue().equals(eidasRequest.getIssuer())) diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java index 189378e0..ef1abbcd 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java @@ -277,7 +277,10 @@ public class EidasProxyServiceControllerTest { .spType("public") .requestedAttributes(ImmutableAttributeMap.builder() .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_BIRTHNAME).first()) + .build()); proxyService.setiLightRequest(authnReqBuilder.build()); @@ -326,6 +329,9 @@ public class EidasProxyServiceControllerTest { assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode()); + assertEquals("requested IDA attributes", 3, spConfig.getRequestedAttributes().size()); + + } @Test @@ -370,6 +376,8 @@ public class EidasProxyServiceControllerTest { .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfilesNat.contains(el))); assertEquals("MandateMode", SpMandateModes.NATURAL, spConfig.getMandateMode()); + assertEquals("requested IDA attributes", 6, spConfig.getRequestedAttributes().size()); + } @Test @@ -414,6 +422,8 @@ public class EidasProxyServiceControllerTest { .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfilesJur.contains(el))); assertEquals("MandateMode", SpMandateModes.LEGAL_FORCE, spConfig.getMandateMode()); + assertEquals("requested IDA attributes", 9, spConfig.getRequestedAttributes().size()); + } @Test @@ -481,6 +491,8 @@ public class EidasProxyServiceControllerTest { assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode()); + + assertEquals("requested IDA attributes", 3, spConfig.getRequestedAttributes().size()); } -- cgit v1.2.3 From 3d9d419a40b17de1f94d46cbc2f5b345a93bff00 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Wed, 8 Jun 2022 12:32:16 +0200 Subject: feat(eidas): perform mapping between IDA and eIDAS attributes based on external configuration --- .../msproxyservice/dto/attributes/Type.java | 7 + .../protocol/ProxyServiceAuthenticationAction.java | 297 ++++++++++----------- .../service/ProxyEidasAttributeRegistry.java | 34 ++- .../ProxyServiceAuthenticationActionTest.java | 217 ++++++++++++--- .../services/ProxyEidasAttributeRegistryTest.java | 35 +++ .../test/resources/config/idaAttributeMapping.json | 56 ++-- 6 files changed, 430 insertions(+), 216 deletions(-) (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java index 86ca49fa..f66bb799 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java @@ -15,6 +15,7 @@ import lombok.Data; @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({ "mds", + "autoIncludeWithMandates", "mandator" }) @Data @@ -27,6 +28,12 @@ public class Type { @JsonProperty("mds") private Boolean mds; + /** + * true if that attribute has to be included into eIDAS response in case of mandates. + */ + @JsonProperty("autoIncludeWithMandates") + private Boolean autoIncludeWithMandates; + /** * Classifie that attribute to specific mandate modes. */ diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java index 92165412..bf1c5e5f 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java @@ -1,6 +1,7 @@ package at.asitplus.eidas.specific.modules.msproxyservice.protocol; import java.io.IOException; +import java.util.Optional; import java.util.UUID; import javax.annotation.PostConstruct; @@ -15,12 +16,11 @@ import org.springframework.context.ApplicationContext; import org.springframework.core.io.ResourceLoader; import org.springframework.web.util.UriComponentsBuilder; -import at.asitplus.eidas.specific.core.MsEidasNodeConstants; import at.asitplus.eidas.specific.core.gui.StaticGuiBuilderConfiguration; import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants; -import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry; import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException; +import at.asitplus.eidas.specific.modules.msproxyservice.service.ProxyEidasAttributeRegistry; import at.asitplus.eidas.specific.modules.msproxyservice.utils.EidasProxyServiceUtils; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions; @@ -69,35 +69,35 @@ public class ProxyServiceAuthenticationAction implements IAction { @Autowired ISpringMvcGuiFormBuilder guiBuilder; @Autowired - EidasAttributeRegistry attrRegistry; + ProxyEidasAttributeRegistry attrRegistry; @Override public SloInformationInterface processRequest(IRequest pendingReq, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws EaafException { if (pendingReq instanceof ProxyServicePendingRequest) { - try { - ILightRequest eidasReq = ((ProxyServicePendingRequest) pendingReq).getEidasRequest(); - - //build eIDAS response - Builder lightRespBuilder = LightResponse.builder(); + try { + final ILightRequest eidasReq = ((ProxyServicePendingRequest) pendingReq).getEidasRequest(); + + // build eIDAS response + final Builder lightRespBuilder = LightResponse.builder(); lightRespBuilder.id(UUID.randomUUID().toString()); lightRespBuilder.inResponseToId(eidasReq.getId()); lightRespBuilder.relayState(eidasReq.getRelayState()); - + lightRespBuilder.status(ResponseStatus.builder() .statusCode(EidasConstants.SUCCESS_URI) .build()); - - //TODO: check if we can use transient subjectNameIds + + // TODO: check if we can use transient subjectNameIds lightRespBuilder.subject(UUID.randomUUID().toString()); lightRespBuilder.subjectNameIdFormat(NameIDType.TRANSIENT); - - //TODO: + + // TODO: lightRespBuilder.issuer(basicConfig.getBasicConfiguration( MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID)); - lightRespBuilder.levelOfAssurance(authData.getEidasQaaLevel()); + lightRespBuilder.levelOfAssurance(authData.getEidasQaaLevel()); lightRespBuilder.attributes(buildAttributesFromAuthData(authData, eidasReq)); - + // set SLO response object of EAAF framework final SloInformationImpl sloInformation = new SloInformationImpl(); sloInformation.setProtocolType(pendingReq.requestedModule()); @@ -121,7 +121,7 @@ public class ProxyServiceAuthenticationAction implements IAction { } } - + @Override public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) { return true; @@ -133,28 +133,29 @@ public class ProxyServiceAuthenticationAction implements IAction { return PROXYSERVICE_AUTH_ACTION_NAME; } - /** * Forward eIDAS Light response to eIDAS node. - * - * @param pendingReq Current pending request. - * @param httpReq Current HTTP request - * @param httpResp Current HTTP response + * + * @param pendingReq Current pending request. + * @param httpReq Current HTTP request + * @param httpResp Current HTTP response * @param lightResponse eIDAS LightResponse * @throws EaafConfigurationException In case of a configuration error - * @throws IOException In case of a general error - * @throws GuiBuildException In case of a GUI rendering error, if http POST binding is used - * @throws ServletException In case of a general error + * @throws IOException In case of a general error + * @throws GuiBuildException In case of a GUI rendering error, if http + * POST binding is used + * @throws ServletException In case of a general error */ public void forwardToEidasProxy(IRequest pendingReq, HttpServletRequest httpReq, - HttpServletResponse httpResp, LightResponse lightResponse) throws EaafConfigurationException, IOException, + HttpServletResponse httpResp, LightResponse lightResponse) throws EaafConfigurationException, + IOException, GuiBuildException, ServletException { // put request into shared cache final BinaryLightToken token = putResponseInCommunicationCache(lightResponse); final String tokenBase64 = BinaryLightTokenHelper.encodeBinaryLightTokenBase64(token); - + // select forward URL regarding the selected environment final String forwardUrl = basicConfig.getBasicConfiguration( MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL); @@ -196,148 +197,80 @@ public class ProxyServiceAuthenticationAction implements IAction { } } - - @PostConstruct + + @PostConstruct private void checkConfiguration() { - //TODO: validate configuration on start-up - + // TODO: validate configuration on start-up + } - - - private ImmutableAttributeMap buildAttributesFromAuthData(IAuthData authData, + + private ImmutableAttributeMap buildAttributesFromAuthData(IAuthData authData, ILightRequest eidasReq) { - IEidAuthData eidAuthData = (IEidAuthData) authData; + final IEidAuthData eidAuthData = (IEidAuthData) authData; + final ImmutableAttributeMap.Builder attributeMap = ImmutableAttributeMap.builder(); + + // inject all requested attributres + injectRequestedAttributes(attributeMap, eidasReq, eidAuthData); + if (eidAuthData.isUseMandate()) { log.debug("Building eIDAS Proxy-Service response with mandate ... "); - final ImmutableAttributeMap.Builder attributeMap = ImmutableAttributeMap.builder(); - injectRepesentativeInformation(attributeMap, eidAuthData); - injectMandatorInformation(attributeMap, eidAuthData); - - // work-around that injects nat. person subject to bypass validation on eIDAS Node + injectMdsRepesentativeInformation(attributeMap, eidAuthData, eidasReq.getRequestedAttributes()); + + // work-around that injects nat. person subject to bypass validation on eIDAS + // Node injectJurPersonWorkaroundIfRequired(attributeMap, eidasReq, authData); - - return attributeMap.build(); - - } else { - log.debug("Building eIDAS Proxy-Service response without mandates ... "); - return buildAttributesWithoutMandate(eidAuthData); - - } - } - - private void injectMandatorInformation( - ImmutableAttributeMap.Builder attributeMap, IEidAuthData eidAuthData) { - String natMandatorId = eidAuthData.getGenericData( - MsEidasNodeConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER, String.class); - - if (StringUtils.isNotEmpty(natMandatorId)) { - log.debug("Injecting natural mandator informations ... "); - final AttributeDefinition attrDefPersonalId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first(); - final AttributeDefinition attrDefFamilyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first(); - final AttributeDefinition attrDefGivenName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first(); - final AttributeDefinition attrDefDateOfBirth = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first(); - - attributeMap.put(attrDefPersonalId, natMandatorId); - attributeMap.put(attrDefFamilyName, eidAuthData.getGenericData( - PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, String.class)); - attributeMap.put(attrDefGivenName, eidAuthData.getGenericData( - PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, String.class)); - attributeMap.put(attrDefDateOfBirth, eidAuthData.getGenericData( - PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, String.class)); - - } else { - log.debug("Injecting legal mandator informations ... "); - final AttributeDefinition commonName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_LEGALNAME).first(); - final AttributeDefinition legalPersonId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first(); - - attributeMap.put(commonName, eidAuthData.getGenericData( - PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, String.class)); - attributeMap.put(legalPersonId, eidAuthData.getGenericData( - MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, String.class)); - - } - } - private void injectRepesentativeInformation( - ImmutableAttributeMap.Builder attributeMap, IEidAuthData eidAuthData) { - final AttributeDefinition attrDefPersonalId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER).first(); - final AttributeDefinition attrDefFamilyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME).first(); - final AttributeDefinition attrDefGivenName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME).first(); - final AttributeDefinition attrDefDateOfBirth = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH).first(); - - attributeMap.put(attrDefPersonalId, - eidAuthData.getGenericData(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, String.class)); - attributeMap.put(attrDefFamilyName, eidAuthData.getFamilyName()); - attributeMap.put(attrDefGivenName, eidAuthData.getGivenName()); - - //TODO: throw an error in case of SZR Date with month or day = "00" - attributeMap.put(attrDefDateOfBirth, eidAuthData.getDateOfBirth()); - + } + + return attributeMap.build(); + } - /** - * Work-around to inject representative information as nat. person subject to bypass eIDAS Node validation. - * - *

Injection will only be done if this work-around is enabled by configuration, - * the mandator is a legal person, and both legal and natural person subject's is requested.

- * - * @param attributeMap Attribute set for eIDAS response - * @param eidasReq Incoming eIDAS request - * @param authData Authentication data - */ - private void injectJurPersonWorkaroundIfRequired( - ImmutableAttributeMap.Builder attributeMap, ILightRequest eidasReq, IAuthData authData) { - if (isLegalPersonWorkaroundActive() && isLegalPersonMandateAvailable(authData) - && EidasProxyServiceUtils.isNaturalPersonRequested(eidasReq) - && EidasProxyServiceUtils.isLegalPersonRequested(eidasReq)) { - log.debug("Injecting representative information as nat. person subject to bypass eIDAS Node validation"); - attributeMap.putAll(buildAttributesWithoutMandate(authData)); - - } + private void injectRequestedAttributes(ImmutableAttributeMap.Builder attributeMap, ILightRequest eidasReq, + IEidAuthData eidAuthData) { + eidasReq.getRequestedAttributes().getAttributeMap().keySet().stream() + .forEach(el -> injectEidasAttribute(attributeMap, eidAuthData, + el.getNameUri().toString(), eidAuthData.isUseMandate())); + } - - private ImmutableAttributeMap buildAttributesWithoutMandate(IAuthData eidAuthData) { - //TODO: throw an error in case of SZR Date with month or day = "00" - return buildAttributesWithoutMandate( - eidAuthData.getGenericData(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, String.class), - eidAuthData.getFamilyName(), - eidAuthData.getGivenName(), - eidAuthData.getDateOfBirth()); - + + private void injectMdsRepesentativeInformation( + ImmutableAttributeMap.Builder attributeMap, IEidAuthData eidAuthData, + ImmutableAttributeMap requestedAttributes) { + attrRegistry.getRepresentativeAttributesToAddByDefault() + .filter(el -> requestedAttributes.getAttributeValuesByNameUri(el) == null) + .forEach(el -> injectEidasAttribute(attributeMap, eidAuthData, el, true)); + } - private ImmutableAttributeMap buildAttributesWithoutMandate(String personalIdentifier, String familyName, - String givenName, String dateOfBirth) { - final AttributeDefinition attrDefPersonalId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first(); - final AttributeDefinition attrDefFamilyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first(); - final AttributeDefinition attrDefGivenName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first(); - final AttributeDefinition attrDefDateOfBirth = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first(); - - final ImmutableAttributeMap.Builder attributeMap = - ImmutableAttributeMap.builder() - .put(attrDefPersonalId, personalIdentifier) - .put(attrDefFamilyName, familyName) - .put(attrDefGivenName, givenName) - .put(attrDefDateOfBirth, dateOfBirth); - - return attributeMap.build(); - + private void injectEidasAttribute(ImmutableAttributeMap.Builder attributeMap, IEidAuthData eidAuthData, + String eidasAttrName, boolean mandatesUsed) { + final Optional releatedIdaAttribute = + attrRegistry.mapEidasAttributeToSpecificIdaAttribute(eidasAttrName, mandatesUsed); + if (releatedIdaAttribute.isPresent()) { + log.trace("Mapping IDA attribute: {} to eIDAS attribute: {}", releatedIdaAttribute.get(), + eidasAttrName); + final String idaAttrValue = eidAuthData.getGenericData(releatedIdaAttribute.get(), String.class); + if (StringUtils.isNotEmpty(idaAttrValue)) { + log.debug("Build eIDAS attribute: {} from IDA attribute: {}", eidasAttrName, releatedIdaAttribute + .get()); + attributeMap.put( + attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getByName(eidasAttrName), + idaAttrValue); + + } else { + log.info("No IDA attribute: {}, eIDAS attribute: {} will be ignored", releatedIdaAttribute.get(), + eidasAttrName); + + } + + } else { + log.warn("Can not build eIDAS attribute: {}, because there is not corresponding IDA attribute defined", + eidasAttrName); + + } } - + private BinaryLightToken putResponseInCommunicationCache(ILightResponse lightResponse) throws ServletException { final BinaryLightToken binaryLightToken; @@ -358,17 +291,61 @@ public class ProxyServiceAuthenticationAction implements IAction { return binaryLightToken; } + /** + * Work-around to inject representative information as nat. person subject to + * bypass eIDAS Node validation. + * + *

+ * Injection will only be done if this work-around is enabled by + * configuration, the mandator is a legal person, and both legal and natural + * person subject's is requested. + *

+ * + * @param attributeMap Attribute set for eIDAS response + * @param eidasReq Incoming eIDAS request + * @param authData Authentication data + */ + private void injectJurPersonWorkaroundIfRequired( + ImmutableAttributeMap.Builder attributeMap, ILightRequest eidasReq, IAuthData authData) { + if (isLegalPersonWorkaroundActive() && isLegalPersonMandateAvailable(authData) + && EidasProxyServiceUtils.isNaturalPersonRequested(eidasReq) + && EidasProxyServiceUtils.isLegalPersonRequested(eidasReq)) { + log.debug( + "Injecting representative information as nat. person subject to bypass eIDAS Node validation"); + + final AttributeDefinition attrDefPersonalId = + attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first(); + final AttributeDefinition attrDefFamilyName = + attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first(); + final AttributeDefinition attrDefGivenName = + attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first(); + final AttributeDefinition attrDefDateOfBirth = + attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first(); + + attributeMap.put(attrDefPersonalId, authData.getGenericData(PvpAttributeDefinitions.BPK_NAME, + String.class)); + attributeMap.put(attrDefFamilyName, authData.getFamilyName()); + attributeMap.put(attrDefGivenName, authData.getGivenName()); + attributeMap.put(attrDefDateOfBirth, authData.getDateOfBirth()); + + } + } + private boolean isLegalPersonWorkaroundActive() { return basicConfig.getBasicConfigurationBoolean( - MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_WORKAROUND_MANDATES_LEGAL_PERSON, + MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_WORKAROUND_MANDATES_LEGAL_PERSON, false); - + } - + private boolean isLegalPersonMandateAvailable(IAuthData authData) { return StringUtils.isNoneEmpty(authData.getGenericData( - MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, String.class)); - + PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, String.class)); + } } diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java index b9e0c488..a6a50100 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java @@ -7,6 +7,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -76,6 +77,19 @@ public class ProxyEidasAttributeRegistry { } + /** + * Get all eIDAS attributes that are added by default in case of mandates. + * + * @return {@link Stream} of eIDAS attributes + */ + @NonNull + public Stream getRepresentativeAttributesToAddByDefault() { + return attributeConfiguration.stream() + .filter(el -> el.getType() != null && el.getType().getAutoIncludeWithMandates()) + .map(el -> el.getEidasAttributeName()); + + } + /** * Get IDA attributes for a specific eIDAS attribute. * @@ -95,8 +109,24 @@ public class ProxyEidasAttributeRegistry { .collect(Collectors.toSet()); } - - + + /** + * Get eIDAS related IDA attribute. + * + * @param eidasAttributeName Name of the eIDAS attribute. + * @param withMandates true if mandates are supported, otherwise false + * @return Name of the related IDA attribute if available + */ + public Optional mapEidasAttributeToSpecificIdaAttribute( + String eidasAttributeName, boolean withMandates) { + return attributeConfiguration.stream() + .filter(el -> el.getEidasAttributeName().equals(eidasAttributeName)) + .findFirst() + .map(el -> withMandates ? el.getIdaAttribute().getWithMandates() : el.getIdaAttribute().getBasic()) + .filter(el -> StringUtils.isNotEmpty(el)); + + } + @PostConstruct private void initialize() throws EaafConfigurationException { final String attrConfPath = basicConfig.getBasicConfiguration( diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java index c41d6c99..d44ffc2d 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java @@ -12,7 +12,6 @@ import java.net.URISyntaxException; import java.net.URLDecoder; import java.time.Instant; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -35,7 +34,6 @@ import org.springframework.web.context.request.ServletRequestAttributes; import com.google.common.collect.ImmutableSortedSet; -import at.asitplus.eidas.specific.core.MsEidasNodeConstants; import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap; import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummySpConfiguration; import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants; @@ -132,7 +130,7 @@ public class ProxyServiceAuthenticationActionTest { @Test public void missingForwardUrl() { Map attr = new HashMap<>(); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + attr.put(PvpAttributeDefinitions.BPK_NAME, "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false); @@ -147,8 +145,7 @@ public class ProxyServiceAuthenticationActionTest { @Test public void responseWithoutMandate() throws EaafException, SpecificCommunicationException { Map attr = new HashMap<>(); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, - "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + attr.put(PvpAttributeDefinitions.BPK_NAME, RandomStringUtils.randomAlphanumeric(10)); IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false); @@ -161,7 +158,7 @@ public class ProxyServiceAuthenticationActionTest { ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); assertEquals("wrong attr. size", 4, respAttr.size()); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, - (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); + (String) attr.get(PvpAttributeDefinitions.BPK_NAME)); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName()); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName()); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, @@ -170,12 +167,89 @@ public class ProxyServiceAuthenticationActionTest { } @Test - public void responseWithNatMandate() throws EaafException, SpecificCommunicationException { + public void responseWithoutMandateAndOptionalAttributesExist() throws EaafException, SpecificCommunicationException { + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByName("http://eidas.europa.eu/attributes/naturalperson/BirthName")) + .build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + Map attr = new HashMap<>(); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, - "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + attr.put(PvpAttributeDefinitions.BPK_NAME, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + attr.put("ida_birthname", RandomStringUtils.randomAlphanumeric(10)); + + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false); + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 5, respAttr.size()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, + (String) attr.get(PvpAttributeDefinitions.BPK_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, + authData.getDateOfBirth()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_BIRTHNAME, + (String) attr.get("ida_birthname")); + + } + + @Test + public void responseWithoutMandateAndOptionalAttributesNotExist() throws EaafException, SpecificCommunicationException { + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByName("http://eidas.europa.eu/attributes/naturalperson/BirthName")) + .build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + + Map attr = new HashMap<>(); + attr.put(PvpAttributeDefinitions.BPK_NAME, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false); + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER, + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 4, respAttr.size()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, + (String) attr.get(PvpAttributeDefinitions.BPK_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, + authData.getDateOfBirth()); + + } + + + @Test + public void responseWithNatMandate() throws EaafException, SpecificCommunicationException { + Map attr = new HashMap<>(); + attr.put(PvpAttributeDefinitions.BPK_NAME, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, RandomStringUtils.randomAlphabetic(10)); attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, RandomStringUtils.randomAlphabetic(10)); @@ -197,13 +271,13 @@ public class ProxyServiceAuthenticationActionTest { ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); assertEquals("wrong attr. size", 8, respAttr.size()); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, - (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); + (String) attr.get(PvpAttributeDefinitions.BPK_NAME)); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName()); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName()); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, - (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER)); + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME)); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME)); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, @@ -213,19 +287,86 @@ public class ProxyServiceAuthenticationActionTest { } + @Test + public void responseWithNatMandateOptionalAttribute() throws EaafException, SpecificCommunicationException { + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByName("http://eidas.europa.eu/attributes/naturalperson/BirthName")) + .build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + Map attr = new HashMap<>(); + attr.put(PvpAttributeDefinitions.BPK_NAME, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + attr.put("ida_birthName_mandator", RandomStringUtils.randomAlphanumeric(10)); + attr.put("ida_birthName", RandomStringUtils.randomAlphanumeric(10)); + + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, + "1985-11-15"); + + + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 9, respAttr.size()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, + (String) attr.get(PvpAttributeDefinitions.BPK_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); + + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME)); + + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_BIRTHNAME, + (String) attr.get("ida_birthName_mandator")); + + } + @Test public void responseWithJurMandate() throws EaafException, SpecificCommunicationException { Map attr = new HashMap<>(); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + attr.put(PvpAttributeDefinitions.BPK_NAME, "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, RandomStringUtils.randomAlphabetic(10)); attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, RandomStringUtils.randomAlphabetic(10)); + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first()) + .build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + //perform test SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); @@ -235,13 +376,13 @@ public class ProxyServiceAuthenticationActionTest { ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); assertEquals("wrong attr. size", 6, respAttr.size()); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, - (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); + (String) attr.get(PvpAttributeDefinitions.BPK_NAME)); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName()); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName()); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER, - (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER)); + (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME)); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALNAME, (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME)); @@ -260,19 +401,12 @@ public class ProxyServiceAuthenticationActionTest { public void responseWithNatMandateWithWorkAround() throws EaafException, SpecificCommunicationException { basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson", "true"); - - //request natural person subject only - LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); - eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder().put( - attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build()); - pendingReq.setEidasRequest(eidasRequestBuilder.build()); - - + Map attr = new HashMap<>(); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + attr.put(PvpAttributeDefinitions.BPK_NAME, "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER, + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, RandomStringUtils.randomAlphabetic(10)); attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, RandomStringUtils.randomAlphabetic(10)); @@ -306,16 +440,17 @@ public class ProxyServiceAuthenticationActionTest { eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first()) .build()); pendingReq.setEidasRequest(eidasRequestBuilder.build()); Map attr = new HashMap<>(); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + attr.put(PvpAttributeDefinitions.BPK_NAME, "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, RandomStringUtils.randomAlphabetic(10)); attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, RandomStringUtils.randomAlphabetic(10)); @@ -329,7 +464,7 @@ public class ProxyServiceAuthenticationActionTest { ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); assertEquals("wrong attr. size", 10, respAttr.size()); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, - (String) attr.get(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER)); + (String) attr.get(PvpAttributeDefinitions.BPK_NAME)); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName()); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName()); checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, authData.getDateOfBirth()); @@ -344,18 +479,18 @@ public class ProxyServiceAuthenticationActionTest { //request natural person subject only LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() - .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( - EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first()) .build()); pendingReq.setEidasRequest(eidasRequestBuilder.build()); Map attr = new HashMap<>(); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, + attr.put(PvpAttributeDefinitions.BPK_NAME, "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); - attr.put(MsEidasNodeConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, RandomStringUtils.randomAlphabetic(10)); attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, RandomStringUtils.randomAlphabetic(10)); @@ -390,7 +525,7 @@ public class ProxyServiceAuthenticationActionTest { } private IAuthData generateDummyAuthData() { - return generateDummyAuthData(Collections.emptyMap(), EaafConstants.EIDAS_LOA_LOW, + return generateDummyAuthData(new HashMap<>(), EaafConstants.EIDAS_LOA_LOW, RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1940-01-01", false); } @@ -445,12 +580,22 @@ public class ProxyServiceAuthenticationActionTest { .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) .spType("public") .requesterId(RandomStringUtils.randomAlphanumeric(10)) - .providerName(RandomStringUtils.randomAlphanumeric(10)); - + .providerName(RandomStringUtils.randomAlphanumeric(10)) + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first()) + .build() + ); } private IAuthData generateDummyAuthData(Map attrs, String loa, String familyName, String givenName, String dateOfBirth, boolean useMandates) { + attrs.put(PvpAttributeDefinitions.BIRTHDATE_NAME, dateOfBirth); + attrs.put(PvpAttributeDefinitions.GIVEN_NAME_NAME, givenName); + attrs.put(PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, familyName); + return new IEidAuthData() { @Override diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java index d3e787bb..8d417c1a 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java @@ -1,11 +1,13 @@ package at.asitplus.eidas.specific.modules.msproxyservice.test.services; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.Set; import org.apache.commons.lang3.RandomStringUtils; @@ -92,6 +94,39 @@ public class ProxyEidasAttributeRegistryTest { } + @Test + public void attributeResponseMapping() { + assertFalse("find wrong IDA mapping", attrRegistry.mapEidasAttributeToSpecificIdaAttribute( + "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", false).isPresent()); + assertFalse("find wrong IDA mapping", attrRegistry.mapEidasAttributeToSpecificIdaAttribute( + "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", true).isPresent()); + + + Optional attr1 = attrRegistry.mapEidasAttributeToSpecificIdaAttribute( + "http://eidas.europa.eu/attributes/naturalperson/BirthName", false); + assertTrue("find wrong IDA mapping", attr1.isPresent()); + assertEquals("find wrong IDA mapping value", "ida_birthname", attr1.get()); + + Optional attr2 = attrRegistry.mapEidasAttributeToSpecificIdaAttribute( + "http://eidas.europa.eu/attributes/naturalperson/BirthName", true); + assertTrue("find wrong IDA mapping", attr2.isPresent()); + assertEquals("find wrong IDA mapping value", "ida_birthName_mandator", attr2.get()); + + + assertTrue("find wrong IDA mapping", attrRegistry.mapEidasAttributeToSpecificIdaAttribute( + "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", false).isPresent()); + assertTrue("find wrong IDA mapping", attrRegistry.mapEidasAttributeToSpecificIdaAttribute( + "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", true).isPresent()); + + } + + @Test + public void defaultRepresentativeAttributes() { + assertEquals("wrong number of rep. attributes", 4, + attrRegistry.getRepresentativeAttributesToAddByDefault().count()); + + } + private void checkAttributeMapping(String eidasAttr, boolean withMandates, List idaAttributes) { @NonNull Set idaAttrResult = attrRegistry.getIdaAttributesForEidasAttribute(eidasAttr, withMandates); diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json b/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json index 2d375acb..7e41d8f6 100644 --- a/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json +++ b/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json @@ -6,7 +6,8 @@ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.98" }, "type": { - "mds": true + "mds": true, + "autoIncludeWithMandates": false } }, { @@ -16,7 +17,8 @@ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.78" }, "type": { - "mds": true + "mds": true, + "autoIncludeWithMandates": false } }, { @@ -26,7 +28,8 @@ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.80" }, "type": { - "mds": true + "mds": true, + "autoIncludeWithMandates": false } }, { @@ -36,21 +39,27 @@ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.82" }, "type": { - "mds": true + "mds": true, + "autoIncludeWithMandates": false } }, { "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", "idaAttribute": {}, "type": { - "mds": false + "mds": false, + "autoIncludeWithMandates": false } }, { "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/BirthName", - "idaAttribute": {}, + "idaAttribute": { + "basic": "ida_birthname", + "withMandates": "ida_birthName_mandator" + }, "type": { - "mds": false + "mds": false, + "autoIncludeWithMandates": false } }, { @@ -65,7 +74,8 @@ "urn:oid:1.2.40.0.10.2.1.1.55" ], "type": { - "mds": true + "mds": true, + "autoIncludeWithMandates": false } }, { @@ -74,7 +84,8 @@ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.84" }, "type": { - "mds": true + "mds": true, + "autoIncludeWithMandates": false } }, { @@ -83,7 +94,8 @@ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.149" }, "type": { - "mds": true + "mds": true, + "autoIncludeWithMandates": true } }, { @@ -92,7 +104,8 @@ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.20" }, "type": { - "mds": true + "mds": true, + "autoIncludeWithMandates": true } }, { @@ -101,7 +114,8 @@ "withMandates": "urn:oid:2.5.4.42" }, "type": { - "mds": true + "mds": true, + "autoIncludeWithMandates": true } }, { @@ -110,7 +124,8 @@ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.55" }, "type": { - "mds": true + "mds": true, + "autoIncludeWithMandates": true } }, { @@ -120,7 +135,8 @@ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.32" }, "type": { - "mds": false + "mds": false, + "autoIncludeWithMandates": false } }, { @@ -130,7 +146,8 @@ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.108" }, "type": { - "mds": false + "mds": false, + "autoIncludeWithMandates": false } }, { @@ -139,7 +156,8 @@ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.68" }, "type": { - "mds": false + "mds": false, + "autoIncludeWithMandates": false } }, { @@ -148,7 +166,8 @@ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.106" }, "type": { - "mds": false + "mds": false, + "autoIncludeWithMandates": false } }, { @@ -157,7 +176,8 @@ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.106" }, "type": { - "mds": false + "mds": false, + "autoIncludeWithMandates": false } } ] \ No newline at end of file -- cgit v1.2.3 From cab2ab4ddb85b305d77798073b868cf42a7e0111 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Wed, 8 Jun 2022 14:56:42 +0200 Subject: chore(core): minory style, test and validation fixes --- .../specific/modules/msproxyservice/dto/attributes/Type.java | 11 ++++++++--- .../test/protocol/EidasProxyServiceControllerTest.java | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java index f66bb799..6a06a5b5 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java @@ -22,8 +22,7 @@ import lombok.Data; public class Type { /** - * true if this attribute is part of MDS, otherwise - * false + * true if this attribute is part of MDS, otherwise false. */ @JsonProperty("mds") private Boolean mds; @@ -50,7 +49,7 @@ public class Type { NONE("none"); private final String value; - private final static Map CONSTANTS = new HashMap<>(); + private static final Map CONSTANTS = new HashMap<>(); static { for (final Type.Mandator c : values()) { @@ -72,6 +71,12 @@ public class Type { return this.value; } + /** + * Build {@link Mandator} from textual representation. + * + * @param value textual representation + * @return Type of the mandator + */ @JsonCreator public static Type.Mandator fromValue(String value) { final Type.Mandator constant = CONSTANTS.get(value); diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java index ef1abbcd..b491c2bf 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java @@ -329,7 +329,7 @@ public class EidasProxyServiceControllerTest { assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode()); - assertEquals("requested IDA attributes", 3, spConfig.getRequestedAttributes().size()); + assertEquals("requested IDA attributes", 4, spConfig.getRequestedAttributes().size()); } -- cgit v1.2.3 From 669e1d6571b4bddcf5955597bcfe90e1523a6714 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Fri, 5 Aug 2022 13:10:37 +0200 Subject: feat(proxy-service): add work-around to support mandates for legal- and natural-persons in parallel --- .../protocol/EidasProxyServiceController.java | 15 ++++- .../protocol/EidasProxyServiceControllerTest.java | 69 +++++++++++++++++++++- 2 files changed, 81 insertions(+), 3 deletions(-) (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java index 26cc51ee..9a0331bd 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java @@ -14,6 +14,7 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.collections4.ListUtils; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang3.StringUtils; import org.opensaml.saml.saml2.core.NameIDType; @@ -429,8 +430,18 @@ public class EidasProxyServiceController extends AbstractController implements I log.trace("eIDAS Proxy-Service allows mandates for Connector: {}. Selecting profiles ... ", spConfig.getUniqueIdentifier()); - //check if legal person is requested - if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)) { + if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest) + && EidasProxyServiceUtils.isNaturalPersonRequested(eidasRequest)) { + log.debug("Find requested attributes for legal and natural persons. Injecting mandate-profiles for both ... "); + spConfig.setMandateProfiles(ListUtils.union( + KeyValueUtils.getListOfCsvValues( + spConfig.getConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL)), + KeyValueUtils.getListOfCsvValues( + spConfig.getConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL)))); + spConfig.setMandateMode(SpMandateModes.BOTH); + + } else if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)) { + //check if legal person is requested spConfig.setMandateProfiles(KeyValueUtils.getListOfCsvValues( spConfig.getConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL))); spConfig.setMandateMode(SpMandateModes.LEGAL_FORCE); diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java index b491c2bf..830360e0 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java @@ -333,7 +333,7 @@ public class EidasProxyServiceControllerTest { } - + @Test public void validAuthnRequestWithMandatesDefaultProfilesNat() throws IOException, EaafException { //initialize state @@ -664,6 +664,73 @@ public class EidasProxyServiceControllerTest { } + @Test + public void validAuthnRequestWithMandatesProfilesBoth() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + String issuer = RandomStringUtils.randomAlphabetic(10); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(issuer) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .build()); + + + // set default mandate configuration + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, + StringUtils.join(Arrays.asList( + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ",")); + + + // add custom SP config to allow both MDS in single request + addConnectorConfig(25, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer); + addConnectorConfig(25, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode); + addConnectorConfig(25, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "true"); + + List mandateProfilesNat = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + List mandateProfilesJur = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + addConnectorConfig(25, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL, + StringUtils.join(mandateProfilesJur, ",")); + addConnectorConfig(25, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL, + StringUtils.join(mandateProfilesNat, ",")); + addConnectorConfig(25, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_VALIDATION_ATTR_MDS, "false"); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("mandateprofile size", mandateProfilesNat.size() + mandateProfilesJur.size(), spConfig.getMandateProfiles().size()); + spConfig.getMandateProfiles().stream() + .forEach(el -> assertTrue("missing mandateProfile: " + el, + mandateProfilesNat.contains(el) || mandateProfilesJur.contains(el))); + assertEquals("MandateMode", SpMandateModes.BOTH, spConfig.getMandateMode()); + + assertEquals("requested IDA attributes", 10, spConfig.getRequestedAttributes().size()); + + } + private void addConnectorConfig(int i, String key, String value) { config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_PREFIX + String.valueOf(i) + "." + key, value); -- cgit v1.2.3 From b54e3424a7ac9a661aae771f13cdc94086b04132 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Mon, 8 Aug 2022 15:00:16 +0200 Subject: feat(proxy): optimize mandate support by selection mandate-mode based on requested attributes and profiles from configuration Now it's possible to deactivte legal- or natural-person mandates by mandate-profile configuration on eIDAS-Connector level --- .../protocol/EidasProxyServiceController.java | 231 +++++++++++---------- .../protocol/ProxyServiceAuthenticationAction.java | 2 + 2 files changed, 124 insertions(+), 109 deletions(-) (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java index 9a0331bd..32be0e22 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java @@ -5,6 +5,7 @@ import java.text.MessageFormat; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.UUID; @@ -77,11 +78,13 @@ public class EidasProxyServiceController extends AbstractController implements I private static final String ERROR_09 = "eidas.proxyservice.09"; private static final String ERROR_10 = "eidas.proxyservice.10"; private static final String ERROR_11 = "eidas.proxyservice.11"; - + public static final String PROTOCOL_ID = "eidasProxy"; - @Autowired ProxyEidasAttributeRegistry attrRegistry; - @Autowired ProxyServiceAuthenticationAction responseAction; + @Autowired + ProxyEidasAttributeRegistry attrRegistry; + @Autowired + ProxyServiceAuthenticationAction responseAction; /** * End-point that receives authentication requests from eIDAS Node. @@ -92,8 +95,8 @@ public class EidasProxyServiceController extends AbstractController implements I * @throws EaafException In case of a validation or processing error */ @RequestMapping(value = { - MsProxyServiceConstants.EIDAS_HTTP_ENDPOINT_IDP_POST, - MsProxyServiceConstants.EIDAS_HTTP_ENDPOINT_IDP_REDIRECT + MsProxyServiceConstants.EIDAS_HTTP_ENDPOINT_IDP_POST, + MsProxyServiceConstants.EIDAS_HTTP_ENDPOINT_IDP_REDIRECT }, method = { RequestMethod.POST, RequestMethod.GET }) public void receiveEidasAuthnRequest(HttpServletRequest httpReq, HttpServletResponse httpResp) @@ -119,17 +122,18 @@ public class EidasProxyServiceController extends AbstractController implements I .toString()); final ILightRequest eidasRequest = specificProxyCommunicationService.getAndRemoveRequest( tokenBase64, - ImmutableSortedSet.copyOf(attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getAttributes())); + ImmutableSortedSet.copyOf(attrRegistry.getCoreRegistry().getCoreAttributeRegistry() + .getAttributes())); if (eidasRequest == null) { log.info("Find no eIDAS Authn. Request with stated token."); throw new EidasProxyServiceException(ERROR_11, null); - - } - + + } + log.debug("Received eIDAS auth. request from: {}, Initializing authentication environment ... ", eidasRequest.getSpCountryCode() != null ? eidasRequest.getSpCountryCode() : "'missing SP-country'"); log.trace("Received eIDAS requst: {}", eidasRequest); - + // create pendingRequest object pendingReq = applicationContext.getBean(ProxyServicePendingRequest.class); pendingReq.initialize(httpReq, authConfig); @@ -141,7 +145,7 @@ public class EidasProxyServiceController extends AbstractController implements I revisionsLogger.logEvent(pendingReq.getUniqueSessionIdentifier(), pendingReq.getUniqueTransactionIdentifier(), EventConstants.TRANSACTION_IP, httpReq.getRemoteAddr()); - + // validate eIDAS Authn. request and set into pending-request validateEidasAuthnRequest(eidasRequest); pendingReq.setEidasRequest(eidasRequest); @@ -149,9 +153,9 @@ public class EidasProxyServiceController extends AbstractController implements I // generate Service-Provider configuration from eIDAS request final ISpConfiguration spConfig = generateSpConfigurationFromEidasRequest(eidasRequest); - // validate eIDAS Authn. request by using eIDAS Connector specifc parameters + // validate eIDAS Authn. request by using eIDAS Connector specifc parameters validateEidasAuthnRequest(spConfig, eidasRequest); - + // populate pendingRequest with parameters pendingReq.setOnlineApplicationConfiguration(spConfig); pendingReq.setSpEntityId(spConfig.getUniqueIdentifier()); @@ -190,16 +194,16 @@ public class EidasProxyServiceController extends AbstractController implements I public boolean generateErrorMessage(Throwable e, HttpServletRequest httpReq, HttpServletResponse httpResp, IRequest pendingReq) throws Throwable { if (pendingReq instanceof ProxyServicePendingRequest) { - try { - ILightRequest eidasReq = ((ProxyServicePendingRequest) pendingReq).getEidasRequest(); - - //build eIDAS response - Builder lightRespBuilder = LightResponse.builder(); + try { + final ILightRequest eidasReq = ((ProxyServicePendingRequest) pendingReq).getEidasRequest(); + + // build eIDAS response + final Builder lightRespBuilder = LightResponse.builder(); lightRespBuilder.id(UUID.randomUUID().toString()); lightRespBuilder.inResponseToId(eidasReq.getId()); lightRespBuilder.relayState(eidasReq.getRelayState()); lightRespBuilder.issuer(authConfig.getBasicConfiguration( - MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID)); + MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID)); lightRespBuilder.subject(UUID.randomUUID().toString()); lightRespBuilder.subjectNameIdFormat(NameIDType.TRANSIENT); lightRespBuilder.status(ResponseStatus.builder() @@ -223,7 +227,7 @@ public class EidasProxyServiceController extends AbstractController implements I ProxyServicePendingRequest.class.getName()); } - + return false; } @@ -253,11 +257,11 @@ public class EidasProxyServiceController extends AbstractController implements I * @throws EidasProxyServiceException In case of a validation error */ private void validateEidasAuthnRequest(ILightRequest eidasRequest) throws EidasProxyServiceException { - if (StringUtils.isEmpty(eidasRequest.getIssuer())) { + if (StringUtils.isEmpty(eidasRequest.getIssuer())) { throw new EidasProxyServiceException(ERROR_05, null); } - + // TODO: validate some other stuff } @@ -266,23 +270,23 @@ public class EidasProxyServiceController extends AbstractController implements I * eIDAS Connector specific validation of incoming eIDAS request. * * @param eidasRequest Incoming eIDAS authentication request - * @param spConfig eIDAS Connector configuration + * @param spConfig eIDAS Connector configuration * @throws EidasProxyServiceException In case of a validation error */ - private void validateEidasAuthnRequest(ISpConfiguration spConfig, ILightRequest eidasRequest) - throws EidasProxyServiceException { + private void validateEidasAuthnRequest(ISpConfiguration spConfig, ILightRequest eidasRequest) + throws EidasProxyServiceException { // check if natural-person and legal-person attributes requested in parallel - if (spConfig.isConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_VALIDATION_ATTR_MDS, true) - && EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest) + if (spConfig.isConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_VALIDATION_ATTR_MDS, true) + && EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest) && EidasProxyServiceUtils.isNaturalPersonRequested(eidasRequest)) { throw new EidasProxyServiceException(ERROR_08, null); - + } - + // TODO: validate some other stuff } - + /** * Generate a dummy Service-Provider configuration for processing. * @@ -293,55 +297,57 @@ public class EidasProxyServiceController extends AbstractController implements I private ISpConfiguration generateSpConfigurationFromEidasRequest(ILightRequest eidasRequest) throws EidasProxyServiceException { try { - - Map connectorConfigMap = extractRawConnectorConfiguration(eidasRequest); - + + final Map connectorConfigMap = extractRawConnectorConfiguration(eidasRequest); + // check if country-code is available - String spCountry = connectorConfigMap.get(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE); - if (StringUtils.isEmpty(spCountry)) { + final String spCountry = connectorConfigMap.get( + MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE); + if (StringUtils.isEmpty(spCountry)) { throw new EidasProxyServiceException(ERROR_07, null); } - - // build FriendyName from CountryCode and SPType + + // build FriendyName from CountryCode and SPType connectorConfigMap.put(MsEidasNodeConstants.PROP_CONFIG_SP_FRIENDLYNAME, MessageFormat.format(MsProxyServiceConstants.TEMPLATE_SP_UNIQUE_ID, spCountry, eidasRequest.getSpType())); - // build Service-Provider configuration object - final ServiceProviderConfiguration spConfig = new ServiceProviderConfiguration(connectorConfigMap, authConfig); + // build Service-Provider configuration object + final ServiceProviderConfiguration spConfig = new ServiceProviderConfiguration(connectorConfigMap, + authConfig); - // build bPK target from Country-Code - final String ccCountry = authConfig.getBasicConfiguration(EidasConstants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, + // build bPK target from Country-Code + final String ccCountry = authConfig.getBasicConfiguration( + EidasConstants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, EidasConstants.DEFAULT_MS_NODE_COUNTRY_CODE); spConfig.setBpkTargetIdentifier( EaafConstants.URN_PREFIX_EIDAS + ccCountry + "+" + spCountry); - + // set required LoA from eIDAS request spConfig.setRequiredLoA( eidasRequest.getLevelsOfAssurance().stream().map(el -> el.getValue()).collect(Collectors.toList())); // build mandate profiles for this specific request buildMandateProfileConfiguration(spConfig, eidasRequest); - + // map eIDAS attributes to national attributes buildNationalRequestedAttributes(spConfig, eidasRequest); - + return spConfig; - } catch (EidasProxyServiceException e) { + } catch (final EidasProxyServiceException e) { throw e; - + } catch (final EaafException e) { throw new EidasProxyServiceException(ERROR_04, new Object[] { e.getMessage() }, e); } } - private void buildNationalRequestedAttributes( - ServiceProviderConfiguration spConfig, ILightRequest eidasRequest) { - boolean mandatesEnabled = !SpMandateModes.NONE.equals(spConfig.getMandateMode()); + ServiceProviderConfiguration spConfig, ILightRequest eidasRequest) { + final boolean mandatesEnabled = !SpMandateModes.NONE.equals(spConfig.getMandateMode()); spConfig.setRequestedAttributes( Streams.concat( eidasRequest.getRequestedAttributes().getAttributeMap().keySet().stream() @@ -350,126 +356,133 @@ public class EidasProxyServiceController extends AbstractController implements I .flatMap(Collection::stream) .filter(Objects::nonNull), attrRegistry.getAlwaysRequestedAttributes(mandatesEnabled)) - .collect(Collectors.toSet())); + .collect(Collectors.toSet())); log.debug("Inject #{} attributes to request from IDA system", spConfig.getRequestedAttributes().size()); - + } - private Map extractRawConnectorConfiguration(ILightRequest eidasRequest) { - Map allConnectorConfigs = authConfig.getBasicConfigurationWithPrefix( + private Map extractRawConnectorConfiguration(ILightRequest eidasRequest) { + final Map allConnectorConfigs = authConfig.getBasicConfigurationWithPrefix( MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_PREFIX); if (log.isTraceEnabled()) { log.trace("Full-connector configuration:"); allConnectorConfigs.entrySet().stream().forEach( el -> log.trace("Key: {} -> Value: {}", el.getKey(), el.getValue())); - + } - - Map connectorConfig = allConnectorConfigs.entrySet().stream() - .filter(el -> el.getKey().endsWith(MsEidasNodeConstants.PROP_CONFIG_SP_UNIQUEIDENTIFIER) + + final Map connectorConfig = allConnectorConfigs.entrySet().stream() + .filter(el -> el.getKey().endsWith(MsEidasNodeConstants.PROP_CONFIG_SP_UNIQUEIDENTIFIER) && el.getValue().equals(eidasRequest.getIssuer())) .findFirst() - .map(el -> KeyValueUtils.getSubSetWithPrefix(allConnectorConfigs, + .map(el -> KeyValueUtils.getSubSetWithPrefix(allConnectorConfigs, KeyValueUtils.getParentKey(el.getKey()) + KeyValueUtils.KEY_DELIMITER)) .orElse(new HashMap<>()); - if (connectorConfig.isEmpty()) { - log.debug("No specific configuration for eIDAS Connector: {} Using default configuration ... ", + log.debug("No specific configuration for eIDAS Connector: {} Using default configuration ... ", eidasRequest.getIssuer()); - + // set EntityId of the requesting eIDAS Connector connectorConfig.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, eidasRequest.getIssuer()); - + // set country-code from eIDAS request - connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, + connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, eidasRequest.getSpCountryCode()); - + // set default mandate configuration - connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, + connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, String.valueOf(authConfig.getBasicConfigurationBoolean( - MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, false))); - connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL, + MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, false))); + connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL, authConfig.getBasicConfiguration( MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL)); - connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL, + connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL, authConfig.getBasicConfiguration( MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL)); - + } else { log.debug("Find specific configuration for eIDAS Connector: {}", eidasRequest.getIssuer()); - + } - + return connectorConfig; - + } - - - private void buildMandateProfileConfiguration(ServiceProviderConfiguration spConfig, ILightRequest eidasRequest) + + private void buildMandateProfileConfiguration(ServiceProviderConfiguration spConfig, + ILightRequest eidasRequest) throws EidasProxyServiceException { // check if mandates are enabled - if (spConfig.isConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, false)) { + if (spConfig.isConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, + false)) { injectMandateInfosIntoSpConfig(spConfig, eidasRequest); - - } else { + + } else { if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)) { throw new EidasProxyServiceException(ERROR_09, null); - - } - + + } + spConfig.setMandateProfiles(Collections.emptyList()); - spConfig.setMandateMode(SpMandateModes.NONE); - + spConfig.setMandateMode(SpMandateModes.NONE); + } } private void injectMandateInfosIntoSpConfig(ServiceProviderConfiguration spConfig, ILightRequest eidasRequest) throws EidasProxyServiceException { - log.trace("eIDAS Proxy-Service allows mandates for Connector: {}. Selecting profiles ... ", + log.trace("eIDAS Proxy-Service allows mandates for Connector: {}. Selecting profiles ... ", spConfig.getUniqueIdentifier()); - if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest) + final List legalPersonProfiles = KeyValueUtils.getListOfCsvValues(spConfig.getConfigurationValue( + MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL)); + final List natPersonProfiles = KeyValueUtils.getListOfCsvValues(spConfig.getConfigurationValue( + MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL)); + + if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest) && EidasProxyServiceUtils.isNaturalPersonRequested(eidasRequest)) { - log.debug("Find requested attributes for legal and natural persons. Injecting mandate-profiles for both ... "); - spConfig.setMandateProfiles(ListUtils.union( - KeyValueUtils.getListOfCsvValues( - spConfig.getConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL)), - KeyValueUtils.getListOfCsvValues( - spConfig.getConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL)))); - spConfig.setMandateMode(SpMandateModes.BOTH); - + log.debug( + "Find requested attributes for legal and natural persons. Injecting mandate-profiles for both ... "); + spConfig.setMandateProfiles(ListUtils.union(natPersonProfiles, legalPersonProfiles)); + + // set Mandate-Mode based on SP configuration + final boolean isLegalPersonProfile = !legalPersonProfiles.isEmpty(); + final boolean isNaturalPersonProfile = !natPersonProfiles.isEmpty(); + spConfig.setMandateMode( + isLegalPersonProfile && isNaturalPersonProfile + ? SpMandateModes.BOTH + : isLegalPersonProfile + ? SpMandateModes.LEGAL_FORCE + : SpMandateModes.NATURAL); + } else if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)) { - //check if legal person is requested - spConfig.setMandateProfiles(KeyValueUtils.getListOfCsvValues( - spConfig.getConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL))); + // check if legal person is requested + spConfig.setMandateProfiles(legalPersonProfiles); spConfig.setMandateMode(SpMandateModes.LEGAL_FORCE); - + if (spConfig.getMandateProfiles().isEmpty()) { throw new EidasProxyServiceException(ERROR_10, null); - + } - + } else if (EidasProxyServiceUtils.isNaturalPersonRequested(eidasRequest)) { - spConfig.setMandateProfiles(KeyValueUtils.getListOfCsvValues( - spConfig.getConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL))); - + spConfig.setMandateProfiles(natPersonProfiles); spConfig.setMandateMode(SpMandateModes.NATURAL); - + } - - + if (spConfig.getMandateProfiles().isEmpty()) { - log.debug("No mandate-profiles for issure: {}. Set mandate-mode to 'none'", + log.debug("No mandate-profiles for issure: {}. Set mandate-mode to 'none'", spConfig.getUniqueIdentifier()); spConfig.setMandateMode(SpMandateModes.NONE); - + } else { log.debug("Set mandate-profiles: {} to request from issuer: {}", spConfig.getMandateProfiles(), spConfig.getUniqueIdentifier()); - + } - + } } diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java index bf1c5e5f..8348558c 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java @@ -307,6 +307,8 @@ public class ProxyServiceAuthenticationAction implements IAction { */ private void injectJurPersonWorkaroundIfRequired( ImmutableAttributeMap.Builder attributeMap, ILightRequest eidasReq, IAuthData authData) { + + //TODO: maybe we have update that check, because we need an activation on Connector level if (isLegalPersonWorkaroundActive() && isLegalPersonMandateAvailable(authData) && EidasProxyServiceUtils.isNaturalPersonRequested(eidasReq) && EidasProxyServiceUtils.isLegalPersonRequested(eidasReq)) { -- cgit v1.2.3 From ca50cb8dda0a24b5a4589db126bfab8d0d885b00 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 16 Aug 2022 10:56:54 +0200 Subject: feat(proxy): add support for custom eIDAS attribute-handler into ProxyEidasAttributeRegistry This allow more sopisticated attribute-processing than simple mapping to IDA attributes --- .../dto/attributes/AttrMappingElement.java | 6 ++++++ .../service/ProxyEidasAttributeRegistry.java | 18 +++++++++++++++- .../services/ProxyEidasAttributeRegistryTest.java | 20 ++++++++++++++++++ .../resources/config/additional-attributes.xml | 19 +++++++++++++++++ .../test/resources/config/idaAttributeMapping.json | 24 ++++++++++++++++++++++ 5 files changed, 86 insertions(+), 1 deletion(-) (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java index cf106bad..2dffbc2d 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java @@ -13,6 +13,8 @@ import lombok.Data; @JsonPropertyOrder({ "eidasAttribute", "idaAttribute", + "addionalRequiredAttributes", + "specificAttributeHandlerClass", "type" }) @Data @@ -34,6 +36,10 @@ public class AttrMappingElement { @JsonProperty("addionalRequiredAttributes") private List addionalRequiredAttributes; + + @JsonProperty("specificAttributeHandlerClass") + private String specificAttributeHandlerClass; + /** * attribute characteristics. */ diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java index a6a50100..a0c99019 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java @@ -111,7 +111,7 @@ public class ProxyEidasAttributeRegistry { } /** - * Get eIDAS related IDA attribute. + * Get eIDAS related IDA attribute for a specific mode-operation. * * @param eidasAttributeName Name of the eIDAS attribute. * @param withMandates true if mandates are supported, otherwise false @@ -127,6 +127,22 @@ public class ProxyEidasAttributeRegistry { } + /** + * Get eIDAS related custom attribute-handler. + * + * @param eidasAttributeName Name of the eIDAS attribute. + * @return full classname of the handler implementation if available + */ + public Optional mapEidasAttributeToAttributeHandler(String eidasAttributeName) { + return attributeConfiguration.stream() + .filter(el -> el.getEidasAttributeName().equals(eidasAttributeName)) + .filter(el -> StringUtils.isNotEmpty(el.getSpecificAttributeHandlerClass())) + .findFirst() + .map(el -> el.getSpecificAttributeHandlerClass()); + + } + + @PostConstruct private void initialize() throws EaafConfigurationException { final String attrConfPath = basicConfig.getBasicConfiguration( diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java index 8d417c1a..fb7d257e 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java @@ -127,6 +127,26 @@ public class ProxyEidasAttributeRegistryTest { } + @Test + public void specificAttributeHandler() { + assertFalse("find wrong attribute", + attrRegistry.mapEidasAttributeToAttributeHandler( + "http://eidas.europa.eu/attributes/jUnit/no/custom/handler").isPresent()); + + assertFalse("find wrong attribute", + attrRegistry.mapEidasAttributeToAttributeHandler( + "http://eidas.europa.eu/attributes/naturalperson/representative/DateOfBirth").isPresent()); + + + Optional attr2 = attrRegistry.mapEidasAttributeToAttributeHandler( + "http://e-justice.europa.eu/attributes/naturalperson/eJusticeNaturalPersonRole"); + assertTrue("find wrong IDA mapping", attr2.isPresent()); + assertEquals("find wrong specific attribute-handler", + "at.asitplus.eidas.specific.modules.msproxyservice.handler.EJusticePersonRoleHandler", attr2.get()); + + } + + private void checkAttributeMapping(String eidasAttr, boolean withMandates, List idaAttributes) { @NonNull Set idaAttrResult = attrRegistry.getIdaAttributesForEidasAttribute(eidasAttr, withMandates); diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml b/modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml index 6510546e..e40ebdc4 100644 --- a/modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml +++ b/modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml @@ -36,4 +36,23 @@ xs eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + http://e-justice.europa.eu/attributes/naturalperson/eJusticeNaturalPersonRole + eJusticeNaturalPersonRole + NaturalPerson + false + http://www.w3.org/2001/XMLSchema + string + xs + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + http://e-justice.europa.eu/attributes/legalperson/eJusticeLegalPersonRole + eJusticeLegalPersonRole + LegalPerson + false + http://www.w3.org/2001/XMLSchema + string + xs + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json b/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json index 7e41d8f6..daaaa37d 100644 --- a/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json +++ b/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json @@ -128,6 +128,22 @@ "autoIncludeWithMandates": true } }, + { + "eidasAttribute": "http://e-justice.europa.eu/attributes/naturalperson/eJusticeNaturalPersonRole", + "specificAttributeHandlerClass": "at.asitplus.eidas.specific.modules.msproxyservice.handler.EJusticePersonRoleHandler", + "type": { + "mds": false, + "autoIncludeWithMandates": false + } + }, + { + "eidasAttribute": "http://e-justice.europa.eu/attributes/legalperson/eJusticeLegalPersonRole", + "specificAttributeHandlerClass": "at.asitplus.eidas.specific.modules.msproxyservice.handler.EJusticePersonRoleHandler", + "type": { + "mds": false, + "autoIncludeWithMandates": false + } + }, { "eidasAttribute": "*", "idaAttribute": { @@ -179,5 +195,13 @@ "mds": false, "autoIncludeWithMandates": false } + }, + { + "eidasAttribute": "http://eidas.europa.eu/attributes/jUnit/no/custom/handler", + "specificAttributeHandlerClass": "", + "type": { + "mds": false, + "autoIncludeWithMandates": false + } } ] \ No newline at end of file -- cgit v1.2.3 From 72e8da84f3ff8cd36d6f62d0d0690ad3f9a19efd Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 16 Aug 2022 11:21:04 +0200 Subject: chore(core): check if custom attribute-handler implementations are available on start-up --- .../msproxyservice/handler/EJusticePersonRoleHandler.java | 13 +++++++++++++ .../msproxyservice/handler/IEidasAttributeHandler.java | 13 +++++++++++++ .../service/ProxyEidasAttributeRegistry.java | 15 +++++++++++++++ .../main/resources/spring/eidas_proxy-service.beans.xml | 3 +++ .../test/services/ProxyEidasAttributeRegistryTest.java | 3 +++ .../src/test/resources/config/idaAttributeMapping.json | 2 +- 6 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java create mode 100644 modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java new file mode 100644 index 00000000..f42a7172 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java @@ -0,0 +1,13 @@ +package at.asitplus.eidas.specific.modules.msproxyservice.handler; + +/** + * Attribute handling to integrate BORIS attributes without full IDA support for sector-specific attributes. + * + *

This attribute-handler maps a specific mandate-profile to an eIDAS attribute.

+ * + * @author tlenz + * + */ +public class EJusticePersonRoleHandler implements IEidasAttributeHandler { + +} diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java new file mode 100644 index 00000000..153cf262 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java @@ -0,0 +1,13 @@ +package at.asitplus.eidas.specific.modules.msproxyservice.handler; + +/** + * Handlers for attribute-processing that requires more features than a simple mapping. + * + * @author tlenz + * + */ +public interface IEidasAttributeHandler { + + + +} diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java index a0c99019..747c808c 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java @@ -17,6 +17,7 @@ import javax.annotation.PostConstruct; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; @@ -27,6 +28,7 @@ import com.google.common.collect.Sets; import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry; import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; import at.asitplus.eidas.specific.modules.msproxyservice.dto.attributes.AttrMappingElement; +import at.asitplus.eidas.specific.modules.msproxyservice.handler.IEidasAttributeHandler; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; import at.gv.egiz.eaaf.core.impl.utils.FileUtils; @@ -41,6 +43,7 @@ public class ProxyEidasAttributeRegistry { private static ObjectMapper mapper = new ObjectMapper(); + @Autowired ApplicationContext context; @Autowired IConfiguration basicConfig; @Autowired ResourceLoader resourceLoader; @@ -204,6 +207,18 @@ public class ProxyEidasAttributeRegistry { if (StringUtils.isNotEmpty(el.getEidasAttributeName())) { if (ATTR_CONFIG_ALL.equals(el.getEidasAttributeName()) || coreRegistry.getCoreAttributeRegistry().getByName(el.getEidasAttributeName()) != null) { + + // check if custom attribute-handler implementation is available + if (StringUtils.isNotEmpty(el.getSpecificAttributeHandlerClass())) { + try { + context.getBean(el.getSpecificAttributeHandlerClass(), IEidasAttributeHandler.class); + + } catch (Exception e) { + log.error("No custom attribute-handler implementation for: {}", el.getSpecificAttributeHandlerClass(), e); + return false; + } + } + return true; } else { diff --git a/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml b/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml index 78b7640a..38bd44da 100644 --- a/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml +++ b/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml @@ -35,4 +35,7 @@ + + \ No newline at end of file diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java index fb7d257e..d3d1d7b0 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java @@ -137,6 +137,9 @@ public class ProxyEidasAttributeRegistryTest { attrRegistry.mapEidasAttributeToAttributeHandler( "http://eidas.europa.eu/attributes/naturalperson/representative/DateOfBirth").isPresent()); + assertFalse("find wrong attribute", + attrRegistry.mapEidasAttributeToAttributeHandler( + "http://e-justice.europa.eu/attributes/legalperson/eJusticeLegalPersonRole").isPresent()); Optional attr2 = attrRegistry.mapEidasAttributeToAttributeHandler( "http://e-justice.europa.eu/attributes/naturalperson/eJusticeNaturalPersonRole"); diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json b/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json index daaaa37d..a3ff1ead 100644 --- a/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json +++ b/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json @@ -138,7 +138,7 @@ }, { "eidasAttribute": "http://e-justice.europa.eu/attributes/legalperson/eJusticeLegalPersonRole", - "specificAttributeHandlerClass": "at.asitplus.eidas.specific.modules.msproxyservice.handler.EJusticePersonRoleHandler", + "specificAttributeHandlerClass": "at.asitplus.eidas.specific.modules.msproxyservice.handler.notExist", "type": { "mds": false, "autoIncludeWithMandates": false -- cgit v1.2.3 From 68c46a22406af910838b3ee6bbea5a4e9807ddaa Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 16 Aug 2022 13:20:02 +0200 Subject: feat(eidas): add advanced SP config post-processing based on requested attributes --- .../handler/EJusticePersonRoleHandler.java | 53 +++++++++++ .../handler/IEidasAttributeHandler.java | 9 ++ .../protocol/EidasProxyServiceController.java | 38 +++++++- .../protocol/EidasProxyServiceControllerTest.java | 106 +++++++++++++++++++++ .../services/ProxyEidasAttributeRegistryTest.java | 2 +- .../resources/config/additional-attributes.xml | 10 ++ .../test/resources/config/idaAttributeMapping.json | 10 +- .../resources/config/junit_config_1.properties | 10 +- 8 files changed, 234 insertions(+), 4 deletions(-) (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java index f42a7172..52a69944 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java @@ -1,5 +1,17 @@ package at.asitplus.eidas.specific.modules.msproxyservice.handler; +import javax.annotation.PostConstruct; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; + +import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration; +import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; +import lombok.extern.slf4j.Slf4j; + /** * Attribute handling to integrate BORIS attributes without full IDA support for sector-specific attributes. * @@ -8,6 +20,47 @@ package at.asitplus.eidas.specific.modules.msproxyservice.handler; * @author tlenz * */ +@Slf4j public class EJusticePersonRoleHandler implements IEidasAttributeHandler { + public static final String CONFIG_PROP_IDA_MANDATE_PROFILE = "advanced.atributes.ejusticerole.mandate.profiles"; + public static final String CONFIG_PROP_IDA_MANDATE_MODE = "advanced.atributes.ejusticerole.mandate.mode"; + + @Autowired IConfiguration config; + + private SpMandateModes mandateMode; + private String mandateProfiles; + + @Override + public void performSpConfigPostprocessing(ServiceProviderConfiguration spConfig) { + spConfig.setMandateMode(mandateMode); + spConfig.setMandateProfiles(KeyValueUtils.getListOfCsvValues(mandateProfiles)); + log.info("Enforcing mandate-mode: {} with profile: {}", mandateMode, mandateProfiles); + + } + + + + @PostConstruct + private void initialize() throws EaafConfigurationException { + mandateMode = SpMandateModes.fromString(loadConfigValue(CONFIG_PROP_IDA_MANDATE_MODE)); + mandateProfiles = loadConfigValue(CONFIG_PROP_IDA_MANDATE_PROFILE); + + log.info("Initialize: {} with mandate-profile: {} mandate-mode: {}", + EJusticePersonRoleHandler.class.getSimpleName(), mandateProfiles, mandateMode); + + } + + private String loadConfigValue(String configProp) throws EaafConfigurationException { + String value = config.getBasicConfiguration(configProp); + if (StringUtils.isEmpty(value)) { + throw new EaafConfigurationException("internal.configuration.00", + new Object[]{configProp}); + + } + + return value; + + } + } diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java index 153cf262..02e091ef 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java @@ -1,5 +1,7 @@ package at.asitplus.eidas.specific.modules.msproxyservice.handler; +import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration; + /** * Handlers for attribute-processing that requires more features than a simple mapping. * @@ -8,6 +10,13 @@ package at.asitplus.eidas.specific.modules.msproxyservice.handler; */ public interface IEidasAttributeHandler { + /** + * Perform attribute-releated post-processing of internal Service-Provider configuration. + * + * @param spConfig SP configuration that was build from incoming eIDAS Authn. request. + */ + void performSpConfigPostprocessing(ServiceProviderConfiguration spConfig); + } diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java index 32be0e22..d0e3d1ba 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java @@ -8,6 +8,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @@ -33,6 +34,7 @@ import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration; import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants; import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException; +import at.asitplus.eidas.specific.modules.msproxyservice.handler.IEidasAttributeHandler; import at.asitplus.eidas.specific.modules.msproxyservice.service.ProxyEidasAttributeRegistry; import at.asitplus.eidas.specific.modules.msproxyservice.utils.EidasProxyServiceUtils; import at.gv.egiz.components.eventlog.api.EventConstants; @@ -333,7 +335,10 @@ public class EidasProxyServiceController extends AbstractController implements I // map eIDAS attributes to national attributes buildNationalRequestedAttributes(spConfig, eidasRequest); - + + // execute custom attribute-handler + advancedAttributeHandler(spConfig, eidasRequest); + return spConfig; } catch (final EidasProxyServiceException e) { @@ -344,6 +349,37 @@ public class EidasProxyServiceController extends AbstractController implements I } } + + private void advancedAttributeHandler(ServiceProviderConfiguration spConfig, ILightRequest eidasRequest) { + Set requiredHandlers = eidasRequest.getRequestedAttributes().getAttributeMap().keySet().stream() + .map(el -> attrRegistry.mapEidasAttributeToAttributeHandler(el.getNameUri().toString()).orElse(null)) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toSet()); + + if (!requiredHandlers.isEmpty()) { + log.info("eIDAS requested attributes requires #{} specific attribute-hander. " + + "Starting advanced attribute-handling ... ", requiredHandlers.size()); + requiredHandlers.forEach(el -> executeAttributeHandler(el, spConfig)); + + } else { + log.debug("No advanced eIDAS attribute-handling required."); + + } + } + + private void executeAttributeHandler(String handlerClass, ServiceProviderConfiguration spConfig) { + try { + IEidasAttributeHandler handler = applicationContext.getBean(handlerClass, IEidasAttributeHandler.class); + + log.trace("Perfom SP config post-processing by using: {}", handler.getClass().getName()); + handler.performSpConfigPostprocessing(spConfig); + + } catch (Exception e) { + log.error("No custom attribute-handler implementation for: {}. Operation can NOT be performed", handlerClass, e); + + } + } private void buildNationalRequestedAttributes( ServiceProviderConfiguration spConfig, ILightRequest eidasRequest) { diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java index 830360e0..4f62b2eb 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java @@ -731,6 +731,112 @@ public class EidasProxyServiceControllerTest { } + + @Test + public void validAuthnRequestWithBorisAttributeLegal() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + String issuer = RandomStringUtils.randomAlphabetic(10); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(issuer) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_LEGALNAME).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + "eJusticeLegalPersonRole").first()) + .build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + + // set default mandate configuration + List mandateProfilesNat = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + List mandateProfilesJur = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(mandateProfilesNat, ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, + StringUtils.join(mandateProfilesJur, ",")); + + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("mandateprofile size", 1, spConfig.getMandateProfiles().size()); + assertEquals("mandateprofile", "MUST_BE_UPDATED", spConfig.getMandateProfiles().get(0)); + assertEquals("MandateMode", SpMandateModes.LEGAL, spConfig.getMandateMode()); + + assertEquals("requested IDA attributes", 10, spConfig.getRequestedAttributes().size()); + + } + + @Test + public void validAuthnRequestWithBorisAttributeNat() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + String issuer = RandomStringUtils.randomAlphabetic(10); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(issuer) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + "eJusticeNaturalPersonRole").first()) + .build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + + // set default mandate configuration + List mandateProfilesNat = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + List mandateProfilesJur = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(mandateProfilesNat, ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, + StringUtils.join(mandateProfilesJur, ",")); + + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("mandateprofile size", 1, spConfig.getMandateProfiles().size()); + assertEquals("mandateprofile", "MUST_BE_UPDATED", spConfig.getMandateProfiles().get(0)); + assertEquals("MandateMode", SpMandateModes.LEGAL, spConfig.getMandateMode()); + + assertEquals("requested IDA attributes", 6, spConfig.getRequestedAttributes().size()); + + } + + private void addConnectorConfig(int i, String key, String value) { config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_PREFIX + String.valueOf(i) + "." + key, value); diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java index d3d1d7b0..b6b8a8df 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java @@ -139,7 +139,7 @@ public class ProxyEidasAttributeRegistryTest { assertFalse("find wrong attribute", attrRegistry.mapEidasAttributeToAttributeHandler( - "http://e-justice.europa.eu/attributes/legalperson/eJusticeLegalPersonRole").isPresent()); + "http://e-justice.europa.eu/attributes/legalperson/eJusticePersonRoleNotExist").isPresent()); Optional attr2 = attrRegistry.mapEidasAttributeToAttributeHandler( "http://e-justice.europa.eu/attributes/naturalperson/eJusticeNaturalPersonRole"); diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml b/modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml index e40ebdc4..c7b40d90 100644 --- a/modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml +++ b/modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml @@ -54,5 +54,15 @@ xs eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + http://e-justice.europa.eu/attributes/legalperson/eJusticePersonRoleNotExist + eJusticeLegalPersonRole + LegalPerson + false + http://www.w3.org/2001/XMLSchema + string + xs + eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller + + diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json b/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json index a3ff1ead..96034d12 100644 --- a/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json +++ b/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json @@ -138,12 +138,20 @@ }, { "eidasAttribute": "http://e-justice.europa.eu/attributes/legalperson/eJusticeLegalPersonRole", - "specificAttributeHandlerClass": "at.asitplus.eidas.specific.modules.msproxyservice.handler.notExist", + "specificAttributeHandlerClass": "at.asitplus.eidas.specific.modules.msproxyservice.handler.EJusticePersonRoleHandler", "type": { "mds": false, "autoIncludeWithMandates": false } }, + { + "eidasAttribute": "http://e-justice.europa.eu/attributes/legalperson/eJusticePersonRoleNotExist", + "specificAttributeHandlerClass": "at.asitplus.eidas.specific.modules.msproxyservice.handler.notExist", + "type": { + "mds": false, + "autoIncludeWithMandates": false + } + }, { "eidasAttribute": "*", "idaAttribute": { diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties index bd4575c3..46e0bb69 100644 --- a/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties +++ b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties @@ -5,4 +5,12 @@ eidas.ms.context.url.request.validation=false eidas.ms.auth.eIDAS.node_v2.proxy.entityId=ownSpecificProxy eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint=http://eidas.proxy/endpoint -eidas.ms.auth.eIDAS.proxy.attribute.mapping.config=idaAttributeMapping.json \ No newline at end of file +eidas.ms.auth.eIDAS.proxy.attribute.mapping.config=idaAttributeMapping.json + + +############################################################################# +## advanced eIDAS attribute processing + +# BORIS attribute for eJustice +eidas.ms.advanced.atributes.ejusticerole.mandate.profiles=MUST_BE_UPDATED +eidas.ms.advanced.atributes.ejusticerole.mandate.mode=legal -- cgit v1.2.3 From d5cb2ae3d5bf3f04646cc23d7d59cd10822349c6 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 16 Aug 2022 15:09:07 +0200 Subject: feat(eidas): generate advanced attributes in response-processing too --- .../handler/EJusticePersonRoleHandler.java | 78 +++++++- .../handler/IEidasAttributeHandler.java | 16 +- .../protocol/ProxyServiceAuthenticationAction.java | 28 ++- .../service/ProxyEidasAttributeRegistry.java | 1 + .../ProxyServiceAuthenticationActionTest.java | 202 +++++++++++++++++++++ .../resources/config/junit_config_1.properties | 2 + 6 files changed, 313 insertions(+), 14 deletions(-) (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java index 52a69944..ec161b1a 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java @@ -1,5 +1,10 @@ package at.asitplus.eidas.specific.modules.msproxyservice.handler; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + import javax.annotation.PostConstruct; import org.apache.commons.lang3.StringUtils; @@ -7,9 +12,12 @@ import org.springframework.beans.factory.annotation.Autowired; import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration; import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes; -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions; +import at.gv.egiz.eaaf.core.api.idp.IEidAuthData; +import at.gv.egiz.eaaf.core.api.idp.IExtendedConfiguration; import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; +import lombok.NonNull; import lombok.extern.slf4j.Slf4j; /** @@ -25,32 +33,84 @@ public class EJusticePersonRoleHandler implements IEidasAttributeHandler { public static final String CONFIG_PROP_IDA_MANDATE_PROFILE = "advanced.atributes.ejusticerole.mandate.profiles"; public static final String CONFIG_PROP_IDA_MANDATE_MODE = "advanced.atributes.ejusticerole.mandate.mode"; - - @Autowired IConfiguration config; + public static final String CONFIG_PROP_RESULT_PREFIX = "advanced.atributes.ejusticerole.value."; + public static final String CONFIG_PROP_RESULT_VALUE_DELIMITER = "="; + + + @Autowired IExtendedConfiguration config; private SpMandateModes mandateMode; - private String mandateProfiles; + private List mandateProfiles; + private Map resultMapper; @Override public void performSpConfigPostprocessing(ServiceProviderConfiguration spConfig) { spConfig.setMandateMode(mandateMode); - spConfig.setMandateProfiles(KeyValueUtils.getListOfCsvValues(mandateProfiles)); + spConfig.setMandateProfiles(mandateProfiles); log.info("Enforcing mandate-mode: {} with profile: {}", mandateMode, mandateProfiles); } + @Override + public String buildAttributeValue(@NonNull IEidAuthData eidAuthData) { + final String mandateType = eidAuthData.getGenericData( + PvpAttributeDefinitions.MANDATE_TYPE_NAME, String.class); + if (StringUtils.isNotEmpty(mandateType)) { + String attrValue = resultMapper.get(mandateType); + if (StringUtils.isNotEmpty(attrValue)) { + log.debug("Mapping mandate-type: {} to EJusticePersonRole: {}", mandateType, attrValue); + return attrValue; + + } else { + log.info("Ignore mandate-type: {}, because it is not mapped to a EJusticePersonRole", mandateType); + + } + + } else { + log.warn("Can not build: EJusticePersonRole, because IDA response contains no attribute: ", + PvpAttributeDefinitions.MANDATE_TYPE_NAME); + + } + + + return null; + + } @PostConstruct private void initialize() throws EaafConfigurationException { mandateMode = SpMandateModes.fromString(loadConfigValue(CONFIG_PROP_IDA_MANDATE_MODE)); - mandateProfiles = loadConfigValue(CONFIG_PROP_IDA_MANDATE_PROFILE); - - log.info("Initialize: {} with mandate-profile: {} mandate-mode: {}", + mandateProfiles = KeyValueUtils.getListOfCsvValues(loadConfigValue(CONFIG_PROP_IDA_MANDATE_PROFILE)); + resultMapper = config.getBasicConfigurationWithPrefix(CONFIG_PROP_RESULT_PREFIX).values().stream() + .filter(el -> el.contains(CONFIG_PROP_RESULT_VALUE_DELIMITER)) + .collect(Collectors.toMap(x -> split(x, 0), x -> split(x, 1))); + + // validate requested profiles to result map + Optional missingConfig = mandateProfiles.stream() + .filter(el -> !resultMapper.containsKey(el)) + .findFirst(); + if (missingConfig.isPresent()) { + log.error("Missing mandate-profile: {} in result mapping", missingConfig.get()); + throw new EaafConfigurationException("internal.configuration.00", + new Object[]{CONFIG_PROP_RESULT_PREFIX}); + + } + + log.info("Initialize: {} with mandate-profile: {} mandate-mode: {} and result-map:", EJusticePersonRoleHandler.class.getSimpleName(), mandateProfiles, mandateMode); + resultMapper.entrySet().stream().forEach(el -> + log.info("Profile: {} --> Attribute-Value: {}", el.getKey(), el.getValue())); + } + private String split(String value, int i) { + return value.split(CONFIG_PROP_RESULT_VALUE_DELIMITER, 2)[i]; + + } + + private String loadConfigValue(String configProp) throws EaafConfigurationException { String value = config.getBasicConfiguration(configProp); if (StringUtils.isEmpty(value)) { @@ -62,5 +122,5 @@ public class EJusticePersonRoleHandler implements IEidasAttributeHandler { return value; } - + } diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java index 02e091ef..5a9c8d8c 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java @@ -1,6 +1,10 @@ package at.asitplus.eidas.specific.modules.msproxyservice.handler; +import javax.annotation.Nullable; + import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration; +import at.gv.egiz.eaaf.core.api.idp.IEidAuthData; +import lombok.NonNull; /** * Handlers for attribute-processing that requires more features than a simple mapping. @@ -15,7 +19,17 @@ public interface IEidasAttributeHandler { * * @param spConfig SP configuration that was build from incoming eIDAS Authn. request. */ - void performSpConfigPostprocessing(ServiceProviderConfiguration spConfig); + void performSpConfigPostprocessing(@NonNull ServiceProviderConfiguration spConfig); + + + /** + * Build eIDAS attribute-value from authentication data. + * + * @param eidAuthData Authentication data for current process + * @return attribute-value if attribute is available, otherwise null + */ + @Nullable + String buildAttributeValue(@NonNull IEidAuthData eidAuthData); diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java index 8348558c..f1cb8f0b 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java @@ -20,6 +20,7 @@ import at.asitplus.eidas.specific.core.gui.StaticGuiBuilderConfiguration; import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants; import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException; +import at.asitplus.eidas.specific.modules.msproxyservice.handler.IEidasAttributeHandler; import at.asitplus.eidas.specific.modules.msproxyservice.service.ProxyEidasAttributeRegistry; import at.asitplus.eidas.specific.modules.msproxyservice.utils.EidasProxyServiceUtils; import at.gv.egiz.eaaf.core.api.IRequest; @@ -264,10 +265,29 @@ public class ProxyServiceAuthenticationAction implements IAction { } - } else { - log.warn("Can not build eIDAS attribute: {}, because there is not corresponding IDA attribute defined", - eidasAttrName); - + } else { + Optional advancedAttributeHandler = attrRegistry.mapEidasAttributeToAttributeHandler(eidasAttrName); + if (advancedAttributeHandler.isPresent()) { + final String idaAttrValue = context.getBean(advancedAttributeHandler.get(), IEidasAttributeHandler.class) + .buildAttributeValue(eidAuthData); + if (StringUtils.isNotEmpty(idaAttrValue)) { + log.debug("Build eIDAS attribute: {} by advanced attribute-handler: {}", + eidasAttrName, advancedAttributeHandler.get()); + attributeMap.put( + attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getByName(eidasAttrName), + idaAttrValue); + + } else { + log.info("Empty attribte-value returned by advanced attribute-handler, eIDAS attribute: {} will be ignored", + eidasAttrName); + + } + + } else { + log.warn("Can not build eIDAS attribute: {}, because there is not corresponding IDA attribute defined", + eidasAttrName); + + } } } diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java index 747c808c..edb21722 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java @@ -124,6 +124,7 @@ public class ProxyEidasAttributeRegistry { String eidasAttributeName, boolean withMandates) { return attributeConfiguration.stream() .filter(el -> el.getEidasAttributeName().equals(eidasAttributeName)) + .filter(el -> el.getIdaAttribute() != null) .findFirst() .map(el -> withMandates ? el.getIdaAttribute().getWithMandates() : el.getIdaAttribute().getBasic()) .filter(el -> StringUtils.isNotEmpty(el)); diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java index d44ffc2d..d9bc017c 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java @@ -397,6 +397,208 @@ public class ProxyServiceAuthenticationActionTest { } + @Test + public void borisModeResponseWithJurMandate() throws EaafException, SpecificCommunicationException { + Map attr = new HashMap<>(); + attr.put(PvpAttributeDefinitions.BPK_NAME, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_TYPE_NAME, + "MUST_BE_UPDATED"); + + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeLegalPersonRole").first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeNaturalPersonRole").first()) + .build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 8, respAttr.size()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, + (String) attr.get(PvpAttributeDefinitions.BPK_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); + + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER, + (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALNAME, + (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME)); + + checkAttrValue(respAttr, "eJusticeLegalPersonRole", "VIP1"); + checkAttrValue(respAttr, "eJusticeNaturalPersonRole", "VIP1"); + + assertNull("find nat. person subject: personalId", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER)); + assertNull("find nat. person subject: familyName", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME)); + assertNull("find nat. person subject: givenName", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME)); + assertNull("find nat. person subject: dateOfBirth", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH)); + + } + + @Test + public void borisModeResponseWithJurMandate2() throws EaafException, SpecificCommunicationException { + Map attr = new HashMap<>(); + attr.put(PvpAttributeDefinitions.BPK_NAME, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_TYPE_NAME, + "SECOND"); + + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeLegalPersonRole").first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeNaturalPersonRole").first()) + .build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 8, respAttr.size()); + + checkAttrValue(respAttr, "eJusticeLegalPersonRole", "VIP2"); + checkAttrValue(respAttr, "eJusticeNaturalPersonRole", "VIP2"); + + + } + + @Test + public void borisModeNoMandateType() throws EaafException, SpecificCommunicationException { + Map attr = new HashMap<>(); + attr.put(PvpAttributeDefinitions.BPK_NAME, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeLegalPersonRole").first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeNaturalPersonRole").first()) + .build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 6, respAttr.size()); + + } + + @Test + public void borisModeEmptyMandateType() throws EaafException, SpecificCommunicationException { + Map attr = new HashMap<>(); + attr.put(PvpAttributeDefinitions.BPK_NAME, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_TYPE_NAME, ""); + + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeLegalPersonRole").first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeNaturalPersonRole").first()) + .build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 6, respAttr.size()); + + } + + @Test + public void borisModeUnknownMandateType() throws EaafException, SpecificCommunicationException { + Map attr = new HashMap<>(); + attr.put(PvpAttributeDefinitions.BPK_NAME, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true); + + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_TYPE_NAME, RandomStringUtils.randomAlphanumeric(10)); + + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeLegalPersonRole").first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeNaturalPersonRole").first()) + .build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + + //perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + //validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData); + assertEquals("wrong attr. size", 6, respAttr.size()); + + } + @Test public void responseWithNatMandateWithWorkAround() throws EaafException, SpecificCommunicationException { basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson", diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties index 46e0bb69..b59cae5f 100644 --- a/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties +++ b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties @@ -14,3 +14,5 @@ eidas.ms.auth.eIDAS.proxy.attribute.mapping.config=idaAttributeMapping.json # BORIS attribute for eJustice eidas.ms.advanced.atributes.ejusticerole.mandate.profiles=MUST_BE_UPDATED eidas.ms.advanced.atributes.ejusticerole.mandate.mode=legal +eidas.ms.advanced.atributes.ejusticerole.value.1=MUST_BE_UPDATED=VIP1 +eidas.ms.advanced.atributes.ejusticerole.value.2=SECOND=VIP2 -- cgit v1.2.3 From ee60dcbde9210e6ecf417af9fd7e4f13e8d95bbd Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 16 Aug 2022 15:46:31 +0200 Subject: style(eidas): fix typo in configuration properties --- .../modules/msproxyservice/handler/EJusticePersonRoleHandler.java | 6 +++--- .../src/test/resources/config/junit_config_1.properties | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java index ec161b1a..87a033eb 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java @@ -31,9 +31,9 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class EJusticePersonRoleHandler implements IEidasAttributeHandler { - public static final String CONFIG_PROP_IDA_MANDATE_PROFILE = "advanced.atributes.ejusticerole.mandate.profiles"; - public static final String CONFIG_PROP_IDA_MANDATE_MODE = "advanced.atributes.ejusticerole.mandate.mode"; - public static final String CONFIG_PROP_RESULT_PREFIX = "advanced.atributes.ejusticerole.value."; + public static final String CONFIG_PROP_IDA_MANDATE_PROFILE = "advanced.attributes.ejusticerole.mandate.profiles"; + public static final String CONFIG_PROP_IDA_MANDATE_MODE = "advanced.attributes.ejusticerole.mandate.mode"; + public static final String CONFIG_PROP_RESULT_PREFIX = "advanced.attributes.ejusticerole.value"; public static final String CONFIG_PROP_RESULT_VALUE_DELIMITER = "="; diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties index b59cae5f..8963129e 100644 --- a/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties +++ b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties @@ -12,7 +12,7 @@ eidas.ms.auth.eIDAS.proxy.attribute.mapping.config=idaAttributeMapping.json ## advanced eIDAS attribute processing # BORIS attribute for eJustice -eidas.ms.advanced.atributes.ejusticerole.mandate.profiles=MUST_BE_UPDATED -eidas.ms.advanced.atributes.ejusticerole.mandate.mode=legal -eidas.ms.advanced.atributes.ejusticerole.value.1=MUST_BE_UPDATED=VIP1 -eidas.ms.advanced.atributes.ejusticerole.value.2=SECOND=VIP2 +eidas.ms.advanced.attributes.ejusticerole.mandate.profiles=MUST_BE_UPDATED +eidas.ms.advanced.attributes.ejusticerole.mandate.mode=legal +eidas.ms.advanced.attributes.ejusticerole.value.1=MUST_BE_UPDATED=VIP1 +eidas.ms.advanced.attributes.ejusticerole.value.2=SECOND=VIP2 -- cgit v1.2.3 From 920d33465e5ab1a71d81cc280e41de10cd8b5247 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Wed, 17 Aug 2022 09:53:46 +0200 Subject: feat(eidas): extend EJusticePersonRoleHandler to include additional requested attributes --- .../handler/EJusticePersonRoleHandler.java | 22 ++- .../EidasProxyServiceControllerBorisTest.java | 197 +++++++++++++++++++++ .../protocol/EidasProxyServiceControllerTest.java | 8 +- .../resources/config/junit_config_1.properties | 1 + .../resources/config/junit_config_2.properties | 18 ++ .../spring/SpringTest-context_basic_mapConfig2.xml | 20 +++ 6 files changed, 259 insertions(+), 7 deletions(-) create mode 100644 modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerBorisTest.java create mode 100644 modules/eidas_proxy-sevice/src/test/resources/config/junit_config_2.properties create mode 100644 modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig2.xml (limited to 'modules/eidas_proxy-sevice/src') diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java index 87a033eb..6a5e4967 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java @@ -33,6 +33,9 @@ public class EJusticePersonRoleHandler implements IEidasAttributeHandler { public static final String CONFIG_PROP_IDA_MANDATE_PROFILE = "advanced.attributes.ejusticerole.mandate.profiles"; public static final String CONFIG_PROP_IDA_MANDATE_MODE = "advanced.attributes.ejusticerole.mandate.mode"; + public static final String CONFIG_PROP_IDA_ADDITIONAL_ATTRIBUTES = + "advanced.attributes.ejusticerole.additional.ida.attributes"; + public static final String CONFIG_PROP_RESULT_PREFIX = "advanced.attributes.ejusticerole.value"; public static final String CONFIG_PROP_RESULT_VALUE_DELIMITER = "="; @@ -41,14 +44,21 @@ public class EJusticePersonRoleHandler implements IEidasAttributeHandler { private SpMandateModes mandateMode; private List mandateProfiles; + private List additionalReqAttributes; private Map resultMapper; @Override public void performSpConfigPostprocessing(ServiceProviderConfiguration spConfig) { spConfig.setMandateMode(mandateMode); - spConfig.setMandateProfiles(mandateProfiles); + spConfig.setMandateProfiles(mandateProfiles); log.info("Enforcing mandate-mode: {} with profile: {}", mandateMode, mandateProfiles); + if (!additionalReqAttributes.isEmpty()) { + spConfig.getRequestedAttributes().addAll(additionalReqAttributes); + log.info("Add additional requested attributes: {}", additionalReqAttributes); + + } + } @Override @@ -80,8 +90,10 @@ public class EJusticePersonRoleHandler implements IEidasAttributeHandler { @PostConstruct private void initialize() throws EaafConfigurationException { - mandateMode = SpMandateModes.fromString(loadConfigValue(CONFIG_PROP_IDA_MANDATE_MODE)); - mandateProfiles = KeyValueUtils.getListOfCsvValues(loadConfigValue(CONFIG_PROP_IDA_MANDATE_PROFILE)); + mandateMode = SpMandateModes.fromString(loadConfigValue(CONFIG_PROP_IDA_MANDATE_MODE, true)); + mandateProfiles = KeyValueUtils.getListOfCsvValues(loadConfigValue(CONFIG_PROP_IDA_MANDATE_PROFILE, true)); + additionalReqAttributes = KeyValueUtils.getListOfCsvValues( + loadConfigValue(CONFIG_PROP_IDA_ADDITIONAL_ATTRIBUTES, false)); resultMapper = config.getBasicConfigurationWithPrefix(CONFIG_PROP_RESULT_PREFIX).values().stream() .filter(el -> el.contains(CONFIG_PROP_RESULT_VALUE_DELIMITER)) .collect(Collectors.toMap(x -> split(x, 0), x -> split(x, 1))); @@ -111,9 +123,9 @@ public class EJusticePersonRoleHandler implements IEidasAttributeHandler { } - private String loadConfigValue(String configProp) throws EaafConfigurationException { + private String loadConfigValue(String configProp, boolean isRequired) throws EaafConfigurationException { String value = config.getBasicConfiguration(configProp); - if (StringUtils.isEmpty(value)) { + if (StringUtils.isEmpty(value) && isRequired) { throw new EaafConfigurationException("internal.configuration.00", new Object[]{configProp}); diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerBorisTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerBorisTest.java new file mode 100644 index 00000000..dfa4e264 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerBorisTest.java @@ -0,0 +1,197 @@ +package at.asitplus.eidas.specific.modules.msproxyservice.test.protocol; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +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.core.config.ServiceProviderConfiguration; +import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap; +import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants; +import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry; +import at.asitplus.eidas.specific.modules.core.eidas.test.dummy.DummySpecificCommunicationService; +import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants; +import at.asitplus.eidas.specific.modules.msproxyservice.protocol.EidasProxyServiceController; +import at.gv.egiz.eaaf.core.api.data.EaafConstants; +import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes; +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 eu.eidas.auth.commons.EidasParameterKeys; +import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; +import eu.eidas.auth.commons.light.impl.LightRequest; +import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames; +import eu.eidas.specificcommunication.protocol.SpecificCommunicationService; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { + "/spring/SpringTest-context_basic_test.xml", + "/spring/SpringTest-context_basic_mapConfig2.xml", + }) +@EnableWebMvc +public class EidasProxyServiceControllerBorisTest { + + @Autowired private EidasProxyServiceController controller; + + @Autowired private DummySpecificCommunicationService proxyService; + @Autowired private DummyProtocolAuthService authService; + @Autowired private EidasAttributeRegistry attrRegistry; + @Autowired private ApplicationContext context; + + @Autowired MsConnectorDummyConfigMap config; + + private MockHttpServletRequest httpReq; + private MockHttpServletResponse httpResp; + + private SpecificCommunicationService springManagedSpecificConnectorCommunicationService; + + /** + * jUnit test set-up. + */ + @Before + public void setUp() throws EaafStorageException, URISyntaxException { + httpReq = new MockHttpServletRequest("POST", "http://localhost/ms_connector/eidas/light/idp/redirect"); + httpResp = new MockHttpServletResponse(); + RequestContextHolder.resetRequestAttributes(); + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp)); + + proxyService.setiLightRequest(null); + proxyService.setError(null); + + config.putConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint", + "http://eidas.proxy/endpoint"); + + springManagedSpecificConnectorCommunicationService = + (SpecificCommunicationService) context.getBean( + SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE + .toString()); + + } + + @Test + public void validAuthnRequestWithBorisAttributeLegal() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + String issuer = RandomStringUtils.randomAlphabetic(10); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(issuer) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_LEGALNAME).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + "eJusticeLegalPersonRole").first()) + .build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + + // set default mandate configuration + List mandateProfilesNat = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + List mandateProfilesJur = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(mandateProfilesNat, ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, + StringUtils.join(mandateProfilesJur, ",")); + + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("mandateprofile size", 1, spConfig.getMandateProfiles().size()); + assertEquals("mandateprofile", "MUST_BE_UPDATED", spConfig.getMandateProfiles().get(0)); + assertEquals("MandateMode", SpMandateModes.LEGAL, spConfig.getMandateMode()); + + assertEquals("requested IDA attributes", 10, spConfig.getRequestedAttributes().size()); + + } + + @Test + public void validAuthnRequestWithBorisAttributeNat() throws IOException, EaafException { + //initialize state + httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10)); + String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase(); + String issuer = RandomStringUtils.randomAlphabetic(10); + LightRequest.Builder authnReqBuilder = LightRequest.builder() + .id(UUID.randomUUID().toString()) + .issuer(issuer) + .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) + .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH) + .spCountryCode(spCountryCode) + .spType("public") + .requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + "eJusticeNaturalPersonRole").first()) + .build()); + + proxyService.setiLightRequest(authnReqBuilder.build()); + + + // set default mandate configuration + List mandateProfilesNat = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + List mandateProfilesJur = + Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true"); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, + StringUtils.join(mandateProfilesNat, ",")); + config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, + StringUtils.join(mandateProfilesJur, ",")); + + + //execute + controller.receiveEidasAuthnRequest(httpReq, httpResp); + + //validate state + ServiceProviderConfiguration spConfig = + authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class); + assertNotNull("mandateprofiles", spConfig.getMandateProfiles()); + assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty()); + assertEquals("mandateprofile size", 1, spConfig.getMandateProfiles().size()); + assertEquals("mandateprofile", "MUST_BE_UPDATED", spConfig.getMandateProfiles().get(0)); + assertEquals("MandateMode", SpMandateModes.LEGAL, spConfig.getMandateMode()); + + assertEquals("requested IDA attributes", 6, spConfig.getRequestedAttributes().size()); + + } + +} + + diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java index 4f62b2eb..5894ea45 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java @@ -781,7 +781,7 @@ public class EidasProxyServiceControllerTest { assertEquals("mandateprofile", "MUST_BE_UPDATED", spConfig.getMandateProfiles().get(0)); assertEquals("MandateMode", SpMandateModes.LEGAL, spConfig.getMandateMode()); - assertEquals("requested IDA attributes", 10, spConfig.getRequestedAttributes().size()); + assertEquals("requested IDA attributes", 11, spConfig.getRequestedAttributes().size()); } @@ -832,7 +832,11 @@ public class EidasProxyServiceControllerTest { assertEquals("mandateprofile", "MUST_BE_UPDATED", spConfig.getMandateProfiles().get(0)); assertEquals("MandateMode", SpMandateModes.LEGAL, spConfig.getMandateMode()); - assertEquals("requested IDA attributes", 6, spConfig.getRequestedAttributes().size()); + assertEquals("requested IDA attributes", 7, spConfig.getRequestedAttributes().size()); + assertTrue("missing additional attribute", spConfig.getRequestedAttributes().stream() + .filter(el -> el.equals("testAttribute")) + .findFirst() + .isPresent()); } diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties index 8963129e..90b44868 100644 --- a/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties +++ b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties @@ -14,5 +14,6 @@ eidas.ms.auth.eIDAS.proxy.attribute.mapping.config=idaAttributeMapping.json # BORIS attribute for eJustice eidas.ms.advanced.attributes.ejusticerole.mandate.profiles=MUST_BE_UPDATED eidas.ms.advanced.attributes.ejusticerole.mandate.mode=legal +eidas.ms.advanced.attributes.ejusticerole.additional.ida.attributes=testAttribute eidas.ms.advanced.attributes.ejusticerole.value.1=MUST_BE_UPDATED=VIP1 eidas.ms.advanced.attributes.ejusticerole.value.2=SECOND=VIP2 diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_2.properties b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_2.properties new file mode 100644 index 00000000..8963129e --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_2.properties @@ -0,0 +1,18 @@ +## Basic service configuration +eidas.ms.context.url.prefix=http://localhost +eidas.ms.context.url.request.validation=false + +eidas.ms.auth.eIDAS.node_v2.proxy.entityId=ownSpecificProxy +eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint=http://eidas.proxy/endpoint + +eidas.ms.auth.eIDAS.proxy.attribute.mapping.config=idaAttributeMapping.json + + +############################################################################# +## advanced eIDAS attribute processing + +# BORIS attribute for eJustice +eidas.ms.advanced.attributes.ejusticerole.mandate.profiles=MUST_BE_UPDATED +eidas.ms.advanced.attributes.ejusticerole.mandate.mode=legal +eidas.ms.advanced.attributes.ejusticerole.value.1=MUST_BE_UPDATED=VIP1 +eidas.ms.advanced.attributes.ejusticerole.value.2=SECOND=VIP2 diff --git a/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig2.xml b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig2.xml new file mode 100644 index 00000000..dfe98ea5 --- /dev/null +++ b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig2.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file -- cgit v1.2.3