Package org.glite.authz.pap.common.xacml.wizard

Source Code of org.glite.authz.pap.common.xacml.wizard.PolicyWizard

/**
* 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.LinkedList;
import java.util.List;

import org.glite.authz.pap.common.utils.Utils;
import org.glite.authz.pap.common.xacml.impl.PolicyTypeString;
import org.glite.authz.pap.common.xacml.impl.TypeStringUtils;
import org.glite.authz.pap.common.xacml.utils.DescriptionTypeHelper;
import org.glite.authz.pap.common.xacml.utils.ObligationsHelper;
import org.glite.authz.pap.common.xacml.utils.PolicyHelper;
import org.glite.authz.pap.common.xacml.utils.XMLObjectHelper;
import org.glite.authz.pap.common.xacml.wizard.exceptions.PolicyWizardException;
import org.glite.authz.pap.common.xacml.wizard.exceptions.UnsupportedPolicyException;
import org.glite.authz.pap.common.xacml.wizard.exceptions.UnsupportedPolicySetWizardException;
import org.opensaml.xacml.policy.EffectType;
import org.opensaml.xacml.policy.ObligationType;
import org.opensaml.xacml.policy.ObligationsType;
import org.opensaml.xacml.policy.PolicyType;
import org.opensaml.xacml.policy.RuleType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* This class allows to render an action (of the simplified policy language) into an OpenSAML object
* and vice versa. The XACML policy this class produces (or recognizes) has a <i>Target</i> with one
* <i>ActionMatch</i> and a set of rules (see {@link RuleWizard}.
* <p>
* The {@link PolicyType} object (and the DOM) is build only if it is used the constructor
* {@link PolicyWizard#PolicyWizard(PolicyType)} or the method {@link PolicyWizard#getXACML()}.<br>
* In order to cut on memory usage release the PolicyType object when it's not needed by using the
* helper method {@link TypeStringUtils#releaseUnneededMemory(Object)}.
* <p>
* The {@link PolicyWizard#getXACML()} method returns an instance of {@link PolicyTypeString}.
* Therefore, if you don't have to do specific operations on it (e.g. just giving it to Axis), call
* the {@link TypeStringUtils#releaseUnneededMemory(Object)} method on it to keep only the string
* representation and save a lot of memory.
*/
public class PolicyWizard extends XACMLWizard {

    private static final Logger log = LoggerFactory.getLogger(PolicyWizard.class);

    /** Prefix used in the policyId to set a policy as private */
    protected static final String VISIBILITY_PRIVATE_PREFIX = "private";
   
    /** Prefix used in the policyId to set a policy as public */
    protected static final String VISIBILITY_PUBLIC_PREFIX = "public";
   
    protected final String actionValue;
   
    /** The action attribute on which this policy is based */
    protected static final AttributeWizardType attributeWizardType = AttributeWizardTypeConfiguration.getInstance()
                                                                                              .getActionAttributeWizard();
    protected final List<ObligationWizard> obligationWizardList = new LinkedList<ObligationWizard>();
    protected final List<RuleWizard> ruleWizardList = new LinkedList<RuleWizard>();
    protected final TargetWizard targetWizard;
   
    protected String description = null;
    protected boolean isPrivate = false;
    protected PolicyTypeString policy = null;
    protected String policyId = null;
    protected String policyIdUniqueNumber;
    protected String version = null;
   
    /**
     * Constructor that renders an action of the simplified policy language to XACML.
     *
     * @param attributeWizard the action attribute defining the <i>Target</i> of the policy.
     *
     * @throws UnsupportedPolicyException if the given attribute is not an action attribute as the
     *             one given by {@link AttributeWizardTypeConfiguration#getActionAttributeWizard()}.
     */
    public PolicyWizard(AttributeWizard attributeWizard) {

        if (attributeWizardType != attributeWizard.getAttributeWizardType()) {
            throw new UnsupportedPolicyException("Attribute not supported: " + attributeWizard.getId());
        }

        actionValue = attributeWizard.getValue();
        targetWizard = new TargetWizard(attributeWizard);

        policyId = generatePolicyId();
        version = "1";
    }

