From da45f62ca88417bd777c01eed31416cd8d69a5c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Sun, 16 Jun 2024 18:10:55 +0200 Subject: [PATCH] chat: use can send & can receive in settings and profile. --- internal/plugins/chat/manager.go | 139 ++++++++++++------------------- 1 file changed, 54 insertions(+), 85 deletions(-) diff --git a/internal/plugins/chat/manager.go b/internal/plugins/chat/manager.go index 79dff3d8..93e3c1bd 100644 --- a/internal/plugins/chat/manager.go +++ b/internal/plugins/chat/manager.go @@ -2,6 +2,8 @@ package chat import ( "encoding/json" + "errors" + "fmt" "net/http" "time" @@ -32,10 +34,35 @@ type Manager struct { sessions types.SessionManager } -func (m *Manager) isEnabledForSession(session types.Session) bool { - return m.config.Enabled && - settingsIsEnabled(m.sessions.Settings()) && - profileIsEnabled(session.Profile()) +type Settings struct { + CanSend bool `json:"can_send" mapstructure:"can_send"` + CanReceive bool `json:"can_receive" mapstructure:"can_receive"` +} + +func (m *Manager) settingsForSession(session types.Session) (Settings, error) { + settings := Settings{ + CanSend: true, // defaults to true + CanReceive: true, // defaults to true + } + err := m.sessions.Settings().Plugins.Unmarshal(PluginName, &settings) + if err != nil && !errors.Is(err, types.ErrPluginSettingsNotFound) { + return Settings{}, fmt.Errorf("unable to unmarshal %s plugin settings from global settings: %w", PluginName, err) + } + + profile := Settings{ + CanSend: true, // defaults to true + CanReceive: true, // defaults to true + } + + err = session.Profile().Plugins.Unmarshal(PluginName, &profile) + if err != nil && !errors.Is(err, types.ErrPluginSettingsNotFound) { + return Settings{}, fmt.Errorf("unable to unmarshal %s plugin settings from profile: %w", PluginName, err) + } + + return Settings{ + CanSend: m.config.Enabled && (settings.CanSend || session.Profile().IsAdmin) && profile.CanSend, + CanReceive: m.config.Enabled && (settings.CanReceive || session.Profile().IsAdmin) && profile.CanReceive, + }, nil } func (m *Manager) sendMessage(session types.Session, content Content) { @@ -44,7 +71,7 @@ func (m *Manager) sendMessage(session types.Session, content Content) { // get all sessions that have chat enabled var sessions []types.Session m.sessions.Range(func(s types.Session) bool { - if m.isEnabledForSession(s) { + if settings, err := m.settingsForSession(s); err == nil && settings.CanReceive { sessions = append(sessions, s) } // continue iteration over all sessions @@ -64,55 +91,11 @@ func (m *Manager) sendMessage(session types.Session, content Content) { func (m *Manager) Start() error { // send init message once a user connects m.sessions.OnConnected(func(session types.Session) { - isEnabled := m.isEnabledForSession(session) - - // send init message session.Send(CHAT_INIT, Init{ - Enabled: isEnabled, + Enabled: m.config.Enabled, }) }) - // do not proceed if chat is disabled in the config - if !m.config.Enabled { - return nil - } - - // on settings change, reinit if chat is enabled/disabled - m.sessions.OnSettingsChanged(func(session types.Session, new, old types.Settings) { - isEnabled := settingsIsEnabled(new) - wasEnabled := settingsIsEnabled(old) - - if !isEnabled && wasEnabled { - // if chat was enabled and is now disabled, broadcast to all sessions - // because it cannot be overridden by profile settings - m.sessions.Broadcast(CHAT_INIT, Init{ - Enabled: false, - }) - } - if isEnabled && !wasEnabled { - // if chat was disabled and is now enabled, loop over all sessions - // and send the init message (because it can be overridden by profile settings) - for _, s := range m.sessions.List() { - s.Send(CHAT_INIT, Init{ - Enabled: m.isEnabledForSession(s), - }) - } - } - }) - - // on profile change, reinit if chat is enabled/disabled - m.sessions.OnProfileChanged(func(session types.Session, new, old types.MemberProfile) { - isEnabled := profileIsEnabled(new) - wasEnabled := profileIsEnabled(old) - - if isEnabled != wasEnabled { - // only if the chat setting was changed, send the init message - session.Send(CHAT_INIT, Init{ - Enabled: m.isEnabledForSession(session), - }) - } - }) - return nil } @@ -134,6 +117,18 @@ func (m *Manager) WebSocketHandler(session types.Session, msg types.WebSocketMes return true } + settings, err := m.settingsForSession(session) + if err != nil { + m.logger.Error().Err(err).Msg("error checking chat permissions for this session") + // we processed the message, return true + return true + } + if !settings.CanSend { + m.logger.Warn().Msg("not allowed to send chat messages") + // we processed the message, return true + return true + } + m.sendMessage(session, content) return true } @@ -146,9 +141,15 @@ func (m *Manager) sendMessageHandler(w http.ResponseWriter, r *http.Request) err return utils.HttpUnauthorized("session not found") } - enabled := m.isEnabledForSession(session) - if !enabled { - return utils.HttpForbidden("chat is disabled") + settings, err := m.settingsForSession(session) + if err != nil { + return utils.HttpInternalServerError(). + WithInternalErr(err). + Msg("error checking chat permissions for this session") + } + + if !settings.CanSend { + return utils.HttpForbidden("not allowed to send chat messages") } content := Content{} @@ -159,35 +160,3 @@ func (m *Manager) sendMessageHandler(w http.ResponseWriter, r *http.Request) err m.sendMessage(session, content) return utils.HttpSuccess(w) } - -func settingsIsEnabled(s types.Settings) bool { - isEnabled := true - - settings, ok := s.Plugins["chat"] - // by default, allow chat if the plugin config is not present - if ok { - isEnabled, ok = settings.(bool) - // if the plugin is present but not a boolean, allow chat - if !ok { - isEnabled = true - } - } - - return isEnabled -} - -func profileIsEnabled(p types.MemberProfile) bool { - isEnabled := true - - settings, ok := p.Plugins["chat"] - // by default, allow chat if the plugin config is not present - if ok { - isEnabled, ok = settings.(bool) - // if the plugin is present but not a boolean, allow chat - if !ok { - isEnabled = true - } - } - - return isEnabled -}