diff --git a/cmd/hack-browser-data/main.go b/cmd/hack-browser-data/main.go index 1e44a41..b480958 100644 --- a/cmd/hack-browser-data/main.go +++ b/cmd/hack-browser-data/main.go @@ -38,22 +38,20 @@ func Execute() { &cli.StringFlag{Name: "browser", Aliases: []string{"b"}, Destination: &browserName, Value: "all", Usage: "available browsers: all|" + strings.Join(browser.ListBrowser(), "|")}, &cli.StringFlag{Name: "results-dir", Aliases: []string{"dir"}, Destination: &outputDir, Value: "results", Usage: "export dir"}, &cli.StringFlag{Name: "format", Aliases: []string{"f"}, Destination: &outputFormat, Value: "csv", Usage: "format, csv|json|console"}, - &cli.StringFlag{Name: "profile-dir-path", Aliases: []string{"p"}, Destination: &profilePath, Value: "", Usage: "custom profile dir path, get with chrome://version"}, + &cli.StringFlag{Name: "profile-path", Aliases: []string{"p"}, Destination: &profilePath, Value: "", Usage: "custom profile dir path, get with chrome://version"}, }, HideHelpCommand: true, Action: func(c *cli.Context) error { if verbose { - log.InitLog("debug") + log.Init("debug") } else { - log.InitLog("error") + log.Init("error") } var ( browsers []browser.Browser err error ) - // if profilePath != "" { - // browsers, err = browser.PickBrowserByProfilePath(browserName, profilePath) - // } + log.Debugf("browser: %s", browserName) browsers, err = browser.PickBrowser(browserName, profilePath) if err != nil { log.Error(err) diff --git a/go.mod b/go.mod index d8c084f..8107b91 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,8 @@ go 1.18 require ( github.com/gocarina/gocsv v0.0.0-20211203214250-4735fba0c1d9 github.com/godbus/dbus/v5 v5.1.0 + github.com/gookit/color v1.5.0 + github.com/gookit/slog v0.2.2-0.20220415153407-dd89ed7b0448 github.com/json-iterator/go v1.1.12 github.com/mattn/go-sqlite3 v1.14.9 github.com/ppacher/go-dbus-keyring v1.0.1 @@ -15,11 +17,14 @@ require ( require ( github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect + github.com/gookit/goutil v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/stretchr/testify v1.7.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect + golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index 4572f41..de3aec9 100644 --- a/go.sum +++ b/go.sum @@ -10,10 +10,21 @@ github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gookit/color v1.5.0 h1:1Opow3+BWDwqor78DcJkJCIwnkviFi+rrOANki9BUFw= +github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= +github.com/gookit/goutil v0.4.4/go.mod h1:qlGVh0PI+WnWSjYnIocfz/7tkeogxL6+EDNP1mRe+7o= +github.com/gookit/goutil v0.5.0 h1:SrbfjqZ8iprxJOfKZVT0yGJ4/82afr4Qa0RQwON19I4= +github.com/gookit/goutil v0.5.0/go.mod h1:pq1eTibwb2wN96jrci0xy7xogWzzo9CihOQJEAvz4yQ= +github.com/gookit/slog v0.2.1 h1:EI47PlvpoPwxwkNTYaevN6iBNjo9nBxo0aQLiq+MTdk= +github.com/gookit/slog v0.2.1/go.mod h1:CsbWzAaZA2FjLuGzvfTAR/QvFisZG31deOcZ05H++NI= +github.com/gookit/slog v0.2.2-0.20220415153407-dd89ed7b0448 h1:7kNDAgYDAu/5X+PbFfzGToaKJiDcghKv7B4XOGosrPM= +github.com/gookit/slog v0.2.2-0.20220415153407-dd89ed7b0448/go.mod h1:9Sh1Utw3LVG0kqN++ankdfrCVQ7yixKDL1+YrYvIulU= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA= github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -27,8 +38,9 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tidwall/gjson v1.9.3 h1:hqzS9wAHMO+KVBBkLxYdkEeeFHuqr95GfClRLKlgK0E= github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -37,8 +49,23 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/urfave/cli/v2 v2.4.0 h1:m2pxjjDFgDxSPtO8WSdbndj17Wu2y8vOT86wE/tjr+I= github.com/urfave/cli/v2 v2.4.0/go.mod h1:NX9W0zmTvedE5oDoOMs2RTC8RvdK98NTYZE5LbaEYPg= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/browser/browser.go b/internal/browser/browser.go index 3104323..08c203b 100644 --- a/internal/browser/browser.go +++ b/internal/browser/browser.go @@ -36,40 +36,25 @@ func PickBrowser(name, profile string) ([]Browser, error) { return browsers, nil } -func PickBrowserByProfilePath(name, profile string) ([]Browser, error) { - var browsers []Browser - clist := pickChromium(name, profile) - for _, b := range clist { - if b != nil { - browsers = append(browsers, b) - } - } - flist := pickFirefox(name, profile) - for _, b := range flist { - if b != nil { - browsers = append(browsers, b) - } - } - return browsers, nil -} - func pickChromium(name, profile string) []Browser { var browsers []Browser name = strings.ToLower(name) // TODO: add support for 「all」 flag and set profilePath if name == "all" { - for _, c := range chromiumList { - if b, err := chromium.New(c.name, c.storage, c.profilePath, c.items); err == nil { + for _, v := range chromiumList { + if b, err := chromium.New(v.name, v.storage, v.profilePath, v.items); err == nil { + log.Infof("find browser %s success", b.Name()) browsers = append(browsers, b) } else { // TODO: show which browser find failed if strings.Contains(err.Error(), "profile path is not exist") { + log.Infof("find browser %s failed, profile path is not exist", v.name) continue + } else { + log.Error("new chromium error:", err) } - panic(err) } } - return browsers } if c, ok := chromiumList[name]; ok { if profile == "" { @@ -78,15 +63,14 @@ func pickChromium(name, profile string) []Browser { b, err := chromium.New(c.name, c.storage, profile, c.items) if err != nil { if strings.Contains(err.Error(), "profile path is not exist") { - log.Error(err.Error()) + log.Infof("find browser %s failed, profile path is not exist", c.name) } else { - panic(err) + log.Error("new chromium error:", err) } } browsers = append(browsers, b) - return browsers } - return nil + return browsers } func pickFirefox(name, profile string) []Browser { @@ -99,18 +83,19 @@ func pickFirefox(name, profile string) []Browser { } else { profile = fileutil.ParentDir(profile) } - multiFirefox, err := firefox.New(v.name, v.storage, profile, v.items) - // TODO: Handle error - if err != nil { + if multiFirefox, err := firefox.New(v.name, v.storage, profile, v.items); err == nil { + for _, b := range multiFirefox { + log.Infof("find browser: %s success", b.Name()) + browsers = append(browsers, b) + } + } else { if strings.Contains(err.Error(), "profile path is not exist") { - log.Error(err.Error()) + log.Infof("find browser: %s failed, profile path is not exist", v.name) } else { - panic(err) + log.Error(err) } } - for _, browser := range multiFirefox { - browsers = append(browsers, browser) - } + } return browsers } diff --git a/internal/browser/chromium/chromium_darwin.go b/internal/browser/chromium/chromium_darwin.go index 3fc247f..30f7772 100644 --- a/internal/browser/chromium/chromium_darwin.go +++ b/internal/browser/chromium/chromium_darwin.go @@ -11,6 +11,7 @@ import ( "golang.org/x/crypto/pbkdf2" "hack-browser-data/internal/item" + "hack-browser-data/internal/log" ) var ( @@ -52,5 +53,6 @@ func (c *chromium) GetMasterKey() ([]byte, error) { return nil, ErrWrongSecurityCommand } c.masterKey = key + log.Infof("%s initialized master key success", c.name) return key, nil } diff --git a/internal/browser/chromium/chromium_linux.go b/internal/browser/chromium/chromium_linux.go index f345b4e..6af3a81 100644 --- a/internal/browser/chromium/chromium_linux.go +++ b/internal/browser/chromium/chromium_linux.go @@ -64,5 +64,6 @@ func (c *chromium) GetMasterKey() ([]byte, error) { // @https://source.chromium.org/chromium/chromium/src/+/master:components/os_crypt/os_crypt_linux.cc key := pbkdf2.Key(chromiumSecret, chromiumSalt, 1, 16, sha1.New) c.masterKey = key + log.Infof("%s initialized master key success", c.name) return key, nil } diff --git a/internal/browser/chromium/chromium_windows.go b/internal/browser/chromium/chromium_windows.go index dfd00fe..44b0963 100644 --- a/internal/browser/chromium/chromium_windows.go +++ b/internal/browser/chromium/chromium_windows.go @@ -9,6 +9,7 @@ import ( "hack-browser-data/internal/decrypter" "hack-browser-data/internal/item" + "hack-browser-data/internal/log" "hack-browser-data/internal/utils/fileutil" ) @@ -29,6 +30,7 @@ func (c *chromium) GetMasterKey() ([]byte, error) { return nil, errDecodeMasterKeyFailed } c.masterKey, err = decrypter.DPApi(pureKey[5:]) + log.Infof("%s initialized master key success", c.name) return c.masterKey, err } return nil, nil diff --git a/internal/log/log.go b/internal/log/log.go index c03e23a..d6a8688 100644 --- a/internal/log/log.go +++ b/internal/log/log.go @@ -1,107 +1,119 @@ package log import ( - "fmt" - "io" - "log" "os" -) - -type Level int -const ( - LevelDebug Level = iota - LevelWarn - LevelError + "github.com/gookit/color" + "github.com/gookit/slog" ) -func (l Level) String() string { - switch l { - case LevelDebug: - return "debug" - case LevelError: - return "error" +var std = &slog.SugaredLogger{} + +func Init(l string) { + if l == "debug" { + std = newStdLogger(slog.DebugLevel) + } else { + std = newStdLogger(slog.ErrorLevel) } - return "" } -var ( - formatLogger *Logger - levelMap = map[string]Level{ - "debug": LevelDebug, - "error": LevelError, - } -) +const template = "[{{datetime}}] [{{level}}] [{{caller}}] {{message}} {{data}} {{extra}}\n" + +// NewStdLogger instance +func newStdLogger(level slog.Level) *slog.SugaredLogger { + return slog.NewSugaredLogger(os.Stdout, level).Configure(func(sl *slog.SugaredLogger) { + sl.SetName("stdLogger") + sl.ReportCaller = true + sl.CallerSkip = 3 + // auto enable console color + sl.Formatter.(*slog.TextFormatter).EnableColor = color.SupportColor() + sl.Formatter.(*slog.TextFormatter).SetTemplate(template) + }) +} -func InitLog(l string) { - formatLogger = newLog(os.Stdout).setLevel(levelMap[l]).setFlags(log.Lshortfile) +// Trace logs a message at level Trace +func Trace(args ...interface{}) { + std.Log(slog.TraceLevel, args...) } -type Logger struct { - level Level - l *log.Logger +// Tracef logs a message at level Trace +func Tracef(format string, args ...interface{}) { + std.Logf(slog.TraceLevel, format, args...) } -func newLog(w io.Writer) *Logger { - return &Logger{ - l: log.New(w, "", 0), - } +// Info logs a message at level Info +func Info(args ...interface{}) { + std.Log(slog.InfoLevel, args...) } -func (l *Logger) setFlags(flag int) *Logger { - l.l.SetFlags(flag) - return l +// Infof logs a message at level Info +func Infof(format string, args ...interface{}) { + std.Logf(slog.InfoLevel, format, args...) } -func (l *Logger) setLevel(level Level) *Logger { - l.level = level - return l +// Notice logs a message at level Notice +func Notice(args ...interface{}) { + std.Log(slog.NoticeLevel, args...) } -func (l *Logger) doLog(level Level, v ...interface{}) bool { - if level < l.level { - return false - } - l.l.Output(3, level.String()+" "+fmt.Sprintln(v...)) - return true +// Noticef logs a message at level Notice +func Noticef(format string, args ...interface{}) { + std.Logf(slog.NoticeLevel, format, args...) } -func (l *Logger) doLogf(level Level, format string, v ...interface{}) bool { - if level < l.level { - return false +// Warn logs a message at level Warn +func Warn(args ...interface{}) { + std.Log(slog.WarnLevel, args...) +} + +// Warnf logs a message at level Warn +func Warnf(format string, args ...interface{}) { + std.Logf(slog.WarnLevel, format, args...) +} + +// Error logs a message at level Error +func Error(args ...interface{}) { + std.Log(slog.ErrorLevel, args...) +} + +// ErrorT logs a error type at level Error +func ErrorT(err error) { + if err != nil { + std.Log(slog.ErrorLevel, err) } - l.l.Output(3, level.String()+" "+fmt.Sprintln(fmt.Sprintf(format, v...))) - return true } -func Debug(v ...interface{}) { - formatLogger.doLog(LevelDebug, v...) +// Errorf logs a message at level Error +func Errorf(format string, args ...interface{}) { + std.Logf(slog.ErrorLevel, format, args...) } -func Warn(v ...interface{}) { - formatLogger.doLog(LevelWarn, v...) +// Debug logs a message at level Debug +func Debug(args ...interface{}) { + std.Log(slog.DebugLevel, args...) } -func Error(v ...interface{}) { - formatLogger.doLog(LevelError, v...) +// Debugf logs a message at level Debug +func Debugf(format string, args ...interface{}) { + std.Logf(slog.DebugLevel, format, args...) } -func Errorf(format string, v ...interface{}) { - formatLogger.doLogf(LevelError, format, v...) +// Fatal logs a message at level Fatal +func Fatal(args ...interface{}) { + std.Log(slog.FatalLevel, args...) } -func Warnf(format string, v ...interface{}) { - formatLogger.doLogf(LevelWarn, format, v...) +// Fatalf logs a message at level Fatal +func Fatalf(format string, args ...interface{}) { + std.Logf(slog.FatalLevel, format, args...) } -func Debugf(format string, v ...interface{}) { - formatLogger.doLogf(LevelDebug, format, v...) +// Panic logs a message at level Panic +func Panic(args ...interface{}) { + std.Log(slog.PanicLevel, args...) } -// NewSugaredLogger(os.Stdout, DebugLevel).Configure(func(sl *SugaredLogger) { -// sl.SetName("stdLogger") -// sl.ReportCaller = true -// // auto enable console color -// sl.Formatter.(*TextFormatter).EnableColor = color.SupportColor() -// sl.Formatter.SetCallerSkip(1) -// }) +// Panicf logs a message at level Panic +func Panicf(format string, args ...interface{}) { + std.Logf(slog.PanicLevel, format, args...) +}