summaryrefslogtreecommitdiff
path: root/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/PvpEntityCategoryFilter.java
diff options
context:
space:
mode:
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/PvpEntityCategoryFilter.java')
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/PvpEntityCategoryFilter.java251
1 files changed, 251 insertions, 0 deletions
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/PvpEntityCategoryFilter.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/PvpEntityCategoryFilter.java
new file mode 100644
index 00000000..2d81b1f8
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/PvpEntityCategoryFilter.java
@@ -0,0 +1,251 @@
+/*
+ * 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.validation.metadata;
+
+import java.util.ArrayList;
+import java.util.List;
+import at.gv.egiz.eaaf.core.impl.data.Trible;
+import at.gv.egiz.eaaf.modules.pvp2.PvpConstants;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpAttributeBuilder;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
+import org.opensaml.common.xml.SAMLConstants;
+import org.opensaml.saml2.common.Extensions;
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.metadata.AttributeConsumingService;
+import org.opensaml.saml2.metadata.EntitiesDescriptor;
+import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml2.metadata.LocalizedString;
+import org.opensaml.saml2.metadata.RequestedAttribute;
+import org.opensaml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.saml2.metadata.ServiceName;
+import org.opensaml.saml2.metadata.provider.FilterException;
+import org.opensaml.saml2.metadata.provider.MetadataFilter;
+import org.opensaml.samlext.saml2mdattr.EntityAttributes;
+import org.opensaml.xml.XMLObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Metadata filter that inject requested attributes based on Metadata EntityCategories.
+ *
+ * @author tlenz
+ *
+ */
+public class PvpEntityCategoryFilter implements MetadataFilter {
+ private static final Logger log = LoggerFactory.getLogger(PvpEntityCategoryFilter.class);
+
+ private boolean isUsed = false;
+
+ /**
+ * Filter to map PVP EntityCategories into a set of single PVP attributes.
+ *
+ * @param isUsed if true PVP EntityCategories are mapped, otherwise they are ignored
+ *
+ */
+ public PvpEntityCategoryFilter(final boolean isUsed) {
+ this.isUsed = isUsed;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.opensaml.saml2.metadata.provider.MetadataFilter#doFilter(org.opensaml.xml.XMLObject)
+ */
+ @Override
+ public void doFilter(final XMLObject metadata) throws FilterException {
+
+ if (isUsed) {
+ log.trace("Map PVP EntityCategory to single PVP Attributes ... ");
+ final String entityId = null;
+ try {
+ if (metadata instanceof EntitiesDescriptor) {
+ log.trace("Find EnitiesDescriptor ... ");
+ final EntitiesDescriptor entitiesDesc = (EntitiesDescriptor) metadata;
+ if (entitiesDesc.getEntityDescriptors() != null) {
+ for (final EntityDescriptor el : entitiesDesc.getEntityDescriptors()) {
+ resolveEntityCategoriesToAttributes(el);
+ }
+
+ }
+
+ } else if (metadata instanceof EntityDescriptor) {
+ log.trace("Find EntityDescriptor");
+ resolveEntityCategoriesToAttributes((EntityDescriptor) metadata);
+
+
+ } else {
+ throw new Pvp2MetadataException("pvp2.26", new Object[] {
+ "Invalid Metadata file Root element is no Entities- or EntityDescriptor"});
+ }
+
+
+
+ } catch (final Exception e) {
+ log.warn("SAML2 Metadata processing FAILED: Can not resolve EntityCategories for metadata: "
+ + entityId, e);
+
+ }
+
+ } else {
+ log.trace("Filter to map PVP EntityCategory to single PVP Attributes is deactivated");
+ }
+
+ }
+
+ private void resolveEntityCategoriesToAttributes(final EntityDescriptor metadata) {
+ log.debug("Resolving EntityCategorie for Entity: " + metadata.getEntityID() + " ...");
+ final Extensions extensions = metadata.getExtensions();
+ if (extensions != null) {
+ final List<XMLObject> listOfExt = extensions.getUnknownXMLObjects();
+ if (listOfExt != null && !listOfExt.isEmpty()) {
+ log.trace("Find #" + listOfExt.size() + " 'Extension' elements ");
+ for (final XMLObject el : listOfExt) {
+ log.trace("Find ExtensionElement: " + el.getElementQName().toString());
+ if (el instanceof EntityAttributes) {
+ final EntityAttributes entityAttrElem = (EntityAttributes) el;
+ if (entityAttrElem.getAttributes() != null) {
+ log.trace("Find EntityAttributes. Start attribute processing ...");
+ for (final Attribute entityAttr : entityAttrElem.getAttributes()) {
+ if (entityAttr.getName().equals(PvpConstants.ENTITY_CATEGORY_ATTRIBITE)) {
+ if (!entityAttr.getAttributeValues().isEmpty()) {
+ final String entityAttrValue =
+ entityAttr.getAttributeValues().get(0).getDOM().getTextContent();
+ if (PvpConstants.EGOVTOKEN.equals(entityAttrValue)) {
+ log.debug(
+ "Find 'EGOVTOKEN' EntityAttribute. Adding single pvp attributes ... ");
+ addAttributesToEntityDescriptor(metadata,
+ buildAttributeList(PvpConstants.EGOVTOKEN_PVP_ATTRIBUTES),
+ entityAttrValue);
+
+
+ } else if (PvpConstants.CITIZENTOKEN.equals(entityAttrValue)) {
+ log.debug(
+ "Find 'CITIZENTOKEN' EntityAttribute. Adding single pvp attributes ... ");
+ addAttributesToEntityDescriptor(metadata,
+ buildAttributeList(PvpConstants.CITIZENTOKEN_PVP_ATTRIBUTES),
+ entityAttrValue);
+
+ } else {
+ log.info("EntityAttributeValue: " + entityAttrValue + " is UNKNOWN!");
+ }
+
+ } else {
+ log.info("EntityAttribute: No attribute value");
+ }
+
+ } else {
+ log.info("EntityAttribute: " + entityAttr.getName() + " is NOT supported");
+ }
+
+ }
+
+ } else {
+ log.info(
+ "Can NOT resolve EntityAttributes! Reason: Only EntityAttributes are supported!");
+ }
+
+ }
+ }
+
+ } else {
+ log.trace("'Extension' element is 'null' or empty");
+ }
+
+ } else {
+ log.trace("No 'Extension' element found");
+ }
+
+ }
+
+
+ private void addAttributesToEntityDescriptor(final EntityDescriptor metadata,
+ final List<RequestedAttribute> attrList, final String entityAttr) {
+ final SPSSODescriptor spSsoDesc = metadata.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
+ if (spSsoDesc != null) {
+ if (spSsoDesc.getAttributeConsumingServices() == null
+ || spSsoDesc.getAttributeConsumingServices().isEmpty()) {
+ log.trace("No 'AttributeConsumingServices' found. Added it ...");
+
+ final AttributeConsumingService attributeService =
+ Saml2Utils.createSamlObject(AttributeConsumingService.class);
+ attributeService.setIndex(0);
+ attributeService.setIsDefault(true);
+ final ServiceName serviceName = Saml2Utils.createSamlObject(ServiceName.class);
+ serviceName.setName(new LocalizedString("Default Service", "en"));
+ attributeService.getNames().add(serviceName);
+
+ if (attrList != null && !attrList.isEmpty()) {
+ attributeService.getRequestAttributes().addAll(attrList);
+ log.info("Add " + attrList.size() + " attributes for 'EntityAttribute': " + entityAttr);
+
+ }
+
+ spSsoDesc.getAttributeConsumingServices().add(attributeService);
+
+ } else {
+ log.debug("Find 'AttributeConsumingServices'. Starting updating process ... ");
+ for (final AttributeConsumingService el : spSsoDesc.getAttributeConsumingServices()) {
+ log.debug("Update 'AttributeConsumingService' with Index: " + el.getIndex());
+
+ // load currently requested attributes
+ final List<String> currentlyReqAttr = new ArrayList<>();
+ for (final RequestedAttribute reqAttr : el.getRequestAttributes()) {
+ currentlyReqAttr.add(reqAttr.getName());
+ }
+
+
+ // check against EntityAttribute List
+ for (final RequestedAttribute entityAttrListEl : attrList) {
+ if (!currentlyReqAttr.contains(entityAttrListEl.getName())) {
+ el.getRequestAttributes().add(entityAttrListEl);
+
+ } else {
+ log.debug("'AttributeConsumingService' already contains attr: "
+ + entityAttrListEl.getName());
+ }
+
+ }
+
+ }
+
+ }
+
+ } else {
+ log.info("Can ONLY add 'EntityAttributes' to 'SPSSODescriptor'");
+ }
+
+ }
+
+ private List<RequestedAttribute> buildAttributeList(
+ final List<Trible<String, String, Boolean>> attrSet) {
+ final List<RequestedAttribute> requestedAttributes = new ArrayList<>();
+ for (final Trible<String, String, Boolean> el : attrSet) {
+ requestedAttributes
+ .add(PvpAttributeBuilder.buildReqAttribute(el.getFirst(), el.getSecond(), el.getThird()));
+ }
+
+ return requestedAttributes;
+
+
+ }
+
+}