Merge pull request #748 from hashicorp/create-orphan-http
Add ability to create orphan tokens from the API
This commit is contained in:
commit
c794c1ea11
|
@ -45,6 +45,7 @@ generate them, leading to client errors.
|
||||||
could fail to revert to a clean state [GH-733]
|
could fail to revert to a clean state [GH-733]
|
||||||
* everywhere: Don't use http.DefaultClient, as it shares state implicitly and
|
* everywhere: Don't use http.DefaultClient, as it shares state implicitly and
|
||||||
is a source of hard-to-track-down bugs [GH-700]
|
is a source of hard-to-track-down bugs [GH-700]
|
||||||
|
* credential/token: Allow creating orphan tokens via an API path [GH-748]
|
||||||
* secret/generic: Validate given duration at write time, not just read time;
|
* secret/generic: Validate given duration at write time, not just read time;
|
||||||
if stored durations are not parseable, return a warning and the default
|
if stored durations are not parseable, return a warning and the default
|
||||||
duration rather than an error [GH-718]
|
duration rather than an error [GH-718]
|
||||||
|
|
|
@ -89,6 +89,17 @@ func NewTokenStore(c *Core, config *logical.BackendConfig) (*TokenStore, error)
|
||||||
},
|
},
|
||||||
|
|
||||||
Paths: []*framework.Path{
|
Paths: []*framework.Path{
|
||||||
|
&framework.Path{
|
||||||
|
Pattern: "create-orphan$",
|
||||||
|
|
||||||
|
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||||
|
logical.WriteOperation: t.handleCreateOrphan,
|
||||||
|
},
|
||||||
|
|
||||||
|
HelpSynopsis: strings.TrimSpace(tokenCreateOrphanHelp),
|
||||||
|
HelpDescription: strings.TrimSpace(tokenCreateOrphanHelp),
|
||||||
|
},
|
||||||
|
|
||||||
&framework.Path{
|
&framework.Path{
|
||||||
Pattern: "create$",
|
Pattern: "create$",
|
||||||
|
|
||||||
|
@ -501,9 +512,23 @@ func (ts *TokenStore) revokeTreeSalted(saltedId string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleCreate handles the auth/token/create path for creation of new tokens
|
// handleCreate handles the auth/token/create path for creation of new orphan
|
||||||
|
// tokens
|
||||||
|
func (ts *TokenStore) handleCreateOrphan(
|
||||||
|
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||||
|
return ts.handleCreateCommon(req, d, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleCreate handles the auth/token/create path for creation of new non-orphan
|
||||||
|
// tokens
|
||||||
func (ts *TokenStore) handleCreate(
|
func (ts *TokenStore) handleCreate(
|
||||||
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||||
|
return ts.handleCreateCommon(req, d, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleCreateCommon handles the auth/token/create path for creation of new tokens
|
||||||
|
func (ts *TokenStore) handleCreateCommon(
|
||||||
|
req *logical.Request, d *framework.FieldData, orphan bool) (*logical.Response, error) {
|
||||||
// Read the parent policy
|
// Read the parent policy
|
||||||
parent, err := ts.Lookup(req.ClientToken)
|
parent, err := ts.Lookup(req.ClientToken)
|
||||||
if err != nil || parent == nil {
|
if err != nil || parent == nil {
|
||||||
|
@ -586,6 +611,11 @@ func (ts *TokenStore) handleCreate(
|
||||||
}
|
}
|
||||||
|
|
||||||
te.Parent = ""
|
te.Parent = ""
|
||||||
|
} else {
|
||||||
|
// This comes from create-orphan, which can be properly ACLd
|
||||||
|
if orphan {
|
||||||
|
te.Parent = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the TTL/lease if any
|
// Parse the TTL/lease if any
|
||||||
|
@ -839,6 +869,7 @@ Client tokens are used to identify a client and to allow Vault to associate poli
|
||||||
which are enforced on every request. This backend also allows for generating sub-tokens as well
|
which are enforced on every request. This backend also allows for generating sub-tokens as well
|
||||||
as revocation of tokens. The tokens are renewable if associated with a lease.`
|
as revocation of tokens. The tokens are renewable if associated with a lease.`
|
||||||
tokenCreateHelp = `The token create path is used to create new tokens.`
|
tokenCreateHelp = `The token create path is used to create new tokens.`
|
||||||
|
tokenCreateOrphanHelp = `The token create path is used to create new orphan tokens.`
|
||||||
tokenLookupHelp = `This endpoint will lookup a token and its properties.`
|
tokenLookupHelp = `This endpoint will lookup a token and its properties.`
|
||||||
tokenRevokeHelp = `This endpoint will delete the given token and all of its child tokens.`
|
tokenRevokeHelp = `This endpoint will delete the given token and all of its child tokens.`
|
||||||
tokenRevokeSelfHelp = `This endpoint will delete the token used to call it and all of its child tokens.`
|
tokenRevokeSelfHelp = `This endpoint will delete the token used to call it and all of its child tokens.`
|
||||||
|
|
|
@ -662,6 +662,27 @@ func TestTokenStore_HandleRequest_CreateToken_Root_NoParent(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTokenStore_HandleRequest_CreateToken_PathBased_NoParent(t *testing.T) {
|
||||||
|
_, ts, root := mockTokenStore(t)
|
||||||
|
|
||||||
|
req := logical.TestRequest(t, logical.WriteOperation, "create-orphan")
|
||||||
|
req.ClientToken = root
|
||||||
|
req.Data["policies"] = []string{"foo"}
|
||||||
|
|
||||||
|
resp, err := ts.HandleRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %v %v", err, resp)
|
||||||
|
}
|
||||||
|
if resp.Auth.ClientToken == "" {
|
||||||
|
t.Fatalf("bad: %#v", resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
out, _ := ts.Lookup(resp.Auth.ClientToken)
|
||||||
|
if out.Parent != "" {
|
||||||
|
t.Fatalf("bad: %#v", out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestTokenStore_HandleRequest_CreateToken_Metadata(t *testing.T) {
|
func TestTokenStore_HandleRequest_CreateToken_Metadata(t *testing.T) {
|
||||||
_, ts, root := mockTokenStore(t)
|
_, ts, root := mockTokenStore(t)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue