Merge pull request #748 from hashicorp/create-orphan-http

Add ability to create orphan tokens from the API
This commit is contained in:
Jeff Mitchell 2015-11-03 15:12:42 -05:00
commit c794c1ea11
3 changed files with 54 additions and 1 deletions

View file

@ -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]

View file

@ -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.`

View file

@ -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)