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);
}
}
}