murarth avatar murarth committed aa617a2

Implemented oper override module

Comments (0)

Files changed (3)

commands/cmd_channels.go

 				&TargetPropagate{user.Server}},
 			"KICK %s %s :%s", ch.Name, kickee.Id, reason)
 
+		ch.RemoveUser(kickee)
+
 		for _, handler := range UserKick {
 			handler.(UserKickHandler).UserKick(serv, user, ch, kickee, reason)
 		}
 			}
 			pfx := ch.GetPrefix(user)
 
-			modes := ParseModes(tokens[1], tokens[2:], true)
+			modeStr := tokens[1]
+			params := tokens[2:]
+
+			allow := false
+
+			for _, handler := range UserPreMode {
+				res, err := handler.(UserPreModeHandler).UserPreMode(serv, user,
+					IsChannel, ch, &modeStr, params)
+
+				if res == Deny {
+					return err
+				} else if res == Allow {
+					allow = true
+					break
+				}
+			}
+
+			modes := ParseModes(modeStr, params, true)
 
 			var serverEmit *EmitModes
 			emitModes := NewEmitModes()
 						}
 				}
 
-				chdlr = hdlr.(CModeHandler)
-
-				switch res, e := chdlr.HandlePre(serv, user, ch, sign, &param); (res) {
-					case Allow:
-						goto modeAllow
-					case Deny:
-						err = e
-						goto modeError
-					case PassThrough:
-				}
-
 				switch (hdlr.CanSet()) {
 					case ModeOpers:
 						if !user.IsOper() {
 						}
 				}
 
-				if hdlr.Type() != ModeList && pfx < chdlr.Requires() {
-					err = ChanOpNeeded.Set(ch.Name)
-					goto modeError
+				chdlr = hdlr.(CModeHandler)
+
+				switch res, e := chdlr.HandlePre(serv, user, ch, sign, &param); (res) {
+					case Allow:
+						goto modeAllow
+					case Deny:
+						err = e
+						goto modeError
+					case PassThrough:
+				}
+
+				if !allow {
+					if hdlr.Type() != ModeList && pfx < chdlr.Requires() {
+						err = ChanOpNeeded.Set(ch.Name)
+						goto modeError
+					}
 				}
 
 				modeAllow:
 					u.Nick, u.ServerNotices.String())
 			}
 		} else {
+			modeStr := tokens[1]
+			params := tokens[2:]
+
+			allow := false
+
+			for _, handler := range UserPreMode {
+				res, err := handler.(UserPreModeHandler).UserPreMode(serv, user,
+					IsUser, u, &modeStr, params)
+
+				if res == Deny {
+					return err
+				} else if res == Allow {
+					allow = true
+				}
+			}
+
 			modes := ParseModes(tokens[1], tokens[2:], false)
 
 			emitModes := NewEmitModes()
 						goto umodeError
 					}
 
+					if allow {
+						goto umodeAllow
+					}
+
 					switch (hdlr.CanSet()) {
 						case ModeOpers:
 							if !user.IsOper() {
 	UserPreKick = NewEvent()
 	// Occurs before a User sends a NOTICE or PRIVMSG
 	UserPreMessage = NewEvent()
+	// Occurs before a User issues a MODE command
+	UserPreMode = NewEvent()
 	// Occurs before a User changes their nickname
 	UserPreNick = NewEvent()
 	// Occurs before a User sets the TOPIC in a Channel
 		level PrefixLevel, cmd string, message *string) (result EventResult, err ClientError)
 }
 
+type UserPreModeHandler interface {
+	EventHandler
+	UserPreMode(serv *Server, user *User, typ TargetType, target interface{},
+		modes *string, params Tokens) (EventResult, ClientError)
+}
+
 type UserPreNickHandler interface {
 	EventHandler
 	UserPreNick(*Server, *User, string) (EventResult, ClientError)
 func HandleUserPreJoin(h UserPreJoinHandler) { UserPreJoin.AddHandler(h) }
 func HandleUserPreKick(h UserPreKickHandler) { UserPreKick.AddHandler(h) }
 func HandleUserPreMessage(h UserPreMessageHandler) { UserPreMessage.AddHandler(h) }
+func HandleUserPreMode(h UserPreModeHandler) { UserPreMode.AddHandler(h) }
 func HandleUserPreNick(h UserPreNickHandler) { UserPreNick.AddHandler(h) }
 func HandleUserPreSetTopic(h UserPreSetTopicHandler) { UserPreSetTopic.AddHandler(h) }
 func HandleUserPreWhois(h UserPreWhoisHandler) { UserPreWhois.AddHandler(h) }

modules/m_override.go

+package main
+
+func init() {
+	override := new(Override)
+	HandleUserPreJoin(override)
+	HandleUserPreKick(override)
+	HandleUserPreMode(override)
+	HandleUserPreSetTopic(override)
+}
+
+type Override struct {
+	HighPriority
+}
+
+func (o *Override) CanOverride(user *User) bool {
+	return user.IsOper()
+}
+
+func (o *Override) UserPreJoin(serv *Server, user *User, name string, ch *Channel,
+		level *PrefixLevel, key string) (EventResult, ClientError) {
+	if o.CanOverride(user) {
+		return Allow, nil
+	}
+	return PassThrough, nil
+}
+
+func (o *Override) UserPreKick(user *User, ch *Channel, kickee *User, reason string) (EventResult, ClientError) {
+	if o.CanOverride(user) {
+		return Allow, nil
+	}
+	return PassThrough, nil
+}
+
+func (o *Override) UserPreMode(serv *Server, user *User, typ TargetType, target interface{},
+		modes *string, params Tokens) (EventResult, ClientError) {
+	if typ == IsChannel && o.CanOverride(user) {
+		return Allow, nil
+	}
+	return PassThrough, nil
+}
+
+func (o *Override) UserPreSetTopic(serv *Server, user *User, ch *Channel, topic string) (EventResult, ClientError) {
+	if o.CanOverride(user) {
+		return Allow, nil
+	}
+	return PassThrough, nil
+}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.