Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable30] feat(calls): Allow moderators to download a call participants list #13555

Merged
merged 1 commit into from
Oct 15, 2024
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 appinfo/routes/routesCallController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
'ocs' => [
/** @see \OCA\Talk\Controller\CallController::getPeersForCall() */
['name' => 'Call#getPeersForCall', 'url' => '/api/{apiVersion}/call/{token}', 'verb' => 'GET', 'requirements' => $requirements],
/** @see \OCA\Talk\Controller\CallController::downloadParticipantsForCall() */
['name' => 'Call#downloadParticipantsForCall', 'url' => '/api/{apiVersion}/call/{token}/download', 'verb' => 'GET', 'requirements' => $requirements],
/** @see \OCA\Talk\Controller\CallController::joinCall() */
['name' => 'Call#joinCall', 'url' => '/api/{apiVersion}/call/{token}', 'verb' => 'POST', 'requirements' => $requirements],
/** @see \OCA\Talk\Controller\CallController::joinFederatedCall() */
Expand Down
1 change: 1 addition & 0 deletions docs/capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,5 +159,6 @@
## 20.1
* `archived-conversations` (local) - Conversations can be marked as archived which will hide them from the conversation list by default
* `talk-polls-drafts` - Whether moderators can store and retrieve poll drafts
* `download-call-participants` - Whether the endpoints for moderators to download the call participants is available
* `config => call => start-without-media` (local) - Boolean, whether media should be disabled when starting or joining a conversation
* `config => call => max-duration` - Integer, maximum call duration in seconds. Please note that this should only be used with system cron and with a reasonable high value, due to the expended duration until the background job ran.
1 change: 1 addition & 0 deletions lib/Capabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class Capabilities implements IPublicCapability {
'edit-messages-note-to-self',
'archived-conversations',
'talk-polls-drafts',
'download-call-participants',
];

public const LOCAL_FEATURES = [
Expand Down
50 changes: 50 additions & 0 deletions lib/Controller/CallController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use OCA\Talk\Middleware\Attribute\RequireCallEnabled;
use OCA\Talk\Middleware\Attribute\RequireFederatedParticipant;
use OCA\Talk\Middleware\Attribute\RequireModeratorOrNoLobby;
use OCA\Talk\Middleware\Attribute\RequireModeratorParticipant;
use OCA\Talk\Middleware\Attribute\RequireParticipant;
use OCA\Talk\Middleware\Attribute\RequirePermission;
use OCA\Talk\Middleware\Attribute\RequireReadWriteConversation;
Expand All @@ -33,7 +34,9 @@
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\BruteForceProtection;
use OCP\AppFramework\Http\Attribute\PublicPage;
use OCP\AppFramework\Http\DataDownloadResponse;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\IRequest;
use OCP\IUserManager;
Expand Down Expand Up @@ -111,6 +114,53 @@ public function getPeersForCall(): DataResponse {
return new DataResponse($result);
}

/**
* Download the list of current call participants
*
* Required capability: `download-call-participants`
*
* @param 'csv'|'pdf' $format Download format
* @return DataDownloadResponse<Http::STATUS_OK, 'text/csv'|'application/pdf', array{}>|Response<Http::STATUS_BAD_REQUEST, array{}>
*
* 200: List of participants in the call downloaded in the requested format
* 400: No call in progress
*/
#[PublicPage]
#[RequireModeratorParticipant]
public function downloadParticipantsForCall(string $format = 'csv'): DataDownloadResponse|Response {
$timeout = $this->timeFactory->getTime() - Session::SESSION_TIMEOUT;
$participants = $this->participantService->getParticipantsInCall($this->room, $timeout);

if (empty($participants)) {
return new Response(Http::STATUS_BAD_REQUEST);
}

if ($format !== 'csv' && $format !== 'pdf') {
// Unsupported format
return new Response(Http::STATUS_BAD_REQUEST);
}

if ($format !== 'csv') {
// FIXME Remove once pdf was implemented.
return new Response(Http::STATUS_BAD_REQUEST);
}

$output = fopen('php://memory', 'w');
fputcsv($output, [
'name',
'type',
'identifier',
]);

foreach ($participants as $participant) {
fputcsv($output, [$participant->getAttendee()->getDisplayName(), $participant->getAttendee()->getActorType(), $participant->getAttendee()->getActorId()]);
}

fseek($output, 0);

return new DataDownloadResponse(stream_get_contents($output), 'participants.csv', 'text/csv');
}

/**
* Join a call
*
Expand Down
87 changes: 87 additions & 0 deletions openapi-full.json
Original file line number Diff line number Diff line change
Expand Up @@ -4544,6 +4544,93 @@
}
}
},
"/ocs/v2.php/apps/spreed/api/{apiVersion}/call/{token}/download": {
"get": {
"operationId": "call-download-participants-for-call",
"summary": "Download the list of current call participants",
"description": "Required capability: `download-call-participants`",
"tags": [
"call"
],
"security": [
{},
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "string",
"enum": [
"v4"
],
"default": "v4"
}
},
{
"name": "token",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-z0-9]{4,30}$"
}
},
{
"name": "format",
"in": "query",
"description": "Download format",
"schema": {
"type": "string",
"default": "csv",
"enum": [
"csv",
"pdf"
]
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "List of participants in the call downloaded in the requested format",
"content": {
"text/csv": {
"schema": {
"type": "string",
"format": "binary"
}
},
"application/pdf": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
},
"400": {
"description": "No call in progress"
}
}
}
},
"/ocs/v2.php/apps/spreed/api/{apiVersion}/call/{token}/federation": {
"post": {
"operationId": "call-join-federated-call",
Expand Down
87 changes: 87 additions & 0 deletions openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -4431,6 +4431,93 @@
}
}
},
"/ocs/v2.php/apps/spreed/api/{apiVersion}/call/{token}/download": {
"get": {
"operationId": "call-download-participants-for-call",
"summary": "Download the list of current call participants",
"description": "Required capability: `download-call-participants`",
"tags": [
"call"
],
"security": [
{},
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "string",
"enum": [
"v4"
],
"default": "v4"
}
},
{
"name": "token",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-z0-9]{4,30}$"
}
},
{
"name": "format",
"in": "query",
"description": "Download format",
"schema": {
"type": "string",
"default": "csv",
"enum": [
"csv",
"pdf"
]
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "List of participants in the call downloaded in the requested format",
"content": {
"text/csv": {
"schema": {
"type": "string",
"format": "binary"
}
},
"application/pdf": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
},
"400": {
"description": "No call in progress"
}
}
}
},
"/ocs/v2.php/apps/spreed/api/{apiVersion}/call/{token}/federation": {
"post": {
"operationId": "call-join-federated-call",
Expand Down
57 changes: 57 additions & 0 deletions src/types/openapi/openapi-full.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,26 @@ export type paths = {
patch?: never;
trace?: never;
};
"/ocs/v2.php/apps/spreed/api/{apiVersion}/call/{token}/download": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* Download the list of current call participants
* @description Required capability: `download-call-participants`
*/
get: operations["call-download-participants-for-call"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/ocs/v2.php/apps/spreed/api/{apiVersion}/call/{token}/federation": {
parameters: {
query?: never;
Expand Down Expand Up @@ -3443,6 +3463,43 @@ export interface operations {
};
};
};
"call-download-participants-for-call": {
parameters: {
query?: {
/** @description Download format */
format?: "csv" | "pdf";
};
header: {
/** @description Required to be true for the API request to pass */
"OCS-APIRequest": boolean;
};
path: {
apiVersion: "v4";
token: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description List of participants in the call downloaded in the requested format */
200: {
headers: {
[name: string]: unknown;
};
content: {
"text/csv": string;
"application/pdf": string;
};
};
/** @description No call in progress */
400: {
headers: {
[name: string]: unknown;
};
content?: never;
};
};
};
"call-update-federated-call-flags": {
parameters: {
query?: never;
Expand Down
Loading
Loading