server icon indicating copy to clipboard operation
server copied to clipboard

Birthday calendar is not shared with groups

Open Mululu opened this issue 4 years ago • 5 comments

Steps to reproduce

  1. The generation of the birthday calendar must be active 2.Share contacts that contain birthday information with group A.
  2. Log in with a user who is in group A.
  3. Open the calendar and see if birthdays are displayed

Expected behaviour

Birthdays should be displayed from the shared contacts

Actual behaviour

When sharing contacts with a group, no birthdays are shown in the calendar. However, if you share the contacts directly with the respective user, the birthday display works.

Calendar app

Calendar app version: 2.3.0

CalDAV-clients used: (Thunderbird Lightning, DAVx5, Evolution, macOS Calendar, etc)

Client configuration

Browser: Chrome

Operating system: Windows 10 64bit

Server configuration

Operating system: Hosting Linux

Web server: Apache

Database: MariaDB

PHP version: 7.4.16

Nextcloud Version: 22.0.0

Mululu avatar Jul 07 '21 20:07 Mululu

ACK - same issue here...

I am just migrating installation from an OC (10.0)@Raspbian to an actual¹ [email protected].

It's used by my family members, and holds an additional fully shared (contacts, calendar, files) "familiy" account to collect all related data and get rid of redundancy and inconsistencies.

But NC hides the mutual/shared contact birthdays, which is of course one main expected feature, that worked flawlessly on the old (OC-10) server... But I understand, that there are scenarios where one don't want others to be able to alter his "calendar-view" (hardly spoken: to /spam/ the calendar) by simply sharing a contact-list with a bunch of birthday-entries...

So, one needs/should have the option to ex- or include the visibility of such shared contact-birthdays. Hope the issue gets necessary attention... while some dirty hack would do it for me ;-)

¹ Server:

Name       Version      Rev    Tracking       Publisher   Notes
nextcloud  21.0.3snap1  28404  latest/stable  nextcloud✓  -

client: Firefox 90.0(64Bit) for Ubuntu

lmchp avatar Jul 18 '21 13:07 lmchp

Any news on this issue?

Mululu avatar Oct 22 '21 07:10 Mululu

I have the same issue. If the adressbook is shared with a user, the birthdays events are created correctly, see #28533.

So i investigated the occ dav:sync-birthday-calendar command. This runs the syncUser in BirthdayService.php on a specified user - named here syncuser.

The shared addressbooks (and the cards) are received correctly. Now the function onCardChanged in BirthdayService.php are called.

I think the "bug" is on line 112 in $targetPrincipals: $targetPrincipals[] = $book['principaluri'];

