From 416faa3df460851b7ac4f304a874cece70985fcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Mon, 6 May 2024 23:47:13 +0200 Subject: [PATCH] add session to host change. --- internal/api/room/control.go | 12 +++++++----- internal/session/manager.go | 28 ++++++++++++--------------- internal/session/session.go | 28 +++++++++++++-------------- internal/websocket/handler/control.go | 4 ++-- internal/websocket/handler/session.go | 2 +- internal/websocket/manager.go | 8 +++++--- pkg/auth/auth_test.go | 2 +- pkg/types/message/messages.go | 1 + pkg/types/session.go | 7 ++++--- 9 files changed, 46 insertions(+), 46 deletions(-) diff --git a/internal/api/room/control.go b/internal/api/room/control.go index ddf04346..ed90cd41 100644 --- a/internal/api/room/control.go +++ b/internal/api/room/control.go @@ -43,7 +43,7 @@ func (h *RoomHandler) controlRequest(w http.ResponseWriter, r *http.Request) err return utils.HttpForbidden("controls are locked") } - h.sessions.SetHost(session) + session.SetAsHost() return utils.HttpSuccess(w) } @@ -55,19 +55,20 @@ func (h *RoomHandler) controlRelease(w http.ResponseWriter, r *http.Request) err } h.desktop.ResetKeys() - h.sessions.ClearHost() + session.ClearHost() return utils.HttpSuccess(w) } func (h *RoomHandler) controlTake(w http.ResponseWriter, r *http.Request) error { session, _ := auth.GetSession(r) - h.sessions.SetHost(session) + session.SetAsHost() return utils.HttpSuccess(w) } func (h *RoomHandler) controlGive(w http.ResponseWriter, r *http.Request) error { + session, _ := auth.GetSession(r) sessionId := chi.URLParam(r, "sessionId") target, ok := h.sessions.Get(sessionId) @@ -79,17 +80,18 @@ func (h *RoomHandler) controlGive(w http.ResponseWriter, r *http.Request) error return utils.HttpBadRequest("target session is not allowed to host") } - h.sessions.SetHost(target) + target.SetAsHostBy(session) return utils.HttpSuccess(w) } func (h *RoomHandler) controlReset(w http.ResponseWriter, r *http.Request) error { + session, _ := auth.GetSession(r) _, hasHost := h.sessions.GetHost() if hasHost { h.desktop.ResetKeys() - h.sessions.ClearHost() + session.ClearHost() } return utils.HttpSuccess(w) diff --git a/internal/session/manager.go b/internal/session/manager.go index c46d6452..44f9d57b 100644 --- a/internal/session/manager.go +++ b/internal/session/manager.go @@ -210,14 +210,14 @@ func (manager *SessionManagerCtx) Range(f func(session types.Session) bool) { // host // --- -func (manager *SessionManagerCtx) SetHost(host types.Session) { +func (manager *SessionManagerCtx) setHost(session, host types.Session) { var hostId string if host != nil { hostId = host.ID() } manager.hostId.Store(hostId) - manager.emmiter.Emit("host_changed", host) + manager.emmiter.Emit("host_changed", session, host) } func (manager *SessionManagerCtx) GetHost() (types.Session, bool) { @@ -229,10 +229,6 @@ func (manager *SessionManagerCtx) GetHost() (types.Session, bool) { return manager.Get(hostId) } -func (manager *SessionManagerCtx) ClearHost() { - manager.SetHost(nil) -} - func (manager *SessionManagerCtx) isHost(host types.Session) bool { hostId, ok := manager.hostId.Load().(string) return ok && hostId == host.ID() @@ -357,12 +353,12 @@ func (manager *SessionManagerCtx) OnStateChanged(listener func(session types.Ses }) } -func (manager *SessionManagerCtx) OnHostChanged(listener func(session types.Session)) { +func (manager *SessionManagerCtx) OnHostChanged(listener func(session, host types.Session)) { manager.emmiter.On("host_changed", func(payload ...any) { - if payload[0] == nil { - listener(nil) + if payload[1] == nil { + listener(payload[0].(*SessionCtx), nil) } else { - listener(payload[0].(*SessionCtx)) + listener(payload[0].(*SessionCtx), payload[1].(*SessionCtx)) } }) } @@ -394,16 +390,16 @@ func (manager *SessionManagerCtx) updateSettings(session types.Session, new, old // if private mode changed if old.PrivateMode != new.PrivateMode { // update webrtc paused state for all sessions - for _, session := range manager.List() { - enabled := session.PrivateModeEnabled() + for _, s := range manager.List() { + enabled := s.PrivateModeEnabled() // if session had control, it must release it - if enabled && session.IsHost() { - manager.ClearHost() + if enabled && s.IsHost() { + session.ClearHost() } // its webrtc connection will be paused or unpaused - if webrtcPeer := session.GetWebRTCPeer(); webrtcPeer != nil { + if webrtcPeer := s.GetWebRTCPeer(); webrtcPeer != nil { webrtcPeer.SetPaused(enabled) } } @@ -434,7 +430,7 @@ func (manager *SessionManagerCtx) updateSettings(session types.Session, new, old // if the host is not admin, it must release controls host, hasHost := manager.GetHost() if hasHost && !host.Profile().IsAdmin { - manager.ClearHost() + session.ClearHost() } } diff --git a/internal/session/session.go b/internal/session/session.go index 716f1115..2a858f68 100644 --- a/internal/session/session.go +++ b/internal/session/session.go @@ -43,7 +43,7 @@ func (session *SessionCtx) Profile() types.MemberProfile { func (session *SessionCtx) profileChanged() { if !session.profile.CanHost && session.IsHost() { - session.manager.ClearHost() + session.ClearHost() } if (!session.profile.CanConnect || !session.profile.CanLogin || !session.profile.CanWatch) && session.state.IsWatching { @@ -68,6 +68,18 @@ func (session *SessionCtx) IsHost() bool { return session.manager.isHost(session) } +func (session *SessionCtx) SetAsHost() { + session.manager.setHost(session, session) +} + +func (session *SessionCtx) SetAsHostBy(host types.Session) { + session.manager.setHost(session, host) +} + +func (session *SessionCtx) ClearHost() { + session.manager.setHost(session, nil) +} + func (session *SessionCtx) PrivateModeEnabled() bool { return session.manager.Settings().PrivateMode && !session.profile.IsAdmin } @@ -82,10 +94,8 @@ func (session *SessionCtx) SetCursor(cursor types.Cursor) { // websocket // --- -// // Connect WebSocket peer sets current peer and emits connected event. It also destroys the // previous peer, if there was one. If the peer is already set, it will be ignored. -// func (session *SessionCtx) ConnectWebSocketPeer(websocketPeer types.WebSocketPeer) { session.websocketMu.Lock() isCurrentPeer := websocketPeer == session.websocketPeer @@ -113,14 +123,12 @@ func (session *SessionCtx) ConnectWebSocketPeer(websocketPeer types.WebSocketPee } } -// // Disconnect WebSocket peer sets current peer to nil and emits disconnected event. It also // allows for a delayed disconnect. That means, the peer will not be disconnected immediately, // but after a delay. If the peer is connected again before the delay, the disconnect will be // cancelled. // // If the peer is not the current peer or the peer is nil, it will be ignored. -// func (session *SessionCtx) DisconnectWebSocketPeer(websocketPeer types.WebSocketPeer, delayed bool) { session.websocketMu.Lock() isCurrentPeer := websocketPeer == session.websocketPeer && websocketPeer != nil @@ -175,10 +183,8 @@ func (session *SessionCtx) DisconnectWebSocketPeer(websocketPeer types.WebSocket session.websocketMu.Unlock() } -// // Destroy WebSocket peer disconnects the peer and destroys it. It ensures that the peer is // disconnected immediately even though normal flow would be to disconnect it delayed. -// func (session *SessionCtx) DestroyWebSocketPeer(reason string) { session.websocketMu.Lock() peer := session.websocketPeer @@ -195,9 +201,7 @@ func (session *SessionCtx) DestroyWebSocketPeer(reason string) { peer.Destroy(reason) } -// // Send event to websocket peer. -// func (session *SessionCtx) Send(event string, payload any) { session.websocketMu.Lock() peer := session.websocketPeer @@ -212,9 +216,7 @@ func (session *SessionCtx) Send(event string, payload any) { // webrtc // --- -// // Set webrtc peer and destroy the old one, if there is old one. -// func (session *SessionCtx) SetWebRTCPeer(webrtcPeer types.WebRTCPeer) { session.webrtcMu.Lock() session.webrtcPeer, webrtcPeer = webrtcPeer, session.webrtcPeer @@ -225,14 +227,12 @@ func (session *SessionCtx) SetWebRTCPeer(webrtcPeer types.WebRTCPeer) { } } -// // Set if current webrtc peer is connected or not. Since there might be lefover calls from // webrtc peer, that are not used anymore, we need to check if the webrtc peer is still the // same as the one we are setting the connected state for. // // If webrtc peer is disconnected, we don't expect it to be reconnected, so we set it to nil // and send a signal close to the client. New connection is expected to use a new webrtc peer. -// func (session *SessionCtx) SetWebRTCConnected(webrtcPeer types.WebRTCPeer, connected bool) { session.webrtcMu.Lock() isCurrentPeer := webrtcPeer == session.webrtcPeer @@ -274,9 +274,7 @@ func (session *SessionCtx) SetWebRTCConnected(webrtcPeer types.WebRTCPeer, conne } } -// // Get current WebRTC peer. Nil if not connected. -// func (session *SessionCtx) GetWebRTCPeer() types.WebRTCPeer { session.webrtcMu.Lock() defer session.webrtcMu.Unlock() diff --git a/internal/websocket/handler/control.go b/internal/websocket/handler/control.go index e92add15..2eb8f989 100644 --- a/internal/websocket/handler/control.go +++ b/internal/websocket/handler/control.go @@ -26,7 +26,7 @@ func (h *MessageHandlerCtx) controlRelease(session types.Session) error { } h.desktop.ResetKeys() - h.sessions.ClearHost() + session.ClearHost() return nil } @@ -58,7 +58,7 @@ func (h *MessageHandlerCtx) controlRequest(session types.Session) error { } } - h.sessions.SetHost(session) + session.SetAsHost() return nil } diff --git a/internal/websocket/handler/session.go b/internal/websocket/handler/session.go index 3b1c5bd5..11ec35b5 100644 --- a/internal/websocket/handler/session.go +++ b/internal/websocket/handler/session.go @@ -56,7 +56,7 @@ func (h *MessageHandlerCtx) SessionDisconnected(session types.Session) error { // clear host if exists if session.IsHost() { h.desktop.ResetKeys() - h.sessions.ClearHost() + session.ClearHost() } if session.Profile().IsAdmin { diff --git a/internal/websocket/manager.go b/internal/websocket/manager.go index f04baf34..b06d20d0 100644 --- a/internal/websocket/manager.go +++ b/internal/websocket/manager.go @@ -110,18 +110,20 @@ func (manager *WebSocketManagerCtx) Start() { Msg("session state changed") }) - manager.sessions.OnHostChanged(func(session types.Session) { + manager.sessions.OnHostChanged(func(session, host types.Session) { payload := message.ControlHost{ - HasHost: session != nil, + ID: session.ID(), + HasHost: host != nil, } if payload.HasHost { - payload.HostID = session.ID() + payload.HostID = host.ID() } manager.sessions.Broadcast(event.CONTROL_HOST, payload) manager.logger.Info(). + Str("session_id", session.ID()). Bool("has_host", payload.HasHost). Str("host_id", payload.HostID). Msg("session host changed") diff --git a/pkg/auth/auth_test.go b/pkg/auth/auth_test.go index d4b082df..dd22d472 100644 --- a/pkg/auth/auth_test.go +++ b/pkg/auth/auth_test.go @@ -97,7 +97,7 @@ func TestHostsOnly(t *testing.T) { } // r2 is host - sessionManager.SetHost(session) + session.SetAsHost() r3, _, err := rWithSession(types.MemberProfile{CanHost: false}) if err != nil { diff --git a/pkg/types/message/messages.go b/pkg/types/message/messages.go index e127d563..a35c07d7 100644 --- a/pkg/types/message/messages.go +++ b/pkg/types/message/messages.go @@ -116,6 +116,7 @@ type SessionCursors struct { ///////////////////////////// type ControlHost struct { + ID string `json:"id"` HasHost bool `json:"has_host"` HostID string `json:"host_id,omitempty"` } diff --git a/pkg/types/session.go b/pkg/types/session.go index 300a86e0..5ea67670 100644 --- a/pkg/types/session.go +++ b/pkg/types/session.go @@ -57,6 +57,9 @@ type Session interface { Profile() MemberProfile State() SessionState IsHost() bool + SetAsHost() + SetAsHostBy(session Session) + ClearHost() PrivateModeEnabled() bool // cursor @@ -83,9 +86,7 @@ type SessionManager interface { List() []Session Range(func(Session) bool) - SetHost(host Session) GetHost() (Session, bool) - ClearHost() SetCursor(cursor Cursor, session Session) PopCursors() map[Session][]Cursor @@ -100,7 +101,7 @@ type SessionManager interface { OnDisconnected(listener func(session Session)) OnProfileChanged(listener func(session Session)) OnStateChanged(listener func(session Session)) - OnHostChanged(listener func(session Session)) + OnHostChanged(listener func(session, host Session)) OnSettingsChanged(listener func(session Session, new Settings, old Settings)) UpdateSettingsFunc(session Session, f func(settings *Settings) bool)