This repository has been archived by the owner on Feb 24, 2020. It is now read-only.
/
audit.go
86 lines (78 loc) · 2.03 KB
/
audit.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
package twocloud
import (
"github.com/fzzbt/radix/redis"
"strconv"
"time"
)
type Auditor struct {
client *redis.Client
}
func NewAuditor(conf redis.Config) *Auditor {
return &Auditor{
client: redis.NewClient(conf),
}
}
func (a *Auditor) Close() {
a.client.Close()
}
type Change struct {
ID uint64 `json:"id"`
Key string `json:"key"`
Field string `json:"field"`
From interface{} `json:"from"`
To interface{} `json:"to"`
IP string `json:"ip"`
User User `json:"user"`
Timestamp time.Time `json:"timestamp"`
}
func (a *Auditor) Insert(r *RequestBundle, key, ip string, user User, from, to map[string]interface{}) error {
changes := []Change{}
for k, v := range to {
id, err := r.GetID()
if err != nil {
return err
}
change := Change{
ID: id,
Key: key,
From: from[k],
To: v,
Field: k,
Timestamp: time.Now(),
IP: ip,
User: user,
}
changes = append(changes, change)
}
reply := a.client.MultiCall(func(mc *redis.MultiCall) {
for _, change := range changes {
user_str := ""
if change.User.ID != 0 {
user_str = strconv.FormatUint(change.User.ID, 10)
}
mc.Hmset("audit:"+change.Key+":item:"+strconv.FormatUint(change.ID, 10), "from", change.From, "to", change.To, "field", change.Field, "timestamp", change.Timestamp.Format(time.RFC3339), "user", user_str)
mc.Lpush("audit:"+key, change.ID)
}
})
return reply.Err
}
func (r *RequestBundle) Audit(key, field, fromstr, tostr string) {
if r.Auditor != nil {
from := map[string]interface{}{}
from[field] = fromstr
to := map[string]interface{}{}
to[field] = tostr
err := r.Auditor.Insert(r, key, r.Request.RemoteAddr, r.AuthUser, from, to)
if err != nil {
r.Log.Error(err.Error())
}
}
}
func (r *RequestBundle) AuditMap(key string, from, to map[string]interface{}) {
if r.Auditor != nil {
err := r.Auditor.Insert(r, key, r.Request.RemoteAddr, r.AuthUser, from, to)
if err != nil {
r.Log.Error(err.Error())
}
}
}