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  }