Skip to content

Commit

Permalink
feat: Add sharing activity for teams
Browse files Browse the repository at this point in the history
This adds support for Teams (previously "Circles"),
the user notification already work, but the notification for the owner
and sharer need support in the `files_sharing` app.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
  • Loading branch information
susnux committed Aug 24, 2024
1 parent f882275 commit b5c753a
Showing 1 changed file with 58 additions and 7 deletions.
65 changes: 58 additions & 7 deletions lib/FilesHooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use OCA\Activity\BackgroundJob\RemoteActivity;
use OCA\Activity\Extension\Files;
use OCA\Activity\Extension\Files_Sharing;
use OCA\Circles\CirclesManager;
use OCA\Circles\Model\Member;
use OCP\Activity\IManager;
use OCP\Constants;
use OCP\Files\Config\IUserMountCache;
Expand Down Expand Up @@ -60,7 +62,8 @@ public function __construct(
protected IUserMountCache $userMountCache,
protected IConfig $config,
protected NotificationGenerator $notificationGenerator,
protected ITagManager $tagManager
protected ITagManager $tagManager,
protected ?CirclesManager $teamManager,

Check failure on line 66 in lib/FilesHooks.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis

UndefinedClass

lib/FilesHooks.php:66:3: UndefinedClass: Class, interface or enum named OCA\Circles\CirclesManager does not exist (see https://psalm.dev/019)
) {
}

Expand Down Expand Up @@ -664,6 +667,16 @@ public function share($share) {
(int)$share->getId()
);
break;
case IShare::TYPE_CIRCLE:
$this->shareWithTeam(
$share->getSharedWith(),
$share->getNodeId(),
$share->getNodeType(),
$share->getTarget(),
(int)$share->getId(),
$share->getSharedBy(),
);
break;
case IShare::TYPE_LINK:
$this->shareByLink(
$share->getNodeId(),
Expand Down Expand Up @@ -726,7 +739,8 @@ protected function shareWithGroup($shareWith, $fileSource, $itemType, $fileTarge
$offset = 0;
$users = $group->searchUsers('', self::USER_BATCH_SIZE, $offset);
while (!empty($users)) {
$this->addNotificationsForGroupUsers($users, 'shared_with_by', $fileSource, $itemType, $fileTarget, $shareId);
$users = array_map(fn (IUser $user) => $user->getUID(), $users);
$this->addNotificationsForUsers($users, 'shared_with_by', $fileSource, $itemType, $fileTarget, $shareId);
$offset += self::USER_BATCH_SIZE;
$users = $group->searchUsers('', self::USER_BATCH_SIZE, $offset);
}
Expand Down Expand Up @@ -758,6 +772,42 @@ protected function shareByLink($fileSource, $itemType, $linkOwner) {
);
}

/**
* Sharing a file or folder with a team
*
* @param string $shareWith
* @param int $fileSource File ID that is being shared
* @param string $itemType File type that is being shared (file or folder)
* @param string $fileTarget File path
* @param int $shareId The Share ID of this share
*/
protected function shareWithTeam(string $shareWith, int $fileSource, string $itemType, string $fileTarget, int $shareId, string $sharer): void {
if ($this->teamManager === null) {
return;
}

try {
$this->teamManager->startSuperSession();

Check failure on line 790 in lib/FilesHooks.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis

UndefinedClass

lib/FilesHooks.php:790:4: UndefinedClass: Class, interface or enum named OCA\Circles\CirclesManager does not exist (see https://psalm.dev/019)
$team = $this->teamManager->getCircle($shareWith);

Check failure on line 791 in lib/FilesHooks.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis

UndefinedClass

lib/FilesHooks.php:791:12: UndefinedClass: Class, interface or enum named OCA\Circles\CirclesManager does not exist (see https://psalm.dev/019)
$members = $team->getInheritedMembers();
$members = array_filter($members, fn ($member) => $member->getUserType() === Member::TYPE_USER);

Check failure on line 793 in lib/FilesHooks.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis

UndefinedClass

lib/FilesHooks.php:793:81: UndefinedClass: Class, interface or enum named OCA\Circles\Model\Member does not exist (see https://psalm.dev/019)
$users = array_map(fn ($member) => $member->getUserId(), $members);
} catch (\Throwable $e) {
$this->logger->debug('Fetching team members for share activity failed', ['exception' => $e]);
// error in teams app - setting users list to empty
$users = [];
}

// Activity for user performing the share
$this->shareNotificationForSharer('shared_team_self', $shareWith, $fileSource, $itemType);
// Activity for original owner of the file (re-sharing)
if ($this->currentUser->getUID() !== null) {
$this->shareNotificationForOriginalOwners($this->currentUser->getUID(), 're-shared_team_by', $shareWith, $fileSource, $itemType);
}
// Activity for all affected users
$this->addNotificationsForUsers($users, 'shared_with_by', $fileSource, $itemType, $fileTarget, $shareId);
}

/**
* Manage unsharing events
*
Expand Down Expand Up @@ -878,9 +928,10 @@ protected function unshareFromGroup(IShare $share) {

$offset = 0;
$users = $group->searchUsers('', self::USER_BATCH_SIZE, $offset);
$users = array_map(fn (IUser $user) => $user->getUID(), $users);
$shouldFlush = $this->startActivityTransaction();
while (!empty($users)) {
$this->addNotificationsForGroupUsers($users, $actionUser, $share->getNodeId(), $share->getNodeType(), $share->getTarget(), (int) $share->getId());
$this->addNotificationsForUsers($users, $actionUser, $share->getNodeId(), $share->getNodeType(), $share->getTarget(), (int)$share->getId());

Check failure on line 934 in lib/FilesHooks.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis

InvalidArgument

lib/FilesHooks.php:934:36: InvalidArgument: Argument 1 of OCA\Activity\FilesHooks::addNotificationsForUsers expects array<array-key, string>, but non-empty-array<array-key, OCP\IUser|string> provided (see https://psalm.dev/004)
$offset += self::USER_BATCH_SIZE;
$users = $group->searchUsers('', self::USER_BATCH_SIZE, $offset);
}
Expand Down Expand Up @@ -940,18 +991,18 @@ protected function unshareLink(IShare $share) {
}

/**
* @param IUser[] $usersInGroup
* @param string[] $usersIds
* @param string $actionUser
* @param int $fileSource File ID that is being shared
* @param string $itemType File type that is being shared (file or folder)
* @param string $fileTarget File path
* @param int $shareId The Share ID of this share
*/
protected function addNotificationsForGroupUsers(array $usersInGroup, $actionUser, $fileSource, $itemType, $fileTarget, $shareId) {
protected function addNotificationsForUsers(array $usersIds, $actionUser, $fileSource, $itemType, $fileTarget, $shareId) {
$affectedUsers = [];

foreach ($usersInGroup as $user) {
$affectedUsers[$user->getUID()] = $fileTarget;
foreach ($usersIds as $user) {
$affectedUsers[$user] = $fileTarget;
}

// Remove the triggering user, we already managed his notifications
Expand Down

0 comments on commit b5c753a

Please sign in to comment.