From edc54ea5d57e6019a14b9b70b3065c62d6d8953e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 18 Jul 2018 14:06:57 +0200 Subject: Add support for public shares to file rooms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Until now file rooms were available only to users with direct access to the file. Now file rooms are available to any user or guest too if the link is publicly shared (with a link share, for example). Public shares are identified by a share token instead of a file id, so a new endpoint, which is a counterpart of FilesController but for share tokens, was added. The file room, however, is still associated to the file id like before. When checking if a participant can join a room if the current user is a user without direct access to the file or a guest it is not even possible to know if the file id belongs to a publicly shared file. Due to this when the room is got for a share token the share token is stored in the session and then used in following requests when checking whether the participant can join a room or not. Signed-off-by: Daniel Calviño Sánchez --- lib/Controller/FilesIntegrationController.php | 23 +++-- lib/Controller/PublicShareController.php | 116 ++++++++++++++++++++++++++ lib/Files/Listener.php | 57 +++++++++---- lib/Files/Util.php | 52 +++++++++++- lib/TalkSession.php | 12 +++ 5 files changed, 235 insertions(+), 25 deletions(-) create mode 100644 lib/Controller/PublicShareController.php (limited to 'lib') diff --git a/lib/Controller/FilesIntegrationController.php b/lib/Controller/FilesIntegrationController.php index 4ab4e44fb..cd5d60b73 100644 --- a/lib/Controller/FilesIntegrationController.php +++ b/lib/Controller/FilesIntegrationController.php @@ -66,20 +66,25 @@ class FilesIntegrationController extends OCSController { * * Returns the token of the room associated to the given file id. * + * This is the counterpart of PublicShareController::getRoom() for file ids + * instead of share tokens, although both return the same room token if the + * given file id and share token refer to the same file. + * * If there is no room associated to the given file id a new room is * created; the new room is a public room associated with a "file" object * with the given file id. Unlike normal rooms in which the owner is the * user that created the room these are special rooms without owner - * (although self joined users become persistent participants automatically - * when they join until they explicitly leave or no longer have access to - * the file). + * (although self joined users with direct access to the file become + * persistent participants automatically when they join until they + * explicitly leave or no longer have access to the file). * * In any case, to create or even get the token of the room, the file must - * be shared and the user must have direct access to that file; an error - * is returned otherwise. A user has direct access to a file if she has - * access to it (or to an ancestor) through a user, group, circle or room - * share (but not through a link share, for example), or if she is the owner - * of such a file. + * be shared and the user must be the owner of a public share of the file + * (like a link share, for example) or have direct access to that file; an + * error is returned otherwise. A user has direct access to a file if she + * has access to it (or to an ancestor) through a user, group, circle or + * room share (but not through a link share, for example), or if she is the + * owner of such a file. * * @param string $fileId * @return DataResponse the status code is "200 OK" if a room is returned, @@ -87,7 +92,7 @@ class FilesIntegrationController extends OCSController { * @throws OCSNotFoundException */ public function getRoom(string $fileId): DataResponse { - $share = $this->util->getAnyDirectShareOfFileAccessibleByUser($fileId, $this->currentUser); + $share = $this->util->getAnyPublicShareOfFileOwnedByUserOrAnyDirectShareOfFileAccessibleByUser($fileId, $this->currentUser); $groupFolder = null; if (!$share) { $groupFolder = $this->util->getGroupFolderNode($fileId, $this->currentUser); diff --git a/lib/Controller/PublicShareController.php b/lib/Controller/PublicShareController.php new file mode 100644 index 000000000..54b8e8acd --- /dev/null +++ b/lib/Controller/PublicShareController.php @@ -0,0 +1,116 @@ +. + * + */ + +namespace OCA\Talk\Controller; + +use OCA\Talk\Exceptions\RoomNotFoundException; +use OCA\Talk\Manager; +use OCA\Talk\TalkSession; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\OCSController; +use OCP\Files\FileInfo; +use OCP\Files\NotFoundException; +use OCP\IRequest; +use OCP\Share\Exceptions\ShareNotFound; +use OCP\Share\IManager as ShareManager; +use OCP\Share\IShare; + +class PublicShareController extends OCSController { + + /** @var ShareManager */ + private $shareManager; + /** @var TalkSession */ + private $talkSession; + /** @var Manager */ + private $manager; + + public function __construct( + $appName, + IRequest $request, + ShareManager $shareManager, + TalkSession $talkSession, + Manager $manager + ) { + parent::__construct($appName, $request); + $this->shareManager = $shareManager; + $this->talkSession = $talkSession; + $this->manager = $manager; + } + + /** + * @PublicPage + * @UseSession + * + * Returns the token of the room associated to the file id of the given + * share token. + * + * This is the counterpart of FilesController::getRoom() for share tokens + * instead of file ids, although both return the same room token if the + * given file id and share token refer to the same file. + * + * If there is no room associated to the file id of the given share token a + * new room is created; the new room is a public room associated with a + * "file" object with the file id of the given share token. Unlike normal + * rooms in which the owner is the user that created the room these are + * special rooms without owner (although self joined users with direct + * access to the file become persistent participants automatically when they + * join until they explicitly leave or no longer have access to the file). + * + * In any case, to create or even get the token of the room, the file must + * be publicly shared (like a link share, for example); an error is returned + * otherwise. + * + * @param string $shareToken + * @return DataResponse the status code is "200 OK" if a room is returned, + * or "404 Not found" if the given share token was invalid. + */ + public function getRoom(string $shareToken) { + try { + $share = $this->shareManager->getShareByToken($shareToken); + } catch (ShareNotFound $e) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + + if ($share->getNodeType() !== FileInfo::TYPE_FILE) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + + $fileId = (string)$share->getNodeId(); + + try { + $room = $this->manager->getRoomByObject('file', $fileId); + } catch (RoomNotFoundException $e) { + $name = $share->getNode()->getName(); + $room = $this->manager->createPublicRoom($name, 'file', $fileId); + } + + $this->talkSession->setFileShareTokenForRoom($room->getToken(), $shareToken); + + return new DataResponse([ + 'token' => $room->getToken() + ]); + } + +} diff --git a/lib/Files/Listener.php b/lib/Files/Listener.php index 332bed37f..0cac3a6fa 100644 --- a/lib/Files/Listener.php +++ b/lib/Files/Listener.php @@ -26,6 +26,7 @@ namespace OCA\Talk\Files; use OCA\Talk\Exceptions\ParticipantNotFoundException; use OCA\Talk\Exceptions\UnauthorizedException; use OCA\Talk\Room; +use OCA\Talk\TalkSession; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\GenericEvent; @@ -34,11 +35,12 @@ use Symfony\Component\EventDispatcher\GenericEvent; * * The rooms for files are intended to give the users a way to talk about a * specific shared file, for example, when collaboratively editing it. The room - * is persistent and can be accessed simultaneously by any user with direct + * is persistent and can be accessed simultaneously by any user or guest if the + * file is publicly shared (link share, for example), or by any user with direct * access (user, group, circle and room share, but not link share, for example) * to that file (or to an ancestor). The room has no owner, although self joined - * users become persistent participants automatically when they join until they - * explicitly leave or no longer have access to the file. + * users with direct access become persistent participants automatically when + * they join until they explicitly leave or no longer have access to the file. * * These rooms are associated to a "file" object, and their custom behaviour is * provided by calling the methods of this class as a response to different room @@ -48,9 +50,13 @@ class Listener { /** @var Util */ protected $util; + /** @var TalkSession */ + protected $talkSession; - public function __construct(Util $util) { + public function __construct(Util $util, + TalkSession $talkSession) { $this->util = $util; + $this->talkSession = $talkSession; } public static function register(EventDispatcherInterface $dispatcher): void { @@ -61,7 +67,7 @@ class Listener { $listener = \OC::$server->query(self::class); try { - $listener->preventUsersWithoutDirectAccessToTheFileFromJoining($room, $event->getArgument('userId')); + $listener->preventUsersWithoutAccessToTheFileFromJoining($room, $event->getArgument('userId')); $listener->addUserAsPersistentParticipant($room, $event->getArgument('userId')); } catch (UnauthorizedException $e) { $event->setArgument('cancel', true); @@ -72,8 +78,11 @@ class Listener { $listener = function(GenericEvent $event) { /** @var Room $room */ $room = $event->getSubject(); + /** @var self $listener */ + $listener = \OC::$server->query(self::class); + try { - self::preventGuestsFromJoining($room); + $listener->preventGuestsFromJoiningIfNotPubliclyAccessible($room); } catch (UnauthorizedException $e) { $event->setArgument('cancel', true); } @@ -82,8 +91,10 @@ class Listener { } /** - * Prevents users from joining if they do not have direct access to the - * file. + * Prevents users from joining if they do not have access to the file. + * + * A user has access to the file if the file is publicly accessible (through + * a link share, for example) or if the user has direct access to it. * * A user has direct access to a file if she received the file (or an * ancestor) through a user, group, circle or room share (but not through a @@ -95,16 +106,22 @@ class Listener { * @param string $userId * @throws UnauthorizedException */ - public function preventUsersWithoutDirectAccessToTheFileFromJoining(Room $room, string $userId): void { + public function preventUsersWithoutAccessToTheFileFromJoining(Room $room, string $userId): void { if ($room->getObjectType() !== 'file') { return; } - $share = $this->util->getAnyDirectShareOfFileAccessibleByUser($room->getObjectId(), $userId); + // If a guest can access the file then any user can too. + $shareToken = $this->talkSession->getFileShareTokenForRoom($room->getToken()); + if ($shareToken && $this->util->canGuestAccessFile($shareToken)) { + return; + } + + $share = $this->util->getAnyPublicShareOfFileOwnedByUserOrAnyDirectShareOfFileAccessibleByUser($room->getObjectId(), $userId); if (!$share) { $groupFolder = $this->util->getGroupFolderNode($room->getObjectId(), $userId); if (!$groupFolder) { - throw new UnauthorizedException('User does not have direct access to the file'); + throw new UnauthorizedException('User does not have access to the file'); } } } @@ -112,6 +129,9 @@ class Listener { /** * Add user as a persistent participant of a file room. * + * Only users with direct access to the file are added as persistent + * participants of the room. + * * This method should be called before a user joins a room, but only if the * user should be able to join the room. * @@ -123,6 +143,10 @@ class Listener { return; } + if (!$this->util->getAnyPublicShareOfFileOwnedByUserOrAnyDirectShareOfFileAccessibleByUser($room->getObjectId(), $userId)) { + return; + } + try { $room->getParticipant($userId); } catch (ParticipantNotFoundException $e) { @@ -131,19 +155,24 @@ class Listener { } /** - * Prevents guests from joining the room. + * Prevents guests from joining the room if it is not publicly accessible. * * This method should be called before a guest joins a room. * * @param Room $room * @throws UnauthorizedException */ - protected static function preventGuestsFromJoining(Room $room): void { + protected function preventGuestsFromJoiningIfNotPubliclyAccessible(Room $room): void { if ($room->getObjectType() !== 'file') { return; } - throw new UnauthorizedException('Guests are not allowed in rooms for files'); + $shareToken = $this->talkSession->getFileShareTokenForRoom($room->getToken()); + if ($shareToken && $this->util->canGuestAccessFile($shareToken)) { + return; + } + + throw new UnauthorizedException('Guests are not allowed in this room'); } } diff --git a/lib/Files/Util.php b/lib/Files/Util.php index 5658a1e7b..c3f45dabc 100644 --- a/lib/Files/Util.php +++ b/lib/Files/Util.php @@ -28,6 +28,7 @@ use OCP\Files\FileInfo; use OCP\Files\IRootFolder; use OCP\Files\Node; use OCP\Files\NotFoundException; +use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager as IShareManager; use OCP\Share\IShare; @@ -67,8 +68,23 @@ class Util { return \in_array($userId, $this->getUsersWithAccessFile($fileId), true); } + public function canGuestAccessFile(string $shareToken): bool { + try { + $this->shareManager->getShareByToken($shareToken); + return true; + } catch (ShareNotFound $e) { + return false; + } + } + /** - * Returns any share of the file that the user has direct access to. + * Returns any share of the file that is public and owned by the user, or + * that the user has direct access to. + * + * A public share is one accessible by any user, including guests, like a + * share by link. Note that only a share of the file itself is taken into + * account; if an ancestor folder is shared publicly that share will not be + * returned. * * A user has direct access to a share and, thus, to a file, if she received * the file through a user, group, circle or room share (but not through a @@ -82,7 +98,7 @@ class Util { * @param string $userId * @return IShare|null */ - public function getAnyDirectShareOfFileAccessibleByUser(string $fileId, string $userId): ?IShare { + public function getAnyPublicShareOfFileOwnedByUserOrAnyDirectShareOfFileAccessibleByUser(string $fileId, string $userId): ?IShare { $userFolder = $this->rootFolder->getUserFolder($userId); $nodes = $userFolder->getById($fileId); if (empty($nodes)) { @@ -93,6 +109,13 @@ class Util { return $node->getType() === FileInfo::TYPE_FILE; }); + if (!empty($nodes)) { + $share = $this->getAnyPublicShareOfNodeOwnedByUser($nodes[0], $userId); + if ($share) { + return $share; + } + } + while (!empty($nodes)) { $node = array_pop($nodes); @@ -110,6 +133,31 @@ class Util { return null; } + /** + * Returns any public share of the node (like a link share) created by the + * user. + * + * @param Node $node + * @param string $userId + * @return IShare|null + */ + private function getAnyPublicShareOfNodeOwnedByUser(Node $node, string $userId): ?IShare { + $reshares = false; + $limit = 1; + + $shares = $this->shareManager->getSharesBy($userId, \OCP\Share::SHARE_TYPE_LINK, $node, $reshares, $limit); + if (\count($shares) > 0) { + return $shares[0]; + } + + $shares = $this->shareManager->getSharesBy($userId, \OCP\Share::SHARE_TYPE_EMAIL, $node, $reshares, $limit); + if (\count($shares) > 0) { + return $shares[0]; + } + + return null; + } + /** * Returns any share of the node that the user has direct access to. * diff --git a/lib/TalkSession.php b/lib/TalkSession.php index 351c14a34..50f55fc70 100644 --- a/lib/TalkSession.php +++ b/lib/TalkSession.php @@ -51,6 +51,18 @@ class TalkSession { $this->removeValue('spreed-session', $token); } + public function getFileShareTokenForRoom(string $roomToken): ?string { + return $this->getValue('spreed-file-share-token', $roomToken); + } + + public function setFileShareTokenForRoom(string $roomToken, string $shareToken): void { + $this->setValue('spreed-file-share-token', $roomToken, $shareToken); + } + + public function removeFileShareTokenForRoom(string $roomToken): void { + $this->removeValue('spreed-file-share-token', $roomToken); + } + public function getPasswordForRoom(string $token): ?string { return $this->getValue('spreed-password', $token); } -- cgit v1.2.3 From b10313cbc48cc230e5ea840c8a73d978d13421a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 14 Aug 2019 17:19:22 +0200 Subject: Add self-joined users and guests to the candidate mentions in file rooms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit File rooms were available only to users with direct access to the file, so those were the users that could be mentioned. Now file rooms are publicly available if the file is shared by link, so the mentions now include all the users with direct access to the file like before plus all the self-joined users and guests currently in the room. Note, however, that self-joined users and guests can still not mention users with direct access to the file that have not joined the room yet, but only those that joined the room already (plus any participant that is currently in the room). Signed-off-by: Daniel Calviño Sánchez --- lib/Chat/AutoComplete/SearchPlugin.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/Chat/AutoComplete/SearchPlugin.php b/lib/Chat/AutoComplete/SearchPlugin.php index eae62560c..64d74172a 100644 --- a/lib/Chat/AutoComplete/SearchPlugin.php +++ b/lib/Chat/AutoComplete/SearchPlugin.php @@ -84,8 +84,6 @@ class SearchPlugin implements ISearchPlugin { if (!empty($usersWithFileAccess)) { $this->searchUsers($search, $usersWithFileAccess, $searchResult); } - - return false; } $userIds = $guestSessionHashes = []; @@ -113,6 +111,8 @@ class SearchPlugin implements ISearchPlugin { protected function searchUsers(string $search, array $userIds, ISearchResult $searchResult): void { $search = strtolower($search); + $type = new SearchResultType('users'); + $matches = $exactMatches = []; foreach ($userIds as $userId) { if ($this->userId !== '' && $this->userId === $userId) { @@ -120,6 +120,10 @@ class SearchPlugin implements ISearchPlugin { continue; } + if ($searchResult->hasResult($type, $userId)) { + continue; + } + if ($search === '') { $matches[] = $this->createResult('user', $userId, ''); continue; @@ -151,7 +155,6 @@ class SearchPlugin implements ISearchPlugin { } } - $type = new SearchResultType('users'); $searchResult->addResultSet($type, $matches, $exactMatches); } -- cgit v1.2.3 From 1ba0f4fd45f9240d77de77c6ec0deadf35ee31af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Thu, 15 Aug 2019 10:10:57 +0200 Subject: Add support for Talk sidebar in public share pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the public share page is loaded "publicshare.js" is initialized, which modifies the page to add a Talk sidebar. The default layout has the header, content and footer in a flex column; when the sidebar is added the layout id modified to still have the header and content in a flex column, but the content is now a flex row that includes "#app-content" and the sidebar, and the footer is moved inside "#app-content" so it does not affect the sidebar. The Talk sidebar includes a call container at the top, which is only shown during calls, and below it a call button and a chat view which are always shown. The CSS styles are a mix of the styles for the public share auth page and the Files app, as well as some rules copied from the main "style.scss" file. Signed-off-by: Daniel Calviño Sánchez --- lib/AppInfo/Application.php | 2 ++ lib/PublicShare/TemplateLoader.php | 57 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 lib/PublicShare/TemplateLoader.php (limited to 'lib') diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 4b46701bb..e1837f65e 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -43,6 +43,7 @@ use OCA\Talk\Notification\Listener as NotificationListener; use OCA\Talk\Notification\Notifier; use OCA\Talk\PublicShareAuth\Listener as PublicShareAuthListener; use OCA\Talk\PublicShareAuth\TemplateLoader as PublicShareAuthTemplateLoader; +use OCA\Talk\PublicShare\TemplateLoader as PublicShareTemplateLoader; use OCA\Talk\Room; use OCA\Talk\Settings\Personal; use OCA\Talk\Share\RoomShareProvider; @@ -110,6 +111,7 @@ class Application extends App { ParserListener::register($dispatcher); PublicShareAuthListener::register($dispatcher); PublicShareAuthTemplateLoader::register($dispatcher); + PublicShareTemplateLoader::register($dispatcher); FilesListener::register($dispatcher); FilesTemplateLoader::register($dispatcher); RestrictStartingCallsListener::register($dispatcher); diff --git a/lib/PublicShare/TemplateLoader.php b/lib/PublicShare/TemplateLoader.php new file mode 100644 index 000000000..1d37eb7c7 --- /dev/null +++ b/lib/PublicShare/TemplateLoader.php @@ -0,0 +1,57 @@ +. + * + */ + +namespace OCA\Talk\PublicShare; + +use OCP\Util; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; + +/** + * Helper class to extend the "publicshare" template from the server. + * + * The "loadTalkSidebarUi" method loads additional scripts that, when run on the + * browser, adjust the page generated by the server to inject the Talk UI as + * needed. + */ +class TemplateLoader { + + public static function register(EventDispatcherInterface $dispatcher): void { + $listener = function() { + self::loadTalkSidebarUi(); + }; + $dispatcher->addListener('OCA\Files_Sharing::loadAdditionalScripts', $listener); + } + + /** + * Load the "Talk sidebar" UI in the public share page for the given share. + * + * This method should be called when loading additional scripts for the + * public share page of the server. + */ + public static function loadTalkSidebarUi() { + Util::addStyle('spreed', 'merged-public-share'); + Util::addScript('spreed', 'merged-public-share'); + } + +} -- cgit v1.2.3 From 41a15569570b1b1208d7a4c2221fb0a9efcb2711 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 16 Aug 2019 21:10:00 +0200 Subject: Correctly check if the share has a password and if it was entered correctly. This prevents joining the room for a file shared by link and protected by password if the password has not been entered yet. Signed-off-by: Joas Schilling --- lib/Controller/PublicShareController.php | 11 +++++++++++ lib/Files/Util.php | 13 ++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/Controller/PublicShareController.php b/lib/Controller/PublicShareController.php index 54b8e8acd..ab7f6f395 100644 --- a/lib/Controller/PublicShareController.php +++ b/lib/Controller/PublicShareController.php @@ -33,6 +33,7 @@ use OCP\AppFramework\OCSController; use OCP\Files\FileInfo; use OCP\Files\NotFoundException; use OCP\IRequest; +use OCP\ISession; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager as ShareManager; use OCP\Share\IShare; @@ -41,6 +42,8 @@ class PublicShareController extends OCSController { /** @var ShareManager */ private $shareManager; + /** @var ISession */ + private $session; /** @var TalkSession */ private $talkSession; /** @var Manager */ @@ -50,11 +53,13 @@ class PublicShareController extends OCSController { $appName, IRequest $request, ShareManager $shareManager, + ISession $session, TalkSession $talkSession, Manager $manager ) { parent::__construct($appName, $request); $this->shareManager = $shareManager; + $this->session = $session; $this->talkSession = $talkSession; $this->manager = $manager; } @@ -89,6 +94,12 @@ class PublicShareController extends OCSController { public function getRoom(string $shareToken) { try { $share = $this->shareManager->getShareByToken($shareToken); + if ($share->getPassword() !== null) { + $shareId = $this->session->get('public_link_authenticated'); + if ($share->getId() !== $shareId) { + throw new ShareNotFound(); + } + } } catch (ShareNotFound $e) { return new DataResponse([], Http::STATUS_NOT_FOUND); } diff --git a/lib/Files/Util.php b/lib/Files/Util.php index c3f45dabc..c4dc0af10 100644 --- a/lib/Files/Util.php +++ b/lib/Files/Util.php @@ -28,6 +28,7 @@ use OCP\Files\FileInfo; use OCP\Files\IRootFolder; use OCP\Files\Node; use OCP\Files\NotFoundException; +use OCP\ISession; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager as IShareManager; use OCP\Share\IShare; @@ -36,14 +37,18 @@ class Util { /** @var IRootFolder */ private $rootFolder; + /** @var ISession */ + private $session; /** @var IShareManager */ private $shareManager; /** @var array[] */ private $accessLists = []; public function __construct(IRootFolder $rootFolder, + ISession $session, IShareManager $shareManager) { $this->rootFolder = $rootFolder; + $this->session = $session; $this->shareManager = $shareManager; } @@ -70,7 +75,13 @@ class Util { public function canGuestAccessFile(string $shareToken): bool { try { - $this->shareManager->getShareByToken($shareToken); + $share = $this->shareManager->getShareByToken($shareToken); + if ($share->getPassword() !== null) { + $shareId = $this->session->get('public_link_authenticated'); + if ($share->getId() !== $shareId) { + throw new ShareNotFound(); + } + } return true; } catch (ShareNotFound $e) { return false; -- cgit v1.2.3 From 7fdcb46777843ac4153689501f4c8933381c1e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 19 Aug 2019 02:49:39 +0200 Subject: Do not add system message for self joined users to file rooms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a user with access to a file joins its file room the user is added as a persistent participant, so a "XXX joined the conversation" system message is shown. However, if a user does not have direct access to a file and joins its room the user is not added as a persistent participant, so the system message should not be shown in that case. Signed-off-by: Daniel Calviño Sánchez --- lib/Chat/SystemMessage/Listener.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/Chat/SystemMessage/Listener.php b/lib/Chat/SystemMessage/Listener.php index 2ef7eb197..3933b6d3a 100644 --- a/lib/Chat/SystemMessage/Listener.php +++ b/lib/Chat/SystemMessage/Listener.php @@ -195,7 +195,9 @@ class Listener { /** @var self $listener */ $listener = \OC::$server->query(self::class); foreach ($participants as $participant) { - if ($room->getObjectType() === 'file' || $userId !== $participant['userId']) { + $userJoinedFileRoom = $room->getObjectType() === 'file' && + (!array_key_exists('participantType', $participant) || $participant['participantType'] !== Participant::USER_SELF_JOINED); + if ($userJoinedFileRoom || $userId !== $participant['userId']) { $listener->sendSystemMessage($room, 'user_added', ['user' => $participant['userId']]); } } -- cgit v1.2.3 From c1e66878fe4e77937615b5a4260b689d22491845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 25 Sep 2019 13:27:06 +0200 Subject: Override the current user when getting the room for a public share page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The public share page uses the incognito mode, so "OC.getCurrentUser()" never returns a user, even if the user is actually logged in. However, Talk API requests honour the actual current user, so the Talk UI needs to honour it as well. Moreover, when the external signaling server is used, the Talk UI needs to honour the current user not only to show the right user name and avatar, but to be able to even connect with the external signaling server. Signed-off-by: Daniel Calviño Sánchez --- lib/Controller/PublicShareController.php | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/Controller/PublicShareController.php b/lib/Controller/PublicShareController.php index ab7f6f395..a555ae86d 100644 --- a/lib/Controller/PublicShareController.php +++ b/lib/Controller/PublicShareController.php @@ -33,6 +33,8 @@ use OCP\AppFramework\OCSController; use OCP\Files\FileInfo; use OCP\Files\NotFoundException; use OCP\IRequest; +use OCP\IUser; +use OCP\IUserManager; use OCP\ISession; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager as ShareManager; @@ -40,6 +42,10 @@ use OCP\Share\IShare; class PublicShareController extends OCSController { + /** @var string|null */ + private $userId; + /** @var IUserManager */ + private $userManager; /** @var ShareManager */ private $shareManager; /** @var ISession */ @@ -51,13 +57,17 @@ class PublicShareController extends OCSController { public function __construct( $appName, + ?string $UserId, IRequest $request, + IUserManager $userManager, ShareManager $shareManager, ISession $session, TalkSession $talkSession, Manager $manager ) { parent::__construct($appName, $request); + $this->userId = $UserId; + $this->userManager = $userManager; $this->shareManager = $shareManager; $this->session = $session; $this->talkSession = $talkSession; @@ -87,6 +97,11 @@ class PublicShareController extends OCSController { * be publicly shared (like a link share, for example); an error is returned * otherwise. * + * Besides the token of the room this also returns the current user ID and + * display name, if any; this is needed by the Talk sidebar to know the + * actual current user, as the public share page uses the incognito mode and + * thus logged in users as seen as guests. + * * @param string $shareToken * @return DataResponse the status code is "200 OK" if a room is returned, * or "404 Not found" if the given share token was invalid. @@ -119,8 +134,14 @@ class PublicShareController extends OCSController { $this->talkSession->setFileShareTokenForRoom($room->getToken(), $shareToken); + $currentUser = $this->userManager->get($this->userId); + $currentUserId = $currentUser instanceof IUser ? $currentUser->getUID() : ''; + $currentUserDisplayName = $currentUser instanceof IUser ? $currentUser->getDisplayName() : ''; + return new DataResponse([ - 'token' => $room->getToken() + 'token' => $room->getToken(), + 'userId' => $currentUserId, + 'userDisplayName' => $currentUserDisplayName, ]); } -- cgit v1.2.3