Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/participant.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
- Status code:
+ `200 OK`
+ `400 Bad Request` When the source type is unknown, currently `users`, `groups`, `emails` are supported. `circles` are supported with `circles-support` capability
+ `400 Bad Request` When the conversation is a one-to-one conversation
+ `400 Bad Request` When the conversation is a one-to-one conversation or a conversation to request a password for a share
+ `403 Forbidden` When the current user is not a moderator or owner
+ `404 Not Found` When the conversation could not be found for the participant
+ `404 Not Found` When the user or group to add could not be found
Expand Down
2 changes: 1 addition & 1 deletion lib/Controller/RoomController.php
Original file line number Diff line number Diff line change
Expand Up @@ -1110,7 +1110,7 @@ public function getParticipants(bool $includeStatus = false): DataResponse {
* @return DataResponse
*/
public function addParticipantToRoom(string $newParticipant, string $source = 'users'): DataResponse {
if ($this->room->getType() === Room::ONE_TO_ONE_CALL) {
if ($this->room->getType() === Room::ONE_TO_ONE_CALL || $this->room->getObjectType() === 'share:password') {
return new DataResponse([], Http::STATUS_BAD_REQUEST);
}

Expand Down
40 changes: 36 additions & 4 deletions lib/PublicShareAuth/Listener.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

namespace OCA\Talk\PublicShareAuth;

use OCA\Talk\Events\AddParticipantsEvent;
use OCA\Talk\Events\JoinRoomGuestEvent;
use OCA\Talk\Events\JoinRoomUserEvent;
use OCA\Talk\Events\RoomEvent;
Expand Down Expand Up @@ -58,6 +59,11 @@ public static function register(IEventDispatcher $dispatcher): void {
};
$dispatcher->addListener(Room::EVENT_BEFORE_GUEST_CONNECT, $listener);

$listener = static function (AddParticipantsEvent $event) {
self::preventExtraUsersFromBeingAdded($event->getRoom(), $event->getParticipants());
};
$dispatcher->addListener(Room::EVENT_BEFORE_USERS_ADD, $listener);

$listener = static function (RoomEvent $event) {
self::destroyRoomOnParticipantLeave($event->getRoom());
};
Expand Down Expand Up @@ -91,8 +97,7 @@ public static function preventExtraUsersFromJoining(Room $room, string $userId):
}

$participantService = \OC::$server->get(ParticipantService::class);
$users = $participantService->getParticipantUserIds($room);
if ($room->getActiveGuests() > 0 || \count($users) > 1) {
if ($participantService->getNumberOfActors($room) > 1) {
throw new \OverflowException('Only the owner and another participant are allowed in rooms to request the password for a share');
}
}
Expand All @@ -112,8 +117,35 @@ public static function preventExtraGuestsFromJoining(Room $room): void {
}

$participantService = \OC::$server->get(ParticipantService::class);
$users = $participantService->getParticipantUserIds($room);
if ($room->getActiveGuests() > 0 || \count($users) > 1) {
if ($participantService->getNumberOfActors($room) > 1) {
throw new \OverflowException('Only the owner and another participant are allowed in rooms to request the password for a share');
}
}

/**
* Prevents other users from being added to the room (as they will not be
* able to join).
*
* This method should be called before a user is added to a room.
*
* @param Room $room
* @param array[] $participants
* @throws \OverflowException
*/
public static function preventExtraUsersFromBeingAdded(Room $room, array $participants): void {
if ($room->getObjectType() !== 'share:password') {
return;
}

// Events with more than one participant can be directly aborted, as
// when the owner is added during room creation or a user self-joins the
// event will always have just one participant.
if (count($participants) > 1) {
throw new \OverflowException('Only the owner and another participant are allowed in rooms to request the password for a share');
}

$participant = $participants[0];
if ($participant['participantType'] !== Participant::OWNER && $participant['participantType'] !== Participant::USER_SELF_JOINED) {
throw new \OverflowException('Only the owner and another participant are allowed in rooms to request the password for a share');
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ export default {
this.cancelableGetParticipants()
} catch (exception) {
console.debug(exception)
showError(t('spreed', 'An error occurred while adding the participants'))
}
},

Expand Down
2 changes: 1 addition & 1 deletion src/components/RightSidebar/RightSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export default {
},
canSearchParticipants() {
return (this.conversation.type === CONVERSATION.TYPE.GROUP
|| this.conversation.type === CONVERSATION.TYPE.PUBLIC)
|| (this.conversation.type === CONVERSATION.TYPE.PUBLIC && this.conversation.objectType !== 'share:password'))
},
isSearching() {
return this.searchText !== ''
Expand Down
59 changes: 56 additions & 3 deletions tests/integration/features/bootstrap/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@ public function userIsParticipantOfRooms($user, TableNode $formData = null) {
return;
}

$this->assertRooms($rooms, $formData);
}

/**
* @param array $rooms
* @param TableNode $formData
*/
private function assertRooms($rooms, TableNode $formData) {
Assert::assertCount(count($formData->getHash()), $rooms, 'Room count does not match');
Assert::assertEquals($formData->getHash(), array_map(function ($room, $expectedRoom) {
$participantNames = array_map(function ($participant) {
Expand Down Expand Up @@ -204,10 +212,11 @@ public function userIsParticipantOfRooms($user, TableNode $formData = null) {
* @param string $user
* @param string $isOrNotParticipant
* @param string $identifier
* @param TableNode|null $formData
*/
public function userIsParticipantOfRoom($user, $isOrNotParticipant, $identifier) {
public function userIsParticipantOfRoom($user, $isOrNotParticipant, $identifier, TableNode $formData = null) {
if (strpos($user, 'guest') === 0) {
$this->guestIsParticipantOfRoom($user, $isOrNotParticipant, $identifier);
$this->guestIsParticipantOfRoom($user, $isOrNotParticipant, $identifier, $formData);

return;
}
Expand All @@ -231,6 +240,15 @@ public function userIsParticipantOfRoom($user, $isOrNotParticipant, $identifier)
foreach ($rooms as $room) {
if (self::$tokenToIdentifier[$room['token']] === $identifier) {
Assert::assertEquals($isParticipant, true, 'Room ' . $identifier . ' found in user´s room list');

if ($formData) {
$this->sendRequest('GET', '/apps/spreed/api/v1/room/' . self::$identifierToToken[$identifier]);

$rooms = [$this->getDataFromResponse($this->response)];

$this->assertRooms($rooms, $formData);
}

return;
}
}
Expand All @@ -242,15 +260,22 @@ public function userIsParticipantOfRoom($user, $isOrNotParticipant, $identifier)
* @param string $guest
* @param string $isOrNotParticipant
* @param string $identifier
* @param TableNode|null $formData
*/
private function guestIsParticipantOfRoom($guest, $isOrNotParticipant, $identifier) {
private function guestIsParticipantOfRoom($guest, $isOrNotParticipant, $identifier, TableNode $formData = null) {
$this->setCurrentUser($guest);
$this->sendRequest('GET', '/apps/spreed/api/v1/room/' . self::$identifierToToken[$identifier]);

$response = $this->getDataFromResponse($this->response);

$isParticipant = $isOrNotParticipant === 'is';

if ($formData) {
$rooms = [$response];

$this->assertRooms($rooms, $formData);
}

if ($isParticipant) {
$this->assertStatusCode($this->response, 200);
Assert::assertEquals(self::$userToSessionId[$guest], $response['sessionId']);
Expand Down Expand Up @@ -424,6 +449,30 @@ public function userGetsTheRoomForLastShare($user, $statusCode) {
self::$tokenToIdentifier[$response['token']] = $identifier;
}

/**
* @Then /^user "([^"]*)" creates the password request room for last share with (\d+)$/
*
* @param string $user
* @param int $statusCode
*/
public function userCreatesThePasswordRequestRoomForLastShare($user, $statusCode) {
$shareToken = $this->sharingContext->getLastShareToken();

$this->setCurrentUser($user);
$this->sendRequest('POST', '/apps/spreed/api/v1/publicshareauth', ['shareToken' => $shareToken]);
$this->assertStatusCode($this->response, $statusCode);

if ($statusCode !== '201') {
return;
}

$response = $this->getDataFromResponse($this->response);

$identifier = 'password request for last share room';
self::$identifierToToken[$identifier] = $response['token'];
self::$tokenToIdentifier[$response['token']] = $identifier;
}

/**
* @Then /^user "([^"]*)" joins room "([^"]*)" with (\d+)$/
*
Expand All @@ -440,6 +489,10 @@ public function userJoinsRoom($user, $identifier, $statusCode, TableNode $formDa
);
$this->assertStatusCode($this->response, $statusCode);

if ($statusCode !== '200') {
return;
}

$response = $this->getDataFromResponse($this->response);
if (array_key_exists('sessionId', $response)) {
// In the chat guest users are identified by their sessionId. The
Expand Down
Loading