示例#1
0
        /// <summary>
        /// Evaluates the variable into a value.
        /// </summary>
        /// <param name="context">The contex of the evaluation.</param>
        /// <returns>The value of the function.</returns>
        public EvaluationValue Evaluate(EvaluationContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            context.Trace("Evaluating variable");
            context.AddIndent();

            try
            {
                if (_variableDefinition.Expression is pol.ApplyElement)
                {
                    context.Trace("Apply within condition.");

                    // There is a nested apply un this policy a new Apply will be created and also
                    // evaluated. It's return value will be used as the processed argument.
                    Apply _childApply = new Apply((pol.ApplyElement)_variableDefinition.Expression);

                    // Evaluate the Apply
                    _value = _childApply.Evaluate(context);

                    context.TraceContextValues();
                    return(_value);
                }
                else if (_variableDefinition.Expression is pol.FunctionElement)
                {
                    throw new NotImplementedException("FunctionElement");                       //TODO:
                }
                else if (_variableDefinition.Expression is pol.VariableReferenceElement)
                {
                    pol.VariableReferenceElement variableRef = _variableDefinition.Expression as pol.VariableReferenceElement;
                    VariableDefinition           variableDef = context.CurrentPolicy.VariableDefinition[variableRef.VariableId] as VariableDefinition;

                    context.TraceContextValues();

                    if (!variableDef.IsEvaluated)
                    {
                        return(variableDef.Evaluate(context));
                    }
                    else
                    {
                        return(variableDef.Value);
                    }
                }
                else if (_variableDefinition.Expression is pol.AttributeValueElementReadWrite)
                {
                    // The AttributeValue does not need to be processed
                    context.Trace("Attribute value {0}", _variableDefinition.Expression.ToString());

                    pol.AttributeValueElementReadWrite att            = (pol.AttributeValueElementReadWrite)_variableDefinition.Expression;
                    pol.AttributeValueElement          attributeValue = new pol.AttributeValueElement(att.DataType, att.Contents, att.SchemaVersion);

                    _value = new EvaluationValue(
                        attributeValue.GetTypedValue(attributeValue.GetType(context), 0),
                        attributeValue.GetType(context));
                    return(_value);
                }
                else if (_variableDefinition.Expression is pol.AttributeDesignatorBase)
                {
                    // Resolve the AttributeDesignator using the EvaluationEngine public methods.
                    context.Trace("Processing attribute designator: {0}", _variableDefinition.Expression.ToString());

                    pol.AttributeDesignatorBase attrDes = (pol.AttributeDesignatorBase)_variableDefinition.Expression;
                    BagValue bag = EvaluationEngine.Resolve(context, attrDes);

                    // If the attribute was not resolved by the EvaluationEngine search the
                    // attribute in the context document, also using the EvaluationEngine public
                    // methods.
                    if (bag.BagSize == 0)
                    {
                        if (_variableDefinition.Expression is pol.SubjectAttributeDesignatorElement)
                        {
                            ctx.AttributeElement attrib = EvaluationEngine.GetAttribute(context, attrDes);
                            if (attrib != null)
                            {
                                context.Trace("Adding subject attribute designator: {0}", attrib.ToString());
                                bag.Add(attrib);
                            }
                        }
                        else if (_variableDefinition.Expression is pol.ResourceAttributeDesignatorElement)
                        {
                            ctx.AttributeElement attrib = EvaluationEngine.GetAttribute(context, attrDes);
                            if (attrib != null)
                            {
                                context.Trace("Adding resource attribute designator {0}", attrib.ToString());
                                bag.Add(attrib);
                            }
                        }
                        else if (_variableDefinition.Expression is pol.ActionAttributeDesignatorElement)
                        {
                            ctx.AttributeElement attrib = EvaluationEngine.GetAttribute(context, attrDes);
                            if (attrib != null)
                            {
                                context.Trace("Adding action attribute designator {0}", attrib.ToString());
                                bag.Add(attrib);
                            }
                        }
                        else if (_variableDefinition.Expression is pol.EnvironmentAttributeDesignatorElement)
                        {
                            ctx.AttributeElement attrib = EvaluationEngine.GetAttribute(context, attrDes);
                            if (attrib != null)
                            {
                                context.Trace("Adding environment attribute designator {0}", attrib.ToString());
                                bag.Add(attrib);
                            }
                        }
                    }

                    // If the argument was not found and the attribute must be present this is
                    // a MissingAttribute situation so set the flag. Otherwise add the attribute
                    // to the processed arguments.
                    if (bag.BagSize == 0 && attrDes.MustBePresent)
                    {
                        context.Trace("Attribute is missing");
                        context.IsMissingAttribute = true;
                        context.AddMissingAttribute(attrDes);
                        _value = EvaluationValue.Indeterminate;
                    }
                    else
                    {
                        _value = new EvaluationValue(bag, bag.GetType(context));
                    }
                    return(_value);
                }
                else if (_variableDefinition.Expression is pol.AttributeSelectorElement)
                {
                    // Resolve the XPath query using the EvaluationEngine public methods.
                    context.Trace("Attribute selector");
                    try
                    {
                        pol.AttributeSelectorElement attributeSelector = (pol.AttributeSelectorElement)_variableDefinition.Expression;
                        BagValue bag = EvaluationEngine.Resolve(context, attributeSelector);
                        if (bag.Elements.Count == 0 && attributeSelector.MustBePresent)
                        {
                            context.Trace("Attribute is missing");
                            context.IsMissingAttribute = true;
                            context.AddMissingAttribute(attributeSelector);
                            _value = EvaluationValue.Indeterminate;
                        }
                        else
                        {
                            _value = new EvaluationValue(bag, bag.GetType(context));
                        }
                    }
                    catch (EvaluationException e)
                    {
                        context.Trace("ERR: {0}", e.Message);
                        context.ProcessingError = true;
                        _value = EvaluationValue.Indeterminate;
                    }
                    return(_value);
                }
                throw new NotSupportedException("internal error");
            }
            finally
            {
                _isEvaluated = true;
                context.RemoveIndent();
            }
        }
