Exemple #1
0
        private static bool Verify(string xsltRule, string content, string metadata, out TestResult result)
        {
            string rng = XsltTransformer.Transform(metadata, xsltRule);

            try
            {
                var rngChecker = new RngVerifier(rng);
                return(rngChecker.Verify(content, out result));
            }
            catch (Exception e)
            {
                if (!ExceptionHelper.IsCatchableExceptionType(e))
                {
                    throw;
                }

                throw new RuntimeException(e, rng);
            }
        }
        private static bool Verify(string xsltRule, string content, string metadata, out TestResult result)
        {
            string rng = XsltTransformer.Transform(metadata, xsltRule);

            try
            {
                var rngChecker = new RngVerifier(rng);
                return rngChecker.Verify(content, out result);
            }
            catch (Exception e)
            {
                if (!ExceptionHelper.IsCatchableExceptionType(e))
                {
                    throw;
                }

                throw new RuntimeException(e, rng);
            }
        }
        /// <summary>
        /// Verify the code rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool? Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool? passed = null;
            info = null;

            //1-get the data service namespace name (try 1st property?)
            string dsns = ResourcePathHelper.GetDataServiceNamespace(XElement.Parse(context.ResponsePayload));

            //2-get names of the properties of the involved entity type
            // ensure they are all unique to protect from repetitive type inheritance declarations in metadata documents
            string[] propertyNames = XmlHelper.GetProperties(context.MetadataDocument, context.EntityTypeShortName).Distinct().ToArray();

            if (context.Projection)
            {
                List<string> aa = new List<string>();
                var queries = HttpUtility.ParseQueryString(context.Destination.Query);
                var qSelect = queries["$select"];
                var selects = qSelect.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var sel in selects)
                {
                    var propName = propertyNames.FirstOrDefault(x => sel.Equals(x, StringComparison.OrdinalIgnoreCase));
                    if (!string.IsNullOrEmpty(propName))
                    {
                        aa.Add(propName);
                    }
                }
                propertyNames = aa.ToArray();
            }

            //3-craft the rng
            StringBuilder sb = new StringBuilder();
            foreach (var p in propertyNames)
            {
                sb.AppendFormat(rngProperty, p);
            }
            string schema = string.Format(rngSchema, dsns, sb.ToString());

            //4-surrender it under rng validator
            RngVerifier verifier = new RngVerifier(schema);
            TestResult result;
            passed = verifier.Verify(context, out result);

            if (passed.Value)
            {
                info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError);
            }

            return passed;
        }
        /// <summary>
        /// Verify the code rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool? Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool passed = false;
            info = null;

            RngVerifier verifier = new RngVerifier(EntryCore2003_NoMeta.rngSchema);
            TestResult result;
            passed = verifier.Verify(context, out result);

            if (!passed)
            {
                info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError);
            }

            return passed;
        }
        /// <summary>
        /// Verify rule logic
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool? Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool? passed = null;
            info = null;

            // get the list of navigation properties of the interesting entity type
            var edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument));
            EntityType et;
            edmxHelper.TryGetItem(context.EntityTypeFullName, out et);
            var navProps = et.NavigationProperties.Select(x => x.Name);

            // find out the data service namespace; falling back the implcit one if none exists
            string dsns = ResourcePathHelper.GetDataServiceNamespace(XElement.Parse(context.ResponsePayload));

            // get the relaxNG schema and verify the payload
            var rngNavLinks = navProps.Select(x => string.Format(tmplRngNavLink, dsns, x));
            var rng = string.Format(tmplRngSchema, string.Join(string.Empty, rngNavLinks), RngCommonPattern.CommonPatterns);

            RngVerifier verifier = new RngVerifier(rng);
            TestResult result;
            passed = verifier.Verify(context, out result);

            if (!passed.Value)
            {
                info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError);
            }

            return passed;
        }
        /// <summary>
        /// Verify the code rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool? Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool? passed = null;
            info = null;

            // run the rng rule if $inlinecount=allpages is part of query string of target uri
            var q = context.Destination.Query;
            var qs = HttpUtility.ParseQueryString(q);
            var v = qs["$inlinecount"];
            if (v != null && v.Equals("allpages", StringComparison.Ordinal))
            {
                var rngSchema = string.Format(FeedCore2005.rngSchemaFormat, RngCommonPattern.CommonPatterns);
                RngVerifier verifier = new RngVerifier(rngSchema);
                TestResult result;
                passed = verifier.Verify(context, out result);
                if (!passed.Value)
                {
                    info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError);
                }
            }

            return passed;
        }
        /// <summary>
        /// Verify the code rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out paramater to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool? Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool passed = true;
            info = null;

            // to check this rule only when request URI if os URI7, and about set of links (not single link)
            bool isCheckingTarget = false;

            var edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument));
            var segments = ResourcePathHelper.GetPathSegments(context);
            UriType uriType;
            var target = edmxHelper.GetTargetType(segments, out uriType);

            if (uriType == UriType.URI7)
            {
                // safe to convert since s must be a RelationshipEndMember
                var targetRelationEndMember = (RelationshipEndMember)target;
                isCheckingTarget = targetRelationEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many;
            }

            if (isCheckingTarget)
            {
                string rngSchema = string.Format(rngFormat, RngCommonPattern.CommonPatterns);
                RngVerifier verifier = new RngVerifier(rngSchema);
                TestResult result;
                passed = verifier.Verify(context, out result);
                if (!passed)
                {
                    info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError);
                }
            }

            return passed;
        }
        /// <summary>
        /// Verify the code rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool? Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool? passed = null;
            info = null;

            // get the leftmost navigation property of expand query option
            var qs = HttpUtility.ParseQueryString(context.Destination.Query);
            string qExpand = qs["$expand"];
            if (!string.IsNullOrEmpty(qExpand))
            {
                var branches = ResourcePathHelper.GetBranchedSegments(qExpand);
                foreach (var paths in branches)
                {
                    string leadNavProp = paths.First();

                    // construct the desired srng schema and verify
                    string rngSchema = string.Format(EntryCore2011.formatRng, leadNavProp, RngCommonPattern.CommonPatterns);
                    RngVerifier verifier = new RngVerifier(rngSchema);
                    TestResult result;
                    passed = verifier.Verify(context, out result);
                    if (!passed.Value)
                    {
                        info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError);
                        break;
                    }
                }
            }

            return passed;
        }
        /// <summary>
        /// Verify the code rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool? Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool? passed = null;
            info = null;

            // get value of attribute of @href of node feed/link[@rel='self']
            var xpath = "/atom:link[@rel='self' and @href]";
            XElement feed;
            context.ResponsePayload.TryToXElement(out feed);
            var selfLink = feed.XPathSelectElement(xpath, ODataNamespaceManager.Instance);
            if (selfLink != null)
            {
                var href = selfLink.GetAttributeValue("href");

                // consider the effect of xml:base in scope
                string xBase = selfLink.GetAttributeValue("xml:base", ODataNamespaceManager.Instance);
                if (string.IsNullOrEmpty(xBase))
                {
                    xBase = feed.GetAttributeValue("xml:base", ODataNamespaceManager.Instance);
                }

                var targetFull = context.DestinationBasePath;
                var targetRelative = (string.IsNullOrEmpty(xBase)) ? targetFull : targetFull.Substring(xBase.Length);
                var rngSchema = string.Format(FeedCore2004.rngSchemaFormat, HttpUtility.HtmlEncode(targetFull), HttpUtility.HtmlEncode(targetRelative), RngCommonPattern.CommonPatterns);
                RngVerifier verifier = new RngVerifier(rngSchema);
                TestResult result;
                passed = verifier.Verify(context, out result);
                if (!passed.Value)
                {
                    info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError);
                }
            }

            return passed;
        }
        /// <summary>
        /// Verify the code rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out paramater to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool? Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool? passed = null;
            info = null;

            XElement meta = XElement.Parse(context.MetadataDocument);
            XElement entry = XElement.Parse(context.ResponsePayload);

            string xpath = string.Format(".//*[local-name()='EntityType' and @Name='{0}']/*[local-name()='Property' and @Name and @m:FC_TargetPath and m:null='true']", context.EntityTypeShortName);
            var mappedProperties = meta.XPathSelectElements(xpath, ODataNamespaceManager.Instance);
            foreach (var mp in mappedProperties)
            {
                var custFeedProperty = new EntryCore2010CFP(mp, entry);

                //check whether mapped value  is present
                var v = entry.XPathSelectElement(custFeedProperty.XPathTarget, custFeedProperty.nsResolver);
                if (v != null)
                {
                    string schema = custFeedProperty.GetRngSchema();

                    RngVerifier verifier = new RngVerifier(schema);
                    TestResult result;
                    passed = verifier.Verify(context, out result);
                    if (!passed.Value)
                    {
                        info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError);
                        break;
                    }
                }
            }

            return passed;
        }
        /// <summary>
        /// Verify the code rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool? Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool? passed = null;
            info = null;

            // if entry in the feed has @m:etag, check @m:etag value is the same as ETag header value if single entry were represented.
            const string xpath = "//*[local-name()='entry' and @m:etag]";
            XElement feed;
            context.ResponsePayload.TryToXElement(out feed);
            var x = feed.XPathSelectElements(xpath, ODataNamespaceManager.Instance);
            foreach (var e in x)
            {
                var href = e.XPathSelectElement("atom:id", ODataNamespaceManager.Instance);
                var target = href.Value;
                // get the ETag header value for the entry
                var etag = WebResponseHelper.GetETagOfEntry(target, Constants.AcceptHeaderAtom);
                var rngSchema = string.Format(FeedCore2003.rngSchemaFormat, HttpUtility.HtmlEncode(etag), HttpUtility.HtmlEncode(target), RngCommonPattern.CommonPatterns);
                RngVerifier verifier = new RngVerifier(rngSchema);
                TestResult result;
                passed = verifier.Verify(context, out result);
                if (!passed.Value)
                {
                    info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError);
                    break;
                }
            }

            return passed;
        }
        /// <summary>
        /// Verify the rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool? Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool? passed = null;
            info = null;

            // if atom:entry[@m:etag] is there, ensure its value equals to ETag header value
            XElement entry;
            context.ResponsePayload.TryToXElement(out entry);
            bool etagInPlace = entry.Attribute("{http://schemas.microsoft.com/ado/2007/08/dataservices/metadata}etag") != null;

            if (etagInPlace)
            {
                var etagInHeader = context.ResponseHttpHeaders.GetHeaderValue("ETag");
                string rngSchema = string.Format(EntryCore2005.rngSchemaFormat, HttpUtility.HtmlEncode(etagInHeader));
                RngVerifier verifier = new RngVerifier(rngSchema);
                TestResult result;
                passed = verifier.Verify(context, out result);
                if (!passed.Value)
                {
                    info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError);
                }
            }

            return passed;
        }
        /// <summary>
        /// Verify the code rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out paramater to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool? Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool? passed = null;
            info = null;

            var edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument));
            var segments = ResourcePathHelper.GetPathSegments(context);
            UriType uriType;
            var target = edmxHelper.GetTargetType(segments, out uriType);
            if (uriType == UriType.URI3)
            {
                XElement meta = XElement.Parse(context.MetadataDocument);
                string targetType = ((EdmProperty)target).TypeUsage.EdmType.FullName;

                var complexType = ResourcePathHelper.GetComplexType(targetType, meta);
                if (complexType != null)
                {
                    XElement payload = XElement.Parse(context.ResponsePayload);
                    string schema = GetRngSchema(ResourcePathHelper.GetBaseName(targetType), payload.Name.NamespaceName);
                    RngVerifier verifier = new RngVerifier(schema);
                    TestResult result;
                    passed = verifier.Verify(context, out result);
                    if (passed.HasValue && !passed.Value)
                    {
                        info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError);
                    }
                }
            }

            return passed;
        }
        /// <summary>
        /// Verify the code rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool? Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool? passed = null;
            info = null;

            XElement meta;
            context.MetadataDocument.TryToXElement(out meta);
            string xpath = string.Format("//*[local-name()='EntityType' and @Name='{0}' and @m:HasStream='true']/*[local-name()='Property' and @ConcurrencyMode='Fixed']",
                context.EntityTypeShortName);
            bool IsConcurrentMle = meta.XPathSelectElement(xpath, ODataNamespaceManager.Instance) != null;

            if (IsConcurrentMle)
            {
                // get ETag header value of the media resource
                XElement entry;
                context.ResponsePayload.TryToXElement(out entry);
                var m = entry.XPathSelectElement("//atom:link[@rel='edit-media' and @href]", ODataNamespaceManager.Instance);
                var targetMedia = context.ServiceBaseUri + m.GetAttributeValue("href");

                var etag = WebResponseHelper.GetETagOfEntry(targetMedia, Constants.AcceptHeaderAtom);
                string rngSchema = string.Format(EntryCore2004.rngSchemaFormat, HttpUtility.HtmlEncode(etag));
                RngVerifier verifier = new RngVerifier(rngSchema);
                TestResult result;
                passed = verifier.Verify(context, out result);
                if (!passed.Value)
                {
                    info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError);
                }
            }

            return passed;
        }
        /// <summary>
        /// Verifies the semantic rule
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool? Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            info = null;
            bool passed = true;

            // if query option of $expand is present, rule shall be verified
            // get the leftmost navigation property of expand query option
            var qs = HttpUtility.ParseQueryString(context.Destination.Query);
            string qExpand = qs["$expand"];

            if (!string.IsNullOrEmpty(qExpand))
            {
                var edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument));
                EntityType et;
                edmxHelper.TryGetItem(context.EntityTypeFullName, out et);

                var segments = ResourcePathHelper.GetPathSegments(context);
                UriType uriType;
                var target = edmxHelper.GetTargetType(segments, out uriType);
                bool isColletcionResource = uriType == UriType.URI1 || uriType == UriType.URI_CollEt;

                var branches = ResourcePathHelper.GetBranchedSegments(qExpand);
                foreach (var paths in branches)
                {
                    var navStack = ODataUriAnalyzer.GetNavigationStack(et, paths).ToArray();
                    bool[] targetIsCollection = (from n in navStack select n.RelationshipMultiplicity == RelationshipMultiplicity.Many).ToArray();

                    string rngCore = @"<ref name=""anyContent"" />";
                    for (int i = paths.Length - 1; i >= 0; i--)
                    {
                        rngCore = targetIsCollection[i] ? GetRngOfInlineFeed(paths[i], rngCore) : GetRngOfInlineEntry(paths[i], rngCore);
                    }

                    // construct the desired srng schema and verify
                    string rngSchema = isColletcionResource
                        ? string.Format(formatRngOfColl, rngCore, RngCommonPattern.CommonPatterns)
                        : string.Format(formatRngSingle, rngCore, RngCommonPattern.CommonPatterns);

                    RngVerifier verifier = new RngVerifier(rngSchema);
                    TestResult result;
                    passed = verifier.Verify(context, out result);
                    if (!passed)
                    {
                        info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError);
                        break;
                    }
                }
            }

            return passed;
        }