Esempio n. 1
0
        public void RetrievalofAllPendingToDos()
        {
            var xmlStr   = @"<C:filter  xmlns:C=""urn:ietf:params:xml:ns:caldav"">
<C:comp-filter name=""VCALENDAR"" xmlns:C=""urn:ietf:params:xml:ns:caldav"">
	<C:comp-filter name=""VTODO"">
<C:prop-filter name=""COMPLETED"">
<C:is-not-defined/>
</C:prop-filter>
<C:prop-filter name=""STATUS"">
<C:text-match
negate-condition=""yes"">CANCELLED</C:text-match>
</C:prop-filter>
</C:comp-filter>
</C:comp-filter></C:filter>";
            var calStr   = @"BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp.//CalDAV Client//EN
BEGIN:VTODO
DTSTAMP:20060205T235335Z
DUE;VALUE=DATE:20060104
STATUS:NEEDS-ACTION
SUMMARY:Task #1
UID:[email protected]
BEGIN:VALARM
ACTION:AUDIO
TRIGGER;RELATED=START:-PT10M
END:VALARM
END:VTODO
END:VCALENDAR";
            var calendar = new VCalendar(calStr);
            var xmlTree  = XmlTreeStructure.Parse(xmlStr);
            var result   = calendar.FilterResource(xmlTree);

            Assert.True(result);
        }
Esempio n. 2
0
        public async Task PropNameMethod(string url, string calendarResourceId, int?depth,
                                         XmlTreeStructure multistatusTree)
        {
            //Here it is created the response body for the collection or resource
            //It depends if calendarResourceId == null.
            var primaryResponse = await PropNameFillTree(url);

            //The response body is added to the result xml tree.
            multistatusTree.AddChild(primaryResponse);

            //Now I start putting all objectResource responses if the primary target was a collection
            //and if depth is greater than depth 0.

            #region Adding the responses for resources.

            if (calendarResourceId == null && depth == 1 || depth == -1)
            {
                var collection = _collectionRepository.Get(url);

                foreach (var calendarResource in collection.CalendarResources)
                {
                    var resourceResponse = await PropNameFillTree(url + calendarResource.Name, calendarResource.Name);

                    multistatusTree.AddChild(resourceResponse);
                }
            }

            #endregion
        }
Esempio n. 3
0
        /// <summary>
        ///     Used to build a response with an error
        /// </summary>
        /// <param name="response">The response that comes from the controller</param>
        /// <param name="errorMessage">The message to put in the error.</param>
        /// <param name="errorCode">The code of the error.</param>
        /// <param name="href">The requested href.</param>
        /// <returns></returns>
        private async Task ReturnError(HttpResponse response, string errorMessage, int errorCode, string href)
        {
            //build the root of the xml
            var multistatusNode = new XmlTreeStructure("multistatus", "DAV:")
            {
                Namespaces = new Dictionary <string, string>
                {
                    { "D", "DAV:" },
                    { "C", "urn:ietf:params:xml:ns:caldav" }
                }
            };

            //each returned resource has is own response and href nodes
            var responseNode = new XmlTreeStructure("response", "DAV:");
            var hrefNode     = new XmlTreeStructure("href", "DAV:");

            hrefNode.AddValue(href);

            //href is a child pf response
            responseNode.AddChild(hrefNode);

            IXMLTreeStructure statusNode = new XmlTreeStructure("status", "DAV:");

            statusNode.AddValue($"HTTP/1.1 {errorCode} {errorMessage}");
            responseNode.AddChild(statusNode);

            multistatusNode.AddChild(responseNode);

            await response.WriteAsync(multistatusNode.ToString());
        }
Esempio n. 4
0
        public void UnitTest3()
        {
            var calStr   = @"BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp.//CalDAV Client//EN
BEGIN:VTODO
DTSTAMP:20060205T235300Z
DUE;TZID=US/Eastern:20060106T120000
LAST-MODIFIED:20060205T235308Z
SEQUENCE:1
STATUS:NEEDS-ACTION
SUMMARY:Task #2
UID:[email protected]
BEGIN:VALARM
ACTION:AUDIO
TRIGGER;RELATED=START:-PT10M
END:VALARM
END:VTODO
END:VCALENDAR";
            var xmlStr   = @"<C:filter  xmlns:C=""urn:ietf:params:xml:ns:caldav"">
<C:comp-filter name=""VCALENDAR"" xmlns:C=""urn:ietf:params:xml:ns:caldav"">
<C:comp-filter name=""VTODO"">
<C:comp-filter name=""VALARM"">
<C:time-range start=""20060106T100000Z""
end=""20060107T100000Z""/>
</C:comp-filter>
</C:comp-filter>
</C:comp-filter></C:filter>";
            var calendar = new VCalendar(calStr);
            var xmlTree  = XmlTreeStructure.Parse(xmlStr);
            var result   = calendar.FilterResource(xmlTree);

            Assert.True(result);
        }
Esempio n. 5
0
        public void UnitTest2()
        {
            var xmlStr = @"<C:filter xmlns:C=""urn:ietf:params:xml:ns:caldav"">
                   <C:comp-filter name=""VCALENDAR"">
                <C:comp-filter name=""VFREEBUSY"">
                <C:time-range start=""20060102T000000Z""
                end=""20060103T000000Z""/>
                </C:comp-filter>
                </C:comp-filter>
                </C:filter>";
            var calStr = @"BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp.//CalDAV Client//EN
BEGIN:VFREEBUSY
ORGANIZER;CN=""Bernard Desruisseaux"":mailto:[email protected]
UID:[email protected]
DTSTAMP:20050530T123421Z
DTSTART:20060101T100000Z
DTEND:20060108T100000Z
FREEBUSY;FBTYPE=BUSY-TENTATIVE:20060102T100000Z/20060102T120000Z
END:VFREEBUSY
END:VCALENDAR";

            var calendar = VCalendar.Parse(calStr);
            var xmlTree  = XmlTreeStructure.Parse(xmlStr);
            var result   = calendar.FilterResource(xmlTree);

            Assert.True(result);
        }
Esempio n. 6
0
        public async Task ReadCalendarObjectResource(Dictionary <string, string> propertiesAndHeaders,
                                                     HttpResponse response)
        {
            #region Extracting Properties

            string url;
            propertiesAndHeaders.TryGetValue("url", out url);

            #endregion

            //An easy way of accessing the headers of the http response
            response.GetTypedHeaders();

            //StorageManagement.SetUserAndCollection(principalUrl, collectionName);
            //Must return the Etag header of the COR

            var calendarRes = _resourceRespository.Get(url);

            if (calendarRes == null || !StorageManagement.ExistCalendarObjectResource(url))
            {
                response.StatusCode = (int)HttpStatusCode.NotFound;
                return;
            }

            var resourceBody = await StorageManagement.GetCalendarObjectResource(url);

            var etagProperty = calendarRes.Properties.FirstOrDefault(x => x.Name == "getetag");
            if (etagProperty != null)
            {
                var etag = XmlTreeStructure.Parse(etagProperty.Value).Value;
                response.Headers["etag"] = etag;
            }

            await response.WriteAsync(resourceBody);
        }
