/// <summary>
        /// The evaluation implementation in the pseudo-code described in the specification.
        /// </summary>
        /// <param name="context">The evaluation context instance.</param>
        /// <param name="policies">The policies that must be evaluated.</param>
        /// <returns>The final decission for the combination of the policy evaluation.</returns>
        public Decision Evaluate(EvaluationContext context, MatchEvaluableCollection policies)
        {
            foreach (IMatchEvaluable policy in policies)
            {
                Decision decision = policy.Evaluate(context);

                context.TraceContextValues();

                if (decision == Decision.Deny)
                {
                    context.ProcessingError = false;
                    context.IsMissingAttribute = false;
                    return Decision.Deny;
                }
                if (decision == Decision.Permit)
                {
                    context.ProcessingError = false;
                    context.IsMissingAttribute = false;
                    return Decision.Permit;
                }
                if (decision == Decision.NotApplicable)
                {
                    continue;
                }
                if (decision == Decision.Indeterminate)
                {
                    return Decision.Indeterminate;
                }
            }
            return Decision.NotApplicable;
        }
        /// <summary>
        /// The evaluation implementation in the pseudo-code described in the specification.
        /// </summary>
        /// <param name="context">The evaluation context instance.</param>
        /// <param name="policies">The policies that must be evaluated.</param>
        /// <returns>The final decission for the combination of the policy evaluation.</returns>
        public Decision Evaluate(EvaluationContext context, MatchEvaluableCollection policies)
        {
            Boolean atLeastOne = false;
            Policy selectedPolicy = null;
            TargetEvaluationValue appResult;
            for (int i = 0; i < policies.Count; i++)
            {
                Policy tempPolicy = (Policy)policies[i];
                appResult = appResult = tempPolicy.Match(context);
                if (appResult == TargetEvaluationValue.Indeterminate)
                {
                    context.ProcessingError = true;
                    context.TraceContextValues();
                    return Decision.Indeterminate;
                }
                if (appResult == TargetEvaluationValue.Match)
                {
                    if (atLeastOne)
                    {
                        context.ProcessingError = true;
                        context.TraceContextValues();
                        return Decision.Indeterminate;
                    }
                    else
                    {
                        atLeastOne = true;
                        selectedPolicy = (Policy)policies[i];
                    }
                }
                if (appResult == TargetEvaluationValue.NoMatch)
                {
                    continue;
                }
            }
            if (atLeastOne)
            {
                Decision retValue = selectedPolicy.Evaluate(context);

                context.TraceContextValues();

                if (retValue == Decision.Deny || retValue == Decision.Permit)
                {
                    context.ProcessingError = false;
                    context.IsMissingAttribute = false;
                }
                return retValue;
            }
            else
            {
                return Decision.NotApplicable;
            }
        }
 /// <summary>
 /// Method called by the EvaluationEngine when an attribute is not found.
 /// </summary>
 /// <param name="context">The evaluation context instance.</param>
 /// <param name="designator">The attribute designator.</param>
 /// <returns>An instance of an Attribute with it's value.</returns>
 public AttributeElement GetAttribute(EvaluationContext context, AttributeDesignatorBase designator)
 {
     if (context == null) throw new ArgumentNullException("context");
     if (designator == null) throw new ArgumentNullException("designator");
     foreach (var attrib in _attributes.Cast<AttributeElement>().Where(attrib => attrib.AttributeId == designator.AttributeId))
     {
         if (!string.IsNullOrEmpty(designator.Issuer))
         {
             if (designator.Issuer == attrib.Issuer)
             {
                 return attrib;
             }
         }
         else
         {
             return attrib;
         }
     }
     return null;
 }
예제 #4
0
        /// <summary>
        /// Main evaluation method which is divided in two phases: Argument processing and 
        /// Function evaluation.
        /// </summary>
        /// <param name="context">The evaluation context instance.</param>
        /// <returns>The result of the evaluation in an EvaluationValue instance.</returns>
        public virtual EvaluationValue Evaluate(EvaluationContext context)
        {
            if (context == null) throw new ArgumentNullException("context");
            // Validate the function exists
            context.Trace("Calling function: {0}", _applyBase.FunctionId);
            IFunction function = EvaluationEngine.GetFunction(_applyBase.FunctionId);
            if (function == null)
            {
                context.Trace("ERR: function not found {0}", _applyBase.FunctionId);
                context.ProcessingError = true;
                return EvaluationValue.Indeterminate;
            }

            // Process the arguments.
            FunctionParameterCollection arguments = ProcessArguments(context, new ExpressionCollection((ExpressionReadWriteCollection)_applyBase.Arguments));

            // Call the function with the arguments processed.
            EvaluationValue returnValue = EvaluationEngine.EvaluateFunction(context, function, arguments.ToArray());
            return returnValue;
        }
		/// <summary>
		/// The evaluation implementation in the pseudo-code described in the specification.
		/// </summary>
		/// <param name="context">The evaluation context instance.</param>
		/// <param name="rules">The policies that must be evaluated.</param>
		/// <returns>The final decission for the combination of the rule evaluation.</returns>
		public Decision Evaluate( EvaluationContext context, RuleCollection rules )
		{
			var decision = Decision.Indeterminate;
			context.Trace( "Evaluating rules..." );
			context.AddIndent();
			try
			{
				foreach( Rule rule in rules )
				{
					decision = rule.Evaluate( context );
					context.TraceContextValues();

					if( decision == Decision.Deny )
					{
						decision = Decision.Deny;
						return decision;
					}
					if( decision == Decision.Permit )
					{
						decision = Decision.Permit;
						return decision;
					}
					if( decision == Decision.NotApplicable )
					{
						continue;
					}
					if( decision == Decision.Indeterminate )
					{
						decision = Decision.Indeterminate;
						return decision;
					}
				}
				return Decision.NotApplicable;
			}
			finally
			{
				context.Trace( "Rule combination algorithm: {0}", decision.ToString() );
				context.RemoveIndent();
			}
		}
 /// <summary>
 /// The evaluation implementation in the pseudo-code described in the specification.
 /// </summary>
 /// <param name="context">The evaluation context instance.</param>
 /// <param name="policies">The policies that must be evaluated.</param>
 /// <returns>The final decission for the combination of the policy evaluation.</returns>
 public Decision Evaluate(EvaluationContext context, MatchEvaluableCollection policies)
 {
     if (context == null) throw new ArgumentNullException("context");
     if (policies == null) throw new ArgumentNullException("policies");
     bool atLeastOnePermit = false;
     foreach (IMatchEvaluable policy in policies)
     {
         Decision decision = policy.Evaluate(context);
         if (decision == Decision.Deny)
         {
             context.ProcessingError = false;
             context.IsMissingAttribute = false;
             return Decision.Deny;
         }
         if (decision == Decision.Permit)
         {
             atLeastOnePermit = true;
             continue;
         }
         if (decision == Decision.NotApplicable)
         {
             continue;
         }
         if (decision == Decision.Indeterminate)
         {
             context.ProcessingError = false;
             context.IsMissingAttribute = false;
             return Decision.Deny;
         }
     }
     if (atLeastOnePermit)
     {
         context.ProcessingError = false;
         context.IsMissingAttribute = false;
         return Decision.Permit;
     }
     return Decision.NotApplicable;
 }
