From 6940f22c28532580111c06d003e56993c02489d8 Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Mon, 20 Jan 2020 14:29:10 +1000 Subject: [PATCH] Ignore 403 ContentOperationNotPermitted errors due to shared calendars Some changes (e.g. changing the organizer of an event in a shared calendar) are not allowed, even if the user has Owner access to the shared calendar (since the organizer field is managed specially by Google in the shared-calendar case, allowing only the organizer or the creator of the event to write changes there). If we hit such a failure, ignore it and allow sync to succeed. --- .../google-calendars/googlecalendarsyncadaptor.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/google/google-calendars/googlecalendarsyncadaptor.cpp b/src/google/google-calendars/googlecalendarsyncadaptor.cpp index ed785a7..aeb539b 100644 --- a/src/google/google-calendars/googlecalendarsyncadaptor.cpp +++ b/src/google/google-calendars/googlecalendarsyncadaptor.cpp @@ -2122,7 +2122,17 @@ void GoogleCalendarSyncAdaptor::upsyncFinishedHandler() // error occurred during request. SOCIALD_LOG_ERROR("error" << httpCode << "occurred while upsyncing calendar data to Google account" << accountId << "; got:"); errorDumpStr(QString::fromUtf8(replyData)); - m_syncSucceeded[accountId] = false; + + // If we get a ContentOperationNotPermittedError, then allow the sync cycle to succeed. + // Most likely, it's an attempt to modify a shared event, and Google prevents + // any user other than the original creator of the event from modifying those. + // Such errors should not prevent the rest of the sync cycle from succeeding. + // TODO: is there some way to detect whether I am the organizer/owner of the event? + if (reply->error() == QNetworkReply::ContentOperationNotPermittedError) { + SOCIALD_LOG_TRACE("Ignoring 403 due to shared calendar resource"); + } else { + m_syncSucceeded[accountId] = false; + } } else if (upsyncType == GoogleCalendarSyncAdaptor::Delete) { // we expect an empty response body on success for Delete operations if (!replyData.isEmpty()) {