    /**
     * Constructor the renders an XACML policy to an action of the simplified policy language.
     *
     * @param policy the XACML policy.
     *
     * @throws UnsupportedPolicyException if the given XACML policy cannot be rendered to an action
     *             of the simplified policy language.
     */
    public PolicyWizard(PolicyType policy) {

        if (!(policy instanceof PolicyTypeString)) {
            throw new PolicyWizardException("Argument is not PolicyTypeString");
        }

        targetWizard = new TargetWizard(policy.getTarget());

        List<AttributeWizard> targetAttributeWizardList = targetWizard.getAttributeWizardList();
        validateTargetAttributewizardList(targetAttributeWizardList);

        policyId = policy.getPolicyId();
        decomposePolicyId(policy.getPolicyId());

        actionValue = targetAttributeWizardList.get(0).getValue();

        if (policy.getDescription() != null) {
            description = policy.getDescription().getValue();
        }

        try {
            version = policy.getVersion();
            new Integer(version);
        } catch (NumberFormatException e) {
            throw new UnsupportedPolicyException("Wrong version format", e);
        }

        if (policy.getObligations() != null) {
            List<ObligationType> obligationList = policy.getObligations().getObligations();
            for (ObligationType obligation : obligationList) {
                obligationWizardList.add(new ObligationWizard(obligation));
            }
        }

        for (RuleType rule : policy.getRules()) {
            ruleWizardList.add(new RuleWizard(rule));
        }

        this.policy = (PolicyTypeString) policy;
    }
   
    /**
     * Return the action value of the given policy.
     *
     * @param policy
     * @return the action value of the given policy.
     *
     * @throws UnsupportedPolicyException if the given policy is not an action policy.
     */
    public static String getActionValue(PolicyType policy) {
        TargetWizard targetWizard = new TargetWizard(policy.getTarget());

        List<AttributeWizard> targetAttributeWizardList = targetWizard.getAttributeWizardList();
        validateTargetAttributewizardList(targetAttributeWizardList);

        return targetAttributeWizardList.get(0).getValue();
    }

    /**
     * Increases by one the version of the given policy. If the existing version of thepolicy is
     * missing or not recognized then it is set to 1.
     *
     * @param policy the policy to increase the verion number.
     */
    public static void increaseVersion(PolicyType policy) {
        int version;

        try {
            version = (new Integer(policy.getVersion())).intValue();
            version++;
        } catch (NumberFormatException e) {
            log.error("Unrecognized version format, setting version to 1. PolicySetId=" + policy.getPolicyId());
            version = 1;
        }

        policy.setVersion(Integer.toString(version));
    }

    /**
     * Checks if the prefix of the given policy id is equal to
     * {@link PolicyWizard#VISIBILITY_PUBLIC_PREFIX}.
     *
     * @param policyId the policy id to check.
     * @return <code>true</code> if the prefix of the given policy id is equal to
     *         {@link PolicyWizard#VISIBILITY_PUBLIC_PREFIX}, <code>false</code> otherwise.
     */
    public static boolean isPrivate(String policyId) {
        return !isPublic(policyId);
    }

    /**
     * Checks if the prefix of the given policy id is not equal to
     * {@link PolicyWizard#VISIBILITY_PRIVATE_PREFIX} or missing.
     *
     * @param policyId the policy id to check.
     * @return <code>true</code> if the prefix of the given policy id is not equal to
     *         {@link PolicyWizard#VISIBILITY_PRIVATE_PREFIX} or missing, <code>false</code>
     *         otherwise.
     */
    public static boolean isPublic(String policyId) {
        String[] idTokens = policyId.split("_");

        if (idTokens.length == 0) {
            throw new UnsupportedPolicyException("Unrecognized policyId: " + policyId);
        }

        if (idTokens.length == 1) {
            return true;
        }

        if (VISIBILITY_PRIVATE_PREFIX.equals(idTokens[0])) {
            return false;
        }

        return true;
    }

    /**
     * The policy id is composed by two tokens: a prefix and an UUID. This method returns the UUID
     * part.
     *
     * @param policyId the policy id.
     * @return the UUID part of the given policy id.
     *
     * @throws UnsupportedPolicyException if the given policy id is not recognized.
     */
    private static String getIdUniqueNumber(String policyId) {

        String[] idTokens = policyId.split("_");

        if (idTokens.length == 0) {
            throw new UnsupportedPolicyException("Unrecognized policyId: " + policyId);
        }

        if (idTokens.length == 1) {
            return idTokens[0];
        }

        if (idTokens.length == 2) {
            if ((VISIBILITY_PRIVATE_PREFIX.equals(idTokens[0])) || (VISIBILITY_PUBLIC_PREFIX.equals(idTokens[0]))) {
                return idTokens[1];
            }
        }
        throw new UnsupportedPolicyException("Unrecognized policyId: " + policyId);
    }

    /**
     * Append an obligation to the list of obligations.
     *
     * @param obligationWizard the obligation to add.
     */
    public void addObligation(ObligationWizard obligationWizard) {
        obligationWizardList.add(obligationWizard);
        invalidatePolicyType();
    }

    /**
     * Add a rule which <i>Target</i> is defined by the given attribute and with the given effect.
     *
     * @param attribute the attribute used to build the Target of the rule.
     * @param effect the effect of the rule.
     */
    public void addRule(AttributeWizard attribute, EffectType effect) {
        addRule(new RuleWizard(attribute, effect));
    }