예제 #7
0
파일: Rule.cs 프로젝트: mingkongbin/anycmd
        /// <summary>
        /// Verifies if the rule target matches
        /// </summary>
        /// <param name="context">The evaluation context instance.</param>
        /// <returns>The result of the Match process.</returns>
        public TargetEvaluationValue Match(EvaluationContext context)
        {
            if (context == null) throw new ArgumentNullException("context");
            TargetEvaluationValue targetEvaluationValue = TargetEvaluationValue.Indeterminate;
            context.Trace("Evaluating rule target");
            context.AddIndent();
            try
            {
                // Evaluate the policy target
                targetEvaluationValue = TargetEvaluationValue.Match;
                if (_target != null)
                {
                    targetEvaluationValue = _target.Evaluate(context);

                    context.TraceContextValues();
                }
                return targetEvaluationValue;
            }
            finally
            {
                context.RemoveIndent();
                context.Trace("Target: {0}", targetEvaluationValue);
            }
        }
        /// <summary>
        /// The evaluation implementation in the pseudo-code described in the specification.
        /// </summary>
        /// <param name="context">The evaluation context instance.</param>
        /// <param name="rules">The policies that must be evaluated.</param>
        /// <returns>The final decission for the combination of the rule evaluation.</returns>
        public Decision Evaluate(EvaluationContext context, RuleCollection rules)
        {
            if (context == null) throw new ArgumentNullException("context");
            if (rules == null) throw new ArgumentNullException("rules");
            var decision = Decision.Indeterminate;
            bool atLeastOneError = false;
            bool potentialPermit = false;
            bool atLeastOneDeny = false;

            context.Trace("Evaluating rules...");
            context.AddIndent();
            try
            {
                foreach (Rule rule in rules)
                {
                    decision = rule.Evaluate(context);

                    context.TraceContextValues();

                    if (decision == Decision.Deny)
                    {
                        atLeastOneDeny = true;
                        continue;
                    }
                    if (decision == Decision.Permit)
                    {
                        decision = Decision.Permit;
                        return decision;
                    }
                    if (decision == Decision.NotApplicable)
                    {
                        continue;
                    }
                    if (decision == Decision.Indeterminate)
                    {
                        atLeastOneError = true;
                        if (rule.RuleDefinition.Effect == Effect.Permit)
                        {
                            potentialPermit = true;
                        }
                        continue;
                    }
                }
                if (potentialPermit)
                {
                    decision = Decision.Indeterminate;
                    return decision;
                }
                if (atLeastOneDeny)
                {
                    decision = Decision.Deny;
                    return decision;
                }
                if (atLeastOneError)
                {
                    decision = Decision.Indeterminate;
                    return decision;
                }
                decision = Decision.NotApplicable;
                return decision;
            }
            finally
            {
                context.Trace("Rule combination algorithm: {0}", decision.ToString());
                context.RemoveIndent();
            }
        }
예제 #9
0
        /// <summary>
        /// Matches this target instance using the context document.
        /// </summary>
        /// <param name="context">The evaluation context instance.</param>
        /// <returns>The results of the evaluation of this target.</returns>
        public TargetEvaluationValue Evaluate(EvaluationContext context)
        {
            if (context == null) throw new ArgumentNullException("context");
            // Set the default value.
            _evaluationValue = TargetEvaluationValue.NoMatch;

            // Resource
            context.Trace("Evaluating Resource...");
            context.AddIndent();

            TargetEvaluationValue resourceEval = _resources.Evaluate(context, context.CurrentResource);

            context.TraceContextValues();
            context.Trace("Target item result: {0}", resourceEval);
            context.RemoveIndent();

            // Action
            context.Trace("Evaluating Action...");
            context.AddIndent();

            TargetEvaluationValue actionEval = _actions.Evaluate(context, context.ContextDocument.Request.Action);

            context.TraceContextValues();
            context.Trace("Target item result: {0}", actionEval);
            context.RemoveIndent();

            context.Trace("Evaluating Subjects...");
            context.AddIndent();
            if (actionEval == TargetEvaluationValue.Match && resourceEval == TargetEvaluationValue.Match)
            {
                // Subjects
                foreach (ctx.SubjectElement ctxSubject in context.ContextDocument.Request.Subjects)
                {
                    context.Trace("Evaluating Subject: {0}", ctxSubject.SubjectCategory);

                    // Subject
                    TargetEvaluationValue subjectEval = _subjects.Evaluate(context, ctxSubject);

                    context.TraceContextValues();
                    if (subjectEval == TargetEvaluationValue.Indeterminate)
                    {
                        _evaluationValue = TargetEvaluationValue.Indeterminate;
                    }
                    else if (subjectEval == TargetEvaluationValue.Match)
                    {
                        _evaluationValue = TargetEvaluationValue.Match;
                        context.RemoveIndent();
                        context.Trace("Target item result: {0}", _evaluationValue);
                        return _evaluationValue;
                    }
                }
                context.RemoveIndent();
                context.Trace("Target item result: {0}", _evaluationValue);
                return _evaluationValue;
            }
            else
            {
                context.Trace("Actions or Resources does not Match so Subjects will not be evaluated");
                if (resourceEval == TargetEvaluationValue.Indeterminate || actionEval == TargetEvaluationValue.Indeterminate)
                {
                    context.RemoveIndent();
                    return TargetEvaluationValue.Indeterminate;
                }
                else
                {
                    context.RemoveIndent();
                    return TargetEvaluationValue.NoMatch;
                }
            }

        }
