Implemented /sys/capabilities-accessor and a way for setting HTTP error code in all the responses
This commit is contained in:
parent
2737c81b39
commit
8117996378
|
@ -35,6 +35,7 @@ func Handler(core *vault.Core) http.Handler {
|
|||
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))
|
||||
|
||||
|
@ -80,12 +81,7 @@ func request(core *vault.Core, w http.ResponseWriter, rawReq *http.Request, r *l
|
|||
return resp, false
|
||||
}
|
||||
if err != nil {
|
||||
// Keep on adding error types here to set proper HTTP status code
|
||||
if errwrap.ContainsType(err, new(vault.ErrUserInput)) {
|
||||
respondError(w, http.StatusBadRequest, err)
|
||||
} else {
|
||||
respondError(w, http.StatusInternalServerError, err)
|
||||
}
|
||||
respondErrorStatus(w, err)
|
||||
return resp, false
|
||||
}
|
||||
|
||||
|
@ -145,6 +141,18 @@ func requestAuth(r *http.Request, req *logical.Request) *logical.Request {
|
|||
return req
|
||||
}
|
||||
|
||||
// Determines the type of the error being returned and sets the HTTP
|
||||
// status code appropriately
|
||||
func respondErrorStatus(w http.ResponseWriter, err error) {
|
||||
status := http.StatusInternalServerError
|
||||
switch {
|
||||
// Keep adding more error types here to appropriate the status codes
|
||||
case errwrap.ContainsType(err, new(vault.ErrUserInput)):
|
||||
status = http.StatusBadRequest
|
||||
}
|
||||
respondError(w, status, err)
|
||||
}
|
||||
|
||||
func respondError(w http.ResponseWriter, status int, err error) {
|
||||
// Adjust status code when sealed
|
||||
if err == vault.ErrSealed {
|
||||
|
|
|
@ -4,11 +4,40 @@ import (
|
|||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/vault/logical"
|
||||
"github.com/hashicorp/vault/vault"
|
||||
)
|
||||
|
||||
func handleSysCapabilitiesAccessor(core *vault.Core) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case "PUT":
|
||||
case "POST":
|
||||
default:
|
||||
respondError(w, http.StatusMethodNotAllowed, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Parse the request if we can
|
||||
var data capabilitiesAccessorRequest
|
||||
if err := parseRequest(r, &data); err != nil {
|
||||
respondError(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
capabilities, err := core.CapabilitiesAccessor(data.AccessorID, data.Path)
|
||||
if err != nil {
|
||||
respondErrorStatus(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
respondOk(w, &capabilitiesResponse{
|
||||
Capabilities: capabilities,
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func handleSysCapabilities(core *vault.Core) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
|
@ -19,9 +48,6 @@ func handleSysCapabilities(core *vault.Core) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
// Get the auth for the request so we can access the token directly
|
||||
req := requestAuth(r, &logical.Request{})
|
||||
|
||||
// Parse the request if we can
|
||||
var data capabilitiesRequest
|
||||
if err := parseRequest(r, &data); err != nil {
|
||||
|
@ -30,18 +56,15 @@ func handleSysCapabilities(core *vault.Core) http.Handler {
|
|||
}
|
||||
|
||||
if strings.HasPrefix(r.URL.Path, "/v1/sys/capabilities-self") {
|
||||
// Get the auth for the request so we can access the token directly
|
||||
req := requestAuth(r, &logical.Request{})
|
||||
data.Token = req.ClientToken
|
||||
}
|
||||
|
||||
capabilities, err := core.Capabilities(data.Token, data.Path)
|
||||
if err != nil {
|
||||
if errwrap.ContainsType(err, new(vault.ErrUserInput)) {
|
||||
respondError(w, http.StatusBadRequest, err)
|
||||
return
|
||||
} else {
|
||||
respondError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
respondErrorStatus(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
respondOk(w, &capabilitiesResponse{
|
||||
|
@ -59,3 +82,8 @@ type capabilitiesRequest struct {
|
|||
Token string `json:"token"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
type capabilitiesAccessorRequest struct {
|
||||
AccessorID string `json:"accessor_id"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
|
|
@ -12,6 +12,29 @@ func (e *ErrUserInput) Error() string {
|
|||
return e.Message
|
||||
}
|
||||
|
||||
// CapabilitiesAccessor is used to fetch the capabilities of the token associated with
|
||||
// the token accessor an the given path
|
||||
func (c *Core) CapabilitiesAccessor(accessorID, path string) ([]string, error) {
|
||||
if path == "" {
|
||||
return nil, &ErrUserInput{
|
||||
Message: "missing path",
|
||||
}
|
||||
}
|
||||
|
||||
if accessorID == "" {
|
||||
return nil, &ErrUserInput{
|
||||
Message: "missing accessor_id",
|
||||
}
|
||||
}
|
||||
|
||||
token, err := c.tokenStore.lookupByAccessorID(accessorID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c.Capabilities(token, path)
|
||||
}
|
||||
|
||||
// Capabilities is used to fetch the capabilities of the given token on the given path
|
||||
func (c *Core) Capabilities(token, path string) ([]string, error) {
|
||||
if path == "" {
|
||||
|
|
Loading…
Reference in a new issue