diff options
author | Gary Kim <gary@garykim.dev> | 2021-08-16 00:09:58 +0300 |
---|---|---|
committer | Gary Kim <gary@garykim.dev> | 2021-09-20 21:30:29 +0300 |
commit | 9f3695d748d163f2de5ea5ef394b8d7a0caf7a6a (patch) | |
tree | 955de07443761f76ccb100fcf1fc5836820a4a04 /lib | |
parent | 886a7753d4424b22e00521a525b8b7d5035b7a30 (diff) |
Set share owner properly
Signed-off-by: Gary Kim <gary@garykim.dev>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/BackgroundJob/RetryJob.php | 2 | ||||
-rw-r--r-- | lib/Controller/RoomController.php | 2 | ||||
-rw-r--r-- | lib/Exceptions/RoomHasNoModeratorException.php | 28 | ||||
-rw-r--r-- | lib/Federation/Notifications.php | 67 | ||||
-rw-r--r-- | lib/Model/AttendeeMapper.php | 25 | ||||
-rw-r--r-- | lib/Service/ParticipantService.php | 4 |
6 files changed, 114 insertions, 14 deletions
diff --git a/lib/BackgroundJob/RetryJob.php b/lib/BackgroundJob/RetryJob.php index 0182cadea..ee659023b 100644 --- a/lib/BackgroundJob/RetryJob.php +++ b/lib/BackgroundJob/RetryJob.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @copyright Copyright (c) 2021 Gary Kim <gary@garykim.dev> diff --git a/lib/Controller/RoomController.php b/lib/Controller/RoomController.php index 09102d13c..1ed4634c0 100644 --- a/lib/Controller/RoomController.php +++ b/lib/Controller/RoomController.php @@ -1101,7 +1101,7 @@ class RoomController extends AEnvironmentAwareController { $participantsToAdd[] = [ 'actorType' => Attendee::ACTOR_FEDERATED_USERS, - 'actorId' => $newUser->getId() . '@' . $newUser->getRemote(), + 'actorId' => $newUser->getId(), 'displayName' => $newUser->getDisplayId(), ]; } else { diff --git a/lib/Exceptions/RoomHasNoModeratorException.php b/lib/Exceptions/RoomHasNoModeratorException.php new file mode 100644 index 000000000..7b9087dbe --- /dev/null +++ b/lib/Exceptions/RoomHasNoModeratorException.php @@ -0,0 +1,28 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2021 Gary Kim <gary@garykim.dev> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Talk\Exceptions; + +class RoomHasNoModeratorException extends \Exception { +} diff --git a/lib/Federation/Notifications.php b/lib/Federation/Notifications.php index fa0963f7e..f88d902ff 100644 --- a/lib/Federation/Notifications.php +++ b/lib/Federation/Notifications.php @@ -28,10 +28,18 @@ namespace OCA\Talk\Federation; use OCA\FederatedFileSharing\AddressHandler; use OCA\Talk\AppInfo\Application; use OCA\Talk\BackgroundJob\RetryJob; +use OCA\Talk\Exceptions\RoomHasNoModeratorException; +use OCA\Talk\MatterbridgeManager; +use OCA\Talk\Model\Attendee; +use OCA\Talk\Model\AttendeeMapper; +use OCA\Talk\Participant; +use OCA\Talk\Room; use OCP\BackgroundJob\IJobList; use OCP\Federation\ICloudFederationFactory; use OCP\Federation\ICloudFederationNotification; use OCP\Federation\ICloudFederationProviderManager; +use OCP\IUser; +use OCP\IUserManager; use Psr\Log\LoggerInterface; class Notifications { @@ -50,41 +58,84 @@ class Notifications { /** @var IJobList */ private $jobList; + /** @var IUserManager */ + private $userManager; + + /** @var AttendeeMapper */ + private $attendeeMapper; + + /** @var MatterbridgeManager */ + private $matterbridgeManager; + public function __construct( ICloudFederationFactory $cloudFederationFactory, AddressHandler $addressHandler, LoggerInterface $logger, ICloudFederationProviderManager $federationProviderManager, - IJobList $jobList + IJobList $jobList, + IUserManager $userManager, + AttendeeMapper $attendeeMapper, + MatterbridgeManager $matterbridgeManager ) { $this->cloudFederationFactory = $cloudFederationFactory; $this->addressHandler = $addressHandler; $this->logger = $logger; $this->federationProviderManager = $federationProviderManager; $this->jobList = $jobList; + $this->userManager = $userManager; + $this->attendeeMapper = $attendeeMapper; + $this->matterbridgeManager = $matterbridgeManager; } - public function sendRemoteShare(string $providerId, string $token, string $shareWith, string $name, string $owner, string $ownerFederatedId, - string $sharedBy, string $sharedByFederatedId, string $shareType, string $roomName, string $roomType): bool { + /** + * @throws \OCP\HintException + * @throws RoomHasNoModeratorException + * @throws \OCP\DB\Exception + */ + public function sendRemoteShare(string $providerId, string $token, string $shareWith, string $sharedBy, + string $sharedByFederatedId, string $shareType, Room $room): bool { [$user, $remote] = $this->addressHandler->splitUserRemote($shareWith); + $roomName = $room->getName(); + $roomType = $room->getType(); + $roomToken = $room->getToken(); + if (!($user && $remote)) { $this->logger->info( - "could not share $name, invalid contact $shareWith", + "could not share $roomToken, invalid contact $shareWith", ['app' => Application::APP_ID] ); return false; } + /** @var IUser|null $roomOwner */ + $roomOwner = null; + try { + $roomOwners = $this->attendeeMapper->getActorsByParticipantTypes($room->getId(), [Participant::OWNER]); + if (!empty($roomOwners) && $roomOwners[0]->getActorType() === Attendee::ACTOR_USERS) { + $roomOwner = $this->userManager->get($roomOwners[0]->getActorId()); + } + } catch (\Exception $e) { + // Get a local moderator instead + try { + $roomOwners = $this->attendeeMapper->getActorsByParticipantTypes($room->getId(), [Participant::MODERATOR]); + if (!empty($roomOwners) && $roomOwners[0]->getActorType() === Attendee::ACTOR_USERS) { + $roomOwner = $this->userManager->get($roomOwners[0]->getActorId()); + } + } catch (\Exception $e) { + throw new RoomHasNoModeratorException(); + } + } + $remote = $this->prepareRemoteUrl($remote); $share = $this->cloudFederationFactory->getCloudFederationShare( $user . '@' . $remote, - $name, + $roomToken, '', $providerId, - $ownerFederatedId, - $owner, + $roomOwner->getCloudId(), + $roomOwner->getDisplayName(), $sharedByFederatedId, $sharedBy, $token, @@ -104,7 +155,7 @@ class Notifications { return true; } $this->logger->info( - "failed sharing $name with $shareWith", + "failed sharing $roomToken with $shareWith", ['app' => Application::APP_ID] ); diff --git a/lib/Model/AttendeeMapper.php b/lib/Model/AttendeeMapper.php index 2599e9d9d..89a9460d3 100644 --- a/lib/Model/AttendeeMapper.php +++ b/lib/Model/AttendeeMapper.php @@ -73,7 +73,7 @@ class AttendeeMapper extends QBMapper { $query = $this->db->getQueryBuilder(); $query->select('*') ->from($this->getTableName()) - ->where($query->expr()->eq('id', $query->createNamedParameter($id))); + ->where($query->expr()->eq('id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT))); return $this->findEntity($query); } @@ -90,8 +90,8 @@ class AttendeeMapper extends QBMapper { $query = $this->db->getQueryBuilder(); $query->select('*') ->from($this->getTableName()) - ->where($query->expr()->eq('id', $query->createNamedParameter($id))) - ->andWhere($query->expr()->eq('access_token', $query->createNamedParameter($token))); + ->where($query->expr()->eq('remote_id', $query->createNamedParameter($id, IQueryBuilder::PARAM_STR))) + ->andWhere($query->expr()->eq('access_token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR))); return $this->findEntity($query); } @@ -118,6 +118,25 @@ class AttendeeMapper extends QBMapper { /** * @param int $roomId + * @param array $participantType + * @return Attendee[] + * @throws DBException + */ + public function getActorsByParticipantTypes(int $roomId, array $participantType): array { + $query = $this->db->getQueryBuilder(); + $query->select('*') + ->from($this->getTableName()) + ->where($query->expr()->eq('room_id', $query->createNamedParameter($roomId, IQueryBuilder::PARAM_INT))); + + if (!empty($participantType)) { + $query->andWhere($query->expr()->in('participant_type', $query->createNamedParameter($participantType, IQueryBuilder::PARAM_INT_ARRAY))); + } + + return $this->findEntities($query); + } + + /** + * @param int $roomId * @param string $actorType * @param int|null $lastJoinedCall * @return int diff --git a/lib/Service/ParticipantService.php b/lib/Service/ParticipantService.php index 02046563e..a4d9a0535 100644 --- a/lib/Service/ParticipantService.php +++ b/lib/Service/ParticipantService.php @@ -310,7 +310,7 @@ class ParticipantService { /** * @param Room $room * @param array $participants - * @param IUser|null $addedBy + * @param IUser|null $addedBy User that is attempting to add these users (must be set for federated users to be added) */ public function addUsers(Room $room, array $participants, ?IUser $addedBy = null): void { if (empty($participants)) { @@ -378,7 +378,7 @@ class ParticipantService { } private function sendRemoteShare(Room $room, IUser $addedBy, string $addingUserId, string $token, int $attendeeId) { - $this->notifications->sendRemoteShare((string) $attendeeId, $token, $addingUserId, $room->getToken(), $addedBy->getDisplayName(), $addedBy->getCloudId(), $addedBy->getDisplayName(), $addedBy->getCloudId(), 'user', $room->getName(), (string) $room->getType()); + $this->notifications->sendRemoteShare((string) $attendeeId, $token, $addingUserId, $addedBy->getDisplayName(), $addedBy->getCloudId(), 'user', $room); } /** |