163 lines
3.6 KiB
Go
163 lines
3.6 KiB
Go
//////////////////////////////////////////////////////////////////////////
|
|
|
|
package libvault
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
import (
|
|
"errors"
|
|
log "github.com/sirupsen/logrus"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
type Token struct {
|
|
Token string
|
|
expires time.Time
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// read and save token to a file
|
|
|
|
func NewTokenFromFile(filename string) (*Token, error) {
|
|
|
|
// default the filename if not passed as arg
|
|
if filename == "" {
|
|
filename = VAULT_TOKEN_FILE
|
|
}
|
|
|
|
// read the contents of the file
|
|
b, err := os.ReadFile(filename)
|
|
if err != nil {
|
|
log.WithFields(log.Fields{
|
|
"filename": filename,
|
|
"error": err,
|
|
}).Error("libvault: failed to read vault token from file")
|
|
return nil, err
|
|
}
|
|
|
|
// get first line and trim any whitespace
|
|
ts, _, _ := strings.Cut(string(b), "\n")
|
|
ts = strings.TrimSpace(ts)
|
|
if ts == "" {
|
|
log.WithFields(log.Fields{
|
|
"filename": filename,
|
|
"raw": string(b),
|
|
}).Error("libvault: failed to parse vault token from file")
|
|
return nil, errors.New("libvault: failed to parse vault token from file")
|
|
}
|
|
|
|
log.WithFields(log.Fields{
|
|
"filename": filename,
|
|
"token": ts,
|
|
}).Debug("libvault: successfully read vault token")
|
|
|
|
return &Token{Token: ts}, nil
|
|
}
|
|
|
|
func (t *Token) SaveToFile(filename string) error {
|
|
|
|
if filename == "" {
|
|
filename = VAULT_TOKEN_FILE
|
|
}
|
|
|
|
data := []byte(t.Token + "\n")
|
|
if err := os.WriteFile(filename, data, 0600); err != nil {
|
|
log.WithFields(log.Fields{
|
|
"filename": filename,
|
|
"error": err,
|
|
}).Error("libvault: failed to write token to file")
|
|
return err
|
|
}
|
|
|
|
log.WithFields(log.Fields{
|
|
"filename": filename,
|
|
}).Debug("libvault: successfully saved vault token")
|
|
|
|
return nil
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// find token expiry date
|
|
|
|
func (t *Token) Expires() (time.Time, error) {
|
|
|
|
if t.expires.IsZero() {
|
|
|
|
// request and response json structures
|
|
req := &struct {
|
|
Token string `json:"token"`
|
|
}{Token: t.Token}
|
|
|
|
resp := &struct {
|
|
Data *struct {
|
|
ExpireTime time.Time `json:"expire_time"`
|
|
} `json:"data"`
|
|
}{}
|
|
|
|
if err := vault.POST(t, "/auth/token/lookup", req, resp); err != nil {
|
|
log.WithFields(log.Fields{
|
|
"token": t.Token,
|
|
}).Error("libvault: failed to determine token expiry date")
|
|
return t.expires, err
|
|
}
|
|
|
|
t.expires = resp.Data.ExpireTime
|
|
}
|
|
|
|
return t.expires, nil
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// renew token
|
|
|
|
func (t *Token) Renew(increment time.Duration) error {
|
|
expiry, err := t.Expires()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// check if token should be renewed
|
|
ttl := expiry.Sub(time.Now())
|
|
if ttl.Seconds() > (VAULT_RENEW_PERIOD.Seconds()) {
|
|
log.WithFields(log.Fields{
|
|
"expiry": expiry.String(),
|
|
"ttl": ttl.String(),
|
|
}).Debug("Token renewal not required")
|
|
return nil
|
|
}
|
|
|
|
// renew token
|
|
|
|
if increment == 0 {
|
|
increment = VAULT_TTL
|
|
}
|
|
|
|
req := &struct {
|
|
Increment string `json:"increment"`
|
|
}{Increment: increment.String()}
|
|
|
|
if err := vault.POST(t, "/auth/token/renew-self", req, nil); err != nil {
|
|
log.WithFields(log.Fields{
|
|
"token": t.Token,
|
|
"expiry": expiry.String(),
|
|
"ttl": ttl.String(),
|
|
"increment": increment.String(),
|
|
}).Error("libvault: failed to renew token")
|
|
return err
|
|
}
|
|
|
|
// reset expiry
|
|
t.expires = time.Time{}
|
|
|
|
return nil
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// end of file
|