mirror of
https://github.com/strukturag/nextcloud-spreed-signaling
synced 2026-03-14 14:35:44 +01:00
Move Talk-specific API to "talk" package.
This commit is contained in:
parent
231f7c8af4
commit
fbf93dca42
34 changed files with 529 additions and 402 deletions
|
|
@ -83,6 +83,25 @@ func (s RoomSessionId) WithoutFederation() RoomSessionId {
|
|||
return RoomSessionId(strings.TrimPrefix(string(s), FederatedRoomSessionIdPrefix))
|
||||
}
|
||||
|
||||
type Permission string
|
||||
|
||||
var (
|
||||
PERMISSION_MAY_PUBLISH_MEDIA Permission = "publish-media"
|
||||
PERMISSION_MAY_PUBLISH_AUDIO Permission = "publish-audio"
|
||||
PERMISSION_MAY_PUBLISH_VIDEO Permission = "publish-video"
|
||||
PERMISSION_MAY_PUBLISH_SCREEN Permission = "publish-screen"
|
||||
PERMISSION_MAY_CONTROL Permission = "control"
|
||||
PERMISSION_TRANSIENT_DATA Permission = "transient-data"
|
||||
PERMISSION_HIDE_DISPLAYNAMES Permission = "hide-displaynames"
|
||||
|
||||
// DefaultPermissionOverrides contains permission overrides for users where
|
||||
// no permissions have been set by the server. If a permission is not set in
|
||||
// this map, it's assumed the user has that permission.
|
||||
DefaultPermissionOverrides = map[Permission]bool{ // +checklocksignore: Global readonly variable.
|
||||
PERMISSION_HIDE_DISPLAYNAMES: false,
|
||||
}
|
||||
)
|
||||
|
||||
// ClientMessage is a message that is sent from a client to the server.
|
||||
type ClientMessage struct {
|
||||
json.Marshaler
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/api"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/talk"
|
||||
)
|
||||
|
||||
type AsyncMessage struct {
|
||||
|
|
@ -36,9 +37,9 @@ type AsyncMessage struct {
|
|||
|
||||
Message *api.ServerMessage `json:"message,omitempty"`
|
||||
|
||||
Room *BackendServerRoomRequest `json:"room,omitempty"`
|
||||
Room *talk.BackendServerRoomRequest `json:"room,omitempty"`
|
||||
|
||||
Permissions []Permission `json:"permissions,omitempty"`
|
||||
Permissions []api.Permission `json:"permissions,omitempty"`
|
||||
|
||||
AsyncRoom *AsyncRoomMessage `json:"asyncroom,omitempty"`
|
||||
|
||||
|
|
|
|||
|
|
@ -91,12 +91,12 @@ func NewAsyncEventsNats(logger log.Logger, client nats.Client) (AsyncEvents, err
|
|||
return events, nil
|
||||
}
|
||||
|
||||
func (e *asyncEventsNats) GetServerInfoNats() *BackendServerInfoNats {
|
||||
func (e *asyncEventsNats) GetServerInfoNats() *talk.BackendServerInfoNats {
|
||||
// TODO: This should call a method on "e.client" directly instead of having a type switch.
|
||||
var result *BackendServerInfoNats
|
||||
var result *talk.BackendServerInfoNats
|
||||
switch n := e.client.(type) {
|
||||
case *nats.NativeClient:
|
||||
result = &BackendServerInfoNats{
|
||||
result = &talk.BackendServerInfoNats{
|
||||
Urls: n.URLs(),
|
||||
}
|
||||
if n.IsConnected() {
|
||||
|
|
@ -107,7 +107,7 @@ func (e *asyncEventsNats) GetServerInfoNats() *BackendServerInfoNats {
|
|||
result.ClusterName = n.ConnectedClusterName()
|
||||
}
|
||||
case *nats.LoopbackClient:
|
||||
result = &BackendServerInfoNats{
|
||||
result = &talk.BackendServerInfoNats{
|
||||
Urls: []string{nats.LoopbackUrl},
|
||||
Connected: true,
|
||||
ServerUrl: nats.LoopbackUrl,
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ func (b *BackendClient) PerformJSONRequest(ctx context.Context, u *url.URL, requ
|
|||
}
|
||||
|
||||
// Add checksum so the backend can validate the request.
|
||||
AddBackendChecksum(req, data.Bytes(), backend.Secret())
|
||||
talk.AddBackendChecksum(req, data.Bytes(), backend.Secret())
|
||||
|
||||
start := time.Now()
|
||||
resp, err := c.Do(req)
|
||||
|
|
|
|||
|
|
@ -264,11 +264,11 @@ func (b *BackendServer) getTurnCredentials(w http.ResponseWriter, r *http.Reques
|
|||
|
||||
if username == "" {
|
||||
// Make sure to include an actual username in the credentials.
|
||||
username = newRandomString(randomUsernameLength)
|
||||
username = internal.RandomString(randomUsernameLength)
|
||||
}
|
||||
|
||||
username, password := calculateTurnSecret(username, b.turnsecret, b.turnvalid)
|
||||
result := TurnCredentials{
|
||||
result := talk.TurnCredentials{
|
||||
Username: username,
|
||||
Password: password,
|
||||
TTL: int64(b.turnvalid.Seconds()),
|
||||
|
|
@ -309,8 +309,8 @@ func (b *BackendServer) parseRequestBody(f func(context.Context, http.ResponseWr
|
|||
return
|
||||
}
|
||||
|
||||
if r.Header.Get(HeaderBackendSignalingRandom) == "" ||
|
||||
r.Header.Get(HeaderBackendSignalingChecksum) == "" {
|
||||
if r.Header.Get(talk.HeaderBackendSignalingRandom) == "" ||
|
||||
r.Header.Get(talk.HeaderBackendSignalingChecksum) == "" {
|
||||
http.Error(w, "Authentication check failed", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
|
@ -500,7 +500,7 @@ func (b *BackendServer) fixupUserSessions(ctx context.Context, cache *container.
|
|||
return result
|
||||
}
|
||||
|
||||
func (b *BackendServer) sendRoomIncall(roomid string, backend *talk.Backend, request *BackendServerRoomRequest) error {
|
||||
func (b *BackendServer) sendRoomIncall(roomid string, backend *talk.Backend, request *talk.BackendServerRoomRequest) error {
|
||||
if !request.InCall.All {
|
||||
timeout := time.Second
|
||||
|
||||
|
|
@ -525,7 +525,7 @@ func (b *BackendServer) sendRoomIncall(roomid string, backend *talk.Backend, req
|
|||
return b.events.PublishBackendRoomMessage(roomid, backend, message)
|
||||
}
|
||||
|
||||
func (b *BackendServer) sendRoomParticipantsUpdate(ctx context.Context, roomid string, backend *talk.Backend, request *BackendServerRoomRequest) error {
|
||||
func (b *BackendServer) sendRoomParticipantsUpdate(ctx context.Context, roomid string, backend *talk.Backend, request *talk.BackendServerRoomRequest) error {
|
||||
timeout := time.Second
|
||||
|
||||
// Convert (Nextcloud) session ids to signaling session ids.
|
||||
|
|
@ -558,18 +558,18 @@ loop:
|
|||
b.logger.Printf("Received invalid permissions %+v (%s) for session %s", permissionsInterface, reflect.TypeOf(permissionsInterface), sessionId)
|
||||
continue
|
||||
}
|
||||
var permissions []Permission
|
||||
var permissions []api.Permission
|
||||
for idx, ob := range permissionsList {
|
||||
permission, ok := ob.(string)
|
||||
if !ok {
|
||||
b.logger.Printf("Received invalid permission at position %d %+v (%s) for session %s", idx, ob, reflect.TypeOf(ob), sessionId)
|
||||
continue loop
|
||||
}
|
||||
permissions = append(permissions, Permission(permission))
|
||||
permissions = append(permissions, api.Permission(permission))
|
||||
}
|
||||
wg.Add(1)
|
||||
|
||||
go func(sessionId api.PublicSessionId, permissions []Permission) {
|
||||
go func(sessionId api.PublicSessionId, permissions []api.Permission) {
|
||||
defer wg.Done()
|
||||
message := &AsyncMessage{
|
||||
Type: "permissions",
|
||||
|
|
@ -589,7 +589,7 @@ loop:
|
|||
return b.events.PublishBackendRoomMessage(roomid, backend, message)
|
||||
}
|
||||
|
||||
func (b *BackendServer) sendRoomMessage(roomid string, backend *talk.Backend, request *BackendServerRoomRequest) error {
|
||||
func (b *BackendServer) sendRoomMessage(roomid string, backend *talk.Backend, request *talk.BackendServerRoomRequest) error {
|
||||
message := &AsyncMessage{
|
||||
Type: "room",
|
||||
Room: request,
|
||||
|
|
@ -597,7 +597,7 @@ func (b *BackendServer) sendRoomMessage(roomid string, backend *talk.Backend, re
|
|||
return b.events.PublishBackendRoomMessage(roomid, backend, message)
|
||||
}
|
||||
|
||||
func (b *BackendServer) sendRoomSwitchTo(ctx context.Context, roomid string, backend *talk.Backend, request *BackendServerRoomRequest) error {
|
||||
func (b *BackendServer) sendRoomSwitchTo(ctx context.Context, roomid string, backend *talk.Backend, request *talk.BackendServerRoomRequest) error {
|
||||
timeout := time.Second
|
||||
|
||||
// Convert (Nextcloud) session ids to signaling session ids.
|
||||
|
|
@ -609,7 +609,7 @@ func (b *BackendServer) sendRoomSwitchTo(ctx context.Context, roomid string, bac
|
|||
if len(request.SwitchTo.Sessions) > 0 {
|
||||
// We support both a list of sessions or a map with additional details per session.
|
||||
if request.SwitchTo.Sessions[0] == '[' {
|
||||
var sessionsList BackendRoomSwitchToSessionsList
|
||||
var sessionsList talk.BackendRoomSwitchToSessionsList
|
||||
if err := json.Unmarshal(request.SwitchTo.Sessions, &sessionsList); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -618,7 +618,7 @@ func (b *BackendServer) sendRoomSwitchTo(ctx context.Context, roomid string, bac
|
|||
return nil
|
||||
}
|
||||
|
||||
var internalSessionsList BackendRoomSwitchToPublicSessionsList
|
||||
var internalSessionsList talk.BackendRoomSwitchToPublicSessionsList
|
||||
for _, roomSessionId := range sessionsList {
|
||||
if roomSessionId == sessionIdNotInMeeting {
|
||||
continue
|
||||
|
|
@ -647,7 +647,7 @@ func (b *BackendServer) sendRoomSwitchTo(ctx context.Context, roomid string, bac
|
|||
request.SwitchTo.SessionsList = internalSessionsList
|
||||
request.SwitchTo.SessionsMap = nil
|
||||
} else {
|
||||
var sessionsMap BackendRoomSwitchToSessionsMap
|
||||
var sessionsMap talk.BackendRoomSwitchToSessionsMap
|
||||
if err := json.Unmarshal(request.SwitchTo.Sessions, &sessionsMap); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -656,7 +656,7 @@ func (b *BackendServer) sendRoomSwitchTo(ctx context.Context, roomid string, bac
|
|||
return nil
|
||||
}
|
||||
|
||||
internalSessionsMap := make(BackendRoomSwitchToPublicSessionsMap)
|
||||
internalSessionsMap := make(talk.BackendRoomSwitchToPublicSessionsMap)
|
||||
for roomSessionId, details := range sessionsMap {
|
||||
if roomSessionId == sessionIdNotInMeeting {
|
||||
continue
|
||||
|
|
@ -700,7 +700,7 @@ type BackendResponseWithStatus interface {
|
|||
}
|
||||
|
||||
type DialoutErrorResponse struct {
|
||||
BackendServerRoomResponse
|
||||
talk.BackendServerRoomResponse
|
||||
|
||||
status int
|
||||
}
|
||||
|
|
@ -711,9 +711,9 @@ func (r *DialoutErrorResponse) Status() int {
|
|||
|
||||
func returnDialoutError(status int, err *api.Error) (any, error) {
|
||||
response := &DialoutErrorResponse{
|
||||
BackendServerRoomResponse: BackendServerRoomResponse{
|
||||
BackendServerRoomResponse: talk.BackendServerRoomResponse{
|
||||
Type: "dialout",
|
||||
Dialout: &BackendRoomDialoutResponse{
|
||||
Dialout: &talk.BackendRoomDialoutResponse{
|
||||
Error: err,
|
||||
},
|
||||
},
|
||||
|
|
@ -729,7 +729,7 @@ func isNumeric(s string) bool {
|
|||
return checkNumeric.MatchString(s)
|
||||
}
|
||||
|
||||
func (b *BackendServer) startDialoutInSession(ctx context.Context, session *ClientSession, roomid string, backend *talk.Backend, backendUrl string, request *BackendServerRoomRequest) (any, error) {
|
||||
func (b *BackendServer) startDialoutInSession(ctx context.Context, session *ClientSession, roomid string, backend *talk.Backend, backendUrl string, request *talk.BackendServerRoomRequest) (any, error) {
|
||||
url := backendUrl
|
||||
if url != "" && url[len(url)-1] != '/' {
|
||||
url += "/"
|
||||
|
|
@ -742,7 +742,7 @@ func (b *BackendServer) startDialoutInSession(ctx context.Context, session *Clie
|
|||
url = urls[0]
|
||||
}
|
||||
}
|
||||
id := newRandomString(32)
|
||||
id := internal.RandomString(32)
|
||||
msg := &api.ServerMessage{
|
||||
Id: id,
|
||||
Type: "internal",
|
||||
|
|
@ -799,9 +799,9 @@ func (b *BackendServer) startDialoutInSession(ctx context.Context, session *Clie
|
|||
return nil, api.NewError("unsupported_status", fmt.Sprintf("Unsupported dialout status received: %+v", dialout))
|
||||
}
|
||||
|
||||
return &BackendServerRoomResponse{
|
||||
return &talk.BackendServerRoomResponse{
|
||||
Type: "dialout",
|
||||
Dialout: &BackendRoomDialoutResponse{
|
||||
Dialout: &talk.BackendRoomDialoutResponse{
|
||||
CallId: dialout.Status.CallId,
|
||||
},
|
||||
}, nil
|
||||
|
|
@ -810,7 +810,7 @@ func (b *BackendServer) startDialoutInSession(ctx context.Context, session *Clie
|
|||
}
|
||||
}
|
||||
|
||||
func (b *BackendServer) startDialout(ctx context.Context, roomid string, backend *talk.Backend, backendUrl string, request *BackendServerRoomRequest) (any, error) {
|
||||
func (b *BackendServer) startDialout(ctx context.Context, roomid string, backend *talk.Backend, backendUrl string, request *talk.BackendServerRoomRequest) (any, error) {
|
||||
if err := request.Dialout.ValidateNumber(); err != nil {
|
||||
return returnDialoutError(http.StatusBadRequest, err)
|
||||
}
|
||||
|
|
@ -862,7 +862,7 @@ func (b *BackendServer) roomHandler(ctx context.Context, w http.ResponseWriter,
|
|||
roomid := v["roomid"]
|
||||
|
||||
var backend *talk.Backend
|
||||
backendUrl := r.Header.Get(HeaderBackendServer)
|
||||
backendUrl := r.Header.Get(talk.HeaderBackendServer)
|
||||
if backendUrl != "" {
|
||||
if u, err := url.Parse(backendUrl); err == nil {
|
||||
backend = b.hub.backend.GetBackend(u)
|
||||
|
|
@ -884,7 +884,7 @@ func (b *BackendServer) roomHandler(ctx context.Context, w http.ResponseWriter,
|
|||
// Old-style Talk, find backend that created the checksum.
|
||||
// TODO(fancycode): Remove once all supported Talk versions send the backend header.
|
||||
for _, b := range b.hub.backend.GetBackends() {
|
||||
if ValidateBackendChecksum(r, body, b.Secret()) {
|
||||
if talk.ValidateBackendChecksum(r, body, b.Secret()) {
|
||||
backend = b
|
||||
break
|
||||
}
|
||||
|
|
@ -898,13 +898,13 @@ func (b *BackendServer) roomHandler(ctx context.Context, w http.ResponseWriter,
|
|||
}
|
||||
}
|
||||
|
||||
if !ValidateBackendChecksum(r, body, backend.Secret()) {
|
||||
if !talk.ValidateBackendChecksum(r, body, backend.Secret()) {
|
||||
throttle(ctx)
|
||||
http.Error(w, "Authentication check failed", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
var request BackendServerRoomRequest
|
||||
var request talk.BackendServerRoomRequest
|
||||
if err := json.Unmarshal(body, &request); err != nil {
|
||||
b.logger.Printf("Error decoding body %s: %s", string(body), err)
|
||||
http.Error(w, "Could not read body", http.StatusBadRequest)
|
||||
|
|
@ -1017,7 +1017,7 @@ func (b *BackendServer) statsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func (b *BackendServer) serverinfoHandler(w http.ResponseWriter, r *http.Request) {
|
||||
info := BackendServerInfo{
|
||||
info := talk.BackendServerInfo{
|
||||
Version: b.version,
|
||||
Features: b.hub.info.Features,
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,10 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/api"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/nats"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/talk"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -229,8 +231,8 @@ func performBackendRequest(requestUrl string, body []byte) (*http.Response, erro
|
|||
return nil, err
|
||||
}
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
rnd := newRandomString(32)
|
||||
check := CalculateBackendChecksum(rnd, body, testBackendSecret)
|
||||
rnd := internal.RandomString(32)
|
||||
check := talk.CalculateBackendChecksum(rnd, body, testBackendSecret)
|
||||
request.Header.Set("Spreed-Signaling-Random", rnd)
|
||||
request.Header.Set("Spreed-Signaling-Checksum", check)
|
||||
u, err := url.Parse(requestUrl)
|
||||
|
|
@ -323,9 +325,9 @@ func TestBackendServer_OldCompatAuth(t *testing.T) {
|
|||
roomId := "the-room-id"
|
||||
userid := "the-user-id"
|
||||
roomProperties := json.RawMessage("{\"foo\":\"bar\"}")
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "invite",
|
||||
Invite: &BackendRoomInviteRequest{
|
||||
Invite: &talk.BackendRoomInviteRequest{
|
||||
UserIds: []string{
|
||||
userid,
|
||||
},
|
||||
|
|
@ -342,8 +344,8 @@ func TestBackendServer_OldCompatAuth(t *testing.T) {
|
|||
request, err := http.NewRequest("POST", server.URL+"/api/v1/room/"+roomId, bytes.NewReader(data))
|
||||
require.NoError(err)
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
rnd := newRandomString(32)
|
||||
check := CalculateBackendChecksum(rnd, data, testBackendSecret)
|
||||
rnd := internal.RandomString(32)
|
||||
check := talk.CalculateBackendChecksum(rnd, data, testBackendSecret)
|
||||
request.Header.Set("Spreed-Signaling-Random", rnd)
|
||||
request.Header.Set("Spreed-Signaling-Checksum", check)
|
||||
client := &http.Client{}
|
||||
|
|
@ -378,7 +380,7 @@ func TestBackendServer_UnsupportedRequest(t *testing.T) {
|
|||
assert := assert.New(t)
|
||||
_, _, _, _, _, server := CreateBackendServerForTest(t)
|
||||
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "lala",
|
||||
}
|
||||
|
||||
|
|
@ -433,9 +435,9 @@ func RunTestBackendServer_RoomInvite(ctx context.Context, t *testing.T) {
|
|||
defer func() {
|
||||
assert.NoError(events.UnregisterUserListener(userid, backend, listener))
|
||||
}()
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "invite",
|
||||
Invite: &BackendRoomInviteRequest{
|
||||
Invite: &talk.BackendRoomInviteRequest{
|
||||
UserIds: []string{
|
||||
userid,
|
||||
},
|
||||
|
|
@ -509,9 +511,9 @@ func RunTestBackendServer_RoomDisinvite(ctx context.Context, t *testing.T) {
|
|||
defer func() {
|
||||
assert.NoError(events.UnregisterUserListener(testDefaultUserId, backend, listener))
|
||||
}()
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "disinvite",
|
||||
Disinvite: &BackendRoomDisinviteRequest{
|
||||
Disinvite: &talk.BackendRoomDisinviteRequest{
|
||||
UserIds: []string{
|
||||
testDefaultUserId,
|
||||
},
|
||||
|
|
@ -569,9 +571,9 @@ func TestBackendServer_RoomDisinviteDifferentRooms(t *testing.T) {
|
|||
MustSucceed2(t, client2.JoinRoom, ctx, roomId2)
|
||||
require.True(client2.RunUntilJoined(ctx, hello2.Hello))
|
||||
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "disinvite",
|
||||
Disinvite: &BackendRoomDisinviteRequest{
|
||||
Disinvite: &talk.BackendRoomDisinviteRequest{
|
||||
UserIds: []string{
|
||||
testDefaultUserId,
|
||||
},
|
||||
|
|
@ -601,9 +603,9 @@ func TestBackendServer_RoomDisinviteDifferentRooms(t *testing.T) {
|
|||
assert.Equal(roomId1, message.RoomId)
|
||||
}
|
||||
|
||||
msg = &BackendServerRoomRequest{
|
||||
msg = &talk.BackendServerRoomRequest{
|
||||
Type: "update",
|
||||
Update: &BackendRoomUpdateRequest{
|
||||
Update: &talk.BackendRoomUpdateRequest{
|
||||
UserIds: []string{
|
||||
testDefaultUserId,
|
||||
},
|
||||
|
|
@ -664,9 +666,9 @@ func RunTestBackendServer_RoomUpdate(ctx context.Context, t *testing.T) {
|
|||
defer func() {
|
||||
assert.NoError(events.UnregisterUserListener(userid, backend, listener))
|
||||
}()
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "update",
|
||||
Update: &BackendRoomUpdateRequest{
|
||||
Update: &talk.BackendRoomUpdateRequest{
|
||||
UserIds: []string{
|
||||
userid,
|
||||
},
|
||||
|
|
@ -732,9 +734,9 @@ func RunTestBackendServer_RoomDelete(ctx context.Context, t *testing.T) {
|
|||
defer func() {
|
||||
assert.NoError(events.UnregisterUserListener(userid, backend, listener))
|
||||
}()
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "delete",
|
||||
Delete: &BackendRoomDeleteRequest{
|
||||
Delete: &talk.BackendRoomDeleteRequest{
|
||||
UserIds: []string{
|
||||
userid,
|
||||
},
|
||||
|
|
@ -801,10 +803,10 @@ func TestBackendServer_ParticipantsUpdatePermissions(t *testing.T) {
|
|||
require.NotNil(session2, "Session %s does not exist", hello2.Hello.SessionId)
|
||||
|
||||
// Sessions have all permissions initially (fallback for old-style sessions).
|
||||
assertSessionHasPermission(t, session1, PERMISSION_MAY_PUBLISH_MEDIA)
|
||||
assertSessionHasPermission(t, session1, PERMISSION_MAY_PUBLISH_SCREEN)
|
||||
assertSessionHasPermission(t, session2, PERMISSION_MAY_PUBLISH_MEDIA)
|
||||
assertSessionHasPermission(t, session2, PERMISSION_MAY_PUBLISH_SCREEN)
|
||||
assertSessionHasPermission(t, session1, api.PERMISSION_MAY_PUBLISH_MEDIA)
|
||||
assertSessionHasPermission(t, session1, api.PERMISSION_MAY_PUBLISH_SCREEN)
|
||||
assertSessionHasPermission(t, session2, api.PERMISSION_MAY_PUBLISH_MEDIA)
|
||||
assertSessionHasPermission(t, session2, api.PERMISSION_MAY_PUBLISH_SCREEN)
|
||||
|
||||
// Join room by id.
|
||||
roomId := "test-room"
|
||||
|
|
@ -817,27 +819,27 @@ func TestBackendServer_ParticipantsUpdatePermissions(t *testing.T) {
|
|||
assert.NoError(client1.DrainMessages(ctx))
|
||||
assert.NoError(client2.DrainMessages(ctx))
|
||||
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "participants",
|
||||
Participants: &BackendRoomParticipantsRequest{
|
||||
Participants: &talk.BackendRoomParticipantsRequest{
|
||||
Changed: []api.StringMap{
|
||||
{
|
||||
"sessionId": fmt.Sprintf("%s-%s", roomId, hello1.Hello.SessionId),
|
||||
"permissions": []Permission{PERMISSION_MAY_PUBLISH_MEDIA},
|
||||
"permissions": []api.Permission{api.PERMISSION_MAY_PUBLISH_MEDIA},
|
||||
},
|
||||
{
|
||||
"sessionId": fmt.Sprintf("%s-%s", roomId, hello2.Hello.SessionId),
|
||||
"permissions": []Permission{PERMISSION_MAY_PUBLISH_SCREEN},
|
||||
"permissions": []api.Permission{api.PERMISSION_MAY_PUBLISH_SCREEN},
|
||||
},
|
||||
},
|
||||
Users: []api.StringMap{
|
||||
{
|
||||
"sessionId": fmt.Sprintf("%s-%s", roomId, hello1.Hello.SessionId),
|
||||
"permissions": []Permission{PERMISSION_MAY_PUBLISH_MEDIA},
|
||||
"permissions": []api.Permission{api.PERMISSION_MAY_PUBLISH_MEDIA},
|
||||
},
|
||||
{
|
||||
"sessionId": fmt.Sprintf("%s-%s", roomId, hello2.Hello.SessionId),
|
||||
"permissions": []Permission{PERMISSION_MAY_PUBLISH_SCREEN},
|
||||
"permissions": []api.Permission{api.PERMISSION_MAY_PUBLISH_SCREEN},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -856,10 +858,10 @@ func TestBackendServer_ParticipantsUpdatePermissions(t *testing.T) {
|
|||
// TODO: Use event to wait for asynchronous messages.
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
assertSessionHasPermission(t, session1, PERMISSION_MAY_PUBLISH_MEDIA)
|
||||
assertSessionHasNotPermission(t, session1, PERMISSION_MAY_PUBLISH_SCREEN)
|
||||
assertSessionHasNotPermission(t, session2, PERMISSION_MAY_PUBLISH_MEDIA)
|
||||
assertSessionHasPermission(t, session2, PERMISSION_MAY_PUBLISH_SCREEN)
|
||||
assertSessionHasPermission(t, session1, api.PERMISSION_MAY_PUBLISH_MEDIA)
|
||||
assertSessionHasNotPermission(t, session1, api.PERMISSION_MAY_PUBLISH_SCREEN)
|
||||
assertSessionHasNotPermission(t, session2, api.PERMISSION_MAY_PUBLISH_MEDIA)
|
||||
assertSessionHasPermission(t, session2, api.PERMISSION_MAY_PUBLISH_SCREEN)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -882,8 +884,8 @@ func TestBackendServer_ParticipantsUpdateEmptyPermissions(t *testing.T) {
|
|||
assert.NotNil(session, "Session %s does not exist", hello.Hello.SessionId)
|
||||
|
||||
// Sessions have all permissions initially (fallback for old-style sessions).
|
||||
assertSessionHasPermission(t, session, PERMISSION_MAY_PUBLISH_MEDIA)
|
||||
assertSessionHasPermission(t, session, PERMISSION_MAY_PUBLISH_SCREEN)
|
||||
assertSessionHasPermission(t, session, api.PERMISSION_MAY_PUBLISH_MEDIA)
|
||||
assertSessionHasPermission(t, session, api.PERMISSION_MAY_PUBLISH_SCREEN)
|
||||
|
||||
// Join room by id.
|
||||
roomId := "test-room"
|
||||
|
|
@ -895,19 +897,19 @@ func TestBackendServer_ParticipantsUpdateEmptyPermissions(t *testing.T) {
|
|||
|
||||
// Updating with empty permissions upgrades to non-old-style and removes
|
||||
// all previously available permissions.
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "participants",
|
||||
Participants: &BackendRoomParticipantsRequest{
|
||||
Participants: &talk.BackendRoomParticipantsRequest{
|
||||
Changed: []api.StringMap{
|
||||
{
|
||||
"sessionId": fmt.Sprintf("%s-%s", roomId, hello.Hello.SessionId),
|
||||
"permissions": []Permission{},
|
||||
"permissions": []api.Permission{},
|
||||
},
|
||||
},
|
||||
Users: []api.StringMap{
|
||||
{
|
||||
"sessionId": fmt.Sprintf("%s-%s", roomId, hello.Hello.SessionId),
|
||||
"permissions": []Permission{},
|
||||
"permissions": []api.Permission{},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -925,8 +927,8 @@ func TestBackendServer_ParticipantsUpdateEmptyPermissions(t *testing.T) {
|
|||
// TODO: Use event to wait for asynchronous messages.
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
assertSessionHasNotPermission(t, session, PERMISSION_MAY_PUBLISH_MEDIA)
|
||||
assertSessionHasNotPermission(t, session, PERMISSION_MAY_PUBLISH_SCREEN)
|
||||
assertSessionHasNotPermission(t, session, api.PERMISSION_MAY_PUBLISH_MEDIA)
|
||||
assertSessionHasNotPermission(t, session, api.PERMISSION_MAY_PUBLISH_SCREEN)
|
||||
}
|
||||
|
||||
func TestBackendServer_ParticipantsUpdateTimeout(t *testing.T) {
|
||||
|
|
@ -963,9 +965,9 @@ func TestBackendServer_ParticipantsUpdateTimeout(t *testing.T) {
|
|||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "incall",
|
||||
InCall: &BackendRoomInCallRequest{
|
||||
InCall: &talk.BackendRoomInCallRequest{
|
||||
InCall: json.RawMessage("7"),
|
||||
Changed: []api.StringMap{
|
||||
{
|
||||
|
|
@ -1010,9 +1012,9 @@ func TestBackendServer_ParticipantsUpdateTimeout(t *testing.T) {
|
|||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "incall",
|
||||
InCall: &BackendRoomInCallRequest{
|
||||
InCall: &talk.BackendRoomInCallRequest{
|
||||
InCall: json.RawMessage("7"),
|
||||
Changed: []api.StringMap{
|
||||
{
|
||||
|
|
@ -1150,9 +1152,9 @@ func TestBackendServer_InCallAll(t *testing.T) {
|
|||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "incall",
|
||||
InCall: &BackendRoomInCallRequest{
|
||||
InCall: &talk.BackendRoomInCallRequest{
|
||||
InCall: json.RawMessage("7"),
|
||||
All: true,
|
||||
},
|
||||
|
|
@ -1207,9 +1209,9 @@ func TestBackendServer_InCallAll(t *testing.T) {
|
|||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "incall",
|
||||
InCall: &BackendRoomInCallRequest{
|
||||
InCall: &talk.BackendRoomInCallRequest{
|
||||
InCall: json.RawMessage("0"),
|
||||
All: true,
|
||||
},
|
||||
|
|
@ -1287,9 +1289,9 @@ func TestBackendServer_RoomMessage(t *testing.T) {
|
|||
assert.NoError(client.DrainMessages(ctx))
|
||||
|
||||
messageData := json.RawMessage("{\"foo\":\"bar\"}")
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "message",
|
||||
Message: &BackendRoomMessageRequest{
|
||||
Message: &talk.BackendRoomMessageRequest{
|
||||
Data: messageData,
|
||||
},
|
||||
}
|
||||
|
|
@ -1328,7 +1330,7 @@ func TestBackendServer_TurnCredentials(t *testing.T) {
|
|||
assert.NoError(err)
|
||||
assert.Equal(http.StatusOK, res.StatusCode, "Expected successful request, got %s", string(body))
|
||||
|
||||
var cred TurnCredentials
|
||||
var cred talk.TurnCredentials
|
||||
require.NoError(json.Unmarshal(body, &cred))
|
||||
|
||||
m := hmac.New(sha1.New, []byte(turnSecret))
|
||||
|
|
@ -1452,9 +1454,9 @@ func TestBackendServer_DialoutNoSipBridge(t *testing.T) {
|
|||
MustSucceed1(t, client.RunUntilHello, ctx)
|
||||
|
||||
roomId := "12345"
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "dialout",
|
||||
Dialout: &BackendRoomDialoutRequest{
|
||||
Dialout: &talk.BackendRoomDialoutRequest{
|
||||
Number: "+1234567890",
|
||||
},
|
||||
}
|
||||
|
|
@ -1468,7 +1470,7 @@ func TestBackendServer_DialoutNoSipBridge(t *testing.T) {
|
|||
assert.NoError(err)
|
||||
require.Equal(http.StatusNotFound, res.StatusCode, "Expected error, got %s", string(body))
|
||||
|
||||
var response BackendServerRoomResponse
|
||||
var response talk.BackendServerRoomResponse
|
||||
if assert.NoError(json.Unmarshal(body, &response)) {
|
||||
assert.Equal("dialout", response.Type)
|
||||
if assert.NotNil(response.Dialout) &&
|
||||
|
|
@ -1539,9 +1541,9 @@ func TestBackendServer_DialoutAccepted(t *testing.T) {
|
|||
<-stopped
|
||||
}()
|
||||
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "dialout",
|
||||
Dialout: &BackendRoomDialoutRequest{
|
||||
Dialout: &talk.BackendRoomDialoutRequest{
|
||||
Number: "+1234567890",
|
||||
},
|
||||
}
|
||||
|
|
@ -1555,7 +1557,7 @@ func TestBackendServer_DialoutAccepted(t *testing.T) {
|
|||
assert.NoError(err)
|
||||
require.Equal(http.StatusOK, res.StatusCode, "Expected success, got %s", string(body))
|
||||
|
||||
var response BackendServerRoomResponse
|
||||
var response talk.BackendServerRoomResponse
|
||||
if err := json.Unmarshal(body, &response); assert.NoError(err) {
|
||||
assert.Equal("dialout", response.Type)
|
||||
if assert.NotNil(response.Dialout) {
|
||||
|
|
@ -1626,9 +1628,9 @@ func TestBackendServer_DialoutAcceptedCompat(t *testing.T) {
|
|||
<-stopped
|
||||
}()
|
||||
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "dialout",
|
||||
Dialout: &BackendRoomDialoutRequest{
|
||||
Dialout: &talk.BackendRoomDialoutRequest{
|
||||
Number: "+1234567890",
|
||||
},
|
||||
}
|
||||
|
|
@ -1642,7 +1644,7 @@ func TestBackendServer_DialoutAcceptedCompat(t *testing.T) {
|
|||
assert.NoError(err)
|
||||
require.Equal(http.StatusOK, res.StatusCode, "Expected success, got %s", string(body))
|
||||
|
||||
var response BackendServerRoomResponse
|
||||
var response talk.BackendServerRoomResponse
|
||||
if err := json.Unmarshal(body, &response); assert.NoError(err) {
|
||||
assert.Equal("dialout", response.Type)
|
||||
if assert.NotNil(response.Dialout) {
|
||||
|
|
@ -1710,9 +1712,9 @@ func TestBackendServer_DialoutRejected(t *testing.T) {
|
|||
<-stopped
|
||||
}()
|
||||
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "dialout",
|
||||
Dialout: &BackendRoomDialoutRequest{
|
||||
Dialout: &talk.BackendRoomDialoutRequest{
|
||||
Number: "+1234567890",
|
||||
},
|
||||
}
|
||||
|
|
@ -1726,7 +1728,7 @@ func TestBackendServer_DialoutRejected(t *testing.T) {
|
|||
assert.NoError(err)
|
||||
require.Equal(http.StatusBadGateway, res.StatusCode, "Expected error, got %s", string(body))
|
||||
|
||||
var response BackendServerRoomResponse
|
||||
var response talk.BackendServerRoomResponse
|
||||
if err := json.Unmarshal(body, &response); assert.NoError(err) {
|
||||
assert.Equal("dialout", response.Type)
|
||||
if assert.NotNil(response.Dialout) &&
|
||||
|
|
@ -1824,9 +1826,9 @@ func TestBackendServer_DialoutFirstFailed(t *testing.T) {
|
|||
wg.Wait()
|
||||
}()
|
||||
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "dialout",
|
||||
Dialout: &BackendRoomDialoutRequest{
|
||||
Dialout: &talk.BackendRoomDialoutRequest{
|
||||
Number: "+1234567890",
|
||||
},
|
||||
}
|
||||
|
|
@ -1840,7 +1842,7 @@ func TestBackendServer_DialoutFirstFailed(t *testing.T) {
|
|||
assert.NoError(err)
|
||||
require.Equal(http.StatusOK, res.StatusCode, "Expected success, got %s", string(body))
|
||||
|
||||
var response BackendServerRoomResponse
|
||||
var response talk.BackendServerRoomResponse
|
||||
if err := json.Unmarshal(body, &response); assert.NoError(err) {
|
||||
assert.Equal("dialout", response.Type)
|
||||
if assert.NotNil(response.Dialout) {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ import (
|
|||
"github.com/mailru/easyjson/jlexer"
|
||||
"github.com/mailru/easyjson/jwriter"
|
||||
|
||||
signaling "github.com/strukturag/nextcloud-spreed-signaling"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/api"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/config"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
|
|
@ -428,28 +427,28 @@ func registerAuthHandler(router *mux.Router) {
|
|||
return
|
||||
}
|
||||
|
||||
rnd := r.Header.Get(signaling.HeaderBackendSignalingRandom)
|
||||
checksum := r.Header.Get(signaling.HeaderBackendSignalingChecksum)
|
||||
rnd := r.Header.Get(talk.HeaderBackendSignalingRandom)
|
||||
checksum := r.Header.Get(talk.HeaderBackendSignalingChecksum)
|
||||
if rnd == "" || checksum == "" {
|
||||
log.Println("No checksum headers found")
|
||||
return
|
||||
}
|
||||
|
||||
if verify := signaling.CalculateBackendChecksum(rnd, body, backendSecret); verify != checksum {
|
||||
if verify := talk.CalculateBackendChecksum(rnd, body, backendSecret); verify != checksum {
|
||||
log.Println("Backend checksum verification failed")
|
||||
return
|
||||
}
|
||||
|
||||
var request signaling.BackendClientRequest
|
||||
var request talk.BackendClientRequest
|
||||
if err := request.UnmarshalJSON(body); err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
response := &signaling.BackendClientResponse{
|
||||
response := &talk.BackendClientResponse{
|
||||
Type: "auth",
|
||||
Auth: &signaling.BackendClientAuthResponse{
|
||||
Version: signaling.BackendVersion,
|
||||
Auth: &talk.BackendClientAuthResponse{
|
||||
Version: talk.BackendVersion,
|
||||
UserId: "sample-user",
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ type ClientSession struct {
|
|||
// +checklocks:mu
|
||||
supportsPermissions bool
|
||||
// +checklocks:mu
|
||||
permissions map[Permission]bool
|
||||
permissions map[api.Permission]bool
|
||||
|
||||
backend *talk.Backend
|
||||
backendUrl string
|
||||
|
|
@ -120,7 +120,7 @@ type ClientSession struct {
|
|||
responseHandlers map[string]ResponseHandlerFunc
|
||||
}
|
||||
|
||||
func NewClientSession(hub *Hub, privateId api.PrivateSessionId, publicId api.PublicSessionId, data *SessionIdData, backend *talk.Backend, hello *api.HelloClientMessage, auth *BackendClientAuthResponse) (*ClientSession, error) {
|
||||
func NewClientSession(hub *Hub, privateId api.PrivateSessionId, publicId api.PublicSessionId, data *SessionIdData, backend *talk.Backend, hello *api.HelloClientMessage, auth *talk.BackendClientAuthResponse) (*ClientSession, error) {
|
||||
ctx := log.NewLoggerContext(context.Background(), hub.logger)
|
||||
ctx, closeFunc := context.WithCancel(ctx)
|
||||
s := &ClientSession{
|
||||
|
|
@ -208,18 +208,18 @@ func (s *ClientSession) HasFeature(feature string) bool {
|
|||
}
|
||||
|
||||
// HasPermission checks if the session has the passed permissions.
|
||||
func (s *ClientSession) HasPermission(permission Permission) bool {
|
||||
func (s *ClientSession) HasPermission(permission api.Permission) bool {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
return s.hasPermissionLocked(permission)
|
||||
}
|
||||
|
||||
func (s *ClientSession) GetPermissions() []Permission {
|
||||
func (s *ClientSession) GetPermissions() []api.Permission {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
result := make([]Permission, len(s.permissions))
|
||||
result := make([]api.Permission, len(s.permissions))
|
||||
for p, ok := range s.permissions {
|
||||
if ok {
|
||||
result = append(result, p)
|
||||
|
|
@ -229,7 +229,7 @@ func (s *ClientSession) GetPermissions() []Permission {
|
|||
}
|
||||
|
||||
// HasAnyPermission checks if the session has one of the passed permissions.
|
||||
func (s *ClientSession) HasAnyPermission(permission ...Permission) bool {
|
||||
func (s *ClientSession) HasAnyPermission(permission ...api.Permission) bool {
|
||||
if len(permission) == 0 {
|
||||
return false
|
||||
}
|
||||
|
|
@ -241,7 +241,7 @@ func (s *ClientSession) HasAnyPermission(permission ...Permission) bool {
|
|||
}
|
||||
|
||||
// +checklocks:s.mu
|
||||
func (s *ClientSession) hasAnyPermissionLocked(permission ...Permission) bool {
|
||||
func (s *ClientSession) hasAnyPermissionLocked(permission ...api.Permission) bool {
|
||||
if len(permission) == 0 {
|
||||
return false
|
||||
}
|
||||
|
|
@ -250,10 +250,10 @@ func (s *ClientSession) hasAnyPermissionLocked(permission ...Permission) bool {
|
|||
}
|
||||
|
||||
// +checklocks:s.mu
|
||||
func (s *ClientSession) hasPermissionLocked(permission Permission) bool {
|
||||
func (s *ClientSession) hasPermissionLocked(permission api.Permission) bool {
|
||||
if !s.supportsPermissions {
|
||||
// Old-style session that doesn't receive permissions from Nextcloud.
|
||||
if result, found := DefaultPermissionOverrides[permission]; found {
|
||||
if result, found := api.DefaultPermissionOverrides[permission]; found {
|
||||
return result
|
||||
}
|
||||
return true
|
||||
|
|
@ -265,11 +265,11 @@ func (s *ClientSession) hasPermissionLocked(permission Permission) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (s *ClientSession) SetPermissions(permissions []Permission) {
|
||||
var p map[Permission]bool
|
||||
func (s *ClientSession) SetPermissions(permissions []api.Permission) {
|
||||
var p map[api.Permission]bool
|
||||
for _, permission := range permissions {
|
||||
if p == nil {
|
||||
p = make(map[Permission]bool)
|
||||
p = make(map[api.Permission]bool)
|
||||
}
|
||||
p[permission] = true
|
||||
}
|
||||
|
|
@ -584,7 +584,7 @@ func (s *ClientSession) doUnsubscribeRoomEvents(notify bool) {
|
|||
// Notify
|
||||
go func(sid api.RoomSessionId) {
|
||||
ctx := log.NewLoggerContext(context.Background(), s.logger)
|
||||
request := NewBackendClientRoomRequest(room.Id(), s.userId, sid)
|
||||
request := talk.NewBackendClientRoomRequest(room.Id(), s.userId, sid)
|
||||
request.Room.UpdateFromSession(s)
|
||||
request.Room.Action = "leave"
|
||||
var response api.StringMap
|
||||
|
|
@ -824,10 +824,10 @@ func (s *ClientSession) SubscriberClosed(subscriber McuSubscriber) {
|
|||
}
|
||||
|
||||
type PermissionError struct {
|
||||
permission Permission
|
||||
permission api.Permission
|
||||
}
|
||||
|
||||
func (e *PermissionError) Permission() Permission {
|
||||
func (e *PermissionError) Permission() api.Permission {
|
||||
return e.permission
|
||||
}
|
||||
|
||||
|
|
@ -843,18 +843,18 @@ func (s *ClientSession) isSdpAllowedToSendLocked(sdp *sdp.SessionDescription) (M
|
|||
}
|
||||
|
||||
var mediaTypes MediaType
|
||||
mayPublishMedia := s.hasPermissionLocked(PERMISSION_MAY_PUBLISH_MEDIA)
|
||||
mayPublishMedia := s.hasPermissionLocked(api.PERMISSION_MAY_PUBLISH_MEDIA)
|
||||
for _, md := range sdp.MediaDescriptions {
|
||||
switch md.MediaName.Media {
|
||||
case "audio":
|
||||
if !mayPublishMedia && !s.hasPermissionLocked(PERMISSION_MAY_PUBLISH_AUDIO) {
|
||||
return 0, &PermissionError{PERMISSION_MAY_PUBLISH_AUDIO}
|
||||
if !mayPublishMedia && !s.hasPermissionLocked(api.PERMISSION_MAY_PUBLISH_AUDIO) {
|
||||
return 0, &PermissionError{api.PERMISSION_MAY_PUBLISH_AUDIO}
|
||||
}
|
||||
|
||||
mediaTypes |= MediaTypeAudio
|
||||
case "video":
|
||||
if !mayPublishMedia && !s.hasPermissionLocked(PERMISSION_MAY_PUBLISH_VIDEO) {
|
||||
return 0, &PermissionError{PERMISSION_MAY_PUBLISH_VIDEO}
|
||||
if !mayPublishMedia && !s.hasPermissionLocked(api.PERMISSION_MAY_PUBLISH_VIDEO) {
|
||||
return 0, &PermissionError{api.PERMISSION_MAY_PUBLISH_VIDEO}
|
||||
}
|
||||
|
||||
mediaTypes |= MediaTypeVideo
|
||||
|
|
@ -870,11 +870,11 @@ func (s *ClientSession) IsAllowedToSend(data *api.MessageClientMessageData) erro
|
|||
|
||||
switch {
|
||||
case data != nil && data.RoomType == "screen":
|
||||
if s.hasPermissionLocked(PERMISSION_MAY_PUBLISH_SCREEN) {
|
||||
if s.hasPermissionLocked(api.PERMISSION_MAY_PUBLISH_SCREEN) {
|
||||
return nil
|
||||
}
|
||||
return &PermissionError{PERMISSION_MAY_PUBLISH_SCREEN}
|
||||
case s.hasPermissionLocked(PERMISSION_MAY_PUBLISH_MEDIA):
|
||||
return &PermissionError{api.PERMISSION_MAY_PUBLISH_SCREEN}
|
||||
case s.hasPermissionLocked(api.PERMISSION_MAY_PUBLISH_MEDIA):
|
||||
// Client is allowed to publish any media (audio / video).
|
||||
return nil
|
||||
case data != nil && data.Type == "offer":
|
||||
|
|
@ -886,7 +886,7 @@ func (s *ClientSession) IsAllowedToSend(data *api.MessageClientMessageData) erro
|
|||
return nil
|
||||
default:
|
||||
// Candidate or unknown event, check if client is allowed to publish any media.
|
||||
if s.hasAnyPermissionLocked(PERMISSION_MAY_PUBLISH_AUDIO, PERMISSION_MAY_PUBLISH_VIDEO) {
|
||||
if s.hasAnyPermissionLocked(api.PERMISSION_MAY_PUBLISH_AUDIO, api.PERMISSION_MAY_PUBLISH_VIDEO) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -904,8 +904,8 @@ func (s *ClientSession) CheckOfferType(streamType StreamType, data *api.MessageC
|
|||
// +checklocks:s.mu
|
||||
func (s *ClientSession) checkOfferTypeLocked(streamType StreamType, data *api.MessageClientMessageData) (MediaType, error) {
|
||||
if streamType == StreamTypeScreen {
|
||||
if !s.hasPermissionLocked(PERMISSION_MAY_PUBLISH_SCREEN) {
|
||||
return 0, &PermissionError{PERMISSION_MAY_PUBLISH_SCREEN}
|
||||
if !s.hasPermissionLocked(api.PERMISSION_MAY_PUBLISH_SCREEN) {
|
||||
return 0, &PermissionError{api.PERMISSION_MAY_PUBLISH_SCREEN}
|
||||
}
|
||||
|
||||
return MediaTypeScreen, nil
|
||||
|
|
@ -1088,10 +1088,10 @@ func (s *ClientSession) processAsyncMessage(message *AsyncMessage) {
|
|||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if !s.hasPermissionLocked(PERMISSION_MAY_PUBLISH_MEDIA) {
|
||||
if !s.hasPermissionLocked(api.PERMISSION_MAY_PUBLISH_MEDIA) {
|
||||
if publisher, found := s.publishers[StreamTypeVideo]; found {
|
||||
if (publisher.HasMedia(MediaTypeAudio) && !s.hasPermissionLocked(PERMISSION_MAY_PUBLISH_AUDIO)) ||
|
||||
(publisher.HasMedia(MediaTypeVideo) && !s.hasPermissionLocked(PERMISSION_MAY_PUBLISH_VIDEO)) {
|
||||
if (publisher.HasMedia(MediaTypeAudio) && !s.hasPermissionLocked(api.PERMISSION_MAY_PUBLISH_AUDIO)) ||
|
||||
(publisher.HasMedia(MediaTypeVideo) && !s.hasPermissionLocked(api.PERMISSION_MAY_PUBLISH_VIDEO)) {
|
||||
delete(s.publishers, StreamTypeVideo)
|
||||
s.logger.Printf("Session %s is no longer allowed to publish media, closing publisher %s", s.PublicId(), publisher.Id())
|
||||
go func() {
|
||||
|
|
@ -1101,7 +1101,7 @@ func (s *ClientSession) processAsyncMessage(message *AsyncMessage) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if !s.hasPermissionLocked(PERMISSION_MAY_PUBLISH_SCREEN) {
|
||||
if !s.hasPermissionLocked(api.PERMISSION_MAY_PUBLISH_SCREEN) {
|
||||
if publisher, found := s.publishers[StreamTypeScreen]; found {
|
||||
delete(s.publishers, StreamTypeScreen)
|
||||
s.logger.Printf("Session %s is no longer allowed to publish screen, closing publisher %s", s.PublicId(), publisher.Id())
|
||||
|
|
@ -1317,7 +1317,7 @@ func (s *ClientSession) filterMessage(message *api.ServerMessage) *api.ServerMes
|
|||
}
|
||||
}
|
||||
|
||||
if s.HasPermission(PERMISSION_HIDE_DISPLAYNAMES) {
|
||||
if s.HasPermission(api.PERMISSION_HIDE_DISPLAYNAMES) {
|
||||
if copied {
|
||||
message.Event.Join = filterDisplayNames(message.Event.Join)
|
||||
} else {
|
||||
|
|
@ -1361,7 +1361,7 @@ func (s *ClientSession) filterMessage(message *api.ServerMessage) *api.ServerMes
|
|||
update = true
|
||||
}
|
||||
|
||||
if len(data.Chat.Comment) > 0 && s.HasPermission(PERMISSION_HIDE_DISPLAYNAMES) {
|
||||
if len(data.Chat.Comment) > 0 && s.HasPermission(api.PERMISSION_HIDE_DISPLAYNAMES) {
|
||||
var comment api.ChatComment
|
||||
if err := json.Unmarshal(data.Chat.Comment, &comment); err != nil {
|
||||
return message
|
||||
|
|
@ -1398,7 +1398,7 @@ func (s *ClientSession) filterMessage(message *api.ServerMessage) *api.ServerMes
|
|||
}
|
||||
}
|
||||
case "message":
|
||||
if message.Message != nil && len(message.Message.Data) > 0 && s.HasPermission(PERMISSION_HIDE_DISPLAYNAMES) {
|
||||
if message.Message != nil && len(message.Message.Data) > 0 && s.HasPermission(api.PERMISSION_HIDE_DISPLAYNAMES) {
|
||||
var data api.MessageServerMessageData
|
||||
if err := json.Unmarshal(message.Message.Data, &data); err != nil {
|
||||
return message
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import (
|
|||
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/api"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/mock"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/talk"
|
||||
)
|
||||
|
||||
func TestBandwidth_Client(t *testing.T) {
|
||||
|
|
@ -219,9 +220,9 @@ func TestFeatureChatRelay(t *testing.T) {
|
|||
// Simulate request from the backend.
|
||||
room.processAsyncMessage(&AsyncMessage{
|
||||
Type: "room",
|
||||
Room: &BackendServerRoomRequest{
|
||||
Room: &talk.BackendServerRoomRequest{
|
||||
Type: "message",
|
||||
Message: &BackendRoomMessageRequest{
|
||||
Message: &talk.BackendRoomMessageRequest{
|
||||
Data: data,
|
||||
},
|
||||
},
|
||||
|
|
@ -416,9 +417,9 @@ func TestFeatureChatRelayFederation(t *testing.T) {
|
|||
// Simulate request from the backend.
|
||||
room.processAsyncMessage(&AsyncMessage{
|
||||
Type: "room",
|
||||
Room: &BackendServerRoomRequest{
|
||||
Room: &talk.BackendServerRoomRequest{
|
||||
Type: "message",
|
||||
Message: &BackendRoomMessageRequest{
|
||||
Message: &talk.BackendRoomMessageRequest{
|
||||
Data: data,
|
||||
},
|
||||
},
|
||||
|
|
@ -494,7 +495,7 @@ func TestPermissionHideDisplayNames(t *testing.T) {
|
|||
require.NotNil(session, "Session %s does not exist", hello.Hello.SessionId)
|
||||
|
||||
// Client may not receive display names.
|
||||
session.SetPermissions([]Permission{PERMISSION_HIDE_DISPLAYNAMES})
|
||||
session.SetPermissions([]api.Permission{api.PERMISSION_HIDE_DISPLAYNAMES})
|
||||
}
|
||||
|
||||
chatComment := api.StringMap{
|
||||
|
|
@ -516,9 +517,9 @@ func TestPermissionHideDisplayNames(t *testing.T) {
|
|||
// Simulate request from the backend.
|
||||
room.processAsyncMessage(&AsyncMessage{
|
||||
Type: "room",
|
||||
Room: &BackendServerRoomRequest{
|
||||
Room: &talk.BackendServerRoomRequest{
|
||||
Type: "message",
|
||||
Message: &BackendRoomMessageRequest{
|
||||
Message: &talk.BackendRoomMessageRequest{
|
||||
Data: data,
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -482,7 +482,7 @@ func (c *FederationClient) sendHello(auth *api.FederationAuthParams) error {
|
|||
|
||||
// +checklocks:c.helloMu
|
||||
func (c *FederationClient) sendHelloLocked(auth *api.FederationAuthParams) error {
|
||||
c.helloMsgId = newRandomString(8)
|
||||
c.helloMsgId = internal.RandomString(8)
|
||||
|
||||
authData, err := json.Marshal(auth)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ import (
|
|||
"github.com/strukturag/nextcloud-spreed-signaling/geoip"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/talk"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -504,7 +505,7 @@ func NewGrpcClients(ctx context.Context, config *goconf.ConfigFile, etcdClient e
|
|||
return result, nil
|
||||
}
|
||||
|
||||
func (c *GrpcClients) GetServerInfoGrpc() (result []BackendServerInfoGrpc) {
|
||||
func (c *GrpcClients) GetServerInfoGrpc() (result []talk.BackendServerInfoGrpc) {
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
|
||||
|
|
@ -513,7 +514,7 @@ func (c *GrpcClients) GetServerInfoGrpc() (result []BackendServerInfoGrpc) {
|
|||
continue
|
||||
}
|
||||
|
||||
grpc := BackendServerInfoGrpc{
|
||||
grpc := talk.BackendServerInfoGrpc{
|
||||
Target: client.rawTarget,
|
||||
}
|
||||
if len(client.ip) > 0 {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import (
|
|||
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/api"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/config"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/talk"
|
||||
)
|
||||
|
|
@ -55,10 +56,10 @@ func init() {
|
|||
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
hostname = newRandomString(8)
|
||||
hostname = internal.RandomString(8)
|
||||
}
|
||||
md := sha256.New()
|
||||
fmt.Fprintf(md, "%s-%s-%d", newRandomString(32), hostname, os.Getpid())
|
||||
fmt.Fprintf(md, "%s-%s-%d", internal.RandomString(32), hostname, os.Getpid())
|
||||
GrpcServerId = hex.EncodeToString(md.Sum(nil))
|
||||
}
|
||||
|
||||
|
|
|
|||
114
hub.go
114
hub.go
|
|
@ -160,10 +160,10 @@ type Hub struct {
|
|||
shutdown *internal.Closer
|
||||
shutdownScheduled atomic.Bool
|
||||
|
||||
roomUpdated chan *BackendServerRoomRequest
|
||||
roomDeleted chan *BackendServerRoomRequest
|
||||
roomInCall chan *BackendServerRoomRequest
|
||||
roomParticipants chan *BackendServerRoomRequest
|
||||
roomUpdated chan *talk.BackendServerRoomRequest
|
||||
roomDeleted chan *talk.BackendServerRoomRequest
|
||||
roomInCall chan *talk.BackendServerRoomRequest
|
||||
roomParticipants chan *talk.BackendServerRoomRequest
|
||||
|
||||
mu sync.RWMutex
|
||||
ru sync.RWMutex
|
||||
|
|
@ -379,10 +379,10 @@ func NewHub(ctx context.Context, cfg *goconf.ConfigFile, events AsyncEvents, rpc
|
|||
closer: internal.NewCloser(),
|
||||
shutdown: internal.NewCloser(),
|
||||
|
||||
roomUpdated: make(chan *BackendServerRoomRequest),
|
||||
roomDeleted: make(chan *BackendServerRoomRequest),
|
||||
roomInCall: make(chan *BackendServerRoomRequest),
|
||||
roomParticipants: make(chan *BackendServerRoomRequest),
|
||||
roomUpdated: make(chan *talk.BackendServerRoomRequest),
|
||||
roomDeleted: make(chan *talk.BackendServerRoomRequest),
|
||||
roomInCall: make(chan *talk.BackendServerRoomRequest),
|
||||
roomParticipants: make(chan *talk.BackendServerRoomRequest),
|
||||
|
||||
clients: make(map[uint64]HandlerClient),
|
||||
sessions: make(map[uint64]Session),
|
||||
|
|
@ -952,7 +952,7 @@ func (h *Hub) newSessionIdData(backend *talk.Backend) *SessionIdData {
|
|||
return sessionIdData
|
||||
}
|
||||
|
||||
func (h *Hub) processRegister(c HandlerClient, message *api.ClientMessage, backend *talk.Backend, auth *BackendClientResponse) {
|
||||
func (h *Hub) processRegister(c HandlerClient, message *api.ClientMessage, backend *talk.Backend, auth *talk.BackendClientResponse) {
|
||||
if !c.IsConnected() {
|
||||
// Client disconnected while waiting for "hello" response.
|
||||
return
|
||||
|
|
@ -1362,7 +1362,7 @@ func (h *Hub) processHello(client HandlerClient, message *api.ClientMessage) {
|
|||
}
|
||||
}
|
||||
|
||||
func (h *Hub) processHelloV1(ctx context.Context, client HandlerClient, message *api.ClientMessage) (*talk.Backend, *BackendClientResponse, error) {
|
||||
func (h *Hub) processHelloV1(ctx context.Context, client HandlerClient, message *api.ClientMessage) (*talk.Backend, *talk.BackendClientResponse, error) {
|
||||
url := message.Hello.Auth.ParsedUrl
|
||||
backend := h.backend.GetBackend(url)
|
||||
if backend == nil {
|
||||
|
|
@ -1375,8 +1375,8 @@ func (h *Hub) processHelloV1(ctx context.Context, client HandlerClient, message
|
|||
ctx, cancel := context.WithTimeout(ctx, h.backendTimeout)
|
||||
defer cancel()
|
||||
|
||||
var auth BackendClientResponse
|
||||
request := NewBackendClientAuthRequest(message.Hello.Auth.Params)
|
||||
var auth talk.BackendClientResponse
|
||||
request := talk.NewBackendClientAuthRequest(message.Hello.Auth.Params)
|
||||
if err := h.backend.PerformJSONRequest(ctx, url, request, &auth); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
|
@ -1386,7 +1386,7 @@ func (h *Hub) processHelloV1(ctx context.Context, client HandlerClient, message
|
|||
return backend, &auth, nil
|
||||
}
|
||||
|
||||
func (h *Hub) processHelloV2(ctx context.Context, client HandlerClient, message *api.ClientMessage) (*talk.Backend, *BackendClientResponse, error) {
|
||||
func (h *Hub) processHelloV2(ctx context.Context, client HandlerClient, message *api.ClientMessage) (*talk.Backend, *talk.BackendClientResponse, error) {
|
||||
url := message.Hello.Auth.ParsedUrl
|
||||
backend := h.backend.GetBackend(url)
|
||||
if backend == nil {
|
||||
|
|
@ -1452,13 +1452,13 @@ func (h *Hub) processHelloV2(ctx context.Context, client HandlerClient, message
|
|||
backendCtx, cancel := context.WithTimeout(ctx, h.backendTimeout)
|
||||
defer cancel()
|
||||
|
||||
keyData, cached, found := h.backend.capabilities.GetStringConfig(backendCtx, url, ConfigGroupSignaling, ConfigKeyHelloV2TokenKey)
|
||||
keyData, cached, found := h.backend.capabilities.GetStringConfig(backendCtx, url, talk.ConfigGroupSignaling, talk.ConfigKeyHelloV2TokenKey)
|
||||
if !found {
|
||||
if cached {
|
||||
// The Nextcloud instance might just have enabled JWT but we probably use
|
||||
// the cached capabilities without the public key. Make sure to re-fetch.
|
||||
h.backend.capabilities.InvalidateCapabilities(url)
|
||||
keyData, _, found = h.backend.capabilities.GetStringConfig(backendCtx, url, ConfigGroupSignaling, ConfigKeyHelloV2TokenKey)
|
||||
keyData, _, found = h.backend.capabilities.GetStringConfig(backendCtx, url, talk.ConfigGroupSignaling, talk.ConfigKeyHelloV2TokenKey)
|
||||
}
|
||||
if !found {
|
||||
return nil, errors.New("no key found for issuer")
|
||||
|
|
@ -1528,9 +1528,9 @@ func (h *Hub) processHelloV2(ctx context.Context, client HandlerClient, message
|
|||
return nil, nil, InvalidToken
|
||||
}
|
||||
|
||||
auth := &BackendClientResponse{
|
||||
auth := &talk.BackendClientResponse{
|
||||
Type: "auth",
|
||||
Auth: &BackendClientAuthResponse{
|
||||
Auth: &talk.BackendClientAuthResponse{
|
||||
Version: message.Hello.Version,
|
||||
UserId: subject,
|
||||
User: authTokenClaims.GetUserData(),
|
||||
|
|
@ -1543,7 +1543,7 @@ func (h *Hub) processHelloClient(client HandlerClient, message *api.ClientMessag
|
|||
// Make sure the client must send another "hello" in case of errors.
|
||||
defer h.startExpectHello(client)
|
||||
|
||||
var authFunc func(context.Context, HandlerClient, *api.ClientMessage) (*talk.Backend, *BackendClientResponse, error)
|
||||
var authFunc func(context.Context, HandlerClient, *api.ClientMessage) (*talk.Backend, *talk.BackendClientResponse, error)
|
||||
switch message.Hello.Version {
|
||||
case api.HelloVersionV1:
|
||||
// Auth information contains a ticket that must be validated against the
|
||||
|
|
@ -1606,9 +1606,9 @@ func (h *Hub) processHelloInternal(client HandlerClient, message *api.ClientMess
|
|||
return
|
||||
}
|
||||
|
||||
auth := &BackendClientResponse{
|
||||
auth := &talk.BackendClientResponse{
|
||||
Type: "auth",
|
||||
Auth: &BackendClientAuthResponse{},
|
||||
Auth: &talk.BackendClientAuthResponse{},
|
||||
}
|
||||
h.processRegister(client, message, backend, auth)
|
||||
}
|
||||
|
|
@ -1846,12 +1846,12 @@ func (h *Hub) processRoom(sess Session, message *api.ClientMessage) {
|
|||
return
|
||||
}
|
||||
|
||||
var room BackendClientResponse
|
||||
var room talk.BackendClientResponse
|
||||
if session.ClientType() == api.HelloClientTypeInternal {
|
||||
// Internal clients can join any room.
|
||||
room = BackendClientResponse{
|
||||
room = talk.BackendClientResponse{
|
||||
Type: "room",
|
||||
Room: &BackendClientRoomResponse{
|
||||
Room: &talk.BackendClientRoomResponse{
|
||||
RoomId: roomId,
|
||||
},
|
||||
}
|
||||
|
|
@ -1866,7 +1866,7 @@ func (h *Hub) processRoom(sess Session, message *api.ClientMessage) {
|
|||
h.logger.Printf("User did not send a room session id, assuming session %s", session.PublicId())
|
||||
sessionId = api.RoomSessionId(session.PublicId())
|
||||
}
|
||||
request := NewBackendClientRoomRequest(roomId, session.UserId(), sessionId)
|
||||
request := talk.NewBackendClientRoomRequest(roomId, session.UserId(), sessionId)
|
||||
request.Room.UpdateFromSession(session)
|
||||
if err := h.backend.PerformJSONRequest(ctx, session.ParsedBackendOcsUrl(), request, &room); err != nil {
|
||||
session.SendMessage(message.NewWrappedErrorServerMessage(err))
|
||||
|
|
@ -1897,7 +1897,7 @@ func (h *Hub) publishFederatedSessions() (int, *sync.WaitGroup) {
|
|||
return 0, &wg
|
||||
}
|
||||
|
||||
rooms := make(map[string]map[string][]BackendPingEntry)
|
||||
rooms := make(map[string]map[string][]talk.BackendPingEntry)
|
||||
urls := make(map[string]*url.URL)
|
||||
for session := range h.federatedSessions {
|
||||
u := session.BackendUrl()
|
||||
|
|
@ -1921,7 +1921,7 @@ func (h *Hub) publishFederatedSessions() (int, *sync.WaitGroup) {
|
|||
roomId := federation.RoomId()
|
||||
entries, found := rooms[roomId]
|
||||
if !found {
|
||||
entries = make(map[string][]BackendPingEntry)
|
||||
entries = make(map[string][]talk.BackendPingEntry)
|
||||
rooms[roomId] = entries
|
||||
}
|
||||
|
||||
|
|
@ -1935,7 +1935,7 @@ func (h *Hub) publishFederatedSessions() (int, *sync.WaitGroup) {
|
|||
urls[u] = p
|
||||
}
|
||||
|
||||
entries[u] = append(e, BackendPingEntry{
|
||||
entries[u] = append(e, talk.BackendPingEntry{
|
||||
SessionId: sid,
|
||||
UserId: uid,
|
||||
})
|
||||
|
|
@ -1950,7 +1950,7 @@ func (h *Hub) publishFederatedSessions() (int, *sync.WaitGroup) {
|
|||
for u, e := range entries {
|
||||
wg.Add(1)
|
||||
count += len(e)
|
||||
go func(roomId string, url *url.URL, entries []BackendPingEntry) {
|
||||
go func(roomId string, url *url.URL, entries []talk.BackendPingEntry) {
|
||||
defer wg.Done()
|
||||
sendCtx, cancel := context.WithTimeout(ctx, h.backendTimeout)
|
||||
defer cancel()
|
||||
|
|
@ -2004,7 +2004,7 @@ func (h *Hub) createRoomLocked(id string, properties json.RawMessage, backend *t
|
|||
return room, nil
|
||||
}
|
||||
|
||||
func (h *Hub) processJoinRoom(session *ClientSession, message *api.ClientMessage, room *BackendClientResponse) {
|
||||
func (h *Hub) processJoinRoom(session *ClientSession, message *api.ClientMessage, room *talk.BackendClientResponse) {
|
||||
if room.Type == "error" {
|
||||
session.SendMessage(message.NewErrorServerMessage(room.Error))
|
||||
return
|
||||
|
|
@ -2327,7 +2327,7 @@ func isAllowedToControl(session Session) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
if session.HasPermission(PERMISSION_MAY_CONTROL) {
|
||||
if session.HasPermission(api.PERMISSION_MAY_CONTROL) {
|
||||
// Moderator clients are allowed to send any control message.
|
||||
return true
|
||||
}
|
||||
|
|
@ -2498,12 +2498,12 @@ func (h *Hub) processInternalMsg(sess Session, message *api.ClientMessage) {
|
|||
}
|
||||
|
||||
if options := msg.Options; options != nil && options.ActorId != "" && options.ActorType != "" {
|
||||
request := NewBackendClientRoomRequest(room.Id(), msg.UserId, api.RoomSessionId(publicSessionId))
|
||||
request := talk.NewBackendClientRoomRequest(room.Id(), msg.UserId, api.RoomSessionId(publicSessionId))
|
||||
request.Room.ActorId = options.ActorId
|
||||
request.Room.ActorType = options.ActorType
|
||||
request.Room.InCall = sess.GetInCall()
|
||||
|
||||
var response BackendClientResponse
|
||||
var response talk.BackendClientResponse
|
||||
if err := h.backend.PerformJSONRequest(ctx, session.ParsedBackendOcsUrl(), request, &response); err != nil {
|
||||
sess.Close()
|
||||
h.logger.Printf("Could not join virtual session %s at backend %s: %s", virtualSessionId, session.BackendUrl(), err)
|
||||
|
|
@ -2520,8 +2520,8 @@ func (h *Hub) processInternalMsg(sess Session, message *api.ClientMessage) {
|
|||
return
|
||||
}
|
||||
} else {
|
||||
request := NewBackendClientSessionRequest(room.Id(), "add", publicSessionId, msg)
|
||||
var response BackendClientSessionResponse
|
||||
request := talk.NewBackendClientSessionRequest(room.Id(), "add", publicSessionId, msg)
|
||||
var response talk.BackendClientSessionResponse
|
||||
if err := h.backend.PerformJSONRequest(ctx, session.ParsedBackendOcsUrl(), request, &response); err != nil {
|
||||
sess.Close()
|
||||
h.logger.Printf("Could not add virtual session %s at backend %s: %s", virtualSessionId, session.BackendUrl(), err)
|
||||
|
|
@ -2620,10 +2620,10 @@ func (h *Hub) processInternalMsg(sess Session, message *api.ClientMessage) {
|
|||
if msg.Dialout.Type == "status" {
|
||||
asyncMessage := &AsyncMessage{
|
||||
Type: "room",
|
||||
Room: &BackendServerRoomRequest{
|
||||
Room: &talk.BackendServerRoomRequest{
|
||||
Type: "transient",
|
||||
Transient: &BackendRoomTransientRequest{
|
||||
Action: TransientActionSet,
|
||||
Transient: &talk.BackendRoomTransientRequest{
|
||||
Action: talk.TransientActionSet,
|
||||
Key: "callstatus_" + msg.Dialout.Status.CallId,
|
||||
Value: msg.Dialout.Status,
|
||||
},
|
||||
|
|
@ -2658,7 +2658,7 @@ func isAllowedToUpdateTransientData(session Session) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
if session.HasPermission(PERMISSION_TRANSIENT_DATA) {
|
||||
if session.HasPermission(api.PERMISSION_TRANSIENT_DATA) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -2957,13 +2957,21 @@ func (h *Hub) processByeMsg(client HandlerClient, message *api.ClientMessage) {
|
|||
}
|
||||
}
|
||||
|
||||
func (h *Hub) processRoomUpdated(message *BackendServerRoomRequest) {
|
||||
room := message.room
|
||||
func (h *Hub) processRoomUpdated(message *talk.BackendServerRoomRequest) {
|
||||
room := h.GetRoomForBackend(message.RoomId, message.Backend)
|
||||
if room == nil {
|
||||
return
|
||||
}
|
||||
|
||||
room.UpdateProperties(message.Update.Properties)
|
||||
}
|
||||
|
||||
func (h *Hub) processRoomDeleted(message *BackendServerRoomRequest) {
|
||||
room := message.room
|
||||
func (h *Hub) processRoomDeleted(message *talk.BackendServerRoomRequest) {
|
||||
room := h.GetRoomForBackend(message.RoomId, message.Backend)
|
||||
if room == nil {
|
||||
return
|
||||
}
|
||||
|
||||
sessions := room.Close()
|
||||
for _, session := range sessions {
|
||||
// The session is no longer in the room
|
||||
|
|
@ -2977,8 +2985,12 @@ func (h *Hub) processRoomDeleted(message *BackendServerRoomRequest) {
|
|||
}
|
||||
}
|
||||
|
||||
func (h *Hub) processRoomInCallChanged(message *BackendServerRoomRequest) {
|
||||
room := message.room
|
||||
func (h *Hub) processRoomInCallChanged(message *talk.BackendServerRoomRequest) {
|
||||
room := h.GetRoomForBackend(message.RoomId, message.Backend)
|
||||
if room == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if message.InCall.All {
|
||||
var flags int
|
||||
if err := json.Unmarshal(message.InCall.InCall, &flags); err != nil {
|
||||
|
|
@ -2999,8 +3011,12 @@ func (h *Hub) processRoomInCallChanged(message *BackendServerRoomRequest) {
|
|||
}
|
||||
}
|
||||
|
||||
func (h *Hub) processRoomParticipants(message *BackendServerRoomRequest) {
|
||||
room := message.room
|
||||
func (h *Hub) processRoomParticipants(message *talk.BackendServerRoomRequest) {
|
||||
room := h.GetRoomForBackend(message.RoomId, message.Backend)
|
||||
if room == nil {
|
||||
return
|
||||
}
|
||||
|
||||
room.PublishUsersChanged(message.Participants.Changed, message.Participants.Users)
|
||||
}
|
||||
|
||||
|
|
@ -3020,12 +3036,12 @@ func (h *Hub) GetStats() api.StringMap {
|
|||
return result
|
||||
}
|
||||
|
||||
func (h *Hub) GetServerInfoDialout() (result []BackendServerInfoDialout) {
|
||||
func (h *Hub) GetServerInfoDialout() (result []talk.BackendServerInfoDialout) {
|
||||
h.mu.RLock()
|
||||
defer h.mu.RUnlock()
|
||||
|
||||
for session := range h.dialoutSessions {
|
||||
dialout := BackendServerInfoDialout{
|
||||
dialout := talk.BackendServerInfoDialout{
|
||||
SessionId: session.PublicId(),
|
||||
}
|
||||
if client := session.GetClient(); client != nil && client.IsConnected() {
|
||||
|
|
@ -3047,7 +3063,7 @@ func (h *Hub) GetServerInfoDialout() (result []BackendServerInfoDialout) {
|
|||
result = append(result, dialout)
|
||||
}
|
||||
|
||||
slices.SortFunc(result, func(a, b BackendServerInfoDialout) int {
|
||||
slices.SortFunc(result, func(a, b talk.BackendServerInfoDialout) int {
|
||||
return strings.Compare(string(a.SessionId), string(b.SessionId))
|
||||
})
|
||||
return
|
||||
|
|
|
|||
146
hub_test.go
146
hub_test.go
|
|
@ -348,23 +348,23 @@ func WaitForHub(ctx context.Context, t *testing.T, h *Hub) {
|
|||
}
|
||||
}
|
||||
|
||||
func validateBackendChecksum(t *testing.T, f func(http.ResponseWriter, *http.Request, *BackendClientRequest) *BackendClientResponse) func(http.ResponseWriter, *http.Request) {
|
||||
func validateBackendChecksum(t *testing.T, f func(http.ResponseWriter, *http.Request, *talk.BackendClientRequest) *talk.BackendClientResponse) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
assert := assert.New(t)
|
||||
body, err := io.ReadAll(r.Body)
|
||||
assert.NoError(err)
|
||||
|
||||
rnd := r.Header.Get(HeaderBackendSignalingRandom)
|
||||
checksum := r.Header.Get(HeaderBackendSignalingChecksum)
|
||||
rnd := r.Header.Get(talk.HeaderBackendSignalingRandom)
|
||||
checksum := r.Header.Get(talk.HeaderBackendSignalingChecksum)
|
||||
if rnd == "" || checksum == "" {
|
||||
assert.Fail("No checksum headers found", "request to %s", r.URL)
|
||||
}
|
||||
|
||||
if verify := CalculateBackendChecksum(rnd, body, testBackendSecret); verify != checksum {
|
||||
if verify := talk.CalculateBackendChecksum(rnd, body, testBackendSecret); verify != checksum {
|
||||
assert.Fail("Backend checksum verification failed", "request to %s", r.URL)
|
||||
}
|
||||
|
||||
var request BackendClientRequest
|
||||
var request talk.BackendClientRequest
|
||||
assert.NoError(json.Unmarshal(body, &request))
|
||||
|
||||
response := f(w, r, &request)
|
||||
|
|
@ -396,7 +396,7 @@ func validateBackendChecksum(t *testing.T, f func(http.ResponseWriter, *http.Req
|
|||
}
|
||||
}
|
||||
|
||||
func processAuthRequest(t *testing.T, w http.ResponseWriter, r *http.Request, request *BackendClientRequest) *BackendClientResponse {
|
||||
func processAuthRequest(t *testing.T, w http.ResponseWriter, r *http.Request, request *talk.BackendClientRequest) *talk.BackendClientResponse {
|
||||
require := require.New(t)
|
||||
if request.Type != "auth" || request.Auth == nil {
|
||||
require.Fail("Expected an auth backend request", "received %+v", request)
|
||||
|
|
@ -413,10 +413,10 @@ func processAuthRequest(t *testing.T, w http.ResponseWriter, r *http.Request, re
|
|||
params.UserId = ""
|
||||
}
|
||||
|
||||
response := &BackendClientResponse{
|
||||
response := &talk.BackendClientResponse{
|
||||
Type: "auth",
|
||||
Auth: &BackendClientAuthResponse{
|
||||
Version: BackendVersion,
|
||||
Auth: &talk.BackendClientAuthResponse{
|
||||
Version: talk.BackendVersion,
|
||||
UserId: params.UserId,
|
||||
},
|
||||
}
|
||||
|
|
@ -428,7 +428,7 @@ func processAuthRequest(t *testing.T, w http.ResponseWriter, r *http.Request, re
|
|||
return response
|
||||
}
|
||||
|
||||
func processRoomRequest(t *testing.T, w http.ResponseWriter, r *http.Request, request *BackendClientRequest) *BackendClientResponse {
|
||||
func processRoomRequest(t *testing.T, w http.ResponseWriter, r *http.Request, request *talk.BackendClientRequest) *talk.BackendClientResponse {
|
||||
require := require.New(t)
|
||||
assert := assert.New(t)
|
||||
if request.Type != "room" || request.Room == nil {
|
||||
|
|
@ -444,7 +444,7 @@ func processRoomRequest(t *testing.T, w http.ResponseWriter, r *http.Request, re
|
|||
assert.Fail("Should not receive \"leave\" event for first user", "received %+v", request.Room)
|
||||
}
|
||||
case "test-invalid-room":
|
||||
response := &BackendClientResponse{
|
||||
response := &talk.BackendClientResponse{
|
||||
Type: "error",
|
||||
Error: &api.Error{
|
||||
Code: "no_such_room",
|
||||
|
|
@ -471,10 +471,10 @@ func processRoomRequest(t *testing.T, w http.ResponseWriter, r *http.Request, re
|
|||
}
|
||||
|
||||
// Allow joining any room.
|
||||
response := &BackendClientResponse{
|
||||
response := &talk.BackendClientResponse{
|
||||
Type: "room",
|
||||
Room: &BackendClientRoomResponse{
|
||||
Version: BackendVersion,
|
||||
Room: &talk.BackendClientRoomResponse{
|
||||
Version: talk.BackendVersion,
|
||||
RoomId: request.Room.RoomId,
|
||||
Properties: testRoomProperties,
|
||||
},
|
||||
|
|
@ -487,7 +487,7 @@ func processRoomRequest(t *testing.T, w http.ResponseWriter, r *http.Request, re
|
|||
tmp, _ := json.Marshal(data)
|
||||
response.Room.Session = tmp
|
||||
case "test-room-initial-permissions":
|
||||
permissions := []Permission{PERMISSION_MAY_PUBLISH_AUDIO}
|
||||
permissions := []api.Permission{api.PERMISSION_MAY_PUBLISH_AUDIO}
|
||||
response.Room.Permissions = &permissions
|
||||
}
|
||||
return response
|
||||
|
|
@ -497,15 +497,15 @@ var (
|
|||
sessionRequestHander struct {
|
||||
sync.Mutex
|
||||
// +checklocks:Mutex
|
||||
handlers map[*testing.T]func(*BackendClientSessionRequest)
|
||||
handlers map[*testing.T]func(*talk.BackendClientSessionRequest)
|
||||
}
|
||||
)
|
||||
|
||||
func setSessionRequestHandler(t *testing.T, f func(*BackendClientSessionRequest)) {
|
||||
func setSessionRequestHandler(t *testing.T, f func(*talk.BackendClientSessionRequest)) {
|
||||
sessionRequestHander.Lock()
|
||||
defer sessionRequestHander.Unlock()
|
||||
if sessionRequestHander.handlers == nil {
|
||||
sessionRequestHander.handlers = make(map[*testing.T]func(*BackendClientSessionRequest))
|
||||
sessionRequestHander.handlers = make(map[*testing.T]func(*talk.BackendClientSessionRequest))
|
||||
}
|
||||
if _, found := sessionRequestHander.handlers[t]; !found {
|
||||
t.Cleanup(func() {
|
||||
|
|
@ -525,7 +525,7 @@ func clearSessionRequestHandler(t *testing.T) { // nolint
|
|||
delete(sessionRequestHander.handlers, t)
|
||||
}
|
||||
|
||||
func processSessionRequest(t *testing.T, w http.ResponseWriter, r *http.Request, request *BackendClientRequest) *BackendClientResponse {
|
||||
func processSessionRequest(t *testing.T, w http.ResponseWriter, r *http.Request, request *talk.BackendClientRequest) *talk.BackendClientResponse {
|
||||
if request.Type != "session" || request.Session == nil {
|
||||
require.Fail(t, "Expected an session backend request", "received %+v", request)
|
||||
}
|
||||
|
|
@ -536,10 +536,10 @@ func processSessionRequest(t *testing.T, w http.ResponseWriter, r *http.Request,
|
|||
f(request.Session)
|
||||
}
|
||||
|
||||
response := &BackendClientResponse{
|
||||
response := &talk.BackendClientResponse{
|
||||
Type: "session",
|
||||
Session: &BackendClientSessionResponse{
|
||||
Version: BackendVersion,
|
||||
Session: &talk.BackendClientSessionResponse{
|
||||
Version: talk.BackendVersion,
|
||||
RoomId: request.Session.RoomId,
|
||||
},
|
||||
}
|
||||
|
|
@ -547,10 +547,10 @@ func processSessionRequest(t *testing.T, w http.ResponseWriter, r *http.Request,
|
|||
}
|
||||
|
||||
var (
|
||||
pingRequests internal.TestStorage[[]*BackendClientRequest]
|
||||
pingRequests internal.TestStorage[[]*talk.BackendClientRequest]
|
||||
)
|
||||
|
||||
func getPingRequests(t *testing.T) []*BackendClientRequest {
|
||||
func getPingRequests(t *testing.T) []*talk.BackendClientRequest {
|
||||
entries, _ := pingRequests.Get(t)
|
||||
return entries
|
||||
}
|
||||
|
|
@ -559,12 +559,12 @@ func clearPingRequests(t *testing.T) {
|
|||
pingRequests.Del(t)
|
||||
}
|
||||
|
||||
func storePingRequest(t *testing.T, request *BackendClientRequest) {
|
||||
func storePingRequest(t *testing.T, request *talk.BackendClientRequest) {
|
||||
entries, _ := pingRequests.Get(t)
|
||||
pingRequests.Set(t, append(entries, request))
|
||||
}
|
||||
|
||||
func processPingRequest(t *testing.T, w http.ResponseWriter, r *http.Request, request *BackendClientRequest) *BackendClientResponse {
|
||||
func processPingRequest(t *testing.T, w http.ResponseWriter, r *http.Request, request *talk.BackendClientRequest) *talk.BackendClientResponse {
|
||||
if request.Type != "ping" || request.Ping == nil {
|
||||
require.Fail(t, "Expected an ping backend request", "received %+v", request)
|
||||
}
|
||||
|
|
@ -577,10 +577,10 @@ func processPingRequest(t *testing.T, w http.ResponseWriter, r *http.Request, re
|
|||
|
||||
storePingRequest(t, request)
|
||||
|
||||
response := &BackendClientResponse{
|
||||
response := &talk.BackendClientResponse{
|
||||
Type: "ping",
|
||||
Ping: &BackendClientRingResponse{
|
||||
Version: BackendVersion,
|
||||
Ping: &talk.BackendClientRingResponse{
|
||||
Version: talk.BackendVersion,
|
||||
RoomId: request.Ping.RoomId,
|
||||
},
|
||||
}
|
||||
|
|
@ -706,7 +706,7 @@ var (
|
|||
)
|
||||
|
||||
func registerBackendHandlerUrl(t *testing.T, router *mux.Router, url string) {
|
||||
handleFunc := validateBackendChecksum(t, func(w http.ResponseWriter, r *http.Request, request *BackendClientRequest) *BackendClientResponse {
|
||||
handleFunc := validateBackendChecksum(t, func(w http.ResponseWriter, r *http.Request, request *talk.BackendClientRequest) *talk.BackendClientResponse {
|
||||
assert.Regexp(t, "/ocs/v2\\.php/apps/spreed/api/v[\\d]/signaling/backend$", r.URL.Path, "invalid url for backend request %+v", request)
|
||||
|
||||
switch request.Type {
|
||||
|
|
@ -748,7 +748,7 @@ func registerBackendHandlerUrl(t *testing.T, router *mux.Router, url string) {
|
|||
"signaling": signaling,
|
||||
}
|
||||
if strings.Contains(t.Name(), "MultiRoom") {
|
||||
signaling[ConfigKeySessionPingLimit] = 2
|
||||
signaling[talk.ConfigKeySessionPingLimit] = 2
|
||||
}
|
||||
skipV2, _ := skipV2Capabilities.Get(t)
|
||||
if (strings.Contains(t.Name(), "V2") && !skipV2) || strings.Contains(t.Name(), "Federation") {
|
||||
|
|
@ -771,9 +771,9 @@ func registerBackendHandlerUrl(t *testing.T, router *mux.Router, url string) {
|
|||
if strings.Contains(t.Name(), "Ed25519_Nextcloud") {
|
||||
// Simulate Nextcloud which returns the Ed25519 key as base64-encoded data.
|
||||
encoded := base64.StdEncoding.EncodeToString(key.(ed25519.PublicKey))
|
||||
signaling[ConfigKeyHelloV2TokenKey] = encoded
|
||||
signaling[talk.ConfigKeyHelloV2TokenKey] = encoded
|
||||
} else {
|
||||
signaling[ConfigKeyHelloV2TokenKey] = string(public)
|
||||
signaling[talk.ConfigKeyHelloV2TokenKey] = string(public)
|
||||
}
|
||||
}
|
||||
spreedCapa, err := json.Marshal(api.StringMap{
|
||||
|
|
@ -2113,15 +2113,15 @@ func TestClientControlMissingPermissions(t *testing.T) {
|
|||
require.NotNil(session2, "Session %s does not exist", hello2.Hello.SessionId)
|
||||
|
||||
// Client 1 may not send control messages (will be ignored).
|
||||
session1.SetPermissions([]Permission{
|
||||
PERMISSION_MAY_PUBLISH_AUDIO,
|
||||
PERMISSION_MAY_PUBLISH_VIDEO,
|
||||
session1.SetPermissions([]api.Permission{
|
||||
api.PERMISSION_MAY_PUBLISH_AUDIO,
|
||||
api.PERMISSION_MAY_PUBLISH_VIDEO,
|
||||
})
|
||||
// Client 2 may send control messages.
|
||||
session2.SetPermissions([]Permission{
|
||||
PERMISSION_MAY_PUBLISH_AUDIO,
|
||||
PERMISSION_MAY_PUBLISH_VIDEO,
|
||||
PERMISSION_MAY_CONTROL,
|
||||
session2.SetPermissions([]api.Permission{
|
||||
api.PERMISSION_MAY_PUBLISH_AUDIO,
|
||||
api.PERMISSION_MAY_PUBLISH_VIDEO,
|
||||
api.PERMISSION_MAY_CONTROL,
|
||||
})
|
||||
|
||||
recipient1 := api.MessageClientMessageRecipient{
|
||||
|
|
@ -2972,7 +2972,7 @@ func TestJoinDisplaynamesPermission(t *testing.T) {
|
|||
require.NotNil(session2, "Session %s does not exist", hello2.Hello.SessionId)
|
||||
|
||||
// Client 2 may not receive display names.
|
||||
session2.SetPermissions([]Permission{PERMISSION_HIDE_DISPLAYNAMES})
|
||||
session2.SetPermissions([]api.Permission{api.PERMISSION_HIDE_DISPLAYNAMES})
|
||||
|
||||
// Join room by id (first client).
|
||||
roomId := "test-room"
|
||||
|
|
@ -3024,8 +3024,8 @@ func TestInitialRoomPermissions(t *testing.T) {
|
|||
session := hub.GetSessionByPublicId(hello.Hello.SessionId).(*ClientSession)
|
||||
require.NotNil(session, "Session %s does not exist", hello.Hello.SessionId)
|
||||
|
||||
assert.True(session.HasPermission(PERMISSION_MAY_PUBLISH_AUDIO), "Session %s should have %s, got %+v", session.PublicId(), PERMISSION_MAY_PUBLISH_AUDIO, session.GetPermissions())
|
||||
assert.False(session.HasPermission(PERMISSION_MAY_PUBLISH_VIDEO), "Session %s should not have %s, got %+v", session.PublicId(), PERMISSION_MAY_PUBLISH_VIDEO, session.GetPermissions())
|
||||
assert.True(session.HasPermission(api.PERMISSION_MAY_PUBLISH_AUDIO), "Session %s should have %s, got %+v", session.PublicId(), api.PERMISSION_MAY_PUBLISH_AUDIO, session.GetPermissions())
|
||||
assert.False(session.HasPermission(api.PERMISSION_MAY_PUBLISH_VIDEO), "Session %s should not have %s, got %+v", session.PublicId(), api.PERMISSION_MAY_PUBLISH_VIDEO, session.GetPermissions())
|
||||
}
|
||||
|
||||
func TestJoinRoomSwitchClient(t *testing.T) {
|
||||
|
|
@ -3382,18 +3382,18 @@ func TestCombineChatRefreshWhileDisconnected(t *testing.T) {
|
|||
// Simulate requests from the backend.
|
||||
room.processAsyncMessage(&AsyncMessage{
|
||||
Type: "room",
|
||||
Room: &BackendServerRoomRequest{
|
||||
Room: &talk.BackendServerRoomRequest{
|
||||
Type: "message",
|
||||
Message: &BackendRoomMessageRequest{
|
||||
Message: &talk.BackendRoomMessageRequest{
|
||||
Data: json.RawMessage(chat_refresh),
|
||||
},
|
||||
},
|
||||
})
|
||||
room.processAsyncMessage(&AsyncMessage{
|
||||
Type: "room",
|
||||
Room: &BackendServerRoomRequest{
|
||||
Room: &talk.BackendServerRoomRequest{
|
||||
Type: "message",
|
||||
Message: &BackendRoomMessageRequest{
|
||||
Message: &talk.BackendRoomMessageRequest{
|
||||
Data: json.RawMessage(chat_refresh),
|
||||
},
|
||||
},
|
||||
|
|
@ -3628,9 +3628,9 @@ func TestClientSendOfferPermissions(t *testing.T) {
|
|||
require.NotNil(session2, "Session %s does not exist", hello2.Hello.SessionId)
|
||||
|
||||
// Client 1 is the moderator
|
||||
session1.SetPermissions([]Permission{PERMISSION_MAY_PUBLISH_MEDIA, PERMISSION_MAY_PUBLISH_SCREEN})
|
||||
session1.SetPermissions([]api.Permission{api.PERMISSION_MAY_PUBLISH_MEDIA, api.PERMISSION_MAY_PUBLISH_SCREEN})
|
||||
// Client 2 is a guest participant.
|
||||
session2.SetPermissions([]Permission{})
|
||||
session2.SetPermissions([]api.Permission{})
|
||||
|
||||
// Client 2 may not send an offer (he doesn't have the necessary permissions).
|
||||
require.NoError(client2.SendMessage(api.MessageClientMessageRecipient{
|
||||
|
|
@ -3706,7 +3706,7 @@ func TestClientSendOfferPermissionsAudioOnly(t *testing.T) {
|
|||
require.NotNil(session, "Session %s does not exist", hello.Hello.SessionId)
|
||||
|
||||
// Client is allowed to send audio only.
|
||||
session.SetPermissions([]Permission{PERMISSION_MAY_PUBLISH_AUDIO})
|
||||
session.SetPermissions([]api.Permission{api.PERMISSION_MAY_PUBLISH_AUDIO})
|
||||
|
||||
// Client may not send an offer with audio and video.
|
||||
require.NoError(client.SendMessage(api.MessageClientMessageRecipient{
|
||||
|
|
@ -3768,7 +3768,7 @@ func TestClientSendOfferPermissionsAudioVideo(t *testing.T) {
|
|||
require.NotNil(session, "Session %s does not exist", hello.Hello.SessionId)
|
||||
|
||||
// Client is allowed to send audio and video.
|
||||
session.SetPermissions([]Permission{PERMISSION_MAY_PUBLISH_AUDIO, PERMISSION_MAY_PUBLISH_VIDEO})
|
||||
session.SetPermissions([]api.Permission{api.PERMISSION_MAY_PUBLISH_AUDIO, api.PERMISSION_MAY_PUBLISH_VIDEO})
|
||||
|
||||
require.NoError(client.SendMessage(api.MessageClientMessageRecipient{
|
||||
Type: "session",
|
||||
|
|
@ -3785,19 +3785,19 @@ func TestClientSendOfferPermissionsAudioVideo(t *testing.T) {
|
|||
require.True(client.RunUntilAnswer(ctx, mock.MockSdpAnswerAudioAndVideo))
|
||||
|
||||
// Client is no longer allowed to send video, this will stop the publisher.
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "participants",
|
||||
Participants: &BackendRoomParticipantsRequest{
|
||||
Participants: &talk.BackendRoomParticipantsRequest{
|
||||
Changed: []api.StringMap{
|
||||
{
|
||||
"sessionId": fmt.Sprintf("%s-%s", roomId, hello.Hello.SessionId),
|
||||
"permissions": []Permission{PERMISSION_MAY_PUBLISH_AUDIO},
|
||||
"permissions": []api.Permission{api.PERMISSION_MAY_PUBLISH_AUDIO},
|
||||
},
|
||||
},
|
||||
Users: []api.StringMap{
|
||||
{
|
||||
"sessionId": fmt.Sprintf("%s-%s", roomId, hello.Hello.SessionId),
|
||||
"permissions": []Permission{PERMISSION_MAY_PUBLISH_AUDIO},
|
||||
"permissions": []api.Permission{api.PERMISSION_MAY_PUBLISH_AUDIO},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -3864,7 +3864,7 @@ func TestClientSendOfferPermissionsAudioVideoMedia(t *testing.T) {
|
|||
require.NotNil(session, "Session %s does not exist", hello.Hello.SessionId)
|
||||
|
||||
// Client is allowed to send audio and video.
|
||||
session.SetPermissions([]Permission{PERMISSION_MAY_PUBLISH_MEDIA})
|
||||
session.SetPermissions([]api.Permission{api.PERMISSION_MAY_PUBLISH_MEDIA})
|
||||
|
||||
// Client may send an offer (audio and video).
|
||||
require.NoError(client.SendMessage(api.MessageClientMessageRecipient{
|
||||
|
|
@ -3882,19 +3882,19 @@ func TestClientSendOfferPermissionsAudioVideoMedia(t *testing.T) {
|
|||
require.True(client.RunUntilAnswer(ctx, mock.MockSdpAnswerAudioAndVideo))
|
||||
|
||||
// Client is no longer allowed to send video, this will stop the publisher.
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "participants",
|
||||
Participants: &BackendRoomParticipantsRequest{
|
||||
Participants: &talk.BackendRoomParticipantsRequest{
|
||||
Changed: []api.StringMap{
|
||||
{
|
||||
"sessionId": fmt.Sprintf("%s-%s", roomId, hello.Hello.SessionId),
|
||||
"permissions": []Permission{PERMISSION_MAY_PUBLISH_MEDIA, PERMISSION_MAY_CONTROL},
|
||||
"permissions": []api.Permission{api.PERMISSION_MAY_PUBLISH_MEDIA, api.PERMISSION_MAY_CONTROL},
|
||||
},
|
||||
},
|
||||
Users: []api.StringMap{
|
||||
{
|
||||
"sessionId": fmt.Sprintf("%s-%s", roomId, hello.Hello.SessionId),
|
||||
"permissions": []Permission{PERMISSION_MAY_PUBLISH_MEDIA, PERMISSION_MAY_CONTROL},
|
||||
"permissions": []api.Permission{api.PERMISSION_MAY_PUBLISH_MEDIA, api.PERMISSION_MAY_CONTROL},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -4552,7 +4552,7 @@ func TestVirtualClientSessions(t *testing.T) {
|
|||
virtualUserId := "virtual-user-id"
|
||||
generatedSessionId := GetVirtualSessionId(session2, virtualSessionId)
|
||||
|
||||
setSessionRequestHandler(t, func(request *BackendClientSessionRequest) {
|
||||
setSessionRequestHandler(t, func(request *talk.BackendClientSessionRequest) {
|
||||
defer calledCancel()
|
||||
assert.Equal("add", request.Action, "%+v", request)
|
||||
assert.Equal(roomId, request.RoomId, "%+v", request)
|
||||
|
|
@ -4661,7 +4661,7 @@ func TestVirtualClientSessions(t *testing.T) {
|
|||
|
||||
calledCtx, calledCancel = context.WithTimeout(ctx, time.Second)
|
||||
|
||||
setSessionRequestHandler(t, func(request *BackendClientSessionRequest) {
|
||||
setSessionRequestHandler(t, func(request *talk.BackendClientSessionRequest) {
|
||||
defer calledCancel()
|
||||
assert.Equal("remove", request.Action, "%+v", request)
|
||||
assert.Equal(roomId, request.RoomId, "%+v", request)
|
||||
|
|
@ -4794,7 +4794,7 @@ func TestDuplicateVirtualSessions(t *testing.T) {
|
|||
virtualUserId := "virtual-user-id"
|
||||
generatedSessionId := GetVirtualSessionId(session2, virtualSessionId)
|
||||
|
||||
setSessionRequestHandler(t, func(request *BackendClientSessionRequest) {
|
||||
setSessionRequestHandler(t, func(request *talk.BackendClientSessionRequest) {
|
||||
defer calledCancel()
|
||||
assert.Equal("add", request.Action, "%+v", request)
|
||||
assert.Equal(roomId, request.RoomId, "%+v", request)
|
||||
|
|
@ -4874,9 +4874,9 @@ func TestDuplicateVirtualSessions(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "incall",
|
||||
InCall: &BackendRoomInCallRequest{
|
||||
InCall: &talk.BackendRoomInCallRequest{
|
||||
InCall: []byte("0"),
|
||||
Users: []api.StringMap{
|
||||
{
|
||||
|
|
@ -4981,7 +4981,7 @@ func TestDuplicateVirtualSessions(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
setSessionRequestHandler(t, func(request *BackendClientSessionRequest) {
|
||||
setSessionRequestHandler(t, func(request *talk.BackendClientSessionRequest) {
|
||||
defer calledCancel()
|
||||
assert.Equal("remove", request.Action, "%+v", request)
|
||||
assert.Equal(roomId, request.RoomId, "%+v", request)
|
||||
|
|
@ -5045,9 +5045,9 @@ func DoTestSwitchToOne(t *testing.T, details api.StringMap) {
|
|||
}
|
||||
|
||||
// Notify first client to switch to different room.
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "switchto",
|
||||
SwitchTo: &BackendRoomSwitchToMessageRequest{
|
||||
SwitchTo: &talk.BackendRoomSwitchToMessageRequest{
|
||||
RoomId: roomId2,
|
||||
Sessions: sessions,
|
||||
},
|
||||
|
|
@ -5146,9 +5146,9 @@ func DoTestSwitchToMultiple(t *testing.T, details1 api.StringMap, details2 api.S
|
|||
require.NoError(err)
|
||||
}
|
||||
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "switchto",
|
||||
SwitchTo: &BackendRoomSwitchToMessageRequest{
|
||||
SwitchTo: &talk.BackendRoomSwitchToMessageRequest{
|
||||
RoomId: roomId2,
|
||||
Sessions: sessions,
|
||||
},
|
||||
|
|
@ -5291,9 +5291,9 @@ func TestDialoutStatus(t *testing.T) {
|
|||
<-stopped
|
||||
}()
|
||||
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "dialout",
|
||||
Dialout: &BackendRoomDialoutRequest{
|
||||
Dialout: &talk.BackendRoomDialoutRequest{
|
||||
Number: "+1234567890",
|
||||
},
|
||||
}
|
||||
|
|
@ -5307,7 +5307,7 @@ func TestDialoutStatus(t *testing.T) {
|
|||
assert.NoError(err)
|
||||
require.Equal(http.StatusOK, res.StatusCode, "Expected success, got %s", string(body))
|
||||
|
||||
var response BackendServerRoomResponse
|
||||
var response talk.BackendServerRoomResponse
|
||||
if assert.NoError(json.Unmarshal(body, &response)) {
|
||||
assert.Equal("dialout", response.Type)
|
||||
if assert.NotNil(response.Dialout) {
|
||||
|
|
|
|||
34
internal/random_string.go
Normal file
34
internal/random_string.go
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* Standalone signaling server for the Nextcloud Spreed app.
|
||||
* Copyright (C) 2025 struktur AG
|
||||
*
|
||||
* @author Joachim Bauch <bauch@struktur.de>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package internal
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
)
|
||||
|
||||
func RandomString(size int) string {
|
||||
s := rand.Text()
|
||||
for len(s) < size {
|
||||
s += rand.Text()
|
||||
}
|
||||
return s[:size]
|
||||
}
|
||||
41
internal/random_string_test.go
Normal file
41
internal/random_string_test.go
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* Standalone signaling server for the Nextcloud Spreed app.
|
||||
* Copyright (C) 2025 struktur AG
|
||||
*
|
||||
* @author Joachim Bauch <bauch@struktur.de>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package internal
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRandomString(t *testing.T) {
|
||||
t.Parallel()
|
||||
assert := assert.New(t)
|
||||
|
||||
s1 := RandomString(10)
|
||||
assert.Len(s1, 10)
|
||||
assert.NotEqual(s1, RandomString(10))
|
||||
|
||||
s2 := RandomString(123)
|
||||
assert.Len(s2, 123)
|
||||
assert.NotEqual(s2, RandomString(123))
|
||||
}
|
||||
|
|
@ -32,6 +32,7 @@ import (
|
|||
"github.com/strukturag/nextcloud-spreed-signaling/api"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/geoip"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/talk"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -135,7 +136,7 @@ type Mcu interface {
|
|||
SetOnDisconnected(func())
|
||||
|
||||
GetStats() any
|
||||
GetServerInfoSfu() *BackendServerInfoSfu
|
||||
GetServerInfoSfu() *talk.BackendServerInfoSfu
|
||||
GetBandwidthLimits() (api.Bandwidth, api.Bandwidth)
|
||||
|
||||
NewPublisher(ctx context.Context, listener McuListener, id api.PublicSessionId, sid string, streamType StreamType, settings NewPublisherSettings, initiator McuInitiator) (McuPublisher, error)
|
||||
|
|
|
|||
11
mcu_janus.go
11
mcu_janus.go
|
|
@ -39,6 +39,7 @@ import (
|
|||
"github.com/strukturag/nextcloud-spreed-signaling/container"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/talk"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -581,8 +582,8 @@ func (m *mcuJanus) Info() *InfoMsg {
|
|||
return m.info.Load()
|
||||
}
|
||||
|
||||
func (m *mcuJanus) GetServerInfoSfu() *BackendServerInfoSfu {
|
||||
janus := &BackendServerInfoSfuJanus{
|
||||
func (m *mcuJanus) GetServerInfoSfu() *talk.BackendServerInfoSfu {
|
||||
janus := &talk.BackendServerInfoSfuJanus{
|
||||
Url: m.url,
|
||||
}
|
||||
if m.IsConnected() {
|
||||
|
|
@ -597,7 +598,7 @@ func (m *mcuJanus) GetServerInfoSfu() *BackendServerInfoSfu {
|
|||
janus.IPv6 = internal.MakePtr(info.IPv6)
|
||||
|
||||
if plugin, found := info.Plugins[pluginVideoRoom]; found {
|
||||
janus.VideoRoom = &BackendServerInfoVideoRoom{
|
||||
janus.VideoRoom = &talk.BackendServerInfoVideoRoom{
|
||||
Name: plugin.Name,
|
||||
Version: plugin.VersionString,
|
||||
Author: plugin.Author,
|
||||
|
|
@ -606,8 +607,8 @@ func (m *mcuJanus) GetServerInfoSfu() *BackendServerInfoSfu {
|
|||
}
|
||||
}
|
||||
|
||||
sfu := &BackendServerInfoSfu{
|
||||
Mode: SfuModeJanus,
|
||||
sfu := &talk.BackendServerInfoSfu{
|
||||
Mode: talk.SfuModeJanus,
|
||||
Janus: janus,
|
||||
}
|
||||
return sfu
|
||||
|
|
|
|||
20
mcu_proxy.go
20
mcu_proxy.go
|
|
@ -53,6 +53,7 @@ import (
|
|||
"github.com/strukturag/nextcloud-spreed-signaling/geoip"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/talk"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -1878,15 +1879,15 @@ func (m *mcuProxy) GetStats() any {
|
|||
return result
|
||||
}
|
||||
|
||||
func (m *mcuProxy) GetServerInfoSfu() *BackendServerInfoSfu {
|
||||
func (m *mcuProxy) GetServerInfoSfu() *talk.BackendServerInfoSfu {
|
||||
m.connectionsMu.RLock()
|
||||
defer m.connectionsMu.RUnlock()
|
||||
|
||||
sfu := &BackendServerInfoSfu{
|
||||
Mode: SfuModeProxy,
|
||||
sfu := &talk.BackendServerInfoSfu{
|
||||
Mode: talk.SfuModeProxy,
|
||||
}
|
||||
for _, c := range m.connections {
|
||||
proxy := BackendServerInfoSfuProxy{
|
||||
proxy := talk.BackendServerInfoSfuProxy{
|
||||
Url: c.rawUrl,
|
||||
|
||||
Temporary: c.IsTemporary(),
|
||||
|
|
@ -1905,11 +1906,18 @@ func (m *mcuProxy) GetServerInfoSfu() *BackendServerInfoSfu {
|
|||
proxy.Features = c.Features()
|
||||
proxy.Country = c.Country()
|
||||
proxy.Load = internal.MakePtr(c.Load())
|
||||
proxy.Bandwidth = c.Bandwidth()
|
||||
if bw := c.Bandwidth(); bw != nil {
|
||||
proxy.Bandwidth = &talk.BackendServerInfoSfuProxyBandwidth{
|
||||
Incoming: bw.Incoming,
|
||||
Outgoing: bw.Outgoing,
|
||||
Received: bw.Received,
|
||||
Sent: bw.Sent,
|
||||
}
|
||||
}
|
||||
}
|
||||
sfu.Proxies = append(sfu.Proxies, proxy)
|
||||
}
|
||||
slices.SortFunc(sfu.Proxies, func(a, b BackendServerInfoSfuProxy) int {
|
||||
slices.SortFunc(sfu.Proxies, func(a, b talk.BackendServerInfoSfuProxy) int {
|
||||
c := strings.Compare(a.Url, b.Url)
|
||||
if c == 0 {
|
||||
c = strings.Compare(a.IP, b.IP)
|
||||
|
|
|
|||
|
|
@ -582,7 +582,7 @@ func (h *TestProxyServerHandler) createPublisher() *testProxyServerPublisher {
|
|||
h.mu.Lock()
|
||||
defer h.mu.Unlock()
|
||||
pub := &testProxyServerPublisher{
|
||||
id: api.PublicSessionId(newRandomString(32)),
|
||||
id: api.PublicSessionId(internal.RandomString(32)),
|
||||
}
|
||||
|
||||
for {
|
||||
|
|
@ -590,7 +590,7 @@ func (h *TestProxyServerHandler) createPublisher() *testProxyServerPublisher {
|
|||
break
|
||||
}
|
||||
|
||||
pub.id = api.PublicSessionId(newRandomString(32))
|
||||
pub.id = api.PublicSessionId(internal.RandomString(32))
|
||||
}
|
||||
h.publishers[pub.id] = pub
|
||||
return pub
|
||||
|
|
@ -621,8 +621,8 @@ func (h *TestProxyServerHandler) createSubscriber(pub *testProxyServerPublisher)
|
|||
defer h.mu.Unlock()
|
||||
|
||||
sub := &testProxyServerSubscriber{
|
||||
id: newRandomString(32),
|
||||
sid: newRandomString(8),
|
||||
id: internal.RandomString(32),
|
||||
sid: internal.RandomString(8),
|
||||
pub: pub,
|
||||
}
|
||||
|
||||
|
|
@ -631,7 +631,7 @@ func (h *TestProxyServerHandler) createSubscriber(pub *testProxyServerPublisher)
|
|||
break
|
||||
}
|
||||
|
||||
sub.id = newRandomString(32)
|
||||
sub.id = internal.RandomString(32)
|
||||
}
|
||||
h.subscribers[sub.id] = sub
|
||||
return sub
|
||||
|
|
@ -753,7 +753,7 @@ func (h *TestProxyServerHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
|
|||
t: h.t,
|
||||
server: h,
|
||||
ws: ws,
|
||||
sessionId: api.PublicSessionId(newRandomString(32)),
|
||||
sessionId: api.PublicSessionId(internal.RandomString(32)),
|
||||
}
|
||||
|
||||
h.setClient(client.sessionId, client)
|
||||
|
|
|
|||
|
|
@ -33,8 +33,10 @@ import (
|
|||
"github.com/dlintw/goconf"
|
||||
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/api"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/mock"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/talk"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -92,7 +94,7 @@ func (m *TestMCU) GetStats() any {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *TestMCU) GetServerInfoSfu() *BackendServerInfoSfu {
|
||||
func (m *TestMCU) GetServerInfoSfu() *talk.BackendServerInfoSfu {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -150,7 +152,7 @@ func (m *TestMCU) NewSubscriber(ctx context.Context, listener McuListener, publi
|
|||
return nil, errors.New("Waiting for publisher not implemented yet")
|
||||
}
|
||||
|
||||
id := newRandomString(8)
|
||||
id := internal.RandomString(8)
|
||||
sub := &TestMCUSubscriber{
|
||||
TestMCUClient: TestMCUClient{
|
||||
t: m.t,
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ import (
|
|||
"github.com/strukturag/nextcloud-spreed-signaling/api"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/talk"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -387,7 +388,7 @@ func (m *TestMCU) GetStats() any {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *TestMCU) GetServerInfoSfu() *signaling.BackendServerInfoSfu {
|
||||
func (m *TestMCU) GetServerInfoSfu() *talk.BackendServerInfoSfu {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
49
room.go
49
room.go
|
|
@ -88,7 +88,7 @@ type Room struct {
|
|||
// +checklocks:mu
|
||||
inCallSessions map[Session]bool
|
||||
// +checklocks:mu
|
||||
roomSessionData map[api.PublicSessionId]*RoomSessionData
|
||||
roomSessionData map[api.PublicSessionId]*talk.RoomSessionData
|
||||
|
||||
// +checklocks:mu
|
||||
statsRoomSessionsCurrent *prometheus.GaugeVec
|
||||
|
|
@ -128,7 +128,7 @@ func NewRoom(roomId string, properties json.RawMessage, hub *Hub, events AsyncEv
|
|||
internalSessions: make(map[*ClientSession]bool),
|
||||
virtualSessions: make(map[*VirtualSession]bool),
|
||||
inCallSessions: make(map[Session]bool),
|
||||
roomSessionData: make(map[api.PublicSessionId]*RoomSessionData),
|
||||
roomSessionData: make(map[api.PublicSessionId]*talk.RoomSessionData),
|
||||
|
||||
statsRoomSessionsCurrent: statsRoomSessionsCurrent.MustCurryWith(prometheus.Labels{
|
||||
"backend": backend.Id(),
|
||||
|
|
@ -255,7 +255,7 @@ func (r *Room) processAsyncMessage(message *AsyncMessage) {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *Room) processBackendRoomRequestRoom(message *BackendServerRoomRequest) {
|
||||
func (r *Room) processBackendRoomRequestRoom(message *talk.BackendServerRoomRequest) {
|
||||
received := message.ReceivedTime
|
||||
if last, found := r.lastRoomRequests[message.Type]; found && last > received {
|
||||
if msg, err := json.Marshal(message); err == nil {
|
||||
|
|
@ -267,7 +267,8 @@ func (r *Room) processBackendRoomRequestRoom(message *BackendServerRoomRequest)
|
|||
}
|
||||
|
||||
r.lastRoomRequests[message.Type] = received
|
||||
message.room = r
|
||||
message.RoomId = r.Id()
|
||||
message.Backend = r.Backend()
|
||||
switch message.Type {
|
||||
case "update":
|
||||
r.hub.roomUpdated <- message
|
||||
|
|
@ -284,13 +285,13 @@ func (r *Room) processBackendRoomRequestRoom(message *BackendServerRoomRequest)
|
|||
r.publishSwitchTo(message.SwitchTo)
|
||||
case "transient":
|
||||
switch message.Transient.Action {
|
||||
case TransientActionSet:
|
||||
case talk.TransientActionSet:
|
||||
if message.Transient.TTL == 0 {
|
||||
r.doSetTransientData(message.Transient.Key, message.Transient.Value)
|
||||
} else {
|
||||
r.doSetTransientDataTTL(message.Transient.Key, message.Transient.Value, message.Transient.TTL)
|
||||
}
|
||||
case TransientActionDelete:
|
||||
case talk.TransientActionDelete:
|
||||
r.doRemoveTransientData(message.Transient.Key)
|
||||
default:
|
||||
r.logger.Printf("Unsupported transient action in room %s: %+v", r.Id(), message.Transient)
|
||||
|
|
@ -313,9 +314,9 @@ func (r *Room) processBackendRoomRequestAsyncRoom(message *AsyncRoomMessage) {
|
|||
}
|
||||
|
||||
func (r *Room) AddSession(session Session, sessionData json.RawMessage) {
|
||||
var roomSessionData *RoomSessionData
|
||||
var roomSessionData *talk.RoomSessionData
|
||||
if len(sessionData) > 0 {
|
||||
roomSessionData = &RoomSessionData{}
|
||||
roomSessionData = &talk.RoomSessionData{}
|
||||
if err := json.Unmarshal(sessionData, roomSessionData); err != nil {
|
||||
r.logger.Printf("Error decoding room session data \"%s\": %s", string(sessionData), err)
|
||||
roomSessionData = nil
|
||||
|
|
@ -572,13 +573,13 @@ func (r *Room) UpdateProperties(properties json.RawMessage) {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *Room) GetRoomSessionData(session Session) *RoomSessionData {
|
||||
func (r *Room) GetRoomSessionData(session Session) *talk.RoomSessionData {
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
return r.roomSessionData[session.PublicId()]
|
||||
}
|
||||
|
||||
func (r *Room) PublishSessionJoined(session Session, sessionData *RoomSessionData) {
|
||||
func (r *Room) PublishSessionJoined(session Session, sessionData *talk.RoomSessionData) {
|
||||
sessionId := session.PublicId()
|
||||
if sessionId == "" {
|
||||
return
|
||||
|
|
@ -1072,7 +1073,7 @@ func (r *Room) publishActiveSessions() (int, *sync.WaitGroup) {
|
|||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
|
||||
entries := make(map[string][]BackendPingEntry)
|
||||
entries := make(map[string][]talk.BackendPingEntry)
|
||||
urls := make(map[string]*url.URL)
|
||||
for _, session := range r.sessions {
|
||||
u := session.BackendUrl()
|
||||
|
|
@ -1120,7 +1121,7 @@ func (r *Room) publishActiveSessions() (int, *sync.WaitGroup) {
|
|||
urls[u] = parsedBackendUrl
|
||||
}
|
||||
|
||||
entries[u] = append(e, BackendPingEntry{
|
||||
entries[u] = append(e, talk.BackendPingEntry{
|
||||
SessionId: sid,
|
||||
UserId: uid,
|
||||
})
|
||||
|
|
@ -1134,7 +1135,7 @@ func (r *Room) publishActiveSessions() (int, *sync.WaitGroup) {
|
|||
for u, e := range entries {
|
||||
wg.Add(1)
|
||||
count += len(e)
|
||||
go func(url *url.URL, entries []BackendPingEntry) {
|
||||
go func(url *url.URL, entries []talk.BackendPingEntry) {
|
||||
defer wg.Done()
|
||||
sendCtx, cancel := context.WithTimeout(ctx, r.hub.backendTimeout)
|
||||
defer cancel()
|
||||
|
|
@ -1147,7 +1148,7 @@ func (r *Room) publishActiveSessions() (int, *sync.WaitGroup) {
|
|||
return count, &wg
|
||||
}
|
||||
|
||||
func (r *Room) publishRoomMessage(message *BackendRoomMessageRequest) {
|
||||
func (r *Room) publishRoomMessage(message *talk.BackendRoomMessageRequest) {
|
||||
if message == nil || len(message.Data) == 0 {
|
||||
return
|
||||
}
|
||||
|
|
@ -1168,7 +1169,7 @@ func (r *Room) publishRoomMessage(message *BackendRoomMessageRequest) {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *Room) publishSwitchTo(message *BackendRoomSwitchToMessageRequest) {
|
||||
func (r *Room) publishSwitchTo(message *talk.BackendRoomSwitchToMessageRequest) {
|
||||
var wg sync.WaitGroup
|
||||
if len(message.SessionsList) > 0 {
|
||||
msg := &api.ServerMessage{
|
||||
|
|
@ -1250,10 +1251,10 @@ func (r *Room) SetTransientData(key string, value any) error {
|
|||
|
||||
return r.events.PublishBackendRoomMessage(r.Id(), r.Backend(), &AsyncMessage{
|
||||
Type: "room",
|
||||
Room: &BackendServerRoomRequest{
|
||||
Room: &talk.BackendServerRoomRequest{
|
||||
Type: "transient",
|
||||
Transient: &BackendRoomTransientRequest{
|
||||
Action: TransientActionSet,
|
||||
Transient: &talk.BackendRoomTransientRequest{
|
||||
Action: talk.TransientActionSet,
|
||||
Key: key,
|
||||
Value: value,
|
||||
},
|
||||
|
|
@ -1274,10 +1275,10 @@ func (r *Room) SetTransientDataTTL(key string, value any, ttl time.Duration) err
|
|||
|
||||
return r.events.PublishBackendRoomMessage(r.Id(), r.Backend(), &AsyncMessage{
|
||||
Type: "room",
|
||||
Room: &BackendServerRoomRequest{
|
||||
Room: &talk.BackendServerRoomRequest{
|
||||
Type: "transient",
|
||||
Transient: &BackendRoomTransientRequest{
|
||||
Action: TransientActionSet,
|
||||
Transient: &talk.BackendRoomTransientRequest{
|
||||
Action: talk.TransientActionSet,
|
||||
Key: key,
|
||||
Value: value,
|
||||
TTL: ttl,
|
||||
|
|
@ -1293,10 +1294,10 @@ func (r *Room) doSetTransientDataTTL(key string, value any, ttl time.Duration) {
|
|||
func (r *Room) RemoveTransientData(key string) error {
|
||||
return r.events.PublishBackendRoomMessage(r.Id(), r.Backend(), &AsyncMessage{
|
||||
Type: "room",
|
||||
Room: &BackendServerRoomRequest{
|
||||
Room: &talk.BackendServerRoomRequest{
|
||||
Type: "transient",
|
||||
Transient: &BackendRoomTransientRequest{
|
||||
Action: TransientActionDelete,
|
||||
Transient: &talk.BackendRoomTransientRequest{
|
||||
Action: talk.TransientActionDelete,
|
||||
Key: key,
|
||||
},
|
||||
},
|
||||
|
|
|
|||
28
room_ping.go
28
room_ping.go
|
|
@ -36,19 +36,19 @@ import (
|
|||
type pingEntries struct {
|
||||
url *url.URL
|
||||
|
||||
entries map[string][]BackendPingEntry
|
||||
entries map[string][]talk.BackendPingEntry
|
||||
}
|
||||
|
||||
func newPingEntries(url *url.URL, roomId string, entries []BackendPingEntry) *pingEntries {
|
||||
func newPingEntries(url *url.URL, roomId string, entries []talk.BackendPingEntry) *pingEntries {
|
||||
return &pingEntries{
|
||||
url: url,
|
||||
entries: map[string][]BackendPingEntry{
|
||||
entries: map[string][]talk.BackendPingEntry{
|
||||
roomId: entries,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (e *pingEntries) Add(roomId string, entries []BackendPingEntry) {
|
||||
func (e *pingEntries) Add(roomId string, entries []talk.BackendPingEntry) {
|
||||
if existing, found := e.entries[roomId]; found {
|
||||
e.entries[roomId] = append(existing, entries...)
|
||||
} else {
|
||||
|
|
@ -121,7 +121,7 @@ func (p *RoomPing) publishEntries(ctx context.Context, entries *pingEntries, tim
|
|||
ctx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
limit, _, found := p.capabilities.GetIntegerConfig(ctx, entries.url, ConfigGroupSignaling, ConfigKeySessionPingLimit)
|
||||
limit, _, found := p.capabilities.GetIntegerConfig(ctx, entries.url, talk.ConfigGroupSignaling, talk.ConfigKeySessionPingLimit)
|
||||
if !found || limit <= 0 {
|
||||
// Limit disabled while waiting for the next iteration, fallback to sending
|
||||
// one request per room.
|
||||
|
|
@ -137,7 +137,7 @@ func (p *RoomPing) publishEntries(ctx context.Context, entries *pingEntries, tim
|
|||
return
|
||||
}
|
||||
|
||||
var allEntries []BackendPingEntry
|
||||
var allEntries []talk.BackendPingEntry
|
||||
for _, e := range entries.entries {
|
||||
allEntries = append(allEntries, e...)
|
||||
}
|
||||
|
|
@ -164,28 +164,28 @@ func (p *RoomPing) publishActiveSessions(ctx context.Context) {
|
|||
wg.Wait()
|
||||
}
|
||||
|
||||
func (p *RoomPing) sendPingsDirect(ctx context.Context, roomId string, url *url.URL, entries []BackendPingEntry) error {
|
||||
request := NewBackendClientPingRequest(roomId, entries)
|
||||
var response BackendClientResponse
|
||||
func (p *RoomPing) sendPingsDirect(ctx context.Context, roomId string, url *url.URL, entries []talk.BackendPingEntry) error {
|
||||
request := talk.NewBackendClientPingRequest(roomId, entries)
|
||||
var response talk.BackendClientResponse
|
||||
return p.backend.PerformJSONRequest(ctx, url, request, &response)
|
||||
}
|
||||
|
||||
func (p *RoomPing) sendPingsCombined(ctx context.Context, url *url.URL, entries []BackendPingEntry, limit int, timeout time.Duration) {
|
||||
func (p *RoomPing) sendPingsCombined(ctx context.Context, url *url.URL, entries []talk.BackendPingEntry, limit int, timeout time.Duration) {
|
||||
logger := log.LoggerFromContext(ctx)
|
||||
for tosend := range slices.Chunk(entries, limit) {
|
||||
subCtx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
request := NewBackendClientPingRequest("", tosend)
|
||||
var response BackendClientResponse
|
||||
request := talk.NewBackendClientPingRequest("", tosend)
|
||||
var response talk.BackendClientResponse
|
||||
if err := p.backend.PerformJSONRequest(subCtx, url, request, &response); err != nil {
|
||||
logger.Printf("Error sending combined ping session entries %+v to %s: %s", tosend, url, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *RoomPing) SendPings(ctx context.Context, roomId string, url *url.URL, entries []BackendPingEntry) error {
|
||||
limit, _, found := p.capabilities.GetIntegerConfig(ctx, url, ConfigGroupSignaling, ConfigKeySessionPingLimit)
|
||||
func (p *RoomPing) SendPings(ctx context.Context, roomId string, url *url.URL, entries []talk.BackendPingEntry) error {
|
||||
limit, _, found := p.capabilities.GetIntegerConfig(ctx, url, talk.ConfigGroupSignaling, talk.ConfigKeySessionPingLimit)
|
||||
if !found || limit <= 0 {
|
||||
// Old-style Nextcloud or session limit not configured. Perform one request
|
||||
// per room. Don't queue to avoid sending all ping requests to old-style
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/talk"
|
||||
)
|
||||
|
||||
func NewRoomPingForTest(ctx context.Context, t *testing.T) (*url.URL, *RoomPing) {
|
||||
|
|
@ -72,7 +73,7 @@ func TestSingleRoomPing(t *testing.T) {
|
|||
room1 := &Room{
|
||||
id: "sample-room-1",
|
||||
}
|
||||
entries1 := []BackendPingEntry{
|
||||
entries1 := []talk.BackendPingEntry{
|
||||
{
|
||||
UserId: "foo",
|
||||
SessionId: "123",
|
||||
|
|
@ -87,7 +88,7 @@ func TestSingleRoomPing(t *testing.T) {
|
|||
room2 := &Room{
|
||||
id: "sample-room-2",
|
||||
}
|
||||
entries2 := []BackendPingEntry{
|
||||
entries2 := []talk.BackendPingEntry{
|
||||
{
|
||||
UserId: "bar",
|
||||
SessionId: "456",
|
||||
|
|
@ -116,7 +117,7 @@ func TestMultiRoomPing(t *testing.T) {
|
|||
room1 := &Room{
|
||||
id: "sample-room-1",
|
||||
}
|
||||
entries1 := []BackendPingEntry{
|
||||
entries1 := []talk.BackendPingEntry{
|
||||
{
|
||||
UserId: "foo",
|
||||
SessionId: "123",
|
||||
|
|
@ -128,7 +129,7 @@ func TestMultiRoomPing(t *testing.T) {
|
|||
room2 := &Room{
|
||||
id: "sample-room-2",
|
||||
}
|
||||
entries2 := []BackendPingEntry{
|
||||
entries2 := []talk.BackendPingEntry{
|
||||
{
|
||||
UserId: "bar",
|
||||
SessionId: "456",
|
||||
|
|
@ -156,7 +157,7 @@ func TestMultiRoomPing_Separate(t *testing.T) {
|
|||
room1 := &Room{
|
||||
id: "sample-room-1",
|
||||
}
|
||||
entries1 := []BackendPingEntry{
|
||||
entries1 := []talk.BackendPingEntry{
|
||||
{
|
||||
UserId: "foo",
|
||||
SessionId: "123",
|
||||
|
|
@ -164,7 +165,7 @@ func TestMultiRoomPing_Separate(t *testing.T) {
|
|||
}
|
||||
assert.NoError(ping.SendPings(ctx, room1.Id(), u, entries1))
|
||||
assert.Empty(getPingRequests(t))
|
||||
entries2 := []BackendPingEntry{
|
||||
entries2 := []talk.BackendPingEntry{
|
||||
{
|
||||
UserId: "bar",
|
||||
SessionId: "456",
|
||||
|
|
@ -192,7 +193,7 @@ func TestMultiRoomPing_DeleteRoom(t *testing.T) {
|
|||
room1 := &Room{
|
||||
id: "sample-room-1",
|
||||
}
|
||||
entries1 := []BackendPingEntry{
|
||||
entries1 := []talk.BackendPingEntry{
|
||||
{
|
||||
UserId: "foo",
|
||||
SessionId: "123",
|
||||
|
|
@ -204,7 +205,7 @@ func TestMultiRoomPing_DeleteRoom(t *testing.T) {
|
|||
room2 := &Room{
|
||||
id: "sample-room-2",
|
||||
}
|
||||
entries2 := []BackendPingEntry{
|
||||
entries2 := []talk.BackendPingEntry{
|
||||
{
|
||||
UserId: "bar",
|
||||
SessionId: "456",
|
||||
|
|
|
|||
17
room_test.go
17
room_test.go
|
|
@ -36,6 +36,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/talk"
|
||||
)
|
||||
|
||||
func TestRoom_InCall(t *testing.T) {
|
||||
|
|
@ -106,9 +107,9 @@ func TestRoom_Update(t *testing.T) {
|
|||
|
||||
// Simulate backend request from Nextcloud to update the room.
|
||||
roomProperties := json.RawMessage("{\"foo\":\"bar\"}")
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "update",
|
||||
Update: &BackendRoomUpdateRequest{
|
||||
Update: &talk.BackendRoomUpdateRequest{
|
||||
UserIds: []string{
|
||||
testDefaultUserId,
|
||||
},
|
||||
|
|
@ -200,9 +201,9 @@ func TestRoom_Delete(t *testing.T) {
|
|||
assert.True(client.RunUntilJoined(ctx, hello.Hello))
|
||||
|
||||
// Simulate backend request from Nextcloud to update the room.
|
||||
msg := &BackendServerRoomRequest{
|
||||
msg := &talk.BackendServerRoomRequest{
|
||||
Type: "delete",
|
||||
Delete: &BackendRoomDeleteRequest{
|
||||
Delete: &talk.BackendRoomDeleteRequest{
|
||||
UserIds: []string{
|
||||
testDefaultUserId,
|
||||
},
|
||||
|
|
@ -387,9 +388,9 @@ func TestRoom_InCallAll(t *testing.T) {
|
|||
client1.RunUntilJoined(ctx, hello2.Hello)
|
||||
|
||||
// Simulate backend request from Nextcloud to update the "inCall" flag of all participants.
|
||||
msg1 := &BackendServerRoomRequest{
|
||||
msg1 := &talk.BackendServerRoomRequest{
|
||||
Type: "incall",
|
||||
InCall: &BackendRoomInCallRequest{
|
||||
InCall: &talk.BackendRoomInCallRequest{
|
||||
All: true,
|
||||
InCall: json.RawMessage(strconv.FormatInt(FlagInCall, 10)),
|
||||
},
|
||||
|
|
@ -413,9 +414,9 @@ func TestRoom_InCallAll(t *testing.T) {
|
|||
}
|
||||
|
||||
// Simulate backend request from Nextcloud to update the "inCall" flag of all participants.
|
||||
msg2 := &BackendServerRoomRequest{
|
||||
msg2 := &talk.BackendServerRoomRequest{
|
||||
Type: "incall",
|
||||
InCall: &BackendRoomInCallRequest{
|
||||
InCall: &talk.BackendRoomInCallRequest{
|
||||
All: true,
|
||||
InCall: json.RawMessage(strconv.FormatInt(0, 10)),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ func (s *DummySession) LeaveRoom(notify bool) *Room {
|
|||
func (s *DummySession) Close() {
|
||||
}
|
||||
|
||||
func (s *DummySession) HasPermission(permission Permission) bool {
|
||||
func (s *DummySession) HasPermission(permission api.Permission) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
|||
21
session.go
21
session.go
|
|
@ -31,25 +31,6 @@ import (
|
|||
"github.com/strukturag/nextcloud-spreed-signaling/talk"
|
||||
)
|
||||
|
||||
type Permission string
|
||||
|
||||
var (
|
||||
PERMISSION_MAY_PUBLISH_MEDIA Permission = "publish-media"
|
||||
PERMISSION_MAY_PUBLISH_AUDIO Permission = "publish-audio"
|
||||
PERMISSION_MAY_PUBLISH_VIDEO Permission = "publish-video"
|
||||
PERMISSION_MAY_PUBLISH_SCREEN Permission = "publish-screen"
|
||||
PERMISSION_MAY_CONTROL Permission = "control"
|
||||
PERMISSION_TRANSIENT_DATA Permission = "transient-data"
|
||||
PERMISSION_HIDE_DISPLAYNAMES Permission = "hide-displaynames"
|
||||
|
||||
// DefaultPermissionOverrides contains permission overrides for users where
|
||||
// no permissions have been set by the server. If a permission is not set in
|
||||
// this map, it's assumed the user has that permission.
|
||||
DefaultPermissionOverrides = map[Permission]bool{ // +checklocksignore: Global readonly variable.
|
||||
PERMISSION_HIDE_DISPLAYNAMES: false,
|
||||
}
|
||||
)
|
||||
|
||||
type Session interface {
|
||||
Context() context.Context
|
||||
PrivateId() api.PrivateSessionId
|
||||
|
|
@ -72,7 +53,7 @@ type Session interface {
|
|||
|
||||
Close()
|
||||
|
||||
HasPermission(permission Permission) bool
|
||||
HasPermission(permission api.Permission) bool
|
||||
|
||||
SendError(e *api.Error) bool
|
||||
SendMessage(message *api.ServerMessage) bool
|
||||
|
|
|
|||
|
|
@ -25,9 +25,11 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/api"
|
||||
)
|
||||
|
||||
func assertSessionHasPermission(t *testing.T, session Session, permission Permission) {
|
||||
func assertSessionHasPermission(t *testing.T, session Session, permission api.Permission) {
|
||||
t.Helper()
|
||||
assert.True(t, session.HasPermission(permission), "Session %s doesn't have permission %s", session.PublicId(), permission)
|
||||
if cs, ok := session.(*ClientSession); ok {
|
||||
|
|
@ -35,7 +37,7 @@ func assertSessionHasPermission(t *testing.T, session Session, permission Permis
|
|||
}
|
||||
}
|
||||
|
||||
func assertSessionHasNotPermission(t *testing.T, session Session, permission Permission) {
|
||||
func assertSessionHasNotPermission(t *testing.T, session Session, permission api.Permission) {
|
||||
t.Helper()
|
||||
assert.False(t, session.HasPermission(permission), "Session %s has permission %s but shouldn't", session.PublicId(), permission)
|
||||
if cs, ok := session.(*ClientSession); ok {
|
||||
|
|
|
|||
|
|
@ -19,11 +19,10 @@
|
|||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package signaling
|
||||
package talk
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/subtle"
|
||||
"encoding/hex"
|
||||
|
|
@ -36,6 +35,7 @@ import (
|
|||
"github.com/strukturag/nextcloud-spreed-signaling/api"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/etcd"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/geoip"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -51,14 +51,6 @@ const (
|
|||
ConfigKeySessionPingLimit = "session-ping-limit"
|
||||
)
|
||||
|
||||
func newRandomString(length int) string {
|
||||
b := make([]byte, length/2)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return hex.EncodeToString(b)
|
||||
}
|
||||
|
||||
func CalculateBackendChecksum(random string, body []byte, secret []byte) string {
|
||||
mac := hmac.New(sha256.New, secret)
|
||||
mac.Write([]byte(random)) // nolint
|
||||
|
|
@ -68,7 +60,7 @@ func CalculateBackendChecksum(random string, body []byte, secret []byte) string
|
|||
|
||||
func AddBackendChecksum(r *http.Request, body []byte, secret []byte) {
|
||||
// Add checksum so the backend can validate the request.
|
||||
rnd := newRandomString(64)
|
||||
rnd := internal.RandomString(64)
|
||||
checksum := CalculateBackendChecksum(rnd, body, secret)
|
||||
r.Header.Set(HeaderBackendSignalingRandom, rnd)
|
||||
r.Header.Set(HeaderBackendSignalingChecksum, checksum)
|
||||
|
|
@ -88,7 +80,8 @@ func ValidateBackendChecksumValue(checksum string, random string, body []byte, s
|
|||
// Requests from Nextcloud to the signaling server.
|
||||
|
||||
type BackendServerRoomRequest struct {
|
||||
room *Room
|
||||
RoomId string `json:"-"`
|
||||
Backend *Backend `json:"-"`
|
||||
|
||||
Type string `json:"type"`
|
||||
|
||||
|
|
@ -315,7 +308,12 @@ type BackendClientRoomRequest struct {
|
|||
InCall int `json:"incall,omitempty"`
|
||||
}
|
||||
|
||||
func (r *BackendClientRoomRequest) UpdateFromSession(s Session) {
|
||||
type SessionWithUserData interface {
|
||||
ClientType() api.ClientType
|
||||
ParsedUserData() (api.StringMap, error)
|
||||
}
|
||||
|
||||
func (r *BackendClientRoomRequest) UpdateFromSession(s SessionWithUserData) {
|
||||
if s.ClientType() == api.HelloClientTypeFederation {
|
||||
// Need to send additional data for requests of federated users.
|
||||
if u, err := s.ParsedUserData(); err == nil && len(u) > 0 {
|
||||
|
|
@ -351,7 +349,7 @@ type BackendClientRoomResponse struct {
|
|||
// See "RoomSessionData" for a possible content.
|
||||
Session json.RawMessage `json:"session,omitempty"`
|
||||
|
||||
Permissions *[]Permission `json:"permissions,omitempty"`
|
||||
Permissions *[]api.Permission `json:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
type RoomSessionData struct {
|
||||
|
|
@ -447,6 +445,18 @@ type BackendServerInfoSfuJanus struct {
|
|||
VideoRoom *BackendServerInfoVideoRoom `json:"videoroom,omitempty"`
|
||||
}
|
||||
|
||||
type BackendServerInfoSfuProxyBandwidth struct {
|
||||
// Incoming is the bandwidth utilization for publishers in percent.
|
||||
Incoming *float64 `json:"incoming,omitempty"`
|
||||
// Outgoing is the bandwidth utilization for subscribers in percent.
|
||||
Outgoing *float64 `json:"outgoing,omitempty"`
|
||||
|
||||
// Received is the incoming bandwidth.
|
||||
Received api.Bandwidth `json:"received,omitempty"`
|
||||
// Sent is the outgoing bandwidth.
|
||||
Sent api.Bandwidth `json:"sent,omitempty"`
|
||||
}
|
||||
|
||||
type BackendServerInfoSfuProxy struct {
|
||||
Url string `json:"url"`
|
||||
IP string `json:"ip,omitempty"`
|
||||
|
|
@ -459,9 +469,9 @@ type BackendServerInfoSfuProxy struct {
|
|||
Version string `json:"version,omitempty"`
|
||||
Features []string `json:"features,omitempty"`
|
||||
|
||||
Country geoip.Country `json:"country,omitempty"`
|
||||
Load *uint64 `json:"load,omitempty"`
|
||||
Bandwidth *EventProxyServerBandwidth `json:"bandwidth,omitempty"`
|
||||
Country geoip.Country `json:"country,omitempty"`
|
||||
Load *uint64 `json:"load,omitempty"`
|
||||
Bandwidth *BackendServerInfoSfuProxyBandwidth `json:"bandwidth,omitempty"`
|
||||
}
|
||||
|
||||
type SfuMode string
|
||||
|
|
@ -19,19 +19,21 @@
|
|||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package signaling
|
||||
package talk
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
)
|
||||
|
||||
func TestBackendChecksum(t *testing.T) {
|
||||
t.Parallel()
|
||||
assert := assert.New(t)
|
||||
rnd := newRandomString(32)
|
||||
rnd := internal.RandomString(32)
|
||||
body := []byte{1, 2, 3, 4, 5}
|
||||
secret := []byte("shared-secret")
|
||||
|
||||
|
|
@ -43,6 +43,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/api"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -492,7 +493,7 @@ func (c *TestClient) SendHelloInternal() error {
|
|||
}
|
||||
|
||||
func (c *TestClient) SendHelloInternalWithFeatures(features []string) error {
|
||||
random := newRandomString(48)
|
||||
random := internal.RandomString(48)
|
||||
mac := hmac.New(sha256.New, testInternalSecret)
|
||||
mac.Write([]byte(random)) // nolint
|
||||
token := hex.EncodeToString(mac.Sum(nil))
|
||||
|
|
|
|||
|
|
@ -197,9 +197,9 @@ func Test_TransientMessages(t *testing.T) {
|
|||
require.NotNil(session2, "Session %s does not exist", hello2.Hello.SessionId)
|
||||
|
||||
// Client 1 may modify transient data.
|
||||
session1.SetPermissions([]Permission{PERMISSION_TRANSIENT_DATA})
|
||||
session1.SetPermissions([]api.Permission{api.PERMISSION_TRANSIENT_DATA})
|
||||
// Client 2 may not modify transient data.
|
||||
session2.SetPermissions([]Permission{})
|
||||
session2.SetPermissions([]api.Permission{})
|
||||
|
||||
require.NoError(client2.SetTransientData("foo", "bar", 0))
|
||||
if msg, ok := client2.RunUntilMessage(ctx); ok {
|
||||
|
|
|
|||
|
|
@ -240,12 +240,12 @@ func (s *VirtualSession) notifyBackendRemoved(room *Room, session Session, messa
|
|||
defer cancel()
|
||||
|
||||
if options := s.Options(); options != nil && options.ActorId != "" && options.ActorType != "" {
|
||||
request := NewBackendClientRoomRequest(room.Id(), s.UserId(), api.RoomSessionId(s.PublicId()))
|
||||
request := talk.NewBackendClientRoomRequest(room.Id(), s.UserId(), api.RoomSessionId(s.PublicId()))
|
||||
request.Room.Action = "leave"
|
||||
request.Room.ActorId = options.ActorId
|
||||
request.Room.ActorType = options.ActorType
|
||||
|
||||
var response BackendClientResponse
|
||||
var response talk.BackendClientResponse
|
||||
if err := s.hub.backend.PerformJSONRequest(ctx, s.ParsedBackendOcsUrl(), request, &response); err != nil {
|
||||
virtualSessionId := GetVirtualSessionId(s.session, s.PublicId())
|
||||
s.logger.Printf("Could not leave virtual session %s at backend %s: %s", virtualSessionId, s.BackendUrl(), err)
|
||||
|
|
@ -266,11 +266,11 @@ func (s *VirtualSession) notifyBackendRemoved(room *Room, session Session, messa
|
|||
return
|
||||
}
|
||||
} else {
|
||||
request := NewBackendClientSessionRequest(room.Id(), "remove", s.PublicId(), &api.AddSessionInternalClientMessage{
|
||||
request := talk.NewBackendClientSessionRequest(room.Id(), "remove", s.PublicId(), &api.AddSessionInternalClientMessage{
|
||||
UserId: s.userId,
|
||||
User: s.userData,
|
||||
})
|
||||
var response BackendClientSessionResponse
|
||||
var response talk.BackendClientSessionResponse
|
||||
err := s.hub.backend.PerformJSONRequest(ctx, s.ParsedBackendOcsUrl(), request, &response)
|
||||
if err != nil {
|
||||
s.logger.Printf("Could not remove virtual session %s from backend %s: %s", s.PublicId(), s.BackendUrl(), err)
|
||||
|
|
@ -282,7 +282,7 @@ func (s *VirtualSession) notifyBackendRemoved(room *Room, session Session, messa
|
|||
}
|
||||
}
|
||||
|
||||
func (s *VirtualSession) HasPermission(permission Permission) bool {
|
||||
func (s *VirtualSession) HasPermission(permission api.Permission) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue