Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Contact could not be saved if both birthday and date of birth given #507

Closed
christian-weiss opened this issue Mar 1, 2018 · 6 comments
Closed
Labels
invalid This doesn't seem right

Comments

@christian-weiss
Copy link

christian-weiss commented Mar 1, 2018

(I do not want to hijack #501. My issues seams to be very similar to #501, execept the fact, that other fields are used.)

The error message "Contact could not be saved" comes directly after changing a contact via WebUI (nearly after each keystroke).

I noticed that this message is misleading, at least for the first change. The first change a non-admin user is doing will be persisted, but all subsequent changes will not be persisted. This is reproducable with login and logoffs. But all change attempts trigger the error message.

As an admin you can see a more detailed error message, related to the above WebUI error message (same point in time):

Fatal webdav Sabre\DAV\Exception\BadRequest: Calendar object with uid already exists in this calendar collection.

Stacktracke:

Sabre\DAV\Exception\BadRequest: Calendar object with uid already exists in this calendar collection.
/var/www/html/apps/dav/lib/CalDAV/BirthdayService.php - line 308: OCA\DAV\CalDAV\CalDavBackend->createCalendarObject('11', 'kontakte-91a46d...', 'BEGIN VCALENDAR...')
/var/www/html/apps/dav/lib/CalDAV/BirthdayService.php - line 99: OCA\DAV\CalDAV\BirthdayService->updateCalendar('91a46d63-24f2-4...', 'BEGIN VCARD\r\nVE...', Array, '11', Array)
/var/www/html/apps/dav/lib/AppInfo/Application.php - line 119: OCA\DAV\CalDAV\BirthdayService->onCardChanged('2', '91a46d63-24f2-4...', 'BEGIN VCARD\r\nVE...')[internal function] OCA\DAV\AppInfo\Application->OCA\DAV\AppInfo{closure}(*** sensitive parameters replaced ***)
/var/www/html/3rdparty/symfony/event-dispatcher/EventDispatcher.php - line 212: call_user_func(Object(Closure), Object(Symfony\Component\EventDispatcher\GenericEvent), '\OCA\DAV\CardDA...', Object(Symfony\Component\EventDispatcher\EventDispatcher))
/var/www/html/3rdparty/symfony/event-dispatcher/EventDispatcher.php - line 44: Symfony\Component\EventDispatcher\EventDispatcher->doDispatch(Array, '\OCA\DAV\CardDA...', Object(Symfony\Component\EventDispatcher\GenericEvent))
/var/www/html/apps/dav/lib/CardDAV/CardDavBackend.php - line 683: Symfony\Component\EventDispatcher\EventDispatcher->dispatch('\OCA\DAV\CardDA...', Object(Symfony\Component\EventDispatcher\GenericEvent))
/var/www/html/3rdparty/sabre/dav/lib/CardDAV/Card.php - line 96: OCA\DAV\CardDAV\CardDavBackend->updateCard('2', '91a46d63-24f2-4...', 'BEGIN VCARD\r\nVE...')
/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php - line 1130: Sabre\CardDAV\Card->put('BEGIN VCARD\r\nVE...')
/var/www/html/3rdparty/sabre/dav/lib/DAV/CorePlugin.php - line 513: Sabre\DAV\Server->updateFile('addressbooks/us...', 'BEGIN VCARD\r\nVE...', NULL)[internal function] Sabre\DAV\CorePlugin->httpPut(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))
/var/www/html/3rdparty/sabre/event/lib/EventEmitterTrait.php - line 105: call_user_func_array(Array, Array)
/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php - line 479: Sabre\Event\EventEmitter->emit('method PUT', Array)
/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php - line 254: Sabre\DAV\Server->invokeMethod(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))
/var/www/html/apps/dav/lib/Server.php - line 283: Sabre\DAV\Server->exec()/var/www/html/apps/dav/appinfo/v2/remote.php - line 35: OCA\DAV\Server->exec()
/var/www/html/remote.php - line 164: require_once('/var/www/html/a...'){main}

As we can see by the URI there is already a vcalendar dataset in database table "oc_calendarobjects", and as i can see it is about "date of death". So i deleted the "Birthday" field via WebUI. Now a can update the contact without issues. Adding the "Birthday" again results in the above issue.

As this exception is related to the calendar. There seams to be a hook that triggers the "birthday calendar updater process". And this process seams maybe only able to manage 1:1 relationship between contact and calendar event . For each date field there will be always the same URI generated. I removed "birthday" and "date of death" and added a "birthday" again => same uri for birthday event as it was for the date of death event. First date field will be saved, all other date fields will fail.

I guess: Not a bug in contacts app. A bug in calendar app.

@skjnldsv
Copy link
Member

skjnldsv commented Mar 1, 2018

Thanks you, I now understand the issue better. This is not a contact issue nor a calendar issue. This should go directly into server since the vcard is being rejected by the webdav instance. :)

@christian-weiss
Copy link
Author

christian-weiss commented Mar 1, 2018

As #501 was a spin-off of #462 my findings may help to tackel down #462, too.

@christian-weiss
Copy link
Author

Just for the sake of completeness:
Running the command line tool to re-sync the birthday calendar will bring the same exception:

 docker exec --user www-data nextcloudapp php occ dav:sync-birthday-calendar christian
Start birthday calendar sync for christian

  [Sabre\DAV\Exception\BadRequest]
  Calendar object with uid already exists in this calendar collection.

dav:sync-birthday-calendar [<user>]

@christian-weiss
Copy link
Author

christian-weiss commented Mar 4, 2018

Event URI is not the same - it is unique for each date field. But birthday, anniversary and day of death date fileds of a single contact do have the exact the same event UID at the moment. Sorry for a small inaccuracy.

The same contact URI is used as event UID for all 3 date fields. And this causes the problem.

The VEVENT component in the VCALENDAR object stored in oc_calendarobjects.calendardata has a event UID field.

RFC5545, UID field:
This property defines the persistent, globally unique identifier for the calendar component.

Using the unique event ObjectUri/DateUri as event UID solved that issue for me.
See pull request in nextcloud/server.

I could not find an existing unit test for that. So unit tests are not changed.
Migration for existing (corrupt) VCALENDAR datasets can be healed with

  • truncate table
  • re-creation of birthday calendar

docker exec --user www-data nextcloudapp php occ dav:sync-birthday-calendar christian

@skjnldsv
Copy link
Member

Duplicate of #571
Could you open the issue in https://github.com/nextcloud/server/issues if it's not already done?

@christian-weiss
Copy link
Author

This issue was filed as nextcloud/server#8629 (nextcloud core).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid This doesn't seem right
Projects
None yet
Development

No branches or pull requests

2 participants