示例#1
0
        /// <summary>
        ///     The CALDAV:calendar-query REPORT performs a search for all calendar object resources that match a
        ///     specified filter. The response of this report will contain all the WebDAV properties and calendar object
        ///     resource data specified in the request. In the case of the CALDAV:calendar-data XML element, one can
        ///     explicitly specify the calendar components and properties that should be returned in the calendar object
        ///     resource data that matches the filter.
        /// </summary>
        /// <param name="xmlDoc">The body of the request.</param>
        /// <param name="collectionURl"></param>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        public async Task CalendarQuery(IXMLTreeStructure xmlDoc, string collectionURl, HttpContext httpContext)
        {
            IFileSystemManagement fs = new FileSystemManagement();
            // take the first prop node to know the data that
            // should ne returned
            IXMLTreeStructure propNode;

            xmlDoc.GetChildAtAnyLevel("prop", out propNode);

            //get the filters to be applied
            IXMLTreeStructure componentFilter;

            xmlDoc.GetChildAtAnyLevel("filter", out componentFilter);


            var userResources = new Dictionary <string, string>();

            await fs.GetAllCalendarObjectResource(collectionURl, userResources);

            var userCalendars = userResources.ToDictionary(userResource => userResource.Key,
                                                           userResource => VCalendar.Parse(userResource.Value));

            //apply the filters to the calendars
            var filteredCalendars = userCalendars.Where(x => x.Value.FilterResource(componentFilter));

            await ReportResponseBuilder(filteredCalendars, propNode, httpContext);
        }
示例#2
0
        /// <summary>
        ///     The CALDAV:calendar-multiget REPORT is used to retrieve specific calendar object resources from within a
        ///     collection, if the Request-URI is a collection, or to retrieve a specific calendar object resource, if the
        ///     Request-URI is a calendar object resource. This report is similar to the CALDAV:calendar-query REPORT
        ///     (see Section 7.8), except that it takes a list of DAV:href elements, instead of a CALDAV:filter element, to
        ///     determine which calendar object resources to return
        /// </summary>
        /// <returns></returns>
        private async Task CalendarMultiget(IXMLTreeStructure xmlBody, HttpContext httpContext)
        {
            // take the first prop node to know the data that
            // should ne returned
            IXMLTreeStructure propNode;

            xmlBody.GetChildAtAnyLevel("prop", out propNode);

            //take the href nodes. Contain the direction of the resources files that
            //are requested
            var hrefs = xmlBody.Children.Where(node => node.NodeName == "href").Select(href => href.Value);

            var result = new Dictionary <string, string>();

            // process the requested resources
            foreach (var href in hrefs)
            {
                var fs = new FileSystemManagement();

                var resourceContent = await fs.GetCalendarObjectResource(href);

                result.Add(href, resourceContent);
            }
            await ReportResponseBuilder(result
                                        .Select(
                                            x =>
                                            new KeyValuePair <string, VCalendar>(x.Key,
                                                                                 string.IsNullOrEmpty(x.Value) ? null : VCalendar.Parse(x.Value))), propNode, httpContext);
        }