예제 #10
0
		/// <summary>
		/// Search for the attribute in the context target item using the attribute designator specified.
		/// </summary>
		/// <param name="context">The evaluation context instance.</param>
		/// <param name="attributeDesignator">The attribute designator instance.</param>
		/// <param name="targetItem">The target item to search in.</param>
		/// <returns>A bag value with the values of the attributes found.</returns>
		public static BagValue FindAttribute(EvaluationContext context, pol.AttributeDesignatorBase attributeDesignator, ctx.TargetItemBase targetItem)
		{
			var bag = new BagValue(GetDataType(attributeDesignator.DataType));
			foreach (ctx.AttributeElement attribute in targetItem.Attributes)
			{
				if (attribute.Match(attributeDesignator))
				{
					context.Trace("Adding target item attribute designator: {0}", attribute.ToString());
					bag.Add(attribute);
				}
			}
			return bag;
		}
예제 #11
0
		/// <summary>
		/// Resolves the AttributeSelector in the context document using the XPath sentence.
		/// </summary>
		/// <param name="context">The evaluation context instance.</param>
		/// <param name="attributeSelector">The attribute selector.</param>
		/// <returns>A bag of values with the contents of the node.</returns>
		public static BagValue Resolve(EvaluationContext context, pol.AttributeSelectorElement attributeSelector)
		{
			var bagValue = new BagValue(GetDataType(attributeSelector.DataType));
			var content = (ctx.ResourceContentElement)context.CurrentResource.ResourceContent;
			if (content != null)
			{
				XmlDocument doc = context.ContextDocument.XmlDocument;
				if (context.ContextDocument.XmlNamespaceManager == null)
				{
					context.ContextDocument.AddNamespaces(context.PolicyDocument.Namespaces);
				}
				try
				{
					string xpath = attributeSelector.RequestContextPath;
					Debug.Assert(doc.DocumentElement != null, "doc.DocumentElement != null");
					XmlNodeList nodeList = doc.DocumentElement.SelectNodes(xpath, context.ContextDocument.XmlNamespaceManager);
					if (nodeList != null)
					{
						foreach (XmlNode node in nodeList)
						{
							var ave =
								new pol.AttributeValueElement(
								attributeSelector.DataType,
								node.InnerText,
								attributeSelector.SchemaVersion);
							bagValue.Add(ave);
						}
					}
				}
				catch (XPathException e)
				{
					context.Trace("ERR: {0}", e.Message);
					bagValue = new BagValue(GetDataType(attributeSelector.DataType));
				}
			}
			return bagValue;
		}
예제 #12
0
		/// <summary>
		/// Evaluate the context document using a specified policy
		/// </summary>
		/// <param name="contextDocument">The context document instance</param>
		/// <returns>The response document.</returns>
		public ctx.ResponseElement Evaluate(ctx.ContextDocument contextDocument)
		{
			var context = new EvaluationContext(this, null, contextDocument);

			try
			{
				// Validates the configuration file was found.
				if (ConfigurationRoot.Config != null)
				{
					// Search all the policies repositories to find a policy that matches the 
					// context document
					pol.PolicyDocument policyDocument = null;
					foreach (IPolicyRepository policyRep in ConfigurationRoot.Config.PolicyRepositories)
					{
						if (policyDocument == null)
						{
							policyDocument = policyRep.Match(context);
						}
						else
						{
							throw new EvaluationException(Properties.Resource.exc_duplicated_policy_in_repository);
						}
					}

					// If the policy was found evaluate the context document, otherwise use the
					// Evaluate method to generate a Response context document.
					if (policyDocument != null)
					{
						return Evaluate(policyDocument, contextDocument);
					}
					else
					{
						return Evaluate(null, null);
					}
				}
				else
				{
					throw new EvaluationException(Properties.Resource.exc_configuration_file_not_found);
				}
			}
			catch (EvaluationException e)
			{
				context.Trace("ERR: {0}", e.Message);
				return Evaluate(null, null);
			}
		}
예제 #13
0
        /// <summary>
        /// This method overrides the ApplyBase method in order to provide extra validations 
        /// required in the condition evaluation, for example the final return value should be a
        /// boolean value.
        /// </summary>
        /// <param name="context">The evaluation context instance.</param>
        /// <returns>The EvaluationValue with the results of the condition evaluation.</returns>
        public override EvaluationValue Evaluate(EvaluationContext context)
        {
            if (context == null) throw new ArgumentNullException("context");
            EvaluationValue evaluationValue = null;
            context.Trace("Evaluating condition...");
            context.AddIndent();
            try
            {
                // Get the function instance
                IFunction function = EvaluationEngine.GetFunction(ApplyDefinition.FunctionId);
                if (function == null)
                {
                    context.Trace("ERR: function not found {0}", ApplyDefinition.FunctionId);
                    context.ProcessingError = true;
                    return EvaluationValue.Indeterminate;
                }

                // Validates the function return value
                if (function.Returns == null)
                {
                    context.Trace("The function '{0}' does not defines it's return value", ApplyDefinition.FunctionId);
                    evaluationValue = EvaluationValue.Indeterminate;
                    context.ProcessingError = true;
                }
                else if (function.Returns != DataTypeDescriptor.Boolean)
                {
                    context.Trace("Function does not return Boolean a value");
                    evaluationValue = EvaluationValue.Indeterminate;
                    context.ProcessingError = true;
                }
                else
                {
                    // Call the ApplyBase method to perform the evaluation.
                    evaluationValue = base.Evaluate(context);
                }

                // Validate the results of the evaluation
                if (evaluationValue.IsIndeterminate)
                {
                    context.Trace("condition evaluated into {0}", evaluationValue.ToString());
                    return evaluationValue;
                }
                if (!(evaluationValue.Value is bool))
                {
                    context.Trace("condition evaluated into {0}", evaluationValue.ToString());
                    return EvaluationValue.Indeterminate;
                }
                if (evaluationValue.BoolValue)
                {
                    context.Trace("condition evaluated into {0}", evaluationValue.ToString());
                    return EvaluationValue.True;
                }
                else
                {
                    // If the evaluation was false, validate if there was a missin attribute during 
                    // evaluation and return an Indeterminate, otherwise return the False value.
                    if (context.IsMissingAttribute)
                    {
                        context.Trace("condition evaluated into {0}", evaluationValue.ToString());
                        return EvaluationValue.Indeterminate;
                    }
                    else
                    {
                        context.Trace("condition evaluated into {0}", evaluationValue.ToString());
                        return EvaluationValue.False;
                    }
                }
            }
            finally
            {
                context.TraceContextValues();

                context.RemoveIndent();
                context.Trace("Condition: {0}", evaluationValue == null ? string.Empty : evaluationValue.ToString());
            }
        }
