tavern/common/allow.go

109 lines
2.1 KiB
Go

package common
import (
"fmt"
"strings"
)
type AllowDenyMatcher struct {
Original string
MatchType int
Data string
}
type AllowDenyMatcherType int16
type MatcherSet struct {
Default bool
HighAllow []AllowDenyMatcher
HighDeny []AllowDenyMatcher
LowAllow []AllowDenyMatcher
LowDeny []AllowDenyMatcher
}
const (
ExactAllowDenyMatcher = iota
PrefixAllowDenyMatcher
SuffixAllowDenyMatcher
ContainsAllowDenyMatcher
AllAllowDenyMatcher
)
const wildcard = "*"
func NewAllowDenyMatcher(input string) AllowDenyMatcher {
if input == wildcard {
return AllowDenyMatcher{
Original: input,
MatchType: AllAllowDenyMatcher,
Data: "",
}
}
t := ExactAllowDenyMatcher
data := input
hasPrefix := false
hasSuffix := false
if hasPrefix = strings.HasPrefix(input, wildcard); hasPrefix {
data = strings.TrimPrefix(input, wildcard)
t = PrefixAllowDenyMatcher
}
if hasSuffix = strings.HasSuffix(input, wildcard); hasSuffix {
data = strings.TrimSuffix(input, wildcard)
if hasPrefix {
t = ContainsAllowDenyMatcher
} else {
t = SuffixAllowDenyMatcher
}
}
return AllowDenyMatcher{
Original: input,
MatchType: t,
Data: data,
}
}
func (m AllowDenyMatcher) Match(test string) bool {
switch m.MatchType {
case AllAllowDenyMatcher:
return true
case ExactAllowDenyMatcher:
return m.Data == test
case PrefixAllowDenyMatcher:
return strings.HasSuffix(test, m.Data)
case SuffixAllowDenyMatcher:
return strings.HasPrefix(test, m.Data)
case ContainsAllowDenyMatcher:
return strings.Contains(test, m.Data)
default:
return false
}
}
func (s MatcherSet) Allow(tests ...string) bool {
for _, test := range tests {
fmt.Println("testing", test)
for _, matcher := range s.HighAllow {
if matcher.Match(test) {
return true
}
}
for _, matcher := range s.HighDeny {
if matcher.Match(test) {
return false
}
}
for _, matcher := range s.LowAllow {
if matcher.Match(test) {
return true
}
}
for _, matcher := range s.LowDeny {
if matcher.Match(test) {
return false
}
}
}
return s.Default
}