Browse Source

Merge pull request #148 from deathwish/restrict-room-creation

Restrict room creation
pull/154/head
Simon Eisenmann 11 years ago
parent
commit
8254693d0d
  1. 2
      doc/CHANNELING-API.txt
  2. 3
      server.conf.in
  3. 4
      src/app/spreed-webrtc-server/channeling.go
  4. 6
      src/app/spreed-webrtc-server/channelling_api.go
  5. 10
      src/app/spreed-webrtc-server/channelling_api_test.go
  6. 77
      src/app/spreed-webrtc-server/config.go
  7. 145
      src/app/spreed-webrtc-server/main.go
  8. 75
      src/app/spreed-webrtc-server/room_manager.go
  9. 32
      src/app/spreed-webrtc-server/room_manager_test.go
  10. 6
      src/app/spreed-webrtc-server/roomworker.go
  11. 4
      src/app/spreed-webrtc-server/roomworker_test.go
  12. 7
      src/app/spreed-webrtc-server/session.go

2
doc/CHANNELING-API.txt

@ -193,6 +193,8 @@ Special purpose documents for channling @@ -193,6 +193,8 @@ Special purpose documents for channling
authorization_not_required : No credentials should be provided for this
room.
invalid_credentials : The provided credentials are incorrect.
room_join_requires_account : Server configuration requires an
authenticated user account to join this room.
Welcome

3
server.conf.in

@ -78,6 +78,9 @@ encryptionSecret = tne-default-encryption-block-key @@ -78,6 +78,9 @@ encryptionSecret = tne-default-encryption-block-key
; all users will join this room if enabled. If it is disabled then a room join
; form will be shown instead.
;defaultRoomEnabled = true
; Whether a user account is required to create a room. This only has an effect
; if user accounts are enabled. Optional, defaults to false.
;authorizeRoomCreation = false
; Server token is a public random string which is used to enhance security of
; server generated security tokens. When the serverToken is changed all existing
; nonces become invalid. Use 32 or 64 characters (eg. 16 or 32 byte hex).

4
src/app/spreed-webrtc-server/channeling.go

