Skip to content

Commit

Permalink
feat: impl encrypt command
Browse files Browse the repository at this point in the history
- refactor main package
- read flags and inputs
- use cipher to encrypt input from terminal
  • Loading branch information
vtno committed May 4, 2023
1 parent dbbc999 commit 60ec952
Show file tree
Hide file tree
Showing 10 changed files with 210 additions and 97 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
build:
go build -o build
go build -o build cmd/zypher.go
.PHONY: build

generate:
Expand Down
38 changes: 0 additions & 38 deletions cmd/encrypt.go

This file was deleted.

32 changes: 0 additions & 32 deletions cmd/encrypt_test.go

This file was deleted.

43 changes: 43 additions & 0 deletions cmd/zypher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package main

import (
"flag"
"os"

"github.com/mitchellh/cli"
"github.com/vtno/zypher"
"github.com/vtno/zypher/internal/encrypt"
)

type CipherFactory struct{}

func (cf *CipherFactory) NewCipher(key string) encrypt.Cipher {
return zypher.NewCipher(key)
}

var (
key string
outFile string
inputFile string
)

func init() {
flag.StringVar(&key, "key", "", "key to encrypt/decrypt")
flag.StringVar(&key, "k", "", "key to encrypt/decrypt (shorthand)")
flag.StringVar(&outFile, "out", "", "output file to be created")
flag.StringVar(&outFile, "o", "", "output file to be created (shorthand)")
flag.StringVar(&inputFile, "file", "", "input file to be encrypted")
flag.StringVar(&inputFile, "f", "", "input file to be encrypted (shorthand)")
}

func main() {
c := cli.NewCLI("zypher", "0.0.1")
c.Args = os.Args[1:]
c.HelpFunc = cli.BasicHelpFunc("zypher")
c.Commands = map[string]cli.CommandFactory{
"encrypt": func() (cli.Command, error) {
return encrypt.NewEncryptCmd(&CipherFactory{}), nil
},
}
c.Run()
}
2 changes: 1 addition & 1 deletion generate.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package zypher

//go:generate mockgen -source=cmd/encrypt.go -destination=cmd/encrypt_mock.go -package=cmd
//go:generate mockgen -source=internal/encrypt/encrypt.go -destination=internal/encrypt/encrypt_mock.go -package=encrypt
8 changes: 8 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package config

type Config struct {
Key string
OutFile string
Input string
InputFile string
}
82 changes: 82 additions & 0 deletions internal/encrypt/encrypt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package encrypt

import (
"flag"
"fmt"

"github.com/vtno/zypher"
"github.com/vtno/zypher/internal/config"
)

type Cipher interface {
Encrypt([]byte) ([]byte, error)
Decrypt([]byte) ([]byte, error)
}

type CipherFactory interface {
NewCipher(string) Cipher
}

const (
HelpMsg = `Usage: zypher encrypt [options] <input-value>
available options:
-k, --key=<key> key to encrypt/decrypt
-f, --file=<path-to-file> input file to be encrypted
-o, --out=<path-to-file> output file to be created
`
SynopsisMsg = "encrypts input value or file with the provided key and prints the encrypted value to stdout or create a file"
)

type EncryptCmd struct {
fs *flag.FlagSet
cfg *config.Config
cf CipherFactory
ci Cipher
}

func NewEncryptCmd(cf CipherFactory) *EncryptCmd {
fs := flag.NewFlagSet("encrypt", flag.ContinueOnError)
cfg := &config.Config{}
fs.StringVar(&cfg.Key, "key", "", "key to encrypt/decrypt")
fs.StringVar(&cfg.Key, "k", "", "key to encrypt/decrypt (shorthand)")
fs.StringVar(&cfg.OutFile, "out", "", "output file to be created")
fs.StringVar(&cfg.OutFile, "o", "", "output file to be created (shorthand)")
fs.StringVar(&cfg.InputFile, "file", "", "input file to be encrypted")
fs.StringVar(&cfg.InputFile, "f", "", "input file to be encrypted (shorthand)")

return &EncryptCmd{
cfg: cfg,
fs: fs,
cf: cf,
}
}

func (e *EncryptCmd) Help() string {
return HelpMsg
}

func (e *EncryptCmd) Synopsis() string {
return SynopsisMsg
}

func (e *EncryptCmd) Init(args []string) error {
err := e.fs.Parse(args)
if err != nil {
return fmt.Errorf("error parsing flag from args: %w", err)
}
e.ci = zypher.NewCipher(e.cfg.Key)
return nil
}

func (e *EncryptCmd) Run(args []string) int {
e.Init(args)
if len(e.fs.Args()) == 1 {
encrypted, err := e.ci.Encrypt([]byte(e.fs.Args()[0]))
if err != nil {
fmt.Printf("error encrypting: %v\n", err)
return 1
}
fmt.Printf(string(encrypted))
}
return 0
}
43 changes: 40 additions & 3 deletions cmd/encrypt_mock.go → internal/encrypt/encrypt_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 35 additions & 0 deletions internal/encrypt/encrypt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package encrypt_test

import (
"testing"

"github.com/golang/mock/gomock"
"github.com/vtno/zypher/internal/encrypt"
)

func TestEncrypt_Help(t *testing.T) {
ctrl := gomock.NewController(t)
encryptCmd := encrypt.NewEncryptCmd(encrypt.NewMockCipherFactory(ctrl))
msg := encryptCmd.Help()
if msg != encrypt.HelpMsg {
t.Errorf("Expected correct help message, got %s", msg)
}
}

func TestEncrypt_Synopsis(t *testing.T) {
ctrl := gomock.NewController(t)
encryptCmd := encrypt.NewEncryptCmd(encrypt.NewMockCipherFactory(ctrl))
msg := encryptCmd.Synopsis()
if msg != "encrypts input value or file with the provided key and prints the encrypted value to stdout or create a file" {
t.Errorf("Expected correct synopsis message, got %s", msg)
}
}

func TestEncrypt_Run(t *testing.T) {
ctrl := gomock.NewController(t)
encryptCmd := encrypt.NewEncryptCmd(encrypt.NewMockCipherFactory(ctrl))
errCode := encryptCmd.Run([]string{"-k", "key", "-f", "input.txt", "-o", "input.enc"})
if errCode != 0 {
t.Errorf("Expected code 0, got %d", errCode)
}
}
22 changes: 0 additions & 22 deletions main.go

This file was deleted.

0 comments on commit 60ec952

Please sign in to comment.