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

Birthday calendar is not shared with groups #29374

Open
Mululu opened this issue Jul 7, 2021 · 8 comments
Open

Birthday calendar is not shared with groups #29374

Mululu opened this issue Jul 7, 2021 · 8 comments
Labels
1. to develop Accepted and waiting to be taken care of 26-feedback bug feature: caldav Related to CalDAV internals feature: dav feature: sharing

Comments

@Mululu
Copy link

Mululu commented Jul 7, 2021

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

@lmchp
Copy link

lmchp commented Jul 18, 2021

ACK - same issue here...

I am just migrating installation from an OC (10.0)@Raspbian
to an actual¹ snap-nextcloud@Ubuntu-Server20.04.

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

@Mululu
Copy link
Author

Mululu commented Oct 22, 2021

Any news on this issue?

@tcitworld tcitworld transferred this issue from nextcloud/calendar Oct 22, 2021
@tcitworld tcitworld added 1. to develop Accepted and waiting to be taken care of bug feature: dav feature: sharing labels Oct 22, 2021
@maphy-psd
Copy link

maphy-psd commented Nov 14, 2021

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.

@Mululu
Copy link
Author

Mululu commented Mar 8, 2022

@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.
nextcloud/contacts#2503

@maphy-psd
Copy link

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?

@Mululu
Copy link
Author

Mululu commented Jan 20, 2023

I wish there was a solution to this.

@tcitworld
Copy link
Member

See #31859

@Mululu
Copy link
Author

Mululu commented Jan 20, 2023

Thanks, that sounds promising

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1. to develop Accepted and waiting to be taken care of 26-feedback bug feature: caldav Related to CalDAV internals feature: dav feature: sharing
Projects
None yet
Development

No branches or pull requests

5 participants