Esempio n. 7
0
        /// <summary>
        ///     Process the report depending on the values of the header
        ///     and the body.
        /// </summary>
        /// <returns></returns>
        public async Task ProcessRequest(HttpContext httpContext)
        {
            var body = new StreamReader(httpContext.Request.Body).ReadToEnd();

            // var node = xmlBody.Children.First();
            var xmlBody = XmlTreeStructure.Parse(body);

            //take the target url that is the identifier of the collection
            var urlId = httpContext.Request.GetRealUrl();

            //take the first node of the xml and process the request
            //by the name of the first node
            switch (xmlBody.NodeName)
            {
            case "calendar-query":
                await CalendarQuery(xmlBody, urlId, httpContext);

                break;

            case "calendar-multiget":
                await CalendarMultiget(xmlBody, httpContext);

                break;

            default:
                throw new NotImplementedException(
                          $"The REPORT request {xmlBody.NodeName} with ns equal to {xmlBody.MainNamespace} is not implemented yet .");
            }
        }
Esempio n. 8
0
        /// <summary>
        ///     Take the calendar that passed the filter and
        ///     create the multi-status xml.
        /// </summary>
        /// <param name="resources">The resources to be returned</param>
        /// <param name="calDataNode">
        ///     THis is the node with name ="prop"
        ///     When used in a calendaring REPORT request, the CALDAV:calendar-data XML
        ///     element specifies which parts of calendar object resources need to be returned in the
        ///     response.If the CALDAV:calendar-data XML element doesn't contain any
        ///     CALDAV:comp element, calendar object resources will be returned in their entirety.
        /// </param>
        /// <param name="httpContext"></param>
        /// <returns>The string representation of the multi-status Xml with the results.</returns>
        public async Task ReportResponseBuilder(IEnumerable <KeyValuePair <string, VCalendar> > resources,
                                                IXMLTreeStructure calDataNode, HttpContext httpContext)
        {
            var multistatusNode = new XmlTreeStructure("multistatus", "DAV:")
            {
                Namespaces = new Dictionary <string, string>
                {
                    { "D", "DAV:" },
                    { "C", "urn:ietf:params:xml:ns:caldav" }
                }
            };

            //take the node that specified the comp and properties
            //to return


            foreach (var resource in resources)
            {
                IXMLTreeStructure statusNode;

                //each returned resource has is own response and nodes
                var responseNode = new XmlTreeStructure("response", "DAV:");
                var hrefNode     = new XmlTreeStructure("href", "DAV:");
                var href         = resource.Key[0] != '/' ? "/" + resource.Key : resource.Key;
                hrefNode.AddValue(href);

                //href is a child pf response
                responseNode.AddChild(hrefNode);

                //if the resource is null it was not foound so
                // add an error status
                if (resource.Value == null)
                {
                    statusNode = new XmlTreeStructure("status", "DAV:");
                    statusNode.AddValue("HTTP/1.1 404 Not Found");
                    responseNode.AddChild(statusNode);
                }
                else
                {
                    var propstatNode = new XmlTreeStructure("propstat", "DAV:");

                    //that the requested data
                    var propStats = await ProccessPropNode(calDataNode, resource);


                    foreach (var propStat in propStats)
                    {
                        responseNode.AddChild(propStat);
                    }
                }

                multistatusNode.AddChild(responseNode);
            }
            var responseText  = multistatusNode.ToString();
            var responseBytes = Encoding.UTF8.GetBytes(responseText);

            httpContext.Response.ContentLength = responseBytes.Length;
            await httpContext.Response.Body.WriteAsync(responseBytes, 0, responseBytes.Length);
        }
Esempio n. 9
0
        public void RecursiveSeekerTest3()
        {
            var calStr   = @"BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp.//CalDAV Client//EN
BEGIN:VTIMEZONE
LAST-MODIFIED:20040110T032845Z
TZID:US/Eastern
BEGIN:DAYLIGHT
DTSTART:20000404T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
END:DAYLIGHT
BEGIN:STANDARD
DTSTART:20001026T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
TZNAME:EST
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:[email protected]
DTSTAMP:20060206T001220Z
DTSTART;TZID=US/Eastern:20060104T100000
DURATION:PT1H
LAST-MODIFIED:20060206T001330Z
ORGANIZER:mailto:[email protected]
SEQUENCE:1
STATUS:TENTATIVE
SUMMARY:Event #3
UID:[email protected]
X-ABC-GUID:[email protected]
END:VEVENT
END:VCALENDAR";
            var xmlStr   = @"<C:comp-filter name=""VCALENDAR"" xmlns:C=""urn:ietf:params:xml:ns:caldav"">
<C:comp-filter name=""VTODO"">
<C:prop-filter name=""UID"">
<C:text-match collation=""i;octet""
>[email protected]</C:text-match>
</C:prop-filter>
</C:comp-filter>
</C:comp-filter>";
            var calendar = new VCalendar(calStr);
            var xmlTree  = XmlTreeStructure.Parse(xmlStr);
            IXMLTreeStructure  tree;
            ICalendarComponent comp;
            var result = calendar.ComponentSeeker(xmlTree, out tree, out comp);

            Assert.False(result);

            /*Assert.Equal("VEVENT", comp.Name);
             *          Assert.Equal("VEVENT", tree.Attributes["name"]);*/
        }
Esempio n. 10
0
        private async Task <bool> BuiltResponseForSet(string url, string calendarResourceId,
                                                      bool errorOccurred, IXMLTreeStructure setTree, IXMLTreeStructure response)
        {
            //For each property it is tried to remove, if not possible change the error occured to true and
            //continue setting dependency error to the rest.
            var prop       = setTree.GetChild("prop");
            var errorStack = new Stack <string>();

            foreach (var property in prop.Children)
            {
                var propstat = new XmlTreeStructure("propstat", "DAV:");
                var stat     = new XmlTreeStructure("status", "DAV:");
                var resProp  = new XmlTreeStructure("prop", "DAV:");

                resProp.AddChild(new XmlTreeStructure(property.NodeName, property.MainNamespace));
                propstat.AddChild(stat);
                propstat.AddChild(resProp);

                response.AddChild(propstat);

                if (errorOccurred)
                {
                    stat.Value = "HTTP/1.1 424 Failed Dependency";
                }

                else
                {
                    //Try to modify the specified property if it exist, if not try to create it
                    //gets an error message from the stack in case of problems.
                    errorOccurred =
                        !(calendarResourceId != null
                            ? await
                          _resourceRespository.CreateOrModifyProperty(url, property.NodeName,
                                                                      property.MainNamespace,
                                                                      GetValueFromRealProperty(property), errorStack, false)
                            : await
                          _collectionRespository.CreateOrModifyProperty(url, property.NodeName,
                                                                        property.MainNamespace,
                                                                        GetValueFromRealProperty(property), errorStack, false));
                    //collection.CreateOrModifyProperty(property.NodeName, property.MainNamespace,
                    //    GetValueFromRealProperty(property), errorStack));
                    if (errorOccurred && errorStack.Count > 0)
                    {
                        stat.Value = errorStack.Pop();
                    }
                    else
                    {
                        stat.Value = "HTTP/1.1 200 OK";
                        //db.SaveChanges();
                    }
                }
            }
            return(errorOccurred);
        }
