mirror of
https://github.com/Luzifer/vault-otp-ui.git
synced 2024-11-08 08:10:11 +00:00
Cache vault token instead of creating one each request
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
a408048b2e
commit
aceb3298a0
2 changed files with 60 additions and 9 deletions
30
main.go
30
main.go
|
@ -5,6 +5,7 @@ package main
|
|||
import (
|
||||
"bytes"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -184,21 +185,42 @@ func handleOAuthCallback(res http.ResponseWriter, r *http.Request) {
|
|||
func handleCodesJSON(res http.ResponseWriter, r *http.Request) {
|
||||
sess, _ := cookieStore.Get(r, sessionName)
|
||||
iAccessToken, hasAccessToken := sess.Values["access_token"]
|
||||
iToken := sess.Values["vault_token"]
|
||||
|
||||
if !hasAccessToken {
|
||||
http.Error(res, `{"error":"Not logged in"}`, http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
accessToken := iAccessToken.(string)
|
||||
|
||||
tokens, err := getSecretsFromVault(accessToken)
|
||||
var tok string
|
||||
if iToken != nil {
|
||||
tok = iToken.(string)
|
||||
log.WithFields(log.Fields{"token": hashSecret(tok)}).Debugf("Restored token from Session")
|
||||
}
|
||||
|
||||
tok, err := useOrRenewToken(tok, accessToken)
|
||||
if err != nil {
|
||||
log.Errorf("Unable to authorize against vault: %s", err)
|
||||
http.Error(res, `{"error":"Unexpected error while fetching tokens"}`, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
log.WithFields(log.Fields{"token": hashSecret(tok)}).Debugf("Checked / renewed token")
|
||||
|
||||
tokens, err := getSecretsFromVault(tok)
|
||||
if err != nil {
|
||||
log.Errorf("Unable to fetch codes: %s", err)
|
||||
http.Error(res, `{"error":"Unexpected error while fetching tokens"}`, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
sess.Values["vault_token"] = tok
|
||||
if err := sess.Save(r, res); err != nil {
|
||||
log.Errorf("Was not able to set the cookie: %s", err)
|
||||
http.Error(res, "Something went wrong while fetching token. Sorry.", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
n := time.Now()
|
||||
result := struct {
|
||||
Tokens []*token `json:"tokens"`
|
||||
|
@ -230,3 +252,7 @@ func handleStatics(res http.ResponseWriter, r *http.Request) {
|
|||
res.Header().Set("Content-Type", t)
|
||||
res.Write(b)
|
||||
}
|
||||
|
||||
func hashSecret(in string) string {
|
||||
return fmt.Sprintf("sha256:%x", sha256.Sum256([]byte(in)))
|
||||
}
|
||||
|
|
39
token.go
39
token.go
|
@ -8,9 +8,9 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/hashicorp/vault/api"
|
||||
"github.com/pquerna/otp/totp"
|
||||
"github.com/prometheus/common/log"
|
||||
)
|
||||
|
||||
type token struct {
|
||||
|
@ -50,7 +50,36 @@ func (t tokenList) LongestName() (l int) {
|
|||
return
|
||||
}
|
||||
|
||||
func getSecretsFromVault(accessToken string) ([]*token, error) {
|
||||
func useOrRenewToken(tok, accessToken string) (string, error) {
|
||||
client, err := api.NewClient(&api.Config{
|
||||
Address: cfg.Vault.Address,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Unable to create client: %s", err)
|
||||
}
|
||||
|
||||
if tok != "" {
|
||||
client.SetToken(tok)
|
||||
if s, err := client.Auth().Token().LookupSelf(); err == nil && s.Data != nil {
|
||||
log.WithFields(log.Fields{"token": hashSecret(tok)}).Debugf("Token is valid for another %vs", s.Data["ttl"])
|
||||
return tok, nil
|
||||
} else {
|
||||
log.WithFields(log.Fields{"token": hashSecret(tok)}).Debugf("Token did not met requirements: err = %s", err)
|
||||
if s != nil {
|
||||
log.WithFields(log.Fields{"token": hashSecret(tok)}).Debugf("Token did not met requirements: data = %v", s.Data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if s, err := client.Logical().Write("auth/github/login", map[string]interface{}{"token": accessToken}); err != nil || s.Auth == nil {
|
||||
return "", fmt.Errorf("Login did not work: Error = %s", err)
|
||||
} else {
|
||||
return s.Auth.ClientToken, nil
|
||||
}
|
||||
}
|
||||
|
||||
func getSecretsFromVault(tok string) ([]*token, error) {
|
||||
client, err := api.NewClient(&api.Config{
|
||||
Address: cfg.Vault.Address,
|
||||
})
|
||||
|
@ -59,11 +88,7 @@ func getSecretsFromVault(accessToken string) ([]*token, error) {
|
|||
return nil, fmt.Errorf("Unable to create client: %s", err)
|
||||
}
|
||||
|
||||
if s, err := client.Logical().Write("auth/github/login", map[string]interface{}{"token": accessToken}); err != nil || s.Auth == nil {
|
||||
return nil, fmt.Errorf("Login did not work: Error = %s", err)
|
||||
} else {
|
||||
client.SetToken(s.Auth.ClientToken)
|
||||
}
|
||||
client.SetToken(tok)
|
||||
|
||||
key := cfg.Vault.Prefix
|
||||
|
||||
|
|
Loading…
Reference in a new issue