github.com/drone/runner-go@v1.12.0/pipeline/runtime/replacer.go (about) 1 // Copyright 2019 Drone.IO Inc. All rights reserved. 2 // Use of this source code is governed by the Polyform License 3 // that can be found in the LICENSE file. 4 5 package runtime 6 7 import ( 8 "io" 9 "strings" 10 ) 11 12 // replacer is an io.Writer that finds and masks sensitive data. 13 type replacer struct { 14 w io.WriteCloser 15 r *strings.Replacer 16 } 17 18 // newReplacer returns a replacer that wraps io.Writer w. 19 func newReplacer(w io.WriteCloser, secrets []Secret) io.WriteCloser { 20 var oldnew []string 21 for _, secret := range secrets { 22 v := secret.GetValue() 23 if len(v) == 0 || secret.IsMasked() == false { 24 continue 25 } 26 27 for _, part := range strings.Split(v, "\n") { 28 part = strings.TrimSpace(part) 29 30 // avoid masking empty or single character 31 // strings. 32 if len(part) < 2 { 33 continue 34 } 35 36 masked := "******" 37 oldnew = append(oldnew, part) 38 oldnew = append(oldnew, masked) 39 } 40 } 41 if len(oldnew) == 0 { 42 return w 43 } 44 return &replacer{ 45 w: w, 46 r: strings.NewReplacer(oldnew...), 47 } 48 } 49 50 // Write writes p to the base writer. The method scans for any 51 // sensitive data in p and masks before writing. 52 func (r *replacer) Write(p []byte) (n int, err error) { 53 _, err = r.w.Write([]byte(r.r.Replace(string(p)))) 54 return len(p), err 55 } 56 57 // Close closes the base writer. 58 func (r *replacer) Close() error { 59 return r.w.Close() 60 }