예제 #14
0
        /// <summary>
        /// Evaluates the policy.
        /// </summary>
        /// <param name="context">The evaluation context instance.</param>
        /// <returns>The decission result for this policy.</returns>
        public Decision Evaluate(EvaluationContext context)
        {
            if (context == null) throw new ArgumentNullException("context");
            context.Trace("Evaluating policy: {0}", _policy.Description);
            context.AddIndent();
            context.CurrentPolicy = this;
            try
            {
                // Evaluate the variables
                if (this._policy.SchemaVersion == XacmlVersion.Version20)
                {
                    if (_variables == null)
                    {
                        context.Trace("Evaluating variables...");
                        _variables = new Hashtable();

                        foreach (pol.VariableDefinitionElement variableDef in _policy.VariableDefinitions.Values)
                        {
                            var variable = new VariableDefinition(variableDef);
                            _variables.Add(variableDef.Id, variable);
                        }
                    }
                }

                // Matches the target.
                TargetEvaluationValue targetEvaluationValue = Match(context);

                // If the target matches.
                if (targetEvaluationValue == TargetEvaluationValue.Match)
                {
                    context.Trace("Rule combination algorithm: {0}", _policy.RuleCombiningAlgorithm);

                    // Evaluate all rules and apply rule combination
                    IRuleCombiningAlgorithm rca = EvaluationEngine.CreateRuleCombiningAlgorithm(_policy.RuleCombiningAlgorithm);
                    _evaluationValue = rca.Evaluate(context, _rules);
                }
                else if (targetEvaluationValue == TargetEvaluationValue.NoMatch)
                {
                    _evaluationValue = Decision.NotApplicable;
                }
                else if (targetEvaluationValue == TargetEvaluationValue.Indeterminate)
                {
                    _evaluationValue = Decision.Indeterminate;
                }

                context.Trace("Policy: {0}", _evaluationValue);

                // Copy all the obligations.
                _obligations = new pol.ObligationCollection();
                if (_evaluationValue != Decision.Indeterminate &&
                    _evaluationValue != Decision.NotApplicable &&
                    _policy.Obligations != null && _policy.Obligations.Count != 0)
                {
                    foreach (pol.ObligationElement obl in _policy.Obligations)
                    {
                        if ((obl.FulfillOn == pol.Effect.Deny && _evaluationValue == Decision.Deny) ||
                            (obl.FulfillOn == pol.Effect.Permit && _evaluationValue == Decision.Permit))
                        {
                            context.Trace("Adding obligation: {0} ", obl.ObligationId);
                            _obligations.Add(obl);
                        }
                    }
                }

                return _evaluationValue;
            }
            finally
            {
                context.RemoveIndent();
                context.CurrentPolicy = null;
            }
        }
예제 #15
0
        /// <summary>
        /// Process the match result.
        /// </summary>
        /// <param name="context">The evaluation context instance.</param>
        /// <param name="targetEvaluationValue">The match evaluation result.</param>
        private void ProcessTargetEvaluationValue(EvaluationContext context, TargetEvaluationValue targetEvaluationValue)
        {
            if (targetEvaluationValue == TargetEvaluationValue.Match)
            {
                try
                {
                    context.Trace("Evaluating policies...");
                    context.AddIndent();

                    context.Trace("Policy combination algorithm: {0}", _policySet.PolicyCombiningAlgorithm);

                    // Evaluate all policies and apply rule combination
                    IPolicyCombiningAlgorithm pca = EvaluationEngine.CreatePolicyCombiningAlgorithm(_policySet.PolicyCombiningAlgorithm);

                    if (pca == null)
                    {
                        throw new EvaluationException("the policy combining algorithm does not exists."); //TODO: resources
                    }

                    _evaluationValue = pca.Evaluate(context, _policies);

                    // Update the flags for general evaluation status.
                    context.TraceContextValues();

                    context.Trace("Policy combination algorithm: {0}", _evaluationValue.ToString());
                }
                finally
                {
                    context.RemoveIndent();
                }
            }
            else if (targetEvaluationValue == TargetEvaluationValue.NoMatch)
            {
                _evaluationValue = Decision.NotApplicable;
            }
            else if (targetEvaluationValue == TargetEvaluationValue.Indeterminate)
            {
                _evaluationValue = Decision.Indeterminate;
            }
        }
예제 #16
0
        /// <summary>
        /// Process the obligations for the policy.
        /// </summary>
        /// <param name="context">The evaluation context instance.</param>
        private void ProcessObligations(EvaluationContext context)
        {
            _obligations = new ObligationCollection();
            if (_evaluationValue != Decision.Indeterminate &&
                _evaluationValue != Decision.NotApplicable &&
                _policySet.Obligations != null &&
                _policySet.Obligations.Count != 0)
            {
                foreach (ObligationElement obl in _policySet.Obligations)
                {
                    if ((obl.FulfillOn == Effect.Deny && _evaluationValue == Decision.Deny) ||
                        (obl.FulfillOn == Effect.Permit && _evaluationValue == Decision.Permit))
                    {
                        context.Trace("Adding obligation: {0} ", obl.ObligationId);
                        _obligations.Add(obl);
                    }
                }

                // Get all obligations from child policies
                foreach (IMatchEvaluable child in _policies)
                {
                    var oblig = child as IObligationsContainer;
                    if (oblig != null && oblig.Obligations != null)
                    {
                        foreach (ObligationElement childObligation in oblig.Obligations)
                        {
                            if ((childObligation.FulfillOn == Effect.Deny && _evaluationValue == Decision.Deny) ||
                                (childObligation.FulfillOn == Effect.Permit && _evaluationValue == Decision.Permit))
                            {
                                _obligations.Add(childObligation);
                            }
                        }
                    }
                }
            }
        }
