Refined permission management, implemented KICK, forbid PRIVMSG to chan from outside
This commit is contained in:
		
							parent
							
								
									0b6442a17e
								
							
						
					
					
						commit
						8088acc214
					
				
					 1 changed files with 84 additions and 51 deletions
				
			
		
							
								
								
									
										135
									
								
								server.go
									
										
									
									
									
								
							
							
						
						
									
										135
									
								
								server.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -22,7 +22,7 @@ const (
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
	queue chan *irc.Message
 | 
			
		||||
| 
						 | 
				
			
			@ -338,6 +338,15 @@ func (sv *Server) channelCheckMode(chid, mode string) bool {
 | 
			
		|||
	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 {
 | 
			
		||||
	HookFn    func(sv *Server, msg *irc.Message)
 | 
			
		||||
	MinArgs   int
 | 
			
		||||
| 
						 | 
				
			
			@ -352,10 +361,12 @@ var svCommandHooks = map[string]commandHook{
 | 
			
		|||
	"QUIT":    {handleCmdQuit, 0, false, ""},
 | 
			
		||||
	"MODE":    {handleCmdMode, 1, false, ""},
 | 
			
		||||
	"TOPIC":   {handleCmdTopic, 1, false, ""},
 | 
			
		||||
	"KICK":    {handleCmdKick, 2, false, ""},
 | 
			
		||||
	"NAMES":   {handleCmdNames, 1, false, ""},
 | 
			
		||||
	"WHOIS":   {handleCmdWhois, 0, false, ""},
 | 
			
		||||
	"PING":    {handleCmdPing, 1, false, ""},
 | 
			
		||||
	"REHASH":  {handleCmdRehash, 0, false, "ao"},
 | 
			
		||||
	"KILL":    {handleCmdKill, 0, false, "ao"},
 | 
			
		||||
	/*
 | 
			
		||||
		"LIST":     {handleCmdList, 0, false, false},
 | 
			
		||||
		"VERSION":  {handleCmdVersion, 0, false, false},
 | 
			
		||||
| 
						 | 
				
			
			@ -366,7 +377,6 @@ var svCommandHooks = map[string]commandHook{
 | 
			
		|||
		"INFO":     {handleCmdInfo, 0, false, false},
 | 
			
		||||
		"WHO":      {handleCmdWho, 0, false, false},
 | 
			
		||||
		"WHOWAS":   {handleCmdWhowas, 0, false, false},
 | 
			
		||||
		"KILL":     {handleCmdKill, 0, false, false},
 | 
			
		||||
		"PONG":     {handleCmdPong, 0, false, false},
 | 
			
		||||
		"ERROR":    {handleCmdError, 0, false, false},
 | 
			
		||||
		"AWAY":     {handleCmdAway, 0, false, false},
 | 
			
		||||
| 
						 | 
				
			
			@ -383,7 +393,12 @@ func handleCmdPrivmsg(sv *Server, msg *irc.Message) {
 | 
			
		|||
		clid := strings.ToLower(msg.Pre)
 | 
			
		||||
		chid := strings.ToLower(msg.Args[0])
 | 
			
		||||
		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
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -452,58 +467,52 @@ func handleCmdMode(sv *Server, msg *irc.Message) {
 | 
			
		|||
		if len(msg.Args) < 2 {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		modeFlag := msg.Args[1]
 | 
			
		||||
		if len(msg.Args) < 3 {
 | 
			
		||||
			//modeTar := ""
 | 
			
		||||
		} else {
 | 
			
		||||
			//modeTar := strings.ToLower(msg.Args[2])
 | 
			
		||||
		mode := ""
 | 
			
		||||
		modeSwitch := msg.Args[1]
 | 
			
		||||
		modeTarget := ""
 | 
			
		||||
		if len(modeSwitch) < 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
 | 
			
		||||
		case "+o":
 | 
			
		||||
			if !sv.channelCheckMode(chid, "o "+clid) {
 | 
			
		||||
		case 'o':
 | 
			
		||||
			if !sv.channelCheckPerm(chid, clid, "o") {
 | 
			
		||||
				goto noPerm
 | 
			
		||||
			}
 | 
			
		||||
		case "-o":
 | 
			
		||||
			if !sv.channelCheckMode(chid, "o "+clid) {
 | 
			
		||||
		case 'h':
 | 
			
		||||
			if !sv.channelCheckPerm(chid, clid, "o") {
 | 
			
		||||
				goto noPerm
 | 
			
		||||
			}
 | 
			
		||||
		case "+h":
 | 
			
		||||
			if !sv.channelCheckMode(chid, "o "+clid) {
 | 
			
		||||
		case 'b':
 | 
			
		||||
			if !sv.channelCheckPerm(chid, clid, "oh") {
 | 
			
		||||
				goto noPerm
 | 
			
		||||
			}
 | 
			
		||||
		case "-h":
 | 
			
		||||
			if !sv.channelCheckMode(chid, "o "+clid) {
 | 
			
		||||
		case 'v':
 | 
			
		||||
			if !sv.channelCheckPerm(chid, clid, "oh") {
 | 
			
		||||
				goto noPerm
 | 
			
		||||
			}
 | 
			
		||||
		case "+b":
 | 
			
		||||
			if !sv.channelCheckMode(chid, "o "+clid) &&
 | 
			
		||||
				!sv.channelCheckMode(chid, "h "+clid) {
 | 
			
		||||
		case 'm':
 | 
			
		||||
			if !sv.channelCheckPerm(chid, clid, "oh") {
 | 
			
		||||
				goto noPerm
 | 
			
		||||
			}
 | 
			
		||||
		case "-b":
 | 
			
		||||
			if !sv.channelCheckMode(chid, "o "+clid) &&
 | 
			
		||||
				!sv.channelCheckMode(chid, "h "+clid) {
 | 
			
		||||
				goto noPerm
 | 
			
		||||
			}
 | 
			
		||||
		case "+v":
 | 
			
		||||
			if !sv.channelCheckMode(chid, "o "+clid) &&
 | 
			
		||||
				!sv.channelCheckMode(chid, "h "+clid) {
 | 
			
		||||
				goto noPerm
 | 
			
		||||
			}
 | 
			
		||||
		case "-v":
 | 
			
		||||
			if !sv.channelCheckMode(chid, "o "+clid) &&
 | 
			
		||||
				!sv.channelCheckMode(chid, "h "+clid) {
 | 
			
		||||
				goto noPerm
 | 
			
		||||
			}
 | 
			
		||||
		case "+m":
 | 
			
		||||
			if !sv.channelCheckMode(chid, "o "+clid) {
 | 
			
		||||
				goto noPerm
 | 
			
		||||
			}
 | 
			
		||||
		case "-m":
 | 
			
		||||
			if !sv.channelCheckMode(chid, "o "+clid) {
 | 
			
		||||
		case 't':
 | 
			
		||||
			if !sv.channelCheckPerm(chid, clid, "oh") {
 | 
			
		||||
				goto noPerm
 | 
			
		||||
			}
 | 
			
		||||
		default:
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		mode = string(modeSwitch[1])
 | 
			
		||||
		if modeTarget != "" {
 | 
			
		||||
			mode = mode + " " + modeTarget
 | 
			
		||||
		}
 | 
			
		||||
		if modeSwitch[0] == '+' {
 | 
			
		||||
			sv.chModes[chid][mode] = true
 | 
			
		||||
		} else {
 | 
			
		||||
			delete(sv.chModes[chid], mode)
 | 
			
		||||
		}
 | 
			
		||||
		sv.sendMsg(msg)
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -513,24 +522,45 @@ func handleCmdMode(sv *Server, msg *irc.Message) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func handleCmdTopic(sv *Server, msg *irc.Message) {
 | 
			
		||||
	ch := msg.Args[0]
 | 
			
		||||
	if _, exists := sv.chUsers[ch]; !exists {
 | 
			
		||||
		sv.sendReply(msg.Pre, ERR_NOSUCHCHANNEL, ch, "No such channel")
 | 
			
		||||
	chid := strings.ToLower(msg.Args[0])
 | 
			
		||||
	clid := strings.ToLower(msg.Pre)
 | 
			
		||||
	if _, exists := sv.chUsers[chid]; !exists {
 | 
			
		||||
		sv.sendReply(msg.Pre, ERR_NOSUCHCHANNEL, chid, "No such channel")
 | 
			
		||||
	}
 | 
			
		||||
	if msg.Trail == "" {
 | 
			
		||||
		sv.sendReply(msg.Pre, RPL_TOPIC, ch, sv.chTopics[ch])
 | 
			
		||||
		sv.sendReply(msg.Pre, RPL_TOPIC, chid, sv.chTopics[chid])
 | 
			
		||||
	} 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.sendReply(msg.Pre, RPL_TOPIC, ch, msg.Trail)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
func handleCmdNames(sv *Server, msg *irc.Message) {
 | 
			
		||||
	ch := msg.Args[0]
 | 
			
		||||
	if _, exists := sv.chUsers[ch]; !exists {
 | 
			
		||||
		sv.sendReply(msg.Pre, ERR_NOSUCHCHANNEL, ch, "No such channel")
 | 
			
		||||
 | 
			
		||||
func handleCmdKick(sv *Server, msg *irc.Message) {
 | 
			
		||||
	chid := strings.ToLower(msg.Args[0])
 | 
			
		||||
	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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -546,3 +576,6 @@ func handleCmdRehash(sv *Server, msg *irc.Message) {
 | 
			
		|||
	sv.sendReply(msg.Pre, RPL_REHASHING, "", "Rehashing.")
 | 
			
		||||
	xlog.Info("Rehashing")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func handleCmdKill(sv *Server, msg *irc.Message) {
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue