aboutsummaryrefslogtreecommitdiff
path: root/config.go
diff options
context:
space:
mode:
Diffstat (limited to 'config.go')
-rw-r--r--config.go126
1 files changed, 126 insertions, 0 deletions
diff --git a/config.go b/config.go
new file mode 100644
index 0000000..d472cee
--- /dev/null
+++ b/config.go
@@ -0,0 +1,126 @@
+// Copyright 2021, Shulhan <ms@kilabit.info>. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gotp
+
+import (
+ "crypto/rsa"
+ "errors"
+ "fmt"
+ "io/fs"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/shuLhan/share/lib/ini"
+)
+
+const (
+ valueSeparator = ":"
+)
+
+type config struct {
+ PrivateKey string `ini:"gotp::private_key"`
+ Issuers map[string]string `ini:"gotp:issuer"`
+
+ file string
+ isNotExist bool
+ privateKey *rsa.PrivateKey // Only RSA private key can do encryption.
+}
+
+func newConfig(file string) (cfg *config, err error) {
+ logp := "newConfig"
+
+ cfg = &config{
+ Issuers: make(map[string]string),
+ file: 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)
+ }
+ cfg.isNotExist = true
+ }
+
+ if cfg.isNotExist {
+ dir := filepath.Dir(file)
+ err = os.MkdirAll(dir, 0700)
+ if err != nil {
+ 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 cfg, nil
+}
+
+func (cfg *config) add(issuer *Issuer) (err error) {
+ var (
+ value string
+ exist bool
+ )
+
+ if issuer == nil {
+ return nil
+ }
+
+ _, exist = cfg.Issuers[issuer.Label]
+ if exist {
+ return fmt.Errorf("duplicate issuer name %q", issuer.Label)
+ }
+
+ value, err = issuer.pack(cfg.privateKey)
+ if err != nil {
+ return err
+ }
+
+ cfg.Issuers[issuer.Label] = value
+
+ return nil
+}
+
+//
+// get the issuer by its name.
+//
+func (cfg *config) get(name string) (issuer *Issuer, err error) {
+ logp := "get"
+
+ name = strings.ToLower(name)
+
+ v, ok := cfg.Issuers[name]
+ if !ok {
+ 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 issuer, nil
+}
+
+// save the config to file.
+func (cfg *config) save() (err error) {
+ logp := "save"
+
+ b, err := ini.Marshal(cfg)
+ if err != nil {
+ 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 nil
+}