@ -27,6 +27,10 @@ type DataError struct { @@ -27,6 +27,10 @@ type DataError struct {
Message string
}
func NewDataError(code, message string) error {
return &DataError{"Error", code, message}
}
func (err *DataError) Error() string {
return err.Message
}

6
src/app/spreed-webrtc-server/channelling_api.go

@ -38,7 +38,6 @@ type ChannellingAPI interface { @@ -38,7 +38,6 @@ type ChannellingAPI interface {
}
type channellingAPI struct {
version string
*Config
RoomStatusManager
SessionEncoder
@ -51,9 +50,8 @@ type channellingAPI struct { @@ -51,9 +50,8 @@ type channellingAPI struct {
buddyImages ImageCache
}
func NewChannellingAPI(version string, config *Config, roomStatus RoomStatusManager, sessionEncoder SessionEncoder, sessionManager SessionManager, statsCounter StatsCounter, contactManager ContactManager, turnDataCreator TurnDataCreator, unicaster Unicaster, broadcaster Broadcaster, buddyImages ImageCache) ChannellingAPI {
func NewChannellingAPI(config *Config, roomStatus RoomStatusManager, sessionEncoder SessionEncoder, sessionManager SessionManager, statsCounter StatsCounter, contactManager ContactManager, turnDataCreator TurnDataCreator, unicaster Unicaster, broadcaster Broadcaster, buddyImages ImageCache) ChannellingAPI {
return &channellingAPI{
version,
config,
roomStatus,
sessionEncoder,
@ -255,7 +253,7 @@ func (api *channellingAPI) SendSelf(c Responder, session *Session) { @@ -255,7 +253,7 @@ func (api *channellingAPI) SendSelf(c Responder, session *Session) {
Userid: session.Userid(),
Suserid: api.EncodeSessionUserID(session),
Token: token,
Version: api.version,
Version: api.Version,
Turn: api.CreateTurnData(session),
Stun: api.StunURIs,
}

10
src/app/spreed-webrtc-server/channelling_api_test.go

@ -26,10 +26,6 @@ import ( @@ -26,10 +26,6 @@ import (
"testing"
)
const (
testAppVersion string = "0.0.0+unittests"
)
type fakeClient struct {
replies map[string]interface{}
}
@ -103,7 +99,7 @@ func assertErrorReply(t *testing.T, client *fakeClient, iid, code string) { @@ -103,7 +99,7 @@ func assertErrorReply(t *testing.T, client *fakeClient, iid, code string) {
func NewTestChannellingAPI() (ChannellingAPI, *fakeClient, *Session, *fakeRoomManager) {
client, roomManager, session := &fakeClient{}, &fakeRoomManager{}, &Session{}
return NewChannellingAPI(testAppVersion, nil, roomManager, nil, nil, nil, nil, nil, nil, roomManager, nil), client, session, roomManager
return NewChannellingAPI(nil, roomManager, nil, nil, nil, nil, nil, nil, roomManager, nil), client, session, roomManager
}
func Test_ChannellingAPI_OnIncoming_HelloMessage_JoinsTheSelectedRoom(t *testing.T) {
@ -199,7 +195,7 @@ func Test_ChannellingAPI_OnIncoming_HelloMessageWithAnIid_RespondsWithAWelcome(t @@ -199,7 +195,7 @@ func Test_ChannellingAPI_OnIncoming_HelloMessageWithAnIid_RespondsWithAWelcome(t
func Test_ChannellingAPI_OnIncoming_HelloMessageWithAnIid_RespondsWithAnErrorIfTheRoomCannotBeJoined(t *testing.T) {
iid := "foo"
api, client, session, roomManager := NewTestChannellingAPI()
roomManager.joinError = &DataError{Type: "Error", Code: "bad_join"}
roomManager.joinError = NewDataError("bad_join", "")
api.OnIncoming(client, session, &DataIncoming{Type: "Hello", Iid: iid, Hello: &DataHello{}})
@ -235,7 +231,7 @@ func Test_ChannellingAPI_OnIncoming_RoomMessage_RespondsWithAndBroadcastsTheUpda @@ -235,7 +231,7 @@ func Test_ChannellingAPI_OnIncoming_RoomMessage_RespondsWithAndBroadcastsTheUpda
func Test_ChannellingAPI_OnIncoming_RoomMessage_RespondsWithAnErrorIfUpdatingTheRoomFails(t *testing.T) {
iid, roomName := "123", "foo"
api, client, session, roomManager := NewTestChannellingAPI()
roomManager.updateError = &DataError{Type: "Error", Code: "a_room_error", Message: ""}
roomManager.updateError = NewDataError("a_room_error", "")
api.OnIncoming(client, session, &DataIncoming{Type: "Hello", Iid: "0", Hello: &DataHello{Id: roomName}})
api.OnIncoming(client, session, &DataIncoming{Type: "Room", Iid: iid, Room: &DataRoom{Name: roomName}})

77
src/app/spreed-webrtc-server/config.go

@ -24,6 +24,10 @@ package main @@ -24,6 +24,10 @@ package main
import (
"fmt"
"net/http"
"strings"
"time"
"github.com/strukturag/phoenix"
)
type Config struct {
@ -41,30 +45,79 @@ type Config struct { @@ -41,30 +45,79 @@ type Config struct {
UsersMode string // Users mode string
DefaultRoomEnabled bool // Flag if default room ("") is enabled
Plugin string // Plugin to load
globalRoomid string // Id of the global room (not exported to Javascript)
globalRoomID string // Id of the global room (not exported to Javascript)
authorizeRoomCreation bool // Whether a user account is required to create rooms (not exported to Javascript)
}
func NewConfig(title, ver, runtimeVersion, basePath, serverToken string, stunURIs, turnURIs []string, tokens bool, globalRoomid string, defaultRoomEnabled, usersEnabled, usersAllowRegistration bool, usersMode, plugin string) *Config {
sv := fmt.Sprintf("static/ver=%s", ver)
func NewConfig(container phoenix.Container, tokens bool) *Config {
ver := container.GetStringDefault("app", "ver", "")
version := container.Version()
if version != "unreleased" {
ver = fmt.Sprintf("%s%s", ver, strings.Replace(version, ".", "", -1))
} else {
ts := fmt.Sprintf("%d", time.Now().Unix())
if ver == "" {
ver = ts
}
version = fmt.Sprintf("unreleased.%s", ts)
}
// Read base path from config and make sure it ends with a slash.
basePath := container.GetStringDefault("http", "basePath", "/")
if !strings.HasSuffix(basePath, "/") {
basePath = fmt.Sprintf("%s/", basePath)
}
if basePath != "/" {
container.Printf("Using '%s' base base path.", basePath)
}
//TODO(longsleep): When we have a database, generate this once from random source and store it.
serverToken := container.GetStringDefault("app", "serverToken", "i-did-not-change-the-public-token-boo")
stunURIsString := container.GetStringDefault("app", "stunURIs", "")
stunURIs := strings.Split(stunURIsString, " ")
trimAndRemoveDuplicates(&stunURIs)
turnURIsString := container.GetStringDefault("app", "turnURIs", "")
turnURIs := strings.Split(turnURIsString, " ")
trimAndRemoveDuplicates(&turnURIs)
return &Config{
Title: title,
Title: container.GetStringDefault("app", "title", "Spreed WebRTC"),
ver: ver,
S: sv,
S: fmt.Sprintf("static/ver=%s", ver),
B: basePath,
Token: serverToken,
StunURIs: stunURIs,
TurnURIs: turnURIs,
Tokens: tokens,
Version: runtimeVersion,
UsersEnabled: usersEnabled,
UsersAllowRegistration: usersAllowRegistration,
UsersMode: usersMode,
DefaultRoomEnabled: defaultRoomEnabled,
Plugin: plugin,
globalRoomid: globalRoomid,
Version: version,
UsersEnabled: container.GetBoolDefault("users", "enabled", false),
UsersAllowRegistration: container.GetBoolDefault("users", "allowRegistration", false),
UsersMode: container.GetStringDefault("users", "mode", ""),
DefaultRoomEnabled: container.GetBoolDefault("app", "defaultRoomEnabled", true),
Plugin: container.GetStringDefault("app", "plugin", ""),
globalRoomID: container.GetStringDefault("app", "globalRoom", ""),
authorizeRoomCreation: container.GetBoolDefault("app", "authorizeRoomCreation", false),
}
}
func (config *Config) Get(request *http.Request) (int, interface{}, http.Header) {
return 200, config, http.Header{"Content-Type": {"application/json; charset=utf-8"}}
}
// Helper function to clean up string arrays.
func trimAndRemoveDuplicates(data *[]string) {
found := make(map[string]bool)
j := 0
for i, x := range *data {
x = strings.TrimSpace(x)
if len(x) > 0 && !found[x] {
found[x] = true
(*data)[j] = (*data)[i]
j++
}
}
*data = (*data)[:j]
}

145
src/app/spreed-webrtc-server/main.go

@ -40,7 +40,6 @@ import ( @@ -40,7 +40,6 @@ import (
"path"
goruntime "runtime"
"strconv"
"strings"
"syscall"
"time"
)
@ -63,21 +62,6 @@ func getRequestLanguages(r *http.Request, supportedLanguages []string) []string @@ -63,21 +62,6 @@ func getRequestLanguages(r *http.Request, supportedLanguages []string) []string
}
// Helper function to clean up string arrays.
func trimAndRemoveDuplicates(data *[]string) {
found := make(map[string]bool)
j := 0
for i, x := range *data {
x = strings.TrimSpace(x)
if len(x) > 0 && !found[x] {
found[x] = true
(*data)[j] = (*data)[i]
j++
}
}
*data = (*data)[:j]
}
func mainHandler(w http.ResponseWriter, r *http.Request) {
handleRoomView("", w, r)
@ -184,17 +168,6 @@ func runner(runtime phoenix.Runtime) error { @@ -184,17 +168,6 @@ func runner(runtime phoenix.Runtime) error {
return fmt.Errorf("Unable to find client. Path correct and compiled css?")
}
// Read base path from config and make sure it ends with a slash.
basePath, err := runtime.GetString("http", "basePath")
if err != nil {
basePath = "/"
} else {
if !strings.HasSuffix(basePath, "/") {
basePath = fmt.Sprintf("%s/", basePath)
}
log.Printf("Using '%s' base base path.", basePath)
}
statsEnabled, err := runtime.GetBool("http", "stats")
if err != nil {
statsEnabled = false
@ -246,109 +219,33 @@ func runner(runtime phoenix.Runtime) error { @@ -246,109 +219,33 @@ func runner(runtime phoenix.Runtime) error {
}
}
tokenFile, err := runtime.GetString("app", "tokenFile")
if err == nil {
if !httputils.HasFilePath(path.Clean(tokenFile)) {
return fmt.Errorf("Unable to find token file at %s", tokenFile)
}
}
title, err := runtime.GetString("app", "title")
if err != nil {
title = "Spreed WebRTC"
}
ver, err := runtime.GetString("app", "ver")
if err != nil {
ver = ""
}
runtimeVersion := version
if version != "unreleased" {
ver1 := ver
if err != nil {
ver1 = ""
}
ver = fmt.Sprintf("%s%s", ver1, strings.Replace(version, ".", "", -1))
} else {
ts := fmt.Sprintf("%d", time.Now().Unix())
if err != nil {
ver = ts
}
runtimeVersion = fmt.Sprintf("unreleased.%s", ts)
}
turnURIsString, err := runtime.GetString("app", "turnURIs")
if err != nil {
turnURIsString = ""
}
turnURIs := strings.Split(turnURIsString, " ")
trimAndRemoveDuplicates(&turnURIs)
var turnSecret []byte
turnSecretString, err := runtime.GetString("app", "turnSecret")
if err == nil {
turnSecret = []byte(turnSecretString)
}
stunURIsString, err := runtime.GetString("app", "stunURIs")
if err != nil {
stunURIsString = ""
}
stunURIs := strings.Split(stunURIsString, " ")
trimAndRemoveDuplicates(&stunURIs)
globalRoomid, err := runtime.GetString("app", "globalRoom")
if err != nil {
// Global room is disabled.
globalRoomid = ""
}
plugin, err := runtime.GetString("app", "plugin")
if err != nil {
plugin = ""
}
defaultRoomEnabled := true
defaultRoomEnabledString, err := runtime.GetString("app", "defaultRoomEnabled")
if err == nil {
defaultRoomEnabled = defaultRoomEnabledString == "true"
}
usersEnabled := false
usersEnabledString, err := runtime.GetString("users", "enabled")
if err == nil {
usersEnabled = usersEnabledString == "true"
}
usersAllowRegistration := false
usersAllowRegistrationString, err := runtime.GetString("users", "allowRegistration")
if err == nil {
usersAllowRegistration = usersAllowRegistrationString == "true"
}
serverToken, err := runtime.GetString("app", "serverToken")
if err != nil {
//TODO(longsleep): When we have a database, generate this once from random source and store it.
serverToken = "i-did-not-change-the-public-token-boo"
}
serverRealm, err := runtime.GetString("app", "serverRealm")
if err != nil {
serverRealm = "local"
}
usersMode, _ := runtime.GetString("users", "mode")
// Create token provider.
tokenFile, err := runtime.GetString("app", "tokenFile")
if err == nil {
if !httputils.HasFilePath(path.Clean(tokenFile)) {
return fmt.Errorf("Unable to find token file at %s", tokenFile)
}
}
var tokenProvider TokenProvider
if tokenFile != "" {
log.Printf("Using token authorization from %s\n", tokenFile)
tokenProvider = TokenFileProvider(tokenFile)
}
// Create configuration data structure.
config = NewConfig(title, ver, runtimeVersion, basePath, serverToken, stunURIs, turnURIs, tokenProvider != nil, globalRoomid, defaultRoomEnabled, usersEnabled, usersAllowRegistration, usersMode, plugin)
// Load remaining configuration items.
config = NewConfig(runtime, tokenProvider != nil)
// Load templates.
tt := template.New("")
@ -373,7 +270,7 @@ func runner(runtime phoenix.Runtime) error { @@ -373,7 +270,7 @@ func runner(runtime phoenix.Runtime) error {
}
// Create realm string from config.
computedRealm := fmt.Sprintf("%s.%s", serverRealm, serverToken)
computedRealm := fmt.Sprintf("%s.%s", serverRealm, config.Token)
// Set number of go routines if it is 1
if goruntime.GOMAXPROCS(0) == 1 {
@ -406,7 +303,7 @@ func runner(runtime phoenix.Runtime) error { @@ -406,7 +303,7 @@ func runner(runtime phoenix.Runtime) error {
// Create router.
router := mux.NewRouter()
r := router.PathPrefix(basePath).Subrouter().StrictSlash(true)
r := router.PathPrefix(config.B).Subrouter().StrictSlash(true)
// HTTP listener support.
if _, err = runtime.GetString("http", "listen"); err == nil {
@ -434,12 +331,12 @@ func runner(runtime phoenix.Runtime) error { @@ -434,12 +331,12 @@ func runner(runtime phoenix.Runtime) error {
tickets := NewTickets(sessionSecret, encryptionSecret, computedRealm)
sessionManager := NewSessionManager(config, tickets, sessionSecret)
statsManager := NewStatsManager(hub, roomManager, sessionManager)
channellingAPI := NewChannellingAPI(runtimeVersion, config, roomManager, tickets, sessionManager, statsManager, hub, hub, hub, roomManager, buddyImages)
channellingAPI := NewChannellingAPI(config, roomManager, tickets, sessionManager, statsManager, hub, hub, hub, roomManager, buddyImages)
r.HandleFunc("/", httputils.MakeGzipHandler(mainHandler))
r.Handle("/static/img/buddy/{flags}/{imageid}/{idx:.*}", http.StripPrefix(basePath, makeImageHandler(buddyImages, time.Duration(24)*time.Hour)))
r.Handle("/static/{path:.*}", http.StripPrefix(basePath, httputils.FileStaticServer(http.Dir(rootFolder))))
r.Handle("/robots.txt", http.StripPrefix(basePath, http.FileServer(http.Dir(path.Join(rootFolder, "static")))))
r.Handle("/favicon.ico", http.StripPrefix(basePath, http.FileServer(http.Dir(path.Join(rootFolder, "static", "img")))))
r.Handle("/static/img/buddy/{flags}/{imageid}/{idx:.*}", http.StripPrefix(config.B, makeImageHandler(buddyImages, time.Duration(24)*time.Hour)))
r.Handle("/static/{path:.*}", http.StripPrefix(config.B, httputils.FileStaticServer(http.Dir(rootFolder))))
r.Handle("/robots.txt", http.StripPrefix(config.B, http.FileServer(http.Dir(path.Join(rootFolder, "static")))))
r.Handle("/favicon.ico", http.StripPrefix(config.B, http.FileServer(http.Dir(path.Join(rootFolder, "static", "img")))))
r.Handle("/ws", makeWSHandler(statsManager, sessionManager, codec, channellingAPI))
r.HandleFunc("/{room}", httputils.MakeGzipHandler(roomHandler))
@ -449,11 +346,11 @@ func runner(runtime phoenix.Runtime) error { @@ -449,11 +346,11 @@ func runner(runtime phoenix.Runtime) error {
api.AddResource(&Rooms{}, "/rooms")
api.AddResource(config, "/config")
api.AddResourceWithWrapper(&Tokens{tokenProvider}, httputils.MakeGzipHandler, "/tokens")
if usersEnabled {
if config.UsersEnabled {
// Create Users handler.
users := NewUsers(hub, tickets, sessionManager, usersMode, serverRealm, runtime)
users := NewUsers(hub, tickets, sessionManager, config.UsersMode, serverRealm, runtime)
api.AddResource(&Sessions{tickets, hub, users}, "/sessions/{id}/")
if usersAllowRegistration {
if config.UsersAllowRegistration {
api.AddResource(users, "/users")
}
}
@ -466,7 +363,7 @@ func runner(runtime phoenix.Runtime) error { @@ -466,7 +363,7 @@ func runner(runtime phoenix.Runtime) error {
if extraFolder != "" {
extraFolderStatic := path.Join(extraFolder, "static")
if _, err = os.Stat(extraFolderStatic); err == nil {
r.Handle("/extra/static/{path:.*}", http.StripPrefix(fmt.Sprintf("%sextra", basePath), httputils.FileStaticServer(http.Dir(extraFolder))))
r.Handle("/extra/static/{path:.*}", http.StripPrefix(fmt.Sprintf("%sextra", config.B), httputils.FileStaticServer(http.Dir(extraFolder))))
log.Printf("Added URL handler /extra/static/... for static files in %s/...\n", extraFolderStatic)
}
}
@ -491,7 +388,7 @@ func boot() error { @@ -491,7 +388,7 @@ func boot() error {
return nil
}
return phoenix.NewServer("server", "").
return phoenix.NewServer("server", version).
Config(configPath).
Log(logPath).
CpuProfile(cpuprofile).

75
src/app/spreed-webrtc-server/room_manager.go

@ -49,18 +49,16 @@ type RoomManager interface { @@ -49,18 +49,16 @@ type RoomManager interface {
type roomManager struct {
sync.RWMutex
*Config
OutgoingEncoder
defaultRoomEnabled bool
globalRoomID string
roomTable map[string]RoomWorker
roomTable map[string]RoomWorker
}
func NewRoomManager(config *Config, encoder OutgoingEncoder) RoomManager {
return &roomManager{
sync.RWMutex{},
config,
encoder,
config.DefaultRoomEnabled,
config.globalRoomid,
make(map[string]RoomWorker),
}
}
@ -74,11 +72,16 @@ func (rooms *roomManager) RoomUsers(session *Session) []*DataSession { @@ -74,11 +72,16 @@ func (rooms *roomManager) RoomUsers(session *Session) []*DataSession {
}
func (rooms *roomManager) JoinRoom(id string, credentials *DataRoomCredentials, session *Session, sender Sender) (*DataRoom, error) {
if id == "" && !rooms.defaultRoomEnabled {
return nil, &DataError{Type: "Error", Code: "default_room_disabled", Message: "The default room is not enabled"}
if id == "" && !rooms.DefaultRoomEnabled {
return nil, NewDataError("default_room_disabled", "The default room is not enabled")
}
return rooms.GetOrCreate(id, credentials).Join(credentials, session, sender)
roomWorker, err := rooms.GetOrCreate(id, credentials, session)
if err != nil {
return nil, err
}
return roomWorker.Join(credentials, session, sender)
}
func (rooms *roomManager) LeaveRoom(session *Session) {
@ -89,7 +92,7 @@ func (rooms *roomManager) LeaveRoom(session *Session) { @@ -89,7 +92,7 @@ func (rooms *roomManager) LeaveRoom(session *Session) {
func (rooms *roomManager) UpdateRoom(session *Session, room *DataRoom) (*DataRoom, error) {
if !session.Hello || session.Roomid != room.Name {
return nil, &DataError{Type: "Error", Code: "not_in_room", Message: "Cannot update other rooms"}
return nil, NewDataError("not_in_room", "Cannot update other rooms")
}
// XXX(lcooper): We'll process and send documents without this field
// correctly, however clients cannot not handle it currently.
@ -149,32 +152,38 @@ func (rooms *roomManager) Get(id string) (room RoomWorker, ok bool) { @@ -149,32 +152,38 @@ func (rooms *roomManager) Get(id string) (room RoomWorker, ok bool) {
return
}
func (rooms *roomManager) GetOrCreate(id string, credentials *DataRoomCredentials) RoomWorker {
room, ok := rooms.Get(id)
if !ok {
rooms.Lock()
// Need to re-check, another thread might have created the room
// while we waited for the lock.
room, ok = rooms.roomTable[id]
if !ok {
room = NewRoomWorker(rooms, id, credentials)
rooms.roomTable[id] = room
rooms.Unlock()
go func() {
// Start room, this blocks until room expired.
room.Start()
// Cleanup room when we are done.
rooms.Lock()
defer rooms.Unlock()
delete(rooms.roomTable, id)
log.Printf("Cleaned up room '%s'\n", id)
}()
} else {
rooms.Unlock()
}
func (rooms *roomManager) GetOrCreate(id string, credentials *DataRoomCredentials, session *Session) (RoomWorker, error) {
if room, ok := rooms.Get(id); ok {
return room, nil
}
rooms.Lock()
// Need to re-check, another thread might have created the room
// while we waited for the lock.
if room, ok := rooms.roomTable[id]; ok {
rooms.Unlock()
return room, nil
}
if rooms.UsersEnabled && rooms.authorizeRoomCreation && !session.Authenticated() {
rooms.Unlock()
return nil, NewDataError("room_join_requires_account", "Room creation requires a user account")
}
return room
room := NewRoomWorker(rooms, id, credentials)
rooms.roomTable[id] = room
rooms.Unlock()
go func() {
// Start room, this blocks until room expired.
room.Start()
// Cleanup room when we are done.
rooms.Lock()
defer rooms.Unlock()
delete(rooms.roomTable, id)
log.Printf("Cleaned up room '%s'\n", id)
}()
return room, nil
}
func (rooms *roomManager) GlobalUsers() []*roomUser {

32
src/app/spreed-webrtc-server/room_manager_test.go

@ -25,26 +25,48 @@ import ( @@ -25,26 +25,48 @@ import (
"testing"
)
func NewTestRoomManager() RoomManager {
return NewRoomManager(&Config{}, nil)
func NewTestRoomManager() (RoomManager, *Config) {
config := &Config{}
return NewRoomManager(config, nil), config
}
func Test_RoomManager_JoinRoom_ReturnsAnErrorForUnauthenticatedSessionsWhenCreationRequiresAnAccount(t *testing.T) {
roomManager, config := NewTestRoomManager()
config.UsersEnabled = true
config.authorizeRoomCreation = true
unauthenticatedSession := &Session{}
_, err := roomManager.JoinRoom("foo", nil, unauthenticatedSession, nil)
assertDataError(t, err, "room_join_requires_account")
authenticatedSession := &Session{userid: "9870457"}
_, err = roomManager.JoinRoom("foo", nil, authenticatedSession, nil)
if err != nil {
t.Fatalf("Unexpected error %v joining room while authenticated", err)
}
_, err = roomManager.JoinRoom("foo", nil, unauthenticatedSession, nil)
if err != nil {
t.Fatalf("Unexpected error %v joining room while unauthenticated", err)
}
}
func Test_RoomManager_UpdateRoom_ReturnsAnErrorIfNoRoomHasBeenJoined(t *testing.T) {
roomManager := NewTestRoomManager()
roomManager, _ := NewTestRoomManager()
_, err := roomManager.UpdateRoom(&Session{}, nil)
assertDataError(t, err, "not_in_room")
}
func Test_RoomManager_UpdateRoom_ReturnsAnErrorIfUpdatingAnUnjoinedRoom(t *testing.T) {
roomManager := NewTestRoomManager()
roomManager, _ := NewTestRoomManager()
session := &Session{Hello: true, Roomid: "foo"}
_, err := roomManager.UpdateRoom(session, &DataRoom{Name: "bar"})
assertDataError(t, err, "not_in_room")
}
func Test_RoomManager_UpdateRoom_ReturnsACorrectlyTypedDocument(t *testing.T) {
roomManager := NewTestRoomManager()
roomManager, _ := NewTestRoomManager()
session := &Session{Hello: true, Roomid: "foo"}
room, err := roomManager.UpdateRoom(session, &DataRoom{Name: session.Roomid})
if err != nil {

6
src/app/spreed-webrtc-server/roomworker.go

@ -244,18 +244,18 @@ func (r *roomWorker) Join(credentials *DataRoomCredentials, session *Session, se @@ -244,18 +244,18 @@ func (r *roomWorker) Join(credentials *DataRoomCredentials, session *Session, se
worker := func() {
r.mutex.Lock()
if r.credentials == nil && credentials != nil {
results <- joinResult{nil, &DataError{"Error", "authorization_not_required", "No credentials may be provided for this room"}}
results <- joinResult{nil, NewDataError("authorization_not_required", "No credentials may be provided for this room")}
r.mutex.Unlock()
return
} else if r.credentials != nil {
if credentials == nil {
results <- joinResult{nil, &DataError{"Error", "authorization_required", "Valid credentials are required to join this room"}}
results <- joinResult{nil, NewDataError("authorization_required", "Valid credentials are required to join this room")}
r.mutex.Unlock()
return
}
if len(r.credentials.PIN) != len(credentials.PIN) || subtle.ConstantTimeCompare([]byte(r.credentials.PIN), []byte(credentials.PIN)) != 1 {
results <- joinResult{nil, &DataError{"Error", "invalid_credentials", "The provided credentials are incorrect"}}
results <- joinResult{nil, NewDataError("invalid_credentials", "The provided credentials are incorrect")}
r.mutex.Unlock()
return
}

4
src/app/spreed-webrtc-server/roomworker_test.go

@ -30,14 +30,14 @@ const ( @@ -30,14 +30,14 @@ const (
)
func NewTestRoomWorker() RoomWorker {
worker := NewRoomWorker(&roomManager{}, testRoomName, nil)
worker := NewRoomWorker(&roomManager{Config: &Config{}}, testRoomName, nil)
go worker.Start()
return worker
}
func NewTestRoomWorkerWithPIN(t *testing.T) (RoomWorker, string) {
pin := "asdf"
worker := NewRoomWorker(&roomManager{}, testRoomName, &DataRoomCredentials{PIN: pin})
worker := NewRoomWorker(&roomManager{Config: &Config{}}, testRoomName, &DataRoomCredentials{PIN: pin})
go worker.Start()
return worker, pin
}

7
src/app/spreed-webrtc-server/session.go

@ -173,6 +173,13 @@ func (s *Session) Authorize(realm string, st *SessionToken) (string, error) { @@ -173,6 +173,13 @@ func (s *Session) Authorize(realm string, st *SessionToken) (string, error) {
}
func (s *Session) Authenticated() (authenticated bool) {
s.mutex.Lock()
authenticated = s.userid != ""
s.mutex.Unlock()
return
}
func (s *Session) Authenticate(realm string, st *SessionToken, userid string) error {
s.mutex.Lock()

Loading…
Cancel
Save