예제 #17
0
        /// <summary>
        /// Evaluates the policy set.
        /// </summary>
        /// <param name="context">The evaluation context instance.</param>
        /// <returns>The decission result for this policy set.</returns>
        public Decision Evaluate(EvaluationContext context)
        {
            if (context == null) throw new ArgumentNullException("context");
            context.Trace("Evaluating policySet: {0}", _policySet.Description);
            context.CurrentPolicySet = this;
            try
            {
                context.Trace("Evaluating Target...");
                context.AddIndent();

                // Evaluate the policy target
                TargetEvaluationValue targetEvaluationValue = Match(context);

                context.RemoveIndent();
                context.Trace("Target: {0}", targetEvaluationValue);

                ProcessTargetEvaluationValue(context, targetEvaluationValue);

                context.Trace("PolicySet: {0}", _evaluationValue);

                // If the policy evaluated to Deny or Permit add the obligations depending on its fulfill value.
                ProcessObligations(context);

                return _evaluationValue;
            }
            finally
            {
                context.CurrentPolicySet = null;
            }
        }
예제 #18
0
 /// <summary>
 /// Match the target of this policy set.
 /// </summary>
 /// <param name="context">The evaluation context instance.</param>
 /// <returns>The retult evaluation of the policy set target.</returns>
 public TargetEvaluationValue Match(EvaluationContext context)
 {
     if (context == null) throw new ArgumentNullException("context");
     // Evaluate the policy target
     var targetEvaluationValue = TargetEvaluationValue.Match;
     if (_target != null)
     {
         targetEvaluationValue = _target.Evaluate(context);
         context.TraceContextValues();
     }
     return targetEvaluationValue;
 }
예제 #19
0
파일: Rule.cs 프로젝트: mingkongbin/anycmd
        /// <summary>
        /// Evaluates the rule contents.
        /// </summary>
        /// <param name="context">The evaluation context instance.</param>
        /// <returns>A decission for this evalauation.</returns>
        public Decision Evaluate(EvaluationContext context)
        {
            if (context == null) throw new ArgumentNullException("context");
            context.Trace("Evaluating rule: {0}", _rule.Description);
            context.AddIndent();
            context.CurrentRule = this;
            try
            {
                // Validate the Target element
                TargetEvaluationValue targetEvaluation = Match(context);

                // If the target matches the conditions ar evaluated
                EvaluationValue conditionEvaluation = EvaluationValue.True;
                if (_rule.HasCondition)
                {
                    // Evaluate the condition
                    conditionEvaluation = _condition.Evaluate(context);
                }
                else
                {
                    context.Trace("Rule does not have a condition");
                }

                // Decite the final rule evaluation value
                if (targetEvaluation == TargetEvaluationValue.Indeterminate || conditionEvaluation.IsIndeterminate)
                {
                    _evaluationValue = Decision.Indeterminate;
                }
                else if (targetEvaluation == TargetEvaluationValue.Match && conditionEvaluation.BoolValue)
                {
                    _evaluationValue = ((_rule.Effect == Effect.Permit) ? Decision.Permit : Decision.Deny);
                }
                else if ((targetEvaluation == TargetEvaluationValue.NoMatch) ||
                    (targetEvaluation == TargetEvaluationValue.Match && !conditionEvaluation.BoolValue))
                {
                    _evaluationValue = Decision.NotApplicable;
                }

                // Return the value
                context.Trace("Rule: {0}", _evaluationValue);
                return _evaluationValue;
            }
            finally
            {
                context.RemoveIndent();
                context.CurrentRule = null;
            }
        }
예제 #20
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;
        }
예제 #21
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;
        }
