Remove injection into top routes (#5101)
This commit is contained in:
parent
e6a6b65ba9
commit
9cf497f688
@ -5,6 +5,12 @@ DEPRECATIONS/CHANGES:
|
||||
* Request Timeouts: A default request timeout of 90s is now enforced. This
|
||||
setting can be overwritten in the config file. If you anticipate requests
|
||||
taking longer than 90s this setting should be updated before upgrading.
|
||||
* `sys/` Top Level Injection: For the last two years for backwards
|
||||
compatibility data for various `sys/` routes has been injected into both the
|
||||
Secret's Data map and into the top level of the JSON response object.
|
||||
However, this has some subtle issues that pop up from time to time and is
|
||||
becoming increasingly complicated to maintain, so it's finally being
|
||||
removed.
|
||||
|
||||
FEATURES:
|
||||
|
||||
|
@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
@ -25,17 +26,24 @@ func (c *Sys) AuditHash(path string, input string) (string, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
type d struct {
|
||||
Hash string `json:"hash"`
|
||||
}
|
||||
|
||||
var result d
|
||||
err = resp.DecodeJSON(&result)
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if secret == nil || secret.Data == nil {
|
||||
return "", errors.New("data from server response is empty")
|
||||
}
|
||||
|
||||
return result.Hash, err
|
||||
hash, ok := secret.Data["hash"]
|
||||
if !ok {
|
||||
return "", errors.New("hash not found in response data")
|
||||
}
|
||||
hashStr, ok := hash.(string)
|
||||
if !ok {
|
||||
return "", errors.New("could not parse hash in response data")
|
||||
}
|
||||
|
||||
return hashStr, nil
|
||||
}
|
||||
|
||||
func (c *Sys) ListAudit() (map[string]*Audit, error) {
|
||||
@ -50,29 +58,18 @@ func (c *Sys) ListAudit() (map[string]*Audit, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result map[string]interface{}
|
||||
err = resp.DecodeJSON(&result)
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil || secret.Data == nil {
|
||||
return nil, errors.New("data from server response is empty")
|
||||
}
|
||||
|
||||
mounts := map[string]*Audit{}
|
||||
for k, v := range result {
|
||||
switch v.(type) {
|
||||
case map[string]interface{}:
|
||||
default:
|
||||
continue
|
||||
}
|
||||
var res Audit
|
||||
err = mapstructure.Decode(v, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Not a mount, some other api.Secret data
|
||||
if res.Type == "" {
|
||||
continue
|
||||
}
|
||||
mounts[k] = &res
|
||||
err = mapstructure.Decode(secret.Data, &mounts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mounts, nil
|
||||
@ -124,16 +121,16 @@ func (c *Sys) DisableAudit(path string) error {
|
||||
// documentation. Please refer to that documentation for more details.
|
||||
|
||||
type EnableAuditOptions struct {
|
||||
Type string `json:"type"`
|
||||
Description string `json:"description"`
|
||||
Options map[string]string `json:"options"`
|
||||
Local bool `json:"local"`
|
||||
Type string `json:"type" mapstructure:"type"`
|
||||
Description string `json:"description" mapstructure:"description"`
|
||||
Options map[string]string `json:"options" mapstructure:"options"`
|
||||
Local bool `json:"local" mapstructure:"local"`
|
||||
}
|
||||
|
||||
type Audit struct {
|
||||
Path string
|
||||
Type string
|
||||
Description string
|
||||
Options map[string]string
|
||||
Local bool
|
||||
Type string `json:"type" mapstructure:"type"`
|
||||
Description string `json:"description" mapstructure:"description"`
|
||||
Options map[string]string `json:"options" mapstructure:"options"`
|
||||
Local bool `json:"local" mapstructure:"local"`
|
||||
Path string `json:"path" mapstructure:"path"`
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
@ -18,29 +19,18 @@ func (c *Sys) ListAuth() (map[string]*AuthMount, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result map[string]interface{}
|
||||
err = resp.DecodeJSON(&result)
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil || secret.Data == nil {
|
||||
return nil, errors.New("data from server response is empty")
|
||||
}
|
||||
|
||||
mounts := map[string]*AuthMount{}
|
||||
for k, v := range result {
|
||||
switch v.(type) {
|
||||
case map[string]interface{}:
|
||||
default:
|
||||
continue
|
||||
}
|
||||
var res AuthMount
|
||||
err = mapstructure.Decode(v, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Not a mount, some other api.Secret data
|
||||
if res.Type == "" {
|
||||
continue
|
||||
}
|
||||
mounts[k] = &res
|
||||
err = mapstructure.Decode(secret.Data, &mounts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mounts, nil
|
||||
|
@ -2,7 +2,10 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
func (c *Sys) CapabilitiesSelf(path string) ([]string, error) {
|
||||
@ -33,22 +36,19 @@ func (c *Sys) Capabilities(token, path string) ([]string, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result map[string]interface{}
|
||||
err = resp.DecodeJSON(&result)
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil || secret.Data == nil {
|
||||
return nil, errors.New("data from server response is empty")
|
||||
}
|
||||
|
||||
var res []string
|
||||
err = mapstructure.Decode(secret.Data[path], &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if result["capabilities"] == nil {
|
||||
return nil, nil
|
||||
}
|
||||
var capabilities []string
|
||||
capabilitiesRaw, ok := result["capabilities"].([]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("error interpreting returned capabilities")
|
||||
}
|
||||
for _, capability := range capabilitiesRaw {
|
||||
capabilities = append(capabilities, capability.(string))
|
||||
}
|
||||
return capabilities, nil
|
||||
return res, nil
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
package api
|
||||
|
||||
import "context"
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
func (c *Sys) CORSStatus() (*CORSResponse, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/sys/config/cors")
|
||||
@ -13,8 +18,20 @@ func (c *Sys) CORSStatus() (*CORSResponse, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil || secret.Data == nil {
|
||||
return nil, errors.New("data from server response is empty")
|
||||
}
|
||||
|
||||
var result CORSResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
err = mapstructure.Decode(secret.Data, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &result, err
|
||||
}
|
||||
|
||||
@ -32,8 +49,20 @@ func (c *Sys) ConfigureCORS(req *CORSRequest) (*CORSResponse, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil || secret.Data == nil {
|
||||
return nil, errors.New("data from server response is empty")
|
||||
}
|
||||
|
||||
var result CORSResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
err = mapstructure.Decode(secret.Data, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &result, err
|
||||
}
|
||||
|
||||
@ -48,18 +77,29 @@ func (c *Sys) DisableCORS() (*CORSResponse, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result CORSResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
return &result, err
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil || secret.Data == nil {
|
||||
return nil, errors.New("data from server response is empty")
|
||||
}
|
||||
|
||||
var result CORSResponse
|
||||
err = mapstructure.Decode(secret.Data, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &result, err
|
||||
}
|
||||
|
||||
type CORSRequest struct {
|
||||
AllowedOrigins string `json:"allowed_origins"`
|
||||
Enabled bool `json:"enabled"`
|
||||
AllowedOrigins string `json:"allowed_origins" mapstructure:"allowed_origins"`
|
||||
Enabled bool `json:"enabled" mapstructure:"enabled"`
|
||||
}
|
||||
|
||||
type CORSResponse struct {
|
||||
AllowedOrigins string `json:"allowed_origins"`
|
||||
Enabled bool `json:"enabled"`
|
||||
AllowedOrigins string `json:"allowed_origins" mapstructure:"allowed_origins"`
|
||||
Enabled bool `json:"enabled" mapstructure:"enabled"`
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
@ -18,29 +19,18 @@ func (c *Sys) ListMounts() (map[string]*MountOutput, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result map[string]interface{}
|
||||
err = resp.DecodeJSON(&result)
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil || secret.Data == nil {
|
||||
return nil, errors.New("data from server response is empty")
|
||||
}
|
||||
|
||||
mounts := map[string]*MountOutput{}
|
||||
for k, v := range result {
|
||||
switch v.(type) {
|
||||
case map[string]interface{}:
|
||||
default:
|
||||
continue
|
||||
}
|
||||
var res MountOutput
|
||||
err = mapstructure.Decode(v, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Not a mount, some other api.Secret data
|
||||
if res.Type == "" {
|
||||
continue
|
||||
}
|
||||
mounts[k] = &res
|
||||
err = mapstructure.Decode(secret.Data, &mounts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mounts, nil
|
||||
@ -121,8 +111,16 @@ func (c *Sys) MountConfig(path string) (*MountConfigOutput, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil || secret.Data == nil {
|
||||
return nil, errors.New("data from server response is empty")
|
||||
}
|
||||
|
||||
var result MountConfigOutput
|
||||
err = resp.DecodeJSON(&result)
|
||||
err = mapstructure.Decode(secret.Data, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -2,7 +2,10 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
func (c *Sys) ListPolicies() ([]string, error) {
|
||||
@ -16,29 +19,25 @@ func (c *Sys) ListPolicies() ([]string, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result map[string]interface{}
|
||||
err = resp.DecodeJSON(&result)
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil || secret.Data == nil {
|
||||
return nil, errors.New("data from server response is empty")
|
||||
}
|
||||
|
||||
var result []string
|
||||
err = mapstructure.Decode(secret.Data["policies"], &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var ok bool
|
||||
if _, ok = result["policies"]; !ok {
|
||||
return nil, fmt.Errorf("policies not found in response")
|
||||
}
|
||||
|
||||
listRaw := result["policies"].([]interface{})
|
||||
var policies []string
|
||||
|
||||
for _, val := range listRaw {
|
||||
policies = append(policies, val.(string))
|
||||
}
|
||||
|
||||
return policies, err
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (c *Sys) GetPolicy(name string) (string, error) {
|
||||
r := c.c.NewRequest("GET", fmt.Sprintf("/v1/sys/policy/%s", name))
|
||||
r := c.c.NewRequest("GET", fmt.Sprintf("/v1/sys/policies/acl/%s", name))
|
||||
|
||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||
defer cancelFunc()
|
||||
@ -53,16 +52,15 @@ func (c *Sys) GetPolicy(name string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var result map[string]interface{}
|
||||
err = resp.DecodeJSON(&result)
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if rulesRaw, ok := result["rules"]; ok {
|
||||
return rulesRaw.(string), nil
|
||||
if secret == nil || secret.Data == nil {
|
||||
return "", errors.New("data from server response is empty")
|
||||
}
|
||||
if policyRaw, ok := result["policy"]; ok {
|
||||
|
||||
if policyRaw, ok := secret.Data["policy"]; ok {
|
||||
return policyRaw.(string), nil
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,11 @@
|
||||
package api
|
||||
|
||||
import "context"
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
func (c *Sys) RekeyStatus() (*RekeyStatusResponse, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/sys/rekey/init")
|
||||
@ -211,8 +216,20 @@ func (c *Sys) RekeyRetrieveBackup() (*RekeyRetrieveResponse, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil || secret.Data == nil {
|
||||
return nil, errors.New("data from server response is empty")
|
||||
}
|
||||
|
||||
var result RekeyRetrieveResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
err = mapstructure.Decode(secret.Data, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &result, err
|
||||
}
|
||||
|
||||
@ -227,8 +244,20 @@ func (c *Sys) RekeyRetrieveRecoveryBackup() (*RekeyRetrieveResponse, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil || secret.Data == nil {
|
||||
return nil, errors.New("data from server response is empty")
|
||||
}
|
||||
|
||||
var result RekeyRetrieveResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
err = mapstructure.Decode(secret.Data, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &result, err
|
||||
}
|
||||
|
||||
@ -340,9 +369,9 @@ type RekeyUpdateResponse struct {
|
||||
}
|
||||
|
||||
type RekeyRetrieveResponse struct {
|
||||
Nonce string `json:"nonce"`
|
||||
Keys map[string][]string `json:"keys"`
|
||||
KeysB64 map[string][]string `json:"keys_base64"`
|
||||
Nonce string `json:"nonce" mapstructure:"nonce"`
|
||||
Keys map[string][]string `json:"keys" mapstructure:"keys"`
|
||||
KeysB64 map[string][]string `json:"keys_base64" mapstructure:"keys_base64"`
|
||||
}
|
||||
|
||||
type RekeyVerificationStatusResponse struct {
|
||||
|
@ -2,6 +2,8 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -28,9 +30,45 @@ func (c *Sys) KeyStatus() (*KeyStatus, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
result := new(KeyStatus)
|
||||
err = resp.DecodeJSON(result)
|
||||
return result, err
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil || secret.Data == nil {
|
||||
return nil, errors.New("data from server response is empty")
|
||||
}
|
||||
|
||||
var result KeyStatus
|
||||
|
||||
termRaw, ok := secret.Data["term"]
|
||||
if !ok {
|
||||
return nil, errors.New("term not found in response")
|
||||
}
|
||||
term, ok := termRaw.(json.Number)
|
||||
if !ok {
|
||||
return nil, errors.New("could not convert term to a number")
|
||||
}
|
||||
term64, err := term.Int64()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.Term = int(term64)
|
||||
|
||||
installTimeRaw, ok := secret.Data["install_time"]
|
||||
if !ok {
|
||||
return nil, errors.New("install_time not found in response")
|
||||
}
|
||||
installTimeStr, ok := installTimeRaw.(string)
|
||||
if !ok {
|
||||
return nil, errors.New("could not convert install_time to a string")
|
||||
}
|
||||
installTime, err := time.Parse(time.RFC3339Nano, installTimeStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.InstallTime = installTime
|
||||
|
||||
return &result, err
|
||||
}
|
||||
|
||||
type KeyStatus struct {
|
||||
|
@ -154,7 +154,7 @@ func (c *AuditListCommand) detailedAudits(audits map[string]*api.Audit) []string
|
||||
}
|
||||
|
||||
columns = append(columns, fmt.Sprintf("%s | %s | %s | %s | %s",
|
||||
audit.Path,
|
||||
path,
|
||||
audit.Type,
|
||||
audit.Description,
|
||||
replication,
|
||||
|
@ -90,14 +90,11 @@ func Handler(props *vault.HandlerProperties) http.Handler {
|
||||
mux.Handle("/v1/sys/rekey-recovery-key/init", handleRequestForwarding(core, handleSysRekeyInit(core, true)))
|
||||
mux.Handle("/v1/sys/rekey-recovery-key/update", handleRequestForwarding(core, handleSysRekeyUpdate(core, true)))
|
||||
mux.Handle("/v1/sys/rekey-recovery-key/verify", handleRequestForwarding(core, handleSysRekeyVerify(core, true)))
|
||||
mux.Handle("/v1/sys/wrapping/lookup", handleRequestForwarding(core, handleLogical(core, false, wrappingVerificationFunc)))
|
||||
mux.Handle("/v1/sys/wrapping/rewrap", handleRequestForwarding(core, handleLogical(core, false, wrappingVerificationFunc)))
|
||||
mux.Handle("/v1/sys/wrapping/unwrap", handleRequestForwarding(core, handleLogical(core, false, wrappingVerificationFunc)))
|
||||
for _, path := range injectDataIntoTopRoutes {
|
||||
mux.Handle(path, handleRequestForwarding(core, handleLogical(core, true, nil)))
|
||||
}
|
||||
mux.Handle("/v1/sys/", handleRequestForwarding(core, handleLogical(core, false, nil)))
|
||||
mux.Handle("/v1/", handleRequestForwarding(core, handleLogical(core, false, nil)))
|
||||
mux.Handle("/v1/sys/wrapping/lookup", handleRequestForwarding(core, handleLogical(core, wrappingVerificationFunc)))
|
||||
mux.Handle("/v1/sys/wrapping/rewrap", handleRequestForwarding(core, handleLogical(core, wrappingVerificationFunc)))
|
||||
mux.Handle("/v1/sys/wrapping/unwrap", handleRequestForwarding(core, handleLogical(core, wrappingVerificationFunc)))
|
||||
mux.Handle("/v1/sys/", handleRequestForwarding(core, handleLogical(core, nil)))
|
||||
mux.Handle("/v1/", handleRequestForwarding(core, handleLogical(core, nil)))
|
||||
if core.UIEnabled() == true {
|
||||
if uiBuiltIn {
|
||||
mux.Handle("/ui/", http.StripPrefix("/ui/", gziphandler.GzipHandler(handleUIHeaders(core, handleUI(http.FileServer(&UIAssetWrapper{FileSystem: assetFS()}))))))
|
||||
@ -592,27 +589,3 @@ func respondOk(w http.ResponseWriter, body interface{}) {
|
||||
type ErrorResponse struct {
|
||||
Errors []string `json:"errors"`
|
||||
}
|
||||
|
||||
var injectDataIntoTopRoutes = []string{
|
||||
"/v1/sys/audit",
|
||||
"/v1/sys/audit/",
|
||||
"/v1/sys/audit-hash/",
|
||||
"/v1/sys/auth",
|
||||
"/v1/sys/auth/",
|
||||
"/v1/sys/config/cors",
|
||||
"/v1/sys/config/auditing/request-headers/",
|
||||
"/v1/sys/config/auditing/request-headers",
|
||||
"/v1/sys/capabilities",
|
||||
"/v1/sys/capabilities-accessor",
|
||||
"/v1/sys/capabilities-self",
|
||||
"/v1/sys/key-status",
|
||||
"/v1/sys/mounts",
|
||||
"/v1/sys/mounts/",
|
||||
"/v1/sys/policy",
|
||||
"/v1/sys/policy/",
|
||||
"/v1/sys/rekey/backup",
|
||||
"/v1/sys/rekey/recovery-key-backup",
|
||||
"/v1/sys/remount",
|
||||
"/v1/sys/rotate",
|
||||
"/v1/sys/wrapping/wrap",
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ func buildLogicalRequest(core *vault.Core, w http.ResponseWriter, r *http.Reques
|
||||
return req, 0, nil
|
||||
}
|
||||
|
||||
func handleLogical(core *vault.Core, injectDataIntoTopLevel bool, prepareRequestCallback PrepareRequestFunc) http.Handler {
|
||||
func handleLogical(core *vault.Core, prepareRequestCallback PrepareRequestFunc) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
req, statusCode, err := buildLogicalRequest(core, w, r)
|
||||
if err != nil || statusCode != 0 {
|
||||
@ -155,11 +155,11 @@ func handleLogical(core *vault.Core, injectDataIntoTopLevel bool, prepareRequest
|
||||
}
|
||||
|
||||
// Build the proper response
|
||||
respondLogical(w, r, req, injectDataIntoTopLevel, resp)
|
||||
respondLogical(w, r, req, resp)
|
||||
})
|
||||
}
|
||||
|
||||
func respondLogical(w http.ResponseWriter, r *http.Request, req *logical.Request, injectDataIntoTopLevel bool, resp *logical.Response) {
|
||||
func respondLogical(w http.ResponseWriter, r *http.Request, req *logical.Request, resp *logical.Response) {
|
||||
var httpResp *logical.HTTPResponse
|
||||
var ret interface{}
|
||||
|
||||
@ -194,13 +194,6 @@ func respondLogical(w http.ResponseWriter, r *http.Request, req *logical.Request
|
||||
}
|
||||
|
||||
ret = httpResp
|
||||
|
||||
if injectDataIntoTopLevel {
|
||||
injector := logical.HTTPSysInjector{
|
||||
Response: httpResp,
|
||||
}
|
||||
ret = injector
|
||||
}
|
||||
}
|
||||
|
||||
// Respond
|
||||
|
@ -318,7 +318,7 @@ func TestLogical_RespondWithStatusCode(t *testing.T) {
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
respondLogical(w, nil, nil, false, resp404)
|
||||
respondLogical(w, nil, nil, resp404)
|
||||
|
||||
if w.Code != 404 {
|
||||
t.Fatalf("Bad Status code: %d", w.Code)
|
||||
|
@ -1,9 +1,6 @@
|
||||
package logical
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -104,46 +101,3 @@ type HTTPWrapInfo struct {
|
||||
CreationPath string `json:"creation_path"`
|
||||
WrappedAccessor string `json:"wrapped_accessor,omitempty"`
|
||||
}
|
||||
|
||||
type HTTPSysInjector struct {
|
||||
Response *HTTPResponse
|
||||
}
|
||||
|
||||
func (h HTTPSysInjector) MarshalJSON() ([]byte, error) {
|
||||
j, err := json.Marshal(h.Response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Fast path no data or empty data
|
||||
if h.Response.Data == nil || len(h.Response.Data) == 0 {
|
||||
return j, nil
|
||||
}
|
||||
|
||||
// Marshaling a response will always be a JSON object, meaning it will
|
||||
// always start with '{', so we hijack this to prepend necessary values
|
||||
|
||||
// Make a guess at the capacity, and write the object opener
|
||||
buf := bytes.NewBuffer(make([]byte, 0, len(j)*2))
|
||||
buf.WriteRune('{')
|
||||
|
||||
for k, v := range h.Response.Data {
|
||||
// Marshal each key/value individually
|
||||
mk, err := json.Marshal(k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mv, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Write into the final buffer. We'll never have a valid response
|
||||
// without any fields so we can unconditionally add a comma after each.
|
||||
buf.WriteString(fmt.Sprintf("%s: %s, ", mk, mv))
|
||||
}
|
||||
|
||||
// Add the rest, without the first '{'
|
||||
buf.Write(j[1:])
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user