示例#2
0
        /// <summary>
        /// Evaluates the target items and return wether the target applies to the context or not.
        /// </summary>
        /// <param name="context">The evaluation context instance.</param>
        /// <param name="targetItem">The target item in the context document.</param>
        /// <returns></returns>
        public virtual TargetEvaluationValue Evaluate(EvaluationContext context, ctx.TargetItemBase targetItem)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (_targetItems.IsAny)
            {
                context.Trace("IsAny");
                return(TargetEvaluationValue.Match);
            }

            _evaluationValue = TargetEvaluationValue.NoMatch;

            //Match TargetItem
            foreach (TargetItemBase polItem in _targetItems.ItemsList)
            {
                foreach (TargetMatchBase match in polItem.Match)
                {
                    _evaluationValue = TargetEvaluationValue.NoMatch;

                    context.Trace("Using function: {0}", match.MatchId);

                    IFunction matchFunction = EvaluationEngine.GetFunction(match.MatchId);
                    if (matchFunction == null)
                    {
                        context.Trace("ERR: function not found {0}", match.MatchId);
                        context.ProcessingError = true;
                        return(TargetEvaluationValue.Indeterminate);
                    }
                    else if (matchFunction.Returns == null)
                    {
                        // Validates the function return value
                        context.Trace("ERR: The function '{0}' does not defines it's return value", match.MatchId);
                        context.ProcessingError = true;
                        return(TargetEvaluationValue.Indeterminate);
                    }
                    else if (matchFunction.Returns != DataTypeDescriptor.Boolean)
                    {
                        context.Trace("ERR: Function does not return Boolean a value");
                        context.ProcessingError = true;
                        return(TargetEvaluationValue.Indeterminate);
                    }
                    else
                    {
                        Context.AttributeElement attribute = EvaluationEngine.Resolve(context, match, targetItem);

                        if (attribute != null)
                        {
                            context.Trace("Attribute found, evaluating match function");
                            try
                            {
                                EvaluationValue returnValue = EvaluationEngine.EvaluateFunction(context, matchFunction, match.AttributeValue, attribute);
                                _evaluationValue = returnValue.BoolValue ? TargetEvaluationValue.Match : TargetEvaluationValue.NoMatch;
                            }
                            catch (EvaluationException e)
                            {
                                context.Trace("ERR: {0}", e.Message);
                                _evaluationValue = TargetEvaluationValue.Indeterminate;
                            }
                        }

                        // Validate MustBePresent
                        if (match.AttributeReference.MustBePresent)
                        {
                            if (context.IsMissingAttribute)
                            {
                                context.Trace("Attribute not found and must be present");
                                _evaluationValue = TargetEvaluationValue.Indeterminate;
                            }
                        }

                        if (context.ProcessingError)
                        {
                            _evaluationValue = TargetEvaluationValue.Indeterminate;
                        }

                        // Do not iterate if the value was found
                        if (_evaluationValue != TargetEvaluationValue.Match)
                        {
                            break;
                        }
                    }
                }

                // Do not iterate if the value was found
                if (_evaluationValue == TargetEvaluationValue.Match)
                {
                    return(_evaluationValue);
                }
            }

            return(_evaluationValue);
        }
