diff --git a/distro-packages/Arch-Linux/skald-git/PKGBUILD b/distro-packages/Arch-Linux/skald-git/PKGBUILD index 3440178..901eb0f 100644 --- a/distro-packages/Arch-Linux/skald-git/PKGBUILD +++ b/distro-packages/Arch-Linux/skald-git/PKGBUILD @@ -2,7 +2,7 @@ # shellcheck shell=bash disable=SC2034,SC2154 pkgname=skald-git -pkgver=0.0.0.r1526.ga0a1b79 +pkgver=0.0.0.r1527.g47d1308 pkgrel=1 pkgdesc='Audio-only hall-based conferencing server' arch=('x86_64' 'aarch64') diff --git a/hall/hall.go b/hall/hall.go index 04781df..61e826e 100644 --- a/hall/hall.go +++ b/hall/hall.go @@ -549,7 +549,7 @@ func AddClient(hall string, c Client, creds ClientCredentials) (*Hall, error) { if g.locked != nil { m := *g.locked if m == "" { - m = "this hall is locked" + m = "Hall is locked." } return nil, UserError(m) } @@ -632,7 +632,7 @@ func autoLockKick(g *Hall) { } } if g.description.Autolock && g.locked == nil { - m := "this hall is locked" + m := "Hall is locked." g.locked = &m for _, c := range clients { c.Joined(g.Name(), "change") diff --git a/hall/hall_test.go b/hall/hall_test.go index 041df3a..85cd10b 100644 --- a/hall/hall_test.go +++ b/hall/hall_test.go @@ -4,10 +4,14 @@ import ( "encoding/json" "errors" "fmt" + "net" + "os" + "path/filepath" "sort" "testing" "time" + "git.stormux.org/storm/skald/conn" "github.com/pion/webrtc/v4" ) @@ -121,6 +125,81 @@ func TestChatHistory(t *testing.T) { } } +type testClient struct { + id string + username string + permissions []string +} + +func (c *testClient) Hall() *Hall { return nil } +func (c *testClient) Addr() net.Addr { return nil } +func (c *testClient) Id() string { return c.id } +func (c *testClient) Username() string { return c.username } +func (c *testClient) SetUsername(username string) { c.username = username } +func (c *testClient) Permissions() []string { return c.permissions } +func (c *testClient) SetPermissions(permissions []string) { c.permissions = permissions } +func (c *testClient) Data() map[string]interface{} { return nil } +func (c *testClient) PushConn(*Hall, string, conn.Up, []conn.UpTrack, string) error { + return nil +} +func (c *testClient) RequestConns(Client, *Hall, string) error { return nil } +func (c *testClient) Joined(string, string) error { return nil } +func (c *testClient) PushClient(string, string, string, string, []string, map[string]interface{}) error { + return nil +} +func (c *testClient) Kick(string, *string, string) error { return nil } + +func TestLockedHallJoinMessage(t *testing.T) { + halls.halls = nil + oldDirectory := Directory + Directory = t.TempDir() + t.Cleanup(func() { + Directory = oldDirectory + halls.halls = nil + }) + + err := os.WriteFile( + filepath.Join(Directory, "locked-message-test.json"), + []byte(`{ + "users": { + "user1": {"password": "secret", "permissions": "present"}, + "admin": {"password": "secret", "permissions": "op"} + } + }`), + 0644, + ) + if err != nil { + t.Fatalf("WriteFile: %v", err) + } + + g, err := Add("locked-message-test", nil) + if err != nil { + t.Fatalf("Add: %v", err) + } + g.SetLocked(true, "") + + username := "user1" + _, err = AddClient(g.Name(), &testClient{id: "user1"}, ClientCredentials{ + Username: &username, + Password: "secret", + }) + if err == nil { + t.Fatalf("AddClient unexpectedly succeeded") + } + if got, want := err.Error(), "Hall is locked."; got != want { + t.Fatalf("locked join message: got %q, want %q", got, want) + } + + adminUsername := "admin" + _, err = AddClient(g.Name(), &testClient{id: "admin"}, ClientCredentials{ + Username: &adminUsername, + Password: "secret", + }) + if err != nil { + t.Fatalf("operator join should bypass lock: %v", err) + } +} + func permissionsEqual(a, b []string) bool { // nil case if len(a) == 0 && len(b) == 0 { diff --git a/rtpconn/webclient.go b/rtpconn/webclient.go index d7ab324..73a6069 100644 --- a/rtpconn/webclient.go +++ b/rtpconn/webclient.go @@ -70,6 +70,18 @@ func broadcastRecordingStatus(g *hall.Hall, message string) { } } +func broadcastHallInfo(g *hall.Hall, message string) { + err := broadcast(g.GetClients(nil), clientMessage{ + Type: "usermessage", + Kind: "info", + Privileged: true, + Value: message, + }) + if err != nil { + log.Printf("broadcast(hall info): %v", err) + } +} + type webClient struct { hall *hall.Hall addr net.Addr @@ -1658,6 +1670,11 @@ func handleClientMessage(c *webClient, m clientMessage) error { message = v } g.SetLocked(m.Kind == "lock", message) + if m.Kind == "lock" { + broadcastHallInfo(g, "Hall locked") + } else { + broadcastHallInfo(g, "Hall unlocked") + } case "record": if !member("record", c.permissions) { return c.error(hall.UserError("not authorised")) diff --git a/static/skald.html b/static/skald.html index 2c5d672..0563446 100644 --- a/static/skald.html +++ b/static/skald.html @@ -103,19 +103,6 @@ -