From 4ee97ddb43c14b710e2ee71c55d808854fd19aec Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Fri, 9 Oct 2020 12:29:09 -0400 Subject: [PATCH] USERHOST needs to respect hidden operators as well --- irc/config.go | 5 ----- irc/handlers.go | 17 +++++++++++++++-- irc/server.go | 8 +++++--- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/irc/config.go b/irc/config.go index e1571984..0dda71e3 100644 --- a/irc/config.go +++ b/irc/config.go @@ -728,11 +728,6 @@ type Oper struct { Modes []modes.ModeChange } -// returns whether this is a publicly visible operator, for WHO/WHOIS purposes -func (oper *Oper) Visible(hasPrivs bool) bool { - return oper != nil && (hasPrivs || !oper.Hidden) -} - // Operators returns a map of operator configs from the given OperClass and config. func (conf *Config) Operators(oc map[string]*OperClass) (map[string]*Oper, error) { operators := make(map[string]*Oper) diff --git a/irc/handlers.go b/irc/handlers.go index c221e307..d231205c 100644 --- a/irc/handlers.go +++ b/irc/handlers.go @@ -2878,8 +2878,21 @@ func userHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp return false } +// does `target` have an operator status that is visible to `client`? +func operStatusVisible(client, target *Client, hasPrivs bool) bool { + targetOper := target.Oper() + if targetOper == nil { + return false + } + if client == target || hasPrivs { + return true + } + return !targetOper.Hidden +} + // USERHOST { } func userhostHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool { + hasPrivs := client.HasMode(modes.Operator) // TODO(#1176) figure out the right capab for this returnedClients := make(ClientSet) var tl utils.TokenLineBuilder @@ -2901,7 +2914,7 @@ func userhostHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb * var isOper, isAway string - if target.HasMode(modes.Operator) { + if operStatusVisible(client, target, hasPrivs) { isOper = "*" } if away, _ := target.Away(); away { @@ -3061,7 +3074,7 @@ func (client *Client) rplWhoReply(channel *Channel, target *Client, rb *Response flags.WriteRune('H') // Here } - if target.HasMode(modes.Operator) && target.Oper().Visible(hasPrivs) { + if target.HasMode(modes.Operator) && operStatusVisible(client, target, hasPrivs) { flags.WriteRune('*') } diff --git a/irc/server.go b/irc/server.go index 807b3e5d..3fd875d6 100644 --- a/irc/server.go +++ b/irc/server.go @@ -439,9 +439,11 @@ func (client *Client) getWhoisOf(target *Client, hasPrivs bool, rb *ResponseBuff if whoischannels != nil { rb.Add(nil, client.server.name, RPL_WHOISCHANNELS, cnick, tnick, strings.Join(whoischannels, " ")) } - tOper := target.Oper() - if tOper.Visible(hasPrivs) { - rb.Add(nil, client.server.name, RPL_WHOISOPERATOR, cnick, tnick, tOper.WhoisLine) + if target.HasMode(modes.Operator) && operStatusVisible(client, target, hasPrivs) { + tOper := target.Oper() + if tOper != nil { + rb.Add(nil, client.server.name, RPL_WHOISOPERATOR, cnick, tnick, tOper.WhoisLine) + } } if client == target || hasPrivs { rb.Add(nil, client.server.name, RPL_WHOISACTUALLY, cnick, tnick, fmt.Sprintf("%s@%s", targetInfo.username, target.RawHostname()), target.IPString(), client.t("Actual user@host, Actual IP"))