1
0
mirror of https://github.com/Luzifer/vault-otp-ui.git synced 2024-09-19 09:03:00 +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 ( import (
"bytes" "bytes"
"crypto/sha1" "crypto/sha1"
"crypto/sha256"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
@ -184,21 +185,42 @@ func handleOAuthCallback(res http.ResponseWriter, r *http.Request) {
func handleCodesJSON(res http.ResponseWriter, r *http.Request) { func handleCodesJSON(res http.ResponseWriter, r *http.Request) {
sess, _ := cookieStore.Get(r, sessionName) sess, _ := cookieStore.Get(r, sessionName)
iAccessToken, hasAccessToken := sess.Values["access_token"] iAccessToken, hasAccessToken := sess.Values["access_token"]
iToken := sess.Values["vault_token"]
if !hasAccessToken { if !hasAccessToken {
http.Error(res, `{"error":"Not logged in"}`, http.StatusUnauthorized) http.Error(res, `{"error":"Not logged in"}`, http.StatusUnauthorized)
return return
} }
accessToken := iAccessToken.(string) 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 { if err != nil {
log.Errorf("Unable to fetch codes: %s", err) log.Errorf("Unable to fetch codes: %s", err)
http.Error(res, `{"error":"Unexpected error while fetching tokens"}`, http.StatusInternalServerError) http.Error(res, `{"error":"Unexpected error while fetching tokens"}`, http.StatusInternalServerError)
return 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() n := time.Now()
result := struct { result := struct {
Tokens []*token `json:"tokens"` Tokens []*token `json:"tokens"`
@ -230,3 +252,7 @@ func handleStatics(res http.ResponseWriter, r *http.Request) {
res.Header().Set("Content-Type", t) res.Header().Set("Content-Type", t)
res.Write(b) 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" "sync"
"time" "time"
log "github.com/Sirupsen/logrus"
"github.com/hashicorp/vault/api" "github.com/hashicorp/vault/api"
"github.com/pquerna/otp/totp" "github.com/pquerna/otp/totp"
"github.com/prometheus/common/log"
) )
type token struct { type token struct {
@ -50,7 +50,36 @@ func (t tokenList) LongestName() (l int) {
return 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{ client, err := api.NewClient(&api.Config{
Address: cfg.Vault.Address, Address: cfg.Vault.Address,
}) })
@ -59,11 +88,7 @@ func getSecretsFromVault(accessToken string) ([]*token, error) {
return nil, fmt.Errorf("Unable to create client: %s", err) 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 { client.SetToken(tok)
return nil, fmt.Errorf("Login did not work: Error = %s", err)
} else {
client.SetToken(s.Auth.ClientToken)
}
key := cfg.Vault.Prefix key := cfg.Vault.Prefix