1
0
mirror of https://github.com/Luzifer/vault-otp-ui.git synced 2024-09-19 00:53:01 +00:00

Cache vault token instead of creating one each request

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2017-06-19 19:33:55 +02:00
parent a408048b2e
commit aceb3298a0
Signed by: luzifer
GPG Key ID: DC2729FDD34BE99E
2 changed files with 60 additions and 9 deletions

30
main.go
View File

@ -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)))
}

View File

@ -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