Merge pull request #969 from ajaspers/master

Add support for default user modes. #942
This commit is contained in:
Shivaram Lingamneni 2020-04-29 22:45:27 -07:00 committed by GitHub
commit 8898d34948
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 75 additions and 8 deletions

View File

@ -430,6 +430,12 @@ accounts:
offer-list: offer-list:
#- "oragono.test" #- "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 # support for deferring password checking to an external LDAP server
# you should probably ignore this section! consult the grafana docs for details: # you should probably ignore this section! consult the grafana docs for details:
# https://grafana.com/docs/grafana/latest/auth/ldap/ # https://grafana.com/docs/grafana/latest/auth/ldap/

View File

@ -318,6 +318,10 @@ func (server *Server) RunClient(conn clientConn, proxyLine string) {
session.idletimer.Initialize(session) session.idletimer.Initialize(session)
session.resetFakelag() session.resetFakelag()
for _, defaultMode := range config.Accounts.defaultUserModes {
client.SetMode(defaultMode, true)
}
if conn.Config.TLSConfig != nil { if conn.Config.TLSConfig != nil {
client.SetMode(modes.TLS, true) client.SetMode(modes.TLS, true)
// error is not useful to us here anyways so we can ignore it // error is not useful to us here anyways so we can ignore it
@ -371,6 +375,10 @@ func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string,
alwaysOn: true, alwaysOn: true,
} }
for _, defaultMode := range config.Accounts.defaultUserModes {
client.SetMode(defaultMode, true)
}
client.SetMode(modes.TLS, true) client.SetMode(modes.TLS, true)
client.writerSemaphore.Initialize(1) client.writerSemaphore.Initialize(1)
client.history.Initialize(0, 0) client.history.Initialize(0, 0)

View File

@ -261,6 +261,8 @@ type AccountConfig struct {
Exempted []string Exempted []string
exemptedNets []net.IPNet exemptedNets []net.IPNet
} `yaml:"require-sasl"` } `yaml:"require-sasl"`
DefaultUserModes *string `yaml:"default-user-modes"`
defaultUserModes modes.Modes
LDAP ldap.ServerConfig LDAP ldap.ServerConfig
LoginThrottling ThrottleConfig `yaml:"login-throttling"` LoginThrottling ThrottleConfig `yaml:"login-throttling"`
SkipServerPassword bool `yaml:"skip-server-password"` 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) config.Accounts.RequireSasl.exemptedNets, err = utils.ParseNetList(config.Accounts.RequireSasl.Exempted)
if err != nil { if err != nil {
return nil, fmt.Errorf("Could not parse require-sasl exempted nets: %v", err.Error()) return nil, fmt.Errorf("Could not parse require-sasl exempted nets: %v", err.Error())

View File

@ -20,6 +20,10 @@ var (
DefaultChannelModes = modes.Modes{ DefaultChannelModes = modes.Modes{
modes.NoOutside, modes.OpOnlyTopic, modes.NoOutside, modes.OpOnlyTopic,
} }
// DefaultUserModes are set on all users when they login.
// this can be overridden in the `accounts` config, with the `default-user-modes` key
DefaultUserModes = modes.Modes{}
) )
// ApplyUserModeChanges applies the given changes, and returns the applied changes. // 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 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 // ParseDefaultChannelModes parses the `default-modes` line of the config
func ParseDefaultChannelModes(rawModes *string) modes.Modes { func ParseDefaultChannelModes(rawModes *string) modes.Modes {
if rawModes == nil { if rawModes == nil {
// not present in config, fall back to compile-time default // not present in config, fall back to compile-time default
return DefaultChannelModes return DefaultChannelModes
} }
modeChangeStrings := strings.Fields(*rawModes) return parseDefaultModes(*rawModes, modes.ParseChannelModeChanges)
modeChanges, _ := modes.ParseChannelModeChanges(modeChangeStrings...) }
defaultChannelModes := make(modes.Modes, 0)
for _, modeChange := range modeChanges { // ParseDefaultUserModes parses the `default-user-modes` line of the config
if modeChange.Op == modes.Add { func ParseDefaultUserModes(rawModes *string) modes.Modes {
defaultChannelModes = append(defaultChannelModes, modeChange.Mode) 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. // ApplyChannelModeChanges applies a given set of mode changes.

View File

@ -35,6 +35,31 @@ func TestParseDefaultChannelModes(t *testing.T) {
} }
} }
func TestParseDefaultUserModes(t *testing.T) {
iR := "+iR"
i := "+i"
empty := ""
rminusi := "+R -i"
var parseTests = []struct {
raw *string
expected modes.Modes
}{
{&iR, modes.Modes{modes.Invisible, modes.RegisteredOnly}},
{&i, modes.Modes{modes.Invisible}},
{&empty, modes.Modes{}},
{&rminusi, modes.Modes{modes.RegisteredOnly}},
{nil, modes.Modes{}},
}
for _, testcase := range parseTests {
result := ParseDefaultUserModes(testcase.raw)
if !reflect.DeepEqual(result, testcase.expected) {
t.Errorf("expected modes %s, got %s", testcase.expected, result)
}
}
}
func TestUmodeGreaterThan(t *testing.T) { func TestUmodeGreaterThan(t *testing.T) {
if !umodeGreaterThan(modes.Halfop, modes.Voice) { if !umodeGreaterThan(modes.Halfop, modes.Voice) {
t.Errorf("expected Halfop > Voice") t.Errorf("expected Halfop > Voice")

View File

@ -451,6 +451,12 @@ accounts:
offer-list: offer-list:
#- "oragono.test" #- "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 # support for deferring password checking to an external LDAP server
# you should probably ignore this section! consult the grafana docs for details: # you should probably ignore this section! consult the grafana docs for details:
# https://grafana.com/docs/grafana/latest/auth/ldap/ # https://grafana.com/docs/grafana/latest/auth/ldap/