command/token: helper to read/write tokens from a helper
This commit is contained in:
parent
e78c972351
commit
62e36ecb68
|
@ -0,0 +1,53 @@
|
|||
package token
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// Helper is the struct that has all the logic for storing and retrieving
|
||||
// tokens from the token helper. The API for the helpers is simple: the
|
||||
// Path is executed within a shell. The last argument appended will be the
|
||||
// operation, which is:
|
||||
//
|
||||
// * "get" - Read the value of the token and write it to stdout.
|
||||
// * "store" - Store the value of the token which is on stdin. Output
|
||||
// nothing.
|
||||
// * "erase" - Erase the contents stored. Output nothing.
|
||||
//
|
||||
// Any errors can be written on stdout. If the helper exits with a non-zero
|
||||
// exit code then the stderr will be made part of the error value.
|
||||
type Helper struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
// Erase deletes the contents from the helper.
|
||||
func (h *Helper) Erase() error {
|
||||
cmd := h.cmd("erase")
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// Get gets the token value from the helper.
|
||||
func (h *Helper) Get() (string, error) {
|
||||
var buf bytes.Buffer
|
||||
cmd := h.cmd("get")
|
||||
cmd.Stdout = &buf
|
||||
if err := cmd.Run(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
// Store stores the token value into the helper.
|
||||
func (h *Helper) Store(v string) error {
|
||||
buf := bytes.NewBufferString(v)
|
||||
cmd := h.cmd("store")
|
||||
cmd.Stdin = buf
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func (h *Helper) cmd(op string) *exec.Cmd {
|
||||
cmd := exec.Command("sh", "-c", h.Path+" "+op)
|
||||
return cmd
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
package token
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHelper(t *testing.T) {
|
||||
h := testHelper(t)
|
||||
if err := h.Store("foo"); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
v, err := h.Get()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if v != "foo" {
|
||||
t.Fatalf("bad: %#v", v)
|
||||
}
|
||||
|
||||
if err := h.Erase(); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
v, err = h.Get()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if v != "" {
|
||||
t.Fatalf("bad: %#v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func testHelper(t *testing.T) *Helper {
|
||||
return &Helper{Path: helperPath("helper")}
|
||||
}
|
||||
|
||||
func helperPath(s ...string) string {
|
||||
tf, err := ioutil.TempFile("", "vault")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
tf.Close()
|
||||
|
||||
cs := []string{"-test.run=TestHelperProcess", "--"}
|
||||
cs = append(cs, s...)
|
||||
return fmt.Sprintf(
|
||||
"GO_HELPER_PATH=%s GO_WANT_HELPER_PROCESS=1 %s %s",
|
||||
tf.Name(),
|
||||
os.Args[0],
|
||||
strings.Join(cs, " "))
|
||||
}
|
||||
|
||||
// This is not a real test. This is just a helper process kicked off by tests.
|
||||
func TestHelperProcess(*testing.T) {
|
||||
if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
|
||||
return
|
||||
}
|
||||
|
||||
defer os.Exit(0)
|
||||
|
||||
args := os.Args
|
||||
for len(args) > 0 {
|
||||
if args[0] == "--" {
|
||||
args = args[1:]
|
||||
break
|
||||
}
|
||||
|
||||
args = args[1:]
|
||||
}
|
||||
|
||||
if len(args) == 0 {
|
||||
fmt.Fprintf(os.Stderr, "No command\n")
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
cmd, args := args[0], args[1:]
|
||||
switch cmd {
|
||||
case "helper":
|
||||
path := os.Getenv("GO_HELPER_PATH")
|
||||
|
||||
switch args[0] {
|
||||
case "erase":
|
||||
os.Remove(path)
|
||||
case "get":
|
||||
f, err := os.Open(path)
|
||||
if os.IsNotExist(err) {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Err: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer f.Close()
|
||||
io.Copy(os.Stdout, f)
|
||||
case "store":
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Err: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer f.Close()
|
||||
io.Copy(f, os.Stdin)
|
||||
}
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "Unknown command: %q\n", cmd)
|
||||
os.Exit(2)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue