Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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: 2 additions & 0 deletions docs/call.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
+ `200 OK`
+ `400 Bad Request` When recording consent is required but was not given
+ `403 Forbidden` When the conversation is read-only
+ `403 Forbidden` When the user is not allowed to start a call and no call is currently active
+ `403 Forbidden` When the conversation is a federated conversation and the host server did not allow joining the call
+ `404 Not Found` When the conversation could not be found for the participant
+ `404 Not Found` When the user did not join the conversation before
+ `412 Precondition Failed` When the lobby is active and the user is not a moderator
Expand Down
3 changes: 2 additions & 1 deletion lib/Controller/CallController.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,11 @@ protected function escapeFormulae(string $value): string {
* or the capability is {@see RecordingService::CONSENT_REQUIRED_OPTIONAL}
* and the conversation `recordingConsent` value is {@see RecordingService::CONSENT_REQUIRED_YES} )
* @param list<string> $silentFor Send no call notification for previous participants
* @return DataResponse<Http::STATUS_OK|Http::STATUS_NOT_FOUND, null, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, array{error: string}, array{}>
* @return DataResponse<Http::STATUS_OK|Http::STATUS_FORBIDDEN|Http::STATUS_NOT_FOUND, null, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, array{error: string}, array{}>
*
* 200: Call joined successfully
* 400: No recording consent was given
* 403: Host server of the federated conversation does not allow joining the call
* 404: Call not found
*/
#[FederationSupported]
Expand Down
14 changes: 12 additions & 2 deletions lib/Controller/SignalingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -906,8 +906,18 @@ private function backendRoom(array $roomRequest): DataResponse {
if ($participant->getSession() instanceof Session) {
if ($inCall !== null) {
$lastJoinedCall = $this->timeFactory->getDateTime();
$this->participantService->changeInCall($room, $participant, $inCall, lastJoinedCall: $lastJoinedCall->getTimestamp());
$this->roomService->setActiveSince($room, $participant, $lastJoinedCall, callFlag: $inCall, silent: false);
try {
$this->participantService->changeInCall($room, $participant, $inCall, lastJoinedCall: $lastJoinedCall->getTimestamp());
$this->roomService->setActiveSince($room, $participant, $lastJoinedCall, callFlag: $inCall, silent: false);
} catch (ForbiddenException) {
return new DataResponse([
'type' => 'error',
'error' => [
'code' => 'start_call_not_allowed',
'message' => 'The participant is not allowed to start a call.',
],
]);
}
}
$this->sessionService->updateLastPing($participant->getSession(), $this->timeFactory->getTime());
}
Expand Down
5 changes: 3 additions & 2 deletions lib/Federation/Proxy/TalkV1/Controller/CallController.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,12 @@ public function getPeersForCall(Room $room, Participant $participant): DataRespo
* @psalm-param int-mask-of<Participant::FLAG_*> $flags
* @param bool $silent Join the call silently
* @param bool $recordingConsent Agreement to be recorded
* @return DataResponse<Http::STATUS_OK|Http::STATUS_NOT_FOUND, null, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, array{error: string}, array{}>
* @return DataResponse<Http::STATUS_OK|Http::STATUS_FORBIDDEN|Http::STATUS_NOT_FOUND, null, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, array{error: string}, array{}>
* @throws CannotReachRemoteException
*
* 200: Federated user is now in the call
* 400: Conditions to join not met
* 403: Host server does not allow the user to join the call
* 404: Room not found
*/
public function joinFederatedCall(Room $room, Participant $participant, int $flags, bool $silent, bool $recordingConsent): DataResponse {
Expand All @@ -96,7 +97,7 @@ public function joinFederatedCall(Room $room, Participant $participant, int $fla
);

$statusCode = $proxy->getStatusCode();
if (!in_array($statusCode, [Http::STATUS_OK, Http::STATUS_BAD_REQUEST, Http::STATUS_NOT_FOUND], true)) {
if (!in_array($statusCode, [Http::STATUS_OK, Http::STATUS_BAD_REQUEST, Http::STATUS_FORBIDDEN, Http::STATUS_NOT_FOUND], true)) {
$this->proxy->logUnexpectedStatusCode(__METHOD__, $proxy->getStatusCode());
throw new CannotReachRemoteException();
}
Expand Down
30 changes: 30 additions & 0 deletions openapi-full.json
Original file line number Diff line number Diff line change
Expand Up @@ -5423,6 +5423,36 @@
}
}
},
"403": {
"description": "Host server of the federated conversation does not allow joining the call",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"nullable": true
}
}
}
}
}
}
}
},
"404": {
"description": "Call not found",
"content": {
Expand Down
30 changes: 30 additions & 0 deletions openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -5328,6 +5328,36 @@
}
}
},
"403": {
"description": "Host server of the federated conversation does not allow joining the call",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"nullable": true
}
}
}
}
}
}
}
},
"404": {
"description": "Call not found",
"content": {
Expand Down
14 changes: 14 additions & 0 deletions src/types/openapi/openapi-full.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4395,6 +4395,20 @@ export interface operations {
};
};
};
/** @description Host server of the federated conversation does not allow joining the call */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": {
ocs: {
meta: components["schemas"]["OCSMeta"];
data: unknown;
};
};
};
};
/** @description Call not found */
404: {
headers: {
Expand Down
14 changes: 14 additions & 0 deletions src/types/openapi/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3829,6 +3829,20 @@ export interface operations {
};
};
};
/** @description Host server of the federated conversation does not allow joining the call */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": {
ocs: {
meta: components["schemas"]["OCSMeta"];
data: unknown;
};
};
};
};
/** @description Call not found */
404: {
headers: {
Expand Down
39 changes: 39 additions & 0 deletions tests/integration/features/federation/call.feature
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,45 @@ Feature: federation/call
| users | participant2 | 7 |
And user "participant2" sees 2 peers in call "LOCAL::room" with 200 (v4)

@skip31
Scenario: Federated user can not start a call when the host only allows moderators to start calls
Given the following "spreed" app config is set
| start_calls | 2 |
And user "participant1" creates room "room" (v4)
| roomType | 2 |
| roomName | room |
And user "participant1" adds federated_user "participant2" to room "room" with 200 (v4)
And using server "REMOTE"
And user "participant2" has the following invitations (v1)
| remoteServerUrl | remoteToken | state | inviterCloudId | inviterDisplayName |
| LOCAL | room | 0 | participant1@LOCAL | participant1-displayname |
And user "participant2" accepts invite to room "room" of server "LOCAL" with 200 (v1)
| id | name | type | remoteServer | remoteToken |
| LOCAL::room | room | 2 | LOCAL | room |
And user "participant2" joins room "LOCAL::room" with 200 (v4)
# The federated user is not a moderator on the host, so they are not allowed to start the call there
When user "participant2" joins call "LOCAL::room" with 403 (v4)
| flags | 7 |
Then user "participant2" is participant of room "LOCAL::room" (v4)
| callFlag |
| 0 |
# A moderator of the host starts the call
And using server "LOCAL"
And user "participant1" joins room "room" with 200 (v4)
And user "participant1" joins call "room" with 200 (v4)
| flags | 3 |
# Now the federated user is allowed to join the already running call
And using server "REMOTE"
And user "participant2" joins call "LOCAL::room" with 200 (v4)
| flags | 7 |
And user "participant2" is participant of room "LOCAL::room" (v4)
| callFlag |
| 7 |
And user "participant2" sees the following attendees in room "LOCAL::room" with 200 (v4)
| actorType | actorId | inCall |
| federated_users | participant1@{$LOCAL_URL} | 3 |
| users | participant2 | 7 |

Scenario: update call flags
Given user "participant1" creates room "room" (v4)
| roomType | 2 |
Expand Down
Loading