예제 #22
0
		/// <summary>
		/// Evaluate the context document using a specified policy
		/// </summary>
		/// <param name="policyDocument">The policy instance</param>
		/// <param name="contextDocument">The context document instance</param>
		/// <returns>The response document</returns>
		public ctx.ResponseElement Evaluate(pol.PolicyDocument policyDocument, ctx.ContextDocument contextDocument)
		{
			if (policyDocument == null) throw new ArgumentNullException("policyDocument");
			if (contextDocument == null) throw new ArgumentNullException("contextDocument");
			var context = new EvaluationContext(this, policyDocument, contextDocument);

			context.Trace("Start evaluation");
			context.AddIndent();

			// Check if both documents are valid
			if (!policyDocument.IsValidDocument || !contextDocument.IsValidDocument)
			{
				// If a validation error was found a response is created with the syntax error message
				var response =
					new ctx.ResponseElement(
						new[] {
							new ctx.ResultElement( 
								null, 
								Decision.Indeterminate, 
								new ctx.StatusElement( 
									new ctx.StatusCodeElement(Consts.ContextSchema.StatusCodes.SyntaxError, null, policyDocument.Version ), 
									null, 
									null, policyDocument.Version ), 
								null, policyDocument.Version ) },
					policyDocument.Version);
				return response;
			}

			// Create a new response
			contextDocument.Response = new ctx.ResponseElement((ctx.ResultElement[])null, policyDocument.Version);

			try
			{
				// Create the evaluable policy intance
				IMatchEvaluable policy = null;
				if (policyDocument.PolicySet != null)
				{
					policy = new PolicySet(this, (pol.PolicySetElement)policyDocument.PolicySet);
				}
				else if (policyDocument.Policy != null)
				{
					policy = new Policy((pol.PolicyElement)policyDocument.Policy);
				}

				// Evaluate the policy or policy set
				if (policy != null)
				{
					// Creates the evaluable policy set
					if (policy.AllResources.Count == 0)
					{
						policy.AllResources.Add("");
					}

					string requestedResourceString = String.Empty;
					Uri requestedResource = null;

					foreach (ctx.ResourceElement resource in contextDocument.Request.Resources)
					{
						// Keep the requested resource
						if (resource.IsHierarchical)
						{
							foreach (ctx.AttributeElement attribute in resource.Attributes)
							{
								if (attribute.AttributeId == Consts.ContextSchema.ResourceElement.ResourceId)
								{
									if (context.PolicyDocument.Version == XacmlVersion.Version10 ||
										context.PolicyDocument.Version == XacmlVersion.Version11)
									{
										requestedResourceString = attribute.AttributeValues[0].Contents;
									}
									else
									{
										if (attribute.AttributeValues.Count > 1)
										{
											throw new NotSupportedException("resources contains a bag of values");
										}
										requestedResourceString = attribute.AttributeValues[0].Contents;
									}
								}
							}
							if (!string.IsNullOrEmpty(requestedResourceString))
							{
								requestedResource = new Uri(requestedResourceString);
							}
						}

						// Iterate through the policy resources evaluating each resource in the context document request 
						foreach (string resourceName in policy.AllResources)
						{
							bool mustEvaluate = false;
							if (resource.IsHierarchical)
							{
								//Validate if the resource is hierarchically desdendant or children 
								//of the requested resource
								Uri policyResource = new Uri(resourceName);

								Debug.Assert(requestedResource != null, "requestedResource != null");
								if (!(mustEvaluate = requestedResource.Equals(policyResource)))
								{
									// Perform the hierarchical evaluation
									if (resource.ResourceScopeValue == ctx.ResourceScope.Children)
									{
										mustEvaluate = typ.AnyUri.IsChildrenOf(requestedResource, policyResource);
									}
									else if (resource.ResourceScopeValue == ctx.ResourceScope.Descendants)
									{
										mustEvaluate = typ.AnyUri.IsDescendantOf(requestedResource, policyResource);
									}
								}

								if (mustEvaluate)
								{
									foreach (ctx.AttributeElementReadWrite attribute in context.CurrentResource.Attributes)
									{
										if (attribute.AttributeId == Consts.ContextSchema.ResourceElement.ResourceId)
										{
											attribute.AttributeValues[0].Contents = resourceName;
											break;
										}
									}
								}
							}
							else
							{
								context.CurrentResource = resource;
								mustEvaluate = true;
							}

							if (mustEvaluate)
							{
								// Evaluates the policy set
								Decision decision = policy.Evaluate(context);

								// Create a status code using the policy execution state
								ctx.StatusCodeElement scode;
								if (context.IsMissingAttribute)
								{
									scode = new ctx.StatusCodeElement(
										Consts.ContextSchema.StatusCodes.MissingAttribute, null, policyDocument.Version);
								}
								else if (context.ProcessingError)
								{
									scode = new ctx.StatusCodeElement(
										Consts.ContextSchema.StatusCodes.ProcessingError, null, policyDocument.Version);
								}
								else
								{
									scode = new ctx.StatusCodeElement(
										Consts.ContextSchema.StatusCodes.Ok, null, policyDocument.Version);
								}

								//Stop the iteration if there is not a hierarchical request
								if (!resource.IsHierarchical)
								{
									// Ussually when a single resource is requested the ResourceId is not specified in the result
									var oblig = policy as IObligationsContainer;
									contextDocument.Response.Results.Add(
										new ctx.ResultElement("", decision,
											new ctx.StatusElement(scode, "", "", policyDocument.Version), oblig.Obligations, policyDocument.Version));
									break;
								}
								else
								{
									// Adding a resource for each requested resource, using the resourceName as the resourceId of the result
									var oblig = policy as IObligationsContainer;
									contextDocument.Response.Results.Add(
										new ctx.ResultElement(resourceName, decision,
											new ctx.StatusElement(scode, "", "", policyDocument.Version), oblig.Obligations, policyDocument.Version));
								}
							} // if( mustEvaluate )
						} // foreach( string resourceName in policy.AllResources )
					}
				} //if( policy != null )
			}
			catch (EvaluationException e)
			{
				// If a validation error was found a response is created with the syntax error message
				contextDocument.Response =
					new ctx.ResponseElement(
						new ctx.ResultElement[] {
							new ctx.ResultElement( 
								null, 
								Decision.Indeterminate, 
								new ctx.StatusElement( 
									new ctx.StatusCodeElement(Consts.ContextSchema.StatusCodes.ProcessingError, null, policyDocument.Version ), 
									e.Message, 
									e.StackTrace, policyDocument.Version ), 
								null, policyDocument.Version ) },
					policyDocument.Version);
			}

			return contextDocument.Response;
		}
예제 #23
0
		/// <summary>
		/// Resolve the attribute desingator that can't be found in the context document
		/// </summary>
		/// <param name="context">The evaluation context instance.</param>
		/// <param name="designator">The attribute designator instance</param>
		public static ctx.AttributeElement GetAttribute(EvaluationContext context, pol.AttributeDesignatorBase designator)
		{
			// Resolve internal attributes
			switch (designator.AttributeId)
			{
				case Consts.ContextSchema.EnvironmentAttributes.CurrentDate:
					return new ctx.AttributeElement(
						designator.AttributeId,
						Consts.Schema1.InternalDataTypes.XsdDate,
						null,
						null,
						XmlConvert.ToString(DateTime.Now, "yyyy-MM-dd"),
						designator.SchemaVersion);
				case Consts.ContextSchema.EnvironmentAttributes.CurrentTime:
					return new ctx.AttributeElement(
						designator.AttributeId,
						Consts.Schema1.InternalDataTypes.XsdTime,
						null,
						null,
						XmlConvert.ToString(DateTime.Now, "HH:mm:sszzzzzz"),
						designator.SchemaVersion);
				case Consts.ContextSchema.EnvironmentAttributes.CurrentDateTime:
					return new ctx.AttributeElement(
						designator.AttributeId,
						Consts.Schema1.InternalDataTypes.XsdDateTime,
						null,
						null,
						XmlConvert.ToString(DateTime.Now, "yyyy-MM-ddTHH:mm:sszzzzzz"),
						designator.SchemaVersion);
				default:
					{
						if (Configuration.ConfigurationRoot.Config != null)
						{
							// Search for attributes in the configured repositories
							foreach (IAttributeRepository repository in Configuration.ConfigurationRoot.Config.AttributeRepositories)
							{
								ctx.AttributeElement attribute = repository.GetAttribute(context, designator);
								if (attribute != null)
								{
									return attribute;
								}
							}
						}
						return null;
					}
			}
		}