    public void addRule(int index, AttributeWizard attribute, EffectType effect) {
        addRule(index, new RuleWizard(attribute, effect));
    }

    public void addRule(int index, List<AttributeWizard> targetAttributeList, EffectType effect) {
        addRule(new RuleWizard(targetAttributeList, effect));
    }

    public void addRule(int index, RuleWizard ruleWizard) {
        ruleWizardList.add(index, ruleWizard);
        invalidatePolicyType();
    }

    public void addRule(List<AttributeWizard> targetAttributeList, EffectType effect) {
        addRule(new RuleWizard(targetAttributeList, effect));
    }

    public void addRule(RuleWizard ruleWizard) {
        ruleWizardList.add(ruleWizard);
        invalidatePolicyType();
    }

    public boolean denyRuleForAttributeExists(AttributeWizard attributeWizard) {

        for (RuleWizard ruleWizard : ruleWizardList) {
            if (ruleWizard.deniesAttribute(attributeWizard)) {
                return true;
            }
        }
        return false;
    }

    public String getDescription() {
        return description;
    }

    public int getNumberOfRules() {
        return ruleWizardList.size();
    }
   
    public String getPolicyId() {
        return policyId;
    }

    public String getPolicyIdPrefix() {
        if (isPrivate) {
            return VISIBILITY_PRIVATE_PREFIX;
        } else {
            return VISIBILITY_PUBLIC_PREFIX;
        }
    }

    public String getTagAndValue() {
        return String.format("%s \"%s\"", attributeWizardType.getId(), actionValue);
    }

    public int getVersion() {
        return Integer.valueOf(version);
    }

    public String getVersionString() {
        return version;
    }

    public PolicyType getXACML() {
        initPolicyTypeIfNotSet();
        return policy;
    }

    public void increaseVersion() {
        setVersion(getVersion() + 1);
    }

    public boolean isDOMReleased() {
        return (policy == null);
    }

    public boolean isEquivalent(PolicyType policy) {

        if (!(targetWizard.isEquivalent(policy.getTarget()))) {
            return false;
        }

        List<RuleType> ruleList = policy.getRules();

        if (ruleList.size() != ruleWizardList.size()) {
            return false;
        }

        for (int i = 0; i < ruleWizardList.size(); i++) {
            if (!(ruleWizardList.get(i).isEquivalent(ruleList.get(i)))) {
                return false;
            }
        }

        if (description != null) {
            if (!(description.equals(policy.getDescription()))) {
                return false;
            }
        } else {
            if (policy.getDescription() != null) {
                return false;
            }
        }
        return true;
    }

    public boolean isPrivate() {
        return isPrivate;
    }

    public boolean isPublic() {
        return !isPrivate;
    }

    public void releaseChildrenDOM() {
        targetWizard.releaseChildrenDOM();
        targetWizard.releaseDOM();
        for (ObligationWizard obligationWizard : obligationWizardList) {
            obligationWizard.releaseChildrenDOM();
            obligationWizard.releaseDOM();
        }
        for (RuleWizard ruleWizard : ruleWizardList) {
            ruleWizard.releaseChildrenDOM();
            ruleWizard.releaseDOM();
        }
    }

    public void releaseDOM() {
        if (policy != null) {
            policy.releaseDOM();
            policy = null;
        }
    }

    public boolean removeDenyRuleForAttribute(AttributeWizard attributeWizard) {

        for (int i = 0; i < ruleWizardList.size(); i++) {

            RuleWizard ruleWizard = ruleWizardList.get(i);

            if (ruleWizard.deniesAttribute(attributeWizard)) {

                if (policy != null) {
                    PolicyHelper.removeRule(policy, ruleWizard.getRuleId());
                }

                ruleWizardList.remove(i);
               
                return true;
            }
        }
        return false;
    }

    public void setDescription(String value) {
        this.description = value;
        if (policy != null) {
            policy.setDescription(DescriptionTypeHelper.build(value));
        }
    }

    public void setPolicyId(String policyId) {
        this.policyId = policyId;
        if (policy != null) {
            policy.setPolicyId(policyId);
        }
    }

    public void setPrivate(boolean isPrivate) {
        this.isPrivate = isPrivate;

        policyId = composeId();

        if (policy != null) {
            policy.setPolicyId(policyId);
        }
    }

    public void setVersion(int version) {
        this.version = Integer.toString(version);

        if (policy != null) {
            policy.setVersion(this.version);
        }
    }

    public String toFormattedString() {
        return toFormattedString(false);
    }

    public String toFormattedString(boolean printPolicyId) {
        return toFormattedString(0, 4, printPolicyId, false);
    }

    public String toFormattedString(int baseIndentation, int internalIndentation) {
        return toFormattedString(baseIndentation, internalIndentation, false, false);
    }