Esempio n. 11
0
        public void FilterResourceTest1()
        {
            var calStr   = @"BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp.//CalDAV Client//EN
BEGIN:VTIMEZONE
LAST-MODIFIED:20040110T032845Z
TZID:US/Eastern
BEGIN:DAYLIGHT
DTSTART:20000404T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
END:DAYLIGHT
BEGIN:STANDARD
DTSTART:20001026T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
TZNAME:EST
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:[email protected]
DTSTAMP:20060206T001220Z
DTSTART;TZID=US/Eastern:20060104T100000
DURATION:PT1H
LAST-MODIFIED:20060206T001330Z
ORGANIZER:mailto:[email protected]
SEQUENCE:1
STATUS:TENTATIVE
SUMMARY:Event #3
UID:[email protected]
X-ABC-GUID:[email protected]
END:VEVENT
END:VCALENDAR";
            var xmlStr   = @"<C:filter  xmlns:C=""urn:ietf:params:xml:ns:caldav"">
<C:comp-filter name=""VCALENDAR"" xmlns:C=""urn:ietf:params:xml:ns:caldav"">
	<C:comp-filter name=""VEVENT"">
		<C:prop-filter name=""ATTENDEE"">
			<C:text-match collation=""i;ascii-casemap"">mailto:[email protected]</C:text-match>
			<C:param-filter name=""PARTSTAT"">
				 <C:text-match collation=""i;ascii-casemap"">NEEDS-ACTION</C:text-match>
			</C:param-filter>
		</C:prop-filter>
	</C:comp-filter>
</C:comp-filter></C:filter>";
            var calendar = new VCalendar(calStr);
            var xmlTree  = XmlTreeStructure.Parse(xmlStr);
            var result   = calendar.FilterResource(xmlTree);

            Assert.True(result);
        }
Esempio n. 12
0
        private async Task <bool> BuiltResponseForRemove(string url, string calendarResourceId,
                                                         bool errorOccurred, IXMLTreeStructure removeTree, IXMLTreeStructure response)
        {
            //For each property it is tried to remove, if not possible change the error occured to true and
            //continue setting dependency error to the rest.
            var prop       = removeTree.GetChild("prop");
            var errorStack = new Stack <string>();

            foreach (var property in prop.Children)
            {
                //The structure for the response does not change.
                //It is constructed with a propstat and the value is never showed in the prop element.
                var propstat = new XmlTreeStructure("propstat", "DAV:");
                var stat     = new XmlTreeStructure("status", "DAV:");
                var resProp  = new XmlTreeStructure("prop", "DAV:");

                propstat.AddChild(stat);
                propstat.AddChild(resProp);
                resProp.AddChild(new XmlTreeStructure(property.NodeName, property.MainNamespace));
                response.AddChild(propstat);

                //If an error occurred previously the stat if 424 Failed Dependency.
                if (errorOccurred)
                {
                    stat.Value = "HTTP/1.1 424 Failed Dependency";
                }


                else
                {
                    //Try to remove the specified property, gets an error message from the stack in case of problems.
                    errorOccurred =
                        !(calendarResourceId != null
                            ? await
                          _resourceRespository.RemoveProperty(url,
                                                              new KeyValuePair <string, string>(property.NodeName, property.MainNamespace),
                                                              errorStack)
                            : await _collectionRespository.RemoveProperty(url,
                                                                          new KeyValuePair <string, string>(property.NodeName, property.MainNamespace), errorStack));
                    //collection.RemoveProperty(property.NodeName, property.MainNamespace, errorStack));
                    if (errorOccurred && errorStack.Count > 0)
                    {
                        stat.Value = errorStack.Pop();
                    }
                    else
                    {
                        stat.Value = "HTTP/1.1 200 OK";
                        // db.SaveChanges();
                    }
                }
            }
            return(errorOccurred);
        }
Esempio n. 13
0
        public async Task AllPropMethod(string url, string calendarResourceId, int?depth,
                                        List <KeyValuePair <string, string> > aditionalProperties, XmlTreeStructure multistatusTree)
        {
            //error flag

            //Here it is created the response body for the collection or resource
            //It depends if calendarResourceId == null.
            var primaryResponse = await AllPropFillTree(url, calendarResourceId, aditionalProperties);

            //The response body is added to the result xml tree.
            multistatusTree.AddChild(primaryResponse);

            //check if there was any error
            IXMLTreeStructure errorNode;
            var errorOcurred = primaryResponse.GetChildAtAnyLevel("responsedescription", out errorNode);

            //Now I start putting all objectResource responses if the primary target was a collection
            //and if depth is greater than depth 0.

            #region Adding the responses for resources.

            if (calendarResourceId == null && depth == 1 || depth == -1)
            {
                var collection = _collectionRepository.Get(url);

                foreach (var calendarResource in collection.CalendarResources)
                {
                    //For every resource in the collection it is added a new xml "response"
                    var resourceResponse = await AllPropFillTree(url + calendarResource.Name, calendarResource.Name,
                                                                 aditionalProperties);

                    multistatusTree.AddChild(resourceResponse);

                    //error check
                    if (!errorOcurred)
                    {
                        errorOcurred = resourceResponse.GetChildAtAnyLevel("responsedescription", out errorNode);
                    }
                }
            }
            if (errorOcurred)
            {
                //if an error occured it is added a new "responsedescription" with a message of the error
                //to the root of the tree. That is the "multistatus" xml.
                errorNode = new XmlTreeStructure("responsedescription", "DAV:");
                errorNode.AddValue("There has been an error");
                multistatusTree.AddChild(errorNode);
            }

            #endregion
        }
