open-vault/command/token/helper_internal.go
Jeff Mitchell 1a324cf347 Make TokenHelper an interface and split exisiting functionality
Functionality is split into ExternalTokenHelper, which is used if a path
is given in a configuration file, and InternalTokenHelper which is used
otherwise. The internal helper no longer shells out to the same Vault
binary, instead performing the same actions with internal code. This
avoids problems using dev mode when there are spaces in paths or when
the binary is built in a container without a shell.

Fixes #850 among others
2015-12-22 10:23:30 -05:00

78 lines
1.6 KiB
Go

package token
import (
"bytes"
"fmt"
"io"
"os"
"github.com/mitchellh/go-homedir"
)
// InternalTokenHelper fulfills the TokenHelper interface when no external
// token-helper is configured, and avoids shelling out
type InternalTokenHelper struct {
tokenPath string
}
// populateTokenPath figures out the token path using homedir to get the user's
// home directory
func (i *InternalTokenHelper) populateTokenPath() {
homePath, err := homedir.Dir()
if err != nil {
panic(fmt.Errorf("error getting user's home directory: %v", err))
}
i.tokenPath = homePath + "/.vault-token"
}
func (i *InternalTokenHelper) Path() string {
return i.tokenPath
}
// Get gets the value of the stored token, if any
func (i *InternalTokenHelper) Get() (string, error) {
i.populateTokenPath()
f, err := os.Open(i.tokenPath)
if os.IsNotExist(err) {
return "", nil
}
if err != nil {
return "", err
}
defer f.Close()
buf := bytes.NewBuffer(nil)
if _, err := io.Copy(buf, f); err != nil {
return "", err
}
return buf.String(), nil
}
// Store stores the value of the token to the file
func (i *InternalTokenHelper) Store(input string) error {
i.populateTokenPath()
f, err := os.OpenFile(i.tokenPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
if err != nil {
return err
}
defer f.Close()
buf := bytes.NewBufferString(input)
if _, err := io.Copy(f, buf); err != nil {
return err
}
return nil
}
// Erase erases the value of the token
func (i *InternalTokenHelper) Erase() error {
i.populateTokenPath()
if err := os.Remove(i.tokenPath); err != nil && !os.IsNotExist(err) {
return err
}
return nil
}