    public String toFormattedString(int baseIndentation, int internalIndentation, boolean printPolicyId, boolean printRuleIds) {

        String baseIndentString = Utils.fillWithSpaces(baseIndentation);
        String indentString = Utils.fillWithSpaces(baseIndentation + internalIndentation);
        StringBuffer sb = new StringBuffer();

        if (printPolicyId) {
            sb.append(String.format("%sid=%s\n", baseIndentString, policyId));
        }

        if (isPrivate()) {
            sb.append(String.format("%sprivate\n", baseIndentString));
        }

        sb.append(String.format("%saction \"%s\" {\n", baseIndentString, actionValue));

        if (description != null) {
            sb.append(String.format("%sdescription=\"%s\"\n", indentString, description));
        }

        for (ObligationWizard obligationWizard : obligationWizardList) {
            sb.append(obligationWizard.toFormattedString(baseIndentation + internalIndentation, internalIndentation));
            sb.append('\n');
        }

        for (RuleWizard ruleWizard : ruleWizardList) {
            if (printRuleIds) {
                sb.append('\n');
            }
            sb.append(ruleWizard.toFormattedString(baseIndentation + internalIndentation, internalIndentation, printRuleIds));
            sb.append('\n');
        }

        sb.append(baseIndentString + "}");

        return sb.toString();
    }

    public String toXACMLString() {
        initPolicyTypeIfNotSet();
        return XMLObjectHelper.toString(policy);
    }

    /**
     * Return the effective policy id by composing the prefix and the UUID.
     *
     * @return the effective policy id.
     */
    private String composeId() {
        return getPolicyIdPrefix() + "_" + policyIdUniqueNumber;
    }

    /**
     * Set the members {@link PolicyWizard#isPrivate}, {@link PolicyWizard#policyIdUniqueNumber} and
     * {@link PolicyWizard#policyIdVisibilityPrefix} from the given policy id.
     *
     * @param policyId the policy id to decompose.
     *
     * @throws UnsupportedPolicyException if the given policy id format is not recognized.
     */
    private void decomposePolicyId(String policyId) {
        isPrivate = isPrivate(policyId);
        policyIdUniqueNumber = getIdUniqueNumber(policyId);
    }

    /**
     * Return a new generated policy id.
     *
     * @return a new generated policy id.
     */
    private String generatePolicyId() {
        policyIdUniqueNumber = WizardUtils.generateId(null);
        return composeId();
    }

    /**
     * Build the PolicyType object if it doesn't already exits.
     */
    private void initPolicyTypeIfNotSet() {
        if (policy == null) {
            log.debug("Initializing policyType");
            setPolicyType();
        } else {
            log.debug("policyType already initialized");
        }
    }

    /**
     * Release the memory used for the PolicyType object.
     */
    private void invalidatePolicyType() {
        releaseChildrenDOM();
        releaseDOM();
    }

    /**
     * Build (or re-build if already exists) the PolicyType object.
     */
    private void setPolicyType() {

        releaseDOM();

        policy = new PolicyTypeString(PolicyHelper.build(policyId, PolicyHelper.RULE_COMBALG_FIRST_APPLICABLE));

        if (description != null) {
            policy.setDescription(DescriptionTypeHelper.build(description));
        }

        policy.setTarget(targetWizard.getXACML());
        policy.setVersion(version);

        if (obligationWizardList.size() > 0) {
            ObligationsType obligations = ObligationsHelper.build();
            List<ObligationType> obligationList = obligations.getObligations();
            for (ObligationWizard obligationWizard : obligationWizardList) {
                obligationList.add(obligationWizard.getXACML());
            }

            policy.setObligations(obligations);
        }

        for (RuleWizard ruleWizard : ruleWizardList) {
            policy.getRules().add(ruleWizard.getXACML());
        }
    }

    /**
     * Checks if the given target attribute wizard list can be used to build an action of the
     * simplified policy language.
     *
     * @param targetAttributeWizardList the list of wizard attributes to validate.
     *
     * @throws UnsupportedPolicyException if the validation fails.
     */
    private static void validateTargetAttributewizardList(List<AttributeWizard> targetAttributeWizardList) {

        if (targetAttributeWizardList == null) {
            throw new UnsupportedPolicySetWizardException("targetAttributeWizardList is null");
        }

        if (targetAttributeWizardList.size() != 1) {
            throw new UnsupportedPolicySetWizardException("Only one action attribute is supported (found "
                    + targetAttributeWizardList.size() + " attributes)");
        }

        AttributeWizard aw = targetAttributeWizardList.get(0);

        if (aw.getAttributeWizardType() != attributeWizardType) {
            throw new UnsupportedPolicySetWizardException("Only one action attribute is supported");
        }
    }
}
TOP

Related Classes of org.glite.authz.pap.common.xacml.wizard.PolicyWizard

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.