예제 #24
0
		/// <summary>
		/// Solves the attribute designator in the context document using the attribute designator type
		/// </summary>
		/// <param name="context">The evaluation context instance.</param>
		/// <param name="attributeDesignator">The attribute designator to resolve</param>
		/// <returns>A bag value with the values found in the context document</returns>
		public static BagValue Resolve(EvaluationContext context, pol.AttributeDesignatorBase attributeDesignator)
		{
			if (attributeDesignator is SubjectAttributeDesignatorElement)
			{
				if (context.ContextDocument.Request != null && context.ContextDocument.Request.Subjects != null)
				{
					var bag = new BagValue(GetDataType(attributeDesignator.DataType));
					foreach (ctx.SubjectElement subject in context.ContextDocument.Request.Subjects)
					{
						if (((SubjectAttributeDesignatorElement)attributeDesignator).SubjectCategory == null ||
							((SubjectAttributeDesignatorElement)attributeDesignator).SubjectCategory == subject.SubjectCategory)
						{
							foreach (ctx.AttributeElement attrib in FindAttribute(context, attributeDesignator, subject).Elements)
							{
								bag.Add(attrib);
							}
						}
					}
					return bag;
				}
			}
			else if (attributeDesignator is ResourceAttributeDesignatorElement)
			{
				if (context.ContextDocument.Request != null && context.CurrentResource != null)
				{
					return FindAttribute(context, attributeDesignator, context.CurrentResource);
				}
				else
				{
					return BagValue.Empty;
				}
			}
			else if (attributeDesignator is ActionAttributeDesignatorElement)
			{
				if (context.ContextDocument.Request != null && context.ContextDocument.Request.Action != null)
				{
					return FindAttribute(context, attributeDesignator, context.ContextDocument.Request.Action);
				}
				else
				{
					return BagValue.Empty;
				}
			}
			else if (attributeDesignator is EnvironmentAttributeDesignatorElement)
			{
				if (context.ContextDocument.Request != null && context.ContextDocument.Request.Environment != null)
				{
					return FindAttribute(context, attributeDesignator, context.ContextDocument.Request.Environment);
				}
				else
				{
					return BagValue.Empty;
				}
			}
			throw new EvaluationException(Properties.Resource.exc_invalid_attribute_designator);
		}
