diff options
| author | Shulhan <ms@kilabit.info> | 2023-07-24 13:01:36 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2023-10-06 10:03:04 +0700 |
| commit | 8a1a81a6428ae970569d9c2a506acf90deb2e0c4 (patch) | |
| tree | d3e82e19718962181b51572a0395ed6b1cef2222 | |
| parent | 479e33040d93e582aa10f19c299b2633f2270d24 (diff) | |
| download | gotp-8a1a81a6428ae970569d9c2a506acf90deb2e0c4.tar.xz | |
all: unfold private key path before reading
By unfolding, user can set the path to private key using "~" that points
to their home.
This make the key can works across home directory, in case user have
multiple homes (Linux and macOS have different home path and maybe
user name, but both can use "~" as substitution for $HOME)
| -rw-r--r-- | cli_test.go | 9 | ||||
| -rw-r--r-- | config.go | 42 | ||||
| -rw-r--r-- | config_test.go | 40 | ||||
| -rw-r--r-- | go.mod | 10 | ||||
| -rw-r--r-- | go.sum | 17 | ||||
| -rw-r--r-- | testdata/config_marshaler_test.txt | 17 |
6 files changed, 105 insertions, 30 deletions
diff --git a/cli_test.go b/cli_test.go index 81253b1..5eeffd4 100644 --- a/cli_test.go +++ b/cli_test.go @@ -151,14 +151,15 @@ func TestCli_SetPrivateKey(t *testing.T) { } var ( - cli = &Cli{} + cli = &Cli{} + cfg = &config{} + rawConfig []byte - cfg *config ) rawConfig = tdata.Input[`config.ini`] - cfg, err = loadConfig(rawConfig) + err = cfg.UnmarshalText(rawConfig) if err != nil { t.Fatal(err) } @@ -185,7 +186,7 @@ func TestCli_SetPrivateKey(t *testing.T) { // Load the encrypted raw config and compare the issuer. - cfg, err = loadConfig(rawConfig) + err = cfg.UnmarshalText(rawConfig) if err != nil { t.Fatal(err) } @@ -13,6 +13,7 @@ import ( "strings" "github.com/shuLhan/share/lib/ini" + libos "github.com/shuLhan/share/lib/os" ) const ( @@ -42,18 +43,18 @@ func newConfig(file string) (cfg *config, err error) { if !errors.Is(err, fs.ErrNotExist) { return nil, fmt.Errorf(`%s: Open %q: %w`, logp, file, err) } - isNotExist = true - } - if isNotExist { var dir = filepath.Dir(file) err = os.MkdirAll(dir, 0700) if err != nil { return nil, fmt.Errorf(`%s: MkdirAll %q: %w`, logp, dir, err) } + isNotExist = true } - cfg, err = loadConfig(content) + cfg = &config{} + + err = cfg.UnmarshalText(content) if err != nil { return nil, fmt.Errorf(`%s: %w`, logp, err) } @@ -64,25 +65,40 @@ func newConfig(file string) (cfg *config, err error) { return cfg, nil } -// loadConfig load configuration from raw bytes. -func loadConfig(content []byte) (cfg *config, err error) { - var logp = `loadConfig` +// UnmarshalText load configuration from raw bytes. +func (cfg *config) UnmarshalText(content []byte) (err error) { + var logp = `UnmarshalText` + + cfg.Issuers = make(map[string]string) - cfg = &config{ - Issuers: make(map[string]string), + if len(content) > 0 { + err = ini.Unmarshal(content, cfg) + if err != nil { + return fmt.Errorf(`%s: %w`, logp, err) + } } - err = ini.Unmarshal(content, cfg) - if err != nil { - return nil, fmt.Errorf(`%s: %w`, logp, err) + if len(cfg.PrivateKey) != 0 { + cfg.PrivateKey, err = libos.PathUnfold(cfg.PrivateKey) + if err != nil { + return fmt.Errorf(`%s: %w`, logp, err) + } } - return cfg, nil + return nil } // MarshalText convert the config object back to INI format. func (cfg *config) MarshalText() (text []byte, err error) { var logp = `MarshalText` + + if len(cfg.PrivateKey) != 0 { + cfg.PrivateKey, err = libos.PathFold(cfg.PrivateKey) + if err != nil { + return nil, fmt.Errorf(`%s: %w`, logp, err) + } + } + text, err = ini.Marshal(cfg) if err != nil { return nil, fmt.Errorf(`%s: %w`, logp, err) diff --git a/config_test.go b/config_test.go index b877236..477b438 100644 --- a/config_test.go +++ b/config_test.go @@ -4,6 +4,8 @@ package gotp import ( + "os" + "path/filepath" "testing" "github.com/shuLhan/share/lib/test" @@ -57,3 +59,41 @@ func TestNewConfig(t *testing.T) { test.Assert(t, `Issuer`, c.expConfig, gotConfig) } } + +func TestMarshaler(t *testing.T) { + var ( + cfg = config{} + + tdata *test.Data + userHomeDir string + err error + ) + + tdata, err = test.LoadData(`testdata/config_marshaler_test.txt`) + if err != nil { + t.Fatal(err) + } + + err = cfg.UnmarshalText(tdata.Input[`input.ini`]) + if err != nil { + t.Fatal(err) + } + + userHomeDir, err = os.UserHomeDir() + if err != nil { + t.Fatal(err) + } + + var expPrivateKey = filepath.Join(userHomeDir, `myprivatekey.pem`) + + test.Assert(t, `UnmarshalText: PrivateKey`, expPrivateKey, cfg.PrivateKey) + + var gotText []byte + + gotText, err = cfg.MarshalText() + if err != nil { + t.Fatal(err) + } + + test.Assert(t, `MarshalText`, string(tdata.Output[`output.ini`]), string(gotText)) +} @@ -3,14 +3,14 @@ module git.sr.ht/~shulhan/gotp -go 1.19 +go 1.20 require ( - github.com/shuLhan/share v0.46.0 - golang.org/x/crypto v0.9.0 - golang.org/x/term v0.8.0 + github.com/shuLhan/share v0.50.0 + golang.org/x/crypto v0.13.0 + golang.org/x/term v0.12.0 ) -require golang.org/x/sys v0.8.0 // indirect +require golang.org/x/sys v0.12.0 // indirect //replace github.com/shuLhan/share => ../share @@ -1,8 +1,9 @@ -github.com/shuLhan/share v0.46.0 h1:cF0Ngj7wVA6TIcdSmfrqxOwMB3hZ+4df5cJf4GGCun4= -github.com/shuLhan/share v0.46.0/go.mod h1:BhnIWJxq84BTOs3Z2gLFAN8ih9mBfhZbRIjqGupGJag= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +github.com/shuLhan/share v0.50.0 h1:L1TR7jsSOv5cDMkH4CapIzDp/Yisq5Xe16GMeQRCSMs= +github.com/shuLhan/share v0.50.0/go.mod h1:YEwLUwwBpDqPn5yxfdb0B8eFP04SKQxv5gMQwB4A+c4= +golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= diff --git a/testdata/config_marshaler_test.txt b/testdata/config_marshaler_test.txt new file mode 100644 index 0000000..b354b28 --- /dev/null +++ b/testdata/config_marshaler_test.txt @@ -0,0 +1,17 @@ +Test UnmarshalText and MarshalText on config. + +>>> input.ini +[gotp "issuer"] +test1 = SHA1:a:6:30: +test2 = SHA1:b:6:30: + +[gotp] +private_key = ~/myprivatekey.pem + +<<< output.ini +[gotp "issuer"] +test1 = SHA1:a:6:30: +test2 = SHA1:b:6:30: + +[gotp] +private_key = ~/myprivatekey.pem |
