diff --git a/irc/chanserv.go b/irc/chanserv.go index cf9eb6fb..c221eb44 100644 --- a/irc/chanserv.go +++ b/irc/chanserv.go @@ -42,10 +42,9 @@ this command if you're the founder of the channel.`, DEOP removes the given nickname, or yourself, the channel admin. You can only use this command if you're the founder of the channel.`, - helpShort: `$bDEOP$b removes the given user (or yourself) from a channel admin.`, - authRequired: true, - enabled: chanregEnabled, - minParams: 1, + helpShort: `$bDEOP$b removes the given user (or yourself) from a channel admin.`, + enabled: chanregEnabled, + minParams: 1, }, "register": { handler: csRegisterHandler, @@ -194,7 +193,6 @@ func csNotice(rb *ResponseBuffer, text string) { rb.Add(nil, chanservMask, "NOTICE", rb.target.Nick(), text) } - func csAmodeHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) { channelName := params[0] @@ -325,16 +323,13 @@ func csOpHandler(server *Server, client *Client, command string, params []string } func csDeopHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) { - channelInfo := server.channels.Get(params[0]) - if channelInfo == nil { + channel := server.channels.Get(params[0]) + if channel == nil { csNotice(rb, client.t("Channel does not exist")) return } - channelName := channelInfo.Name() - - clientAccount := client.Account() - if clientAccount == "" || clientAccount != channelInfo.Founder() { - csNotice(rb, client.t("Only the channel founder can do this")) + if !channel.hasClient(client) { + csNotice(rb, client.t("You're not on that channel")) return } @@ -349,29 +344,35 @@ func csDeopHandler(server *Server, client *Client, command string, params []stri target = client } - // give them privs - givenMode := modes.ChannelOperator - if clientAccount == target.Account() { - givenMode = modes.ChannelFounder + present, cumodes := channel.ClientStatus(target) + if !present || len(cumodes) == 0 { + csNotice(rb, client.t("Target has no privileges to remove")) + return } - applied, change := channelInfo.applyModeToMember(client, - modes.ModeChange{Mode: givenMode, - Op: modes.Remove, - Arg: target.NickCasefolded(), - }, - rb) - if applied { - announceCmodeChanges(channelInfo, modes.ModeChanges{change}, chanservMask, "*", "", rb) + + tnick := target.Nick() + modeChanges := make(modes.ModeChanges, len(cumodes)) + for i, mode := range cumodes { + modeChanges[i] = modes.ModeChange{ + Mode: mode, + Op: modes.Remove, + Arg: tnick, + } + } + + // use the user's own permissions for the check, then announce + // the changes as coming from chanserv + applied := channel.ApplyChannelModeChanges(client, false, modeChanges, rb) + details := client.Details() + announceCmodeChanges(channel, applied, details.nickMask, details.accountName, details.account, rb) + + if len(applied) == 0 { + return } csNotice(rb, client.t("Successfully removed operator privileges")) - - tnick := target.Nick() - server.logger.Info("services", fmt.Sprintf("Client %s deop'd [%s] in channel %s", client.Nick(), tnick, channelName)) - server.snomasks.Send(sno.LocalChannels, fmt.Sprintf(ircfmt.Unescape("Client $c[grey][$r%s$c[grey]] CS deOP'd $c[grey][$r%s$c[grey]] in channel $c[grey][$r%s$c[grey]]"), client.NickMaskString(), tnick, channelName)) } - func csRegisterHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) { if server.Config().Channels.Registration.OperatorOnly && !client.HasRoleCapabs("chanreg") { csNotice(rb, client.t("Channel registration is restricted to server operators"))