Refuse to change nick on bouncer connection

Also simplify the code.

Closes: https://todo.sr.ht/~emersion/soju/192
This commit is contained in:
Simon Ser 2022-04-01 14:55:36 +02:00
parent 29b1e6f47b
commit 303c663d02
2 changed files with 34 additions and 37 deletions

View File

@ -1135,16 +1135,27 @@ func (dc *downstreamConn) updateSupportedCaps() {
} }
func (dc *downstreamConn) updateNick() { func (dc *downstreamConn) updateNick() {
if uc := dc.upstream(); uc != nil && uc.nick != dc.nick { var nick string
if uc := dc.upstream(); uc != nil {
nick = uc.nick
} else if dc.network != nil {
nick = GetNick(&dc.user.User, &dc.network.Network)
} else {
nick = GetNick(&dc.user.User, nil)
}
if nick == dc.nick {
return
}
dc.SendMessage(&irc.Message{ dc.SendMessage(&irc.Message{
Prefix: dc.prefix(), Prefix: dc.prefix(),
Command: "NICK", Command: "NICK",
Params: []string{uc.nick}, Params: []string{nick},
}) })
dc.nick = uc.nick dc.nick = nick
dc.nickCM = casemapASCII(dc.nick) dc.nickCM = casemapASCII(dc.nick)
} }
}
func (dc *downstreamConn) updateHost() { func (dc *downstreamConn) updateHost() {
uc := dc.upstream() uc := dc.upstream()
@ -1756,57 +1767,42 @@ func (dc *downstreamConn) handleMessageRegistered(ctx context.Context, msg *irc.
Params: []string{dc.nick, "You may not reregister"}, Params: []string{dc.nick, "You may not reregister"},
}} }}
case "NICK": case "NICK":
var rawNick string var nick string
if err := parseMessageParams(msg, &rawNick); err != nil { if err := parseMessageParams(msg, &nick); err != nil {
return err return err
} }
nick := rawNick if dc.network == nil {
var upstream *upstreamConn return ircError{&irc.Message{
if dc.upstream() == nil { Command: err_unknownerror,
uc, unmarshaledNick, err := dc.unmarshalEntity(nick) Params: []string{dc.nick, "NICK", "Cannot change nickname on the bouncer connection"},
if err == nil { // NICK nick/network: NICK only on a specific upstream }}
upstream = uc
nick = unmarshaledNick
} }
}
if nick == "" || strings.ContainsAny(nick, illegalNickChars) { if nick == "" || strings.ContainsAny(nick, illegalNickChars) {
return ircError{&irc.Message{ return ircError{&irc.Message{
Command: irc.ERR_ERRONEUSNICKNAME, Command: irc.ERR_ERRONEUSNICKNAME,
Params: []string{dc.nick, rawNick, "Nickname contains illegal characters"}, Params: []string{dc.nick, nick, "Nickname contains illegal characters"},
}} }}
} }
if casemapASCII(nick) == serviceNickCM { if casemapASCII(nick) == serviceNickCM {
return ircError{&irc.Message{ return ircError{&irc.Message{
Command: irc.ERR_NICKNAMEINUSE, Command: irc.ERR_NICKNAMEINUSE,
Params: []string{dc.nick, rawNick, "Nickname reserved for bouncer service"}, Params: []string{dc.nick, nick, "Nickname reserved for bouncer service"},
}} }}
} }
var err error record := dc.network.Network
dc.forEachNetwork(func(n *network) { record.Nick = nick
if err != nil || (upstream != nil && upstream.network != n) { if err := dc.srv.db.StoreNetwork(ctx, dc.user.ID, &record); err != nil {
return
}
n.Nick = nick
err = dc.srv.db.StoreNetwork(ctx, dc.user.ID, &n.Network)
})
if err != nil {
return err return err
} }
dc.forEachUpstream(func(uc *upstreamConn) { if uc := dc.upstream(); uc != nil {
if upstream != nil && upstream != uc {
return
}
uc.SendMessageLabeled(ctx, dc.id, &irc.Message{ uc.SendMessageLabeled(ctx, dc.id, &irc.Message{
Command: "NICK", Command: "NICK",
Params: []string{nick}, Params: []string{nick},
}) })
}) } else {
if dc.upstream() == nil && upstream == nil && dc.nick != nick {
dc.SendMessage(&irc.Message{ dc.SendMessage(&irc.Message{
Prefix: dc.prefix(), Prefix: dc.prefix(),
Command: "NICK", Command: "NICK",

1
irc.go
View File

@ -20,6 +20,7 @@ const (
rpl_whospcrpl = "354" rpl_whospcrpl = "354"
rpl_whoisaccount = "330" rpl_whoisaccount = "330"
rpl_visiblehost = "396" rpl_visiblehost = "396"
err_unknownerror = "400"
err_invalidcapcmd = "410" err_invalidcapcmd = "410"
// https://ircv3.net/specs/extensions/bot-mode // https://ircv3.net/specs/extensions/bot-mode