simple-privacy-tool/cmd/spt/spt.go

189 lines
3.4 KiB
Go

package spt
import (
"errors"
"os"
tw "gitea.suyono.dev/suyono/terminal_wrapper"
"github.com/spf13/cobra"
"log"
)
type cApp struct {
term *tw.Terminal
srcPath string
dstPath string
srcFile *os.File
dstFile *os.File
passphrase string
}
var (
//ErrFatalError = errors.New("fatal error occurred")
ErrPassphraseMismatch = errors.New("mismatch passphrase")
rootCmd = &cobra.Command{
Use: "simple-privacy-tool",
Short: "a simple tool to encrypt and decrypt file",
}
hintCmd = &cobra.Command{
Use: "hint file",
Args: cobra.ExactArgs(1),
RunE: CmdReadHint,
Short: "extract and print hint from encrypted file",
}
encryptCmd = &cobra.Command{
Use: "encrypt srcFile dstFile",
Args: validatePositionalArgs,
RunE: func(cmd *cobra.Command, args []string) error {
if err := processFlags(); err != nil {
return err
}
return encrypt(cmd, args)
},
Short: "encrypt srcFile, output to dstFile",
}
decryptCmd = &cobra.Command{
Use: "decrypt srcFile dstFile",
RunE: func(cmd *cobra.Command, args []string) error {
if err := processFlags(); err != nil {
return err
}
return decrypt(cmd, args)
},
Args: validatePositionalArgs,
Short: "decrypt srcFile, output to dstFile",
}
)
func Execute() error {
return rootCmd.Execute()
}
func init() {
initFlags()
rootCmd.AddCommand(encryptCmd, decryptCmd, hintCmd)
}
func validatePositionalArgs(cmd *cobra.Command, args []string) error {
if len(args) != 0 && len(args) != 2 {
//TODO: improve the error message
return errors.New("invalid arguments")
}
return nil
}
func encrypt(cmd *cobra.Command, args []string) (err error) {
var (
terminal *tw.Terminal
app *cApp
eApp *encryptApp
)
if terminal, err = tw.MakeTerminal(os.Stderr); err != nil {
return
}
log.SetOutput(terminal)
defer func() {
existingErr := err
if err = terminal.Restore(); err == nil && existingErr != nil {
err = existingErr
}
log.SetOutput(os.Stderr)
}()
app = &cApp{
term: terminal,
}
if err = app.ProcessArgs(args); err != nil {
return
}
eApp = &encryptApp{
cApp: *app,
}
if err = eApp.GetPassphrase(); err != nil {
return
}
if err = eApp.ProcessFiles(); err != nil {
return
}
return nil
}
func decrypt(cmd *cobra.Command, args []string) (err error) {
var (
terminal *tw.Terminal
app *cApp
dApp *decryptApp
)
if terminal, err = tw.MakeTerminal(os.Stderr); err != nil {
return
}
log.SetOutput(terminal)
defer func() {
existingErr := err
if err = terminal.Restore(); err == nil && existingErr != nil {
err = existingErr
}
log.SetOutput(os.Stderr)
}()
app = &cApp{
term: terminal,
}
if err = app.ProcessArgs(args); err != nil {
return
}
dApp = &decryptApp{
cApp: *app,
}
if err = dApp.GetPassphrase(); err != nil {
return
}
if err = dApp.ProcessFiles(); err != nil {
return
}
return nil
}
func (a *cApp) ProcessArgs(args []string) (err error) {
if len(args) == 0 {
a.srcFile = os.Stdin
a.dstFile = os.Stdout
} else {
a.srcPath = args[0]
a.dstPath = args[1]
if a.srcPath == "-" {
a.srcFile = os.Stdin
} else {
if a.srcFile, err = os.Open(a.srcPath); err != nil {
return
}
}
if a.dstPath == "-" {
a.dstFile = os.Stdout
} else {
if a.dstFile, err = os.OpenFile(a.dstPath, os.O_CREATE|os.O_WRONLY, 0640); err != nil { //TODO: allow user to define the destination file permission
return
}
}
}
return
}