Skip to content

fix(recording): store recordings and transcripts as the owning user - #19078

Open
bakiburakogun wants to merge 2 commits into
nextcloud:mainfrom
bakiburakogun:fix/recording-file-owner-attribution
Open

fix(recording): store recordings and transcripts as the owning user#19078
bakiburakogun wants to merge 2 commits into
nextcloud:mainfrom
bakiburakogun:fix/recording-file-owner-attribution

Conversation

@bakiburakogun

Copy link
Copy Markdown

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 when RecordingService::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 see

"remote account" created Recording 2026-08-23 23-23-09.mp4

instead 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

  • The owner parameter that the recording backend sends is already validated in store() (getParticipant() throws owner_participant for an unknown owner), the helper additionally falls back to the previous behaviour if the user cannot be loaded.
  • The active user is restored in a finally block, so a failing write cannot leak the session user into the rest of the request.
  • Sharing the recording to the chat is unaffected, that path already posts with the participant actor.

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.

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>
@bakiburakogun

Copy link
Copy Markdown
Author

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 You created Recording 2026-08-24 00-02-34.mp4, while the recordings stored before the patch still show "remote account" created .... The file, the "recording available" notification and sharing it to the chat behave as before.

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>
@bakiburakogun

Copy link
Copy Markdown
Author

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

"remote account" created Recording 2026-08-24 13-55-16.mp4 and <conversation token>

for the first recording of a conversation. The reason is that getRecordingFolder() creates the attachment folder and the per-conversation folder with newFolder() outside of the user context that newFileAsUser() sets up, so the folder creation is still attributed to nobody.

The new commit moves the user switch into a small runAsUser() helper and uses it for the folder lookup as well, so the folder and the file end up with the same actor. No behaviour changes beyond the attribution.

@bakiburakogun

Copy link
Copy Markdown
Author

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 .mp4 to the user who started the recording. Before this commit the same case produced a single entry reading "remote account" created Recording ....mp4 and <conversation token>, with the file and the folder both unattributed.

Recording, the "recording available" notification and sharing it into the chat behave as before.

}

$previousUser = $this->userSession->getUser();
$this->userSession->setUser($user);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@nickvergessen nickvergessen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per comment

@nickvergessen nickvergessen added this to the ☃️ Next Major (36) milestone Aug 28, 2026
@nickvergessen nickvergessen added bug feature: api 🛠️ OCS API for conversations, chats and participants feature: recordings ⏺️ Including the recording server labels Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug feature: api 🛠️ OCS API for conversations, chats and participants feature: recordings ⏺️ Including the recording server

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Call recordings are attributed to "remote account" in the Files activity stream

2 participants