예제 #25
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 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((ApplyElement)_variableDefinition.Expression);

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

                    context.TraceContextValues();
                    return _value;
                }
                else if (_variableDefinition.Expression is FunctionElement)
                {
                    throw new NotImplementedException("FunctionElement"); //TODO:
                }
                else if (_variableDefinition.Expression is VariableReferenceElement)
                {
                    var variableRef = _variableDefinition.Expression as VariableReferenceElement;
                    var 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 AttributeValueElementReadWrite)
                {
                    // The AttributeValue does not need to be processed
                    context.Trace("Attribute value {0}", _variableDefinition.Expression.ToString());

                    var att = (AttributeValueElementReadWrite)_variableDefinition.Expression;
                    var attributeValue = new 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 AttributeDesignatorBase)
                {
                    // Resolve the AttributeDesignator using the EvaluationEngine public methods.
                    context.Trace("Processing attribute designator: {0}", _variableDefinition.Expression.ToString());

                    var attrDes = (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 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 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 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 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 AttributeSelectorElement)
                {
                    // Resolve the XPath query using the EvaluationEngine public methods.
                    context.Trace("Attribute selector");
                    try
                    {
                        var attributeSelector = (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();
            }
        }
예제 #26
0
		/// <summary>
		/// Resolves the attribute reference defined within the given match.
		/// </summary>
		/// <param name="context">The evaluation context instance.</param>
		/// <param name="match">The target item match.</param>
		/// <param name="contextTargetItem">The context target item.</param>
		/// <returns>The context attribute.</returns>
		public static Context.AttributeElement Resolve(EvaluationContext context, TargetMatchBaseReadWrite match, ctx.TargetItemBase contextTargetItem)
		{
			Context.AttributeElementReadWrite attribute = null;
			if (match.AttributeReference is pol.AttributeDesignatorBase)
			{
				var attrDesig = (pol.AttributeDesignatorBase)match.AttributeReference;
				context.Trace("Looking for attribute: {0}", attrDesig.AttributeId);
				foreach (Context.AttributeElementReadWrite tempAttribute in contextTargetItem.Attributes)
				{
					if (tempAttribute.Match(attrDesig))
					{
						attribute = tempAttribute;
						break;
					}
				}

				if (attribute == null)
				{
					context.Trace("Attribute not found, loading searching an external repository");
					attribute = GetAttribute(context, attrDesig);
				}
			}
			else if (match.AttributeReference is pol.AttributeSelectorElement)
			{
				var attrSelec = (pol.AttributeSelectorElement)match.AttributeReference;
				var content = (ctx.ResourceContentElement)((ctx.ResourceElement)contextTargetItem).ResourceContent;
				if (content != null)
				{
					XmlDocument doc = context.ContextDocument.XmlDocument;

					if (context.ContextDocument.XmlNamespaceManager == null)
					{
						context.ContextDocument.AddNamespaces(context.PolicyDocument.Namespaces);
					}

					string xpath = attrSelec.RequestContextPath;
					try
					{
						Debug.Assert(doc.DocumentElement != null, "doc.DocumentElement != null");
						XmlNode node = doc.DocumentElement.SelectSingleNode(xpath, context.ContextDocument.XmlNamespaceManager);
						if (node != null)
						{
							attribute = new ctx.AttributeElement(null, attrSelec.DataType, null, null, node.InnerText, attrSelec.SchemaVersion);
						}
					}
					catch (XPathException e)
					{
						context.Trace("ERR: {0}", e.Message);
						context.ProcessingError = true;
					}
				}
			}

			if (!context.ProcessingError && attribute == null && match.AttributeReference.MustBePresent)
			{
				context.IsMissingAttribute = true;
				context.AddMissingAttribute(match.AttributeReference);
			}

			if (attribute != null)
			{
				return new Context.AttributeElement(attribute.AttributeId, attribute.DataType, attribute.Issuer, attribute.IssueInstant,
					attribute.Value, attribute.SchemaVersion);
			}
			return null;
		}
예제 #27
0
        /// <summary>
        /// This method overrides the ApplyBase method in order to provide extra validations 
        /// required in the condition evaluation, for example the final return value should be a
        /// boolean value.
        /// </summary>
        /// <param name="context">The evaluation context instance.</param>
        /// <returns>The EvaluationValue with the results of the condition evaluation.</returns>
        public override EvaluationValue Evaluate(EvaluationContext context)
        {
            if (context == null) throw new ArgumentNullException("context");
            context.Trace("Evaluating condition");
            context.AddIndent();
            try
            {
                // Iterate through the arguments, the IExpressionType is a mark interface
                foreach (IExpression arg in ApplyDefinition.Arguments)
                {
                    if (arg is 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.
                        var childApply = new Apply((ApplyElement)arg);

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

                        return retVal;
                    }
                    else if (arg is FunctionElementReadWrite)
                    {
                        throw new NotImplementedException("FunctionElement"); //TODO:
                    }
                    else if (arg is VariableReferenceElement)
                    {
                        var variableRef = arg as VariableReferenceElement;
                        var variableDef = context.CurrentPolicy.VariableDefinition[variableRef.VariableId] as VariableDefinition;

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

                        var attributeValue = new AttributeValueElement(((AttributeValueElementReadWrite)arg).DataType, ((AttributeValueElementReadWrite)arg).Contents, ((AttributeValueElementReadWrite)arg).SchemaVersion);

                        return new EvaluationValue(
                            attributeValue.GetTypedValue(attributeValue.GetType(context), 0),
                            attributeValue.GetType(context));
                    }
                    else if (arg is AttributeDesignatorBase)
                    {
                        // Returning an empty bag, since the condition is not supposed to work with a bag
                        context.Trace("Processing attribute designator: {0}", arg.ToString());

                        var attrDes = (AttributeDesignatorBase)arg;
                        var bag = new BagValue(EvaluationEngine.GetDataType(attrDes.DataType));
                        return new EvaluationValue(bag, bag.GetType(context));
                    }
                    else if (arg is AttributeSelectorElement)
                    {
                        // Returning an empty bag, since the condition is not supposed to work with a bag
                        context.Trace("Attribute selector");

                        var attrSel = (AttributeSelectorElement)arg;
                        var bag = new BagValue(EvaluationEngine.GetDataType(attrSel.DataType));
                        return new EvaluationValue(bag, bag.GetType(context));
                    }
                }
                throw new NotSupportedException("internal error");
            }
            finally
            {
                context.TraceContextValues();
                context.RemoveIndent();
            }
        }
예제 #28
0
		/// <summary>
		/// Evaluates a function and also validates it's return value and parameter data types
		/// </summary>
		/// <param name="context">The evaluation context instance.</param>
		/// <param name="functionInstance">The function to call</param>
		/// <param name="arguments">The function arguments</param>
		/// <returns>The return value of the function</returns>
		public static EvaluationValue EvaluateFunction(EvaluationContext context, IFunction functionInstance, params IFunctionParameter[] arguments)
		{
			if (context == null) throw new ArgumentNullException("context");
			// If the caller is in a missing attribute state the function should not be called
			if (context.IsMissingAttribute)
			{
				context.Trace("There's a missing attribute in the parameters"); 
				return EvaluationValue.Indeterminate;
			}
			else
			{
				// Validate function defined arguments
				int functionArgumentIdx;
				for (functionArgumentIdx = 0; functionArgumentIdx < functionInstance.Arguments.Length; functionArgumentIdx++)
				{
					// Validate the value is not an Indeterminate value
					if (arguments[functionArgumentIdx] is EvaluationValue &&
						((EvaluationValue)arguments[functionArgumentIdx]).IsIndeterminate)
					{
						if (!context.IsMissingAttribute)
						{
							context.ProcessingError = true;
						}
						context.Trace("There's a parameter with Indeterminate value");
						return EvaluationValue.Indeterminate;
					}

					// Compare the function and the value data type
					if (((functionInstance.Arguments[functionArgumentIdx] != arguments[functionArgumentIdx].GetType(context)) &&
						((functionInstance.Arguments[functionArgumentIdx] != DataTypeDescriptor.Bag) && (arguments[functionArgumentIdx] is BagValue))))
					{
						context.ProcessingError = true;
						context.Trace("There's a parameter with an invalid datatype"); 
						return EvaluationValue.Indeterminate;
					}
				}

				//If the function supports variable arguments, the last datatype is used to validate the
				//rest of the parameters
				if (functionInstance.VarArgs)
				{
					functionArgumentIdx--;
					for (int argumentValueIdx = functionArgumentIdx; argumentValueIdx < arguments.Length; argumentValueIdx++)
					{
						// Validate the value is not an Indeterminate value
						if (arguments[argumentValueIdx] is EvaluationValue && ((EvaluationValue)arguments[argumentValueIdx]).IsIndeterminate)
						{
							if (!context.IsMissingAttribute)
							{
								context.ProcessingError = true;
							}
							context.Trace("There's a parameter with Indeterminate value"); 
							return EvaluationValue.Indeterminate;
						}

						// Compare the function and the value data type
						if ((functionInstance.Arguments[functionArgumentIdx] != arguments[argumentValueIdx].GetType(context)) &&
							((arguments[argumentValueIdx] is BagValue) && (functionInstance.Arguments[functionArgumentIdx] != DataTypeDescriptor.Bag)))
						{
							context.ProcessingError = true;
							context.Trace("There's a parameter with an invalid datatype"); 
							return EvaluationValue.Indeterminate;
						}
					}
				}

				var sb = new StringBuilder();

				// Call the function in a controlled evironment to capture any exception
				try
				{
					sb.Append(functionInstance.Id);
					sb.Append("( ");
					bool isFirst = true;
					foreach (IFunctionParameter param in arguments)
					{
						if (isFirst)
						{
							isFirst = false;
						}
						else
						{
							sb.Append(", ");
						}
						sb.Append(param.ToString());
					}
					sb.Append(" )");
					sb.Append(" = ");

					EvaluationValue returnValue = functionInstance.Evaluate(context, arguments);

					sb.Append(returnValue.ToString());
					context.Trace(sb.ToString());

					return returnValue;
				}
				catch (EvaluationException e)
				{
					context.Trace(sb.ToString());
					context.ProcessingError = true;
					context.Trace("Error: {0}", e.Message); 
					return EvaluationValue.Indeterminate;
				}
			}
		}
예제 #29
0
 /// <summary>
 /// Gets the data type of the value.
 /// </summary>
 /// <param name="context">The evaluation context.</param>
 /// <returns>The data type descriptor.</returns>
 public IDataType GetType(EvaluationContext context)
 {
     return _dataType;
 }