Browse Source

Add option to specify a regular expression for public rooms.

Public rooms can be created / joined even if "authorizeRoomCreation" or
"authorizeRoomJoin" are set.
pull/436/head
Joachim Bauch 8 years ago committed by Joachim Bauch
parent
commit
1550e625e1
Failed to extract signature
  1. 1
      go/channelling/config.go
  2. 19
      go/channelling/room_manager.go
  3. 50
      go/channelling/room_manager_test.go
  4. 11
      go/channelling/server/config.go
  5. 4
      server.conf.in

1
go/channelling/config.go

@ -34,6 +34,7 @@ type Config struct { @@ -34,6 +34,7 @@ type Config struct {
RoomTypes map[*regexp.Regexp]string `json:"-"` // Map of regular expression -> room type
RoomNameCaseSensitive bool // Whether the room names are case sensitive.
LockedRoomJoinableWithPIN bool // Whether locked rooms should be joinable by providing the PIN the room was locked with
PublicRoomNames *regexp.Regexp `json:"-"` // Regular expression that specifies room paths that may be created/joined without a user account.
}
func (config *Config) WithModule(m string) bool {

19
go/channelling/room_manager.go

@ -209,9 +209,17 @@ func (rooms *roomManager) Get(roomID string) (room RoomWorker, ok bool) { @@ -209,9 +209,17 @@ func (rooms *roomManager) Get(roomID string) (room RoomWorker, ok bool) {
return
}
func (rooms *roomManager) isPublicRoom(roomName string) bool {
return rooms.PublicRoomNames != nil &&
rooms.PublicRoomNames.MatchString(roomName)
}
func (rooms *roomManager) GetOrCreate(roomID, roomName, roomType string, credentials *DataRoomCredentials, sessionAuthenticated bool) (RoomWorker, error) {
isPublic := false
if rooms.AuthorizeRoomJoin && rooms.UsersEnabled && !sessionAuthenticated {
return nil, NewDataError("room_join_requires_account", "Room join requires a user account")
if isPublic = rooms.isPublicRoom(roomName); !isPublic {
return nil, NewDataError("room_join_requires_account", "Room join requires a user account")
}
}
if room, ok := rooms.Get(roomID); ok {
@ -231,8 +239,13 @@ func (rooms *roomManager) GetOrCreate(roomID, roomName, roomType string, credent @@ -231,8 +239,13 @@ func (rooms *roomManager) GetOrCreate(roomID, roomName, roomType string, credent
}
if rooms.UsersEnabled && rooms.AuthorizeRoomCreation && !sessionAuthenticated {
rooms.Unlock()
return nil, NewDataError("room_join_requires_account", "Room creation requires a user account")
// Only need to check for public room if not checked above.
if !isPublic {
if isPublic = rooms.isPublicRoom(roomName); !isPublic {
rooms.Unlock()
return nil, NewDataError("room_join_requires_account", "Room creation requires a user account")
}
}
}
room := NewRoomWorker(rooms, roomID, roomName, roomType, credentials)

50
go/channelling/room_manager_test.go

@ -22,6 +22,7 @@ @@ -22,6 +22,7 @@
package channelling
import (
"regexp"
"testing"
"github.com/strukturag/spreed-webrtc/go/channelling"
@ -74,6 +75,55 @@ func Test_RoomManager_JoinRoom_ReturnsAnErrorForUnauthenticatedSessionsWhenJoinR @@ -74,6 +75,55 @@ func Test_RoomManager_JoinRoom_ReturnsAnErrorForUnauthenticatedSessionsWhenJoinR
assertDataError(t, err, "room_join_requires_account")
}
func Test_RoomManager_JoinPublicRoom_ForUnauthenticatedSessionsWhenCreationRequiresAnAccount(t *testing.T) {
roomManager, config := NewTestRoomManager()
config.UsersEnabled = true
config.AuthorizeRoomCreation = true
unauthenticatedSession := &Session{}
_, err := roomManager.JoinRoom(channelling.RoomTypeRoom+":public", "public", channelling.RoomTypeRoom, nil, unauthenticatedSession, false, nil)
assertDataError(t, err, "room_join_requires_account")
config.PublicRoomNames = regexp.MustCompile("^public$")
_, err = roomManager.JoinRoom(channelling.RoomTypeRoom+":public", "public", channelling.RoomTypeRoom, nil, unauthenticatedSession, false, nil)
if err != nil {
t.Fatalf("Unexpected error %v joining public room", err)
}
_, err = roomManager.JoinRoom(channelling.RoomTypeRoom+":private", "private", channelling.RoomTypeRoom, nil, unauthenticatedSession, false, nil)
assertDataError(t, err, "room_join_requires_account")
}
func Test_RoomManager_JoinPublicRoom_ForUnauthenticatedSessionsWhenJoinRequiresAnAccount(t *testing.T) {
roomManager, config := NewTestRoomManager()
config.UsersEnabled = true
config.AuthorizeRoomJoin = true
authenticatedSession := &Session{userid: "9870457"}
_, err := roomManager.JoinRoom(channelling.RoomTypeRoom+":public", "public", channelling.RoomTypeRoom, nil, authenticatedSession, true, nil)
if err != nil {
t.Fatalf("Unexpected error %v joining room while authenticated", err)
}
unauthenticatedSession := &Session{}
_, err = roomManager.JoinRoom(channelling.RoomTypeRoom+":public", "public", channelling.RoomTypeRoom, nil, unauthenticatedSession, false, nil)
assertDataError(t, err, "room_join_requires_account")
config.PublicRoomNames = regexp.MustCompile("^public$")
_, err = roomManager.JoinRoom(channelling.RoomTypeRoom+":public", "public", channelling.RoomTypeRoom, nil, unauthenticatedSession, false, nil)
if err != nil {
t.Fatalf("Unexpected error %v joining public room", err)
}
_, err = roomManager.JoinRoom(channelling.RoomTypeRoom+":private", "private", channelling.RoomTypeRoom, nil, authenticatedSession, true, nil)
if err != nil {
t.Fatalf("Unexpected error %v joining room while authenticated", err)
}
_, err = roomManager.JoinRoom(channelling.RoomTypeRoom+":private", "private", channelling.RoomTypeRoom, nil, unauthenticatedSession, false, nil)
assertDataError(t, err, "room_join_requires_account")
}
func Test_RoomManager_UpdateRoom_ReturnsAnErrorIfNoRoomHasBeenJoined(t *testing.T) {
roomManager, _ := NewTestRoomManager()
_, err := roomManager.UpdateRoom(&Session{}, nil)

11
go/channelling/server/config.go

@ -119,6 +119,16 @@ func NewConfig(container phoenix.Container, tokens bool) (*channelling.Config, e @@ -119,6 +119,16 @@ func NewConfig(container phoenix.Container, tokens bool) (*channelling.Config, e
}
}
publicRoomNamesString := container.GetStringDefault("app", "publicRooms", "")
var publicRoomNames *regexp.Regexp
if publicRoomNamesString != "" {
var err error
if publicRoomNames, err = regexp.Compile(publicRoomNamesString); err != nil {
return nil, fmt.Errorf("Invalid regular expression '%s': %s", publicRoomNamesString, err)
}
log.Printf("Allowed public rooms: %s\n", publicRoomNamesString)
}
return &channelling.Config{
Title: container.GetStringDefault("app", "title", "Spreed WebRTC"),
Ver: ver,
@ -148,6 +158,7 @@ func NewConfig(container phoenix.Container, tokens bool) (*channelling.Config, e @@ -148,6 +158,7 @@ func NewConfig(container phoenix.Container, tokens bool) (*channelling.Config, e
RoomTypes: roomTypes,
RoomNameCaseSensitive: container.GetBoolDefault("app", "caseSensitiveRooms", false),
LockedRoomJoinableWithPIN: container.GetBoolDefault("app", "lockedRoomJoinableWithPIN", true),
PublicRoomNames: publicRoomNames,
}, nil
}

4
server.conf.in

@ -100,6 +100,10 @@ encryptionSecret = tne-default-encryption-block-key @@ -100,6 +100,10 @@ encryptionSecret = tne-default-encryption-block-key
; Whether locked rooms should be joinable by providing the PIN the room was
; locked with. Optional, defaults to true.
;lockedRoomJoinableWithPIN = true
; Regular expression specifying room names that can be created / joined without
; a valid user account (even if "authorizeRoomJoin" or "authorizeRoomCreation"
; is enabled).
;publicRooms =
; Whether the pipelines API should be enabled. Optional, defaults to false.
;pipelinesEnabled = false
; Server token is a public random string which is used to enhance security of

Loading…
Cancel
Save