mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-11 06:29:29 +01:00
commit
34fc8aa3c8
@ -337,6 +337,10 @@ server:
|
||||
# to the working directory. set this to customize:
|
||||
#output-path: "/home/oragono/out"
|
||||
|
||||
# the hostname used by "services", e.g., NickServ, defaults to "localhost",
|
||||
# e.g., `NickServ!NickServ@localhost`. uncomment this to override:
|
||||
#override-services-hostname: "example.network"
|
||||
|
||||
# account options
|
||||
accounts:
|
||||
# is account authentication enabled, i.e., can users log into existing accounts?
|
||||
|
@ -1037,7 +1037,7 @@ func (channel *Channel) replayHistoryForResume(session *Session, after time.Time
|
||||
}
|
||||
if !complete && !session.resumeDetails.HistoryIncomplete {
|
||||
// warn here if we didn't warn already
|
||||
rb.Add(nil, histServMask, "NOTICE", channel.Name(), session.client.t("Some additional message history may have been lost"))
|
||||
rb.Add(nil, histservService.prefix, "NOTICE", channel.Name(), session.client.t("Some additional message history may have been lost"))
|
||||
}
|
||||
rb.Send(true)
|
||||
}
|
||||
@ -1099,7 +1099,7 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I
|
||||
} else {
|
||||
message = fmt.Sprintf(client.t("%[1]s [account: %[2]s] joined the channel"), nick, item.AccountName)
|
||||
}
|
||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histServMask, "*", nil, "PRIVMSG", chname, message)
|
||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", chname, message)
|
||||
}
|
||||
case history.Part:
|
||||
if eventPlayback {
|
||||
@ -1109,14 +1109,14 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I
|
||||
continue // #474
|
||||
}
|
||||
message := fmt.Sprintf(client.t("%[1]s left the channel (%[2]s)"), nick, item.Message.Message)
|
||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histServMask, "*", nil, "PRIVMSG", chname, message)
|
||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", chname, message)
|
||||
}
|
||||
case history.Kick:
|
||||
if eventPlayback {
|
||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "KICK", chname, item.Params[0], item.Message.Message)
|
||||
} else {
|
||||
message := fmt.Sprintf(client.t("%[1]s kicked %[2]s (%[3]s)"), nick, item.Params[0], item.Message.Message)
|
||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histServMask, "*", nil, "PRIVMSG", chname, message)
|
||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", chname, message)
|
||||
}
|
||||
case history.Quit:
|
||||
if eventPlayback {
|
||||
@ -1126,21 +1126,21 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I
|
||||
continue // #474
|
||||
}
|
||||
message := fmt.Sprintf(client.t("%[1]s quit (%[2]s)"), nick, item.Message.Message)
|
||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histServMask, "*", nil, "PRIVMSG", chname, message)
|
||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", chname, message)
|
||||
}
|
||||
case history.Nick:
|
||||
if eventPlayback {
|
||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "NICK", item.Params[0])
|
||||
} else {
|
||||
message := fmt.Sprintf(client.t("%[1]s changed nick to %[2]s"), nick, item.Params[0])
|
||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histServMask, "*", nil, "PRIVMSG", chname, message)
|
||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", chname, message)
|
||||
}
|
||||
case history.Topic:
|
||||
if eventPlayback {
|
||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "TOPIC", chname, item.Message.Message)
|
||||
} else {
|
||||
message := fmt.Sprintf(client.t("%[1]s set the channel topic to: %[2]s"), nick, item.Message.Message)
|
||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histServMask, "*", nil, "PRIVMSG", chname, message)
|
||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", chname, message)
|
||||
}
|
||||
case history.Mode:
|
||||
params := make([]string, len(item.Message.Split)+1)
|
||||
@ -1152,7 +1152,7 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I
|
||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "MODE", params...)
|
||||
} else {
|
||||
message := fmt.Sprintf(client.t("%[1]s set channel modes: %[2]s"), nick, strings.Join(params[1:], " "))
|
||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histServMask, "*", nil, "PRIVMSG", chname, message)
|
||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", chname, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
220
irc/chanserv.go
220
irc/chanserv.go
@ -17,7 +17,6 @@ import (
|
||||
)
|
||||
|
||||
const chanservHelp = `ChanServ lets you register and manage channels.`
|
||||
const chanservMask = "ChanServ!ChanServ@localhost"
|
||||
|
||||
func chanregEnabled(config *Config) bool {
|
||||
return config.Channels.Registration.Enabled
|
||||
@ -188,27 +187,22 @@ SET modifies a channel's settings. The following settings are available:`,
|
||||
}
|
||||
)
|
||||
|
||||
// csNotice sends the client a notice from ChanServ
|
||||
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) {
|
||||
func csAmodeHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
channelName := params[0]
|
||||
|
||||
channel := server.channels.Get(channelName)
|
||||
if channel == nil {
|
||||
csNotice(rb, client.t("Channel does not exist"))
|
||||
service.Notice(rb, client.t("Channel does not exist"))
|
||||
return
|
||||
} else if channel.Founder() == "" {
|
||||
csNotice(rb, client.t("Channel is not registered"))
|
||||
service.Notice(rb, client.t("Channel is not registered"))
|
||||
return
|
||||
}
|
||||
|
||||
modeChanges, unknown := modes.ParseChannelModeChanges(params[1:]...)
|
||||
var change modes.ModeChange
|
||||
if len(modeChanges) > 1 || len(unknown) > 0 {
|
||||
csNotice(rb, client.t("Invalid mode change"))
|
||||
service.Notice(rb, client.t("Invalid mode change"))
|
||||
return
|
||||
} else if len(modeChanges) == 1 {
|
||||
change = modeChanges[0]
|
||||
@ -233,17 +227,17 @@ func csAmodeHandler(server *Server, client *Client, command string, params []str
|
||||
accountIsValid = (change.Arg != "")
|
||||
}
|
||||
if !accountIsValid {
|
||||
csNotice(rb, client.t("Account does not exist"))
|
||||
service.Notice(rb, client.t("Account does not exist"))
|
||||
return
|
||||
}
|
||||
|
||||
affectedModes, err := channel.ProcessAccountToUmodeChange(client, change)
|
||||
|
||||
if err == errInsufficientPrivs {
|
||||
csNotice(rb, client.t("Insufficient privileges"))
|
||||
service.Notice(rb, client.t("Insufficient privileges"))
|
||||
return
|
||||
} else if err != nil {
|
||||
csNotice(rb, client.t("Internal error"))
|
||||
service.Notice(rb, client.t("Internal error"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -253,13 +247,13 @@ func csAmodeHandler(server *Server, client *Client, command string, params []str
|
||||
sort.Slice(affectedModes, func(i, j int) bool {
|
||||
return umodeGreaterThan(affectedModes[i].Mode, affectedModes[j].Mode)
|
||||
})
|
||||
csNotice(rb, fmt.Sprintf(client.t("Channel %[1]s has %[2]d persistent modes set"), channelName, len(affectedModes)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Channel %[1]s has %[2]d persistent modes set"), channelName, len(affectedModes)))
|
||||
for _, modeChange := range affectedModes {
|
||||
csNotice(rb, fmt.Sprintf(client.t("Account %[1]s receives mode +%[2]s"), modeChange.Arg, string(modeChange.Mode)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Account %[1]s receives mode +%[2]s"), modeChange.Arg, string(modeChange.Mode)))
|
||||
}
|
||||
case modes.Add, modes.Remove:
|
||||
if len(affectedModes) > 0 {
|
||||
csNotice(rb, fmt.Sprintf(client.t("Successfully set persistent mode %[1]s on %[2]s"), strings.Join([]string{string(change.Op), string(change.Mode)}, ""), change.Arg))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Successfully set persistent mode %[1]s on %[2]s"), strings.Join([]string{string(change.Op), string(change.Mode)}, ""), change.Arg))
|
||||
// #729: apply change to current membership
|
||||
for _, member := range channel.Members() {
|
||||
if member.Account() == change.Arg {
|
||||
@ -270,22 +264,22 @@ func csAmodeHandler(server *Server, client *Client, command string, params []str
|
||||
}
|
||||
}
|
||||
} else {
|
||||
csNotice(rb, client.t("No changes were made"))
|
||||
service.Notice(rb, client.t("No changes were made"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func csOpHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func csOpHandler(service *ircService, 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"))
|
||||
service.Notice(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"))
|
||||
service.Notice(rb, client.t("Only the channel founder can do this"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -293,7 +287,7 @@ func csOpHandler(server *Server, client *Client, command string, params []string
|
||||
if len(params) > 1 {
|
||||
target = server.clients.Get(params[1])
|
||||
if target == nil {
|
||||
csNotice(rb, client.t("Could not find given client"))
|
||||
service.Notice(rb, client.t("Could not find given client"))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
@ -315,21 +309,21 @@ func csOpHandler(server *Server, client *Client, command string, params []string
|
||||
announceCmodeChanges(channelInfo, modes.ModeChanges{change}, server.name, "*", "", rb)
|
||||
}
|
||||
|
||||
csNotice(rb, client.t("Successfully granted operator privileges"))
|
||||
service.Notice(rb, client.t("Successfully granted operator privileges"))
|
||||
|
||||
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 csDeopHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func csDeopHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
channel := server.channels.Get(params[0])
|
||||
if channel == nil {
|
||||
csNotice(rb, client.t("Channel does not exist"))
|
||||
service.Notice(rb, client.t("Channel does not exist"))
|
||||
return
|
||||
}
|
||||
if !channel.hasClient(client) {
|
||||
csNotice(rb, client.t("You're not on that channel"))
|
||||
service.Notice(rb, client.t("You're not on that channel"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -337,7 +331,7 @@ func csDeopHandler(server *Server, client *Client, command string, params []stri
|
||||
if len(params) > 1 {
|
||||
target = server.clients.Get(params[1])
|
||||
if target == nil {
|
||||
csNotice(rb, client.t("Could not find given client"))
|
||||
service.Notice(rb, client.t("Could not find given client"))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
@ -346,7 +340,7 @@ func csDeopHandler(server *Server, client *Client, command string, params []stri
|
||||
|
||||
present, cumodes := channel.ClientStatus(target)
|
||||
if !present || len(cumodes) == 0 {
|
||||
csNotice(rb, client.t("Target has no privileges to remove"))
|
||||
service.Notice(rb, client.t("Target has no privileges to remove"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -370,38 +364,38 @@ func csDeopHandler(server *Server, client *Client, command string, params []stri
|
||||
return
|
||||
}
|
||||
|
||||
csNotice(rb, client.t("Successfully removed operator privileges"))
|
||||
service.Notice(rb, client.t("Successfully removed operator privileges"))
|
||||
}
|
||||
|
||||
func csRegisterHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func csRegisterHandler(service *ircService, 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"))
|
||||
service.Notice(rb, client.t("Channel registration is restricted to server operators"))
|
||||
return
|
||||
}
|
||||
channelName := params[0]
|
||||
channelInfo := server.channels.Get(channelName)
|
||||
if channelInfo == nil {
|
||||
csNotice(rb, client.t("No such channel"))
|
||||
service.Notice(rb, client.t("No such channel"))
|
||||
return
|
||||
}
|
||||
if !channelInfo.ClientIsAtLeast(client, modes.ChannelOperator) {
|
||||
csNotice(rb, client.t("You must be an oper on the channel to register it"))
|
||||
service.Notice(rb, client.t("You must be an oper on the channel to register it"))
|
||||
return
|
||||
}
|
||||
|
||||
account := client.Account()
|
||||
if !checkChanLimit(client, rb) {
|
||||
if !checkChanLimit(service, client, rb) {
|
||||
return
|
||||
}
|
||||
|
||||
// this provides the synchronization that allows exactly one registration of the channel:
|
||||
err := server.channels.SetRegistered(channelName, account)
|
||||
if err != nil {
|
||||
csNotice(rb, err.Error())
|
||||
service.Notice(rb, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
csNotice(rb, fmt.Sprintf(client.t("Channel %s successfully registered"), channelName))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Channel %s successfully registered"), 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))
|
||||
@ -415,38 +409,38 @@ func csRegisterHandler(server *Server, client *Client, command string, params []
|
||||
},
|
||||
rb)
|
||||
if applied {
|
||||
announceCmodeChanges(channelInfo, modes.ModeChanges{change}, chanservMask, "*", "", rb)
|
||||
announceCmodeChanges(channelInfo, modes.ModeChanges{change}, service.prefix, "*", "", rb)
|
||||
}
|
||||
}
|
||||
|
||||
// check whether a client has already registered too many channels
|
||||
func checkChanLimit(client *Client, rb *ResponseBuffer) (ok bool) {
|
||||
func checkChanLimit(service *ircService, client *Client, rb *ResponseBuffer) (ok bool) {
|
||||
account := client.Account()
|
||||
channelsAlreadyRegistered := client.server.accounts.ChannelsForAccount(account)
|
||||
ok = len(channelsAlreadyRegistered) < client.server.Config().Channels.Registration.MaxChannelsPerAccount || client.HasRoleCapabs("chanreg")
|
||||
if !ok {
|
||||
csNotice(rb, client.t("You have already registered the maximum number of channels; try dropping some with /CS UNREGISTER"))
|
||||
service.Notice(rb, client.t("You have already registered the maximum number of channels; try dropping some with /CS UNREGISTER"))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func csPrivsCheck(channel RegisteredChannel, client *Client, rb *ResponseBuffer) (success bool) {
|
||||
func csPrivsCheck(service *ircService, channel RegisteredChannel, client *Client, rb *ResponseBuffer) (success bool) {
|
||||
founder := channel.Founder
|
||||
if founder == "" {
|
||||
csNotice(rb, client.t("That channel is not registered"))
|
||||
service.Notice(rb, client.t("That channel is not registered"))
|
||||
return false
|
||||
}
|
||||
if client.HasRoleCapabs("chanreg") {
|
||||
return true
|
||||
}
|
||||
if founder != client.Account() {
|
||||
csNotice(rb, client.t("Insufficient privileges"))
|
||||
service.Notice(rb, client.t("Insufficient privileges"))
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func csUnregisterHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func csUnregisterHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
channelName := params[0]
|
||||
var verificationCode string
|
||||
if len(params) > 1 {
|
||||
@ -455,41 +449,41 @@ func csUnregisterHandler(server *Server, client *Client, command string, params
|
||||
|
||||
channel := server.channels.Get(channelName)
|
||||
if channel == nil {
|
||||
csNotice(rb, client.t("No such channel"))
|
||||
service.Notice(rb, client.t("No such channel"))
|
||||
return
|
||||
}
|
||||
|
||||
info := channel.ExportRegistration(0)
|
||||
channelKey := info.NameCasefolded
|
||||
if !csPrivsCheck(info, client, rb) {
|
||||
if !csPrivsCheck(service, info, client, rb) {
|
||||
return
|
||||
}
|
||||
|
||||
expectedCode := utils.ConfirmationCode(info.Name, info.RegisteredAt)
|
||||
if expectedCode != verificationCode {
|
||||
csNotice(rb, ircfmt.Unescape(client.t("$bWarning: unregistering this channel will remove all stored channel attributes.$b")))
|
||||
csNotice(rb, fmt.Sprintf(client.t("To confirm, run this command: %s"), fmt.Sprintf("/CS UNREGISTER %s %s", channelKey, expectedCode)))
|
||||
service.Notice(rb, ircfmt.Unescape(client.t("$bWarning: unregistering this channel will remove all stored channel attributes.$b")))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("To confirm, run this command: %s"), fmt.Sprintf("/CS UNREGISTER %s %s", channelKey, expectedCode)))
|
||||
return
|
||||
}
|
||||
|
||||
server.channels.SetUnregistered(channelKey, info.Founder)
|
||||
csNotice(rb, fmt.Sprintf(client.t("Channel %s is now unregistered"), channelKey))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Channel %s is now unregistered"), channelKey))
|
||||
}
|
||||
|
||||
func csClearHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func csClearHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
channel := server.channels.Get(params[0])
|
||||
if channel == nil {
|
||||
csNotice(rb, client.t("Channel does not exist"))
|
||||
service.Notice(rb, client.t("Channel does not exist"))
|
||||
return
|
||||
}
|
||||
if !csPrivsCheck(channel.ExportRegistration(0), client, rb) {
|
||||
if !csPrivsCheck(service, channel.ExportRegistration(0), client, rb) {
|
||||
return
|
||||
}
|
||||
|
||||
switch strings.ToLower(params[1]) {
|
||||
case "access":
|
||||
channel.resetAccess()
|
||||
csNotice(rb, client.t("Successfully reset channel access"))
|
||||
service.Notice(rb, client.t("Successfully reset channel access"))
|
||||
case "users":
|
||||
for _, target := range channel.Members() {
|
||||
if target != client {
|
||||
@ -497,20 +491,20 @@ func csClearHandler(server *Server, client *Client, command string, params []str
|
||||
}
|
||||
}
|
||||
default:
|
||||
csNotice(rb, client.t("Invalid parameters"))
|
||||
service.Notice(rb, client.t("Invalid parameters"))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func csTransferHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func csTransferHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
if strings.ToLower(params[0]) == "accept" {
|
||||
processTransferAccept(client, params[1], rb)
|
||||
processTransferAccept(service, client, params[1], rb)
|
||||
return
|
||||
}
|
||||
chname := params[0]
|
||||
channel := server.channels.Get(chname)
|
||||
if channel == nil {
|
||||
csNotice(rb, client.t("Channel does not exist"))
|
||||
service.Notice(rb, client.t("Channel does not exist"))
|
||||
return
|
||||
}
|
||||
regInfo := channel.ExportRegistration(0)
|
||||
@ -519,21 +513,21 @@ func csTransferHandler(server *Server, client *Client, command string, params []
|
||||
isFounder := account != "" && account == regInfo.Founder
|
||||
hasPrivs := client.HasRoleCapabs("chanreg")
|
||||
if !(isFounder || hasPrivs) {
|
||||
csNotice(rb, client.t("Insufficient privileges"))
|
||||
service.Notice(rb, client.t("Insufficient privileges"))
|
||||
return
|
||||
}
|
||||
target := params[1]
|
||||
targetAccount, err := server.accounts.LoadAccount(params[1])
|
||||
if err != nil {
|
||||
csNotice(rb, client.t("Account does not exist"))
|
||||
service.Notice(rb, client.t("Account does not exist"))
|
||||
return
|
||||
}
|
||||
if targetAccount.NameCasefolded != account {
|
||||
expectedCode := utils.ConfirmationCode(regInfo.Name, regInfo.RegisteredAt)
|
||||
codeValidated := 2 < len(params) && params[2] == expectedCode
|
||||
if !codeValidated {
|
||||
csNotice(rb, ircfmt.Unescape(client.t("$bWarning: you are about to transfer control of your channel to another user.$b")))
|
||||
csNotice(rb, fmt.Sprintf(client.t("To confirm your channel transfer, type: /CS TRANSFER %[1]s %[2]s %[3]s"), chname, target, expectedCode))
|
||||
service.Notice(rb, ircfmt.Unescape(client.t("$bWarning: you are about to transfer control of your channel to another user.$b")))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("To confirm your channel transfer, type: /CS TRANSFER %[1]s %[2]s %[3]s"), chname, target, expectedCode))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -541,19 +535,19 @@ func csTransferHandler(server *Server, client *Client, command string, params []
|
||||
if err == nil {
|
||||
switch status {
|
||||
case channelTransferComplete:
|
||||
csNotice(rb, fmt.Sprintf(client.t("Successfully transferred channel %[1]s to account %[2]s"), chname, target))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Successfully transferred channel %[1]s to account %[2]s"), chname, target))
|
||||
case channelTransferPending:
|
||||
sendTransferPendingNotice(server, target, chname)
|
||||
csNotice(rb, fmt.Sprintf(client.t("Transfer of channel %[1]s to account %[2]s succeeded, pending acceptance"), chname, target))
|
||||
sendTransferPendingNotice(service, server, target, chname)
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Transfer of channel %[1]s to account %[2]s succeeded, pending acceptance"), chname, target))
|
||||
case channelTransferCancelled:
|
||||
csNotice(rb, fmt.Sprintf(client.t("Cancelled pending transfer of channel %s"), chname))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Cancelled pending transfer of channel %s"), chname))
|
||||
}
|
||||
} else {
|
||||
csNotice(rb, client.t("Could not transfer channel"))
|
||||
service.Notice(rb, client.t("Could not transfer channel"))
|
||||
}
|
||||
}
|
||||
|
||||
func sendTransferPendingNotice(server *Server, account, chname string) {
|
||||
func sendTransferPendingNotice(service *ircService, server *Server, account, chname string) {
|
||||
clients := server.accounts.AccountToClients(account)
|
||||
if len(clients) == 0 {
|
||||
return
|
||||
@ -565,29 +559,29 @@ func sendTransferPendingNotice(server *Server, account, chname string) {
|
||||
break // prefer the login where the nick is the account
|
||||
}
|
||||
}
|
||||
client.Send(nil, chanservMask, "NOTICE", client.Nick(), fmt.Sprintf(client.t("You have been offered ownership of channel %[1]s. To accept, /CS TRANSFER ACCEPT %[1]s"), chname))
|
||||
client.Send(nil, service.prefix, "NOTICE", client.Nick(), fmt.Sprintf(client.t("You have been offered ownership of channel %[1]s. To accept, /CS TRANSFER ACCEPT %[1]s"), chname))
|
||||
}
|
||||
|
||||
func processTransferAccept(client *Client, chname string, rb *ResponseBuffer) {
|
||||
func processTransferAccept(service *ircService, client *Client, chname string, rb *ResponseBuffer) {
|
||||
channel := client.server.channels.Get(chname)
|
||||
if channel == nil {
|
||||
csNotice(rb, client.t("Channel does not exist"))
|
||||
service.Notice(rb, client.t("Channel does not exist"))
|
||||
return
|
||||
}
|
||||
if !checkChanLimit(client, rb) {
|
||||
if !checkChanLimit(service, client, rb) {
|
||||
return
|
||||
}
|
||||
switch channel.AcceptTransfer(client) {
|
||||
case nil:
|
||||
csNotice(rb, fmt.Sprintf(client.t("Successfully accepted ownership of channel %s"), channel.Name()))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Successfully accepted ownership of channel %s"), channel.Name()))
|
||||
case errChannelTransferNotOffered:
|
||||
csNotice(rb, fmt.Sprintf(client.t("You weren't offered ownership of channel %s"), channel.Name()))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("You weren't offered ownership of channel %s"), channel.Name()))
|
||||
default:
|
||||
csNotice(rb, fmt.Sprintf(client.t("Could not accept ownership of channel %s"), channel.Name()))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Could not accept ownership of channel %s"), channel.Name()))
|
||||
}
|
||||
}
|
||||
|
||||
func csPurgeHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func csPurgeHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
oper := client.Oper()
|
||||
if oper == nil {
|
||||
return // should be impossible because you need oper capabs for this
|
||||
@ -611,29 +605,29 @@ func csPurgeHandler(server *Server, client *Client, command string, params []str
|
||||
channel.Kick(client, target, "Cleared by ChanServ", rb, true)
|
||||
}
|
||||
}
|
||||
csNotice(rb, fmt.Sprintf(client.t("Successfully purged channel %s from the server"), chname))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Successfully purged channel %s from the server"), chname))
|
||||
case errInvalidChannelName:
|
||||
csNotice(rb, fmt.Sprintf(client.t("Can't purge invalid channel %s"), chname))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Can't purge invalid channel %s"), chname))
|
||||
default:
|
||||
csNotice(rb, client.t("An error occurred"))
|
||||
service.Notice(rb, client.t("An error occurred"))
|
||||
}
|
||||
}
|
||||
|
||||
func csUnpurgeHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func csUnpurgeHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
chname := params[0]
|
||||
switch server.channels.Unpurge(chname) {
|
||||
case nil:
|
||||
csNotice(rb, fmt.Sprintf(client.t("Successfully unpurged channel %s from the server"), chname))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Successfully unpurged channel %s from the server"), chname))
|
||||
case errNoSuchChannel:
|
||||
csNotice(rb, fmt.Sprintf(client.t("Channel %s wasn't previously purged from the server"), chname))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Channel %s wasn't previously purged from the server"), chname))
|
||||
default:
|
||||
csNotice(rb, client.t("An error occurred"))
|
||||
service.Notice(rb, client.t("An error occurred"))
|
||||
}
|
||||
}
|
||||
|
||||
func csListHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func csListHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
if !client.HasRoleCapabs("chanreg") {
|
||||
csNotice(rb, client.t("Insufficient privileges"))
|
||||
service.Notice(rb, client.t("Insufficient privileges"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -642,27 +636,27 @@ func csListHandler(server *Server, client *Client, command string, params []stri
|
||||
var err error
|
||||
searchRegex, err = regexp.Compile(params[0])
|
||||
if err != nil {
|
||||
csNotice(rb, client.t("Invalid regex"))
|
||||
service.Notice(rb, client.t("Invalid regex"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
csNotice(rb, ircfmt.Unescape(client.t("*** $bChanServ LIST$b ***")))
|
||||
service.Notice(rb, ircfmt.Unescape(client.t("*** $bChanServ LIST$b ***")))
|
||||
|
||||
channels := server.channelRegistry.AllChannels()
|
||||
for _, channel := range channels {
|
||||
if searchRegex == nil || searchRegex.MatchString(channel) {
|
||||
csNotice(rb, fmt.Sprintf(" %s", channel))
|
||||
service.Notice(rb, fmt.Sprintf(" %s", channel))
|
||||
}
|
||||
}
|
||||
|
||||
csNotice(rb, ircfmt.Unescape(client.t("*** $bEnd of ChanServ LIST$b ***")))
|
||||
service.Notice(rb, ircfmt.Unescape(client.t("*** $bEnd of ChanServ LIST$b ***")))
|
||||
}
|
||||
|
||||
func csInfoHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func csInfoHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
chname, err := CasefoldChannel(params[0])
|
||||
if err != nil {
|
||||
csNotice(rb, client.t("Invalid channel name"))
|
||||
service.Notice(rb, client.t("Invalid channel name"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -670,16 +664,16 @@ func csInfoHandler(server *Server, client *Client, command string, params []stri
|
||||
if client.HasRoleCapabs("chanreg") {
|
||||
purgeRecord, err := server.channelRegistry.LoadPurgeRecord(chname)
|
||||
if err == nil {
|
||||
csNotice(rb, fmt.Sprintf(client.t("Channel %s was purged by the server operators and cannot be used"), chname))
|
||||
csNotice(rb, fmt.Sprintf(client.t("Purged by operator: %s"), purgeRecord.Oper))
|
||||
csNotice(rb, fmt.Sprintf(client.t("Purged at: %s"), purgeRecord.PurgedAt.Format(time.RFC1123)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Channel %s was purged by the server operators and cannot be used"), chname))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Purged by operator: %s"), purgeRecord.Oper))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Purged at: %s"), purgeRecord.PurgedAt.Format(time.RFC1123)))
|
||||
if purgeRecord.Reason != "" {
|
||||
csNotice(rb, fmt.Sprintf(client.t("Purge reason: %s"), purgeRecord.Reason))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Purge reason: %s"), purgeRecord.Reason))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if server.channels.IsPurged(chname) {
|
||||
csNotice(rb, fmt.Sprintf(client.t("Channel %s was purged by the server operators and cannot be used"), chname))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Channel %s was purged by the server operators and cannot be used"), chname))
|
||||
}
|
||||
}
|
||||
|
||||
@ -690,59 +684,59 @@ func csInfoHandler(server *Server, client *Client, command string, params []stri
|
||||
} else {
|
||||
chinfo, err = server.channelRegistry.LoadChannel(chname)
|
||||
if err != nil && !(err == errNoSuchChannel || err == errFeatureDisabled) {
|
||||
csNotice(rb, client.t("An error occurred"))
|
||||
service.Notice(rb, client.t("An error occurred"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// channel exists but is unregistered, or doesn't exist:
|
||||
if chinfo.Founder == "" {
|
||||
csNotice(rb, fmt.Sprintf(client.t("Channel %s is not registered"), chname))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Channel %s is not registered"), chname))
|
||||
return
|
||||
}
|
||||
csNotice(rb, fmt.Sprintf(client.t("Channel %s is registered"), chinfo.Name))
|
||||
csNotice(rb, fmt.Sprintf(client.t("Founder: %s"), chinfo.Founder))
|
||||
csNotice(rb, fmt.Sprintf(client.t("Registered at: %s"), chinfo.RegisteredAt.Format(time.RFC1123)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Channel %s is registered"), chinfo.Name))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Founder: %s"), chinfo.Founder))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Registered at: %s"), chinfo.RegisteredAt.Format(time.RFC1123)))
|
||||
}
|
||||
|
||||
func displayChannelSetting(settingName string, settings ChannelSettings, client *Client, rb *ResponseBuffer) {
|
||||
func displayChannelSetting(service *ircService, settingName string, settings ChannelSettings, client *Client, rb *ResponseBuffer) {
|
||||
config := client.server.Config()
|
||||
|
||||
switch strings.ToLower(settingName) {
|
||||
case "history":
|
||||
effectiveValue := historyEnabled(config.History.Persistent.RegisteredChannels, settings.History)
|
||||
csNotice(rb, fmt.Sprintf(client.t("The stored channel history setting is: %s"), historyStatusToString(settings.History)))
|
||||
csNotice(rb, fmt.Sprintf(client.t("Given current server settings, the channel history setting is: %s"), historyStatusToString(effectiveValue)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("The stored channel history setting is: %s"), historyStatusToString(settings.History)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Given current server settings, the channel history setting is: %s"), historyStatusToString(effectiveValue)))
|
||||
default:
|
||||
csNotice(rb, client.t("Invalid params"))
|
||||
service.Notice(rb, client.t("Invalid params"))
|
||||
}
|
||||
}
|
||||
|
||||
func csGetHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func csGetHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
chname, setting := params[0], params[1]
|
||||
channel := server.channels.Get(chname)
|
||||
if channel == nil {
|
||||
csNotice(rb, client.t("No such channel"))
|
||||
service.Notice(rb, client.t("No such channel"))
|
||||
return
|
||||
}
|
||||
info := channel.ExportRegistration(IncludeSettings)
|
||||
if !csPrivsCheck(info, client, rb) {
|
||||
if !csPrivsCheck(service, info, client, rb) {
|
||||
return
|
||||
}
|
||||
|
||||
displayChannelSetting(setting, info.Settings, client, rb)
|
||||
displayChannelSetting(service, setting, info.Settings, client, rb)
|
||||
}
|
||||
|
||||
func csSetHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func csSetHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
chname, setting, value := params[0], params[1], params[2]
|
||||
channel := server.channels.Get(chname)
|
||||
if channel == nil {
|
||||
csNotice(rb, client.t("No such channel"))
|
||||
service.Notice(rb, client.t("No such channel"))
|
||||
return
|
||||
}
|
||||
info := channel.ExportRegistration(IncludeSettings)
|
||||
settings := info.Settings
|
||||
if !csPrivsCheck(info, client, rb) {
|
||||
if !csPrivsCheck(service, info, client, rb) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -760,12 +754,12 @@ func csSetHandler(server *Server, client *Client, command string, params []strin
|
||||
|
||||
switch err {
|
||||
case nil:
|
||||
csNotice(rb, client.t("Successfully changed the channel settings"))
|
||||
displayChannelSetting(setting, settings, client, rb)
|
||||
service.Notice(rb, client.t("Successfully changed the channel settings"))
|
||||
displayChannelSetting(service, setting, settings, client, rb)
|
||||
case errInvalidParams:
|
||||
csNotice(rb, client.t("Invalid parameters"))
|
||||
service.Notice(rb, client.t("Invalid parameters"))
|
||||
default:
|
||||
server.logger.Error("internal", "CS SET error:", err.Error())
|
||||
csNotice(rb, client.t("An error occurred"))
|
||||
service.Notice(rb, client.t("An error occurred"))
|
||||
}
|
||||
}
|
||||
|
@ -537,6 +537,7 @@ type Config struct {
|
||||
EnforceUtf8 bool `yaml:"enforce-utf8"`
|
||||
OutputPath string `yaml:"output-path"`
|
||||
IPCheckScript ScriptConfig `yaml:"ip-check-script"`
|
||||
OverrideServicesHostname string `yaml:"override-services-hostname"`
|
||||
}
|
||||
|
||||
Roleplay struct {
|
||||
|
@ -77,23 +77,23 @@ func registrationErrorToMessage(err error) (message string) {
|
||||
}
|
||||
|
||||
// helper function to dispatch messages when a client successfully registers
|
||||
func sendSuccessfulRegResponse(client *Client, rb *ResponseBuffer, forNS bool) {
|
||||
func sendSuccessfulRegResponse(service *ircService, client *Client, rb *ResponseBuffer) {
|
||||
details := client.Details()
|
||||
if forNS {
|
||||
nsNotice(rb, client.t("Account created"))
|
||||
if service != nil {
|
||||
service.Notice(rb, client.t("Account created"))
|
||||
} else {
|
||||
rb.Add(nil, client.server.name, RPL_REG_SUCCESS, details.nick, details.accountName, client.t("Account created"))
|
||||
}
|
||||
client.server.snomasks.Send(sno.LocalAccounts, fmt.Sprintf(ircfmt.Unescape("Client $c[grey][$r%s$c[grey]] registered account $c[grey][$r%s$c[grey]] from IP %s"), details.nickMask, details.accountName, rb.session.IP().String()))
|
||||
sendSuccessfulAccountAuth(client, rb, forNS, false)
|
||||
sendSuccessfulAccountAuth(service, client, rb, false)
|
||||
}
|
||||
|
||||
// sendSuccessfulAccountAuth means that an account auth attempt completed successfully, and is used to dispatch messages.
|
||||
func sendSuccessfulAccountAuth(client *Client, rb *ResponseBuffer, forNS, forSASL bool) {
|
||||
func sendSuccessfulAccountAuth(service *ircService, client *Client, rb *ResponseBuffer, forSASL bool) {
|
||||
details := client.Details()
|
||||
|
||||
if forNS {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("You're now logged in as %s"), details.accountName))
|
||||
if service != nil {
|
||||
service.Notice(rb, fmt.Sprintf(client.t("You're now logged in as %s"), details.accountName))
|
||||
} else {
|
||||
//TODO(dan): some servers send this numeric even for NickServ logins iirc? to confirm and maybe do too
|
||||
rb.Add(nil, client.server.name, RPL_LOGGEDIN, details.nick, details.nickMask, details.accountName, fmt.Sprintf(client.t("You are now logged in as %s"), details.accountName))
|
||||
@ -253,11 +253,11 @@ func authPlainHandler(server *Server, client *Client, mechanism string, value []
|
||||
msg := authErrorToMessage(server, err)
|
||||
rb.Add(nil, server.name, ERR_SASLFAIL, client.Nick(), fmt.Sprintf("%s: %s", client.t("SASL authentication failed"), client.t(msg)))
|
||||
return false
|
||||
} else if !fixupNickEqualsAccount(client, rb, server.Config()) {
|
||||
} else if !fixupNickEqualsAccount(client, rb, server.Config(), "") {
|
||||
return false
|
||||
}
|
||||
|
||||
sendSuccessfulAccountAuth(client, rb, false, true)
|
||||
sendSuccessfulAccountAuth(nil, client, rb, true)
|
||||
return false
|
||||
}
|
||||
|
||||
@ -311,11 +311,11 @@ func authExternalHandler(server *Server, client *Client, mechanism string, value
|
||||
msg := authErrorToMessage(server, err)
|
||||
rb.Add(nil, server.name, ERR_SASLFAIL, client.nick, fmt.Sprintf("%s: %s", client.t("SASL authentication failed"), client.t(msg)))
|
||||
return false
|
||||
} else if !fixupNickEqualsAccount(client, rb, server.Config()) {
|
||||
} else if !fixupNickEqualsAccount(client, rb, server.Config(), "") {
|
||||
return false
|
||||
}
|
||||
|
||||
sendSuccessfulAccountAuth(client, rb, false, true)
|
||||
sendSuccessfulAccountAuth(nil, client, rb, true)
|
||||
return false
|
||||
}
|
||||
|
||||
@ -1525,7 +1525,7 @@ func listHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
|
||||
config := server.Config()
|
||||
if time.Since(client.ctime) < config.Channels.ListDelay && client.Account() == "" && !client.HasMode(modes.Operator) {
|
||||
remaining := time.Until(client.ctime.Add(config.Channels.ListDelay))
|
||||
csNotice(rb, fmt.Sprintf(client.t("This server requires that you wait %v after connecting before you can use /LIST. You have %v left."), config.Channels.ListDelay, remaining))
|
||||
rb.Notice(fmt.Sprintf(client.t("This server requires that you wait %v after connecting before you can use /LIST. You have %v left."), config.Channels.ListDelay, remaining))
|
||||
rb.Add(nil, server.name, RPL_LISTEND, client.Nick(), client.t("End of LIST"))
|
||||
return false
|
||||
}
|
||||
@ -2355,7 +2355,7 @@ func passHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
|
||||
}
|
||||
err := server.accounts.AuthenticateByPassphrase(client, account, accountPass)
|
||||
if err == nil {
|
||||
sendSuccessfulAccountAuth(client, rb, false, true)
|
||||
sendSuccessfulAccountAuth(nil, client, rb, true)
|
||||
// login-via-pass-command entails that we do not need to check
|
||||
// an actual server password (either no password or skip-server-password)
|
||||
rb.session.passStatus = serverPassSuccessful
|
||||
@ -2446,13 +2446,13 @@ func registerHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *
|
||||
err := server.accounts.Verify(client, accountName, "")
|
||||
if err == nil {
|
||||
if client.registered {
|
||||
if !fixupNickEqualsAccount(client, rb, config) {
|
||||
if !fixupNickEqualsAccount(client, rb, config, "") {
|
||||
err = errNickAccountMismatch
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
rb.Add(nil, server.name, "REGISTER", "SUCCESS", accountName, client.t("Account successfully registered"))
|
||||
sendSuccessfulRegResponse(client, rb, true)
|
||||
sendSuccessfulRegResponse(nil, client, rb)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
@ -2494,14 +2494,14 @@ func verifyHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
|
||||
accountName, verificationCode := msg.Params[0], msg.Params[1]
|
||||
err := server.accounts.Verify(client, accountName, verificationCode)
|
||||
if err == nil && client.registered {
|
||||
if !fixupNickEqualsAccount(client, rb, config) {
|
||||
if !fixupNickEqualsAccount(client, rb, config, "") {
|
||||
err = errNickAccountMismatch
|
||||
}
|
||||
}
|
||||
switch err {
|
||||
case nil:
|
||||
rb.Add(nil, server.name, "VERIFY", "SUCCESS", accountName, client.t("Account successfully registered"))
|
||||
sendSuccessfulRegResponse(client, rb, true)
|
||||
sendSuccessfulRegResponse(nil, client, rb)
|
||||
case errAccountVerificationInvalidCode:
|
||||
rb.Add(nil, server.name, "FAIL", "VERIFY", "INVALID_CODE", client.t("Invalid verification code"))
|
||||
default:
|
||||
@ -2873,7 +2873,7 @@ func userHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
|
||||
username, password = username[:colonIndex], username[colonIndex+1:]
|
||||
err := server.accounts.AuthenticateByPassphrase(client, username, password)
|
||||
if err == nil {
|
||||
sendSuccessfulAccountAuth(client, rb, false, true)
|
||||
sendSuccessfulAccountAuth(nil, client, rb, true)
|
||||
} else {
|
||||
// this is wrong, but send something for debugging that will show up in a raw transcript
|
||||
rb.Add(nil, server.name, ERR_SASLFAIL, client.Nick(), client.t("SASL authentication failed"))
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
|
||||
const (
|
||||
histservHelp = `HistServ provides commands related to history.`
|
||||
histServMask = "HistServ!HistServ@localhost"
|
||||
)
|
||||
|
||||
func histservEnabled(config *Config) bool {
|
||||
@ -83,24 +82,19 @@ CHATHISTORY.`,
|
||||
}
|
||||
)
|
||||
|
||||
// histNotice sends the client a notice from HistServ
|
||||
func histNotice(rb *ResponseBuffer, text string) {
|
||||
rb.Add(nil, histServMask, "NOTICE", rb.target.Nick(), text)
|
||||
}
|
||||
|
||||
func histservForgetHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func histservForgetHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
accountName := server.accounts.AccountToAccountName(params[0])
|
||||
if accountName == "" {
|
||||
histNotice(rb, client.t("Could not look up account name, proceeding anyway"))
|
||||
service.Notice(rb, client.t("Could not look up account name, proceeding anyway"))
|
||||
accountName = params[0]
|
||||
}
|
||||
|
||||
server.ForgetHistory(accountName)
|
||||
|
||||
histNotice(rb, fmt.Sprintf(client.t("Enqueued account %s for message deletion"), accountName))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Enqueued account %s for message deletion"), accountName))
|
||||
}
|
||||
|
||||
func histservDeleteHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func histservDeleteHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
var target, msgid string
|
||||
if len(params) == 1 {
|
||||
msgid = params[0]
|
||||
@ -113,27 +107,27 @@ func histservDeleteHandler(server *Server, client *Client, command string, param
|
||||
if !hasPrivs {
|
||||
accountName = client.AccountName()
|
||||
if !(server.Config().History.Retention.AllowIndividualDelete && accountName != "*") {
|
||||
histNotice(rb, client.t("Insufficient privileges"))
|
||||
service.Notice(rb, client.t("Insufficient privileges"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err := server.DeleteMessage(target, msgid, accountName)
|
||||
if err == nil {
|
||||
histNotice(rb, client.t("Successfully deleted message"))
|
||||
service.Notice(rb, client.t("Successfully deleted message"))
|
||||
} else {
|
||||
if hasPrivs {
|
||||
histNotice(rb, fmt.Sprintf(client.t("Error deleting message: %v"), err))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Error deleting message: %v"), err))
|
||||
} else {
|
||||
histNotice(rb, client.t("Could not delete message"))
|
||||
service.Notice(rb, client.t("Could not delete message"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func histservExportHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func histservExportHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
cfAccount, err := CasefoldName(params[0])
|
||||
if err != nil {
|
||||
histNotice(rb, client.t("Invalid account name"))
|
||||
service.Notice(rb, client.t("Invalid account name"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -143,15 +137,15 @@ func histservExportHandler(server *Server, client *Client, command string, param
|
||||
pathname := config.getOutputPath(filename)
|
||||
outfile, err := os.Create(pathname)
|
||||
if err != nil {
|
||||
histNotice(rb, fmt.Sprintf(client.t("Error opening export file: %v"), err))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Error opening export file: %v"), err))
|
||||
} else {
|
||||
histNotice(rb, fmt.Sprintf(client.t("Started exporting data for account %[1]s to file %[2]s"), cfAccount, filename))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Started exporting data for account %[1]s to file %[2]s"), cfAccount, filename))
|
||||
}
|
||||
|
||||
go histservExportAndNotify(server, cfAccount, outfile, filename, client.Nick())
|
||||
go histservExportAndNotify(service, server, cfAccount, outfile, filename, client.Nick())
|
||||
}
|
||||
|
||||
func histservExportAndNotify(server *Server, cfAccount string, outfile *os.File, filename, alertNick string) {
|
||||
func histservExportAndNotify(service *ircService, server *Server, cfAccount string, outfile *os.File, filename, alertNick string) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
server.logger.Error("history",
|
||||
@ -167,19 +161,19 @@ func histservExportAndNotify(server *Server, cfAccount string, outfile *os.File,
|
||||
|
||||
client := server.clients.Get(alertNick)
|
||||
if client != nil && client.HasRoleCapabs("history") {
|
||||
client.Send(nil, histServMask, "NOTICE", client.Nick(), fmt.Sprintf(client.t("Data export for %[1]s completed and written to %[2]s"), cfAccount, filename))
|
||||
client.Send(nil, service.prefix, "NOTICE", client.Nick(), fmt.Sprintf(client.t("Data export for %[1]s completed and written to %[2]s"), cfAccount, filename))
|
||||
}
|
||||
}
|
||||
|
||||
func histservPlayHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func histservPlayHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
items, _, err := easySelectHistory(server, client, params)
|
||||
if err != nil {
|
||||
histNotice(rb, client.t("Could not retrieve history"))
|
||||
service.Notice(rb, client.t("Could not retrieve history"))
|
||||
return
|
||||
}
|
||||
|
||||
playMessage := func(timestamp time.Time, nick, message string) {
|
||||
histNotice(rb, fmt.Sprintf("%s <%s> %s", timestamp.Format("15:04:05"), stripMaskFromNick(nick), message))
|
||||
service.Notice(rb, fmt.Sprintf("%s <%s> %s", timestamp.Format("15:04:05"), stripMaskFromNick(nick), message))
|
||||
}
|
||||
|
||||
for _, item := range items {
|
||||
@ -196,7 +190,7 @@ func histservPlayHandler(server *Server, client *Client, command string, params
|
||||
}
|
||||
}
|
||||
|
||||
histNotice(rb, client.t("End of history playback"))
|
||||
service.Notice(rb, client.t("End of history playback"))
|
||||
}
|
||||
|
||||
// handles parameter parsing and history queries for /HISTORY and /HISTSERV PLAY
|
||||
|
@ -16,7 +16,6 @@ import (
|
||||
const (
|
||||
hostservHelp = `HostServ lets you manage your vhost (i.e., the string displayed
|
||||
in place of your client's hostname/IP).`
|
||||
hsNickMask = "HostServ!HostServ@localhost"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -95,12 +94,7 @@ display the necessary code.`,
|
||||
}
|
||||
)
|
||||
|
||||
// hsNotice sends the client a notice from HostServ
|
||||
func hsNotice(rb *ResponseBuffer, text string) {
|
||||
rb.Add(nil, hsNickMask, "NOTICE", rb.target.Nick(), text)
|
||||
}
|
||||
|
||||
func hsOnOffHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func hsOnOffHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
enable := false
|
||||
if command == "on" {
|
||||
enable = true
|
||||
@ -108,28 +102,28 @@ func hsOnOffHandler(server *Server, client *Client, command string, params []str
|
||||
|
||||
_, err := server.accounts.VHostSetEnabled(client, enable)
|
||||
if err == errNoVhost {
|
||||
hsNotice(rb, client.t(err.Error()))
|
||||
service.Notice(rb, client.t(err.Error()))
|
||||
} else if err != nil {
|
||||
hsNotice(rb, client.t("An error occurred"))
|
||||
service.Notice(rb, client.t("An error occurred"))
|
||||
} else if enable {
|
||||
hsNotice(rb, client.t("Successfully enabled your vhost"))
|
||||
service.Notice(rb, client.t("Successfully enabled your vhost"))
|
||||
} else {
|
||||
hsNotice(rb, client.t("Successfully disabled your vhost"))
|
||||
service.Notice(rb, client.t("Successfully disabled your vhost"))
|
||||
}
|
||||
}
|
||||
|
||||
func hsStatusHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func hsStatusHandler(service *ircService, 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"))
|
||||
service.Notice(rb, client.t("Command restricted"))
|
||||
return
|
||||
}
|
||||
accountName = params[0]
|
||||
} else {
|
||||
accountName = client.Account()
|
||||
if accountName == "" {
|
||||
hsNotice(rb, client.t("You're not logged into an account"))
|
||||
service.Notice(rb, client.t("You're not logged into an account"))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -139,17 +133,17 @@ func hsStatusHandler(server *Server, client *Client, command string, params []st
|
||||
if err != errAccountDoesNotExist {
|
||||
server.logger.Warning("internal", "error loading account info", accountName, err.Error())
|
||||
}
|
||||
hsNotice(rb, client.t("No such account"))
|
||||
service.Notice(rb, client.t("No such account"))
|
||||
return
|
||||
}
|
||||
|
||||
if account.VHost.ApprovedVHost != "" {
|
||||
hsNotice(rb, fmt.Sprintf(client.t("Account %[1]s has vhost: %[2]s"), accountName, account.VHost.ApprovedVHost))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Account %[1]s has vhost: %[2]s"), accountName, account.VHost.ApprovedVHost))
|
||||
if !account.VHost.Enabled {
|
||||
hsNotice(rb, client.t("This vhost is currently disabled, but can be enabled with /HS ON"))
|
||||
service.Notice(rb, client.t("This vhost is currently disabled, but can be enabled with /HS ON"))
|
||||
}
|
||||
} else {
|
||||
hsNotice(rb, fmt.Sprintf(client.t("Account %s has no vhost"), accountName))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Account %s has no vhost"), accountName))
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,14 +158,14 @@ func validateVhost(server *Server, vhost string, oper bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func hsSetHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func hsSetHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
user := params[0]
|
||||
var vhost string
|
||||
|
||||
if command == "set" {
|
||||
vhost = params[1]
|
||||
if validateVhost(server, vhost, true) != nil {
|
||||
hsNotice(rb, client.t("Invalid vhost"))
|
||||
service.Notice(rb, client.t("Invalid vhost"))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -179,22 +173,22 @@ func hsSetHandler(server *Server, client *Client, command string, params []strin
|
||||
|
||||
_, err := server.accounts.VHostSet(user, vhost)
|
||||
if err != nil {
|
||||
hsNotice(rb, client.t("An error occurred"))
|
||||
service.Notice(rb, client.t("An error occurred"))
|
||||
} else if vhost != "" {
|
||||
hsNotice(rb, client.t("Successfully set vhost"))
|
||||
service.Notice(rb, client.t("Successfully set vhost"))
|
||||
} else {
|
||||
hsNotice(rb, client.t("Successfully cleared vhost"))
|
||||
service.Notice(rb, client.t("Successfully cleared vhost"))
|
||||
}
|
||||
}
|
||||
|
||||
func hsSetCloakSecretHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func hsSetCloakSecretHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
secret := params[0]
|
||||
expectedCode := utils.ConfirmationCode(secret, server.ctime)
|
||||
if len(params) == 1 || params[1] != expectedCode {
|
||||
hsNotice(rb, ircfmt.Unescape(client.t("$bWarning: changing the cloak secret will invalidate stored ban/invite/exception lists.$b")))
|
||||
hsNotice(rb, fmt.Sprintf(client.t("To confirm, run this command: %s"), fmt.Sprintf("/HS SETCLOAKSECRET %s %s", secret, expectedCode)))
|
||||
service.Notice(rb, ircfmt.Unescape(client.t("$bWarning: changing the cloak secret will invalidate stored ban/invite/exception lists.$b")))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("To confirm, run this command: %s"), fmt.Sprintf("/HS SETCLOAKSECRET %s %s", secret, expectedCode)))
|
||||
return
|
||||
}
|
||||
StoreCloakSecret(server.store, secret)
|
||||
hsNotice(rb, client.t("Rotated the cloak secret; you must rehash or restart the server for it to take effect"))
|
||||
service.Notice(rb, client.t("Rotated the cloak secret; you must rehash or restart the server for it to take effect"))
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ func (server *Server) RandomlyRename(client *Client) {
|
||||
// so we need to re-NICK automatically on every login event (IDENTIFY,
|
||||
// VERIFY, and a REGISTER that auto-verifies). if we can't get the nick
|
||||
// then we log them out (they will be able to reattach with SASL)
|
||||
func fixupNickEqualsAccount(client *Client, rb *ResponseBuffer, config *Config) (success bool) {
|
||||
func fixupNickEqualsAccount(client *Client, rb *ResponseBuffer, config *Config, source string) (success bool) {
|
||||
if !config.Accounts.NickReservation.ForceNickEqualsAccount {
|
||||
return true
|
||||
}
|
||||
@ -161,7 +161,10 @@ func fixupNickEqualsAccount(client *Client, rb *ResponseBuffer, config *Config)
|
||||
err := performNickChange(client.server, client, client, rb.session, client.AccountName(), rb)
|
||||
if err != nil && err != errNoop {
|
||||
client.server.accounts.Logout(client)
|
||||
nsNotice(rb, client.t("A client is already using that account; try logging out and logging back in with SASL"))
|
||||
if source == "" {
|
||||
source = client.server.name
|
||||
}
|
||||
rb.Add(nil, source, "NOTICE", client.t("A client is already using that account; try logging out and logging back in with SASL"))
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
379
irc/nickserv.go
379
irc/nickserv.go
@ -36,10 +36,6 @@ func servCmdRequiresBouncerEnabled(config *Config) bool {
|
||||
return config.Accounts.Multiclient.Enabled
|
||||
}
|
||||
|
||||
const (
|
||||
nsPrefix = "NickServ!NickServ@localhost"
|
||||
)
|
||||
|
||||
const nickservHelp = `NickServ lets you register, log in to, and manage an account.`
|
||||
|
||||
var (
|
||||
@ -361,14 +357,7 @@ Currently, you can only change the canonical casefolding of an account
|
||||
}
|
||||
)
|
||||
|
||||
// nsNotice sends the client a notice from NickServ
|
||||
func nsNotice(rb *ResponseBuffer, text string) {
|
||||
// XXX i can't figure out how to use OragonoServices[servicename].prefix here
|
||||
// without creating a compile-time initialization loop
|
||||
rb.Add(nil, nsPrefix, "NOTICE", rb.target.Nick(), text)
|
||||
}
|
||||
|
||||
func nsGetHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsGetHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
var account string
|
||||
if command == "saget" {
|
||||
account = params[0]
|
||||
@ -379,101 +368,101 @@ func nsGetHandler(server *Server, client *Client, command string, params []strin
|
||||
|
||||
accountData, err := server.accounts.LoadAccount(account)
|
||||
if err == errAccountDoesNotExist {
|
||||
nsNotice(rb, client.t("No such account"))
|
||||
service.Notice(rb, client.t("No such account"))
|
||||
return
|
||||
} else if err != nil {
|
||||
nsNotice(rb, client.t("Error loading account data"))
|
||||
service.Notice(rb, client.t("Error loading account data"))
|
||||
return
|
||||
}
|
||||
|
||||
displaySetting(params[0], accountData.Settings, client, rb)
|
||||
displaySetting(service, params[0], accountData.Settings, client, rb)
|
||||
}
|
||||
|
||||
func displaySetting(settingName string, settings AccountSettings, client *Client, rb *ResponseBuffer) {
|
||||
func displaySetting(service *ircService, settingName string, settings AccountSettings, client *Client, rb *ResponseBuffer) {
|
||||
config := client.server.Config()
|
||||
switch strings.ToLower(settingName) {
|
||||
case "enforce":
|
||||
storedValue := settings.NickEnforcement
|
||||
serializedStoredValue := nickReservationToString(storedValue)
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Your stored nickname enforcement setting is: %s"), serializedStoredValue))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Your stored nickname enforcement setting is: %s"), serializedStoredValue))
|
||||
serializedActualValue := nickReservationToString(configuredEnforcementMethod(config, storedValue))
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Given current server settings, your nickname is enforced with: %s"), serializedActualValue))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Given current server settings, your nickname is enforced with: %s"), serializedActualValue))
|
||||
case "autoreplay-lines":
|
||||
if settings.AutoreplayLines == nil {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("You will receive the server default of %d lines of autoreplayed history"), config.History.AutoreplayOnJoin))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("You will receive the server default of %d lines of autoreplayed history"), config.History.AutoreplayOnJoin))
|
||||
} else {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("You will receive %d lines of autoreplayed history"), *settings.AutoreplayLines))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("You will receive %d lines of autoreplayed history"), *settings.AutoreplayLines))
|
||||
}
|
||||
case "replay-joins":
|
||||
switch settings.ReplayJoins {
|
||||
case ReplayJoinsCommandsOnly:
|
||||
nsNotice(rb, client.t("You will see JOINs and PARTs in /HISTORY output, but not in autoreplay"))
|
||||
service.Notice(rb, client.t("You will see JOINs and PARTs in /HISTORY output, but not in autoreplay"))
|
||||
case ReplayJoinsAlways:
|
||||
nsNotice(rb, client.t("You will see JOINs and PARTs in /HISTORY output and in autoreplay"))
|
||||
service.Notice(rb, client.t("You will see JOINs and PARTs in /HISTORY output and in autoreplay"))
|
||||
case ReplayJoinsNever:
|
||||
nsNotice(rb, client.t("You will not see JOINs and PARTs in /HISTORY output or in autoreplay"))
|
||||
service.Notice(rb, client.t("You will not see JOINs and PARTs in /HISTORY output or in autoreplay"))
|
||||
}
|
||||
case "multiclient":
|
||||
if !config.Accounts.Multiclient.Enabled {
|
||||
nsNotice(rb, client.t("This feature has been disabled by the server administrators"))
|
||||
service.Notice(rb, client.t("This feature has been disabled by the server administrators"))
|
||||
} else {
|
||||
switch settings.AllowBouncer {
|
||||
case MulticlientAllowedServerDefault:
|
||||
if config.Accounts.Multiclient.AllowedByDefault {
|
||||
nsNotice(rb, client.t("Multiclient functionality is currently enabled for your account, but you can opt out"))
|
||||
service.Notice(rb, client.t("Multiclient functionality is currently enabled for your account, but you can opt out"))
|
||||
} else {
|
||||
nsNotice(rb, client.t("Multiclient functionality is currently disabled for your account, but you can opt in"))
|
||||
service.Notice(rb, client.t("Multiclient functionality is currently disabled for your account, but you can opt in"))
|
||||
}
|
||||
case MulticlientDisallowedByUser:
|
||||
nsNotice(rb, client.t("Multiclient functionality is currently disabled for your account"))
|
||||
service.Notice(rb, client.t("Multiclient functionality is currently disabled for your account"))
|
||||
case MulticlientAllowedByUser:
|
||||
nsNotice(rb, client.t("Multiclient functionality is currently enabled for your account"))
|
||||
service.Notice(rb, client.t("Multiclient functionality is currently enabled for your account"))
|
||||
}
|
||||
}
|
||||
case "always-on":
|
||||
stored := settings.AlwaysOn
|
||||
actual := persistenceEnabled(config.Accounts.Multiclient.AlwaysOn, stored)
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Your stored always-on setting is: %s"), persistentStatusToString(stored)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Your stored always-on setting is: %s"), persistentStatusToString(stored)))
|
||||
if actual {
|
||||
nsNotice(rb, client.t("Given current server settings, your client is always-on"))
|
||||
service.Notice(rb, client.t("Given current server settings, your client is always-on"))
|
||||
} else {
|
||||
nsNotice(rb, client.t("Given current server settings, your client is not always-on"))
|
||||
service.Notice(rb, client.t("Given current server settings, your client is not always-on"))
|
||||
}
|
||||
case "autoreplay-missed":
|
||||
stored := settings.AutoreplayMissed
|
||||
if stored {
|
||||
alwaysOn := persistenceEnabled(config.Accounts.Multiclient.AlwaysOn, settings.AlwaysOn)
|
||||
if alwaysOn {
|
||||
nsNotice(rb, client.t("Autoreplay of missed messages is enabled"))
|
||||
service.Notice(rb, client.t("Autoreplay of missed messages is enabled"))
|
||||
} else {
|
||||
nsNotice(rb, client.t("You have enabled autoreplay of missed messages, but you can't receive them because your client isn't set to always-on"))
|
||||
service.Notice(rb, client.t("You have enabled autoreplay of missed messages, but you can't receive them because your client isn't set to always-on"))
|
||||
}
|
||||
} else {
|
||||
nsNotice(rb, client.t("Your account is not configured to receive autoreplayed missed messages"))
|
||||
service.Notice(rb, client.t("Your account is not configured to receive autoreplayed missed messages"))
|
||||
}
|
||||
case "auto-away":
|
||||
stored := settings.AutoAway
|
||||
alwaysOn := persistenceEnabled(config.Accounts.Multiclient.AlwaysOn, settings.AlwaysOn)
|
||||
actual := persistenceEnabled(config.Accounts.Multiclient.AutoAway, settings.AutoAway)
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Your stored auto-away setting is: %s"), persistentStatusToString(stored)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Your stored auto-away setting is: %s"), persistentStatusToString(stored)))
|
||||
if actual && alwaysOn {
|
||||
nsNotice(rb, client.t("Given current server settings, auto-away is enabled for your client"))
|
||||
service.Notice(rb, client.t("Given current server settings, auto-away is enabled for your client"))
|
||||
} else if actual && !alwaysOn {
|
||||
nsNotice(rb, client.t("Because your client is not always-on, auto-away is disabled"))
|
||||
service.Notice(rb, client.t("Because your client is not always-on, auto-away is disabled"))
|
||||
} else if !actual {
|
||||
nsNotice(rb, client.t("Given current server settings, auto-away is disabled for your client"))
|
||||
service.Notice(rb, client.t("Given current server settings, auto-away is disabled for your client"))
|
||||
}
|
||||
case "dm-history":
|
||||
effectiveValue := historyEnabled(config.History.Persistent.DirectMessages, settings.DMHistory)
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Your stored direct message history setting is: %s"), historyStatusToString(settings.DMHistory)))
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Given current server settings, your direct message history setting is: %s"), historyStatusToString(effectiveValue)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Your stored direct message history setting is: %s"), historyStatusToString(settings.DMHistory)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Given current server settings, your direct message history setting is: %s"), historyStatusToString(effectiveValue)))
|
||||
|
||||
default:
|
||||
nsNotice(rb, client.t("No such setting"))
|
||||
service.Notice(rb, client.t("No such setting"))
|
||||
}
|
||||
}
|
||||
|
||||
func nsSetHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsSetHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
var account string
|
||||
if command == "saset" {
|
||||
account = params[0]
|
||||
@ -487,7 +476,7 @@ func nsSetHandler(server *Server, client *Client, command string, params []strin
|
||||
var err error
|
||||
switch strings.ToLower(params[0]) {
|
||||
case "pass", "password":
|
||||
nsNotice(rb, client.t("To change a password, use the PASSWD command. For details, /msg NickServ HELP PASSWD"))
|
||||
service.Notice(rb, client.t("To change a password, use the PASSWD command. For details, /msg NickServ HELP PASSWD"))
|
||||
return
|
||||
case "enforce":
|
||||
var method NickEnforcementMethod
|
||||
@ -612,19 +601,19 @@ func nsSetHandler(server *Server, client *Client, command string, params []strin
|
||||
|
||||
switch err {
|
||||
case nil:
|
||||
nsNotice(rb, client.t("Successfully changed your account settings"))
|
||||
displaySetting(params[0], finalSettings, client, rb)
|
||||
service.Notice(rb, client.t("Successfully changed your account settings"))
|
||||
displaySetting(service, params[0], finalSettings, client, rb)
|
||||
case errInvalidParams, errAccountDoesNotExist, errFeatureDisabled, errAccountUnverified, errAccountUpdateFailed:
|
||||
nsNotice(rb, client.t(err.Error()))
|
||||
service.Notice(rb, client.t(err.Error()))
|
||||
case errNickAccountMismatch:
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Your nickname must match your account name %s exactly to modify this setting. Try changing it with /NICK, or logging out and back in with the correct nickname."), client.AccountName()))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Your nickname must match your account name %s exactly to modify this setting. Try changing it with /NICK, or logging out and back in with the correct nickname."), client.AccountName()))
|
||||
default:
|
||||
// unknown error
|
||||
nsNotice(rb, client.t("An error occurred"))
|
||||
service.Notice(rb, client.t("An error occurred"))
|
||||
}
|
||||
}
|
||||
|
||||
func nsDropHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsDropHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
sadrop := command == "sadrop"
|
||||
var nick string
|
||||
if len(params) > 0 {
|
||||
@ -635,28 +624,28 @@ func nsDropHandler(server *Server, client *Client, command string, params []stri
|
||||
|
||||
err := server.accounts.SetNickReserved(client, nick, sadrop, false)
|
||||
if err == nil {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Successfully ungrouped nick %s with your account"), nick))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Successfully ungrouped nick %s with your account"), nick))
|
||||
} else if err == errAccountNotLoggedIn {
|
||||
nsNotice(rb, client.t("You're not logged into an account"))
|
||||
service.Notice(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)"))
|
||||
service.Notice(rb, client.t("You can't ungroup your primary nickname (try unregistering your account instead)"))
|
||||
} else {
|
||||
nsNotice(rb, client.t("Could not ungroup nick"))
|
||||
service.Notice(rb, client.t("Could not ungroup nick"))
|
||||
}
|
||||
}
|
||||
|
||||
func nsGhostHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsGhostHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
nick := params[0]
|
||||
|
||||
ghost := server.clients.Get(nick)
|
||||
if ghost == nil {
|
||||
nsNotice(rb, client.t("No such nick"))
|
||||
service.Notice(rb, client.t("No such nick"))
|
||||
return
|
||||
} else if ghost == client {
|
||||
nsNotice(rb, client.t("You can't GHOST yourself (try /QUIT instead)"))
|
||||
service.Notice(rb, client.t("You can't GHOST yourself (try /QUIT instead)"))
|
||||
return
|
||||
} else if ghost.AlwaysOn() {
|
||||
nsNotice(rb, client.t("You can't GHOST an always-on client"))
|
||||
service.Notice(rb, client.t("You can't GHOST an always-on client"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -667,7 +656,7 @@ func nsGhostHandler(server *Server, client *Client, command string, params []str
|
||||
authorized = (server.accounts.NickToAccount(nick) == account) || (ghost.Account() == account)
|
||||
}
|
||||
if !authorized {
|
||||
nsNotice(rb, client.t("You don't own that nick"))
|
||||
service.Notice(rb, client.t("You don't own that nick"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -675,31 +664,31 @@ func nsGhostHandler(server *Server, client *Client, command string, params []str
|
||||
ghost.destroy(nil)
|
||||
}
|
||||
|
||||
func nsGroupHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsGroupHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
nick := client.Nick()
|
||||
err := server.accounts.SetNickReserved(client, nick, false, true)
|
||||
if err == nil {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Successfully grouped nick %s with your account"), nick))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Successfully grouped nick %s with your account"), nick))
|
||||
} else if err == errAccountTooManyNicks {
|
||||
nsNotice(rb, client.t("You have too many nicks reserved already (you can remove some with /NS DROP)"))
|
||||
service.Notice(rb, client.t("You have too many nicks reserved already (you can remove some with /NS DROP)"))
|
||||
} else if err == errNicknameReserved {
|
||||
nsNotice(rb, client.t("That nickname is already reserved by someone else"))
|
||||
service.Notice(rb, client.t("That nickname is already reserved by someone else"))
|
||||
} else {
|
||||
nsNotice(rb, client.t("Error reserving nickname"))
|
||||
service.Notice(rb, client.t("Error reserving nickname"))
|
||||
}
|
||||
}
|
||||
|
||||
func nsLoginThrottleCheck(client *Client, rb *ResponseBuffer) (success bool) {
|
||||
func nsLoginThrottleCheck(service *ircService, client *Client, rb *ResponseBuffer) (success bool) {
|
||||
throttled, remainingTime := client.checkLoginThrottle()
|
||||
if throttled {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Please wait at least %v and try again"), remainingTime))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Please wait at least %v and try again"), remainingTime))
|
||||
}
|
||||
return !throttled
|
||||
}
|
||||
|
||||
func nsIdentifyHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsIdentifyHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
if client.LoggedIntoAccount() {
|
||||
nsNotice(rb, client.t("You're already logged into an account"))
|
||||
service.Notice(rb, client.t("You're already logged into an account"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -735,7 +724,7 @@ func nsIdentifyHandler(server *Server, client *Client, command string, params []
|
||||
|
||||
nickFixupFailed := false
|
||||
if loginSuccessful {
|
||||
if !fixupNickEqualsAccount(client, rb, server.Config()) {
|
||||
if !fixupNickEqualsAccount(client, rb, server.Config(), service.prefix) {
|
||||
loginSuccessful = false
|
||||
// fixupNickEqualsAccount sends its own error message, don't send another
|
||||
nickFixupFailed = true
|
||||
@ -743,15 +732,15 @@ func nsIdentifyHandler(server *Server, client *Client, command string, params []
|
||||
}
|
||||
|
||||
if loginSuccessful {
|
||||
sendSuccessfulAccountAuth(client, rb, true, true)
|
||||
sendSuccessfulAccountAuth(service, client, rb, true)
|
||||
} else if !nickFixupFailed {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Authentication failed: %s"), authErrorToMessage(server, err)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Authentication failed: %s"), authErrorToMessage(server, err)))
|
||||
}
|
||||
}
|
||||
|
||||
func nsListHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsListHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
if !client.HasRoleCapabs("accreg") {
|
||||
nsNotice(rb, client.t("Insufficient privileges"))
|
||||
service.Notice(rb, client.t("Insufficient privileges"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -760,26 +749,26 @@ func nsListHandler(server *Server, client *Client, command string, params []stri
|
||||
var err error
|
||||
searchRegex, err = regexp.Compile(params[0])
|
||||
if err != nil {
|
||||
nsNotice(rb, client.t("Invalid regex"))
|
||||
service.Notice(rb, client.t("Invalid regex"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
nsNotice(rb, ircfmt.Unescape(client.t("*** $bNickServ LIST$b ***")))
|
||||
service.Notice(rb, ircfmt.Unescape(client.t("*** $bNickServ LIST$b ***")))
|
||||
|
||||
nicks := server.accounts.AllNicks()
|
||||
for _, nick := range nicks {
|
||||
if searchRegex == nil || searchRegex.MatchString(nick) {
|
||||
nsNotice(rb, fmt.Sprintf(" %s", nick))
|
||||
service.Notice(rb, fmt.Sprintf(" %s", nick))
|
||||
}
|
||||
}
|
||||
|
||||
nsNotice(rb, ircfmt.Unescape(client.t("*** $bEnd of NickServ LIST$b ***")))
|
||||
service.Notice(rb, ircfmt.Unescape(client.t("*** $bEnd of NickServ LIST$b ***")))
|
||||
}
|
||||
|
||||
func nsInfoHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsInfoHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
if !server.Config().Accounts.AuthenticationEnabled && !client.HasRoleCapabs("accreg") {
|
||||
nsNotice(rb, client.t("This command has been disabled by the server administrators"))
|
||||
service.Notice(rb, client.t("This command has been disabled by the server administrators"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -789,7 +778,7 @@ func nsInfoHandler(server *Server, client *Client, command string, params []stri
|
||||
if server.Config().Accounts.NickReservation.Enabled {
|
||||
accountName = server.accounts.NickToAccount(nick)
|
||||
if accountName == "" {
|
||||
nsNotice(rb, client.t("That nickname is not registered"))
|
||||
service.Notice(rb, client.t("That nickname is not registered"))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
@ -798,33 +787,33 @@ func nsInfoHandler(server *Server, client *Client, command string, params []stri
|
||||
} else {
|
||||
accountName = client.Account()
|
||||
if accountName == "" {
|
||||
nsNotice(rb, client.t("You're not logged into an account"))
|
||||
service.Notice(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"))
|
||||
service.Notice(rb, client.t("Account does not exist"))
|
||||
return
|
||||
}
|
||||
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Account: %s"), account.Name))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Account: %s"), account.Name))
|
||||
registeredAt := account.RegisteredAt.Format(time.RFC1123)
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Registered at: %s"), registeredAt))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Registered at: %s"), registeredAt))
|
||||
// TODO nicer formatting for this
|
||||
for _, nick := range account.AdditionalNicks {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Additional grouped nick: %s"), nick))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Additional grouped nick: %s"), nick))
|
||||
}
|
||||
for _, channel := range server.accounts.ChannelsForAccount(accountName) {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Registered channel: %s"), channel))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Registered channel: %s"), channel))
|
||||
}
|
||||
if account.Suspended != nil {
|
||||
nsNotice(rb, suspensionToString(client, *account.Suspended))
|
||||
service.Notice(rb, suspensionToString(client, *account.Suspended))
|
||||
}
|
||||
}
|
||||
|
||||
func nsRegisterHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsRegisterHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
details := client.Details()
|
||||
passphrase := params[0]
|
||||
var email string
|
||||
@ -835,7 +824,7 @@ func nsRegisterHandler(server *Server, client *Client, command string, params []
|
||||
certfp := rb.session.certfp
|
||||
if passphrase == "*" {
|
||||
if certfp == "" {
|
||||
nsNotice(rb, client.t("You must be connected with TLS and a client certificate to do this"))
|
||||
service.Notice(rb, client.t("You must be connected with TLS and a client certificate to do this"))
|
||||
return
|
||||
} else {
|
||||
passphrase = ""
|
||||
@ -845,12 +834,12 @@ func nsRegisterHandler(server *Server, client *Client, command string, params []
|
||||
if passphrase != "" {
|
||||
cfPassphrase, err := Casefold(passphrase)
|
||||
if err == nil && cfPassphrase == details.nickCasefolded {
|
||||
nsNotice(rb, client.t("Usage: REGISTER <passphrase> [email]")) // #1179
|
||||
service.Notice(rb, client.t("Usage: REGISTER <passphrase> [email]")) // #1179
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if !nsLoginThrottleCheck(client, rb) {
|
||||
if !nsLoginThrottleCheck(service, client, rb) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -859,7 +848,7 @@ func nsRegisterHandler(server *Server, client *Client, command string, params []
|
||||
if config.Accounts.NickReservation.ForceGuestFormat {
|
||||
matches := config.Accounts.NickReservation.guestRegexp.FindStringSubmatch(account)
|
||||
if matches == nil || len(matches) < 2 {
|
||||
nsNotice(rb, client.t("Erroneous nickname"))
|
||||
service.Notice(rb, client.t("Erroneous nickname"))
|
||||
return
|
||||
}
|
||||
account = matches[1]
|
||||
@ -867,7 +856,7 @@ func nsRegisterHandler(server *Server, client *Client, command string, params []
|
||||
|
||||
callbackNamespace, callbackValue, validationErr := parseCallback(email, config)
|
||||
if validationErr != nil {
|
||||
nsNotice(rb, client.t("Registration requires a valid e-mail address"))
|
||||
service.Notice(rb, client.t("Registration requires a valid e-mail address"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -875,22 +864,22 @@ func nsRegisterHandler(server *Server, client *Client, command string, params []
|
||||
if err == nil {
|
||||
if callbackNamespace == "*" {
|
||||
err = server.accounts.Verify(client, account, "")
|
||||
if err == nil && fixupNickEqualsAccount(client, rb, config) {
|
||||
sendSuccessfulRegResponse(client, rb, true)
|
||||
if err == nil && fixupNickEqualsAccount(client, rb, config, service.prefix) {
|
||||
sendSuccessfulRegResponse(service, client, rb)
|
||||
}
|
||||
} else {
|
||||
messageTemplate := client.t("Account created, pending verification; verification code has been sent to %s")
|
||||
message := fmt.Sprintf(messageTemplate, callbackValue)
|
||||
nsNotice(rb, message)
|
||||
service.Notice(rb, message)
|
||||
}
|
||||
} else {
|
||||
// details could not be stored and relevant numerics have been dispatched, abort
|
||||
message := registrationErrorToMessage(err)
|
||||
nsNotice(rb, client.t(message))
|
||||
service.Notice(rb, client.t(message))
|
||||
}
|
||||
}
|
||||
|
||||
func nsSaregisterHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsSaregisterHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
var account, passphrase string
|
||||
account = params[0]
|
||||
if 1 < len(params) && params[1] != "*" {
|
||||
@ -908,14 +897,14 @@ func nsSaregisterHandler(server *Server, client *Client, command string, params
|
||||
server.logger.Error("services", "unknown error from saregister", err.Error())
|
||||
errMsg = client.t("Could not register")
|
||||
}
|
||||
nsNotice(rb, errMsg)
|
||||
service.Notice(rb, errMsg)
|
||||
} else {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Successfully registered account %s"), account))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Successfully registered account %s"), account))
|
||||
server.snomasks.Send(sno.LocalAccounts, fmt.Sprintf(ircfmt.Unescape("Operator $c[grey][$r%s$c[grey]] registered account $c[grey][$r%s$c[grey]] with SAREGISTER"), client.Oper().Name, account))
|
||||
}
|
||||
}
|
||||
|
||||
func nsUnregisterHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsUnregisterHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
erase := command == "erase"
|
||||
|
||||
username := params[0]
|
||||
@ -925,7 +914,7 @@ func nsUnregisterHandler(server *Server, client *Client, command string, params
|
||||
}
|
||||
|
||||
if username == "" {
|
||||
nsNotice(rb, client.t("You must specify an account"))
|
||||
service.Notice(rb, client.t("You must specify an account"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -939,10 +928,10 @@ func nsUnregisterHandler(server *Server, client *Client, command string, params
|
||||
} else {
|
||||
account, err := server.accounts.LoadAccount(username)
|
||||
if err == errAccountDoesNotExist {
|
||||
nsNotice(rb, client.t("Invalid account name"))
|
||||
service.Notice(rb, client.t("Invalid account name"))
|
||||
return
|
||||
} else if err != nil {
|
||||
nsNotice(rb, client.t("Internal error"))
|
||||
service.Notice(rb, client.t("Internal error"))
|
||||
return
|
||||
}
|
||||
accountName = account.Name
|
||||
@ -950,34 +939,34 @@ func nsUnregisterHandler(server *Server, client *Client, command string, params
|
||||
}
|
||||
|
||||
if !(accountName == client.AccountName() || client.HasRoleCapabs("accreg")) {
|
||||
nsNotice(rb, client.t("Insufficient oper privs"))
|
||||
service.Notice(rb, client.t("Insufficient oper privs"))
|
||||
return
|
||||
}
|
||||
|
||||
expectedCode := utils.ConfirmationCode(accountName, registeredAt)
|
||||
if expectedCode != verificationCode {
|
||||
if erase {
|
||||
nsNotice(rb, ircfmt.Unescape(client.t("$bWarning: erasing this account will allow it to be re-registered; consider UNREGISTER instead.$b")))
|
||||
service.Notice(rb, ircfmt.Unescape(client.t("$bWarning: erasing this account will allow it to be re-registered; consider UNREGISTER instead.$b")))
|
||||
} else {
|
||||
nsNotice(rb, ircfmt.Unescape(client.t("$bWarning: unregistering this account will remove its stored privileges.$b")))
|
||||
service.Notice(rb, ircfmt.Unescape(client.t("$bWarning: unregistering this account will remove its stored privileges.$b")))
|
||||
}
|
||||
nsNotice(rb, fmt.Sprintf(client.t("To confirm, run this command: %s"), fmt.Sprintf("/NS %s %s %s", strings.ToUpper(command), accountName, expectedCode)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("To confirm, run this command: %s"), fmt.Sprintf("/NS %s %s %s", strings.ToUpper(command), accountName, expectedCode)))
|
||||
return
|
||||
}
|
||||
|
||||
err := server.accounts.Unregister(accountName, erase)
|
||||
if err == errAccountDoesNotExist {
|
||||
nsNotice(rb, client.t(err.Error()))
|
||||
service.Notice(rb, client.t(err.Error()))
|
||||
} else if err != nil {
|
||||
nsNotice(rb, client.t("Error while unregistering account"))
|
||||
service.Notice(rb, client.t("Error while unregistering account"))
|
||||
} else {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Successfully unregistered account %s"), accountName))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Successfully unregistered account %s"), accountName))
|
||||
server.logger.Info("accounts", "client", client.Nick(), "unregistered account", accountName)
|
||||
client.server.snomasks.Send(sno.LocalAccounts, fmt.Sprintf(ircfmt.Unescape("Client $c[grey][$r%s$c[grey]] unregistered account $c[grey][$r%s$c[grey]]"), client.NickMaskString(), accountName))
|
||||
}
|
||||
}
|
||||
|
||||
func nsVerifyHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsVerifyHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
username, code := params[0], params[1]
|
||||
err := server.accounts.Verify(client, username, code)
|
||||
|
||||
@ -992,16 +981,16 @@ func nsVerifyHandler(server *Server, client *Client, command string, params []st
|
||||
}
|
||||
|
||||
if errorMessage != "" {
|
||||
nsNotice(rb, client.t(errorMessage))
|
||||
service.Notice(rb, client.t(errorMessage))
|
||||
return
|
||||
}
|
||||
|
||||
if fixupNickEqualsAccount(client, rb, server.Config()) {
|
||||
sendSuccessfulRegResponse(client, rb, true)
|
||||
if fixupNickEqualsAccount(client, rb, server.Config(), service.prefix) {
|
||||
sendSuccessfulRegResponse(service, client, rb)
|
||||
}
|
||||
}
|
||||
|
||||
func nsPasswdHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsPasswdHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
var target string
|
||||
var newPassword string
|
||||
var errorMessage string
|
||||
@ -1025,7 +1014,7 @@ func nsPasswdHandler(server *Server, client *Client, command string, params []st
|
||||
} else if params[1] != params[2] {
|
||||
errorMessage = `Passwords do not match`
|
||||
} else {
|
||||
if !nsLoginThrottleCheck(client, rb) {
|
||||
if !nsLoginThrottleCheck(service, client, rb) {
|
||||
return
|
||||
}
|
||||
accountData, err := server.accounts.LoadAccount(target)
|
||||
@ -1048,37 +1037,37 @@ func nsPasswdHandler(server *Server, client *Client, command string, params []st
|
||||
}
|
||||
|
||||
if errorMessage != "" {
|
||||
nsNotice(rb, client.t(errorMessage))
|
||||
service.Notice(rb, client.t(errorMessage))
|
||||
return
|
||||
}
|
||||
|
||||
err := server.accounts.setPassword(target, newPassword, hasPrivs)
|
||||
switch err {
|
||||
case nil:
|
||||
nsNotice(rb, client.t("Password changed"))
|
||||
service.Notice(rb, client.t("Password changed"))
|
||||
case errEmptyCredentials:
|
||||
nsNotice(rb, client.t("You can't delete your password unless you add a certificate fingerprint"))
|
||||
service.Notice(rb, client.t("You can't delete your password unless you add a certificate fingerprint"))
|
||||
case errCredsExternallyManaged:
|
||||
nsNotice(rb, client.t("Your account credentials are managed externally and cannot be changed here"))
|
||||
service.Notice(rb, client.t("Your account credentials are managed externally and cannot be changed here"))
|
||||
case errCASFailed:
|
||||
nsNotice(rb, client.t("Try again later"))
|
||||
service.Notice(rb, client.t("Try again later"))
|
||||
default:
|
||||
server.logger.Error("internal", "could not upgrade user password:", err.Error())
|
||||
nsNotice(rb, client.t("Password could not be changed due to server error"))
|
||||
service.Notice(rb, client.t("Password could not be changed due to server error"))
|
||||
}
|
||||
}
|
||||
|
||||
func nsEnforceHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsEnforceHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
newParams := []string{"enforce"}
|
||||
if len(params) == 0 {
|
||||
nsGetHandler(server, client, "get", newParams, rb)
|
||||
nsGetHandler(service, server, client, "get", newParams, rb)
|
||||
} else {
|
||||
newParams = append(newParams, params[0])
|
||||
nsSetHandler(server, client, "set", newParams, rb)
|
||||
nsSetHandler(service, server, client, "set", newParams, rb)
|
||||
}
|
||||
}
|
||||
|
||||
func nsClientsHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsClientsHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
var verb string
|
||||
|
||||
if command == "sessions" {
|
||||
@ -1091,56 +1080,56 @@ func nsClientsHandler(server *Server, client *Client, command string, params []s
|
||||
|
||||
switch verb {
|
||||
case "list":
|
||||
nsClientsListHandler(server, client, params, rb)
|
||||
nsClientsListHandler(service, server, client, params, rb)
|
||||
case "logout":
|
||||
nsClientsLogoutHandler(server, client, params, rb)
|
||||
nsClientsLogoutHandler(service, server, client, params, rb)
|
||||
default:
|
||||
nsNotice(rb, client.t("Invalid parameters"))
|
||||
service.Notice(rb, client.t("Invalid parameters"))
|
||||
}
|
||||
}
|
||||
|
||||
func nsClientsListHandler(server *Server, client *Client, params []string, rb *ResponseBuffer) {
|
||||
func nsClientsListHandler(service *ircService, server *Server, client *Client, params []string, rb *ResponseBuffer) {
|
||||
target := client
|
||||
hasPrivs := client.HasRoleCapabs("local_ban")
|
||||
if 0 < len(params) {
|
||||
target = server.clients.Get(params[0])
|
||||
if target == nil {
|
||||
nsNotice(rb, client.t("No such nick"))
|
||||
service.Notice(rb, client.t("No such nick"))
|
||||
return
|
||||
}
|
||||
if target != client && !hasPrivs {
|
||||
nsNotice(rb, client.t("Command restricted"))
|
||||
service.Notice(rb, client.t("Command restricted"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
sessionData, currentIndex := target.AllSessionData(rb.session, hasPrivs)
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Nickname %[1]s has %[2]d attached clients(s)"), target.Nick(), len(sessionData)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Nickname %[1]s has %[2]d attached clients(s)"), target.Nick(), len(sessionData)))
|
||||
for i, session := range sessionData {
|
||||
if currentIndex == i {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Client %d (currently attached client):"), session.sessionID))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Client %d (currently attached client):"), session.sessionID))
|
||||
} else {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Client %d:"), session.sessionID))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Client %d:"), session.sessionID))
|
||||
}
|
||||
if session.deviceID != "" {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Device ID: %s"), session.deviceID))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Device ID: %s"), session.deviceID))
|
||||
}
|
||||
nsNotice(rb, fmt.Sprintf(client.t("IP address: %s"), session.ip.String()))
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Hostname: %s"), session.hostname))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("IP address: %s"), session.ip.String()))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Hostname: %s"), session.hostname))
|
||||
if hasPrivs {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Connection: %s"), session.connInfo))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Connection: %s"), session.connInfo))
|
||||
}
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Created at: %s"), session.ctime.Format(time.RFC1123)))
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Last active: %s"), session.atime.Format(time.RFC1123)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Created at: %s"), session.ctime.Format(time.RFC1123)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Last active: %s"), session.atime.Format(time.RFC1123)))
|
||||
if session.certfp != "" {
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Certfp: %s"), session.certfp))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Certfp: %s"), session.certfp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func nsClientsLogoutHandler(server *Server, client *Client, params []string, rb *ResponseBuffer) {
|
||||
func nsClientsLogoutHandler(service *ircService, server *Server, client *Client, params []string, rb *ResponseBuffer) {
|
||||
if len(params) < 1 {
|
||||
nsNotice(rb, client.t("Missing client ID to logout (or \"all\")"))
|
||||
service.Notice(rb, client.t("Missing client ID to logout (or \"all\")"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -1149,14 +1138,14 @@ func nsClientsLogoutHandler(server *Server, client *Client, params []string, rb
|
||||
// CLIENTS LOGOUT [nickname] [client ID]
|
||||
target = server.clients.Get(params[0])
|
||||
if target == nil {
|
||||
nsNotice(rb, client.t("No such nick"))
|
||||
service.Notice(rb, client.t("No such nick"))
|
||||
return
|
||||
}
|
||||
// User must have "local_kill" privileges to logout other user sessions.
|
||||
if target != client {
|
||||
oper := client.Oper()
|
||||
if oper == nil || !oper.Class.Capabilities.Has("local_kill") {
|
||||
nsNotice(rb, client.t("Insufficient oper privs"))
|
||||
service.Notice(rb, client.t("Insufficient oper privs"))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -1167,7 +1156,7 @@ func nsClientsLogoutHandler(server *Server, client *Client, params []string, rb
|
||||
if strings.ToLower(params[0]) != "all" {
|
||||
sessionID, err := strconv.ParseInt(params[0], 10, 64)
|
||||
if err != nil {
|
||||
nsNotice(rb, client.t("Client ID to logout should be an integer (or \"all\")"))
|
||||
service.Notice(rb, client.t("Client ID to logout should be an integer (or \"all\")"))
|
||||
return
|
||||
}
|
||||
// Find the client ID that the user requested to logout.
|
||||
@ -1178,7 +1167,7 @@ func nsClientsLogoutHandler(server *Server, client *Client, params []string, rb
|
||||
}
|
||||
}
|
||||
if sessionToDestroy == nil {
|
||||
nsNotice(rb, client.t("Specified client ID does not exist"))
|
||||
service.Notice(rb, client.t("Specified client ID does not exist"))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -1186,14 +1175,14 @@ func nsClientsLogoutHandler(server *Server, client *Client, params []string, rb
|
||||
target.destroy(sessionToDestroy)
|
||||
if (sessionToDestroy != nil && rb.session != sessionToDestroy) || client != target {
|
||||
if sessionToDestroy != nil {
|
||||
nsNotice(rb, client.t("Successfully logged out session"))
|
||||
service.Notice(rb, client.t("Successfully logged out session"))
|
||||
} else {
|
||||
nsNotice(rb, client.t("Successfully logged out all sessions"))
|
||||
service.Notice(rb, client.t("Successfully logged out all sessions"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func nsCertHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsCertHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
verb := strings.ToLower(params[0])
|
||||
params = params[1:]
|
||||
var target, certfp string
|
||||
@ -1211,22 +1200,22 @@ func nsCertHandler(server *Server, client *Client, command string, params []stri
|
||||
} else if len(params) == 0 && verb == "add" && rb.session.certfp != "" {
|
||||
certfp = rb.session.certfp // #1059
|
||||
} else {
|
||||
nsNotice(rb, client.t("Invalid parameters"))
|
||||
service.Notice(rb, client.t("Invalid parameters"))
|
||||
return
|
||||
}
|
||||
default:
|
||||
nsNotice(rb, client.t("Invalid parameters"))
|
||||
service.Notice(rb, client.t("Invalid parameters"))
|
||||
return
|
||||
}
|
||||
|
||||
hasPrivs := client.HasRoleCapabs("accreg")
|
||||
if target != "" && !hasPrivs {
|
||||
nsNotice(rb, client.t("Insufficient privileges"))
|
||||
service.Notice(rb, client.t("Insufficient privileges"))
|
||||
return
|
||||
} else if target == "" {
|
||||
target = client.Account()
|
||||
if target == "" {
|
||||
nsNotice(rb, client.t("You're not logged into an account"))
|
||||
service.Notice(rb, client.t("You're not logged into an account"))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -1236,16 +1225,16 @@ func nsCertHandler(server *Server, client *Client, command string, params []stri
|
||||
case "list":
|
||||
accountData, err := server.accounts.LoadAccount(target)
|
||||
if err == errAccountDoesNotExist {
|
||||
nsNotice(rb, client.t("Account does not exist"))
|
||||
service.Notice(rb, client.t("Account does not exist"))
|
||||
return
|
||||
} else if err != nil {
|
||||
nsNotice(rb, client.t("An error occurred"))
|
||||
service.Notice(rb, client.t("An error occurred"))
|
||||
return
|
||||
}
|
||||
certfps := accountData.Credentials.Certfps
|
||||
nsNotice(rb, fmt.Sprintf(client.t("There are %[1]d certificate fingerprint(s) authorized for account %[2]s."), len(certfps), accountData.Name))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("There are %[1]d certificate fingerprint(s) authorized for account %[2]s."), len(certfps), accountData.Name))
|
||||
for i, certfp := range certfps {
|
||||
nsNotice(rb, fmt.Sprintf("%d: %s", i+1, certfp))
|
||||
service.Notice(rb, fmt.Sprintf("%d: %s", i+1, certfp))
|
||||
}
|
||||
return
|
||||
case "add":
|
||||
@ -1257,54 +1246,54 @@ func nsCertHandler(server *Server, client *Client, command string, params []stri
|
||||
switch err {
|
||||
case nil:
|
||||
if verb == "add" {
|
||||
nsNotice(rb, client.t("Certificate fingerprint successfully added"))
|
||||
service.Notice(rb, client.t("Certificate fingerprint successfully added"))
|
||||
} else {
|
||||
nsNotice(rb, client.t("Certificate fingerprint successfully removed"))
|
||||
service.Notice(rb, client.t("Certificate fingerprint successfully removed"))
|
||||
}
|
||||
case errNoop:
|
||||
if verb == "add" {
|
||||
nsNotice(rb, client.t("That certificate fingerprint was already authorized"))
|
||||
service.Notice(rb, client.t("That certificate fingerprint was already authorized"))
|
||||
} else {
|
||||
nsNotice(rb, client.t("Certificate fingerprint not found"))
|
||||
service.Notice(rb, client.t("Certificate fingerprint not found"))
|
||||
}
|
||||
case errAccountDoesNotExist:
|
||||
nsNotice(rb, client.t("Account does not exist"))
|
||||
service.Notice(rb, client.t("Account does not exist"))
|
||||
case errLimitExceeded:
|
||||
nsNotice(rb, client.t("You already have too many certificate fingerprints"))
|
||||
service.Notice(rb, client.t("You already have too many certificate fingerprints"))
|
||||
case utils.ErrInvalidCertfp:
|
||||
nsNotice(rb, client.t("Invalid certificate fingerprint"))
|
||||
service.Notice(rb, client.t("Invalid certificate fingerprint"))
|
||||
case errCertfpAlreadyExists:
|
||||
nsNotice(rb, client.t("That certificate fingerprint is already associated with another account"))
|
||||
service.Notice(rb, client.t("That certificate fingerprint is already associated with another account"))
|
||||
case errEmptyCredentials:
|
||||
nsNotice(rb, client.t("You can't remove all your certificate fingerprints unless you add a password"))
|
||||
service.Notice(rb, client.t("You can't remove all your certificate fingerprints unless you add a password"))
|
||||
case errCredsExternallyManaged:
|
||||
nsNotice(rb, client.t("Your account credentials are managed externally and cannot be changed here"))
|
||||
service.Notice(rb, client.t("Your account credentials are managed externally and cannot be changed here"))
|
||||
case errCASFailed:
|
||||
nsNotice(rb, client.t("Try again later"))
|
||||
service.Notice(rb, client.t("Try again later"))
|
||||
default:
|
||||
server.logger.Error("internal", "could not modify certificates:", err.Error())
|
||||
nsNotice(rb, client.t("An error occurred"))
|
||||
service.Notice(rb, client.t("An error occurred"))
|
||||
}
|
||||
}
|
||||
|
||||
func nsSuspendHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsSuspendHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
subCmd := strings.ToLower(params[0])
|
||||
params = params[1:]
|
||||
switch subCmd {
|
||||
case "add":
|
||||
nsSuspendAddHandler(server, client, command, params, rb)
|
||||
nsSuspendAddHandler(service, server, client, command, params, rb)
|
||||
case "del", "delete", "remove":
|
||||
nsSuspendRemoveHandler(server, client, command, params, rb)
|
||||
nsSuspendRemoveHandler(service, server, client, command, params, rb)
|
||||
case "list":
|
||||
nsSuspendListHandler(server, client, command, params, rb)
|
||||
nsSuspendListHandler(service, server, client, command, params, rb)
|
||||
default:
|
||||
nsNotice(rb, client.t("Invalid parameters"))
|
||||
service.Notice(rb, client.t("Invalid parameters"))
|
||||
}
|
||||
}
|
||||
|
||||
func nsSuspendAddHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsSuspendAddHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
if len(params) == 0 {
|
||||
nsNotice(rb, client.t("Invalid parameters"))
|
||||
service.Notice(rb, client.t("Invalid parameters"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -1316,7 +1305,7 @@ func nsSuspendAddHandler(server *Server, client *Client, command string, params
|
||||
var err error
|
||||
cDuration, err := custime.ParseDuration(params[1])
|
||||
if err != nil {
|
||||
nsNotice(rb, client.t("Invalid time duration for NS SUSPEND"))
|
||||
service.Notice(rb, client.t("Invalid time duration for NS SUSPEND"))
|
||||
return
|
||||
}
|
||||
duration = time.Duration(cDuration)
|
||||
@ -1333,30 +1322,30 @@ func nsSuspendAddHandler(server *Server, client *Client, command string, params
|
||||
err := server.accounts.Suspend(account, duration, name, reason)
|
||||
switch err {
|
||||
case nil:
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Successfully suspended account %s"), account))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Successfully suspended account %s"), account))
|
||||
case errAccountDoesNotExist:
|
||||
nsNotice(rb, client.t("No such account"))
|
||||
service.Notice(rb, client.t("No such account"))
|
||||
default:
|
||||
nsNotice(rb, client.t("An error occurred"))
|
||||
service.Notice(rb, client.t("An error occurred"))
|
||||
}
|
||||
}
|
||||
|
||||
func nsSuspendRemoveHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsSuspendRemoveHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
if len(params) == 0 {
|
||||
nsNotice(rb, client.t("Invalid parameters"))
|
||||
service.Notice(rb, client.t("Invalid parameters"))
|
||||
return
|
||||
}
|
||||
|
||||
err := server.accounts.Unsuspend(params[0])
|
||||
switch err {
|
||||
case nil:
|
||||
nsNotice(rb, fmt.Sprintf(client.t("Successfully un-suspended account %s"), params[0]))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Successfully un-suspended account %s"), params[0]))
|
||||
case errAccountDoesNotExist:
|
||||
nsNotice(rb, client.t("No such account"))
|
||||
service.Notice(rb, client.t("No such account"))
|
||||
case errNoop:
|
||||
nsNotice(rb, client.t("Account was not suspended"))
|
||||
service.Notice(rb, client.t("Account was not suspended"))
|
||||
default:
|
||||
nsNotice(rb, client.t("An error occurred"))
|
||||
service.Notice(rb, client.t("An error occurred"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1367,12 +1356,12 @@ func (a ByCreationTime) Len() int { return len(a) }
|
||||
func (a ByCreationTime) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a ByCreationTime) Less(i, j int) bool { return a[i].TimeCreated.After(a[j].TimeCreated) }
|
||||
|
||||
func nsSuspendListHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsSuspendListHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
suspensions := server.accounts.ListSuspended()
|
||||
sort.Sort(ByCreationTime(suspensions))
|
||||
nsNotice(rb, fmt.Sprintf(client.t("There are %d active suspensions."), len(suspensions)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("There are %d active suspensions."), len(suspensions)))
|
||||
for _, suspension := range suspensions {
|
||||
nsNotice(rb, suspensionToString(client, suspension))
|
||||
service.Notice(rb, suspensionToString(client, suspension))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1389,21 +1378,21 @@ 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)
|
||||
}
|
||||
|
||||
func nsRenameHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
func nsRenameHandler(service *ircService, 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())))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Couldn't rename account: %s"), client.t(err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
nsNotice(rb, client.t("Successfully renamed account"))
|
||||
service.Notice(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))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Warning: could not rename affected client: %v"), err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -530,6 +530,8 @@ func (server *Server) applyConfig(config *Config) (err error) {
|
||||
} else if oldConfig.Server.IPCheckScript.MaxConcurrency != config.Server.IPCheckScript.MaxConcurrency ||
|
||||
oldConfig.Accounts.AuthScript.MaxConcurrency != config.Accounts.AuthScript.MaxConcurrency {
|
||||
return fmt.Errorf("Cannot change max-concurrency for scripts after launching the server, rehash aborted")
|
||||
} else if oldConfig.Server.OverrideServicesHostname != config.Server.OverrideServicesHostname {
|
||||
return fmt.Errorf("Cannot change override-services-hostname after launching the server, rehash aborted")
|
||||
}
|
||||
}
|
||||
|
||||
@ -563,6 +565,10 @@ func (server *Server) applyConfig(config *Config) (err error) {
|
||||
if maxAuthConc != 0 {
|
||||
server.semaphores.AuthScript.Initialize(maxAuthConc)
|
||||
}
|
||||
|
||||
if err := overrideServicePrefixes(config.Server.OverrideServicesHostname); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if oldConfig != nil {
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
type ircService struct {
|
||||
Name string
|
||||
ShortName string
|
||||
prefix string
|
||||
prefix string // NUH source of messages from this service
|
||||
CommandAliases []string
|
||||
Commands map[string]*serviceCommand
|
||||
HelpBanner string
|
||||
@ -30,7 +30,7 @@ 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 string, params []string, rb *ResponseBuffer)
|
||||
handler func(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer)
|
||||
help string
|
||||
helpStrings []string
|
||||
helpShort string
|
||||
@ -60,36 +60,47 @@ func lookupServiceCommand(commands map[string]*serviceCommand, command string) *
|
||||
return nil
|
||||
}
|
||||
|
||||
// all services, by lowercase name
|
||||
var OragonoServices = map[string]*ircService{
|
||||
"nickserv": {
|
||||
var (
|
||||
nickservService = &ircService{
|
||||
Name: "NickServ",
|
||||
ShortName: "NS",
|
||||
CommandAliases: []string{"NICKSERV", "NS"},
|
||||
Commands: nickservCommands,
|
||||
HelpBanner: nickservHelp,
|
||||
},
|
||||
"chanserv": {
|
||||
}
|
||||
chanservService = &ircService{
|
||||
Name: "ChanServ",
|
||||
ShortName: "CS",
|
||||
CommandAliases: []string{"CHANSERV", "CS"},
|
||||
Commands: chanservCommands,
|
||||
HelpBanner: chanservHelp,
|
||||
},
|
||||
"hostserv": {
|
||||
}
|
||||
hostservService = &ircService{
|
||||
Name: "HostServ",
|
||||
ShortName: "HS",
|
||||
CommandAliases: []string{"HOSTSERV", "HS"},
|
||||
Commands: hostservCommands,
|
||||
HelpBanner: hostservHelp,
|
||||
},
|
||||
"histserv": {
|
||||
}
|
||||
histservService = &ircService{
|
||||
Name: "HistServ",
|
||||
ShortName: "HISTSERV",
|
||||
CommandAliases: []string{"HISTSERV"},
|
||||
Commands: histservCommands,
|
||||
HelpBanner: histservHelp,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// all services, by lowercase name
|
||||
var OragonoServices = map[string]*ircService{
|
||||
"nickserv": nickservService,
|
||||
"chanserv": chanservService,
|
||||
"hostserv": hostservService,
|
||||
"histserv": histservService,
|
||||
}
|
||||
|
||||
func (service *ircService) Notice(rb *ResponseBuffer, text string) {
|
||||
rb.Add(nil, service.prefix, "NOTICE", rb.target.Nick(), text)
|
||||
}
|
||||
|
||||
// all service commands at the protocol level, by uppercase command name
|
||||
@ -212,7 +223,7 @@ func serviceRunCommand(service *ircService, server *Server, client *Client, cmd
|
||||
if commandName == "help" {
|
||||
serviceHelpHandler(service, server, client, params, rb)
|
||||
} else {
|
||||
cmd.handler(server, client, commandName, params, rb)
|
||||
cmd.handler(service, server, client, commandName, params, rb)
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,6 +316,19 @@ func makeServiceHelpTextGenerator(cmd string, banner string) func(*Client) strin
|
||||
}
|
||||
}
|
||||
|
||||
func overrideServicePrefixes(hostname string) error {
|
||||
if hostname == "" {
|
||||
return nil
|
||||
}
|
||||
if !utils.IsHostname(hostname) {
|
||||
return fmt.Errorf("`%s` is an invalid services hostname", hostname)
|
||||
}
|
||||
for _, serv := range OragonoServices {
|
||||
serv.prefix = fmt.Sprintf("%s!%s@%s", serv.Name, serv.Name, hostname)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func initializeServices() {
|
||||
// this modifies the global Commands map,
|
||||
// so it must be called from irc/commands.go's init()
|
||||
|
@ -309,6 +309,10 @@ server:
|
||||
# to the working directory. set this to customize:
|
||||
#output-path: "/home/oragono/out"
|
||||
|
||||
# the hostname used by "services", e.g., NickServ, defaults to "localhost",
|
||||
# e.g., `NickServ!NickServ@localhost`. uncomment this to override:
|
||||
#override-services-hostname: "example.network"
|
||||
|
||||
# account options
|
||||
accounts:
|
||||
# is account authentication enabled, i.e., can users log into existing accounts?
|
||||
|
Loading…
Reference in New Issue
Block a user