-
Notifications
You must be signed in to change notification settings - Fork 4
/
permission.go
92 lines (77 loc) · 2.22 KB
/
permission.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
86
87
88
89
90
91
92
// Content managed by Project Forge, see [projectforge.md] for details.
package user
import (
"fmt"
"strings"
"golang.org/x/exp/slices"
"projectforge.dev/projectforge/app/util"
)
const permPrefix = "perm: "
var (
PermissionsLogger util.Logger
perms Permissions
)
func SetPermissions(allowDefault bool, ps ...*Permission) {
perms = make(Permissions, 0, len(ps)+4)
perms = append(perms, Perm("/auth", "*", true), Perm("/profile", "*", true))
perms = append(perms, ps...)
perms = append(perms, Perm("/admin", "*", false), Perm("/about", "*", true), Perm("/", "*", allowDefault))
}
func GetPermissions() Permissions {
ret := make(Permissions, 0, len(perms))
return append(ret, perms...)
}
type Permission struct {
Path string `json:"path"`
Match string `json:"match"`
Allow bool `json:"allow"`
}
func Check(path string, accounts Accounts) (bool, string) {
return perms.Check(path, accounts)
}
func Perm(p string, m string, a bool) *Permission {
return &Permission{Path: p, Match: m, Allow: a}
}
func (p Permission) Matches(path string) bool {
return strings.HasPrefix(path, p.Path)
}
func (p Permission) String() string {
return fmt.Sprintf("%s [%s::%t]", p.Path, p.Match, p.Allow)
}
type Permissions []*Permission
func (p Permissions) Sort() {
slices.SortFunc(p, func(l *Permission, r *Permission) bool {
if l.Path == r.Path {
return l.Match < r.Match
}
return l.Path < r.Path
})
}
func (p Permissions) Check(path string, accounts Accounts) (bool, string) {
if PermissionsLogger != nil {
PermissionsLogger.Debugf(permPrefix+"checking [%d] permissions for [%s]", len(p), accounts.String())
}
if len(p) == 0 {
const msg = "no permissions configured"
if PermissionsLogger != nil {
PermissionsLogger.Debug(permPrefix + msg)
}
return true, msg
}
for _, perm := range p {
if perm.Matches(path) {
if accounts.Matches(perm.Match) {
msg := fmt.Sprintf("matched [%s], result [%t]", perm.Match, perm.Allow)
if PermissionsLogger != nil {
PermissionsLogger.Debug(permPrefix + msg)
}
return perm.Allow, msg
}
}
}
msg := fmt.Sprintf("no matches among [%d] permissions", len(p))
if PermissionsLogger != nil {
PermissionsLogger.Debug(permPrefix + msg)
}
return false, msg
}