-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathprotect.go
140 lines (125 loc) · 2.87 KB
/
protect.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package p4
import (
"bytes"
"sort"
"strings"
"text/template"
"github.com/pkg/errors"
)
const (
_group = "group"
_user = "user"
)
type Permission struct {
Mode string `json:"mode"`
IsGroup bool `json:"isGroup"`
Name string `json:"name"`
Host string `json:"host"`
Path string `json:"path"`
Comment string `json:"comment"`
}
type ACL struct {
store map[int]*Permission
List []*Permission
}
func (p *ACL) String() string {
var (
contentBuf = bytes.NewBuffer(nil)
)
if _, err := _protectionsTemplate.Parse(_protectionsTemplateTxt); err != nil {
return ""
}
if err := _protectionsTemplate.Execute(contentBuf, p); err != nil {
return ""
}
return contentBuf.String()
}
func newPermission(line string) (err error, p *Permission) {
p = new(Permission)
if err = p.updatePermit(line); err != nil {
return
}
return
}
func newComment(line string) (err error, p *Permission) {
p = new(Permission)
if err = p.updateComment(line); err != nil {
return
}
return
}
func (permission *Permission) updatePermit(line string) (err error) {
line = strings.TrimSpace(line)
fields := strings.Split(line, " ")
if len(fields) != 5 {
err = errors.New("Invalid format")
return
}
isGroup := true
if fields[1] == _user {
isGroup = false
}
permission.Mode = fields[0]
permission.IsGroup = isGroup
permission.Name = fields[2]
permission.Host = fields[3]
permission.Path = fields[4]
return
}
func (permission *Permission) updateComment(line string) (err error) {
if len(line) <= 0 {
err = errors.New("Comment is empty")
return
}
comment := strings.TrimSpace(line)
if !strings.HasPrefix(comment, "##") {
err = errors.New("Comment format invalid")
return
}
comment = strings.TrimPrefix(comment, "##")
comment = strings.TrimSpace(comment)
permission.Comment = comment
return
}
var (
_protectionsTemplate = template.New("ACL config template")
)
var _protectionsTemplateTxt = `Protections:
{{- range .List }}
{{.Mode}} {{if .IsGroup}} group {{else}} user {{end}} {{.Name}} {{.Host}} {{.Path}}{{if .Comment}} ## {{.Comment}} {{end}}
{{- end }}`
func (conn *Conn) WriteProtections(acl *ACL) (out []byte, err error) {
if acl == nil {
err = errors.New("Access control list is empty!")
return
}
content := []byte(acl.String())
return conn.Input([]string{"protect", "-i"}, content)
}
func (conn *Conn) Protections() (acl *ACL, err error) {
var (
keys []int
result []Result
)
if result, err = conn.RunMarshaled("protect", []string{"-o"}); err != nil {
return
}
if len(result) == 0 {
return
}
if acl, _ = result[0].(*ACL); acl == nil {
err = errors.New("Type not match")
return
}
for k := range acl.store {
keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
acl.List = append(acl.List, acl.store[k])
}
return
}
func (conn *Conn) ProtectionsDump() (out []byte, err error) {
return conn.Output([]string{"protect", "-o"})
}