summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2022-08-07 00:43:59 +0700
committerShulhan <ms@kilabit.info>2022-08-07 00:43:59 +0700
commit06016118084334cb22ee1455a7f3786c6162673a (patch)
treec278c6c4fc327b2d16313eebdb4bff8d1aeaae25
parent25809666ff0050b10e786714ae97c0c00df48918 (diff)
downloadgotp-06016118084334cb22ee1455a7f3786c6162673a.tar.xz
all: clean up code
Changes, * Replace variable declaration ":=" using explicit one * Use raw string literal whenever possible * Realign struct Config from 56 to 40 bytes (-16 bytes) * Realign struct Issuer from 88 to 72 bytes (-16 bytes)
-rw-r--r--cli.go141
-rw-r--r--cli_test.go99
-rw-r--r--cmd/gotp/main.go120
-rw-r--r--config.go53
-rw-r--r--config_test.go34
-rw-r--r--gotp.go22
-rw-r--r--issuer.go57
-rw-r--r--provider_aegis.go47
8 files changed, 340 insertions, 233 deletions
diff --git a/cli.go b/cli.go
index f22e626..c9cccf4 100644
--- a/cli.go
+++ b/cli.go
@@ -28,39 +28,42 @@ type Cli struct {
func NewCli() (cli *Cli, err error) {
var (
- logp = "NewCli"
+ logp = `NewCli`
+
+ userConfigDir string
+ cfgFile string
)
cli = &Cli{}
- userConfigDir, err := os.UserConfigDir()
+ userConfigDir, err = os.UserConfigDir()
if err != nil {
- return nil, fmt.Errorf("%s: UserConfigDir: %w", logp, err)
+ return nil, fmt.Errorf(`%s: UserConfigDir: %w`, logp, err)
}
- cfgFile := filepath.Join(userConfigDir, configDir, configFile)
+ cfgFile = filepath.Join(userConfigDir, configDir, configFile)
cli.cfg, err = newConfig(cfgFile)
if err != nil {
- return nil, fmt.Errorf("%s: UserConfigDir: %w", logp, err)
+ return nil, fmt.Errorf(`%s: UserConfigDir: %w`, logp, err)
}
if cli.cfg.isNotExist {
cli.cfg.PrivateKey, err = cli.inputPrivateKey(os.Stdin)
if err != nil {
- return nil, fmt.Errorf("%s: %w", logp, err)
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
}
}
if len(cli.cfg.PrivateKey) > 0 {
cli.cfg.privateKey, err = cli.loadPrivateKey(cli.cfg.PrivateKey, nil)
if err != nil {
- return nil, fmt.Errorf("%s: %w", logp, err)
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
}
}
if cli.cfg.isNotExist {
err = cli.cfg.save()
if err != nil {
- return nil, fmt.Errorf("%s: %w", logp, err)
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
}
}
@@ -68,17 +71,15 @@ func NewCli() (cli *Cli, err error) {
}
func (cli *Cli) inputPrivateKey(stdin *os.File) (privateKeyFile string, err error) {
- fmt.Printf("Seems like this is your first time using this gotp.\n")
- fmt.Printf("If you would like to encrypt the secret, please\n")
- fmt.Printf("enter the path to private key or enter to skip it: ")
+ fmt.Println(`Seems like this is your first time using this gotp.`)
+ fmt.Println(`If you would like to encrypt the secret, please`)
+ fmt.Printf(`enter the path to private key or enter to skip it: `)
fmt.Fscanln(stdin, &privateKeyFile)
return privateKeyFile, nil
}
-//
// loadPrivateKey parse the RSA private key with optional passphrase.
-//
func (cli *Cli) loadPrivateKey(privateKeyFile string, pass []byte) (
rsaPrivateKey *rsa.PrivateKey, err error,
) {
@@ -87,14 +88,18 @@ func (cli *Cli) loadPrivateKey(privateKeyFile string, pass []byte) (
}
var (
- logp = "loadPrivateKey"
+ logp = `loadPrivateKey`
+ errPassMissing = &ssh.PassphraseMissingError{}
+
privateKey interface{}
+ stdin int
+ rawPem []byte
ok bool
)
- rawPem, err := os.ReadFile(privateKeyFile)
+ rawPem, err = os.ReadFile(privateKeyFile)
if err != nil {
- return nil, fmt.Errorf("%s: %w", logp, err)
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
}
if len(pass) == 0 {
@@ -103,48 +108,48 @@ func (cli *Cli) loadPrivateKey(privateKeyFile string, pass []byte) (
privateKey, err = ssh.ParseRawPrivateKeyWithPassphrase(rawPem, pass)
}
if err != nil {
- errPassMissing := &ssh.PassphraseMissingError{}
if !errors.As(err, &errPassMissing) {
- return nil, fmt.Errorf("%s %q: %w", logp, privateKeyFile, err)
+ return nil, fmt.Errorf(`%s %q: %w`, logp, privateKeyFile, err)
}
- fmt.Printf("Enter passphrase for %s: ", privateKeyFile)
+ fmt.Printf(`Enter passphrase for %s: `, privateKeyFile)
+
+ stdin = int(os.Stdin.Fd())
- stdin := os.Stdin.Fd()
- pass, err := terminal.ReadPassword(int(stdin))
- fmt.Printf("\n")
+ pass, err = terminal.ReadPassword(stdin)
+ fmt.Println()
if err != nil {
- return nil, fmt.Errorf("%s %q: %w", logp, privateKeyFile, err)
+ return nil, fmt.Errorf(`%s %q: %w`, logp, privateKeyFile, err)
}
return cli.loadPrivateKey(privateKeyFile, pass)
}
rsaPrivateKey, ok = privateKey.(*rsa.PrivateKey)
if !ok {
- return nil, fmt.Errorf("%s: invalid or unsupported private key", logp)
+ return nil, fmt.Errorf(`%s: invalid or unsupported private key`, logp)
}
return rsaPrivateKey, nil
}
-//
// Add new issuer to the config.
-//
func (cli *Cli) Add(issuer *Issuer) (err error) {
if issuer == nil {
return nil
}
- logp := "Add"
+ var (
+ logp = `Add`
+ )
err = cli.add(issuer)
if err != nil {
- return fmt.Errorf("%s: %w", logp, err)
+ return fmt.Errorf(`%s: %w`, logp, err)
}
err = cli.cfg.save()
if err != nil {
- return fmt.Errorf("%s: %w", logp, err)
+ return fmt.Errorf(`%s: %w`, logp, err)
}
return nil
@@ -157,16 +162,19 @@ func (cli *Cli) Generate(label string, n int) (listOtp []string, err error) {
b32Enc = base32.StdEncoding.WithPadding(base32.NoPadding)
cryptoHash totp.CryptoHash
+ issuer *Issuer
+ secret []byte
+ proto totp.Protocol
)
- issuer, err := cli.cfg.get(label)
+ issuer, err = cli.cfg.get(label)
if err != nil {
- return nil, fmt.Errorf("%s: %w", logp, err)
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
}
- secret, err := b32Enc.DecodeString(issuer.Secret)
+ secret, err = b32Enc.DecodeString(issuer.Secret)
if err != nil {
- return nil, fmt.Errorf("%s: secret is not a valid base32 encoding: %w", logp, err)
+ return nil, fmt.Errorf(`%s: secret is not a valid base32 encoding: %w`, logp, err)
}
switch issuer.Hash {
@@ -178,105 +186,116 @@ func (cli *Cli) Generate(label string, n int) (listOtp []string, err error) {
cryptoHash = totp.CryptoHashSHA1
}
- proto := totp.New(cryptoHash, issuer.Digits, issuer.TimeStep)
+ proto = totp.New(cryptoHash, issuer.Digits, issuer.TimeStep)
listOtp, err = proto.GenerateN(secret, n)
if err != nil {
- return nil, fmt.Errorf("%s: %w", logp, err)
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
}
return listOtp, nil
}
-//
// Import the TOTP configuration from file format based on provider.
-//
func (cli *Cli) Import(providerName, file string) (n int, err error) {
- logp := "Import"
+ var (
+ logp = `Import`
+
+ issuers []*Issuer
+ issuer *Issuer
+ )
providerName = strings.ToLower(providerName)
switch providerName {
case providerNameAegis:
default:
- return 0, fmt.Errorf("%s: unknown provider %q", logp, providerName)
+ return 0, fmt.Errorf(`%s: unknown provider %q`, logp, providerName)
}
- issuers, err := parseProviderAegis(file)
+ issuers, err = parseProviderAegis(file)
if err != nil {
- return 0, fmt.Errorf("%s: %w", logp, err)
+ return 0, fmt.Errorf(`%s: %w`, logp, err)
}
- for _, issuer := range issuers {
+ for _, issuer = range issuers {
err = issuer.validate()
if err != nil {
- return 0, fmt.Errorf("%s: %w", logp, err)
+ return 0, fmt.Errorf(`%s: %w`, logp, err)
}
err = cli.cfg.add(issuer)
if err != nil {
- return 0, fmt.Errorf("%s: %w", logp, err)
+ return 0, fmt.Errorf(`%s: %w`, logp, err)
}
}
err = cli.cfg.save()
if err != nil {
- return 0, fmt.Errorf("%s: %w", logp, err)
+ return 0, fmt.Errorf(`%s: %w`, logp, err)
}
return len(issuers), nil
}
-//
// List all labels sorted in ascending order.
-//
func (cli *Cli) List() (labels []string) {
- for label := range cli.cfg.Issuers {
+ var (
+ label string
+ )
+
+ for label = range cli.cfg.Issuers {
labels = append(labels, label)
}
sort.Strings(labels)
return labels
}
-//
// Remove a TOTP configuration by its label.
-//
func (cli *Cli) Remove(label string) (err error) {
- logp := "Remove"
+ var (
+ logp = `Remove`
+
+ ok bool
+ )
label = strings.ToLower(label)
- _, ok := cli.cfg.Issuers[label]
+
+ _, ok = cli.cfg.Issuers[label]
if !ok {
- return fmt.Errorf("%s: %q not exist", logp, label)
+ return fmt.Errorf(`%s: %q not exist`, logp, label)
}
delete(cli.cfg.Issuers, label)
err = cli.cfg.save()
if err != nil {
- return fmt.Errorf("%s: %w", logp, err)
+ return fmt.Errorf(`%s: %w`, logp, err)
}
return nil
}
-//
// Rename a label to newLabel.
// It will return an error if the label parameter is not exist or newLabel
// already exist.
-//
func (cli *Cli) Rename(label, newLabel string) (err error) {
- logp := "Rename"
+ var (
+ logp = `Rename`
+
+ rawValue string
+ ok bool
+ )
label = strings.ToLower(label)
- rawValue, ok := cli.cfg.Issuers[label]
+ rawValue, ok = cli.cfg.Issuers[label]
if !ok {
- return fmt.Errorf("%s: %q not exist", logp, label)
+ return fmt.Errorf(`%s: %q not exist`, logp, label)
}
newLabel = strings.ToLower(newLabel)
_, ok = cli.cfg.Issuers[newLabel]
if ok {
- return fmt.Errorf("%s: new label %q already exist", logp, newLabel)
+ return fmt.Errorf(`%s: new label %q already exist`, logp, newLabel)
}
delete(cli.cfg.Issuers, label)
@@ -285,7 +304,7 @@ func (cli *Cli) Rename(label, newLabel string) (err error) {
err = cli.cfg.save()
if err != nil {
- return fmt.Errorf("%s: %w", logp, err)
+ return fmt.Errorf(`%s: %w`, logp, err)
}
return nil
diff --git a/cli_test.go b/cli_test.go
index 9827def..8bd1c6a 100644
--- a/cli_test.go
+++ b/cli_test.go
@@ -12,34 +12,44 @@ import (
)
func TestCli_inputPrivateKey(t *testing.T) {
- cli := &Cli{
- cfg: &config{
- file: "testdata/save.conf",
- isNotExist: true,
- },
- }
-
- cases := []struct {
+ type testCase struct {
desc string
privateKey string
exp string
- }{{
- desc: "Without private key",
+ }
+
+ var (
+ cli = &Cli{
+ cfg: &config{
+ file: `testdata/save.conf`,
+ isNotExist: true,
+ },
+ }
+
+ c testCase
+ r *os.File
+ w *os.File
+ gotPrivateKeyFile string
+ err error
+ )
+
+ var cases = []testCase{{
+ desc: `Without private key`,
exp: "[gotp]\nprivate_key =\n",
}, {
- desc: "With private key",
- privateKey: "testdata/rsa",
+ desc: `With private key`,
+ privateKey: `testdata/rsa`,
}}
- for _, c := range cases {
- r, w, err := os.Pipe()
+ for _, c = range cases {
+ r, w, err = os.Pipe()
if err != nil {
t.Fatal(err)
}
fmt.Fprintf(w, "%s\n", c.privateKey)
- gotPrivateKeyFile, err := cli.inputPrivateKey(r)
+ gotPrivateKeyFile, err = cli.inputPrivateKey(r)
if err != nil {
t.Fatal(err)
}
@@ -49,59 +59,70 @@ func TestCli_inputPrivateKey(t *testing.T) {
}
func TestCli_Add(t *testing.T) {
- cli := &Cli{
- cfg: &config{
- Issuers: make(map[string]string),
- file: "testdata/add.conf",
- },
+ type testCase struct {
+ issuer *Issuer
+ desc string
+ expError string
+ expConfig string
}
- err := cli.cfg.save()
+ var (
+ cli = &Cli{
+ cfg: &config{
+ Issuers: make(map[string]string),
+ file: `testdata/add.conf`,
+ },
+ }
+
+ err error
+ )
+
+ err = cli.cfg.save()
if err != nil {
t.Fatal(err)
}
- cases := []struct {
- desc string
- issuer *Issuer
- expError string
- expConfig string
- }{{
- desc: "With nil issuer",
+ var cases = []testCase{{
+ desc: `With nil issuer`,
expConfig: "[gotp]\nprivate_key =\n",
}, {
- desc: "With invalid label",
+ desc: `With invalid label`,
issuer: &Issuer{
- Label: "Not@valid",
+ Label: `Not@valid`,
},
expError: `Add: validate: invalid label "Not@valid"`,
}, {
- desc: "With invalid hash",
+ desc: `With invalid hash`,
issuer: &Issuer{
- Label: "Test",
- Hash: "SHA255",
+ Label: `Test`,
+ Hash: `SHA255`,
},
expError: `Add: validate: invalid algorithm "SHA255"`,
}, {
- desc: "With valid label",
+ desc: `With valid label`,
issuer: &Issuer{
- Label: "Test",
+ Label: `Test`,
Hash: HashSHA1,
- Secret: "x",
+ Secret: `x`,
},
expConfig: "[gotp]\nprivate_key =\n\n[gotp \"issuer\"]\ntest = SHA1:x:6:30:\n",
}}
- for _, c := range cases {
+ var (
+ c testCase
+ got []byte
+ )
+
+ for _, c = range cases {
t.Log(c.desc)
err = cli.Add(c.issuer)
if err != nil {
- test.Assert(t, "error", c.expError, err.Error())
+ test.Assert(t, `error`, c.expError, err.Error())
continue
}
- got, err := os.ReadFile(cli.cfg.file)
+ got, err = os.ReadFile(cli.cfg.file)
if err != nil {
t.Fatal(err)
}
diff --git a/cmd/gotp/main.go b/cmd/gotp/main.go
index 7b95cbf..f031e8b 100644
--- a/cmd/gotp/main.go
+++ b/cmd/gotp/main.go
@@ -15,16 +15,23 @@ import (
)
const (
- cmdName = "gotp"
- cmdAdd = "add"
- cmdGenerate = "gen"
- cmdImport = "import"
- cmdList = "list"
- cmdRemove = "remove"
- cmdRename = "rename"
+ cmdName = `gotp`
+ cmdAdd = `add`
+ cmdGenerate = `gen`
+ cmdImport = `import`
+ cmdList = `list`
+ cmdRemove = `remove`
+ cmdRename = `rename`
)
func main() {
+ var (
+ cmd string
+ cli *gotp.Cli
+ err error
+ args []string
+ )
+
log.SetFlags(0)
flag.Usage = func() {
@@ -33,49 +40,50 @@ func main() {
}
flag.Parse()
- args := flag.Args()
+ args = flag.Args()
+
if len(args) == 0 {
flag.Usage()
}
- cmd := strings.ToLower(args[0])
+ cmd = strings.ToLower(args[0])
switch cmd {
case cmdAdd:
if len(args) < 3 {
- log.Printf("%s %s: missing parameters", cmdName, cmd)
+ log.Printf(`%s %s: missing parameters`, cmdName, cmd)
os.Exit(1)
}
case cmdGenerate:
if len(args) < 2 {
- log.Printf("%s %s: missing parameters", cmdName, cmd)
+ log.Printf(`%s %s: missing parameters`, cmdName, cmd)
os.Exit(1)
}
case cmdImport:
if len(args) <= 2 {
- log.Printf("%s %s: missing parameters", cmdName, cmd)
+ log.Printf(`%s %s: missing parameters`, cmdName, cmd)
os.Exit(1)
}
case cmdList:
// NOOP.
case cmdRemove:
if len(args) <= 1 {
- log.Printf("%s %s: missing parameters", cmdName, cmd)
+ log.Printf(`%s %s: missing parameters`, cmdName, cmd)
os.Exit(1)
}
case cmdRename:
if len(args) <= 2 {
- log.Printf("%s %s: missing parameters", cmdName, cmd)
+ log.Printf(`%s %s: missing parameters`, cmdName, cmd)
os.Exit(1)
}
default:
- log.Printf("%s: unknown command %q", cmdName, cmd)
+ log.Printf(`%s: unknown command %q`, cmdName, cmd)
flag.Usage()
}
- cli, err := gotp.NewCli()
+ cli, err = gotp.NewCli()
if err != nil {
- log.Printf("%s: %s", cmdName, err)
+ log.Printf(`%s: %s`, cmdName, err)
os.Exit(1)
}
@@ -96,40 +104,51 @@ func main() {
}
func doAdd(cli *gotp.Cli, args []string) {
- label := args[1]
- rawConfig := args[2]
- issuer, err := gotp.NewIssuer(label, rawConfig, nil)
+ var (
+ label = args[1]
+ rawConfig = args[2]
+
+ issuer *gotp.Issuer
+ err error
+ )
+
+ issuer, err = gotp.NewIssuer(label, rawConfig, nil)
if err != nil {
- log.Printf("%s: %s", cmdName, err)
+ log.Printf(`%s: %s`, cmdName, err)
os.Exit(1)
}
err = cli.Add(issuer)
if err != nil {
- log.Printf("%s: %s", cmdName, err)
+ log.Printf(`%s: %s`, cmdName, err)
os.Exit(1)
}
- fmt.Println("OK")
+ fmt.Println(`OK`)
}
func doGenerate(cli *gotp.Cli, args []string) {
var (
label = args[1]
n int = 1
- err error
+
+ listOtp []string
+ otp string
+ err error
)
+
if len(args) >= 3 {
n, err = strconv.Atoi(args[2])
if err != nil {
- log.Printf("%s: %s", cmdName, err)
+ log.Printf(`%s: %s`, cmdName, err)
os.Exit(1)
}
}
- listOtp, err := cli.Generate(label, n)
+
+ listOtp, err = cli.Generate(label, n)
if err != nil {
- log.Printf("%s: %s", cmdName, err)
+ log.Printf(`%s: %s`, cmdName, err)
os.Exit(1)
}
- for _, otp := range listOtp {
+ for _, otp = range listOtp {
fmt.Println(otp)
}
}
@@ -138,40 +157,57 @@ func doImport(cli *gotp.Cli, args []string) {
var (
providerName = args[1]
file = args[2]
+
+ n int
+ err error
)
- n, err := cli.Import(providerName, file)
+ n, err = cli.Import(providerName, file)
if err != nil {
- log.Printf("%s: %s", cmdName, err)
+ log.Printf(`%s: %s`, cmdName, err)
os.Exit(1)
}
- fmt.Printf("OK - %d imported", n)
+ fmt.Printf(`OK - %d imported`, n)
}
func doList(cli *gotp.Cli) {
- labels := cli.List()
- for _, label := range labels {
+ var (
+ labels []string = cli.List()
+
+ label string
+ )
+
+ for _, label = range labels {
fmt.Println(label)
}
}
func doRemove(cli *gotp.Cli, args []string) {
- label := args[1]
- err := cli.Remove(label)
+ var (
+ label = args[1]
+
+ err error
+ )
+
+ err = cli.Remove(label)
if err != nil {
- log.Printf("%s: %s", cmdName, err)
+ log.Printf(`%s: %s`, cmdName, err)
os.Exit(1)
}
- fmt.Println("OK")
+ fmt.Println(`OK`)
}
func doRename(cli *gotp.Cli, args []string) {
- label := args[1]
- newLabel := args[2]
+ var (
+ label = args[1]
+ newLabel = args[2]
+
+ err error
+ )
- err := cli.Rename(label, newLabel)
+ err = cli.Rename(label, newLabel)
if err != nil {
- log.Printf("%s: %s", cmdName, err)
+ log.Printf(`%s: %s`, cmdName, err)
os.Exit(1)
}
- fmt.Println("OK")
+ fmt.Println(`OK`)
}
diff --git a/config.go b/config.go
index fe4752f..f5feb9e 100644
--- a/config.go
+++ b/config.go
@@ -16,46 +16,52 @@ import (
)
const (
- valueSeparator = ":"
+ valueSeparator = `:`
)
type config struct {
- PrivateKey string `ini:"gotp::private_key"`
+ privateKey *rsa.PrivateKey // Only RSA private key can do encryption.
+
Issuers map[string]string `ini:"gotp:issuer"`
+ PrivateKey string `ini:"gotp::private_key"`
file string
isNotExist bool
- privateKey *rsa.PrivateKey // Only RSA private key can do encryption.
}
func newConfig(file string) (cfg *config, err error) {
- logp := "newConfig"
+ var (
+ logp = `newConfig`
+
+ in *ini.Ini
+ dir string
+ )
cfg = &config{
Issuers: make(map[string]string),
file: file,
}
- in, err := ini.Open(file)
+ in, err = ini.Open(file)
if err != nil {
if !errors.Is(err, fs.ErrNotExist) {
- return nil, fmt.Errorf("%s: Open %q: %w", logp, file, err)
+ return nil, fmt.Errorf(`%s: Open %q: %w`, logp, file, err)
}
cfg.isNotExist = true
}
if cfg.isNotExist {
- dir := filepath.Dir(file)
+ dir = filepath.Dir(file)
err = os.MkdirAll(dir, 0700)
if err != nil {
- return nil, fmt.Errorf("%s: MkdirAll %q: %w", logp, dir, err)
+ return nil, fmt.Errorf(`%s: MkdirAll %q: %w`, logp, dir, err)
}
return cfg, nil
}
err = in.Unmarshal(cfg)
if err != nil {
- return nil, fmt.Errorf("%s: %w", logp, err)
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
}
return cfg, nil
@@ -73,7 +79,7 @@ func (cfg *config) add(issuer *Issuer) (err error) {
_, exist = cfg.Issuers[issuer.Label]
if exist {
- return fmt.Errorf("duplicate issuer name %q", issuer.Label)
+ return fmt.Errorf(`duplicate issuer name %q`, issuer.Label)
}
value, err = issuer.pack(cfg.privateKey)
@@ -86,22 +92,25 @@ func (cfg *config) add(issuer *Issuer) (err error) {
return nil
}
-//
// get the issuer by its name.
-//
func (cfg *config) get(name string) (issuer *Issuer, err error) {
- logp := "get"
+ var (
+ logp = `get`
+
+ v string
+ ok bool
+ )
name = strings.ToLower(name)
- v, ok := cfg.Issuers[name]
+ v, ok = cfg.Issuers[name]
if !ok {
- return nil, fmt.Errorf("%s: issuer %q not found", logp, name)
+ return nil, fmt.Errorf(`%s: issuer %q not found`, logp, name)
}
issuer, err = NewIssuer(name, v, cfg.privateKey)
if err != nil {
- return nil, fmt.Errorf("%s %q: %w", logp, name, err)
+ return nil, fmt.Errorf(`%s %q: %w`, logp, name, err)
}
return issuer, nil
@@ -109,16 +118,20 @@ func (cfg *config) get(name string) (issuer *Issuer, err error) {
// save the config to file.
func (cfg *config) save() (err error) {
- logp := "save"
+ var (
+ logp = `save`
+
+ b []byte
+ )
- b, err := ini.Marshal(cfg)
+ b, err = ini.Marshal(cfg)
if err != nil {
- return fmt.Errorf("%s %s: %w", logp, cfg.file, err)
+ return fmt.Errorf(`%s %s: %w`, logp, cfg.file, err)
}
err = os.WriteFile(cfg.file, b, 0600)
if err != nil {
- return fmt.Errorf("%s %s: %w", logp, cfg.file, err)
+ return fmt.Errorf(`%s %s: %w`, logp, cfg.file, err)
}
return nil
diff --git a/config_test.go b/config_test.go
index eea7a05..772ea1e 100644
--- a/config_test.go
+++ b/config_test.go
@@ -10,33 +10,41 @@ import (
)
func TestNewConfig(t *testing.T) {
- cases := []struct {
+ type testCase struct {
+ expConfig *config
desc string
configFile string
- expConfig *config
expError string
- }{{
- desc: "With openssh rsa",
- configFile: "testdata/rsa.conf",
+ }
+
+ var cases = []testCase{{
+ desc: `With openssh rsa`,
+ configFile: `testdata/rsa.conf`,
expConfig: &config{
- PrivateKey: "testdata/rsa",
+ PrivateKey: `testdata/rsa`,
Issuers: map[string]string{
- "email-domain": "XYZ",
- "test": "ABCD",
+ `email-domain`: `XYZ`,
+ `test`: `ABCD`,
},
- file: "testdata/rsa.conf",
+ file: `testdata/rsa.conf`,
},
}}
- for _, c := range cases {
+ var (
+ c testCase
+ gotConfig *config
+ err error
+ )
+
+ for _, c = range cases {
t.Log(c.desc)
- gotConfig, err := newConfig(c.configFile)
+ gotConfig, err = newConfig(c.configFile)
if err != nil {
- test.Assert(t, "error", c.expError, err.Error())
+ test.Assert(t, `error`, c.expError, err.Error())
continue
}
- test.Assert(t, "Issuer", c.expConfig, gotConfig)
+ test.Assert(t, `Issuer`, c.expConfig, gotConfig)
}
}
diff --git a/gotp.go b/gotp.go
index ade3266..3b9625a 100644
--- a/gotp.go
+++ b/gotp.go
@@ -10,30 +10,30 @@ import (
// List of available algorithm for Provider.
const (
- HashSHA1 = "SHA1" // Default algorithm.
- HashSHA256 = "SHA256"
- HashSHA512 = "SHA512"
+ HashSHA1 = `SHA1` // Default algorithm.
+ HashSHA256 = `SHA256`
+ HashSHA512 = `SHA512`
)
const (
- configDir = "gotp"
- configFile = "gotp.conf"
+ configDir = `gotp`
+ configFile = `gotp.conf`
defaultHash = HashSHA1
// List of known providers
- providerNameAegis = "aegis"
+ providerNameAegis = `aegis`
)
-//
// normalizeLabel convert non alpha number, hyphen, underscore, or period
-// characters into "-".
-//
+// characters into `-`.
func normalizeLabel(in string) (out string) {
var (
- buf strings.Builder
replacement rune = '-'
+
+ buf strings.Builder
+ r rune
)
- for _, r := range in {
+ for _, r = range in {
if unicode.IsLetter(r) || unicode.IsDigit(r) ||
r == '-' || r == '_' || r == '.' {
buf.WriteRune(r)
diff --git a/issuer.go b/issuer.go
index e3d32d6..ac63871 100644
--- a/issuer.go
+++ b/issuer.go
@@ -16,44 +16,45 @@ import (
"github.com/shuLhan/share/lib/totp"
)
-//
// Issuer contains the configuration for single TOTP issuer, including
// their unique label, algorithm, secret key, and number of digits.
-//
type Issuer struct {
+ Name string
Label string
Hash string
Secret string // The secret value in base32.
+ raw []byte
Digits int
TimeStep int
- Name string
- raw []byte
}
-//
// NewIssuer create and initialize new issuer from raw value.
// If the rsaPrivateKey is not nil, that means the rawConfig is encrypted.
-//
func NewIssuer(label, rawConfig string, rsaPrivateKey *rsa.PrivateKey) (issuer *Issuer, err error) {
- logp := "NewIssuer"
+ var (
+ logp = `NewIssuer`
+
+ vals []string
+ vbytes []byte
+ )
if rsaPrivateKey != nil {
- cipherText, err := base64.StdEncoding.DecodeString(rawConfig)
+ vbytes, err = base64.StdEncoding.DecodeString(rawConfig)
if err != nil {
- return nil, fmt.Errorf("%s: %w", logp, err)
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
}
- raw, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, rsaPrivateKey, cipherText, nil)
+ vbytes, err = rsa.DecryptOAEP(sha256.New(), rand.Reader, rsaPrivateKey, vbytes, nil)
if err != nil {
- return nil, fmt.Errorf("%s: %w", logp, err)
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
}
- rawConfig = string(raw)
+ rawConfig = string(vbytes)
}
- vals := strings.Split(rawConfig, valueSeparator)
+ vals = strings.Split(rawConfig, valueSeparator)
if len(vals) < 2 {
- return nil, fmt.Errorf("%s: invalid value %q", logp, rawConfig)
+ return nil, fmt.Errorf(`%s: invalid value %q`, logp, rawConfig)
}
issuer = &Issuer{
Label: label,
@@ -63,7 +64,7 @@ func NewIssuer(label, rawConfig string, rsaPrivateKey *rsa.PrivateKey) (issuer *
if len(vals) >= 3 {
issuer.Digits, err = strconv.Atoi(vals[2])
if err != nil {
- return nil, fmt.Errorf("%s: invalid digits %s: %w", logp, vals[2], err)
+ return nil, fmt.Errorf(`%s: invalid digits %s: %w`, logp, vals[2], err)
}
} else {
issuer.Digits = totp.DefCodeDigits
@@ -71,7 +72,7 @@ func NewIssuer(label, rawConfig string, rsaPrivateKey *rsa.PrivateKey) (issuer *
if len(vals) >= 4 {
issuer.TimeStep, err = strconv.Atoi(vals[3])
if err != nil {
- return nil, fmt.Errorf("%s: invalid time step %s: %w", logp, vals[3], err)
+ return nil, fmt.Errorf(`%s: invalid time step %s: %w`, logp, vals[3], err)
}
} else {
issuer.TimeStep = totp.DefTimeStep
@@ -84,19 +85,18 @@ func NewIssuer(label, rawConfig string, rsaPrivateKey *rsa.PrivateKey) (issuer *
}
func (issuer *Issuer) String() string {
- return fmt.Sprintf("%s:%s:%d:%d:%s", issuer.Hash, issuer.Secret,
+ return fmt.Sprintf(`%s:%s:%d:%d:%s`, issuer.Hash, issuer.Secret,
issuer.Digits, issuer.TimeStep, issuer.Name)
}
-//
-// pack the Issuer into string separated by ":".
+// pack the Issuer into string separated by `:`.
// If the privateKey is not nil, the string will be encrypted and encoded to
// base64.
-//
func (issuer *Issuer) pack(privateKey *rsa.PrivateKey) (value string, err error) {
var (
- logp = "pack"
+ logp = `pack`
plainText = issuer.String()
+ rng = rand.Reader
)
issuer.raw = []byte(plainText)
@@ -104,10 +104,9 @@ func (issuer *Issuer) pack(privateKey *rsa.PrivateKey) (value string, err error)
return string(issuer.raw), nil
}
- rng := rand.Reader
issuer.raw, err = rsa.EncryptOAEP(sha256.New(), rng, &privateKey.PublicKey, issuer.raw, nil)
if err != nil {
- return "", fmt.Errorf("%s: %w", logp, err)
+ return ``, fmt.Errorf(`%s: %w`, logp, err)
}
value = base64.StdEncoding.EncodeToString(issuer.raw)
@@ -116,23 +115,25 @@ func (issuer *Issuer) pack(privateKey *rsa.PrivateKey) (value string, err error)
}
func (issuer *Issuer) validate() (err error) {
- logp := "validate"
+ var (
+ logp = `validate`
+ )
if !ini.IsValidVarName(issuer.Label) {
- return fmt.Errorf("%s: invalid label %q", logp, issuer.Label)
+ return fmt.Errorf(`%s: invalid label %q`, logp, issuer.Label)
}
issuer.Hash = strings.ToUpper(issuer.Hash)
switch issuer.Hash {
- case "":
+ case ``:
issuer.Hash = defaultHash
case HashSHA1, HashSHA256, HashSHA512:
// NOOP
default:
- return fmt.Errorf("%s: invalid algorithm %q", logp, issuer.Hash)
+ return fmt.Errorf(`%s: invalid algorithm %q`, logp, issuer.Hash)
}
if len(issuer.Secret) == 0 {
- return fmt.Errorf("%s: empty key", logp)
+ return fmt.Errorf(`%s: empty key`, logp)
}
if issuer.Digits <= 0 {
issuer.Digits = totp.DefCodeDigits
diff --git a/provider_aegis.go b/provider_aegis.go
index 8a24c37..bdc71ec 100644
--- a/provider_aegis.go
+++ b/provider_aegis.go
@@ -12,43 +12,52 @@ import (
)
func parseProviderAegis(file string) (issuers []*Issuer, err error) {
- logp := "parseProviderAegis"
+ var (
+ logp = `parseProviderAegis`
- b, err := os.ReadFile(file)
+ u *url.URL
+ issuer *Issuer
+ q url.Values
+ val string
+ lines [][]byte
+ line []byte
+ b []byte
+ x int
+ )
+
+ b, err = os.ReadFile(file)
if err != nil {
- return nil, fmt.Errorf("%s: %w", logp, err)
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
}
- lines := bytes.Split(b, []byte("\n"))
- for x, line := range lines {
- u, err := url.Parse(string(line))
+ lines = bytes.Split(b, []byte("\n"))
+ for x, line = range lines {
+ u, err = url.Parse(string(line))
if err != nil {
- return nil, fmt.Errorf("%s: line %d: invalid format %q", logp, x, line)
+ return nil, fmt.Errorf(`%s: line %d: invalid format %q`, logp, x, line)
}
- if u.Host != "totp" {
+ if u.Host != `totp` {
continue
}
- q := u.Query()
- issuer := &Issuer{
+ q = u.Query()
+ issuer = &Issuer{
Label: normalizeLabel(u.Path[1:]),
- Hash: q.Get("algorithm"),
- Secret: q.Get("secret"),
- Name: q.Get("issuer"),
+ Hash: q.Get(`algorithm`),
+ Secret: q.Get(`secret`),
+ Name: q.Get(`issuer`),
}
- val := q.Get("digits")
+ val = q.Get(`digits`)
issuer.Digits, err = strconv.Atoi(val)
if err != nil {
- return nil, fmt.Errorf("%s: line %d: invalid digits %q",
- logp, x, val)
+ return nil, fmt.Errorf(`%s: line %d: invalid digits %q`, logp, x, val)
}
- val = q.Get("period")
+ val = q.Get(`period`)
issuer.TimeStep, err = strconv.Atoi(val)
if err != nil {
- return nil, fmt.Errorf("%s: line %d: invalid period %q",
- logp, x, val)
+ return nil, fmt.Errorf(`%s: line %d: invalid period %q`, logp, x, val)
}
issuers = append(issuers, issuer)