github.com/arunkumar7540/cli@v6.45.0+incompatible/util/ui/sanitize_json.go (about) 1 package ui 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "regexp" 8 ) 9 10 // tokenEndpoint is explicitly excluded from sanitization 11 const tokenEndpoint = "token_endpoint" 12 13 var keysToSanitize = regexp.MustCompile("(?i)token|password") 14 var sanitizeURIParams = regexp.MustCompile(`([&?]password)=[A-Za-z0-9\-._~!$'()*+,;=:@/?]*`) 15 var sanitizeURLPassword = regexp.MustCompile(`([\d\w]+):\/\/([^:]+):(?:[^@]+)@`) 16 17 func SanitizeJSON(raw []byte) ([]byte, error) { 18 var result interface{} 19 decoder := json.NewDecoder(bytes.NewBuffer(raw)) 20 decoder.UseNumber() 21 err := decoder.Decode(&result) 22 if err != nil { 23 return nil, err 24 } 25 26 sanitized := iterateAndRedact(result) 27 28 buff := new(bytes.Buffer) 29 encoder := json.NewEncoder(buff) 30 encoder.SetEscapeHTML(false) 31 encoder.SetIndent("", " ") 32 err = encoder.Encode(sanitized) 33 if err != nil { 34 return nil, err 35 } 36 37 return buff.Bytes(), nil 38 } 39 40 func iterateAndRedact(blob interface{}) interface{} { 41 switch v := blob.(type) { 42 case string: 43 return sanitizeURL(v) 44 case []interface{}: 45 var list []interface{} 46 for _, val := range v { 47 list = append(list, iterateAndRedact(val)) 48 } 49 50 return list 51 case map[string]interface{}: 52 for key, value := range v { 53 if keysToSanitize.MatchString(key) && key != tokenEndpoint { 54 v[key] = RedactedValue 55 } else { 56 v[key] = iterateAndRedact(value) 57 } 58 } 59 return v 60 } 61 return blob 62 } 63 64 func sanitizeURL(rawURL string) string { 65 sanitized := sanitizeURLPassword.ReplaceAllString(rawURL, fmt.Sprintf("$1://$2:%s@", RedactedValue)) 66 sanitized = sanitizeURIParams.ReplaceAllString(sanitized, fmt.Sprintf("$1=%s", RedactedValue)) 67 return sanitized 68 }