Skip to content

Commit

Permalink
Merge pull request strukturag#436 from fancycode/public_rooms
Browse files Browse the repository at this point in the history
Add option to specify a regular expression for public rooms.
  • Loading branch information
fancycode authored Aug 14, 2017
2 parents a61ad61 + 1550e62 commit ff95b5e
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 3 deletions.
1 change: 1 addition & 0 deletions go/channelling/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
19 changes: 16 additions & 3 deletions go/channelling/room_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
Expand Down
50 changes: 50 additions & 0 deletions go/channelling/room_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
package channelling

import (
"regexp"
"testing"

"github.com/strukturag/spreed-webrtc/go/channelling"
Expand Down Expand Up @@ -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)
Expand Down
11 changes: 11 additions & 0 deletions go/channelling/server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
}

Expand Down
4 changes: 4 additions & 0 deletions server.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ff95b5e

Please sign in to comment.