diff --git a/irc/client.go b/irc/client.go index 1443d6f7..a50959c3 100644 --- a/irc/client.go +++ b/irc/client.go @@ -318,6 +318,10 @@ func (server *Server) RunClient(conn clientConn, proxyLine string) { session.idletimer.Initialize(session) session.resetFakelag() + for _, defaultMode := range config.Accounts.defaultUserModes { + client.SetMode(defaultMode, true) + } + if conn.Config.TLSConfig != nil { client.SetMode(modes.TLS, true) // error is not useful to us here anyways so we can ignore it diff --git a/irc/config.go b/irc/config.go index 42d58512..e40f04cc 100644 --- a/irc/config.go +++ b/irc/config.go @@ -261,6 +261,8 @@ type AccountConfig struct { Exempted []string exemptedNets []net.IPNet } `yaml:"require-sasl"` + DefaultUserModes *string `yaml:"default-user-modes"` + defaultUserModes modes.Modes LDAP ldap.ServerConfig LoginThrottling ThrottleConfig `yaml:"login-throttling"` SkipServerPassword bool `yaml:"skip-server-password"` @@ -982,6 +984,8 @@ func LoadConfig(filename string) (config *Config, err error) { } } + config.Accounts.defaultUserModes = ParseDefaultUserModes(config.Accounts.DefaultUserModes) + config.Accounts.RequireSasl.exemptedNets, err = utils.ParseNetList(config.Accounts.RequireSasl.Exempted) if err != nil { return nil, fmt.Errorf("Could not parse require-sasl exempted nets: %v", err.Error()) diff --git a/irc/modes.go b/irc/modes.go index e6f2c04e..4372f9bb 100644 --- a/irc/modes.go +++ b/irc/modes.go @@ -20,6 +20,10 @@ var ( DefaultChannelModes = modes.Modes{ modes.NoOutside, modes.OpOnlyTopic, } + + // DefaultUserModes are set on all users when they login. + // this can be overridden in the `server` config, with the `default-user-modes` key + DefaultUserModes = modes.Modes{} ) // ApplyUserModeChanges applies the given changes, and returns the applied changes. @@ -102,21 +106,35 @@ func ApplyUserModeChanges(client *Client, changes modes.ModeChanges, force bool, return applied } +// parseDefaultModes uses the provided mode change parser to parse the rawModes. +func parseDefaultModes(rawModes string, parser func(params ...string) (modes.ModeChanges, map[rune]bool)) modes.Modes { + modeChangeStrings := strings.Fields(rawModes) + modeChanges, _ := parser(modeChangeStrings...) + defaultModes := make(modes.Modes, 0) + for _, modeChange := range modeChanges { + if modeChange.Op == modes.Add { + defaultModes = append(defaultModes, modeChange.Mode) + } + } + return defaultModes +} + // ParseDefaultChannelModes parses the `default-modes` line of the config func ParseDefaultChannelModes(rawModes *string) modes.Modes { if rawModes == nil { // not present in config, fall back to compile-time default return DefaultChannelModes } - modeChangeStrings := strings.Fields(*rawModes) - modeChanges, _ := modes.ParseChannelModeChanges(modeChangeStrings...) - defaultChannelModes := make(modes.Modes, 0) - for _, modeChange := range modeChanges { - if modeChange.Op == modes.Add { - defaultChannelModes = append(defaultChannelModes, modeChange.Mode) - } + return parseDefaultModes(*rawModes, modes.ParseChannelModeChanges) +} + +// ParseDefaultUserModes parses the `default-user-modes` line of the config +func ParseDefaultUserModes(rawModes *string) modes.Modes { + if rawModes == nil { + // not present in config, fall back to compile-time default + return DefaultUserModes } - return defaultChannelModes + return parseDefaultModes(*rawModes, modes.ParseUserModeChanges) } // ApplyChannelModeChanges applies a given set of mode changes. diff --git a/oragono.yaml b/oragono.yaml index 9ae504ab..9bf309e5 100644 --- a/oragono.yaml +++ b/oragono.yaml @@ -451,6 +451,12 @@ accounts: offer-list: #- "oragono.test" + # modes that are set by default when a user connects + # if unset, no user modes will be set by default + # +i is invisible (a user's channels are hidden from whois replies) + # see /QUOTE HELP umodes for more user modes + # default-user-modes: +i + # support for deferring password checking to an external LDAP server # you should probably ignore this section! consult the grafana docs for details: # https://grafana.com/docs/grafana/latest/auth/ldap/