/
rule.go
85 lines (72 loc) · 1.8 KB
/
rule.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package permission
import (
"strings"
)
// Rule holds permission information related to a specific path
type Rule struct {
Path string
Methods []string
MethodsAreBlacklist bool
}
const (
blacklistChar = "~"
)
var (
errUnknownMethod = "failed to create Rule: method \"%s\" unknown."
)
// MatchesMethod checks if the permission matches the given HTTP method.
func (r *Rule) MatchesMethod(method string) bool {
found := false
for _, m := range r.Methods {
if method == m {
found = true
break
}
}
if found {
return !r.MethodsAreBlacklist
}
return r.MethodsAreBlacklist
}
// MatchesPath checks if the permission rule matches the given HTTP request path.
func (r *Rule) MatchesPath(path string) bool {
if len(path) < len(r.Path) {
return false
}
return strings.HasPrefix(path, r.Path)
}
// MatchesParentPath checks if the HTTP request path is a parent of the permission rule path.
func (r *Rule) MatchesParentPath(path string) bool {
if len(path) <= len(r.Path) {
return false
}
return strings.HasPrefix(r.Path, path)
}
// NewRule creates a new permission rule with the given concatenated method string and path
func NewRule(methods, path string) (*Rule, error) {
new := Rule{
Path: path,
}
if methods == blacklistChar || methods == "none" {
return &new, nil
}
if methods == "any" {
new.MethodsAreBlacklist = true
return &new, nil
}
if strings.HasPrefix(methods, blacklistChar) {
new.MethodsAreBlacklist = true
methods = strings.TrimLeft(methods, blacklistChar)
}
splitted := strings.Split(methods, ",")
for _, method := range splitted {
method = strings.TrimSpace(method)
shortcuts, ok := aliases[method]
if ok {
new.Methods = append(new.Methods, shortcuts...)
} else {
new.Methods = append(new.Methods, method)
}
}
return &new, nil
}