Implicit control gain (#108)
* add client side implicit hosting. * add server side implicit hosting. * update changelog. * allow clipboard & keybaord access.
This commit is contained in:
@ -29,6 +29,8 @@ type SessionManager struct {
|
||||
remote types.RemoteManager
|
||||
members map[string]*Session
|
||||
emmiter events.EventEmmiter
|
||||
// TODO: Handle locks in sessions as flags.
|
||||
controlLocked bool
|
||||
}
|
||||
|
||||
func (manager *SessionManager) New(id string, admin bool, socket types.WebSocket) types.Session {
|
||||
@ -104,6 +106,16 @@ func (manager *SessionManager) Get(id string) (types.Session, bool) {
|
||||
return session, ok
|
||||
}
|
||||
|
||||
// TODO: Handle locks in sessions as flags.
|
||||
func (manager *SessionManager) SetControlLocked(locked bool) {
|
||||
manager.controlLocked = locked
|
||||
}
|
||||
|
||||
func (manager *SessionManager) CanControl(id string) bool {
|
||||
session, ok := manager.Get(id)
|
||||
return ok && (!manager.controlLocked || session.Admin())
|
||||
}
|
||||
|
||||
func (manager *SessionManager) Admins() []*types.Member {
|
||||
manager.mu.Lock()
|
||||
defer manager.mu.Unlock()
|
||||
|
@ -22,6 +22,8 @@ type WebRTC struct {
|
||||
NAT1To1IPs []string
|
||||
TCPMUX int
|
||||
UDPMUX int
|
||||
|
||||
ImplicitControl bool
|
||||
}
|
||||
|
||||
func (WebRTC) Init(cmd *cobra.Command) error {
|
||||
@ -65,6 +67,12 @@ func (WebRTC) Init(cmd *cobra.Command) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: Should be moved to session config.
|
||||
cmd.PersistentFlags().Bool("implicitcontrol", false, "if enabled members can gain control implicitly")
|
||||
if err := viper.BindPFlag("implicitcontrol", cmd.PersistentFlags().Lookup("implicitcontrol")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -120,4 +128,7 @@ func (s *WebRTC) Set() {
|
||||
s.EphemeralMin = min
|
||||
s.EphemeralMax = max
|
||||
}
|
||||
|
||||
// TODO: Should be moved to session config.
|
||||
s.ImplicitControl = viper.GetBool("implicitcontrol")
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ type SessionManager interface {
|
||||
ClearHost()
|
||||
Has(id string) bool
|
||||
Get(id string) (Session, bool)
|
||||
SetControlLocked(locked bool)
|
||||
CanControl(id string) bool
|
||||
Members() []*Member
|
||||
Admins() []*Member
|
||||
Destroy(id string)
|
||||
|
@ -13,6 +13,7 @@ type WebRTCManager interface {
|
||||
CreatePeer(id string, session Session) (Peer, error)
|
||||
ICELite() bool
|
||||
ICEServers() []webrtc.ICEServer
|
||||
ImplicitControl() bool
|
||||
}
|
||||
|
||||
type Peer interface {
|
||||
|
@ -39,7 +39,7 @@ type PayloadKey struct {
|
||||
}
|
||||
|
||||
func (manager *WebRTCManager) handle(id string, msg webrtc.DataChannelMessage) error {
|
||||
if !manager.sessions.IsHost(id) {
|
||||
if (!manager.config.ImplicitControl && !manager.sessions.IsHost(id)) || (manager.config.ImplicitControl && !manager.sessions.CanControl(id)) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -301,6 +301,10 @@ func (manager *WebRTCManager) ICEServers() []webrtc.ICEServer {
|
||||
return manager.config.ICEServers
|
||||
}
|
||||
|
||||
func (manager *WebRTCManager) ImplicitControl() bool {
|
||||
return manager.config.ImplicitControl
|
||||
}
|
||||
|
||||
func (manager *WebRTCManager) createTrack(codecName string) (*webrtc.TrackLocalStaticSample, webrtc.RTPCodecParameters, error) {
|
||||
var codec webrtc.RTPCodecParameters
|
||||
|
||||
|
@ -25,6 +25,11 @@ func (h *MessageHandler) adminLock(id string, session types.Session, payload *me
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: Handle locks in sessions as flags.
|
||||
if payload.Resource == "control" {
|
||||
h.sessions.SetControlLocked(true)
|
||||
}
|
||||
|
||||
h.locked[payload.Resource] = id
|
||||
|
||||
if err := h.sessions.Broadcast(
|
||||
@ -52,6 +57,11 @@ func (h *MessageHandler) adminUnlock(id string, session types.Session, payload *
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: Handle locks in sessions as flags.
|
||||
if payload.Resource == "control" {
|
||||
h.sessions.SetControlLocked(false)
|
||||
}
|
||||
|
||||
delete(h.locked, payload.Resource)
|
||||
|
||||
if err := h.sessions.Broadcast(
|
||||
|
@ -125,9 +125,9 @@ func (h *MessageHandler) controlGive(id string, session types.Session, payload *
|
||||
}
|
||||
|
||||
func (h *MessageHandler) controlClipboard(id string, session types.Session, payload *message.Clipboard) error {
|
||||
// check if session is host
|
||||
if !h.sessions.IsHost(id) {
|
||||
h.logger.Debug().Str("id", id).Msg("is not the host")
|
||||
// check if session can access clipboard
|
||||
if (!h.webrtc.ImplicitControl() && !h.sessions.IsHost(id)) || (h.webrtc.ImplicitControl() && !h.sessions.CanControl(id)) {
|
||||
h.logger.Debug().Str("id", id).Msg("cannot access clipboard")
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -136,9 +136,9 @@ func (h *MessageHandler) controlClipboard(id string, session types.Session, payl
|
||||
}
|
||||
|
||||
func (h *MessageHandler) controlKeyboard(id string, session types.Session, payload *message.Keyboard) error {
|
||||
// check if session is host
|
||||
if !h.sessions.IsHost(id) {
|
||||
h.logger.Debug().Str("id", id).Msg("is not the host")
|
||||
// check if session can control keyboard
|
||||
if (!h.webrtc.ImplicitControl() && !h.sessions.IsHost(id)) || (h.webrtc.ImplicitControl() && !h.sessions.CanControl(id)) {
|
||||
h.logger.Debug().Str("id", id).Msg("cannot control keyboard")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ func (h *MessageHandler) SessionCreated(id string, session types.Session) error
|
||||
// send initialization information
|
||||
if err := session.Send(message.SystemInit{
|
||||
Event: event.SYSTEM_INIT,
|
||||
ImplicitHosting: true,
|
||||
ImplicitHosting: h.webrtc.ImplicitControl(),
|
||||
Locks: h.locked,
|
||||
}); err != nil {
|
||||
h.logger.Warn().Str("id", id).Err(err).Msgf("sending event %s has failed", event.SYSTEM_INIT)
|
||||
|
@ -105,6 +105,7 @@ func (ws *WebSocketHandler) Start() {
|
||||
sess, ok := ws.handler.locked["control"]
|
||||
if ok && ws.conf.ControlProtection && sess == CONTROL_PROTECTION_SESSION && len(ws.sessions.Admins()) > 0 {
|
||||
delete(ws.handler.locked, "control")
|
||||
ws.sessions.SetControlLocked(false) // TODO: Handle locks in sessions as flags.
|
||||
ws.logger.Info().Msgf("control unlocked on behalf of control protection")
|
||||
|
||||
if err := ws.sessions.Broadcast(
|
||||
@ -140,6 +141,7 @@ func (ws *WebSocketHandler) Start() {
|
||||
_, ok := ws.handler.locked["control"]
|
||||
if !ok && ws.conf.ControlProtection && adminCount == 0 {
|
||||
ws.handler.locked["control"] = CONTROL_PROTECTION_SESSION
|
||||
ws.sessions.SetControlLocked(true) // TODO: Handle locks in sessions as flags.
|
||||
ws.logger.Info().Msgf("control locked and released on behalf of control protection")
|
||||
ws.handler.adminRelease(id, session)
|
||||
|
||||
|
Reference in New Issue
Block a user