fix(recording): store recordings and transcripts as the owning user - #19078
fix(recording): store recordings and transcripts as the owning user#19078bakiburakogun wants to merge 2 commits into
Conversation
The recording backend uploads the file through a public endpoint that is authenticated with the recording shared secret, so there is no active user while the file is written. The activity subsystem falls back to an empty actor and the Files activity stream ends up showing `"remote account" created Recording 2026-08-23 23-23-09.mp4` instead of the participant that started the recording. Set the owner as active user while the recording and the transcript or summary files are created and restore the previous user afterwards, so the file events are attributed to them. Signed-off-by: Baki Burak Öğün <burak@burakogun.com>
|
Deployed on the instance from the report (Nextcloud 34.0.3, Talk 24.0.4, nextcloud-talk-recording 0.2.1) and recorded a call with it. The activity entry for the new recording now reads |
The recording and transcript files are created with the owner as the active user, but the folder that holds them is created in getRecordingFolder() outside of that context. For the first recording of a conversation the folder therefore appears in the activity stream as created by "remote account", next to the file that is attributed correctly. Move the user switch into a small runAsUser() helper and use it for the folder lookup as well, so both the folder and the file are attributed to the owner. Signed-off-by: Baki Burak Öğün <burak@burakogun.com>
|
Pushed a follow-up commit. After running the first version on the instance from the report, the recordings themselves are attributed correctly, but the activity stream still shows an entry like for the first recording of a conversation. The reason is that The new commit moves the user switch into a small |
|
Verified on the instance from the report (Nextcloud 34.0.3, Talk 24.0.4, nextcloud-talk-recording 0.2.1, four signaling servers, seven application servers). Recorded a call in a conversation that had never been recorded before, so the per-conversation folder was created as part of storing the recording. The activity stream now attributes both the folder and the Recording, the "recording available" notification and sharing it into the chat behave as before. |
| } | ||
|
|
||
| $previousUser = $this->userSession->getUser(); | ||
| $this->userSession->setUser($user); |
There was a problem hiding this comment.
I'm not sure it's the best idea to overwrite the session user like this.
Also it's not going to work on the new chunked-uploading of recordings we implemented recently.
I think instead we need work in the activity app to allow defining different actors:
https://github.com/nextcloud/activity/blob/f95186c14cb89cb8e9f7f367e9ac394b2c398c50/lib/CurrentUser.php#L35
The activity manager has code for this already: https://github.com/nextcloud/server/blob/1ab09ec753f106661beadee1794b390ebec455dd/lib/private/Activity/Manager.php#L346-L354
but it's not used in the activity app itself. I think CurrentUser should first check IManager::getCurrentUserId() that would allow Talk to overwrite the user for the action
Fixes #19077
Summary
Call recordings are stored through
POST /ocs/v2.php/apps/spreed/api/v1/recording/{token}/store, which is a#[PublicPage]endpoint authenticated with the recording shared secret only. There is no active user during that request, so whenRecordingService::store()writes the file the activity subsystem cannot resolve an actor and falls back to an empty one. The Files activity provider renders that as"remote account", so users seeinstead of their own name, even though the file is in their own recording folder.
This sets the owner as active user while the file is created and restores the previous user afterwards, so the file events and the resulting activity are attributed to them. The same helper is used for the transcript and summary files written in
storeTranscript(), which have the same problem.Notes
ownerparameter that the recording backend sends is already validated instore()(getParticipant()throwsowner_participantfor an unknown owner), the helper additionally falls back to the previous behaviour if the user cannot be loaded.finallyblock, so a failing write cannot leak the session user into the rest of the request.Testing
Reproduced on Nextcloud 34.0.3 with Talk 24.0.4 and nextcloud-talk-recording 0.2.1 (four node signaling cluster). The patch is being rolled out on that instance now and I will confirm here once a recording has been stored with it.