-
Notifications
You must be signed in to change notification settings - Fork 9
/
mask.go
66 lines (59 loc) · 1.56 KB
/
mask.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
// Copyright Kuei-chun Chen, 2022-present. All rights reserved.
package hummingbird
import (
"regexp"
"strings"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
const (
// MaskDefault uses default masking method
MaskDefault = "default"
// MaskHEX uses HEX masking method
MaskHEX = "hex"
// MaskPartial uses partial masking method
MaskPartial = "partial"
)
// MaskFields mask all matched fields by traversing a doc
func MaskFields(doc *bson.D, fields []string, method string) {
for _, field := range fields {
elems := strings.Split(field, ".")
maskDoc(*doc, elems, method)
}
}
func maskDoc(doc bson.D, elems []string, method string) {
elem := elems[0]
elems = elems[1:]
for i, v := range doc {
if v.Key == elem {
if len(elems) == 0 {
doc[i].Value = getMaskedValue(doc[i].Value, method)
} else if bsonD, ok := doc[i].Value.(bson.D); ok {
maskDoc(bsonD, elems, method)
} else if bsonA, ok := doc[i].Value.(bson.A); ok {
for _, val := range bsonA {
if bsonD, ok = val.(bson.D); ok {
maskDoc(bsonD, elems, method)
}
}
}
return
}
}
}
func getMaskedValue(v interface{}, method string) interface{} {
switch s := v.(type) {
case string:
if method == MaskPartial && len(s) > 4 {
reg, _ := regexp.Compile("[a-zA-Z0-9]")
return reg.ReplaceAllString(s[:len(s)-4], "X") + s[len(s)-4:]
} else if method == MaskHEX {
return primitive.NewObjectID().Hex()
} else { // maskDefault
reg, _ := regexp.Compile("[a-zA-Z0-9]")
return reg.ReplaceAllString(s, "X")
}
default:
return v
}
}