mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 18:48:08 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			116 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package http
 | |
| 
 | |
| import (
 | |
| 	"net/http"
 | |
| 	"strings"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/hashicorp/vault/logical"
 | |
| 	"github.com/hashicorp/vault/vault"
 | |
| )
 | |
| 
 | |
| func handleLogical(core *vault.Core) http.Handler {
 | |
| 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | |
| 		// Determine the path...
 | |
| 		if !strings.HasPrefix(r.URL.Path, "/v1/") {
 | |
| 			respondError(w, http.StatusNotFound, nil)
 | |
| 			return
 | |
| 		}
 | |
| 		path := r.URL.Path[len("/v1/"):]
 | |
| 		if path == "" {
 | |
| 			respondError(w, http.StatusNotFound, nil)
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		// Determine the operation
 | |
| 		var op logical.Operation
 | |
| 		switch r.Method {
 | |
| 		case "GET":
 | |
| 			op = logical.ReadOperation
 | |
| 		case "PUT":
 | |
| 			op = logical.WriteOperation
 | |
| 		default:
 | |
| 			respondError(w, http.StatusMethodNotAllowed, nil)
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		// Parse the request if we can
 | |
| 		var req map[string]interface{}
 | |
| 		if op == logical.WriteOperation {
 | |
| 			if err := parseRequest(r, &req); err != nil {
 | |
| 				respondError(w, http.StatusBadRequest, err)
 | |
| 				return
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		// Make the internal request. We attach the connection info
 | |
| 		// as well in case this is an authentication request that requires
 | |
| 		// it. Vault core handles stripping this if we need to.
 | |
| 		resp, err := core.HandleRequest(requestAuth(r, &logical.Request{
 | |
| 			Operation: op,
 | |
| 			Path:      path,
 | |
| 			Data:      req,
 | |
| 			Connection: &logical.Connection{
 | |
| 				RemoteAddr: r.RemoteAddr,
 | |
| 				ConnState:  r.TLS,
 | |
| 			},
 | |
| 		}))
 | |
| 		if err != nil {
 | |
| 			respondError(w, http.StatusInternalServerError, err)
 | |
| 			return
 | |
| 		}
 | |
| 		if respondCommon(w, resp) {
 | |
| 			return
 | |
| 		}
 | |
| 		if op == logical.ReadOperation && resp == nil {
 | |
| 			respondError(w, http.StatusNotFound, nil)
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		var httpResp interface{}
 | |
| 		if resp != nil {
 | |
| 			if resp.Redirect != "" {
 | |
| 				// If we have a redirect, redirect! We use a 302 code
 | |
| 				// because we don't actually know if its permanent.
 | |
| 				http.Redirect(w, r, resp.Redirect, 302)
 | |
| 				return
 | |
| 			}
 | |
| 
 | |
| 			logicalResp := &LogicalResponse{Data: resp.Data}
 | |
| 			if resp.Secret != nil {
 | |
| 				logicalResp.VaultId = resp.Secret.VaultID
 | |
| 				logicalResp.Renewable = resp.Secret.Renewable
 | |
| 				logicalResp.LeaseDuration = int(resp.Secret.Lease.Seconds())
 | |
| 			}
 | |
| 
 | |
| 			// If we have authentication information, then set the cookie
 | |
| 			if resp.Auth != nil {
 | |
| 				expireDuration := 365 * 24 * time.Hour
 | |
| 				if logicalResp.LeaseDuration != 0 {
 | |
| 					expireDuration =
 | |
| 						time.Duration(logicalResp.LeaseDuration) * time.Second
 | |
| 				}
 | |
| 
 | |
| 				http.SetCookie(w, &http.Cookie{
 | |
| 					Name:    AuthCookieName,
 | |
| 					Value:   resp.Auth.ClientToken,
 | |
| 					Path:    "/",
 | |
| 					Expires: time.Now().UTC().Add(expireDuration),
 | |
| 				})
 | |
| 			}
 | |
| 
 | |
| 			httpResp = logicalResp
 | |
| 		}
 | |
| 
 | |
| 		// Respond
 | |
| 		respondOk(w, httpResp)
 | |
| 	})
 | |
| }
 | |
| 
 | |
| type LogicalResponse struct {
 | |
| 	VaultId       string                 `json:"vault_id"`
 | |
| 	Renewable     bool                   `json:"renewable"`
 | |
| 	LeaseDuration int                    `json:"lease_duration"`
 | |
| 	Data          map[string]interface{} `json:"data"`
 | |
| }
 | 
