Example #1
0
// GetModes gets the modeline associated with a user or channel.
// It caches its result via metadata on the user, using the mode parser's
// mode ID to disambiguate it from other mode parsers.
func (p *ModeParser) GetModes(e core.Extensible) string {
	var modes string
	var params string

	for name, char := range p.nameToSimple {
		data := e.Data(name)

		if v, ok := p.getExt[char]; ok {
			data = v(e)
		}

		if data != "" {
			modes += string(char)
		}
	}

	for name, char := range p.nameToParametered {
		data := e.Data(name)

		if v, ok := p.getExt[char]; ok {
			data = v(e)
		}

		if data != "" {
			modes += string(char)
			params += " " + data
		}
	}

	return modes + params
}
Example #2
0
// HasOpFlag returns whether the user has the given op flag.
// This both checks for the presence of the flag, and, if the flag is default,
// the "on" keyword for default privileges. This function should not be used as
// a direct means of determining a user's ability to do something; instead,
// the appropriate permission check should be used, as this permits module to
// hook the check on other conditions. It should be used IN said permission
// hooks.
//
// If ch is non-nil, this is a channel op flag check and the user's membership
// entry on the channel will be checked. If no such entry exists, the check
// automatically fails. If ch is nil, this is a server op flag check, and the user's own metadata will be checked.
func HasOpFlag(u *core.User, ch *core.Channel, flag string) bool {
	var e core.Extensible
	var defwords []string
	if ch == nil {
		e = u
		defwords = defServerOp
	} else {
		if m := ch.GetMember(u); m != nil {
			e = m
		} else {
			return false
		}
		defwords = defChanOp
	}

	words := strings.Fields(e.Data("op"))
	for _, word := range words {
		if word == flag {
			return true
		}
		if word == "on" {
			for _, defword := range defwords {
				if defword == flag {
					return true
				}
			}
		}
	}

	return false
}
Example #3
0
// Restricted returns whether the user is restricted by a restriction of the
// given type on the given extensible. It handles checking for unrestriction
// modes, as well as the given restriction being set.
func Restricted(u *core.User, e core.Extensible, restrict string) bool {
	if e.Data("restrict "+restrict) != "" {
		if !banMatch(u, e, "unrestrict", restrict) {
			return true
		}
	}
	return false
}
Example #4
0
// ListMode calls the given function for every entry in the list mode,
// with the parameter of this mode list entry, and its metadata value. If
// there are none, it will not be called.
func (p *ModeParser) ListMode(e core.Extensible, char int, f func(param, value string)) bool {
	prefix := p.list[char]
	if prefix != "" {
		e.DataRange(prefix+" ", func(name, value string) {
			if v, ok := p.nameToExt[prefix]; ok {
				_, addpar, _, _ := v(e, name, "", value)
				for _, par := range addpar {
					f(par, value)
				}
			} else {
				f(name[len(prefix)+1:], value)
			}
		})
		return true
	}
	return false
}
Example #5
0
// banMatch returns whether the user has a ban on the given Extensible,
// matching the given restriction, under the given prefix for ban types.
// It handles checking for default bans, if this ban type is part of the
// default.
func banMatch(u *core.User, e core.Extensible, prefix, restrict string) (match bool) {
	def := defaultBan
	if prefix == "unrestrict" {
		def = defaultUnrestrict
	}
	defwords := strings.Fields(def)

	// Create matcher closure, to run for each ban.
	var reverse bool
	var prefixlen int
	var t string
	var hook func(u *core.User, mask string) bool
	matcher := func(name, value string) {
		words := strings.Fields(value)
		var found bool
		for _, word := range words {
			if word == restrict {
				found = true
				break
			}
			if word == "on" {
				var deffound bool
				for _, defword := range defwords {
					if defword == restrict {
						deffound = true
						break
					}
				}
				if deffound {
					found = true
					break
				}
			}
		}

		if !found {
			return
		}

		// If the hook returns true and we're NOT reversed, match.
		// If the hook returns false and we are reversed, match.
		if hook(u, name[prefixlen:]) == !reverse {
			match = true
		}
	}

	for t, hook = range banTypes {
		reverse = false
		prefixlen = len(prefix) + len(t) + 2
		e.DataRange(prefix+" "+t+" ", matcher)
		if match == true {
			break
		}

		reverse = true
		prefixlen = len(prefix) + len(t) + 3
		e.DataRange(prefix+" ~"+t+" ", matcher)
		if match == true {
			break
		}
	}

	return
}