/** * Copyright (c) Members of the EGEE Collaboration. 2006-2009. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * 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. */ package org.glite.authz.pap.common.xacml.wizard; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; import org.glite.authz.pap.common.xacml.utils.ActionHelper; import org.glite.authz.pap.common.xacml.utils.ActionMatchHelper; import org.glite.authz.pap.common.xacml.utils.ActionsHelper; import org.glite.authz.pap.common.xacml.utils.EnvironmentHelper; import org.glite.authz.pap.common.xacml.utils.EnvironmentMatchHelper; import org.glite.authz.pap.common.xacml.utils.EnvironmentsHelper; import org.glite.authz.pap.common.xacml.utils.ResourceHelper; import org.glite.authz.pap.common.xacml.utils.ResourceMatchHelper; import org.glite.authz.pap.common.xacml.utils.ResourcesHelper; import org.glite.authz.pap.common.xacml.utils.SubjectHelper; import org.glite.authz.pap.common.xacml.utils.SubjectMatchHelper; import org.glite.authz.pap.common.xacml.utils.SubjectsHelper; import org.glite.authz.pap.common.xacml.utils.TargetHelper; import org.glite.authz.pap.common.xacml.wizard.exceptions.TargetWizardException; import org.glite.authz.pap.common.xacml.wizard.exceptions.UnsupportedAttributeException; import org.glite.authz.pap.common.xacml.wizard.exceptions.UnsupportedTargetException; import org.opensaml.xacml.ctx.AttributeType; import org.opensaml.xacml.policy.ActionMatchType; import org.opensaml.xacml.policy.ActionType; import org.opensaml.xacml.policy.ActionsType; import org.opensaml.xacml.policy.EnvironmentMatchType; import org.opensaml.xacml.policy.EnvironmentType; import org.opensaml.xacml.policy.EnvironmentsType; import org.opensaml.xacml.policy.ResourceMatchType; import org.opensaml.xacml.policy.ResourceType; import org.opensaml.xacml.policy.ResourcesType; import org.opensaml.xacml.policy.SubjectMatchType; import org.opensaml.xacml.policy.SubjectType; import org.opensaml.xacml.policy.SubjectsType; import org.opensaml.xacml.policy.TargetType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class renders a list of {@link AttributeWizard} into an XACML Target and vice versa. * Supported targets are the ones with single SubjectType, ResourceType, ActionType and * EnvironmentType elements. */ public class TargetWizard { private static final Logger log = LoggerFactory.getLogger(TargetWizard.class); private TargetType target = null; private final List<AttributeWizard> targetAttributeWizardList; /** * Constructor. * * @param attributeWizard the attribute wizard to build the Target with. */ public TargetWizard(AttributeWizard attributeWizard) { targetAttributeWizardList = Arrays.asList(attributeWizard); } /** * Constructor. * <p> * Attributes of the same category (resource, action, subject, environment) are * <i>Category</i>Match elements of the generated target. For example if the given list of * attributes as two subject attributes the generated Target contains two <i>SubjectMatch</i> * elements. * * @param targetAttributeWizardList the list of attribute wizard to build the Target with. */ public TargetWizard(List<AttributeWizard> targetAttributeWizardList) { if (targetAttributeWizardList == null) { this.targetAttributeWizardList = Collections.emptyList(); } else { this.targetAttributeWizardList = targetAttributeWizardList; } } /** * Constructor. * * @param target the XACML target. */ public TargetWizard(TargetType target) { this.target = target; this.targetAttributeWizardList = buildAttributeWizardList(target); } /** * Build a list of attribute wizard from the given XACML Target. * <p> * Supported targets are the ones with single SubjectType, ResourceType, ActionType and * EnvironmentType elements. * * @param target the XACML Target. * @return a list of attribute wizard from the given XACML Target. * * @throws UnsupportedTargetException if the given XACML Target is not recognized. * @throws UnsupportedAttributeException if the given XACML Target have some attributes that are * not recognized. */ private static List<AttributeWizard> buildAttributeWizardList(TargetType target) { List<AttributeWizard> attributeWizardList = new LinkedList<AttributeWizard>(); List<AttributeType> attributeList = new LinkedList<AttributeType>(); // get subjects SubjectsType subjects = target.getSubjects(); if (subjects != null) { List<SubjectType> subjectList = subjects.getSubjects(); if (!subjectList.isEmpty()) { if (subjectList.size() > 1) { throw new UnsupportedTargetException("Only one SubjectType is allowed"); } attributeList.addAll(SubjectMatchHelper.getAttributeList(subjectList.get(0).getSubjectMatches())); } } // get resources ResourcesType resources = target.getResources(); if (resources != null) { List<ResourceType> resourceList = resources.getResources(); if (!resourceList.isEmpty()) { if (resourceList.size() > 1) { throw new UnsupportedTargetException("Only one ResourceType is allowed"); } attributeList.addAll(ResourceMatchHelper.getAttributeList(resourceList.get(0).getResourceMatches())); } } // get actions ActionsType actions = target.getActions(); if (actions != null) { List<ActionType> actionList = actions.getActions(); if (!actionList.isEmpty()) { if (actionList.size() > 1) { throw new UnsupportedTargetException("Only one ActionType is allowed"); } attributeList.addAll(ActionMatchHelper.getAttributeList(actionList.get(0).getActionMatches())); } } // get environments EnvironmentsType environments = target.getEnvironments(); if (environments != null) { List<EnvironmentType> environmentList = environments.getEnvrionments(); if (!environmentList.isEmpty()) { if (environmentList.size() > 1) { throw new UnsupportedTargetException("Only one EnvironmentType is allowed"); } attributeList.addAll(EnvironmentMatchHelper.getAttributeList(environmentList.get(0).getEnvrionmentMatches())); } } // build AttributeWizard list for (AttributeType attribute : attributeList) { attributeWizardList.add(new AttributeWizard(attribute)); } return attributeWizardList; } /** * Return the list of attributes (as <code>AttributeWizard</code> objects) of this Target. * * @return the list of attributes (as <code>AttributeWizard</code> objects) of this Target. */ public List<AttributeWizard> getAttributeWizardList() { return targetAttributeWizardList; } /** * Return the <code>TargetType</code> object. * @return the <code>TargetType</code> object. */ public TargetType getXACML() { initTargetTypeIfNotSet(); return target; } /** * Check if this target is equivalent to the given one. * <p> * Two Targets are considered to be equivalent if they have the same list of attributes. * * @param target the <code>TargetType</code> to compare this target against. * @return <code>true</code> if this Target and the given one are equivalent, <code>false</code> * otherwise. */ public boolean isEquivalent(TargetType target) { if (target == null) { return false; } TargetWizard targetWizard; try { targetWizard = new TargetWizard(target); } catch (TargetWizardException e) { return false; } return isEquivalent(targetWizard); } /** * Check if this target is equivalent to the given one. * <p> * Two Targets are considered to be equivalent if they have the same list of attributes. * * @param targetWizard the <code>TargetWizard</code> to compare this target against. * @return <code>true</code> if this Target and the given one are equivalent, <code>false</code> * otherwise. */ public boolean isEquivalent(TargetWizard targetWizard) { List<AttributeWizard> attributeWizardList = targetWizard.getAttributeWizardList(); if (targetAttributeWizardList.size() != attributeWizardList.size()) { return false; } for (AttributeWizard thisAttributeWizard : targetAttributeWizardList) { boolean found = false; for (AttributeWizard attributeWizard : attributeWizardList) { if (thisAttributeWizard.equals(attributeWizard)) { found = true; break; } } if (!found) { log.debug(thisAttributeWizard.toFormattedString() + " NOT FOUND"); return false; } } return true; } /** * Release children DOM of the internal <code>TargetType</code> object. */ public void releaseChildrenDOM() { if (target != null) { target.releaseChildrenDOM(true); } } /** * Release DOM of the internal <code>TargetType</code> object. */ public void releaseDOM() { if (target != null) { target.releaseDOM(); target = null; } } /** * Build the <code>TargetType</code> object if it doesn't exist. */ private void initTargetTypeIfNotSet() { if (target == null) { setTargetType(); } } /** * Build the <code>TargetType</code> object replacing the existing one (if any). */ private void setTargetType() { releaseDOM(); List<SubjectMatchType> subjectMatchTypeList = new LinkedList<SubjectMatchType>(); for (AttributeWizard attributeWizard : targetAttributeWizardList) { if (attributeWizard.isSubjectAttribute()) { subjectMatchTypeList.add(SubjectMatchHelper.buildWithDesignator(attributeWizard.getXACML(), attributeWizard.getMatchfunction(), attributeWizard.getMatchFunctionDataType() )); } } List<ResourceMatchType> resourceMatchTypeList = new LinkedList<ResourceMatchType>(); for (AttributeWizard attributeWizard : targetAttributeWizardList) { if (attributeWizard.isResourceAttribute()) { resourceMatchTypeList.add(ResourceMatchHelper.buildWithDesignator(attributeWizard.getXACML(), attributeWizard.getMatchfunction(), attributeWizard.getMatchFunctionDataType() )); } } List<ActionMatchType> actionMatchTypeList = new LinkedList<ActionMatchType>(); for (AttributeWizard attributeWizard : targetAttributeWizardList) { if (attributeWizard.isActionAttribute()) { actionMatchTypeList.add(ActionMatchHelper.buildWithDesignator(attributeWizard.getXACML(), attributeWizard.getMatchfunction(), attributeWizard.getMatchFunctionDataType() )); } } List<EnvironmentMatchType> environmentMatchTypeList = new LinkedList<EnvironmentMatchType>(); for (AttributeWizard attributeWizard : targetAttributeWizardList) { if (attributeWizard.isEnvironmentAttribute()) { environmentMatchTypeList.add(EnvironmentMatchHelper.buildWithDesignator(attributeWizard.getXACML(), attributeWizard.getMatchfunction(), attributeWizard.getMatchFunctionDataType())); } } SubjectsType subjects = SubjectsHelper.build(SubjectHelper.build(subjectMatchTypeList)); ResourcesType resources = ResourcesHelper.build(ResourceHelper.build(resourceMatchTypeList)); ActionsType actions = ActionsHelper.build(ActionHelper.build(actionMatchTypeList)); EnvironmentsType environments = EnvironmentsHelper.build(EnvironmentHelper.build(environmentMatchTypeList)); target = TargetHelper.build(subjects, actions, resources, environments); } }