Fixed permission handling with room deletion (#233)

This commit is contained in:
David Zhao
2021-12-03 14:27:13 -08:00
committed by GitHub
parent edafb0a118
commit c00d799ac6
6 changed files with 557 additions and 4 deletions

View File

@@ -26,6 +26,7 @@ type RoomStore interface {
DeleteParticipant(ctx context.Context, roomName, identity string) error
}
//counterfeiter:generate . RORoomStore
type RORoomStore interface {
LoadRoom(ctx context.Context, name string) (*livekit.Room, error)
ListRooms(ctx context.Context) ([]*livekit.Room, error)
@@ -34,6 +35,7 @@ type RORoomStore interface {
ListParticipants(ctx context.Context, roomName string) ([]*livekit.ParticipantInfo, error)
}
//counterfeiter:generate . RoomAllocator
type RoomAllocator interface {
CreateRoom(ctx context.Context, req *livekit.CreateRoomRequest) (*livekit.Room, error)
}

View File

@@ -18,7 +18,7 @@ type RoomService struct {
roomStore RORoomStore
}
func NewRoomService(ra RoomAllocator, rs RORoomStore, router routing.MessageRouter) (svc livekit.RoomService, err error) {
func NewRoomService(ra RoomAllocator, rs RORoomStore, router routing.MessageRouter) (svc *RoomService, err error) {
svc = &RoomService{
router: router,
roomAllocator: ra,
@@ -62,12 +62,12 @@ func (s *RoomService) DeleteRoom(ctx context.Context, req *livekit.DeleteRoomReq
if err := EnsureCreatePermission(ctx); err != nil {
return nil, twirpAuthError(err)
}
if err := s.writeRoomMessage(ctx, req.Room, "", &livekit.RTCNodeMessage{
err := s.router.WriteRoomRTC(ctx, req.Room, "", &livekit.RTCNodeMessage{
Message: &livekit.RTCNodeMessage_DeleteRoom{
DeleteRoom: req,
},
}); err != nil {
})
if err != nil {
return nil, err
}

View File

@@ -0,0 +1,66 @@
package service_test
import (
"context"
"testing"
"github.com/livekit/livekit-server/pkg/routing/routingfakes"
"github.com/livekit/livekit-server/pkg/service"
"github.com/livekit/livekit-server/pkg/service/servicefakes"
"github.com/livekit/protocol/auth"
livekit "github.com/livekit/protocol/proto"
"github.com/stretchr/testify/require"
)
const grantsKey = "grants"
func TestDeleteRoom(t *testing.T) {
t.Run("normal deletion", func(t *testing.T) {
svc := newTestRoomService()
grant := &auth.ClaimGrants{
Video: &auth.VideoGrant{
RoomCreate: true,
},
}
ctx := context.WithValue(context.Background(), grantsKey, grant)
_, err := svc.DeleteRoom(ctx, &livekit.DeleteRoomRequest{
Room: "testroom",
})
require.NoError(t, err)
})
t.Run("missing permissions", func(t *testing.T) {
svc := newTestRoomService()
grant := &auth.ClaimGrants{
Video: &auth.VideoGrant{},
}
ctx := context.WithValue(context.Background(), grantsKey, grant)
_, err := svc.DeleteRoom(ctx, &livekit.DeleteRoomRequest{
Room: "testroom",
})
require.Error(t, err)
})
}
func newTestRoomService() *TestRoomService {
router := &routingfakes.FakeRouter{}
allocator := &servicefakes.FakeRoomAllocator{}
store := &servicefakes.FakeRORoomStore{}
svc, err := service.NewRoomService(allocator, store, router)
if err != nil {
panic(err)
}
return &TestRoomService{
RoomService: *svc,
router: router,
allocator: allocator,
store: store,
}
}
type TestRoomService struct {
service.RoomService
router *routingfakes.FakeRouter
allocator *servicefakes.FakeRoomAllocator
store *servicefakes.FakeRORoomStore
}

View File

@@ -0,0 +1,120 @@
// Code generated by counterfeiter. DO NOT EDIT.
package servicefakes
import (
"context"
"sync"
"github.com/livekit/livekit-server/pkg/service"
livekit "github.com/livekit/protocol/proto"
)
type FakeRoomAllocator struct {
CreateRoomStub func(context.Context, *livekit.CreateRoomRequest) (*livekit.Room, error)
createRoomMutex sync.RWMutex
createRoomArgsForCall []struct {
arg1 context.Context
arg2 *livekit.CreateRoomRequest
}
createRoomReturns struct {
result1 *livekit.Room
result2 error
}
createRoomReturnsOnCall map[int]struct {
result1 *livekit.Room
result2 error
}
invocations map[string][][]interface{}
invocationsMutex sync.RWMutex
}
func (fake *FakeRoomAllocator) CreateRoom(arg1 context.Context, arg2 *livekit.CreateRoomRequest) (*livekit.Room, error) {
fake.createRoomMutex.Lock()
ret, specificReturn := fake.createRoomReturnsOnCall[len(fake.createRoomArgsForCall)]
fake.createRoomArgsForCall = append(fake.createRoomArgsForCall, struct {
arg1 context.Context
arg2 *livekit.CreateRoomRequest
}{arg1, arg2})
stub := fake.CreateRoomStub
fakeReturns := fake.createRoomReturns
fake.recordInvocation("CreateRoom", []interface{}{arg1, arg2})
fake.createRoomMutex.Unlock()
if stub != nil {
return stub(arg1, arg2)
}
if specificReturn {
return ret.result1, ret.result2
}
return fakeReturns.result1, fakeReturns.result2
}
func (fake *FakeRoomAllocator) CreateRoomCallCount() int {
fake.createRoomMutex.RLock()
defer fake.createRoomMutex.RUnlock()
return len(fake.createRoomArgsForCall)
}
func (fake *FakeRoomAllocator) CreateRoomCalls(stub func(context.Context, *livekit.CreateRoomRequest) (*livekit.Room, error)) {
fake.createRoomMutex.Lock()
defer fake.createRoomMutex.Unlock()
fake.CreateRoomStub = stub
}
func (fake *FakeRoomAllocator) CreateRoomArgsForCall(i int) (context.Context, *livekit.CreateRoomRequest) {
fake.createRoomMutex.RLock()
defer fake.createRoomMutex.RUnlock()
argsForCall := fake.createRoomArgsForCall[i]
return argsForCall.arg1, argsForCall.arg2
}
func (fake *FakeRoomAllocator) CreateRoomReturns(result1 *livekit.Room, result2 error) {
fake.createRoomMutex.Lock()
defer fake.createRoomMutex.Unlock()
fake.CreateRoomStub = nil
fake.createRoomReturns = struct {
result1 *livekit.Room
result2 error
}{result1, result2}
}
func (fake *FakeRoomAllocator) CreateRoomReturnsOnCall(i int, result1 *livekit.Room, result2 error) {
fake.createRoomMutex.Lock()
defer fake.createRoomMutex.Unlock()
fake.CreateRoomStub = nil
if fake.createRoomReturnsOnCall == nil {
fake.createRoomReturnsOnCall = make(map[int]struct {
result1 *livekit.Room
result2 error
})
}
fake.createRoomReturnsOnCall[i] = struct {
result1 *livekit.Room
result2 error
}{result1, result2}
}
func (fake *FakeRoomAllocator) Invocations() map[string][][]interface{} {
fake.invocationsMutex.RLock()
defer fake.invocationsMutex.RUnlock()
fake.createRoomMutex.RLock()
defer fake.createRoomMutex.RUnlock()
copiedInvocations := map[string][][]interface{}{}
for key, value := range fake.invocations {
copiedInvocations[key] = value
}
return copiedInvocations
}
func (fake *FakeRoomAllocator) recordInvocation(key string, args []interface{}) {
fake.invocationsMutex.Lock()
defer fake.invocationsMutex.Unlock()
if fake.invocations == nil {
fake.invocations = map[string][][]interface{}{}
}
if fake.invocations[key] == nil {
fake.invocations[key] = [][]interface{}{}
}
fake.invocations[key] = append(fake.invocations[key], args)
}
var _ service.RoomAllocator = new(FakeRoomAllocator)

View File

@@ -0,0 +1,363 @@
// Code generated by counterfeiter. DO NOT EDIT.
package servicefakes
import (
"context"
"sync"
"github.com/livekit/livekit-server/pkg/service"
livekit "github.com/livekit/protocol/proto"
)
type FakeRORoomStore struct {
ListParticipantsStub func(context.Context, string) ([]*livekit.ParticipantInfo, error)
listParticipantsMutex sync.RWMutex
listParticipantsArgsForCall []struct {
arg1 context.Context
arg2 string
}
listParticipantsReturns struct {
result1 []*livekit.ParticipantInfo
result2 error
}
listParticipantsReturnsOnCall map[int]struct {
result1 []*livekit.ParticipantInfo
result2 error
}
ListRoomsStub func(context.Context) ([]*livekit.Room, error)
listRoomsMutex sync.RWMutex
listRoomsArgsForCall []struct {
arg1 context.Context
}
listRoomsReturns struct {
result1 []*livekit.Room
result2 error
}
listRoomsReturnsOnCall map[int]struct {
result1 []*livekit.Room
result2 error
}
LoadParticipantStub func(context.Context, string, string) (*livekit.ParticipantInfo, error)
loadParticipantMutex sync.RWMutex
loadParticipantArgsForCall []struct {
arg1 context.Context
arg2 string
arg3 string
}
loadParticipantReturns struct {
result1 *livekit.ParticipantInfo
result2 error
}
loadParticipantReturnsOnCall map[int]struct {
result1 *livekit.ParticipantInfo
result2 error
}
LoadRoomStub func(context.Context, string) (*livekit.Room, error)
loadRoomMutex sync.RWMutex
loadRoomArgsForCall []struct {
arg1 context.Context
arg2 string
}
loadRoomReturns struct {
result1 *livekit.Room
result2 error
}
loadRoomReturnsOnCall map[int]struct {
result1 *livekit.Room
result2 error
}
invocations map[string][][]interface{}
invocationsMutex sync.RWMutex
}
func (fake *FakeRORoomStore) ListParticipants(arg1 context.Context, arg2 string) ([]*livekit.ParticipantInfo, error) {
fake.listParticipantsMutex.Lock()
ret, specificReturn := fake.listParticipantsReturnsOnCall[len(fake.listParticipantsArgsForCall)]
fake.listParticipantsArgsForCall = append(fake.listParticipantsArgsForCall, struct {
arg1 context.Context
arg2 string
}{arg1, arg2})
stub := fake.ListParticipantsStub
fakeReturns := fake.listParticipantsReturns
fake.recordInvocation("ListParticipants", []interface{}{arg1, arg2})
fake.listParticipantsMutex.Unlock()
if stub != nil {
return stub(arg1, arg2)
}
if specificReturn {
return ret.result1, ret.result2
}
return fakeReturns.result1, fakeReturns.result2
}
func (fake *FakeRORoomStore) ListParticipantsCallCount() int {
fake.listParticipantsMutex.RLock()
defer fake.listParticipantsMutex.RUnlock()
return len(fake.listParticipantsArgsForCall)
}
func (fake *FakeRORoomStore) ListParticipantsCalls(stub func(context.Context, string) ([]*livekit.ParticipantInfo, error)) {
fake.listParticipantsMutex.Lock()
defer fake.listParticipantsMutex.Unlock()
fake.ListParticipantsStub = stub
}
func (fake *FakeRORoomStore) ListParticipantsArgsForCall(i int) (context.Context, string) {
fake.listParticipantsMutex.RLock()
defer fake.listParticipantsMutex.RUnlock()
argsForCall := fake.listParticipantsArgsForCall[i]
return argsForCall.arg1, argsForCall.arg2
}
func (fake *FakeRORoomStore) ListParticipantsReturns(result1 []*livekit.ParticipantInfo, result2 error) {
fake.listParticipantsMutex.Lock()
defer fake.listParticipantsMutex.Unlock()
fake.ListParticipantsStub = nil
fake.listParticipantsReturns = struct {
result1 []*livekit.ParticipantInfo
result2 error
}{result1, result2}
}
func (fake *FakeRORoomStore) ListParticipantsReturnsOnCall(i int, result1 []*livekit.ParticipantInfo, result2 error) {
fake.listParticipantsMutex.Lock()
defer fake.listParticipantsMutex.Unlock()
fake.ListParticipantsStub = nil
if fake.listParticipantsReturnsOnCall == nil {
fake.listParticipantsReturnsOnCall = make(map[int]struct {
result1 []*livekit.ParticipantInfo
result2 error
})
}
fake.listParticipantsReturnsOnCall[i] = struct {
result1 []*livekit.ParticipantInfo
result2 error
}{result1, result2}
}
func (fake *FakeRORoomStore) ListRooms(arg1 context.Context) ([]*livekit.Room, error) {
fake.listRoomsMutex.Lock()
ret, specificReturn := fake.listRoomsReturnsOnCall[len(fake.listRoomsArgsForCall)]
fake.listRoomsArgsForCall = append(fake.listRoomsArgsForCall, struct {
arg1 context.Context
}{arg1})
stub := fake.ListRoomsStub
fakeReturns := fake.listRoomsReturns
fake.recordInvocation("ListRooms", []interface{}{arg1})
fake.listRoomsMutex.Unlock()
if stub != nil {
return stub(arg1)
}
if specificReturn {
return ret.result1, ret.result2
}
return fakeReturns.result1, fakeReturns.result2
}
func (fake *FakeRORoomStore) ListRoomsCallCount() int {
fake.listRoomsMutex.RLock()
defer fake.listRoomsMutex.RUnlock()
return len(fake.listRoomsArgsForCall)
}
func (fake *FakeRORoomStore) ListRoomsCalls(stub func(context.Context) ([]*livekit.Room, error)) {
fake.listRoomsMutex.Lock()
defer fake.listRoomsMutex.Unlock()
fake.ListRoomsStub = stub
}
func (fake *FakeRORoomStore) ListRoomsArgsForCall(i int) context.Context {
fake.listRoomsMutex.RLock()
defer fake.listRoomsMutex.RUnlock()
argsForCall := fake.listRoomsArgsForCall[i]
return argsForCall.arg1
}
func (fake *FakeRORoomStore) ListRoomsReturns(result1 []*livekit.Room, result2 error) {
fake.listRoomsMutex.Lock()
defer fake.listRoomsMutex.Unlock()
fake.ListRoomsStub = nil
fake.listRoomsReturns = struct {
result1 []*livekit.Room
result2 error
}{result1, result2}
}
func (fake *FakeRORoomStore) ListRoomsReturnsOnCall(i int, result1 []*livekit.Room, result2 error) {
fake.listRoomsMutex.Lock()
defer fake.listRoomsMutex.Unlock()
fake.ListRoomsStub = nil
if fake.listRoomsReturnsOnCall == nil {
fake.listRoomsReturnsOnCall = make(map[int]struct {
result1 []*livekit.Room
result2 error
})
}
fake.listRoomsReturnsOnCall[i] = struct {
result1 []*livekit.Room
result2 error
}{result1, result2}
}
func (fake *FakeRORoomStore) LoadParticipant(arg1 context.Context, arg2 string, arg3 string) (*livekit.ParticipantInfo, error) {
fake.loadParticipantMutex.Lock()
ret, specificReturn := fake.loadParticipantReturnsOnCall[len(fake.loadParticipantArgsForCall)]
fake.loadParticipantArgsForCall = append(fake.loadParticipantArgsForCall, struct {
arg1 context.Context
arg2 string
arg3 string
}{arg1, arg2, arg3})
stub := fake.LoadParticipantStub
fakeReturns := fake.loadParticipantReturns
fake.recordInvocation("LoadParticipant", []interface{}{arg1, arg2, arg3})
fake.loadParticipantMutex.Unlock()
if stub != nil {
return stub(arg1, arg2, arg3)
}
if specificReturn {
return ret.result1, ret.result2
}
return fakeReturns.result1, fakeReturns.result2
}
func (fake *FakeRORoomStore) LoadParticipantCallCount() int {
fake.loadParticipantMutex.RLock()
defer fake.loadParticipantMutex.RUnlock()
return len(fake.loadParticipantArgsForCall)
}
func (fake *FakeRORoomStore) LoadParticipantCalls(stub func(context.Context, string, string) (*livekit.ParticipantInfo, error)) {
fake.loadParticipantMutex.Lock()
defer fake.loadParticipantMutex.Unlock()
fake.LoadParticipantStub = stub
}
func (fake *FakeRORoomStore) LoadParticipantArgsForCall(i int) (context.Context, string, string) {
fake.loadParticipantMutex.RLock()
defer fake.loadParticipantMutex.RUnlock()
argsForCall := fake.loadParticipantArgsForCall[i]
return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3
}
func (fake *FakeRORoomStore) LoadParticipantReturns(result1 *livekit.ParticipantInfo, result2 error) {
fake.loadParticipantMutex.Lock()
defer fake.loadParticipantMutex.Unlock()
fake.LoadParticipantStub = nil
fake.loadParticipantReturns = struct {
result1 *livekit.ParticipantInfo
result2 error
}{result1, result2}
}
func (fake *FakeRORoomStore) LoadParticipantReturnsOnCall(i int, result1 *livekit.ParticipantInfo, result2 error) {
fake.loadParticipantMutex.Lock()
defer fake.loadParticipantMutex.Unlock()
fake.LoadParticipantStub = nil
if fake.loadParticipantReturnsOnCall == nil {
fake.loadParticipantReturnsOnCall = make(map[int]struct {
result1 *livekit.ParticipantInfo
result2 error
})
}
fake.loadParticipantReturnsOnCall[i] = struct {
result1 *livekit.ParticipantInfo
result2 error
}{result1, result2}
}
func (fake *FakeRORoomStore) LoadRoom(arg1 context.Context, arg2 string) (*livekit.Room, error) {
fake.loadRoomMutex.Lock()
ret, specificReturn := fake.loadRoomReturnsOnCall[len(fake.loadRoomArgsForCall)]
fake.loadRoomArgsForCall = append(fake.loadRoomArgsForCall, struct {
arg1 context.Context
arg2 string
}{arg1, arg2})
stub := fake.LoadRoomStub
fakeReturns := fake.loadRoomReturns
fake.recordInvocation("LoadRoom", []interface{}{arg1, arg2})
fake.loadRoomMutex.Unlock()
if stub != nil {
return stub(arg1, arg2)
}
if specificReturn {
return ret.result1, ret.result2
}
return fakeReturns.result1, fakeReturns.result2
}
func (fake *FakeRORoomStore) LoadRoomCallCount() int {
fake.loadRoomMutex.RLock()
defer fake.loadRoomMutex.RUnlock()
return len(fake.loadRoomArgsForCall)
}
func (fake *FakeRORoomStore) LoadRoomCalls(stub func(context.Context, string) (*livekit.Room, error)) {
fake.loadRoomMutex.Lock()
defer fake.loadRoomMutex.Unlock()
fake.LoadRoomStub = stub
}
func (fake *FakeRORoomStore) LoadRoomArgsForCall(i int) (context.Context, string) {
fake.loadRoomMutex.RLock()
defer fake.loadRoomMutex.RUnlock()
argsForCall := fake.loadRoomArgsForCall[i]
return argsForCall.arg1, argsForCall.arg2
}
func (fake *FakeRORoomStore) LoadRoomReturns(result1 *livekit.Room, result2 error) {
fake.loadRoomMutex.Lock()
defer fake.loadRoomMutex.Unlock()
fake.LoadRoomStub = nil
fake.loadRoomReturns = struct {
result1 *livekit.Room
result2 error
}{result1, result2}
}
func (fake *FakeRORoomStore) LoadRoomReturnsOnCall(i int, result1 *livekit.Room, result2 error) {
fake.loadRoomMutex.Lock()
defer fake.loadRoomMutex.Unlock()
fake.LoadRoomStub = nil
if fake.loadRoomReturnsOnCall == nil {
fake.loadRoomReturnsOnCall = make(map[int]struct {
result1 *livekit.Room
result2 error
})
}
fake.loadRoomReturnsOnCall[i] = struct {
result1 *livekit.Room
result2 error
}{result1, result2}
}
func (fake *FakeRORoomStore) Invocations() map[string][][]interface{} {
fake.invocationsMutex.RLock()
defer fake.invocationsMutex.RUnlock()
fake.listParticipantsMutex.RLock()
defer fake.listParticipantsMutex.RUnlock()
fake.listRoomsMutex.RLock()
defer fake.listRoomsMutex.RUnlock()
fake.loadParticipantMutex.RLock()
defer fake.loadParticipantMutex.RUnlock()
fake.loadRoomMutex.RLock()
defer fake.loadRoomMutex.RUnlock()
copiedInvocations := map[string][][]interface{}{}
for key, value := range fake.invocations {
copiedInvocations[key] = value
}
return copiedInvocations
}
func (fake *FakeRORoomStore) recordInvocation(key string, args []interface{}) {
fake.invocationsMutex.Lock()
defer fake.invocationsMutex.Unlock()
if fake.invocations == nil {
fake.invocations = map[string][][]interface{}{}
}
if fake.invocations[key] == nil {
fake.invocations[key] = [][]interface{}{}
}
fake.invocations[key] = append(fake.invocations[key], args)
}
var _ service.RORoomStore = new(FakeRORoomStore)

View File

@@ -10,6 +10,7 @@ import (
"github.com/go-redis/redis/v8"
"github.com/google/wire"
livekit "github.com/livekit/protocol/proto"
"github.com/pkg/errors"
"github.com/livekit/protocol/auth"
@@ -32,6 +33,7 @@ func InitializeServer(conf *config.Config, currentNode routing.LocalNode) (*Live
createWebhookNotifier,
routing.CreateRouter,
wire.Bind(new(routing.MessageRouter), new(routing.Router)),
wire.Bind(new(livekit.RoomService), new(*RoomService)),
telemetry.NewAnalyticsService,
telemetry.NewTelemetryService,
NewRecordingService,