mirror of
https://github.com/strukturag/nextcloud-spreed-signaling
synced 2026-03-14 14:35:44 +01:00
Convert actorId / actorType in participants updates for federated users.
See https://github.com/nextcloud/spreed/pull/12863 for details.
This commit is contained in:
parent
c83c42c8ff
commit
11a1f365d9
3 changed files with 86 additions and 10 deletions
|
|
@ -41,6 +41,9 @@ const (
|
|||
|
||||
// Version 2.0 validates auth params encoded as JWT.
|
||||
HelloVersionV2 = "2.0"
|
||||
|
||||
ActorTypeUsers = "users"
|
||||
ActorTypeFederatedUsers = "federated_users"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -52,6 +55,17 @@ func makePtr[T any](v T) *T {
|
|||
return &v
|
||||
}
|
||||
|
||||
func getStringMapEntry[T any](m map[string]interface{}, key string) (s T, ok bool) {
|
||||
var defaultValue T
|
||||
v, found := m[key]
|
||||
if !found {
|
||||
return defaultValue, false
|
||||
}
|
||||
|
||||
s, ok = v.(T)
|
||||
return
|
||||
}
|
||||
|
||||
// ClientMessage is a message that is sent from a client to the server.
|
||||
type ClientMessage struct {
|
||||
json.Marshaler
|
||||
|
|
|
|||
|
|
@ -55,6 +55,18 @@ func isClosedError(err error) bool {
|
|||
strings.Contains(err.Error(), net.ErrClosed.Error())
|
||||
}
|
||||
|
||||
func getCloudUrl(s string) string {
|
||||
if strings.HasPrefix(s, "https://") {
|
||||
s = s[8:]
|
||||
} else {
|
||||
s = strings.TrimPrefix(s, "http://")
|
||||
}
|
||||
if pos := strings.Index(s, "/ocs/v"); pos != -1 {
|
||||
s = s[:pos]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
type FederationClient struct {
|
||||
hub *Hub
|
||||
session *ClientSession
|
||||
|
|
@ -577,17 +589,36 @@ func (c *FederationClient) joinRoom() error {
|
|||
}
|
||||
|
||||
func (c *FederationClient) updateEventUsers(users []map[string]interface{}, localSessionId string, remoteSessionId string) {
|
||||
localCloudUrl := "@" + getCloudUrl(c.session.BackendUrl())
|
||||
localCloudUrlLen := len(localCloudUrl)
|
||||
remoteCloudUrl := "@" + getCloudUrl(c.federation.Load().NextcloudUrl)
|
||||
checkSessionId := true
|
||||
for _, u := range users {
|
||||
key := "sessionId"
|
||||
sid, found := u[key]
|
||||
if !found {
|
||||
key := "sessionid"
|
||||
sid, found = u[key]
|
||||
if actorType, found := getStringMapEntry[string](u, "actorType"); found {
|
||||
if actorId, found := getStringMapEntry[string](u, "actorId"); found {
|
||||
switch actorType {
|
||||
case ActorTypeFederatedUsers:
|
||||
if strings.HasSuffix(actorId, localCloudUrl) {
|
||||
u["actorId"] = actorId[:len(actorId)-localCloudUrlLen]
|
||||
u["actorType"] = ActorTypeUsers
|
||||
}
|
||||
case ActorTypeUsers:
|
||||
u["actorId"] = actorId + remoteCloudUrl
|
||||
u["actorType"] = ActorTypeFederatedUsers
|
||||
}
|
||||
}
|
||||
}
|
||||
if found {
|
||||
if sid, ok := sid.(string); ok && sid == remoteSessionId {
|
||||
|
||||
if checkSessionId {
|
||||
key := "sessionId"
|
||||
sid, found := getStringMapEntry[string](u, key)
|
||||
if !found {
|
||||
key := "sessionid"
|
||||
sid, found = getStringMapEntry[string](u, key)
|
||||
}
|
||||
if found && sid == remoteSessionId {
|
||||
u[key] = localSessionId
|
||||
break
|
||||
checkSessionId = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ package signaling
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
|
@ -286,23 +287,53 @@ func Test_Federation(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Simulate request from the backend that somebody joined the call.
|
||||
// Simulate request from the backend that a federated user joined the call.
|
||||
users := []map[string]interface{}{
|
||||
{
|
||||
"sessionId": remoteSessionId,
|
||||
"inCall": 1,
|
||||
"actorId": "remoteUser@" + strings.TrimPrefix(server2.URL, "http://"),
|
||||
"actorType": "federated_users",
|
||||
},
|
||||
}
|
||||
room := hub1.getRoom(roomId)
|
||||
require.NotNil(room)
|
||||
room.PublishUsersInCallChanged(users, users)
|
||||
var event *EventServerMessage
|
||||
// For the local user, it's a federated user on server 2 that joined.
|
||||
assert.NoError(checkReceiveClientEvent(ctx, client1, "update", &event))
|
||||
assert.Equal(remoteSessionId, event.Update.Users[0]["sessionId"])
|
||||
assert.Equal("remoteUser@"+strings.TrimPrefix(server2.URL, "http://"), event.Update.Users[0]["actorId"])
|
||||
assert.Equal("federated_users", event.Update.Users[0]["actorType"])
|
||||
assert.Equal(roomId, event.Update.RoomId)
|
||||
|
||||
// For the federated user, it's a local user that joined.
|
||||
assert.NoError(checkReceiveClientEvent(ctx, client2, "update", &event))
|
||||
assert.Equal(hello2.Hello.SessionId, event.Update.Users[0]["sessionId"])
|
||||
assert.Equal("remoteUser", event.Update.Users[0]["actorId"])
|
||||
assert.Equal("users", event.Update.Users[0]["actorType"])
|
||||
assert.Equal(federatedRoomId, event.Update.RoomId)
|
||||
|
||||
// Simulate request from the backend that a local user joined the call.
|
||||
users = []map[string]interface{}{
|
||||
{
|
||||
"sessionId": hello1.Hello.SessionId,
|
||||
"inCall": 1,
|
||||
"actorId": "localUser",
|
||||
"actorType": "users",
|
||||
},
|
||||
}
|
||||
room.PublishUsersInCallChanged(users, users)
|
||||
// For the local user, it's a local user that joined.
|
||||
assert.NoError(checkReceiveClientEvent(ctx, client1, "update", &event))
|
||||
assert.Equal(hello1.Hello.SessionId, event.Update.Users[0]["sessionId"])
|
||||
assert.Equal("localUser", event.Update.Users[0]["actorId"])
|
||||
assert.Equal("users", event.Update.Users[0]["actorType"])
|
||||
assert.Equal(roomId, event.Update.RoomId)
|
||||
// For the federated user, it's a federated user on server 1 that joined.
|
||||
assert.NoError(checkReceiveClientEvent(ctx, client2, "update", &event))
|
||||
assert.Equal(hello1.Hello.SessionId, event.Update.Users[0]["sessionId"])
|
||||
assert.Equal("localUser@"+strings.TrimPrefix(server1.URL, "http://"), event.Update.Users[0]["actorId"])
|
||||
assert.Equal("federated_users", event.Update.Users[0]["actorType"])
|
||||
assert.Equal(federatedRoomId, event.Update.RoomId)
|
||||
|
||||
// Joining another "direct" session will trigger correct events.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue