3
0
mirror of https://github.com/ergochat/ergo.git synced 2025-02-16 13:40:48 +01:00

Merge branch 'realname_again'

This commit is contained in:
Shivaram Lingamneni 2020-07-12 16:49:30 -04:00
commit a99c893f9b
5 changed files with 59 additions and 9 deletions

View File

@ -39,7 +39,8 @@ 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 keyAccountModes = "account.modes %s" // user modes for the always-on client as a string
keyAccountRealname = "account.realname %s" // client realname stored as string
keyVHostQueueAcctToId = "vhostQueue %s" keyVHostQueueAcctToId = "vhostQueue %s"
vhostRequestIdx = "vhostQueue" vhostRequestIdx = "vhostQueue"
@ -127,7 +128,13 @@ 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.loadModes(accountName)) am.server.AddAlwaysOnClient(
account,
am.loadChannels(accountName),
am.loadLastSeen(accountName),
am.loadModes(accountName),
am.loadRealname(accountName),
)
} }
} }
} }
@ -650,6 +657,27 @@ func (am *AccountManager) loadLastSeen(account string) (lastSeen map[string]time
return return
} }
func (am *AccountManager) saveRealname(account string, realname string) {
key := fmt.Sprintf(keyAccountRealname, account)
am.server.store.Update(func(tx *buntdb.Tx) error {
if realname != "" {
tx.Set(key, realname, nil)
} else {
tx.Delete(key)
}
return nil
})
}
func (am *AccountManager) loadRealname(account string) (realname string) {
key := fmt.Sprintf(keyAccountRealname, account)
am.server.store.Update(func(tx *buntdb.Tx) error {
realname, _ = tx.Get(key)
return nil
})
return
}
func (am *AccountManager) addRemoveCertfp(account, certfp string, add bool, hasPrivs bool) (err error) { func (am *AccountManager) addRemoveCertfp(account, certfp string, add bool, hasPrivs bool) (err error) {
certfp, err = utils.NormalizeCertfp(certfp) certfp, err = utils.NormalizeCertfp(certfp)
if err != nil { if err != nil {
@ -874,6 +902,9 @@ func (am *AccountManager) Verify(client *Client, account string, code string) er
am.server.RandomlyRename(currentClient) am.server.RandomlyRename(currentClient)
} }
} }
if client.AlwaysOn() {
client.markDirty(IncludeRealname)
}
return nil return nil
} }

View File

@ -364,7 +364,7 @@ func (server *Server) RunClient(conn IRCConn) {
client.run(session) client.run(session)
} }
func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string, lastSeen map[string]time.Time, uModes modes.Modes) { func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string, lastSeen map[string]time.Time, uModes modes.Modes, realname string) {
now := time.Now().UTC() now := time.Now().UTC()
config := server.Config() config := server.Config()
if lastSeen == nil && account.Settings.AutoreplayMissed { if lastSeen == nil && account.Settings.AutoreplayMissed {
@ -385,6 +385,7 @@ func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string,
realIP: utils.IPv4LoopbackAddress, realIP: utils.IPv4LoopbackAddress,
alwaysOn: true, alwaysOn: true,
realname: realname,
} }
client.SetMode(modes.TLS, true) client.SetMode(modes.TLS, true)
@ -1706,6 +1707,7 @@ const (
IncludeChannels uint = 1 << iota IncludeChannels uint = 1 << iota
IncludeLastSeen IncludeLastSeen
IncludeUserModes IncludeUserModes
IncludeRealname
) )
func (client *Client) markDirty(dirtyBits uint) { func (client *Client) markDirty(dirtyBits uint) {
@ -1777,6 +1779,9 @@ func (client *Client) performWrite(additionalDirtyBits uint) {
} }
client.server.accounts.saveModes(account, uModes) client.server.accounts.saveModes(account, uModes)
} }
if (dirtyBits & IncludeRealname) != 0 {
client.server.accounts.saveRealname(account, client.realname)
}
} }
// Blocking store; see Channel.Store and Socket.BlockingWrite // Blocking store; see Channel.Store and Socket.BlockingWrite

View File

@ -225,12 +225,10 @@ func (clients *ClientManager) SetNick(client *Client, session *Session, newNick
client.server.stats.AddRegistered(invisible, operator) client.server.stats.AddRegistered(invisible, operator)
} }
session.autoreplayMissedSince = lastSeen session.autoreplayMissedSince = lastSeen
// XXX SetNames only changes names if they are unset, so the realname change only // TODO: transition mechanism for #1065, clean this up eventually:
// takes effect on first attach to an always-on client (good), but the user/ident if currentClient.Realname() == "" {
// change is always a no-op (bad). we could make user/ident act the same way as currentClient.SetRealname(realname)
// realname, but then we'd have to send CHGHOST and i don't want to deal with that }
// for performance reasons
currentClient.SetNames("user", realname, true)
// successful reattach! // successful reattach!
return newNick, nil, back return newNick, nil, back
} else if currentClient == client && currentClient.Nick() == newNick { } else if currentClient == client && currentClient.Nick() == newNick {

View File

@ -375,7 +375,11 @@ func (client *Client) SetMode(mode modes.Mode, on bool) bool {
func (client *Client) SetRealname(realname string) { func (client *Client) SetRealname(realname string) {
client.stateMutex.Lock() client.stateMutex.Lock()
client.realname = realname client.realname = realname
alwaysOn := client.alwaysOn
client.stateMutex.Unlock() client.stateMutex.Unlock()
if alwaysOn {
client.markDirty(IncludeRealname)
}
} }
func (client *Client) Channels() (result []*Channel) { func (client *Client) Channels() (result []*Channel) {
@ -428,6 +432,13 @@ func (client *Client) UpdateActive(session *Session) {
session.lastActive = now session.lastActive = now
} }
func (client *Client) Realname() string {
client.stateMutex.RLock()
result := client.realname
client.stateMutex.RUnlock()
return result
}
func (channel *Channel) Name() string { func (channel *Channel) Name() string {
channel.stateMutex.RLock() channel.stateMutex.RLock()
defer channel.stateMutex.RUnlock() defer channel.stateMutex.RUnlock()

View File

@ -2565,6 +2565,11 @@ func sceneHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
// SETNAME <realname> // SETNAME <realname>
func setnameHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool { func setnameHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
realname := msg.Params[0] realname := msg.Params[0]
if realname == "" {
rb.Add(nil, server.name, "FAIL", "SETNAME", "INVALID_REALNAME", client.t("Realname is not valid"))
return false
}
client.SetRealname(realname) client.SetRealname(realname)
details := client.Details() details := client.Details()