Handled root token use case
This commit is contained in:
parent
93a1ebe743
commit
f00261785a
@ -1,6 +1,6 @@
|
||||
package api
|
||||
|
||||
func (c *Sys) CapabilitiesSelf(path string) ([]string, error) {
|
||||
func (c *Sys) CapabilitiesSelf(path string) (*CapabilitiesResponse, error) {
|
||||
body := map[string]string{
|
||||
"path": path,
|
||||
}
|
||||
@ -16,12 +16,12 @@ func (c *Sys) CapabilitiesSelf(path string) ([]string, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result capabilitiesResp
|
||||
var result CapabilitiesResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
return result.Capabilities, err
|
||||
return &result, err
|
||||
}
|
||||
|
||||
func (c *Sys) Capabilities(token, path string) ([]string, error) {
|
||||
func (c *Sys) Capabilities(token, path string) (*CapabilitiesResponse, error) {
|
||||
body := map[string]string{
|
||||
"token": token,
|
||||
"path": path,
|
||||
@ -38,11 +38,12 @@ func (c *Sys) Capabilities(token, path string) ([]string, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result capabilitiesResp
|
||||
var result CapabilitiesResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
return result.Capabilities, err
|
||||
return &result, err
|
||||
}
|
||||
|
||||
type capabilitiesResp struct {
|
||||
type CapabilitiesResponse struct {
|
||||
Message string `json:"message"`
|
||||
Capabilities []string `json:"capabilities"`
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package command
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/vault/api"
|
||||
)
|
||||
|
||||
// CapabilitiesCommand is a Command that enables a new endpoint.
|
||||
@ -45,7 +47,7 @@ func (c *CapabilitiesCommand) Run(args []string) int {
|
||||
return 2
|
||||
}
|
||||
|
||||
var capabilities []string
|
||||
var capabilities *api.CapabilitiesResponse
|
||||
if token == "" {
|
||||
capabilities, err = client.Sys().CapabilitiesSelf(path)
|
||||
} else {
|
||||
@ -57,7 +59,7 @@ func (c *CapabilitiesCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
c.Ui.Output(fmt.Sprintf("Capabilities: %s", capabilities))
|
||||
c.Ui.Output(fmt.Sprintf("Capabilities:%s\nMessage:%s\n", capabilities.Capabilities, capabilities.Message))
|
||||
return 0
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/vault/logical"
|
||||
"github.com/hashicorp/vault/vault"
|
||||
@ -18,10 +18,8 @@ func handleSysCapabilities(core *vault.Core) http.Handler {
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("r.URL.Path: %s\n", r.URL.Path)
|
||||
// Get the auth for the request so we can access the token directly
|
||||
req := requestAuth(r, &logical.Request{})
|
||||
log.Printf("handleSysCapabilities req:%#v\n", req)
|
||||
|
||||
// Parse the request if we can
|
||||
var data capabilitiesRequest
|
||||
@ -29,7 +27,8 @@ func handleSysCapabilities(core *vault.Core) http.Handler {
|
||||
respondError(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
if data.Token == "" {
|
||||
|
||||
if strings.HasPrefix(r.URL.Path, "/v1/sys/capabilities-self") {
|
||||
data.Token = req.ClientToken
|
||||
}
|
||||
|
||||
@ -39,18 +38,28 @@ func handleSysCapabilities(core *vault.Core) http.Handler {
|
||||
return
|
||||
}
|
||||
if capabilities == nil {
|
||||
respondOk(w, &capabilitiesResponse{Capabilities: nil})
|
||||
respondOk(w, &capabilitiesResponse{Message: "Token has no capabilities on the given path"})
|
||||
return
|
||||
}
|
||||
|
||||
respondOk(w, &capabilitiesResponse{
|
||||
Capabilities: capabilities.Capabilities,
|
||||
})
|
||||
var response capabilitiesResponse
|
||||
switch capabilities.Root {
|
||||
case true:
|
||||
response.Message = `Thij is a 'root' token. It has all the capabilities on all the paths.
|
||||
This token can be used on any valid path.`
|
||||
response.Capabilities = nil
|
||||
case false:
|
||||
response.Message = ""
|
||||
response.Capabilities = capabilities.Capabilities
|
||||
}
|
||||
|
||||
respondOk(w, response)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
type capabilitiesResponse struct {
|
||||
Message string `json:"message"`
|
||||
Capabilities []string `json:"capabilities"`
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
|
||||
// CapabilitiesResult holds the result of fetching the capabilities of token on a path
|
||||
type CapabilitiesResult struct {
|
||||
Root bool
|
||||
Capabilities []string
|
||||
}
|
||||
|
||||
@ -33,46 +34,32 @@ func (c *Core) Capabilities(token, path string) (*CapabilitiesResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
maps := make(map[string]bool)
|
||||
var result CapabilitiesResult
|
||||
capabilities := make(map[string]bool)
|
||||
for _, tePolicy := range te.Policies {
|
||||
if tePolicy == "root" {
|
||||
//TODO: check if the path is actually a valid path. Otherwise, there is no
|
||||
// meaning in returning the capabilities
|
||||
// Add all the capabilities
|
||||
maps["create"] = true
|
||||
maps["read"] = true
|
||||
maps["update"] = true
|
||||
maps["delete"] = true
|
||||
maps["list"] = true
|
||||
maps["sudo"] = true
|
||||
result.Root = true
|
||||
break
|
||||
}
|
||||
policy, err := c.policyStore.GetPolicy(tePolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if policy == nil {
|
||||
return nil, fmt.Errorf("policy '%s' not found", tePolicy)
|
||||
}
|
||||
|
||||
if policy.Paths == nil {
|
||||
return nil, fmt.Errorf("policy '%s' does not contain any paths", tePolicy)
|
||||
}
|
||||
for _, pathCapability := range policy.Paths {
|
||||
switch pathCapability.Glob {
|
||||
case true:
|
||||
if strings.HasPrefix(path, pathCapability.Prefix) {
|
||||
for _, capability := range pathCapability.Capabilities {
|
||||
if _, ok := maps[capability]; !ok {
|
||||
maps[capability] = true
|
||||
if _, ok := capabilities[capability]; !ok {
|
||||
capabilities[capability] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
case false:
|
||||
if path == pathCapability.Prefix {
|
||||
for _, capability := range pathCapability.Capabilities {
|
||||
if _, ok := maps[capability]; !ok {
|
||||
maps[capability] = true
|
||||
if _, ok := capabilities[capability]; !ok {
|
||||
capabilities[capability] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -80,12 +67,9 @@ func (c *Core) Capabilities(token, path string) (*CapabilitiesResult, error) {
|
||||
}
|
||||
}
|
||||
|
||||
var capabilities []string
|
||||
for capability, _ := range maps {
|
||||
capabilities = append(capabilities, capability)
|
||||
for capability, _ := range capabilities {
|
||||
result.Capabilities = append(result.Capabilities, capability)
|
||||
}
|
||||
sort.Strings(capabilities)
|
||||
return &CapabilitiesResult{
|
||||
Capabilities: capabilities,
|
||||
}, nil
|
||||
sort.Strings(result.Capabilities)
|
||||
return &result, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user