I think $targetPrincipals has to be the principal of the birthday calendar of syncuser and not the principal of the group the addressbook has shared it, hasn’t it?

		$targetPrincipals = $this->getAllAffectedPrincipals($addressBookId);
		$book = $this->cardDavBackEnd->getAddressBookById($addressBookId);
		$targetPrincipals[] = $book['principaluri'];
		(...)

		foreach ($targetPrincipals as $principalUri) {
			(...)

			$calendar = $this->ensureCalendarExists($principalUri);
			foreach ($datesToSync as $type) {
				$this->updateCalendar($cardUri, $cardData, $book, (int) $calendar['id'], $type);
			}
		

In my test the $targetPrincipals has the value:

Array
(
    [0] => principals/groups/Groupname
    [1] => principals/users/UserWhoSharedTheAddressbookWithAGroupGroupname
)

As I understood the code, the birthday calendar of syncuser gets never updated with the shared addressbook cards, because the calendar gets never selected by $calendar = $this->ensureCalendarExists($principalUri);. But only if the addressbook is shared with a group. Is it shared with a user the $targetPrincipals has the value:

Array
(
    [0] => principals/users/SyncUser
    [1] => principals/users/UserWhoSharedTheAddressbookWithSyncUser
)

So maybe the principal of syncuser has to hand over to the function onCardChanged. Or modify getAddressBookById in CardDavBackend.php to return the principals of all user who have access to the addressbook.

Sorry for my bad english.

maphy-psd avatar Nov 14 '21 17:11 maphy-psd

@tcitworld

Is there already a solution for this?

With over 100 users, it's not all that great to manage. In addition, there is the problem with the wrong display. https://github.com/nextcloud/contacts/pull/2503

Mululu avatar Mar 08 '22 09:03 Mululu

In addition to my last post, I investigated a little further. I have found three errors (see below) and a possible solution.

Since I am not really familiar with CardDAV/CalDAV and the nextcloud internal functions, I would now need help from the developers, whether this is correct so far.

possible solution

I believe that the function onCardChanged is not purposeful here. This function is probably actually intended for when you change an entry in the address book, that the corresponding birthday calendars are changed. Also, the functions for the principals are probably not consistent for groups. I don't know.

So I used the function updateCalendar in syncUser and copied some code from the onCardChanged function. My changes:

  • add $calendar = $this->ensureCalendarExists($principal); to get the birthday calendar of the user
  • copy $datesToSync from onCardChanged
  • copy foreach ($datesToSync as $type) from onCardChanged
public function syncUser(string $user):void {
		$principal = 'principals/users/'.$user;
		$calendar = $this->ensureCalendarExists($principal);
		$books = $this->cardDavBackEnd->getAddressBooksForUser($principal);
		
		$datesToSync = [
			['postfix' => '', 'field' => 'BDAY'],
			['postfix' => '-death', 'field' => 'DEATHDATE'],
			['postfix' => '-anniversary', 'field' => 'ANNIVERSARY'],
		];
		
		foreach ($books as $book) {
			$cards = $this->cardDavBackEnd->getCards($book['id']);
			foreach ($cards as $card) {
				foreach ($datesToSync as $type) {
					$this->updateCalendar($card['uri'], $card['carddata'], $book, (int) $calendar['id'], $type);
				}
			}
		}
	}

errors

1. syncuser is not selected from onCardChanged

The function getAllAffectedPrincipals($addressBookId); is called to find out all shares of the addressbook.

the following function sequence is used for this: getAllAffectedPrincipals($addressBookId); => sharingBackend->getShares($addressBookId); => getShares(int $resourceId)

a row of the result in getShares(int $resourceId) is:

Array
(
    [principaluri] => principals/groups/GroupName
    [access] => 2
)

The check in '{http://owncloud.org/ns}group-share' => is_null($p) is always false because the result of $p = $this->principalBackend->getPrincipalByPath($row['principaluri']); is in my case:

Array
(
    [uri] => principals/groups/GroupName
    [{DAV:}displayname] => DisplaynameOfGroup
)

So $shares = $this->cardDavBackEnd->getShares($addressBookId); is:

Array
(
    [href] => principal:principals/groups/Lehrer
    [commonName] => Lehrer:innen
    [status] => 1
    [readOnly] =>
    [{http://owncloud.org/ns}principal] => principals/groups/Lehrer
    [{http://owncloud.org/ns}group-share] =>
)

and var_export($share['{http://owncloud.org/ns}group-share']); is false.

Back to getAllAffectedPrincipals. Here in if ($share['{http://owncloud.org/ns}group-share']) the true part is never called, because $share['{http://owncloud.org/ns}group-share'] is always false (see above). The result of getAllAffectedPrincipals is therefore: $targetPrincipals[] = $share['{http://owncloud.org/ns}principal']; In my case

Array
(
    [0] => principals/groups/Groupname
    [1] => principals/users/UserWhoSharedTheAddressbookWithAGroup
)

For testing i have changed the "group-check" to '{http://owncloud.org/ns}group-share' => str_contains($row['principaluri'], 'group'). But now each group member will go through and update their calendars. See 2.

2. each member of a group is synchronized.

You can give the command dav:sync-birthday-calendar a user for which the calendar should be updated. This information is only used to find out the address books of the corresponding user. But the function onCardChanged will then update all users who have access to the address book.

3. the line $this->ensureCalendarExists($principal); has no benefit, does it?

maphy-psd avatar Aug 07 '22 14:08 maphy-psd

I wish there was a solution to this.

Mululu avatar Jan 20 '23 12:01 Mululu

See https://github.com/nextcloud/server/pull/31859

tcitworld avatar Jan 20 '23 13:01 tcitworld

Thanks, that sounds promising

Mululu avatar Jan 20 '23 13:01 Mululu