示例#3
0
        /// <summary>
        /// THe argument processing method resolves all the attribute designators, attribute
        /// selectors. If there is an internal Apply it will be evaulated within this method.
        /// </summary>
        /// <remarks>All the processed arguments are converted into an IFunctionParameter instance
        /// because this is the only value that can be used to call a function.</remarks>
        /// <param name="context">The evaluation context instance.</param>
        /// <param name="arguments">The arguments to process.</param>
        /// <returns>A list of arguments ready to be used by a function.</returns>
        private FunctionParameterCollection ProcessArguments(EvaluationContext context, ExpressionCollection arguments)
        {
            context.Trace("Processing arguments");
            context.AddIndent();

            // Create a list to return the processed values.
            var processedArguments = new FunctionParameterCollection();

            // Iterate through the arguments, the IExpressionType is a mark interface
            foreach (IExpression arg in arguments)
            {
                var apply = arg as ApplyElement;
                if (apply != null)
                {
                    context.Trace("Nested apply");

                    // There is a nested apply un this policy a new Apply will be created and also
                    // evaluated. It's return value will be used as the processed argument.
                    var childApply = new Apply(apply);

                    // Evaluate the Apply
                    EvaluationValue retVal = childApply.Evaluate(context);

                    context.TraceContextValues();

                    // If the results were Indeterminate the Indeterminate value will be placed in
                    // the processed arguments, later another method will validate the parameters
                    // and cancel the evaluation propperly.
                    if (!retVal.IsIndeterminate)
                    {
                        if (!context.IsMissingAttribute)
                        {
                            processedArguments.Add(retVal);
                        }
                    }
                    else
                    {
                        processedArguments.Add(retVal);
                    }
                }
                else
                {
                    var write = arg as FunctionElementReadWrite;
                    if (write != null)
                    {
                        // Search for the function and place it in the processed arguments.
                        var functionId = new FunctionElement(write.FunctionId, write.SchemaVersion);

                        context.Trace("Function {0}", functionId.FunctionId);
                        IFunction function = EvaluationEngine.GetFunction(functionId.FunctionId);
                        if (function == null)
                        {
                            context.Trace("ERR: function not found {0}", _applyBase.FunctionId);
                            context.ProcessingError = true;
                            processedArguments.Add(EvaluationValue.Indeterminate);
                        }
                        else
                        {
                            processedArguments.Add(function);
                        }
                    }
                    else if (arg is VariableReferenceElement)
                    {
                        var variableRef = arg as VariableReferenceElement;
                        var variableDef = context.CurrentPolicy.VariableDefinition[variableRef.VariableId] as VariableDefinition;

                        context.TraceContextValues();

                        Debug.Assert(variableDef != null, "variableDef != null");
                        processedArguments.Add(!variableDef.IsEvaluated ? variableDef.Evaluate(context) : variableDef.Value);
                    }
                    else
                    {
                        var readWrite = arg as AttributeValueElementReadWrite;
                        if (readWrite != null)
                        {
                            // The AttributeValue does not need to be processed
                            context.Trace("Attribute value {0}", arg.ToString());
                            processedArguments.Add(new AttributeValueElement(readWrite.DataType, readWrite.Contents, readWrite.SchemaVersion));
                        }
                        else
                        {
                            var des = arg as AttributeDesignatorBase;
                            if (des != null)
                            {
                                // Resolve the AttributeDesignator using the EvaluationEngine public methods.
                                context.Trace("Processing attribute designator: {0}", arg.ToString());

                                var      attrDes = des;
                                BagValue bag     = EvaluationEngine.Resolve(context, attrDes);

                                // If the attribute was not resolved by the EvaluationEngine search the
                                // attribute in the context document, also using the EvaluationEngine public
                                // methods.
                                if (bag.BagSize == 0)
                                {
                                    if (arg is SubjectAttributeDesignatorElement)
                                    {
                                        ctx.AttributeElement attrib = EvaluationEngine.GetAttribute(context, attrDes);
                                        if (attrib != null)
                                        {
                                            context.Trace("Adding subject attribute designator: {0}", attrib.ToString());
                                            bag.Add(attrib);
                                            break;
                                        }
                                    }
                                    else if (arg is ResourceAttributeDesignatorElement)
                                    {
                                        ctx.AttributeElement attrib = EvaluationEngine.GetAttribute(context, attrDes);
                                        if (attrib != null)
                                        {
                                            context.Trace("Adding resource attribute designator {0}", attrib.ToString());
                                            bag.Add(attrib);
                                        }
                                    }
                                    else if (arg is ActionAttributeDesignatorElement)
                                    {
                                        ctx.AttributeElement attrib = EvaluationEngine.GetAttribute(context, attrDes);
                                        if (attrib != null)
                                        {
                                            context.Trace("Adding action attribute designator {0}", attrib.ToString());
                                            bag.Add(attrib);
                                        }
                                    }
                                    else if (arg is EnvironmentAttributeDesignatorElement)
                                    {
                                        ctx.AttributeElement attrib = EvaluationEngine.GetAttribute(context, attrDes);
                                        if (attrib != null)
                                        {
                                            context.Trace("Adding environment attribute designator {0}", attrib.ToString());
                                            bag.Add(attrib);
                                        }
                                    }
                                }

                                // If the argument was not found and the attribute must be present this is
                                // a MissingAttribute situation so set the flag. Otherwise add the attribute
                                // to the processed arguments.
                                if (bag.BagSize == 0 && attrDes.MustBePresent)
                                {
                                    context.Trace("Attribute is missing");
                                    context.IsMissingAttribute = true;
                                    context.AddMissingAttribute(attrDes);
                                }
                                else
                                {
                                    processedArguments.Add(bag);
                                }
                            }
                            else
                            {
                                var @base = arg as AttributeSelectorElement;
                                if (@base != null)
                                {
                                    // Resolve the XPath query using the EvaluationEngine public methods.
                                    context.Trace("Attribute selector");
                                    try
                                    {
                                        BagValue bag = EvaluationEngine.Resolve(context, @base);
                                        if (bag.Elements.Count == 0 && @base.MustBePresent)
                                        {
                                            context.Trace("Attribute is missing");
                                            context.IsMissingAttribute = true;
                                            context.AddMissingAttribute(@base);
                                        }
                                        else
                                        {
                                            processedArguments.Add(bag);
                                        }
                                    }
                                    catch (EvaluationException e)
                                    {
                                        context.Trace("ERR: {0}", e.Message);
                                        processedArguments.Add(EvaluationValue.Indeterminate);
                                        context.ProcessingError = true;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            context.RemoveIndent();

            return(processedArguments);
        }
示例#4
0
        /// <summary>
        /// Creates a new runtime policy set evaluation.
        /// </summary>
        /// <param name="engine">The evaluation engine.</param>
        /// <param name="policySet">The policy set defined in the policy document.</param>
        public PolicySet(EvaluationEngine engine, PolicySetElement policySet)
        {
            if (engine == null)
            {
                throw new ArgumentNullException("engine");
            }
            if (policySet == null)
            {
                throw new ArgumentNullException("policySet");
            }
            _policySet = policySet;

            // Create a runtime target of this policy set.
            if (policySet.Target != null)
            {
                _target = new Target((TargetElement)policySet.Target);

                foreach (ResourceElement resource in policySet.Target.Resources.ItemsList)
                {
                    foreach (ResourceMatchElement rmatch in resource.Match)
                    {
                        if (!_allResources.Contains(rmatch.AttributeValue.Contents))
                        {
                            _allResources.Add(rmatch.AttributeValue.Contents);
                        }
                    }
                }
            }

            // Add all the policies (or policy set) inside this policy set.
            foreach (object child in policySet.Policies)
            {
                var childPolicySet                = child as PolicySetElement;
                var childPolicyElement            = child as PolicyElement;
                var childPolicySetIdReference     = child as PolicySetIdReferenceElement;
                var childPolicyIdReferenceElement = child as PolicyIdReferenceElement;
                if (childPolicySet != null)
                {
                    var policySetEv = new PolicySet(engine, childPolicySet);
                    foreach (string rName in policySetEv.AllResources)
                    {
                        if (!_allResources.Contains(rName))
                        {
                            _allResources.Add(rName);
                        }
                    }
                    _policies.Add(policySetEv);
                }
                else if (childPolicyElement != null)
                {
                    var policyEv = new Policy(childPolicyElement);
                    foreach (string rName in policyEv.AllResources)
                    {
                        if (!_allResources.Contains(rName))
                        {
                            _allResources.Add(rName);
                        }
                    }
                    _policies.Add(policyEv);
                }
                else if (childPolicySetIdReference != null)
                {
                    PolicySetElement policySetDefinition = EvaluationEngine.Resolve(childPolicySetIdReference);
                    if (policySetDefinition != null)
                    {
                        var policySetEv = new PolicySet(engine, policySetDefinition);
                        foreach (string rName in policySetEv.AllResources)
                        {
                            if (!_allResources.Contains(rName))
                            {
                                _allResources.Add(rName);
                            }
                        }
                        _policies.Add(policySetEv);
                    }
                    else
                    {
                        throw new EvaluationException(string.Format(Properties.Resource.exc_policyset_reference_not_resolved, ((PolicySetIdReferenceElement)child).PolicySetId));
                    }
                }
                else if (childPolicyIdReferenceElement != null)
                {
                    PolicyElement policyDefinition = EvaluationEngine.Resolve(childPolicyIdReferenceElement);
                    if (policyDefinition != null)
                    {
                        var policyEv = new Policy(policyDefinition);
                        foreach (string rName in policyEv.AllResources)
                        {
                            if (!_allResources.Contains(rName))
                            {
                                _allResources.Add(rName);
                            }
                        }
                        _policies.Add(policyEv);
                    }
                    else
                    {
                        throw new EvaluationException(string.Format(Properties.Resource.exc_policy_reference_not_resolved, ((PolicyIdReferenceElement)child).PolicyId));
                    }
                }
            }
        }