diff --git a/pkg/rtc/participant_signal.go b/pkg/rtc/participant_signal.go index 35dc7148d..3d825d752 100644 --- a/pkg/rtc/participant_signal.go +++ b/pkg/rtc/participant_signal.go @@ -197,6 +197,18 @@ func (p *ParticipantImpl) SendRefreshToken(token string) error { }) } +func (p *ParticipantImpl) SendErrorResponse(errorResponse *livekit.ErrorResponse) error { + if errorResponse.RequestId == 0 { + return nil + } + + return p.writeMessage(&livekit.SignalResponse{ + Message: &livekit.SignalResponse_ErrorResponse{ + ErrorResponse: errorResponse, + }, + }) +} + func (p *ParticipantImpl) HandleReconnectAndSendResponse(reconnectReason livekit.ReconnectReason, reconnectResponse *livekit.ReconnectResponse) error { p.TransportManager.HandleClientReconnect(reconnectReason) diff --git a/pkg/rtc/signalhandler.go b/pkg/rtc/signalhandler.go index f9202e039..bac5181e6 100644 --- a/pkg/rtc/signalhandler.go +++ b/pkg/rtc/signalhandler.go @@ -92,6 +92,7 @@ func HandleParticipantSignal(room types.Room, participant types.LocalParticipant } case *livekit.SignalRequest_UpdateMetadata: + var errorResponse *livekit.ErrorResponse if participant.ClaimGrants().Video.GetCanUpdateOwnMetadata() { err := room.UpdateParticipantMetadata( participant, @@ -101,7 +102,25 @@ func HandleParticipantSignal(room types.Room, participant types.LocalParticipant ) if err != nil { pLogger.Warnw("could not update metadata", err) + + switch err { + case ErrAttributeExceedsLimits: + errorResponse = &livekit.ErrorResponse{ + Reason: livekit.ErrorResponse_INVALID_ARGUMENT, + Message: "exceeds attributes size limit", + } + } + } + } else { + errorResponse = &livekit.ErrorResponse{ + Reason: livekit.ErrorResponse_NOT_ALLOWED, + Message: "does not have permission to update own metadata", + } + } + if errorResponse != nil { + errorResponse.RequestId = msg.UpdateMetadata.RequestId + participant.SendErrorResponse(errorResponse) } case *livekit.SignalRequest_UpdateAudioTrack: diff --git a/pkg/rtc/types/interfaces.go b/pkg/rtc/types/interfaces.go index e877677c7..73e656a99 100644 --- a/pkg/rtc/types/interfaces.go +++ b/pkg/rtc/types/interfaces.go @@ -379,6 +379,7 @@ type LocalParticipant interface { SendConnectionQualityUpdate(update *livekit.ConnectionQualityUpdate) error SubscriptionPermissionUpdate(publisherID livekit.ParticipantID, trackID livekit.TrackID, allowed bool) SendRefreshToken(token string) error + SendErrorResponse(errorResponse *livekit.ErrorResponse) error HandleReconnectAndSendResponse(reconnectReason livekit.ReconnectReason, reconnectResponse *livekit.ReconnectResponse) error IssueFullReconnect(reason ParticipantCloseReason) diff --git a/pkg/rtc/types/typesfakes/fake_local_participant.go b/pkg/rtc/types/typesfakes/fake_local_participant.go index 7c239d81e..30faa1122 100644 --- a/pkg/rtc/types/typesfakes/fake_local_participant.go +++ b/pkg/rtc/types/typesfakes/fake_local_participant.go @@ -677,6 +677,17 @@ type FakeLocalParticipant struct { sendDataPacketReturnsOnCall map[int]struct { result1 error } + SendErrorResponseStub func(*livekit.ErrorResponse) error + sendErrorResponseMutex sync.RWMutex + sendErrorResponseArgsForCall []struct { + arg1 *livekit.ErrorResponse + } + sendErrorResponseReturns struct { + result1 error + } + sendErrorResponseReturnsOnCall map[int]struct { + result1 error + } SendJoinResponseStub func(*livekit.JoinResponse) error sendJoinResponseMutex sync.RWMutex sendJoinResponseArgsForCall []struct { @@ -4576,6 +4587,67 @@ func (fake *FakeLocalParticipant) SendDataPacketReturnsOnCall(i int, result1 err }{result1} } +func (fake *FakeLocalParticipant) SendErrorResponse(arg1 *livekit.ErrorResponse) error { + fake.sendErrorResponseMutex.Lock() + ret, specificReturn := fake.sendErrorResponseReturnsOnCall[len(fake.sendErrorResponseArgsForCall)] + fake.sendErrorResponseArgsForCall = append(fake.sendErrorResponseArgsForCall, struct { + arg1 *livekit.ErrorResponse + }{arg1}) + stub := fake.SendErrorResponseStub + fakeReturns := fake.sendErrorResponseReturns + fake.recordInvocation("SendErrorResponse", []interface{}{arg1}) + fake.sendErrorResponseMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeLocalParticipant) SendErrorResponseCallCount() int { + fake.sendErrorResponseMutex.RLock() + defer fake.sendErrorResponseMutex.RUnlock() + return len(fake.sendErrorResponseArgsForCall) +} + +func (fake *FakeLocalParticipant) SendErrorResponseCalls(stub func(*livekit.ErrorResponse) error) { + fake.sendErrorResponseMutex.Lock() + defer fake.sendErrorResponseMutex.Unlock() + fake.SendErrorResponseStub = stub +} + +func (fake *FakeLocalParticipant) SendErrorResponseArgsForCall(i int) *livekit.ErrorResponse { + fake.sendErrorResponseMutex.RLock() + defer fake.sendErrorResponseMutex.RUnlock() + argsForCall := fake.sendErrorResponseArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeLocalParticipant) SendErrorResponseReturns(result1 error) { + fake.sendErrorResponseMutex.Lock() + defer fake.sendErrorResponseMutex.Unlock() + fake.SendErrorResponseStub = nil + fake.sendErrorResponseReturns = struct { + result1 error + }{result1} +} + +func (fake *FakeLocalParticipant) SendErrorResponseReturnsOnCall(i int, result1 error) { + fake.sendErrorResponseMutex.Lock() + defer fake.sendErrorResponseMutex.Unlock() + fake.SendErrorResponseStub = nil + if fake.sendErrorResponseReturnsOnCall == nil { + fake.sendErrorResponseReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.sendErrorResponseReturnsOnCall[i] = struct { + result1 error + }{result1} +} + func (fake *FakeLocalParticipant) SendJoinResponse(arg1 *livekit.JoinResponse) error { fake.sendJoinResponseMutex.Lock() ret, specificReturn := fake.sendJoinResponseReturnsOnCall[len(fake.sendJoinResponseArgsForCall)] @@ -6633,6 +6705,8 @@ func (fake *FakeLocalParticipant) Invocations() map[string][][]interface{} { defer fake.sendConnectionQualityUpdateMutex.RUnlock() fake.sendDataPacketMutex.RLock() defer fake.sendDataPacketMutex.RUnlock() + fake.sendErrorResponseMutex.RLock() + defer fake.sendErrorResponseMutex.RUnlock() fake.sendJoinResponseMutex.RLock() defer fake.sendJoinResponseMutex.RUnlock() fake.sendParticipantUpdateMutex.RLock()