示例#3
0
        public async Task AclPrincipalPropSet(IXMLTreeStructure body, HttpResponse response)
        {
            //take the requested properties from the body
            // of the request
            IXMLTreeStructure propNode;

            //first take the node container of the property names
            body.GetChildAtAnyLevel("prop", out propNode);

            //take the children of the node, these are the proeprties
            var requestedProperties = propNode.Children.Select(x =>
                                                               new KeyValuePair <string, string>(x.NodeName, x.MainNamespace));

            var colUrl = "";

            //Take the resource with the href == to the given url
            //TODO: should the href property be store in a property?
            var resource = await _resourceRepository.GetAsync(colUrl);

            //take the string representation of the acl property
            //this property is stored in xml format so is needed to
            //be parsed to xml
            var aclProperty    = resource.Properties.First(x => x.Name == "acl");
            var aclXmlProperty = XDocument.Parse(aclProperty.Value);

            //take the href of the principals of the property
            var principalsURLs = aclXmlProperty.Elements("principal")
                                 .Select(x => x.Descendants("href").FirstOrDefault());

            var principals = new Dictionary <Principal, IEnumerable <Property> >();

            //take all the principals with its url equal to the givens
            foreach (var pUrl in principalsURLs)
            {
                var principal = _principalRepository.Get(pUrl.Value);
                if (principal != null)
                {
                    principals.Add(principal, null);
                }
            }

            //take the requested properties from the principals
            foreach (var principal in principals)
            {
                principals[principal.Key] = principal.Key.TakeProperties(requestedProperties);
            }

            await WriteBody(response, principals);
        }
 /// <summary>
 ///     The filters have to be applied in an specific component, property
 ///     or param of a property. This method go deep in the calCOmponents following the
 ///     treeStructure of the filter till it get the component where to apply the filter.
 /// </summary>
 /// <param name="container">The container of the components.</param>
 /// <param name="treeStructure">The IXMLTree where is the filter.</param>
 /// <param name="filter">Return The XmlTreeStructure node that contains the filter.</param>
 /// <param name="component">The final component where to apply the filter.</param>
 /// <returns>True if found the component, false otherwise.</returns>
 public static bool ComponentSeeker(this ICalendarComponentsContainer container,
                                    IXMLTreeStructure treeStructure, out IXMLTreeStructure filter, out ICalendarComponent component)
 {
     filter    = null;
     component = null;
     while (true)
     {
         ICalendarComponent comp     = null;
         IXMLTreeStructure  compNode = null;
         treeStructure.GetChildAtAnyLevel("comp-filter", out compNode);
         if (compNode == null)
         {
             //if the filter doesn't has a child with comp-filter name
             //and the name of the current container is the same
             if (((ICalendarObject)container).Name == treeStructure.Attributes["name"])
             {
                 filter    = treeStructure;
                 component = container as ICalendarComponent;
                 return(true);
             }
             else
             {
                 return(false);
             }
         }
         var compName = compNode.Attributes["name"];
         //if the container doesn't has a calComponent with the desired compName
         //then return false
         if (!container.CalendarComponents.ContainsKey(compName))
         {
             return(false);
         }
         //take the comp with the desired name
         comp = container.CalendarComponents[compName].First();
         var componentsContainer = comp as ICalendarComponentsContainer;
         //if the the filter has more components and the container has more calendarComp
         //then go deeper
         if (componentsContainer != null && compNode.Children.Any(x => x.NodeName == "comp-filter"))
         {
             container     = componentsContainer;
             treeStructure = compNode;
             continue;
         }
         //if not then apply the filter in the comp
         component = comp;
         filter    = compNode;
         return(true);
     }
 }
示例#5
0
        /// <summary>
        ///     Extract all property names and property namespace from a prop element of a  propfind body.
        /// </summary>
        /// <param name="propFindTree"></param>
        /// <returns></returns>
        private List <KeyValuePair <string, string> > ExtractPropertiesNameMainNS(IXMLTreeStructure propFindTree)
        {
            var retList = new List <KeyValuePair <string, string> >();
            IXMLTreeStructure props;

            if (propFindTree.GetChildAtAnyLevel("prop", out props))
            {
                retList.AddRange(
                    props.Children.Select(
                        child =>
                        new KeyValuePair <string, string>(child.NodeName,
                                                          string.IsNullOrEmpty(child.MainNamespace) ? "DAV:" : child.MainNamespace)));
            }
            return(retList);
        }
        /// <summary>
        ///     Apply different filters to the given calendar.
        /// </summary>
        /// <param name="calendar">THe calendar to apply the filter.</param>
        /// <param name="filterTree">The filter container. The node in the xml with name = "filter"</param>
        /// <returns>True if the calendar pass the filter, false otherwise</returns>
        public static bool FilterResource(this VCalendar calendar, IXMLTreeStructure filterTree)
        {
            //first get the component in the calendar where to apply the filter.
            IXMLTreeStructure  filtersContainer;
            ICalendarComponent component;

            //take the first node with "comp-filter" name,
            // this is the node with name="VCALENDAR"
            filterTree.GetChildAtAnyLevel("comp-filter", out filterTree);

            //get the component and filter in the position of the first component
            // required by the filter that is a child of VCALENDAR
            if (!ComponentSeeker(calendar, filterTree, out filtersContainer, out component))
            {
                return(false); //if the container doesn't have the requested comp then return false;
            }
            foreach (var filter in filtersContainer.Children)
            {
                switch (filter.NodeName)
                {
                case "prop-filter":
                    var result = component.PropertyFilter(filter);
                    if (!result)
                    {
                        return(false);
                    }
                    break;

                case "time-range":
                    result = component.ApplyTimeFilter(filter);
                    if (!result)
                    {
                        return(false);
                    }
                    break;

                default:
                    throw new NotImplementedException($"The filter with name{filter.NodeName} isn't implemented yet");
                }
            }
            return(true);
        }