-
Notifications
You must be signed in to change notification settings - Fork 11
/
template-each.go
118 lines (101 loc) · 3.55 KB
/
template-each.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
// Copyright (C) 2021 CGI France
//
// This file is part of PIMO.
//
// PIMO is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// PIMO is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with PIMO. If not, see <http://www.gnu.org/licenses/>.
package templateeach
import (
"bytes"
"strings"
"text/template"
"unicode"
sprig "github.com/Masterminds/sprig/v3"
"github.com/cgi-fr/pimo/pkg/model"
"github.com/rs/zerolog/log"
"golang.org/x/text/runes"
"golang.org/x/text/transform"
"golang.org/x/text/unicode/norm"
)
// MaskEngine is to mask a value thanks to a template
type MaskEngine struct {
template *template.Template
itemName string
indexName string
}
// rmAcc removes accents from string
// Function derived from: http://blog.golang.org/normalization
func rmAcc(s string) string {
t := transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC)
result, _, _ := transform.String(t, s)
return result
}
// NewMask create a MaskEngine
func NewMask(text string, itemName string, indexName string, funcMap template.FuncMap) (MaskEngine, error) {
funcMap["ToUpper"] = strings.ToUpper
funcMap["ToLower"] = strings.ToLower
funcMap["NoAccent"] = rmAcc
temp, err := template.New("template-each").Funcs(sprig.TxtFuncMap()).Funcs(funcMap).Parse(text)
if len(itemName) == 0 {
itemName = "it"
}
return MaskEngine{temp, itemName, indexName}, err
}
// Mask masks a value with a template
func (tmpl MaskEngine) MaskContext(context model.Dictionary, key string, contexts ...model.Dictionary) (model.Dictionary, error) {
log.Info().Msg("Mask template-each")
log.Trace().Interface("input", context).Str("key", key).Interface("contexts", contexts).Msg("Enter MaskContext")
copy := model.CopyDictionary(context)
var tmplctx map[string]model.Entry
if dict, ok := contexts[0].TryUnpackAsDict(); ok {
tmplctx = dict.Unordered()
} else {
tmplctx = contexts[0].Unordered()
}
value, ok := copy.GetValue(key)
if ok {
switch typedVal := model.CleanTypes(value).(type) {
case []model.Entry:
result := []model.Entry{}
for idx, item := range typedVal {
tmplctx[tmpl.itemName] = item
if len(tmpl.indexName) > 0 {
tmplctx[tmpl.indexName] = idx + 1
}
var output bytes.Buffer
if err := tmpl.template.Execute(&output, tmplctx); err != nil {
return copy, err
}
result = append(result, output.String())
}
copy.Set(key, result)
default:
log.Debug().Str("key", key).Msg("Mask template-each - value is not an array, ignored masking")
}
} else {
log.Debug().Str("key", key).Msg("Mask template-each - key is not present in context, ignored masking")
}
log.Trace().Interface("output", copy).Str("key", key).Msg("Exit MaskContext")
return copy, nil
}
// Factory create a mask from a yaml config
func Factory(conf model.MaskFactoryConfiguration) (model.MaskContextEngine, bool, error) {
if len(conf.Masking.Mask.TemplateEach.Template) != 0 {
mask, err := NewMask(conf.Masking.Mask.TemplateEach.Template, conf.Masking.Mask.TemplateEach.Item, conf.Masking.Mask.TemplateEach.Index, conf.Functions)
if err != nil {
return nil, false, err
}
return mask, true, nil
}
return nil, false, nil
}