This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / spindle / models / secret_mask.go
1.8 kB 85 lines
1package models 2 3import ( 4 "encoding/base64" 5 "strings" 6) 7 8// SecretMask replaces secret values in strings with "***". 9type SecretMask struct { 10 replacer *strings.Replacer 11 // length of the longest secret. writers keep the last window-1 12 // bytes unflushed so a secret split across writes can still match 13 // whole 14 window int 15} 16 17// NewSecretMask creates a mask for the given secret values. 18// Also registers base64-encoded variants of each secret. 19func NewSecretMask(values []string) *SecretMask { 20 var pairs []string 21 add := func(value string) { 22 if value != "" { 23 pairs = append(pairs, value, "***") 24 } 25 } 26 27 for _, value := range values { 28 if value == "" { 29 continue 30 } 31 32 add(value) 33 // mask each non-empty line of a multiline secret 34 // output may split a secret over multiple log lines... 35 for _, line := range strings.FieldsFunc(value, func(r rune) bool { 36 return r == '\r' || r == '\n' 37 }) { 38 add(line) 39 } 40 41 b64 := base64.StdEncoding.EncodeToString([]byte(value)) 42 if b64 != value { 43 add(b64) 44 } 45 46 b64NoPad := strings.TrimRight(b64, "=") 47 if b64NoPad != b64 && b64NoPad != value { 48 add(b64NoPad) 49 } 50 } 51 52 if len(pairs) == 0 { 53 return nil 54 } 55 56 window := 0 57 for i := 0; i < len(pairs); i += 2 { 58 window = max(window, len(pairs[i])) 59 } 60 61 return &SecretMask{ 62 replacer: strings.NewReplacer(pairs...), 63 window: window, 64 } 65} 66 67// trailing bytes a streaming caller must keep unflushed so a secret 68// spanning a write boundary still matches 69func (m *SecretMask) Window() int { 70 if m == nil { 71 return 0 72 } 73 if m.window <= 1 { 74 return 0 75 } 76 return m.window - 1 77} 78 79// Mask replaces all registered secret values with "***". 80func (m *SecretMask) Mask(input string) string { 81 if m == nil || m.replacer == nil { 82 return input 83 } 84 return m.replacer.Replace(input) 85}