add persistence for user modes

This commit is contained in:
Shivaram Lingamneni 2020-05-19 14:38:56 -04:00
parent a0f4e90b7e
commit 4d50607c79
3 changed files with 48 additions and 4 deletions

View File

@ -19,6 +19,7 @@ import (
"github.com/oragono/oragono/irc/connection_limits" "github.com/oragono/oragono/irc/connection_limits"
"github.com/oragono/oragono/irc/email" "github.com/oragono/oragono/irc/email"
"github.com/oragono/oragono/irc/ldap" "github.com/oragono/oragono/irc/ldap"
"github.com/oragono/oragono/irc/modes"
"github.com/oragono/oragono/irc/passwd" "github.com/oragono/oragono/irc/passwd"
"github.com/oragono/oragono/irc/utils" "github.com/oragono/oragono/irc/utils"
"github.com/tidwall/buntdb" "github.com/tidwall/buntdb"
@ -40,6 +41,7 @@ const (
keyAccountChannels = "account.channels %s" // channels registered to the account keyAccountChannels = "account.channels %s" // channels registered to the account
keyAccountJoinedChannels = "account.joinedto %s" // channels a persistent client has joined keyAccountJoinedChannels = "account.joinedto %s" // channels a persistent client has joined
keyAccountLastSeen = "account.lastseen %s" keyAccountLastSeen = "account.lastseen %s"
keyAccountModes = "account.modes %s" // user modes for the always-on client as a string
keyVHostQueueAcctToId = "vhostQueue %s" keyVHostQueueAcctToId = "vhostQueue %s"
vhostRequestIdx = "vhostQueue" vhostRequestIdx = "vhostQueue"
@ -127,7 +129,7 @@ func (am *AccountManager) createAlwaysOnClients(config *Config) {
account, err := am.LoadAccount(accountName) account, err := am.LoadAccount(accountName)
if err == nil && account.Verified && if err == nil && account.Verified &&
persistenceEnabled(config.Accounts.Multiclient.AlwaysOn, account.Settings.AlwaysOn) { persistenceEnabled(config.Accounts.Multiclient.AlwaysOn, account.Settings.AlwaysOn) {
am.server.AddAlwaysOnClient(account, am.loadChannels(accountName), am.loadLastSeen(accountName)) am.server.AddAlwaysOnClient(account, am.loadChannels(accountName), am.loadLastSeen(accountName), am.loadModes(accountName))
} }
} }
} }
@ -594,6 +596,28 @@ func (am *AccountManager) loadChannels(account string) (channels []string) {
return return
} }
func (am *AccountManager) saveModes(account string, uModes modes.Modes) {
modeStr := uModes.String()
key := fmt.Sprintf(keyAccountModes, account)
am.server.store.Update(func(tx *buntdb.Tx) error {
tx.Set(key, modeStr, nil)
return nil
})
}
func (am *AccountManager) loadModes(account string) (uModes modes.Modes) {
key := fmt.Sprintf(keyAccountModes, account)
var modeStr string
am.server.store.View(func(tx *buntdb.Tx) error {
modeStr, _ = tx.Get(key)
return nil
})
for _, m := range modeStr {
uModes = append(uModes, modes.Mode(m))
}
return
}
func (am *AccountManager) saveLastSeen(account string, lastSeen time.Time) { func (am *AccountManager) saveLastSeen(account string, lastSeen time.Time) {
key := fmt.Sprintf(keyAccountLastSeen, account) key := fmt.Sprintf(keyAccountLastSeen, account)
var val string var val string

View File

@ -360,7 +360,7 @@ func (server *Server) RunClient(conn IRCConn) {
client.run(session) client.run(session)
} }
func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string, lastSeen time.Time) { func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string, lastSeen time.Time, uModes modes.Modes) {
now := time.Now().UTC() now := time.Now().UTC()
config := server.Config() config := server.Config()
if lastSeen.IsZero() { if lastSeen.IsZero() {
@ -383,9 +383,10 @@ func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string,
alwaysOn: true, alwaysOn: true,
} }
ApplyUserModeChanges(client, config.Accounts.defaultUserModes, false, nil)
client.SetMode(modes.TLS, true) client.SetMode(modes.TLS, true)
for _, m := range uModes {
client.SetMode(m, true)
}
client.writerSemaphore.Initialize(1) client.writerSemaphore.Initialize(1)
client.history.Initialize(0, 0) client.history.Initialize(0, 0)
client.brbTimer.Initialize(client) client.brbTimer.Initialize(client)
@ -1633,6 +1634,7 @@ func (client *Client) historyStatus(config *Config) (status HistoryStatus, targe
const ( const (
IncludeChannels uint = 1 << iota IncludeChannels uint = 1 << iota
IncludeLastSeen IncludeLastSeen
IncludeUserModes
) )
func (client *Client) markDirty(dirtyBits uint) { func (client *Client) markDirty(dirtyBits uint) {
@ -1691,4 +1693,18 @@ func (client *Client) performWrite() {
if (dirtyBits & IncludeLastSeen) != 0 { if (dirtyBits & IncludeLastSeen) != 0 {
client.server.accounts.saveLastSeen(account, lastSeen) client.server.accounts.saveLastSeen(account, lastSeen)
} }
if (dirtyBits & IncludeUserModes) != 0 {
uModes := make(modes.Modes, 0, len(modes.SupportedUserModes))
for _, m := range modes.SupportedUserModes {
switch m {
case modes.Operator, modes.ServerNotice:
// these can't be persisted because they depend on the operator block
default:
if client.HasMode(m) {
uModes = append(uModes, m)
}
}
}
client.server.accounts.saveModes(account, uModes)
}
} }

View File

@ -102,6 +102,10 @@ func ApplyUserModeChanges(client *Client, changes modes.ModeChanges, force bool,
// can't do anything to TLS mode // can't do anything to TLS mode
} }
if len(applied) != 0 {
client.markDirty(IncludeUserModes)
}
// return the changes we could actually apply // return the changes we could actually apply
return applied return applied
} }