Refined permission management, implemented KICK, forbid PRIVMSG to chan from outside
This commit is contained in:
parent
0b6442a17e
commit
8088acc214
131
server.go
131
server.go
|
@ -22,7 +22,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var myinfo string = "%s %s/%s * *"
|
var myinfo string = "%s %s/%s * *"
|
||||||
var isupport string = "CASEMAPPING=rfc1459 CHANTYPES=# NICKLEN=32 PREFIX=(aohv)&@%%+"
|
var isupport string = "CASEMAPPING=rfc1459 CHANTYPES=# NICKLEN=32 PREFIX=(ohv)@%%+"
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
queue chan *irc.Message
|
queue chan *irc.Message
|
||||||
|
@ -338,6 +338,15 @@ func (sv *Server) channelCheckMode(chid, mode string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sv *Server) channelCheckPerm(chid, clid, modes string) bool {
|
||||||
|
for _, m := range modes {
|
||||||
|
if sv.channelCheckMode(chid, string(m)+" "+clid) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
type commandHook struct {
|
type commandHook struct {
|
||||||
HookFn func(sv *Server, msg *irc.Message)
|
HookFn func(sv *Server, msg *irc.Message)
|
||||||
MinArgs int
|
MinArgs int
|
||||||
|
@ -352,10 +361,12 @@ var svCommandHooks = map[string]commandHook{
|
||||||
"QUIT": {handleCmdQuit, 0, false, ""},
|
"QUIT": {handleCmdQuit, 0, false, ""},
|
||||||
"MODE": {handleCmdMode, 1, false, ""},
|
"MODE": {handleCmdMode, 1, false, ""},
|
||||||
"TOPIC": {handleCmdTopic, 1, false, ""},
|
"TOPIC": {handleCmdTopic, 1, false, ""},
|
||||||
|
"KICK": {handleCmdKick, 2, false, ""},
|
||||||
"NAMES": {handleCmdNames, 1, false, ""},
|
"NAMES": {handleCmdNames, 1, false, ""},
|
||||||
"WHOIS": {handleCmdWhois, 0, false, ""},
|
"WHOIS": {handleCmdWhois, 0, false, ""},
|
||||||
"PING": {handleCmdPing, 1, false, ""},
|
"PING": {handleCmdPing, 1, false, ""},
|
||||||
"REHASH": {handleCmdRehash, 0, false, "ao"},
|
"REHASH": {handleCmdRehash, 0, false, "ao"},
|
||||||
|
"KILL": {handleCmdKill, 0, false, "ao"},
|
||||||
/*
|
/*
|
||||||
"LIST": {handleCmdList, 0, false, false},
|
"LIST": {handleCmdList, 0, false, false},
|
||||||
"VERSION": {handleCmdVersion, 0, false, false},
|
"VERSION": {handleCmdVersion, 0, false, false},
|
||||||
|
@ -366,7 +377,6 @@ var svCommandHooks = map[string]commandHook{
|
||||||
"INFO": {handleCmdInfo, 0, false, false},
|
"INFO": {handleCmdInfo, 0, false, false},
|
||||||
"WHO": {handleCmdWho, 0, false, false},
|
"WHO": {handleCmdWho, 0, false, false},
|
||||||
"WHOWAS": {handleCmdWhowas, 0, false, false},
|
"WHOWAS": {handleCmdWhowas, 0, false, false},
|
||||||
"KILL": {handleCmdKill, 0, false, false},
|
|
||||||
"PONG": {handleCmdPong, 0, false, false},
|
"PONG": {handleCmdPong, 0, false, false},
|
||||||
"ERROR": {handleCmdError, 0, false, false},
|
"ERROR": {handleCmdError, 0, false, false},
|
||||||
"AWAY": {handleCmdAway, 0, false, false},
|
"AWAY": {handleCmdAway, 0, false, false},
|
||||||
|
@ -383,7 +393,12 @@ func handleCmdPrivmsg(sv *Server, msg *irc.Message) {
|
||||||
clid := strings.ToLower(msg.Pre)
|
clid := strings.ToLower(msg.Pre)
|
||||||
chid := strings.ToLower(msg.Args[0])
|
chid := strings.ToLower(msg.Args[0])
|
||||||
if sv.channelCheckMode(chid, "m") &&
|
if sv.channelCheckMode(chid, "m") &&
|
||||||
!sv.channelCheckMode(chid, "v "+clid) {
|
!sv.channelCheckPerm(chid, clid, "ohv") {
|
||||||
|
sv.sendReply(clid, ERR_CANNOTSENDTOCHAN, chid, "Cannot send to channel")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, exists := sv.chUsers[clid]; !exists {
|
||||||
|
sv.sendReply(clid, ERR_CANNOTSENDTOCHAN, chid, "Cannot send to channel")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -452,58 +467,52 @@ func handleCmdMode(sv *Server, msg *irc.Message) {
|
||||||
if len(msg.Args) < 2 {
|
if len(msg.Args) < 2 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
modeFlag := msg.Args[1]
|
mode := ""
|
||||||
if len(msg.Args) < 3 {
|
modeSwitch := msg.Args[1]
|
||||||
//modeTar := ""
|
modeTarget := ""
|
||||||
} else {
|
if len(modeSwitch) < 2 {
|
||||||
//modeTar := strings.ToLower(msg.Args[2])
|
return
|
||||||
}
|
}
|
||||||
switch modeFlag {
|
if len(msg.Args) > 2 {
|
||||||
|
modeTarget = strings.ToLower(msg.Args[2])
|
||||||
|
}
|
||||||
|
switch modeSwitch[1] {
|
||||||
// maybe this can be done more elegant
|
// maybe this can be done more elegant
|
||||||
case "+o":
|
case 'o':
|
||||||
if !sv.channelCheckMode(chid, "o "+clid) {
|
if !sv.channelCheckPerm(chid, clid, "o") {
|
||||||
goto noPerm
|
goto noPerm
|
||||||
}
|
}
|
||||||
case "-o":
|
case 'h':
|
||||||
if !sv.channelCheckMode(chid, "o "+clid) {
|
if !sv.channelCheckPerm(chid, clid, "o") {
|
||||||
goto noPerm
|
goto noPerm
|
||||||
}
|
}
|
||||||
case "+h":
|
case 'b':
|
||||||
if !sv.channelCheckMode(chid, "o "+clid) {
|
if !sv.channelCheckPerm(chid, clid, "oh") {
|
||||||
goto noPerm
|
goto noPerm
|
||||||
}
|
}
|
||||||
case "-h":
|
case 'v':
|
||||||
if !sv.channelCheckMode(chid, "o "+clid) {
|
if !sv.channelCheckPerm(chid, clid, "oh") {
|
||||||
goto noPerm
|
goto noPerm
|
||||||
}
|
}
|
||||||
case "+b":
|
case 'm':
|
||||||
if !sv.channelCheckMode(chid, "o "+clid) &&
|
if !sv.channelCheckPerm(chid, clid, "oh") {
|
||||||
!sv.channelCheckMode(chid, "h "+clid) {
|
|
||||||
goto noPerm
|
goto noPerm
|
||||||
}
|
}
|
||||||
case "-b":
|
case 't':
|
||||||
if !sv.channelCheckMode(chid, "o "+clid) &&
|
if !sv.channelCheckPerm(chid, clid, "oh") {
|
||||||
!sv.channelCheckMode(chid, "h "+clid) {
|
|
||||||
goto noPerm
|
goto noPerm
|
||||||
}
|
}
|
||||||
case "+v":
|
default:
|
||||||
if !sv.channelCheckMode(chid, "o "+clid) &&
|
return
|
||||||
!sv.channelCheckMode(chid, "h "+clid) {
|
|
||||||
goto noPerm
|
|
||||||
}
|
}
|
||||||
case "-v":
|
mode = string(modeSwitch[1])
|
||||||
if !sv.channelCheckMode(chid, "o "+clid) &&
|
if modeTarget != "" {
|
||||||
!sv.channelCheckMode(chid, "h "+clid) {
|
mode = mode + " " + modeTarget
|
||||||
goto noPerm
|
|
||||||
}
|
|
||||||
case "+m":
|
|
||||||
if !sv.channelCheckMode(chid, "o "+clid) {
|
|
||||||
goto noPerm
|
|
||||||
}
|
|
||||||
case "-m":
|
|
||||||
if !sv.channelCheckMode(chid, "o "+clid) {
|
|
||||||
goto noPerm
|
|
||||||
}
|
}
|
||||||
|
if modeSwitch[0] == '+' {
|
||||||
|
sv.chModes[chid][mode] = true
|
||||||
|
} else {
|
||||||
|
delete(sv.chModes[chid], mode)
|
||||||
}
|
}
|
||||||
sv.sendMsg(msg)
|
sv.sendMsg(msg)
|
||||||
return
|
return
|
||||||
|
@ -513,24 +522,45 @@ func handleCmdMode(sv *Server, msg *irc.Message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleCmdTopic(sv *Server, msg *irc.Message) {
|
func handleCmdTopic(sv *Server, msg *irc.Message) {
|
||||||
ch := msg.Args[0]
|
chid := strings.ToLower(msg.Args[0])
|
||||||
if _, exists := sv.chUsers[ch]; !exists {
|
clid := strings.ToLower(msg.Pre)
|
||||||
sv.sendReply(msg.Pre, ERR_NOSUCHCHANNEL, ch, "No such channel")
|
if _, exists := sv.chUsers[chid]; !exists {
|
||||||
|
sv.sendReply(msg.Pre, ERR_NOSUCHCHANNEL, chid, "No such channel")
|
||||||
}
|
}
|
||||||
if msg.Trail == "" {
|
if msg.Trail == "" {
|
||||||
sv.sendReply(msg.Pre, RPL_TOPIC, ch, sv.chTopics[ch])
|
sv.sendReply(msg.Pre, RPL_TOPIC, chid, sv.chTopics[chid])
|
||||||
} else {
|
} else {
|
||||||
sv.chTopics[ch] = msg.Trail
|
if sv.channelCheckMode(chid, "t") &&
|
||||||
|
!sv.channelCheckPerm(chid, clid, "oh") {
|
||||||
|
sv.sendReply(clid, ERR_CHANOPRIVSNEEDED, chid, "You're not channel operator")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sv.chTopics[chid] = msg.Trail
|
||||||
sv.sendMsg(msg)
|
sv.sendMsg(msg)
|
||||||
//sv.sendReply(msg.Pre, RPL_TOPIC, ch, msg.Trail)
|
//sv.sendReply(msg.Pre, RPL_TOPIC, ch, msg.Trail)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func handleCmdNames(sv *Server, msg *irc.Message) {
|
|
||||||
ch := msg.Args[0]
|
func handleCmdKick(sv *Server, msg *irc.Message) {
|
||||||
if _, exists := sv.chUsers[ch]; !exists {
|
chid := strings.ToLower(msg.Args[0])
|
||||||
sv.sendReply(msg.Pre, ERR_NOSUCHCHANNEL, ch, "No such channel")
|
clid := strings.ToLower(msg.Pre)
|
||||||
|
target := strings.ToLower(msg.Args[1])
|
||||||
|
if !sv.channelCheckPerm(chid, clid, "oh") {
|
||||||
|
sv.sendReply(clid, ERR_CHANOPRIVSNEEDED, chid, "You're not channel operator")
|
||||||
}
|
}
|
||||||
sv.channelNames(msg.Pre, ch)
|
sv.sendMsg(msg)
|
||||||
|
delete(sv.chUsers[chid], target)
|
||||||
|
delete(sv.chModes[chid], "o "+target)
|
||||||
|
delete(sv.chModes[chid], "h "+target)
|
||||||
|
delete(sv.chModes[chid], "v "+target)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleCmdNames(sv *Server, msg *irc.Message) {
|
||||||
|
chid := strings.ToLower(msg.Args[0])
|
||||||
|
if _, exists := sv.chUsers[chid]; !exists {
|
||||||
|
sv.sendReply(msg.Pre, ERR_NOSUCHCHANNEL, chid, "No such channel")
|
||||||
|
}
|
||||||
|
sv.channelNames(msg.Pre, chid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleCmdWhois(sv *Server, msg *irc.Message) {
|
func handleCmdWhois(sv *Server, msg *irc.Message) {
|
||||||
|
@ -546,3 +576,6 @@ func handleCmdRehash(sv *Server, msg *irc.Message) {
|
||||||
sv.sendReply(msg.Pre, RPL_REHASHING, "", "Rehashing.")
|
sv.sendReply(msg.Pre, RPL_REHASHING, "", "Rehashing.")
|
||||||
xlog.Info("Rehashing")
|
xlog.Info("Rehashing")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleCmdKill(sv *Server, msg *irc.Message) {
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue