mirror of
https://github.com/ergochat/ergo.git
synced 2025-12-20 02:00:11 -08:00
Centralise all command handlers in handlers.go
This commit is contained in:
parent
29266ce80f
commit
47d2ce351c
16 changed files with 2629 additions and 2661 deletions
271
irc/dline.go
271
irc/dline.go
|
|
@ -7,18 +7,11 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"strings"
|
||||
|
||||
"encoding/json"
|
||||
|
||||
"github.com/goshuirc/irc-go/ircfmt"
|
||||
"github.com/goshuirc/irc-go/ircmsg"
|
||||
"github.com/oragono/oragono/irc/custime"
|
||||
"github.com/oragono/oragono/irc/sno"
|
||||
"github.com/tidwall/buntdb"
|
||||
)
|
||||
|
||||
|
|
@ -216,270 +209,6 @@ func (dm *DLineManager) CheckIP(addr net.IP) (isBanned bool, info *IPBanInfo) {
|
|||
return false, nil
|
||||
}
|
||||
|
||||
// DLINE [ANDKILL] [MYSELF] [duration] <ip>/<net> [ON <server>] [reason [| oper reason]]
|
||||
// DLINE LIST
|
||||
func dlineHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||
// check oper permissions
|
||||
if !client.class.Capabilities["oper:local_ban"] {
|
||||
client.Send(nil, server.name, ERR_NOPRIVS, client.nick, msg.Command, client.t("Insufficient oper privs"))
|
||||
return false
|
||||
}
|
||||
|
||||
currentArg := 0
|
||||
|
||||
// if they say LIST, we just list the current dlines
|
||||
if len(msg.Params) == currentArg+1 && strings.ToLower(msg.Params[currentArg]) == "list" {
|
||||
bans := server.dlines.AllBans()
|
||||
|
||||
if len(bans) == 0 {
|
||||
client.Notice(client.t("No DLINEs have been set!"))
|
||||
}
|
||||
|
||||
for key, info := range bans {
|
||||
client.Notice(fmt.Sprintf(client.t("Ban - %[1]s - added by %[2]s - %[3]s"), key, info.OperName, info.BanMessage("%s")))
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// when setting a ban, if they say "ANDKILL" we should also kill all users who match it
|
||||
var andKill bool
|
||||
if len(msg.Params) > currentArg+1 && strings.ToLower(msg.Params[currentArg]) == "andkill" {
|
||||
andKill = true
|
||||
currentArg++
|
||||
}
|
||||
|
||||
// when setting a ban that covers the oper's current connection, we require them to say
|
||||
// "DLINE MYSELF" so that we're sure they really mean it.
|
||||
var dlineMyself bool
|
||||
if len(msg.Params) > currentArg+1 && strings.ToLower(msg.Params[currentArg]) == "myself" {
|
||||
dlineMyself = true
|
||||
currentArg++
|
||||
}
|
||||
|
||||
// duration
|
||||
duration, err := custime.ParseDuration(msg.Params[currentArg])
|
||||
durationIsUsed := err == nil
|
||||
if durationIsUsed {
|
||||
currentArg++
|
||||
}
|
||||
|
||||
// get host
|
||||
if len(msg.Params) < currentArg+1 {
|
||||
client.Send(nil, server.name, ERR_NEEDMOREPARAMS, client.nick, msg.Command, client.t("Not enough parameters"))
|
||||
return false
|
||||
}
|
||||
hostString := msg.Params[currentArg]
|
||||
currentArg++
|
||||
|
||||
// check host
|
||||
var hostAddr net.IP
|
||||
var hostNet *net.IPNet
|
||||
|
||||
_, hostNet, err = net.ParseCIDR(hostString)
|
||||
if err != nil {
|
||||
hostAddr = net.ParseIP(hostString)
|
||||
}
|
||||
|
||||
if hostAddr == nil && hostNet == nil {
|
||||
client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, client.t("Could not parse IP address or CIDR network"))
|
||||
return false
|
||||
}
|
||||
|
||||
if hostNet == nil {
|
||||
hostString = hostAddr.String()
|
||||
if !dlineMyself && hostAddr.Equal(client.IP()) {
|
||||
client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, client.t("This ban matches you. To DLINE yourself, you must use the command: /DLINE MYSELF <arguments>"))
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
hostString = hostNet.String()
|
||||
if !dlineMyself && hostNet.Contains(client.IP()) {
|
||||
client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, client.t("This ban matches you. To DLINE yourself, you must use the command: /DLINE MYSELF <arguments>"))
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// check remote
|
||||
if len(msg.Params) > currentArg && msg.Params[currentArg] == "ON" {
|
||||
client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, client.t("Remote servers not yet supported"))
|
||||
return false
|
||||
}
|
||||
|
||||
// get comment(s)
|
||||
reason := "No reason given"
|
||||
operReason := "No reason given"
|
||||
if len(msg.Params) > currentArg {
|
||||
tempReason := strings.TrimSpace(msg.Params[currentArg])
|
||||
if len(tempReason) > 0 && tempReason != "|" {
|
||||
tempReasons := strings.SplitN(tempReason, "|", 2)
|
||||
if tempReasons[0] != "" {
|
||||
reason = tempReasons[0]
|
||||
}
|
||||
if len(tempReasons) > 1 && tempReasons[1] != "" {
|
||||
operReason = tempReasons[1]
|
||||
} else {
|
||||
operReason = reason
|
||||
}
|
||||
}
|
||||
}
|
||||
operName := client.operName
|
||||
if operName == "" {
|
||||
operName = server.name
|
||||
}
|
||||
|
||||
// assemble ban info
|
||||
var banTime *IPRestrictTime
|
||||
if durationIsUsed {
|
||||
banTime = &IPRestrictTime{
|
||||
Duration: duration,
|
||||
Expires: time.Now().Add(duration),
|
||||
}
|
||||
}
|
||||
|
||||
info := IPBanInfo{
|
||||
Reason: reason,
|
||||
OperReason: operReason,
|
||||
OperName: operName,
|
||||
Time: banTime,
|
||||
}
|
||||
|
||||
// save in datastore
|
||||
err = server.store.Update(func(tx *buntdb.Tx) error {
|
||||
dlineKey := fmt.Sprintf(keyDlineEntry, hostString)
|
||||
|
||||
// assemble json from ban info
|
||||
b, err := json.Marshal(info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx.Set(dlineKey, string(b), nil)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
client.Notice(fmt.Sprintf(client.t("Could not successfully save new D-LINE: %s"), err.Error()))
|
||||
return false
|
||||
}
|
||||
|
||||
if hostNet == nil {
|
||||
server.dlines.AddIP(hostAddr, banTime, reason, operReason, operName)
|
||||
} else {
|
||||
server.dlines.AddNetwork(*hostNet, banTime, reason, operReason, operName)
|
||||
}
|
||||
|
||||
var snoDescription string
|
||||
if durationIsUsed {
|
||||
client.Notice(fmt.Sprintf(client.t("Added temporary (%[1]s) D-Line for %[2]s"), duration.String(), hostString))
|
||||
snoDescription = fmt.Sprintf(ircfmt.Unescape("%s [%s]$r added temporary (%s) D-Line for %s"), client.nick, operName, duration.String(), hostString)
|
||||
} else {
|
||||
client.Notice(fmt.Sprintf(client.t("Added D-Line for %s"), hostString))
|
||||
snoDescription = fmt.Sprintf(ircfmt.Unescape("%s [%s]$r added D-Line for %s"), client.nick, operName, hostString)
|
||||
}
|
||||
server.snomasks.Send(sno.LocalXline, snoDescription)
|
||||
|
||||
var killClient bool
|
||||
if andKill {
|
||||
var clientsToKill []*Client
|
||||
var killedClientNicks []string
|
||||
var toKill bool
|
||||
|
||||
for _, mcl := range server.clients.AllClients() {
|
||||
if hostNet == nil {
|
||||
toKill = hostAddr.Equal(mcl.IP())
|
||||
} else {
|
||||
toKill = hostNet.Contains(mcl.IP())
|
||||
}
|
||||
|
||||
if toKill {
|
||||
clientsToKill = append(clientsToKill, mcl)
|
||||
killedClientNicks = append(killedClientNicks, mcl.nick)
|
||||
}
|
||||
}
|
||||
|
||||
for _, mcl := range clientsToKill {
|
||||
mcl.exitedSnomaskSent = true
|
||||
mcl.Quit(fmt.Sprintf(mcl.t("You have been banned from this server (%s)"), reason))
|
||||
if mcl == client {
|
||||
killClient = true
|
||||
} else {
|
||||
// if mcl == client, we kill them below
|
||||
mcl.destroy(false)
|
||||
}
|
||||
}
|
||||
|
||||
// send snomask
|
||||
sort.Strings(killedClientNicks)
|
||||
server.snomasks.Send(sno.LocalKills, fmt.Sprintf(ircfmt.Unescape("%s [%s] killed %d clients with a DLINE $c[grey][$r%s$c[grey]]"), client.nick, operName, len(killedClientNicks), strings.Join(killedClientNicks, ", ")))
|
||||
}
|
||||
|
||||
return killClient
|
||||
}
|
||||
|
||||
func unDLineHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||
// check oper permissions
|
||||
if !client.class.Capabilities["oper:local_unban"] {
|
||||
client.Send(nil, server.name, ERR_NOPRIVS, client.nick, msg.Command, client.t("Insufficient oper privs"))
|
||||
return false
|
||||
}
|
||||
|
||||
// get host
|
||||
hostString := msg.Params[0]
|
||||
|
||||
// check host
|
||||
var hostAddr net.IP
|
||||
var hostNet *net.IPNet
|
||||
|
||||
_, hostNet, err := net.ParseCIDR(hostString)
|
||||
if err != nil {
|
||||
hostAddr = net.ParseIP(hostString)
|
||||
}
|
||||
|
||||
if hostAddr == nil && hostNet == nil {
|
||||
client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, client.t("Could not parse IP address or CIDR network"))
|
||||
return false
|
||||
}
|
||||
|
||||
if hostNet == nil {
|
||||
hostString = hostAddr.String()
|
||||
} else {
|
||||
hostString = hostNet.String()
|
||||
}
|
||||
|
||||
// save in datastore
|
||||
err = server.store.Update(func(tx *buntdb.Tx) error {
|
||||
dlineKey := fmt.Sprintf(keyDlineEntry, hostString)
|
||||
|
||||
// check if it exists or not
|
||||
val, err := tx.Get(dlineKey)
|
||||
if val == "" {
|
||||
return errNoExistingBan
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx.Delete(dlineKey)
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, fmt.Sprintf(client.t("Could not remove ban [%s]"), err.Error()))
|
||||
return false
|
||||
}
|
||||
|
||||
if hostNet == nil {
|
||||
server.dlines.RemoveIP(hostAddr)
|
||||
} else {
|
||||
server.dlines.RemoveNetwork(*hostNet)
|
||||
}
|
||||
|
||||
client.Notice(fmt.Sprintf(client.t("Removed D-Line for %s"), hostString))
|
||||
server.snomasks.Send(sno.LocalXline, fmt.Sprintf(ircfmt.Unescape("%s$r removed D-Line for %s"), client.nick, hostString))
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Server) loadDLines() {
|
||||
s.dlines = NewDLineManager()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue