/* * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a * cooperation between EGIZ, A-SIT Plus, 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 "Licence"); You may not use this work except in * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * * Unless required by applicable law or agreed to in writing, software distributed under the Licence * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the Licence for the specific language governing permissions and limitations under * the Licence. * * 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.gv.egiz.eaaf.modules.pvp2.impl.builder; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.ServiceLoader; import at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder; import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator; import at.gv.egiz.eaaf.core.api.idp.IAuthData; import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration; import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException; import at.gv.egiz.eaaf.core.exceptions.InvalidDateFormatAttributeException; import at.gv.egiz.eaaf.core.exceptions.UnavailableAttributeException; import at.gv.egiz.eaaf.core.impl.idp.builder.attributes.PvpMetadata; import at.gv.egiz.eaaf.modules.pvp2.exception.InvalidDateFormatException; import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; import org.opensaml.saml.saml2.core.Attribute; import org.opensaml.saml.saml2.metadata.RequestedAttribute; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PvpAttributeBuilder { private static final Logger log = LoggerFactory.getLogger(PvpAttributeBuilder.class); private static IAttributeGenerator generator = new SamlAttributeGenerator(); private static HashMap builders; private static ServiceLoader attributBuilderLoader = ServiceLoader.load(IAttributeBuilder.class); private static void addBuilder(final IAttributeBuilder builder) { builders.put(builder.getName(), builder); } static { builders = new HashMap<>(); log.info("Loading protocol attribut-builder modules:"); if (attributBuilderLoader != null) { final Iterator moduleLoaderInterator = attributBuilderLoader.iterator(); while (moduleLoaderInterator.hasNext()) { try { final IAttributeBuilder modul = moduleLoaderInterator.next(); log.info("Loading attribut-builder Modul Information: " + modul.getName()); addBuilder(modul); } catch (final Throwable e) { log.error("Check configuration! " + "Some attribute-builder modul" + " is not a valid IAttributeBuilder", e); } } } log.info("Loading attribute-builder modules done"); } /** * Get a specific attribute builder. * * @param name Attribute-builder friendly name * * @return Attribute-builder with this name or null if builder does not exists */ public static IAttributeBuilder getAttributeBuilder(final String name) { return builders.get(name); } /** * Build an SAML2 attribute. * * @param name attribute name * @param value attribute value * @return SAML2 attribute */ public static Attribute buildAttribute(final String name, final String value) { log.warn("Attribute value: {} is NOT injected", value); if (builders.containsKey(name)) { return builders.get(name).buildEmpty(generator); } return null; } /** * Build a SAML2 attribute. * * @param name attribute name * @param oaParam Service-Provider configuration * @param authData serice-provider specific authentication data * @return SAML2 attribute * @throws Pvp2Exception In case of a general error * @throws AttributeBuilderException In case of an attribute builder error */ public static Attribute buildAttribute(final String name, final ISpConfiguration oaParam, final IAuthData authData) throws Pvp2Exception, AttributeBuilderException { if (builders.containsKey(name)) { try { return builders.get(name).build(oaParam, authData, generator); } catch (final AttributeBuilderException e) { if (e instanceof UnavailableAttributeException) { throw e; } else if (e instanceof InvalidDateFormatAttributeException) { throw new InvalidDateFormatException(); } else { throw new UnavailableAttributeException(name); } } } return null; } /** * Build an empty attribute. * * @param name attributename * @return SAML2 attribute */ public static Attribute buildEmptyAttribute(final String name) { if (builders.containsKey(name)) { return builders.get(name).buildEmpty(generator); } return null; } /** * Return all attributes that has a {@link PvpMetadata} annotation. * * @return */ public static List buildSupportedEmptyAttributes() { final List attributes = new ArrayList<>(); final Iterator builderIt = builders.values().iterator(); while (builderIt.hasNext()) { final IAttributeBuilder builder = builderIt.next(); if (builder.getClass().isAnnotationPresent(PvpMetadata.class)) { final Attribute emptyAttribute = builder.buildEmpty(generator); if (emptyAttribute != null) { attributes.add(emptyAttribute); } } else { log.trace(builder.getName() + "is no PVP Metadata attribute"); } } return attributes; } /** * Build a requested attribute. * * @param name attribute name * @param friendlyName attribute friendlyname * @param required is attribute mandatory * @return SAML2 requested attribute */ public static RequestedAttribute buildReqAttribute(final String name, final String friendlyName, final boolean required) { final RequestedAttribute attribute = Saml2Utils.createSamlObject(RequestedAttribute.class); attribute.setIsRequired(required); attribute.setName(name); attribute.setFriendlyName(friendlyName); attribute.setNameFormat(Attribute.URI_REFERENCE); return attribute; } /** * Build a set of PVP Response-Attributes
*
* INFO: If a specific attribute can not be build, a info is logged, but * no execpetion is thrown. Therefore, the return List must not include all * requested attributes. * * @param authData AuthenticationData IAuthData which is * used to build the attribute values, but never * null * @param reqAttributenName List of PVP attribute names which are requested, but * never null * @return List of PVP attributes, but never null */ public static List buildSetOfResponseAttributes(final IAuthData authData, final Collection reqAttributenName) { final List attrList = new ArrayList<>(); if (reqAttributenName != null) { final Iterator it = reqAttributenName.iterator(); while (it.hasNext()) { final String reqAttributName = it.next(); try { final Attribute attr = PvpAttributeBuilder.buildAttribute(reqAttributName, null, authData); if (attr == null) { log.info("Attribute generation failed! for " + reqAttributName); } else { attrList.add(attr); } } catch (final Pvp2Exception e) { log.info("Attribute generation failed! for " + reqAttributName); } catch (final Exception e) { log.warn("General Attribute generation failed! for " + reqAttributName, e); } } } return attrList; } }