go-spectre/cmd/spectre/main.go

87 lines
1.9 KiB
Go

package main
import (
"flag"
"fmt"
"os"
"strings"
"go.jolheiser.com/go-spectre"
)
func main() {
fs := flag.NewFlagSet("spectre", flag.ExitOnError)
fs.Usage = func() {
fmt.Fprintln(fs.Output(), "spectre [FLAGS] [site]")
fs.PrintDefaults()
}
usernameFlag := fs.String("username", "", "username")
secretFlag := fs.String("secret", "", "secret")
counterFlag := fs.Int("counter", 1, "counter")
scoperFlag := fs.String("scoper", "com.lyndir.masterpassword", "scoper base")
scopeFlag := spectre.Authentication
fs.Func("scope", "scope", func(s string) (err error) {
scopeFlag, err = spectre.ParseScope(s)
return
})
var templateFlag spectre.Template
fs.Func("template", "template", func(s string) (err error) {
templateFlag, err = spectre.ParseTemplate(s)
return
})
if err := fs.Parse(os.Args[1:]); err != nil {
panic(err)
}
if err := checkEnv(fs); err != nil {
panic(err)
}
if templateFlag == "" {
templateFlag = scopeFlag.DefaultTemplate()
}
if *usernameFlag == "" || *secretFlag == "" || fs.NArg() < 1 {
panic("username, secret, and site are required")
}
s, err := spectre.New(*usernameFlag, *secretFlag, spectre.WithScoper(spectre.SimpleScoper{
Key: *scoperFlag,
}))
if err != nil {
panic(err)
}
pw := s.Site(fs.Arg(0),
spectre.WithScope(scopeFlag),
spectre.WithTemplate(templateFlag),
spectre.WithCounter(*counterFlag),
)
fmt.Println(pw)
}
func checkEnv(fs *flag.FlagSet) error {
provided := map[string]struct{}{}
fs.Visit(func(f *flag.Flag) {
provided[f.Name] = struct{}{}
})
var visitErr error
fs.VisitAll(func(f *flag.Flag) {
if visitErr != nil {
return
}
if _, ok := provided[f.Name]; ok {
return
}
env := os.Getenv(fmt.Sprintf("SPECTRE_%s", strings.ToUpper(f.Name)))
if env == "" {
return
}
if err := fs.Set(f.Name, env); err != nil {
visitErr = fmt.Errorf("could not set flag %q to %q", f.Name, env)
}
})
return nil
}