Esempio n. 14
0
        public async Task ProcessRequest(HttpRequest request, HttpResponse response)
        {
            //check the depth of the header
            // This report is only defined when the Depth header has value "0";
            // other values result in a 400 (Bad Request) error response.
            if (request.Headers.ContainsKey("Depth"))
            {
                var depth = request.Headers["Depth"];
                if (depth != "\"0\"")
                {
                    response.StatusCode = 400;
                    return;
                }
            }

            string href = request.Path;
            //TODO: take here the email of the user by calling
            //to the authentication api
            var userEmail = "";

            response = null;
            //take the string representation of the body
            var bodyStr = request.Body.ToString();
            var xmlbody = XmlTreeStructure.Parse(bodyStr);

            switch (xmlbody.NodeName)
            {
            case "acl-principal-prop-set":
                await AclPrincipalPropSet(xmlbody, response);

                break;

            case "principal-match":
                await PrincipalMatch(xmlbody, userEmail, href, response);

                break;

            case "principal-property-search":
                await PrincipalPropertySearch(xmlbody, request, response);

                break;

            case "principal-search-property-set":
                await PrincipalSearchPropertySet(response);

                break;
            }
        }
Esempio n. 15
0
        public void UnitTest4()
        {
            var doc  = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<C:calendar-query xmlns:D=""DAV:""
xmlns:C=""urn:ietf:params:xml:ns:caldav"">
<D:prop>
<D:getetag/>
<C:calendar-data>
<C:comp name=""VCALENDAR"">
<C:prop name=""VERSION""/>
<C:comp name=""VEVENT"">
<C:prop name=""SUMMARY""/>
<C:prop name=""UID""/>
<C:prop name=""DTSTART""/>
<C:prop name=""DTEND""/>
<C:prop name=""DURATION""/>
<C:prop name=""RRULE""/>
<C:prop name=""RDATE""/>
<C:prop name=""EXRULE""/>
<C:prop name=""EXDATE""/>
<C:prop name=""RECURRENCE-ID""/>
</C:comp>
<C:comp name=""VTIMEZONE""/>
</C:comp>
</C:calendar-data>
</D:prop>
<C:filter>
<C:comp-filter name=""VCALENDAR"">
<C:comp-filter name=""VEVENT"">
<C:time-range start=""20060104T000000Z""
end=""20060105T000000Z""/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>";
            var xDoc = XDocument.Parse(doc);

            xDoc.ToString();
            var temp1 = xDoc.Root.Attributes().Where(x => x.IsNamespaceDeclaration);
            var item  = xDoc.CreateWriter();

            var result = XmlTreeStructure.Parse(doc);
            IXMLTreeStructure filter;

            Assert.True(result.GetChildAtAnyLevel("filter", out filter));
            Assert.Equal(filter.GetChild("comp-filter").Attributes["name"], "VCALENDAR");
        }
Esempio n. 16
0
        public void IXmlTreeStrucureToString()
        {
            var doc = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<C:calendar-query xmlns:D=""DAV:""
xmlns:C=""urn:ietf:params:xml:ns:caldav"">
<D:prop>
<D:getetag/>
<C:calendar-data>
<C:comp name=""VCALENDAR"">
<C:prop name=""VERSION""/>
<C:comp name=""VEVENT"">
<C:prop name=""SUMMARY""/>
<C:prop name=""UID""/>
<C:prop name=""DTSTART""/>
<C:prop name=""DTEND""/>
<C:prop name=""DURATION""/>
<C:prop name=""RRULE""/>
<C:prop name=""RDATE""/>
<C:prop name=""EXRULE""/>
<C:prop name=""EXDATE""/>
<C:prop name=""RECURRENCE-ID""/>
</C:comp>
<C:comp name=""VTIMEZONE""/>
</C:comp>
</C:calendar-data>
</D:prop>
<C:filter>
<C:comp-filter name=""VCALENDAR"">
<C:comp-filter name=""VEVENT"">
<C:time-range start=""20060104T000000Z""
end=""20060105T000000Z""/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>";
            var xmlTreeStructure  = XmlTreeStructure.Parse(doc);
            var xmlTreeStructure2 = XmlTreeStructure.Parse(xmlTreeStructure.ToString());
            var xmlStr1           = xmlTreeStructure.ToString();
            var xmlStr2           = xmlTreeStructure2.ToString();

            Assert.Equal(xmlStr1, xmlStr2);
        }
Esempio n. 17
0
        public void PartialRetrievalofEventsbyTimeRange()
        {
            var xmlStr   = @"<C:filter  xmlns:C=""urn:ietf:params:xml:ns:caldav"">
<C:comp-filter name=""VCALENDAR"" xmlns:C=""urn:ietf:params:xml:ns:caldav"">
	<C:comp-filter name=""VEVENT"">
		<C:time-range start=""20060104T000000Z"" end=""20060105T000000Z""/>
	</C:comp-filter>
</C:comp-filter></C:filter>";
            var calStr   = @"BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VTIMEZONE
LAST-MODIFIED:20040110T032845Z
TZID:US/Eastern
BEGIN:DAYLIGHT
DTSTART:20000404T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
END:DAYLIGHT
BEGIN:STANDARD
DTSTART:20001026T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
TZNAME:EST
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=US/Eastern:20060102T120000
DURATION:PT1H
RRULE:FREQ=DAILY;COUNT=5
SUMMARY:Event #2
UID:[email protected]
END:VEVENT
END:VCALENDAR";
            var calendar = new VCalendar(calStr);
            var xmlTree  = XmlTreeStructure.Parse(xmlStr);
            var result   = calendar.FilterResource(xmlTree);

            Assert.True(result);
        }
