From a4aae01c15510951defb212c628375caf1e85391 Mon Sep 17 00:00:00 2001 From: Javad Date: Sun, 22 Dec 2024 11:03:16 +0330 Subject: [PATCH 1/6] feat: add read file content util --- util/utils.go | 24 +++++++++++++++ util/utils_test.go | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/util/utils.go b/util/utils.go index ba58dc8b4..bef088943 100644 --- a/util/utils.go +++ b/util/utils.go @@ -3,8 +3,10 @@ package util import ( crand "crypto/rand" "fmt" + "io" "math/big" "math/bits" + "os" "golang.org/x/exp/constraints" ) @@ -160,3 +162,25 @@ func FormatBytesToHumanReadable(bytes uint64) string { return fmt.Sprintf("%.2f %s", value, unit) } + +// ReadFileContent reads the content of the file at the given path +// up to the specified maxSize. It returns the content as a string +// and any error encountered. +func ReadFileContent(filePath string, maxSize int) (string, error) { + file, err := os.Open(filePath) + if err != nil { + return "", fmt.Errorf("failed to open file: %w", err) + } + defer func() { + _ = file.Close() + }() + + buffer := make([]byte, maxSize) + + n, err := file.Read(buffer) + if err != nil && err != io.EOF { + return "", fmt.Errorf("failed to read file content: %w", err) + } + + return string(buffer[:n]), nil +} diff --git a/util/utils_test.go b/util/utils_test.go index 7def6e3e0..dddafe16e 100644 --- a/util/utils_test.go +++ b/util/utils_test.go @@ -2,6 +2,7 @@ package util import ( "math/big" + "os" "testing" "github.com/stretchr/testify/assert" @@ -139,3 +140,76 @@ func TestFormatBytesToHumanReadable(t *testing.T) { } } } + +func TestReadFileContent(t *testing.T) { + testCases := []struct { + name string + fileContent string + maxSize int + expected string + expectErr bool + }{ + { + name: "Read full content within maxSize", + fileContent: "Hello, World!", + maxSize: 50, + expected: "Hello, World!", + expectErr: false, + }, + { + name: "Read partial content limited by maxSize", + fileContent: "Hello, World!", + maxSize: 5, + expected: "Hello", + expectErr: false, + }, + { + name: "Empty file", + fileContent: "", + maxSize: 10, + expected: "", + expectErr: false, + }, + { + name: "Zero maxSize", + fileContent: "Content", + maxSize: 0, + expected: "", + expectErr: false, + }, + { + name: "Non-existent file", + fileContent: "", + maxSize: 10, + expected: "", + expectErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + var filePath string + if tc.fileContent != "" || tc.name == "Empty file" { + tmpFile, err := os.CreateTemp(TempDirPath(), "testfile") + assert.NoError(t, err, "Failed to create temp file") + defer os.Remove(tmpFile.Name()) + + _, err = tmpFile.WriteString(tc.fileContent) + assert.NoError(t, err, "Failed to write to temp file") + tmpFile.Close() + filePath = tmpFile.Name() + } else { + filePath = "nonexistent_file" + } + + content, err := ReadFileContent(filePath, tc.maxSize) + + if tc.expectErr { + assert.Error(t, err, "Expected an error but got none") + } else { + assert.NoError(t, err, "Unexpected error occurred") + assert.Equal(t, tc.expected, content, "Content does not match expected value") + } + }) + } +} From 7148bac867d43e4f799428ff957fb96787072310 Mon Sep 17 00:00:00 2001 From: Javad Date: Sun, 22 Dec 2024 11:30:25 +0330 Subject: [PATCH 2/6] feat: add switch password from file for daemon and gtk --- cmd/daemon/start.go | 10 ++++++++++ cmd/gtk/main.go | 17 ++++++++++++++--- util/utils.go | 11 +++++------ util/utils_test.go | 40 ++++++++++++---------------------------- 4 files changed, 41 insertions(+), 37 deletions(-) diff --git a/cmd/daemon/start.go b/cmd/daemon/start.go index 7565aa607..cb117c7f9 100644 --- a/cmd/daemon/start.go +++ b/cmd/daemon/start.go @@ -6,6 +6,7 @@ import ( "github.com/gofrs/flock" "github.com/pactus-project/pactus/cmd" + "github.com/pactus-project/pactus/util" "github.com/pactus-project/pactus/wallet" "github.com/spf13/cobra" ) @@ -24,6 +25,9 @@ func buildStartCmd(parentCmd *cobra.Command) { passwordOpt := startCmd.Flags().StringP("password", "p", "", "the wallet password") + passwordFromFileOpt := startCmd.Flags().String("password-from-file", "", + "the file containing the wallet password") + startCmd.Run = func(_ *cobra.Command, _ []string) { workingDir, _ := filepath.Abs(*workingDirOpt) // change working directory @@ -49,8 +53,14 @@ func buildStartCmd(parentCmd *cobra.Command) { } var password string + if *passwordOpt != "" { password = *passwordOpt + } else if *passwordFromFileOpt != "" { + password, err = util.ReadFileContent(*passwordFromFileOpt) + if err != nil { + return "", false + } } else { password = cmd.PromptPassword("Wallet password", false) } diff --git a/cmd/gtk/main.go b/cmd/gtk/main.go index f503aa88b..6e36810fb 100644 --- a/cmd/gtk/main.go +++ b/cmd/gtk/main.go @@ -24,14 +24,16 @@ import ( const appID = "com.github.pactus-project.pactus.pactus-gui" var ( - workingDirOpt *string - passwordOpt *string - testnetOpt *bool + workingDirOpt *string + passwordOpt *string + passwordFromFileOpt *string + testnetOpt *bool ) func init() { workingDirOpt = flag.String("working-dir", cmd.PactusDefaultHomeDir(), "working directory path") passwordOpt = flag.String("password", "", "wallet password") + passwordFromFileOpt = flag.String("password-from-file", "", "file containing the wallet password") testnetOpt = flag.Bool("testnet", false, "initializing for the testnet") version.NodeAgent.AppType = "gui" @@ -153,6 +155,15 @@ func newNode(workingDir string) (*node.Node, *wallet.Wallet, error) { return *passwordOpt, true } + if *passwordFromFileOpt != "" { + password, err := util.ReadFileContent(*passwordFromFileOpt) + if err != nil { + return "", false + } + + return password, true + } + return getWalletPassword(wlt) } n, wlt, err := cmd.StartNode(workingDir, passwordFetcher) diff --git a/util/utils.go b/util/utils.go index bef088943..55b3bad51 100644 --- a/util/utils.go +++ b/util/utils.go @@ -7,6 +7,7 @@ import ( "math/big" "math/bits" "os" + "strings" "golang.org/x/exp/constraints" ) @@ -166,7 +167,7 @@ func FormatBytesToHumanReadable(bytes uint64) string { // ReadFileContent reads the content of the file at the given path // up to the specified maxSize. It returns the content as a string // and any error encountered. -func ReadFileContent(filePath string, maxSize int) (string, error) { +func ReadFileContent(filePath string) (string, error) { file, err := os.Open(filePath) if err != nil { return "", fmt.Errorf("failed to open file: %w", err) @@ -175,12 +176,10 @@ func ReadFileContent(filePath string, maxSize int) (string, error) { _ = file.Close() }() - buffer := make([]byte, maxSize) - - n, err := file.Read(buffer) - if err != nil && err != io.EOF { + buf, err := io.ReadAll(file) + if err != nil { return "", fmt.Errorf("failed to read file content: %w", err) } - return string(buffer[:n]), nil + return strings.TrimSpace(string(buf)), nil } diff --git a/util/utils_test.go b/util/utils_test.go index dddafe16e..73a8c8f9b 100644 --- a/util/utils_test.go +++ b/util/utils_test.go @@ -145,70 +145,54 @@ func TestReadFileContent(t *testing.T) { testCases := []struct { name string fileContent string - maxSize int expected string expectErr bool }{ { - name: "Read full content within maxSize", + name: "Read full content", fileContent: "Hello, World!", - maxSize: 50, expected: "Hello, World!", expectErr: false, }, - { - name: "Read partial content limited by maxSize", - fileContent: "Hello, World!", - maxSize: 5, - expected: "Hello", - expectErr: false, - }, { name: "Empty file", fileContent: "", - maxSize: 10, - expected: "", - expectErr: false, - }, - { - name: "Zero maxSize", - fileContent: "Content", - maxSize: 0, expected: "", expectErr: false, }, { name: "Non-existent file", fileContent: "", - maxSize: 10, expected: "", expectErr: true, }, } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { var filePath string - if tc.fileContent != "" || tc.name == "Empty file" { + if test.fileContent != "" || test.name == "Empty file" { tmpFile, err := os.CreateTemp(TempDirPath(), "testfile") assert.NoError(t, err, "Failed to create temp file") - defer os.Remove(tmpFile.Name()) + defer func() { + _ = os.Remove(tmpFile.Name()) + }() - _, err = tmpFile.WriteString(tc.fileContent) + _, err = tmpFile.WriteString(test.fileContent) assert.NoError(t, err, "Failed to write to temp file") - tmpFile.Close() + _ = tmpFile.Close() filePath = tmpFile.Name() } else { filePath = "nonexistent_file" } - content, err := ReadFileContent(filePath, tc.maxSize) + content, err := ReadFileContent(filePath) - if tc.expectErr { + if test.expectErr { assert.Error(t, err, "Expected an error but got none") } else { assert.NoError(t, err, "Unexpected error occurred") - assert.Equal(t, tc.expected, content, "Content does not match expected value") + assert.Equal(t, test.expected, content, "Content does not match expected value") } }) } From 0fe8e1a223f0f573f14ab2290bcf3a69298b3351 Mon Sep 17 00:00:00 2001 From: Javad Date: Sun, 29 Dec 2024 08:37:53 +0330 Subject: [PATCH 3/6] fix: remove password from file for gtk --- cmd/gtk/main.go | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/cmd/gtk/main.go b/cmd/gtk/main.go index 6e36810fb..f503aa88b 100644 --- a/cmd/gtk/main.go +++ b/cmd/gtk/main.go @@ -24,16 +24,14 @@ import ( const appID = "com.github.pactus-project.pactus.pactus-gui" var ( - workingDirOpt *string - passwordOpt *string - passwordFromFileOpt *string - testnetOpt *bool + workingDirOpt *string + passwordOpt *string + testnetOpt *bool ) func init() { workingDirOpt = flag.String("working-dir", cmd.PactusDefaultHomeDir(), "working directory path") passwordOpt = flag.String("password", "", "wallet password") - passwordFromFileOpt = flag.String("password-from-file", "", "file containing the wallet password") testnetOpt = flag.Bool("testnet", false, "initializing for the testnet") version.NodeAgent.AppType = "gui" @@ -155,15 +153,6 @@ func newNode(workingDir string) (*node.Node, *wallet.Wallet, error) { return *passwordOpt, true } - if *passwordFromFileOpt != "" { - password, err := util.ReadFileContent(*passwordFromFileOpt) - if err != nil { - return "", false - } - - return password, true - } - return getWalletPassword(wlt) } n, wlt, err := cmd.StartNode(workingDir, passwordFetcher) From 86f8e8a20184bb249e8afcd403a7054d1f4f416b Mon Sep 17 00:00:00 2001 From: Javad Date: Sun, 29 Dec 2024 08:42:53 +0330 Subject: [PATCH 4/6] fix: used readfile to get password from file --- cmd/daemon/start.go | 4 +++- util/utils.go | 23 ------------------ util/utils_test.go | 58 --------------------------------------------- 3 files changed, 3 insertions(+), 82 deletions(-) diff --git a/cmd/daemon/start.go b/cmd/daemon/start.go index cb117c7f9..fe2efc737 100644 --- a/cmd/daemon/start.go +++ b/cmd/daemon/start.go @@ -3,6 +3,7 @@ package main import ( "os" "path/filepath" + "strings" "github.com/gofrs/flock" "github.com/pactus-project/pactus/cmd" @@ -57,10 +58,11 @@ func buildStartCmd(parentCmd *cobra.Command) { if *passwordOpt != "" { password = *passwordOpt } else if *passwordFromFileOpt != "" { - password, err = util.ReadFileContent(*passwordFromFileOpt) + b, err := util.ReadFile(*passwordFromFileOpt) if err != nil { return "", false } + password = strings.TrimSpace(string(b)) } else { password = cmd.PromptPassword("Wallet password", false) } diff --git a/util/utils.go b/util/utils.go index 55b3bad51..ba58dc8b4 100644 --- a/util/utils.go +++ b/util/utils.go @@ -3,11 +3,8 @@ package util import ( crand "crypto/rand" "fmt" - "io" "math/big" "math/bits" - "os" - "strings" "golang.org/x/exp/constraints" ) @@ -163,23 +160,3 @@ func FormatBytesToHumanReadable(bytes uint64) string { return fmt.Sprintf("%.2f %s", value, unit) } - -// ReadFileContent reads the content of the file at the given path -// up to the specified maxSize. It returns the content as a string -// and any error encountered. -func ReadFileContent(filePath string) (string, error) { - file, err := os.Open(filePath) - if err != nil { - return "", fmt.Errorf("failed to open file: %w", err) - } - defer func() { - _ = file.Close() - }() - - buf, err := io.ReadAll(file) - if err != nil { - return "", fmt.Errorf("failed to read file content: %w", err) - } - - return strings.TrimSpace(string(buf)), nil -} diff --git a/util/utils_test.go b/util/utils_test.go index 73a8c8f9b..7def6e3e0 100644 --- a/util/utils_test.go +++ b/util/utils_test.go @@ -2,7 +2,6 @@ package util import ( "math/big" - "os" "testing" "github.com/stretchr/testify/assert" @@ -140,60 +139,3 @@ func TestFormatBytesToHumanReadable(t *testing.T) { } } } - -func TestReadFileContent(t *testing.T) { - testCases := []struct { - name string - fileContent string - expected string - expectErr bool - }{ - { - name: "Read full content", - fileContent: "Hello, World!", - expected: "Hello, World!", - expectErr: false, - }, - { - name: "Empty file", - fileContent: "", - expected: "", - expectErr: false, - }, - { - name: "Non-existent file", - fileContent: "", - expected: "", - expectErr: true, - }, - } - - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - var filePath string - if test.fileContent != "" || test.name == "Empty file" { - tmpFile, err := os.CreateTemp(TempDirPath(), "testfile") - assert.NoError(t, err, "Failed to create temp file") - defer func() { - _ = os.Remove(tmpFile.Name()) - }() - - _, err = tmpFile.WriteString(test.fileContent) - assert.NoError(t, err, "Failed to write to temp file") - _ = tmpFile.Close() - filePath = tmpFile.Name() - } else { - filePath = "nonexistent_file" - } - - content, err := ReadFileContent(filePath) - - if test.expectErr { - assert.Error(t, err, "Expected an error but got none") - } else { - assert.NoError(t, err, "Unexpected error occurred") - assert.Equal(t, test.expected, content, "Content does not match expected value") - } - }) - } -} From 5bcc226b2f560d7d3acac755af7cc29323ae4f22 Mon Sep 17 00:00:00 2001 From: Javad Date: Mon, 30 Dec 2024 09:47:35 +0330 Subject: [PATCH 5/6] fix: show error on failed open password file --- cmd/daemon/start.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cmd/daemon/start.go b/cmd/daemon/start.go index fe2efc737..339c4bd08 100644 --- a/cmd/daemon/start.go +++ b/cmd/daemon/start.go @@ -59,9 +59,7 @@ func buildStartCmd(parentCmd *cobra.Command) { password = *passwordOpt } else if *passwordFromFileOpt != "" { b, err := util.ReadFile(*passwordFromFileOpt) - if err != nil { - return "", false - } + cmd.FatalErrorCheck(err) password = strings.TrimSpace(string(b)) } else { password = cmd.PromptPassword("Wallet password", false) From aedfdaf1e5acea10e6add49f8db04891daf90e36 Mon Sep 17 00:00:00 2001 From: b00f Date: Mon, 30 Dec 2024 14:42:17 +0800 Subject: [PATCH 6/6] Update cmd/daemon/start.go --- cmd/daemon/start.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/daemon/start.go b/cmd/daemon/start.go index 339c4bd08..2d0616ad8 100644 --- a/cmd/daemon/start.go +++ b/cmd/daemon/start.go @@ -60,6 +60,7 @@ func buildStartCmd(parentCmd *cobra.Command) { } else if *passwordFromFileOpt != "" { b, err := util.ReadFile(*passwordFromFileOpt) cmd.FatalErrorCheck(err) + password = strings.TrimSpace(string(b)) } else { password = cmd.PromptPassword("Wallet password", false)