3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-12-22 18:52:41 +01:00

implement NS RENAME

Fixes #1380
This commit is contained in:
Shivaram Lingamneni 2020-11-10 19:59:12 -05:00
parent 4861ac90b6
commit 4f571c2cf3
4 changed files with 69 additions and 0 deletions

View File

@ -1406,6 +1406,36 @@ func (am *AccountManager) ListSuspended() (result []AccountSuspension) {
return return
} }
// renames an account (within very restrictive limits); see #1380
func (am *AccountManager) Rename(oldName, newName string) (err error) {
accountData, err := am.LoadAccount(oldName)
if err != nil {
return
}
newCfName, err := CasefoldName(newName)
if err != nil {
return errNicknameInvalid
}
if newCfName != accountData.NameCasefolded {
return errInvalidAccountRename
}
key := fmt.Sprintf(keyAccountName, accountData.NameCasefolded)
err = am.server.store.Update(func(tx *buntdb.Tx) error {
tx.Set(key, newName, nil)
return nil
})
if err != nil {
return err
}
am.RLock()
defer am.RUnlock()
for _, client := range am.accountToClients[accountData.NameCasefolded] {
client.setAccountName(newName)
}
return nil
}
func (am *AccountManager) Unregister(account string, erase bool) error { func (am *AccountManager) Unregister(account string, erase bool) error {
config := am.server.Config() config := am.server.Config()
casefoldedAccount, err := CasefoldName(account) casefoldedAccount, err := CasefoldName(account)

View File

@ -73,6 +73,7 @@ var (
errInviteOnly = errors.New("Cannot join invite-only channel without an invite") errInviteOnly = errors.New("Cannot join invite-only channel without an invite")
errRegisteredOnly = errors.New("Cannot join registered-only channel without an account") errRegisteredOnly = errors.New("Cannot join registered-only channel without an account")
errValidEmailRequired = errors.New("A valid email address is required for account registration") errValidEmailRequired = errors.New("A valid email address is required for account registration")
errInvalidAccountRename = errors.New("Account renames can only change the casefolding of the account name")
) )
// String Errors // String Errors

View File

@ -300,6 +300,13 @@ func (client *Client) Login(account ClientAccount) {
return return
} }
func (client *Client) setAccountName(name string) {
// XXX this assumes validation elsewhere
client.stateMutex.Lock()
defer client.stateMutex.Unlock()
client.accountName = name
}
func (client *Client) historyCutoff() (cutoff time.Time) { func (client *Client) historyCutoff() (cutoff time.Time) {
client.stateMutex.Lock() client.stateMutex.Lock()
if client.account != "" { if client.account != "" {

View File

@ -347,6 +347,17 @@ command lists all current suspensions.`,
minParams: 1, minParams: 1,
capabs: []string{"accreg"}, capabs: []string{"accreg"},
}, },
"rename": {
handler: nsRenameHandler,
help: `Syntax: $bRENAME <account> <newname>$b
RENAME allows a server administrator to change the name of an account.
Currently, you can only change the canonical casefolding of an account
(e.g., you can change "Alice" to "alice", but not "Alice" to "Amanda").`,
helpShort: `$bRENAME$b renames an account`,
minParams: 2,
capabs: []string{"accreg"},
},
} }
) )
@ -1377,3 +1388,23 @@ func suspensionToString(client *Client, suspension AccountSuspension) (result st
} }
return fmt.Sprintf(client.t("Account %[1]s suspended at %[2]s. Duration: %[3]s. %[4]s"), suspension.AccountName, ts, duration, reason) return fmt.Sprintf(client.t("Account %[1]s suspended at %[2]s. Duration: %[3]s. %[4]s"), suspension.AccountName, ts, duration, reason)
} }
func nsRenameHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
oldName, newName := params[0], params[1]
err := server.accounts.Rename(oldName, newName)
if err != nil {
nsNotice(rb, fmt.Sprintf(client.t("Couldn't rename account: %s"), client.t(err.Error())))
return
}
nsNotice(rb, client.t("Successfully renamed account"))
if server.Config().Accounts.NickReservation.ForceNickEqualsAccount {
if curClient := server.clients.Get(oldName); curClient != nil {
renameErr := performNickChange(client.server, client, curClient, nil, newName, rb)
if renameErr != nil && renameErr != errNoop {
nsNotice(rb, fmt.Sprintf(client.t("Warning: could not rename affected client: %v"), err))
}
}
}
}