Add basic form of log redaction for user names and passwords (#1810)
This commit is contained in:
parent
cbadd13db1
commit
ca3f793eb1
30 changed files with 92 additions and 36 deletions
|
|
@ -75,7 +75,7 @@ func NewEaseeFromConfig(other map[string]interface{}) (api.Charger, error) {
|
|||
|
||||
// NewEasee creates Easee charger
|
||||
func NewEasee(user, password, charger string, circuit int, cache time.Duration) (*Easee, error) {
|
||||
log := util.NewLogger("easee")
|
||||
log := util.NewLogger("easee").Redact(user, password)
|
||||
|
||||
if !sponsor.IsAuthorized() {
|
||||
return nil, api.ErrSponsorRequired
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ func NewGoEFromConfig(other map[string]interface{}) (api.Charger, error) {
|
|||
func NewGoE(uri, token string, cache time.Duration) (api.Charger, error) {
|
||||
c := &GoE{}
|
||||
|
||||
log := util.NewLogger("go-e")
|
||||
log := util.NewLogger("go-e").Redact(token)
|
||||
|
||||
if token != "" {
|
||||
c.api = goe.NewCloud(log, token, cache)
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ func NewDiscovergyFromConfig(other map[string]interface{}) (api.Meter, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
log := util.NewLogger("discgy")
|
||||
log := util.NewLogger("discgy").Redact(cc.User, cc.Password, cc.Meter)
|
||||
|
||||
client := request.NewHelper(log)
|
||||
client.Transport = basicauth.NewTransport(cc.User, cc.Password, client.Transport)
|
||||
|
||||
|
|
|
|||
|
|
@ -19,5 +19,6 @@ func NewFritzDECTFromConfig(other map[string]interface{}) (api.Meter, error) {
|
|||
if err := util.DecodeOther(other, &cc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return fritzdect.NewConnection(cc.URI, cc.AIN, cc.User, cc.Password)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ func NewSMAFromConfig(other map[string]interface{}) (api.Meter, error) {
|
|||
// NewSMA creates a SMA Meter
|
||||
func NewSMA(uri, password, iface string, serial uint32, scale float64) (api.Meter, error) {
|
||||
sm := &SMA{
|
||||
log: util.NewLogger("sma"),
|
||||
log: util.NewLogger("sma").Redact(password),
|
||||
uri: uri,
|
||||
scale: scale,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ func NewTeslaFromConfig(other map[string]interface{}) (api.Meter, error) {
|
|||
|
||||
// NewTesla creates a Tesla Meter
|
||||
func NewTesla(uri, usage, password string) (api.Meter, error) {
|
||||
log := util.NewLogger("tesla")
|
||||
log := util.NewLogger("tesla").Redact(password)
|
||||
|
||||
m := &Tesla{
|
||||
Helper: request.NewHelper(log),
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ func NewConnection(uri, ain, user, password string) (*Connection, error) {
|
|||
Password: password,
|
||||
}
|
||||
|
||||
log := util.NewLogger("fritzdect")
|
||||
log := util.NewLogger("fritzdect").Redact(password)
|
||||
|
||||
fritzdect := &Connection{
|
||||
Helper: request.NewHelper(log),
|
||||
|
|
|
|||
18
util/log.go
18
util/log.go
|
|
@ -3,7 +3,6 @@ package util
|
|||
import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
|
@ -32,6 +31,7 @@ var LogAreaPadding = 6
|
|||
type Logger struct {
|
||||
*jww.Notepad
|
||||
name string
|
||||
*Redactor
|
||||
}
|
||||
|
||||
// NewLogger creates a logger with the given log area and adds it to the registry
|
||||
|
|
@ -49,13 +49,17 @@ func NewLogger(area string) *Logger {
|
|||
}
|
||||
|
||||
level := LogLevelForArea(area)
|
||||
notepad := jww.NewNotepad(level, level, os.Stdout, io.Discard, padded, log.Ldate|log.Ltime)
|
||||
redactor := new(Redactor)
|
||||
notepad := jww.NewNotepad(level, level, redactor, io.Discard, padded, log.Ldate|log.Ltime)
|
||||
|
||||
logger := &Logger{
|
||||
Notepad: notepad,
|
||||
name: area,
|
||||
Notepad: notepad,
|
||||
Redactor: redactor,
|
||||
name: area,
|
||||
}
|
||||
|
||||
loggers[area] = logger
|
||||
|
||||
return logger
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +68,12 @@ func (l *Logger) Name() string {
|
|||
return l.name
|
||||
}
|
||||
|
||||
// Redact adds items for redaction
|
||||
func (l *Logger) Redact(items ...string) *Logger {
|
||||
l.Redactor.Redact(items...)
|
||||
return l
|
||||
}
|
||||
|
||||
// Loggers invokes callback for each configured logger
|
||||
func Loggers(cb func(string, *Logger)) {
|
||||
for name, logger := range loggers {
|
||||
|
|
|
|||
42
util/redactor.go
Normal file
42
util/redactor.go
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/url"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
// RedactReplacement is the default replacement string
|
||||
RedactReplacement = "***"
|
||||
|
||||
// RedactHook is the hook for expanding different representations of
|
||||
// redaction items. Setting to nil will disable redaction.
|
||||
RedactHook = RedactDefaultHook
|
||||
)
|
||||
|
||||
// Redactor implements a redacting io.Writer
|
||||
type Redactor struct {
|
||||
redact []string
|
||||
}
|
||||
|
||||
// Redact adds items for redaction
|
||||
func (l *Redactor) Redact(redact ...string) {
|
||||
for _, s := range redact {
|
||||
if RedactHook != nil && len(s) > 0 {
|
||||
l.redact = append(l.redact, RedactHook(s)...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Redactor) Write(p []byte) (n int, err error) {
|
||||
for _, s := range l.redact {
|
||||
p = bytes.ReplaceAll(p, []byte(s), []byte(RedactReplacement))
|
||||
}
|
||||
return os.Stdout.Write(p)
|
||||
}
|
||||
|
||||
// RedactDefaultHook expands a redaction item to include URL encoding
|
||||
func RedactDefaultHook(s string) []string {
|
||||
return []string{s, url.QueryEscape(s)}
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ func NewAudiFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
embed: &cc.embed,
|
||||
}
|
||||
|
||||
log := util.NewLogger("audi")
|
||||
log := util.NewLogger("audi").Redact(cc.User, cc.Password, cc.VIN)
|
||||
identity := vw.NewIdentity(log)
|
||||
|
||||
query := url.Values(map[string][]string{
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ func NewBMWFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
embed: &cc.embed,
|
||||
}
|
||||
|
||||
log := util.NewLogger("bmw")
|
||||
log := util.NewLogger("bmw").Redact(cc.User, cc.Password, cc.VIN)
|
||||
identity := bmw.NewIdentity(log)
|
||||
|
||||
if err := identity.Login(cc.User, cc.Password); err != nil {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
carwingsRequestTimeout = 90 * time.Second
|
||||
carwingsStatusExpiry = 5 * time.Minute // if returned status value is older, evcc will init refresh
|
||||
carwingsRefreshTimeout = 2 * time.Minute // timeout to get status after refresh
|
||||
)
|
||||
|
|
@ -54,17 +55,16 @@ func NewCarWingsFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
return nil, errors.New("missing credentials")
|
||||
}
|
||||
|
||||
// http client with high dial/handshake timeout
|
||||
const timeout = 90 * time.Second
|
||||
log := util.NewLogger("carwings")
|
||||
log := util.NewLogger("carwings").Redact(cc.User, cc.Password, cc.VIN)
|
||||
|
||||
// http client with high dial/handshake timeout
|
||||
transport := request.NewTripper(log, &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment, // default
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: timeout,
|
||||
Timeout: carwingsRequestTimeout,
|
||||
KeepAlive: 30 * time.Second, // default
|
||||
}).DialContext,
|
||||
TLSHandshakeTimeout: timeout,
|
||||
TLSHandshakeTimeout: carwingsRequestTimeout,
|
||||
ForceAttemptHTTP2: true, // default
|
||||
MaxIdleConns: 100, // default
|
||||
IdleConnTimeout: 90 * time.Second, // default
|
||||
|
|
@ -72,7 +72,7 @@ func NewCarWingsFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
})
|
||||
|
||||
carwings.Client = &http.Client{
|
||||
Timeout: timeout,
|
||||
Timeout: carwingsRequestTimeout,
|
||||
Transport: transport,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ func NewEnyaqFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
}
|
||||
|
||||
var err error
|
||||
log := util.NewLogger("enyaq")
|
||||
log := util.NewLogger("enyaq").Redact(cc.User, cc.Password, cc.VIN)
|
||||
|
||||
if cc.VIN == "" {
|
||||
identity := vw.NewIdentity(log)
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ func NewFiatFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
embed: &cc.embed,
|
||||
}
|
||||
|
||||
log := util.NewLogger("fiat")
|
||||
log := util.NewLogger("fiat").Redact(cc.User, cc.Password, cc.VIN)
|
||||
identity := fiat.NewIdentity(log, cc.User, cc.Password)
|
||||
|
||||
err := identity.Login()
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ func NewFordFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
return nil, errors.New("missing credentials")
|
||||
}
|
||||
|
||||
log := util.NewLogger("ford")
|
||||
log := util.NewLogger("ford").Redact(cc.User, cc.Password, cc.VIN)
|
||||
|
||||
v := &Ford{
|
||||
embed: &cc.embed,
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ func NewHyundaiFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
return nil, errors.New("missing credentials")
|
||||
}
|
||||
|
||||
log := util.NewLogger("hyundai")
|
||||
log := util.NewLogger("hyundai").Redact(cc.User, cc.Password, cc.VIN)
|
||||
|
||||
settings := bluelink.Config{
|
||||
URI: "https://prd.eu-ccapi.hyundai.com:8080",
|
||||
BasicToken: "NmQ0NzdjMzgtM2NhNC00Y2YzLTk1NTctMmExOTI5YTk0NjU0OktVeTQ5WHhQekxwTHVvSzB4aEJDNzdXNlZYaG10UVI5aVFobUlGampvWTRJcHhzVg==",
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ func NewIDFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
embed: &cc.embed,
|
||||
}
|
||||
|
||||
log := util.NewLogger("id")
|
||||
log := util.NewLogger("id").Redact(cc.User, cc.Password, cc.VIN)
|
||||
identity := vw.NewIdentity(log)
|
||||
|
||||
query := url.Values(map[string][]string{
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ func NewKiaFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
return nil, errors.New("missing credentials")
|
||||
}
|
||||
|
||||
log := util.NewLogger("kia")
|
||||
log := util.NewLogger("kia").Redact(cc.User, cc.Password, cc.VIN)
|
||||
|
||||
settings := bluelink.Config{
|
||||
URI: "https://prd.eu-ccapi.kia.com:8080",
|
||||
BasicToken: "ZmRjODVjMDAtMGEyZi00YzY0LWJjYjQtMmNmYjE1MDA3MzBhOnNlY3JldA==",
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ func NewNissanFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
embed: &cc.embed,
|
||||
}
|
||||
|
||||
log := util.NewLogger("nissan")
|
||||
log := util.NewLogger("nissan").Redact(cc.User, cc.Password, cc.VIN)
|
||||
identity := nissan.NewIdentity(log)
|
||||
|
||||
if err := identity.Login(cc.User, cc.Password); err != nil {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ func NewNiuFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
return nil, errors.New("missing user, password or serial")
|
||||
}
|
||||
|
||||
log := util.NewLogger("niu")
|
||||
log := util.NewLogger("niu").Redact(cc.User, cc.Password)
|
||||
|
||||
v := &Niu{
|
||||
embed: &cc.embed,
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ func NewOvmsFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
log := util.NewLogger("ovms")
|
||||
log := util.NewLogger("ovms").Redact(cc.User, cc.Password, cc.VehicleID)
|
||||
|
||||
v := &Ovms{
|
||||
embed: &cc.embed,
|
||||
|
|
|
|||
|
|
@ -38,12 +38,11 @@ func NewPorscheFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
Cache: interval,
|
||||
}
|
||||
|
||||
log := util.NewLogger("porsche")
|
||||
|
||||
if err := util.DecodeOther(other, &cc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log := util.NewLogger("porsche").Redact(cc.User, cc.Password, cc.VIN)
|
||||
identity := porsche.NewIdentity(log, cc.User, cc.Password)
|
||||
|
||||
accessTokens, err := identity.Login()
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ func newPSA(log *util.Logger, brand, realm, id, secret string, other map[string]
|
|||
embed: &cc.embed,
|
||||
}
|
||||
|
||||
log.Redact(cc.User, cc.Password, cc.VIN)
|
||||
identity := psa.NewIdentity(log, brand, cc.Credentials.ID, cc.Credentials.Secret)
|
||||
|
||||
if err := identity.Login(cc.User, cc.Password); err != nil {
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ func NewRenaultFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
log := util.NewLogger("renault")
|
||||
log := util.NewLogger("renault").Redact(cc.User, cc.Password, cc.VIN)
|
||||
|
||||
v := &Renault{
|
||||
embed: &cc.embed,
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ func NewSeatFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
embed: &cc.embed,
|
||||
}
|
||||
|
||||
log := util.NewLogger("seat")
|
||||
log := util.NewLogger("seat").Redact(cc.User, cc.Password, cc.VIN)
|
||||
identity := vw.NewIdentity(log)
|
||||
|
||||
query := url.Values(map[string][]string{
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ func NewSkodaFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
embed: &cc.embed,
|
||||
}
|
||||
|
||||
log := util.NewLogger("skoda")
|
||||
log := util.NewLogger("skoda").Redact(cc.User, cc.Password, cc.VIN)
|
||||
identity := vw.NewIdentity(log)
|
||||
|
||||
query := url.Values(map[string][]string{
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ func NewTeslaFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
}
|
||||
|
||||
// authenticated http client with logging injected to the Tesla client
|
||||
log := util.NewLogger("tesla")
|
||||
log := util.NewLogger("tesla").Redact(cc.Tokens.Access, cc.Tokens.Refresh)
|
||||
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, request.NewHelper(log).Client)
|
||||
|
||||
options := []tesla.ClientOption{tesla.WithToken(&oauth2.Token{
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ func NewTronityFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
}
|
||||
|
||||
// authenticated http client with logging injected to the tronity client
|
||||
log := util.NewLogger("tronity")
|
||||
log := util.NewLogger("tronity").Redact(cc.Credentials.ID, cc.Credentials.Secret)
|
||||
|
||||
oc, err := tronity.OAuth2Config(cc.Credentials.ID, cc.Credentials.Secret)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ func NewVolvoFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
log := util.NewLogger("volvo")
|
||||
log := util.NewLogger("volvo").Redact(cc.User, cc.Password, cc.VIN)
|
||||
|
||||
v := &Volvo{
|
||||
embed: &cc.embed,
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ func NewVWFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
embed: &cc.embed,
|
||||
}
|
||||
|
||||
log := util.NewLogger("vw")
|
||||
log := util.NewLogger("vw").Redact(cc.User, cc.Password, cc.VIN)
|
||||
identity := vw.NewIdentity(log)
|
||||
|
||||
query := url.Values(map[string][]string{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue