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

refactor services code

This commit is contained in:
Shivaram Lingamneni 2019-01-03 22:32:07 -05:00
parent ea970f94a0
commit b80df0885f
5 changed files with 172 additions and 164 deletions

View File

@ -15,7 +15,6 @@ import (
"github.com/goshuirc/irc-go/ircfmt"
"github.com/oragono/oragono/irc/modes"
"github.com/oragono/oragono/irc/sno"
"github.com/oragono/oragono/irc/utils"
)
const chanservHelp = `ChanServ lets you register and manage channels.
@ -26,8 +25,8 @@ To see in-depth help for a specific ChanServ command, try:
Here are the commands you can use:
%s`
func chanregEnabled(server *Server) bool {
return server.ChannelRegistrationEnabled()
func chanregEnabled(config *Config) bool {
return config.Channels.Registration.Enabled
}
var (
@ -41,6 +40,7 @@ this command if you're the founder of the channel.`,
helpShort: `$bOP$b makes the given user (or yourself) a channel admin.`,
authRequired: true,
enabled: chanregEnabled,
minParams: 1,
},
"register": {
handler: csRegisterHandler,
@ -52,6 +52,7 @@ remembered.`,
helpShort: `$bREGISTER$b lets you own a given channel.`,
authRequired: true,
enabled: chanregEnabled,
minParams: 1,
},
"unregister": {
handler: csUnregisterHandler,
@ -62,6 +63,7 @@ To prevent accidental unregistrations, a verification code is required;
invoking the command without a code will display the necessary code.`,
helpShort: `$bUNREGISTER$b deletes a channel registration.`,
enabled: chanregEnabled,
minParams: 1,
},
"drop": {
aliasOf: "unregister",
@ -77,6 +79,7 @@ accounts and modes, use $bAMODE #channel$b. Note that users are always
referenced by their registered account names, not their nicknames.`,
helpShort: `$bAMODE$b modifies persistent mode settings for channel members.`,
enabled: chanregEnabled,
minParams: 1,
},
}
)
@ -86,8 +89,9 @@ func csNotice(rb *ResponseBuffer, text string) {
rb.Add(nil, "ChanServ", "NOTICE", rb.target.Nick(), text)
}
func csAmodeHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
channelName, modeChange := utils.ExtractParam(params)
func csAmodeHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
channelName := params[0]
modeChange := strings.Join(params[1:], " ")
channel := server.channels.Get(channelName)
if channel == nil {
@ -159,27 +163,13 @@ func csAmodeHandler(server *Server, client *Client, command, params string, rb *
}
}
func csOpHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
channelName, clientToOp := utils.ExtractParam(params)
if channelName == "" {
csNotice(rb, ircfmt.Unescape(client.t("Syntax: $bOP #channel [nickname]$b")))
return
}
clientToOp = strings.TrimSpace(clientToOp)
channelKey, err := CasefoldChannel(channelName)
if err != nil {
csNotice(rb, client.t("Channel name is not valid"))
return
}
channelInfo := server.channels.Get(channelKey)
func csOpHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
channelInfo := server.channels.Get(params[0])
if channelInfo == nil {
csNotice(rb, client.t("Channel does not exist"))
return
}
channelName := channelInfo.Name()
clientAccount := client.Account()
if clientAccount == "" || clientAccount != channelInfo.Founder() {
@ -188,10 +178,9 @@ func csOpHandler(server *Server, client *Client, command, params string, rb *Res
}
var target *Client
if clientToOp != "" {
casefoldedNickname, err := CasefoldName(clientToOp)
target = server.clients.Get(casefoldedNickname)
if err != nil || target == nil {
if len(params) > 1 {
target = server.clients.Get(params[1])
if target == nil {
csNotice(rb, client.t("Could not find given client"))
return
}
@ -216,16 +205,13 @@ func csOpHandler(server *Server, client *Client, command, params string, rb *Res
csNotice(rb, fmt.Sprintf(client.t("Successfully op'd in channel %s"), channelName))
server.logger.Info("chanserv", fmt.Sprintf("Client %s op'd [%s] in channel %s", client.nick, clientToOp, channelName))
server.snomasks.Send(sno.LocalChannels, fmt.Sprintf(ircfmt.Unescape("Client $c[grey][$r%s$c[grey]] CS OP'd $c[grey][$r%s$c[grey]] in channel $c[grey][$r%s$c[grey]]"), client.nickMaskString, clientToOp, channelName))
tnick := target.Nick()
server.logger.Info("services", fmt.Sprintf("Client %s op'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 OP'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, params string, rb *ResponseBuffer) {
channelName := strings.TrimSpace(params)
if channelName == "" {
csNotice(rb, ircfmt.Unescape(client.t("Syntax: $bREGISTER #channel$b")))
return
}
func csRegisterHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
channelName := params[0]
channelKey, err := CasefoldChannel(channelName)
if err != nil {
@ -251,7 +237,7 @@ func csRegisterHandler(server *Server, client *Client, command, params string, r
csNotice(rb, fmt.Sprintf(client.t("Channel %s successfully registered"), channelName))
server.logger.Info("chanserv", fmt.Sprintf("Client %s registered channel %s", client.nick, channelName))
server.logger.Info("services", fmt.Sprintf("Client %s registered channel %s", client.nick, channelName))
server.snomasks.Send(sno.LocalChannels, fmt.Sprintf(ircfmt.Unescape("Channel registered $c[grey][$r%s$c[grey]] by $c[grey][$r%s$c[grey]]"), channelName, client.nickMaskString))
// give them founder privs
@ -266,8 +252,13 @@ func csRegisterHandler(server *Server, client *Client, command, params string, r
}
}
func csUnregisterHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
channelName, verificationCode := utils.ExtractParam(params)
func csUnregisterHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
channelName := params[0]
var verificationCode string
if len(params) > 1 {
verificationCode = params[1]
}
channelKey, err := CasefoldChannel(channelName)
if channelKey == "" || err != nil {
csNotice(rb, client.t("Channel name is not valid"))

View File

@ -9,8 +9,6 @@ import (
"regexp"
"strings"
"time"
"github.com/oragono/oragono/irc/utils"
)
const hostservHelp = `HostServ lets you manage your vhost (i.e., the string displayed
@ -29,13 +27,12 @@ var (
defaultValidVhostRegex = regexp.MustCompile(`^[0-9A-Za-z.\-_/]+$`)
)
func hostservEnabled(server *Server) bool {
return server.AccountConfig().VHosts.Enabled
func hostservEnabled(config *Config) bool {
return config.Accounts.VHosts.Enabled
}
func hostservRequestsEnabled(server *Server) bool {
ac := server.AccountConfig()
return ac.VHosts.Enabled && ac.VHosts.UserRequests.Enabled
func hostservRequestsEnabled(config *Config) bool {
return config.Accounts.VHosts.Enabled && config.Accounts.VHosts.UserRequests.Enabled
}
var (
@ -67,15 +64,15 @@ then be approved by a server operator.`,
helpShort: `$bREQUEST$b requests a new vhost, pending operator approval.`,
authRequired: true,
enabled: hostservRequestsEnabled,
minParams: 1,
},
"status": {
handler: hsStatusHandler,
help: `Syntax: $bSTATUS$b
help: `Syntax: $bSTATUS [user]$b
STATUS displays your current vhost, if any, and the status of your most recent
request for a new one.`,
request for a new one. A server operator can view someone else's status.`,
helpShort: `$bSTATUS$b shows your vhost and request status.`,
authRequired: true,
enabled: hostservEnabled,
},
"set": {
@ -86,6 +83,7 @@ SET sets a user's vhost, bypassing the request system.`,
helpShort: `$bSET$b sets a user's vhost.`,
capabs: []string{"vhosts"},
enabled: hostservEnabled,
minParams: 2,
},
"del": {
handler: hsSetHandler,
@ -95,6 +93,7 @@ DEL deletes a user's vhost.`,
helpShort: `$bDEL$b deletes a user's vhost.`,
capabs: []string{"vhosts"},
enabled: hostservEnabled,
minParams: 1,
},
"waiting": {
handler: hsWaitingHandler,
@ -114,6 +113,7 @@ APPROVE approves a user's vhost request.`,
helpShort: `$bAPPROVE$b approves a user's vhost request.`,
capabs: []string{"vhosts"},
enabled: hostservEnabled,
minParams: 1,
},
"reject": {
handler: hsRejectHandler,
@ -124,6 +124,7 @@ for the rejection.`,
helpShort: `$bREJECT$b rejects a user's vhost request.`,
capabs: []string{"vhosts"},
enabled: hostservEnabled,
minParams: 1,
},
}
)
@ -146,7 +147,7 @@ func hsNotifyChannel(server *Server, message string) {
}
}
func hsOnOffHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
func hsOnOffHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
enable := false
if command == "on" {
enable = true
@ -162,8 +163,8 @@ func hsOnOffHandler(server *Server, client *Client, command, params string, rb *
}
}
func hsRequestHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
vhost, _ := utils.ExtractParam(params)
func hsRequestHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
vhost := params[0]
if validateVhost(server, vhost, false) != nil {
hsNotice(rb, client.t("Invalid vhost"))
return
@ -195,12 +196,24 @@ func hsRequestHandler(server *Server, client *Client, command, params string, rb
}
}
func hsStatusHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
accountName := client.Account()
func hsStatusHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
var accountName string
if len(params) > 0 {
if !client.HasRoleCapabs("vhosts") {
hsNotice(rb, client.t("Command restricted"))
return
}
accountName = params[0]
} else {
accountName = client.Account()
}
account, err := server.accounts.LoadAccount(accountName)
if err != nil {
if err != errAccountDoesNotExist {
server.logger.Warning("internal", "error loading account info", accountName, err.Error())
hsNotice(rb, client.t("An error occurred"))
}
hsNotice(rb, client.t("No such account"))
return
}
@ -232,23 +245,18 @@ func validateVhost(server *Server, vhost string, oper bool) error {
return nil
}
func hsSetHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
var user, vhost string
user, params = utils.ExtractParam(params)
if user == "" {
hsNotice(rb, client.t("A user is required"))
return
}
func hsSetHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
user := params[0]
var vhost string
if command == "set" {
vhost, _ = utils.ExtractParam(params)
vhost = params[1]
if validateVhost(server, vhost, true) != nil {
hsNotice(rb, client.t("Invalid vhost"))
return
}
} else if command != "del" {
server.logger.Warning("internal", "invalid hostserv set command", command)
return
}
// else: command == "del", vhost == ""
_, err := server.accounts.VHostSet(user, vhost)
if err != nil {
@ -260,7 +268,7 @@ func hsSetHandler(server *Server, client *Client, command, params string, rb *Re
}
}
func hsWaitingHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
func hsWaitingHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
requests, total := server.accounts.VHostListRequests(10)
hsNotice(rb, fmt.Sprintf(client.t("There are %d pending requests for vhosts (%d displayed)"), total, len(requests)))
for i, request := range requests {
@ -268,12 +276,8 @@ func hsWaitingHandler(server *Server, client *Client, command, params string, rb
}
}
func hsApproveHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
user, _ := utils.ExtractParam(params)
if user == "" {
hsNotice(rb, client.t("A user is required"))
return
}
func hsApproveHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
user := params[0]
vhostInfo, err := server.accounts.VHostApprove(user)
if err != nil {
@ -288,13 +292,12 @@ func hsApproveHandler(server *Server, client *Client, command, params string, rb
}
}
func hsRejectHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
user, params := utils.ExtractParam(params)
if user == "" {
hsNotice(rb, client.t("A user is required"))
return
func hsRejectHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
var reason string
user := params[0]
if len(params) > 1 {
reason = strings.Join(params[1:], " ")
}
reason := strings.TrimSpace(params)
vhostInfo, err := server.accounts.VHostReject(user, reason)
if err != nil {

View File

@ -8,25 +8,22 @@ import (
"strings"
"github.com/goshuirc/irc-go/ircfmt"
"github.com/oragono/oragono/irc/utils"
)
// "enabled" callbacks for specific nickserv commands
func servCmdRequiresAccreg(server *Server) bool {
return server.AccountConfig().Registration.Enabled
func servCmdRequiresAccreg(config *Config) bool {
return config.Accounts.Registration.Enabled
}
func servCmdRequiresAuthEnabled(server *Server) bool {
return server.AccountConfig().AuthenticationEnabled
func servCmdRequiresAuthEnabled(config *Config) bool {
return config.Accounts.AuthenticationEnabled
}
func nsGroupEnabled(server *Server) bool {
conf := server.Config()
return conf.Accounts.AuthenticationEnabled && conf.Accounts.NickReservation.Enabled
func nsGroupEnabled(config *Config) bool {
return config.Accounts.AuthenticationEnabled && config.Accounts.NickReservation.Enabled
}
func nsEnforceEnabled(server *Server) bool {
config := server.Config()
func nsEnforceEnabled(config *Config) bool {
return config.Accounts.NickReservation.Enabled && config.Accounts.NickReservation.AllowCustomEnforcement
}
@ -73,6 +70,7 @@ GHOST disconnects the given user from the network if they're logged in with the
same user account, letting you reclaim your nickname.`,
helpShort: `$bGHOST$b reclaims your nickname.`,
authRequired: true,
minParams: 1,
},
"group": {
handler: nsGroupHandler,
@ -84,7 +82,6 @@ users from changing to it (or forcing them to rename).`,
enabled: nsGroupEnabled,
authRequired: true,
},
"identify": {
handler: nsIdentifyHandler,
help: `Syntax: $bIDENTIFY <username> [password]$b
@ -92,6 +89,7 @@ users from changing to it (or forcing them to rename).`,
IDENTIFY lets you login to the given username using either password auth, or
certfp (your client certificate) if a password is not given.`,
helpShort: `$bIDENTIFY$b lets you login to your account.`,
minParams: 1,
},
"info": {
handler: nsInfoHandler,
@ -113,6 +111,7 @@ If the password is left out, your account will be registered to your TLS client
certificate (and you will need to use that certificate to login in future).`,
helpShort: `$bREGISTER$b lets you register a user account.`,
enabled: servCmdRequiresAccreg,
minParams: 2,
},
"sadrop": {
handler: nsDropHandler,
@ -122,6 +121,7 @@ SADROP forcibly de-links the given nickname from the attached user account.`,
helpShort: `$bSADROP$b forcibly de-links the given nickname from its user account.`,
capabs: []string{"accreg"},
enabled: servCmdRequiresAccreg,
minParams: 1,
},
"unregister": {
handler: nsUnregisterHandler,
@ -132,6 +132,8 @@ IRC operator with the correct permissions). To prevent accidental
unregistrations, a verification code is required; invoking the command without
a code will display the necessary code.`,
helpShort: `$bUNREGISTER$b lets you delete your user account.`,
enabled: servCmdRequiresAccreg,
minParams: 1,
},
"verify": {
handler: nsVerifyHandler,
@ -141,6 +143,7 @@ VERIFY lets you complete an account registration, if the server requires email
or other verification.`,
helpShort: `$bVERIFY$b lets you complete account registration.`,
enabled: servCmdRequiresAccreg,
minParams: 2,
},
"passwd": {
handler: nsPasswdHandler,
@ -153,6 +156,7 @@ with the correct permissions, you can use PASSWD to reset someone else's
password by supplying their username and then the desired password.`,
helpShort: `$bPASSWD$b lets you change your password.`,
enabled: servCmdRequiresAuthEnabled,
minParams: 2,
},
}
)
@ -162,9 +166,14 @@ func nsNotice(rb *ResponseBuffer, text string) {
rb.Add(nil, "NickServ", "NOTICE", rb.target.Nick(), text)
}
func nsDropHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
func nsDropHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
sadrop := command == "sadrop"
nick, _ := utils.ExtractParam(params)
var nick string
if len(params) > 0 {
nick = params[0]
} else {
nick = client.NickCasefolded()
}
err := server.accounts.SetNickReserved(client, nick, sadrop, false)
if err == nil {
@ -173,15 +182,13 @@ func nsDropHandler(server *Server, client *Client, command, params string, rb *R
nsNotice(rb, client.t("You're not logged into an account"))
} else if err == errAccountCantDropPrimaryNick {
nsNotice(rb, client.t("You can't ungroup your primary nickname (try unregistering your account instead)"))
} else if err == errNicknameReserved {
nsNotice(rb, client.t("That nickname is already reserved by someone else"))
} else {
nsNotice(rb, client.t("Could not ungroup nick"))
}
}
func nsGhostHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
nick, _ := utils.ExtractParam(params)
func nsGhostHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
nick := params[0]
ghost := server.clients.Get(nick)
if ghost == nil {
@ -207,7 +214,7 @@ func nsGhostHandler(server *Server, client *Client, command, params string, rb *
ghost.destroy(false)
}
func nsGroupHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
func nsGroupHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
nick := client.NickCasefolded()
err := server.accounts.SetNickReserved(client, nick, false, true)
if err == nil {
@ -230,13 +237,17 @@ func nsLoginThrottleCheck(client *Client, rb *ResponseBuffer) (success bool) {
return true
}
func nsIdentifyHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
func nsIdentifyHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
loginSuccessful := false
username, passphrase := utils.ExtractParam(params)
username := params[0]
var passphrase string
if len(params) > 1 {
passphrase = params[1]
}
// try passphrase
if username != "" && passphrase != "" {
if passphrase != "" {
if !nsLoginThrottleCheck(client, rb) {
return
}
@ -257,25 +268,31 @@ func nsIdentifyHandler(server *Server, client *Client, command, params string, r
}
}
func nsInfoHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
nick, _ := utils.ExtractParam(params)
if nick == "" {
nick = client.Nick()
}
accountName := nick
func nsInfoHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
var accountName string
if len(params) > 0 {
nick := params[0]
if server.AccountConfig().NickReservation.Enabled {
accountName = server.accounts.NickToAccount(nick)
if accountName == "" {
nsNotice(rb, client.t("That nickname is not registered"))
return
}
} else {
accountName = nick
}
} else {
accountName = client.Account()
if accountName == "" {
nsNotice(rb, client.t("You're not logged into an account"))
return
}
}
account, err := server.accounts.LoadAccount(accountName)
if err != nil || !account.Verified {
nsNotice(rb, client.t("Account does not exist"))
return
}
nsNotice(rb, fmt.Sprintf(client.t("Account: %s"), account.Name))
@ -287,10 +304,13 @@ func nsInfoHandler(server *Server, client *Client, command, params string, rb *R
}
}
func nsRegisterHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
func nsRegisterHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
// get params
username, afterUsername := utils.ExtractParam(params)
email, passphrase := utils.ExtractParam(afterUsername)
username, email := params[0], params[1]
var passphrase string
if len(params) > 0 {
passphrase = params[2]
}
if !server.AccountConfig().Registration.Enabled {
nsNotice(rb, client.t("Account registration has been disabled"))
@ -366,12 +386,11 @@ func nsRegisterHandler(server *Server, client *Client, command, params string, r
}
}
func nsUnregisterHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
username, verificationCode := utils.ExtractParam(params)
if !server.AccountConfig().Registration.Enabled {
nsNotice(rb, client.t("Account registration has been disabled"))
return
func nsUnregisterHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
username := params[0]
var verificationCode string
if len(params) > 1 {
verificationCode = params[1]
}
if username == "" {
@ -415,9 +434,8 @@ func nsUnregisterHandler(server *Server, client *Client, command, params string,
}
}
func nsVerifyHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
username, code := utils.ExtractParam(params)
func nsVerifyHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
username, code := params[0], params[1]
err := server.accounts.Verify(client, username, code)
var errorMessage string
@ -435,7 +453,7 @@ func nsVerifyHandler(server *Server, client *Client, command, params string, rb
sendSuccessfulRegResponse(client, rb, true)
}
func nsPasswdHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
func nsPasswdHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
var target string
var newPassword string
var errorMessage string
@ -445,27 +463,26 @@ func nsPasswdHandler(server *Server, client *Client, command, params string, rb
return
}
fields := strings.Fields(params)
switch len(fields) {
switch len(params) {
case 2:
if !hasPrivs {
errorMessage = "Insufficient privileges"
} else {
target, newPassword = fields[0], fields[1]
target, newPassword = params[0], params[1]
}
case 3:
target = client.Account()
if target == "" {
errorMessage = "You're not logged into an account"
} else if fields[1] != fields[2] {
} else if params[1] != params[2] {
errorMessage = "Passwords do not match"
} else {
// check that they correctly supplied the preexisting password
_, err := server.accounts.checkPassphrase(target, fields[0])
_, err := server.accounts.checkPassphrase(target, params[0])
if err != nil {
errorMessage = "Password incorrect"
} else {
newPassword = fields[1]
newPassword = params[1]
}
}
default:
@ -486,14 +503,12 @@ func nsPasswdHandler(server *Server, client *Client, command, params string, rb
}
}
func nsEnforceHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
arg := strings.TrimSpace(params)
if arg == "" {
func nsEnforceHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
if len(params) == 0 {
status := server.accounts.getStoredEnforcementStatus(client.Account())
nsNotice(rb, fmt.Sprintf(client.t("Your current nickname enforcement is: %s"), status))
} else {
method, err := nickReservationFromString(arg)
method, err := nickReservationFromString(params[0])
if err != nil {
nsNotice(rb, client.t("Invalid parameters"))
return

View File

@ -11,8 +11,6 @@ import (
"github.com/goshuirc/irc-go/ircfmt"
"github.com/goshuirc/irc-go/ircmsg"
"github.com/oragono/oragono/irc/utils"
)
// defines an IRC service, e.g., NICKSERV
@ -28,11 +26,12 @@ type ircService struct {
type serviceCommand struct {
aliasOf string // marks this command as an alias of another
capabs []string // oper capabs the given user has to have to access this command
handler func(server *Server, client *Client, command, params string, rb *ResponseBuffer)
handler func(server *Server, client *Client, command string, params []string, rb *ResponseBuffer)
help string
helpShort string
authRequired bool
enabled func(*Server) bool // is this command enabled in the server config?
enabled func(*Config) bool // is this command enabled in the server config?
minParams int
}
// looks up a command in the table of command definitions for a service, resolving aliases
@ -90,7 +89,7 @@ HELP returns information on the given command.`,
helpShort: `$bHELP$b shows in-depth information about commands.`,
}
// this handles IRC commands like `/NICKSERV INFO`, translating into `/MSG NICKSERV INFO`
// generic handler for IRC commands like `/NICKSERV INFO`
func serviceCmdHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
service, ok := oragonoServicesByCommandAlias[msg.Command]
if !ok {
@ -98,15 +97,22 @@ func serviceCmdHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb
return false
}
fakePrivmsg := strings.Join(msg.Params, " ")
servicePrivmsgHandler(service, server, client, fakePrivmsg, rb)
serviceRunCommand(service, server, client, msg.Params, rb)
return false
}
// generic handler for service PRIVMSG
// generic handler for service PRIVMSG, like `/msg NickServ INFO`
func servicePrivmsgHandler(service *ircService, server *Server, client *Client, message string, rb *ResponseBuffer) {
commandName, params := utils.ExtractParam(message)
commandName = strings.ToLower(commandName)
serviceRunCommand(service, server, client, strings.Fields(message), rb)
}
// actually execute a service command
func serviceRunCommand(service *ircService, server *Server, client *Client, params []string, rb *ResponseBuffer) {
if len(params) == 0 {
return
}
commandName := strings.ToLower(params[0])
params = params[1:]
nick := rb.target.Nick()
sendNotice := func(notice string) {
@ -119,7 +125,12 @@ func servicePrivmsgHandler(service *ircService, server *Server, client *Client,
return
}
if cmd.enabled != nil && !cmd.enabled(server) {
if len(params) < cmd.minParams {
sendNotice(fmt.Sprintf(client.t("Invalid parameters. For usage, do /msg %s HELP %s"), service.Name, strings.ToUpper(commandName)))
return
}
if cmd.enabled != nil && !cmd.enabled(server.Config()) {
sendNotice(client.t("This command has been disabled by the server administrators"))
return
}
@ -143,15 +154,16 @@ func servicePrivmsgHandler(service *ircService, server *Server, client *Client,
}
// generic handler that displays help for service commands
func serviceHelpHandler(service *ircService, server *Server, client *Client, params string, rb *ResponseBuffer) {
func serviceHelpHandler(service *ircService, server *Server, client *Client, params []string, rb *ResponseBuffer) {
nick := rb.target.Nick()
config := server.Config()
sendNotice := func(notice string) {
rb.Add(nil, service.Name, "NOTICE", nick, notice)
}
sendNotice(ircfmt.Unescape(fmt.Sprintf("*** $b%s HELP$b ***", service.Name)))
if params == "" {
if len(params) == 0 {
// show general help
var shownHelpLines sort.StringSlice
var disabledCommands bool
@ -163,7 +175,7 @@ func serviceHelpHandler(service *ircService, server *Server, client *Client, par
if commandInfo.aliasOf != "" {
continue // don't show help lines for aliases
}
if commandInfo.enabled != nil && !commandInfo.enabled(server) {
if commandInfo.enabled != nil && !commandInfo.enabled(config) {
disabledCommands = true
continue
}
@ -187,7 +199,7 @@ func serviceHelpHandler(service *ircService, server *Server, client *Client, par
sendNotice(line)
}
} else {
commandName := strings.ToLower(strings.TrimSpace(params))
commandName := strings.ToLower(params[0])
commandInfo := lookupServiceCommand(service.Commands, commandName)
if commandInfo == nil {
sendNotice(client.t(fmt.Sprintf("Unknown command. To see available commands, run /%s HELP", service.ShortName)))

View File

@ -3,19 +3,6 @@
package utils
import "strings"
// ExtractParam extracts a parameter from the given string, returning the param and the rest of the string.
func ExtractParam(line string) (string, string) {
rawParams := strings.SplitN(strings.TrimSpace(line), " ", 2)
param0 := rawParams[0]
var param1 string
if 1 < len(rawParams) {
param1 = strings.TrimSpace(rawParams[1])
}
return param0, param1
}
// ArgsToStrings takes the arguments and splits them into a series of strings,
// each argument separated by delim and each string bounded by maxLength.
func ArgsToStrings(maxLength int, arguments []string, delim string) []string {