示例#1
0
        /// <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);
        }
示例#2
0
        /// <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]", context.EntityTypeShortName);
            var    mappedProperties = meta.XPathSelectElements(xpath, ODataNamespaceManager.Instance);

            foreach (var mp in mappedProperties)
            {
                var    custFeedProperty = new EntryCore2012CFP(mp, entry);
                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);
        }
示例#3
0
        /// <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://docs.oasis-open.org/odata/ns/edm/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 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);
        }
示例#5
0
        /// <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);
        }
        /// <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;
            bool isNullable       = 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.One ||
                                   targetRelationEndMember.RelationshipMultiplicity == RelationshipMultiplicity.ZeroOrOne;
                isNullable = targetRelationEndMember.RelationshipMultiplicity == RelationshipMultiplicity.ZeroOrOne;
            }

            if (isCheckingTarget)
            {
                string      rngSchema = string.Format(isNullable ? rngFormat_nullable : rngFormat_one, 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);
        }
示例#7
0
        /// <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);
        }
示例#8
0
        /// <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.OriginalString.TrimEnd('/') + @"/" + 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>
        /// 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 = 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 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);
        }
示例#12
0
        /// <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);
        }
示例#13
0
        /// <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);
        }