Esempio n. 18
0
        public void UnitTest3()
        {
            var doc    = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<C:calendar-query xmlns:D=""DAV:""
xmlns:C=""urn:ietf:params:xml:ns:caldav"">
<D:prop>
<D:getetag/>
<C:calendar-data>
<C:comp name=""VCALENDAR"">
<C:prop name=""VERSION""/>
<C:comp name=""VEVENT"">
<C:prop name=""SUMMARY""/>
<C:prop name=""UID""/>
<C:prop name=""DTSTART""/>
<C:prop name=""DTEND""/>
<C:prop name=""DURATION""/>
<C:prop name=""RRULE""/>
<C:prop name=""RDATE""/>
<C:prop name=""EXRULE""/>
<C:prop name=""EXDATE""/>
<C:prop name=""RECURRENCE-ID""/>
</C:comp>
<C:comp name=""VTIMEZONE""/>
</C:comp>
</C:calendar-data>
</D:prop>
<C:filter>
<C:comp-filter name=""VCALENDAR"">
<C:comp-filter name=""VEVENT"">
<C:time-range start=""20060104T000000Z""
end=""20060105T000000Z""/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>";
            var result = XmlTreeStructure.Parse(doc);
            IXMLTreeStructure filter;

            Assert.True(result.GetChildAtAnyLevel("filter", out filter));
            Assert.NotNull(filter.GetChild("comp-filter"));
        }
        public async Task <bool> PreconditionsOK(Dictionary <string, string> propertiesAndHeaders, HttpResponse response)
        {
            #region Extracting Properties

            var body = propertiesAndHeaders["body"];
            var url  = propertiesAndHeaders["url"];

            #endregion

            if (fs.ExistCalendarCollection(url) || await _collectionRepository.Exist(url))
            {
                response.StatusCode = (int)HttpStatusCode.Forbidden;
                response.Body.Write(@"<?xml version='1.0' encoding='UTF-8'?>
<error xmlns='DAV:'>
  <resource-must-be-null/>  
</error>");

                return(false);
            }

            if (!string.IsNullOrEmpty(body))
            {
                var bodyTree = XmlTreeStructure.Parse(body);
                if (bodyTree == null)
                {
                    response.StatusCode = (int)HttpStatusCode.Forbidden;
                    response.Body.Write("Wrong Body");
                    return(false);
                }
                if (bodyTree.NodeName != "mkcalendar")
                {
                    response.StatusCode = (int)HttpStatusCode.Forbidden;
                    response.Body.Write("Wrong Body");

                    return(false);
                }
            }

            return(true);
        }
Esempio n. 20
0
        private static IXMLTreeStructure xmlWalker(XElement node)
        {
            var output = new XmlTreeStructure(node.Name.LocalName, null)
            {
                Namespaces = node.Attributes().Where(x => x.IsNamespaceDeclaration).
                             ToDictionary(x => x.Name.LocalName, x => x.Value),
                Value = node.Value
            };

            foreach (var attribute in node.Attributes().Where(x => !output.Namespaces.Keys.Contains(x.Name.LocalName)))
            {
                output.AddAttribute(attribute.Name.LocalName, attribute.Value);
            }
            var descendants = node.Elements();
            var descNodes   = node.DescendantNodes();

            foreach (var descendant in descendants)
            {
                output.AddChild(xmlWalker(descendant));
            }
            return(output);
        }
Esempio n. 21
0
        public void UnitTest2()
        {
            var tree = new XmlTreeStructure("node1", "DAV:",
                                            new Dictionary <string, string>
            {
                { "D", "DAV:" },
                { "C", "urn:ietf:params:xml: ns: caldav" }
            });

            tree.AddChild(new XmlTreeStructure("child1", null)).
            AddChild(new XmlTreeStructure("child2", null));
            IXMLTreeStructure child2;

            tree.GetChildAtAnyLevel("child2", out child2);
            child2.AddChild(new XmlTreeStructure("child3", null))
            .GetChild("child3").AddChild(new XmlTreeStructure("child4", null));
            IXMLTreeStructure child4;

            tree.GetChildAtAnyLevel("child4", out child4);
            child4.AddChild(new XmlTreeStructure("child5", null));
            var child6 = new XmlTreeStructure("child6", null);
            IXMLTreeStructure child5;

            tree.GetChildAtAnyLevel("child5", out child5);
            child5.AddChild(child6);
            IXMLTreeStructure child6_1;

            tree.GetChildAtAnyLevel("child6", out child6_1);
            IXMLTreeStructure test;

            tree.GetChildAtAnyLevel("prop", out test);

            Assert.Null(test);

            test = tree.GetChild("prop");

            Assert.Null(test);
            Assert.Equal(child6_1, child6);
        }
Esempio n. 22
0
        /// <summary>
        ///     Call the method to perform a PROFIND over a
        ///     principal.
        ///     Initially the client could do a PROFIND over
        ///     the server to discover all the user calendars
        ///     or could PORFIND directly over a calendar URL.
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns>The request</returns>
        public async Task Profind(HttpContext httpContext)
        {
            var requestPath  = httpContext.Request.Path;
            var streamReader = new StreamReader(httpContext.Request.Body);
            //read the body of the request
            var bodyString = streamReader.ReadToEnd();

            //try to authenticate the request either with the cookies or the user credentials
            var principal = _authenticate.AuthenticateRequest(httpContext);

            //if the principal is null then there is some problem with the authentication
            //so return
            //if (principal == null)
            //    return;

            var body = XmlTreeStructure.Parse(bodyString);

            //take the requested properties
            var reqProperties = ExtractPropertiesNameMainNS(body);

            await BuildResponse(httpContext.Response, requestPath, reqProperties, principal);
        }
Esempio n. 23
0
        private void ChangeToDependencyError(XmlTreeStructure response)
        {
            //this method is the one in charge of fix the status messages
            //of all the properties that were fine before the error.
            foreach (var child in response.Children)
            {
                if (child.NodeName != "propstat")
                {
                    continue;
                }

                var status      = child.GetChild("status");
                var statMessage = status.Value;
                //if the message is not OK means that we reach
                //the error and no more further message changing is needed.
                if (statMessage != "HTTP/1.1 200 OK")
                {
                    return;
                }
                ((XmlTreeStructure)status).Value = "HTTP/1.1 424 Failed Dependency";
            }
        }
Esempio n. 24
0
        /// <summary>
        ///     Get the permission for the given principal
        ///     in some resource.
        /// </summary>
        /// <param name="principal">The principal that wants to know his permissions.</param>
        /// <param name="property">The resource or collection's DAV:acl property</param>
        /// <returns>Return an I</returns>
        public static XmlTreeStructure GetCurrentUserPermissions(this Principal principal, Property property)
        {
            var pUrl = principal.PrincipalURL;
            var aclP = XDocument.Parse(property.Value).Root;
            IEnumerable <XElement> principalGrantPermissions = null;
            XName aceName = "ace";

            //take the permission for the principal if any
            var descendants  = aclP?.Descendants();
            var aces         = descendants.Where(x => x.Name.LocalName == aceName);
            var principalAce = aces.FirstOrDefault(ace => ace.Descendants()
                                                   .FirstOrDefault(x => x.Name.LocalName == "href")?.Value == pUrl);

            if (principalAce != null)
            {
                principalGrantPermissions = principalAce.Descendants()
                                            .FirstOrDefault(x => x.Name.LocalName == "grant")?.Elements();
            }

            //take the permission for all users if any

            var output = new XElement("current-user-privilege-set", new XAttribute(XNamespace.Xmlns + "D", "DAV:"));


            //add the permission to the response
            if (principalGrantPermissions != null)
            {
                foreach (var permission in principalGrantPermissions)
                {
                    output.Add(permission);
                }
            }
            var outputStr = output.ToString();
            var xmlTree   = XmlTreeStructure.Parse(outputStr) as XmlTreeStructure;

            return(xmlTree);
        }
Esempio n. 25
0
        /// <summary>
        ///     Create the DAV:current-user-principal.
        ///     If not principalUrl is provided means that the
        ///     user is not authenticated.
        /// </summary>
        /// <param name="principal">
        ///     The current principal url, or nothing if the principal is not
        ///     authenticated.
        /// </param>
        /// <returns></returns>
        public static IXMLTreeStructure CreateCurrentUserPrincipal(Principal principal)
        {
            var output = new XmlTreeStructure("current-user-principal", "DAV:");

            IXMLTreeStructure href;

            //if not principal URL is provided means that
            //the principal is not authenticated.
            if (principal != null)
            {
                href = new XmlTreeStructure("href", "DAV:")
                {
                    Value = principal.PrincipalURL
                }
            }
            ;

            else
            {
                href = new XmlTreeStructure("unauthenticated", "DAV:");
            }
            output.AddChild(href);
            return(output);
        }
Esempio n. 26
0
        /// <summary>
        ///     Returns a Response XML element with all the property names
        ///     and property values of the visible properties.
        /// </summary>
        /// <param name="url"></param>
        /// <param name="calendarResourceId">Name of the resource</param>
        /// <param name="additionalProperties">List of additional requested properties (key=name; value=namespace)</param>
        /// <returns></returns>
        private async Task <XmlTreeStructure> AllPropFillTree(string url, string calendarResourceId,
                                                              List <KeyValuePair <string, string> > additionalProperties)
        {
            #region Adding the response of the collection or resource.

            //Adding standard structure for a "response" element.
            var treeChild = new XmlTreeStructure("response", "DAV:");

            #region Adding the <D:href>/api/v1/collections/users|groups/principalId/{collectionName}/{calendarResourceId}?</D:href>

            var href = new XmlTreeStructure("href", "DAV:");
            href.AddValue(SystemProperties._baseUrl + url);

            treeChild.AddChild(href);

            #endregion

            #region Adding the propstat

            #region Selecting properties

            var propertiesCol   = new List <XmlTreeStructure>();
            var propertiesOk    = new List <XmlTreeStructure>();
            var propertiesWrong = new List <XmlTreeStructure>();
            var errorStack      = new Stack <string>();

            //Here all visible properties are retrieve plus a collection of extra properties that can be
            //defined in the request body.

            if (calendarResourceId == null)
            {
                var properties = await _collectionRepository.GetAllProperties(url);

                foreach (var property in properties)
                {
                    //TODO: Check that the property is accessible beyond its visibility.
                    var tempTree = property.Value == null
                        ? new XmlTreeStructure(property.Name, property.Namespace)
                    {
                        Value = ""
                    }
                        : XmlTreeStructure.Parse(property.Value);

                    propertiesCol.Add((XmlTreeStructure)tempTree);
                }

                //looking for additional properties
                if (additionalProperties != null && additionalProperties.Count > 0)
                {
                    foreach (var addProperty in additionalProperties)
                    {
                        //gets the property from database
                        var property = await _collectionRepository.GetProperty(url, addProperty);

                        //Builds the xmlTreeExtructure checking that if the value is null thats because
                        //the property was not found.
                        IXMLTreeStructure prop;
                        if (property != null)
                        {
                            prop = property.Value == null
                                ? new XmlTreeStructure(property.Name, property.Namespace)
                            {
                                Value = ""
                            }
                        }
                        : XmlTreeStructure.Parse(property.Value);
                        else
                        {
                            prop = new XmlTreeStructure(addProperty.Key, addProperty.Value);
                        }
                        propertiesCol.Add((XmlTreeStructure)prop);
                    }
                }
            }
            else
            {
                var properties = await _resourceRespository.GetAllProperties(url);

                foreach (var property in properties)
                {
                    //TODO: Check that the property is accessible beyond its visibility.
                    var tempTree = property.Value == null
                        ? new XmlTreeStructure(property.Name, property.Namespace)
                    {
                        Value = ""
                    }
                        : XmlTreeStructure.Parse(property.Value);

                    propertiesCol.Add((XmlTreeStructure)tempTree);
                }

                //looking for additional properties
                if (additionalProperties != null && additionalProperties.Count > 0)
                {
                    foreach (var addProperty in additionalProperties)
                    {
                        //gets the property from database
                        var property = await _resourceRespository.GetProperty(url, addProperty);

                        //Builds the xmlTreeExtructure checking that if the value is null thats because
                        //the property was not found.
                        IXMLTreeStructure prop;
                        if (property != null)
                        {
                            prop = property.Value == null
                                ? new XmlTreeStructure(property.Name, property.Namespace)
                            {
                                Value = ""
                            }
                        }
                        : XmlTreeStructure.Parse(property.Value);
                        else
                        {
                            prop = new XmlTreeStructure(addProperty.Key, addProperty.Value);
                        }
                        propertiesCol.Add((XmlTreeStructure)prop);
                    }
                }
            }

            //Here there are divided all properties between recovered and error recovering
            foreach (var propTree in propertiesCol)
            {
                if (propTree.Value != null)
                {
                    propertiesOk.Add(propTree);
                }
                else
                {
                    propertiesWrong.Add(propTree);
                }
            }

            #endregion

            #region Adding nested propOK

            //This procedure has been explained in another method.
            //Here the retrieve properties are grouped.

            var propstatOk = new XmlTreeStructure("propstat", "DAV:");
            var propOk     = new XmlTreeStructure("prop", "DAV:");

            //Here i add all properties to the prop.
            foreach (var property in propertiesOk)
            {
                propOk.AddChild(property);
            }

            propstatOk.AddChild(propOk);

            #region Adding nested status OK

            var statusOk = new XmlTreeStructure("status", "DAV:");
            statusOk.AddValue("HTTP/1.1 200 OK");
            propstatOk.AddChild(statusOk);

            #endregion

            #endregion

            #region Adding nested propWrong

            //Here the properties that could not be retrieved are grouped.
            var propstatWrong = new XmlTreeStructure("propstat", "DAV:");
            var propWrong     = new XmlTreeStructure("prop", "DAV:");

            //Here i add all properties to the prop.
            foreach (var property in propertiesWrong)
            {
                propWrong.AddChild(property);
            }

            propstatWrong.AddChild(propWrong);

            #region Adding nested status Not Found

            var statusWrong = new XmlTreeStructure("status", "DAV:");
            statusWrong.AddValue("HTTP/1.1 400 Not Found");
            propstatWrong.AddChild(statusWrong);

            #endregion

            #region Adding responseDescription when wrong

            //Here i add an description for explain the errors.
            //This should be aplied in all method with an similar structure but for the moment is only used here.
            //However this is not required.
            var responseDescrpWrong = new XmlTreeStructure("responsedescription", "DAV:");
            responseDescrpWrong.AddValue("The properties doesn't  exist");
            propstatWrong.AddChild(responseDescrpWrong);

            #endregion

            #endregion

            //If any of the "status" group is empty, it is not included.
            if (propertiesOk.Count > 0)
            {
                treeChild.AddChild(propstatOk);
            }
            if (propertiesWrong.Count > 0)
            {
                treeChild.AddChild(propstatWrong);
            }

            #endregion

            return(treeChild);

            #endregion
        }
Esempio n. 27
0
        /// <summary>
        ///     Build the xml of the body and write
        ///     its string representation to the HttpRespose.Body
        /// </summary>
        /// <param name="response">The response of the request.</param>
        /// <param name="principalsAndProperties">The principals with its properties.</param>
        /// <returns></returns>
        public async Task WriteBody(HttpResponse response,
                                    Dictionary <Principal, IEnumerable <Property> > principalsAndProperties)
        {
            //build the root of the xml
            var multistatusNode = new XmlTreeStructure("multistatus", "DAV:")
            {
                Namespaces = new Dictionary <string, string>
                {
                    { "D", "DAV:" },
                    { "C", "urn:ietf:params:xml:ns:caldav" }
                }
            };

            //take the node that specified the comp and properties
            //to return

            foreach (var pp in principalsAndProperties)
            {
                IXMLTreeStructure statusNode;

                //each returned resource has is own response and href nodes
                var responseNode = new XmlTreeStructure("response", "DAV:");
                var hrefNode     = new XmlTreeStructure("href", "DAV:");
                hrefNode.AddValue(pp.Key.PrincipalURL);

                //href is a child pf response
                responseNode.AddChild(hrefNode);

                //if the resource is null it was not foound so
                // add an error status
                if (pp.Value == null)
                {
                    statusNode = new XmlTreeStructure("status", "DAV:");
                    statusNode.AddValue("HTTP/1.1 404 Not Found");
                    responseNode.AddChild(statusNode);
                }
                else
                {
                    var propstatNode = new XmlTreeStructure("propstat", "DAV:");
                    var propNode     = new XmlTreeStructure("prop", "DAV:");
                    //add the properties to the prop node.
                    foreach (var property in pp.Value)
                    {
                        propNode.AddChild(XmlTreeStructure.Parse(property.Value));
                    }

                    propstatNode.AddChild(propNode);
                    //adding the status node
                    // TODO: check the status!!
                    statusNode = new XmlTreeStructure("status", "DAV:");
                    statusNode.AddValue("HTTP/1.1 200 OK");

                    propstatNode.AddChild(statusNode);

                    responseNode.AddChild(propstatNode);
                }

                multistatusNode.AddChild(responseNode);
                await response.WriteAsync(multistatusNode.ToString());
            }
        }
Esempio n. 28
0
        /// <summary>
        ///     Returns a Response XML element with the name of all properties
        ///     of a collection or resource.
        /// </summary>
        /// <param name="url"></param>
        /// <param name="calendarResourceId"></param>
        /// <returns></returns>
        private async Task <XmlTreeStructure> PropNameFillTree(string url, string calendarResourceId = null)
        {
            #region Adding the response of the collection or resource.

            //A "response" structure with all its children is build in this method.
            var treeChild = new XmlTreeStructure("response", "DAV:");

            #region Adding the <D:href>/api/v1/caldav/{userEmail}/calendars/{collectionName}/{calendarResourceId}?</D:href>

            var href = new XmlTreeStructure("href", "DAV:");
            href.AddValue(SystemProperties._baseUrl + url);

            treeChild.AddChild(href);

            #endregion

            #region Adding the propstat

            //in this section is where the "propstat" structure its build.
            var propstat = new XmlTreeStructure("propstat", "DAV:");

            #region Adding nested status

            //each "propstat" has a "status" with the message that define it.
            //"propname" is always "200 OK" because you are only accessing the name of the established properties.
            var status = new XmlTreeStructure("status", "DAV:");
            status.AddValue("HTTP/1.1 200 OK");
            propstat.AddChild(status);

            #endregion

            #region Adding nested prop

            var prop = new XmlTreeStructure("prop", "DAV:");
            List <XmlTreeStructure> properties;

            //Depending if the target is a collection or a resource this section
            //will find the object in the database and get from there all names of properties.
            if (calendarResourceId == null)
            {
                //var collection = _collectionRepository.Get(url).Result;
                properties =
                    (await _collectionRepository.GetAllPropname(url)).Select(p => new XmlTreeStructure(p.Key, p.Value))
                    .ToList();
                //properties = collection.GetAllPropertyNames();
            }
            else
            {
                properties =
                    (await _resourceRespository.GetAllPropname(url)).Select(p => new XmlTreeStructure(p.Key, p.Value))
                    .ToList();
            }

            //Here i add all properties to the prop.
            foreach (var property in properties)
            {
                prop.AddChild(property);
            }

            propstat.AddChild(prop);

            #endregion

            treeChild.AddChild(propstat);

            #endregion

            return(treeChild);

            #endregion
        }
Esempio n. 29
0
        public void UnitTest1()
        {
            var xmlStr   = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<C:calendar-query xmlns:D=""DAV:""
xmlns:C=""urn:ietf:params:xml:ns:caldav"">
<D:prop>
<D:getetag/>
<C:calendar-data>
<C:comp name=""VCALENDAR"">
<C:prop name=""VERSION""/>
<C:comp name=""VEVENT"">
<C:prop name=""SUMMARY""/>
<C:prop name=""UID""/>
<C:prop name=""DTSTART""/>
<C:prop name=""DTEND""/>
<C:prop name=""DURATION""/>
<C:prop name=""RRULE""/>
<C:prop name=""RDATE""/>
<C:prop name=""EXRULE""/>
<C:prop name=""EXDATE""/>
<C:prop name=""RECURRENCE-ID""/>
</C:comp>
<C:comp name=""VTIMEZONE""/>
</C:comp>
</C:calendar-data>
</D:prop>
<C:filter>
<C:comp-filter name=""VCALENDAR"">
<C:comp-filter name=""VEVENT"">
<C:time-range start=""20060104T000000Z""
end=""20060105T000000Z""/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>";
            var calStr   = @"BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VTIMEZONE
LAST-MODIFIED:20040110T032845Z
TZID:US/Eastern
BEGIN:DAYLIGHT
DTSTART:20000404T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
END:DAYLIGHT
BEGIN:STANDARD
DTSTART:20001026T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
TZNAME:EST
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=US/Eastern:20060102T120000
DURATION:PT1H
RRULE:FREQ=DAILY;COUNT=5
SUMMARY:Event #2
UID:[email protected]
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=US/Eastern:20060104T140000
DURATION:PT1H
RECURRENCE-ID;TZID=US/Eastern:20060104T120000
SUMMARY:Event #2 bis
UID:[email protected]
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=US/Eastern:20060106T140000
DURATION:PT1H
RECURRENCE-ID;TZID=US/Eastern:20060106T120000
SUMMARY:Event #2 bis bis
UID:[email protected]
END:VEVENT
END:VCALENDAR";
            var calendar = new VCalendar(calStr);
            var xmlTree  = XmlTreeStructure.Parse(xmlStr);
            var result   = calendar.FilterResource(xmlTree);

            Assert.True(result);
        }
Esempio n. 30
0
        /// <summary>
        ///     Returns a Response XML tree for a prop request with all the property names
        ///     and property values specified in the request.
        /// </summary>
        /// <param name="url"></param>
        /// <param name="calendarResourceId">Name of the resource</param>
        /// <param name="propertiesNameNamespace">List of requested properties (key=name; value=namespace)</param>
        /// <param name="principal"></param>
        /// <returns></returns>
        private async Task <XmlTreeStructure> PropFillTree(string url, string calendarResourceId,
                                                           List <KeyValuePair <string, string> > propertiesNameNamespace, Principal principal)
        {
            //a "response xml element is added for each collection or resource"

            #region Adding the response of the collection or resource.

            var treeChild = new XmlTreeStructure("response", "DAV:");

            #region Adding the <D:href>/api/v1/caldav/{userEmail}/calendars/{collectionName}/{calendarResourceId}?</D:href>

            //an href with the corresponding url is added to the response
            var href = new XmlTreeStructure("href", "DAV:");
            href.AddValue(SystemProperties._baseUrl + url);

            treeChild.AddChild(href);

            #endregion

            #region Adding the propstats

            #region Selecting properties

            CalendarCollection collection;
            CalendarResource   resource;
            var propertiesCol   = new List <XmlTreeStructure>();
            var propertiesOk    = new List <XmlTreeStructure>();
            var propertiesWrong = new List <XmlTreeStructure>();
            var errorStack      = new Stack <string>();

            //the current-user-privilege-set is generated per request
            //it needs the DAV:acl property and the principalID
            Property aclProperty = null;

            //It take the list of requested properties and tries to get the corresponding property from db.
            //The methods are called for a resource or a collection accordingly its circumstances.
            //The properties are stored inside the propertiesCol. Where if the value is null it means that the collection could not be
            //retrieve.
            if (calendarResourceId == null)
            {
                collection = _collectionRepository.Get(url);
                if (propertiesNameNamespace != null)
                {
                    foreach (var addProperty in propertiesNameNamespace)
                    {
                        //gets the property from database
                        var property = await _collectionRepository.GetProperty(url, addProperty);

                        //Builds the xmlTreeExtructure checking that if the value is null thats because
                        //the property was not found.
                        IXMLTreeStructure prop;
                        if (property != null)
                        {
                            prop = property.Value == null
                                ? new XmlTreeStructure(property.Name, property.Namespace)
                            {
                                Value = ""
                            }
                        }
                        : XmlTreeStructure.Parse(property.Value);
                        else
                        {
                            prop = new XmlTreeStructure(addProperty.Key, addProperty.Value);
                        }
                        propertiesCol.Add((XmlTreeStructure)prop);
                    }
                    //take the acl property
                    aclProperty = collection.Properties.FirstOrDefault(x => x.Name == "acl");
                }
            }
            else
            {
                resource = _resourceRespository.Get(url);
                if (propertiesNameNamespace != null)
                {
                    foreach (var addProperty in propertiesNameNamespace)
                    {
                        //gets the property from database
                        var property = await _resourceRespository.GetProperty(url, addProperty);

                        //Builds the xmlTreeExtructure checking that if the value is null thats because
                        //the property was not found.
                        IXMLTreeStructure prop;
                        if (property != null)
                        {
                            prop = property.Value == null
                                ? new XmlTreeStructure(property.Name, property.Namespace)
                            {
                                Value = ""
                            }
                        }
                        : XmlTreeStructure.Parse(property.Value);
                        else
                        {
                            prop = new XmlTreeStructure(addProperty.Key, addProperty.Value);
                        }
                        propertiesCol.Add((XmlTreeStructure)prop);
                    }
                    //take the acl property
                    aclProperty = resource.Properties.FirstOrDefault(x => x.Name == "acl");
                }
            }

            //add the additional properties that are generated per request
            if (propertiesNameNamespace != null)
            {
                foreach (var pair in propertiesNameNamespace)
                {
                    switch (pair.Key)
                    {
                    case "current-user-privilege-set":
                        propertiesCol.RemoveAll(x => x.NodeName == pair.Key);
                        propertiesCol.Add(principal.GetCurrentUserPermissions(aclProperty));
                        break;
                    }
                }
            }


            //Here, properties are divided between recovered and error recovering
            foreach (var propTree in propertiesCol)
            {
                if (propTree.Value != null)
                {
                    propertiesOk.Add(propTree);
                }
                else
                {
                    propertiesWrong.Add(propTree);
                }
            }

            #endregion

            //For each returned status a "propstat" is created, containing a "prop" with all properties that belong to that current status.
            // And a "status" containing the message of the corresponding status.
            //Right Now there are only two "propstat" taking place OK and Wrong an therefore only two "status"
            //200 OK and 400 Not Found.
            //More should be added when ACL is working entairly.

            //TODO: Add the status forbidden for authentication permissions problems.

            #region Adding nested propOK

            var propstatOk = new XmlTreeStructure("propstat", "DAV:");
            var propOk     = new XmlTreeStructure("prop", "DAV:");

            //Here i add all properties to the prop.
            foreach (var property in propertiesOk)
            {
                propOk.AddChild(property);
            }

            propstatOk.AddChild(propOk);
            //This when i group the OK properties

            #region Adding nested status OK

            var statusOk = new XmlTreeStructure("status", "DAV:");
            statusOk.AddValue("HTTP/1.1 200 OK");
            propstatOk.AddChild(statusOk);

            #endregion

            #endregion

            //Here the same is made. The Wrong properties are grouped.

            #region Adding nested propWrong

            var propstatWrong = new XmlTreeStructure("propstat", "DAV:");
            var propWrong     = new XmlTreeStructure("prop", "DAV:");

            //Here i add all properties to the prop.
            foreach (var property in propertiesWrong)
            {
                propWrong.AddChild(property);
            }

            propstatWrong.AddChild(propWrong);

            #region Adding nested status Not Found

            var statusWrong = new XmlTreeStructure("status", "DAV:");
            statusWrong.AddValue("HTTP/1.1 400 Not Found");
            propstatWrong.AddChild(statusWrong);

            #endregion

            #region Adding responseDescription when wrong

            var responseDescrpWrong = new XmlTreeStructure("responsedescription", "DAV:");
            responseDescrpWrong.AddValue("The properties doesn't  exist");
            propstatWrong.AddChild(responseDescrpWrong);

            #endregion

            #endregion

            //If anyone of the property groups is empty it is not included in the response.
            if (propertiesOk.Count > 0)
            {
                treeChild.AddChild(propstatOk);
            }
            if (propertiesWrong.Count > 0)
            {
                treeChild.AddChild(propstatWrong);
            }

            #endregion

            return(treeChild);

            #endregion
        }