Move TokenEntry into logical. (#4729)
This allows the HTTP logicalAuth handler to cache the value in the logical.Request, avoiding a lookup later when performing acl checks/counting a use.
This commit is contained in:
parent
ab6547383c
commit
575a606db7
|
@ -474,6 +474,7 @@ func requestAuth(core *vault.Core, r *http.Request, req *logical.Request) *logic
|
|||
if err == nil && te != nil {
|
||||
req.ClientTokenAccessor = te.Accessor
|
||||
req.ClientTokenRemainingUses = te.NumUses
|
||||
req.SetTokenEntry(te)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -141,6 +141,14 @@ type Request struct {
|
|||
// accessible.
|
||||
Unauthenticated bool `json:"unauthenticated" structs:"unauthenticated" mapstructure:"unauthenticated"`
|
||||
|
||||
// Cached token entry. This avoids another lookup in request handling when
|
||||
// we've already looked it up at http handling time. Note that this token
|
||||
// has not been "used", as in it will not properly take into account use
|
||||
// count limitations. As a result this field should only ever be used for
|
||||
// transport to a function that would otherwise do a lookup and then
|
||||
// properly use the token.
|
||||
tokenEntry *TokenEntry
|
||||
|
||||
// For replication, contains the last WAL on the remote side after handling
|
||||
// the request, used for best-effort avoidance of stale read-after-write
|
||||
lastRemoteWAL uint64
|
||||
|
@ -199,6 +207,14 @@ func (r *Request) SetLastRemoteWAL(last uint64) {
|
|||
r.lastRemoteWAL = last
|
||||
}
|
||||
|
||||
func (r *Request) TokenEntry() *TokenEntry {
|
||||
return r.tokenEntry
|
||||
}
|
||||
|
||||
func (r *Request) SetTokenEntry(te *TokenEntry) {
|
||||
r.tokenEntry = te
|
||||
}
|
||||
|
||||
// RenewRequest creates the structure of the renew request.
|
||||
func RenewRequest(path string, secret *Secret, data map[string]interface{}) *Request {
|
||||
return &Request{
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
package logical
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
sockaddr "github.com/hashicorp/go-sockaddr"
|
||||
)
|
||||
|
||||
// TokenEntry is used to represent a given token
|
||||
type TokenEntry struct {
|
||||
// ID of this entry, generally a random UUID
|
||||
ID string `json:"id" mapstructure:"id" structs:"id" sentinel:""`
|
||||
|
||||
// Accessor for this token, a random UUID
|
||||
Accessor string `json:"accessor" mapstructure:"accessor" structs:"accessor" sentinel:""`
|
||||
|
||||
// Parent token, used for revocation trees
|
||||
Parent string `json:"parent" mapstructure:"parent" structs:"parent" sentinel:""`
|
||||
|
||||
// Which named policies should be used
|
||||
Policies []string `json:"policies" mapstructure:"policies" structs:"policies"`
|
||||
|
||||
// Used for audit trails, this is something like "auth/user/login"
|
||||
Path string `json:"path" mapstructure:"path" structs:"path"`
|
||||
|
||||
// Used for auditing. This could include things like "source", "user", "ip"
|
||||
Meta map[string]string `json:"meta" mapstructure:"meta" structs:"meta" sentinel:"meta"`
|
||||
|
||||
// Used for operators to be able to associate with the source
|
||||
DisplayName string `json:"display_name" mapstructure:"display_name" structs:"display_name"`
|
||||
|
||||
// Used to restrict the number of uses (zero is unlimited). This is to
|
||||
// support one-time-tokens (generalized). There are a few special values:
|
||||
// if it's -1 it has run through its use counts and is executing its final
|
||||
// use; if it's -2 it is tainted, which means revocation is currently
|
||||
// running on it; and if it's -3 it's also tainted but revocation
|
||||
// previously ran and failed, so this hints the tidy function to try it
|
||||
// again.
|
||||
NumUses int `json:"num_uses" mapstructure:"num_uses" structs:"num_uses"`
|
||||
|
||||
// Time of token creation
|
||||
CreationTime int64 `json:"creation_time" mapstructure:"creation_time" structs:"creation_time" sentinel:""`
|
||||
|
||||
// Duration set when token was created
|
||||
TTL time.Duration `json:"ttl" mapstructure:"ttl" structs:"ttl" sentinel:""`
|
||||
|
||||
// Explicit maximum TTL on the token
|
||||
ExplicitMaxTTL time.Duration `json:"explicit_max_ttl" mapstructure:"explicit_max_ttl" structs:"explicit_max_ttl" sentinel:""`
|
||||
|
||||
// If set, the role that was used for parameters at creation time
|
||||
Role string `json:"role" mapstructure:"role" structs:"role"`
|
||||
|
||||
// If set, the period of the token. This is only used when created directly
|
||||
// through the create endpoint; periods managed by roles or other auth
|
||||
// backends are subject to those renewal rules.
|
||||
Period time.Duration `json:"period" mapstructure:"period" structs:"period" sentinel:""`
|
||||
|
||||
// These are the deprecated fields
|
||||
DisplayNameDeprecated string `json:"DisplayName" mapstructure:"DisplayName" structs:"DisplayName" sentinel:""`
|
||||
NumUsesDeprecated int `json:"NumUses" mapstructure:"NumUses" structs:"NumUses" sentinel:""`
|
||||
CreationTimeDeprecated int64 `json:"CreationTime" mapstructure:"CreationTime" structs:"CreationTime" sentinel:""`
|
||||
ExplicitMaxTTLDeprecated time.Duration `json:"ExplicitMaxTTL" mapstructure:"ExplicitMaxTTL" structs:"ExplicitMaxTTL" sentinel:""`
|
||||
|
||||
EntityID string `json:"entity_id" mapstructure:"entity_id" structs:"entity_id"`
|
||||
|
||||
// The set of CIDRs that this token can be used with
|
||||
BoundCIDRs []*sockaddr.SockAddrMarshaler `json:"bound_cidrs"`
|
||||
}
|
||||
|
||||
func (te *TokenEntry) SentinelGet(key string) (interface{}, error) {
|
||||
if te == nil {
|
||||
return nil, nil
|
||||
}
|
||||
switch key {
|
||||
case "period":
|
||||
return te.Period, nil
|
||||
|
||||
case "period_seconds":
|
||||
return int64(te.Period.Seconds()), nil
|
||||
|
||||
case "explicit_max_ttl":
|
||||
return te.ExplicitMaxTTL, nil
|
||||
|
||||
case "explicit_max_ttl_seconds":
|
||||
return int64(te.ExplicitMaxTTL.Seconds()), nil
|
||||
|
||||
case "creation_ttl":
|
||||
return te.TTL, nil
|
||||
|
||||
case "creation_ttl_seconds":
|
||||
return int64(te.TTL.Seconds()), nil
|
||||
|
||||
case "creation_time":
|
||||
return time.Unix(te.CreationTime, 0).Format(time.RFC3339Nano), nil
|
||||
|
||||
case "creation_time_unix":
|
||||
return time.Unix(te.CreationTime, 0), nil
|
||||
|
||||
case "meta", "metadata":
|
||||
return te.Meta, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (te *TokenEntry) SentinelKeys() []string {
|
||||
return []string{
|
||||
"period",
|
||||
"period_seconds",
|
||||
"explicit_max_ttl",
|
||||
"explicit_max_ttl_seconds",
|
||||
"creation_ttl",
|
||||
"creation_ttl_seconds",
|
||||
"creation_time",
|
||||
"creation_time_unix",
|
||||
"meta",
|
||||
"metadata",
|
||||
}
|
||||
}
|
|
@ -406,7 +406,7 @@ CHECK:
|
|||
ret.Allowed = true
|
||||
return
|
||||
}
|
||||
func (c *Core) performPolicyChecks(ctx context.Context, acl *ACL, te *TokenEntry, req *logical.Request, inEntity *identity.Entity, opts *PolicyCheckOpts) (ret *AuthResults) {
|
||||
func (c *Core) performPolicyChecks(ctx context.Context, acl *ACL, te *logical.TokenEntry, req *logical.Request, inEntity *identity.Entity, opts *PolicyCheckOpts) (ret *AuthResults) {
|
||||
ret = new(AuthResults)
|
||||
|
||||
// First, perform normal ACL checks if requested. The only time no ACL
|
||||
|
|
|
@ -69,7 +69,7 @@ path "secret/sample" {
|
|||
entityID := resp.Data["id"].(string)
|
||||
|
||||
// Create a token for the entity and assign policy2 on the token
|
||||
ent := &TokenEntry{
|
||||
ent := &logical.TokenEntry{
|
||||
ID: "capabilitiestoken",
|
||||
Path: "secret/sample",
|
||||
Policies: []string{"policy2"},
|
||||
|
@ -135,7 +135,7 @@ func TestCapabilities(t *testing.T) {
|
|||
}
|
||||
|
||||
// Create a token for the policy
|
||||
ent := &TokenEntry{
|
||||
ent := &logical.TokenEntry{
|
||||
ID: "capabilitiestoken",
|
||||
Path: "testpath",
|
||||
Policies: []string{"dev"},
|
||||
|
|
|
@ -276,7 +276,7 @@ func TestCore_Seal_BadToken(t *testing.T) {
|
|||
// GH-3497
|
||||
func TestCore_Seal_SingleUse(t *testing.T) {
|
||||
c, keys, _ := TestCoreUnsealed(t)
|
||||
c.tokenStore.create(context.Background(), &TokenEntry{
|
||||
c.tokenStore.create(context.Background(), &logical.TokenEntry{
|
||||
ID: "foo",
|
||||
NumUses: 1,
|
||||
Policies: []string{"root"},
|
||||
|
@ -719,7 +719,7 @@ func TestCore_HandleLogin_Token(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
expect := &TokenEntry{
|
||||
expect := &logical.TokenEntry{
|
||||
ID: clientToken,
|
||||
Accessor: te.Accessor,
|
||||
Parent: "",
|
||||
|
@ -1022,7 +1022,7 @@ func TestCore_HandleRequest_CreateToken_Lease(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
expect := &TokenEntry{
|
||||
expect := &logical.TokenEntry{
|
||||
ID: clientToken,
|
||||
Accessor: te.Accessor,
|
||||
Parent: root,
|
||||
|
@ -1067,7 +1067,7 @@ func TestCore_HandleRequest_CreateToken_NoDefaultPolicy(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
expect := &TokenEntry{
|
||||
expect := &logical.TokenEntry{
|
||||
ID: clientToken,
|
||||
Accessor: te.Accessor,
|
||||
Parent: root,
|
||||
|
|
|
@ -557,7 +557,7 @@ func (m *ExpirationManager) RevokePrefix(prefix string) error {
|
|||
// This is done by using the secondary index. It also removes the lease entry
|
||||
// for the token itself. As a result it should *ONLY* ever be called from the
|
||||
// token store's revokeSalted function.
|
||||
func (m *ExpirationManager) RevokeByToken(te *TokenEntry) error {
|
||||
func (m *ExpirationManager) RevokeByToken(te *logical.TokenEntry) error {
|
||||
defer metrics.MeasureSince([]string{"expire", "revoke-by-token"}, time.Now())
|
||||
|
||||
// Lookup the leases
|
||||
|
@ -1227,7 +1227,7 @@ func (m *ExpirationManager) removeIndexByToken(token, leaseID string) error {
|
|||
// CreateOrFetchRevocationLeaseByToken is used to create or fetch the matching
|
||||
// leaseID for a particular token. The lease is set to expire immediately after
|
||||
// it's created.
|
||||
func (m *ExpirationManager) CreateOrFetchRevocationLeaseByToken(te *TokenEntry) (string, error) {
|
||||
func (m *ExpirationManager) CreateOrFetchRevocationLeaseByToken(te *logical.TokenEntry) (string, error) {
|
||||
// Fetch the saltedID of the token and construct the leaseID
|
||||
saltedID, err := m.tokenStore.SaltID(m.quitContext, te.ID)
|
||||
if err != nil {
|
||||
|
|
|
@ -736,7 +736,7 @@ func TestExpiration_RevokeByToken(t *testing.T) {
|
|||
}
|
||||
|
||||
// Should nuke all the keys
|
||||
te := &TokenEntry{
|
||||
te := &logical.TokenEntry{
|
||||
ID: "foobarbaz",
|
||||
}
|
||||
if err := exp.RevokeByToken(te); err != nil {
|
||||
|
@ -823,7 +823,7 @@ func TestExpiration_RevokeByToken_Blocking(t *testing.T) {
|
|||
}
|
||||
|
||||
// Should nuke all the keys
|
||||
te := &TokenEntry{
|
||||
te := &logical.TokenEntry{
|
||||
ID: "foobarbaz",
|
||||
}
|
||||
if err := exp.RevokeByToken(te); err != nil {
|
||||
|
@ -899,7 +899,7 @@ func TestExpiration_RenewToken(t *testing.T) {
|
|||
|
||||
func TestExpiration_RenewToken_period(t *testing.T) {
|
||||
exp := mockExpiration(t)
|
||||
root := &TokenEntry{
|
||||
root := &logical.TokenEntry{
|
||||
Policies: []string{"root"},
|
||||
Path: "auth/token/root",
|
||||
DisplayName: "root",
|
||||
|
|
|
@ -29,7 +29,7 @@ func TestIdentityStore_EntityIDPassthrough(t *testing.T) {
|
|||
}
|
||||
|
||||
// Create a token with the above created entity set on it
|
||||
ent := &TokenEntry{
|
||||
ent := &logical.TokenEntry{
|
||||
ID: "testtokenid",
|
||||
Path: "test",
|
||||
Policies: []string{"root"},
|
||||
|
@ -221,7 +221,7 @@ func TestIdentityStore_WrapInfoInheritance(t *testing.T) {
|
|||
|
||||
// Create a token which has EntityID set and has update permissions to
|
||||
// sys/wrapping/wrap
|
||||
te := &TokenEntry{
|
||||
te := &logical.TokenEntry{
|
||||
Path: "test",
|
||||
Policies: []string{"default", responseWrappingPolicyName},
|
||||
EntityID: entityID,
|
||||
|
@ -260,7 +260,7 @@ func TestIdentityStore_TokenEntityInheritance(t *testing.T) {
|
|||
ts := c.tokenStore
|
||||
|
||||
// Create a token which has EntityID set
|
||||
te := &TokenEntry{
|
||||
te := &logical.TokenEntry{
|
||||
Path: "test",
|
||||
Policies: []string{"dev", "prod"},
|
||||
EntityID: "testentityid",
|
||||
|
|
|
@ -1283,7 +1283,7 @@ func TestSystemBackend_revokePrefixAuth_newUrl(t *testing.T) {
|
|||
|
||||
exp := ts.expiration
|
||||
|
||||
te := &TokenEntry{
|
||||
te := &logical.TokenEntry{
|
||||
ID: "foo",
|
||||
Path: "auth/github/login/bar",
|
||||
TTL: time.Hour,
|
||||
|
@ -1346,7 +1346,7 @@ func TestSystemBackend_revokePrefixAuth_origUrl(t *testing.T) {
|
|||
|
||||
exp := ts.expiration
|
||||
|
||||
te := &TokenEntry{
|
||||
te := &logical.TokenEntry{
|
||||
ID: "foo",
|
||||
Path: "auth/github/login/bar",
|
||||
TTL: time.Hour,
|
||||
|
|
|
@ -77,7 +77,7 @@ func (c *Core) fetchEntityAndDerivedPolicies(entityID string) (*identity.Entity,
|
|||
return entity, policies, err
|
||||
}
|
||||
|
||||
func (c *Core) fetchACLTokenEntryAndEntity(req *logical.Request) (*ACL, *TokenEntry, *identity.Entity, error) {
|
||||
func (c *Core) fetchACLTokenEntryAndEntity(req *logical.Request) (*ACL, *logical.TokenEntry, *identity.Entity, error) {
|
||||
defer metrics.MeasureSince([]string{"core", "fetch_acl_and_token"}, time.Now())
|
||||
|
||||
// Ensure there is a client token
|
||||
|
@ -91,10 +91,17 @@ func (c *Core) fetchACLTokenEntryAndEntity(req *logical.Request) (*ACL, *TokenEn
|
|||
}
|
||||
|
||||
// Resolve the token policy
|
||||
te, err := c.tokenStore.Lookup(c.activeContext, req.ClientToken)
|
||||
if err != nil {
|
||||
c.logger.Error("failed to lookup token", "error", err)
|
||||
return nil, nil, nil, ErrInternalError
|
||||
var te *logical.TokenEntry
|
||||
switch req.TokenEntry() {
|
||||
case nil:
|
||||
var err error
|
||||
te, err = c.tokenStore.Lookup(c.activeContext, req.ClientToken)
|
||||
if err != nil {
|
||||
c.logger.Error("failed to lookup token", "error", err)
|
||||
return nil, nil, nil, ErrInternalError
|
||||
}
|
||||
default:
|
||||
te = req.TokenEntry()
|
||||
}
|
||||
|
||||
// Ensure the token is valid
|
||||
|
@ -142,11 +149,11 @@ func (c *Core) fetchACLTokenEntryAndEntity(req *logical.Request) (*ACL, *TokenEn
|
|||
return acl, te, entity, nil
|
||||
}
|
||||
|
||||
func (c *Core) checkToken(ctx context.Context, req *logical.Request, unauth bool) (*logical.Auth, *TokenEntry, error) {
|
||||
func (c *Core) checkToken(ctx context.Context, req *logical.Request, unauth bool) (*logical.Auth, *logical.TokenEntry, error) {
|
||||
defer metrics.MeasureSince([]string{"core", "check_token"}, time.Now())
|
||||
|
||||
var acl *ACL
|
||||
var te *TokenEntry
|
||||
var te *logical.TokenEntry
|
||||
var entity *identity.Entity
|
||||
var err error
|
||||
|
||||
|
@ -783,7 +790,7 @@ func (c *Core) handleLoginRequest(ctx context.Context, req *logical.Request) (re
|
|||
}
|
||||
|
||||
// Generate a token
|
||||
te := TokenEntry{
|
||||
te := logical.TokenEntry{
|
||||
Path: req.Path,
|
||||
Policies: auth.Policies,
|
||||
Meta: auth.Metadata,
|
||||
|
|
|
@ -79,7 +79,7 @@ var (
|
|||
// is particularly useful to fetch the accessor of the client token and get it
|
||||
// populated in the logical request along with the client token. The accessor
|
||||
// of the client token can get audit logged.
|
||||
func (c *Core) LookupToken(token string) (*TokenEntry, error) {
|
||||
func (c *Core) LookupToken(token string) (*logical.TokenEntry, error) {
|
||||
if token == "" {
|
||||
return nil, fmt.Errorf("missing client token")
|
||||
}
|
||||
|
@ -551,118 +551,6 @@ func (ts *TokenStore) Salt(ctx context.Context) (*salt.Salt, error) {
|
|||
return salt, nil
|
||||
}
|
||||
|
||||
// TokenEntry is used to represent a given token
|
||||
type TokenEntry struct {
|
||||
// ID of this entry, generally a random UUID
|
||||
ID string `json:"id" mapstructure:"id" structs:"id" sentinel:""`
|
||||
|
||||
// Accessor for this token, a random UUID
|
||||
Accessor string `json:"accessor" mapstructure:"accessor" structs:"accessor" sentinel:""`
|
||||
|
||||
// Parent token, used for revocation trees
|
||||
Parent string `json:"parent" mapstructure:"parent" structs:"parent" sentinel:""`
|
||||
|
||||
// Which named policies should be used
|
||||
Policies []string `json:"policies" mapstructure:"policies" structs:"policies"`
|
||||
|
||||
// Used for audit trails, this is something like "auth/user/login"
|
||||
Path string `json:"path" mapstructure:"path" structs:"path"`
|
||||
|
||||
// Used for auditing. This could include things like "source", "user", "ip"
|
||||
Meta map[string]string `json:"meta" mapstructure:"meta" structs:"meta" sentinel:"meta"`
|
||||
|
||||
// Used for operators to be able to associate with the source
|
||||
DisplayName string `json:"display_name" mapstructure:"display_name" structs:"display_name"`
|
||||
|
||||
// Used to restrict the number of uses (zero is unlimited). This is to
|
||||
// support one-time-tokens (generalized). There are a few special values:
|
||||
// if it's -1 it has run through its use counts and is executing its final
|
||||
// use; if it's -2 it is tainted, which means revocation is currently
|
||||
// running on it; and if it's -3 it's also tainted but revocation
|
||||
// previously ran and failed, so this hints the tidy function to try it
|
||||
// again.
|
||||
NumUses int `json:"num_uses" mapstructure:"num_uses" structs:"num_uses"`
|
||||
|
||||
// Time of token creation
|
||||
CreationTime int64 `json:"creation_time" mapstructure:"creation_time" structs:"creation_time" sentinel:""`
|
||||
|
||||
// Duration set when token was created
|
||||
TTL time.Duration `json:"ttl" mapstructure:"ttl" structs:"ttl" sentinel:""`
|
||||
|
||||
// Explicit maximum TTL on the token
|
||||
ExplicitMaxTTL time.Duration `json:"explicit_max_ttl" mapstructure:"explicit_max_ttl" structs:"explicit_max_ttl" sentinel:""`
|
||||
|
||||
// If set, the role that was used for parameters at creation time
|
||||
Role string `json:"role" mapstructure:"role" structs:"role"`
|
||||
|
||||
// If set, the period of the token. This is only used when created directly
|
||||
// through the create endpoint; periods managed by roles or other auth
|
||||
// backends are subject to those renewal rules.
|
||||
Period time.Duration `json:"period" mapstructure:"period" structs:"period" sentinel:""`
|
||||
|
||||
// These are the deprecated fields
|
||||
DisplayNameDeprecated string `json:"DisplayName" mapstructure:"DisplayName" structs:"DisplayName" sentinel:""`
|
||||
NumUsesDeprecated int `json:"NumUses" mapstructure:"NumUses" structs:"NumUses" sentinel:""`
|
||||
CreationTimeDeprecated int64 `json:"CreationTime" mapstructure:"CreationTime" structs:"CreationTime" sentinel:""`
|
||||
ExplicitMaxTTLDeprecated time.Duration `json:"ExplicitMaxTTL" mapstructure:"ExplicitMaxTTL" structs:"ExplicitMaxTTL" sentinel:""`
|
||||
|
||||
EntityID string `json:"entity_id" mapstructure:"entity_id" structs:"entity_id"`
|
||||
|
||||
// The set of CIDRs that this token can be used with
|
||||
BoundCIDRs []*sockaddr.SockAddrMarshaler `json:"bound_cidrs"`
|
||||
}
|
||||
|
||||
func (te *TokenEntry) SentinelGet(key string) (interface{}, error) {
|
||||
if te == nil {
|
||||
return nil, nil
|
||||
}
|
||||
switch key {
|
||||
case "period":
|
||||
return te.Period, nil
|
||||
|
||||
case "period_seconds":
|
||||
return int64(te.Period.Seconds()), nil
|
||||
|
||||
case "explicit_max_ttl":
|
||||
return te.ExplicitMaxTTL, nil
|
||||
|
||||
case "explicit_max_ttl_seconds":
|
||||
return int64(te.ExplicitMaxTTL.Seconds()), nil
|
||||
|
||||
case "creation_ttl":
|
||||
return te.TTL, nil
|
||||
|
||||
case "creation_ttl_seconds":
|
||||
return int64(te.TTL.Seconds()), nil
|
||||
|
||||
case "creation_time":
|
||||
return time.Unix(te.CreationTime, 0).Format(time.RFC3339Nano), nil
|
||||
|
||||
case "creation_time_unix":
|
||||
return time.Unix(te.CreationTime, 0), nil
|
||||
|
||||
case "meta", "metadata":
|
||||
return te.Meta, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (te *TokenEntry) SentinelKeys() []string {
|
||||
return []string{
|
||||
"period",
|
||||
"period_seconds",
|
||||
"explicit_max_ttl",
|
||||
"explicit_max_ttl_seconds",
|
||||
"creation_ttl",
|
||||
"creation_ttl_seconds",
|
||||
"creation_time",
|
||||
"creation_time_unix",
|
||||
"meta",
|
||||
"metadata",
|
||||
}
|
||||
}
|
||||
|
||||
// tsRoleEntry contains token store role information
|
||||
type tsRoleEntry struct {
|
||||
// The name of the role. Embedded so it can be used for pathing
|
||||
|
@ -720,8 +608,8 @@ func (ts *TokenStore) SaltID(ctx context.Context, id string) (string, error) {
|
|||
}
|
||||
|
||||
// RootToken is used to generate a new token with root privileges and no parent
|
||||
func (ts *TokenStore) rootToken(ctx context.Context) (*TokenEntry, error) {
|
||||
te := &TokenEntry{
|
||||
func (ts *TokenStore) rootToken(ctx context.Context) (*logical.TokenEntry, error) {
|
||||
te := &logical.TokenEntry{
|
||||
Policies: []string{"root"},
|
||||
Path: "auth/token/root",
|
||||
DisplayName: "root",
|
||||
|
@ -763,7 +651,7 @@ func (ts *TokenStore) tokenStoreAccessorList(ctx context.Context, req *logical.R
|
|||
|
||||
// createAccessor is used to create an identifier for the token ID.
|
||||
// A storage index, mapping the accessor to the token ID is also created.
|
||||
func (ts *TokenStore) createAccessor(ctx context.Context, entry *TokenEntry) error {
|
||||
func (ts *TokenStore) createAccessor(ctx context.Context, entry *logical.TokenEntry) error {
|
||||
defer metrics.MeasureSince([]string{"token", "createAccessor"}, time.Now())
|
||||
|
||||
// Create a random accessor
|
||||
|
@ -798,7 +686,7 @@ func (ts *TokenStore) createAccessor(ctx context.Context, entry *TokenEntry) err
|
|||
|
||||
// Create is used to create a new token entry. The entry is assigned
|
||||
// a newly generated ID if not provided.
|
||||
func (ts *TokenStore) create(ctx context.Context, entry *TokenEntry) error {
|
||||
func (ts *TokenStore) create(ctx context.Context, entry *logical.TokenEntry) error {
|
||||
defer metrics.MeasureSince([]string{"token", "create"}, time.Now())
|
||||
// Generate an ID if necessary
|
||||
if entry.ID == "" {
|
||||
|
@ -830,14 +718,14 @@ func (ts *TokenStore) create(ctx context.Context, entry *TokenEntry) error {
|
|||
|
||||
// Store is used to store an updated token entry without writing the
|
||||
// secondary index.
|
||||
func (ts *TokenStore) store(ctx context.Context, entry *TokenEntry) error {
|
||||
func (ts *TokenStore) store(ctx context.Context, entry *logical.TokenEntry) error {
|
||||
defer metrics.MeasureSince([]string{"token", "store"}, time.Now())
|
||||
return ts.storeCommon(ctx, entry, false)
|
||||
}
|
||||
|
||||
// storeCommon handles the actual storage of an entry, possibly generating
|
||||
// secondary indexes
|
||||
func (ts *TokenStore) storeCommon(ctx context.Context, entry *TokenEntry, writeSecondary bool) error {
|
||||
func (ts *TokenStore) storeCommon(ctx context.Context, entry *logical.TokenEntry, writeSecondary bool) error {
|
||||
saltedID, err := ts.SaltID(ctx, entry.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -895,7 +783,7 @@ func (ts *TokenStore) storeCommon(ctx context.Context, entry *TokenEntry, writeS
|
|||
// locking here isn't perfect, as other parts of the code may update an entry,
|
||||
// but usually none after the entry is already created...so this is pretty
|
||||
// good.
|
||||
func (ts *TokenStore) UseToken(ctx context.Context, te *TokenEntry) (*TokenEntry, error) {
|
||||
func (ts *TokenStore) UseToken(ctx context.Context, te *logical.TokenEntry) (*logical.TokenEntry, error) {
|
||||
if te == nil {
|
||||
return nil, fmt.Errorf("invalid token entry provided for use count decrementing")
|
||||
}
|
||||
|
@ -955,7 +843,7 @@ func (ts *TokenStore) UseToken(ctx context.Context, te *TokenEntry) (*TokenEntry
|
|||
return te, nil
|
||||
}
|
||||
|
||||
func (ts *TokenStore) UseTokenByID(ctx context.Context, id string) (*TokenEntry, error) {
|
||||
func (ts *TokenStore) UseTokenByID(ctx context.Context, id string) (*logical.TokenEntry, error) {
|
||||
te, err := ts.Lookup(ctx, id)
|
||||
if err != nil {
|
||||
return te, err
|
||||
|
@ -965,7 +853,7 @@ func (ts *TokenStore) UseTokenByID(ctx context.Context, id string) (*TokenEntry,
|
|||
}
|
||||
|
||||
// Lookup is used to find a token given its ID. It acquires a read lock, then calls lookupSalted.
|
||||
func (ts *TokenStore) Lookup(ctx context.Context, id string) (*TokenEntry, error) {
|
||||
func (ts *TokenStore) Lookup(ctx context.Context, id string) (*logical.TokenEntry, error) {
|
||||
defer metrics.MeasureSince([]string{"token", "lookup"}, time.Now())
|
||||
if id == "" {
|
||||
return nil, fmt.Errorf("cannot lookup blank token")
|
||||
|
@ -984,7 +872,7 @@ func (ts *TokenStore) Lookup(ctx context.Context, id string) (*TokenEntry, error
|
|||
|
||||
// lookupTainted is used to find a token that may or maynot be tainted given its
|
||||
// ID. It acquires a read lock, then calls lookupSalted.
|
||||
func (ts *TokenStore) lookupTainted(ctx context.Context, id string) (*TokenEntry, error) {
|
||||
func (ts *TokenStore) lookupTainted(ctx context.Context, id string) (*logical.TokenEntry, error) {
|
||||
defer metrics.MeasureSince([]string{"token", "lookup"}, time.Now())
|
||||
if id == "" {
|
||||
return nil, fmt.Errorf("cannot lookup blank token")
|
||||
|
@ -1004,7 +892,7 @@ func (ts *TokenStore) lookupTainted(ctx context.Context, id string) (*TokenEntry
|
|||
// lookupSalted is used to find a token given its salted ID. If tainted is
|
||||
// true, entries that are in some revocation state (currently, indicated by num
|
||||
// uses < 0), the entry will be returned anyways
|
||||
func (ts *TokenStore) lookupSalted(ctx context.Context, saltedID string, tainted bool) (*TokenEntry, error) {
|
||||
func (ts *TokenStore) lookupSalted(ctx context.Context, saltedID string, tainted bool) (*logical.TokenEntry, error) {
|
||||
// Lookup token
|
||||
path := lookupPrefix + saltedID
|
||||
raw, err := ts.view.Get(ctx, path)
|
||||
|
@ -1018,7 +906,7 @@ func (ts *TokenStore) lookupSalted(ctx context.Context, saltedID string, tainted
|
|||
}
|
||||
|
||||
// Unmarshal the token
|
||||
entry := new(TokenEntry)
|
||||
entry := new(logical.TokenEntry)
|
||||
if err := jsonutil.DecodeJSON(raw.Value, entry); err != nil {
|
||||
return nil, errwrap.Wrapf("failed to decode entry: {{err}}", err)
|
||||
}
|
||||
|
@ -1075,7 +963,7 @@ func (ts *TokenStore) lookupSalted(ctx context.Context, saltedID string, tainted
|
|||
return nil, errwrap.Wrapf("failed to fetch lease times: {{err}}", err)
|
||||
}
|
||||
|
||||
var ret *TokenEntry
|
||||
var ret *logical.TokenEntry
|
||||
|
||||
switch {
|
||||
// It's a root token with unlimited creation TTL (so never had an
|
||||
|
@ -1551,10 +1439,10 @@ func (ts *TokenStore) handleTidy(ctx context.Context, req *logical.Request, data
|
|||
if te == nil {
|
||||
ts.logger.Info("deleting token with nil entry", "salted_token", saltedID)
|
||||
|
||||
// RevokeByToken expects a '*TokenEntry'. For the
|
||||
// RevokeByToken expects a '*logical.TokenEntry'. For the
|
||||
// purposes of tidying, it is sufficient if the token
|
||||
// entry only has ID set.
|
||||
tokenEntry := &TokenEntry{
|
||||
tokenEntry := &logical.TokenEntry{
|
||||
ID: accessorEntry.TokenID,
|
||||
}
|
||||
|
||||
|
@ -1754,7 +1642,7 @@ func (ts *TokenStore) handleCreateCommon(ctx context.Context, req *logical.Reque
|
|||
}
|
||||
|
||||
// Setup the token entry
|
||||
te := TokenEntry{
|
||||
te := logical.TokenEntry{
|
||||
Parent: req.ClientToken,
|
||||
|
||||
// The mount point is always the same since we have only one token
|
||||
|
|
|
@ -108,7 +108,7 @@ func TestTokenStore_TokenEntryUpgrade(t *testing.T) {
|
|||
}
|
||||
|
||||
// Test the default case to ensure there are no regressions
|
||||
ent := &TokenEntry{
|
||||
ent := &logical.TokenEntry{
|
||||
DisplayName: "test-display-name",
|
||||
Path: "test",
|
||||
Policies: []string{"dev", "ops"},
|
||||
|
@ -152,7 +152,7 @@ func TestTokenStore_TokenEntryUpgrade(t *testing.T) {
|
|||
}
|
||||
|
||||
// Fill in the deprecated fields and read out from proper fields
|
||||
ent = &TokenEntry{
|
||||
ent = &logical.TokenEntry{
|
||||
Path: "test",
|
||||
Policies: []string{"dev", "ops"},
|
||||
DisplayNameDeprecated: "test-display-name",
|
||||
|
@ -196,7 +196,7 @@ func TestTokenStore_TokenEntryUpgrade(t *testing.T) {
|
|||
}
|
||||
|
||||
// Check if NumUses picks up a lower value
|
||||
ent = &TokenEntry{
|
||||
ent = &logical.TokenEntry{
|
||||
Path: "test",
|
||||
NumUses: 5,
|
||||
NumUsesDeprecated: 10,
|
||||
|
@ -229,7 +229,7 @@ func TestTokenStore_TokenEntryUpgrade(t *testing.T) {
|
|||
|
||||
// Switch the values from deprecated and proper field and check if the
|
||||
// lower value is still getting picked up
|
||||
ent = &TokenEntry{
|
||||
ent = &logical.TokenEntry{
|
||||
Path: "test",
|
||||
NumUses: 10,
|
||||
NumUsesDeprecated: 5,
|
||||
|
@ -301,7 +301,7 @@ func testMakeTokenViaRequest(t testing.TB, ts *TokenStore, req *logical.Request)
|
|||
return resp
|
||||
}
|
||||
|
||||
func testMakeTokenDirectly(t testing.TB, ts *TokenStore, te *TokenEntry) {
|
||||
func testMakeTokenDirectly(t testing.TB, ts *TokenStore, te *logical.TokenEntry) {
|
||||
if err := ts.create(context.Background(), te); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -346,7 +346,7 @@ func TestTokenStore_AccessorIndex(t *testing.T) {
|
|||
c, _, _ := TestCoreUnsealed(t)
|
||||
ts := c.tokenStore
|
||||
|
||||
ent := &TokenEntry{
|
||||
ent := &logical.TokenEntry{
|
||||
Path: "test",
|
||||
Policies: []string{"dev", "ops"},
|
||||
TTL: time.Hour,
|
||||
|
@ -603,7 +603,7 @@ func TestTokenStore_CreateLookup(t *testing.T) {
|
|||
c, _, _ := TestCoreUnsealed(t)
|
||||
ts := c.tokenStore
|
||||
|
||||
ent := &TokenEntry{
|
||||
ent := &logical.TokenEntry{
|
||||
Path: "test",
|
||||
Policies: []string{"dev", "ops"},
|
||||
TTL: time.Hour,
|
||||
|
@ -642,7 +642,7 @@ func TestTokenStore_CreateLookup_ProvidedID(t *testing.T) {
|
|||
c, _, _ := TestCoreUnsealed(t)
|
||||
ts := c.tokenStore
|
||||
|
||||
ent := &TokenEntry{
|
||||
ent := &logical.TokenEntry{
|
||||
ID: "foobarbaz",
|
||||
Path: "test",
|
||||
Policies: []string{"dev", "ops"},
|
||||
|
@ -685,7 +685,7 @@ func TestTokenStore_CreateLookup_ExpirationInRestoreMode(t *testing.T) {
|
|||
c, _, _ := TestCoreUnsealed(t)
|
||||
ts := c.tokenStore
|
||||
|
||||
ent := &TokenEntry{Path: "test", Policies: []string{"dev", "ops"}}
|
||||
ent := &logical.TokenEntry{Path: "test", Policies: []string{"dev", "ops"}}
|
||||
if err := ts.create(context.Background(), ent); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
@ -778,7 +778,7 @@ func TestTokenStore_UseToken(t *testing.T) {
|
|||
}
|
||||
|
||||
// Create a restricted token
|
||||
ent = &TokenEntry{
|
||||
ent = &logical.TokenEntry{
|
||||
Path: "test",
|
||||
Policies: []string{"dev", "ops"},
|
||||
NumUses: 2,
|
||||
|
@ -835,7 +835,7 @@ func TestTokenStore_Revoke(t *testing.T) {
|
|||
c, _, _ := TestCoreUnsealed(t)
|
||||
ts := c.tokenStore
|
||||
|
||||
ent := &TokenEntry{Path: "test", Policies: []string{"dev", "ops"}}
|
||||
ent := &logical.TokenEntry{Path: "test", Policies: []string{"dev", "ops"}}
|
||||
if err := ts.create(context.Background(), ent); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
@ -871,7 +871,7 @@ func TestTokenStore_Revoke_Leases(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ent := &TokenEntry{Path: "test", Policies: []string{"dev", "ops"}}
|
||||
ent := &logical.TokenEntry{Path: "test", Policies: []string{"dev", "ops"}}
|
||||
if err := ts.create(context.Background(), ent); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
@ -920,14 +920,14 @@ func TestTokenStore_Revoke_Orphan(t *testing.T) {
|
|||
c, _, _ := TestCoreUnsealed(t)
|
||||
ts := c.tokenStore
|
||||
|
||||
ent := &TokenEntry{
|
||||
ent := &logical.TokenEntry{
|
||||
Path: "test",
|
||||
Policies: []string{"dev", "ops"},
|
||||
TTL: time.Hour,
|
||||
}
|
||||
testMakeTokenDirectly(t, ts, ent)
|
||||
|
||||
ent2 := &TokenEntry{
|
||||
ent2 := &logical.TokenEntry{
|
||||
Parent: ent.ID,
|
||||
TTL: time.Hour,
|
||||
}
|
||||
|
@ -1006,24 +1006,24 @@ func BenchmarkTokenStore_RevokeTree(b *testing.B) {
|
|||
|
||||
// Builds a TokenTree of a specified depth, so that
|
||||
// we may run revoke tests on it.
|
||||
func buildTokenTree(t testing.TB, ts *TokenStore, depth uint64) (root *TokenEntry, children []*TokenEntry) {
|
||||
root = &TokenEntry{
|
||||
func buildTokenTree(t testing.TB, ts *TokenStore, depth uint64) (root *logical.TokenEntry, children []*logical.TokenEntry) {
|
||||
root = &logical.TokenEntry{
|
||||
TTL: time.Hour,
|
||||
}
|
||||
testMakeTokenDirectly(t, ts, root)
|
||||
|
||||
frontier := []*TokenEntry{root}
|
||||
frontier := []*logical.TokenEntry{root}
|
||||
current := uint64(0)
|
||||
for current < depth {
|
||||
next := make([]*TokenEntry, 0, 2*len(frontier))
|
||||
next := make([]*logical.TokenEntry, 0, 2*len(frontier))
|
||||
for _, node := range frontier {
|
||||
left := &TokenEntry{
|
||||
left := &logical.TokenEntry{
|
||||
Parent: node.ID,
|
||||
TTL: time.Hour,
|
||||
}
|
||||
testMakeTokenDirectly(t, ts, left)
|
||||
|
||||
right := &TokenEntry{
|
||||
right := &logical.TokenEntry{
|
||||
Parent: node.ID,
|
||||
TTL: time.Hour,
|
||||
}
|
||||
|
@ -1043,24 +1043,24 @@ func TestTokenStore_RevokeSelf(t *testing.T) {
|
|||
exp := mockExpiration(t)
|
||||
ts := exp.tokenStore
|
||||
|
||||
ent1 := &TokenEntry{
|
||||
ent1 := &logical.TokenEntry{
|
||||
TTL: time.Hour,
|
||||
}
|
||||
testMakeTokenDirectly(t, ts, ent1)
|
||||
|
||||
ent2 := &TokenEntry{
|
||||
ent2 := &logical.TokenEntry{
|
||||
Parent: ent1.ID,
|
||||
TTL: time.Hour,
|
||||
}
|
||||
testMakeTokenDirectly(t, ts, ent2)
|
||||
|
||||
ent3 := &TokenEntry{
|
||||
ent3 := &logical.TokenEntry{
|
||||
Parent: ent2.ID,
|
||||
TTL: time.Hour,
|
||||
}
|
||||
testMakeTokenDirectly(t, ts, ent3)
|
||||
|
||||
ent4 := &TokenEntry{
|
||||
ent4 := &logical.TokenEntry{
|
||||
Parent: ent2.ID,
|
||||
TTL: time.Hour,
|
||||
}
|
||||
|
@ -1075,7 +1075,7 @@ func TestTokenStore_RevokeSelf(t *testing.T) {
|
|||
}
|
||||
|
||||
lookup := []string{ent1.ID, ent2.ID, ent3.ID, ent4.ID}
|
||||
var out *TokenEntry
|
||||
var out *logical.TokenEntry
|
||||
for _, id := range lookup {
|
||||
var found bool
|
||||
for i := 0; i < 10; i++ {
|
||||
|
@ -1135,7 +1135,7 @@ func TestTokenStore_HandleRequest_CreateToken_DisplayName(t *testing.T) {
|
|||
t.Fatalf("err: %v\nresp: %#v", err, resp)
|
||||
}
|
||||
|
||||
expected := &TokenEntry{
|
||||
expected := &logical.TokenEntry{
|
||||
ID: resp.Auth.ClientToken,
|
||||
Accessor: resp.Auth.Accessor,
|
||||
Parent: root,
|
||||
|
@ -1167,7 +1167,7 @@ func TestTokenStore_HandleRequest_CreateToken_NumUses(t *testing.T) {
|
|||
t.Fatalf("err: %v\nresp: %#v", err, resp)
|
||||
}
|
||||
|
||||
expected := &TokenEntry{
|
||||
expected := &logical.TokenEntry{
|
||||
ID: resp.Auth.ClientToken,
|
||||
Accessor: resp.Auth.Accessor,
|
||||
Parent: root,
|
||||
|
@ -1234,7 +1234,7 @@ func TestTokenStore_HandleRequest_CreateToken_NoPolicy(t *testing.T) {
|
|||
t.Fatalf("err: %v\nresp: %#v", err, resp)
|
||||
}
|
||||
|
||||
expected := &TokenEntry{
|
||||
expected := &logical.TokenEntry{
|
||||
ID: resp.Auth.ClientToken,
|
||||
Accessor: resp.Auth.Accessor,
|
||||
Parent: root,
|
||||
|
|
|
@ -109,7 +109,7 @@ DONELISTHANDLING:
|
|||
// wrapping token ID in the audit logs, so that it can be determined from
|
||||
// the audit logs whether the token was ever actually used.
|
||||
creationTime := time.Now()
|
||||
te := TokenEntry{
|
||||
te := logical.TokenEntry{
|
||||
Path: req.Path,
|
||||
Policies: []string{"response-wrapping"},
|
||||
CreationTime: creationTime.Unix(),
|
||||
|
|
Loading…
Reference in New Issue