Enable callbacks for handling logical.Request changes before processing requests

This commit is contained in:
vishalnayak 2016-03-17 22:29:53 -04:00
parent f1feee9b53
commit 4e6dcfd6d0
3 changed files with 40 additions and 18 deletions

View File

@ -22,7 +22,7 @@ func (c *Sys) CapabilitiesSelf(path string) ([]string, error) {
return nil, err
}
var capabilities []string
capabilitiesRaw := result["data"].(map[string]interface{})["capabilities"].([]interface{})
capabilitiesRaw := result["capabilities"].([]interface{})
for _, capability := range capabilitiesRaw {
capabilities = append(capabilities, capability.(string))
}
@ -52,7 +52,7 @@ func (c *Sys) Capabilities(token, path string) ([]string, error) {
return nil, err
}
var capabilities []string
capabilitiesRaw := result["data"].(map[string]interface{})["capabilities"].([]interface{})
capabilitiesRaw := result["capabilities"].([]interface{})
for _, capability := range capabilitiesRaw {
capabilities = append(capabilities, capability.(string))
}

View File

@ -26,18 +26,18 @@ func Handler(core *vault.Core) http.Handler {
mux.Handle("/v1/sys/seal", handleSysSeal(core))
mux.Handle("/v1/sys/step-down", handleSysStepDown(core))
mux.Handle("/v1/sys/unseal", handleSysUnseal(core))
mux.Handle("/v1/sys/renew/", handleLogical(core, false))
mux.Handle("/v1/sys/renew/", handleLogical(core, false, nil))
mux.Handle("/v1/sys/leader", handleSysLeader(core))
mux.Handle("/v1/sys/health", handleSysHealth(core))
mux.Handle("/v1/sys/generate-root/attempt", handleSysGenerateRootAttempt(core))
mux.Handle("/v1/sys/generate-root/update", handleSysGenerateRootUpdate(core))
mux.Handle("/v1/sys/rekey/init", handleSysRekeyInit(core))
mux.Handle("/v1/sys/rekey/update", handleSysRekeyUpdate(core))
mux.Handle("/v1/sys/capabilities", handleSysCapabilities(core))
mux.Handle("/v1/sys/capabilities-self", handleSysCapabilities(core))
mux.Handle("/v1/sys/capabilities-accessor", handleSysCapabilitiesAccessor(core))
mux.Handle("/v1/sys/", handleLogical(core, true))
mux.Handle("/v1/", handleLogical(core, false))
//mux.Handle("/v1/sys/capabilities", handleLogical(core, false, sysCapabilitiesCallback))
mux.Handle("/v1/sys/capabilities-self", handleLogical(core, true, sysCapabilitiesCallback))
//mux.Handle("/v1/sys/capabilities-accessor", handleSysCapabilitiesAccessor(core))
mux.Handle("/v1/sys/", handleLogical(core, true, nil))
mux.Handle("/v1/", handleLogical(core, false, nil))
// Wrap the handler in another handler to trigger all help paths.
handler := handleHelpHandler(mux, core)
@ -45,6 +45,14 @@ func Handler(core *vault.Core) http.Handler {
return handler
}
func sysCapabilitiesCallback(req *logical.Request) error {
if req.Path == "sys/capabilities-self" {
req.Path = "sys/capabilities"
req.Data["token"] = req.ClientToken
}
return nil
}
// stripPrefix is a helper to strip a prefix from the path. It will
// return false from the second return value if it the prefix doesn't exist.
func stripPrefix(prefix, path string) (string, bool) {

View File

@ -11,7 +11,9 @@ import (
"github.com/hashicorp/vault/vault"
)
func handleLogical(core *vault.Core, dataOnly bool) http.Handler {
type PrepareRequest func(req *logical.Request) error
func handleLogical(core *vault.Core, dataOnly bool, prepareRequestCallback PrepareRequest) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Determine the path...
if !strings.HasPrefix(r.URL.Path, "/v1/") {
@ -53,11 +55,11 @@ func handleLogical(core *vault.Core, dataOnly bool) http.Handler {
}
// Parse the request if we can
var req map[string]interface{}
var data map[string]interface{}
if op == logical.UpdateOperation {
err := parseRequest(r, &req)
err := parseRequest(r, &data)
if err == io.EOF {
req = nil
data = nil
err = nil
}
if err != nil {
@ -66,15 +68,27 @@ func handleLogical(core *vault.Core, dataOnly bool) http.Handler {
}
}
req := requestAuth(r, &logical.Request{
Operation: op,
Path: path,
Data: data,
Connection: getConnection(r),
})
// Certain endpoints may require changes to the request object.
// They will have a callback registered to do the needful.
// Invoking it before proceeding.
if prepareRequestCallback != nil {
if err := prepareRequestCallback(req); err != nil {
respondError(w, http.StatusInternalServerError, 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, ok := request(core, w, r, requestAuth(r, &logical.Request{
Operation: op,
Path: path,
Data: req,
Connection: getConnection(r),
}))
resp, ok := request(core, w, r, req)
if !ok {
return
}