X-Git-Url: http://Server1/repobrowser/?a=blobdiff_plain;f=source%2Fobjects%2FCalDAV%2FCalDAV.cpp;h=38c5bdb5fc1330c5951c290753fb947198b1837a;hb=6db84a2ded5a6d8f10b341965e303f329588f293;hp=27bc692dbd6d2379126d1044e765196edd9cbb83;hpb=621bf070915428c376b76f1a9e031e742f82af48;p=xestiacalendar%2F.git diff --git a/source/objects/CalDAV/CalDAV.cpp b/source/objects/CalDAV/CalDAV.cpp index 27bc692..38c5bdb 100644 --- a/source/objects/CalDAV/CalDAV.cpp +++ b/source/objects/CalDAV/CalDAV.cpp @@ -20,7 +20,7 @@ using namespace std; -size_t CalDAVOutput(char *ReceivedBuffer, size_t Size, size_t NewMemoryBytes, string *StringPointer) +size_t CalDAVReceive(char *ReceivedBuffer, size_t Size, size_t NewMemoryBytes, string *StringPointer) { string ReceivedBufferString = ""; @@ -32,6 +32,29 @@ size_t CalDAVOutput(char *ReceivedBuffer, size_t Size, size_t NewMemoryBytes, st } +size_t CalDAVSend(char *SendBuffer, size_t Size, size_t NewMemoryBytes, void *DataStruct){ + + struct CalDAVSendData *UploadPtr = (struct CalDAVSendData *)DataStruct; + + if (UploadPtr->sizeleft){ + + UploadPtr->sizeleft--; + char CharSend; + + CharSend = (*UploadPtr->readptr)[UploadPtr->seek]; + + *SendBuffer = CharSend; + + UploadPtr->seek++; + + return 1; + + } + + return 0; + +} + CalDAV::CalDAV(){ // Setup the objects within the CalDAV connection @@ -92,23 +115,7 @@ CalDAVServerResult CalDAV::Connect(){ // Setup the server address. - if (ConnectionData.UseSSL == true){ - ServerAddress += "https://"; - } else { - ServerAddress += "http://"; - } - - ServerAddress += ConnectionData.Hostname; - - // Check if server port is 80, otherwise - // specifiy the port number in the address. - - if (ConnectionData.Port != 80){ - ServerAddress += ":"; - ServerAddress += to_string(ConnectionData.Port); - } - - ServerAddress += "/principals/"; + ServerAddress = BuildServerAddress(&ConnectionData, "/principals/"); // Setup the server password. @@ -121,7 +128,7 @@ CalDAVServerResult CalDAV::Connect(){ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); curl_easy_setopt(ConnectionHandle, CURLOPT_FAILONERROR, 1L); curl_easy_setopt(ConnectionHandle, CURLOPT_TIMEOUT, ConnectionData.Timeout); - curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEFUNCTION, CalDAVOutput); + curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEFUNCTION, CalDAVReceive); curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEDATA, &ServerData); curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEHEADER, &ServerHeader); @@ -149,6 +156,1032 @@ CalDAVServerResult CalDAV::Connect(){ } +CalDAVServerResult CalDAV::GetServerResult(){ + + return ConnectionServerResult; + +} + +CalDAVServerSupport CalDAV::GetServerSupport(){ + + CalDAVServerSupport ServerStatus; + + // Setup the server connection. + + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "OPTIONS"); + + CURLcode ServerResult = curl_easy_perform(ConnectionHandle); + + // Set the results. + + if (ServerResult == CURLE_OK){ + ConnectionServerResult.Result = CALDAVQUERYRESULT_OK; + } else { + ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR; + } + ConnectionServerResult.Code = ServerResult; + curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode); + + if (ServerResult != CURLE_OK){ + return ServerStatus; + } + + // Check that the server header has data in, + // otherwise return an "empty" CalDAVServerSupport. + + if (ServerHeader.size() == 0){ + return ServerStatus; + } + + // Process each line looking for the first DAV header + // line. + + bool NewlineMode = true; + + string DAVLine; + + for (int CharSeek = 0; CharSeek < ServerHeader.size(); CharSeek++){ + + if (NewlineMode == true){ + + // Check if we have reached the end of the string. + + if (CharSeek >= ServerHeader.size()){ + + break; + + } + + // Check the first four letters to make sure + // they are 'DAV:'. + + string DAVHeaderCheck = ""; + + try { + DAVHeaderCheck = ServerHeader.substr(CharSeek, 4); + } + + catch (out_of_range &oor){ + break; + } + + if (DAVHeaderCheck == "DAV:"){ + + CharSeek += 5; + + for (; CharSeek < ServerHeader.size(); CharSeek++){ + + if (ServerHeader[CharSeek] == '\n'){ + + break; + + } + + DAVLine.push_back(ServerHeader[CharSeek]); + + } + + break; + + } + + NewlineMode = false; + + } + + if (ServerHeader[CharSeek] == '\n'){ + + NewlineMode = true; + + } + + } + + // Process the DAV line. + + vector DAVLineData; + string DAVSegmentString; + + for (int CharSeek = 0; CharSeek < DAVLine.size(); CharSeek++){ + + if (DAVLine[CharSeek] == ' '){ + continue; + } + + if (DAVLine[CharSeek] == ','){ + + DAVLineData.push_back(DAVSegmentString); + DAVSegmentString.clear(); + continue; + + } + + DAVSegmentString += DAVLine[CharSeek]; + + } + + // Process the DAV values and set each value + // to true as required. + + for (int DAVItemSeek = 0; + DAVItemSeek < DAVLineData.size(); + DAVItemSeek++){ + + if (DAVLineData.at(DAVItemSeek) == "calendar-access"){ + + ServerStatus.BasicSupport = true; + + } + + } + + // Reset the connection status. + + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL); + + return ServerStatus; + +} + +string CalDAV::GetUserPrincipal(){ + + string CurrentUserPrincipal = ""; + string UserPrincipalRequest = ""; + CalDAVSendData UserPrincipalSendData; + + UserPrincipalRequest = "\n" + "\n" + " \n" + " \n" + " \n" + ""; + + UserPrincipalSendData.readptr = &UserPrincipalRequest; + UserPrincipalSendData.sizeleft = UserPrincipalRequest.size(); + + // Setup the header. + + struct curl_slist *UserPrincipalRequestHeader = NULL; + + UserPrincipalRequestHeader = curl_slist_append(UserPrincipalRequestHeader, "Depth: 0"); + UserPrincipalRequestHeader = curl_slist_append(UserPrincipalRequestHeader, "Prefer: return-minimal"); + UserPrincipalRequestHeader = curl_slist_append(UserPrincipalRequestHeader, "Content-Type: application/xml; charset=utf-8"); + + curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, UserPrincipalRequestHeader); + + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND"); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &UserPrincipalSendData); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend); + + // Process the data. + + ServerData.clear(); + ServerHeader.clear(); + + CURLcode ServerResult = curl_easy_perform(ConnectionHandle); + + // Set the results. + + if (ServerResult == CURLE_OK){ + ConnectionServerResult.Result = CALDAVQUERYRESULT_OK; + } else { + ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR; + } + ConnectionServerResult.Code = ServerResult; + curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode); + + if (ServerResult != CURLE_OK){ + + return CurrentUserPrincipal; + + } + + // Process the User Principal from the ServerData. + + CurrentUserPrincipal = ProcessXMLUserPrincipal(); + + // Reset the changed settings. + + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL); + + return CurrentUserPrincipal; + +} + +string CalDAV::GetCalendarHome(string UserPrincipalURI){ + + string CalendarHomeURI = ""; + + // Build the Calendar Home URL address. + + string CalendarHomeURL = BuildServerAddress(&ConnectionData, UserPrincipalURI); + + // Setup the header request. + + CalDAVSendData CalendarHomeSendData; + + string CalendarHomeRequest = "\n" + "\n" + " \n" + " \n" + " \n" + ""; + + CalendarHomeSendData.readptr = &CalendarHomeRequest; + CalendarHomeSendData.sizeleft = CalendarHomeRequest.size(); + + // Setup the header. + + struct curl_slist *CalendarRequestHeader = NULL; + + CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Depth: 0"); + CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Prefer: return-minimal"); + CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Content-Type: application/xml; charset=utf-8"); + + curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, CalendarHomeURL.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND"); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &CalendarHomeSendData); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend); + + // Process the data. + + ServerData.clear(); + ServerHeader.clear(); + + CURLcode ServerResult = curl_easy_perform(ConnectionHandle); + + // Set the results. + + if (ServerResult == CURLE_OK){ + ConnectionServerResult.Result = CALDAVQUERYRESULT_OK; + } else { + ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR; + } + ConnectionServerResult.Code = ServerResult; + curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode); + + if (ServerResult != CURLE_OK){ + + return CalendarHomeURI; + + } + + // Process the User Principal from the ServerData. + + CalendarHomeURI = ProcessXMLCalendarHome(); + + // Reset the changed settings. + + string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/"); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str()); + + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL); + + return CalendarHomeURI; + +} + +CalDAVCalendarList CalDAV::GetCalendars(){ + + CalDAVCalendarList ServerList; + CalDAVSendData CalendarListSendData; + + // Build the server address. + + string UserPrincipalURI = ""; + UserPrincipalURI = GetUserPrincipal(); + + if (UserPrincipalURI.size() == 0){ + + return ServerList; + + } + + string CalendarHomeURI = ""; + CalendarHomeURI = GetCalendarHome(UserPrincipalURI); + + string CalendarListURLAddress = BuildServerAddress(&ConnectionData, CalendarHomeURI); + + string CalendarListRequest = "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + ""; + + CalendarListSendData.readptr = &CalendarListRequest; + CalendarListSendData.sizeleft = CalendarListRequest.size(); + + // Setup the header. + + struct curl_slist *CalendarListRequestHeader = NULL; + + CalendarListRequestHeader = curl_slist_append(CalendarListRequestHeader, "Depth: 1"); + CalendarListRequestHeader = curl_slist_append(CalendarListRequestHeader, "Prefer: return-minimal"); + CalendarListRequestHeader = curl_slist_append(CalendarListRequestHeader, "Content-Type: application/xml; charset=utf-8"); + + curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarListRequestHeader); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, CalendarListURLAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND"); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &CalendarListSendData); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend); + + // Process the data. + + ServerData.clear(); + ServerHeader.clear(); + + CURLcode ServerResult = curl_easy_perform(ConnectionHandle); + + //ServerList = ProcessXMLCalendarList(); + + if (ServerResult == CURLE_OK){ + ConnectionServerResult.Result = CALDAVQUERYRESULT_OK; + } else { + ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR; + } + ConnectionServerResult.Code = ServerResult; + curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode); + + if (ServerResult != CURLE_OK){ + + return ServerList; + + } + + // Process the received XML data into a list of calendars + // and locations. + + ServerList = ProcessXMLCalendarList(); + + // Restore the original settings. + + string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/"); + + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL); + + return ServerList; + +} + +CalDAVServerResult CalDAV::AddCalendar(string CalendarName){ + + CalDAVServerResult ServerResult; + + AddCalendar(&CalendarName, nullptr); + + return ServerResult; + +} + +CalDAVServerResult CalDAV::AddCalendar(string *CalendarName, string *CalendarShortName){ + + CalDAVServerResult ServerResult; + CalDAVSendData CalendarAddSendData; + + // Build the server address. + + string UserPrincipalURI = ""; + UserPrincipalURI = GetUserPrincipal(); + + if (UserPrincipalURI.size() == 0){ + + return ServerResult; + + } + + string CalendarHomeURI = ""; + CalendarHomeURI = GetCalendarHome(UserPrincipalURI); + + // Generate the UUID. + + string UUIDValue = ""; + + if (CalendarShortName == nullptr){ + + UUIDValue = GenerateUUID(); + UUIDValue.erase(UUIDValue.end()-1); + + } else { + + UUIDValue = *CalendarShortName; + + } + + string CalendarHomeURL = CalendarHomeURI; + CalendarHomeURL.append(UUIDValue); + CalendarHomeURL.append("/"); + + // Build the calendar list address. + + string CalendarListURLAddress = BuildServerAddress(&ConnectionData, CalendarHomeURL); + + string CalendarAddRequest = "\n" + "\n" + " \n" + " \n" + " "; + CalendarAddRequest += *CalendarName; + CalendarAddRequest += "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + ""; + + CalendarAddSendData.readptr = &CalendarAddRequest; + CalendarAddSendData.sizeleft = CalendarAddRequest.size(); + + // Setup the header. + + struct curl_slist *CalendarRequestHeader = NULL; + + //curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, CalendarListURLAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "MKCALENDAR"); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &CalendarAddSendData); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend); + + // Process the data. + + ServerData.clear(); + ServerHeader.clear(); + + CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle); + + if (ServerConnectionResult == CURLE_OK){ + ServerResult.Result = CALDAVQUERYRESULT_OK; + } else { + ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR; + } + ServerResult.Code = ServerConnectionResult; + curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode); + + // Restore the original settings. + + string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/"); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL); + + return ServerResult; + +} + +CalDAVServerResult CalDAV::EditCalendarProcess(string *CalendarHREF, + string *CalendarName, + Colour *CalendarColour, + string *CalendarDescription, + int *CalendarOrder){ + + CalDAVServerResult ServerResult; + CalDAVSendData CalendarEditSendData; + + // Build the server address. + + string UserPrincipalURI = ""; + UserPrincipalURI = GetUserPrincipal(); + + if (UserPrincipalURI.size() == 0){ + + return ServerResult; + + } + + string CalendarHomeURI = ""; + CalendarHomeURI = GetCalendarHome(UserPrincipalURI); + + // Generate the UUID. + + string UUIDValue = GenerateUUID(); + UUIDValue.erase(UUIDValue.end()-1); + + string CalendarHomeURL = CalendarHomeURI; + CalendarHomeURL.append(UUIDValue); + CalendarHomeURL.append("/"); + + // Build the calendar list address. + + string CalendarEditURLAddress = BuildServerAddress(&ConnectionData, (*CalendarHREF)); + + string CalendarEditRequest = "\n" + "\n" + " \n" + " \n"; + + // Update the calendar name. + + if (CalendarName != nullptr){ + + CalendarEditRequest += ""; + CalendarEditRequest += (*CalendarName); + CalendarEditRequest += "\n"; + + } + + // Update the calendar colour. + + if (CalendarColour != nullptr){ + + CalendarEditRequest += ""; + CalendarEditRequest += (*CalendarColour); + CalendarEditRequest += "\n"; + + } + + // Update the calendar description. + + if (CalendarDescription != nullptr){ + + CalendarEditRequest += ""; + CalendarEditRequest += (*CalendarDescription); + CalendarEditRequest += "\n"; + + } + + // Update the calendar order. + + if (CalendarOrder != nullptr){ + + CalendarEditRequest += ""; + CalendarEditRequest += to_string((*CalendarOrder)); + CalendarEditRequest += "\n"; + + } + + CalendarEditRequest += " \n" + " \n" + ""; + + CalendarEditSendData.readptr = &CalendarEditRequest; + CalendarEditSendData.sizeleft = CalendarEditRequest.size(); + + // Setup the header. + + struct curl_slist *CalendarRequestHeader = NULL; + + //curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, CalendarEditURLAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PROPPATCH"); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &CalendarEditSendData); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend); + + // Process the data. + + ServerData.clear(); + ServerHeader.clear(); + + CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle); + + if (ServerConnectionResult == CURLE_OK){ + ServerResult.Result = CALDAVQUERYRESULT_OK; + } else { + ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR; + } + ServerResult.Code = ServerConnectionResult; + curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode); + + // Restore the original settings. + + string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/"); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL); + + return ServerResult; + +} + +CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF, + string *CalendarName, + Colour *CalendarColour, + string *CalendarDescription, + int *CalendarOrder){ + + CalDAVServerResult ServerResult; + + ServerResult = EditCalendarProcess(CalendarHREF, + CalendarName, + CalendarColour, + CalendarDescription, + CalendarOrder); + + return ServerResult; + +} + +CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF, + Colour *CalendarColour){ + + + CalDAVServerResult ServerResult; + + ServerResult = EditCalendarProcess(CalendarHREF, + nullptr, + CalendarColour, + nullptr, + nullptr); + + return ServerResult; + +} + +CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF, + string *CalendarName){ + + CalDAVServerResult ServerResult; + + ServerResult = EditCalendarProcess(CalendarHREF, + CalendarName, + nullptr, + nullptr, + nullptr); + + return ServerResult; + +} + +CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF, + int *CalendarOrder){ + + CalDAVServerResult ServerResult; + + ServerResult = EditCalendarProcess(CalendarHREF, + nullptr, + nullptr, + nullptr, + CalendarOrder); + + return ServerResult; + +} + +CalDAVServerResult CalDAV::EditCalendarDescription(string *CalendarHREF, + string *CalendarDescription){ + + CalDAVServerResult ServerResult; + + ServerResult = EditCalendarProcess(CalendarHREF, + nullptr, + nullptr, + CalendarDescription, + nullptr); + + return ServerResult; + +} + +CalDAVServerResult CalDAV::DeleteCalendar(string *CalendarHREF){ + + CalDAVServerResult ServerResult; + + // Build the server address. + + string UserPrincipalURI = ""; + UserPrincipalURI = GetUserPrincipal(); + + if (UserPrincipalURI.size() == 0){ + + return ServerResult; + + } + + string CalendarHomeURI = ""; + CalendarHomeURI = GetCalendarHome(UserPrincipalURI); + + // Generate the UUID. + + string UUIDValue = GenerateUUID(); + UUIDValue.erase(UUIDValue.end()-1); + + string CalendarHomeURL = CalendarHomeURI; + CalendarHomeURL.append(UUIDValue); + CalendarHomeURL.append("/"); + + // Build the calendar list address. + + struct curl_slist *DeleteRequestHeader = NULL; + + DeleteRequestHeader = curl_slist_append(DeleteRequestHeader, "Depth: infinity"); + + string CalendarDeleteURLAddress = BuildServerAddress(&ConnectionData, (*CalendarHREF)); + + curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, DeleteRequestHeader); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, CalendarDeleteURLAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "DELETE"); + + // Delete the calendar. + + ServerData.clear(); + ServerHeader.clear(); + + CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle); + + if (ServerConnectionResult == CURLE_OK){ + ServerResult.Result = CALDAVQUERYRESULT_OK; + } else { + ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR; + } + ServerResult.Code = ServerConnectionResult; + curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode); + + // Restore the original settings. + + string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/"); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL); + + return ServerResult; + +} + +CalDAVServerResult CalDAV::GetEntryETag(string *CalendarEntryHREF, string *ETagValue){ + + CalDAVServerResult ServerResult; + CalDAVSendData EntryETagGetData; + + // Build the server address. + + string UserPrincipalURI = ""; + UserPrincipalURI = GetUserPrincipal(); + + if (UserPrincipalURI.size() == 0){ + + return ServerResult; + + } + + string CalendarHomeURI = ""; + CalendarHomeURI = GetCalendarHome(UserPrincipalURI); + + // Split the path and filename. + + string EntryURIPath; + string EntryFilename; + + SplitPathFilename(CalendarEntryHREF, &EntryURIPath, &EntryFilename); + + // Build the request for the server. + + string EntryETagRequest = "\n" + "\n" + " \n" + " \n" + " \n" + " "; + EntryETagRequest += (*CalendarEntryHREF); + EntryETagRequest += "\n" + ""; + + EntryETagGetData.readptr = &EntryETagRequest; + EntryETagGetData.sizeleft = EntryETagRequest.size(); + + // Build the calendar list address. + + struct curl_slist *GetETagRequestHeader = NULL; + + GetETagRequestHeader = curl_slist_append(GetETagRequestHeader, "Depth: 1"); + GetETagRequestHeader = curl_slist_append(GetETagRequestHeader, "Prefer: return-minimal"); + GetETagRequestHeader = curl_slist_append(GetETagRequestHeader, "Content-Type: application/xml; charset=utf-8"); + + string GetETagURLAddress = BuildServerAddress(&ConnectionData, EntryURIPath); + + curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, GetETagRequestHeader); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, GetETagURLAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT"); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &EntryETagGetData); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend); + + // Attempt to get the entity tag. + + ServerData.clear(); + ServerHeader.clear(); + + CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle); + + if (ServerConnectionResult == CURLE_OK){ + ServerResult.Result = CALDAVQUERYRESULT_OK; + } else { + ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR; + } + ServerResult.Code = ServerConnectionResult; + curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode); + + if (ServerConnectionResult != CURLE_OK){ + return ServerResult; + } + + // Get the entity tag from the result. + + *ETagValue = ProcessXMLEntryETag(); + + // Restore the original settings. + + string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/"); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL); + + return ServerResult; + +} + +CalDAVServerResult CalDAV::AddEntry(string *CalendarEntryHREF, string *EntryData){ + + // Add an entry to the calendar collection. + + CalDAVServerResult ServerResult; + CalDAVSendData EntryAddSendData; + + // Build the calendar list address. + + string EntryAddURLAddress = BuildServerAddress(&ConnectionData, (*CalendarEntryHREF)); + + EntryAddSendData.readptr = EntryData; + EntryAddSendData.sizeleft = EntryData->size(); + + struct curl_slist *CalendarRequestHeader = NULL; + + CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Content-Type: text/calendar; charset=utf-8"); + + curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryAddURLAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PUT"); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &EntryAddSendData); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend); + + // Process the data. + + ServerData.clear(); + ServerHeader.clear(); + + CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle); + + if (ServerConnectionResult == CURLE_OK){ + ServerResult.Result = CALDAVQUERYRESULT_OK; + } else { + ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR; + } + ServerResult.Code = ServerConnectionResult; + curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode); + + // Restore the original settings. + + string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/"); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL); + + return ServerResult; + +} + +CalDAVServerResult CalDAV::EditEntry(string *CalendarEntryHREF, string *EntryData, string *EntryETag){ + + // Edit an entry in the calendar collection. + + // Add an entry to the calendar collection. + + CalDAVServerResult ServerResult; + CalDAVSendData EntryAddSendData; + + // Build the calendar list address. + + string EntryAddURLAddress = BuildServerAddress(&ConnectionData, (*CalendarEntryHREF)); + + EntryAddSendData.readptr = EntryData; + EntryAddSendData.sizeleft = EntryData->size(); + + string IfMatchHeader = "If-Match: \""; + IfMatchHeader.append(*EntryETag); + IfMatchHeader.append("\""); + + struct curl_slist *CalendarRequestHeader = NULL; + + CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Content-Type: text/calendar; charset=utf-8"); + CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, IfMatchHeader.c_str()); + + curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryAddURLAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PUT"); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &EntryAddSendData); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend); + + // Process the data. + + ServerData.clear(); + ServerHeader.clear(); + + CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle); + + if (ServerConnectionResult == CURLE_OK){ + ServerResult.Result = CALDAVQUERYRESULT_OK; + } else { + ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR; + } + ServerResult.Code = ServerConnectionResult; + curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode); + + // Restore the original settings. + + string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/"); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL); + + return ServerResult; + +} + +CalDAVServerResult CalDAV::DeleteEntry(string *CalendarEntryHREF){ + + // Delete an entry in the calendar collection. + + CalDAVServerResult ServerResult; + + // Build the calendar list address. + + string EntryDeleteURLAddress = BuildServerAddress(&ConnectionData, (*CalendarEntryHREF)); + + curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryDeleteURLAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "DELETE"); + + // Delete the calendar. + + ServerData.clear(); + ServerHeader.clear(); + + CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle); + + if (ServerConnectionResult == CURLE_OK){ + ServerResult.Result = CALDAVQUERYRESULT_OK; + } else { + ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR; + } + ServerResult.Code = ServerConnectionResult; + curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode); + + // Restore the original settings. + + string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/"); + curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str()); + curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L); + curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL); + curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL); + + return ServerResult; + +} + bool CalDAVObjectValidSettings(CalDAVConnectionData *ConnData){ // Check if the passed CalDAV Connection Data is has @@ -208,4 +1241,32 @@ bool CalDAVObjectValidSettings(CalDAVConnectionData *ConnData){ return true; +} + +string BuildServerAddress(CalDAVConnectionData *ConnData, string URIAddress){ + + string ServerAddress; + + // Setup the server address. + + if (ConnData->UseSSL == true){ + ServerAddress += "https://"; + } else { + ServerAddress += "http://"; + } + + ServerAddress += ConnData->Hostname; + + // Check if server port is 80, otherwise + // specifiy the port number in the address. + + if (ConnData->Port != 80){ + ServerAddress += ":"; + ServerAddress += to_string(ConnData->Port); + } + + ServerAddress += URIAddress; + + return ServerAddress; + } \ No newline at end of file