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; import org.springframework.beans.factory.annotation.Autowired; import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration; import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException; import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes; 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 eu.eidas.auth.commons.light.ILightRequest; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; /** * 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 * */ @Slf4j public class EJusticePersonRoleHandler implements IEidasAttributeHandler { public static final String EIDAS_ATTR_EJUSTIC_NAT = "http://e-justice.europa.eu/attributes/naturalperson/eJusticeNaturalPersonRole"; public static final String EIDAS_ATTR_EJUSTIC_JUR = "http://e-justice.europa.eu/attributes/legalperson/eJusticeLegalPersonRole"; 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 = "="; @Autowired IExtendedConfiguration config; private SpMandateModes mandateMode; private List mandateProfiles; private List additionalReqAttributes; private Map resultMapper; @Override public void performSpConfigPostprocessing(ServiceProviderConfiguration spConfig) { spConfig.setMandateMode(mandateMode); 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 public void performAuthDataPostprocessing(@NonNull IEidAuthData authData) { log.trace("{} needs no post processing of authData, because we are in regular mode of operation.", EJusticePersonRoleHandler.class.getName()); } @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, 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))); // 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, boolean isRequired) throws EaafConfigurationException { String value = config.getBasicConfiguration(configProp); if (StringUtils.isEmpty(value) && isRequired) { throw new EaafConfigurationException("internal.configuration.00", new Object[]{configProp}); } return value; } @Override public final void validateAuthnRequest(ILightRequest eidasRequest) throws EidasProxyServiceException { boolean isNatReq = eidasRequest.getRequestedAttributes().getAttributeValuesByNameUri(EIDAS_ATTR_EJUSTIC_NAT) != null; boolean isJurReq = eidasRequest.getRequestedAttributes().getAttributeValuesByNameUri(EIDAS_ATTR_EJUSTIC_JUR) != null; if (isNatReq && isJurReq) { log.warn("eJustice attributes for legal and natural person can NOT be requested at the same time."); throw new EidasProxyServiceException("eidas.proxyservice.ejustice.01", null); } } }