/* * 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.auth.eidas.v2.utils; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.Nullable; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableList; import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; import at.gv.egiz.eaaf.core.impl.data.Trible; import eu.eidas.auth.commons.attribute.AttributeDefinition; import eu.eidas.auth.commons.attribute.AttributeValue; import eu.eidas.auth.commons.attribute.AttributeValueMarshaller; import eu.eidas.auth.commons.attribute.AttributeValueMarshallingException; import eu.eidas.auth.commons.attribute.AttributeValueTransliterator; import eu.eidas.auth.commons.protocol.eidas.impl.PostalAddress; public class EidasResponseUtils { private static final Logger log = LoggerFactory.getLogger(EidasResponseUtils.class); public static final String PERSONALIDENIFIER_VALIDATION_PATTERN = "^[A-Z,a-z]{2}/[A-Z,a-z]{2}/.*"; /** * Validate a eIDAS PersonalIdentifier attribute value This validation is done * according to eIDAS SAML Attribute Profile - Section 2.2.3 Unique Identifier * * @param uniqueID eIDAS attribute value of a unique identifier * @return true if the uniqueID matches to eIDAS to Unique Identifier * specification, otherwise false */ public static boolean validateEidasPersonalIdentifier(String uniqueID) { final Pattern pattern = Pattern.compile(PERSONALIDENIFIER_VALIDATION_PATTERN); final Matcher matcher = pattern.matcher(uniqueID); return matcher.matches(); } /** * Parse an eIDAS PersonalIdentifier attribute value into it components. This * processing is done according to eIDAS SAML Attribute Profile - Section 2.2.3 * Unique Identifier * * @param uniqueID eIDAS attribute value of a unique identifier * @return {@link Trible} that contains:
* First : citizen country
* Second: destination country
* Third : unique identifier
* or null if the attribute value has a wrong format */ public static Trible parseEidasPersonalIdentifier(String uniqueID) { if (!validateEidasPersonalIdentifier(uniqueID)) { log.error("eIDAS attribute value for {} looks wrong formated. Value: {}", Constants.eIDAS_ATTR_PERSONALIDENTIFIER, uniqueID); return null; } return Trible.newInstance(uniqueID.substring(0, 2), uniqueID.substring(3, 5), uniqueID.substring(6)); } /** * Get eIDAS attribute-values from eIDAS Node attributes. * * @param attributeDefinition eIDAS attribute definition * @param attributeValues Attributes from eIDAS response * @return Set of attribute values. If more then one value than the first value contains the 'Latin' value. */ // TODO: check possible problem with nonLatinCharacters public static List translateStringListAttribute(AttributeDefinition attributeDefinition, ImmutableList> attributeValues) { final List stringListAttribute = new ArrayList<>(); final AttributeValueMarshaller attributeValueMarshaller = attributeDefinition .getAttributeValueMarshaller(); for (final AttributeValue attributeValue : attributeValues) { String valueString = null; try { valueString = attributeValueMarshaller.marshal((AttributeValue) attributeValue); log.trace("Find attr: {} with value: {} nonLatinFlag: {} needTransliteration: {}", attributeDefinition.getFriendlyName(), attributeValue.toString(), attributeValue.isNonLatinScriptAlternateVersion(), AttributeValueTransliterator.needsTransliteration(valueString)); // if (attributeValue.isNonLatinScriptAlternateVersion()) { if (!AttributeValueTransliterator.needsTransliteration(valueString)) { stringListAttribute.add(0, valueString); } else { log.trace("Find 'needsTransliteration' flag. Setting this value at last list element ... "); stringListAttribute.add(valueString); } } catch (final AttributeValueMarshallingException e) { throw new IllegalStateException(e); } } log.trace("Extract values: {} for attr: {}", StringUtils.join(stringListAttribute, ","), attributeDefinition.getFriendlyName()); return stringListAttribute; } /** * Convert eIDAS DateTime attribute to Java Object. * * @param attributeDefinition eIDAS attribute definition. * @param attributeValues eIDAS attribute value * @return */ @Nullable public static DateTime translateDateAttribute(AttributeDefinition attributeDefinition, ImmutableList> attributeValues) { if (attributeValues.size() != 0) { final AttributeValue firstAttributeValue = attributeValues.get(0); return (DateTime) firstAttributeValue.getValue(); } return null; } /** * Concert eIDAS Address attribute to Java object. * * @param attributeDefinition eIDAS attribute definition * @param attributeValues eIDAS attribute value * @return */ @Nullable public static PostalAddress translateAddressAttribute(AttributeDefinition attributeDefinition, ImmutableList> attributeValues) { final AttributeValue firstAttributeValue = attributeValues.get(0); return (PostalAddress) firstAttributeValue.getValue(); } }