Repository navigation
Expand file tree
/
Copy pathredact.go
More file actions
67 lines (54 loc) · 1.65 KB
/
Copy pathredact.go
File metadata and controls
67 lines (54 loc) · 1.65 KB
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
package sensitive
import (
"errors"
"github.com/ln80/struct-sensitive/internal/option"
)
var (
ErrRedactFuncNotFound = errors.New("redact function not found")
)
// RedactConfig holds the configuration for [Redact].
type RedactConfig struct {
// RequireSubjectID force the subjectID resolution from the struct value.
// This config is disabled by default.
RequireSubjectID bool
// RedactFunc overrides the default redaction function `RedactDefaultFunc`.
RedactFunc ReplaceFunc
// fieldErrs collects per-field failures that were replaced with full redaction.
fieldErrs []error
}
// Redact redacts sensitive data from struct field values by replacing each character with '*'.
//
// It returns an error if the value is not a struct pointer, the 'sensitive' tag is misconfigured,
// or if the redact function is nil.
//
// Optionally, you can override the default redact function by passing a custom one.
func Redact(structPtr any, opts ...func(*RedactConfig)) (err error) {
defer catchPanic(&err)
cfg := RedactConfig{
RedactFunc: RedactDefaultFunc,
}
option.Apply(&cfg, opts)
if cfg.RedactFunc == nil {
return ErrRedactFuncNotFound
}
accessor, err := Scan(structPtr, cfg.RequireSubjectID)
if err != nil {
return err
}
if !accessor.HasSensitive() {
return nil
}
if err = accessor.Replace(cfg.RedactFunc); err != nil {
return err
}
return errors.Join(cfg.fieldErrs...)
}
// Redacted is the fixed placeholder written by RedactDefaultFunc.
// It does not preserve the length of the original value.
const Redacted = "***"
func RedactDefaultFunc(_ FieldReplace, val string) (string, error) {
if val == "" {
return "", nil
}
return Redacted, nil
}